aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ChangeLog60
-rw-r--r--src/lib/crypto/ChangeLog21
-rw-r--r--src/lib/crypto/Makefile.in4
-rw-r--r--src/lib/crypto/coll_proof_cksum.c9
-rw-r--r--src/lib/crypto/crypto_libinit.h6
-rw-r--r--src/lib/crypto/des/ChangeLog18
-rw-r--r--src/lib/crypto/des/afsstring2key.c58
-rw-r--r--src/lib/crypto/des/des_int.h2
-rw-r--r--src/lib/crypto/des/string2key.c3
-rw-r--r--src/lib/crypto/dk/ChangeLog14
-rw-r--r--src/lib/crypto/dk/derive.c4
-rw-r--r--src/lib/crypto/dk/dk_decrypt.c20
-rw-r--r--src/lib/crypto/dk/dk_encrypt.c30
-rw-r--r--src/lib/crypto/keyed_cksum.c8
-rw-r--r--src/lib/crypto/make_checksum.c1
-rw-r--r--src/lib/crypto/old/ChangeLog6
-rw-r--r--src/lib/crypto/old/old_decrypt.c19
-rw-r--r--src/lib/crypto/old/old_encrypt.c9
-rw-r--r--src/lib/crypto/prng.c2
-rw-r--r--src/lib/crypto/sha1/ChangeLog23
-rw-r--r--src/lib/crypto/sha1/Makefile.in21
-rw-r--r--src/lib/crypto/sha1/shs.c75
-rw-r--r--src/lib/crypto/sha1/shs.h19
-rw-r--r--src/lib/crypto/sha1/t_shs.c12
-rw-r--r--src/lib/crypto/sha1/t_shs3.c583
-rw-r--r--src/lib/crypto/valid_cksumtype.c8
-rw-r--r--src/lib/crypto/valid_enctype.c8
-rw-r--r--src/lib/gssapi/ChangeLog13
-rw-r--r--src/lib/gssapi/Makefile.in2
-rw-r--r--src/lib/gssapi/generic/ChangeLog47
-rw-r--r--src/lib/gssapi/generic/disp_com_err_status.c5
-rw-r--r--src/lib/gssapi/generic/gssapi.hin148
-rw-r--r--src/lib/gssapi/generic/gssapiP_generic.h34
-rw-r--r--src/lib/gssapi/generic/gssapi_generic.c118
-rw-r--r--src/lib/gssapi/generic/gssapi_generic.h22
-rw-r--r--src/lib/gssapi/gss_libinit.c8
-rw-r--r--src/lib/gssapi/krb5/3des.txt274
-rw-r--r--src/lib/gssapi/krb5/ChangeLog193
-rw-r--r--src/lib/gssapi/krb5/accept_sec_context.c508
-rw-r--r--src/lib/gssapi/krb5/acquire_cred.c44
-rw-r--r--src/lib/gssapi/krb5/add_cred.c46
-rw-r--r--src/lib/gssapi/krb5/disp_status.c5
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h85
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5.c23
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5.h54
-rw-r--r--src/lib/gssapi/krb5/import_sec_context.c2
-rw-r--r--src/lib/gssapi/krb5/init_sec_context.c523
-rw-r--r--src/lib/gssapi/krb5/inq_cred.c32
-rw-r--r--src/lib/gssapi/krb5/k5seal.c852
-rw-r--r--src/lib/gssapi/krb5/k5unseal.c1086
-rw-r--r--src/lib/gssapi/krb5/ser_sctx.c6
-rw-r--r--src/lib/gssapi/krb5/util_cksum.c1
-rw-r--r--src/lib/gssapi/krb5/util_crypt.c36
-rw-r--r--src/lib/gssapi/krb5/util_seed.c2
-rw-r--r--src/lib/gssapi/krb5/util_seqnum.c4
-rw-r--r--src/lib/gssapi/krb5/wrap_size_limit.c131
-rw-r--r--src/lib/gssapi32.def8
-rw-r--r--src/lib/kadm5/ChangeLog53
-rw-r--r--src/lib/kadm5/adb.h1
-rw-r--r--src/lib/kadm5/admin.h32
-rw-r--r--src/lib/kadm5/admin_internal.h3
-rw-r--r--src/lib/kadm5/alt_prof.c73
-rw-r--r--src/lib/kadm5/chpass_util.c60
-rw-r--r--src/lib/kadm5/clnt/ChangeLog20
-rw-r--r--src/lib/kadm5/clnt/Makefile.in2
-rw-r--r--src/lib/kadm5/clnt/client_init.c8
-rw-r--r--src/lib/kadm5/clnt/clnt_chpass_util.c5
-rw-r--r--src/lib/kadm5/kadm_rpc_xdr.c10
-rw-r--r--src/lib/kadm5/logger.c5
-rw-r--r--src/lib/kadm5/ovsec_glue.c6
-rw-r--r--src/lib/kadm5/srv/ChangeLog44
-rw-r--r--src/lib/kadm5/srv/Makefile.in2
-rw-r--r--src/lib/kadm5/srv/adb_openclose.c57
-rw-r--r--src/lib/kadm5/srv/svr_chpass_util.c5
-rw-r--r--src/lib/kadm5/srv/svr_principal.c44
-rw-r--r--src/lib/kadm5/str_conv.c17
-rw-r--r--src/lib/kadm5/unit-test/ChangeLog13
-rw-r--r--src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp4
-rw-r--r--src/lib/kadm5/unit-test/api.2/get-principal-v2.exp4
-rw-r--r--src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp4
-rw-r--r--src/lib/kadm5/unit-test/config/unix.exp8
-rw-r--r--src/lib/kdb/ChangeLog73
-rw-r--r--src/lib/kdb/Makefile.in2
-rw-r--r--src/lib/kdb/fetch_mkey.c2
-rw-r--r--src/lib/kdb/kdb_db2.c38
-rw-r--r--src/lib/kdb/kdb_db2.h6
-rw-r--r--src/lib/kdb/kdb_xdr.c16
-rw-r--r--src/lib/kdb/keytab.c58
-rw-r--r--src/lib/kdb/setup_mkey.c2
-rw-r--r--src/lib/kdb/store_mkey.c2
-rw-r--r--src/lib/kdb/t_kdb.c47
-rw-r--r--src/lib/krb4/ChangeLog103
-rw-r--r--src/lib/krb4/Password.c9
-rw-r--r--src/lib/krb4/configure.in2
-rw-r--r--src/lib/krb4/cr_auth_repl.c10
-rw-r--r--src/lib/krb4/cr_ciph.c11
-rw-r--r--src/lib/krb4/cr_death_pkt.c5
-rw-r--r--src/lib/krb4/cr_err_repl.c9
-rw-r--r--src/lib/krb4/cr_tkt.c18
-rw-r--r--src/lib/krb4/decomp_tkt.c16
-rw-r--r--src/lib/krb4/dest_tkt.c127
-rw-r--r--src/lib/krb4/g_ad_tkt.c45
-rw-r--r--src/lib/krb4/g_in_tkt.c14
-rw-r--r--src/lib/krb4/g_krbhst.c8
-rw-r--r--src/lib/krb4/g_krbrlm.c3
-rw-r--r--src/lib/krb4/g_pw_in_tkt.c1
-rw-r--r--src/lib/krb4/in_tkt.c92
-rw-r--r--src/lib/krb4/kntoln.c7
-rw-r--r--src/lib/krb4/kparse.c73
-rw-r--r--src/lib/krb4/kuserok.c7
-rw-r--r--src/lib/krb4/mk_auth.c6
-rw-r--r--src/lib/krb4/mk_err.c8
-rw-r--r--src/lib/krb4/mk_req.c13
-rw-r--r--src/lib/krb4/rd_req.c44
-rw-r--r--src/lib/krb4/rd_svc_key.c8
-rw-r--r--src/lib/krb4/realmofhost.c8
-rw-r--r--src/lib/krb4/recvauth.c7
-rw-r--r--src/lib/krb4/send_to_kdc.c3
-rw-r--r--src/lib/krb4/sendauth.c3
-rw-r--r--src/lib/krb4/tf_util.c123
-rw-r--r--src/lib/krb4/win_store.c20
-rw-r--r--src/lib/krb5/ChangeLog38
-rw-r--r--src/lib/krb5/Makefile.in6
-rw-r--r--src/lib/krb5/asn.1/ChangeLog91
-rw-r--r--src/lib/krb5/asn.1/asn1_encode.c12
-rw-r--r--src/lib/krb5/asn.1/asn1_get.c9
-rw-r--r--src/lib/krb5/asn.1/asn1_k_decode.c97
-rw-r--r--src/lib/krb5/asn.1/asn1buf.c71
-rw-r--r--src/lib/krb5/asn.1/asn1buf.h15
-rw-r--r--src/lib/krb5/asn.1/krb5_decode.c30
-rw-r--r--src/lib/krb5/ccache/ChangeLog61
-rw-r--r--src/lib/krb5/ccache/Makefile.in3
-rw-r--r--src/lib/krb5/ccache/ccapi/ChangeLog90
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc.c8
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc.h6
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc_util.c717
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc_util.h13
-rw-r--r--src/lib/krb5/ccache/ccapi/winccld.c3
-rw-r--r--src/lib/krb5/ccache/ccapi/winccld.h54
-rw-r--r--src/lib/krb5/ccache/ccdefault.c84
-rw-r--r--src/lib/krb5/ccache/ccdefops.c2
-rw-r--r--src/lib/krb5/ccache/ccfns.c131
-rw-r--r--src/lib/krb5/ccache/file/ChangeLog3
-rw-r--r--src/lib/krb5/ccache/file/fcc_gprin.c1
-rw-r--r--src/lib/krb5/ccache/stdio/ChangeLog3
-rw-r--r--src/lib/krb5/ccache/stdio/scc_skip.c1
-rw-r--r--src/lib/krb5/error_tables/ChangeLog16
-rw-r--r--src/lib/krb5/error_tables/asn1_err.et2
-rw-r--r--src/lib/krb5/error_tables/kdb5_err.et2
-rw-r--r--src/lib/krb5/error_tables/krb5_err.et8
-rw-r--r--src/lib/krb5/keytab/ChangeLog24
-rw-r--r--src/lib/krb5/keytab/Makefile.in2
-rw-r--r--src/lib/krb5/keytab/file/ChangeLog13
-rw-r--r--src/lib/krb5/keytab/file/ktf_g_ent.c34
-rw-r--r--src/lib/krb5/keytab/ktfns.c80
-rw-r--r--src/lib/krb5/keytab/ktfr_entry.c10
-rw-r--r--src/lib/krb5/keytab/srvtab/ChangeLog10
-rw-r--r--src/lib/krb5/keytab/srvtab/kts_g_ent.c1
-rw-r--r--src/lib/krb5/keytab/srvtab/kts_util.c2
-rw-r--r--src/lib/krb5/krb/ChangeLog298
-rw-r--r--src/lib/krb5/krb/Makefile.in8
-rw-r--r--src/lib/krb5/krb/addr_comp.c2
-rw-r--r--src/lib/krb5/krb/addr_order.c2
-rw-r--r--src/lib/krb5/krb/appdefault.c183
-rw-r--r--src/lib/krb5/krb/auth_con.c6
-rw-r--r--src/lib/krb5/krb/bld_princ.c1
-rw-r--r--src/lib/krb5/krb/chk_trans.c497
-rw-r--r--src/lib/krb5/krb/conv_princ.c126
-rw-r--r--src/lib/krb5/krb/fwd_tgt.c38
-rw-r--r--src/lib/krb5/krb/gc_frm_kdc.c4
-rw-r--r--src/lib/krb5/krb/get_creds.c23
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c69
-rw-r--r--src/lib/krb5/krb/gic_keytab.c16
-rw-r--r--src/lib/krb5/krb/gic_pwd.c28
-rw-r--r--src/lib/krb5/krb/init_ctx.c45
-rw-r--r--src/lib/krb5/krb/init_keyblock.c61
-rw-r--r--src/lib/krb5/krb/kfree.c129
-rw-r--r--src/lib/krb5/krb/mk_cred.c2
-rw-r--r--src/lib/krb5/krb/mk_priv.c8
-rw-r--r--src/lib/krb5/krb/mk_req_ext.c16
-rw-r--r--src/lib/krb5/krb/mk_safe.c29
-rw-r--r--src/lib/krb5/krb/parse.c11
-rw-r--r--src/lib/krb5/krb/preauth.c5
-rw-r--r--src/lib/krb5/krb/preauth2.c8
-rw-r--r--src/lib/krb5/krb/princ_comp.c2
-rw-r--r--src/lib/krb5/krb/rd_cred.c89
-rw-r--r--src/lib/krb5/krb/rd_priv.c9
-rw-r--r--src/lib/krb5/krb/rd_req_dec.c4
-rw-r--r--src/lib/krb5/krb/rd_safe.c2
-rw-r--r--src/lib/krb5/krb/recvauth.c69
-rw-r--r--src/lib/krb5/krb/send_tgs.c1
-rw-r--r--src/lib/krb5/krb/sendauth.c32
-rw-r--r--src/lib/krb5/krb/ser_actx.c10
-rw-r--r--src/lib/krb5/krb/srv_rcache.c3
-rw-r--r--src/lib/krb5/krb/t_kerb.c32
-rw-r--r--src/lib/krb5/krb/t_krb5.conf6
-rw-r--r--src/lib/krb5/krb/t_ref_kerb.out2
-rw-r--r--src/lib/krb5/krb/unparse.c6
-rw-r--r--src/lib/krb5/krb/vfy_increds.c2
-rw-r--r--src/lib/krb5/krb/walk_rtree.c25
-rw-r--r--src/lib/krb5/krb5_libinit.c10
-rw-r--r--src/lib/krb5/os/ChangeLog209
-rw-r--r--src/lib/krb5/os/an_to_ln.c22
-rw-r--r--src/lib/krb5/os/c_ustime.c141
-rw-r--r--src/lib/krb5/os/ccdefname.c15
-rw-r--r--src/lib/krb5/os/changepw.c61
-rw-r--r--src/lib/krb5/os/def_realm.c13
-rw-r--r--src/lib/krb5/os/gmt_mktime.c2
-rw-r--r--src/lib/krb5/os/hst_realm.c19
-rw-r--r--src/lib/krb5/os/init_os_ctx.c80
-rw-r--r--src/lib/krb5/os/kuserok.c5
-rw-r--r--src/lib/krb5/os/localaddr.c233
-rw-r--r--src/lib/krb5/os/locate_kdc.c148
-rw-r--r--src/lib/krb5/os/os-proto.h3
-rw-r--r--src/lib/krb5/os/prompter.c14
-rw-r--r--src/lib/krb5/os/promptusr.c2
-rw-r--r--src/lib/krb5/os/sendto_kdc.c26
-rw-r--r--src/lib/krb5/os/t_std_conf.c4
-rw-r--r--src/lib/krb5/os/timeofday.c6
-rw-r--r--src/lib/krb5/os/toffset.c2
-rw-r--r--src/lib/krb5/posix/ChangeLog11
-rw-r--r--src/lib/krb5/posix/setenv.c2
-rw-r--r--src/lib/krb5/posix/syslog.c10
-rw-r--r--src/lib/krb5/rcache/ChangeLog22
-rw-r--r--src/lib/krb5/rcache/rc_dfl.c2
-rw-r--r--src/lib/krb5/rcache/rc_io.c27
-rw-r--r--src/lib/krb5_32.def342
-rw-r--r--src/lib/krb5util/ChangeLog5
-rw-r--r--src/lib/krb5util/compat_recv.c145
-rw-r--r--src/lib/rpc/ChangeLog64
-rw-r--r--src/lib/rpc/auth_gssapi_misc.c16
-rw-r--r--src/lib/rpc/clnt_perror.c98
-rw-r--r--src/lib/rpc/clnt_simple.c5
-rw-r--r--src/lib/rpc/clnt_tcp.c2
-rw-r--r--src/lib/rpc/clnt_udp.c2
-rw-r--r--src/lib/rpc/configure.in2
-rw-r--r--src/lib/rpc/get_myaddress.c2
-rw-r--r--src/lib/rpc/pmap_rmt.c11
-rw-r--r--src/lib/rpc/svc_auth_gssapi.c16
-rw-r--r--src/lib/rpc/unit-test/ChangeLog19
-rw-r--r--src/lib/rpc/unit-test/lib/helpers.exp6
-rw-r--r--src/lib/rpc/unit-test/rpc_test.0/expire.exp2
-rw-r--r--src/lib/rpc/unit-test/server.c1
-rw-r--r--src/lib/rpc/xdr.c2
-rw-r--r--src/lib/rpc/xdr_array.c3
-rw-r--r--src/lib/rpc/xdr_mem.c21
-rw-r--r--src/lib/win_glue.c34
247 files changed, 8421 insertions, 4012 deletions
diff --git a/src/lib/ChangeLog b/src/lib/ChangeLog
index b5abe94..d1daec7 100644
--- a/src/lib/ChangeLog
+++ b/src/lib/ChangeLog
@@ -1,3 +1,63 @@
+2002-04-16 Danilo Almeida <dalmeida@mit.edu>
+
+ * krb5_32.def: Remove krb5_mcc_ops and krb5_cc_register() as
+ GSSAPI no longer needs those.
+
+2002-04-16 Danilo Almeida <dalmeida@mit.edu>
+
+ * krb5_32.def: Add krb5_free_ap_req() as private for GSSAPI. Add
+ krb5_get_host_realm() and krb5_free_host_realm() as public
+ functions. Reformat to make it easier to read and compare.
+
+2002-04-05 Danilo Almeida <dalmeida@mit.edu>
+
+ * krb5_32.def: Hopefully final cut at consistent exports between
+ Windows and MacOS X. Still has private stuff needed by gssapi and
+ krb4.
+
+2002-04-03 Danilo Almeida <dalmeida@mit.edu>
+
+ * krb5_32.def: First cut at consistent exports between Windows and
+ MacOS X. More work needs to be done.
+
+2001-11-29 Danilo Almeida <dalmeida@mit.edu>
+
+ * gssapi32.def: Export gss_mech_krb5 as DATA. Mark all exported
+ variables as DATA. [Copied over from trunk.]
+
+2000-06-02 Danilo Almeida <dalmeida@mit.edu>
+
+ * win_glue.c (GetCallingAppVerInfo, krb5_vercheck): Use
+ APPVERINFO_SIZE-sized buffers instead of hard-coding a number
+ everywhere. Document the buffer size in funciton documentation.
+
+ * krb5_32.def: Add krb5int_cc_default for the benefit of GSS API DLL.
+
+2000-05-23 Nalin Dahyabhai <nalin@redhat.com>
+
+ * win_glue.c (GetCallingAppVerInfo): Don't overfill buffers
+ "AppTitle", "AppVer", and "AppIni".
+
+2000-05-15 Jeffrey Altman <jaltman@columbia.edu>
+
+ * krb5_32.def -- Added exports for new public functions
+
+ krb5_appdefault_string
+ krb5_appdefault_boolean
+
+2000-05-04 Danilo Almeida <dalmeida@mit.edu>
+
+ * krb5_32.def: Reflect something closer to the reality of
+ what we would like to do for 1.3.
+
+2000-05-03 Nalin Dahyabhai <nalin@redhat.com>
+
+ * win_glue.c (do_timebomb): Don't overflow buffer "buf".
+
+2000-04-29 Jeffrey Altman <jaltman@columbia.edu>
+
+ * krb5_32.def: Add krb5_get_tgs_ktypes, krb5_free_ktypes for gssapi
+
2000-03-15 Danilo Almeida <dalmeida@mit.edu>
* krb5_32.def: Add krb5_get_prompt_types.
diff --git a/src/lib/crypto/ChangeLog b/src/lib/crypto/ChangeLog
index a48ec1f..058576d 100644
--- a/src/lib/crypto/ChangeLog
+++ b/src/lib/crypto/ChangeLog
@@ -1,3 +1,24 @@
+2002-04-02 Ken Raeburn <raeburn@mit.edu>
+
+ * valid_enctype.c (krb5_c_valid_enctype): New name on old
+ function, with old name kept as an alias (wrapper).
+ * keyed_cksum.c (krb5_c_is_keyed_cksum): Likewise.
+ * valid_cksumtype.c (krb5_c_valid_cksumtype): Likewise.
+ * coll_proof_cksum.c (krb5_c_is_coll_proof_cksum): Likewise.
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * crypto_libinit.h: Changed macros so you can include crypto_libinit.h
+ and krb5_libinit.h at the same time
+
+2001-01-29 Ken Raeburn <raeburn@mit.edu>
+
+ * make_checksum.c (krb5_c_make_checksum): Clear checksum contents
+ pointer after freeing it in error case.
+
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in(LIBMAJOR, LIBMINOR): Bump library version.
+
2000-01-24 Tom Yu <tlyu@mit.edu>
* crypto_libinit.c: Add terminating newline; use 0 and 1 instead
diff --git a/src/lib/crypto/Makefile.in b/src/lib/crypto/Makefile.in
index 71bddf5..64f19d1 100644
--- a/src/lib/crypto/Makefile.in
+++ b/src/lib/crypto/Makefile.in
@@ -106,8 +106,8 @@ SRCS=\
LIB=k5crypto
-LIBMAJOR=2
-LIBMINOR=1
+LIBMAJOR=3
+LIBMINOR=0
RELDIR=crypto
STOBJLISTS=crc32/OBJS.ST des/OBJS.ST dk/OBJS.ST enc_provider/OBJS.ST \
diff --git a/src/lib/crypto/coll_proof_cksum.c b/src/lib/crypto/coll_proof_cksum.c
index 31bf1fe..95a2aef 100644
--- a/src/lib/crypto/coll_proof_cksum.c
+++ b/src/lib/crypto/coll_proof_cksum.c
@@ -28,7 +28,7 @@
#include "cksumtypes.h"
KRB5_DLLIMP krb5_boolean KRB5_CALLCONV
-is_coll_proof_cksum(ctype)
+krb5_c_is_coll_proof_cksum(ctype)
krb5_cksumtype ctype;
{
int i;
@@ -43,3 +43,10 @@ is_coll_proof_cksum(ctype)
old code would have done */
return(0);
}
+
+#undef is_coll_proof_cksum
+KRB5_DLLIMP krb5_boolean KRB5_CALLCONV
+is_coll_proof_cksum(krb5_cksumtype ctype)
+{
+ return krb5_c_is_coll_proof_cksum (ctype);
+}
diff --git a/src/lib/crypto/crypto_libinit.h b/src/lib/crypto/crypto_libinit.h
index 3586a63..44c7e16 100644
--- a/src/lib/crypto/crypto_libinit.h
+++ b/src/lib/crypto/crypto_libinit.h
@@ -1,7 +1,7 @@
-#ifndef KRB5_LIBINIT_H
-#define KRB5_LIBINIT_H
+#ifndef K5CRYPTO_LIBINIT_H
+#define K5CRYPTO_LIBINIT_H
int cryptoint_initialize_library (void);
void cryptoint_cleanup_library (void);
-#endif /* KRB5_LIBINIT_H */
+#endif /* K5CRYPTO_LIBINIT_H */
diff --git a/src/lib/crypto/des/ChangeLog b/src/lib/crypto/des/ChangeLog
index 7a2155c..7438600 100644
--- a/src/lib/crypto/des/ChangeLog
+++ b/src/lib/crypto/des/ChangeLog
@@ -1,3 +1,21 @@
+2002-08-16 Tom Yu <tlyu@mit.edu>
+
+ * string2key.c: Work around possible bug with AFS salts;
+ [krb5-clients/1146] from <Wolfgang.Friebel@cern.ch>.
+ [port from trunk]
+
+2002-03-14 Alexandra Ellwood <lxs@mit.edu>
+ * afsstring2key.c: made static data const to improve load time
+ on Mach-O
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * afsstring2key.c: fixed warnings about types defaulting to int
+ and two-dimensional array declaration without second-level braces
+
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * des_int.h: use "" includes for k5-int.h
+
2000-02-25 Ezra Peisach <epeisach@mit.edu>
* t_verify.c: Add "const" to casts in calls to mit_des_cbc_encrypt().
diff --git a/src/lib/crypto/des/afsstring2key.c b/src/lib/crypto/des/afsstring2key.c
index 7eac080..7c828ba 100644
--- a/src/lib/crypto/des/afsstring2key.c
+++ b/src/lib/crypto/des/afsstring2key.c
@@ -150,7 +150,7 @@ static void krb5_afs_encrypt PROTOTYPE((char*,long));
/*
* Initial permutation,
*/
-static char IP[] = {
+static const char IP[] = {
58,50,42,34,26,18,10, 2,
60,52,44,36,28,20,12, 4,
62,54,46,38,30,22,14, 6,
@@ -164,7 +164,7 @@ static char IP[] = {
/*
* Final permutation, FP = IP^(-1)
*/
-static char FP[] = {
+static const char FP[] = {
40, 8,48,16,56,24,64,32,
39, 7,47,15,55,23,63,31,
38, 6,46,14,54,22,62,30,
@@ -179,14 +179,14 @@ static char FP[] = {
* Permuted-choice 1 from the key bits to yield C and D.
* Note that bits 8,16... are left out: They are intended for a parity check.
*/
-static char PC1_C[] = {
+static const char PC1_C[] = {
57,49,41,33,25,17, 9,
1,58,50,42,34,26,18,
10, 2,59,51,43,35,27,
19,11, 3,60,52,44,36,
};
-static char PC1_D[] = {
+static const char PC1_D[] = {
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14, 6,61,53,45,37,29,
@@ -196,7 +196,7 @@ static char PC1_D[] = {
/*
* Sequence of shifts used for the key schedule.
*/
-static char shifts[] = {
+static const char shifts[] = {
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
};
@@ -204,14 +204,14 @@ static char shifts[] = {
* Permuted-choice 2, to pick out the bits from
* the CD array that generate the key schedule.
*/
-static char PC2_C[] = {
+static const char PC2_C[] = {
14,17,11,24, 1, 5,
3,28,15, 6,21,10,
23,19,12, 4,26, 8,
16, 7,27,20,13, 2,
};
-static char PC2_D[] = {
+static const char PC2_D[] = {
41,52,31,37,47,55,
30,40,51,45,33,48,
44,49,39,56,34,53,
@@ -222,7 +222,7 @@ static char PC2_D[] = {
* The E bit-selection table.
*/
static char E[48];
-static char e[] = {
+static const char e[] = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9,10,11,12,13,
@@ -237,7 +237,7 @@ static char e[] = {
* P is a permutation on the selected combination
* of the current L and key.
*/
-static char P[] = {
+static const char P[] = {
16, 7,20,21,
29,12,28,17,
1,15,23,26,
@@ -253,46 +253,46 @@ static char P[] = {
* For some reason, they give a 0-origin
* index, unlike everything else.
*/
-static char S[8][64] = {
- 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
+static const char S[8][64] = {
+ {14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
- 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
+ 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13},
- 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
+ {15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
- 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
+ 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9},
- 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
+ {10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
- 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
+ 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12},
- 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
+ {7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
- 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
+ 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14},
- 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
+ {2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
- 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
+ 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3},
- 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
+ {12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
- 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
+ 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13},
- 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
+ {4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
- 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
+ 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12},
- 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
+ {13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
- 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
+ 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11},
};
/*
@@ -325,7 +325,7 @@ static char *afs_crypt(pw, salt)
char *pw;
char *salt;
{
- register i, j, c;
+ register int i, j, c;
int temp;
static char block[66], iobuf[16];
@@ -384,7 +384,7 @@ static char *afs_crypt(pw, salt)
static void krb5_afs_crypt_setkey(key)
char *key;
{
- register i, j, k;
+ register int i, j, k;
int t;
/*
@@ -439,7 +439,7 @@ static void krb5_afs_encrypt(block, edflag)
long edflag;
{
int i, ii;
- register t, j, k;
+ register int t, j, k;
/*
* First, permute the bits in the input
diff --git a/src/lib/crypto/des/des_int.h b/src/lib/crypto/des/des_int.h
index de8f2a4..bd591ae 100644
--- a/src/lib/crypto/des/des_int.h
+++ b/src/lib/crypto/des/des_int.h
@@ -57,7 +57,7 @@
#ifndef DES_INTERNAL_DEFS
#define DES_INTERNAL_DEFS
-#include <k5-int.h>
+#include "k5-int.h"
/*
* Begin "mit-des.h"
*/
diff --git a/src/lib/crypto/des/string2key.c b/src/lib/crypto/des/string2key.c
index 5381fdb..d51145b 100644
--- a/src/lib/crypto/des/string2key.c
+++ b/src/lib/crypto/des/string2key.c
@@ -99,6 +99,9 @@ const krb5_data FAR * salt;
if (salt) {
if (salt->length == -1) {
/* cheat and do AFS string2key instead */
+ char *c;
+ c = strchr(salt->data, '@');
+ if (c != NULL) *c = '\0'; /* workaround from krb5-clients/1146 */
return mit_afs_string_to_key (keyblock, data, salt);
} else
length = data->length + salt->length;
diff --git a/src/lib/crypto/dk/ChangeLog b/src/lib/crypto/dk/ChangeLog
index 90e34f8..7908f56 100644
--- a/src/lib/crypto/dk/ChangeLog
+++ b/src/lib/crypto/dk/ChangeLog
@@ -1,3 +1,17 @@
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * dk_encrypt.c (krb5_dk_encrypt, krb5_marc_dk_encrypt): Chain
+ ivecs.
+
+ * dk_decrypt.c (krb5_dk_decrypt, krb5_marc_dk_decrypt): Chain
+ ivecs.
+
+2000-04-28 Ken Raeburn <raeburn@mit.edu>
+
+ * derive.c (krb5_derive_key): If memory allocation fails, release
+ other allocated blocks before returning, instead of trying to
+ release them after returning.
+
2000-01-21 Ken Raeburn <raeburn@mit.edu>
* checksum.c (krb5_dk_make_checksum): enc_providers are now
diff --git a/src/lib/crypto/dk/derive.c b/src/lib/crypto/dk/derive.c
index 8765605..dbd4a2a 100644
--- a/src/lib/crypto/dk/derive.c
+++ b/src/lib/crypto/dk/derive.c
@@ -51,14 +51,14 @@ krb5_derive_key(enc, inkey, outkey, in_constant)
return(ENOMEM);
if ((outblockdata = (unsigned char *) malloc(blocksize)) == NULL) {
- return(ENOMEM);
free(inblockdata);
+ return(ENOMEM);
}
if ((rawkey = (unsigned char *) malloc(keybytes)) == NULL) {
- return(ENOMEM);
free(outblockdata);
free(inblockdata);
+ return(ENOMEM);
}
inblock.data = inblockdata;
diff --git a/src/lib/crypto/dk/dk_decrypt.c b/src/lib/crypto/dk/dk_decrypt.c
index d307761..d6e7c0d 100644
--- a/src/lib/crypto/dk/dk_decrypt.c
+++ b/src/lib/crypto/dk/dk_decrypt.c
@@ -41,7 +41,7 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
{
krb5_error_code ret;
size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen;
- unsigned char *plaindata, *kedata, *kidata, *cksum;
+ unsigned char *plaindata, *kedata, *kidata, *cksum, *cn;
krb5_keyblock ke, ki;
krb5_data d1, d2;
unsigned char constantdata[K5CLENGTH];
@@ -108,6 +108,11 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
if ((ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2))) != 0)
goto cleanup;
+ if (ivec != NULL && ivec->length == blocksize)
+ cn = d1.data + d1.length - blocksize;
+ else
+ cn = NULL;
+
/* verify the hash */
d1.length = hashsize;
@@ -134,6 +139,9 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
memcpy(output->data, d2.data+blocksize, output->length);
+ if (cn != NULL)
+ memcpy(ivec->data, cn, blocksize);
+
ret = 0;
cleanup:
@@ -163,7 +171,7 @@ krb5_marc_dk_decrypt(enc, hash, key, usage, ivec, input, output)
{
krb5_error_code ret;
size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen;
- unsigned char *plaindata, *kedata, *kidata, *cksum;
+ unsigned char *plaindata, *kedata, *kidata, *cksum, *cn;
krb5_keyblock ke, ki;
krb5_data d1, d2;
unsigned char constantdata[K5CLENGTH];
@@ -230,6 +238,11 @@ krb5_marc_dk_decrypt(enc, hash, key, usage, ivec, input, output)
if ((ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2))) != 0)
goto cleanup;
+ if (ivec != NULL && ivec->length == blocksize)
+ cn = d1.data + d1.length - blocksize;
+ else
+ cn = NULL;
+
/* verify the hash */
d1.length = hashsize;
@@ -264,6 +277,9 @@ krb5_marc_dk_decrypt(enc, hash, key, usage, ivec, input, output)
memcpy(output->data, d2.data+4+blocksize, output->length);
+ if (cn != NULL)
+ memcpy(ivec->data, cn, blocksize);
+
ret = 0;
cleanup:
diff --git a/src/lib/crypto/dk/dk_encrypt.c b/src/lib/crypto/dk/dk_encrypt.c
index 8627353..2bc2b6b 100644
--- a/src/lib/crypto/dk/dk_encrypt.c
+++ b/src/lib/crypto/dk/dk_encrypt.c
@@ -65,7 +65,7 @@ krb5_dk_encrypt(enc, hash, key, usage, ivec, input, output)
krb5_error_code ret;
unsigned char constantdata[K5CLENGTH];
krb5_data d1, d2;
- unsigned char *plaintext, *kedata, *kidata;
+ unsigned char *plaintext, *kedata, *kidata, *cn;
krb5_keyblock ke, ki;
/* allocate and set up plaintext and to-be-derived keys */
@@ -142,6 +142,11 @@ krb5_dk_encrypt(enc, hash, key, usage, ivec, input, output)
if ((ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2))))
goto cleanup;
+ if (ivec != NULL && ivec->length == blocksize)
+ cn = d2.data + d2.length - blocksize;
+ else
+ cn = NULL;
+
/* hash the plaintext */
d2.length = enclen - plainlen;
@@ -149,8 +154,14 @@ krb5_dk_encrypt(enc, hash, key, usage, ivec, input, output)
output->length = enclen;
- if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2)))
+ if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2))) {
memset(d2.data, 0, d2.length);
+ goto cleanup;
+ }
+
+ /* update ivec */
+ if (cn != NULL)
+ memcpy(ivec->data, cn, blocksize);
/* ret is set correctly by the prior call */
@@ -196,7 +207,7 @@ krb5_marc_dk_encrypt(enc, hash, key, usage, ivec, input, output)
krb5_error_code ret;
unsigned char constantdata[K5CLENGTH];
krb5_data d1, d2;
- unsigned char *plaintext, *kedata, *kidata;
+ unsigned char *plaintext, *kedata, *kidata, *cn;
krb5_keyblock ke, ki;
/* allocate and set up plaintext and to-be-derived keys */
@@ -278,6 +289,11 @@ krb5_marc_dk_encrypt(enc, hash, key, usage, ivec, input, output)
if ((ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2))))
goto cleanup;
+ if (ivec != NULL && ivec->length == blocksize)
+ cn = d2.data + d2.length - blocksize;
+ else
+ cn = NULL;
+
/* hash the plaintext */
d2.length = enclen - plainlen;
@@ -285,8 +301,14 @@ krb5_marc_dk_encrypt(enc, hash, key, usage, ivec, input, output)
output->length = enclen;
- if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2)))
+ if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2))) {
memset(d2.data, 0, d2.length);
+ goto cleanup;
+ }
+
+ /* update ivec */
+ if (cn != NULL)
+ memcpy(ivec->data, cn, blocksize);
/* ret is set correctly by the prior call */
diff --git a/src/lib/crypto/keyed_cksum.c b/src/lib/crypto/keyed_cksum.c
index 39979c0..e32620e 100644
--- a/src/lib/crypto/keyed_cksum.c
+++ b/src/lib/crypto/keyed_cksum.c
@@ -28,7 +28,7 @@
#include "cksumtypes.h"
KRB5_DLLIMP krb5_boolean KRB5_CALLCONV
-is_keyed_cksum(ctype)
+krb5_c_is_keyed_cksum(ctype)
krb5_cksumtype ctype;
{
int i;
@@ -48,3 +48,9 @@ is_keyed_cksum(ctype)
old code would have done */
return(-1);
}
+
+KRB5_DLLIMP krb5_boolean KRB5_CALLCONV
+is_keyed_cksum(krb5_cksumtype ctype)
+{
+ return krb5_c_is_keyed_cksum (ctype);
+}
diff --git a/src/lib/crypto/make_checksum.c b/src/lib/crypto/make_checksum.c
index 300f375..64f6389 100644
--- a/src/lib/crypto/make_checksum.c
+++ b/src/lib/crypto/make_checksum.c
@@ -114,6 +114,7 @@ cleanup:
if (ret) {
memset(cksum->contents, 0, cksum->length);
free(cksum->contents);
+ cksum->contents = NULL;
}
return(ret);
diff --git a/src/lib/crypto/old/ChangeLog b/src/lib/crypto/old/ChangeLog
index cada473..74f994b 100644
--- a/src/lib/crypto/old/ChangeLog
+++ b/src/lib/crypto/old/ChangeLog
@@ -1,3 +1,9 @@
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * old_encrypt.c (krb5_old_encrypt): Chain ivecs.
+
+ * old_decrypt.c (krb5_old_decrypt): Chain ivecs.
+
2000-01-21 Ken Raeburn <raeburn@mit.edu>
* des_stringtokey.c (mit_des_string_to_key_int): Declare.
diff --git a/src/lib/crypto/old/old_decrypt.c b/src/lib/crypto/old/old_decrypt.c
index 1bcb0d3..bfbe56a 100644
--- a/src/lib/crypto/old/old_decrypt.c
+++ b/src/lib/crypto/old/old_decrypt.c
@@ -45,7 +45,7 @@ krb5_old_decrypt(enc, hash, key, usage, ivec, input, arg_output)
{
krb5_error_code ret;
size_t blocksize, hashsize, plainsize;
- unsigned char *cksumdata;
+ unsigned char *cksumdata, *cn;
krb5_data output, cksum, crcivec;
int alloced;
@@ -82,6 +82,17 @@ krb5_old_decrypt(enc, hash, key, usage, ivec, input, arg_output)
/* decrypt it */
+ /* save last ciphertext block in case we decrypt in place */
+ if (ivec != NULL && ivec->length == blocksize) {
+ cn = malloc(blocksize);
+ if (cn == NULL) {
+ ret = ENOMEM;
+ goto cleanup;
+ }
+ memcpy(cn, input->data + input->length - blocksize, blocksize);
+ } else
+ cn = NULL;
+
/* XXX this is gross, but I don't have much choice */
if ((key->enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) {
crcivec.length = key->length;
@@ -119,6 +130,10 @@ krb5_old_decrypt(enc, hash, key, usage, ivec, input, arg_output)
}
arg_output->length = plainsize;
+ /* update ivec */
+ if (cn != NULL)
+ memcpy(ivec->data, cn, blocksize);
+
ret = 0;
cleanup:
@@ -127,6 +142,8 @@ cleanup:
free(output.data);
}
+ if (cn != NULL)
+ free(cn);
memset(cksumdata, 0, hashsize);
free(cksumdata);
return(ret);
diff --git a/src/lib/crypto/old/old_encrypt.c b/src/lib/crypto/old/old_encrypt.c
index d90d0f8..8860ba5 100644
--- a/src/lib/crypto/old/old_encrypt.c
+++ b/src/lib/crypto/old/old_encrypt.c
@@ -55,6 +55,7 @@ krb5_old_encrypt(enc, hash, key, usage, ivec, input, output)
krb5_error_code ret;
size_t blocksize, hashsize, enclen;
krb5_data datain, crcivec;
+ int real_ivec;
(*(enc->block_size))(&blocksize);
(*(hash->hash_size))(&hashsize);
@@ -92,11 +93,17 @@ krb5_old_encrypt(enc, hash, key, usage, ivec, input, output)
crcivec.length = key->length;
crcivec.data = key->contents;
ivec = &crcivec;
- }
+ real_ivec = 0;
+ } else
+ real_ivec = 1;
if ((ret = ((*(enc->encrypt))(key, ivec, output, output))))
goto cleanup;
+ /* update ivec */
+ if (real_ivec && ivec != NULL && ivec->length == blocksize)
+ memcpy(ivec->data, output->data + output->length - blocksize,
+ blocksize);
cleanup:
if (ret)
memset(output->data, 0, output->length);
diff --git a/src/lib/crypto/prng.c b/src/lib/crypto/prng.c
index 6d401a9..b22131e 100644
--- a/src/lib/crypto/prng.c
+++ b/src/lib/crypto/prng.c
@@ -158,4 +158,4 @@ void prng_cleanup (void)
{
free (random_state);
inited = 0;
-} \ No newline at end of file
+}
diff --git a/src/lib/crypto/sha1/ChangeLog b/src/lib/crypto/sha1/ChangeLog
index a6a00f3..0030dc9 100644
--- a/src/lib/crypto/sha1/ChangeLog
+++ b/src/lib/crypto/sha1/ChangeLog
@@ -1,3 +1,26 @@
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * shs.c: use "" include for k5-int.h
+
+2001-07-16 Ken Raeburn <raeburn@mit.edu>
+
+ * t_shs3.c: New test file from Marcus Watts.
+ (longReverse): Resurrected function long since deleted from
+ shs.c.
+ * Makefile.in (check-unix, check-windows): Use t_shs3 test.
+ (clean): Delete it.
+
+ * shs.c (SHSTransform): Make input data pointer point to const.
+ (SHSUpdate): Bugfixes suggested by Marcus Watts, to fix buffer
+ overruns, bugs with small or odd block sizes.
+
+2001-07-05 Danilo Almeida <dalmeida@mit.edu>
+
+ * shs.h, shs.c, t_shs.c: Fix sha1 on Windows by renaming LONG to
+ SHS_LONG to avoid problem with LONG being signed on Windows.
+ Rename BYTE to SHS_BYTE to avoid any name colisions with Windows
+ (where BYTE and LONG are types defined in the Platform SDK).
+
2000-01-21 Ken Raeburn <raeburn@mit.edu>
* shs.c (ROTL): Change (a&b|c) construct to make meaning clear,
diff --git a/src/lib/crypto/sha1/Makefile.in b/src/lib/crypto/sha1/Makefile.in
index 5d1b69c..2d0e209 100644
--- a/src/lib/crypto/sha1/Makefile.in
+++ b/src/lib/crypto/sha1/Makefile.in
@@ -33,13 +33,28 @@ t_shs: t_shs.o shs.o
$(OUTPRE)t_shs.exe: $(OUTPRE)t_shs.obj $(OUTPRE)shs.obj
link -out:$@ $**
-check-unix:: t_shs
+check-unix:: t_shs t_shs3
$(C)t_shs -x
+ $(C)t_shs3
-check-windows:: $(OUTPRE)t_shs.exe
+check-windows:: $(OUTPRE)t_shs.exe $(OUTPRE)t_shs3.exe
$(OUTPRE)$(C)t_shs.exe -x
+ $(OUTPRE)$(C)t_shs3.exe
clean::
- $(RM) t_shs$(EXEEXT) t_shs.$(OBJEXT)
+ $(RM) t_shs$(EXEEXT) t_shs.$(OBJEXT) t_shs3$(EXEEXT) t_shs3.$(OBJEXT)
clean-unix:: clean-libobjs
+
+t_shs3: t_shs3.o shs.o
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o t_shs3 t_shs3.o shs.o
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+shs.o: shs.c shs.h $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
+ $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
+ $(BUILDTOP)/include/profile.h $(BUILDTOP)/include/com_err.h \
+ $(SRCTOP)/include/krb5/kdb.h
+
diff --git a/src/lib/crypto/sha1/shs.c b/src/lib/crypto/sha1/shs.c
index 358e6ba..873f878 100644
--- a/src/lib/crypto/sha1/shs.c
+++ b/src/lib/crypto/sha1/shs.c
@@ -97,15 +97,15 @@ void shsInit(shsInfo)
Note that this corrupts the shsInfo->data area */
-static void SHSTransform KRB5_PROTOTYPE((LONG *digest, LONG *data));
+static void SHSTransform (SHS_LONG *digest, const SHS_LONG *data);
static
void SHSTransform(digest, data)
- LONG *digest;
- LONG *data;
+ SHS_LONG *digest;
+ const SHS_LONG *data;
{
- LONG A, B, C, D, E; /* Local vars */
- LONG eData[ 16 ]; /* Expanded data */
+ SHS_LONG A, B, C, D, E; /* Local vars */
+ SHS_LONG eData[ 16 ]; /* Expanded data */
/* Set up first buffer and local data buffer */
A = digest[ 0 ];
@@ -217,16 +217,16 @@ void SHSTransform(digest, data)
void shsUpdate(shsInfo, buffer, count)
SHS_INFO *shsInfo;
- BYTE *buffer;
+ SHS_BYTE *buffer;
int count;
{
- LONG tmp;
+ SHS_LONG tmp;
int dataCount, canfill;
- LONG *lp;
+ SHS_LONG *lp;
/* Update bitcount */
tmp = shsInfo->countLo;
- shsInfo->countLo = tmp + (((LONG) count) << 3 );
+ shsInfo->countLo = tmp + (((SHS_LONG) count) << 3 );
if ((shsInfo->countLo &= 0xffffffff) < tmp)
shsInfo->countHi++; /* Carry from low to high */
shsInfo->countHi += count >> 29;
@@ -237,37 +237,38 @@ void shsUpdate(shsInfo, buffer, count)
/* Handle any leading odd-sized chunks */
if (dataCount) {
lp = shsInfo->data + dataCount / 4;
- canfill = (count >= dataCount);
dataCount = SHS_DATASIZE - dataCount;
+ canfill = (count >= 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);
+ *lp |= (SHS_LONG) *buffer++ << ((--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) {
+ if (count < 4) {
*lp = 0;
switch (count % 4) {
case 3:
- *lp |= (LONG) buffer[2] << 8;
+ *lp |= (SHS_LONG) buffer[2] << 8;
case 2:
- *lp |= (LONG) buffer[1] << 16;
+ *lp |= (SHS_LONG) buffer[1] << 16;
case 1:
- *lp |= (LONG) buffer[0] << 24;
+ *lp |= (SHS_LONG) buffer[0] << 24;
}
- break;
count = 0;
+ break; /* out of while loop */
}
+ *lp = (SHS_LONG) *buffer++ << 24;
+ *lp |= (SHS_LONG) *buffer++ << 16;
+ *lp |= (SHS_LONG) *buffer++ << 8;
+ *lp++ |= (SHS_LONG) *buffer++;
+ count -= 4;
}
if (canfill) {
SHSTransform(shsInfo->digest, shsInfo->data);
@@ -278,10 +279,10 @@ void shsUpdate(shsInfo, buffer, count)
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++;
+ *lp = ((SHS_LONG) *buffer++) << 24;
+ *lp |= ((SHS_LONG) *buffer++) << 16;
+ *lp |= ((SHS_LONG) *buffer++) << 8;
+ *lp++ |= (SHS_LONG) *buffer++;
}
SHSTransform(shsInfo->digest, shsInfo->data);
count -= SHS_DATASIZE;
@@ -290,22 +291,22 @@ void shsUpdate(shsInfo, buffer, count)
if (count > 0) {
lp = shsInfo->data;
while (count > 4) {
- *lp = ((LONG) *buffer++) << 24;
- *lp |= ((LONG) *buffer++) << 16;
- *lp |= ((LONG) *buffer++) << 8;
- *lp++ |= (LONG) *buffer++;
+ *lp = ((SHS_LONG) *buffer++) << 24;
+ *lp |= ((SHS_LONG) *buffer++) << 16;
+ *lp |= ((SHS_LONG) *buffer++) << 8;
+ *lp++ |= (SHS_LONG) *buffer++;
count -= 4;
}
*lp = 0;
switch (count % 4) {
case 0:
- *lp |= ((LONG) buffer[3]);
+ *lp |= ((SHS_LONG) buffer[3]);
case 3:
- *lp |= ((LONG) buffer[2]) << 8;
+ *lp |= ((SHS_LONG) buffer[2]) << 8;
case 2:
- *lp |= ((LONG) buffer[1]) << 16;
+ *lp |= ((SHS_LONG) buffer[1]) << 16;
case 1:
- *lp |= ((LONG) buffer[0]) << 24;
+ *lp |= ((SHS_LONG) buffer[0]) << 24;
}
}
}
@@ -317,7 +318,7 @@ void shsFinal(shsInfo)
SHS_INFO *shsInfo;
{
int count;
- LONG *lp;
+ SHS_LONG *lp;
/* Compute number of bytes mod 64 */
count = (int) shsInfo->countLo;
@@ -328,16 +329,16 @@ void shsFinal(shsInfo)
lp = shsInfo->data + count / 4;
switch (count % 4) {
case 3:
- *lp++ |= (LONG) 0x80;
+ *lp++ |= (SHS_LONG) 0x80;
break;
case 2:
- *lp++ |= (LONG) 0x80 << 8;
+ *lp++ |= (SHS_LONG) 0x80 << 8;
break;
case 1:
- *lp++ |= (LONG) 0x80 << 16;
+ *lp++ |= (SHS_LONG) 0x80 << 16;
break;
case 0:
- *lp++ = (LONG) 0x80 << 24;
+ *lp++ = (SHS_LONG) 0x80 << 24;
}
/* at this point, lp can point *past* shsInfo->data. If it points
diff --git a/src/lib/crypto/sha1/shs.h b/src/lib/crypto/sha1/shs.h
index 01acddb..24eda9e 100644
--- a/src/lib/crypto/sha1/shs.h
+++ b/src/lib/crypto/sha1/shs.h
@@ -1,18 +1,13 @@
#ifndef _SHS_DEFINED
-#include <k5-int.h>
+#include "k5-int.h"
#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
-
+typedef krb5_octet SHS_BYTE;
+typedef krb5_ui_4 SHS_LONG;
/* Define the following to use the updated SHS implementation */
#define NEW_SHS /**/
@@ -25,16 +20,16 @@ typedef krb5_ui_4 LONG;
/* 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_LONG digest[ 5 ]; /* Message digest */
+ SHS_LONG countLo, countHi; /* 64-bit bit count */
+ SHS_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));
+ KRB5_PROTOTYPE((SHS_INFO *shsInfo, SHS_BYTE *buffer, int count));
void shsFinal
KRB5_PROTOTYPE((SHS_INFO *shsInfo));
diff --git a/src/lib/crypto/sha1/t_shs.c b/src/lib/crypto/sha1/t_shs.c
index da55992..de021bb 100644
--- a/src/lib/crypto/sha1/t_shs.c
+++ b/src/lib/crypto/sha1/t_shs.c
@@ -13,7 +13,7 @@
#ifdef NEW_SHS
-static LONG shsTestResults[][ 5 ] = {
+static SHS_LONG shsTestResults[][ 5 ] = {
{ 0xA9993E36L, 0x4706816AL, 0xBA3E2571L, 0x7850C26CL, 0x9CD0D89DL, },
{ 0x84983E44L, 0x1C3BD26EL, 0xBAAE4AA1L, 0xF95129E5L, 0xE54670F1L, },
{ 0x34AA973CL, 0xD4C4DAA4L, 0xF61EEB2BL, 0xDBAD2731L, 0x6534016FL, }
@@ -21,7 +21,7 @@ static LONG shsTestResults[][ 5 ] = {
#else
-static LONG shsTestResults[][ 5 ] = {
+static SHS_LONG shsTestResults[][ 5 ] = {
{ 0x0164B8A9L, 0x14CD2A5EL, 0x74C4F7FFL, 0x082C4D97L, 0xF1EDF880L },
{ 0xD2516EE1L, 0xACFA5BAFL, 0x33DFC1C4L, 0x71E43844L, 0x9EF134C8L },
{ 0x3232AFFAL, 0x48628A26L, 0x653B5AAAL, 0x44541FD9L, 0x0D690603L }
@@ -58,7 +58,7 @@ main()
SHS_INFO shsInfo;
unsigned int i;
time_t secondCount;
- BYTE data[ 200 ];
+ SHS_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,
@@ -69,7 +69,7 @@ main()
/* Test SHS against values given in SHS standards document */
printf( "Running SHS test 1 ... " );
shsInit( &shsInfo );
- shsUpdate( &shsInfo, ( BYTE * ) "abc", 3 );
+ shsUpdate( &shsInfo, ( SHS_BYTE * ) "abc", 3 );
shsFinal( &shsInfo );
if( compareSHSresults( &shsInfo, 0 ) == -1 )
{
@@ -85,7 +85,7 @@ main()
printf( "Running SHS test 2 ... " );
shsInit( &shsInfo );
- shsUpdate( &shsInfo, ( BYTE * ) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56 );
+ shsUpdate( &shsInfo, ( SHS_BYTE * ) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56 );
shsFinal( &shsInfo );
if( compareSHSresults( &shsInfo, 1 ) == -1 )
{
@@ -102,7 +102,7 @@ main()
printf( "Running SHS test 3 ... " );
shsInit( &shsInfo );
for( i = 0; i < 15625; i++ )
- shsUpdate( &shsInfo, ( BYTE * ) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64 );
+ shsUpdate( &shsInfo, ( SHS_BYTE * ) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64 );
shsFinal( &shsInfo );
if( compareSHSresults( &shsInfo, 2 ) == -1 )
{
diff --git a/src/lib/crypto/sha1/t_shs3.c b/src/lib/crypto/sha1/t_shs3.c
new file mode 100644
index 0000000..1ba030d
--- /dev/null
+++ b/src/lib/crypto/sha1/t_shs3.c
@@ -0,0 +1,583 @@
+/* test shs code */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "shs.h"
+
+/* 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( SHS_LONG *buffer, int byteCount )
+{
+ SHS_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( SHS_LONG );
+ while( byteCount-- ) {
+ value = *buffer;
+ value = ( ( value & 0xFF00FF00L ) >> 8 ) |
+ ( ( value & 0x00FF00FFL ) << 8 );
+ *buffer++ = ( value << 16 ) | ( value >> 16 );
+ }
+}
+
+int rc;
+int mode;
+int Dflag;
+
+main(argc,argv)
+ char **argv;
+{
+ int f = 0;
+ char *argp;
+
+ while (--argc > 0) if (*(argp = *++argv)=='-')
+ while (*++argp) switch(*argp)
+ {
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ if (mode) goto Usage;
+ mode = *argp;
+ break;
+ case 'D':
+ if (argc <= 1) goto Usage;
+ --argc;
+ Dflag = atoi(*++argv);
+ break;
+ case '-':
+ break;
+ default:
+ fprintf (stderr,"Bad switch char <%c>\n", *argp);
+ Usage:
+ fprintf(stderr, "Usage: t_shs [-1234567] [-D #]\n");
+ exit(1);
+ }
+ else goto Usage;
+
+ process();
+ exit(rc);
+}
+
+process()
+{
+ switch(mode)
+ {
+ case '1':
+ test1();
+ break;
+ case '2':
+ test2();
+ break;
+ case '3':
+ test3();
+ break;
+ case '4':
+ test4();
+ break;
+ case '5':
+ test5();
+ break;
+ case '6':
+ test6();
+ break;
+ case '7':
+ test7();
+ break;
+ default:
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+ test6();
+ test7();
+ }
+}
+
+#ifndef shsDigest
+unsigned char *
+shsDigest(si)
+ SHS_INFO *si;
+{
+ longReverse(si->digest, SHS_DIGESTSIZE);
+ return (unsigned char*) si->digest;
+}
+#endif
+
+unsigned char results1[SHS_DIGESTSIZE] = {
+0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e,
+0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d};
+
+test1()
+{
+ SHS_INFO si[1];
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ int i;
+
+ printf("Running SHS test 1 ...\n");
+ shsInit(si);
+ shsUpdate(si, "abc", 3);
+ shsFinal(si);
+ memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+ if (failed = memcmp(digest, results1, SHS_DIGESTSIZE))
+ {
+ fprintf(stderr,"SHS test 1 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results1[i]);
+ }
+ printf("\n");
+}
+
+unsigned char results2[SHS_DIGESTSIZE] = {
+0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae,
+0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1};
+
+test2()
+{
+ SHS_INFO si[1];
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ int i;
+
+ printf("Running SHS test 2 ...\n");
+ shsInit(si);
+ shsUpdate(si,
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ 56);
+ shsFinal(si);
+ memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+ if (failed = memcmp(digest, results2, SHS_DIGESTSIZE))
+ {
+ fprintf(stderr,"SHS test 2 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results2[i]);
+ }
+ printf("\n");
+}
+
+unsigned char results3[SHS_DIGESTSIZE] = {
+0x34,0xaa,0x97,0x3c,0xd4,0xc4,0xda,0xa4,0xf6,0x1e,
+0xeb,0x2b,0xdb,0xad,0x27,0x31,0x65,0x34,0x01,0x6f};
+
+test3()
+{
+ SHS_INFO si[1];
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ int i;
+
+ printf("Running SHS test 3 ...\n");
+ shsInit(si);
+ for (i = 0; i < 15625; ++i)
+ shsUpdate(si,
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ 64);
+ shsFinal(si);
+ memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+ if (failed = memcmp(digest, results3, SHS_DIGESTSIZE))
+ {
+ fprintf(stderr,"SHS test 3 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results3[i]);
+ }
+ printf("\n");
+}
+
+unsigned char randdata[] = {
+0xfe,0x28,0x79,0x25,0xf5,0x03,0xf9,0x1c,0xcd,0x70,0x7b,0xb0,0x42,0x02,0xb8,0x2f,
+0xf3,0x63,0xa2,0x79,0x8e,0x9b,0x33,0xd7,0x2b,0xc4,0xb4,0xd2,0xcb,0x61,0xec,0xbb,
+0x94,0xe1,0x8f,0x53,0x80,0x55,0xd9,0x90,0xb2,0x03,0x58,0xfa,0xa6,0xe5,0x18,0x57,
+0x68,0x04,0x24,0x98,0x41,0x7e,0x84,0xeb,0xc1,0x39,0xbc,0x1d,0xf7,0x4e,0x92,0x72,
+0x1a,0x5b,0xb6,0x99,0x43,0xa5,0x0a,0x45,0x73,0x55,0xfd,0x57,0x83,0x45,0x36,0x5c,
+0xfd,0x39,0x08,0x6e,0xe2,0x01,0x9a,0x8c,0x4e,0x39,0xd2,0x0d,0x5f,0x0e,0x35,0x15,
+0xb9,0xac,0x5f,0xa1,0x8a,0xe6,0xdd,0x6e,0x68,0x9d,0xf6,0x29,0x95,0xf6,0x7d,0x7b,
+0xd9,0x5e,0xf4,0x67,0x25,0xbd,0xee,0xed,0x53,0x60,0xb0,0x47,0xdf,0xef,0xf4,0x41,
+0xbd,0x45,0xcf,0x5c,0x93,0x41,0x87,0x97,0x82,0x39,0x20,0x66,0xb4,0xda,0xcb,0x66,
+0x93,0x02,0x2e,0x7f,0x94,0x4c,0xc7,0x3b,0x2c,0xcf,0xf6,0x99,0x6f,0x13,0xf1,0xc5,
+0x28,0x2b,0xa6,0x6c,0x39,0x26,0x7f,0x76,0x24,0x4a,0x6e,0x01,0x40,0x63,0xf8,0x00,
+0x06,0x23,0x5a,0xaa,0xa6,0x2f,0xd1,0x37,0xc7,0xcc,0x76,0xe9,0x54,0x1e,0x57,0x73,
+0xf5,0x33,0xaa,0x96,0xbe,0x35,0xcd,0x1d,0xd5,0x7d,0xac,0x50,0xd5,0xf8,0x47,0x2d,
+0xd6,0x93,0x5f,0x6e,0x38,0xd3,0xac,0xd0,0x7e,0xad,0x9e,0xf8,0x87,0x95,0x63,0x15,
+0x65,0xa3,0xd4,0xb3,0x9a,0x6c,0xac,0xcd,0x2a,0x54,0x83,0x13,0xc4,0xb4,0x94,0xfa,
+0x76,0x87,0xc5,0x8b,0x4a,0x10,0x92,0x05,0xd1,0x0e,0x97,0xfd,0xc8,0xfb,0xc5,0xdc,
+0x21,0x4c,0xc8,0x77,0x5c,0xed,0x32,0x22,0x77,0xc1,0x38,0x30,0xd7,0x8e,0x2a,0x70,
+0x72,0x67,0x13,0xe4,0xb7,0x18,0xd4,0x76,0xdd,0x32,0x12,0xf4,0x5d,0xc9,0xec,0xc1,
+0x2c,0x8a,0xfe,0x08,0x6c,0xea,0xf6,0xab,0x5a,0x0e,0x8e,0x81,0x1d,0xc8,0x5a,0x4b,
+0xed,0xb9,0x7f,0x4b,0x67,0xe3,0x65,0x46,0xc9,0xf2,0xab,0x37,0x0a,0x98,0x67,0x5b,
+0xb1,0x3b,0x02,0x91,0x38,0x71,0xea,0x62,0x88,0xae,0xb6,0xdb,0xfc,0x55,0x79,0x33,
+0x69,0x95,0x51,0xb6,0xe1,0x3b,0xab,0x22,0x68,0x54,0xf9,0x89,0x9c,0x94,0xe0,0xe3,
+0xd3,0x48,0x5c,0xe9,0x78,0x5b,0xb3,0x4b,0xba,0xd8,0x48,0xd8,0xaf,0x91,0x4e,0x23,
+0x38,0x23,0x23,0x6c,0xdf,0x2e,0xf0,0xff,0xac,0x1d,0x2d,0x27,0x10,0x45,0xa3,0x2d,
+0x8b,0x00,0xcd,0xe2,0xfc,0xb7,0xdb,0x52,0x13,0xb7,0x66,0x79,0xd9,0xd8,0x29,0x0e,
+0x32,0xbd,0x52,0x6b,0x75,0x71,0x08,0x83,0x1b,0x67,0x28,0x93,0x97,0x97,0x32,0xff,
+0x8b,0xd3,0x98,0xa3,0xce,0x2b,0x88,0x37,0x1c,0xcc,0xa0,0xd1,0x19,0x9b,0xe6,0x11,
+0xfc,0xc0,0x3c,0x4e,0xe1,0x35,0x49,0x29,0x19,0xcf,0x1d,0xe1,0x60,0x74,0xc0,0xe9,
+0xf7,0xb4,0x99,0xa0,0x23,0x50,0x51,0x78,0xcf,0xc0,0xe5,0xc2,0x1c,0x16,0xd2,0x24,
+0x5a,0x63,0x54,0x83,0xaa,0x74,0x3d,0x41,0x0d,0x52,0xee,0xfe,0x0f,0x4d,0x13,0xe1,
+0x27,0x00,0xc4,0xf3,0x2b,0x55,0xe0,0x9c,0x81,0xe0,0xfc,0xc2,0x13,0xd4,0x39,0x09
+};
+
+unsigned char results4[SHS_DIGESTSIZE] = {
+0x13,0x62,0xfc,0x87,0x68,0x33,0xd5,0x1d,0x2f,0x0c,
+0x73,0xe3,0xfb,0x87,0x6a,0x6b,0xc3,0x25,0x54,0xfc};
+
+test4()
+{
+ SHS_INFO si[1];
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ int i, j, k;
+
+ printf("Running SHS test 4 ...\n");
+ shsInit(si);
+ shsUpdate(si, randdata, 19);
+ shsFinal(si);
+ memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+ if (failed = memcmp(digest, results4, SHS_DIGESTSIZE))
+ {
+ fprintf(stderr,"SHS test 4 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results4[i]);
+ }
+ printf("\n");
+}
+
+unsigned char results5[SHS_DIGESTSIZE] = {
+0x19,0x4d,0xf6,0xeb,0x8e,0x02,0x6d,0x37,0x58,0x64,
+0xe5,0x95,0x19,0x2a,0xdd,0x1c,0xc4,0x3c,0x24,0x86};
+
+test5()
+{
+ SHS_INFO si[1];
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ int i, j, k;
+
+ printf("Running SHS test 5 ...\n");
+ shsInit(si);
+ shsUpdate(si, randdata, 19);
+ shsUpdate(si, randdata+32, 15);
+ shsFinal(si);
+ memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+ if (failed = memcmp(digest, results5, SHS_DIGESTSIZE))
+ {
+ fprintf(stderr,"SHS test 5 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results5[i]);
+ }
+ printf("\n");
+}
+
+unsigned char results6[SHS_DIGESTSIZE] = {
+0x4e,0x16,0x57,0x9d,0x4b,0x48,0xa9,0x1c,0x88,0x72,
+0x83,0xdb,0x88,0xd1,0xea,0x3a,0x45,0xdf,0xa1,0x10};
+
+test6()
+{
+ struct {
+ long pad1;
+ SHS_INFO si1;
+ long pad2;
+ SHS_INFO si2;
+ long pad3;
+ } sdata;
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ int i, j, k;
+
+ printf("Running SHS test 6 ...\n");
+ sdata.pad1 = 0x12345678;
+ sdata.pad2 = 0x87654321;
+ sdata.pad3 = 0x78563412;
+ shsInit((&sdata.si2));
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #20 %#lx\n",
+sdata.pad2);
+sdata.pad2 = 0x87654321;
+}
+if (sdata.pad3 != 0x78563412) {
+printf ("Overrun #21 %#lx\n",
+sdata.pad3);
+sdata.pad3 = 0x78563412;
+}
+ for (i = 0; i < 400; ++i)
+ {
+ shsInit(&sdata.si1);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #22 %#lx at %d\n",
+sdata.pad1, i);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #23 %#lx at %d\n",
+sdata.pad2, i);
+sdata.pad2 = 0x87654321;
+}
+ shsUpdate(&sdata.si1, (randdata+sizeof(randdata))-i, i);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #24 %#lx at %d\n",
+sdata.pad1, i);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #25 %#lx at %d\n",
+sdata.pad2, i);
+sdata.pad2 = 0x87654321;
+}
+ shsFinal(&sdata.si1);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #26 %#lx at %d\n",
+sdata.pad1, i);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #27 %#lx at %d\n",
+sdata.pad2, i);
+sdata.pad2 = 0x87654321;
+}
+ memcpy(digest, shsDigest(&sdata.si1), SHS_DIGESTSIZE);
+ if (Dflag & 1)
+ {
+ printf ("%d: ", i);
+ for (j = 0; j < SHS_DIGESTSIZE; ++j)
+ printf("%02x",digest[j]);
+ printf("\n");
+ }
+ shsUpdate((&sdata.si2), digest, SHS_DIGESTSIZE);
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #28 %#lx at %d\n",
+sdata.pad2, i);
+sdata.pad2 = 0x87654321;
+}
+if (sdata.pad3 != 0x78563412) {
+printf ("Overrun #29 %#lx at %d\n",
+sdata.pad3, i);
+sdata.pad3 = 0x78563412;
+}
+ if (Dflag & 2)
+ printf ("%d: %08lx%08lx%08lx%08lx%08lx\n",
+ i,
+ sdata.si2.digest[0],
+ sdata.si2.digest[1],
+ sdata.si2.digest[2],
+ sdata.si2.digest[3],
+ sdata.si2.digest[4]);
+ }
+ shsFinal((&sdata.si2));
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #30 %#lx\n",
+sdata.pad2);
+sdata.pad2 = 0x87654321;
+}
+if (sdata.pad3 != 0x78563412) {
+printf ("Overrun #31 %#lx\n",
+sdata.pad3);
+sdata.pad3 = 0x78563412;
+}
+ memcpy(digest, shsDigest((&sdata.si2)), SHS_DIGESTSIZE);
+ if (failed = memcmp(digest, results6, SHS_DIGESTSIZE))
+ {
+ fprintf(stderr,"SHS test 6 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results6[i]);
+ }
+ printf("\n");
+}
+
+unsigned char results7[SHS_DIGESTSIZE] = {
+0x89,0x41,0x65,0xce,0x76,0xc1,0xd1,0xd1,0xc3,0x6f,
+0xab,0x92,0x79,0x30,0x01,0x71,0x63,0x1f,0x74,0xfe};
+
+int jfsize[] = {0,1,31,32,
+ 33,55,56,63,
+ 64,65,71,72,
+ 73,95,96,97,
+ 119,120,123,127};
+int kfsize[] = {0,1,31,32,33,55,56,63};
+
+test7()
+{
+ struct {
+ long pad1;
+ SHS_INFO si1;
+ long pad2;
+ SHS_INFO si2;
+ long pad3;
+ } sdata;
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ int i, j, k, l;
+
+ printf("Running SHS test 7 ...\n");
+ sdata.pad1 = 0x12345678;
+ sdata.pad2 = 0x87654321;
+ sdata.pad3 = 0x78563412;
+ shsInit((&sdata.si2));
+ for (i = 1; i <= 128; ++i)
+ for (j = 0; j < 20; ++j)
+ for (k = 0; k < 8; ++k)
+ {
+ shsInit(&sdata.si1);
+ shsUpdate(&sdata.si1, (randdata+80+j), i);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #1 %#lx at %d,%d,%d\n",
+sdata.pad1, i,j,k);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #2 %#lx at %d,%d,%d\n",
+sdata.pad2, i,j,k);
+sdata.pad2 = 0x87654321;
+}
+ shsUpdate(&sdata.si1, randdata+i, jfsize[j]);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #3 %#lx at %d,%d,%d\n",
+sdata.pad1, i,j,k);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #4 %#lx at %d,%d,%d\n",
+sdata.pad2, i,j,k);
+sdata.pad2 = 0x87654321;
+}
+ if (k) shsUpdate(&sdata.si1, randdata+(i^j), kfsize[k]);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #5 %#lx at %d,%d,%d\n",
+sdata.pad1, i,j,k);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #6 %#lx at %d,%d,%d\n",
+sdata.pad2, i,j,k);
+sdata.pad2 = 0x87654321;
+}
+ shsFinal(&sdata.si1);
+if (sdata.pad1 != 0x12345678) {
+printf ("Overrun #7 %#lx at %d,%d,%d\n",
+sdata.pad1, i,j,k);
+sdata.pad1 = 0x12345678;
+}
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #8 %#lx at %d,%d,%d\n",
+sdata.pad2, i,j,k);
+sdata.pad2 = 0x87654321;
+}
+ memcpy(digest, shsDigest(&sdata.si1), SHS_DIGESTSIZE);
+ if (Dflag & 1)
+ {
+ printf ("%d,%d,%d: ", i, j, k);
+ for (l = 0; l < SHS_DIGESTSIZE; ++l)
+ printf("%02x",digest[l]);
+ printf("\n");
+ }
+ shsUpdate((&sdata.si2), digest, SHS_DIGESTSIZE);
+if (sdata.pad2 != 0x87654321) {
+printf ("Overrun #9 %#lx at %d,%d,%d\n",
+sdata.pad2, i,j,k);
+sdata.pad2 = 0x87654321;
+}
+if (sdata.pad3 != 0x78563412) {
+printf ("Overrun #10 %#lx at %d,%d,%d\n",
+sdata.pad3, i,j,k);
+sdata.pad3 = 0x78563412;
+}
+ if (Dflag & 2)
+ printf ("%d,%d,%d: %08lx%08lx%08lx%08lx%08lx\n",
+ i,j,k,
+ sdata.si2.digest[0],
+ sdata.si2.digest[1],
+ sdata.si2.digest[2],
+ sdata.si2.digest[3],
+ sdata.si2.digest[4]);
+ }
+ shsFinal((&sdata.si2));
+ memcpy(digest, shsDigest((&sdata.si2)), SHS_DIGESTSIZE);
+ if (failed = memcmp(digest, results7, SHS_DIGESTSIZE))
+ {
+ fprintf(stderr,"SHS test 7 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results7[i]);
+ }
+ printf("\n");
+}
diff --git a/src/lib/crypto/valid_cksumtype.c b/src/lib/crypto/valid_cksumtype.c
index 68000be..16efdc6 100644
--- a/src/lib/crypto/valid_cksumtype.c
+++ b/src/lib/crypto/valid_cksumtype.c
@@ -28,7 +28,7 @@
#include "cksumtypes.h"
KRB5_DLLIMP krb5_boolean KRB5_CALLCONV
-valid_cksumtype(ctype)
+krb5_c_valid_cksumtype(ctype)
krb5_cksumtype ctype;
{
int i;
@@ -40,3 +40,9 @@ valid_cksumtype(ctype)
return(0);
}
+
+KRB5_DLLIMP krb5_boolean KRB5_CALLCONV
+valid_cksumtype(krb5_cksumtype ctype)
+{
+ return krb5_c_valid_cksumtype (ctype);
+}
diff --git a/src/lib/crypto/valid_enctype.c b/src/lib/crypto/valid_enctype.c
index 39e48c0..ce955d8 100644
--- a/src/lib/crypto/valid_enctype.c
+++ b/src/lib/crypto/valid_enctype.c
@@ -28,7 +28,7 @@
#include "etypes.h"
KRB5_DLLIMP krb5_boolean KRB5_CALLCONV
-valid_enctype(etype)
+krb5_c_valid_enctype(etype)
krb5_enctype etype;
{
int i;
@@ -40,3 +40,9 @@ valid_enctype(etype)
return(0);
}
+
+KRB5_DLLIMP krb5_boolean KRB5_CALLCONV
+valid_enctype(krb5_enctype etype)
+{
+ return krb5_c_valid_enctype (etype);
+}
diff --git a/src/lib/gssapi/ChangeLog b/src/lib/gssapi/ChangeLog
index 1e0213f..37b9d26 100644
--- a/src/lib/gssapi/ChangeLog
+++ b/src/lib/gssapi/ChangeLog
@@ -1,3 +1,16 @@
+2002-05-22 Alexandra Ellwood <lxs@mit.edu>
+ * gss_libinit.c: Conditionalized error table loading for
+ Mac OS X. Error tables should always be loaded on other
+ platforms.
+
+2002-03-03 Alexandra Ellwood <lxs@mit.edu>
+ * gss_libinit.c: updated for Mac OS X header paths and added
+ include of gssapiP_krb5.h to get function prototypes.
+
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in(LIBMINOR): Bump library version.
+
Tue Feb 22 10:23:19 2000 Ezra Peisach <epeisach@mit.edu>
* Makefile.in (clean-unix): Add clean-libobjs.
diff --git a/src/lib/gssapi/Makefile.in b/src/lib/gssapi/Makefile.in
index bee2b85..20936da 100644
--- a/src/lib/gssapi/Makefile.in
+++ b/src/lib/gssapi/Makefile.in
@@ -24,7 +24,7 @@ SRCS=\
LIB=gssapi_krb5
LIBMAJOR=2
-LIBMINOR=1
+LIBMINOR=2
STOBJLISTS=OBJS.ST generic/OBJS.ST krb5/OBJS.ST
SHLIB_EXPDEPS=\
$(TOPLIBD)/libkrb5$(SHLIBEXT) \
diff --git a/src/lib/gssapi/generic/ChangeLog b/src/lib/gssapi/generic/ChangeLog
index 234c953..1bbf501 100644
--- a/src/lib/gssapi/generic/ChangeLog
+++ b/src/lib/gssapi/generic/ChangeLog
@@ -1,3 +1,50 @@
+2002-05-05 Alexandra Ellwood <lxs@mit.edu>
+ * gssapi_generic.h: allow inclusion by C++
+
+2002-03-28 Alexandra Ellwood <lxs@mit.edu>
+ * gssapi.hin: Conditionalized pragmas for Metrowerks
+
+2002-03-07 Alexandra Ellwood <lxs@mit.edu>
+ * gssapi.hin: Added check for CFM compiles. Removed dependency on
+ PRAGMA_* macros. Moved check struct alignment check before struct declarations.
+
+2002-03-03 Alexandra Ellwood <lxs@mit.edu>
+ * disp_com_err_status.c: Updated Mac OS X headers to new
+ framework layout... this time for real.
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * disp_com_err_status.c, gssapi.hin, gssapi_generic.h:
+ Updated Mac OS X headers to new framework layout
+
+2000-11-19 Alexandra Ellwood <lxs@mit.edu>
+ * gssapi_generic.h: Fixed check for Mac OS X includes.
+
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * gssapi.hin, gssapi_generic.h, gssapi_generic.c:
+ added oids from rfc 2744. Kept old oids for compatibility.
+ * gssapi.hin: Changed KerberosConditionalMacros.h to
+ KerberosSupport.h.
+ * gssapi.hin: Fixed Mac OS preprocessor test
+ * gssapi_generic.h: corrected Mac OS include to <GSS/gssapi.h>
+ * gssapiP_generic.h: use "" include for krb5.h
+ * disp_com_err_status.c, gssapi.hin: Updated Mac OS #defines
+ and #includes for new header layout and Mac OS X frameworks
+ * gssapi_generic.h: Added check for Mac OS X includes. This will
+ not break autoconf-style builds because they do not include
+ ConditionalMacros.h.
+
+2001-10-20 Ken Raeburn <raeburn@mit.edu>
+
+ * gssapiP_generic.h (g_*): For every g_ function declared here,
+ first define the name as a macro using a gssint_ prefix to avoid
+ conflicting with glib function names.
+
+2000-09-11 Alexandra Ellwood <lxs@mit.edu>
+ * gssapi_generic.h: Added check for Mac OS X includes. This will
+ not break autoconf-style builds because they do not include
+ ConditionalMacros.h.
+
1999-10-26 Tom Yu <tlyu@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/gssapi/generic/disp_com_err_status.c b/src/lib/gssapi/generic/disp_com_err_status.c
index c4db913..71c7505 100644
--- a/src/lib/gssapi/generic/disp_com_err_status.c
+++ b/src/lib/gssapi/generic/disp_com_err_status.c
@@ -25,7 +25,12 @@
*/
#include "gssapiP_generic.h"
+
+#if TARGET_OS_MAC
+#include <Kerberos/com_err.h>
+#else
#include "com_err.h"
+#endif
/* XXXX internationalization!! */
diff --git a/src/lib/gssapi/generic/gssapi.hin b/src/lib/gssapi/generic/gssapi.hin
index f6a0f57..05edd74 100644
--- a/src/lib/gssapi/generic/gssapi.hin
+++ b/src/lib/gssapi/generic/gssapi.hin
@@ -27,13 +27,33 @@
* Determine platform-dependent configuration.
*/
-#if defined(_MSDOS) || defined(_WIN32) || defined(macintosh)
-#include <win-mac.h>
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+ #include <TargetConditionals.h>
+ #if TARGET_RT_MAC_CFM
+ #error "Use KfM 4.0 SDK headers for CFM compilation."
+ #endif
+
+ /* This is an API divergence in 1.2.3. This will be reconciled in 1.3, when
+ all platforms will have RFC-compliant OID declarations. */
+ #define GSS_RFC_COMPLIANT_OIDS 1
+#else
+ #define GSS_RFC_COMPLIANT_OIDS 0
+#endif
-/* Macintoh CFM-68K magic incantation */
-#if defined(macintosh) && defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
-#pragma import on
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if TARGET_OS_MAC
+ #if defined(__MWERKS__)
+ #pragma import on
+ #pragma enumsalwaysint on
+ #endif
+ #pragma options align=mac68k
#endif
+
+#if defined(_MSDOS) || defined(_WIN32)
+#include <win-mac.h>
#endif
#ifndef KRB5_CALLCONV
@@ -327,9 +347,106 @@ typedef int gss_cred_usage_t;
* Finally, function prototypes for the GSSAPI routines.
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
+/* RFC-compliant GSS_oids will be present on all platforms in 1.3 */
+#if GSS_RFC_COMPLIANT_OIDS
+
+/* Reserved static storage for GSS_oids. Comments are quotes from RFC 2744.
+ *
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_USER_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_MACHINE_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_STRING_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) org(3) dod(6) internet(1) security(5)
+ * nametypes(6) gss-host-based-services(2)). The constant
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
+ * to that gss_OID_desc. This is a deprecated OID value, and
+ * implementations wishing to support hostbased-service names
+ * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
+ * defined below, to identify such names;
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
+ * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
+ * parameter, but should not be emitted by GSS-API
+ * implementations
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x04"}, corresponding to an
+ * object-identifier value of {iso(1) member-body(2)
+ * Unites States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) service_name(4)}. The constant
+ * GSS_C_NT_HOSTBASED_SERVICE should be initialized
+ * to point to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_HOSTBASED_SERVICE;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ * corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_ANONYMOUS;
+
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_EXPORT_NAME;
+
+#endif /* GSS_RFC_COMPLIANT_OIDS */
+
+/* Function Prototypes */
GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_acquire_cred
PROTOTYPE( (OM_uint32 FAR *, /* minor_status */
@@ -684,9 +801,17 @@ PROTOTYPE( (OM_uint32 *, /* minor_status */
gss_name_t * /* output_name */
));
+#if TARGET_OS_MAC
+ #if defined(__MWERKS__)
+ #pragma enumsalwaysint reset
+ #pragma import reset
+ #endif
+ #pragma options align=reset
+#endif
+
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
/* XXXX these are not part of the GSSAPI C bindings! (but should be) */
@@ -700,9 +825,4 @@ PROTOTYPE( (OM_uint32 *, /* minor_status */
/* XXXX This is a necessary evil until the spec is fixed */
#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
-/* Macintoh CFM-68K magic incantation */
-#if defined(macintosh) && defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
-#pragma import reset
-#endif
-
#endif /* _GSSAPI_H_ */
diff --git a/src/lib/gssapi/generic/gssapiP_generic.h b/src/lib/gssapi/generic/gssapiP_generic.h
index a0fa7c4..3f7fd75 100644
--- a/src/lib/gssapi/generic/gssapiP_generic.h
+++ b/src/lib/gssapi/generic/gssapiP_generic.h
@@ -28,7 +28,7 @@
*/
#if (defined(_MSDOS) || defined(_WIN32) || defined(macintosh))
-#include <k5-int.h>
+#include "k5-int.h"
#else
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
@@ -97,6 +97,38 @@
/** helper functions **/
+/* hide names from applications, especially glib applications */
+#define g_set_init gssint_g_set_init
+#define g_set_destroy gssint_g_set_destroy
+#define g_set_entry_add gssint_g_set_entry_add
+#define g_set_entry_delete gssint_g_set_entry_delete
+#define g_set_entry_get gssint_g_set_entry_get
+#define g_save_name gssint_g_save_name
+#define g_save_cred_id gssint_g_save_cred_id
+#define g_save_ctx_id gssint_g_save_ctx_id
+#define g_validate_name gssint_g_validate_name
+#define g_validate_cred_id gssint_g_validate_cred_id
+#define g_validate_ctx_id gssint_g_validate_ctx_id
+#define g_delete_name gssint_g_delete_name
+#define g_delete_cred_id gssint_g_delete_cred_id
+#define g_delete_ctx_id gssint_g_delete_ctx_id
+#define g_make_string_buffer gssint_g_make_string_buffer
+#define g_copy_OID_set gssint_g_copy_OID_set
+#define g_token_size gssint_g_token_size
+#define g_make_token_header gssint_g_make_token_header
+#define g_verify_token_header gssint_g_verify_token_header
+#define g_display_major_status gssint_g_display_major_status
+#define g_display_com_err_status gssint_g_display_com_err_status
+#define g_order_init gssint_g_order_init
+#define g_order_check gssint_g_order_check
+#define g_order_free gssint_g_order_free
+#define g_queue_size gssint_g_queue_size
+#define g_queue_externalize gssint_g_queue_externalize
+#define g_queue_internalize gssint_g_queue_internalize
+#define g_canonicalize_host gssint_g_canonicalize_host
+#define g_local_host_name gssint_g_local_host_name
+#define g_strdup gssint_g_strdup
+
typedef struct _g_set *g_set;
int g_set_init PROTOTYPE((g_set *s));
diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c
index 10cc4d7..ea7cb82 100644
--- a/src/lib/gssapi/generic/gssapi_generic.c
+++ b/src/lib/gssapi/generic/gssapi_generic.c
@@ -53,17 +53,111 @@
*/
static gss_OID_desc oids[] = {
- {10, "\052\206\110\206\367\022\001\002\001\001"},
- {10, "\052\206\110\206\367\022\001\002\001\002"},
- {10, "\052\206\110\206\367\022\001\002\001\003"},
- {10, "\052\206\110\206\367\022\001\002\001\004"},
- { 6, "\053\006\001\005\006\004"},
- { 6, "\053\006\001\005\006\002"},
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) org(3) dod(6) internet(1) security(5)
+ * nametypes(6) gss-host-based-services(2)). The constant
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
+ * to that gss_OID_desc. This is a deprecated OID value, and
+ * implementations wishing to support hostbased-service names
+ * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
+ * defined below, to identify such names;
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
+ * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
+ * parameter, but should not be emitted by GSS-API
+ * implementations
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) member-body(2) Unites States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) service_name(4)}.
+ * The constant GSS_C_NT_HOSTBASED_SERVICE should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ /* corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ /* corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
};
-GSS_DLLIMP gss_OID gss_nt_user_name = oids+0;
-GSS_DLLIMP gss_OID gss_nt_machine_uid_name = oids+1;
-GSS_DLLIMP gss_OID gss_nt_string_uid_name = oids+2;
-GSS_DLLIMP gss_OID gss_nt_service_name = oids+3;
-GSS_DLLIMP gss_OID gss_nt_exported_name = oids+4;
-GSS_DLLIMP gss_OID gss_nt_service_name_v2 = oids+5;
+/* Here are the constants which point to the static structure above.
+ *
+ * Constants of the form GSS_C_NT_* are specified by rfc 2744.
+ *
+ * Constants of the form gss_nt_* are the original MIT krb5 names
+ * found in gssapi_generic.h. They are provided for compatibility. */
+
+#if GSS_RFC_COMPLIANT_OIDS
+GSS_DLLIMP gss_OID GSS_C_NT_USER_NAME = oids+0;
+GSS_DLLIMP gss_OID GSS_C_NT_MACHINE_UID_NAME = oids+1;
+GSS_DLLIMP gss_OID GSS_C_NT_STRING_UID_NAME = oids+2;
+GSS_DLLIMP gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = oids+3;
+GSS_DLLIMP gss_OID GSS_C_NT_HOSTBASED_SERVICE = oids+4;
+GSS_DLLIMP gss_OID GSS_C_NT_ANONYMOUS = oids+5;
+GSS_DLLIMP gss_OID GSS_C_NT_EXPORT_NAME = oids+6;
+#endif /* GSS_RFC_COMPLIANT_OIDS */
+
+GSS_DLLIMP gss_OID gss_nt_user_name = oids+0;
+GSS_DLLIMP gss_OID gss_nt_machine_uid_name = oids+1;
+GSS_DLLIMP gss_OID gss_nt_string_uid_name = oids+2;
+GSS_DLLIMP gss_OID gss_nt_service_name_v2 = oids+3;
+GSS_DLLIMP gss_OID gss_nt_service_name = oids+4;
+GSS_DLLIMP gss_OID gss_nt_exported_name = oids+6;
diff --git a/src/lib/gssapi/generic/gssapi_generic.h b/src/lib/gssapi/generic/gssapi_generic.h
index 8317cad..337558a 100644
--- a/src/lib/gssapi/generic/gssapi_generic.h
+++ b/src/lib/gssapi/generic/gssapi_generic.h
@@ -27,17 +27,33 @@
* $Id$
*/
-#if defined(__MWERKS__) || defined(applec) || defined(THINK_C)
-#include <gssapi.h>
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+#include <Kerberos/gssapi.h>
#else
#include <gssapi/gssapi.h>
#endif
+#if defined(__cplusplus) && !defined(GSSAPIGENERIC_BEGIN_DECLS)
+#define GSSAPIGENERIC_BEGIN_DECLS extern "C" {
+#define GSSAPIGENERIC_END_DECLS }
+#else
+#define GSSAPIGENERIC_BEGIN_DECLS
+#define GSSAPIGENERIC_END_DECLS
+#endif
+
+GSSAPIGENERIC_BEGIN_DECLS
+
+/* Deprecated MIT krb5 oid names provided for compatibility.
+ * The correct oids (GSS_C_NT_USER_NAME, etc) from rfc 2744
+ * are defined in gssapi.h. */
+
GSS_DLLIMP extern gss_OID gss_nt_user_name;
GSS_DLLIMP extern gss_OID gss_nt_machine_uid_name;
GSS_DLLIMP extern gss_OID gss_nt_string_uid_name;
+GSS_DLLIMP extern gss_OID gss_nt_service_name_v2;
GSS_DLLIMP extern gss_OID gss_nt_service_name;
GSS_DLLIMP extern gss_OID gss_nt_exported_name;
-GSS_DLLIMP extern gss_OID gss_nt_service_name_v2;
+
+GSSAPIGENERIC_END_DECLS
#endif /* _GSSAPI_GENERIC_H_ */
diff --git a/src/lib/gssapi/gss_libinit.c b/src/lib/gssapi/gss_libinit.c
index e011ebd..3c57203 100644
--- a/src/lib/gssapi/gss_libinit.c
+++ b/src/lib/gssapi/gss_libinit.c
@@ -1,5 +1,11 @@
#include <assert.h>
+#if TARGET_OS_MAC
+// Mac OS X com_err files do not include com_err for you
+#include <Kerberos/com_err.h>
+#endif
+
+#include "gssapiP_krb5.h"
#include "gssapi_err_generic.h"
#include "gssapi_err_krb5.h"
@@ -15,8 +21,10 @@ OM_uint32 gssint_initialize_library (void)
{
if (!initialized) {
+#if !TARGET_OS_MAC || USE_HARDCODED_FALLBACK_ERROR_TABLES
add_error_table(&et_k5g_error_table);
add_error_table(&et_ggss_error_table);
+#endif
initialized = 1;
}
diff --git a/src/lib/gssapi/krb5/3des.txt b/src/lib/gssapi/krb5/3des.txt
new file mode 100644
index 0000000..f39c6fc
--- /dev/null
+++ b/src/lib/gssapi/krb5/3des.txt
@@ -0,0 +1,274 @@
+CAT Working Group K. Raeburn
+Internet-draft MIT
+Category: June xx, 2000
+Updates: RFC 1964
+Document: draft-raeburn-gssapi-krb5-3des-XX.txt
+
+ Triple-DES Support for the Kerberos 5 GSSAPI Mechanism
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of RFC2026 [1]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF),
+ its areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts. Internet-Drafts
+ are draft documents valid for a maximum of six months and may be
+ updated, replaced, or obsoleted by other documents at any time. It
+ is inappropriate to use Internet-Drafts as reference material or to
+ cite them other than as "work in progress."
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed at
+ http://www.ietf.org/shadow.html.
+
+1. Abstract
+
+ The MIT Kerberos 5 release version 1.2 includes support for
+ triple-DES with key derivation [KrbRev]. Recent work by the EFF
+ [EFF] has demonstrated the vulnerability of single-DES mechanisms
+ to brute-force attacks by sufficiently motivated and well-funded
+ parties.
+
+ The GSSAPI Kerberos 5 mechanism definition [GSSAPI-KRB5]
+ specifically enumerates encryption and checksum types,
+ independently of how such schemes may be used in Kerberos. In the
+ long run, a new Kerberos-based mechanism, which does not require
+ separately enumerating for the GSSAPI mechanism each of the various
+ encryption types defined by Kerberos, is a better approach.
+ Efforts to produce such a specification are under way.
+
+ In the interest of providing increased security in the near term,
+ however, MIT is adding support for triple-DES to the existing
+ mechanism implementation we ship, as described here.
+
+2. New Algorithm Identifiers
+
+ One new sealing algorithm is defined, for use in WRAP tokens:
+
+ 02 00 - DES3-KD
+
+ This algorithm uses triple-DES with key derivation, with a usage
+ value KG_USAGE_SEAL. Padding is still to 8-byte multiples, and the
+ IV for encrypting application data is zero.
+
+ One new signing algorithm is defined, for use in MIC, Wrap, and
+ Delete tokens:
+
+ 04 00 - HMAC SHA1 DES3-KD
+
+ This algorithm generates an HMAC using SHA-1 and a derived DES3 key
+ with usage KG_USAGE_SIGN, as (should be described) in [KrbRev].
+ [XXX: The current [KrbRev] description refers to out-of-date I-Ds
+ from Marc Horowitz. The text in [KrbRev] may be inadequate to
+ produce an interoperable implementation.]
+
+ The checksum size for this algorithm is 20 octets. See section 4.3
+ below for the use of checksum lengths of other than eight bytes.
+
+3. Key Derivation
+
+ For purposes of key derivation, we add three new usage values to the
+ list defined in [KrbRev]; one for signing messages, one for
+ sealing messages, and one for encrypting sequence numbers:
+
+ #define KG_USAGE_SEAL 22
+ #define KG_USAGE_SIGN 23
+ #define KG_USAGE_SEQ 24
+
+4. Adjustments to Previous Definitions
+
+4.1. Quality of Protection
+
+ The GSSAPI specification [GSSAPI] says that a zero QOP value
+ indicates the "default". The original specification for the
+ Kerberos 5 mechanism says that a zero QOP value (or a QOP value
+ with the appropriate bits clear) means DES encryption.
+
+ Rather than continue to force the use of plain DES when the
+ application doesn't use mechanism-specific QOP values, the better
+ choice appears to be to redefine the DES QOP value as some non-zero
+ value, and define a triple-DES value as well. Then a zero value
+ continues to imply the default, which would be triple-DES
+ protection when given a triple-DES session key.
+
+ Our values are:
+
+ GSS_KRB5_INTEG_C_QOP_HMAC_SHA1 0x0004
+ /* SHA-1 checksum encrypted with key derivation */
+
+ GSS_KRB5_CONF_C_QOP_DES 0x0100
+ /* plain DES encryption */
+ GSS_KRB5_CONF_C_QOP_DES3_KD 0x0200
+ /* triple-DES with key derivation */
+
+ Rather than open the question of whether to specify means for
+ deriving a key of one type given a key of another type, and the
+ security implications of whether to generate a long key from a
+ shorter one, our implementation will simply return an error if the
+ QOP value specified does not correspond to the session key type.
+
+ [XXX: Not implemented yet. Currently an error is reported for all
+ non-zero values. This should be changed before the release, so an
+ application can insist on getting no less than triple-DES
+ protection.]
+
+4.2. MIC Sequence Number Encryption
+
+ The sequence numbers are encrypted in the context key (as defined
+ in [GSSAPI-KRB5] -- this will be either the Kerberos session key or
+ asubkey provided by the context initiator), using whatever
+ encryption system is designated by the type of that context key.
+ The IV is formed from the first N bytes of the SGN_CKSUM field,
+ where N is the number of bytes needed for the IV. (With all
+ algorithms described here and in [GSSAPI-KRB5], the checksum is at
+ least as large as the IV.)
+
+4.3. Message Layout
+
+ Both MIC and Wrap tokens, as defined in [GSSAPI-KRB5], contain an
+ checksum field SGN_CKSUM. In [GSSAPI-KRB5], this field was
+ specified as being 8 bytes long. We now change this size to be
+ "defined by the checksum algorithm", and retroactively amend the
+ descriptions of all the checksum algorithms described in
+ [GSSAPI-KRB5] to explicitly specify 8-byte output. Application
+ data continues to immediately follow the checksum field in the Wrap
+ token.
+
+ The revised message descriptions are thus:
+
+ MIC:
+
+ Byte no Name Description
+ 0..1 TOK_ID Identification field.
+ 2..3 SGN_ALG Integrity algorithm indicator.
+ 4..7 Filler Contains ff ff ff ff
+ 8..15 SND_SEQ Sequence number field.
+ 16..s+15 SGN_CKSUM Checksum of "to-be-signed data",
+ calculated according to algorithm
+ specified in SGN_ALG field.
+
+ Wrap:
+
+ Byte no Name Description
+ 0..1 TOK_ID Identification field.
+ Tokens emitted by GSS_Wrap() contain
+ the hex value 02 01 in this field.
+ 2..3 SGN_ALG Checksum algorithm indicator.
+ 4..5 SEAL_ALG Sealing algorithm indicator.
+ 6..7 Filler Contains ff ff
+ 8..15 SND_SEQ Encrypted sequence number field.
+ 16..s+15 SGN_CKSUM Checksum of plaintext padded data,
+ calculated according to algorithm
+ specified in SGN_ALG field.
+ s+16..last Data encrypted or plaintext padded data
+
+ Where "s" indicates the size of the checksum.
+
+ As indicated above in section 2, we define the HMAC SHA1 DES3-KD
+ checksum algorithm to produce a 20-byte output, so encrypted data
+ begins at byte 36.
+
+5. Backwards Compatibility Considerations
+
+ The context initiator should request of the KDC credentials using
+ session-key cryptosystem types supported by that implementation; if
+ the only types returned by the KDC are not supported by the
+ mechanism implementation, it should indicate a failure. This may
+ seem obvious, but early implementations of both Kerberos and the
+ GSSAPI Kerberos mechanism supported only DES keys, so the
+ cryptosystem compatibility question was easy to overlook.
+
+ Under the current mechanism, no negotiation of algorithm types
+ occurs, so server-side (acceptor) implementations cannot request
+ that clients not use algorithm types not understood by the server.
+ However, administration of the server's Kerberos data has to be
+ done in communication with the KDC, and it is from the KDC that the
+ client will request credentials. The KDC could therefore be tasked
+ with limiting session keys for a given service to types actually
+ supported by the Kerberos and GSSAPI software on the server.
+
+ This does have a drawback for cases where a service principal name
+ is used both for GSSAPI-based and non-GSSAPI-based communication,
+ if the GSSAPI implementation does not understand triple-DES but the
+ Kerberos implementation does. It means that triple-DES session
+ keys cannot be issued for that service principal, which keeps the
+ protection of non-GSSAPI services weaker than necessary. However,
+ in the most recent MIT releases thus far, while triple-DES support
+ has been present, it has required additional work to enable, so it
+ should not be in use for many services.
+
+ It would also be possible to have clients attempt to get single-DES
+ session keys before trying to get triple-DES session keys, and have
+ the KDC refuse to issue the single-DES keys only for the most
+ critical of services, for which single-DES protection is considered
+ inadequate. However, that would eliminate the possibility of
+ connecting with the more secure cryptosystem to any service that
+ can be accessed with the weaker cryptosystem.
+
+ We have chosen to go with the former approach, putting the burden
+ on the KDC administration and gaining the best protection possible
+ for GSSAPI services, possibly at the cost of protection of
+ non-GSSAPI Kerberos services running earlier versions of the
+ software.
+ [XXX: Actually, we haven't entirely decided and cast it in stone
+ yet, it's just what I've implemented; it's easy to change.]
+
+6. Security Considerations
+
+ Various tradeoffs arise regarding the mixing of new and old
+ software, or GSSAPI-based and non-GSSAPI Kerberos authentication.
+ They are discussed in section 4.
+
+7. References
+
+ [EFF] Electronic Frontier Foundation, "Cracking DES: Secrets of
+ Encryption Research, Wiretap Politics, and Chip Design", O'Reilly &
+ Associates, Inc., May, 1998.
+
+ [GSSAPI] Linn, J., "Generic Security Service Application Program
+ Interface Version 2, Update 1", RFC 2743, January, 2000.
+
+ [GSSAPI-KRB5] Linn, J., "The Kerberos Version 5 GSS-API Mechanism",
+ RFC 1964, June, 1996.
+
+ [KrbRev] Neuman, C., Kohl, J., Ts'o, T., "The Kerberos Network
+ Authentication Service (V5)",
+ draft-ietf-cat-kerberos-revisions-05.txt, March 10, 2000.
+
+8. Author's Address
+
+ Kenneth Raeburn
+ Massachusetts Institute of Technology
+ 77 Massachusetts Avenue
+ Cambridge, MA 02139
+
+9. Full Copyright Statement
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph
+ are included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE."
diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog
index 06639d4..3803df1 100644
--- a/src/lib/gssapi/krb5/ChangeLog
+++ b/src/lib/gssapi/krb5/ChangeLog
@@ -1,4 +1,195 @@
-2000-01-27 Ken Raeburn <raeburn@raeburn.org>
+2002-04-16 Danilo Almeida <dalmeida@mit.edu>
+
+ * accept_sec_context.c (rd_and_store_for_creds): Remove
+ registration of MEMORY cache type since that's already registered.
+
+2002-04-16 Alexandra Ellwood <lxs@mit.edu>
+ * gssapi_krb5.h: Added #include of gssapi.h and gssapi_generic.h for the
+ Mac because we can't assume people will include them and get the OID
+ macro and the old names on the Mac.
+
+2002-03-03 Sam Hartman <hartmans@mit.edu>
+
+ * accept_sec_context.c (rd_and_store_for_creds): Patch from Steven
+ Michaud <smch@midway.uchicago.edu> to accept encrypted or
+ unencrypted credentials. This is important because Heimdal (and
+ sometimes Microsoft) send encrypted credentials.
+
+2002-03-03 Alexandra Ellwood <lxs@mit.edu>
+ * accept_sec_context.c, ser_sctx.c, util_crypt.c, wrap_size_limit.c:
+ Removed unused variables.
+ * acquire_cred.c: Added include of k5-int.h to get prototypes.
+ * disp_status.c: Updated Mac OS X header paths.
+ * gssapi_krb5.c: Added include of k5-int.h to get prototypes.
+ * gssapiP_krb5.h: Updated Mac OS X header paths and added prototype on Mac.
+ * init_sec_context.c: Removed unused function on the mac to avoid warning.
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * gssapi_krb5.h: Updated Mac OS X headers to new framework layout
+
+2002-02-19 Danilo Almeida <dalmeida@mit.edu>
+
+ * init_sec_context.c (krb5_gss_init_sec_context): Remove unsused
+ variables. Fix fencepost error in loop that prevents duplicates
+ while trying to figure out the desired enctype. Make the loop
+ structure in a little more readable.
+ (get_credentials): Remove unused variable.
+
+2001-12-07 Ken Raeburn <raeburn@mit.edu>
+
+ * init_sec_context.c (krb5_gss_init_sec_context): When supplying a
+ list of enctypes to use, use the subset and ordering indicated by
+ krb5.conf.
+
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * add_cred.c (krb5_gss_add_cred): Added constness to some char*s to make
+ them compiler with strict compilers.
+ * gssapi_krb5.h, gssapi_krb5.c: Added oids from rfc 1964 using the
+ suggested names.
+ * gssapi_krb5.h: Added #include of KerberosSupport.h in case this header
+ is included by itself.
+ * disp-status.c, gssapiP_krb5.h, gssapi_krb5.h: Updated Mac OS #defines
+ and #includes for new header layout and Mac OS X frameworks
+
+2001-10-04 Tom Yu <tlyu@mit.edu>
+
+ * accept_sec_context.c (krb5_gss_accept_sec_context): Ignore
+ unrecognized options properly. [krb5-libs/738]
+
+2001-10-01 Tom Yu <tlyu@mit.edu>
+
+ * accept_sec_context.c (rd_and_store_for_creds): Handle error
+ returns from krb5_rd_cred more sanely.
+
+2001-01-30 Ezra Peisach <epeisach@mit.edu>
+
+ * accept_sec_context.c (krb5_gss_accept_sec_context): If an error
+ occurs after the auth_context is established, but before the
+ krb5_gss_ctx_id_rec is established, release our pointer to the
+ replay cache and invoke krb5_auth_con_free(). [krb5-libs/855]
+
+2000-09-19 Miro Jurisic <meeroh@mit.edu>
+
+ * accept_sec_context.c (krb5_gss_accept_sec_context)
+ * acquire_cred.c (krb5_gss_acquire_cred)
+ * import_sec_context.c (krb5_gss_convert_static_mech_oid)
+ * init_sec_context.c (krb5_gss_init_sec_context)
+ * inq_cred.c (krb5_gss_inquire_cred)
+ Cast away constness from gss_OID where necessary to compile
+ with strict compilers
+
+2000-06-27 Tom Yu <tlyu@mit.edu>
+
+ * init_sec_context.c (get_credentials): Add initial iteration of
+ krb5_get_credentials in order to differentiate between an actual
+ missing credential and merely a bad match based on enctype. This
+ was causing problems with kadmin.
+
+2000-06-09 Tom Yu <tlyu@mit.edu>
+
+ * init_sec_context.c (get_credentials): The KDC as well as the
+ ccache may indicate that an enctype is not supported; reflect that
+ in the loop breakout condition.
+
+2000-06-07 Tom Yu <tlyu@mit.edu>
+
+ * init_sec_context.c (get_credentials): Rework the enctype loop
+ again.
+
+ * accept_sec_context.c (krb5_gss_accept_sec_context): Remove
+ explicit check of mech OID against credential.
+
+2000-06-04 Tom Yu <tlyu@mit.edu>
+
+ * init_sec_context.c (get_credentials): Reverse sense of test;
+ break out of enctype loop if one succeeds.
+
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * util_crypt.c (kg_encrypt): Copy ivec, since c_encrypt() now
+ updates ivecs.
+ (kg_decrypt): Copy ivec, since c_decrypt() now updates ivecs.
+
+2000-06-02 Ken Raeburn <raeburn@mit.edu>
+
+ * init_sec_context.c (get_credentials): Don't check each enctype
+ against a list from the krb5 library; instead, just try to use it,
+ and go on to the next if the error code indicates we can't use it.
+
+2000-05-31 Ken Raeburn <raeburn@mit.edu>
+
+ * gssapiP_krb5.h (KG_USAGE_SEQ): New value.
+ (enum qop): New type, derived from spec but currently not used.
+ * util_crypt.c (kg_encrypt, kg_decrypt): Added key derivation
+ usage value as an argument. Prototypes and callers updated; all
+ callers use KG_USAGE_SEAL, except KG_USAGE_SEQ when encrypting
+ sequence numbers.
+ * 3des.txt: New file.
+
+2000-5-19 Alexandra Ellwood <lxs@mit.edu>
+
+ * acquire_cred.c: Changed to use krb5int_cc_default. This function
+ supports the Kerberos Login Library and pops up a dialog if the cache does
+ not contain valid tickets. This is used to automatically get a tgt before
+ obtaining service tickets. Note that this should be an internal function
+ because callers don't expect krb5_cc_default to pop up a dialog!
+ (We found this out the hard way :-)
+
+2000-05-03 Nalin Dahyabhai <nalin@redhat.com>
+
+ * add_cred.c (krb5_gss_add_cred): Don't overflow buffers "ktboth"
+ or "ccboth".
+
+2000-04-21 Ken Raeburn <raeburn@mit.edu>
+
+ * gssapiP_krb5.h (struct _krb5_gss_ctx_id_rec): Delete field
+ gsskrb5_version.
+ (struct _krb5_gss_cred_id_rec): Delete field rfcv2_mech.
+ * accept_sec_context.c, acquire_cred.c, add_cred.c, inq_cred.c,
+ k5seal.c, k5unseal.c, ser_ctx.c:
+ Delete krb5-mech2 support.
+
+ * init_sec_context.c (get_credentials): Enctype argument is now a
+ pointer to a list of enctypes. Explicitly try each in order until
+ success or an error other than cryptosystem not being supported.
+ (krb5_gss_init_sec_context): Pass list of cryptosystems, starting
+ with 3DES.
+
+ * gssapiP_krb5.h (enum sgn_alg, enum seal_alg): New types,
+ giving symbolic names for values from RFC 1964, a Microsoft win2k
+ I-D, and our proposed 3des-sha1 values.
+ (KG_USAGE_SEAL, KG_USAGE_SIGN): New macros.
+
+ * accept_sec_context.c (rd_req_keyproc): Already-disabled routine
+ deleted.
+ (krb5_gss_accept_sec_context): Use sgn_alg and seal_alg symbolic
+ names. Add a case for des3-hmac-sha1.
+ * k5seal.c (make_seal_token_v1): Likewise. Do key derivation for
+ checksums.
+ * k5unseal.c (kg_unseal_v1): Likewise.
+ * util_crypt.c (kg_encrypt, kg_decrypt): Do key derivation for
+ encryption.
+
+ * util_crypt.c (zeros): Unused variable deleted.
+
+2000-04-18 Ken Raeburn <raeburn@mit.edu>
+
+ * wrap_size_limit.c: Remove mech2 support. Add MIT copyright.
+
+2000-04-08 Tom Yu <tlyu@mit.edu>
+
+ * wrap_size_limit.c (krb5_gss_wrap_size_limit): Fix up
+ wrap_size_limit() to deal with integrity wrap tokens properly.
+ The rfc1964 mech always pads and confounds regardless of whether
+ confidentiality is requested.
+
+2000-03-20 Ken Raeburn <raeburn@mit.edu>
+
+ * accept_sec_context.c, init_sec_context.c: Disable krb5-mech2
+ stuff for now. (Tom Yu's krb5-1.1 patch.)
+
+2000-01-27 Ken Raeburn <raeburn@mit.edu>
* init_sec_context.c (krb5_gss_init_sec_context): Default to
des-cbc-crc.
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index fc920ec..c8e7916 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -49,65 +73,61 @@
#include "k5-int.h"
#include "gssapiP_krb5.h"
#include <memory.h>
+#include <assert.h>
/*
* $Id$
*/
-#if 0
-
-/* XXXX This widen/narrow stuff is bletcherous, but it seems to be
- necessary. Perhaps there is a "better" way, but I don't know what it
- is */
-
-#include <krb5/widen.h>
-static krb5_error_code
-rd_req_keyproc(krb5_pointer keyprocarg, krb5_principal server,
- krb5_kvno kvno, krb5_keyblock **keyblock)
-#include <krb5/narrow.h>
-{
- krb5_error_code code;
- krb5_keytab_entry ktentry;
-
- if (code = krb5_kt_get_entry((krb5_keytab) keyprocarg, server, kvno,
- &ktentry))
- return(code);
-
- code = krb5_copy_keyblock(&ktentry.key, keyblock);
-
- (void) krb5_kt_free_entry(&ktentry);
-
- return(code);
-}
-
-#endif
-
/* Decode, decrypt and store the forwarded creds in the local ccache. */
static krb5_error_code
-rd_and_store_for_creds(context, inbuf, out_cred)
+rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
krb5_context context;
+ krb5_auth_context auth_context;
krb5_data *inbuf;
krb5_gss_cred_id_t *out_cred;
{
- krb5_creds ** creds;
+ krb5_creds ** creds = NULL;
krb5_error_code retval;
- krb5_ccache ccache;
+ krb5_ccache ccache = NULL;
krb5_gss_cred_id_t cred = NULL;
- extern krb5_cc_ops krb5_mcc_ops;
- krb5_auth_context auth_context = 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;
+ krb5_auth_context new_auth_ctx = NULL;
+ krb5_int32 flags_org;
+
+ if (retval = krb5_auth_con_getflags(context, auth_context, &flags_org))
+ return retval;
+ krb5_auth_con_setflags(context, auth_context, 0);
+
+ /* By the time krb5_rd_cred is called here (after krb5_rd_req has been */
+ /* called in krb5_gss_accept_sec_context), the "keyblock" field of */
+ /* auth_context contains a pointer to the session key, and the */
+ /* "remote_subkey" field might contain a session subkey. Either of */
+ /* these (the "remote_subkey" if it isn't NULL, otherwise the */
+ /* "keyblock") might have been used to encrypt the encrypted part of */
+ /* the KRB_CRED message that contains the forwarded credentials. (The */
+ /* Java Crypto and Security Implementation from the DSTC in Australia */
+ /* always uses the session key. But apparently it never negotiates a */
+ /* subkey, so this code works fine against a JCSI client.) Up to the */
+ /* present, though, GSSAPI clients linked against the MIT code (which */
+ /* is almost all GSSAPI clients) don't encrypt the KRB_CRED message at */
+ /* all -- at this level. So if the first call to krb5_rd_cred fails, */
+ /* we should call it a second time with another auth context freshly */
+ /* created by krb5_auth_con_init. All of its keyblock fields will be */
+ /* NULL, so krb5_rd_cred will assume that the KRB_CRED message is */
+ /* unencrypted. (The MIT code doesn't actually send the KRB_CRED */
+ /* message in the clear -- the "authenticator" whose "checksum" ends up */
+ /* containing the KRB_CRED message does get encrypted.) */
+ if (krb5_rd_cred(context, auth_context, inbuf, &creds, NULL)) {
+ if (retval = krb5_auth_con_init(context, &new_auth_ctx))
+ goto cleanup;
+ krb5_auth_con_setflags(context, new_auth_ctx, 0);
+ if (retval = krb5_rd_cred(context, new_auth_ctx, inbuf, &creds, NULL))
+ goto cleanup;
+ }
/* Lots of kludging going on here... Some day the ccache interface
will be rewritten though */
- krb5_cc_register(context, &krb5_mcc_ops, 0);
if ((retval = krb5_cc_resolve(context, "MEMORY:GSSAPI", &ccache)))
goto cleanup;
@@ -145,7 +165,6 @@ rd_and_store_for_creds(context, inbuf, out_cred)
/* 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 */
@@ -157,7 +176,8 @@ rd_and_store_for_creds(context, inbuf, out_cred)
goto cleanup;
*/
cleanup:
- krb5_free_tgt_creds(context, creds);
+ if (creds)
+ krb5_free_tgt_creds(context, creds);
if (!cred && ccache)
(void)krb5_cc_close(context, ccache);
@@ -165,8 +185,10 @@ cleanup:
if (out_cred)
*out_cred = cred; /* return credential */
- if (auth_context)
- krb5_auth_con_free(context, auth_context);
+ if (new_auth_ctx)
+ krb5_auth_con_free(context, new_auth_ctx);
+
+ krb5_auth_con_setflags(context, auth_context, flags_org);
return retval;
}
@@ -206,9 +228,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
krb5_ui_4 gss_flags = 0;
int decode_req_message = 0;
krb5_gss_ctx_id_rec *ctx = 0;
-#if 0
- krb5_enctype enctype;
-#endif
krb5_timestamp now;
gss_buffer_desc token;
krb5_auth_context auth_context = NULL;
@@ -221,11 +240,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
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 = 0;
- struct kg2_option fwcred;
if (GSS_ERROR(kg_get_context(minor_status, &context)))
return(GSS_S_FAILURE);
@@ -296,13 +311,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
&(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),
@@ -315,56 +324,15 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
* 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 {
major_status = GSS_S_DEFECTIVE_TOKEN;
goto fail;
}
- 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;
- }
+ sptr = (char *) ptr;
+ TREAD_STR(sptr, ap_req.data, ap_req.length);
+ decode_req_message = 1;
/* construct the sender_addr */
@@ -416,9 +384,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
}
#endif
- if (gsskrb5_vers == 2000) {
- bigend = 1;
- } else {
+ {
/* gss krb5 v1 */
/* stash this now, for later. */
@@ -480,12 +446,16 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
goto fail;
}
- TREAD_STR(ptr, ptr2, reqcksum.length);
- if (memcmp(ptr2, reqcksum.contents, reqcksum.length) != 0) {
- code = 0;
- major_status = GSS_S_BAD_BINDINGS;
- goto fail;
- }
+ TREAD_STR(ptr, ptr2, reqcksum.length);
+ /* If server has chosen not to use channel bindings, ignore */
+ /* any channel bindings sent by the client. */
+ if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
+ if (memcmp(ptr2, reqcksum.contents, reqcksum.length) != 0) {
+ code = 0;
+ major_status = GSS_S_BAD_BINDINGS;
+ goto fail;
+ }
+ }
xfree(reqcksum.contents);
reqcksum.contents = 0;
@@ -502,33 +472,41 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
i = authdat->checksum->length - 24;
- while(i>0) {
+ while (i >= 4) {
TREAD_INT16(ptr, option_id, bigend);
- switch(option_id) {
+ TREAD_INT16(ptr, option.length, bigend);
- case KRB5_GSS_FOR_CREDS_OPTION:
+ i -= 4;
- TREAD_INT16(ptr, option.length, bigend);
+ /* have to use ptr2, since option.data is wrong type and
+ macro uses ptr as both lvalue and rvalue */
- /* have to use ptr2, since option.data is wrong type and
- macro uses ptr as both lvalue and rvalue */
+ if (i < option.length || option.length < 0) {
+ code = KG_BAD_LENGTH;
+ major_status = GSS_S_FAILURE;
+ goto fail;
+ }
+
+ TREAD_STR(ptr, ptr2, bigend);
+ option.data = (char FAR *) ptr2;
+
+ i -= option.length;
+
+ switch(option_id) {
- TREAD_STR(ptr, ptr2, bigend);
- option.data = (char FAR *) ptr2;
+ case KRB5_GSS_FOR_CREDS_OPTION:
/* store the delegated credential */
- if (code = rd_and_store_for_creds(context, &option,
+ if (code = rd_and_store_for_creds(context, auth_context, &option,
(delegated_cred_handle) ?
&deleg_cred : NULL)) {
major_status = GSS_S_FAILURE;
goto fail;
}
- i -= option.length + 4;
-
gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */
break;
@@ -551,13 +529,12 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
}
memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
- ctx->mech_used = mech_used;
+ ctx->mech_used = (gss_OID) mech_used;
ctx->auth_context = auth_context;
ctx->initiate = 0;
ctx->gss_flags = KG_IMPLFLAGS(gss_flags);
ctx->seed_init = 0;
ctx->big_endian = bigend;
- 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)) {
@@ -603,114 +580,37 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
goto fail;
}
- 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);
+ switch(ctx->subkey->enctype) {
+ case ENCTYPE_DES_CBC_MD5:
+ case ENCTYPE_DES_CBC_CRC:
+ ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
+ ctx->signalg = SGN_ALG_DES_MAC_MD5;
+ ctx->cksum_size = 8;
+ ctx->sealalg = SEAL_ALG_DES;
- cksumdata.length = cblen + ((char *)(ap_req.data-2) - (char *)(ptr-2));
+ /* fill in the encryption descriptors */
- if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) {
- code = ENOMEM;
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) {
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)));
+ for (i=0; i<ctx->enc->length; i++)
+ /*SUPPRESS 113*/
+ ctx->enc->contents[i] ^= 0xf0;
- if (code = krb5_c_verify_checksum(context, ctx->subkey,
- KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
- &cksumdata, authdat->checksum,
- &valid)) {
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) {
major_status = GSS_S_FAILURE;
goto fail;
}
- free(cksumdata.data);
- cksumdata.data = 0;
+ break;
- 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;
-#endif
- default:
- code = KRB5_BAD_ENCTYPE;
- goto fail;
- }
+ case ENCTYPE_DES3_CBC_SHA1:
+ ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
+ ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
+ ctx->cksum_size = 20;
+ ctx->sealalg = SEAL_ALG_DES3KD;
/* fill in the encryption descriptors */
@@ -719,14 +619,16 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
goto fail;
}
- for (i=0; i<ctx->enc->length; i++)
- /*SUPPRESS 113*/
- ctx->enc->contents[i] ^= 0xf0;
-
if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) {
major_status = GSS_S_FAILURE;
goto fail;
}
+
+ break;
+
+ default:
+ code = KRB5_BAD_ENCTYPE;
+ goto fail;
}
ctx->endtime = ticket->enc_part2->times.endtime;
@@ -769,122 +671,22 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
/* 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; i<ctx->nctypes; 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;
+ token.length = g_token_size((gss_OID) mech_used, ap_rep.length);
- /* 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);
+ 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);
+ TWRITE_STR(ptr, ap_rep.data, ap_rep.length);
- ctx->established = 1;
+ ctx->established = 1;
- }
} else {
token.length = 0;
token.value = NULL;
@@ -943,6 +745,11 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
free(ctypes);
if (authdat)
krb5_free_authenticator(context, authdat);
+ /* The ctx structure has the handle of the auth_context */
+ if (auth_context && !ctx) {
+ (void)krb5_auth_con_setrcache(context, auth_context, NULL);
+ krb5_auth_con_free(context, auth_context);
+ }
if (reqcksum.contents)
xfree(reqcksum.contents);
if (ap_rep.data)
@@ -1014,13 +821,8 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
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;
- }
+ tmsglen = scratch.length;
+ toktype = KG_TOK_CTX_ERROR;
token.length = g_token_size((gss_OID) mech_used, tmsglen);
token.value = (unsigned char *) xmalloc(token.length);
@@ -1030,24 +832,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
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);
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
index b67eb4f..0cdff4a 100644
--- a/src/lib/gssapi/krb5/acquire_cred.c
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -47,6 +71,7 @@
*/
#include "gssapiP_krb5.h"
+#include "k5-int.h"
#ifdef HAVE_STRING_H
#include <string.h>
#else
@@ -154,7 +179,7 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
/* open the default credential cache */
- if ((code = krb5_cc_default(context, &ccache))) {
+ if ((code = krb5int_cc_default(context, &ccache))) {
*minor_status = code;
return(GSS_S_CRED_UNAVAIL);
}
@@ -283,7 +308,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;
- int req_old, req_new, req_v2;
+ int req_old, req_new;
OM_uint32 ret;
krb5_error_code code;
@@ -313,22 +338,18 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
if (desired_mechs == GSS_C_NULL_OID_SET) {
req_old = 1;
req_new = 1;
- req_v2 = 1;
} else {
req_old = 0;
req_new = 0;
- req_v2 = 0;
for (i=0; i<desired_mechs->count; 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 && !req_v2) {
+ if (!req_old && !req_new) {
*minor_status = 0;
return(GSS_S_BAD_MECH);
}
@@ -347,7 +368,6 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
cred->princ = NULL;
cred->prerfc_mech = req_old;
cred->rfc_mech = req_new;
- cred->rfcv2_mech = req_v2;
cred->keytab = NULL;
cred->ccache = NULL;
@@ -442,15 +462,11 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
&ret_mechs)) ||
(cred->prerfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- gss_mech_krb5_old,
+ (gss_OID) 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,
+ (gss_OID) gss_mech_krb5,
&ret_mechs)))) {
if (cred->ccache)
(void)krb5_cc_close(context, cred->ccache);
diff --git a/src/lib/gssapi/krb5/add_cred.c b/src/lib/gssapi/krb5/add_cred.c
index 2a6fdb4..a13ba52 100644
--- a/src/lib/gssapi/krb5/add_cred.c
+++ b/src/lib/gssapi/krb5/add_cred.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
* All rights reserved.
@@ -110,8 +134,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
/* 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)) {
+ (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech)) {
*minor_status = 0;
return(GSS_S_DUPLICATE_ELEMENT);
}
@@ -143,7 +166,9 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
/* make a copy */
krb5_gss_cred_id_t new_cred;
char *kttype, ktboth[1024];
- char *cctype, *ccname, ccboth[1024];
+ char ccboth[1024];
+ const char *ccname;
+ const char *cctype;
if ((new_cred =
(krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec)))
@@ -156,7 +181,6 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
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,
@@ -177,8 +201,9 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
return(GSS_S_FAILURE);
}
- strcpy(ktboth, kttype);
- strcat(ktboth, ":");
+ strncpy(ktboth, kttype, sizeof(ktboth) - 1);
+ ktboth[sizeof(ktboth) - 1] = '\0';
+ strncat(ktboth, ":", sizeof(ktboth) - 1 - strlen(ktboth));
if (code = krb5_kt_get_name(context, cred->keytab,
ktboth+strlen(ktboth),
@@ -234,9 +259,10 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
return(GSS_S_FAILURE);
}
- strcpy(ccboth, cctype);
- strcat(ccboth, ":");
- strcat(ccboth, ccname);
+ strncpy(ccboth, cctype, sizeof(ccboth) - 1);
+ ccboth[sizeof(ccboth) - 1] = '\0';
+ strncat(ccboth, ":", sizeof(ccboth) - 1 - strlen(ccboth));
+ strncat(ccboth, ccname, sizeof(ccboth) - 1 - strlen(ccboth));
if (code = krb5_cc_resolve(context, ccboth, &new_cred->ccache)) {
if (new_cred->rcache)
@@ -280,8 +306,6 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
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 */
diff --git a/src/lib/gssapi/krb5/disp_status.c b/src/lib/gssapi/krb5/disp_status.c
index 3a6ba7b..5991f87 100644
--- a/src/lib/gssapi/krb5/disp_status.c
+++ b/src/lib/gssapi/krb5/disp_status.c
@@ -21,7 +21,12 @@
*/
#include "gssapiP_krb5.h"
+
+#if TARGET_OS_MAC
+#include <Kerberos/com_err.h>
+#else
#include "com_err.h"
+#endif
/* XXXX internationalization!! */
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index e344b4f..a234530 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -27,7 +51,12 @@
* $Id$
*/
+#if TARGET_OS_MAC
+#include <Kerberos/krb5.h>
+#else
#include <krb5.h>
+#endif
+
#include <memory.h>
/* work around sunos braindamage */
@@ -38,11 +67,7 @@
#undef minor
#endif
-#ifndef macintosh
-#include "../generic/gssapiP_generic.h"
-#else
#include "gssapiP_generic.h"
-#endif
/* The include of gssapi_krb5.h will dtrt with the above #defines in
* effect.
@@ -79,6 +104,39 @@
#define KG2_RESP_FLAG_ERROR 0x0001
#define KG2_RESP_FLAG_DELEG_OK 0x0002
+/* These are to be stored in little-endian order, i.e., des-mac is
+ stored as 02 00. */
+enum sgn_alg {
+ SGN_ALG_DES_MAC_MD5 = 0x0000,
+ SGN_ALG_MD2_5 = 0x0001,
+ SGN_ALG_DES_MAC = 0x0002,
+ SGN_ALG_3 = 0x0003, /* not published */
+ SGN_ALG_HMAC_MD5 = 0x0011, /* microsoft w2k; no support */
+ SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004
+};
+enum seal_alg {
+ SEAL_ALG_NONE = 0xffff,
+ SEAL_ALG_DES = 0x0000,
+ SEAL_ALG_1 = 0x0001, /* not published */
+ SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; no support */
+ SEAL_ALG_DES3KD = 0x0002
+};
+
+#define KG_USAGE_SEAL 22
+#define KG_USAGE_SIGN 23
+#define KG_USAGE_SEQ 24
+
+enum qop {
+ GSS_KRB5_INTEG_C_QOP_MD5 = 0x0001, /* *partial* MD5 = "MD2.5" */
+ GSS_KRB5_INTEG_C_QOP_DES_MD5 = 0x0002,
+ GSS_KRB5_INTEG_C_QOP_DES_MAC = 0x0003,
+ GSS_KRB5_INTEG_C_QOP_HMAC_SHA1 = 0x0004,
+ GSS_KRB5_INTEG_C_QOP_MASK = 0x00ff,
+ GSS_KRB5_CONF_C_QOP_DES = 0x0100,
+ GSS_KRB5_CONF_C_QOP_DES3_KD = 0x0200,
+ GSS_KRB5_CONF_C_QOP_MASK = 0xff00
+};
+
/** internal types **/
typedef krb5_principal krb5_gss_name_t;
@@ -89,7 +147,6 @@ typedef struct _krb5_gss_cred_id_rec {
krb5_principal princ; /* this is not interned as a gss_name_t */
int prerfc_mech;
int rfc_mech;
- int rfcv2_mech;
/* keytab (accept) data */
krb5_keytab keytab;
@@ -125,7 +182,6 @@ typedef struct _krb5_gss_ctx_id_rec {
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;
@@ -190,12 +246,18 @@ int kg_encrypt_size PROTOTYPE((krb5_context context,
krb5_keyblock *key, int n));
krb5_error_code kg_encrypt PROTOTYPE((krb5_context context,
- krb5_keyblock *key,
- krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length));
+ krb5_keyblock *key, int usage,
+ krb5_pointer iv,
+ krb5_pointer in,
+ krb5_pointer out,
+ int length));
krb5_error_code kg_decrypt PROTOTYPE((krb5_context context,
- krb5_keyblock *key,
- krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length));
+ krb5_keyblock *key, int usage,
+ krb5_pointer iv,
+ krb5_pointer in,
+ krb5_pointer out,
+ int length));
OM_uint32 kg_seal PROTOTYPE((krb5_context context,
OM_uint32 *minor_status,
@@ -517,7 +579,8 @@ PROTOTYPE( (OM_uint32 *, /* minor_status */
gss_ctx_id_t * /* context_handle */
));
-#if 0
+#if TARGET_OS_MAC
+/* need prototypes on Mac OS X -- why *was* this #if 0? */
OM_uint32 krb5_gss_release_oid
PROTOTYPE( (OM_uint32 *, /* minor_status */
gss_OID * /* oid */
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
index e700bb8..70ef491 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.c
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
@@ -51,6 +51,7 @@
*/
#include "gssapiP_krb5.h"
+#include "k5-int.h"
/** exported constants defined in gssapi_krb5{,_nx}.h **/
@@ -90,16 +91,28 @@ const gss_OID_desc krb5_gss_oid_array[] = {
/* this is the v2 assigned OID */
{9, "\052\206\110\206\367\022\001\002\003"},
/* these two are name type OID's */
+
+ /* 2.1.1. Kerberos Principal Name Form: (rfc 1964)
+ * This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * krb5(2) krb5_name(1)}. The recommended symbolic name for this type
+ * is "GSS_KRB5_NT_PRINCIPAL_NAME". */
{10, "\052\206\110\206\367\022\001\002\002\001"},
+
+ /* gss_nt_krb5_principal. Object identifier for a krb5_principal. Do not use. */
{10, "\052\206\110\206\367\022\001\002\002\002"},
{ 0, 0 }
};
-const gss_OID_desc * const gss_mech_krb5 = krb5_gss_oid_array+0;
-const gss_OID_desc * const gss_mech_krb5_old = krb5_gss_oid_array+1;
-const gss_OID_desc * const gss_mech_krb5_v2 = krb5_gss_oid_array+2;
-const gss_OID_desc * const gss_nt_krb5_name = krb5_gss_oid_array+3;
-const gss_OID_desc * const gss_nt_krb5_principal = krb5_gss_oid_array+4;
+const gss_OID_desc * const gss_mech_krb5 = krb5_gss_oid_array+0;
+const gss_OID_desc * const gss_mech_krb5_old = krb5_gss_oid_array+1;
+const gss_OID_desc * const gss_mech_krb5_v2 = krb5_gss_oid_array+2;
+const gss_OID_desc * const gss_nt_krb5_name = krb5_gss_oid_array+3;
+const gss_OID_desc * const gss_nt_krb5_principal = krb5_gss_oid_array+4;
+#if GSS_RFC_COMPLIANT_OIDS
+const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME = krb5_gss_oid_array+3;
+#endif /* GSS_RFC_COMPLIANT_OIDS */
+
static const gss_OID_set_desc oidsets[] = {
{1, (gss_OID) krb5_gss_oid_array+0},
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.h b/src/lib/gssapi/krb5/gssapi_krb5.h
index e4bac76..c1ad99f 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.h
+++ b/src/lib/gssapi/krb5/gssapi_krb5.h
@@ -23,13 +23,65 @@
#ifndef _GSSAPI_KRB5_H_
#define _GSSAPI_KRB5_H_
-#include <krb5.h>
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+ #include <TargetConditionals.h>
+#endif
+
+#if TARGET_OS_MAC
+ #include <Kerberos/krb5.h>
+ #include <Kerberos/gssapi.h>
+ #include <Kerberos/gssapi_generic.h>
+#else
+ #include <krb5.h>
+#endif
/* C++ friendlyness */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
+#if GSS_RFC_COMPLIANT_OIDS
+/* Reserved static storage for GSS_oids. See rfc 1964 for more details. */
+
+/* 2.1.1. Kerberos Principal Name Form: */
+GSS_DLLIMP extern const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME;
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * krb5(2) krb5_name(1)}. The recommended symbolic name for this type
+ * is "GSS_KRB5_NT_PRINCIPAL_NAME". */
+
+/* 2.1.2. Host-Based Service Name Form */
+#define GSS_KRB5_NT_HOSTBASED_SERVICE_NAME GSS_C_NT_HOSTBASED_SERVICE
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) service_name(4)}. The previously recommended symbolic
+ * name for this type is "GSS_KRB5_NT_HOSTBASED_SERVICE_NAME". The
+ * currently preferred symbolic name for this type is
+ * "GSS_C_NT_HOSTBASED_SERVICE". */
+
+/* 2.2.1. User Name Form */
+#define GSS_KRB5_NT_USER_NAME GSS_C_NT_USER_NAME
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) user_name(1)}. The recommended symbolic name for this
+ * type is "GSS_KRB5_NT_USER_NAME". */
+
+/* 2.2.2. Machine UID Form */
+#define GSS_KRB5_NT_MACHINE_UID_NAME GSS_C_NT_MACHINE_UID_NAME
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) machine_uid_name(2)}. The recommended symbolic name for
+ * this type is "GSS_KRB5_NT_MACHINE_UID_NAME". */
+
+/* 2.2.3. String UID Form */
+#define GSS_KRB5_NT_STRING_UID_NAME GSS_C_NT_STRING_UID_NAME
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) string_uid_name(3)}. The recommended symbolic name for
+ * this type is "GSS_KRB5_NT_STRING_UID_NAME". */
+
+#endif /* GSS_RFC_COMPLIANT_OIDS */
+
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;
diff --git a/src/lib/gssapi/krb5/import_sec_context.c b/src/lib/gssapi/krb5/import_sec_context.c
index fd5415a..659cdc2 100644
--- a/src/lib/gssapi/krb5/import_sec_context.c
+++ b/src/lib/gssapi/krb5/import_sec_context.c
@@ -44,7 +44,7 @@ gss_OID krb5_gss_convert_static_mech_oid(oid)
if ((oid->length == p->length) &&
(memcmp(oid->elements, p->elements, p->length) == 0)) {
gss_release_oid(&minor_status, &oid);
- return p;
+ return (gss_OID) p;
}
}
return oid;
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index d0c8bc9..40c50cb 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -49,6 +73,7 @@
#include "gssapiP_krb5.h"
#include <memory.h>
#include <stdlib.h>
+#include <assert.h>
/*
* $Id$
@@ -63,13 +88,13 @@ int krb5_gss_dbg_client_expcreds = 0;
* ccache.
*/
static krb5_error_code get_credentials(context, cred, server, now,
- endtime, enctype, out_creds)
+ endtime, enctypes, out_creds)
krb5_context context;
krb5_gss_cred_id_t cred;
krb5_principal server;
krb5_timestamp now;
krb5_timestamp endtime;
- krb5_enctype enctype;
+ const krb5_enctype *enctypes;
krb5_creds **out_creds;
{
krb5_error_code code;
@@ -82,10 +107,15 @@ static krb5_error_code get_credentials(context, cred, server, now,
if ((code = krb5_copy_principal(context, server, &in_creds.server)))
goto cleanup;
in_creds.times.endtime = endtime;
- in_creds.keyblock.enctype = enctype;
- if ((code = krb5_get_credentials(context, 0, cred->ccache,
- &in_creds, out_creds)))
+ in_creds.keyblock.enctype = 0;
+
+ code = krb5_set_default_tgs_enctypes (context, enctypes);
+ if (code)
+ goto cleanup;
+ code = krb5_get_credentials(context, 0, cred->ccache,
+ &in_creds, out_creds);
+ if (code)
goto cleanup;
/*
@@ -93,7 +123,8 @@ static krb5_error_code get_credentials(context, cred, server, now,
* boundaries) because accept_sec_context code is also similarly
* non-forgiving.
*/
- if (!krb5_gss_dbg_client_expcreds && (*out_creds)->times.endtime < now) {
+ if (!krb5_gss_dbg_client_expcreds && *out_creds != NULL &&
+ (*out_creds)->times.endtime < now) {
code = KRB5KRB_AP_ERR_TKT_EXPIRED;
goto cleanup;
}
@@ -106,7 +137,7 @@ cleanup:
return code;
}
-
+#if !defined(TARGET_OS_MAC) || !TARGET_OS_MAC
static krb5_error_code
make_ap_req_v2(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
krb5_context context;
@@ -117,197 +148,10 @@ make_ap_req_v2(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
gss_OID mech_type;
gss_buffer_t token;
{
- krb5_flags mk_req_flags = 0;
- krb5_int32 con_flags;
- krb5_error_code code;
- 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;
-
- /* create the option data if necessary */
- if (ctx->gss_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, ctx->auth_context, &con_flags);
- krb5_auth_con_setflags(context, ctx->auth_context,
- con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME);
-
- code = krb5_fwd_tgt_creds(context, ctx->auth_context, 0,
- cred->princ, ctx->there, cred->ccache, 1,
- &credmsg);
-
- /* turn KRB5_AUTH_CONTEXT_DO_TIME back on */
- krb5_auth_con_setflags(context, ctx->auth_context, con_flags);
-
- if (code) {
- /* don't fail here; just don't accept/do the delegation
- request */
- ctx->gss_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;
- }
-
- /* construct the list of compatible cksum types */
-
- if ((code = krb5_c_keyed_checksum_types(context,
- k_cred->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] = (ctx->gss_flags >> 24) & 0xff;
- ptr[3] = (ctx->gss_flags >> 16) & 0xff;
- ptr[4] = (ctx->gss_flags >> 8) & 0xff;
- ptr[5] = ctx->gss_flags & 0xff;
-
- ptr[6] = (nctypes >> 8) & 0xff;
- ptr[7] = nctypes & 0xff;
-
- ptr += 8;
-
- for (i=0; i<nctypes; i++) {
- ptr[0] = (ctypes[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 (ctx->gss_flags & GSS_C_MUTUAL_FLAG)
- mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED;
-
- if ((code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags,
- &cksumdata, k_cred, &ap_req)))
- goto cleanup;
-
- /* store the interesting stuff from creds and authent */
- ctx->endtime = k_cred->times.endtime;
- ctx->krb_flags = k_cred->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 */
-
- ctx->nctypes = nctypes;
- ctx->ctypes = ctypes;
-
- token->length = tlen;
- token->value = (void *) t;
-
- code = 0;
-
-cleanup:
- if (code) {
- if (ctypes)
- krb5_free_cksumtypes(context, ctypes);
- }
-
- if (credmsg.data)
- free(credmsg.data);
- if (ap_req.data)
- free(ap_req.data);
- if (cksumdata.data)
- free(cksumdata.data);
-
- return(code);
+ int krb5_mech2_supported = 0;
+ assert(krb5_mech2_supported);
}
+#endif
static krb5_error_code
make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
@@ -480,15 +324,22 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
krb5_context context;
krb5_gss_cred_id_t cred;
krb5_creds *k_cred = 0;
- krb5_enctype enctype = ENCTYPE_DES_CBC_CRC;
+ static const krb5_enctype wanted_enctypes[] = {
+#if 1
+ ENCTYPE_DES3_CBC_SHA1,
+#endif
+ ENCTYPE_DES_CBC_CRC,
+ ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4,
+ };
+#define N_WANTED_ENCTYPES (sizeof(wanted_enctypes)/sizeof(wanted_enctypes[0]))
+ krb5_enctype requested_enctypes[N_WANTED_ENCTYPES + 1];
+ krb5_enctype *default_enctypes = 0;
krb5_error_code code;
krb5_gss_ctx_id_rec *ctx, *ctx_free;
krb5_timestamp now;
gss_buffer_desc token;
- int gsskrb5_vers = 0;
- int i, err;
+ int i, j, k, err;
int default_mech = 0;
- krb5_ui_4 resp_flags;
OM_uint32 major_status;
if (GSS_ERROR(kg_get_context(minor_status, &context)))
@@ -528,32 +379,19 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
err = 0;
if (mech_type == GSS_C_NULL_OID) {
default_mech = 1;
- 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;
- enctype = ENCTYPE_DES_CBC_CRC;
+ if (cred->rfc_mech) {
+ mech_type = (gss_OID) gss_mech_krb5;
} else if (cred->prerfc_mech) {
- mech_type = gss_mech_krb5_old;
- gsskrb5_vers = 1000;
- enctype = ENCTYPE_DES_CBC_CRC;
+ mech_type = (gss_OID) gss_mech_krb5_old;
} 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;
- gsskrb5_vers = 1000;
} else {
err = 1;
}
@@ -607,7 +445,6 @@ 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;
@@ -627,28 +464,57 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
&ctx->there)))
goto fail;
+ code = krb5_get_tgs_ktypes (context, 0, &default_enctypes);
+ if (code)
+ goto fail;
+ /* "i" denotes *next* slot to fill. Don't forget to save room
+ for a trailing zero. */
+ i = 0;
+ for (j = 0;
+ (default_enctypes[j] != 0
+ /* This part should be redundant, but let's be paranoid. */
+ && i < N_WANTED_ENCTYPES);
+ j++) {
+
+ int is_duplicate_enctype;
+ int is_wanted_enctype;
+
+ krb5_enctype e = default_enctypes[j];
+
+ /* Is this enctype one of the ones we want for GSSAPI? */
+ is_wanted_enctype = 0;
+ for (k = 0; k < N_WANTED_ENCTYPES; k++) {
+ if (wanted_enctypes[k] == e) {
+ is_wanted_enctype = 1;
+ break;
+ }
+ }
+ /* If unwanted, go to the next one. */
+ if (!is_wanted_enctype)
+ continue;
+
+ /* Is this enctype already in the list of enctypes to
+ request? (Is it a duplicate?) */
+ is_duplicate_enctype = 0;
+ for (k = 0; k < i; k++) {
+ if (requested_enctypes[k] == e) {
+ is_duplicate_enctype = 1;
+ break;
+ }
+ }
+ /* If it is not a duplicate, add it. */
+ if (!is_duplicate_enctype)
+ requested_enctypes[i++] = e;
+ }
+ requested_enctypes[i++] = 0;
+
if ((code = get_credentials(context, cred, ctx->there, now,
- ctx->endtime, enctype, &k_cred)))
+ ctx->endtime, requested_enctypes, &k_cred)))
goto fail;
- /*
- * If the default mechanism was requested, and the keytype is
- * DES_CBC, force the old mechanism
- */
- if (default_mech &&
- ((k_cred->keyblock.enctype == ENCTYPE_DES_CBC_CRC) ||
- (k_cred->keyblock.enctype == ENCTYPE_DES_CBC_MD4) ||
- (k_cred->keyblock.enctype == ENCTYPE_DES_CBC_MD5))) {
- ctx->gsskrb5_version = gsskrb5_vers = 1000;
- mech_type = gss_mech_krb5;
- if (k_cred->keyblock.enctype != ENCTYPE_DES_CBC_CRC) {
- krb5_free_creds(context, k_cred);
- enctype = ENCTYPE_DES_CBC_CRC;
- if ((code = get_credentials(context, cred, ctx->there, now,
- ctx->endtime, enctype, &k_cred)))
- goto fail;
- }
- }
+ if (default_mech) {
+ mech_type = (gss_OID) gss_mech_krb5;
+ }
if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used)
!= GSS_S_COMPLETE) {
@@ -660,24 +526,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
*/
ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
- if (ctx->gsskrb5_version == 2000) {
- /* gsskrb5 v2 */
- if ((code = make_ap_req_v2(context, ctx,
- cred, k_cred, input_chan_bindings,
- mech_type, &token))) {
- if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) ||
- (code == KG_EMPTY_CCACHE))
- major_status = GSS_S_NO_CRED;
- if (code == KRB5KRB_AP_ERR_TKT_EXPIRED)
- major_status = GSS_S_CREDENTIALS_EXPIRED;
- goto fail;
- }
-
- 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,
cred, k_cred, input_chan_bindings,
@@ -699,11 +548,41 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
switch(ctx->subkey->enctype) {
case ENCTYPE_DES_CBC_MD5:
+ case ENCTYPE_DES_CBC_MD4:
case ENCTYPE_DES_CBC_CRC:
ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
- ctx->signalg = 0;
+ ctx->signalg = SGN_ALG_DES_MAC_MD5;
ctx->cksum_size = 8;
- ctx->sealalg = 0;
+ ctx->sealalg = SEAL_ALG_DES;
+
+ /* The encryption key is the session key XOR
+ 0xf0f0f0f0f0f0f0f0. */
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
+ goto fail;
+
+ for (i=0; i<ctx->enc->length; i++)
+ /*SUPPRESS 113*/
+ ctx->enc->contents[i] ^= 0xf0;
+
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq)))
+ goto fail;
+
+ break;
+
+ case ENCTYPE_DES3_CBC_SHA1:
+ ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
+ ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
+ ctx->cksum_size = 20;
+ ctx->sealalg = SEAL_ALG_DES3KD;
+
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
+ if (code)
+ goto fail;
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
+ if (code) {
+ krb5_free_keyblock (context, ctx->enc);
+ goto fail;
+ }
break;
#if 0
case ENCTYPE_DES3_CBC_MD5:
@@ -714,20 +593,10 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
break;
#endif
default:
+ *minor_status = KRB5_BAD_ENCTYPE;
return GSS_S_FAILURE;
}
- /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */
-
- if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
- goto fail;
-
- for (i=0; i<ctx->enc->length; i++)
- /*SUPPRESS 113*/
- ctx->enc->contents[i] ^= 0xf0;
-
- if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq)))
- goto fail;
}
if (k_cred) {
@@ -780,7 +649,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
} else {
unsigned char *ptr;
char *sptr;
- krb5_data ap_rep, mic;
+ krb5_data ap_rep;
krb5_ap_rep_enc_part *ap_rep_data;
krb5_error *krb_error;
@@ -824,94 +693,38 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
ptr = (unsigned char *) input_token->value;
- if (ctx->gsskrb5_version == 2000) {
- int token_length;
- int nctypes;
- krb5_cksumtype *ctypes = 0;
-
- /* gsskrb5 v2 */
-
- if ((code = g_verify_token_header((gss_OID) ctx->mech_used,
- &token_length,
- &ptr, KG2_TOK_RESPONSE,
- input_token->length))) {
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
-
- if (GSS_ERROR(major_status =
- kg2_parse_token(minor_status, ptr, token_length,
- &resp_flags, &nctypes, &ctypes,
- 0, NULL, &ap_rep, &mic))) {
- if (ctypes)
- free(ctypes);
- code = *minor_status;
- goto fail;
- }
- major_status = GSS_S_FAILURE;
-
- kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes);
+ if ((err = g_verify_token_header((gss_OID) ctx->mech_used,
+ &(ap_rep.length),
+ &ptr, KG_TOK_CTX_AP_REP,
+ input_token->length))) {
+ if (g_verify_token_header((gss_OID) ctx->mech_used,
+ &(ap_rep.length),
+ &ptr, KG_TOK_CTX_ERROR,
+ input_token->length) == 0) {
- free(ctypes);
+ /* Handle a KRB_ERROR message from the server */
- 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)))
+ 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);
goto fail;
+ } else {
+ *minor_status = 0;
+ return(GSS_S_DEFECTIVE_TOKEN);
}
-
- 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) ctx->mech_used,
- &(ap_rep.length),
- &ptr, KG_TOK_CTX_AP_REP,
- input_token->length))) {
- if (g_verify_token_header((gss_OID) ctx->mech_used,
- &(ap_rep.length),
- &ptr, KG_TOK_CTX_ERROR,
- input_token->length) == 0) {
-
- /* Handle a KRB_ERROR message from the server */
-
- 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);
- goto fail;
- } else {
- *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,
&ap_rep_data))) {
@@ -938,26 +751,6 @@ 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))) {
- code = *minor_status;
- goto fail;
- }
- major_status = GSS_S_FAILURE;
- }
-
/* set returns */
if (time_rec) {
diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c
index c800012..6fbbadc 100644
--- a/src/lib/gssapi/krb5/inq_cred.c
+++ b/src/lib/gssapi/krb5/inq_cred.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -116,15 +140,11 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
&mechs)) ||
(cred->prerfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- gss_mech_krb5_old,
+ (gss_OID) 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,
+ (gss_OID) gss_mech_krb5,
&mechs)))) {
krb5_free_principal(context, ret_name);
/* *minor_status set above */
diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
index ae8cc75..1ca108e 100644
--- a/src/lib/gssapi/krb5/k5seal.c
+++ b/src/lib/gssapi/krb5/k5seal.c
@@ -1,6 +1,6 @@
/*
* Copyright 1993 by OpenVision Technologies, Inc.
- *
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
@@ -10,7 +10,7 @@
* without specific, written prior permission. OpenVision makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
- *
+ *
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -22,14 +22,14 @@
/*
* 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
@@ -40,7 +40,7 @@
* 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.
@@ -49,196 +49,280 @@
#include "gssapiP_krb5.h"
static krb5_error_code
-make_priv_token_v2 PROTOTYPE((krb5_context context,
- krb5_keyblock *subkey,
+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_priv_token_v2(context, subkey, seqnum, direction, text, token, oid)
- krb5_context context;
- 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;
+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;
+ gss_buffer_t token;
+ int signalg;
+ int cksum_size;
+ int sealalg;
+ int encrypt;
+ int toktype;
+ int bigend;
+ gss_OID oid;
{
krb5_error_code code;
- int tmp, tlen;
- unsigned char *t, *ptr;
- krb5_data plain;
+ size_t sumlen;
+ char *data_ptr;
+ krb5_data plaind;
+ krb5_checksum md5cksum;
krb5_checksum cksum;
+ int conflen=0, tmsglen, tlen;
+ unsigned char *t, *ptr;
- plain.data = 0;
- t = 0;
- cksum.contents = 0;
+ int encblksize, sumblksize;
+
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ case SGN_ALG_HMAC_MD5:
+ sumblksize = 1;
+ break;
+ case SGN_ALG_DES_MAC:
+ sumblksize = 8;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ sumblksize = 1;
+ break;
+ default:
+ abort ();
+ return 123; /* find error code */
+ }
- /* assemble the checksum buffer and compute the checksum */
+ switch (sealalg) {
+ case SEAL_ALG_NONE:
+ case SEAL_ALG_DES:
+ case SEAL_ALG_DES3KD:
+ encblksize = 8;
+ break;
+ default:
+ abort ();
+ return 12345654321;
+ }
- plain.length = 7+text->length;
+ /* create the token buffer */
- if ((plain.data = (char *) malloc(plain.length)) == NULL) {
- code = errno;
- goto cleanup;
+ if (toktype == KG_TOK_SEAL_MSG) {
+ if (bigend && !encrypt) {
+ tmsglen = text->length;
+ } else {
+ conflen = kg_confounder_size(context, enc);
+ /* XXX knows that des block size is 8 */
+ tmsglen = (conflen+text->length+8)&(~7);
+ }
+ } else {
+ tmsglen = 0;
}
- plain.data[0] = (*seqnum >> 24) & 0xff;
- plain.data[1] = (*seqnum >> 16) & 0xff;
- plain.data[2] = (*seqnum >> 8) & 0xff;
- plain.data[3] = *seqnum & 0xff;
+ tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen);
- plain.data[4] = direction?0:0xff;
+ if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
+ return(ENOMEM);
- plain.data[5] = (text->length >> 8) & 0xff;
- plain.data[6] = text->length & 0xff;
+ /*** fill in the token */
- memcpy(plain.data+7, text->value, text->length);
+ ptr = t;
- 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;
+ g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype);
- /* assemble the token itself */
+ /* 0..1 SIGN_ALG */
- if (toktype == KG2_TOK_WRAP_INTEG)
- tmp = 4+(7+text->length)+2+cksum.length;
- else
- tmp = 4+(5)+2+cksum.length;
+ ptr[0] = signalg & 0xff;
+ ptr[1] = (signalg >> 8) & 0xff;
- tlen = g_token_size((gss_OID) oid, tmp);
+ /* 2..3 SEAL_ALG or Filler */
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
- return(ENOMEM);
+ if ((toktype == KG_TOK_SEAL_MSG) && encrypt) {
+ ptr[2] = sealalg & 0xff;
+ ptr[3] = (sealalg >> 8) & 0xff;
+ } else {
+ /* No seal */
+ ptr[2] = 0xff;
+ ptr[3] = 0xff;
+ }
- ptr = t;
+ /* 4..5 Filler */
+
+ ptr[4] = 0xff;
+ ptr[5] = 0xff;
+
+ /* pad the plaintext, encrypt if needed, and stick it in the token */
+
+ /* initialize the the cksum */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ case SGN_ALG_HMAC_MD5:
+ md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3;
+ break;
+ default:
+ case SGN_ALG_DES_MAC:
+ abort ();
+ }
- g_make_token_header((gss_OID) oid, tmp, &ptr, toktype);
+ if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen))
+ return(code);
+ 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(t);
+ return(ENOMEM);
+ }
+
+ if ((code = kg_make_confounder(context, enc, plain))) {
+ xfree(plain);
+ xfree(t);
+ return(code);
+ }
+
+ memcpy(plain+conflen, text->value, text->length);
+
+ /* XXX 8 is DES cblock size */
+ pad = 8-(text->length%8);
+
+ memset(plain+conflen+text->length, pad, pad);
+ } else {
+ /* plain is never used in the bigend && !encrypt case */
+ plain = NULL;
+ }
+
+ if (encrypt) {
+ if ((code = kg_encrypt(context, enc, KG_USAGE_SEAL, NULL,
+ (krb5_pointer) plain,
+ (krb5_pointer) (ptr+cksum_size+14),
+ tmsglen))) {
+ if (plain)
+ xfree(plain);
+ xfree(t);
+ return(code);
+ }
+ } else {
+ if (bigend)
+ memcpy(ptr+14+cksum_size, text->value, text->length);
+ else
+ memcpy(ptr+14+cksum_size, plain, tmsglen);
+ }
+
+ /* compute the checksum */
+
+ /* 8 = head of token body as specified by mech spec */
+ if (! (data_ptr =
+ (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) {
+ if (plain)
+ xfree(plain);
+ xfree(t);
+ return(ENOMEM);
+ }
+ (void) memcpy(data_ptr, ptr-2, 8);
+ if (bigend)
+ (void) memcpy(data_ptr+8, text->value, text->length);
+ else
+ (void) memcpy(data_ptr+8, plain, tmsglen);
+ plaind.length = 8 + (bigend ? text->length : tmsglen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq,
+ KG_USAGE_SIGN, &plaind, &md5cksum);
+ xfree(data_ptr);
+
+ if (code) {
+ if (plain)
+ xfree(plain);
+ xfree(t);
+ return(code);
+ }
- ptr[0] = (ctype >> 24) & 0xff;
- ptr[1] = (ctype >> 16) & 0xff;
- ptr[2] = (ctype >> 8) & 0xff;
- ptr[3] = ctype & 0xff;
+ if (plain)
+ xfree(plain);
+ } else {
+ /* Sign only. */
+ /* compute the checksum */
- ptr += 4;
+ if (! (data_ptr = (char *) xmalloc(8 + text->length))) {
+ xfree(t);
+ return(ENOMEM);
+ }
+ (void) memcpy(data_ptr, ptr-2, 8);
+ (void) memcpy(data_ptr+8, text->value, text->length);
+ plaind.length = 8 + text->length;
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq,
+ KG_USAGE_SIGN, &plaind, &md5cksum);
+ xfree(data_ptr);
+ if (code) {
+ xfree(t);
+ return(code);
+ }
+ }
- 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;
+ switch(signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case 3:
+
+ if ((code = kg_encrypt(context, seq, KG_USAGE_SEAL,
+ (g_OID_equal(oid, gss_mech_krb5_old) ?
+ seq->contents : NULL),
+ md5cksum.contents, md5cksum.contents, 16))) {
+ xfree(md5cksum.contents);
+ xfree(t);
+ return code;
+ }
+
+ cksum.length = cksum_size;
+ cksum.contents = md5cksum.contents + 16 - cksum.length;
+
+ memcpy(ptr+14, cksum.contents, cksum.length);
+ break;
+
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ /*
+ * Using key derivation, the call to krb5_c_make_checksum
+ * already dealt with encrypting.
+ */
+ if (md5cksum.length != cksum_size)
+ abort ();
+ memcpy (ptr+14, md5cksum.contents, md5cksum.length);
+ break;
}
- ptr[0] = (cksum.length >> 8) & 0xff;
- ptr[1] = cksum.length & 0xff;
- ptr += 2;
+ xfree(md5cksum.contents);
+
+ /* create the seq_num */
- memcpy(ptr, cksum.contents, cksum.length);
+ if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum,
+ ptr+14, ptr+6))) {
+ xfree(t);
+ return(code);
+ }
/* that's it. return the token */
@@ -247,372 +331,110 @@ make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token,
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);
+ return(0);
}
-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));
+/* if signonly is true, ignore conf_req, conf_state,
+ and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */
-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;
- gss_buffer_t token;
- int signalg;
- int cksum_size;
- int sealalg;
- int encrypt;
- int toktype;
- int bigend;
- gss_OID oid;
+OM_uint32
+kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req,
+ input_message_buffer, conf_state, output_message_buffer, toktype)
+ krb5_context context;
+ OM_uint32 *minor_status;
+ gss_ctx_id_t context_handle;
+ int conf_req_flag;
+ int qop_req;
+ gss_buffer_t input_message_buffer;
+ int *conf_state;
+ gss_buffer_t output_message_buffer;
+ int toktype;
{
- krb5_error_code code;
- size_t sumlen;
- char *data_ptr;
- krb5_data plaind;
- krb5_checksum md5cksum;
- krb5_checksum cksum;
- int conflen=0, tmsglen, tlen;
- unsigned char *t, *ptr;
-
- /* create the token buffer */
-
- if (toktype == KG_TOK_SEAL_MSG) {
- if (bigend && !encrypt) {
- tmsglen = text->length;
- } else {
- conflen = kg_confounder_size(context, enc);
- /* XXX knows that des block size is 8 */
- tmsglen = (conflen+text->length+8)&(~7);
- }
- } else {
- tmsglen = 0;
- }
-
- tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen);
-
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
- return(ENOMEM);
-
- /*** fill in the token */
-
- ptr = t;
-
- g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype);
-
- /* 0..1 SIGN_ALG */
-
- ptr[0] = signalg;
- ptr[1] = 0;
-
- /* 2..3 SEAL_ALG or Filler */
-
- if ((toktype == KG_TOK_SEAL_MSG) && encrypt) {
- ptr[2] = sealalg;
- ptr[3] = 0;
- } else {
- /* No seal */
- ptr[2] = 0xff;
- ptr[3] = 0xff;
- }
-
- /* 4..5 Filler */
-
- ptr[4] = 0xff;
- ptr[5] = 0xff;
-
- /* pad the plaintext, encrypt if needed, and stick it in the token */
-
- /* 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 = sumlen;
- if (toktype == KG_TOK_SEAL_MSG) {
- unsigned char *plain;
- unsigned char pad;
-
- if (!bigend || encrypt) {
- if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
- xfree(t);
- return(ENOMEM);
- }
-
- if ((code = kg_make_confounder(context, enc, plain))) {
- xfree(plain);
- xfree(t);
- return(code);
- }
-
- memcpy(plain+conflen, text->value, text->length);
-
- /* XXX 8 is DES cblock size */
- pad = 8-(text->length%8);
-
- memset(plain+conflen+text->length, pad, pad);
- } else {
- /* plain is never used in the bigend && !encrypt case */
- plain = NULL;
- }
+ krb5_gss_ctx_id_rec *ctx;
+ krb5_error_code code;
+ krb5_timestamp now;
- if (encrypt) {
- if ((code = kg_encrypt(context, enc, NULL, (krb5_pointer) plain,
- (krb5_pointer) (ptr+cksum_size+14),
- tmsglen))) {
- if (plain)
- xfree(plain);
- xfree(t);
- return(code);
- }
- } else {
- if (bigend)
- memcpy(ptr+14+cksum_size, text->value, text->length);
- else
- memcpy(ptr+14+cksum_size, plain, tmsglen);
- }
-
- /* compute the checksum */
-
- /* 8 = head of token body as specified by mech spec */
- if (! (data_ptr =
- (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) {
- if (plain)
- xfree(plain);
- xfree(t);
- return(ENOMEM);
- }
- (void) memcpy(data_ptr, ptr-2, 8);
- if (bigend)
- (void) memcpy(data_ptr+8, text->value, text->length);
- else
- (void) memcpy(data_ptr+8, plain, tmsglen);
- 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(t);
- return(code);
- memcpy(ptr+14+cksum_size, plain, tmsglen);
- }
-
- if (plain)
- xfree(plain);
- } else {
- /* compute the checksum */
-
- if (! (data_ptr = (char *) xmalloc(8 + text->length))) {
- xfree(t);
- return(ENOMEM);
- }
- (void) memcpy(data_ptr, ptr-2, 8);
- (void) memcpy(data_ptr+8, text->value, text->length);
- 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(t);
- return(code);
- }
- }
-
- switch(signalg) {
- case 0:
- case 3:
+ output_message_buffer->length = 0;
+ output_message_buffer->value = NULL;
+ /* only default qop or matching established cryptosystem is allowed */
+
#if 0
- /* XXX this depends on the key being a single-des key */
-
- /* DES CBC doesn't use a zero IV like it should in some
- krb5 implementations (beta5+). So we just do the
- 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->contents,
- seq->length,
- &cksum)) {
- xfree(cksum.contents);
- xfree(md5cksum.contents);
- xfree(t);
- return(code);
- }
-
- memcpy(ptr+14, cksum.contents, 8);
-
- xfree(cksum.contents);
+ switch (qop_req & GSS_KRB5_CONF_C_QOP_MASK) {
+ case GSS_C_QOP_DEFAULT:
+ break;
+ default:
+ unknown_qop:
+ *minor_status = (OM_uint32) G_UNKNOWN_QOP;
+ return GSS_S_FAILURE;
+ case GSS_KRB5_CONF_C_QOP_DES:
+ if (ctx->sealalg != SEAL_ALG_DES) {
+ bad_qop:
+ *minor_status = (OM_uint32) G_BAD_QOP;
+ return GSS_S_FAILURE;
+ }
+ break;
+ case GSS_KRB5_CONF_C_QOP_DES3:
+ if (ctx->sealalg != SEAL_ALG_DES3)
+ goto bad_qop;
+ break;
+ }
+ switch (qop_req & GSS_KRB5_INTEG_C_QOP_MASK) {
+ case GSS_C_QOP_DEFAULT:
+ break;
+ default:
+ goto unknown_qop;
+ case GSS_KRB5_INTEG_C_QOP_MD5:
+ case GSS_KRB5_INTEG_C_QOP_DES_MD5:
+ case GSS_KRB5_INTEG_C_QOP_DES_MAC:
+ if (ctx->sealalg != SEAL_ALG_DES)
+ goto bad_qop;
+ break;
+ case GSS_KRB5_INTEG_C_QOP_HMAC_SHA1:
+ if (ctx->sealalg != SEAL_ALG_DES3KD)
+ goto bad_qop;
+ break;
+ }
#else
- if ((code = kg_encrypt(context, seq,
- (g_OID_equal(oid, gss_mech_krb5_old) ?
- seq->contents : NULL),
- md5cksum.contents, md5cksum.contents, 16))) {
- xfree(md5cksum.contents);
- xfree(t);
- return code;
- }
-
- cksum.length = cksum_size;
- cksum.contents = md5cksum.contents + 16 - cksum.length;
-
- memcpy(ptr+14, cksum.contents, cksum.length);
+ if (qop_req != 0) {
+ *minor_status = (OM_uint32) G_UNKNOWN_QOP;
+ return GSS_S_FAILURE;
+ }
#endif
- break;
- }
-
- xfree(md5cksum.contents);
-
- /* create the seq_num */
+ /* validate the context handle */
+ if (! kg_validate_ctx_id(context_handle)) {
+ *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+ return(GSS_S_NO_CONTEXT);
+ }
- if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum,
- ptr+14, ptr+6))) {
- xfree(t);
- return(code);
- }
+ ctx = (krb5_gss_ctx_id_rec *) context_handle;
- /* that's it. return the token */
+ if (! ctx->established) {
+ *minor_status = KG_CTX_INCOMPLETE;
+ return(GSS_S_NO_CONTEXT);
+ }
- (*seqnum)++;
+ if ((code = krb5_timeofday(context, &now))) {
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- token->length = tlen;
- token->value = (void *) t;
+ 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);
- return(0);
-}
+ if (code) {
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
-/* if signonly is true, ignore conf_req, conf_state,
- and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */
+ if (conf_state)
+ *conf_state = conf_req_flag;
-OM_uint32
-kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req,
- input_message_buffer, conf_state, output_message_buffer, toktype)
- krb5_context context;
- OM_uint32 *minor_status;
- gss_ctx_id_t context_handle;
- int conf_req_flag;
- int qop_req;
- gss_buffer_t input_message_buffer;
- int *conf_state;
- gss_buffer_t output_message_buffer;
- int toktype;
-{
- krb5_gss_ctx_id_rec *ctx;
- krb5_error_code code;
- krb5_timestamp now;
-
- output_message_buffer->length = 0;
- output_message_buffer->value = NULL;
-
- /* only default qop is allowed */
- if (qop_req != GSS_C_QOP_DEFAULT) {
- *minor_status = (OM_uint32) G_UNKNOWN_QOP;
- return(GSS_S_FAILURE);
- }
-
- /* 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);
- }
-
- if ((code = krb5_timeofday(context, &now))) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- 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 (conf_state)
- *conf_state = conf_req_flag;
-
- *minor_status = 0;
- return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
+ *minor_status = 0;
+ return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
}
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
index 64a9539..9e4d353 100644
--- a/src/lib/gssapi/krb5/k5unseal.c
+++ b/src/lib/gssapi/krb5/k5unseal.c
@@ -1,6 +1,6 @@
/*
* Copyright 1993 by OpenVision Technologies, Inc.
- *
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
@@ -10,7 +10,7 @@
* without specific, written prior permission. OpenVision makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
- *
+ *
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -22,14 +22,14 @@
/*
* 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
@@ -40,7 +40,7 @@
* 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.
@@ -53,834 +53,438 @@
* $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;
+/* 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_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
+ conf_state, qop_state, toktype)
+ krb5_context context;
+ OM_uint32 *minor_status;
+ krb5_gss_ctx_id_rec *ctx;
+ unsigned char *ptr;
+ int bodysize;
+ gss_buffer_t message_buffer;
+ int *conf_state;
+ int *qop_state;
+ int toktype;
{
- size_t cksumlen;
krb5_error_code code;
- krb5_data plain;
- krb5_cksumtype tctype;
- krb5_ui_4 tseqnum;
- int tdirection;
+ int tmsglen;
+ int conflen = 0;
+ int signalg;
+ int sealalg;
+ gss_buffer_desc token;
krb5_checksum cksum;
- krb5_boolean ckvalid;
+ krb5_checksum md5cksum;
+ krb5_data plaind;
+ char *data_ptr;
krb5_timestamp now;
+ unsigned char *plain;
+ int cksum_len = 0;
+ int plainlen;
+ int direction;
+ krb5_int32 seqnum;
OM_uint32 retval;
+ size_t sumlen;
- 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);
+ if (toktype == KG_TOK_SEAL_MSG) {
+ message_buffer->length = 0;
+ message_buffer->value = NULL;
}
- /* allocate the checksum buffer */
-
- plain.length = 7+text->length;
-
- if ((plain.data = (char *) malloc(plain.length)) == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
+ /* get the sign and seal algorithms */
- /* suck out the body parts from the token */
+ signalg = ptr[0] + (ptr[1]<<8);
+ sealalg = ptr[2] + (ptr[3]<<8);
- tctype = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) |
- (ptr[2]<<8) | ptr[3]);
- ptr += 4;
+ /* Sanity checks */
- 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);
+ if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
}
- cksum.contents = ptr;
- cksum.checksum_type = tctype;
+ if ((toktype != KG_TOK_SEAL_MSG) &&
+ (sealalg != 0xffff)) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
- /* finish assembling the checksum buffer and compute the checksum */
+ /* in the current spec, there is only one valid seal algorithm per
+ key type, so a simple comparison is ok */
- plain.data[5] = (text->length >> 8) & 0xff;
- plain.data[6] = text->length & 0xff;
+ if ((toktype == KG_TOK_SEAL_MSG) &&
+ !((sealalg == 0xffff) ||
+ (sealalg == ctx->sealalg))) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
- memcpy(plain.data+7, text->value, text->length);
+ /* there are several mappings of seal algorithms to sign algorithms,
+ but few enough that we can try them all. */
- 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 ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) ||
+ (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
+ (ctx->sealalg == SEAL_ALG_DES3KD &&
+ signalg != SGN_ALG_HMAC_SHA1_DES3_KD)) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
}
- if (!ckvalid) {
- free(plain.data);
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ cksum_len = 8;
+ break;
+ case SGN_ALG_3:
+ cksum_len = 16;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ cksum_len = 20;
+ break;
+ default:
*minor_status = 0;
- return(GSS_S_BAD_SIG);
+ return GSS_S_DEFECTIVE_TOKEN;
}
- /* check context expiry */
+ if (toktype == KG_TOK_SEAL_MSG)
+ tmsglen = bodysize-(14+cksum_len);
- if ((code = krb5_timeofday(context, &now))) {
- free(plain.data);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
+ /* get the token parameters */
- if (now > ctx->endtime) {
- free(plain.data);
- *minor_status = 0;
- return(GSS_S_CONTEXT_EXPIRED);
- }
+ /* decode the message, if SEAL */
- /* do sequencing checks */
+ if (toktype == KG_TOK_SEAL_MSG) {
+ if (sealalg != 0xffff) {
+ if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
- if ((ctx->initiate && tdirection != 0xff) ||
- (!ctx->initiate && tdirection != 0)) {
- free(plain.data);
- *minor_status = G_BAD_DIRECTION;
- return(GSS_S_BAD_SIG);
- }
+ if ((code = kg_decrypt(context, ctx->enc, KG_USAGE_SEAL, NULL,
+ ptr+14+cksum_len, plain, tmsglen))) {
+ xfree(plain);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
+ } else {
+ plain = ptr+14+cksum_len;
+ }
- retval = g_order_check(&(ctx->seqstate), tseqnum);
+ plainlen = tmsglen;
- free(plain.data);
+ if ((sealalg == 0xffff) && ctx->big_endian) {
+ token.length = tmsglen;
+ } else {
+ conflen = kg_confounder_size(context, ctx->enc);
+ token.length = tmsglen - conflen - plain[tmsglen-1];
+ }
- if (retval) {
- *minor_status = 0;
- return(retval);
- }
+ if (token.length) {
+ if ((token.value = (void *) xmalloc(token.length)) == NULL) {
+ if (sealalg != 0xffff)
+ xfree(plain);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
+ memcpy(token.value, plain+conflen, token.length);
+ }
+ } else if (toktype == KG_TOK_SIGN_MSG) {
+ token = *message_buffer;
+ plain = token.value;
+ plainlen = token.length;
+ } else {
+ token.length = 0;
+ token.value = NULL;
+ plain = token.value;
+ plainlen = token.length;
+ }
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
+ /* compute the checksum of the message */
+
+ /* initialize the the cksum */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ case SGN_ALG_HMAC_MD5:
+ case SGN_ALG_DES_MAC:
+ case SGN_ALG_3:
+ md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3;
+ break;
+ default:
+ abort ();
+ }
- *minor_status = 0;
- return(GSS_S_COMPLETE);
-}
+ if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen))
+ return(code);
+ md5cksum.length = sumlen;
-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;
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_3:
+ /* compute the checksum of the message */
- output->length = 0;
- output->value = NULL;
+ /* 8 = bytes of token body to be checksummed according to spec */
- /* read the body parts out of the message */
+ if (! (data_ptr = (void *)
+ xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) {
+ if (sealalg != 0xffff)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
- if (bodysize < 11) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ (void) memcpy(data_ptr, ptr-2, 8);
- tcksum.checksum_type = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) |
- (ptr[2]<<8) | ptr[3]);
- ptr += 4;
+ if (ctx->big_endian)
+ (void) memcpy(data_ptr+8, token.value, token.length);
+ else
+ (void) memcpy(data_ptr+8, plain, plainlen);
- plain.data = ptr;
+ plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+ xfree(data_ptr);
+
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
- ptr += 4;
- tdirection = ptr[0];
- ptr += 1;
+ if ((code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL,
+ (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
+ ctx->seq->contents : NULL),
+ md5cksum.contents, md5cksum.contents, 16))) {
+ xfree(md5cksum.contents);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return GSS_S_FAILURE;
+ }
- tmsglen = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 11;
+ if (signalg == 0)
+ cksum.length = 8;
+ else
+ cksum.length = 16;
+ cksum.contents = md5cksum.contents + 16 - cksum.length;
- if (bodysize < tmsglen) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ code = memcmp(cksum.contents, ptr+14, cksum.length);
+ break;
- tmsg = ptr;
- ptr += tmsglen;
- bodysize -= tmsglen;
+ case SGN_ALG_MD2_5:
+ if (!ctx->seed_init &&
+ (code = kg_make_seed(context, ctx->subkey, ctx->seed))) {
+ xfree(md5cksum.contents);
+ if (sealalg != 0xffff)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return GSS_S_FAILURE;
+ }
- plain.length = ((char*)ptr) - ((char *)plain.data);
+ if (! (data_ptr = (void *)
+ xmalloc(sizeof(ctx->seed) + 8 +
+ (ctx->big_endian ? token.length : plainlen)))) {
+ xfree(md5cksum.contents);
+ if (sealalg == 0)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
+ (void) memcpy(data_ptr, ptr-2, 8);
+ (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed));
+ if (ctx->big_endian)
+ (void) memcpy(data_ptr+8+sizeof(ctx->seed),
+ token.value, token.length);
+ else
+ (void) memcpy(data_ptr+8+sizeof(ctx->seed),
+ plain, plainlen);
+ 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,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+ xfree(data_ptr);
+
+ if (code) {
+ if (sealalg == 0)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- tcksum.length = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 2;
+ code = memcmp(md5cksum.contents, ptr+14, 8);
+ /* Falls through to defective-token?? */
- if (bodysize != tcksum.length) {
- *minor_status = G_TOK_TRUNC;
+ default:
+ *minor_status = 0;
return(GSS_S_DEFECTIVE_TOKEN);
- }
-
- tcksum.contents = ptr;
- /* verify the MIC */
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ /* compute the checksum of the message */
- 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);
- }
+ /* 8 = bytes of token body to be checksummed according to spec */
- if (!ckvalid) {
- *minor_status = 0;
- return(GSS_S_BAD_SIG);
- }
+ if (! (data_ptr = (void *)
+ xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) {
+ if (sealalg != 0xffff)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
- /* 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 (tmsglen) {
- 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);
-}
+ (void) memcpy(data_ptr, ptr-2, 8);
-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;
+ if (ctx->big_endian)
+ (void) memcpy(data_ptr+8, token.value, token.length);
+ else
+ (void) memcpy(data_ptr+8, plain, plainlen);
- output->length = 0;
- output->value = NULL;
+ plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+ xfree(data_ptr);
- /* read the body parts out of the message */
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- if (bodysize < 2) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
+ code = memcmp(md5cksum.contents, ptr+14, md5cksum.length);
+ break;
}
- cipher.ciphertext.length = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 2;
+ xfree(md5cksum.contents);
+ if (sealalg != 0xffff)
+ xfree(plain);
- if (bodysize != cipher.ciphertext.length) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ /* compare the computed checksum against the transmitted checksum */
- cipher.ciphertext.data = ptr;
- cipher.enctype = ENCTYPE_UNKNOWN;
-
- plain.length = cipher.ciphertext.length;
- if ((plain.data = (char *) malloc(plain.length)) == NULL) {
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
*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);
+ return(GSS_S_BAD_SIG);
}
- /* parse out the encrypted fields */
- ptr = plain.data;
- bodysize = plain.length;
+ /* it got through unscathed. Make sure the context is unexpired */
- if (bodysize < 7) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ if (toktype == KG_TOK_SEAL_MSG)
+ *message_buffer = token;
- tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
- ptr += 4;
- tdirection = ptr[0];
- ptr += 1;
+ if (conf_state)
+ *conf_state = (sealalg != 0xffff);
- tmsglen = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 7;
-
- /* check context expiry */
+ if (qop_state)
+ *qop_state = GSS_C_QOP_DEFAULT;
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;
+ if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction,
+ &seqnum))) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
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 (tmsglen) {
- 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 ((ctx->initiate && direction != 0xff) ||
+ (!ctx->initiate && direction != 0)) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = G_BAD_DIRECTION;
+ return(GSS_S_BAD_SIG);
}
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
+ retval = g_order_check(&(ctx->seqstate), seqnum);
- free(plain.data);
+ /* success or ordering violation */
*minor_status = 0;
- return(GSS_S_COMPLETE);
+ 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_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
- conf_state, qop_state, toktype)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t message_buffer;
- int *conf_state;
- int *qop_state;
- int toktype;
+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_error_code code;
- int tmsglen;
- int conflen = 0;
- int signalg;
- int sealalg;
- gss_buffer_desc token;
- krb5_checksum cksum;
- krb5_checksum desmac;
- krb5_checksum md5cksum;
- krb5_data plaind;
- char *data_ptr;
- krb5_timestamp now;
- unsigned char *plain;
- int cksum_len = 0;
- int plainlen;
- int err;
- 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;
- }
-
- /* get the sign and seal algorithms */
-
- signalg = ptr[0] + (ptr[1]<<8);
- sealalg = ptr[2] + (ptr[3]<<8);
-
- /* Sanity checks */
-
- if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- if ((toktype != KG_TOK_SEAL_MSG) &&
- (sealalg != 0xffff)) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- /* in the current spec, there is only one valid seal algorithm per
- key type, so a simple comparison is ok */
-
- if ((toktype == KG_TOK_SEAL_MSG) &&
- !((sealalg == 0xffff) ||
- (sealalg == ctx->sealalg))) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- /* there are several mappings of seal algorithms to sign algorithms,
- but few enough that we can try them all. */
-
- if (((ctx->sealalg == 0) &&
- (signalg > 1)) ||
- ((ctx->sealalg == 1) &&
- (signalg != 3))) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- switch (signalg) {
- case 0:
- case 1:
- cksum_len = 8;
- break;
- case 3:
- cksum_len = 16;
- break;
- }
-
- if (toktype == KG_TOK_SEAL_MSG)
- tmsglen = bodysize-(14+cksum_len);
-
- /* get the token parameters */
-
- /* decode the message, if SEAL */
-
- if (toktype == KG_TOK_SEAL_MSG) {
- if (sealalg != 0xffff) {
- if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
+ krb5_gss_ctx_id_rec *ctx;
+ unsigned char *ptr;
+ int bodysize;
+ int err;
+
+ /* validate the context handle */
+ if (! kg_validate_ctx_id(context_handle)) {
+ *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+ return(GSS_S_NO_CONTEXT);
+ }
- if ((code = kg_decrypt(context, ctx->enc, NULL,
- ptr+14+cksum_len, plain, tmsglen))) {
- xfree(plain);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
- } else {
- plain = ptr+14+cksum_len;
- }
-
- plainlen = tmsglen;
-
- if ((sealalg == 0xffff) && ctx->big_endian) {
- token.length = tmsglen;
- } else {
- conflen = kg_confounder_size(context, ctx->enc);
- token.length = tmsglen - conflen - plain[tmsglen-1];
- }
-
- if (token.length) {
- if ((token.value = (void *) xmalloc(token.length)) == NULL) {
- if (sealalg != 0xffff)
- xfree(plain);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- memcpy(token.value, plain+conflen, token.length);
- }
- } else if (toktype == KG_TOK_SIGN_MSG) {
- token = *message_buffer;
- plain = token.value;
- plainlen = token.length;
- } else {
- token.length = 0;
- token.value = NULL;
- plain = token.value;
- plainlen = token.length;
- }
-
- /* compute the checksum of the message */
-
- /* 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 = sumlen;
-
- switch (signalg) {
- case 0:
- case 3:
- /* compute the checksum of the message */
-
- /* 8 = bytes of token body to be checksummed according to spec */
-
- if (! (data_ptr = (void *)
- xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) {
- if (sealalg != 0xffff)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
-
- (void) memcpy(data_ptr, ptr-2, 8);
-
- if (ctx->big_endian)
- (void) memcpy(data_ptr+8, token.value, token.length);
- else
- (void) memcpy(data_ptr+8, plain, plainlen);
-
- 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) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
-#if 0
- /* XXX this depends on the key being a single-des key, but that's
- all that kerberos supports right now */
-
- /* 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) {
- xfree(md5cksum.contents);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = ENOMEM;
- 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,
- ctx->seq.key->length,
- &cksum)) {
- xfree(cksum.contents);
- xfree(md5cksum.contents);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- code = memcmp(cksum.contents, ptr+14, cksum.length);
-
- xfree(cksum.contents);
-#else
- if ((code = kg_encrypt(context, ctx->seq,
- (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
- ctx->seq->contents : NULL),
- md5cksum.contents, md5cksum.contents, 16))) {
- xfree(md5cksum.contents);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return GSS_S_FAILURE;
- }
-
- if (signalg == 0)
- cksum.length = 8;
- else
- cksum.length = 16;
- cksum.contents = md5cksum.contents + 16 - cksum.length;
-
- code = memcmp(cksum.contents, ptr+14, cksum.length);
-#endif
- break;
-
- case 1:
- if (!ctx->seed_init &&
- (code = kg_make_seed(context, ctx->subkey, ctx->seed))) {
- xfree(md5cksum.contents);
- if (sealalg != 0xffff)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return GSS_S_FAILURE;
- }
-
- if (! (data_ptr = (void *)
- xmalloc(sizeof(ctx->seed) + 8 +
- (ctx->big_endian ? token.length : plainlen)))) {
- xfree(md5cksum.contents);
- if (sealalg == 0)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- (void) memcpy(data_ptr, ptr-2, 8);
- (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed));
- if (ctx->big_endian)
- (void) memcpy(data_ptr+8+sizeof(ctx->seed),
- token.value, token.length);
- else
- (void) memcpy(data_ptr+8+sizeof(ctx->seed),
- plain, plainlen);
- 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) {
- if (sealalg == 0)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- code = memcmp(md5cksum.contents, ptr+14, 8);
-
- default:
- *minor_status = 0;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
-
- xfree(md5cksum.contents);
- if (sealalg != 0xffff)
- xfree(plain);
-
- /* compare the computed checksum against the transmitted checksum */
-
- if (code) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = 0;
- return(GSS_S_BAD_SIG);
- }
-
-
- /* it got through unscathed. Make sure the context is unexpired */
-
- if (toktype == KG_TOK_SEAL_MSG)
- *message_buffer = token;
-
- if (conf_state)
- *conf_state = (sealalg != 0xffff);
-
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
-
- 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 ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction,
- &seqnum))) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_BAD_SIG);
- }
-
- if ((ctx->initiate && direction != 0xff) ||
- (!ctx->initiate && direction != 0)) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = G_BAD_DIRECTION;
- return(GSS_S_BAD_SIG);
- }
-
- retval = g_order_check(&(ctx->seqstate), seqnum);
-
- /* success or ordering violation */
-
- *minor_status = 0;
- return(retval);
-}
+ ctx = (krb5_gss_ctx_id_rec *) context_handle;
-/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
- conf_state is only valid if SEAL. */
+ if (! ctx->established) {
+ *minor_status = KG_CTX_INCOMPLETE;
+ return(GSS_S_NO_CONTEXT);
+ }
-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);
+ /* 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))) {
+ 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/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c
index 2a6231e..781e8ee 100644
--- a/src/lib/gssapi/krb5/ser_sctx.c
+++ b/src/lib/gssapi/krb5/ser_sctx.c
@@ -155,7 +155,6 @@ kg_queue_internalize(kcontext, argp, buffer, lenremain)
size_t *lenremain;
{
krb5_error_code kret;
- gss_OID oid;
krb5_int32 ibuf;
krb5_octet *bp;
size_t remain;
@@ -233,7 +232,6 @@ 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.
*/
@@ -349,8 +347,6 @@ 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);
@@ -477,8 +473,6 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
(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,
diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c
index 10e6b65..47ffc5b 100644
--- a/src/lib/gssapi/krb5/util_cksum.c
+++ b/src/lib/gssapi/krb5/util_cksum.c
@@ -27,6 +27,7 @@
#include "gssapiP_krb5.h"
#include <memory.h>
+/* Checksumming the channel bindings always uses plain MD5. */
krb5_error_code
kg_checksum_channel_bindings(context, cb, cksum, bigend)
krb5_context context;
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c
index 93d4694..33562bc 100644
--- a/src/lib/gssapi/krb5/util_crypt.c
+++ b/src/lib/gssapi/krb5/util_crypt.c
@@ -54,8 +54,6 @@
* $Id$
*/
-static unsigned char zeros[8] = {0,0,0,0,0,0,0,0};
-
int
kg_confounder_size(context, key)
krb5_context context;
@@ -105,9 +103,10 @@ kg_encrypt_size(context, key, n)
}
krb5_error_code
-kg_encrypt(context, key, iv, in, out, length)
+kg_encrypt(context, key, usage, iv, in, out, length)
krb5_context context;
krb5_keyblock *key;
+ int usage;
krb5_pointer iv;
krb5_pointer in;
krb5_pointer out;
@@ -123,7 +122,10 @@ kg_encrypt(context, key, iv, in, out, length)
return(code);
ivd.length = blocksize;
- ivd.data = iv;
+ ivd.data = malloc(ivd.length);
+ if (ivd.data == NULL)
+ return ENOMEM;
+ memcpy(ivd.data, iv, ivd.length);
pivd = &ivd;
} else {
pivd = NULL;
@@ -135,25 +137,26 @@ kg_encrypt(context, key, iv, in, out, length)
outputd.ciphertext.length = length;
outputd.ciphertext.data = out;
- 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));
+ code = krb5_c_encrypt(context, key, usage, pivd, &inputd, &outputd);
+ if (pivd != NULL)
+ krb5_free_data_contents(context, pivd);
+ return code;
}
/* length is the length of the cleartext. */
krb5_error_code
-kg_decrypt(context, key, iv, in, out, length)
+kg_decrypt(context, key, usage, iv, in, out, length)
krb5_context context;
krb5_keyblock *key;
+ int usage;
krb5_pointer iv;
krb5_pointer in;
krb5_pointer out;
int length;
{
krb5_error_code code;
- size_t blocksize, enclen;
+ size_t blocksize;
krb5_data ivd, *pivd, outputd;
krb5_enc_data inputd;
@@ -162,7 +165,10 @@ kg_decrypt(context, key, iv, in, out, length)
return(code);
ivd.length = blocksize;
- ivd.data = iv;
+ ivd.data = malloc(ivd.length);
+ if (ivd.data == NULL)
+ return ENOMEM;
+ memcpy(ivd.data, iv, ivd.length);
pivd = &ivd;
} else {
pivd = NULL;
@@ -175,8 +181,8 @@ kg_decrypt(context, key, iv, in, out, length)
outputd.length = length;
outputd.data = out;
- 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));
+ code = krb5_c_decrypt(context, key, usage, pivd, &inputd, &outputd);
+ if (pivd != NULL)
+ krb5_free_data_contents(context, pivd);
+ return code;
}
diff --git a/src/lib/gssapi/krb5/util_seed.c b/src/lib/gssapi/krb5/util_seed.c
index 206ee68..b4a9044 100644
--- a/src/lib/gssapi/krb5/util_seed.c
+++ b/src/lib/gssapi/krb5/util_seed.c
@@ -47,7 +47,7 @@ kg_make_seed(context, key, seed)
for (i=0; i<tmpkey->length; i++)
tmpkey->contents[i] = key->contents[key->length - 1 - i];
- code = kg_encrypt(context, tmpkey, NULL, zeros, seed, 16);
+ code = kg_encrypt(context, tmpkey, KG_USAGE_SEAL, NULL, zeros, seed, 16);
krb5_free_keyblock(context, tmpkey);
diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c
index e14b2f3..b8f2b38 100644
--- a/src/lib/gssapi/krb5/util_seqnum.c
+++ b/src/lib/gssapi/krb5/util_seqnum.c
@@ -47,7 +47,7 @@ kg_make_seq_num(context, key, direction, seqnum, cksum, buf)
plain[6] = direction;
plain[7] = direction;
- return(kg_encrypt(context, key, cksum, plain, buf, 8));
+ return(kg_encrypt(context, key, KG_USAGE_SEQ, cksum, plain, buf, 8));
}
krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum)
@@ -61,7 +61,7 @@ krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum)
krb5_error_code code;
unsigned char plain[8];
- if (code = kg_decrypt(context, key, cksum, buf, plain, 8))
+ if (code = kg_decrypt(context, key, KG_USAGE_SEQ, 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 f7fee73..1f2db4a 100644
--- a/src/lib/gssapi/krb5/wrap_size_limit.c
+++ b/src/lib/gssapi/krb5/wrap_size_limit.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -65,7 +89,9 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
{
krb5_context context;
krb5_gss_ctx_id_rec *ctx;
- krb5_error_code code;
+ OM_uint32 data_size, conflen;
+ OM_uint32 ohlen;
+ int overhead;
if (GSS_ERROR(kg_get_context(minor_status, &context)))
return(GSS_S_FAILURE);
@@ -88,92 +114,23 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
return(GSS_S_NO_CONTEXT);
}
- 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);
- }
-
- 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 data_size, conflen;
- OM_uint32 ohlen;
- int overhead;
-
- /* Calculate the token size and subtract that from the output size */
- overhead = 7 + ctx->mech_used->length;
- data_size = req_output_size;
- if (conf_req_flag) {
- conflen = kg_confounder_size(context, ctx->enc);
- data_size = (conflen + data_size + 8) & (~7);
- }
- ohlen = g_token_size((gss_OID) ctx->mech_used,
- (unsigned int) (data_size + ctx->cksum_size + 14))
- - req_output_size;
-
- if (ohlen+overhead < req_output_size)
- /*
- * Cannot have trailer length that will cause us to pad over
- * our length
- */
- *max_input_size = (req_output_size - ohlen - overhead) & (~7);
- else
- *max_input_size = 0;
- }
+ /* Calculate the token size and subtract that from the output size */
+ overhead = 7 + ctx->mech_used->length;
+ data_size = req_output_size;
+ conflen = kg_confounder_size(context, ctx->enc);
+ data_size = (conflen + data_size + 8) & (~(OM_uint32)7);
+ ohlen = g_token_size((gss_OID) ctx->mech_used,
+ (unsigned int) (data_size + ctx->cksum_size + 14))
+ - req_output_size;
+
+ if (ohlen+overhead < req_output_size)
+ /*
+ * Cannot have trailer length that will cause us to pad over our
+ * length.
+ */
+ *max_input_size = (req_output_size - ohlen - overhead) & (~(OM_uint32)7);
+ else
+ *max_input_size = 0;
*minor_status = 0;
return(GSS_S_COMPLETE);
diff --git a/src/lib/gssapi32.def b/src/lib/gssapi32.def
index 5132ea4..3a43be2 100644
--- a/src/lib/gssapi32.def
+++ b/src/lib/gssapi32.def
@@ -72,7 +72,7 @@ EXPORTS
;
; GSS-API variables
;
- gss_nt_user_name
- gss_nt_machine_uid_name
- gss_nt_string_uid_name
- gss_nt_service_name
+ gss_nt_user_name DATA
+ gss_nt_machine_uid_name DATA
+ gss_nt_string_uid_name DATA
+ gss_nt_service_name DATA
diff --git a/src/lib/kadm5/ChangeLog b/src/lib/kadm5/ChangeLog
index 8706ec0..54e1bc5 100644
--- a/src/lib/kadm5/ChangeLog
+++ b/src/lib/kadm5/ChangeLog
@@ -1,3 +1,56 @@
+2002-02-05 Ken Raeburn <raeburn@mit.edu>
+
+ * kadm_rpc_xdr.c (xdr_krb5_kvno): Disable previous change.
+
+2002-01-25 Ken Raeburn <raeburn@mit.edu>
+
+ * kadm_rpc_xdr.c (xdr_krb5_kvno): Return an error if the key
+ version number won't fit in the one-byte encoding we currently
+ use.
+
+2001-10-31 Ezra Peisach <epeisach@mit.edu>
+
+ * str_conv.c (krb5_string_to_keysalts): When parsing string, allow
+ for extra separator characters (like spaces) between keysalts.
+ [pullup 1.7->1.8 from trunk]
+
+2001-09-25 Ken Raeburn <raeburn@mit.edu>
+
+ * admin.h (krb5_realm_params): Add fields realm_reject_bad_transit
+ and realm_reject_bad_transit_valid; delete field realm_filler.
+ * alt_prof.c (string_to_boolean, krb5_aprof_get_boolean): New
+ functions.
+ (krb5_read_realm_params): Parse "reject_bad_transit" value as
+ boolean and save it.
+
+2001-09-07 Tom Yu <tlyu@mit.edu>
+
+ * adb.h: Add btinfo. [pullup from trunk]
+
+2000-05-31 Ken Raeburn <raeburn@mit.edu>
+
+ * alt_prof.c (kadm5_get_config_params): Include des3 in supported
+ enctypes by default.
+
+2000-05-19 Ken Raeburn <raeburn@mit.edu>
+
+ * ovsec_glue.c (ovsec_kadm_chpass_principal_util): Use 1024 for
+ hard-coded length, to match existing callers.
+
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * admin.h: Add a length parameter to kadm5_chpass_principal_util().
+ * admin_internal.h: Add a length parameter to
+ _kadm5_chpass_principal_util().
+ * chpass_util.c (_kadm5_chpass_principal_util): Add a length parameter,
+ and use it to avoid overflowing "msg_ret".
+ * ovsec_glue.c (ovsec_kadm_chpass_principal_util): Adjust for new
+ parameter in kadm5_chpass_principal_util().
+
+2000-05-01 Nalin Dahyabhai <nalin@redhat.com>
+
+ * logger.c (klog_com_err_proc): Don't overflow buffer "outbuf".
+
2000-02-26 Tom Yu <tlyu@mit.edu>
* kadm_rpc_xdr.c (xdr_cprinc3_arg): Don't XDR the nonexistent
diff --git a/src/lib/kadm5/adb.h b/src/lib/kadm5/adb.h
index ce0d600..81ff96c 100644
--- a/src/lib/kadm5/adb.h
+++ b/src/lib/kadm5/adb.h
@@ -44,6 +44,7 @@ typedef struct _osa_adb_db_ent_t {
int magic;
DB *db;
HASHINFO info;
+ BTREEINFO btinfo;
char *filename;
osa_adb_lock_t lock;
} osa_adb_db_ent, *osa_adb_db_t, *osa_adb_princ_t, *osa_adb_policy_t;
diff --git a/src/lib/kadm5/admin.h b/src/lib/kadm5/admin.h
index 159c7fb..6e06636 100644
--- a/src/lib/kadm5/admin.h
+++ b/src/lib/kadm5/admin.h
@@ -1,4 +1,30 @@
/*
+ * lib/kadm5/admin.h
+ *
+ * Copyright 2001 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ */
+/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
* $Header$
@@ -234,13 +260,14 @@ typedef struct __krb5_realm_params {
krb5_timestamp realm_expiration;
krb5_flags realm_flags;
krb5_key_salt_tuple *realm_keysalts;
+ unsigned int realm_reject_bad_transit:1;
unsigned int realm_kadmind_port_valid:1;
unsigned int realm_enctype_valid:1;
unsigned int realm_max_life_valid:1;
unsigned int realm_max_rlife_valid:1;
unsigned int realm_expiration_valid:1;
unsigned int realm_flags_valid:1;
- unsigned int realm_filler:7;
+ unsigned int realm_reject_bad_transit_valid:1;
krb5_int32 realm_num_keysalts;
} krb5_realm_params;
@@ -411,7 +438,8 @@ kadm5_ret_t kadm5_chpass_principal_util(void *server_handle,
krb5_principal princ,
char *new_pw,
char **ret_pw,
- char *msg_ret);
+ char *msg_ret,
+ int msg_len);
kadm5_ret_t kadm5_free_principal_ent(void *server_handle,
kadm5_principal_ent_t
diff --git a/src/lib/kadm5/admin_internal.h b/src/lib/kadm5/admin_internal.h
index d2d1533..97cb5e5 100644
--- a/src/lib/kadm5/admin_internal.h
+++ b/src/lib/kadm5/admin_internal.h
@@ -62,7 +62,8 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
krb5_principal princ,
char *new_pw,
char **ret_pw,
- char *msg_ret);
+ char *msg_ret,
+ int msg_len);
/* this is needed by the alt_prof code I stole. The functions
maybe shouldn't be named krb5_*, but they are. */
diff --git a/src/lib/kadm5/alt_prof.c b/src/lib/kadm5/alt_prof.c
index 5582df0..50f0b6a 100644
--- a/src/lib/kadm5/alt_prof.c
+++ b/src/lib/kadm5/alt_prof.c
@@ -1,7 +1,7 @@
/*
* lib/kadm/alt_prof.c
*
- * Copyright 1995 by the Massachusetts Institute of Technology.
+ * Copyright 1995,2001 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -117,6 +117,64 @@ krb5_aprof_getvals(acontext, hierarchy, retdata)
}
/*
+ * krb5_aprof_get_boolean()
+ *
+ * Parameters:
+ * acontext - opaque context for alternate profile
+ * hierarchy - hierarchy of value to retrieve
+ * retdata - Returned data value
+ * Returns:
+ * error codes
+ */
+
+static krb5_error_code
+string_to_boolean (const char *string, krb5_boolean *out)
+{
+ static const char *const yes[] = { "y", "yes", "true", "t", "1", "on" };
+ static const char *const no[] = { "n", "no", "false", "f", "nil", "0", "off" };
+ int i;
+
+ for (i = 0; i < sizeof(yes)/sizeof(yes[0]); i++)
+ if (!strcasecmp(string, yes[i])) {
+ *out = 1;
+ return 0;
+ }
+ for (i = 0; i < sizeof(no)/sizeof(no[0]); i++)
+ if (!strcasecmp(string, no[i])) {
+ *out = 0;
+ return 0;
+ }
+ return PROF_BAD_BOOLEAN;
+}
+
+krb5_error_code
+krb5_aprof_get_boolean(krb5_pointer acontext, const char **hierarchy,
+ int uselast, int *retdata)
+{
+ krb5_error_code kret;
+ char **values;
+ char *valp;
+ int idx;
+ krb5_boolean val;
+
+ kret = krb5_aprof_getvals (acontext, hierarchy, &values);
+ if (kret)
+ return kret;
+ idx = 0;
+ if (uselast) {
+ while (values[idx])
+ idx++;
+ idx--;
+ }
+ valp = values[idx];
+ kret = string_to_boolean (valp, &val);
+ if (kret)
+ return kret;
+ *retdata = val;
+ return 0;
+}
+
+/*
* krb5_aprof_get_deltat() - Get a delta time value from the alternate
* profile.
*
@@ -644,8 +702,8 @@ krb5_error_code kadm5_get_config_params(context, kdcprofile, kdcenv,
if (aprofile)
krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue);
if (svalue == NULL)
- svalue = strdup("des-cbc-crc:normal");
-
+ svalue = strdup("des3-hmac-sha1:normal des-cbc-crc:normal");
+
params.keysalts = NULL;
params.num_keysalts = 0;
krb5_string_to_keysalts(svalue,
@@ -736,6 +794,7 @@ krb5_read_realm_params(kcontext, realm, kdcprofile, kdcenv, rparamp)
const char *hierarchy[4];
char *svalue;
krb5_int32 ivalue;
+ krb5_boolean bvalue;
krb5_deltat dtvalue;
krb5_error_code kret;
@@ -832,7 +891,13 @@ krb5_read_realm_params(kcontext, realm, kdcprofile, kdcenv, rparamp)
rparams->realm_expiration_valid = 1;
krb5_xfree(svalue);
}
-
+
+ hierarchy[2] = "reject_bad_transit";
+ if (!krb5_aprof_get_boolean(aprofile, hierarchy, TRUE, &bvalue)) {
+ rparams->realm_reject_bad_transit = bvalue;
+ rparams->realm_reject_bad_transit_valid = 1;
+ }
+
/* Get the value for the default principal flags */
hierarchy[2] = "default_principal_flags";
if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
diff --git a/src/lib/kadm5/chpass_util.c b/src/lib/kadm5/chpass_util.c
index dbf610c..ec97a0e 100644
--- a/src/lib/kadm5/chpass_util.c
+++ b/src/lib/kadm5/chpass_util.c
@@ -61,7 +61,8 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
krb5_principal princ,
char *new_pw,
char **ret_pw,
- char *msg_ret)
+ char *msg_ret,
+ int msg_len)
{
int code, code2, pwsize;
static char buffer[255];
@@ -94,12 +95,18 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
memset(buffer, 0, sizeof(buffer));
#endif
if (code == KRB5_LIBOS_BADPWDMATCH) {
- strcpy(msg_ret, string_text(CHPASS_UTIL_NEW_PASSWORD_MISMATCH));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_NEW_PASSWORD_MISMATCH),
+ msg_len - 1);
+ msg_ret[msg_len - 1] = '\0';
return(code);
} else {
- sprintf(msg_ret, "%s %s\n%s\n", error_message(code),
- string_text(CHPASS_UTIL_WHILE_READING_PASSWORD),
- string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
+ strncpy(msg_ret, error_message(code), msg_len - 1);
+ strncat(msg_ret, " ", msg_len - 1);
+ strncat(msg_ret, string_text(CHPASS_UTIL_WHILE_READING_PASSWORD),
+ msg_len - 1);
+ strncat(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
+ msg_len - 1);
+ msg_ret[msg_len - 1] = '\0';
return(code);
}
}
@@ -107,7 +114,8 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
#ifdef ZEROPASSWD
memset(buffer, 0, sizeof(buffer));
#endif
- strcpy(msg_ret, string_text(CHPASS_UTIL_NO_PASSWORD_READ));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_NO_PASSWORD_READ), msg_len - 1);
+ msg_ret[msg_len - 1] = '\0';
return(KRB5_LIBOS_CANTREADPWD); /* could do better */
}
}
@@ -123,7 +131,8 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
#endif
if (code == KADM5_OK) {
- strcpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_CHANGED));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_CHANGED), msg_len - 1);
+ msg_ret[msg_len - 1] = '\0';
return(0);
}
@@ -141,12 +150,15 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
/* Ok, we have a password quality error. Return a good message */
if (code == KADM5_PASS_REUSE) {
- strcpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_REUSE));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_REUSE), msg_len - 1);
+ msg_ret[msg_len - 1] = '\0';
return(code);
}
if (code == KADM5_PASS_Q_DICT) {
- strcpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_IN_DICTIONARY));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_IN_DICTIONARY),
+ msg_len - 1);
+ msg_ret[msg_len - 1] = '\0';
return(code);
}
@@ -155,18 +167,32 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
code2 = kadm5_get_principal (lhandle, princ, &princ_ent,
KADM5_PRINCIPAL_NORMAL_MASK);
if (code2 != 0) {
- sprintf(msg_ret, "%s %s\n%s %s\n\n%s\n ", error_message(code2),
- string_text(CHPASS_UTIL_GET_PRINC_INFO),
- error_message(code),
- string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE),
- string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
+ strncpy(msg_ret, error_message(code2), msg_len - 1);
+ strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, string_text(CHPASS_UTIL_GET_PRINC_INFO), msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, "\n", msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, error_message(code), msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE),
+ msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, "\n\n", msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
+ msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, "\n", msg_len - 1 - strlen(msg_ret));
+ msg_ret[msg_len - 1] = '\0';
return(code);
}
if ((princ_ent.aux_attributes & KADM5_POLICY) == 0) {
- sprintf(msg_ret, "%s %s\n\n%s", error_message(code),
- string_text(CHPASS_UTIL_NO_POLICY_YET_Q_ERROR),
- string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
+ strncpy(msg_ret, error_message(code), msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_NO_POLICY_YET_Q_ERROR),
+ msg_len - 1 - strlen(msg_ret));
+ strncat(msg_ret, "\n\n", msg_len - 1 - strlen(msg_ret));
+ strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
+ msg_len - 1 - strlen(msg_ret));
+ msg_ret[msg_len - 1] = '\0';
+
(void) kadm5_free_principal_ent(lhandle, &princ_ent);
return(code);
}
diff --git a/src/lib/kadm5/clnt/ChangeLog b/src/lib/kadm5/clnt/ChangeLog
index 79dc124..ac8850a 100644
--- a/src/lib/kadm5/clnt/ChangeLog
+++ b/src/lib/kadm5/clnt/ChangeLog
@@ -1,3 +1,23 @@
+2001-11-05 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in (LIBMAJOR): Bump to avoid Heimdal conflict.
+
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * clnt_chpass_util.c (kadm5_chpass_principal_util): Adjust for new
+ length parameter in both kadm5_chpass_principal_util() and in
+ _kadm5_chpass_principal_util().
+
+2000-05-09 Ken Raeburn <raeburn@mit.edu>
+
+ * client_init.c (enctypes): Add des3 and des-md5 to the list of
+ permitted enctypes.
+
+2000-05-01 Nalin Dahyabhai <nalin@redhat.com>
+
+ * client_init.c (_kadm5_init_any): Fix determination of client
+ name length for overflow checking.
+
2000-02-26 Tom Yu <tlyu@mit.edu>
* client_principal.c (kadm5_create_principal_3): Remove keepold
diff --git a/src/lib/kadm5/clnt/Makefile.in b/src/lib/kadm5/clnt/Makefile.in
index 2d69cdc..e434236 100644
--- a/src/lib/kadm5/clnt/Makefile.in
+++ b/src/lib/kadm5/clnt/Makefile.in
@@ -5,7 +5,7 @@ BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U)
LOCALINCLUDES = -I$(BUILDTOP)/include/kadm5
LIB=kadm5clnt
-LIBMAJOR=4
+LIBMAJOR=5
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 a3d2613..b3832bb 100644
--- a/src/lib/kadm5/clnt/client_init.c
+++ b/src/lib/kadm5/clnt/client_init.c
@@ -134,6 +134,8 @@ static int preauth_search_list[] = {
};
static krb5_enctype enctypes[] = {
+ ENCTYPE_DES3_CBC_SHA1,
+ ENCTYPE_DES_CBC_MD5,
ENCTYPE_DES_CBC_CRC,
0,
};
@@ -282,9 +284,15 @@ static kadm5_ret_t _kadm5_init_any(char *client_name,
goto error;
if (realm) {
+ if(strlen(service_name) + strlen(realm) + 1 >= sizeof(full_service_name)) {
+ goto error;
+ }
sprintf(full_service_name, "%s@%s", service_name, realm);
} else {
/* krb5_princ_realm(creds.client) is not null terminated */
+ if(strlen(service_name) + krb5_princ_realm(handle->context, creds.client)->length + 1 >= sizeof(full_service_name)) {
+ goto error;
+ }
strcpy(full_service_name, service_name);
strcat(full_service_name, "@");
strncat(full_service_name, krb5_princ_realm(handle->context,
diff --git a/src/lib/kadm5/clnt/clnt_chpass_util.c b/src/lib/kadm5/clnt/clnt_chpass_util.c
index d6c7f0b..ae9ced0 100644
--- a/src/lib/kadm5/clnt/clnt_chpass_util.c
+++ b/src/lib/kadm5/clnt/clnt_chpass_util.c
@@ -5,11 +5,12 @@ kadm5_ret_t kadm5_chpass_principal_util(void *server_handle,
krb5_principal princ,
char *new_pw,
char **ret_pw,
- char *msg_ret)
+ char *msg_ret,
+ int msg_len)
{
kadm5_server_handle_t handle = server_handle;
CHECK_HANDLE(server_handle);
return _kadm5_chpass_principal_util(handle, handle->lhandle, princ,
- new_pw, ret_pw, msg_ret);
+ new_pw, ret_pw, msg_ret, msg_len);
}
diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c
index bf40048..c92dc60 100644
--- a/src/lib/kadm5/kadm_rpc_xdr.c
+++ b/src/lib/kadm5/kadm_rpc_xdr.c
@@ -135,8 +135,16 @@ xdr_krb5_kvno(XDR *xdrs, krb5_kvno *objp)
tmp = '\0'; /* for purify, else xdr_u_char performs a umr */
- if (xdrs->x_op == XDR_ENCODE)
+ if (xdrs->x_op == XDR_ENCODE) {
tmp = (unsigned char) *objp;
+#if 0
+ /* We can't change the protocol right now, so let's
+ just reject (legitimate!) values that won't fit in
+ our broken one-byte encoding. */
+ if (tmp != *objp)
+ return FALSE;
+#endif
+ }
if (!xdr_u_char(xdrs, &tmp))
return (FALSE);
diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c
index 4f2ad20..bf6bbfd 100644
--- a/src/lib/kadm5/logger.c
+++ b/src/lib/kadm5/logger.c
@@ -199,8 +199,9 @@ klog_com_err_proc(whoami, code, format, ap)
/* If reporting an error message, separate it. */
if (code) {
- strcat(outbuf, error_message(code));
- strcat(outbuf, " - ");
+ outbuf[sizeof(outbuf) - 1] = '\0';
+ strncat(outbuf, error_message(code), sizeof(outbuf) - 1 - strlen(outbuf));
+ strncat(outbuf, " - ", sizeof(outbuf) - 1 - strlen(outbuf));
}
cp = &outbuf[strlen(outbuf)];
diff --git a/src/lib/kadm5/ovsec_glue.c b/src/lib/kadm5/ovsec_glue.c
index 6118282..ce81893 100644
--- a/src/lib/kadm5/ovsec_glue.c
+++ b/src/lib/kadm5/ovsec_glue.c
@@ -102,8 +102,10 @@ ovsec_kadm_ret_t ovsec_kadm_chpass_principal_util(void *server_handle,
char **ret_pw,
char *msg_ret)
{
- return kadm5_chpass_principal_util(server_handle, princ, new_pw,
- ret_pw, msg_ret);
+ /* Oh crap. Can't change the API without bumping the API version... */
+ memset(msg_ret, '\0', 1024);
+ return kadm5_chpass_principal_util(server_handle, princ, new_pw,
+ ret_pw, msg_ret, 1024);
}
ovsec_kadm_ret_t ovsec_kadm_randkey_principal(void *server_handle,
diff --git a/src/lib/kadm5/srv/ChangeLog b/src/lib/kadm5/srv/ChangeLog
index 792936d..6d45fa3 100644
--- a/src/lib/kadm5/srv/ChangeLog
+++ b/src/lib/kadm5/srv/ChangeLog
@@ -1,3 +1,47 @@
+2002-11-07 Tom Yu <tlyu@mit.edu>
+
+ * svr_principal.c (kadm5_setkey_principal_3): Apply patch from
+ Emily Ratliff to allow n_ks_tuple to be zero, which is the case if
+ being called from kadmind answering a client's setkey_principal
+ request.
+ [pullup from trunk]
+
+2001-11-05 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in (LIBMAJOR): Bump to avoid Heimdal conflict.
+
+2001-10-22 Tom Yu <tlyu@mit.edu>
+
+ * svr_principal.c (kadm5_decrypt_key): For now, coerce enctype of
+ output keyblock in case we got a match on a similar enctype.
+
+2001-10-16 Mitchell Berger <mitchb@mit.edu>
+ Matt Crawford <crawdad@fnal.gov>
+
+ * svr_principal.c (add_to_history): If the policy a principal uses has
+ been changed to hold a lesser number of history entries than it did
+ before, extract the correct number and value of old keys from the
+ history array into a newly allocated array of the proper size. Failing
+ to do this made kadmind vulnerable to a crash upon changing such a
+ principal's password. Original patch written by Matt Crawford, with
+ a few changes.
+ [pullup from trunk]
+
+2001-09-07 Tom Yu <tlyu@mit.edu>
+
+ * adb_openclose.c (osa_adb_create_db): Default to btree.
+ (osa_adb_init_db): Set up btinfo as well.
+ (osa_adb_open_and_lock): Try btree, then hash.
+ [pullup from trunk]
+
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * adb_openclose.c (osa_adb_create_db): Open lock files using O_EXCL
+ and fdopen() the descriptor instead of using fopen().
+ * svr_chpass_util.c (kadm5_chpass_principal_util): Adjust for new
+ length parameter in both kadm5_chpass_principal_util() and in
+ _kadm5_chpass_principal_util().
+
2000-03-16 Ken Raeburn <raeburn@mit.edu>
Matt Crawford <crawdad@fnal.gov>
diff --git a/src/lib/kadm5/srv/Makefile.in b/src/lib/kadm5/srv/Makefile.in
index a0d18e4..3459760 100644
--- a/src/lib/kadm5/srv/Makefile.in
+++ b/src/lib/kadm5/srv/Makefile.in
@@ -9,7 +9,7 @@ DEFINES = @HESIOD_DEFS@
##DOSLIBNAME = libkadm5srv.lib
LIB=kadm5srv
-LIBMAJOR=4
+LIBMAJOR=5
LIBMINOR=0
STOBJLISTS=../OBJS.ST OBJS.ST
SHLIB_EXPDEPS=\
diff --git a/src/lib/kadm5/srv/adb_openclose.c b/src/lib/kadm5/srv/adb_openclose.c
index e776192..dbbc3b6 100644
--- a/src/lib/kadm5/srv/adb_openclose.c
+++ b/src/lib/kadm5/srv/adb_openclose.c
@@ -24,27 +24,29 @@ struct _locklist {
osa_adb_ret_t osa_adb_create_db(char *filename, char *lockfilename,
int magic)
{
- FILE *lf;
+ int lf;
DB *db;
- HASHINFO info;
+ BTREEINFO btinfo;
- memset(&info, 0, sizeof(info));
- info.hash = NULL;
- info.bsize = 256;
- info.ffactor = 8;
- info.nelem = 25000;
- info.lorder = 0;
- db = dbopen(filename, O_RDWR | O_CREAT | O_EXCL, 0600, DB_HASH, &info);
+ memset(&btinfo, 0, sizeof(btinfo));
+ btinfo.flags = 0;
+ btinfo.cachesize = 0;
+ btinfo.psize = 4096;
+ btinfo.lorder = 0;
+ btinfo.minkeypage = 0;
+ btinfo.compare = NULL;
+ btinfo.prefix = NULL;
+ db = dbopen(filename, O_RDWR | O_CREAT | O_EXCL, 0600, DB_BTREE, &btinfo);
if (db == NULL)
return errno;
if (db->close(db) < 0)
return errno;
/* only create the lock file if we successfully created the db */
- lf = fopen(lockfilename, "w+");
- if (lf == NULL)
+ lf = THREEPARAMOPEN(lockfilename, O_RDWR | O_CREAT | O_EXCL, 0600);
+ if (lf == -1)
return errno;
- (void) fclose(lf);
+ (void) close(lf);
return OSA_ADB_OK;
}
@@ -128,6 +130,13 @@ osa_adb_ret_t osa_adb_init_db(osa_adb_db_t *dbp, char *filename,
db->info.nelem = 25000;
db->info.lorder = 0;
+ db->btinfo.flags = 0;
+ db->btinfo.cachesize = 0;
+ db->btinfo.psize = 4096;
+ db->btinfo.lorder = 0;
+ db->btinfo.minkeypage = 0;
+ db->btinfo.compare = NULL;
+ db->btinfo.prefix = NULL;
/*
* A process is allowed to open the same database multiple times
* and access it via different handles. If the handles use
@@ -333,7 +342,7 @@ osa_adb_ret_t osa_adb_get_lock(osa_adb_db_t db, int mode)
osa_adb_ret_t osa_adb_release_lock(osa_adb_db_t db)
{
- int ret;
+ int ret, fd;
if (!db->lock->lockcnt) /* lock already unlocked */
return OSA_ADB_NOTLOCKED;
@@ -341,8 +350,9 @@ osa_adb_ret_t osa_adb_release_lock(osa_adb_db_t db)
if (--db->lock->lockcnt == 0) {
if (db->lock->lockmode == OSA_ADB_PERMANENT) {
/* now we need to create the file since it does not exist */
- if ((db->lock->lockfile = fopen(db->lock->filename,
- "w+")) == NULL)
+ fd = THREEPARAMOPEN(db->lock->filename,O_RDWR | O_CREAT | O_EXCL,
+ 0600);
+ if ((db->lock->lockfile = fdopen(fd, "w+")) == NULL)
return OSA_ADB_NOLOCKFILE;
} else if (ret = krb5_lock_file(db->lock->context,
fileno(db->lock->lockfile),
@@ -362,14 +372,23 @@ osa_adb_ret_t osa_adb_open_and_lock(osa_adb_princ_t db, int locktype)
if (ret != OSA_ADB_OK)
return ret;
- db->db = dbopen(db->filename, O_RDWR, 0600, DB_HASH, &db->info);
- if (db->db == NULL) {
+ db->db = dbopen(db->filename, O_RDWR, 0600, DB_BTREE, &db->btinfo);
+ if (db->db != NULL)
+ return OSA_ADB_OK;
+ switch (errno) {
+#ifdef EFTYPE
+ case EFTYPE:
+#endif
+ case EINVAL:
+ db->db = dbopen(db->filename, O_RDWR, 0600, DB_HASH, &db->info);
+ if (db->db != NULL)
+ return OSA_ADB_OK;
+ default:
(void) osa_adb_release_lock(db);
- if(errno == EINVAL)
+ if (errno == EINVAL)
return OSA_ADB_BAD_DB;
return errno;
}
- return OSA_ADB_OK;
}
osa_adb_ret_t osa_adb_close_and_unlock(osa_adb_princ_t db)
diff --git a/src/lib/kadm5/srv/svr_chpass_util.c b/src/lib/kadm5/srv/svr_chpass_util.c
index df2bf4c..4c4c6bb 100644
--- a/src/lib/kadm5/srv/svr_chpass_util.c
+++ b/src/lib/kadm5/srv/svr_chpass_util.c
@@ -5,11 +5,12 @@ kadm5_ret_t kadm5_chpass_principal_util(void *server_handle,
krb5_principal princ,
char *new_pw,
char **ret_pw,
- char *msg_ret)
+ char *msg_ret,
+ int msg_len)
{
kadm5_server_handle_t handle = server_handle;
CHECK_HANDLE(server_handle);
return _kadm5_chpass_principal_util(handle, handle->lhandle, princ,
- new_pw, ret_pw, msg_ret);
+ new_pw, ret_pw, msg_ret, msg_len);
}
diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
index 4981703..aeae090 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -974,6 +974,7 @@ int free_history_entry(krb5_context context, osa_pw_hist_ent *hist)
* array where the next element should be written, and must be [0,
* adb->old_key_len).
*/
+#define KADM_MOD(x) (x + adb->old_key_next) % adb->old_key_len
static kadm5_ret_t add_to_history(krb5_context context,
osa_princ_ent_t adb,
kadm5_policy_ent_t pol,
@@ -1001,6 +1002,39 @@ static kadm5_ret_t add_to_history(krb5_context context,
memset(&adb->old_keys[adb->old_key_len],0,sizeof(osa_pw_hist_ent));
adb->old_key_len++;
+ } else if (adb->old_key_len > pol->pw_history_num-1) {
+ /*
+ * The policy must have changed! Shrink the array.
+ * Can't simply realloc() down, since it might be wrapped.
+ * To understand the arithmetic below, note that we are
+ * copying into new positions 0 .. N-1 from old positions
+ * old_key_next-N .. old_key_next-1, modulo old_key_len,
+ * where N = pw_history_num - 1 is the length of the
+ * shortened list. Matt Crawford, FNAL
+ */
+ int j;
+ histp = (osa_pw_hist_ent *)
+ malloc((pol->pw_history_num - 1) * sizeof (osa_pw_hist_ent));
+ if (histp) {
+ for (i = 0; i < pol->pw_history_num - 1; i++) {
+ /* We need the number we use the modulus operator on to be
+ positive, so after subtracting pol->pw_history_num-1, we
+ add back adb->old_key_len. */
+ j = KADM_MOD(i - (pol->pw_history_num - 1) + adb->old_key_len);
+ histp[i] = adb->old_keys[j];
+ }
+ /* Now free the ones we don't keep (the oldest ones) */
+ for (i = 0; i < adb->old_key_len - (pol->pw_history_num - 1); i++)
+ for (j = 0; j < adb->old_keys[KADM_MOD(i)].n_key_data; j++)
+ krb5_free_key_data_contents(context,
+ &adb->old_keys[KADM_MOD(i)].key_data[j]);
+ free((void *)adb->old_keys);
+ adb->old_keys = histp;
+ adb->old_key_len = pol->pw_history_num - 1;
+ adb->old_key_next = 0;
+ } else {
+ return(ENOMEM);
+ }
}
/* free the old pw history entry if it contains data */
@@ -1017,6 +1051,7 @@ static kadm5_ret_t add_to_history(krb5_context context,
return(0);
}
+#undef KADM_MOD
kadm5_ret_t
kadm5_chpass_principal(void *server_handle,
@@ -1482,7 +1517,7 @@ kadm5_setkey_principal_3(void *server_handle,
}
}
- if (n_ks_tuple != n_keys)
+ if (n_ks_tuple && n_ks_tuple != n_keys)
return KADM5_SETKEY3_ETYPE_MISMATCH;
if ((ret = kdb_get_entry(handle, principal, &kdb, &adb)))
@@ -1703,6 +1738,13 @@ kadm5_ret_t kadm5_decrypt_key(void *server_handle,
keyblock, keysalt))
return ret;
+ /*
+ * Coerce the enctype of the output keyblock in case we got an
+ * inexact match on the enctype; this behavior will go away when
+ * the key storage architecture gets redesigned for 1.3.
+ */
+ keyblock->enctype = ktype;
+
if (kvnop)
*kvnop = key_data->key_data_kvno;
diff --git a/src/lib/kadm5/str_conv.c b/src/lib/kadm5/str_conv.c
index 16ad534..f4f572a 100644
--- a/src/lib/kadm5/str_conv.c
+++ b/src/lib/kadm5/str_conv.c
@@ -361,7 +361,22 @@ krb5_string_to_keysalts(string, tupleseps, ksaltseps, dups, ksaltp, nksaltp)
if (ep)
ep[-1] = trailchar;
kp = ep;
- }
+
+ /* Skip over extra separators - like spaces */
+ if (kp && *tseplist) {
+ septmp = tseplist;
+ while(*septmp && *kp) {
+ if(*septmp == *kp) {
+ /* Increment string - reset separator list */
+ kp++;
+ septmp = tseplist;
+ } else {
+ septmp++;
+ }
+ }
+ if (!*kp) kp = NULL;
+ }
+ } /* while kp */
return(kret);
}
diff --git a/src/lib/kadm5/unit-test/ChangeLog b/src/lib/kadm5/unit-test/ChangeLog
index b8e4b71..2e9b74f 100644
--- a/src/lib/kadm5/unit-test/ChangeLog
+++ b/src/lib/kadm5/unit-test/ChangeLog
@@ -1,3 +1,16 @@
+2002-11-03 Tom Yu <tlyu@mit.edu>
+
+ * config/unix.exp: Work around tcl 8.4's (incorrect?) output EOL
+ translation.
+ [pullup from trunk]
+
+2000-05-09 Ken Raeburn <raeburn@mit.edu>
+
+ * api.2/chpass-principal-v2.exp (test200): Expect an additional
+ key to be reported, since des3 has been added to the list.
+ * api.2/get-principal-v2.exp (test101_102): Likewise.
+ * api.2/randkey-principal-v2.exp (test100): Likewise.
+
2000-02-08 Tom Yu <tlyu@mit.edu>
* api.1/lock.exp: Since a "wait" directive to the command list of
diff --git a/src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp b/src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp
index 40a78c9..ef45510 100644
--- a/src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp
+++ b/src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp
@@ -53,10 +53,10 @@ proc test200 {} {
}
# XXX Perhaps I should actually check the key type returned.
- if {$num_keys == 2} {
+ if {$num_keys == 3} {
pass "$test"
} else {
- fail "$test: $num_keys keys, should be 2"
+ fail "$test: $num_keys keys, should be 3"
}
if { ! [cmd {kadm5_destroy $server_handle}]} {
error "$test: unexpected failure in destroy"
diff --git a/src/lib/kadm5/unit-test/api.2/get-principal-v2.exp b/src/lib/kadm5/unit-test/api.2/get-principal-v2.exp
index 0e3e1b5..d2eb85a 100644
--- a/src/lib/kadm5/unit-test/api.2/get-principal-v2.exp
+++ b/src/lib/kadm5/unit-test/api.2/get-principal-v2.exp
@@ -143,8 +143,8 @@ proc test101_102 {rpc} {
}
set failed 0
- if {$num_keys != 2} {
- fail "$test: num_keys $num_keys should be 2"
+ if {$num_keys != 3} {
+ fail "$test: num_keys $num_keys should be 3"
set failed 1
}
for {set i 0} {$i < $num_keys} {incr i} {
diff --git a/src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp b/src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp
index 5c8fdc5..d9cc971 100644
--- a/src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp
+++ b/src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp
@@ -47,10 +47,10 @@ proc test100 {} {
}
# XXX Perhaps I should actually check the key type returned.
- if {$num_keys == 1} {
+ if {$num_keys == 2} {
pass "$test"
} else {
- fail "$test: $num_keys keys, should be 1"
+ fail "$test: $num_keys keys, should be 2"
}
if { ! [cmd {kadm5_destroy $server_handle}]} {
error "$test: unexpected failure in destroy"
diff --git a/src/lib/kadm5/unit-test/config/unix.exp b/src/lib/kadm5/unit-test/config/unix.exp
index 2aab9e4..0472789 100644
--- a/src/lib/kadm5/unit-test/config/unix.exp
+++ b/src/lib/kadm5/unit-test/config/unix.exp
@@ -58,6 +58,14 @@ proc api_start {} {
if {! [info exists env(TCLUTIL)]} {
error "TCLUTIL environment variable isn't set"
}
+ # tcl 8.4 for some reason screws up autodetection of output
+ # EOL translation. Work around it for now.
+ send "if { \[info commands fconfigure\] ne \"\" } { fconfigure stdout -translation lf }\n"
+ expect {
+ -re "$prompt$" {}
+ eof { error "EOF starting API" }
+ timeout { error "Timeout starting API" }
+ }
send "source $env(TCLUTIL)\n"
expect {
-re "$prompt$" {}
diff --git a/src/lib/kdb/ChangeLog b/src/lib/kdb/ChangeLog
index a710eb7..4aeb862 100644
--- a/src/lib/kdb/ChangeLog
+++ b/src/lib/kdb/ChangeLog
@@ -1,3 +1,76 @@
+2003-03-16 Sam Hartman <hartmans@mit.edu>
+
+ * keytab.c (krb5_ktkdb_get_entry): Match only against the first
+ enctype for non-cross-realm tickets so we will only accept
+ tickets that the current configuration would have issued. For
+ cross-realm tickets be liberal and match against the specified
+ enctype.
+
+2002-08-26 Tom Yu <tlyu@mit.edu>
+
+ * kdb_db2.h: Add prototype and rename for
+ krb5_db2_db_iterate_ext().
+
+ * kdb_db2.c (krb5_db2_db_iterate_ext): New function; allow
+ optional backwards or recursive (if btree) traversal of the
+ database.
+
+ * Makefile.in (LIBMINOR): Bump due to addition of
+ krb5_db_iterate_ext().
+
+ [pullups from trunk]
+
+2002-08-15 Tom Yu <tlyu@mit.edu>
+
+ * keytab.c (krb5_ktkdb_get_entry): For consistency, check for
+ DISALLOW_ALL_TIX and DISALLOW_SVR when looking up keys.
+ [pullup from trunk]
+
+2002-08-12 Sam Hartman <hartmans@mit.edu>
+
+ * kdb_xdr.c (krb5_dbe_search_enctype): Initialize ret to 0; thanks
+ to Lubos Kejzlar <kejzlar@civ.zcu.cz>
+ [pullup from trunk]
+
+2001-11-05 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in (LIBMINOR): Bump due to some behavior changes
+ regarding enctype similarity.
+
+2001-10-22 Tom Yu <tlyu@mit.edu>
+
+ * kdb_xdr.c (krb5_dbe_search_enctype): Filter out enctypes that
+ aren't in permitted_enctypes. This prevents the KDC from issuing
+ a ticket whose enctype that it won't accept.
+
+2001-10-20 Tom Yu <tlyu@mit.edu>
+
+ * keytab.c (krb5_ktkdb_get_entry): For now, coerce enctype of
+ output keyblock in case we got a match on a similar enctype.
+
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * t_kdb.c (gen_principal): Don't overflow "pnamebuf" if bad data was
+ passed in.
+
+2000-05-03 Nalin Dahyabhai <nalin@redhat.com>
+
+ * setup_mkey.c (krb5_db_setup_mkey_name): Use REALM_SEP_STRING
+ when computing size of buffer that is to include it.
+
+ * fetch_mkey.c (krb5_db_fetch_mkey): Make sure "defkeyfile" is
+ null terminated after construction.
+ * store_mkey.c (krb5_db_store_mkey): Likewise.
+
+2000-04-27 Ken Raeburn <raeburn@mit.edu>
+ Ezra Peisach <epeisach@mit.edu>
+
+ * t_kdb.c (gen_principal): Force argument to isalnum to be in
+ range 0..255.
+ (do_testing): Cast pid_t to long before passing to fprintf, and
+ use %ld format. Fix argument lists to find_principal and
+ delete_principal.
+
2000-03-16 Ezra Peisach <epeisach@mit.edu>
* kdb_xdr.c (krb5_dbe_lookup_mod_princ_data): Get rid of
diff --git a/src/lib/kdb/Makefile.in b/src/lib/kdb/Makefile.in
index 68c6361..10f7580 100644
--- a/src/lib/kdb/Makefile.in
+++ b/src/lib/kdb/Makefile.in
@@ -9,7 +9,7 @@ PROG_RPATH=$(KRB5_LIBDIR)
LIB=kdb5
LIBMAJOR=3
-LIBMINOR=0
+LIBMINOR=2
RELDIR=kdb
# Depends on libk5crypto and libkrb5
SHLIB_EXPDEPS = \
diff --git a/src/lib/kdb/fetch_mkey.c b/src/lib/kdb/fetch_mkey.c
index 2ff5c29..7ae26bb 100644
--- a/src/lib/kdb/fetch_mkey.c
+++ b/src/lib/kdb/fetch_mkey.c
@@ -133,7 +133,7 @@ krb5_db_fetch_mkey(context, mname, etype, fromkeyboard, twice, keyfile,
(void) strncat(defkeyfile, realm->data,
min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1,
realm->length));
- (void) strcat(defkeyfile, "");
+ defkeyfile[sizeof(defkeyfile) - 1] = '\0';
#ifdef ANSI_STDIO
if (!(kf = fopen((keyfile) ? keyfile : defkeyfile, "rb")))
diff --git a/src/lib/kdb/kdb_db2.c b/src/lib/kdb/kdb_db2.c
index 627aa75..6420acc 100644
--- a/src/lib/kdb/kdb_db2.c
+++ b/src/lib/kdb/kdb_db2.c
@@ -1115,10 +1115,11 @@ cleanup:
}
krb5_error_code
-krb5_db2_db_iterate (context, func, func_arg)
+krb5_db2_db_iterate_ext(context, func, func_arg, backwards, recursive)
krb5_context context;
krb5_error_code (*func) PROTOTYPE((krb5_pointer, krb5_db_entry *));
krb5_pointer func_arg;
+ int backwards, recursive;
{
krb5_db2_context *db_ctx;
DB *db;
@@ -1127,17 +1128,31 @@ krb5_db2_db_iterate (context, func, func_arg)
krb5_db_entry entries;
krb5_error_code retval;
int dbret;
-
+ void *cookie;
+
+ cookie = NULL;
if (!k5db2_inited(context))
return KRB5_KDB_DBNOTINITED;
db_ctx = (krb5_db2_context *) context->db_context;
retval = krb5_db2_db_lock(context, KRB5_LOCKMODE_SHARED);
+
if (retval)
return retval;
db = db_ctx->db;
- dbret = (*db->seq)(db, &key, &contents, R_FIRST);
+ if (recursive && db->type != DB_BTREE) {
+ (void)krb5_db2_db_unlock(context);
+ return KRB5_KDB_UK_RERROR; /* Not optimal, but close enough. */
+ }
+
+ if (!recursive) {
+ dbret = (*db->seq)(db, &key, &contents,
+ backwards ? R_LAST : R_FIRST);
+ } else {
+ dbret = bt_rseq(db, &key, &contents, &cookie,
+ backwards ? R_LAST : R_FIRST);
+ }
while (dbret == 0) {
contdata.data = contents.data;
contdata.length = contents.size;
@@ -1148,7 +1163,13 @@ krb5_db2_db_iterate (context, func, func_arg)
krb5_dbe_free_contents(context, &entries);
if (retval)
break;
- dbret = (*db->seq)(db, &key, &contents, R_NEXT);
+ if (!recursive) {
+ dbret = (*db->seq)(db, &key, &contents,
+ backwards ? R_PREV : R_NEXT);
+ } else {
+ dbret = bt_rseq(db, &key, &contents, &cookie,
+ backwards ? R_PREV : R_NEXT);
+ }
}
switch (dbret) {
case 1:
@@ -1162,6 +1183,15 @@ krb5_db2_db_iterate (context, func, func_arg)
return retval;
}
+krb5_error_code
+krb5_db2_db_iterate(context, func, func_arg)
+ krb5_context context;
+ krb5_error_code (*func) (krb5_pointer, krb5_db_entry *);
+ krb5_pointer func_arg;
+{
+ return krb5_db2_db_iterate_ext(context, func, func_arg, 0, 0);
+}
+
krb5_boolean
krb5_db2_db_set_lockmode(context, mode)
krb5_context context;
diff --git a/src/lib/kdb/kdb_db2.h b/src/lib/kdb/kdb_db2.h
index fd35c81..d8f7ba5 100644
--- a/src/lib/kdb/kdb_db2.h
+++ b/src/lib/kdb/kdb_db2.h
@@ -41,6 +41,7 @@
#define krb5_db2_db_free_principal krb5_db_free_principal
#define krb5_db2_db_put_principal krb5_db_put_principal
#define krb5_db2_db_delete_principal krb5_db_delete_principal
+#define krb5_db2_db_iterate_ext krb5_db_iterate_ext
#define krb5_db2_db_iterate krb5_db_iterate
#define krb5_db2_db_lock krb5_db_lock
#define krb5_db2_db_unlock krb5_db_unlock
@@ -104,6 +105,11 @@ krb5_error_code krb5_db2_db_put_principal
KRB5_PROTOTYPE((krb5_context,
krb5_db_entry *,
int * ));
+krb5_error_code krb5_db2_db_iterate_ext
+ KRB5_PROTOTYPE((krb5_context,
+ krb5_error_code (*) (krb5_pointer,
+ krb5_db_entry *),
+ krb5_pointer, int, int ));
krb5_error_code krb5_db2_db_iterate
KRB5_PROTOTYPE((krb5_context,
krb5_error_code (*) KRB5_PROTOTYPE((krb5_pointer,
diff --git a/src/lib/kdb/kdb_xdr.c b/src/lib/kdb/kdb_xdr.c
index 5d1911e2..b7b8b4a 100644
--- a/src/lib/kdb/kdb_xdr.c
+++ b/src/lib/kdb/kdb_xdr.c
@@ -724,7 +724,9 @@ krb5_dbe_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap)
int i, index;
int maxkvno;
krb5_key_data *datap;
+ krb5_error_code ret;
+ ret = 0;
if (kvno == -1 && stype == -1 && ktype == -1)
kvno = 0;
@@ -741,15 +743,25 @@ krb5_dbe_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap)
datap = (krb5_key_data *) NULL;
for (i = *start; i < dbentp->n_key_data; i++) {
krb5_boolean similar;
- krb5_error_code ret;
krb5_int32 db_stype;
+ ret = 0;
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;
}
+
+ /*
+ * Filter out non-permitted enctypes.
+ */
+ if (!krb5_is_permitted_enctype(kcontext,
+ dbentp->key_data[i].key_data_type[0])) {
+ ret = KRB5_KDB_NO_PERMITTED_KEY;
+ continue;
+ }
+
if (ktype >= 0) {
if ((ret = krb5_c_enctype_compare(kcontext, (krb5_enctype) ktype,
dbentp->key_data[i].key_data_type[0],
@@ -776,7 +788,7 @@ krb5_dbe_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap)
}
}
if (maxkvno < 0)
- return ENOENT;
+ return ret ? ret : KRB5_KDB_NO_MATCHING_KEY;
*kdatap = datap;
*start = index+1;
return 0;
diff --git a/src/lib/kdb/keytab.c b/src/lib/kdb/keytab.c
index 1e5025c..5881fa1 100644
--- a/src/lib/kdb/keytab.c
+++ b/src/lib/kdb/keytab.c
@@ -28,6 +28,8 @@
#include "k5-int.h"
#include "kdb_kt.h"
+static int
+is_xrealm_tgt(krb5_context, krb5_const_principal);
krb5_error_code krb5_ktkdb_close KRB5_PROTOTYPE((krb5_context, krb5_keytab));
krb5_error_code krb5_ktkdb_get_entry KRB5_PROTOTYPE((krb5_context, krb5_keytab, krb5_const_principal,
@@ -98,6 +100,8 @@ krb5_ktkdb_get_entry(context, id, principal, kvno, enctype, entry)
krb5_db_entry db_entry;
krb5_boolean more = 0;
int n = 0;
+ int xrealm_tgt = is_xrealm_tgt(context, principal);
+ int similar;
/* Open database */
/* krb5_db_init(context); */
@@ -116,21 +120,49 @@ krb5_ktkdb_get_entry(context, id, principal, kvno, enctype, entry)
return KRB5_KT_NOTFOUND;
}
+ if (db_entry.attributes & KRB5_KDB_DISALLOW_SVR
+ || db_entry.attributes & KRB5_KDB_DISALLOW_ALL_TIX) {
+ kerror = KRB5_KT_NOTFOUND;
+ goto error;
+ }
+
/* match key */
kerror = krb5_db_get_mkey(context, &master_key);
if (kerror)
goto error;
+ /* For cross realm tgts, we match whatever enctype is provided;
+ * for other principals, we only match the first enctype that is
+ * found. Since the TGS and AS code do the same thing, then we
+ * will only successfully decrypt tickets we have issued.*/
kerror = krb5_dbe_find_enctype(context, &db_entry,
- enctype, -1, kvno, &key_data);
+ xrealm_tgt?enctype:-1,
+ -1, kvno, &key_data);
if (kerror)
goto error;
+
kerror = krb5_dbekd_decrypt_key_data(context, master_key,
key_data, &entry->key, NULL);
if (kerror)
goto error;
+ kerror = krb5_c_enctype_compare(context, enctype, entry->key.enctype, &similar);
+ if (kerror)
+ goto error;
+
+ if (!similar) {
+ kerror = KRB5_KDB_NO_PERMITTED_KEY;
+ goto error;
+ }
+
+ /*
+ * Coerce the enctype of the output keyblock in case we got an
+ * inexact match on the enctype; this behavior will go away when
+ * the key storage architecture gets redesigned for 1.3.
+ */
+ entry->key.enctype = enctype;
+
kerror = krb5_copy_principal(context, principal, &entry->principal);
if (kerror)
goto error;
@@ -141,3 +173,27 @@ krb5_ktkdb_get_entry(context, id, principal, kvno, enctype, entry)
krb5_db_close_database(context);
return(kerror);
}
+
+/*
+ * is_xrealm_tgt: Returns true if the principal is a cross-realm TGT
+ * principal-- a principal with first component krbtgt and second
+ * component not equal to realm.
+ */
+static int
+is_xrealm_tgt(krb5_context context, krb5_const_principal princ)
+{
+ krb5_data *dat;
+ if (krb5_princ_size(context, princ) != 2)
+ return 0;
+ dat = krb5_princ_component(context, princ, 0);
+ if (strncmp("krbtgt", dat->data, dat->length) != 0)
+ return 0;
+ dat = krb5_princ_component(context, princ, 1);
+ if (dat->length != princ->realm.length)
+ return 1;
+ if (strcmp(dat->data, princ->realm.data) == 0)
+ return 0;
+ return 1;
+
+}
+
diff --git a/src/lib/kdb/setup_mkey.c b/src/lib/kdb/setup_mkey.c
index 0898a63..1788ecd 100644
--- a/src/lib/kdb/setup_mkey.c
+++ b/src/lib/kdb/setup_mkey.c
@@ -56,7 +56,7 @@ krb5_db_setup_mkey_name(context, keyname, realm, fullname, principal)
keylen = strlen(keyname);
- fname = malloc(keylen+rlen+2);
+ fname = malloc(keylen+rlen+strlen(REALM_SEP_STRING)+1);
if (!fname)
return ENOMEM;
diff --git a/src/lib/kdb/store_mkey.c b/src/lib/kdb/store_mkey.c
index d18630a..47e0bc9 100644
--- a/src/lib/kdb/store_mkey.c
+++ b/src/lib/kdb/store_mkey.c
@@ -68,7 +68,7 @@ krb5_db_store_mkey(context, keyfile, mname, key)
(void) strncat(defkeyfile, realm->data,
min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1,
realm->length));
- (void) strcat(defkeyfile, "");
+ defkeyfile[sizeof(defkeyfile) - 1] = '\0';
keyfile = defkeyfile;
}
diff --git a/src/lib/kdb/t_kdb.c b/src/lib/kdb/t_kdb.c
index 8358088..10e6163 100644
--- a/src/lib/kdb/t_kdb.c
+++ b/src/lib/kdb/t_kdb.c
@@ -363,15 +363,23 @@ gen_principal(kcontext, realm, do_rand, n, princp, namep)
complen = RANDOM(1,MAX_COMP_SIZE);
for (j=0; j<complen; j++) {
*cp = (char) RANDOM(0,256);
- while (!isalnum(*cp))
+ while (!isalnum(*cp & 0xff))
*cp = (char) RANDOM(0,256);
cp++;
+ if(cp + strlen(realm) >= pnamebuf + sizeof(pnamebuf))
+ break;
}
+ if(cp + strlen(realm) >= pnamebuf + sizeof(pnamebuf))
+ break;
*cp = '/';
cp++;
}
- cp[-1] = '@';
- strcpy(cp, realm);
+ if(cp + strlen(realm) < pnamebuf + sizeof(pnamebuf)) {
+ cp[-1] = '@';
+ strcpy(cp, realm);
+ } else {
+ strcpy(cp , "");
+ }
}
else {
instname = instnames[n % (sizeof(instnames)/sizeof(instnames[0]))];
@@ -894,45 +902,40 @@ do_testing(db, passes, verbose, timing, rcases, check, save_db, dontclean,
&stat_kb,
rseed))) {
fprintf(stderr,
- "%d: (%d,%d) Failed add of %s with %s\n",
- getpid(), i, j, playback_name(base+j),
+ "%ld: (%d,%d) Failed add of %s with %s\n",
+ (long) getpid(), i, j, playback_name(base+j),
error_message(kret));
break;
}
if (verbose > 4)
- fprintf(stderr, "*A[%d](%s)\n", getpid(),
+ fprintf(stderr, "*A[%ld](%s)\n", (long) getpid(),
playback_name(base+j));
}
for (j=0; (j<nper) && (!kret); j++) {
if ((kret = find_principal(ccontext,
playback_principal(base+j),
- &master_encblock,
- &stat_kb,
- rseed))) {
+ check))) {
fprintf(stderr,
- "%d: (%d,%d) Failed lookup of %s with %s\n",
- getpid(), i, j, playback_name(base+j),
+ "%ld: (%d,%d) Failed lookup of %s with %s\n",
+ (long) getpid(), i, j, playback_name(base+j),
error_message(kret));
break;
}
if (verbose > 4)
- fprintf(stderr, "-S[%d](%s)\n", getpid(),
+ fprintf(stderr, "-S[%ld](%s)\n", (long) getpid(),
playback_name(base+j));
}
for (j=0; (j<nper) && (!kret); j++) {
if ((kret = delete_principal(ccontext,
- playback_principal(base+j),
- &master_encblock,
- &stat_kb,
- rseed))) {
+ playback_principal(base+j)))) {
fprintf(stderr,
- "%d: (%d,%d) Failed delete of %s with %s\n",
- getpid(), i, j, playback_name(base+j),
+ "%ld: (%d,%d) Failed delete of %s with %s\n",
+ (long) getpid(), i, j, playback_name(base+j),
error_message(kret));
break;
}
if (verbose > 4)
- fprintf(stderr, "XD[%d](%s)\n", getpid(),
+ fprintf(stderr, "XD[%ld](%s)\n", (long) getpid(),
playback_name(base+j));
}
krb5_db_fini(ccontext);
@@ -949,13 +952,13 @@ do_testing(db, passes, verbose, timing, rcases, check, save_db, dontclean,
for (i=0; i<nprocs; i++) {
if (waitpid(children[i], &existat, 0) == children[i]) {
if (verbose)
- fprintf(stderr, "%d finished with %d\n", children[i],
- existat);
+ fprintf(stderr, "%ld finished with %d\n",
+ (long) children[i], existat);
if (existat)
kret = KRB5KRB_ERR_GENERIC;
}
else
- fprintf(stderr, "Wait for %d failed\n", children[i]);
+ fprintf(stderr, "Wait for %ld failed\n", (long) children[i]);
}
}
diff --git a/src/lib/krb4/ChangeLog b/src/lib/krb4/ChangeLog
index 187505b..a55bd6c 100644
--- a/src/lib/krb4/ChangeLog
+++ b/src/lib/krb4/ChangeLog
@@ -1,3 +1,106 @@
+2001-10-28 Ezra Peisach <epeisach@mit.edu>
+
+ * rd_svc_key.c (krb54_get_service_keyblock): If the keytab
+ encryption type is a non-raw des3 key, bash its enctype. This
+ matches kdc/kerberos_v4.c.
+ [pullup from trunk]
+
+2001-01-26 Tom Yu <tlyu@mit.edu>
+
+ * dest_tkt.c: Clean up uid handling. Fix stat checks.
+
+ * in_tkt.c: Clean up uid handling. Fix stat checks.
+
+ * tf_util.c: Clean up uid handling. Fix stat checks.
+
+2000-06-09 Tom Yu <tlyu@mit.edu>
+
+ * configure.in: Check for strdup().
+
+ * kparse.c: Remove strsave() and replace with an inlined static
+ version of strdup() if HAVE_STRDUP is not defined.
+
+ * g_ad_tkt.c (get_ad_tkt): ptr may be signed; cast while
+ assigning to larger types. [from Charles Hannum by way of
+ ghudson]
+
+2000-05-23 Ken Raeburn <raeburn@mit.edu>
+
+ * decomp_tkt.c (dcmp_tkt_int): Add a couple more length checks.
+ Reject names that are exactly ANAME_SZ (etc) bytes long without
+ the trailing nul, because krb.h says the *_SZ macros are "maximum
+ sizes ... +1".
+ * mk_auth.c (krb_mk_auth): Force nul termination of inst.
+ * sendauth.c (krb_sendauth): Force nul termination of srv_inst.
+
+2000-05-11 Nalin Dahyabhai <nalin@redhat.com>
+
+ * Password.c (GetUserInfo): Truncate user name if it's too long
+ to fit.
+ * cr_auth_repl.c (cr_auth_reply): Bail if the reply packet won't
+ fit into its buffer.
+ * cr_ciph.c (create_ciph): Ditto.
+ * cr_death_pkt.c (krb_create_death_packet): Truncate "aname" to
+ make it fit into the packet's data buffer.
+ * cr_err_repl.c (cr_err_reply): Bail if the reply packet won't
+ fit into its buffer.
+ * cr_tkt.c (krb_create_ticket): Ditto.
+ * g_ad_tkt.c (get_ad_tkt): Stop if data being added to buffer
+ would overflow it. Add more sanity checks when decomposing the
+ credential received.
+ * g_in_tkt.c (krb_mk_in_tkt_preauth): Bail if the request packet
+ won't fit into its buffer.
+ * g_krbhst.c (get_krbhst_default): Truncate the guessed KDC's
+ hostname if it is too long.
+ * g_pw_in_tkt.c: Remove useless strcpy() prototype.
+ * kntoln.c (krb_kntoln): Don't overflow buffer "lname".
+ * mk_err.c (krb_mk_err): Return the needed buffer length if the
+ pointer passed in is NULL.
+ * mk_req.c (krb_mk_req): Bail if the reply packet won't
+ fit into its buffer.
+ * rd_req.c (krb_rd_req): Sanity check the realm name being read,
+ and truncate the service name, nstance, and realm from credential
+ read from keytab.
+ * realmofhost.c (krb_realmofhost): Truncate realm names read
+ from file if they are too long.
+ * send_to_kdc.c (send_to_kdc): Truncate passed-in realm name.
+
+2000-05-08 Ken Raeburn <raeburn@mit.edu>
+
+ * rd_req.c (krb_rd_req): Mask length byte with 0xff in case the
+ length is over 127 and char is signed.
+
+ * recvauth.c (krb_recvauth): If the number of bytes to be read
+ from the net is not positive, just return an error.
+
+2000-05-03 Tom Yu <tlyu@mit.edu>
+
+ * cr_tkt.c: Delete prototype for krb_cr_tkt_int(), since the
+ definition is K&R style and contains narrow types. Thank you
+ HP/UX for having a compiler that actually makes this a fatal
+ error.
+
+2000-04-28 Ken Raeburn <raeburn@mit.edu>
+ Nalin Dahyabhai <nalin@redhat.com>
+
+ * dest_tkt.c (dest_tkt): Don't overflow buffer "shmidname".
+ * in_tkt.c (in_tkt): Don't overflow buffer "shmidname".
+ * kuserok.c (kuserok): Don't overflow buffer "pbuf".
+ * tf_util.c (tf_init): Don't overflow buffer "shmidname".
+ * win_store.c (krb__get_cnffile): Don't overflow buffers "defname"
+ and "cnfname".
+ (krb__get_realmsfile): Don't overflow buffers "defname" and
+ "realmsname".
+
+2000-04-28 Tom Yu <tlyu@mit.edu>
+
+ * rd_req.c (krb_rd_req): Fix some uses of strcpy().
+
+2000-03-12 Ezra Peisach <epeisach@mit.edu>
+
+ * cr_tkt.c (krb_cr_tkt_int): Add static prototype.
+ * decomp_tkt.c: (dcmp_tkt_int): Add static prototype
+
1999-10-26 Tom Yu <tlyu@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/krb4/Password.c b/src/lib/krb4/Password.c
index b296630..5862e0e 100644
--- a/src/lib/krb4/Password.c
+++ b/src/lib/krb4/Password.c
@@ -177,7 +177,8 @@ OSErr GetUserInfo( char *password )
// already got a password, just get the initial ticket
//////////////////////////////////////////////////////
if (*gPassword) {
- strcpy (UserName, krb_get_default_user( ));
+ strncpy (UserName, krb_get_default_user( ), sizeof(UserName)-1);
+ UserName[sizeof(UserName) - 1] = '\0';
/* FIXME jcm - if we have a password then no dialog
comes up for setting the uinstance. */
rc = kname_parse(uname, uinst, realm, UserName);
@@ -201,7 +202,8 @@ OSErr GetUserInfo( char *password )
}
// Insert user's name in dialog
- strcpy (UserName, krb_get_default_user( ));
+ strncpy (UserName, krb_get_default_user( ), sizeof(UserName) - 1);
+ UserName[sizeof(UserName) - 1] = '\0';
if (*UserName) {
tempStr[0] = strlen(UserName);
memcpy( &(tempStr[1]), UserName, tempStr[0]);
@@ -417,7 +419,8 @@ CacheInitialTicket( serviceName )
if (!serviceName || (serviceName[0] == '\0'))
return err;
- strcpy (UserName, krb_get_default_user());
+ strncpy (UserName, krb_get_default_user(), sizeof(UserName) - 1);
+ UserName[sizeof(UserName) - 1] = '\0';
err = kname_parse(uname, uinst, urealm, UserName);
if (err) return err;
diff --git a/src/lib/krb4/configure.in b/src/lib/krb4/configure.in
index 0434c7d..59937e1 100644
--- a/src/lib/krb4/configure.in
+++ b/src/lib/krb4/configure.in
@@ -38,7 +38,7 @@ else
AC_DEFINE(BITS32)
fi
AC_DEFINE(KRB4_USE_KEYTAB)
-AC_HAVE_FUNCS(strsave seteuid setreuid setresuid)
+AC_HAVE_FUNCS(strdup seteuid setreuid setresuid)
AC_PROG_AWK
KRB5_BUILD_LIBOBJS
KRB5_BUILD_LIBRARY_WITH_DEPS
diff --git a/src/lib/krb4/cr_auth_repl.c b/src/lib/krb4/cr_auth_repl.c
index 5203506..a0562d9 100644
--- a/src/lib/krb4/cr_auth_repl.c
+++ b/src/lib/krb4/cr_auth_repl.c
@@ -83,6 +83,16 @@ create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher)
if (n != 0)
*v = 3;
+ /* Make sure the response will actually fit into its buffer. */
+ if(sizeof(pkt->dat) < 3 + strlen(pname) +
+ 1 + strlen(pinst) +
+ 1 + strlen(prealm) +
+ 4 + 1 + 4 +
+ 1 + 2 + cipher->length) {
+ pkt->length = 0;
+ return NULL;
+ }
+
/* Add the basic info */
(void) strcpy((char *) (pkt->dat+2), pname);
pkt->length = 3 + strlen(pname);
diff --git a/src/lib/krb4/cr_ciph.c b/src/lib/krb4/cr_ciph.c
index d15a4e0..d9c7512 100644
--- a/src/lib/krb4/cr_ciph.c
+++ b/src/lib/krb4/cr_ciph.c
@@ -71,6 +71,17 @@ create_ciph(c, session, service, instance, realm, life, kvno, tkt,
ptr = (char *) c->dat;
+ if(sizeof(c->dat) / 8 < (8 +
+ strlen(service) + 1 +
+ strlen(instance) + 1 +
+ strlen(realm) + 1 +
+ 1 + 1 + 1 +
+ tkt->length + 4 +
+ 7) / 8) {
+ c->length = 0;
+ return(KFAILURE);
+ }
+
memcpy(ptr, (char *) session, 8);
ptr += 8;
diff --git a/src/lib/krb4/cr_death_pkt.c b/src/lib/krb4/cr_death_pkt.c
index 8daa2d6..c356267 100644
--- a/src/lib/krb4/cr_death_pkt.c
+++ b/src/lib/krb4/cr_death_pkt.c
@@ -52,8 +52,9 @@ krb_create_death_packet(a_name)
*v = (unsigned char) KRB_PROT_VERSION;
*t = (unsigned char) AUTH_MSG_DIE;
*t |= HOST_BYTE_ORDER;
- (void) strcpy((char *) (pkt->dat+2),a_name);
- pkt->length = 3 + strlen(a_name);
+ (void) strncpy((char *) (pkt->dat+2),a_name,sizeof(pkt->dat) - 3);
+ pkt->dat[sizeof(pkt->dat) - 1] = '\0';
+ pkt->length = 3 + strlen(pkt->dat+2);
return pkt;
}
#endif /* DEBUG */
diff --git a/src/lib/krb4/cr_err_repl.c b/src/lib/krb4/cr_err_repl.c
index 7f68bda..54e87d8 100644
--- a/src/lib/krb4/cr_err_repl.c
+++ b/src/lib/krb4/cr_err_repl.c
@@ -78,6 +78,15 @@ cr_err_reply(pkt,pname,pinst,prealm,time_ws,e,e_string)
*t = (unsigned char) AUTH_MSG_ERR_REPLY;
*t |= HOST_BYTE_ORDER;
+ /* Make sure the reply will fit into the buffer. */
+ if(sizeof(pkt->dat) < 3 + strlen(pname) +
+ 1 + strlen(pinst) +
+ 1 + strlen(prealm) +
+ 4 + 4 +
+ 1 + strlen(e_string)) {
+ pkt->length = 0;
+ return;
+ }
/* Add the basic info */
(void) strcpy((char *) (pkt->dat+2),pname);
pkt->length = 3 + strlen(pname);
diff --git a/src/lib/krb4/cr_tkt.c b/src/lib/krb4/cr_tkt.c
index a8224f8..34bec48 100644
--- a/src/lib/krb4/cr_tkt.c
+++ b/src/lib/krb4/cr_tkt.c
@@ -14,6 +14,7 @@
#include "prot.h"
#include <string.h>
#include <krb5.h>
+
/*
* Create ticket takes as arguments information that should be in a
* ticket, and the KTEXT object in which the ticket should be
@@ -134,6 +135,23 @@ krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress,
register char *data; /* running index into ticket */
tkt->length = 0; /* Clear previous data */
+
+ /* Check length of ticket */
+ if (sizeof(tkt->dat) < (sizeof(flags) +
+ 1 + strlen(pname) +
+ 1 + strlen(pinstance) +
+ 1 + strlen(prealm) +
+ 4 + /* address */
+ 8 + /* session */
+ 1 + /* life */
+ 4 + /* issue time */
+ 1 + strlen(sname) +
+ 1 + strlen(sinstance) +
+ 7) / 8) { /* roundoff */
+ memset(tkt->dat, 0, sizeof(tkt->dat));
+ return KFAILURE /* XXX */;
+ }
+
flags |= HOST_BYTE_ORDER; /* ticket byte order */
memcpy((char *) (tkt->dat), (char *) &flags, sizeof(flags));
data = ((char *)tkt->dat) + sizeof(flags);
diff --git a/src/lib/krb4/decomp_tkt.c b/src/lib/krb4/decomp_tkt.c
index 03398ac..06e9e31 100644
--- a/src/lib/krb4/decomp_tkt.c
+++ b/src/lib/krb4/decomp_tkt.c
@@ -19,6 +19,12 @@
extern int krb_debug;
#endif
+static int dcmp_tkt_int PROTOTYPE((KTEXT tkt, unsigned char *flags,
+ char *pname, char *pinstance, char *prealm,
+ unsigned KRB4_32 *paddress, C_Block session,
+ int *life, unsigned KRB4_32 *time_sec,
+ char *sname, char *sinstance, C_Block key,
+ Key_schedule key_s, krb5_keyblock *k5key));
/*
* This routine takes a ticket and pointers to the variables that
* should be filled in based on the information in the ticket. It
@@ -186,17 +192,17 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1))
tkt_swap_bytes++;
- if (strlen(ptr) > ANAME_SZ)
+ if (strlen(ptr) >= ANAME_SZ)
return(KFAILURE);
(void) strcpy(pname,ptr); /* pname */
ptr += strlen(pname) + 1;
- if (strlen(ptr) > INST_SZ)
+ if (strlen(ptr) >= INST_SZ)
return(KFAILURE);
(void) strcpy(pinstance,ptr); /* instance */
ptr += strlen(pinstance) + 1;
- if (strlen(ptr) > REALM_SZ)
+ if (strlen(ptr) >= REALM_SZ)
return(KFAILURE);
(void) strcpy(prealm,ptr); /* realm */
ptr += strlen(prealm) + 1;
@@ -223,9 +229,13 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
if (tkt_swap_bytes)
*time_sec = krb4_swab32(*time_sec);
+ if (strlen(ptr) >= ANAME_SZ)
+ return KFAILURE;
(void) strcpy(sname,ptr); /* service name */
ptr += 1 + strlen(sname);
+ if (strlen (ptr) >= INST_SZ)
+ return KFAILURE;
(void) strcpy(sinstance,ptr); /* instance */
ptr += 1 + strlen(sinstance);
diff --git a/src/lib/krb4/dest_tkt.c b/src/lib/krb4/dest_tkt.c
index 7057818..7887822 100644
--- a/src/lib/krb4/dest_tkt.c
+++ b/src/lib/krb4/dest_tkt.c
@@ -1,14 +1,29 @@
/*
- * dest_tkt.c
+ * lib/krb4/dest_tkt.c
*
- * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1985, 1986, 1987, 1988, 2000, 2001 by the Massachusetts
+ * Institute of Technology. All Rights Reserved.
*
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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 "mit-copyright.h"
#include "krb.h"
#include <stdio.h>
#include <string.h>
@@ -17,12 +32,29 @@
#ifdef TKT_SHMEM
#include <sys/param.h>
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#include <errno.h>
#ifndef O_SYNC
#define O_SYNC 0
#endif
+#ifdef HAVE_SETEUID
+#define do_seteuid(e) seteuid((e))
+#else
+#ifdef HAVE_SETRESUID
+#define do_seteuid(e) setresuid(-1, (e), -1)
+#else
+#ifdef HAVE_SETREUID
+#define do_seteuid(e) setreuid(geteuid(), (e))
+#else
+#define do_seteuid(e) (errno = EPERM, -1)
+#endif
+#endif
+#endif
+
/*
* dest_tkt() is used to destroy the ticket store upon logout.
* If the ticket file does not exist, dest_tkt() returns RET_TKFIL.
@@ -38,10 +70,13 @@ dest_tkt()
char *file = TKT_FILE;
int i,fd;
extern int errno;
- struct stat statb;
+ int ret;
+ struct stat statpre, statpost;
char buf[BUFSIZ];
+ uid_t me, metoo;
#ifdef TKT_SHMEM
char shmidname[MAXPATHLEN];
+ size_t shmidlen;
#endif /* TKT_SHMEM */
/* If ticket cache selector is null, use default cache. */
@@ -49,22 +84,56 @@ dest_tkt()
file = tkt_string();
errno = 0;
- if (lstat(file,&statb) < 0)
- goto out;
+ ret = KSUCCESS;
+ me = getuid();
+ metoo = geteuid();
- if (!(statb.st_mode & S_IFREG)
-#ifdef notdef
- || statb.st_mode & 077
-#endif
- )
+ if (lstat(file, &statpre) < 0)
+ return (errno == ENOENT) ? RET_TKFIL : KFAILURE;
+ /*
+ * This does not guard against certain cases that are vulnerable
+ * to race conditions, such as world-writable or group-writable
+ * directories that are not stickybitted, or untrusted path
+ * components. In all other cases, the following checks should be
+ * sufficient. It is assumed that the aforementioned certain
+ * vulnerable cases are unlikely to arise on a well-administered
+ * system where the user is not deliberately being stupid.
+ */
+ if (!(statpre.st_mode & S_IFREG) || me != statpre.st_uid
+ || statpre.st_nlink != 1)
+ return KFAILURE;
+ /*
+ * Yes, we do uid twiddling here. It's not optimal, but some
+ * applications may expect that the ruid is what should really own
+ * the ticket file, e.g. setuid applications.
+ */
+ if (me != metoo && do_seteuid(me) < 0)
+ return KFAILURE;
+ if ((fd = open(file, O_RDWR|O_SYNC, 0)) < 0) {
+ ret = (errno == ENOENT) ? RET_TKFIL : KFAILURE;
goto out;
-
- if ((fd = open(file, O_RDWR|O_SYNC, 0)) < 0)
+ }
+ /*
+ * Do some additional paranoid things. The worst-case situation
+ * is that a user may be fooled into opening a non-regular file
+ * briefly if the file is in a directory with improper
+ * permissions.
+ */
+ if (fstat(fd, &statpost) < 0) {
+ (void)close(fd);
+ ret = KFAILURE;
+ goto out;
+ }
+ if (statpre.st_dev != statpost.st_dev
+ || statpre.st_ino != statpost.st_ino) {
+ (void)close(fd);
+ errno = 0;
+ ret = KFAILURE;
goto out;
+ }
memset(buf, 0, BUFSIZ);
-
- for (i = 0; i < statb.st_size; i += BUFSIZ)
+ for (i = 0; i < statpost.st_size; i += BUFSIZ)
if (write(fd, buf, BUFSIZ) != BUFSIZ) {
#ifndef NO_FSYNC
(void) fsync(fd);
@@ -81,16 +150,22 @@ dest_tkt()
(void) unlink(file);
out:
- if (errno == ENOENT) return RET_TKFIL;
- else if (errno != 0) return KFAILURE;
+ if (me != metoo && do_seteuid(metoo) < 0)
+ return KFAILURE;
+ if (ret != KSUCCESS)
+ return ret;
+
#ifdef TKT_SHMEM
/*
* handle the shared memory case
*/
- (void) strcpy(shmidname, file);
- (void) strcat(shmidname, ".shm");
- if ((i = krb_shm_dest(shmidname)) != KSUCCESS)
- return(i);
-#endif /* TKT_SHMEM */
- return(KSUCCESS);
+ shmidlen = strlen(file) + sizeof(".shm");
+ if (shmidlen > sizeof(shmidname))
+ return RET_TKFIL;
+ (void)strcpy(shmidname, file);
+ (void)strcat(shmidname, ".shm");
+ return krb_shm_dest(shmidname);
+#else /* !TKT_SHMEM */
+ return KSUCCESS;
+#endif /* !TKT_SHMEM */
}
diff --git a/src/lib/krb4/g_ad_tkt.c b/src/lib/krb4/g_ad_tkt.c
index b3abb2d..afcd0c6 100644
--- a/src/lib/krb4/g_ad_tkt.c
+++ b/src/lib/krb4/g_ad_tkt.c
@@ -19,6 +19,19 @@
extern int krb_debug;
extern int swap_bytes;
+/* Return the length of the string if a NUL is found within the first
+ * max_len bytes, otherwise, -1. */
+static int krb_strnlen(const char *str, int max_len)
+{
+ int i;
+ for(i = 0; i < max_len; i++) {
+ if(str[i] == '\0') {
+ return i;
+ }
+ }
+ return -1;
+}
+
/*
* get_ad_tkt obtains a new service ticket from Kerberos, using
* the ticket-granting ticket which must be in the ticket file.
@@ -136,11 +149,22 @@ get_ad_tkt(service,sinstance,realm,lifetime)
return(AD_NOTGT);
/* timestamp */ /* FIXME -- always 0 now, should we fill it in??? */
+ if(pkt->length + 4 > sizeof(pkt->dat))
+ return(INTK_ERR);
memcpy((char *) (pkt->dat+pkt->length), (char *) &time_ws, 4);
pkt->length += 4;
+
+ if(pkt->length + 1 > sizeof(pkt->dat))
+ return(INTK_ERR);
*(pkt->dat+(pkt->length)++) = (char) lifetime;
+
+ if(pkt->length + 1 + strlen(service) > sizeof(pkt->dat))
+ return(INTK_ERR);
(void) strcpy((char *) (pkt->dat+pkt->length),service);
pkt->length += 1 + strlen(service);
+
+ if(pkt->length + 1 + strlen(sinstance) > sizeof(pkt->dat))
+ return(INTK_ERR);
(void) strcpy((char *)(pkt->dat+pkt->length),sinstance);
pkt->length += 1 + strlen(sinstance);
@@ -199,18 +223,27 @@ get_ad_tkt(service,sinstance,realm,lifetime)
memcpy((char *)ses, ptr, 8);
ptr += 8;
- (void) strcpy(s_name,ptr);
+ if(krb_strnlen(ptr, sizeof(s_name)) < 0)
+ return RD_AP_MODIFIED;
+ (void) strncpy(s_name,ptr,sizeof(s_name) - 1);
+ s_name[sizeof(s_name) - 1] = '\0';
ptr += strlen(s_name) + 1;
- (void) strcpy(s_instance,ptr);
+ if(krb_strnlen(ptr, sizeof(s_instance)) < 0)
+ return RD_AP_MODIFIED;
+ (void) strncpy(s_instance,ptr,sizeof(s_instance)-1);
+ s_instance[sizeof(s_instance)-1] = '\0';
ptr += strlen(s_instance) + 1;
- (void) strcpy(rlm,ptr);
+ if(krb_strnlen(ptr, sizeof(rlm)) < 0)
+ return RD_AP_MODIFIED;
+ (void) strncpy(rlm,ptr,sizeof(rlm) - 1);
+ rlm[sizeof(rlm)-1];
ptr += strlen(rlm) + 1;
- lifetime = (unsigned long) ptr[0];
- kvno = (unsigned long) ptr[1];
- tkt->length = (int) ptr[2];
+ lifetime = (unsigned char) ptr[0];
+ kvno = (unsigned char) ptr[1];
+ tkt->length = (unsigned char) ptr[2];
ptr += 3;
memcpy((char *)(tkt->dat), ptr, tkt->length);
ptr += tkt->length;
diff --git a/src/lib/krb4/g_in_tkt.c b/src/lib/krb4/g_in_tkt.c
index c9d6183..361273c 100644
--- a/src/lib/krb4/g_in_tkt.c
+++ b/src/lib/krb4/g_in_tkt.c
@@ -152,6 +152,20 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
*t = (unsigned char) AUTH_MSG_KDC_REQUEST;
*t |= HOST_BYTE_ORDER;
+ /* Make sure the ticket data will fit into the buffer. */
+ if(sizeof(pkt->dat) < 2 + /* protocol version + flags */
+ 3 + strlen(user) +
+ 1 + strlen(instance) +
+ 1 + strlen(realm) +
+ 4 + /* timestamp */
+ 1 + /* lifetime */
+ 1 + strlen(service) +
+ 1 + strlen(sinstance) +
+ preauth_len) {
+ pkt->length = 0;
+ return INTK_ERR;
+ }
+
/* Now for the variable info */
(void) strcpy((char *)(pkt->dat+2),user); /* aname */
pkt->length = 3 + strlen(user);
diff --git a/src/lib/krb4/g_krbhst.c b/src/lib/krb4/g_krbhst.c
index 529ac07..4e0fd6d 100644
--- a/src/lib/krb4/g_krbhst.c
+++ b/src/lib/krb4/g_krbhst.c
@@ -52,9 +52,11 @@ get_krbhst_default(h, r, n)
int n;
{
if (n==1) {
- (void) strcpy(h,KRB_HOST);
- (void) strcat(h,".");
- (void) strcat(h,r); /* KRB_HOST.REALM (ie. kerberos.CYGNUS.COM) */
+ (void) strncpy(h,KRB_HOST,MAXHOSTNAMELEN-1);
+ h[MAXHOSTNAMELEN-1] = '\0';
+ (void) strncat(h,".",MAXHOSTNAMELEN-1-strlen(h));
+ (void) strncat(h,r,MAXHOSTNAMELEN-1-strlen(h));
+ /* KRB_HOST.REALM (ie. kerberos.CYGNUS.COM) */
return(KSUCCESS);
}
else
diff --git a/src/lib/krb4/g_krbrlm.c b/src/lib/krb4/g_krbrlm.c
index 983150c..c750231 100644
--- a/src/lib/krb4/g_krbrlm.c
+++ b/src/lib/krb4/g_krbrlm.c
@@ -44,7 +44,8 @@ krb_get_lrealm(r,n)
cnffile = krb__get_cnffile();
if (!cnffile) {
if (n == 1) {
- (void) strcpy(r, KRB_REALM);
+ (void) strncpy(r, KRB_REALM, REALM_SZ);
+ r[REALM_SZ - 1] = '\0';
return(KSUCCESS);
}
else
diff --git a/src/lib/krb4/g_pw_in_tkt.c b/src/lib/krb4/g_pw_in_tkt.c
index 6723df8..13f762b 100644
--- a/src/lib/krb4/g_pw_in_tkt.c
+++ b/src/lib/krb4/g_pw_in_tkt.c
@@ -176,7 +176,6 @@ krb_get_pw_in_tkt_preauth(user,instance,realm,service,sinstance,life,password)
#include <signal.h>
#include <setjmp.h>
#else
-char *strcpy();
int strcmp();
#endif
#if defined(__svr4__) || defined(__SVR4)
diff --git a/src/lib/krb4/in_tkt.c b/src/lib/krb4/in_tkt.c
index ea17be8..a34f318 100644
--- a/src/lib/krb4/in_tkt.c
+++ b/src/lib/krb4/in_tkt.c
@@ -1,14 +1,29 @@
/*
- * in_tkt.c
+ * lib/krb4/in_tkt.c
*
- * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
+ * Copyright 1985, 1986, 1987, 1988, 2000, 2001 by the Massachusetts
+ * Institute of Technology. All Rights Reserved.
*
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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 "mit-copyright.h"
#include <stdio.h>
#include <string.h>
#include "krb.h"
@@ -34,7 +49,7 @@ extern int krb_debug;
#define do_seteuid(e) seteuid((e))
#else
#ifdef HAVE_SETRESUID
-#define do_seteuid(e) setresuid(getuid(), (e), geteuid())
+#define do_seteuid(e) setresuid(-1, (e), -1)
#else
#ifdef HAVE_SETREUID
#define do_seteuid(e) setreuid(geteuid(), (e))
@@ -55,7 +70,7 @@ in_tkt(pname,pinst)
{
int tktfile;
uid_t me, metoo, getuid(), geteuid();
- struct stat buf;
+ struct stat statpre, statpost;
int count;
char *file = TKT_FILE;
int fd;
@@ -72,20 +87,49 @@ in_tkt(pname,pinst)
me = getuid ();
metoo = geteuid();
- if (lstat(file,&buf) == 0) {
- if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
- buf.st_mode & 077) {
+ if (lstat(file, &statpre) == 0) {
+ if (statpre.st_uid != me || !(statpre.st_mode & S_IFREG)
+ || statpre.st_nlink != 1 || statpre.st_mode & 077) {
if (krb_debug)
fprintf(stderr,"Error initializing %s",file);
return(KFAILURE);
}
+ /*
+ * Yes, we do uid twiddling here. It's not optimal, but some
+ * applications may expect that the ruid is what should really
+ * own the ticket file, e.g. setuid applications.
+ */
+ if (me != metoo && do_seteuid(me) < 0)
+ return KFAILURE;
/* file already exists, and permissions appear ok, so nuke it */
- if ((fd = open(file, O_RDWR|O_SYNC, 0)) < 0)
+ fd = open(file, O_RDWR|O_SYNC, 0);
+ (void)unlink(file);
+ if (me != metoo && do_seteuid(metoo) < 0)
+ return KFAILURE;
+ if (fd < 0) {
goto out; /* can't zero it, but we can still try truncating it */
+ }
+
+ /*
+ * Do some additional paranoid things. The worst-case
+ * situation is that a user may be fooled into opening a
+ * non-regular file briefly if the file is in a directory with
+ * improper permissions.
+ */
+ if (fstat(fd, &statpost) < 0) {
+ (void)close(fd);
+ goto out;
+ }
+ if (statpre.st_dev != statpost.st_dev
+ || statpre.st_ino != statpost.st_ino) {
+ (void)close(fd);
+ errno = 0;
+ goto out;
+ }
memset(charbuf, 0, sizeof(charbuf));
- for (i = 0; i < buf.st_size; i += sizeof(charbuf))
+ for (i = 0; i < statpost.st_size; i += sizeof(charbuf))
if (write(fd, charbuf, sizeof(charbuf)) != sizeof(charbuf)) {
#ifndef NO_FSYNC
(void) fsync(fd);
@@ -117,12 +161,7 @@ in_tkt(pname,pinst)
/* Set umask to ensure that we have write access on the created
ticket file. */
mask = umask(077);
- if ((tktfile = creat(file,0600)) < 0) {
- umask(mask);
- if (krb_debug)
- fprintf(stderr,"Error initializing %s",TKT_FILE);
- return(KFAILURE);
- }
+ tktfile = open(file, O_RDWR|O_SYNC|O_CREAT|O_EXCL, 0600);
umask(mask);
if (me != metoo) {
if (do_seteuid(metoo) < 0) {
@@ -134,19 +173,11 @@ in_tkt(pname,pinst)
if (krb_debug)
printf("swapped UID's %d and %d\n",me,metoo);
}
- if (lstat(file,&buf) < 0) {
+ if (tktfile < 0) {
if (krb_debug)
fprintf(stderr,"Error initializing %s",TKT_FILE);
return(KFAILURE);
}
-
- if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
- buf.st_mode & 077) {
- if (krb_debug)
- fprintf(stderr,"Error initializing %s",TKT_FILE);
- return(KFAILURE);
- }
-
count = strlen(pname)+1;
if (write(tktfile,pname,count) != count) {
(void) close(tktfile);
@@ -159,8 +190,9 @@ in_tkt(pname,pinst)
}
(void) close(tktfile);
#ifdef TKT_SHMEM
- (void) strcpy(shmidname, file);
- (void) strcat(shmidname, ".shm");
+ (void) strncpy(shmidname, file, sizeof(shmidname) - 1);
+ shmidname[sizeof(shmidname) - 1] = '\0';
+ (void) strncat(shmidname, ".shm", sizeof(shmidname) - 1 - strlen(shmidname));
return(krb_shm_create(shmidname));
#else /* !TKT_SHMEM */
return(KSUCCESS);
diff --git a/src/lib/krb4/kntoln.c b/src/lib/krb4/kntoln.c
index 8b6cdfe..f86599c 100644
--- a/src/lib/krb4/kntoln.c
+++ b/src/lib/krb4/kntoln.c
@@ -38,6 +38,10 @@
* KSUCCESS if all goes well, otherwise KFAILURE.
*/
+/* The definition of MAX_USERNAME here MUST agree with kuserok.c, or bad
+ * things will happen. */
+#define MAX_USERNAME 10
+
krb_kntoln(ad,lname)
AUTH_DAT *ad;
char *lname;
@@ -51,6 +55,7 @@ krb_kntoln(ad,lname)
return(KFAILURE);
if (strcmp(ad->prealm,lrealm))
return(KFAILURE);
- (void) strcpy(lname,ad->pname);
+ (void) strncpy(lname,ad->pname,MAX_USERNAME-1);
+ lname[MAX_USERNAME - 1] = '\0';
return(KSUCCESS);
}
diff --git a/src/lib/krb4/kparse.c b/src/lib/krb4/kparse.c
index 98e48fb..e72295c 100644
--- a/src/lib/krb4/kparse.c
+++ b/src/lib/krb4/kparse.c
@@ -54,8 +54,8 @@
static char *strutol();
-#ifndef HAVE_STRSAVE
-static char *strsave();
+#ifndef HAVE_STRDUP
+static char *strdup();
#endif
#ifndef HAVE_STDLIB_H
extern char *malloc();
@@ -104,7 +104,7 @@ int fGetParameterSet( fp,parm,parmcount )
keyword);
return(PS_BAD_KEYWORD);
}
- parm[i].value = strsave( value );
+ parm[i].value = strdup(value);
break;
}
}
@@ -552,34 +552,6 @@ int fGetChar(fp)
return(ch);
}
-
-/*
- * Routine Name: strsave
- *
- * Function: return a pointer to a saved copy of the
- * input string. the copy will be allocated
- * as large as necessary.
- *
- * Explicit Parameters: pointer to string to save
- *
- * Implicit Parameters: None
- *
- * External Procedures: malloc,strcpy,strlen
- *
- * Side Effects: None
- *
- * Return Value: pointer to copied string
- *
- */
-#ifndef HAVE_STRSAVE
-static char * strsave(p)
- char *p;
-{
- return(strcpy(malloc(strlen(p)+1),p));
-}
-#endif
-
-
/*
* strutol changes all characters in a string to lower case, in place.
* the pointer to the beginning of the string is returned.
@@ -770,3 +742,42 @@ main(argc,argv)
exit(0);
}
#endif
+
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* based on @(#)strdup.c 5.3 (Berkeley) 6/1/90 */
+
+#ifndef HAVE_STRDUP
+static char *
+strdup(str)
+ const char *str;
+{
+ int len;
+ char *copy;
+
+ if (!str)
+ return((char *)0);
+ len = strlen(str) + 1;
+ if (!(copy = malloc((u_int)len)))
+ return((char *)0);
+ memcpy(copy, str, len);
+ return(copy);
+}
+#endif
diff --git a/src/lib/krb4/kuserok.c b/src/lib/krb4/kuserok.c
index 0aee893..20587cb 100644
--- a/src/lib/krb4/kuserok.c
+++ b/src/lib/krb4/kuserok.c
@@ -118,8 +118,11 @@ kuserok(kdata, luser)
if ((pwd = getpwnam(luser)) == NULL) {
return(NOTOK);
}
- (void) strcpy(pbuf, pwd->pw_dir);
- (void) strcat(pbuf, "/.klogin");
+ if (strlen (pwd->pw_dir) + sizeof ("/.klogin") >= sizeof (pbuf))
+ return NOTOK;
+ (void) strncpy(pbuf, pwd->pw_dir, sizeof(pbuf) - 1);
+ pbuf[sizeof(pbuf) - 1] = '\0';
+ (void) strncat(pbuf, "/.klogin", sizeof(pbuf) - 1 - strlen(pbuf));
if (access(pbuf, F_OK)) { /* not accessible */
/*
diff --git a/src/lib/krb4/mk_auth.c b/src/lib/krb4/mk_auth.c
index 39a2e2f..a94a25d 100644
--- a/src/lib/krb4/mk_auth.c
+++ b/src/lib/krb4/mk_auth.c
@@ -124,8 +124,10 @@ krb_mk_auth(options, ticket, service, inst, realm, checksum, version, buf)
realm = krb_realm;
}
- if (!(options & KOPT_DONT_CANON))
- (void) strncpy(inst, krb_get_phost(inst), INST_SZ);
+ if (!(options & KOPT_DONT_CANON)) {
+ (void) strncpy(inst, krb_get_phost(inst), INST_SZ - 1);
+ inst[INST_SZ-1] = 0;
+ }
/* get the ticket if desired */
if (!(options & KOPT_DONT_MK_REQ)) {
diff --git a/src/lib/krb4/mk_err.c b/src/lib/krb4/mk_err.c
index e30e299..029aa9f 100644
--- a/src/lib/krb4/mk_err.c
+++ b/src/lib/krb4/mk_err.c
@@ -41,6 +41,14 @@ krb_mk_err(p,e,e_string)
{
u_char *start;
+ /* Just return the buffer length if p is NULL, because writing to the
+ * buffer would be a bad idea. Note that this feature is a change from
+ * previous versions, and can therefore only be used safely in this
+ * source tree, where we know this function supports it. */
+ if(p == NULL) {
+ return 2 + sizeof(e) + strlen(e_string);
+ }
+
start = p;
/* Create fixed part of packet */
diff --git a/src/lib/krb4/mk_req.c b/src/lib/krb4/mk_req.c
index 1936cb2..468dccd 100644
--- a/src/lib/krb4/mk_req.c
+++ b/src/lib/krb4/mk_req.c
@@ -130,6 +130,19 @@ krb_mk_req(authent,service,instance,realm,checksum)
if (retval != KSUCCESS) return (retval);
+ if(sizeof(authent->dat) / 8 < (3 +
+ strlen(realm) + 1 + 2 +
+ 3 + ticket->length +
+ strlen(cr.pname) + 1 +
+ strlen(cr.pinst) + 1 +
+ strlen(myrealm) + 1 +
+ 4 + /* checksum */
+ 4 + /* timestamp */
+ 7) / 8) { /* round-up */
+ authent->length = 0;
+ return KFAILURE;
+ }
+
if (krb_ap_req_debug)
DEB (("%s %s %s %s %s\n", service, instance, realm,
cr.pname, cr.pinst));
diff --git a/src/lib/krb4/rd_req.c b/src/lib/krb4/rd_req.c
index c9b6ac7..09f914d 100644
--- a/src/lib/krb4/rd_req.c
+++ b/src/lib/krb4/rd_req.c
@@ -108,6 +108,19 @@ krb_clear_key_krb5(ctx)
krb5_key = 0;
}
+/* A helper function to let us see if a buffer is properly terminated. */
+static int
+krb_strnlen(const char *str, size_t max_len)
+{
+ int i = 0;
+ for(i = 0; i < max_len; i++) {
+ if(str[i] == '\0') {
+ return i;
+ }
+ }
+ return -1;
+}
+
/*
* krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or
* AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(),
@@ -184,6 +197,8 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
krb5_keyblock keyblock;
int status;
+ tkt->mbz = req_id->mbz = 0;
+
if (authent->length <= 0)
return(RD_AP_MODIFIED);
@@ -219,8 +234,13 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
mutual = 0;
#endif /* lint */
s_kvno = *ptr++; /* get server key version */
- (void) strcpy(realm,ptr); /* And the realm of the issuing KDC */
- ptr += strlen(ptr) + 1; /* skip the realm "hint" */
+ if(krb_strnlen(ptr, sizeof(realm)) < 0) {
+ return RD_AP_MODIFIED; /* must have been modified, the client wouldn't
+ try to trick us with wacky data */
+ }
+ (void) strncpy(realm,ptr,REALM_SZ); /* And the realm of the issuing KDC */
+ realm[REALM_SZ-1] = '\0';
+ ptr += strlen(realm) + 1; /* skip the realm "hint" */
/*
* If "fn" is NULL, key info should already be set; don't
@@ -249,13 +269,16 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
return(RD_AP_UNDEC);
#endif /* !NOENCRYPTION */
- (void) strcpy(st_rlm,realm);
- (void) strcpy(st_nam,service);
- (void) strcpy(st_inst,instance);
+ (void) strncpy(st_rlm,realm, sizeof(st_rlm) - 1);
+ st_rlm[sizeof(st_rlm) - 1] = '\0';
+ (void) strncpy(st_nam,service, sizeof(st_nam) - 1);
+ st_nam[sizeof(st_nam) - 1] = '\0';
+ (void) strncpy(st_inst,instance, sizeof(st_inst) - 1);
+ st_inst[sizeof(st_inst) - 1] = '\0';
}
/* Get ticket from authenticator */
- tkt->length = (int) *ptr++;
+ tkt->length = (int) *ptr++ & 0xff;
if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length)
return(RD_AP_MODIFIED);
memcpy((char *)(tkt->dat), ptr+1, tkt->length);
@@ -324,13 +347,16 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
#define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED);
ptr = (char *) req_id->dat;
- (void) strcpy(r_aname,ptr); /* Authentication name */
+ (void) strncpy(r_aname,ptr,ANAME_SZ); /* Authentication name */
+ r_aname[ANAME_SZ-1] = '\0';
ptr += strlen(r_aname)+1;
check_ptr();
- (void) strcpy(r_inst,ptr); /* Authentication instance */
+ (void) strncpy(r_inst,ptr,INST_SZ); /* Authentication instance */
+ r_inst[INST_SZ-1] = '\0';
ptr += strlen(r_inst)+1;
check_ptr();
- (void) strcpy(r_realm,ptr); /* Authentication name */
+ (void) strncpy(r_realm,ptr,REALM_SZ); /* Authentication name */
+ r_realm[REALM_SZ-1] = '\0';
ptr += strlen(r_realm)+1;
check_ptr();
memcpy((char *)&ad->checksum, ptr, 4); /* Checksum */
diff --git a/src/lib/krb4/rd_svc_key.c b/src/lib/krb4/rd_svc_key.c
index 831becd..a9b6fd5 100644
--- a/src/lib/krb4/rd_svc_key.c
+++ b/src/lib/krb4/rd_svc_key.c
@@ -183,7 +183,7 @@ krb54_get_service_keyblock(service,instance,realm,kvno,file,keyblock)
if ((retval = krb5_kt_resolve(krb5__krb4_context, keytabname, &kt_id)))
goto errout;
-
+
if ((retval = krb5_kt_get_entry(krb5__krb4_context, kt_id, princ, kvno,
0, &kt_entry))) {
krb5_kt_close(krb5__krb4_context, kt_id);
@@ -192,6 +192,12 @@ krb54_get_service_keyblock(service,instance,realm,kvno,file,keyblock)
retval = krb5_copy_keyblock_contents(krb5__krb4_context,
&kt_entry.key, keyblock);
+ /* Bash types */
+ /* KLUDGE! If it's a non-raw des3 key, bash its enctype */
+ /* See kdc/kerberos_v4.c */
+ if (keyblock->enctype == ENCTYPE_DES3_CBC_SHA1 ||
+ keyblock->enctype == ENCTYPE_LOCAL_DES3_HMAC_SHA1)
+ keyblock->enctype = ENCTYPE_DES3_CBC_RAW;
krb5_kt_free_entry(krb5__krb4_context, &kt_entry);
krb5_kt_close (krb5__krb4_context, kt_id);
diff --git a/src/lib/krb4/realmofhost.c b/src/lib/krb4/realmofhost.c
index 90e01bb..1e4b786 100644
--- a/src/lib/krb4/realmofhost.c
+++ b/src/lib/krb4/realmofhost.c
@@ -131,14 +131,18 @@ krb_realmofhost(host)
if (domain && (strlen(trans_host) == strlen(domain))
&& !strcasecmp (trans_host, domain)) {
/* got domain match, save for later */
- (void) strcpy (ret_realm, trans_realm);
+ (void) strncpy (ret_realm, trans_realm,
+ sizeof(ret_realm) - 1);
+ ret_realm[sizeof(ret_realm) - 1] = '\0';
continue;
}
} else {
/* want exact match of hostname */
if ((strlen(lhost) == strlen(trans_host)) &&
!strcasecmp (trans_host, lhost)) {
- (void) strcpy (ret_realm, trans_realm);
+ (void) strncpy (ret_realm, trans_realm,
+ sizeof(ret_realm) - 1);
+ ret_realm[sizeof(ret_realm) - 1] = '\0';
break;
}
}
diff --git a/src/lib/krb4/recvauth.c b/src/lib/krb4/recvauth.c
index e62e3f9..2a66656 100644
--- a/src/lib/krb4/recvauth.c
+++ b/src/lib/krb4/recvauth.c
@@ -188,9 +188,12 @@ krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata,
if (i < KRB_SENDAUTH_VLEN) {
/* since we already got the space, and part of the ticket,
we read fewer bytes to get the rest of the ticket */
+ int len_to_read = tkt_len - KRB_SENDAUTH_VLEN + 1 + i;
+ if (len_to_read <= 0)
+ return KFAILURE;
if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN),
- (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
- != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
+ len_to_read)
+ != len_to_read)
return(errno);
} else {
if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) !=
diff --git a/src/lib/krb4/send_to_kdc.c b/src/lib/krb4/send_to_kdc.c
index c7e0fb3..f93b9d0 100644
--- a/src/lib/krb4/send_to_kdc.c
+++ b/src/lib/krb4/send_to_kdc.c
@@ -94,12 +94,13 @@ send_to_kdc(pkt,rpkt,realm)
* local realm.
*/
if (realm)
- (void) strcpy(lrealm, realm);
+ (void) strncpy(lrealm, realm, sizeof(lrealm) - 1);
else
if (krb_get_lrealm(lrealm,1)) {
DEB (("%s: can't get local realm\n", prog));
return(SKDC_CANT);
}
+ lrealm[sizeof(lrealm) - 1] = '\0';
DEB (("lrealm is %s\n", lrealm));
if (SOCKET_INITIALIZE()) {
diff --git a/src/lib/krb4/sendauth.c b/src/lib/krb4/sendauth.c
index 9b8fb39..76c470c 100644
--- a/src/lib/krb4/sendauth.c
+++ b/src/lib/krb4/sendauth.c
@@ -208,7 +208,8 @@ krb_sendauth(options, fd, ticket, service, inst, realm, checksum,
}
/* copy instance into local storage, so mk_auth can canonicalize */
- (void) strncpy(srv_inst, inst, INST_SZ);
+ (void) strncpy(srv_inst, inst, INST_SZ-1);
+ srv_inst[INST_SZ-1] = 0;
rem = krb_mk_auth (options, ticket, service, srv_inst, realm, checksum,
version, packet);
if (rem != KSUCCESS)
diff --git a/src/lib/krb4/tf_util.c b/src/lib/krb4/tf_util.c
index ebf500b..faf115e 100644
--- a/src/lib/krb4/tf_util.c
+++ b/src/lib/krb4/tf_util.c
@@ -1,20 +1,38 @@
/*
- * tf_util.c
+ * lib/krb4/tf_util.c
*
- * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * Copyright 1985, 1986, 1987, 1988, 2000, 2001 by the Massachusetts
+ * Institute of Technology. All Rights Reserved.
*
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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 "mit-copyright.h"
-
#include "krb.h"
#include "k5-int.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#include <sys/stat.h>
#include <fcntl.h>
@@ -44,7 +62,6 @@ char *shmat();
#ifdef NEED_UTIMES
#include <sys/time.h>
-#include <unistd.h>
#ifdef __SCO__
#include <utime.h>
#endif
@@ -62,6 +79,20 @@ int utimes(path, times)
}
#endif
+#ifdef HAVE_SETEUID
+#define do_seteuid(e) seteuid((e))
+#else
+#ifdef HAVE_SETRESUID
+#define do_seteuid(e) setresuid(-1, (e), -1)
+#else
+#ifdef HAVE_SETREUID
+#define do_seteuid(e) setreuid(geteuid(), (e))
+#else
+#define do_seteuid(e) (errno = EPERM, -1)
+#endif
+#endif
+#endif
+
/*
* fd must be initialized to something that won't ever occur as a real
* file descriptor. Since open(2) returns only non-negative numbers as
@@ -149,7 +180,7 @@ int tf_init(tf_name, rw)
int rw;
{
int wflag;
- uid_t me= getuid();
+ uid_t me, metoo;
struct stat stat_buf, stat_buffd;
#ifdef TKT_SHMEM
char shmidname[MAXPATHLEN];
@@ -163,6 +194,7 @@ int tf_init(tf_name, rw)
}
me = getuid();
+ metoo = geteuid();
switch (rw) {
case R_TKT_FIL:
@@ -181,8 +213,9 @@ int tf_init(tf_name, rw)
tf_name = tkt_string();
#ifdef TKT_SHMEM
- (void) strcpy(shmidname, tf_name);
- (void) strcat(shmidname, ".shm");
+ (void) strncpy(shmidname, tf_name, sizeof(shmidname) - 1);
+ shmidname[sizeof(shmidname) - 1] = '\0';
+ (void) strncat(shmidname, ".shm", sizeof(shmidname) - 1 - strlen(shmidname));
#endif /* TKT_SHMEM */
/*
@@ -195,8 +228,30 @@ int tf_init(tf_name, rw)
curpos = sizeof(tfbfr);
#ifdef TKT_SHMEM
+ if (lstat(shmidname, &stat_buf) < 0) {
+ switch (errno) {
+ case ENOENT:
+ return NO_TKT_FIL;
+ default:
+ return TKT_FIL_ACC;
+ }
+ }
+ if (stat_buf.st_uid != me || !(stat_buf.st_mode & S_IFREG)
+ || stat_buf.st_nlink != 1 || stat_buf.st_mode & 077) {
+ return TKT_FIL_ACC;
+ }
+
+ /*
+ * Yes, we do uid twiddling here. It's not optimal, but some
+ * applications may expect that the ruid is what should really own
+ * the ticket file, e.g. setuid applications.
+ */
+ if (me != metoo && do_seteuid(me) < 0)
+ return KFAILURE;
sfp = fopen(shmidname, "r"); /* only need read/write on the
actual tickets */
+ if (me != metoo && do_seteuid(metoo) < 0)
+ return KFAILURE;
if (sfp == 0) {
switch(errno) {
case ENOENT:
@@ -206,10 +261,11 @@ int tf_init(tf_name, rw)
}
}
- /* lstat() and fstat() the file to check that the file we opened is the *
- * one we think it is, and to check ownership. */
- if ((fstat(sfp->_file, &stat_buffd) < 0) ||
- (lstat(shmidname, &stat_buf) < 0)) {
+ /*
+ * fstat() the file to check that the file we opened is the one we
+ * think it is.
+ */
+ if (fstat(fileno(sfp), &stat_buffd) < 0) {
(void) close(fd);
fd = -1;
switch(errno) {
@@ -270,8 +326,25 @@ int tf_init(tf_name, rw)
tmp_shm_addr = krb_shm_addr;
#endif /* TKT_SHMEM */
+ if (lstat(tf_name, &stat_buf) < 0) {
+ switch (errno) {
+ case ENOENT:
+ return NO_TKT_FIL;
+ default:
+ return TKT_FIL_ACC;
+ }
+ }
+ if (stat_buf.st_uid != me || !(stat_buf.st_mode & S_IFREG)
+ || stat_buf.st_nlink != 1 || stat_buf.st_mode & 077) {
+ return TKT_FIL_ACC;
+ }
+
if (wflag) {
+ if (me != metoo && do_seteuid(me) < 0)
+ return KFAILURE;
fd = open(tf_name, O_RDWR, 0600);
+ if (me != metoo && do_seteuid(metoo) < 0)
+ return KFAILURE;
if (fd < 0) {
switch(errno) {
case ENOENT:
@@ -280,10 +353,11 @@ int tf_init(tf_name, rw)
return TKT_FIL_ACC;
}
}
- /* lstat() and fstat() the file to check that the file we opened is the *
- * one we think it is, and to check ownership. */
- if ((fstat(fd, &stat_buffd) < 0) ||
- (lstat(tf_name, &stat_buf) < 0)) {
+ /*
+ * fstat() the file to check that the file we opened is the
+ * one we think it is, and to check ownership.
+ */
+ if (fstat(fd, &stat_buffd) < 0) {
(void) close(fd);
fd = -1;
switch(errno) {
@@ -326,7 +400,11 @@ int tf_init(tf_name, rw)
* for read-only operations and locked for shared access.
*/
+ if (me != metoo && do_seteuid(me) < 0)
+ return KFAILURE;
fd = open(tf_name, O_RDONLY, 0600);
+ if (me != metoo && do_seteuid(metoo) < 0)
+ return KFAILURE;
if (fd < 0) {
switch(errno) {
case ENOENT:
@@ -335,10 +413,11 @@ int tf_init(tf_name, rw)
return TKT_FIL_ACC;
}
}
- /* lstat() and fstat() the file to check that the file we opened is the *
- * one we think it is, and to check ownership. */
- if ((fstat(fd, &stat_buffd) < 0) ||
- (lstat(tf_name, &stat_buf) < 0)) {
+ /*
+ * fstat() the file to check that the file we opened is the one we
+ * think it is, and to check ownership.
+ */
+ if (fstat(fd, &stat_buffd) < 0) {
(void) close(fd);
fd = -1;
switch(errno) {
diff --git a/src/lib/krb4/win_store.c b/src/lib/krb4/win_store.c
index 50507aa..28d11bd 100644
--- a/src/lib/krb4/win_store.c
+++ b/src/lib/krb4/win_store.c
@@ -62,15 +62,17 @@ krb__get_cnffile()
char defname[FILENAME_MAX];
UINT rc;
- rc = GetWindowsDirectory(defname, sizeof(defname));
+ defname[sizeof(defname) - 1] = '\0';
+ rc = GetWindowsDirectory(defname, sizeof(defname) - 1);
assert(rc > 0);
- strcat(defname, "\\");
+ strncat(defname, "\\", sizeof(defname) - 1 - strlen(defname));
- strcat(defname, DEF_KRB_CONF);
+ strncat(defname, DEF_KRB_CONF, sizeof(defname) - 1 - strlen(defname));
+ cnfname[sizeof(cnfname) - 1] = '\0';
GetPrivateProfileString(INI_FILES, INI_KRB_CONF, defname,
- cnfname, sizeof(cnfname), KERBEROS_INI);
+ cnfname, sizeof(cnfname) - 1, KERBEROS_INI);
cnffile = fopen(cnfname, "r");
@@ -94,15 +96,17 @@ krb__get_realmsfile()
char defname[FILENAME_MAX];
UINT rc;
- rc = GetWindowsDirectory(defname, sizeof(defname));
+ defname[sizeof(defname) - 1] = '\0';
+ rc = GetWindowsDirectory(defname, sizeof(defname) - 1);
assert(rc > 0);
- strcat(defname, "\\");
+ strncat(defname, "\\", sizeof(defname) - 1 - strlen(defname));
- strcat(defname, DEF_KRB_REALMS);
+ strncat(defname, DEF_KRB_REALMS, sizeof(defname) - 1 - strlen(defname));
+ defname[sizeof(defname) - 1] = '\0';
GetPrivateProfileString(INI_FILES, INI_KRB_REALMS, defname,
- realmsname, sizeof(realmsname), KERBEROS_INI);
+ realmsname, sizeof(realmsname) - 1, KERBEROS_INI);
realmsfile = fopen(realmsname, "r");
diff --git a/src/lib/krb5/ChangeLog b/src/lib/krb5/ChangeLog
index a2ab81a..13007dd 100644
--- a/src/lib/krb5/ChangeLog
+++ b/src/lib/krb5/ChangeLog
@@ -1,3 +1,41 @@
+2002-05-22 Alexandra Ellwood <lxs@mit.edu>
+ * krb5_libinit.c: Conditionalized error table loading for
+ Mac OS X. Error tables should always be loaded on other
+ platforms.
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * krb5_libinit.c: Added an include for com_err.h since
+ it is not included by error table headers on Mac OS X. Also
+ fixed busted check for Mac OS
+
+2001-12-03 Miro Jurisic <meeroh@mit.edu>
+
+ * krb5_libinit.c: punted the Mac OS 9 sleep notification code
+
+2001-11-05 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in (LIBMINOR): Bump due to changes in error tables.
+
+2000-11-29 Miro Jurisic <meeroh@mit.edu>
+
+ * krb5_libinit.c: Install a callback in the Mac OS sleep
+ queue to get notification of the machine coming out
+ of sleep, in order to refresh the cached uptime to
+ real time offset
+
+2000-10-02 Alexandra Ellwood <lxs@mit.edu
+
+ * krb5_libinit.c: added #define for Mac OS X so
+ that krb5int_cleanup_library calls krb5_stdcc_shutdown.
+
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in (LIBMAJOR, LIBMINOR): Bump version.
+
+2000-04-18 Ken Raeburn <raeburn@mit.edu>
+
+ * Makefile.in (SHLIB_EXPLIBS): Add @RESOLV_LIB@.
+
2000-03-14 Ken Raeburn <raeburn@mit.edu>
* configure.in: Check for gethostbyname2.
diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in
index 0dab1f3..3b42585 100644
--- a/src/lib/krb5/Makefile.in
+++ b/src/lib/krb5/Makefile.in
@@ -32,8 +32,8 @@ LIBDONE= error_tables/DONE asn.1/DONE ccache/DONE ccache/stdio/DONE \
STLIBOBJS=krb5_libinit.o
LIB=krb5
-LIBMAJOR=2
-LIBMINOR=2
+LIBMAJOR=3
+LIBMINOR=1
STOBJLISTS= \
OBJS.ST \
@@ -58,7 +58,7 @@ RELDIR=krb5
SHLIB_EXPDEPS = \
$(TOPLIBD)/libk5crypto$(SHLIBEXT) \
$(TOPLIBD)/libcom_err$(SHLIBEXT)
-SHLIB_EXPLIBS=-lk5crypto -lcom_err @GEN_LIB@
+SHLIB_EXPLIBS=-lk5crypto -lcom_err @GEN_LIB@ @RESOLV_LIB@
SHLIB_DIRS=-L$(TOPLIBD)
SHLIB_RDIRS=$(KRB5_LIBDIR)
diff --git a/src/lib/krb5/asn.1/ChangeLog b/src/lib/krb5/asn.1/ChangeLog
index 96f7098..bc8b40a 100644
--- a/src/lib/krb5/asn.1/ChangeLog
+++ b/src/lib/krb5/asn.1/ChangeLog
@@ -1,3 +1,94 @@
+2002-04-08 Tom Yu <tlyu@mit.edu>
+
+ * asn1_get.c (asn1_get_length): Check for negative length.
+
+2002-03-06 Alexandra Ellwood <lxs@mit.edu>
+ * asn1_encode.c: Removed unused Mac OS 9 code
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * asn1_get.c: removed unused variable to reduce warnings
+
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * asn1_encode.c: Updated Utilities.h #include
+
+2001-01-31 Tom Yu <tlyu@mit.edu>
+
+ * asn1buf.c (asn1buf_sync): Add new arguments to include the full
+ complement of data about a prefetched tag, as well as to indicate
+ whether the prefetched tag or the surrounding sequence is of an
+ indefinite length.
+ (asn1buf_skiptail): Add new arguments to indicate whether the
+ prefetched tag is indefinite, as well as its length. This
+ facilitates proper skipping of trailing garbage.
+ (asn1buf_remains): Add new argument to indicate whether the
+ surrounding encoding is indefinite. Don't advance buf->next if an
+ EOC encoding is detected; the caller will do that.
+ [pullup from trunk]
+
+ * asn1buf.h: Update prototypes. [pullup from trunk]
+
+ * asn1_get.c (asn1_get_tag_indef): Don't treat EOC encoding as
+ special anymore, since previous behavior was overloading the
+ tag number in a bad way. Also, report a MISMATCH_INDEF error if
+ the tag encoding is for the forbidden primitive constructed
+ encoding. [pullup from trunk]
+
+ * asn1_k_decode.c (next_tag): Call get_tag_indef() in order to get
+ information about whether the length is indefinite. Don't check
+ the tag class and construction explicitly.
+ (get_eoc): New macro to get a tag and check if it is an EOC
+ encoding.
+ (get_field, opt_field): Move the check for the tag class and
+ construction to here.
+ (get_field_body, get_lenfield_body): Call get_eoc() instead of
+ next_tag() if we are decoding a constructed indefinite encoding.
+ (begin_structure): Use a different variable to indicate whether
+ the sequence is indefinite as opposed to whether an individual
+ field is indefinite.
+ (end_structure): Update to new calling convention of
+ asn1buf_sync().
+ (sequence_of): Rewrite significantly.
+ (sequence_of_common): Move the bulk of previous sequence_of()
+ macro to here. Does not declare some variables that sequence_of()
+ declares.
+ (sequence_of_no_tagvars): Similar to sequence_of() macro but
+ declares different variables for the purpose of prefetching the
+ final tag.
+ (end_sequence_of_no_tagvars): Similar to end_sequence_of() macro
+ but uses variables declared by the sequence_of_no_tagvars() macro
+ to prefetch the final tag.
+ (asn1_decode_principal_name): Update for new asn1buf_remains()
+ calling convention. Call sequence_of_no_tagvars(), etc. instead
+ of sequence_of(), etc. in order to not declare shadowing
+ block-local variables.
+ (decode_array_body): Update for new asn1buf_remains() calling
+ convention.
+ (asn1_decode_sequence_of_enctype): Update for new
+ asn1buf_remains() calling convention.
+ [pullup from trunk]
+
+ * krb5_decode.c (next_tag): Call get_tag_indef() in order to get
+ information about whether the length is indefinite. Don't check
+ the tag class and construction explicitly.
+ (get_eoc): New macro to get a tag and check if it is an EOC
+ encoding.
+ (get_field, opt_field): Move the check for the tag class and
+ construction to here.
+ (get_field_body, get_lenfield_body): Call get_eoc() instead of
+ next_tag() if we are decoding a constructed indefinite encoding.
+ (begin_structure): Use a different variable to indicate whether
+ the sequence is indefinite as opposed to whether an individual
+ field is indefinite.
+ (end_structure): Update to new calling convention of
+ asn1buf_sync().
+ [pullup from trunk]
+
+2000-09-28 Miro Jurisic <meeroh@mit.edu>
+
+ * asn1_encode.c (asn1_encode_generaltime): Fixed the Mac code to
+ use the correct epoch.
+
2000-02-06 Ken Raeburn <raeburn@mit.edu>
Patches from Frank Cusack for helping in preauth replay
diff --git a/src/lib/krb5/asn.1/asn1_encode.c b/src/lib/krb5/asn.1/asn1_encode.c
index 7ef89c8..7cc8042 100644
--- a/src/lib/krb5/asn.1/asn1_encode.c
+++ b/src/lib/krb5/asn.1/asn1_encode.c
@@ -186,12 +186,6 @@ asn1_error_code asn1_encode_ia5string(buf, len, val, retlen)
return 0;
}
-#ifdef macintosh
-#define EPOCH ((70 * 365 * 24 * 60 * 60) + (17 * 24 * 60 * 60) + (getTimeZoneOffset() * 60 * 60))
-#else
-#define EPOCH (0)
-#endif
-
asn1_error_code asn1_encode_generaltime(buf, val, retlen)
asn1buf * buf;
const time_t val;
@@ -201,9 +195,11 @@ asn1_error_code asn1_encode_generaltime(buf, val, retlen)
struct tm *gtime;
char s[16];
int length, sum=0;
- time_t gmt_time;
+ time_t gmt_time = val;
- gmt_time = val + EPOCH;
+#ifdef macintosh
+ unix_time_to_msl_time (&gmt_time);
+#endif
gtime = gmtime(&gmt_time);
/*
diff --git a/src/lib/krb5/asn.1/asn1_get.c b/src/lib/krb5/asn.1/asn1_get.c
index 20334a2..90f5dd9 100644
--- a/src/lib/krb5/asn.1/asn1_get.c
+++ b/src/lib/krb5/asn.1/asn1_get.c
@@ -42,12 +42,6 @@ asn1_get_tag_indef(buf, class, construction, tagnum, retlen, indef)
*tagnum = ASN1_TAGNUM_CEILING;
return 0;
}
- /* Allow for the indefinite encoding */
- if ( !*(buf->next) && !*(buf->next + 1)) {
- buf->next += 2;
- *tagnum = ASN1_TAGNUM_CEILING;
- return 0;
- }
retval = asn1_get_id(buf,class,construction,tagnum);
if(retval) return retval;
retval = asn1_get_length(buf,retlen,indef);
@@ -63,7 +57,6 @@ asn1_get_tag(buf, class, construction, tagnum, retlen)
asn1_tagnum *tagnum;
int *retlen;
{
- asn1_error_code retval;
int indef;
return asn1_get_tag_indef(buf, class, construction, tagnum, retlen, &indef);
@@ -149,6 +142,8 @@ asn1_error_code asn1_get_length(buf, retlen, indef)
if(retval) return retval;
len = (len<<8) + (int)o;
}
+ if (len < 0)
+ return ASN1_OVERRUN;
if (indef != NULL && !len)
*indef = 1;
if(retlen != NULL) *retlen = len;
diff --git a/src/lib/krb5/asn.1/asn1_k_decode.c b/src/lib/krb5/asn.1/asn1_k_decode.c
index 6f72d8e..a855527 100644
--- a/src/lib/krb5/asn.1/asn1_k_decode.c
+++ b/src/lib/krb5/asn.1/asn1_k_decode.c
@@ -39,10 +39,16 @@ int length,taglen
#define unused_var(x) if(0) x=0
#define next_tag()\
-retval = asn1_get_tag(&subbuf,&class,&construction,&tagnum,&taglen);\
-if(retval) return retval;\
-if(class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\
- return ASN1_BAD_ID
+retval = asn1_get_tag_indef(&subbuf,&class,&construction,\
+ &tagnum,&taglen,&indef);\
+if(retval) return retval;
+
+#define get_eoc() \
+retval = asn1_get_tag_indef(&subbuf,&class,&construction, \
+ &tagnum,&taglen,&indef); \
+if(retval) return retval; \
+if(class != UNIVERSAL || tagnum || indef) \
+ return ASN1_MISSING_EOC
#define alloc_field(var,type)\
var = (type*)calloc(1,sizeof(type));\
@@ -59,15 +65,21 @@ if(class != APPLICATION || construction != CONSTRUCTED ||\
#define get_field_body(var,decoder)\
retval = decoder(&subbuf,&(var));\
if(retval) return retval;\
-if(!taglen) { next_tag(); }\
+if(!taglen && indef) { get_eoc(); }\
next_tag()
#define get_field(var,tagexpect,decoder)\
if(tagnum > (tagexpect)) return ASN1_MISSING_FIELD;\
if(tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD;\
+if((class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \
+ && (tagnum || taglen || class != UNIVERSAL)) \
+ return ASN1_BAD_ID;\
get_field_body(var,decoder)
#define opt_field(var,tagexpect,decoder,optvalue)\
+if((class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \
+ && (tagnum || taglen || class != UNIVERSAL)) \
+ return ASN1_BAD_ID;\
if(tagnum == (tagexpect)){\
get_field_body(var,decoder); }\
else var = optvalue
@@ -76,12 +88,15 @@ else var = optvalue
#define get_lenfield_body(len,var,decoder)\
retval = decoder(&subbuf,&(len),&(var));\
if(retval) return retval;\
-if(!taglen) { next_tag(); }\
+if(!taglen && indef) { get_eoc(); }\
next_tag()
#define get_lenfield(len,var,tagexpect,decoder)\
if(tagnum > (tagexpect)) return ASN1_MISSING_FIELD;\
if(tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD;\
+if((class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \
+ && (tagnum || taglen || class != UNIVERSAL)) \
+ return ASN1_BAD_ID;\
get_lenfield_body(len,var,decoder)
#define opt_lenfield(len,var,tagexpect,decoder)\
@@ -92,30 +107,58 @@ else { len = 0; var = 0; }
#define begin_structure()\
asn1buf subbuf;\
+int seqindef;\
int indef;\
-retval = asn1_get_sequence(buf,&length,&indef);\
+retval = asn1_get_sequence(buf,&length,&seqindef);\
if(retval) return retval;\
-retval = asn1buf_imbed(&subbuf,buf,length,indef);\
+retval = asn1buf_imbed(&subbuf,buf,length,seqindef);\
if(retval) return retval;\
next_tag()
#define end_structure()\
-retval = asn1buf_sync(buf,&subbuf,tagnum,length);\
+retval = asn1buf_sync(buf,&subbuf,class,tagnum,length,indef,seqindef);\
if(retval) return retval
-#define sequence_of(buf)\
-int size=0;\
-asn1buf seqbuf;\
-int length;\
-int indef;\
-retval = asn1_get_sequence(buf,&length,&indef);\
-if(retval) return retval;\
-retval = asn1buf_imbed(&seqbuf,buf,length,indef);\
+#define sequence_of(buf) \
+unsigned int length, taglen; \
+asn1_class class; \
+asn1_construction construction; \
+asn1_tagnum tagnum; \
+int indef; \
+sequence_of_common(buf)
+
+#define sequence_of_common(buf) \
+int size=0; \
+asn1buf seqbuf; \
+int seqofindef; \
+retval = asn1_get_sequence(buf,&length,&seqofindef); \
+if(retval) return retval; \
+retval = asn1buf_imbed(&seqbuf,buf,length,seqofindef); \
if(retval) return retval
-#define end_sequence_of(buf)\
-retval = asn1buf_sync(buf,&seqbuf,ASN1_TAGNUM_CEILING,length);\
-if(retval) return retval
+#define sequence_of_no_tagvars(buf) \
+asn1_class eseqclass; \
+asn1_construction eseqconstr; \
+asn1_tagnum eseqnum; \
+unsigned int eseqlen; \
+int eseqindef; \
+sequence_of_common(buf)
+
+#define end_sequence_of_no_tagvars(buf) \
+retval = asn1_get_tag_indef(&seqbuf,&eseqclass,&eseqconstr, \
+ &eseqnum,&eseqlen,&eseqindef); \
+if(retval) return retval; \
+retval = asn1buf_sync(buf,&seqbuf,eseqclass,eseqnum, \
+ eseqlen,eseqindef,seqofindef); \
+if(retval) return retval;
+
+#define end_sequence_of(buf) \
+retval = asn1_get_tag_indef(&seqbuf,&class,&construction, \
+ &tagnum,&taglen,&indef); \
+if(retval) return retval; \
+retval = asn1buf_sync(buf,&seqbuf,class,tagnum, \
+ length,indef,seqofindef); \
+if(retval) return retval;
#define cleanup()\
return 0
@@ -206,8 +249,8 @@ asn1_error_code asn1_decode_principal_name(buf, val)
{ begin_structure();
get_field((*val)->type,0,asn1_decode_int32);
- { sequence_of(&subbuf);
- while(asn1buf_remains(&seqbuf)){
+ { sequence_of_no_tagvars(&subbuf);
+ while(asn1buf_remains(&seqbuf,seqofindef) > 0){
size++;
if ((*val)->data == NULL)
(*val)->data = (krb5_data*)malloc(size*sizeof(krb5_data));
@@ -221,8 +264,12 @@ asn1_error_code asn1_decode_principal_name(buf, val)
if(retval) return retval;
}
(*val)->length = size;
- end_sequence_of(&subbuf);
+ end_sequence_of_no_tagvars(&subbuf);
+ }
+ if (indef) {
+ get_eoc();
}
+ next_tag();
end_structure();
(*val)->magic = KV5M_PRINCIPAL;
}
@@ -528,7 +575,7 @@ if(*(array) == NULL) return ENOMEM;\
type *elt;\
\
{ sequence_of(buf);\
- while(asn1buf_remains(&seqbuf) > 0){\
+ while(asn1buf_remains(&seqbuf,seqofindef) > 0){\
alloc_field(elt,type);\
get_element(elt,decoder);\
array_append(val,size,elt,type);\
@@ -660,7 +707,7 @@ asn1_error_code asn1_decode_sequence_of_enctype(buf, num, val)
{
asn1_error_code retval;
{ sequence_of(buf);
- while(asn1buf_remains(&seqbuf) > 0){
+ while(asn1buf_remains(&seqbuf,seqofindef) > 0){
size++;
if (*val == NULL)
*val = (krb5_enctype*)malloc(size*sizeof(krb5_enctype));
diff --git a/src/lib/krb5/asn.1/asn1buf.c b/src/lib/krb5/asn.1/asn1buf.c
index 9c63927..4be82fb 100644
--- a/src/lib/krb5/asn.1/asn1buf.c
+++ b/src/lib/krb5/asn.1/asn1buf.c
@@ -54,6 +54,9 @@
#include <stdio.h>
#include "asn1_get.h"
+#define asn1_is_eoc(class, num, indef) \
+((class) == UNIVERSAL && !(num) && !(indef))
+
asn1_error_code asn1buf_create(buf)
asn1buf ** buf;
{
@@ -91,34 +94,35 @@ asn1_error_code asn1buf_imbed(subbuf, buf, length, indef)
return 0;
}
-asn1_error_code asn1buf_sync(buf, subbuf, lasttag, length)
+asn1_error_code asn1buf_sync(buf, subbuf, class, lasttag, length, indef, seqindef)
asn1buf * buf;
asn1buf * subbuf;
+ const asn1_class class;
const asn1_tagnum lasttag;
const int length;
+ const int indef;
+ const int seqindef;
{
asn1_error_code retval;
- if (length) {
+ if (!seqindef) {
+ /* sequence was encoded as definite length */
buf->next = subbuf->bound + 1;
+ } else if (!asn1_is_eoc(class, lasttag, indef)) {
+ retval = asn1buf_skiptail(subbuf, length, indef);
+ if (retval)
+ return retval;
} else {
- /*
- * indefinite length:
- *
- * Note that asn1_get_tag() returns ASN1_TAGNUM_CEILING
- * for an EOC encoding.
- */
- if (lasttag != ASN1_TAGNUM_CEILING) {
- retval = asn1buf_skiptail(subbuf);
- if (retval) return retval;
- }
+ /* We have just read the EOC octets. */
buf->next = subbuf->next;
}
return 0;
}
-asn1_error_code asn1buf_skiptail(buf)
+asn1_error_code asn1buf_skiptail(buf, length, indef)
asn1buf *buf;
+ const int length;
+ const int indef;
{
asn1_error_code retval;
asn1_class class;
@@ -126,15 +130,29 @@ asn1_error_code asn1buf_skiptail(buf)
asn1_tagnum tagnum;
int taglen;
int nestlevel;
+ int tagindef;
- nestlevel = 1;
+ nestlevel = 1 + indef;
+ if (!indef) {
+ if (length <= buf->bound - buf->next + 1)
+ buf->next += length;
+ else
+ return ASN1_OVERRUN;
+ }
while (nestlevel > 0) {
- retval = asn1_get_tag(buf, &class, &construction, &tagnum, &taglen);
+ retval = asn1_get_tag_indef(buf, &class, &construction, &tagnum,
+ &taglen, &tagindef);
if (retval) return retval;
- if (construction == CONSTRUCTED && taglen == 0)
+ if (!tagindef) {
+ if (taglen <= buf->bound - buf->next + 1)
+ buf->next += taglen;
+ else
+ return ASN1_OVERRUN;
+ }
+ if (tagindef)
nestlevel++;
- if (tagnum == ASN1_TAGNUM_CEILING)
- nestlevel--;
+ if (asn1_is_eoc(class, tagnum, tagindef))
+ nestlevel--; /* got an EOC encoding */
}
return 0;
}
@@ -247,8 +265,9 @@ asn1_error_code asn1buf_remove_charstring(buf, len, s)
return 0;
}
-int asn1buf_remains(buf)
+int asn1buf_remains(buf, indef)
asn1buf *buf;
+ int indef;
{
int remain;
if(buf == NULL || buf->base == NULL) return 0;
@@ -256,15 +275,9 @@ int asn1buf_remains(buf)
if (remain <= 0) return remain;
/*
* Two 0 octets means the end of an indefinite encoding.
- *
- * XXX Do we need to test to make sure we'er actually doing an
- * indefinite encoding here?
*/
- if ( !*(buf->next) && !*(buf->next + 1)) {
- /* buf->bound = buf->next + 1; */
- buf->next += 2;
+ if (indef && remain >= 2 && !*(buf->next) && !*(buf->next + 1))
return 0;
- }
else return remain;
}
@@ -379,9 +392,9 @@ asn1_error_code asn1buf_ensure_space(buf, amount)
asn1buf * buf;
const int amount;
{
- int free = asn1buf_free(buf);
- if(free < amount){
- asn1_error_code retval = asn1buf_expand(buf, amount-free);
+ int avail = asn1buf_free(buf);
+ if(avail < amount){
+ asn1_error_code retval = asn1buf_expand(buf, amount-avail);
if(retval) return retval;
}
return 0;
diff --git a/src/lib/krb5/asn.1/asn1buf.h b/src/lib/krb5/asn.1/asn1buf.h
index 52fc0d6..3f4a6ac 100644
--- a/src/lib/krb5/asn.1/asn1buf.h
+++ b/src/lib/krb5/asn.1/asn1buf.h
@@ -121,14 +121,17 @@ asn1_error_code asn1buf_imbed
position starts at the beginning of *subbuf. */
asn1_error_code asn1buf_sync
- PROTOTYPE((asn1buf *buf, asn1buf *subbuf, const asn1_tagnum lasttag,
- const int length));
+ PROTOTYPE((asn1buf *buf, asn1buf *subbuf, const asn1_class class,
+ const asn1_tagnum lasttag,
+ const int length, const int indef,
+ const int seqindef));
/* requires *subbuf is a sub-buffer of *buf, as created by asn1buf_imbed.
- lasttag is a pointer to the last tagnumber read.
+ lasttag is the last tagnumber read.
effects Synchronizes *buf's current position to match that of *subbuf. */
asn1_error_code asn1buf_skiptail
- PROTOTYPE((asn1buf *buf));
+ PROTOTYPE((asn1buf *buf, const int length,
+ const int indef));
/* requires *buf is a subbuffer used in a decoding of a
constructed indefinite sequence.
effects skips trailing fields. */
@@ -143,7 +146,7 @@ asn1_error_code asn1buf_insert_octet
effects Inserts o into the buffer *buf, expanding the buffer if
necessary. Returns ENOMEM memory is exhausted. */
#if ((__GNUC__ >= 2) && !defined(ASN1BUF_OMIT_INLINE_FUNCS))
-extern inline asn1_error_code asn1buf_insert_octet(buf, o)
+extern __inline__ asn1_error_code asn1buf_insert_octet(buf, o)
asn1buf * buf;
const int o;
{
@@ -221,7 +224,7 @@ asn1_error_code asn12krb5_buf
int asn1buf_remains
- PROTOTYPE((asn1buf *buf));
+ PROTOTYPE((asn1buf *buf, int indef));
/* requires *buf is a buffer containing an asn.1 structure or array
modifies *buf
effects Returns the number of unprocessed octets remaining in *buf. */
diff --git a/src/lib/krb5/asn.1/krb5_decode.c b/src/lib/krb5/asn.1/krb5_decode.c
index 69028b9..ff935c6 100644
--- a/src/lib/krb5/asn.1/krb5_decode.c
+++ b/src/lib/krb5/asn.1/krb5_decode.c
@@ -77,23 +77,29 @@ if(tagnum != (tagexpect)) clean_return(KRB5_BADMSGTYPE)
/* decode an explicit tag and place the number in tagnum */
#define next_tag()\
-retval = asn1_get_tag(&subbuf,&class,&construction,&tagnum,NULL);\
-if(retval) clean_return(retval);\
-if(class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\
- clean_return(ASN1_BAD_ID)
+retval = asn1_get_tag_indef(&subbuf,&class,&construction,&tagnum,NULL,&indef);\
+if(retval) clean_return(retval)
+
+#define get_eoc() \
+retval = asn1_get_tag_indef(&subbuf,&class,&construction, \
+ &tagnum,NULL,&indef); \
+if(retval) return retval; \
+if(class != UNIVERSAL || tagnum || indef) \
+ return ASN1_MISSING_EOC
/* decode sequence header and initialize tagnum with the first field */
#define begin_structure()\
asn1buf subbuf;\
+int seqindef;\
int indef;\
-retval = asn1_get_sequence(&buf,&length,&indef);\
+retval = asn1_get_sequence(&buf,&length,&seqindef);\
if(retval) clean_return(retval);\
-retval = asn1buf_imbed(&subbuf,&buf,length,indef);\
+retval = asn1buf_imbed(&subbuf,&buf,length,seqindef);\
if(retval) clean_return(retval);\
next_tag()
#define end_structure()\
-retval = asn1buf_sync(&buf,&subbuf,tagnum,length);\
+retval = asn1buf_sync(&buf,&subbuf,class,tagnum,length,indef,seqindef);\
if (retval) clean_return(retval)
/* process fields *******************************************/
@@ -101,6 +107,7 @@ if (retval) clean_return(retval)
#define get_field_body(var,decoder)\
retval = decoder(&subbuf,&(var));\
if(retval) clean_return(retval);\
+if (indef) { get_eoc(); }\
next_tag()
/* decode a field (<[UNIVERSAL id]> <length> <contents>)
@@ -110,26 +117,35 @@ next_tag()
#define get_field(var,tagexpect,decoder)\
if(tagnum > (tagexpect)) clean_return(ASN1_MISSING_FIELD);\
if(tagnum < (tagexpect)) clean_return(ASN1_MISPLACED_FIELD);\
+if(class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\
+ clean_return(ASN1_BAD_ID);\
get_field_body(var,decoder)
/* decode (or skip, if not present) an optional field */
#define opt_field(var,tagexpect,decoder)\
+if(class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\
+ clean_return(ASN1_BAD_ID);\
if(tagnum == (tagexpect)){ get_field_body(var,decoder); }
/* field w/ accompanying length *********/
#define get_lenfield_body(len,var,decoder)\
retval = decoder(&subbuf,&(len),&(var));\
if(retval) clean_return(retval);\
+if (indef) { get_eoc(); }\
next_tag()
/* decode a field w/ its length (for string types) */
#define get_lenfield(len,var,tagexpect,decoder)\
if(tagnum > (tagexpect)) clean_return(ASN1_MISSING_FIELD);\
if(tagnum < (tagexpect)) clean_return(ASN1_MISPLACED_FIELD);\
+if(class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\
+ clean_return(ASN1_BAD_ID);\
get_lenfield_body(len,var,decoder)
/* decode an optional field w/ length */
#define opt_lenfield(len,var,tagexpect,decoder)\
+if(class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\
+ clean_return(ASN1_BAD_ID);\
if(tagnum == (tagexpect)){\
get_lenfield_body(len,var,decoder);\
}
diff --git a/src/lib/krb5/ccache/ChangeLog b/src/lib/krb5/ccache/ChangeLog
index 2f74235..b9f1516 100644
--- a/src/lib/krb5/ccache/ChangeLog
+++ b/src/lib/krb5/ccache/ChangeLog
@@ -1,3 +1,64 @@
+2002-04-05 Danilo Almeida <dalmeida@mit.edu>
+
+ * Makefile.in: Build cc accessor functions on Windows.
+
+2002-04-2 Alexandra Ellwood <lxs@mit.edu>
+ * ccdefault.c: updated to new KLL function name
+
+2002-03-03 Alexandra Ellwood <lxs@mit.edu>
+ * ccdefault.c: swapped include of KerberosLoginPrivate with k5-int.h
+ to avoid problems with including CoreServices.h after profile.h and krb.h
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * ccdefault.c: Updated Mac OS X headers to new framework layout
+
+2002-01-29 Tom Yu <tlyu@mit.edu>
+
+ * ccdefault.c: Add terminal newline. Fixes [krb5-build/1041].
+
+2001-11-16 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch: LoginLib #include changes
+
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * Makefile.in: Added ccfns.c
+ * ccdefault.h: Updated Mac OS #defines and #includes for new header layout
+ and Mac OS X frameworks
+
+2000-09-12 Alexandra Ellwood <lxs@mit.edu>
+
+ * ccdefops.c: created #define for USE_CCAPI now that both Mac OS 9 and
+ Mac OS 10 use ccapi.
+
+2000-5-31 Alexandra Ellwood <lxs@mit.edu>
+
+ * ccdefault.c: Changed kerberosPrincipal_V5 to kerberosVersion_V5 to reflect
+ the new constant name.
+
+2000-5-19 Alexandra Ellwood <lxs@mit.edu>
+
+ * ccdefault.c: Added krb5int_cc_default. This function
+ supports the Kerberos Login Library and pops up a dialog if the cache does
+ not contain valid tickets. This is used to automatically get a tgt before
+ obtaining service tickets. Note that this should be an internal function
+ because callers don't expect krb5_cc_default to pop up a dialog!
+ (We found this out the hard way :-)
+
+2000-4-26 Alexandra Ellwood <lxs@mit.edu>
+
+ * ccdefault.c: Added version number to internal Kerberos Login Library
+ routine.
+
+2000-4-13 Alexandra Ellwood <lxs@mit.edu>
+
+ * ccdefault.c: Added Kerberos Login library support (with ifdefs to control
+ whether or not it is on. Also added support to store a krb5_principal in the
+ os_context along with the default ccache name (if known, this principal is
+ the same as the last time we looked at the ccache.
+ * ccdefname.c: Added support to store a krb5_principal in the os_context
+ along with the default ccache name (if known, this principal is the same
+ as the last time we looked at the ccache.
+
1999-10-26 Tom Yu <tlyu@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/krb5/ccache/Makefile.in b/src/lib/krb5/ccache/Makefile.in
index 37abee4..ae09347 100644
--- a/src/lib/krb5/ccache/Makefile.in
+++ b/src/lib/krb5/ccache/Makefile.in
@@ -35,9 +35,12 @@ SRCS= $(srcdir)/ccbase.c \
$(srcdir)/cccopy.c \
$(srcdir)/ccdefault.c \
$(srcdir)/ccdefops.c \
+ $(srcdir)/ccfns.c \
$(srcdir)/cc_retr.c \
$(srcdir)/ser_cc.c
+##DOS##OBJS=$(OBJS) $(OUTPRE)ccfns.$(OBJEXT)
+
all-unix:: all-libobjs
all-windows:: subdirs $(OBJFILE)
diff --git a/src/lib/krb5/ccache/ccapi/ChangeLog b/src/lib/krb5/ccache/ccapi/ChangeLog
index e4dac98..9b07b33 100644
--- a/src/lib/krb5/ccache/ccapi/ChangeLog
+++ b/src/lib/krb5/ccache/ccapi/ChangeLog
@@ -1,3 +1,93 @@
+2002-04-05 Danilo Almeida <dalmeida@mit.edu>
+
+ * winccld.c: Include k5-int.h to get hidden ops struct.
+
+2002-04-03 Danilo Almeida <dalmeida@mit.edu>
+
+ * stdcc.h: Remove KRB5_DLLIMP, KRB5_CALLCONV from
+ krb5_stdcc_shutdown() prototype (to fix Windows build).
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * stdcc.h: Added prototype for krb5_stdcc_shutdown.
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * stdcc.h, stdcc_util.h, stdcc_util.c: Updated Mac OS X headers to new
+ framework layout
+ * stdcc.c: Removed unused variables and fixed macros to reduce warnings
+
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * stdcc.c: Replaced cc_* macros with functions
+ * stdcc.h, stdcc_util.h: Updated Mac OS #defines and #includes for new
+ header layout and Mac OS X frameworks
+
+2000-10-02 Alexandra Ellwood <lxs@mit.edu>
+
+ * stdcc_util.c: now Mac OS X uses get_time_offsets to store offset time
+ like Mac OS 9.
+
+2000-09-12 Alexandra Ellwood <lxs@mit.edu>
+
+ * stdcc.h, stdcc_util.h: created #define for USE_CCAPI now that
+ both Mac OS 9 and Mac OS 10 use ccapi.
+
+2000-06-08 Alexandra Ellwood <lxs@mit.edu>
+
+ * stdcc_util.c (dupCCtoK5, dupK5toCC):
+ Fixed code that stores times in localtime, not in kdc time.
+
+2000-05-18 Danilo Almeida <dalmeida@mit.edu>
+
+ * stdcc_util.c (dupK5toCC): Remove unused variables.
+
+ * stdcc_util.c: Reindent to krb5 coding style. Remove whitespace
+ at end of lines. Replace C++ comments with C comments.
+
+ * stdcc_util.h: Replace C++ comments with C comments.
+
+ * winccld.h: Define CC_API_VER2 for all Windows code using ccapi.
+ Update dynamic loading declarations to use CC_API_VER2.
+
+ * winccld.h: Do not define or try to load cc_lock_request, which is
+ not actually used anywhere in the code.
+
+ * stdcc.c: Define CC_API_VER2 if not defined rather than just if
+ not Windows.
+
+ * winccld.c (LoadFuncs): Get error on DLL load failure even though
+ we do not use it in case we are doing source-level debugging.
+
+2000-05-04 Miro Jurisic <meeroh@mit.edu>
+
+ * stdcc_util.c (dupCCtoK5, dupK5toCC):
+ Conditionalized local/KDC time conversions for Mac-only
+ until we figure out what to do about that
+
+2000-04-07 Jeffrey Altman <jaltman@columbia.edu>
+
+ * stdcc_util.c (copyCCDataArrayToK5, copyCCDataArrayToK5):
+ * stdcc_util.c (dupCCtoK5, dupK5toCC):
+
+ memory was being allocated as (sizeof(foo) * count + 1)
+ instead of (sizeof(foo) * (count + 1))
+
+2000-04-03 Jeffrey Altman <jaltman@columbia.edu>
+
+ * stdcc_util.c (copyCCDataArrayToK5, copyCCDataArrayToK5):
+ * stdcc_util.c (dupCCtoK5, dupK5toCC):
+
+ Changed all references to the type UInt32 to unsigned int
+ since UInt32 is not a standard type on Unix or Win32
+
+2000-03-24 Alexandra Ellwood <lxs@mit.edu>
+
+ * stdcc_util.c (copyCCDataArrayToK5, copyCCDataArrayToK5):
+ Modified to copy authdata as well... this code may have
+ bugs since I couldn't get a good case where authdata != NULL
+
+ * stdcc_util.c (dupCCtoK5, dupK5toCC):
+ Added code to store times in localtime, not in kdc time.
+
2000-03-15 Danilo Almeida <dalmeida@mit.edu>
* stdcc.c (krb5_stdcc_destroy): Do not mask KRB5_FCC_NOFILE error
diff --git a/src/lib/krb5/ccache/ccapi/stdcc.c b/src/lib/krb5/ccache/ccapi/stdcc.c
index a17cd02..b885885 100644
--- a/src/lib/krb5/ccache/ccapi/stdcc.c
+++ b/src/lib/krb5/ccache/ccapi/stdcc.c
@@ -32,6 +32,7 @@
#include "stdcc.h"
#include "stdcc_util.h"
#include "string.h"
+#include "k5-int.h"
#include <stdio.h>
apiCB *gCntrlBlock = NULL;
@@ -40,7 +41,7 @@ apiCB *gCntrlBlock = NULL;
#include "winccld.h"
#endif
-#if !defined(_MSDOS) && !defined(_WIN32)
+#ifndef CC_API_VER2
#define CC_API_VER2
#endif
@@ -264,7 +265,7 @@ krb5_error_code KRB5_CALLCONV krb5_stdcc_resolve
stdccCacheDataPtr ccapi_data = NULL;
int err;
krb5_error_code retval;
- char *cName;
+ char *cName = NULL;
if ((retval = stdcc_setup(context, NULL)))
return retval;
@@ -548,7 +549,9 @@ krb5_error_code KRB5_CALLCONV krb5_stdcc_end_seq_get
krb5_error_code retval;
stdccCacheDataPtr ccapi_data = NULL;
int err;
+#ifndef CC_API_VER2
cred_union *credU = NULL;
+#endif
ccapi_data = id->data;
@@ -656,7 +659,6 @@ krb5_stdcc_destroy (krb5_context context, krb5_ccache id)
char * KRB5_CALLCONV krb5_stdcc_get_name
(krb5_context context, krb5_ccache id )
{
- char *name = NULL;
stdccCacheDataPtr ccapi_data = id->data;
if (!ccapi_data)
diff --git a/src/lib/krb5/ccache/ccapi/stdcc.h b/src/lib/krb5/ccache/ccapi/stdcc.h
index 109c4fc..a9825b7 100644
--- a/src/lib/krb5/ccache/ccapi/stdcc.h
+++ b/src/lib/krb5/ccache/ccapi/stdcc.h
@@ -1,7 +1,7 @@
#include "krb5.h"
-#if defined(macintosh)
-#include "CCache2.h"
+#if TARGET_OS_MAC
+#include <Kerberos/CredentialsCache2.h>
#endif
#if defined(_MSDOS) || defined(_WIN32)
@@ -24,6 +24,8 @@ typedef struct _stdccCacheData {
/* function protoypes */
+void krb5_stdcc_shutdown(void);
+
KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_stdcc_close
KRB5_PROTOTYPE((krb5_context, krb5_ccache id ));
diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.c b/src/lib/krb5/ccache/ccapi/stdcc_util.c
index 4262eed..cf2054e 100644
--- a/src/lib/krb5/ccache/ccapi/stdcc_util.c
+++ b/src/lib/krb5/ccache/ccapi/stdcc_util.c
@@ -23,112 +23,170 @@
* - 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++;
+int copyCCDataArrayToK5(cc_creds *ccCreds, krb5_creds *v5Creds, char whichArray) {
+
+ if (whichArray == kAddressArray) {
+ if (ccCreds->addresses == NULL) {
+ v5Creds->addresses = NULL;
+ } else {
+
+ krb5_address **addrPtr, *addr;
+ cc_data **dataPtr, *data;
+ unsigned int numRecords = 0;
+
+ /* Allocate the array of pointers: */
+ for (dataPtr = ccCreds->addresses; *dataPtr != NULL; numRecords++, dataPtr++) {}
+
+ v5Creds->addresses = (krb5_address **) malloc (sizeof(krb5_address *) * (numRecords + 1));
+ if (v5Creds->addresses == NULL)
+ return ENOMEM;
+
+ /* Fill in the array, allocating the address structures: */
+ for (dataPtr = ccCreds->addresses, addrPtr = v5Creds->addresses; *dataPtr != NULL; addrPtr++, dataPtr++) {
+
+ *addrPtr = (krb5_address *) malloc (sizeof(krb5_address));
+ if (*addrPtr == NULL)
+ return ENOMEM;
+ data = *dataPtr;
+ addr = *addrPtr;
+
+ addr->addrtype = data->type;
+ addr->magic = KV5M_ADDRESS;
+ addr->length = data->length;
+ addr->contents = (krb5_octet *) malloc (sizeof(krb5_octet) * addr->length);
+ if (addr->contents == NULL)
+ return ENOMEM;
+ memmove(addr->contents, data->data, addr->length); /* copy contents */
+ }
+
+ /* Write terminator: */
+ *addrPtr = NULL;
+ }
+ }
+
+ if (whichArray == kAuthDataArray) {
+ if (ccCreds->authdata == NULL) {
+ v5Creds->authdata = NULL;
+ } else {
+ krb5_authdata **authPtr, *auth;
+ cc_data **dataPtr, *data;
+ unsigned int numRecords = 0;
+
+ /* Allocate the array of pointers: */
+ for (dataPtr = ccCreds->authdata; *dataPtr != NULL; numRecords++, dataPtr++) {}
+
+ v5Creds->authdata = (krb5_authdata **) malloc (sizeof(krb5_authdata *) * (numRecords + 1));
+ if (v5Creds->authdata == NULL)
+ return ENOMEM;
+
+ /* Fill in the array, allocating the address structures: */
+ for (dataPtr = ccCreds->authdata, authPtr = v5Creds->authdata; *dataPtr != NULL; authPtr++, dataPtr++) {
+
+ *authPtr = (krb5_authdata *) malloc (sizeof(krb5_authdata));
+ if (*authPtr == NULL)
+ return ENOMEM;
+ data = *dataPtr;
+ auth = *authPtr;
+
+ auth->ad_type = data->type;
+ auth->magic = KV5M_AUTHDATA;
+ auth->length = data->length;
+ auth->contents = (krb5_octet *) malloc (sizeof(krb5_octet) * auth->length);
+ if (auth->contents == NULL)
+ return ENOMEM;
+ memmove(auth->contents, data->data, auth->length); /* copy contents */
+ }
+
+ /* Write terminator: */
+ *authPtr = NULL;
}
-
- //write terminator
- *kbase = NULL;
- if (whichArray == kAddressArray) kc->addresses = constKBase;
- else kc->authdata = (krb5_authdata **)constKBase;
+ }
- return 0;
+ 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 **)malloc((numRecords+1)*sizeof(char *));
- //reset base
- kbase = (whichArray == kAddressArray) ? kc->addresses : (krb5_address **)kc->authdata;
-
-
- //copy records
- while (*kbase != NULL) {
- *cbase = (cc_data *)malloc(sizeof(krb5_address));
- kAdr = *kbase;
- ccAdr = *cbase;
- ccAdr->type = kAdr->addrtype;
- ccAdr->length = kAdr->length;
- ccAdr->data = (unsigned char *)malloc(ccAdr->length);
- memcpy(ccAdr->data, kAdr->contents, kAdr->length);
- //next element please
- kbase++; cbase++;
+int copyK5DataArrayToCC(krb5_creds *v5Creds, cc_creds *ccCreds, char whichArray)
+{
+ if (whichArray == kAddressArray) {
+ if (v5Creds->addresses == NULL) {
+ ccCreds->addresses = NULL;
+ } else {
+
+ krb5_address **addrPtr, *addr;
+ cc_data **dataPtr, *data;
+ unsigned int numRecords = 0;
+
+ /* Allocate the array of pointers: */
+ for (addrPtr = v5Creds->addresses; *addrPtr != NULL; numRecords++, addrPtr++) {}
+
+ ccCreds->addresses = (cc_data **) malloc (sizeof(cc_data *) * (numRecords + 1));
+ if (ccCreds->addresses == NULL)
+ return ENOMEM;
+
+ /* Fill in the array, allocating the address structures: */
+ for (dataPtr = ccCreds->addresses, addrPtr = v5Creds->addresses; *addrPtr != NULL; addrPtr++, dataPtr++) {
+
+ *dataPtr = (cc_data *) malloc (sizeof(cc_data));
+ if (*dataPtr == NULL)
+ return ENOMEM;
+ data = *dataPtr;
+ addr = *addrPtr;
+
+ data->type = addr->addrtype;
+ data->length = addr->length;
+ data->data = malloc (sizeof(char) * data->length);
+ if (data->data == NULL)
+ return ENOMEM;
+ memmove(data->data, addr->contents, data->length); /* copy contents */
+ }
+
+ /* Write terminator: */
+ *dataPtr = NULL;
+ }
+ }
+
+ if (whichArray == kAuthDataArray) {
+ if (v5Creds->authdata == NULL) {
+ ccCreds->authdata = NULL;
+ } else {
+ krb5_authdata **authPtr, *auth;
+ cc_data **dataPtr, *data;
+ unsigned int numRecords = 0;
+
+ /* Allocate the array of pointers: */
+ for (authPtr = v5Creds->authdata; *authPtr != NULL; numRecords++, authPtr++) {}
+
+ ccCreds->authdata = (cc_data **) malloc (sizeof(cc_data *) * (numRecords + 1));
+ if (ccCreds->authdata == NULL)
+ return ENOMEM;
+
+ /* Fill in the array, allocating the address structures: */
+ for (dataPtr = ccCreds->authdata, authPtr = v5Creds->authdata; *authPtr != NULL; authPtr++, dataPtr++) {
+
+ *dataPtr = (cc_data *) malloc (sizeof(cc_data));
+ if (*dataPtr == NULL)
+ return ENOMEM;
+ data = *dataPtr;
+ auth = *authPtr;
+
+ data->type = auth->ad_type;
+ data->length = auth->length;
+ data->data = malloc (sizeof(char) * data->length);
+ if (data->data == NULL)
+ return ENOMEM;
+ memmove(data->data, auth->contents, data->length); /* copy contents */
+ }
+
+ /* Write terminator: */
+ *dataPtr = NULL;
}
-
- //write terminator
- *cbase = NULL;
- if (whichArray == kAddressArray) cc->addresses = (cc_data **)constCBase;
- else cc->authdata = (cc_data **)constCBase;
+ }
- return 0;
+ return 0;
}
/*
@@ -136,52 +194,56 @@ int copyK5DataArrayToCC(krb5_creds *kc, cc_creds *cc, char whichArray) {
* - 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;
+void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest)
+{
+ krb5_int32 offset_seconds = 0, offset_microseconds = 0;
+ 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 */
+#if TARGET_OS_MAC
+ err = krb5_get_time_offsets(context, &offset_seconds, &offset_microseconds);
+ if (err) return;
+#endif
+ dest->times.authtime = src->authtime + offset_seconds;
+ dest->times.starttime = src->starttime + offset_seconds;
+ dest->times.endtime = src->endtime + offset_seconds;
+ dest->times.renew_till = src->renew_till + offset_seconds;
+ dest->is_skey = src->is_skey;
+ dest->ticket_flags = src->ticket_flags;
+
+ /* more branching fields */
+ err = copyCCDataArrayToK5(src, dest, kAddressArray);
+ if (err) return;
+
+ 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;
+
+ /* authdata */
+ err = copyCCDataArrayToK5(src, dest, kAuthDataArray);
+ if (err) return;
+
+ return;
}
/*
@@ -190,90 +252,97 @@ void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest) {
*/
void dupK5toCC(krb5_context context, krb5_creds *creds, cred_union **cu)
{
- cc_creds *c;
- int err;
+ cc_creds *c;
+ int err;
+ krb5_int32 offset_seconds = 0, offset_microseconds = 0;
#ifdef macintosh
- char *tempname = NULL;
+ char *tempname = NULL;
#endif
-
- if (cu == NULL) return;
-
- /* allocate the cred_union */
- *cu = (cred_union *)malloc(sizeof(cred_union));
- if ((*cu) == NULL)
- return;
-
- (*cu)->cred_type = CC_CRED_V5;
-
- /* allocate creds structure (and install) */
- c = (cc_creds *)malloc(sizeof(cc_creds));
- if (c == NULL) return;
- (*cu)->cred.pV5Cred = c;
-
- /* convert krb5 principals to flat principals */
+
+ if (cu == NULL) return;
+
+ /* allocate the cred_union */
+ *cu = (cred_union *)malloc(sizeof(cred_union));
+ if ((*cu) == NULL)
+ return;
+
+ (*cu)->cred_type = CC_CRED_V5;
+
+ /* allocate creds structure (and install) */
+ c = (cc_creds *)malloc(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 = malloc(strlen(tempname)+1);
- if (c->client != NULL)
- strcpy(c->client,tempname);
- free(tempname);
- tempname = NULL;
-
- err = krb5_unparse_name(context, creds->server, &tempname);
- c->server = malloc(strlen(tempname)+1);
- if (c->server != NULL)
- strcpy(c->server,tempname);
- free(tempname);
+ /*
+ * 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 = malloc(strlen(tempname)+1);
+ if (c->client != NULL)
+ strcpy(c->client,tempname);
+ free(tempname);
+ tempname = NULL;
+
+ err = krb5_unparse_name(context, creds->server, &tempname);
+ c->server = malloc(strlen(tempname)+1);
+ 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));
+ 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 *)malloc(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 *)malloc(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 *)malloc(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;
+ 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 *)malloc(creds->keyblock.length);
+ memcpy(c->keyblock.data, creds->keyblock.contents, creds->keyblock.length);
+ } else {
+ c->keyblock.data = NULL;
+ }
+
+#if TARGET_OS_MAC
+ err = krb5_get_time_offsets(context, &offset_seconds, &offset_microseconds);
+ if (err) return;
+#endif
+ c->authtime = creds->times.authtime - offset_seconds;
+ c->starttime = creds->times.starttime - offset_seconds;
+ c->endtime = creds->times.endtime - offset_seconds;
+ c->renew_till = creds->times.renew_till - offset_seconds;
+ c->is_skey = creds->is_skey;
+ c->ticket_flags = creds->ticket_flags;
+
+ err = copyK5DataArrayToCC(creds, c, kAddressArray);
+ if (err) return;
+
+ c->ticket.length = creds->ticket.length;
+ if (creds->ticket.data != NULL) {
+ c->ticket.data = (unsigned char *)malloc(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 *)malloc(creds->second_ticket.length);
+ memcpy(c->second_ticket.data, creds->second_ticket.data, creds->second_ticket.length);
+ } else {
+ c->second_ticket.data = NULL;
+ }
+
+ err = copyK5DataArrayToCC(creds, c, kAuthDataArray);
+ if (err) return;
+
+ return;
}
/*
@@ -281,7 +350,7 @@ void dupK5toCC(krb5_context context, krb5_creds *creds, cred_union **cu)
*/
static krb5_boolean
times_match(t1, t2)
-register const krb5_ticket_times *t1;
+ register const krb5_ticket_times *t1;
register const krb5_ticket_times *t2;
{
if (t1->renew_till) {
@@ -308,7 +377,7 @@ times_match_exact (t1, t2)
static krb5_boolean
standard_fields_match(context, mcreds, creds)
- krb5_context context;
+ krb5_context context;
register const krb5_creds *mcreds, *creds;
{
return (krb5_principal_compare(context, mcreds->client,creds->client) &&
@@ -319,12 +388,12 @@ register const krb5_creds *mcreds, *creds;
static krb5_boolean
srvname_match(context, mcreds, creds)
- krb5_context context;
+ krb5_context context;
register const krb5_creds *mcreds, *creds;
{
krb5_boolean retval;
krb5_principal_data p1, p2;
-
+
retval = krb5_principal_compare(context, mcreds->client,creds->client);
if (retval != TRUE)
return retval;
@@ -368,7 +437,7 @@ authdata_match(mdata, data)
static krb5_boolean
data_match(data1, data2)
-register const krb5_data *data1, *data2;
+ register const krb5_data *data1, *data2;
{
if (!data1) {
if (!data2)
@@ -396,117 +465,113 @@ register const krb5_data *data1, *data2;
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;
-
- if (((MATCH_SET(KRB5_TC_MATCH_SRV_NAMEONLY) &&
- srvname_match(context, match, base)) ||
- standard_fields_match(context, match, base))
- &&
- (! MATCH_SET(KRB5_TC_MATCH_IS_SKEY) ||
- match->is_skey == base->is_skey)
- &&
- (! MATCH_SET(KRB5_TC_MATCH_FLAGS_EXACT) ||
- match->ticket_flags == base->ticket_flags)
- &&
- (! MATCH_SET(KRB5_TC_MATCH_FLAGS) ||
- flags_match(match->ticket_flags, base->ticket_flags))
- &&
- (! MATCH_SET(KRB5_TC_MATCH_TIMES_EXACT) ||
- times_match_exact(&match->times, &base->times))
- &&
- (! MATCH_SET(KRB5_TC_MATCH_TIMES) ||
- times_match(&match->times, &base->times))
- &&
- (! MATCH_SET(KRB5_TC_MATCH_AUTHDATA) ||
- authdata_match (match->authdata, base->authdata))
- &&
- (! MATCH_SET(KRB5_TC_MATCH_2ND_TKT) ||
- data_match (&match->second_ticket, &base->second_ticket))
- &&
- ((! MATCH_SET(KRB5_TC_MATCH_KTYPE))||
- (match->keyblock.enctype == base->keyblock.enctype))
- )
- return TRUE;
- return FALSE;
-
+ if (((MATCH_SET(KRB5_TC_MATCH_SRV_NAMEONLY) &&
+ srvname_match(context, match, base)) ||
+ standard_fields_match(context, match, base))
+ &&
+ (! MATCH_SET(KRB5_TC_MATCH_IS_SKEY) ||
+ match->is_skey == base->is_skey)
+ &&
+ (! MATCH_SET(KRB5_TC_MATCH_FLAGS_EXACT) ||
+ match->ticket_flags == base->ticket_flags)
+ &&
+ (! MATCH_SET(KRB5_TC_MATCH_FLAGS) ||
+ flags_match(match->ticket_flags, base->ticket_flags))
+ &&
+ (! MATCH_SET(KRB5_TC_MATCH_TIMES_EXACT) ||
+ times_match_exact(&match->times, &base->times))
+ &&
+ (! MATCH_SET(KRB5_TC_MATCH_TIMES) ||
+ times_match(&match->times, &base->times))
+ &&
+ (! MATCH_SET(KRB5_TC_MATCH_AUTHDATA) ||
+ authdata_match (match->authdata, base->authdata))
+ &&
+ (! MATCH_SET(KRB5_TC_MATCH_2ND_TKT) ||
+ data_match (&match->second_ticket, &base->second_ticket))
+ &&
+ ((! MATCH_SET(KRB5_TC_MATCH_KTYPE))||
+ (match->keyblock.enctype == base->keyblock.enctype))
+ )
+ return TRUE;
+ return FALSE;
}
-// ----- free_cc_cred_union, etc --------------
+/* ----- free_cc_cred_union, etc -------------- */
/*
- Since the Kerberos5 library allocates a credentials cache structure
- (in dupK5toCC() above) with its own memory allocation routines - which
- may be different than how the CCache allocates memory - the Kerb5 library
- must have its own version of cc_free_creds() to deallocate it. These
- functions do that. The top-level function to substitue for cc_free_creds()
- is krb5_free_cc_cred_union().
-
- If the CCache library wants to use a cred_union structure created by
- the Kerb5 library, it should make a deep copy of it to "translate" to its
- own memory allocation space.
+ Since the Kerberos5 library allocates a credentials cache structure
+ (in dupK5toCC() above) with its own memory allocation routines - which
+ may be different than how the CCache allocates memory - the Kerb5 library
+ must have its own version of cc_free_creds() to deallocate it. These
+ functions do that. The top-level function to substitue for cc_free_creds()
+ is krb5_free_cc_cred_union().
+
+ If the CCache library wants to use a cred_union structure created by
+ the Kerb5 library, it should make a deep copy of it to "translate" to its
+ own memory allocation space.
*/
-static void deep_free_cc_data (cc_data data) {
-
- if (data.data != NULL)
- free (data.data);
+static void deep_free_cc_data (cc_data data)
+{
+ if (data.data != NULL)
+ free (data.data);
}
static void deep_free_cc_data_array (cc_data** data) {
-
- unsigned int index;
-
- if (data == NULL)
- return;
-
- for (index = 0; data [index] != NULL; index++) {
- deep_free_cc_data (*(data [index]));
- free (data [index]);
- }
-
- free (data);
+
+ unsigned int index;
+
+ if (data == NULL)
+ return;
+
+ for (index = 0; data [index] != NULL; index++) {
+ deep_free_cc_data (*(data [index]));
+ free (data [index]);
+ }
+
+ free (data);
}
-static void deep_free_cc_v5_creds (cc_creds* creds) {
-
- if (creds == NULL)
- return;
-
- if (creds -> client != NULL)
- free (creds -> client);
- if (creds -> server != NULL)
- free (creds -> server);
-
- deep_free_cc_data (creds -> keyblock);
- deep_free_cc_data (creds -> ticket);
- deep_free_cc_data (creds -> second_ticket);
-
- deep_free_cc_data_array (creds -> addresses);
- deep_free_cc_data_array (creds -> authdata);
-
- free(creds);
+static void deep_free_cc_v5_creds (cc_creds* creds)
+{
+ if (creds == NULL)
+ return;
+
+ if (creds -> client != NULL)
+ free (creds -> client);
+ if (creds -> server != NULL)
+ free (creds -> server);
+
+ deep_free_cc_data (creds -> keyblock);
+ deep_free_cc_data (creds -> ticket);
+ deep_free_cc_data (creds -> second_ticket);
+
+ deep_free_cc_data_array (creds -> addresses);
+ deep_free_cc_data_array (creds -> authdata);
+
+ free(creds);
}
-static void deep_free_cc_creds (cred_union creds) {
-
- if (creds.cred_type == CC_CRED_V4) { // we shouldn't get this, of course
- free (creds.cred.pV4Cred);
- } else if (creds.cred_type == CC_CRED_V5) {
- deep_free_cc_v5_creds (creds.cred.pV5Cred);
- }
+static void deep_free_cc_creds (cred_union creds)
+{
+ if (creds.cred_type == CC_CRED_V4) {
+ /* we shouldn't get this, of course */
+ free (creds.cred.pV4Cred);
+ } else if (creds.cred_type == CC_CRED_V5) {
+ deep_free_cc_v5_creds (creds.cred.pV5Cred);
+ }
}
-// top-level exported function
-cc_int32 krb5_free_cc_cred_union (cred_union** creds) {
-
- if (creds == NULL)
- return CC_BAD_PARM;
-
- if (*creds != NULL) {
- deep_free_cc_creds (**creds);
- free (*creds);
- *creds = NULL;
- }
-
- return CC_NOERROR;
+/* top-level exported function */
+cc_int32 krb5_free_cc_cred_union (cred_union** creds)
+{
+ if (creds == NULL)
+ return CC_BAD_PARM;
+
+ if (*creds != NULL) {
+ deep_free_cc_creds (**creds);
+ free (*creds);
+ *creds = NULL;
+ }
+
+ return CC_NOERROR;
}
diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.h b/src/lib/krb5/ccache/ccapi/stdcc_util.h
index 93538bf..e8426d4 100644
--- a/src/lib/krb5/ccache/ccapi/stdcc_util.h
+++ b/src/lib/krb5/ccache/ccapi/stdcc_util.h
@@ -1,9 +1,10 @@
-//stdcc_util.h
-//
-// Frank Dabek, July 1998
+/* stdcc_util.h
+ *
+ * Frank Dabek, July 1998
+ */
-#if defined(macintosh)
-#include "CCache2.h"
+#if TARGET_OS_MAC
+#include <Kerberos/CredentialsCache2.h>
#endif
#if defined(_MSDOS) || defined(_WIN32)
@@ -12,7 +13,7 @@
#include "krb5.h"
-//protoypes for private functions declared in stdcc_util.c
+/* 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);
diff --git a/src/lib/krb5/ccache/ccapi/winccld.c b/src/lib/krb5/ccache/ccapi/winccld.c
index 2792cee..e6e4d58 100644
--- a/src/lib/krb5/ccache/ccapi/winccld.c
+++ b/src/lib/krb5/ccache/ccapi/winccld.c
@@ -7,6 +7,7 @@
#include <windows.h>
#include <stdio.h>
#include "stdcc.h"
+#include "k5-int.h"
/* from fcc-proto.h */
KRB5_DLLIMP extern krb5_cc_ops krb5_fcc_ops;
@@ -45,6 +46,8 @@ static int LoadFuncs(const char* dll_name, FUNC_INFO fi[],
}
if (!(h = LoadLibrary(dll_name))) {
+ /* Get error for source debugging purposes. */
+ error = (int)GetLastError();
return LF_NODLL;
}
diff --git a/src/lib/krb5/ccache/ccapi/winccld.h b/src/lib/krb5/ccache/ccapi/winccld.h
index 09a7ef5..e285d1f 100644
--- a/src/lib/krb5/ccache/ccapi/winccld.h
+++ b/src/lib/krb5/ccache/ccapi/winccld.h
@@ -6,6 +6,10 @@
#ifndef KRB5_WINCCLD_H_
#define KRB5_WINCCLD_H_
+#ifndef CC_API_VER2
+#define CC_API_VER2
+#endif
+
#include "cacheapi.h"
typedef cc_int32 (*FP_cc_initialize)(apiCB**, const cc_int32,
@@ -19,6 +23,9 @@ typedef cc_int32 (*FP_cc_open)(apiCB*, const char*, const enum cc_cred_vers,
typedef cc_int32 (*FP_cc_close)(apiCB*, ccache_p**);
typedef cc_int32 (*FP_cc_destroy)(apiCB*, ccache_p**);
typedef cc_int32 (*FP_cc_seq_fetch_NCs)(apiCB*, ccache_p**, ccache_cit**);
+typedef cc_int32 (*FP_cc_seq_fetch_NCs_begin)(apiCB*, ccache_cit**);
+typedef cc_int32 (*FP_cc_seq_fetch_NCs_next)(apiCB*, ccache_p**, ccache_cit*);
+typedef cc_int32 (*FP_cc_seq_fetch_NCs_end)(apiCB*, ccache_cit**);
typedef cc_int32 (*FP_cc_get_NC_info)(apiCB*, struct _infoNC***);
typedef cc_int32 (*FP_cc_free_NC_info)(apiCB*, struct _infoNC***);
typedef cc_int32 (*FP_cc_get_name)(apiCB*, const ccache_p*, char**);
@@ -34,6 +41,11 @@ typedef cc_int32 (*FP_cc_remove_cred)(apiCB*, const ccache_p*,
const cred_union);
typedef cc_int32 (*FP_cc_seq_fetch_creds)(apiCB*, const ccache_p*,
cred_union**, ccache_cit**);
+typedef cc_int32 (*FP_cc_seq_fetch_creds_begin)(apiCB*, const ccache_p*,
+ ccache_cit**);
+typedef cc_int32 (*FP_cc_seq_fetch_creds_next)(apiCB*, cred_union**,
+ ccache_cit*);
+typedef cc_int32 (*FP_cc_seq_fetch_creds_end)(apiCB*, ccache_cit**);
typedef cc_int32 (*FP_cc_free_principal)(apiCB*, char**);
typedef cc_int32 (*FP_cc_free_name)(apiCB*, char** name);
typedef cc_int32 (*FP_cc_free_creds)(apiCB*, cred_union** pCred);
@@ -58,17 +70,33 @@ DECL_FUNC_PTR(cc_create);
DECL_FUNC_PTR(cc_open);
DECL_FUNC_PTR(cc_close);
DECL_FUNC_PTR(cc_destroy);
+#if 0 /* Not used */
+#ifdef CC_API_VER2
+DECL_FUNC_PTR(cc_seq_fetch_NCs_begin);
+DECL_FUNC_PTR(cc_seq_fetch_NCs_next);
+DECL_FUNC_PTR(cc_seq_fetch_NCs_end);
+#else
DECL_FUNC_PTR(cc_seq_fetch_NCs);
+#endif
DECL_FUNC_PTR(cc_get_NC_info);
DECL_FUNC_PTR(cc_free_NC_info);
+#endif
DECL_FUNC_PTR(cc_get_name);
DECL_FUNC_PTR(cc_set_principal);
DECL_FUNC_PTR(cc_get_principal);
DECL_FUNC_PTR(cc_get_cred_version);
+#if 0 /* Not used */
DECL_FUNC_PTR(cc_lock_request);
+#endif
DECL_FUNC_PTR(cc_store);
DECL_FUNC_PTR(cc_remove_cred);
+#ifdef CC_API_VER2
+DECL_FUNC_PTR(cc_seq_fetch_creds_begin);
+DECL_FUNC_PTR(cc_seq_fetch_creds_next);
+DECL_FUNC_PTR(cc_seq_fetch_creds_end);
+#else
DECL_FUNC_PTR(cc_seq_fetch_creds);
+#endif
DECL_FUNC_PTR(cc_free_principal);
DECL_FUNC_PTR(cc_free_name);
DECL_FUNC_PTR(cc_free_creds);
@@ -82,17 +110,27 @@ FUNC_INFO krbcc_fi[] = {
MAKE_FUNC_INFO(cc_open),
MAKE_FUNC_INFO(cc_close),
MAKE_FUNC_INFO(cc_destroy),
+#if 0 /* Not used */
MAKE_FUNC_INFO(cc_seq_fetch_NCs),
MAKE_FUNC_INFO(cc_get_NC_info),
MAKE_FUNC_INFO(cc_free_NC_info),
+#endif
MAKE_FUNC_INFO(cc_get_name),
MAKE_FUNC_INFO(cc_set_principal),
MAKE_FUNC_INFO(cc_get_principal),
MAKE_FUNC_INFO(cc_get_cred_version),
+#if 0 /* Not used */
MAKE_FUNC_INFO(cc_lock_request),
+#endif
MAKE_FUNC_INFO(cc_store),
MAKE_FUNC_INFO(cc_remove_cred),
+#ifdef CC_API_VER2
+ MAKE_FUNC_INFO(cc_seq_fetch_creds_begin),
+ MAKE_FUNC_INFO(cc_seq_fetch_creds_next),
+ MAKE_FUNC_INFO(cc_seq_fetch_creds_end),
+#else
MAKE_FUNC_INFO(cc_seq_fetch_creds),
+#endif
MAKE_FUNC_INFO(cc_free_principal),
MAKE_FUNC_INFO(cc_free_name),
MAKE_FUNC_INFO(cc_free_creds),
@@ -109,17 +147,33 @@ FUNC_INFO krbcc_fi[] = {
#define cc_open pcc_open
#define cc_close pcc_close
#define cc_destroy pcc_destroy
+#if 0 /* Not used */
+#ifdef CC_API_VER2
+#define cc_seq_fetch_NCs_begin pcc_seq_fetch_NCs_begin
+#define cc_seq_fetch_NCs_next pcc_seq_fetch_NCs_next
+#define cc_seq_fetch_NCs_end pcc_seq_fetch_NCs_end
+#else
#define cc_seq_fetch_NCs pcc_seq_fetch_NCs
+#endif
#define cc_get_NC_info pcc_get_NC_info
#define cc_free_NC_info pcc_free_NC_info
+#endif /* End of Not used */
#define cc_get_name pcc_get_name
#define cc_set_principal pcc_set_principal
#define cc_get_principal pcc_get_principal
#define cc_get_cred_version pcc_get_cred_version
+#if 0 /* Not used */
#define cc_lock_request pcc_lock_request
+#endif
#define cc_store pcc_store
#define cc_remove_cred pcc_remove_cred
+#ifdef CC_API_VER2
+#define cc_seq_fetch_creds_begin pcc_seq_fetch_creds_begin
+#define cc_seq_fetch_creds_next pcc_seq_fetch_creds_next
+#define cc_seq_fetch_creds_end pcc_seq_fetch_creds_end
+#else
#define cc_seq_fetch_creds pcc_seq_fetch_creds
+#endif
#define cc_free_principal pcc_free_principal
#define cc_free_name pcc_free_name
#define cc_free_creds pcc_free_creds
diff --git a/src/lib/krb5/ccache/ccdefault.c b/src/lib/krb5/ccache/ccdefault.c
index 3e2699c..fc3e0ad 100644
--- a/src/lib/krb5/ccache/ccdefault.c
+++ b/src/lib/krb5/ccache/ccdefault.c
@@ -27,6 +27,10 @@
* Find default credential cache
*/
+#ifdef USE_LOGIN_LIBRARY
+#include <Kerberos/KerberosLoginPrivate.h>
+#endif
+
#include "k5-int.h"
KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
@@ -34,5 +38,83 @@ krb5_cc_default(context, ccache)
krb5_context context;
krb5_ccache FAR *ccache;
{
- return krb5_cc_resolve(context, krb5_cc_default_name(context), ccache);
+ krb5_error_code retval;
+ krb5_os_context os_ctx;
+
+ if (!context || context->magic != KV5M_CONTEXT)
+ return KV5M_CONTEXT;
+
+ os_ctx = context->os_context;
+
+ retval = krb5_cc_resolve(context, krb5_cc_default_name(context), ccache);
+ if (!retval && ccache && !os_ctx->default_ccprincipal) {
+ /* We got a ccache... remember what principal is associated with it */
+ if (krb5_cc_get_principal (context, *ccache, &os_ctx->default_ccprincipal) != 0)
+ os_ctx->default_ccprincipal = 0;
+ }
+ return retval;
+}
+
+/* This is the internal function which opens the default ccache. On platforms supporting
+ the login library's automatic popup dialog to get tickets, this function also updated the
+ library's internal view of the current principal associated with this cache.
+
+ All krb5 and GSS functions which need to open a cache to get a tgt to obtain service tickets
+ should call this function, not krb5_cc_default() */
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5int_cc_default(context, ccache)
+ krb5_context context;
+ krb5_ccache FAR *ccache;
+{
+#ifdef USE_LOGIN_LIBRARY
+ {
+ /* make sure the default cache has tix before you open it */
+ char *outCacheName;
+ KLPrincipal desiredPrincipal = nil;
+ krb5_principal desiredKrb5Principal;
+ krb5_error_code err;
+ krb5_os_context os_ctx;
+
+ if (!context || context->magic != KV5M_CONTEXT)
+ return KV5M_CONTEXT;
+
+ os_ctx = context->os_context;
+
+ desiredKrb5Principal = os_ctx->default_ccprincipal;
+
+ /* do we want a specific client principal? */
+ if (desiredKrb5Principal != NULL) {
+ char *desiredName;
+
+ err = krb5_unparse_name (context, desiredKrb5Principal, &desiredName);
+ if (!err) {
+ err = KLCreatePrincipalFromString (desiredName,
+ kerberosVersion_V5, &desiredPrincipal);
+ krb5_free_unparsed_name (context, desiredName);
+ if (err != klNoErr)
+ desiredPrincipal = nil;
+ }
+ }
+
+ /* Try to make sure a krb5 tgt is in the cache */
+ err = __KLInternalAcquireInitialTicketsForCache (desiredPrincipal, NULL,
+ krb5_cc_default_name (context),
+ kerberosVersion_V5, nil, &outCacheName);
+ if (err == klNoErr) {
+ /* This function tries to get tickets and put them in the specified
+ cache, however, if the cache does not exist, it may choose to put
+ them elsewhere (ie: the system default) so we set that here */
+ if (strcmp (krb5_cc_default_name (context), outCacheName) != 0) {
+ krb5_cc_set_default_name (context, outCacheName);
+ }
+ KLDisposeString (outCacheName);
+ }
+
+ if (desiredPrincipal != nil)
+ KLDisposePrincipal (desiredPrincipal);
+ }
+#endif
+
+ return krb5_cc_default (context, ccache);
}
diff --git a/src/lib/krb5/ccache/ccdefops.c b/src/lib/krb5/ccache/ccdefops.c
index 2651273..092503e 100644
--- a/src/lib/krb5/ccache/ccdefops.c
+++ b/src/lib/krb5/ccache/ccdefops.c
@@ -30,7 +30,7 @@
#include "k5-int.h"
-#if defined(macintosh)
+#if defined(USE_CCAPI)
/*
* Macs use the shared, memory based credentials cache
diff --git a/src/lib/krb5/ccache/ccfns.c b/src/lib/krb5/ccache/ccfns.c
new file mode 100644
index 0000000..b12c93e
--- /dev/null
+++ b/src/lib/krb5/ccache/ccfns.c
@@ -0,0 +1,131 @@
+/*
+ * lib/krb5/ccache/ccfns.c
+ *
+ * Copyright 2000 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ */
+
+/*
+ * Dispatch methods for credentials cache code.
+ */
+
+#include "k5-int.h"
+#include "krb5.h"
+
+#if KRB5_CCACHE_ACCESSOR_FUNCTIONS
+
+const char FAR * KRB5_CALLCONV
+krb5_cc_get_name (krb5_context context, krb5_ccache cache)
+{
+ return cache->ops->get_name(context, cache);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_gen_new (krb5_context context, krb5_ccache FAR *cache)
+{
+ return (*cache)->ops->gen_new(context, cache);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_initialize(krb5_context context, krb5_ccache cache,
+ krb5_principal principal)
+{
+ return cache->ops->init(context, cache, principal);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_destroy (krb5_context context, krb5_ccache cache)
+{
+ return cache->ops->destroy(context, cache);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_close (krb5_context context, krb5_ccache cache)
+{
+ return cache->ops->close(context, cache);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_store_cred (krb5_context context, krb5_ccache cache,
+ krb5_creds FAR *creds)
+{
+ return cache->ops->store(context, cache, creds);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_retrieve_cred (krb5_context context, krb5_ccache cache,
+ krb5_flags flags, krb5_creds FAR *mcreds,
+ krb5_creds FAR *creds)
+{
+ return cache->ops->retrieve(context, cache, flags, mcreds, creds);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_get_principal (krb5_context context, krb5_ccache cache,
+ krb5_principal FAR *principal)
+{
+ return cache->ops->get_princ(context, cache, principal);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_start_seq_get (krb5_context context, krb5_ccache cache,
+ krb5_cc_cursor FAR *cursor)
+{
+ return cache->ops->get_first(context, cache, cursor);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_next_cred (krb5_context context, krb5_ccache cache,
+ krb5_cc_cursor FAR *cursor, krb5_creds FAR *creds)
+{
+ return cache->ops->get_next(context, cache, cursor, creds);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_end_seq_get (krb5_context context, krb5_ccache cache,
+ krb5_cc_cursor FAR *cursor)
+{
+ return cache->ops->end_get(context, cache, cursor);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_remove_cred (krb5_context context, krb5_ccache cache, krb5_flags flags,
+ krb5_creds FAR *creds)
+{
+ return cache->ops->remove_cred(context, cache, flags, creds);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_set_flags (krb5_context context, krb5_ccache cache, krb5_flags flags)
+{
+ return cache->ops->set_flags(context, cache, flags);
+}
+
+const char FAR * KRB5_CALLCONV
+krb5_cc_get_type (krb5_context context, krb5_ccache cache)
+{
+ return cache->ops->prefix;
+}
+#else
+/* Dummy variable for compilers which don't like empty files */
+static krb5_int dummy = 0;
+#endif /* KRB5_CCACHE_ACCESSOR_FUNCTIONS */ \ No newline at end of file
diff --git a/src/lib/krb5/ccache/file/ChangeLog b/src/lib/krb5/ccache/file/ChangeLog
index 298360b..cda7184 100644
--- a/src/lib/krb5/ccache/file/ChangeLog
+++ b/src/lib/krb5/ccache/file/ChangeLog
@@ -1,3 +1,6 @@
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * fcc_gprinc.c: removed unused data variable to reduce warnings
+
1999-10-26 Tom Yu <tlyu@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/krb5/ccache/file/fcc_gprin.c b/src/lib/krb5/ccache/file/fcc_gprin.c
index b8a2595..bbac185 100644
--- a/src/lib/krb5/ccache/file/fcc_gprin.c
+++ b/src/lib/krb5/ccache/file/fcc_gprin.c
@@ -50,7 +50,6 @@ krb5_fcc_get_principal(context, id, princ)
krb5_principal *princ;
{
krb5_error_code kret = KRB5_OK;
- krb5_fcc_data *data = (krb5_fcc_data *)id->data;
MAYBE_OPEN(context, id, FCC_OPEN_RDONLY);
diff --git a/src/lib/krb5/ccache/stdio/ChangeLog b/src/lib/krb5/ccache/stdio/ChangeLog
index c520ca3..1379190 100644
--- a/src/lib/krb5/ccache/stdio/ChangeLog
+++ b/src/lib/krb5/ccache/stdio/ChangeLog
@@ -1,3 +1,6 @@
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * scc_skip.c: removed unused princ variable to reduce warnings
+
1999-10-26 Tom Yu <tlyu@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/krb5/ccache/stdio/scc_skip.c b/src/lib/krb5/ccache/stdio/scc_skip.c
index c203c71..9c86cb7 100644
--- a/src/lib/krb5/ccache/stdio/scc_skip.c
+++ b/src/lib/krb5/ccache/stdio/scc_skip.c
@@ -37,7 +37,6 @@ krb5_scc_skip_header(context, id)
krb5_ccache id;
{
krb5_error_code kret;
- krb5_principal princ;
krb5_scc_data *data = (krb5_scc_data *) id->data;
krb5_ui_2 scc_flen;
diff --git a/src/lib/krb5/error_tables/ChangeLog b/src/lib/krb5/error_tables/ChangeLog
index d93bf5e..710d7a4 100644
--- a/src/lib/krb5/error_tables/ChangeLog
+++ b/src/lib/krb5/error_tables/ChangeLog
@@ -1,3 +1,19 @@
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * krb5_err.et: Changed Credentials Cache file to Credentials Cache
+ because on Mac and Windows, the credentials cache is in memory.
+
+2001-10-24 Tom Yu <tlyu@mit.edu>
+
+ * kdb5_err.et: Add KRB5_KDB_NO_PERMITTED_KEY,
+ KRB5_KDB_NO_MATCHING_KEY for libkdb so we can return something
+ other than ENOENT (which was Just Wrong).
+
+2001-01-31 Tom Yu <tlyu@mit.edu>
+
+ * asn1_err.et: Add error codes MISMATCH_INDEF and MISSING_EOC.
+ [pullup from trunk]
+
1999-12-01 Ken Raeburn <raeburn@mit.edu>
* krb5_err.et (KRB5_OBSOLETE_FN): New error code.
diff --git a/src/lib/krb5/error_tables/asn1_err.et b/src/lib/krb5/error_tables/asn1_err.et
index f0136cf..06078ff 100644
--- a/src/lib/krb5/error_tables/asn1_err.et
+++ b/src/lib/krb5/error_tables/asn1_err.et
@@ -10,4 +10,6 @@ error_code ASN1_BAD_LENGTH, "ASN.1 length doesn't match expected value"
error_code ASN1_BAD_FORMAT, "ASN.1 badly-formatted encoding"
error_code ASN1_PARSE_ERROR, "ASN.1 parse error"
error_code ASN1_BAD_GMTIME, "ASN.1 bad return from gmtime"
+error_code ASN1_MISMATCH_INDEF, "ASN.1 non-constructed indefinite encoding"
+error_code ASN1_MISSING_EOC, "ASN.1 missing expected EOC"
end
diff --git a/src/lib/krb5/error_tables/kdb5_err.et b/src/lib/krb5/error_tables/kdb5_err.et
index 982a9c1..aee3c4a 100644
--- a/src/lib/krb5/error_tables/kdb5_err.et
+++ b/src/lib/krb5/error_tables/kdb5_err.et
@@ -66,4 +66,6 @@ ec KRB5_KDB_BAD_VERSION, "Unsupported version in database entry"
ec KRB5_KDB_BAD_SALTTYPE, "Unsupported salt type"
ec KRB5_KDB_BAD_ENCTYPE, "Unsupported encryption type"
ec KRB5_KDB_BAD_CREATEFLAGS, "Bad database creation flags"
+ec KRB5_KDB_NO_PERMITTED_KEY, "No matching key in entry having a permitted enctype"
+ec KRB5_KDB_NO_MATCHING_KEY, "No matching key in entry"
end
diff --git a/src/lib/krb5/error_tables/krb5_err.et b/src/lib/krb5/error_tables/krb5_err.et
index 6135a9d..8ff5ff3 100644
--- a/src/lib/krb5/error_tables/krb5_err.et
+++ b/src/lib/krb5/error_tables/krb5_err.et
@@ -259,10 +259,10 @@ error_code KRB5_CC_TYPE_EXISTS, "Credentials cache type is already registered."
error_code KRB5_KT_TYPE_EXISTS, "Key table type is already registered."
error_code KRB5_CC_IO, "Credentials cache I/O operation failed XXX"
-error_code KRB5_FCC_PERM, "Credentials cache file permissions incorrect"
-error_code KRB5_FCC_NOFILE, "No credentials cache file found"
-error_code KRB5_FCC_INTERNAL, "Internal file credentials cache error"
-error_code KRB5_CC_WRITE, "Error writing to credentials cache file"
+error_code KRB5_FCC_PERM, "Credentials cache permissions incorrect"
+error_code KRB5_FCC_NOFILE, "No credentials cache found"
+error_code KRB5_FCC_INTERNAL, "Internal credentials cache error"
+error_code KRB5_CC_WRITE, "Error writing to credentials cache"
error_code KRB5_CC_NOMEM, "No more memory to allocate (in credentials cache code)"
error_code KRB5_CC_FORMAT, "Bad format in credentials cache"
error_code KRB5_CC_NOT_KTYPE, "No credentials found with supported encryption types"
diff --git a/src/lib/krb5/keytab/ChangeLog b/src/lib/krb5/keytab/ChangeLog
index fa1e715..ab4e5e4 100644
--- a/src/lib/krb5/keytab/ChangeLog
+++ b/src/lib/krb5/keytab/ChangeLog
@@ -1,3 +1,27 @@
+2003-04-01 Nalin Dahyabhai <nalin@redhat.com>
+
+ * kt_file.c (krb5_ktfileint_internal_read_entry): Use
+ krb5_princ_size instead of direct field access.
+ (krb5_ktfileint_write_entry, krb5_ktfileint_size_entry):
+ Likewise.
+
+2002-04-05 Danilo Almeida <dalmeida@mit.edu>
+
+ * Makefile.in: Build kt accessor functions on Windows.
+
+ * ktfr_entry.c: Rename krb5_kt_free_entry_contents as
+ krb5_free_keytab_entry_contents to make it consistent with rest of
+ API.
+
+2002-04-02 Ken Raeburn <raeburn@mit.edu>
+
+ * ktfr_entry.c (krb5_kt_free_entry_contents): Rename from
+ krb5_kt_free_entry, keep old name as wrapper.
+
+2000-04-01 Miro Jurisic <meeroh@mit.edu>
+
+ * ktfns.c: Merged from trunk
+
2000-03-12 Ezra Peisach <epeisach@mit.edu>
* ktbase.c (krb5_kt_resolve): Change prototype from const to
diff --git a/src/lib/krb5/keytab/Makefile.in b/src/lib/krb5/keytab/Makefile.in
index 66677a1..7d2b023 100644
--- a/src/lib/krb5/keytab/Makefile.in
+++ b/src/lib/krb5/keytab/Makefile.in
@@ -35,6 +35,8 @@ SRCS= \
$(srcdir)/ktremove.c \
$(srcdir)/read_servi.c
+##DOS##OBJS=$(OBJS) $(OUTPRE)ktfns.$(OBJEXT)
+
all-windows:: subdirs $(OBJFILE)
##DOSsubdirs:: file\$(OUTPRE)file.lst srvtab\$(OUTPRE)srvtab.lst
diff --git a/src/lib/krb5/keytab/file/ChangeLog b/src/lib/krb5/keytab/file/ChangeLog
index 4be401b..d0ececa 100644
--- a/src/lib/krb5/keytab/file/ChangeLog
+++ b/src/lib/krb5/keytab/file/ChangeLog
@@ -1,3 +1,16 @@
+2002-01-30 Ken Raeburn <raeburn@mit.edu>
+
+ * ktf_g_ent.c (krb5_ktfile_get_entry): For non-zero kvno, match
+ only low 8 bits. For zero kvno, if any kvno in the keytab is over
+ 240, assume we're dealing with numbers 128 through (127+256)
+ instead. This allows for wrapping at 256 while retaining a small
+ set of consecutively numbered prior keys in the keytab.
+
+2001-11-19 Tom Yu <tlyu@mit.edu>
+
+ * ktf_g_ent.c (krb5_ktfile_get_entry): Coerce enctype for now to
+ restore 1.0.x enctype similarity behavior.
+
1999-10-26 Tom Yu <tlyu@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/krb5/keytab/file/ktf_g_ent.c b/src/lib/krb5/keytab/file/ktf_g_ent.c
index b45ab6f..905ff6c 100644
--- a/src/lib/krb5/keytab/file/ktf_g_ent.c
+++ b/src/lib/krb5/keytab/file/ktf_g_ent.c
@@ -45,6 +45,7 @@ krb5_ktfile_get_entry(context, id, principal, kvno, enctype, entry)
krb5_error_code kerror = 0;
int found_wrong_kvno = 0;
krb5_boolean similar;
+ int kvno_offset = 0;
/* Open the keyfile for reading */
if ((kerror = krb5_ktfileint_openr(context, id)))
@@ -81,6 +82,14 @@ krb5_ktfile_get_entry(context, id, principal, kvno, enctype, entry)
krb5_kt_free_entry(context, &new_entry);
continue;
}
+ /*
+ * Coerce the enctype of the output keyblock in case we
+ * got an inexact match on the enctype; this behavior will
+ * go away when the key storage architecture gets
+ * redesigned for 1.3.
+ */
+ new_entry.key.enctype = enctype;
+
}
/* if the principal isn't the one requested, free new_entry
@@ -95,9 +104,24 @@ krb5_ktfile_get_entry(context, id, principal, kvno, enctype, entry)
/* if this is the first match, or if the new vno is
bigger, free the current and keep the new. Otherwise,
free the new. */
-
+ /* A 1.2.x keytab contains only the low 8 bits of the key
+ version number. Since it can be much bigger, and thus
+ the 8-bit value can wrap, we need some heuristics to
+ figure out the "highest" numbered key if some numbers
+ close to 255 and some near 0 are used.
+
+ The heuristic here:
+
+ If we have any keys with versions over 240, then assume
+ that all version numbers 0-127 refer to 256+N instead.
+ Not perfect, but maybe good enough? */
+
+#define M(VNO) (((VNO) - kvno_offset + 256) % 256)
+
+ if (new_entry.vno > 240)
+ kvno_offset = 128;
if (! cur_entry.principal ||
- (new_entry.vno > cur_entry.vno)) {
+ M(new_entry.vno) > M(cur_entry.vno)) {
krb5_kt_free_entry(context, &cur_entry);
cur_entry = new_entry;
} else {
@@ -108,8 +132,12 @@ krb5_ktfile_get_entry(context, id, principal, kvno, enctype, entry)
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 */
+ /* Yuck. The krb5-1.2.x keytab format only stores one byte
+ for the kvno, so we're toast if the kvno requested is
+ higher than that. Short-term workaround: only compare
+ the low 8 bits. */
- if (new_entry.vno == kvno) {
+ if (new_entry.vno == (kvno & 0xff)) {
krb5_kt_free_entry(context, &cur_entry);
cur_entry = new_entry;
break;
diff --git a/src/lib/krb5/keytab/ktfns.c b/src/lib/krb5/keytab/ktfns.c
new file mode 100644
index 0000000..5bd6b40
--- /dev/null
+++ b/src/lib/krb5/keytab/ktfns.c
@@ -0,0 +1,80 @@
+/*
+ * lib/krb5/keytab/ktfns.c
+ *
+ * Copyright 2001 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ */
+
+/*
+ * Dispatch methods for keytab code.
+ */
+
+#include "krb5.h"
+#include "k5-int.h"
+
+char * KRB5_CALLCONV
+krb5_kt_get_type (krb5_context context, krb5_keytab keytab)
+{
+ return keytab->ops->prefix;
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_kt_get_name(krb5_context context, krb5_keytab keytab, char *name,
+ unsigned int namelen)
+{
+ return krb5_x((keytab)->ops->get_name,(context, keytab,name,namelen));
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_kt_close(krb5_context context, krb5_keytab keytab)
+{
+ return krb5_x((keytab)->ops->close,(context, keytab));
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_kt_get_entry(krb5_context context, krb5_keytab keytab,
+ krb5_const_principal principal, krb5_kvno vno,
+ krb5_enctype enctype, krb5_keytab_entry *entry)
+{
+ return krb5_x((keytab)->ops->get,(context, keytab, principal, vno, enctype, entry));
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_kt_start_seq_get(krb5_context context, krb5_keytab keytab,
+ krb5_kt_cursor *cursor)
+{
+ return krb5_x((keytab)->ops->start_seq_get,(context, keytab, cursor));
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_kt_next_entry(krb5_context context, krb5_keytab keytab,
+ krb5_keytab_entry *entry, krb5_kt_cursor *cursor)
+{
+ return krb5_x((keytab)->ops->get_next,(context, keytab, entry, cursor));
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_kt_end_seq_get(krb5_context context, krb5_keytab keytab,
+ krb5_kt_cursor *cursor)
+{
+ return krb5_x((keytab)->ops->end_get,(context, keytab, cursor));
+}
diff --git a/src/lib/krb5/keytab/ktfr_entry.c b/src/lib/krb5/keytab/ktfr_entry.c
index ddccb17..abd5d4d 100644
--- a/src/lib/krb5/keytab/ktfr_entry.c
+++ b/src/lib/krb5/keytab/ktfr_entry.c
@@ -30,7 +30,7 @@
#include "k5-int.h"
KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
-krb5_kt_free_entry (context, entry)
+krb5_free_keytab_entry_contents (context, entry)
krb5_context context;
krb5_keytab_entry FAR *entry;
{
@@ -44,3 +44,11 @@ krb5_kt_free_entry (context, entry)
}
return 0;
}
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_kt_free_entry (context, entry)
+ krb5_context context;
+ krb5_keytab_entry FAR *entry;
+{
+ return krb5_free_keytab_entry_contents (context, entry);
+}
diff --git a/src/lib/krb5/keytab/srvtab/ChangeLog b/src/lib/krb5/keytab/srvtab/ChangeLog
index a4157a0..8724b71 100644
--- a/src/lib/krb5/keytab/srvtab/ChangeLog
+++ b/src/lib/krb5/keytab/srvtab/ChangeLog
@@ -1,9 +1,17 @@
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * kts_util.c: removed unused variable n
+
+2002-02-05 Ken Raeburn <raeburn@mit.edu>
+
+ * kts_g_ent.c (krb5_ktsrvtab_get_entry): If a specific DES enctype
+ was requested, set the key's enctype to it, instead of always
+ returning des-cbc-crc.
+
Fri Jan 28 19:53:44 2000 Ezra Peisach <epeisach@mit.edu>
* kts_g_ent.c, ktsrvtab.h (krb5_ktsrvtab_get_entry): Change the
third argument to krb5_const_principal (from krb5_principal) to
agree with krb5_kts_ops entries.
-
1999-10-26 Tom Yu <tlyu@mit.edu>
diff --git a/src/lib/krb5/keytab/srvtab/kts_g_ent.c b/src/lib/krb5/keytab/srvtab/kts_g_ent.c
index e422c38..0237241 100644
--- a/src/lib/krb5/keytab/srvtab/kts_g_ent.c
+++ b/src/lib/krb5/keytab/srvtab/kts_g_ent.c
@@ -65,6 +65,7 @@ krb5_ktsrvtab_get_entry(context, id, principal, kvno, enctype, entry)
best_entry.vno = 0;
best_entry.key.contents = 0;
while ((kerror = krb5_ktsrvint_read_entry(context, id, &ent)) == 0) {
+ ent.key.enctype = enctype;
if (krb5_principal_compare(context, principal, ent.principal)) {
if (kvno == IGNORE_VNO) {
if (!best_entry.principal || (best_entry.vno < ent.vno)) {
diff --git a/src/lib/krb5/keytab/srvtab/kts_util.c b/src/lib/krb5/keytab/srvtab/kts_util.c
index d95aceb..35f4a16 100644
--- a/src/lib/krb5/keytab/srvtab/kts_util.c
+++ b/src/lib/krb5/keytab/srvtab/kts_util.c
@@ -62,7 +62,7 @@ read_field(fp, s, len)
char *s;
int len;
{
- int c, n = 0;
+ int c = 0;
while ((c = getc(fp)) != 0) {
if (c == EOF || len <= 1)
diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog
index 59d8765..1cc8d59 100644
--- a/src/lib/krb5/krb/ChangeLog
+++ b/src/lib/krb5/krb/ChangeLog
@@ -1,3 +1,301 @@
+2003-04-01 Nalin Dahyabhai <nalin@redhat.com>
+
+ * gc_frm_kdc.c (krb5_get_cred_from_kdc_opt): Check principal name
+ length before examining components.
+
+ * parse.c (krb5_parse_name): Double-check principal name length
+ before filling in components.
+
+ * srv_rcache.c (krb5_get_server_rcache): Check for null pointer
+ supplied in place of name.
+
+ * unparse.c (krb5_unparse_name_ext): Don't move buffer pointer
+ backwards if nothing has been put into the buffer yet.
+
+2002-10-30 Tom Yu <tlyu@mit.edu>
+
+ * chk_trans.c (krb5_check_transited_list): Style nit: check
+ character against '\0' not NULL.
+ [pullup from trunk]
+
+2002-10-30 Sam Hartman <hartmans@mit.edu>
+
+ * chk_trans.c: Ignore trailing null in transited encoding; older
+ versions of MIT code included this.
+ [pullup from trunk]
+
+2002-08-12 Tom Yu <tlyu@mit.edu>
+
+ * unparse.c (krb5_unparse_name_ext): Error out if passed a NULL
+ pointer. Patch from Mark Levinson; fixes [krb5-admin/1140].
+ [pullup from trunk]
+
+2002-04-05 Danilo Almeida <dalmeida@mit.edu>
+
+ * princ_comp.c (krb5_realm_compare), auth_con.c
+ (krb5_auth_con_setports, krb5_auth_con_getaddrs,
+ krb5_auth_con_initivector), addr_order.c (krb5_address_order),
+ addr_comp.c (krb5_address_compare): Make KRB5_CALLCONV.
+
+2002-04-03 Danilo Almeida <dalmeida@mit.edu>
+
+ * bld_princ.c (krb5_build_principal_va): Make
+ krb5_build_principal_va() KRB5_CALLCONV.
+
+2002-04-02 Sam Hartman <hartmans@mit.edu>
+
+ * init_keyblock.c: Merge from mainline
+
+2002-03-15 Sam Hartman <hartmans@mit.edu>
+
+ * walk_rtree.c (krb5_walk_realm_tree): Fix handling of null realms
+
+2002-03-14 Alexandra Ellwood <lxs@mit.edu>
+ * appdefault.c, get_in_tkt.c: made conf_yes and conf_no const to
+ improve load time on Mach-O
+
+2002-03-13 Sam Hartman <hartmans@mit.edu>
+
+ * rd_cred.c (krb5_rd_cred): Don't check IP addresses; improves
+ Heimdal compatibility.
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * conv_princ.c: removed unused variable cpp to reduce warnings
+ * get_creds.c: removed unused variables fields and mcreds to
+ reduce warnings
+ * get_in_tkt.c: removed unused variables cpp and preauth_to_use
+ to reduce warnings
+ * init_ctx: fixed Mac OS macros
+ * parse.c: added type in to avoid "defaults to int" warning
+ * send_tgs.c: removed unused variable enclen
+
+2001-12-20 Ken Raeburn <raeburn@mit.edu>
+
+ * ser_actx.c (krb5_auth_context_externalize): Pass address of a
+ size_t, not a krb5_int32, to krb5_c_block_size.
+
+2001-11-29 Ken Raeburn <raeburn@mit.edu>
+
+ * fwd_tgt.c (krb5_fwd_tgt_creds): If no session key has been set,
+ try getting credentials and use the session key type as a hint
+ for the enctype to use for the forwarded credentials.
+
+ 2001-11-24 Sam Hartman <hartmans@mit.edu>
+
+ * fwd_tgt.c (krb5_fwd_tgt_creds): Get a session key for the
+ forwarded tgt that is the same as the session key for the
+ auth_context. This is an enctype we know the remote side
+ supports.
+
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * rd_safe.c, rd_priv.c, rd_cred.c, preauth.c, mk_safe.c,
+ mk_cred.c, appdefault.c: use "" includes for krb5.h, k5-int.h and
+ syslog.h
+ * gic_pwd.c, sendauth.c, recvauth.c: com_err.h is already included by
+ k5-int.h. Removed #include because it was confusing the Mac OS X builds
+
+2001-09-25 Ken Raeburn <raeburn@mit.edu>
+
+ * chk_trans.c: Reimplemented from scratch.
+
+2001-01-30 Tom Yu <tlyu@mit.edu>
+
+ * preauth.c (krb5_obtain_padata): Don't dereference a NULL pointer
+ if we receive an empty ETYPE_INFO preauth. [krb5-libs/903 from
+ craziboy77@hotmail.com]
+
+ * preauth2.c (krb5_do_preauth): Don't dereference a NULL pointer
+ if we receive an empty ETYPE_INFO preauth. [krb5-libs/903 from
+ craziboy77@hotmail.com]
+
+2001-01-30 Ezra Peisach <epeisach@mit.edu>
+
+ * rd_req_dec.c (krb5_rd_req_decrypt_tkt_part): Free
+ krb5_keytab_entry if call to krb5_decrypt_tkt_part()
+ fails. [krb5-libs/855 reported by guy@packeteer.com]
+
+2001-01-30 Ken Raeburn <raeburn@mit.edu>
+
+ * mk_safe.c (krb5_mk_safe): Only use safe_cksumtype from the
+ auth_context (derived from the config file or hardcoded default)
+ if it's suitable for the enctype of the key we're going to use.
+
+2001-01-29 Alexandra Ellwood <lxs@mit.edu>
+
+ * conv_princ.c (krb5_524_conv_principal): Fixed strncmp bug where principals
+ which are left substrings of "changepw" were being remapped into "changepw".
+ Added length check to if() statement.
+
+2001-01-29 Ken Raeburn <raeburn@mit.edu>
+
+ * preauth2.c (pa_sam): Check for a null prompter function pointer,
+ and return an error for that case rather than crashing.
+
+2000-10-02 Alexandra Ellwood <lxs@mit.edu>
+
+ * init_ctx.c: Added #defines for Mac OS X (__MACH__)
+
+2000-06-29 Tom Yu <tlyu@mit.edu>
+
+ * conv_princ.c (krb5_425_conv_principal): NULL, not nil.
+
+2000-06-28 Miro Jurisic <meeroh@mit.edu>
+
+ * conv_princ.c (krb5_425_conv_principal): Fixed a memory leak
+
+2000-06-17 Miro Jurisic <meeroh@mit.edu>
+
+ * conv_princ.c (krb5_425_conv_principal): Fixed v4->v5 realm
+ name conversion
+
+2000-06-17 Miro Jurisic <meeroh@mit.edu>
+
+ * conv_princ.c (krb5_425_conv_principal): Honor v4/v5 realm name
+ differences when convertion from v4 principals to v5.
+
+2000-06-07 Tom Yu <tlyu@mit.edu>
+
+ * get_creds.c (krb5_get_credentials): Translate KRB5_CC_NOTFOUND
+ returned from krb5_get_cred_from_kdc() if a prior call to
+ krb5_cc_retrieve_cred() returned KRB5_CC_NOT_KTYPE.
+
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * rd_priv.c (krb5_rd_priv_basic): Delete code that was incorrectly
+ doing explicit ivec chaining; c_decrypt() does it now.
+
+ * mk_priv.c (krb5_mk_priv_basic): Delete code that was incorrectly
+ doing explicit ivec chaining; c_encrypt() does it now.
+
+2000-06-03 Ken Raeburn <raeburn@mit.edu>
+
+ * get_in_tkt.c (krb5_get_in_tkt): If enctypes are specified, send
+ the server the intersection of that list and the supported types,
+ in the order requested.
+
+2000-06-02 Danilo Almeida <dalmeida@mit.edu>
+
+ * init_ctx.c (krb5_get_tgs_ktypes, krb5_free_ktypes): Fix linkage to
+ be KRB5_CALLCONV.
+
+2000-05-31 Ken Raeburn <raeburn@mit.edu>
+
+ * recvauth.c (krb5_recvauth_version): New routine, takes a
+ krb5_data in which to store the client's application version
+ string.
+ (recvauth_common): Renamed from krb5_recvauth, added above
+ functionality depending on extra argument values.
+ (krb5_recvauth): New stub, calls above routine with extra dummy
+ values.
+
+2000-5-19 Alexandra Ellwood <lxs@mit.edu>
+
+ * sendauth.c, fwd_tgt.c: Changed to use krb5int_cc_default. This function
+ supports the Kerberos Login Library and pops up a dialog if the cache does
+ not contain valid tickets. This is used to automatically get a tgt before
+ obtaining service tickets. Note that this should be an internal function
+ because callers don't expect krb5_cc_default to pop up a dialog!
+ (We found this out the hard way :-)
+
+2000-05-16 Ken Raeburn <raeburn@mit.edu>
+ Nalin Dahyabhai <nalin@redhat.com>
+
+ * conv_princ.c (krb5_524_conv_principal): Return an error if name
+ is too long. Use memcpy for character data since we already know
+ the length.
+
+2000-05-16 Ken Raeburn <raeburn@mit.edu>
+
+ * kfree.c: Remove unneeded "return" statements at the end of many
+ functions.
+ (krb5_free_*_content, krb5_free_*_contents,
+ krb5_free_cred_enc_part, krb5_free_pwd_sequences): Set freed
+ pointer members to null when containing structure isn't being
+ freed.
+
+2000-05-16 Tom Yu <tlyu@mit.edu>
+
+ * conv_princ.c (krb5_524_conv_principal): Make a copy of the krb5
+ realm that is nul-terminated to avoid falling off the end of the
+ krb5 realm, which is not necessarily nul-terminated.
+
+2000-05-16 Nalin Dahyabhai <nalin@redhat.com>
+
+ * kfree.c (krb5_free_keyblock_contents): Set contents pointer to
+ null after freeing.
+
+2000-05-15 Jeffrey Altman <jaltman@columbia.edu>
+
+ * Added new source file appdefault.c
+ Implements new public functions
+
+ krb5_appdefault_string
+ krb5_appdefault_boolean
+
+2000-05-12 Ken Raeburn <raeburn@mit.edu>
+
+ * t_kerb.c (test_524_conv_principal): New test code, to exercise
+ yesterday's code addition.
+ (main, usage): Updated.
+ * t_krb5.conf: Added stanford.edu->IR.STANFORD.EDU mapping, and a
+ test case for improperly long v4 realm names.
+ * Makefile.in (check-unix): Run 524 conversion test for some test
+ Athena and Stanford names.
+ * t_ref_kerb.out: Updated.
+
+ * init_ctx.c (init_common): Feed current-microsecond time and
+ process-id into PRNG, instead of just current-second time.
+ * mk_req_ext.c (krb5_mk_req_extended): Feed current time into
+ PRNG if a subkey will be generated.
+ * sendauth.c (krb5_sendauth): Feed local and remote addresses of
+ socket, if they can be determined, into the PRNG if a subkey will
+ be used.
+
+2000-05-11 Ken Raeburn <raeburn@mit.edu>
+ Booker C. Bense <bbense@networking.stanford.edu>
+
+ * conv_princ.c (krb5_524_conv_principal): Look up v4_realm in
+ config file, in case site's krb4 realm name isn't the same as the
+ krb5 realm name.
+
+2000-04-28 Nalin Dahyabhai <nalin@redhat.com>
+
+ * chk_trans.c (krb5_check_transited_list): Don't overflow buffers
+ "prev" and "next".
+ * conv_princ.c (krb5_425_conv_principal): Don't overflow buffer
+ "buf".
+
+2000-04-28 Alexandra Ellwood <lxs@mit.edu>
+
+ * gic_pwd.c (krb5_init_creds_password) added code to return to
+ login library if the password is expired (login library handles
+ this error appropriately).
+
+2000-04-18 Ken Raeburn <raeburn@mit.edu>
+
+ * init_ctx.c (krb5_free_ktypes): New routine, to free values
+ returned by krb5_get_tgs_ktypes, krb5_get_permitted_enctypes, and
+ krb5_get_default_in_tkt_ktypes.
+ (krb5_set_default_tgs_ktypes, krb5_is_permitted_enctype): Use it.
+ (get_profile_etype_list): Use passed-in enctype list if the
+ passed-in count is non-zero, instead of checking the
+ in_tkt_ktype_count value in the context.
+
+2000-04-08 Tom Yu <tlyu@mit.edu>
+
+ * vfy_increds.c (krb5_verify_init_creds): appdefault_boolean ->
+ libdefault_boolean; it somehow got missed earlier.
+
+2000-04-07 Jeffrey Altman <jaltman@columbia.edu>
+
+ * gic_pwd.c (krb5_get_init_creds_keytab), gic_pwd.c
+ (krb5_get_init_creds_password) when determining whether or not to
+ retry with a "master kdc" do not retry if the return value from
+ the first attempt was KRB5_REALM_CANT_RESOLV. Also, do not
+ overwrite the return code if the return value from the access to
+ the "master kdc" was KRB5_REALM_CANT_RESOLV.
+
2000-03-15 Danilo Almeida <dalmeida@mit.edu>
* init_ctx.c (init_common), gic_pwd.c (krb5_get_as_key_password,
diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in
index ba76662..484cd39 100644
--- a/src/lib/krb5/krb/Makefile.in
+++ b/src/lib/krb5/krb/Makefile.in
@@ -15,6 +15,7 @@ STLIBOBJS= \
addr_comp.o \
addr_order.o \
addr_srch.o \
+ appdefault.o \
auth_con.o \
bld_pr_ext.o \
bld_princ.o \
@@ -52,6 +53,7 @@ STLIBOBJS= \
in_tkt_pwd.o \
in_tkt_sky.o \
init_ctx.o \
+ init_keyblock.o \
kdc_rep_dc.o \
kfree.o \
mk_cred.o \
@@ -99,6 +101,7 @@ STLIBOBJS= \
OBJS= $(OUTPRE)addr_comp.$(OBJEXT) \
$(OUTPRE)addr_order.$(OBJEXT) \
$(OUTPRE)addr_srch.$(OBJEXT) \
+ $(OUTPRE)appdefault.$(OBJEXT) \
$(OUTPRE)auth_con.$(OBJEXT) \
$(OUTPRE)bld_pr_ext.$(OBJEXT) \
$(OUTPRE)bld_princ.$(OBJEXT) \
@@ -136,6 +139,7 @@ OBJS= $(OUTPRE)addr_comp.$(OBJEXT) \
$(OUTPRE)in_tkt_pwd.$(OBJEXT) \
$(OUTPRE)in_tkt_sky.$(OBJEXT) \
$(OUTPRE)init_ctx.$(OBJEXT) \
+ $(OUTPRE)init_keyblock.$(OBJEXT) \
$(OUTPRE)kdc_rep_dc.$(OBJEXT) \
$(OUTPRE)kfree.$(OBJEXT) \
$(OUTPRE)mk_cred.$(OBJEXT) \
@@ -183,6 +187,7 @@ OBJS= $(OUTPRE)addr_comp.$(OBJEXT) \
SRCS= $(srcdir)/addr_comp.c \
$(srcdir)/addr_order.c \
$(srcdir)/addr_srch.c \
+ $(srcdir)/appdefault.c \
$(srcdir)/auth_con.c \
$(srcdir)/bld_pr_ext.c \
$(srcdir)/bld_princ.c \
@@ -221,6 +226,7 @@ SRCS= $(srcdir)/addr_comp.c \
$(srcdir)/in_tkt_pwd.c \
$(srcdir)/in_tkt_sky.c \
$(srcdir)/init_ctx.c \
+ $(srcdir)/init_keyblock.c \
$(srcdir)/kdc_rep_dc.c \
$(srcdir)/kfree.c \
$(srcdir)/mk_cred.c \
@@ -324,6 +330,8 @@ check-unix:: $(TEST_PROGS)
425_conv_principal rcmd uunet UU.NET \
425_conv_principal zephyr zephyr ATHENA.MIT.EDU \
425_conv_principal kadmin ATHENA.MIT.EDU ATHENA.MIT.EDU \
+ 524_conv_principal host/e40-po.mit.edu@ATHENA.MIT.EDU \
+ 524_conv_principal host/foobar.stanford.edu@stanford.edu \
set_realm marc@MIT.EDU CYGNUS.COM \
> test.out
cmp test.out $(srcdir)/t_ref_kerb.out
diff --git a/src/lib/krb5/krb/addr_comp.c b/src/lib/krb5/krb/addr_comp.c
index 587bd5f..f9e10bb 100644
--- a/src/lib/krb5/krb/addr_comp.c
+++ b/src/lib/krb5/krb/addr_comp.c
@@ -32,7 +32,7 @@
/*
* If the two addresses are the same, return TRUE, else return FALSE
*/
-krb5_boolean
+krb5_boolean KRB5_CALLCONV
krb5_address_compare(context, addr1, addr2)
krb5_context context;
krb5_const krb5_address *addr1;
diff --git a/src/lib/krb5/krb/addr_order.c b/src/lib/krb5/krb/addr_order.c
index 800fa2b..2598205 100644
--- a/src/lib/krb5/krb/addr_order.c
+++ b/src/lib/krb5/krb/addr_order.c
@@ -37,7 +37,7 @@
* Return an ordering on two addresses: 0 if the same,
* < 0 if first is less than 2nd, > 0 if first is greater than 2nd.
*/
-int
+int KRB5_CALLCONV
krb5_address_order(context, addr1, addr2)
krb5_context context;
register krb5_const krb5_address *addr1;
diff --git a/src/lib/krb5/krb/appdefault.c b/src/lib/krb5/krb/appdefault.c
new file mode 100644
index 0000000..65a9459
--- /dev/null
+++ b/src/lib/krb5/krb/appdefault.c
@@ -0,0 +1,183 @@
+/*
+ * appdefault - routines designed to be called from applications to
+ * handle the [appdefaults] profile section
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "k5-int.h"
+
+
+
+ /*xxx Duplicating this is annoying; try to work on a better way.*/
+static const char *conf_yes[] = {
+ "y", "yes", "true", "t", "1", "on",
+ 0,
+};
+
+static const char *conf_no[] = {
+ "n", "no", "false", "nil", "0", "off",
+ 0,
+};
+
+static int conf_boolean(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;
+ }
+ /* Default to "no" */
+ return 0;
+}
+
+static krb5_error_code appdefault_get(context, appname, realm, option,
+ ret_value)
+ krb5_context context;
+ const char *appname, *option;
+ const krb5_data *realm;
+ char **ret_value;
+{
+ profile_t profile;
+ const char *names[5];
+ char **nameval = NULL;
+ krb5_error_code retval;
+ const char * realmstr = realm?realm->data:NULL;
+
+ if (!context || (context->magic != KV5M_CONTEXT))
+ return KV5M_CONTEXT;
+
+ profile = context->profile;
+
+ /*
+ * Try number one:
+ *
+ * [appdefaults]
+ * app = {
+ * SOME.REALM = {
+ * option = <boolean>
+ * }
+ * }
+ */
+
+ names[0] = "appdefaults";
+ names[1] = appname;
+
+ if (realmstr) {
+ names[2] = realmstr;
+ names[3] = option;
+ names[4] = 0;
+ retval = profile_get_values(profile, names, &nameval);
+ if (retval == 0 && nameval && nameval[0]) {
+ *ret_value = strdup(nameval[0]);
+ goto goodbye;
+ }
+ }
+
+ /*
+ * Try number two:
+ *
+ * [appdefaults]
+ * app = {
+ * option = <boolean>
+ * }
+ */
+
+ names[2] = option;
+ names[3] = 0;
+ retval = profile_get_values(profile, names, &nameval);
+ if (retval == 0 && nameval && nameval[0]) {
+ *ret_value = strdup(nameval[0]);
+ goto goodbye;
+ }
+
+ /*
+ * Try number three:
+ *
+ * [appdefaults]
+ * realm = {
+ * option = <boolean>
+ */
+
+ if (realmstr) {
+ names[1] = realmstr;
+ names[2] = option;
+ names[3] = 0;
+ retval = profile_get_values(profile, names, &nameval);
+ if (retval == 0 && nameval && nameval[0]) {
+ *ret_value = strdup(nameval[0]);
+ goto goodbye;
+ }
+ }
+
+ /*
+ * Try number four:
+ *
+ * [appdefaults]
+ * option = <boolean>
+ */
+
+ names[1] = option;
+ names[2] = 0;
+ retval = profile_get_values(profile, names, &nameval);
+ if (retval == 0 && nameval && nameval[0]) {
+ *ret_value = strdup(nameval[0]);
+ } else {
+ return retval;
+ }
+
+goodbye:
+ if (nameval) {
+ char **cpp;
+ for (cpp = nameval; *cpp; cpp++)
+ free(*cpp);
+ free(nameval);
+ }
+ return 0;
+}
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_appdefault_boolean(context, appname, realm, option,
+ default_value, ret_value)
+ krb5_context context;
+ const char *appname, *option;
+ const krb5_data *realm;
+ int default_value;
+ int *ret_value;
+{
+ char *string = NULL;
+ krb5_error_code retval;
+
+ retval = appdefault_get(context, appname, realm, option, &string);
+
+ if (! retval && string) {
+ *ret_value = conf_boolean(string);
+ free(string);
+ } else
+ *ret_value = default_value;
+}
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_appdefault_string(context, appname, realm, option, default_value,
+ ret_value)
+ krb5_context context;
+ const char *appname, *option, *default_value;
+ char **ret_value;
+ const krb5_data *realm;
+ {
+ krb5_error_code retval;
+ char *string;
+
+ retval = appdefault_get(context, appname, realm, option, &string);
+
+ if (! retval && string) {
+ *ret_value = string;
+ } else {
+ *ret_value = strdup(default_value);
+ }
+}
diff --git a/src/lib/krb5/krb/auth_con.c b/src/lib/krb5/krb/auth_con.c
index 335f7ae..f80a167 100644
--- a/src/lib/krb5/krb/auth_con.c
+++ b/src/lib/krb5/krb/auth_con.c
@@ -109,7 +109,7 @@ krb5_auth_con_setaddrs(context, auth_context, local_addr, remote_addr)
return retval;
}
-krb5_error_code
+krb5_error_code KRB5_CALLCONV
krb5_auth_con_getaddrs(context, auth_context, local_addr, remote_addr)
krb5_context context;
krb5_auth_context auth_context;
@@ -132,7 +132,7 @@ krb5_auth_con_getaddrs(context, auth_context, local_addr, remote_addr)
return retval;
}
-krb5_error_code
+krb5_error_code KRB5_CALLCONV
krb5_auth_con_setports(context, auth_context, local_port, remote_port)
krb5_context context;
krb5_auth_context auth_context;
@@ -270,7 +270,7 @@ krb5_auth_con_getremoteseqnumber(context, auth_context, seqnumber)
return 0;
}
-krb5_error_code
+krb5_error_code KRB5_CALLCONV
krb5_auth_con_initivector(context, auth_context)
krb5_context context;
krb5_auth_context auth_context;
diff --git a/src/lib/krb5/krb/bld_princ.c b/src/lib/krb5/krb/bld_princ.c
index bf49105..34b50c0 100644
--- a/src/lib/krb5/krb/bld_princ.c
+++ b/src/lib/krb5/krb/bld_princ.c
@@ -37,6 +37,7 @@
#endif
krb5_error_code
+KRB5_CALLCONV
krb5_build_principal_va(context, princ, rlen, realm, ap)
krb5_context context;
krb5_principal princ;
diff --git a/src/lib/krb5/krb/chk_trans.c b/src/lib/krb5/krb/chk_trans.c
index c2ac716..9fe73c8 100644
--- a/src/lib/krb5/krb/chk_trans.c
+++ b/src/lib/krb5/krb/chk_trans.c
@@ -1,12 +1,14 @@
/*
- * Copyright (c) 1994 CyberSAFE Corporation.
- * All rights reserved.
+ * lib/krb5/krb/chk_trans.c
+ *
+ * Copyright 2001 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
@@ -14,97 +16,426 @@
* 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. Neither M.I.T., the Open Computing Security Group, nor
- * CyberSAFE Corporation make any representations about the suitability of
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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_check_transited_list()
*/
-
#include "k5-int.h"
-#include <stdio.h>
+#include <stdarg.h>
-#define MAX_REALM_LN 500
+#if defined (TEST) || defined (TEST2)
+# undef DEBUG
+# define DEBUG
+#endif
-krb5_error_code
-krb5_check_transited_list(context, trans, realm1, realm2)
- krb5_context context;
-krb5_data *trans;
-krb5_data *realm1;
-krb5_data *realm2;
+#ifdef DEBUG
+#define verbose krb5int_chk_trans_verbose
+static int verbose = 0;
+# define Tprintf(ARGS) if (verbose) printf ARGS
+#else
+# define Tprintf(ARGS) (void)(0)
+#endif
+
+#define MAXLEN 512
+
+static krb5_error_code
+process_intermediates (krb5_error_code (*fn)(krb5_data *, void *), void *data,
+ const krb5_data *n1, const krb5_data *n2) {
+ unsigned int len1, len2, i;
+ char *p1, *p2;
+
+ Tprintf (("process_intermediates(%.*s,%.*s)\n",
+ (int) n1->length, n1->data, (int) n2->length, n2->data));
+
+ len1 = n1->length;
+ len2 = n2->length;
+
+ Tprintf (("(walking intermediates now)\n"));
+ /* Simplify... */
+ if (len1 > len2) {
+ const krb5_data *p;
+ int tmp = len1;
+ len1 = len2;
+ len2 = tmp;
+ p = n1;
+ n1 = n2;
+ n2 = p;
+ }
+ /* Okay, now len1 is always shorter or equal. */
+ if (len1 == len2) {
+ if (memcmp (n1->data, n2->data, len1)) {
+ Tprintf (("equal length but different strings in path: '%.*s' '%.*s'\n",
+ (int) n1->length, n1->data, (int) n2->length, n2->data));
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
+ }
+ Tprintf (("(end intermediates)\n"));
+ return 0;
+ }
+ /* Now len1 is always shorter. */
+ if (len1 == 0)
+ /* Shouldn't be possible. Internal error? */
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
+ p1 = n1->data;
+ p2 = n2->data;
+ if (p1[0] == '/') {
+ /* X.500 style names, with common prefix. */
+ if (p2[0] != '/') {
+ Tprintf (("mixed name formats in path: x500='%.*s' domain='%.*s'\n",
+ (int) len1, p1, (int) len2, p2));
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
+ }
+ if (memcmp (p1, p2, len1)) {
+ Tprintf (("x500 names with different prefixes '%.*s' '%.*s'\n",
+ (int) len1, p1, (int) len2, p2));
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
+ }
+ for (i = len1 + 1; i < len2; i++)
+ if (p2[i] == '/') {
+ krb5_data d;
+ krb5_error_code r;
+
+ d.data = p2;
+ d.length = i;
+ r = (*fn) (&d, data);
+ if (r)
+ return r;
+ }
+ } else {
+ /* Domain style names, with common suffix. */
+ if (p2[0] == '/') {
+ Tprintf (("mixed name formats in path: domain='%.*s' x500='%.*s'\n",
+ (int) len1, p1, (int) len2, p2));
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
+ }
+ if (memcmp (p1, p2 + (len2 - len1), len1)) {
+ Tprintf (("domain names with different suffixes '%.*s' '%.*s'\n",
+ (int) len1, p1, (int) len2, p2));
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
+ }
+ for (i = len2 - len1 - 1; i > 0; i--) {
+ Tprintf (("looking at '%.*s'\n", (int) (len2 - i), p2+i));
+ if (p2[i-1] == '.') {
+ krb5_data d;
+ krb5_error_code r;
+
+ d.data = p2+i;
+ d.length = len2 - i;
+ r = (*fn) (&d, data);
+ if (r)
+ return r;
+ }
+ }
+ }
+ Tprintf (("(end intermediates)\n"));
+ return 0;
+}
+
+static krb5_error_code
+maybe_join (krb5_data *last, krb5_data *buf, int bufsiz)
+{
+ if (buf->length == 0)
+ return 0;
+ if (buf->data[0] == '/') {
+ if (last->length + buf->length > bufsiz) {
+ Tprintf (("too big: last=%d cur=%d max=%d\n", last->length, buf->length, bufsiz));
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
+ }
+ memmove (buf->data+last->length, buf->data, buf->length);
+ memcpy (buf->data, last->data, last->length);
+ buf->length += last->length;
+ } else if (buf->data[buf->length-1] == '.') {
+ /* We can ignore the case where the previous component was
+ empty; the strcat will be a no-op. It should probably
+ be an error case, but let's be flexible. */
+ if (last->length+buf->length > bufsiz) {
+ Tprintf (("too big\n"));
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
+ }
+ memcpy (buf->data + buf->length, last->data, last->length);
+ buf->length += last->length;
+ }
+ /* Otherwise, do nothing. */
+ return 0;
+}
+
+/* The input strings cannot contain any \0 bytes, according to the
+ spec, but our API is such that they may not be \0 terminated
+ either. Thus we keep on treating them as krb5_data objects instead
+ of C strings. */
+static krb5_error_code
+foreach_realm (krb5_error_code (*fn)(krb5_data *comp,void *data), void *data,
+ const krb5_data *crealm, const krb5_data *srealm,
+ const krb5_data *transit)
+{
+ char buf[MAXLEN], last[MAXLEN];
+ char *p, *bufp;
+ int next_lit, intermediates, l;
+ krb5_data this_component;
+ krb5_error_code r;
+ krb5_data last_component;
+
+ /* Invariants:
+ - last_component points to last[]
+ - this_component points to buf[]
+ - last_component has length of last
+ - this_component has length of buf when calling out
+ Keep these consistent, and we should be okay. */
+
+ next_lit = 0;
+ intermediates = 0;
+ memset (buf, 0, sizeof (buf));
+
+ this_component.data = buf;
+ last_component.data = last;
+ last_component.length = 0;
+
+#define print_data(fmt,d) Tprintf((fmt,(int)(d)->length,(d)->data))
+ print_data ("client realm: %.*s\n", crealm);
+ print_data ("server realm: %.*s\n", srealm);
+ print_data ("transit enc.: %.*s\n", transit);
+
+ if (transit->length == 0) {
+ Tprintf (("no other realms transited\n"));
+ return 0;
+ }
+
+ bufp = buf;
+ for (p = transit->data, l = transit->length; l; p++, l--) {
+ if (next_lit) {
+ *bufp++ = *p;
+ if (bufp == buf+sizeof(buf))
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
+ next_lit = 0;
+ } else if (*p == '\\') {
+ next_lit = 1;
+ } else if (*p == ',') {
+ if (bufp != buf) {
+ this_component.length = bufp - buf;
+ r = maybe_join (&last_component, &this_component, sizeof(buf));
+ if (r)
+ return r;
+ r = (*fn) (&this_component, data);
+ if (r)
+ return r;
+ if (intermediates) {
+ if (p == transit->data)
+ r = process_intermediates (fn, data,
+ &this_component, crealm);
+ else {
+ r = process_intermediates (fn, data, &this_component,
+ &last_component);
+ }
+ if (r)
+ return r;
+ }
+ intermediates = 0;
+ memcpy (last, buf, sizeof (buf));
+ last_component.length = this_component.length;
+ memset (buf, 0, sizeof (buf));
+ bufp = buf;
+ } else {
+ intermediates = 1;
+ if (p == transit->data) {
+ if (crealm->length >= MAXLEN)
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
+ memcpy (last, crealm->data, crealm->length);
+ last[crealm->length] = '\0';
+ last_component.length = crealm->length;
+ }
+ }
+ } else if (*p == ' ' && bufp == buf) {
+ /* This next component stands alone, even if it has a
+ trailing dot or leading slash. */
+ memset (last, 0, sizeof (last));
+ last_component.length = 0;
+ } else {
+ /* Not a special character; literal. */
+ *bufp++ = *p;
+ if (bufp == buf+sizeof(buf))
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
+ }
+ }
+ /* At end. Must be normal state. */
+ if (next_lit)
+ Tprintf (("ending in next-char-literal state\n"));
+ /* Process trailing element or comma. */
+ if (bufp == buf) {
+ /* Trailing comma. */
+ r = process_intermediates (fn, data, &last_component, srealm);
+ } else {
+ /* Trailing component. */
+ this_component.length = bufp - buf;
+ r = maybe_join (&last_component, &this_component, sizeof(buf));
+ if (r)
+ return r;
+ r = (*fn) (&this_component, data);
+ if (r)
+ return r;
+ if (intermediates)
+ r = process_intermediates (fn, data, &this_component,
+ &last_component);
+ }
+ if (r != 0)
+ return r;
+ return 0;
+}
+
+
+struct check_data {
+ krb5_context ctx;
+ krb5_principal *tgs;
+};
+
+static int
+same_data (krb5_data *d1, krb5_data *d2)
{
- char prev[MAX_REALM_LN+1];
- char next[MAX_REALM_LN+1];
- char *nextp;
- int i, j;
- int trans_length;
- krb5_error_code retval = 0;
- krb5_principal *tgs_list;
-
- if (trans == NULL || trans->data == NULL || trans->length == 0)
- return(0);
- trans_length = trans->data[trans->length-1] ?
- trans->length : trans->length - 1;
-
- for (i = 0; i < trans_length; i++)
- if (trans->data[i] == '\0') {
- /* Realms may not contain ASCII NUL character. */
- return(KRB5KRB_AP_ERR_ILL_CR_TKT);
+ return (d1->length == d2->length
+ && !memcmp (d1->data, d2->data, d1->length));
+}
+
+static krb5_error_code
+check_realm_in_list (krb5_data *realm, void *data)
+{
+ struct check_data *cdata = data;
+ int i;
+
+ Tprintf ((".. checking '%.*s'\n", (int) realm->length, realm->data));
+ for (i = 0; cdata->tgs[i]; i++) {
+ if (same_data (krb5_princ_realm (cdata->ctx, cdata->tgs[i]), realm))
+ return 0;
}
+ Tprintf (("BAD!\n"));
+ return KRB5KRB_AP_ERR_ILL_CR_TKT;
+}
+
+krb5_error_code
+krb5_check_transited_list (krb5_context ctx, const krb5_data *trans_in,
+ const krb5_data *crealm, const krb5_data *srealm)
+{
+ krb5_data trans;
+ struct check_data cdata;
+ krb5_error_code r;
- if ((retval = krb5_walk_realm_tree(context, realm1, realm2, &tgs_list,
- KRB5_REALM_BRANCH_CHAR))) {
- return(retval);
- }
-
- memset(prev, 0, MAX_REALM_LN + 1);
- memset(next, 0, MAX_REALM_LN + 1), nextp = next;
- for (i = 0; i < trans_length; i++) {
- if (i < trans_length-1 && trans->data[i] == '\\') {
- i++;
- *nextp++ = trans->data[i];
- if (nextp - next > MAX_REALM_LN) {
- retval = KRB5KRB_AP_ERR_ILL_CR_TKT;
- goto finish;
- }
- continue;
+ trans.length = trans_in->length;
+ trans.data = (char *) trans_in->data;
+ if (trans.length && (trans.data[trans.length-1] == '\0'))
+ trans.length--;
+
+ Tprintf (("krb5_check_transited_list(trans=\"%.*s\", crealm=\"%.*s\", srealm=\"%.*s\")\n",
+ (int) trans.length, trans.data,
+ (int) crealm->length, crealm->data,
+ (int) srealm->length, srealm->data));
+ if (trans.length == 0)
+ return 0;
+ r = krb5_walk_realm_tree (ctx, crealm, srealm, &cdata.tgs,
+ KRB5_REALM_BRANCH_CHAR);
+ if (r) {
+ Tprintf (("error %ld\n", (long) r));
+ return r;
+ }
+#ifdef DEBUG /* avoid compiler warning about 'd' unused */
+ {
+ int i;
+ Tprintf (("tgs list = {\n"));
+ for (i = 0; cdata.tgs[i]; i++) {
+ char *name;
+ r = krb5_unparse_name (ctx, cdata.tgs[i], &name);
+ Tprintf (("\t'%s'\n", name));
+ free (name);
+ }
+ Tprintf (("}\n"));
}
- if (i < trans_length && trans->data[i] != ',') {
- *nextp++ = trans->data[i];
- if (nextp - next > MAX_REALM_LN) {
- retval = KRB5KRB_AP_ERR_ILL_CR_TKT;
- goto finish;
- }
- continue;
+#endif
+ cdata.ctx = ctx;
+ r = foreach_realm (check_realm_in_list, &cdata, crealm, srealm, &trans);
+ krb5_free_realm_tree (ctx, cdata.tgs);
+ return r;
+}
+
+#ifdef TEST
+
+static krb5_error_code
+print_a_realm (krb5_data *realm, void *data)
+{
+ printf ("%.*s\n", (int) realm->length, realm->data);
+ return 0;
+}
+
+int main (int argc, char *argv[]) {
+ const char *me;
+ krb5_data crealm, srealm, transit;
+ krb5_error_code r;
+ int expand_only = 0;
+
+ me = strrchr (argv[0], '/');
+ me = me ? me+1 : argv[0];
+
+ while (argc > 3 && argv[1][0] == '-') {
+ if (!strcmp ("-v", argv[1]))
+ verbose++, argc--, argv++;
+ else if (!strcmp ("-x", argv[1]))
+ expand_only++, argc--, argv++;
+ else
+ goto usage;
}
- if (strlen(next) > 0) {
- if (next[0] != '/') {
- if (*(nextp-1) == '.' && strlen(next) + strlen(prev) <= MAX_REALM_LN)
- strcat(next, prev);
- retval = KRB5KRB_AP_ERR_ILL_CR_TKT;
- for (j = 0; tgs_list[j]; j++) {
- if (strlen(next) == (size_t) krb5_princ_realm(context, tgs_list[j])->length &&
- !memcmp(next, krb5_princ_realm(context, tgs_list[j])->data,
- strlen(next))) {
- retval = 0;
- break;
- }
- }
- if (retval) goto finish;
- }
- if (i+1 < trans_length && trans->data[i+1] == ' ') {
- i++;
- memset(next, 0, MAX_REALM_LN + 1), nextp = next;
- continue;
- }
- if (i+1 < trans_length && trans->data[i+1] != '/') {
- strcpy(prev, next);
- memset(next, 0, MAX_REALM_LN + 1), nextp = next;
- continue;
- }
+
+ if (argc != 4) {
+ usage:
+ printf ("usage: %s [-v] [-x] clientRealm serverRealm transitEncoding\n",
+ me);
+ return 1;
}
- }
-finish:
- krb5_free_realm_tree(context, tgs_list);
- return(retval);
+ crealm.data = argv[1];
+ crealm.length = strlen(argv[1]);
+ srealm.data = argv[2];
+ srealm.length = strlen(argv[2]);
+ transit.data = argv[3];
+ transit.length = strlen(argv[3]);
+
+ if (expand_only) {
+
+ printf ("client realm: %s\n", argv[1]);
+ printf ("server realm: %s\n", argv[2]);
+ printf ("transit enc.: %s\n", argv[3]);
+
+ if (argv[3][0] == 0) {
+ printf ("no other realms transited\n");
+ return 0;
+ }
+
+ r = foreach_realm (print_a_realm, NULL, &crealm, &srealm, &transit);
+ if (r)
+ printf ("--> returned error %ld\n", (long) r);
+ return r != 0;
+
+ } else {
+
+ /* Actually check the values against the supplied krb5.conf file. */
+ krb5_context ctx;
+ r = krb5_init_context (&ctx);
+ if (r) {
+ com_err (me, r, "initializing krb5 context");
+ return 1;
+ }
+ r = krb5_check_transited_list (ctx, &transit, &crealm, &srealm);
+ if (r == KRB5KRB_AP_ERR_ILL_CR_TKT) {
+ printf ("NO\n");
+ } else if (r == 0) {
+ printf ("YES\n");
+ } else {
+ printf ("kablooey!\n");
+ com_err (me, r, "checking transited-realm list");
+ return 1;
+ }
+ return 0;
+ }
}
+
+#endif /* TEST */
diff --git a/src/lib/krb5/krb/conv_princ.c b/src/lib/krb5/krb/conv_princ.c
index b90289a..e7aab77 100644
--- a/src/lib/krb5/krb/conv_princ.c
+++ b/src/lib/krb5/krb/conv_princ.c
@@ -137,7 +137,8 @@ krb5_524_conv_principal(context, princ, name, inst, realm)
{
const struct krb_convert *p;
krb5_data *compo;
- char *c;
+ char *c, *tmp_realm, *tmp_prealm;
+ int tmp_realm_len, retval;
*name = *inst = '\0';
switch (krb5_princ_size(context, princ)) {
@@ -146,19 +147,24 @@ krb5_524_conv_principal(context, princ, name, inst, realm)
compo = krb5_princ_component(context, princ, 0);
p = sconv_list;
while (p->v4_str) {
- if (strncmp(p->v5_str, compo->data, compo->length) == 0) {
- /* It is, so set the new name now, and chop off */
- /* instance's domain name if requested */
- strcpy(name, p->v4_str);
- if (p->flags & DO_REALM_CONVERSION) {
- compo = krb5_princ_component(context, princ, 1);
- c = strnchr(compo->data, '.', compo->length);
- if (!c || (c - compo->data) > INST_SZ - 1)
- return KRB5_INVALID_PRINCIPAL;
- strncpy(inst, compo->data, c - compo->data);
- inst[c - compo->data] = '\0';
- }
- break;
+ if (strncmp(p->v5_str, compo->data, compo->length) == 0 &&
+ strlen(p->v5_str) == compo->length) {
+ /*
+ * It is, so set the new name now, and chop off
+ * instance's domain name if requested.
+ */
+ if (strlen (p->v4_str) > ANAME_SZ - 1)
+ return KRB5_INVALID_PRINCIPAL;
+ strcpy(name, p->v4_str);
+ if (p->flags & DO_REALM_CONVERSION) {
+ compo = krb5_princ_component(context, princ, 1);
+ c = strnchr(compo->data, '.', compo->length);
+ if (!c || (c - compo->data) >= INST_SZ - 1)
+ return KRB5_INVALID_PRINCIPAL;
+ memcpy(inst, compo->data, c - compo->data);
+ inst[c - compo->data] = '\0';
+ }
+ break;
}
p++;
}
@@ -168,7 +174,7 @@ krb5_524_conv_principal(context, princ, name, inst, realm)
compo = krb5_princ_component(context, princ, 1);
if (compo->length >= INST_SZ - 1)
return KRB5_INVALID_PRINCIPAL;
- strncpy(inst, compo->data, compo->length);
+ memcpy(inst, compo->data, compo->length);
inst[compo->length] = '\0';
}
/* fall through */
@@ -178,7 +184,7 @@ krb5_524_conv_principal(context, princ, name, inst, realm)
compo = krb5_princ_component(context, princ, 0);
if (compo->length >= ANAME_SZ)
return KRB5_INVALID_PRINCIPAL;
- strncpy(name, compo->data, compo->length);
+ memcpy(name, compo->data, compo->length);
name[compo->length] = '\0';
}
break;
@@ -187,11 +193,39 @@ krb5_524_conv_principal(context, princ, name, inst, realm)
}
compo = krb5_princ_realm(context, princ);
- if (compo->length > REALM_SZ - 1)
- return KRB5_INVALID_PRINCIPAL;
- strncpy(realm, compo->data, compo->length);
- realm[compo->length] = '\0';
+ tmp_prealm = malloc(compo->length + 1);
+ if (tmp_prealm == NULL)
+ return ENOMEM;
+ strncpy(tmp_prealm, compo->data, compo->length);
+ tmp_prealm[compo->length] = '\0';
+
+ /* Ask for v4_realm corresponding to
+ krb5 principal realm from krb5.conf realms stanza */
+
+ if (context->profile == 0)
+ return KRB5_CONFIG_CANTOPEN;
+ retval = profile_get_string(context->profile, "realms",
+ tmp_prealm, "v4_realm", 0,
+ &tmp_realm);
+ free(tmp_prealm);
+ if (retval) {
+ return retval;
+ } else {
+ if (tmp_realm == 0) {
+ if (compo->length > REALM_SZ - 1)
+ return KRB5_INVALID_PRINCIPAL;
+ strncpy(realm, compo->data, compo->length);
+ realm[compo->length] = '\0';
+ } else {
+ tmp_realm_len = strlen(tmp_realm);
+ if (tmp_realm_len > REALM_SZ - 1)
+ return KRB5_INVALID_PRINCIPAL;
+ strncpy(realm, tmp_realm, tmp_realm_len);
+ realm[tmp_realm_len] = '\0';
+ profile_release_string(tmp_realm);
+ }
+ }
return 0;
}
@@ -207,8 +241,47 @@ krb5_425_conv_principal(context, name, instance, realm, princ)
char buf[256]; /* V4 instances are limited to 40 characters */
krb5_error_code retval;
char *domain, *cp;
- char **full_name = 0, **cpp;
+ char **full_name = 0;
const char *names[5];
+ void* iterator = NULL;
+ char** v4realms = NULL;
+ char* realm_name = NULL;
+ char* dummy_value = NULL;
+
+ /* First, convert the realm, since the v4 realm is not necessarily the same as the v5 realm
+ To do that, iterate over all the realms in the config file, looking for a matching
+ v4_realm line */
+ names [0] = "realms";
+ names [1] = NULL;
+ retval = profile_iterator_create (context -> profile, names, PROFILE_ITER_LIST_SECTION | PROFILE_ITER_SECTIONS_ONLY, &iterator);
+ while (retval == 0) {
+ retval = profile_iterator (&iterator, &realm_name, &dummy_value);
+ if ((retval == 0) && (realm_name != NULL)) {
+ names [0] = "realms";
+ names [1] = realm_name;
+ names [2] = "v4_realm";
+ names [3] = NULL;
+
+ retval = profile_get_values (context -> profile, names, &v4realms);
+ if ((retval == 0) && (v4realms != NULL) && (v4realms [0] != NULL) && (strcmp (v4realms [0], realm) == 0)) {
+ realm = realm_name;
+ break;
+ } else if (retval == PROF_NO_RELATION) {
+ /* If it's not found, just keep going */
+ retval = 0;
+ }
+ } else if ((retval == 0) && (realm_name == NULL)) {
+ break;
+ }
+ if (realm_name != NULL) {
+ profile_release_string (realm_name);
+ realm_name = NULL;
+ }
+ if (dummy_value != NULL) {
+ profile_release_string (dummy_value);
+ dummy_value = NULL;
+ }
+ }
if (instance) {
if (instance[0] == '\0') {
@@ -234,7 +307,8 @@ krb5_425_conv_principal(context, name, instance, realm, princ)
if (retval == 0 && full_name && full_name[0]) {
instance = full_name[0];
} else {
- strcpy(buf, instance);
+ strncpy(buf, instance, sizeof(buf));
+ buf[sizeof(buf) - 1] = '\0';
retval = krb5_get_realm_domain(context, realm, &domain);
if (retval)
return retval;
@@ -242,8 +316,8 @@ krb5_425_conv_principal(context, name, instance, realm, princ)
for (cp = domain; *cp; cp++)
if (isupper(*cp))
*cp = tolower(*cp);
- strcat(buf, ".");
- strcat(buf, domain);
+ strncat(buf, ".", sizeof(buf) - 1 - strlen(buf));
+ strncat(buf, domain, sizeof(buf) - 1 - strlen(buf));
krb5_xfree(domain);
}
instance = buf;
@@ -254,6 +328,10 @@ krb5_425_conv_principal(context, name, instance, realm, princ)
not_service:
retval = krb5_build_principal(context, princ, strlen(realm), realm, name,
instance, 0);
+ profile_iterator_free (&iterator);
profile_free_list(full_name);
+ profile_free_list(v4realms);
+ profile_release_string (realm_name);
+ profile_release_string (dummy_value);
return retval;
}
diff --git a/src/lib/krb5/krb/fwd_tgt.c b/src/lib/krb5/krb/fwd_tgt.c
index 814195a..2e2c5db 100644
--- a/src/lib/krb5/krb/fwd_tgt.c
+++ b/src/lib/krb5/krb/fwd_tgt.c
@@ -53,6 +53,8 @@ krb5_fwd_tgt_creds(context, auth_context, rhost, client, server, cc,
krb5_flags kdcoptions;
int close_cc = 0;
int free_rhost = 0;
+ krb5_enctype enctype = 0;
+ krb5_keyblock *session_key;
memset((char *)&creds, 0, sizeof(creds));
memset((char *)&tgt, 0, sizeof(creds));
@@ -71,7 +73,36 @@ krb5_fwd_tgt_creds(context, auth_context, rhost, client, server, cc,
memcpy(rhost, server->data[1].data, server->data[1].length);
rhost[server->data[1].length] = '\0';
}
-
+ retval = krb5_auth_con_getkey (context, auth_context, &session_key);
+ if (retval)
+ goto errout;
+ if (session_key) {
+ enctype = session_key->enctype;
+ krb5_free_keyblock (context, session_key);
+ session_key = NULL;
+ } else if (server) { /* must server be non-NULL when rhost is given? */
+ /* Try getting credentials to see what the remote side supports.
+ Not bulletproof, just a heuristic. */
+ krb5_creds in, *out = 0;
+ memset (&in, 0, sizeof(in));
+
+ retval = krb5_copy_principal (context, server, &in.server);
+ if (retval)
+ goto punt;
+ retval = krb5_copy_principal (context, client, &in.client);
+ if (retval)
+ goto punt;
+ retval = krb5_get_credentials (context, 0, cc, &in, &out);
+ if (retval)
+ goto punt;
+ /* Got the credentials. Okay, now record the enctype and
+ throw them away. */
+ enctype = out->keyblock.enctype;
+ krb5_free_creds (context, out);
+ punt:
+ krb5_free_cred_contents (context, &in);
+ }
+
retval = krb5_os_hostaddr(context, rhost, &addrs);
if (retval)
goto errout;
@@ -90,7 +121,7 @@ krb5_fwd_tgt_creds(context, auth_context, rhost, client, server, cc,
goto errout;
if (cc == 0) {
- if ((retval = krb5_cc_default(context, &cc)))
+ if ((retval = krb5int_cc_default(context, &cc)))
goto errout;
close_cc = 1;
}
@@ -111,7 +142,8 @@ krb5_fwd_tgt_creds(context, auth_context, rhost, client, server, cc,
retval = KRB5_NO_TKT_SUPPLIED;
goto errout;
}
-
+
+ creds.keyblock.enctype = enctype;
creds.times = tgt.times;
creds.times.starttime = 0;
kdcoptions = flags2options(tgt.ticket_flags)|KDC_OPT_FORWARDED;
diff --git a/src/lib/krb5/krb/gc_frm_kdc.c b/src/lib/krb5/krb/gc_frm_kdc.c
index 1e315fe..fd36385 100644
--- a/src/lib/krb5/krb/gc_frm_kdc.c
+++ b/src/lib/krb5/krb/gc_frm_kdc.c
@@ -347,7 +347,9 @@ krb5_get_cred_from_kdc_opt(context, ccache, in_cred, out_cred, tgts, kdcopt)
for (next_server = top_server; *next_server; next_server++) {
krb5_data *realm_1 = krb5_princ_component(context, next_server[0], 1);
krb5_data *realm_2 = krb5_princ_component(context, tgtr->server, 1);
- if (realm_1->length == realm_2->length &&
+ if (realm_1 != NULL &&
+ realm_2 != NULL &&
+ realm_1->length == realm_2->length &&
!memcmp(realm_1->data, realm_2->data, realm_1->length)) {
break;
}
diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c
index 3bcaa0b..de8d29f 100644
--- a/src/lib/krb5/krb/get_creds.c
+++ b/src/lib/krb5/krb/get_creds.c
@@ -102,6 +102,7 @@ krb5_get_credentials(context, options, ccache, in_creds, out_creds)
krb5_creds *ncreds;
krb5_creds **tgts;
krb5_flags fields;
+ int not_ktype;
retval = krb5_get_credentials_core(context, options, ccache,
in_creds, out_creds,
@@ -128,6 +129,11 @@ krb5_get_credentials(context, options, ccache, in_creds, out_creds)
|| options & KRB5_GC_CACHED)
return retval;
+ if (retval == KRB5_CC_NOT_KTYPE)
+ not_ktype = 1;
+ else
+ not_ktype = 0;
+
retval = krb5_get_cred_from_kdc(context, ccache, ncreds, out_creds, &tgts);
if (tgts) {
register int i = 0;
@@ -141,6 +147,21 @@ krb5_get_credentials(context, options, ccache, in_creds, out_creds)
}
krb5_free_tgt_creds(context, tgts);
}
+ /*
+ * Translate KRB5_CC_NOTFOUND if we previously got
+ * KRB5_CC_NOT_KTYPE from krb5_cc_retrieve_cred(), in order to
+ * handle the case where there is no TGT in the ccache and the
+ * input enctype didn't match. This handling is necessary because
+ * some callers, such as GSSAPI, iterate through enctypes and
+ * KRB5_CC_NOTFOUND passed through from the
+ * krb5_get_cred_from_kdc() is semantically incorrect, since the
+ * actual failure was the non-existence of a ticket of the correct
+ * enctype rather than the missing TGT.
+ */
+ if ((retval == KRB5_CC_NOTFOUND || retval == KRB5_CC_NOT_KTYPE)
+ && not_ktype)
+ retval = KRB5_CC_NOT_KTYPE;
+
if (!retval)
retval = krb5_cc_store_cred(context, ccache, *out_creds);
return retval;
@@ -160,10 +181,8 @@ krb5_get_credentials_val_renew_core(context, options, ccache,
int which;
{
krb5_error_code retval;
- krb5_creds mcreds;
krb5_principal tmp;
krb5_creds **tgts = 0;
- krb5_flags fields;
switch(which) {
case INT_GC_VALIDATE:
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index c1c6df1..57d0313 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -84,13 +84,13 @@ static krb5_error_code make_preauth_list PROTOTYPE((krb5_context,
*/
static krb5_error_code
send_as_request(context, request, time_now, ret_err_reply, ret_as_reply,
- master)
+ use_master)
krb5_context context;
krb5_kdc_req *request;
krb5_timestamp *time_now;
krb5_error ** ret_err_reply;
krb5_kdc_rep ** ret_as_reply;
- int * master;
+ int use_master;
{
krb5_kdc_rep *as_reply = 0;
krb5_error_code retval;
@@ -116,7 +116,7 @@ send_as_request(context, request, time_now, ret_err_reply, ret_as_reply,
k4_version = packet->data[0];
retval = krb5_sendto_kdc(context, packet,
krb5_princ_realm(context, request->client),
- &reply, master);
+ &reply, use_master);
krb5_free_data(context, packet);
if (retval)
goto cleanup;
@@ -367,7 +367,6 @@ make_preauth_list(context, ptypes, nptypes, ret_list)
{
krb5_preauthtype * ptypep;
krb5_pa_data ** preauthp;
- krb5_pa_data ** preauth_to_use;
int i;
if (nptypes < 0) {
@@ -457,12 +456,35 @@ krb5_get_in_tkt(context, options, addrs, ktypes, ptypes, key_proc, keyseed,
request.from = creds->times.starttime;
request.till = creds->times.endtime;
request.rtime = creds->times.renew_till;
- if (ktypes)
- request.ktype = ktypes;
- else
- if ((retval = krb5_get_default_in_tkt_ktypes(context, &request.ktype)))
- goto cleanup;
+ if ((retval = krb5_get_default_in_tkt_ktypes(context, &request.ktype)))
+ goto cleanup;
for (request.nktypes = 0;request.ktype[request.nktypes];request.nktypes++);
+ if (ktypes) {
+ int i, req, next = 0;
+ for (req = 0; ktypes[req]; req++) {
+ if (ktypes[req] == request.ktype[next]) {
+ next++;
+ continue;
+ }
+ for (i = next + 1; i < request.nktypes; i++)
+ if (ktypes[req] == request.ktype[i]) {
+ /* Found the enctype we want, but not in the
+ position we want. Move it, but keep the old
+ one from the desired slot around in case it's
+ later in our requested-ktypes list. */
+ krb5_enctype t;
+ t = request.ktype[next];
+ request.ktype[next] = request.ktype[i];
+ request.ktype[i] = t;
+ next++;
+ break;
+ }
+ /* If we didn't find it, don't do anything special, just
+ drop it. */
+ }
+ request.ktype[next] = 0;
+ request.nktypes = next;
+ }
request.authorization_data.ciphertext.length = 0;
request.authorization_data.ciphertext.data = 0;
request.unenc_authdata = 0;
@@ -538,7 +560,7 @@ krb5_get_in_tkt(context, options, addrs, ktypes, ptypes, key_proc, keyseed,
goto cleanup;
cleanup:
- if (!ktypes && request.ktype)
+ if (request.ktype)
free(request.ktype);
if (!addrs && request.addresses)
krb5_free_addresses(context, request.addresses);
@@ -559,17 +581,17 @@ cleanup:
return (retval);
}
-/* begin appdefaults parsing code. This should almost certainly move
+/* begin libdefaults parsing code. This should almost certainly move
somewhere else, but I don't know where the correct somewhere else
is yet. */
/* XXX Duplicating this is annoying; try to work on a better way.*/
-static char *conf_yes[] = {
+static const char *conf_yes[] = {
"y", "yes", "true", "t", "1", "on",
0,
};
-static char *conf_no[] = {
+static const char *conf_no[] = {
"n", "no", "false", "nil", "0", "off",
0,
};
@@ -595,7 +617,7 @@ _krb5_conf_boolean(s)
}
static krb5_error_code
-krb5_appdefault_string(context, realm, option, ret_value)
+krb5_libdefault_string(context, realm, option, ret_value)
krb5_context context;
const krb5_data *realm;
const char *option;
@@ -606,7 +628,6 @@ krb5_appdefault_string(context, realm, option, ret_value)
char **nameval = NULL;
krb5_error_code retval;
char realmstr[1024];
- char **cpp;
if (realm->length > sizeof(realmstr)-1)
return(EINVAL);
@@ -673,7 +694,7 @@ goodbye:
/* as well as the DNS code */
krb5_error_code
-krb5_appdefault_boolean(context, realm, option, ret_value)
+krb5_libdefault_boolean(context, realm, option, ret_value)
krb5_context context;
const char *option;
const krb5_data *realm;
@@ -682,7 +703,7 @@ krb5_appdefault_boolean(context, realm, option, ret_value)
char *string = NULL;
krb5_error_code retval;
- retval = krb5_appdefault_string(context, realm, option, &string);
+ retval = krb5_libdefault_string(context, realm, option, &string);
if (retval)
return(retval);
@@ -696,7 +717,7 @@ krb5_appdefault_boolean(context, realm, option, ret_value)
KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
krb5_get_init_creds(context, creds, client, prompter, prompter_data,
start_time, in_tkt_service, options, gak_fct, gak_data,
- master, as_reply)
+ use_master, as_reply)
krb5_context context;
krb5_creds *creds;
krb5_principal client;
@@ -707,7 +728,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data,
krb5_get_init_creds_opt *options;
krb5_gic_get_as_key_fct gak_fct;
void *gak_data;
- int *master;
+ int use_master;
krb5_kdc_rep **as_reply;
{
krb5_error_code ret;
@@ -751,7 +772,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data,
if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE))
tempint = options->forwardable;
- else if ((ret = krb5_appdefault_boolean(context, &client->realm,
+ else if ((ret = krb5_libdefault_boolean(context, &client->realm,
"forwardable", &tempint)) == 0)
;
else
@@ -763,7 +784,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data,
if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_PROXIABLE))
tempint = options->proxiable;
- else if ((ret = krb5_appdefault_boolean(context, &client->realm,
+ else if ((ret = krb5_libdefault_boolean(context, &client->realm,
"proxiable", &tempint)) == 0)
;
else
@@ -775,7 +796,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data,
if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE)) {
renew_life = options->renew_life;
- } else if ((ret = krb5_appdefault_string(context, &client->realm,
+ } else if ((ret = krb5_libdefault_string(context, &client->realm,
"renew_lifetime", &tempstr))
== 0) {
if (ret = krb5_string_to_deltat(tempstr, &renew_life)) {
@@ -868,7 +889,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data,
}
/* it would be nice if this parsed out an address list, but
that would be work. */
- else if (((ret = krb5_appdefault_boolean(context, &client->realm,
+ else if (((ret = krb5_libdefault_boolean(context, &client->realm,
"noaddresses", &tempint)) == 0)
&& tempint) {
;
@@ -923,7 +944,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data,
err_reply = 0;
local_as_reply = 0;
if ((ret = send_as_request(context, &request, &time_now, &err_reply,
- &local_as_reply, master)))
+ &local_as_reply, use_master)))
goto cleanup;
if (err_reply) {
diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c
index 8b6f231..98bbbd0 100644
--- a/src/lib/krb5/krb/gic_keytab.c
+++ b/src/lib/krb5/krb/gic_keytab.c
@@ -61,7 +61,7 @@ krb5_get_init_creds_keytab(context, creds, client, arg_keytab,
krb5_get_init_creds_opt *options;
{
krb5_error_code ret, ret2;
- int master;
+ int use_master;
krb5_keytab keytab;
if (arg_keytab == NULL) {
@@ -71,14 +71,14 @@ krb5_get_init_creds_keytab(context, creds, client, arg_keytab,
keytab = arg_keytab;
}
- master = 0;
+ use_master = 0;
/* first try: get the requested tkt from any kdc */
ret = krb5_get_init_creds(context, creds, client, NULL, NULL,
start_time, in_tkt_service, options,
krb5_get_as_key_keytab, (void *) keytab,
- &master, NULL);
+ use_master,NULL);
/* check for success */
@@ -87,19 +87,19 @@ krb5_get_init_creds_keytab(context, creds, client, arg_keytab,
/* If all the kdc's are unavailable fail */
- if (ret == KRB5_KDC_UNREACH)
+ if ((ret == KRB5_KDC_UNREACH) || (ret == KRB5_REALM_CANT_RESOLVE))
goto cleanup;
/* if the reply did not come from the master kdc, try again with
the master kdc */
- if (!master) {
- master = 1;
+ if (!use_master) {
+ use_master = 1;
ret2 = krb5_get_init_creds(context, creds, client, NULL, NULL,
start_time, in_tkt_service, options,
krb5_get_as_key_keytab, (void *) keytab,
- &master, NULL);
+ use_master, NULL);
if (ret2 == 0) {
ret = 0;
@@ -109,7 +109,7 @@ krb5_get_init_creds_keytab(context, creds, client, arg_keytab,
/* if the master is unreachable, return the error from the
slave we were able to contact */
- if (ret2 == KRB5_KDC_UNREACH)
+ if ((ret2 == KRB5_KDC_UNREACH) || (ret == KRB5_REALM_CANT_RESOLVE))
goto cleanup;
ret = ret2;
diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c
index 7ca4343..f867989 100644
--- a/src/lib/krb5/krb/gic_pwd.c
+++ b/src/lib/krb5/krb/gic_pwd.c
@@ -1,5 +1,4 @@
#include "k5-int.h"
-#include "com_err.h"
static krb5_error_code
krb5_get_as_key_password(context, client, etype, prompter, prompter_data,
@@ -97,7 +96,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data,
krb5_get_init_creds_opt *options;
{
krb5_error_code ret, ret2;
- int master;
+ int use_master;
krb5_kdc_rep *as_reply;
int tries;
krb5_creds chpw_creds;
@@ -107,7 +106,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data,
krb5_prompt prompt[2];
krb5_prompt_type prompt_types[sizeof(prompt)/sizeof(prompt[0])];
- master = 0;
+ use_master = 0;
as_reply = NULL;
memset(&chpw_creds, 0, sizeof(chpw_creds));
@@ -133,7 +132,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data,
ret = krb5_get_init_creds(context, creds, client, prompter, data,
start_time, in_tkt_service, options,
krb5_get_as_key_password, (void *) &pw0,
- &master, &as_reply);
+ use_master, &as_reply);
/* check for success */
@@ -144,19 +143,20 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data,
user interrupt, fail */
if ((ret == KRB5_KDC_UNREACH) ||
- (ret == KRB5_LIBOS_PWDINTR))
+ (ret == KRB5_LIBOS_PWDINTR) ||
+ (ret == KRB5_REALM_CANT_RESOLVE))
goto cleanup;
/* if the reply did not come from the master kdc, try again with
the master kdc */
- if (!master) {
- master = 1;
+ if (!use_master) {
+ use_master = 1;
ret2 = krb5_get_init_creds(context, creds, client, prompter, data,
start_time, in_tkt_service, options,
krb5_get_as_key_password, (void *) &pw0,
- &master, &as_reply);
+ use_master, &as_reply);
if (ret2 == 0) {
ret = 0;
@@ -166,12 +166,18 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data,
/* if the master is unreachable, return the error from the
slave we were able to contact */
- if (ret2 == KRB5_KDC_UNREACH)
+ if ((ret2 == KRB5_KDC_UNREACH) ||
+ (ret2 == KRB5_REALM_CANT_RESOLVE))
goto cleanup;
ret = ret2;
}
+#ifdef USE_LOGIN_LIBRARY
+ if (ret == KRB5KDC_ERR_KEY_EXP)
+ goto cleanup; /* Login library will deal appropriately with this error */
+#endif
+
/* at this point, we have an error from the master. if the error
is not password expired, or if it is but there's no prompter,
return this error */
@@ -195,7 +201,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data,
prompter, data,
start_time, "kadmin/changepw", &chpw_opts,
krb5_get_as_key_password, (void *) &pw0,
- &master, NULL)))
+ use_master, NULL)))
goto cleanup;
prompt[0].prompt = "Enter new password";
@@ -282,7 +288,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data,
ret = krb5_get_init_creds(context, creds, client, prompter, data,
start_time, in_tkt_service, options,
krb5_get_as_key_password, (void *) &pw0,
- &master, &as_reply);
+ use_master, &as_reply);
cleanup:
krb5int_set_prompt_types(context, 0);
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index e2eccc4..abcb573 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -1,7 +1,7 @@
/*
* lib/krb5/krb/init_ctx.c
*
- * Copyright 1994 by the Massachusetts Institute of Technology.
+ * Copyright 1994,1999,2000 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -84,7 +84,10 @@ init_common (context, secure)
{
krb5_context ctx = 0;
krb5_error_code retval;
- krb5_timestamp now;
+ struct {
+ krb5_int32 now, now_usec;
+ long pid;
+ } seed_data;
krb5_data seed;
int tmp;
@@ -129,10 +132,11 @@ init_common (context, secure)
goto cleanup;
/* initialize the prng (not well, but passable) */
- if ((retval = krb5_timeofday(ctx, &now)))
+ if ((retval = krb5_crypto_us_timeofday(&seed_data.now, &seed_data.now_usec)))
goto cleanup;
- seed.length = sizeof(now);
- seed.data = (char *) &now;
+ seed_data.pid = getpid ();
+ seed.length = sizeof(seed_data);
+ seed.data = (char *) &seed_data;
if ((retval = krb5_c_random_seed(ctx, &seed)))
goto cleanup;
@@ -169,7 +173,7 @@ init_common (context, secure)
"kdc_default_options", 0,
KDC_OPT_RENEWABLE_OK, &tmp);
ctx->kdc_default_options = KDC_OPT_RENEWABLE_OK;
-#ifdef macintosh
+#if TARGET_OS_MAC
#define DEFAULT_KDC_TIMESYNC 1
#else
#define DEFAULT_KDC_TIMESYNC 0
@@ -187,7 +191,7 @@ init_common (context, secure)
* Note: DCE 1.0.3a only supports a cache type of 1
* DCE 1.1 supports a cache type of 2.
*/
-#ifdef macintosh
+#if TARGET_OS_MAC
#define DEFAULT_CCACHE_TYPE 4
#else
#define DEFAULT_CCACHE_TYPE 3
@@ -281,7 +285,7 @@ get_profile_etype_list(context, ktypes, profstr, ctx_count, ctx_list)
{
krb5_enctype *old_ktypes;
- if (context->in_tkt_ktype_count) {
+ if (ctx_count) {
/* application-set defaults */
if ((old_ktypes =
(krb5_enctype *)malloc(sizeof(krb5_enctype) *
@@ -370,8 +374,8 @@ krb5_get_default_in_tkt_ktypes(context, ktypes)
context->in_tkt_ktypes));
}
-krb5_error_code
-krb5_set_default_tgs_ktypes(context, ktypes)
+krb5_error_code KRB5_CALLCONV
+krb5_set_default_tgs_enctypes (context, ktypes)
krb5_context context;
const krb5_enctype *ktypes;
{
@@ -396,13 +400,30 @@ krb5_set_default_tgs_ktypes(context, ktypes)
}
if (context->tgs_ktypes)
- free(context->tgs_ktypes);
+ krb5_free_ktypes(context, context->tgs_ktypes);
context->tgs_ktypes = new_ktypes;
context->tgs_ktype_count = i;
return 0;
}
+krb5_error_code krb5_set_default_tgs_ktypes
+(krb5_context context, const krb5_enctype *etypes)
+{
+ return (krb5_set_default_tgs_enctypes (context, etypes));
+}
+
+
+void
+KRB5_CALLCONV
+krb5_free_ktypes (context, val)
+ krb5_context context;
+ krb5_enctype FAR *val;
+{
+ free (val);
+}
+
krb5_error_code
+KRB5_CALLCONV
krb5_get_tgs_ktypes(context, princ, ktypes)
krb5_context context;
krb5_const_principal princ;
@@ -441,7 +462,7 @@ krb5_is_permitted_enctype(context, etype)
if (*ptr == etype)
ret = 1;
- krb5_xfree(list);
+ krb5_free_ktypes (context, list);
return(ret);
}
diff --git a/src/lib/krb5/krb/init_keyblock.c b/src/lib/krb5/krb/init_keyblock.c
new file mode 100644
index 0000000..eb60b06
--- /dev/null
+++ b/src/lib/krb5/krb/init_keyblock.c
@@ -0,0 +1,61 @@
+/*
+ * lib/krb5/krb/init_keyblock.c
+ *
+ * Copyright (C) 2002 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. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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_init_keyblock- a function to set up
+ * an empty keyblock
+ */
+
+
+#include "k5-int.h"
+#include <assert.h>
+
+krb5_error_code KRB5_CALLCONV
+krb5_init_keyblock(krb5_context context, krb5_enctype enctype,
+ size_t length, krb5_keyblock **out)
+{
+ krb5_keyblock *kb;
+ kb = malloc (sizeof(krb5_keyblock));
+ assert (out);
+ *out = NULL;
+ if (!kb) {
+ return ENOMEM;
+ }
+ kb->magic = KV5M_KEYBLOCK;
+ kb->enctype = enctype;
+ kb->length = length;
+ if(length) {
+ kb->contents = malloc (length);
+ if(!kb->contents) {
+ free (kb);
+ return ENOMEM;
+ }
+ } else {
+ kb->contents = NULL;
+ }
+ *out = kb;
+ return 0;
+}
diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c
index 24d8aaf..8e57f83 100644
--- a/src/lib/krb5/krb/kfree.c
+++ b/src/lib/krb5/krb/kfree.c
@@ -36,7 +36,6 @@ krb5_free_address(context, val)
if (val->contents)
krb5_xfree(val->contents);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -52,7 +51,6 @@ krb5_free_addresses(context, val)
krb5_xfree(*temp);
}
krb5_xfree(val);
- return;
}
@@ -64,7 +62,6 @@ krb5_free_ap_rep(context, val)
if (val->enc_part.ciphertext.data)
krb5_xfree(val->enc_part.ciphertext.data);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -77,7 +74,6 @@ krb5_free_ap_req(context, val)
if (val->authenticator.ciphertext.data)
krb5_xfree(val->authenticator.ciphertext.data);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -88,7 +84,6 @@ krb5_free_ap_rep_enc_part(context, val)
if (val->subkey)
krb5_free_keyblock(context, val->subkey);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -96,15 +91,22 @@ krb5_free_authenticator_contents(context, val)
krb5_context context;
krb5_authenticator FAR *val;
{
- if (val->checksum)
+ if (val->checksum) {
krb5_free_checksum(context, val->checksum);
- if (val->client)
+ val->checksum = 0;
+ }
+ if (val->client) {
krb5_free_principal(context, val->client);
- if (val->subkey)
+ val->client = 0;
+ }
+ if (val->subkey) {
krb5_free_keyblock(context, val->subkey);
- if (val->authorization_data)
- krb5_free_authdata(context, val->authorization_data);
- return;
+ val->subkey = 0;
+ }
+ if (val->authorization_data) {
+ krb5_free_authdata(context, val->authorization_data);
+ val->authorization_data = 0;
+ }
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -120,7 +122,6 @@ krb5_free_authdata(context, val)
krb5_xfree(*temp);
}
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -128,16 +129,8 @@ krb5_free_authenticator(context, val)
krb5_context context;
krb5_authenticator FAR *val;
{
- if (val->checksum)
- krb5_free_checksum(context, val->checksum);
- if (val->client)
- krb5_free_principal(context, val->client);
- if (val->subkey)
- krb5_free_keyblock(context, val->subkey);
- if (val->authorization_data)
- krb5_free_authdata(context, val->authorization_data);
+ krb5_free_authenticator_contents(context, val);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -145,10 +138,8 @@ krb5_free_checksum(context, val)
krb5_context context;
register krb5_checksum *val;
{
- if (val->contents)
- krb5_xfree(val->contents);
+ krb5_free_checksum_contents(context, val);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -156,9 +147,10 @@ krb5_free_checksum_contents(context, val)
krb5_context context;
register krb5_checksum *val;
{
- if (val->contents)
+ if (val->contents) {
krb5_xfree(val->contents);
- return;
+ val->contents = 0;
+ }
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -171,7 +163,6 @@ krb5_free_cred(context, val)
if (val->enc_part.ciphertext.data)
krb5_xfree(val->enc_part.ciphertext.data);
krb5_xfree(val);
- return;
}
/*
@@ -184,23 +175,35 @@ krb5_free_cred_contents(context, val)
krb5_context context;
krb5_creds FAR *val;
{
- if (val->client)
+ if (val->client) {
krb5_free_principal(context, val->client);
- if (val->server)
+ val->client = 0;
+ }
+ if (val->server) {
krb5_free_principal(context, val->server);
+ val->server = 0;
+ }
if (val->keyblock.contents) {
memset((char *)val->keyblock.contents, 0, val->keyblock.length);
krb5_xfree(val->keyblock.contents);
+ val->keyblock.contents = 0;
}
- if (val->ticket.data)
+ if (val->ticket.data) {
krb5_xfree(val->ticket.data);
- if (val->second_ticket.data)
+ val->ticket.data = 0;
+ }
+ if (val->second_ticket.data) {
krb5_xfree(val->second_ticket.data);
- if (val->addresses)
+ val->second_ticket.data = 0;
+ }
+ if (val->addresses) {
krb5_free_addresses(context, val->addresses);
- if (val->authdata)
+ val->addresses = 0;
+ }
+ if (val->authdata) {
krb5_free_authdata(context, val->authdata);
- return;
+ val->authdata = 0;
+ }
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -210,10 +213,14 @@ krb5_free_cred_enc_part(context, val)
{
register krb5_cred_info **temp;
- if (val->r_address)
- krb5_free_address(context, val->r_address);
- if (val->s_address)
- krb5_free_address(context, val->s_address);
+ if (val->r_address) {
+ krb5_free_address(context, val->r_address);
+ val->r_address = 0;
+ }
+ if (val->s_address) {
+ krb5_free_address(context, val->s_address);
+ val->s_address = 0;
+ }
if (val->ticket_info) {
for (temp = val->ticket_info; *temp; temp++) {
@@ -228,8 +235,8 @@ krb5_free_cred_enc_part(context, val)
krb5_xfree((*temp));
}
krb5_xfree(val->ticket_info);
+ val->ticket_info = 0;
}
- return;
}
@@ -240,7 +247,6 @@ krb5_free_creds(context, val)
{
krb5_free_cred_contents(context, val);
krb5_xfree(val);
- return;
}
@@ -252,7 +258,6 @@ krb5_free_data(context, val)
if (val->data)
krb5_xfree(val->data);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -260,9 +265,10 @@ krb5_free_data_contents(context, val)
krb5_context context;
krb5_data FAR * val;
{
- if (val->data)
+ if (val->data) {
krb5_xfree(val->data);
- return;
+ val->data = 0;
+ }
}
void krb5_free_etype_info(context, info)
@@ -294,7 +300,6 @@ krb5_free_enc_kdc_rep_part(context, val)
if (val->caddrs)
krb5_free_addresses(context, val->caddrs);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -313,7 +318,6 @@ krb5_free_enc_tkt_part(context, val)
if (val->authorization_data)
krb5_free_authdata(context, val->authorization_data);
krb5_xfree(val);
- return;
}
@@ -331,7 +335,6 @@ krb5_free_error(context, val)
if (val->e_data.data)
krb5_xfree(val->e_data.data);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -350,7 +353,6 @@ krb5_free_kdc_rep(context, val)
if (val->enc_part2)
krb5_free_enc_kdc_rep_part(context, val->enc_part2);
krb5_xfree(val);
- return;
}
@@ -376,7 +378,6 @@ krb5_free_kdc_req(context, val)
if (val->second_ticket)
krb5_free_tickets(context, val->second_ticket);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -387,8 +388,8 @@ krb5_free_keyblock_contents(context, key)
if (key->contents) {
memset(key->contents, 0, key->length);
krb5_xfree(key->contents);
+ key->contents = 0;
}
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -398,7 +399,6 @@ krb5_free_keyblock(context, val)
{
krb5_free_keyblock_contents(context, val);
krb5_xfree(val);
- return;
}
@@ -413,7 +413,6 @@ krb5_free_last_req(context, val)
for (temp = val; *temp; temp++)
krb5_xfree(*temp);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -429,7 +428,6 @@ krb5_free_pa_data(context, val)
krb5_xfree(*temp);
}
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -451,7 +449,6 @@ krb5_free_principal(context, val)
if (val->realm.data)
krb5_xfree(val->realm.data);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -462,7 +459,6 @@ krb5_free_priv(context, val)
if (val->enc_part.ciphertext.data)
krb5_xfree(val->enc_part.ciphertext.data);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -477,7 +473,6 @@ krb5_free_priv_enc_part(context, val)
if (val->s_address)
krb5_free_address(context, val->s_address);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -488,7 +483,6 @@ krb5_free_pwd_data(context, val)
if (val->element)
krb5_free_pwd_sequences(context, val->element);
krb5_xfree(val);
- return;
}
@@ -497,11 +491,14 @@ krb5_free_pwd_sequences(context, val)
krb5_context context;
passwd_phrase_element FAR * FAR *val;
{
- if ((*val)->passwd)
+ if ((*val)->passwd) {
krb5_xfree((*val)->passwd);
- if ((*val)->phrase)
+ (*val)->passwd = 0;
+ }
+ if ((*val)->phrase) {
krb5_xfree((*val)->phrase);
- return;
+ (*val)->phrase = 0;
+ }
}
@@ -519,7 +516,6 @@ krb5_free_safe(context, val)
if (val->checksum)
krb5_free_checksum(context, val->checksum);
krb5_xfree(val);
- return;
}
@@ -535,7 +531,6 @@ krb5_free_ticket(context, val)
if (val->enc_part2)
krb5_free_enc_tkt_part(context, val->enc_part2);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -548,7 +543,6 @@ krb5_free_tickets(context, val)
for (temp = val; *temp; temp++)
krb5_free_ticket(context, *temp);
krb5_xfree(val);
- return;
}
@@ -573,7 +567,6 @@ krb5_free_tkt_authent(context, val)
if (val->authenticator)
krb5_free_authenticator(context, val->authenticator);
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -583,7 +576,6 @@ krb5_free_unparsed_name(context, val)
{
if (val)
krb5_xfree(val);
- return;
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -612,8 +604,10 @@ krb5_free_sam_challenge_contents(krb5_context ctx, krb5_sam_challenge FAR *sc)
krb5_free_data_contents(ctx, &sc->sam_response_prompt);
if (sc->sam_pk_for_sad.data)
krb5_free_data_contents(ctx, &sc->sam_pk_for_sad);
- if (sc->sam_cksum.contents)
+ if (sc->sam_cksum.contents) {
krb5_xfree(sc->sam_cksum.contents);
+ sc->sam_cksum.contents = 0;
+ }
}
KRB5_DLLIMP void KRB5_CALLCONV
@@ -656,8 +650,10 @@ krb5_free_predicted_sam_response_contents(krb5_context ctx,
return;
if (psr->sam_key.contents)
krb5_free_keyblock_contents(ctx, &psr->sam_key);
- if (psr->client)
+ if (psr->client) {
krb5_free_principal(ctx, psr->client);
+ psr->client = 0;
+ }
if (psr->msd.data)
krb5_free_data_contents(ctx, &psr->msd);
}
@@ -689,4 +685,3 @@ krb5_free_pa_enc_ts(krb5_context ctx, krb5_pa_enc_ts FAR *pa_enc_ts)
return;
krb5_xfree(pa_enc_ts);
}
-
diff --git a/src/lib/krb5/krb/mk_cred.c b/src/lib/krb5/krb/mk_cred.c
index cdda80d..9bcfe84 100644
--- a/src/lib/krb5/krb/mk_cred.c
+++ b/src/lib/krb5/krb/mk_cred.c
@@ -7,7 +7,7 @@
* structures.
*
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "cleanup.h"
#include "auth_con.h"
diff --git a/src/lib/krb5/krb/mk_priv.c b/src/lib/krb5/krb/mk_priv.c
index 7685817..d72f6b2 100644
--- a/src/lib/krb5/krb/mk_priv.c
+++ b/src/lib/krb5/krb/mk_priv.c
@@ -93,14 +93,6 @@ krb5_mk_priv_basic(context, userdata, keyblock, replaydata, local_addr,
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 - blocksize),
- blocksize);
-
if ((retval = encode_krb5_priv(&privmsg, &scratch2)))
goto clean_encpart;
diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c
index a8b20eb..88daab5 100644
--- a/src/lib/krb5/krb/mk_req_ext.c
+++ b/src/lib/krb5/krb/mk_req_ext.c
@@ -126,10 +126,24 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
/* generate subkey if needed */
- if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->local_subkey))
+ if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->local_subkey)) {
+ /* Provide some more fodder for random number code.
+ This isn't strong cryptographically; the point here is not
+ to guarantee randomness, but to make it less likely that multiple
+ sessions could pick the same subkey. */
+ struct {
+ krb5_int32 sec, usec;
+ } rnd_data;
+ krb5_data d;
+ krb5_crypto_us_timeofday (&rnd_data.sec, &rnd_data.usec);
+ d.length = sizeof (rnd_data);
+ d.data = (char *) &rnd_data;
+ (void) krb5_c_random_seed (context, &d);
+
if ((retval = krb5_generate_subkey(context, &(in_creds)->keyblock,
&(*auth_context)->local_subkey)))
goto cleanup;
+ }
if (in_data) {
if ((*auth_context)->req_cksumtype == 0x8003) {
diff --git a/src/lib/krb5/krb/mk_safe.c b/src/lib/krb5/krb/mk_safe.c
index 781e256..dd7d1ef 100644
--- a/src/lib/krb5/krb/mk_safe.c
+++ b/src/lib/krb5/krb/mk_safe.c
@@ -27,7 +27,7 @@
* krb5_mk_safe()
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "cleanup.h"
#include "auth_con.h"
@@ -169,6 +169,7 @@ krb5_mk_safe(context, auth_context, userdata, outbuf, outdata)
krb5_address * plocal_fulladdr = NULL;
krb5_address remote_fulladdr;
krb5_address local_fulladdr;
+ krb5_cksumtype sumtype;
CLEANUP_INIT(2);
@@ -204,9 +205,33 @@ krb5_mk_safe(context, auth_context, userdata, outbuf, outdata)
}
}
+ {
+ unsigned int nsumtypes;
+ unsigned int i;
+ krb5_cksumtype *sumtypes;
+ retval = krb5_c_keyed_checksum_types (context, keyblock->enctype,
+ &nsumtypes, &sumtypes);
+ if (retval) {
+ CLEANUP_DONE ();
+ goto error;
+ }
+ if (nsumtypes == 0) {
+ retval = KRB5_BAD_ENCTYPE;
+ krb5_free_cksumtypes (context, sumtypes);
+ CLEANUP_DONE ();
+ goto error;
+ }
+ for (i = 0; i < nsumtypes; i++)
+ if (auth_context->safe_cksumtype == sumtypes[i])
+ break;
+ if (i == nsumtypes)
+ i = 0;
+ sumtype = sumtypes[i];
+ krb5_free_cksumtypes (context, sumtypes);
+ }
if ((retval = krb5_mk_safe_basic(context, userdata, keyblock, &replaydata,
plocal_fulladdr, premote_fulladdr,
- auth_context->safe_cksumtype, outbuf))) {
+ sumtype, outbuf))) {
CLEANUP_DONE();
goto error;
}
diff --git a/src/lib/krb5/krb/parse.c b/src/lib/krb5/krb/parse.c
index b628a0d..43faf32 100644
--- a/src/lib/krb5/krb/parse.c
+++ b/src/lib/krb5/krb/parse.c
@@ -71,7 +71,7 @@ krb5_parse_name(context, name, nprincipal)
{
register const char *cp;
register char *q;
- register i,c,size;
+ register int i,c,size;
int components = 0;
const char *parsed_realm = NULL;
int fcompsize[FCOMPNUM];
@@ -173,11 +173,13 @@ krb5_parse_name(context, name, nprincipal)
cp++;
size++;
} else if (c == COMPONENT_SEP) {
- krb5_princ_component(context, principal, i)->length = size;
+ if (krb5_princ_size(context, principal) > i)
+ krb5_princ_component(context, principal, i)->length = size;
size = 0;
i++;
} else if (c == REALM_SEP) {
- krb5_princ_component(context, principal, i)->length = size;
+ if (krb5_princ_size(context, principal) > i)
+ krb5_princ_component(context, principal, i)->length = size;
size = 0;
parsed_realm = cp+1;
} else
@@ -186,7 +188,8 @@ krb5_parse_name(context, name, nprincipal)
if (parsed_realm)
krb5_princ_realm(context, principal)->length = size;
else
- krb5_princ_component(context, principal, i)->length = size;
+ if (krb5_princ_size(context, principal) > i)
+ krb5_princ_component(context, principal, i)->length = size;
if (i + 1 != components) {
#if !defined(_MSDOS) && !defined(_WIN32) && !defined(macintosh)
fprintf(stderr,
diff --git a/src/lib/krb5/krb/preauth.c b/src/lib/krb5/krb/preauth.c
index 9f301da..173170a 100644
--- a/src/lib/krb5/krb/preauth.c
+++ b/src/lib/krb5/krb/preauth.c
@@ -32,7 +32,6 @@
#include "k5-int.h"
#include <stdio.h>
#include <time.h>
-#include <syslog.h>
#ifdef _MSDOS
#define getpid _getpid
#include <process.h>
@@ -172,6 +171,10 @@ krb5_error_code krb5_obtain_padata(context, preauth_to_use, key_proc,
retval = decode_krb5_etype_info(&scratch, &etype_info);
if (retval)
return retval;
+ if (etype_info[0] == NULL) {
+ krb5_free_etype_info(context, etype_info);
+ etype_info = NULL;
+ }
}
}
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index 5ea61c9..78afab9 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -256,6 +256,9 @@ krb5_error_code pa_sam(krb5_context context,
krb5_data * scratch;
krb5_pa_data * pa;
+ if (prompter == NULL)
+ return KRB5_LIBOS_CANTREADPWD;
+
tmpsam.length = in_padata->length;
tmpsam.data = (char *) in_padata->contents;
if (ret = decode_krb5_sam_challenge(&tmpsam, &sam_challenge))
@@ -530,6 +533,11 @@ krb5_do_preauth(krb5_context context,
}
return ret;
}
+ if (etype_info[0] == NULL) {
+ krb5_free_etype_info(context, etype_info);
+ etype_info = NULL;
+ break;
+ }
salt->data = (char *) etype_info[0]->salt;
salt->length = etype_info[0]->length;
*etype = etype_info[0]->etype;
diff --git a/src/lib/krb5/krb/princ_comp.c b/src/lib/krb5/krb/princ_comp.c
index cba26a6..dbcd29d 100644
--- a/src/lib/krb5/krb/princ_comp.c
+++ b/src/lib/krb5/krb/princ_comp.c
@@ -30,7 +30,7 @@
#include "k5-int.h"
-krb5_boolean
+krb5_boolean KRB5_CALLCONV
krb5_realm_compare(context, princ1, princ2)
krb5_context context;
krb5_const_principal princ1;
diff --git a/src/lib/krb5/krb/rd_cred.c b/src/lib/krb5/krb/rd_cred.c
index 86c5ccf..593eb42 100644
--- a/src/lib/krb5/krb/rd_cred.c
+++ b/src/lib/krb5/krb/rd_cred.c
@@ -1,4 +1,4 @@
-#include <k5-int.h>
+#include "k5-int.h"
#include "cleanup.h"
#include "auth_con.h"
@@ -55,24 +55,22 @@ cleanup:
/*----------------------- krb5_rd_cred_basic -----------------------*/
static krb5_error_code
-krb5_rd_cred_basic(context, pcreddata, pkeyblock, local_addr, remote_addr,
+krb5_rd_cred_basic(context, pcreddata, pkeyblock,
replaydata, pppcreds)
krb5_context context;
krb5_data * pcreddata;
krb5_keyblock * pkeyblock;
- krb5_address * local_addr;
- krb5_address * remote_addr;
krb5_replay_data * replaydata;
krb5_creds *** pppcreds;
{
- krb5_error_code retval;
- krb5_cred * pcred;
+ krb5_error_code retval;
+ krb5_cred * pcred;
krb5_int32 ncreds;
krb5_int32 i = 0;
krb5_cred_enc_part encpart;
/* decode cred message */
- if ((retval = decode_krb5_cred(pcreddata, &pcred)))
+ if ((retval = decode_krb5_cred(pcreddata, &pcred)))
return retval;
memset(&encpart, 0, sizeof(encpart));
@@ -80,38 +78,6 @@ krb5_rd_cred_basic(context, pcreddata, pkeyblock, local_addr, remote_addr,
if ((retval = decrypt_credencdata(context, pcred, pkeyblock, &encpart)))
goto cleanup_cred;
- /*
- * Only check the remote address if the KRB_CRED message was
- * protected by encryption. If it came in the checksum field of
- * an init_sec_context message, skip over this check.
- */
- if (remote_addr && encpart.s_address && pkeyblock != NULL) {
- if (!krb5_address_compare(context, remote_addr, encpart.s_address)) {
- retval = KRB5KRB_AP_ERR_BADADDR;
- goto cleanup_cred;
- }
- }
-
- if (encpart.r_address) {
- if (local_addr) {
- if (!krb5_address_compare(context, local_addr, encpart.r_address)) {
- retval = KRB5KRB_AP_ERR_BADADDR;
- goto cleanup_cred;
- }
- } else {
- krb5_address **our_addrs;
-
- if ((retval = krb5_os_localaddr(context, &our_addrs))) {
- goto cleanup_cred;
- }
- if (!krb5_address_search(context, encpart.r_address, our_addrs)) {
- krb5_free_addresses(context, our_addrs);
- retval = KRB5KRB_AP_ERR_BADADDR;
- goto cleanup_cred;
- }
- krb5_free_addresses(context, our_addrs);
- }
- }
replaydata->timestamp = encpart.timestamp;
replaydata->usec = encpart.usec;
@@ -232,54 +198,12 @@ krb5_rd_cred(context, auth_context, pcreddata, pppcreds, outdata)
(auth_context->rcache == NULL))
return KRB5_RC_REQUIRED;
-{
- krb5_address * premote_fulladdr = NULL;
- krb5_address * plocal_fulladdr = NULL;
- krb5_address remote_fulladdr;
- krb5_address local_fulladdr;
- CLEANUP_INIT(2);
-
- if (auth_context->local_addr) {
- if (auth_context->local_port) {
- if (!(retval = krb5_make_fulladdr(context,auth_context->local_addr,
- auth_context->local_port,
- &local_fulladdr))){
- CLEANUP_PUSH(local_fulladdr.contents, free);
- plocal_fulladdr = &local_fulladdr;
- } else {
- return retval;
- }
- } else {
- plocal_fulladdr = auth_context->local_addr;
- }
- }
-
- if (auth_context->remote_addr) {
- if (auth_context->remote_port) {
- if (!(retval = krb5_make_fulladdr(context,auth_context->remote_addr,
- auth_context->remote_port,
- &remote_fulladdr))){
- CLEANUP_PUSH(remote_fulladdr.contents, free);
- premote_fulladdr = &remote_fulladdr;
- } else {
- return retval;
- }
- } else {
- premote_fulladdr = auth_context->remote_addr;
- }
- }
if ((retval = krb5_rd_cred_basic(context, pcreddata, keyblock,
- plocal_fulladdr, premote_fulladdr,
&replaydata, pppcreds))) {
- CLEANUP_DONE();
- return retval;
+ return retval;
}
- CLEANUP_DONE();
-}
-
-
if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) {
krb5_donot_replay replay;
krb5_timestamp currenttime;
@@ -327,4 +251,3 @@ error:;
return retval;
}
-
diff --git a/src/lib/krb5/krb/rd_priv.c b/src/lib/krb5/krb/rd_priv.c
index 9629b0c..bf33ad2 100644
--- a/src/lib/krb5/krb/rd_priv.c
+++ b/src/lib/krb5/krb/rd_priv.c
@@ -27,7 +27,7 @@
* krb5_rd_priv()
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "cleanup.h"
#include "auth_con.h"
@@ -101,13 +101,6 @@ krb5_rd_priv_basic(context, inbuf, keyblock, local_addr, remote_addr,
&privmsg->enc_part, &scratch)))
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 - blocksize),
- blocksize);
-
/* now decode the decrypted stuff */
if ((retval = decode_krb5_enc_priv_part(&scratch, &privmsg_enc_part)))
goto cleanup_scratch;
diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c
index 442e78b..4e9f44e 100644
--- a/src/lib/krb5/krb/rd_req_dec.c
+++ b/src/lib/krb5/krb/rd_req_dec.c
@@ -83,8 +83,8 @@ krb5_rd_req_decrypt_tkt_part(context, req, keytab)
enctype, &ktent)))
return retval;
- if ((retval = krb5_decrypt_tkt_part(context, &ktent.key, req->ticket)))
- return retval;
+ retval = krb5_decrypt_tkt_part(context, &ktent.key, req->ticket);
+ /* Upon error, Free keytab entry first, then return */
(void) krb5_kt_free_entry(context, &ktent);
return retval;
diff --git a/src/lib/krb5/krb/rd_safe.c b/src/lib/krb5/krb/rd_safe.c
index 19c541f..3909f16 100644
--- a/src/lib/krb5/krb/rd_safe.c
+++ b/src/lib/krb5/krb/rd_safe.c
@@ -27,7 +27,7 @@
* krb5_rd_safe()
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "cleanup.h"
#include "auth_con.h"
diff --git a/src/lib/krb5/krb/recvauth.c b/src/lib/krb5/krb/recvauth.c
index 3d5bce4..7458cb9 100644
--- a/src/lib/krb5/krb/recvauth.c
+++ b/src/lib/krb5/krb/recvauth.c
@@ -30,27 +30,24 @@
#define NEED_SOCKETS
#include "k5-int.h"
#include "auth_con.h"
-#include "com_err.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>
static char *sendauth_version = "KRB5_SENDAUTH_V1.0";
-KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
-krb5_recvauth(context, auth_context,
- /* IN */
- fd, appl_version, server, flags, keytab,
- /* OUT */
- ticket)
- krb5_context context;
- krb5_auth_context FAR * auth_context;
- krb5_pointer fd;
- char FAR * appl_version;
- krb5_principal server;
- krb5_int32 flags;
- krb5_keytab keytab;
- krb5_ticket FAR * FAR * ticket;
+krb5_error_code
+recvauth_common(krb5_context context,
+ krb5_auth_context FAR * auth_context,
+ /* IN */
+ krb5_pointer fd,
+ char FAR *appl_version,
+ krb5_principal server,
+ krb5_int32 flags,
+ krb5_keytab keytab,
+ /* OUT */
+ krb5_ticket FAR * FAR * ticket,
+ krb5_data FAR *version)
{
krb5_auth_context new_auth_context;
krb5_flags ap_option;
@@ -91,12 +88,15 @@ krb5_recvauth(context, auth_context,
*/
if ((retval = krb5_read_message(context, fd, &inbuf)))
return(retval);
- if (strcmp(inbuf.data, appl_version)) {
+ if (appl_version && strcmp(inbuf.data, appl_version)) {
krb5_xfree(inbuf.data);
if (!problem)
problem = KRB5_SENDAUTH_BADAPPLVERS;
}
- krb5_xfree(inbuf.data);
+ if (version && !problem)
+ *version = inbuf;
+ else
+ krb5_xfree(inbuf.data);
/*
* OK, now check the problem variable. If it's zero, we're
* fine and we can continue. Otherwise, we have to signal an
@@ -243,3 +243,38 @@ cleanup:;
}
return retval;
}
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_recvauth(context, auth_context,
+ /* IN */
+ fd, appl_version, server, flags, keytab,
+ /* OUT */
+ ticket)
+ krb5_context context;
+ krb5_auth_context FAR * auth_context;
+ krb5_pointer fd;
+ char FAR * appl_version;
+ krb5_principal server;
+ krb5_int32 flags;
+ krb5_keytab keytab;
+ krb5_ticket FAR * FAR * ticket;
+{
+ return recvauth_common (context, auth_context, fd, appl_version,
+ server, flags, keytab, ticket, 0);
+}
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_recvauth_version(krb5_context context,
+ krb5_auth_context FAR *auth_context,
+ /* IN */
+ krb5_pointer fd,
+ krb5_principal server,
+ krb5_int32 flags,
+ krb5_keytab keytab,
+ /* OUT */
+ krb5_ticket FAR * FAR *ticket,
+ krb5_data FAR *version)
+{
+ return recvauth_common (context, auth_context, fd, 0,
+ server, flags, keytab, ticket, version);
+}
diff --git a/src/lib/krb5/krb/send_tgs.c b/src/lib/krb5/krb/send_tgs.c
index 520c0e2..49bc1c9 100644
--- a/src/lib/krb5/krb/send_tgs.c
+++ b/src/lib/krb5/krb/send_tgs.c
@@ -150,7 +150,6 @@ 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
diff --git a/src/lib/krb5/krb/sendauth.c b/src/lib/krb5/krb/sendauth.c
index 4e7c3a7..24d8a8e 100644
--- a/src/lib/krb5/krb/sendauth.c
+++ b/src/lib/krb5/krb/sendauth.c
@@ -30,7 +30,6 @@
#define NEED_SOCKETS
#include "k5-int.h"
-#include "com_err.h"
#include "auth_con.h"
#include <errno.h>
#include <stdio.h>
@@ -119,7 +118,7 @@ krb5_sendauth(context, auth_context,
if (!in_creds || !in_creds->ticket.length) {
if (ccache)
use_ccache = ccache;
- else if ((retval = krb5_cc_default(context, &use_ccache)))
+ else if ((retval = krb5int_cc_default(context, &use_ccache)))
goto error_return;
}
if (!in_creds) {
@@ -152,9 +151,32 @@ krb5_sendauth(context, auth_context,
credsp = in_creds;
}
- if ((retval = krb5_mk_req_extended(context, auth_context, ap_req_options,
- in_data, credsp, &outbuf)))
- goto error_return;
+ if (ap_req_options & AP_OPTS_USE_SUBKEY) {
+ /* Provide some more fodder for random number code.
+ This isn't strong cryptographically; the point here is
+ not to guarantee randomness, but to make it less likely
+ that multiple sessions could pick the same subkey. */
+ char rnd_data[1024];
+ size_t len;
+ krb5_data d;
+ d.length = sizeof (rnd_data);
+ d.data = rnd_data;
+ len = sizeof (rnd_data);
+ if (getpeername (*(int*)fd, (struct sockaddr *) rnd_data, &len) == 0) {
+ d.length = len;
+ (void) krb5_c_random_seed (context, &d);
+ }
+ len = sizeof (rnd_data);
+ if (getsockname (*(int*)fd, (struct sockaddr *) rnd_data, &len) == 0) {
+ d.length = len;
+ (void) krb5_c_random_seed (context, &d);
+ }
+ }
+
+ if ((retval = krb5_mk_req_extended(context, auth_context,
+ ap_req_options, in_data, credsp,
+ &outbuf)))
+ goto error_return;
/*
* First write the length of the AP_REQ message, then write
diff --git a/src/lib/krb5/krb/ser_actx.c b/src/lib/krb5/krb/ser_actx.c
index bac90e3..fdebbe3 100644
--- a/src/lib/krb5/krb/ser_actx.c
+++ b/src/lib/krb5/krb/ser_actx.c
@@ -208,6 +208,7 @@ krb5_auth_context_externalize(kcontext, arg, buffer, lenremain)
krb5_octet *bp;
size_t remain;
krb5_int32 obuf;
+ size_t vecsize;
required = 0;
bp = *buffer;
@@ -237,11 +238,14 @@ krb5_auth_context_externalize(kcontext, arg, buffer, lenremain)
if (auth_context->i_vector) {
kret = krb5_c_block_size(kcontext,
auth_context->keyblock->enctype,
- &obuf);
+ &vecsize);
} else {
- obuf = 0;
+ vecsize = 0;
}
-
+ obuf = vecsize;
+ if (obuf != vecsize)
+ kret = EINVAL;
+
if (!kret)
(void) krb5_ser_pack_int32(obuf, &bp, &remain);
diff --git a/src/lib/krb5/krb/srv_rcache.c b/src/lib/krb5/krb/srv_rcache.c
index c94201b..04e9707 100644
--- a/src/lib/krb5/krb/srv_rcache.c
+++ b/src/lib/krb5/krb/srv_rcache.c
@@ -48,6 +48,9 @@ krb5_get_server_rcache(context, piece, rcptr)
unsigned long uid = geteuid();
#endif
+ if (piece == NULL)
+ return ENOMEM;
+
rcache = (krb5_rcache) malloc(sizeof(*rcache));
if (!rcache)
return ENOMEM;
diff --git a/src/lib/krb5/krb/t_kerb.c b/src/lib/krb5/krb/t_kerb.c
index 2feef39..458015d 100644
--- a/src/lib/krb5/krb/t_kerb.c
+++ b/src/lib/krb5/krb/t_kerb.c
@@ -4,6 +4,7 @@
*/
#include "krb5.h"
+#include "kerberosIV/krb.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -56,6 +57,32 @@ void test_425_conv_principal(ctx, name, inst, realm)
krb5_free_principal(ctx, princ);
}
+void test_524_conv_principal(ctx, name)
+ krb5_context ctx;
+ char *name;
+{
+ krb5_principal princ = 0;
+ krb5_error_code retval;
+ char aname[ANAME_SZ+1], inst[INST_SZ+1], realm[REALM_SZ+1];
+
+ aname[ANAME_SZ] = inst[INST_SZ] = realm[REALM_SZ] = 0;
+ retval = krb5_parse_name(ctx, name, &princ);
+ if (retval) {
+ com_err("krb5_parse_name", retval, 0);
+ goto fail;
+ }
+ retval = krb5_524_conv_principal(ctx, princ, aname, inst, realm);
+ if (retval) {
+ com_err("krb5_524_conv_principal", retval, 0);
+ goto fail;
+ }
+ printf("524_converted_principal(%s): '%s' '%s' '%s'\n",
+ name, aname, inst, realm);
+ fail:
+ if (princ)
+ krb5_free_principal (ctx, princ);
+}
+
void test_parse_name(ctx, name)
krb5_context ctx;
const char *name;
@@ -131,6 +158,7 @@ void usage(progname)
{
fprintf(stderr, "%s: Usage: %s 425_conv_principal <name> <inst> <realm\n",
progname, progname);
+ fprintf(stderr, "\t%s 524_conv_principal <name>\n", progname);
fprintf(stderr, "\t%s parse_name <name>\n", progname);
fprintf(stderr, "\t%s set_realm <name> <realm>\n", progname);
fprintf(stderr, "\t%s string_to_timestamp <time>\n", progname);
@@ -186,6 +214,10 @@ main(argc, argv)
argc--; argv++;
if (!argc) usage(progname);
test_string_to_timestamp(ctx, *argv);
+ } else if (strcmp(*argv, "524_conv_principal") == 0) {
+ argc--; argv++;
+ if (!argc) usage(progname);
+ test_524_conv_principal(ctx, *argv);
}
else
usage(progname);
diff --git a/src/lib/krb5/krb/t_krb5.conf b/src/lib/krb5/krb/t_krb5.conf
index 5882d97..8d7a4d9 100644
--- a/src/lib/krb5/krb/t_krb5.conf
+++ b/src/lib/krb5/krb/t_krb5.conf
@@ -19,6 +19,12 @@
kdc = KERBEROS.CYGNUS.COM
admin_server = KERBEROS.MIT.EDU
}
+ stanford.edu = {
+ v4_realm = IR.STANFORD.EDU
+ }
+ LONGNAMES.COM = {
+ v4_realm = SOME-REALLY-LONG-REALM-NAME-V4-CANNOT-HANDLE.COM
+ }
[domain_realm]
.mit.edu = ATHENA.MIT.EDU
diff --git a/src/lib/krb5/krb/t_ref_kerb.out b/src/lib/krb5/krb/t_ref_kerb.out
index 9423944..08a5334 100644
--- a/src/lib/krb5/krb/t_ref_kerb.out
+++ b/src/lib/krb5/krb/t_ref_kerb.out
@@ -14,4 +14,6 @@ parsed (and unparsed) principal(\/slash/\@atsign/octa\/thorpe@\/slash\@at\/sign)
425_converted principal(rcmd, uunet, UU.NET): 'host/uunet.uu.net@UU.NET'
425_converted principal(zephyr, zephyr, ATHENA.MIT.EDU): 'zephyr/zephyr@ATHENA.MIT.EDU'
425_converted principal(kadmin, ATHENA.MIT.EDU, ATHENA.MIT.EDU): 'kadmin/ATHENA.MIT.EDU@ATHENA.MIT.EDU'
+524_converted_principal(host/e40-po.mit.edu@ATHENA.MIT.EDU): 'rcmd' 'e40-po' 'ATHENA.MIT.EDU'
+524_converted_principal(host/foobar.stanford.edu@stanford.edu): 'rcmd' 'foobar' 'IR.STANFORD.EDU'
old principal: marc@MIT.EDU, modified principal: marc@CYGNUS.COM
diff --git a/src/lib/krb5/krb/unparse.c b/src/lib/krb5/krb/unparse.c
index f7df6ab..d0dfadc 100644
--- a/src/lib/krb5/krb/unparse.c
+++ b/src/lib/krb5/krb/unparse.c
@@ -70,6 +70,9 @@ krb5_unparse_name_ext(context, principal, name, size)
krb5_int32 nelem;
register int totalsize = 0;
+ if (!principal)
+ return KRB5_PARSE_MALFORMED;
+
cp = krb5_princ_realm(context, principal)->data;
length = krb5_princ_realm(context, principal)->length;
totalsize += length;
@@ -150,7 +153,8 @@ krb5_unparse_name_ext(context, principal, name, size)
*q++ = COMPONENT_SEP;
}
- q--; /* Back up last component separator */
+ if (i > 0)
+ q--; /* Back up last component separator */
*q++ = REALM_SEP;
cp = krb5_princ_realm(context, principal)->data;
diff --git a/src/lib/krb5/krb/vfy_increds.c b/src/lib/krb5/krb/vfy_increds.c
index 85a8465..f046ab5 100644
--- a/src/lib/krb5/krb/vfy_increds.c
+++ b/src/lib/krb5/krb/vfy_increds.c
@@ -109,7 +109,7 @@ krb5_verify_init_creds(krb5_context context,
(options->flags & KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL)) {
if (options->ap_req_nofail)
goto cleanup;
- } else if ((ret2 = krb5_appdefault_boolean(context,
+ } else if ((ret2 = krb5_libdefault_boolean(context,
&creds->client->realm,
"verify_ap_req_nofail",
&nofail))
diff --git a/src/lib/krb5/krb/walk_rtree.c b/src/lib/krb5/krb/walk_rtree.c
index 833ec61..163b7bb 100644
--- a/src/lib/krb5/krb/walk_rtree.c
+++ b/src/lib/krb5/krb/walk_rtree.c
@@ -93,6 +93,27 @@
#define max(x,y) ((x) > (y) ? (x) : (y))
#endif
+/*
+ * xxx The following function is very confusing to read and probably
+ * is buggy. It should be documented better. Here is what I've
+ * learned about it doing a quick bug fixing walk through. The
+ * function takes a client and server realm name and returns the set
+ * of realms (in a field called tree) that you need to get tickets in
+ * in order to get from the source realm to the destination realm. It
+ * takes a realm separater character (normally ., but presumably there
+ * for all those X.500 realms) . There are two modes it runs in: the
+ * ANL krb5.confmode and the hierarchy mode. The ANL mode is
+ * fairly obvious. The hierarchy mode looks for common components in
+ * both the client and server realms. In general, the pointer scp and
+ * ccp are used to walk through the client and server realms. The
+ * com_sdot and com_cdot pointers point to (I think) the beginning of
+ * the common part of the realm names. I.E. strcmp(com_cdot,
+ * com_sdot) ==0 is roughly an invarient. However, there are cases
+ * where com_sdot and com_cdot are set to point before the start of
+ * the client or server strings. I think this only happens when there
+ * are no common components. --hartmans 2002/03/14
+ */
+
krb5_error_code
krb5_walk_realm_tree(context, client, server, tree, realm_branch_char)
krb5_context context;
@@ -115,6 +136,10 @@ krb5_walk_realm_tree(context, client, server, tree, realm_branch_char)
char *cap_client, *cap_server;
char **cap_nodes;
krb5_error_code cap_code;
+#endif
+ if (!(client->data &&server->data))
+ return KRB5_NO_TKT_IN_RLM;
+#ifdef CONFIGURABLE_AUTHENTICATION_PATH
if ((cap_client = (char *)malloc(client->length + 1)) == NULL)
return ENOMEM;
strncpy(cap_client, client->data, client->length);
diff --git a/src/lib/krb5/krb5_libinit.c b/src/lib/krb5/krb5_libinit.c
index beeb06d..547be4d 100644
--- a/src/lib/krb5/krb5_libinit.c
+++ b/src/lib/krb5/krb5_libinit.c
@@ -1,5 +1,9 @@
#include <assert.h>
+#if TARGET_OS_MAC
+ #include <Kerberos/com_err.h>
+#endif
+
#include "krb5.h"
#include "krb5_err.h"
#include "kv5m_err.h"
@@ -16,10 +20,12 @@ krb5_error_code krb5int_initialize_library (void)
{
if (!initialized) {
+#if !TARGET_OS_MAC || USE_HARDCODED_FALLBACK_ERROR_TABLES
add_error_table(&et_krb5_error_table);
add_error_table(&et_kv5m_error_table);
add_error_table(&et_kdb5_error_table);
add_error_table(&et_asn1_error_table);
+#endif
initialized = 1;
}
@@ -35,14 +41,16 @@ void krb5int_cleanup_library (void)
{
assert (initialized);
-#if defined(_MSDOS) || defined(_WIN32) || defined(macintosh)
+#if defined(_MSDOS) || defined(_WIN32) || TARGET_OS_MAC
krb5_stdcc_shutdown();
#endif
+#if !TARGET_OS_MAC || USE_HARDCODED_FALLBACK_ERROR_TABLES
remove_error_table(&et_krb5_error_table);
remove_error_table(&et_kv5m_error_table);
remove_error_table(&et_kdb5_error_table);
remove_error_table(&et_asn1_error_table);
+#endif
initialized = 0;
}
diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog
index 8f8c018..ee721ce 100644
--- a/src/lib/krb5/os/ChangeLog
+++ b/src/lib/krb5/os/ChangeLog
@@ -1,3 +1,212 @@
+2002-10-31 Tom Yu <tlyu@mit.edu>
+
+ * hst_realm.c (krb5_try_realm_txt_rr): Apply patch from Nalin
+ Dahyabhai to bounds-check return value from res_search().
+
+ * locate_kdc.c (krb5_locate_srv_dns_1): Apply patch from Nalin
+ Dahyabhai to bounds-check return value from res_search().
+
+ [pullups from trunk]
+
+2002-05-24 Alexandra Ellwood <lxs@mit.edu>
+ * init_os_ctx.c: krb4 needs to get the os config files so it can use
+ the profile too. Define these functions on Mac OS X now.
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * init_os_ctx.c: Removed use of FSSpecs because these cause serious
+ performance problems on Mac OS X. We now search paths the same way
+ the rest of the Unix platforms do.
+
+2002-04-05 Danilo Almeida <dalmeida@mit.edu>
+
+ * toffset.c (krb5_get_time_offsets), an_to_ln.c
+ (krb5_aname_to_localname): Make KRB5_CALLCONV.
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * init_os_ctx.c: Add CoreServices.h before k5-int.h so we don't get
+ multiple definitions for FSSpec. Also removed an unused variable in
+ Mac OS X code and added casts for Mac OS X code so FSSpecs are cast
+ to profile file types (code deals properly on the other side)
+ * timeofday.c: Added casts to remove warnings
+
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * ccdefname.c, init_os_ctx.c, timeofday.c: Updated Mac OS X headers to new
+ framework layout and updated Mac OS macros
+ * changepw.c: removed unused variable
+ * gmt_mktime.c: added int to removed warning about type defaulting to int
+
+2002-01-29 Tom Yu <tlyu@mit.edu>
+
+ * def_realm.c: Add terminal newline. Fixes [krb5-build/1041].
+
+2001-12-03 Miro Jurisic <meeroh@mit.edu>
+
+ * c_ustime.c: punted the accurate microseconds timing code because it
+ wasn't so accurate after all.
+
+2000-11-27 Alexandra Ellwood <lxs@mit.edu>
+
+ * read_pwd.c: Removed #defines for Mac OS X (__MACH__) because we
+ now export krb5_read_password on Mac OS X
+
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * localaddr.c: Fixed typo.
+ * localaddr.c: Added a special krb5_os_localaddr for Mac OS 9
+ which looks up the addresses without querying DNS synchronously
+ * prompter.c, promptusr.c, read_pwd.c: We now export
+ krb5_prompter_posix and krb5_read_password on Mac OS X
+ * c_us_time.c: Updated Utilities.h #include
+ * c_us_time.c: Fix the sleep queue notification code to
+ only run on machines with power management
+ * ccdefname.c, init_os_ctx.c: Updated Mac OS #defines and #includes
+ for new header layout and Mac OS X frameworks
+
+2001-02-05 Tom Yu <tlyu@mit.edu>
+
+ * prompter.c (krb5_prompter_posix): Fix up terminal modes if we're
+ interrupted. [reported by Booker Bense] [pullup from trunk]
+
+2001-02-02 Ken Raeburn <raeburn@mit.edu>
+
+ * localaddr.c (foreach_localaddr): Increase buffer space initially
+ allocated. Add more slop space at the end that must remain unused
+ before we stop growing the buffer. Impose a maximum size on the
+ buffer. Handle possibility of returned ifc_len being larger than
+ the supplied buffer.
+
+2001-01-30 Ken Raeburn <raeburn@mit.edu>
+
+ * changepw.c (fixup_ports): New function, uses correct level of
+ indirection for elements of socket address array.
+ (krb5_locate_kpasswd): Call fixup_ports.
+
+2001-01-24 Miro Jurisic <meeroh@mit.edu>
+
+ * c_us_time.c: Fix the sleep queue notification code to
+ avoid denying sleep requests
+
+2000-12-19 Miro Jurisic <meeroh@mit.edu>
+
+ * c_us_time.c: Fix the sleep queue notification code to
+ build with Universal Headers 3.3
+
+2000-11-29 Miro Jurisic <meeroh@mit.edu>
+
+ * c_us_time.c: Install a callback in the Mac OS sleep
+ queue to get notification of the machine coming out
+ of sleep, in order to refresh the cached uptime to
+ real time offset
+
+2000-10-28 Miro Jurisic <meeroh@mit.edu>
+
+ * c_ustime.c: Fixed epoch calculation under Mac OS 9 Carbon and Mac OS X
+
+2000-10-16 Miro Jurisic <meeroh@mit.edu>
+
+ * init_os_ctx.c: Use PreferencesLib to discover config files on Mac OS X
+
+2000-10-02 Alexandra Ellwood <lxs@mit.edu>
+
+ * ccdefname.c, init_os_ctx.c, prompter.c, prompterusr.c. read_pwd.c
+ timeofday.c: Added #defines for Mac OS X (__MACH__) to mimic macintosh
+ behavior
+
+2000-09-28 Miro Jurisic <meeroh@mit.edu>
+
+ * c_us_time.c: Fixed Mac code to use the correct epoch
+
+2000-09-23 Miro Jurisic <meeroh@mit.edu>
+
+ * c_us_time.c: Added modifications to Mac OS Microseconds timing
+ to work properly under Carbon.
+
+2000-06-19 Ken Raeburn <raeburn@mit.edu>
+
+ * localaddr.c (foreach_localaddr): Use SIOCGSIZIFCONF ioctl if
+ available to get the buffer size needed for SIOCGIFCONF, and skip
+ the silly heuristics if it returns a reasonable value.
+
+2000-06-14 Miro Jurisic <meeroh@mit.edu>
+
+ * init_os_ctx.c (os_get_default_config_files):
+ Return ENOENT when file is not found on MacOS (not ENFILE)
+
+2000-06-09 Miro Jurisic <meeroh@mit.edu>
+
+ * init_os_ctx.c (os_get_default_config_files):
+ Eliminated some dead code
+
+2000-06-09 Miro Jurisic <meeroh@mit.edu>
+
+ * init_os_ctx.c (os_get_default_config_files): Use Kerberos
+ Preferences library to locate the config files on Mac OS
+
+2000-05-17 Nalin Dahyabhai <nalin@redhat.com>
+
+ * an_to_ln.c (do_replacement): Don't overflow buffers "in" or "out".
+ * hst_realm.c (krb5_try_realm_txt_rr): Don't overfill "host" when
+ malformed DNS responses are received.
+
+2000-05-15 Jeffrey Altman <jaltman@columbia.edu>
+
+ * hst_realm.c (krb5_get_host_realm)
+ remove the searchlist and defaultrealm _kerberos queries
+
+2000-05-09 Alexandra Ellwood <lxs@mit.edu>
+
+ *localaddr.c: Fixed the local_addr_fallback_kludge so that it actually does something.
+ Before that the error code it was handling was blowing it away in cleanup.
+
+2000-04-28 Nalin Dahyabhai <nalin@redhat.com>
+
+ * ccdefname.c (get_from_os): Don't overflow buffer "name_buf".
+ * kuserok.c (krb5_kuserok): Don't overflow buffer "pbuf".
+
+2000-04-22 Ken Raeburn <raeburn@mit.edu>
+
+ * localaddr.c: Include stddef.h.
+ (foreach_localaddr): Check each address against previously used
+ addresses, and skip duplicates, in case multiple interfaces have
+ the same address. If called functions fail, drop out of loop and
+ return nonzero.
+ (krb5_os_localaddr): Increment count of addresses to include null
+ pointer terminator. Delete check for zero count.
+
+2000-04-18 Danilo Almeida <dalmeida@mit.edu>
+
+ * prompter.c (krb5int_set_prompt_types): Set to actual value
+ intead of 0.
+
+2000-4-13 Alexandra Ellwood <lxs@mit.edu>
+
+ * init_os_ctx.c: Added support to store a krb5_principal in the os_context
+ along with the default ccache name (if known, this principal is the same
+ as the last time we looked at the ccache.
+ * ccdefname.c: Added support to store a krb5_principal in the os_context
+ along with the default ccache name (if known, this principal is the same
+ as the last time we looked at the ccache.
+
+2000-04-04 Ken Raeburn <raeburn@mit.edu>
+
+ * locate_kdc.c (maybe_use_dns): Renamed from _krb5_use_dns. Now
+ takes an arg to indicate a key to look up in krb5.conf, falling
+ back to "dns_fallback", and an arg indicating the default value if
+ no config file entries match.
+ (_krb5_use_dns_realm): New routine; use "dns_lookup_realm" and
+ KRB5_DNS_LOOKUP_REALM setting.
+ (_krb5_use_dns_kdc): New routine; use "dns_lookup_kdc" and
+ KRB5_DNS_LOOKUP_KDC.
+ (krb5_locate_kdc): Call _krb5_use_dns_kdc.
+ * changepw.c (krb5_locate_kpasswd): Call _krb5_use_dns_kdc.
+ * def_realm.c (krb5_get_default_realm): Call _krb5_use_dns_realm.
+ * hst_realm.c (krb5_get_host_realm): Call _krb5_use_dns_realm.
+
+2000-03-20 Miro Jurisic <meeroh@mit.edu>
+
+ * def_realm.c (krb5_free_default_realm): Added, use to free
+ result of krb5_get_default_realm
+
2000-03-15 Danilo Almeida <dalmeida@mit.edu>
* prompter.c: Add krb5int_set_prompt_types() and
diff --git a/src/lib/krb5/os/an_to_ln.c b/src/lib/krb5/os/an_to_ln.c
index 3c721fb..df4b5d5 100644
--- a/src/lib/krb5/os/an_to_ln.c
+++ b/src/lib/krb5/os/an_to_ln.c
@@ -298,15 +298,15 @@ do_replacement(regexp, repl, doall, in, out)
strncpy(op, cp, match_match.rm_so);
op += match_match.rm_so;
}
- strcpy(op, repl);
- op += strlen(repl);
+ strncpy(op, repl, MAX_FORMAT_BUFFER - 1 - (op - out));
+ op += strlen(op);
cp += match_match.rm_eo;
if (!doall)
- strcpy(op, cp);
+ strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out));
matched = 1;
}
else {
- strcpy(op, cp);
+ strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out));
matched = 0;
}
} while (doall && matched);
@@ -333,20 +333,20 @@ do_replacement(regexp, repl, doall, in, out)
strncpy(op, cp, sdispl);
op += sdispl;
}
- strcpy(op, repl);
+ strncpy(op, repl, MAX_FORMAT_BUFFER - 1 - (op - out));
op += strlen(repl);
cp += edispl;
if (!doall)
- strcpy(op, cp);
+ strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out));
matched = 1;
}
else {
- strcpy(op, cp);
+ strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out));
matched = 0;
}
} while (doall && matched);
#else /* HAVE_REGEXP_H */
- strcpy(out, in);
+ memcpy(out, in, MAX_FORMAT_BUFFER);
#endif /* HAVE_REGCOMP */
}
@@ -379,7 +379,8 @@ aname_replacer(string, contextp, result)
* Prime the buffers. Copy input string to "out" to simulate it
* being the result of an initial iteration.
*/
- strcpy(out, string);
+ strncpy(out, string, MAX_FORMAT_BUFFER - 1);
+ out[MAX_FORMAT_BUFFER - 1] = '\0';
in[0] = '\0';
kret = 0;
/*
@@ -421,6 +422,7 @@ aname_replacer(string, contextp, result)
out = ep;
/* Do the replacemenbt */
+ memset(out, '\0', MAX_FORMAT_BUFFER);
do_replacement(rule, repl, doglobal, in, out);
free(rule);
free(repl);
@@ -651,7 +653,7 @@ default_an_to_ln(context, aname, lnsize, lname)
returns system errors, NOT_ENOUGH_SPACE
*/
-krb5_error_code
+krb5_error_code KRB5_CALLCONV
krb5_aname_to_localname(context, aname, lnsize, lname)
krb5_context context;
krb5_const_principal aname;
diff --git a/src/lib/krb5/os/c_ustime.c b/src/lib/krb5/os/c_ustime.c
index 5f73587..d294e01 100644
--- a/src/lib/krb5/os/c_ustime.c
+++ b/src/lib/krb5/os/c_ustime.c
@@ -51,12 +51,17 @@
#include <DriverServices.h> /* Nanosecond timing */
#include <CodeFragments.h> /* Check for presence of UpTime */
#include <Math64.h> /* 64-bit integer math */
+#include <KerberosSupport/Utilities.h> /* Mac time -> UNIX time conversion */
+#include <Power.h> /* Sleep queue */
/* Mac Cincludes */
#include <string.h>
#include <stddef.h>
static krb5_int32 last_sec = 0, last_usec = 0;
+static int gResetCachedDifference = 0;
+static SleepQRec gSleepQRecord;
+static SleepQUPP gSleepQUPP;
/* Check for availability of microseconds or better timer */
Boolean HaveAccurateTime ();
@@ -68,6 +73,21 @@ void AbsoluteToSecsNanosecs (
UInt32 *residualNanoseconds /* Fractional second */
);
+/* Convert Microseconds to date and time */
+void MicrosecondsToSecsMicrosecs (
+ UnsignedWide eventTime, /* Value to convert */
+ UInt32 *eventSeconds, /* Result goes here */
+ UInt32 *residualMicroseconds /* Fractional second */
+ );
+
+/* Sleep notification callback in needed to reset cached
+difference when the machine goes to sleep */
+void InstallSleepNotification ();
+void RemoveSleepNotification ();
+pascal long SleepNotification (
+ SInt32 message,
+ SleepQRecPtr qRecPtr);
+
/*
* The Unix epoch is 1/1/70, the Mac epoch is 1/1/04.
*
@@ -101,14 +121,6 @@ getTimeZoneOffset()
/* Returns the GMT in seconds (and fake microseconds) using the Unix epoch */
-/*
- * Note that unix timers are guaranteed that consecutive calls to timing functions will
- * always return monotonically increasing values for time; even if called within one microsecond,
- * they must increase from one call to another. We must preserve this property in this code,
- * even though Mac UpTime does not make such guarantees... (actually it does, but it measures in
- * units that can be finer than 1 microsecond, so conversion can cause repeat microsecond values
- */
-
krb5_error_code
krb5_crypto_us_timeofday(seconds, microseconds)
krb5_int32 *seconds, *microseconds;
@@ -116,34 +128,13 @@ krb5_crypto_us_timeofday(seconds, microseconds)
krb5_int32 sec, usec;
time_t the_time;
- GetDateTime (&the_time);
-
- sec = the_time -
- ((66 * 365 * 24 * 60 * 60) + (17 * 24 * 60 * 60) +
- (getTimeZoneOffset() * 60 * 60));
-
-#if TARGET_CPU_PPC /* Only PPC has accurate time */
- if (HaveAccurateTime ()) { /* Does hardware support accurate time? */
-
- AbsoluteTime absoluteTime;
- UInt32 nanoseconds;
-
- absoluteTime = UpTime ();
- AbsoluteToSecsNanosecs (absoluteTime, &sec, &nanoseconds);
-
- usec = nanoseconds / 1000;
- } else
-#endif /* TARGET_CPU_PPC */
- {
- GetDateTime (&sec);
- usec = 0;
- }
+ GetDateTime (&sec);
+ usec = 0;
/* Fix secs to UNIX epoch */
- sec -= ((66 * 365 * 24 * 60 * 60) + (17 * 24 * 60 * 60) +
- (getTimeZoneOffset() * 60 * 60));
-
+ mac_time_to_unix_time (&sec);
+
/* Make sure that we are _not_ repeating */
if (sec < last_sec) { /* Seconds should be at least equal to last seconds */
@@ -170,90 +161,6 @@ krb5_crypto_us_timeofday(seconds, microseconds)
return 0;
}
-/* Check if we have microsecond or better timer */
-
-Boolean HaveAccurateTime ()
-{
- static Boolean alreadyChecked = false;
- static haveAccurateTime = false;
-
- if (!alreadyChecked) {
- alreadyChecked = true;
- haveAccurateTime = false;
-#if TARGET_CPU_PPC
- if ((Ptr) UpTime != (Ptr) kUnresolvedCFragSymbolAddress) {
- UInt32 minAbsoluteTimeDelta;
- UInt32 theAbsoluteTimeToNanosecondNumerator;
- UInt32 theAbsoluteTimeToNanosecondDenominator;
- UInt32 theProcessorToAbsoluteTimeNumerator;
- UInt32 theProcessorToAbsoluteTimeDenominator;
-
- GetTimeBaseInfo (
- &minAbsoluteTimeDelta,
- &theAbsoluteTimeToNanosecondNumerator,
- &theAbsoluteTimeToNanosecondDenominator,
- &theProcessorToAbsoluteTimeNumerator,
- &theProcessorToAbsoluteTimeDenominator);
-
- /* minAbsoluteTimeDelta is the period in which Uptime is updated, in absolute time */
- /* We convert it to nanoseconds and compare it with .5 microsecond */
-
- if (minAbsoluteTimeDelta * theAbsoluteTimeToNanosecondNumerator <
- 500 * theAbsoluteTimeToNanosecondDenominator) {
- haveAccurateTime = true;
- }
- }
-#endif /* TARGET_CPU_PPC */
- }
-
- return haveAccurateTime;
-}
-
-/* Convert nanoseconds to date and time */
-
-void AbsoluteToSecsNanosecs (
- AbsoluteTime eventTime, /* Value to convert */
- UInt32 *eventSeconds, /* Result goes here */
- UInt32 *residualNanoseconds /* Fractional second */
- )
-{
- UInt64 eventNanoseconds;
- UInt64 eventSeconds64;
- static const UInt64 kTenE9 = U64SetU (1000000000);
- static UInt64 gNanosecondsAtStart = U64SetU (0);
-
- /*
- * If this is the first call, compute the offset between
- * GetDateTime and UpTime.
- */
- if (U64Compare (gNanosecondsAtStart, U64SetU (0)) == 0) {
- UInt32 secondsAtStart;
- AbsoluteTime absoluteTimeAtStart;
- UInt64 upTimeAtStart;
- UInt64 nanosecondsAtStart;
-
- GetDateTime (&secondsAtStart);
- upTimeAtStart = UnsignedWideToUInt64 (AbsoluteToNanoseconds (UpTime()));
- nanosecondsAtStart = U64SetU (secondsAtStart);
- nanosecondsAtStart = U64Multiply (nanosecondsAtStart, kTenE9);
- gNanosecondsAtStart = U64Subtract (nanosecondsAtStart, upTimeAtStart);
- }
- /*
- * Convert the event time (UpTime value) to nanoseconds and add
- * the local time epoch.
- */
- eventNanoseconds = UnsignedWideToUInt64 (AbsoluteToNanoseconds (eventTime));
- eventNanoseconds = U64Add (gNanosecondsAtStart, eventNanoseconds);
- /*
- * eventSeconds = eventNanoseconds /= 10e9;
- * residualNanoseconds = eventNanoseconds % 10e9;
- * Finally, compute the local time (seconds) and fraction.
- */
- eventSeconds64 = U64Div (eventNanoseconds, kTenE9);
- eventNanoseconds = U64Subtract (eventNanoseconds, U64Multiply (eventSeconds64, kTenE9));
- *eventSeconds = (UInt64ToUnsignedWide (eventSeconds64)).lo;
- *residualNanoseconds = (UInt64ToUnsignedWide (eventNanoseconds)).lo;
-}
#elif defined(_WIN32)
/* Microsoft Windows NT and 95 (32bit) */
diff --git a/src/lib/krb5/os/ccdefname.c b/src/lib/krb5/os/ccdefname.c
index 53e7888..76c7528 100644
--- a/src/lib/krb5/os/ccdefname.c
+++ b/src/lib/krb5/os/ccdefname.c
@@ -31,8 +31,8 @@
#include "k5-int.h"
#include <stdio.h>
-#ifdef macintosh
-#include "CCache.h"
+#if TARGET_OS_MAC
+#include <Kerberos/CredentialsCache.h>
#endif
#if defined(_WIN32)
@@ -160,7 +160,7 @@ static krb5_error_code get_from_os(char *name_buf, int name_size)
if (get_from_registry_indirect(name_buf, name_size) != 0)
return 0;
- strncpy(name_buf, prefix, name_size);
+ strncpy(name_buf, prefix, name_size - 1);
name_buf[name_size - 1] = 0;
size = name_size - strlen(prefix);
if (size > 0)
@@ -186,7 +186,7 @@ static krb5_error_code get_from_os(char *name_buf, int name_size)
}
#endif
-#if defined (macintosh)
+#if TARGET_OS_MAC
static krb5_error_code get_from_os(char *name_buf, int name_size)
{
@@ -261,6 +261,13 @@ krb5_cc_set_default_name(context, name)
return ENOMEM;
strcpy(new_name, name_buf);
+ if (!os_ctx->default_ccname || (strcmp(os_ctx->default_ccname, new_name) != 0)) {
+ /* the ccache changed... forget the old principal */
+ if (os_ctx->default_ccprincipal)
+ krb5_free_principal (context, os_ctx->default_ccprincipal);
+ os_ctx->default_ccprincipal = 0; /* we don't care until we use it */
+ }
+
if (os_ctx->default_ccname)
free(os_ctx->default_ccname);
diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c
index 6ed95bc..44161d6 100644
--- a/src/lib/krb5/os/changepw.c
+++ b/src/lib/krb5/os/changepw.c
@@ -52,45 +52,50 @@
* Wrapper function for the two backends
*/
+static void
+fixup_ports (struct sockaddr *addr_p, int naddrs, int port)
+{
+ /* Ick: In this version of krb5_locate_foo, we have a pointer to a
+ pointer to an array of sockaddr_in structures -- NOT an array
+ of pointers like we should have. */
+ int i;
+ port = htons (port);
+ if (addr_p->sa_family != AF_INET)
+ abort ();
+ for (i = 0; i < naddrs; i++) {
+ struct sockaddr_in *sinp = (struct sockaddr_in *) &addr_p[i];
+ sinp->sin_port = port;
+ }
+}
+
static krb5_error_code
-krb5_locate_kpasswd(context, realm, addr_pp, naddrs, master_index, nmasters)
+krb5_locate_kpasswd(context, realm, addr_pp, naddrs)
krb5_context context;
const krb5_data *realm;
struct sockaddr **addr_pp;
int *naddrs;
- int *master_index;
- int *nmasters;
{
krb5_error_code code;
- int i;
-#ifdef KRB5_DNS_LOOKUP
- struct sockaddr *admin_addr_p, *kdc_addr_p;
- int nadmin_addrs, nkdc_addrs;
- int j;
-#endif /* KRB5_DNS_LOOKUP */
/*
* We always try the local file first
*/
- code = krb5_locate_srv_conf(context, realm, "kpasswd_server", addr_pp, naddrs,
- master_index, nmasters);
+ code = krb5_locate_srv_conf(context, realm, "kpasswd_server",
+ addr_pp, naddrs, 0);
if (code) {
- code = krb5_locate_srv_conf(context, realm, "admin_server", addr_pp, naddrs,
- master_index, nmasters);
+ code = krb5_locate_srv_conf(context, realm, "admin_server",
+ addr_pp, naddrs, 0);
if ( !code ) {
- /* success with admin_server but now we need to change the port */
- /* number to use DEFAULT_KPASSWD_PORT. */
- for ( i=0;i<*naddrs;i++ ) {
- struct sockaddr_in *sin = (struct sockaddr_in *) addr_pp[i];
- sin->sin_port = htons(DEFAULT_KPASSWD_PORT);
- }
+ /* Success with admin_server but now we need to change the
+ port number to use DEFAULT_KPASSWD_PORT. */
+ fixup_ports (*addr_pp, *naddrs, DEFAULT_KPASSWD_PORT);
}
}
#ifdef KRB5_DNS_LOOKUP
if (code) {
- int use_dns = _krb5_use_dns(context);
+ int use_dns = _krb5_use_dns_kdc(context);
if ( use_dns ) {
code = krb5_locate_srv_dns(realm, "_kpasswd", "_udp",
addr_pp, naddrs);
@@ -100,18 +105,12 @@ krb5_locate_kpasswd(context, realm, addr_pp, naddrs, master_index, nmasters)
"_tcp",
addr_pp, naddrs);
if ( !code ) {
- /* success with admin_server but now we need to change the port */
- /* number to use DEFAULT_KPASSWD_PORT. */
- for ( i=0;i<*naddrs;i++ ) {
- struct sockaddr_in *sin = (struct sockaddr_in *) addr_pp[i];
- sin->sin_port = htons(DEFAULT_KPASSWD_PORT);
- }
+ /* Success with admin_server but now we need to
+ change the port number to use
+ DEFAULT_KPASSWD_PORT. */
+ fixup_ports (*addr_pp, *naddrs, DEFAULT_KPASSWD_PORT);
}
}
- if ( !code && master_index && nmasters ) {
- *master_index = 1;
- *nmasters = *naddrs;
- }
}
}
#endif /* KRB5_DNS_LOOKUP */
@@ -158,7 +157,7 @@ krb5_change_password(context, creds, newpw, result_code,
if (code = krb5_locate_kpasswd(context,
krb5_princ_realm(context, creds->client),
- &addr_p, &naddr_p,NULL,NULL))
+ &addr_p, &naddr_p))
goto cleanup;
/* this is really obscure. s1 is used for all communications. it
diff --git a/src/lib/krb5/os/def_realm.c b/src/lib/krb5/os/def_realm.c
index 8647f89..b2a9e1d 100644
--- a/src/lib/krb5/os/def_realm.c
+++ b/src/lib/krb5/os/def_realm.c
@@ -24,7 +24,8 @@
* or implied warranty.
*
*
- * krb5_get_default_realm() function.
+ * krb5_get_default_realm(), krb5_set_default_realm(),
+ * krb5_free_default_realm() functions.
*/
#include "k5-int.h"
@@ -103,7 +104,7 @@ krb5_get_default_realm(context, lrealm)
#ifdef KRB5_DNS_LOOKUP
if (context->default_realm == 0) {
- int use_dns = _krb5_use_dns(context);
+ int use_dns = _krb5_use_dns_realm(context);
if ( use_dns ) {
/*
* Since this didn't appear in our config file, try looking
@@ -202,3 +203,11 @@ krb5_set_default_realm(context, lrealm)
return(0);
}
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_free_default_realm(context, lrealm)
+ krb5_context context;
+ char FAR* lrealm;
+{
+ free (lrealm);
+}
diff --git a/src/lib/krb5/os/gmt_mktime.c b/src/lib/krb5/os/gmt_mktime.c
index b231790..1e3eebd 100644
--- a/src/lib/krb5/os/gmt_mktime.c
+++ b/src/lib/krb5/os/gmt_mktime.c
@@ -19,7 +19,7 @@
/* like mktime, this ignores tm_wday and tm_yday. */
/* unlike mktime, this does not set them... it only passes a return value. */
-static const days_in_month[12] = {
+static const int days_in_month[12] = {
0, /* jan 31 */
31, /* feb 28 */
59, /* mar 31 */
diff --git a/src/lib/krb5/os/hst_realm.c b/src/lib/krb5/os/hst_realm.c
index 3c0005c..6aa3083 100644
--- a/src/lib/krb5/os/hst_realm.c
+++ b/src/lib/krb5/os/hst_realm.c
@@ -117,6 +117,8 @@ krb5_try_realm_txt_rr(prefix, name, realm)
*/
if (name == NULL || name[0] == '\0') {
+ if (strlen (prefix) >= sizeof(host)-1)
+ return KRB5_ERR_HOST_REALM_UNKNOWN;
strcpy(host,prefix);
} else {
if ( strlen(prefix) + strlen(name) + 3 > MAX_DNS_NAMELEN )
@@ -134,12 +136,12 @@ krb5_try_realm_txt_rr(prefix, name, realm)
*/
h = host + strlen (host);
- if (h > host && h[-1] != '.')
+ if ((h > host) && (h[-1] != '.') && ((h - host + 1) < sizeof(host)))
strcpy (h, ".");
}
size = res_search(host, C_IN, T_TXT, answer.bytes, sizeof(answer.bytes));
- if (size < 0)
+ if ((size < sizeof(HEADER)) || (size > sizeof(answer.bytes)))
return KRB5_ERR_HOST_REALM_UNKNOWN;
p = answer.bytes;
@@ -312,7 +314,7 @@ krb5_get_host_realm(context, host, realmsp)
#ifdef KRB5_DNS_LOOKUP
if (realm == (char *)NULL) {
- int use_dns = _krb5_use_dns(context);
+ int use_dns = _krb5_use_dns_realm(context);
if ( use_dns ) {
/*
* Since this didn't appear in our config file, try looking
@@ -330,17 +332,6 @@ krb5_get_host_realm(context, host, realmsp)
if (cp)
cp++;
} while (retval && cp && cp[0]);
- if (retval)
- retval = krb5_try_realm_txt_rr("_kerberos", "", &realm);
- if (retval && default_realm) {
- cp = default_realm;
- do {
- retval = krb5_try_realm_txt_rr("_kerberos", cp, &realm);
- cp = strchr(cp,'.');
- if (cp)
- cp++;
- } while (retval && cp && cp[0]);
- }
}
}
#endif /* KRB5_DNS_LOOKUP */
diff --git a/src/lib/krb5/os/init_os_ctx.c b/src/lib/krb5/os/init_os_ctx.c
index 48d8bc2..7cc456c 100644
--- a/src/lib/krb5/os/init_os_ctx.c
+++ b/src/lib/krb5/os/init_os_ctx.c
@@ -27,26 +27,8 @@
*/
#define NEED_WINDOWS
-#include "k5-int.h"
-
-#ifdef macintosh
-OSErr
-GetMacProfileFileSpec (FSSpec* outFileSpec, StringPtr inName, UInt32 whichFolder)
-{
- OSErr err;
-
-
-
- err = FindFolder (kOnSystemDisk, whichFolder, kCreateFolder,
- &(outFileSpec -> vRefNum) , &(outFileSpec -> parID));
-
- if (err == noErr) {
- BlockMoveData (inName, &(outFileSpec -> name), strlen (inName) + 1);
- }
- return err;
-}
-#endif /* macintosh */
+#include "k5-int.h"
#if defined(_MSDOS) || defined(_WIN32)
@@ -185,7 +167,7 @@ static void
free_filespecs(files)
profile_filespec_t *files;
{
-#ifndef macintosh
+#if !TARGET_OS_MAC
char **cp;
if (files == 0)
@@ -203,44 +185,6 @@ os_get_default_config_files(pfiles, secure)
krb5_boolean secure;
{
profile_filespec_t* files;
-#ifdef macintosh
- files = malloc(7 * sizeof(FSSpec));
-
- if (files != 0) {
- OSErr err = GetMacProfileFileSpec(&(files [3]), "\pKerberos Preferences", kApplicationSupportFolderType);
- if (err == noErr) {
- err = GetMacProfileFileSpec( &(files [4]), "\pkrb5.ini", kApplicationSupportFolderType);
- }
- if (err == noErr) {
- err = GetMacProfileFileSpec( &(files [5]), "\pKerberos5 Configuration", kApplicationSupportFolderType);
- }
-
- if (err == noErr) {
- files[6].vRefNum = 0;
- files[6].parID = 0;
- files[6].name[0] = '\0';
- } else {
- files[3].vRefNum = 0;
- files[3].parID = 0;
- files[3].name[0] = '\0';
- }
-
- err = GetMacProfileFileSpec(&(files [0]), "\pKerberos Preferences", kPreferencesFolderType);
- if (err == noErr) {
- err = GetMacProfileFileSpec( &(files [1]), "\pkrb5.ini", kPreferencesFolderType);
- }
- if (err == noErr) {
- err = GetMacProfileFileSpec( &(files [2]), "\pKerberos5 Configuration", kPreferencesFolderType);
- }
-
- if (err != noErr) {
- free (files);
- return ENFILE;
- }
- } else {
- return ENOMEM;
- }
-#else /* !macintosh */
#if defined(_MSDOS) || defined(_WIN32)
krb5_error_code retval = 0;
char *name = 0;
@@ -327,8 +271,7 @@ os_get_default_config_files(pfiles, secure)
/* cap the array */
files[i] = 0;
#endif /* !_MSDOS && !_WIN32 */
-#endif /* !macintosh */
- *pfiles = files;
+ *pfiles = (profile_filespec_t *)files;
return 0;
}
@@ -349,10 +292,11 @@ os_init_paths(ctx)
#endif /* KRB5_DNS_LOOKUP */
retval = os_get_default_config_files(&files, secure);
-
+
if (!retval) {
retval = profile_init((const_profile_filespec_t *) files,
&ctx->profile);
+
#ifdef KRB5_DNS_LOOKUP
/* if none of the filenames can be opened use an empty profile */
if (retval == ENOENT) {
@@ -404,6 +348,7 @@ krb5_os_init_context(ctx)
os_ctx->usec_offset = 0;
os_ctx->os_flags = 0;
os_ctx->default_ccname = 0;
+ os_ctx->default_ccprincipal = 0;
krb5_cc_set_default_name(ctx, NULL);
@@ -427,8 +372,10 @@ krb5_get_profile (ctx, profile)
retval = os_get_default_config_files(&files, ctx->profile_secure);
- if (!retval)
- retval = profile_init((const_profile_filespec_t *) files, profile);
+ if (!retval) {
+ retval = profile_init((const_profile_filespec_t *) files,
+ profile);
+ }
if (files)
free_filespecs(files);
@@ -446,7 +393,6 @@ krb5_get_profile (ctx, profile)
return retval;
}
-#ifndef macintosh
krb5_error_code
krb5_set_config_files(ctx, filenames)
@@ -483,7 +429,6 @@ krb5_free_config_files(filenames)
free_filespecs(filenames);
}
-#endif /* macintosh */
krb5_error_code
krb5_secure_config_files(ctx)
@@ -524,6 +469,11 @@ krb5_os_free_context(ctx)
os_ctx->default_ccname = 0;
}
+ if (os_ctx->default_ccprincipal) {
+ krb5_free_principal (ctx, os_ctx->default_ccprincipal);
+ os_ctx->default_ccprincipal = 0;
+ }
+
os_ctx->magic = 0;
free(os_ctx);
ctx->os_context = 0;
diff --git a/src/lib/krb5/os/kuserok.c b/src/lib/krb5/os/kuserok.c
index ef08037..6d2adb1 100644
--- a/src/lib/krb5/os/kuserok.c
+++ b/src/lib/krb5/os/kuserok.c
@@ -80,8 +80,9 @@ krb5_kuserok(context, principal, luser)
if ((pwd = getpwnam(luser)) == NULL) {
return(FALSE);
}
- (void) strcpy(pbuf, pwd->pw_dir);
- (void) strcat(pbuf, "/.k5login");
+ (void) strncpy(pbuf, pwd->pw_dir, sizeof(pbuf) - 1);
+ pbuf[sizeof(pbuf) - 1] = '\0';
+ (void) strncat(pbuf, "/.k5login", sizeof(pbuf) - 1 - strlen(pbuf));
if (access(pbuf, F_OK)) { /* not accessible */
/*
diff --git a/src/lib/krb5/os/localaddr.c b/src/lib/krb5/os/localaddr.c
index 9079500..aaeade6 100644
--- a/src/lib/krb5/os/localaddr.c
+++ b/src/lib/krb5/os/localaddr.c
@@ -1,7 +1,7 @@
/*
* lib/krb5/os/localaddr.c
*
- * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,2000 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -39,6 +39,7 @@
#include <sys/ioctl.h>
#include <sys/time.h>
#include <errno.h>
+#include <stddef.h>
/*
* The SIOCGIF* ioctls require a socket.
@@ -248,6 +249,45 @@ add_addr (void *P_data, struct sockaddr *a)
#define ifreq_size(i) sizeof(struct ifreq)
#endif /* HAVE_SA_LEN*/
+/* SIOCGIFCONF:
+
+ The behavior of this ioctl varies across systems.
+
+ NetBSD 1.5-alpha: The returned ifc_len is the desired amount of
+ space, always. The returned list may be truncated if there isn't
+ enough room; no overrun.
+
+ Solaris 2.7: Return EINVAL if the buffer space is too small,
+ including ifc_len==0. (Not sure if this is "too small for a single
+ entry" or "too small for the entire list"; my Sun has only one
+ interface.) Solaris is the only system I've found so far that
+ actually returns an error.
+
+ AIX 4.3.3: Sometimes the returned ifc_len is bigger than the
+ supplied one, but it may not be big enough for *all* the
+ interfaces. Sometimes it's smaller than the supplied value, even
+ if the returned list is truncated. The list is filled in with as
+ many entries as will fit; no overrun.
+
+ Linux 2.2.12 (RH 6.1 dist, x86): The buffer is filled in with as
+ many entries as will fit, and the size used is returned in ifc_len.
+ The list is truncated if needed, with no indication.
+
+ IRIX 6.5: The buffer is filled in with as many entries as will fit
+ in N-1 bytes, and the size used is returned in ifc_len. Providing
+ exactly the desired number of bytes is inadequate; the buffer must
+ be *bigger* than needed. (E.g., 32->0, 33->32.) The returned
+ ifc_len is always less than the supplied one.
+
+ Digital UNIX 4.0F: If input ifc_len is zero, return an ifc_len
+ that's big enough to include all entries. (Actually, on our
+ system, it appears to be larger than that by 32.) If input ifc_len
+ is nonzero, fill in as many entries as will fit, and set ifc_len
+ accordingly.
+
+ Using this ioctl is going to be messy. Let's just hope that
+ getifaddrs() catches on quickly.... */
+
static int
foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
void *data;
@@ -255,13 +295,17 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
int (*betweenfn) (void *);
int (*pass2fn) (void *, struct sockaddr *);
{
- struct ifreq *ifr, ifreq;
+ struct ifreq *ifr, ifreq, *ifr2;
struct ifconf ifc;
- int s, code, n, i;
+ int s, code, n, i, j;
int est_if_count = 8, est_ifreq_size;
char *buf = 0;
size_t current_buf_size = 0;
-
+ int fail = 0;
+#ifdef SIOCGSIZIFCONF
+ int ifconfsize = -1;
+#endif
+
s = socket (USE_AF, USE_TYPE, USE_PROTO);
if (s < 0)
return SOCKET_ERRNO;
@@ -269,8 +313,17 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
/* At least on NetBSD, an ifreq can hold an IPv4 address, but
isn't big enough for an IPv6 or ethernet address. So add a
little more space. */
- est_ifreq_size = sizeof (struct ifreq) + 8;
- current_buf_size = est_ifreq_size * est_if_count;
+ est_ifreq_size = sizeof (struct ifreq) + 16;
+#ifdef SIOCGSIZIFCONF
+ code = ioctl (s, SIOCGSIZIFCONF, &ifconfsize);
+ if (!code) {
+ current_buf_size = ifconfsize;
+ est_if_count = ifconfsize / est_ifreq_size;
+ }
+#endif
+ if (current_buf_size == 0) {
+ current_buf_size = est_ifreq_size * est_if_count;
+ }
buf = malloc (current_buf_size);
ask_again:
@@ -284,12 +337,35 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
closesocket (s);
return retval;
}
- /* Test that the buffer was big enough that another ifreq could've
+ /* BSD 4.4 and similar systems truncate the address list if the
+ supplied buffer isn't big enough.
+
+ Test that the buffer was big enough that another ifreq could've
fit easily, if the OS wanted to provide one. That seems to be
the only indication we get, complicated by the fact that the
associated address may make the required storage a little
bigger than the size of an ifreq. */
- if (current_buf_size - ifc.ifc_len < sizeof (struct ifreq) + 40) {
+#define SLOP (sizeof (struct ifreq) + 128)
+ if ((current_buf_size - ifc.ifc_len < sizeof (struct ifreq) + SLOP
+ /* On AIX 4.3.3, ifc.ifc_len may be set to a larger size than
+ provided under some circumstances. On my test system, a
+ supplied value of 32..112 gets me 112, but with no data
+ filled in even at 112. But larger input ifc_len values get
+ me larger output values, so it's not necessarily the full
+ desired output buffer size. And as near as I can tell, the
+ ifc_len output has little to do with the offset of the last
+ byte in the buffer actually modified, except that both
+ input and output ifc_len values are higher (i.e., no buffer
+ overrun takes place in my testing). */
+ || current_buf_size < ifc.ifc_len)
+ /* But let's let SIOCGSIZIFCONF dominate, unless we discover
+ it's broken somewhere. */
+#ifdef SIOCGSIZIFCONF
+ && ifconfsize <= 0
+#endif
+ /* And we need *some* sort of bounds. */
+ && current_buf_size <= 100000
+ ) {
int new_size;
char *newbuf;
@@ -307,31 +383,62 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
}
n = ifc.ifc_len;
-
+ if (n > current_buf_size)
+ n = current_buf_size;
+
+ /* Note: Apparently some systems put the size (used or wanted?)
+ into the start of the buffer, just none that I'm actually
+ using. Fix this when there's such a test system available.
+ The Samba mailing list archives mention that NTP looks for the
+ size on these systems: *-fujitsu-uxp* *-ncr-sysv4*
+ *-univel-sysv*. [raeburn:20010201T2226-05] */
for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
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
-#ifdef IFF_LOOPBACK
- /* None of the current callers want loopback addresses. */
- || (ifreq.ifr_flags & IFF_LOOPBACK)
-#endif
- /* Ignore interfaces that are down. */
- || !(ifreq.ifr_flags & IFF_UP)) {
+ if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+ skip:
/* mark for next pass */
ifr->ifr_name[0] = 0;
continue;
}
+#ifdef IFF_LOOPBACK
+ /* None of the current callers want loopback addresses. */
+ if (ifreq.ifr_flags & IFF_LOOPBACK)
+ goto skip;
+#endif
+ /* Ignore interfaces that are down. */
+ if (!(ifreq.ifr_flags & IFF_UP))
+ goto skip;
+
+ /* Make sure we didn't process this address already. */
+ for (j = 0; j < i; j += ifreq_size(*ifr2)) {
+ ifr2 = (struct ifreq *)((caddr_t) ifc.ifc_buf+j);
+ if (ifr2->ifr_name[0] == 0)
+ continue;
+ if (ifr2->ifr_addr.sa_family == ifr->ifr_addr.sa_family
+ && ifreq_size (*ifr) == ifreq_size (*ifr2)
+ /* Compare address info. If this isn't good enough --
+ i.e., if random padding bytes turn out to differ
+ when the addresses are the same -- then we'll have
+ to do it on a per address family basis. */
+ && !memcmp (&ifr2->ifr_addr.sa_data, &ifr->ifr_addr.sa_data,
+ (ifreq_size (*ifr)
+ - offsetof (struct ifreq, ifr_addr.sa_data))))
+ goto skip;
+ }
+
if ((*pass1fn) (data, &ifr->ifr_addr)) {
- abort ();
+ fail = 1;
+ goto punt;
}
}
if (betweenfn && (*betweenfn)(data)) {
- abort ();
+ fail = 1;
+ goto punt;
}
if (pass2fn)
@@ -343,13 +450,15 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn)
continue;
if ((*pass2fn) (data, &ifr->ifr_addr)) {
- abort ();
+ fail = 1;
+ goto punt;
}
}
+ punt:
closesocket(s);
free (buf);
- return 0;
+ return fail;
}
@@ -376,10 +485,9 @@ krb5_os_localaddr(context, addr)
return r;
}
+ data.cur_idx++; /* null termination */
if (data.mem_err)
return ENOMEM;
- else if (data.cur_idx == 0)
- abort ();
else if (data.cur_idx == data.count)
*addr = data.addr_temp;
else {
@@ -396,14 +504,13 @@ krb5_os_localaddr(context, addr)
return 0;
}
-#else /* Windows/Mac version */
+#elif defined(_MSDOS) || defined(_WIN32) /* Windows version */
/*
* Hold on to your lunch! Backup kludge method of obtaining your
* local IP address, courtesy of Windows Socket Network Programming,
* by Robert Quinn
*/
-#if defined(_MSDOS) || defined(_WIN32)
static struct hostent *local_addr_fallback_kludge()
{
static struct hostent host;
@@ -442,7 +549,6 @@ static struct hostent *local_addr_fallback_kludge()
return &host;
}
-#endif
/* No ioctls in winsock so we just assume there is only one networking
* card per machine, so gethostent is good enough.
@@ -473,6 +579,8 @@ krb5_os_localaddr (krb5_context context, krb5_address ***addr) {
hostrec = local_addr_fallback_kludge();
if (!hostrec)
return err;
+ else
+ err = 0; /* otherwise we will die at cleanup */
}
for (count = 0; hostrec->h_addr_list[count]; count++);
@@ -526,4 +634,79 @@ krb5_os_localaddr (krb5_context context, krb5_address ***addr) {
return(err);
}
+
+#else
+
+/* Mac OS 9 version */
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_os_localaddr (krb5_context context, krb5_address ***addr)
+{
+ // First, build the new list
+ krb5_address ** addresses = NULL;
+ SInt32 interfaceCount;
+ SInt32 interfaceIndex;
+ InetInterfaceInfo info;
+ krb5_error_code err = 0;
+
+ // Loop over the addressed once so we know how many there are
+ for (interfaceCount = 0; err == noErr; interfaceCount++) {
+ err = OTInetGetInterfaceInfo (&info, interfaceCount);
+ }
+
+ // Allocate storage for the address list
+ addresses = (krb5_address **) malloc( sizeof (krb5_address *) * (interfaceCount + 1));
+ if (addresses == NULL) {
+ err = ENOMEM;
+ goto cleanup;
+ }
+
+ // Set the pointers to NULL so we will have a termination pointer
+ memset (addresses, 0, sizeof (krb5_address *) * (interfaceCount + 1));
+
+ // Look up the addresses and store them in the list
+ for (interfaceIndex = 0; interfaceIndex < interfaceCount; interfaceIndex++) {
+ err = OTInetGetInterfaceInfo (&info, interfaceIndex);
+ if (err != noErr) {
+ err = 0;
+ break;
+ }
+
+ addresses[interfaceIndex] = (krb5_address *) malloc (sizeof (krb5_address));
+ if (addresses[interfaceIndex] == NULL) {
+ err = ENOMEM;
+ goto cleanup;
+ }
+
+ addresses[interfaceIndex]->magic = KV5M_ADDRESS;
+ addresses[interfaceIndex]->addrtype = AF_INET;
+ addresses[interfaceIndex]->length = INADDRSZ;
+ addresses[interfaceIndex]->contents = (unsigned char *) malloc (addresses[interfaceIndex]->length);
+ if (addresses[interfaceIndex]->contents == NULL) {
+ err = ENOMEM;
+ goto cleanup;
+ }
+
+ memcpy(addresses[interfaceIndex]->contents, &info.fAddress, addresses[interfaceIndex]->length);
+ }
+
+cleanup:
+ if (err) {
+ if (addresses != NULL) {
+ for (interfaceIndex = 0; interfaceIndex < interfaceCount; interfaceIndex++) {
+ if (addresses[interfaceIndex] != NULL) {
+ if (addresses[interfaceIndex]->contents != NULL) {
+ free (addresses[interfaceIndex]->contents);
+ }
+ free (addresses[interfaceIndex]);
+ }
+ }
+ free(addresses);
+ }
+ } else {
+ *addr = addresses;
+ }
+
+ return(err);
+
+}
#endif
diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c
index fcdfa03..6668bbf 100644
--- a/src/lib/krb5/os/locate_kdc.c
+++ b/src/lib/krb5/os/locate_kdc.c
@@ -53,29 +53,57 @@
#define KPASSWD_PORTNAME "kpasswd"
#endif
-int
-_krb5_use_dns(context)
- krb5_context context;
+#if KRB5_DNS_LOOKUP_KDC
+#define DEFAULT_LOOKUP_KDC 1
+#else
+#define DEFAULT_LOOKUP_KDC 0
+#endif
+#if KRB5_DNS_LOOKUP_REALM
+#define DEFAULT_LOOKUP_REALM 1
+#else
+#define DEFAULT_LOOKUP_REALM 0
+#endif
+
+static int
+maybe_use_dns (context, name, defalt)
+ krb5_context context;
+ const char *name;
+ int defalt;
{
krb5_error_code code;
char * value = NULL;
int use_dns = 0;
code = profile_get_string(context->profile, "libdefaults",
- "dns_fallback", 0,
- context->profile_in_memory?"1":"0",
- &value);
+ name, 0, 0, &value);
+ if (value == 0 && code == 0)
+ code = profile_get_string(context->profile, "libdefaults",
+ "dns_fallback", 0, 0, &value);
if (code)
- return(code);
+ return defalt;
- if (value) {
- use_dns = _krb5_conf_boolean(value);
- profile_release_string(value);
- }
+ if (value == 0)
+ return defalt;
+ use_dns = _krb5_conf_boolean(value);
+ profile_release_string(value);
return use_dns;
}
+int
+_krb5_use_dns_kdc(context)
+ krb5_context context;
+{
+ return maybe_use_dns (context, "dns_lookup_kdc", DEFAULT_LOOKUP_KDC);
+}
+
+int
+_krb5_use_dns_realm(context)
+ krb5_context context;
+{
+ return maybe_use_dns (context, "dns_lookup_realm", DEFAULT_LOOKUP_REALM);
+}
+
#endif /* KRB5_DNS_LOOKUP */
/*
@@ -85,14 +113,13 @@ _krb5_use_dns(context)
*/
krb5_error_code
-krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmasters)
+krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, get_masters)
krb5_context context;
const krb5_data *realm;
const char * name;
struct sockaddr **addr_pp;
int *naddrs;
- int *master_index;
- int *nmasters;
+ int get_masters;
{
const char *realm_srv_names[4];
char **masterlist, **hostlist, *host, *port, *cp;
@@ -162,10 +189,7 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste
return 0;
}
- if (master_index) {
- *master_index = 0;
- *nmasters = 0;
-
+ if (get_masters) {
realm_srv_names[0] = "realms";
realm_srv_names[1] = host;
realm_srv_names[2] = "admin_server";
@@ -209,8 +233,10 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste
addr_p = (struct sockaddr *)malloc (sizeof (struct sockaddr) * count);
if (addr_p == NULL) {
- profile_free_list(hostlist);
- profile_free_list(masterlist);
+ if (hostlist)
+ profile_free_list(hostlist);
+ if (masterlist)
+ profile_free_list(masterlist);
return ENOMEM;
}
@@ -239,12 +265,12 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste
if (masterlist) {
for (j=0; masterlist[j]; j++) {
if (strcasecmp(hostlist[i], masterlist[j]) == 0) {
- *master_index = out;
ismaster = 1;
}
}
}
+ if ( !get_masters || ismaster ) {
switch (hp->h_addrtype) {
#ifdef HAVE_NETINET_IN_H
@@ -263,8 +289,10 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste
realloc ((char *)addr_p,
sizeof(struct sockaddr) * count);
if (addr_p == NULL) {
- profile_free_list(hostlist);
- profile_free_list(masterlist);
+ if (hostlist)
+ profile_free_list(hostlist);
+ if (masterlist)
+ profile_free_list(masterlist);
return ENOMEM;
}
}
@@ -279,12 +307,13 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste
default:
break;
}
- if (ismaster)
- *nmasters = out - *master_index;
+ }
}
- profile_free_list(hostlist);
- profile_free_list(masterlist);
+ if (hostlist)
+ profile_free_list(hostlist);
+ if (masterlist)
+ profile_free_list(masterlist);
if (out == 0) { /* Couldn't resolve any KDC names */
free (addr_p);
@@ -362,7 +391,7 @@ krb5_locate_srv_dns(realm, service, protocol, addr_pp, naddrs)
size = res_search(host, C_IN, T_SRV, answer.bytes, sizeof(answer.bytes));
- if (size < hdrsize)
+ if ((size < hdrsize) || (size > sizeof(answer.bytes)))
goto out;
/*
@@ -564,78 +593,29 @@ krb5_locate_srv_dns(realm, service, protocol, addr_pp, naddrs)
*/
krb5_error_code
-krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters)
+krb5_locate_kdc(context, realm, addr_pp, naddrs, get_masters)
krb5_context context;
const krb5_data *realm;
struct sockaddr **addr_pp;
int *naddrs;
- int *master_index;
- int *nmasters;
+ int get_masters;
{
krb5_error_code code;
-#ifdef KRB5_DNS_LOOKUP
- struct sockaddr *admin_addr_p, *kdc_addr_p;
- int nadmin_addrs, nkdc_addrs;
- int i,j;
-#endif /* KRB5_DNS_LOOKUP */
/*
* We always try the local file first
*/
code = krb5_locate_srv_conf(context, realm, "kdc", addr_pp, naddrs,
- master_index, nmasters);
+ get_masters);
#ifdef KRB5_DNS_LOOKUP
if (code) {
- int use_dns = _krb5_use_dns(context);
+ int use_dns = _krb5_use_dns_kdc(context);
if ( use_dns ) {
- code = krb5_locate_srv_dns(realm, "_kerberos", "_udp",
- addr_pp, naddrs);
- if ( master_index && nmasters ) {
-
- code = krb5_locate_srv_dns(realm, "_kerberos-adm", "_tcp",
- &admin_addr_p, &nadmin_addrs);
- if ( code ) {
- free(*addr_pp);
- *addr_pp = NULL;
- *naddrs = 0;
- return(code);
- }
-
- kdc_addr_p = *addr_pp;
- nkdc_addrs = *naddrs;
-
- *naddrs = 0;
- *addr_pp = (struct sockaddr *) malloc(sizeof(*kdc_addr_p));
- if ( *addr_pp == NULL ) {
- free(kdc_addr_p);
- free(admin_addr_p);
- return ENOMEM;
- }
-
- for ( i=0; i<nkdc_addrs; i++ ) {
- for ( j=0 ; j<nadmin_addrs; j++) {
- if ( !memcmp(&kdc_addr_p[i].sa_data[2],&admin_addr_p[j].sa_data[2],4) ) {
- memcpy(&(*addr_pp)[(*naddrs)],&kdc_addr_p[i],
- sizeof(struct sockaddr));
- (*naddrs)++;
- break;
- }
- }
- }
-
- free(kdc_addr_p);
- free(admin_addr_p);
-
- if ( *naddrs == 0 ) {
- free(*addr_pp);
- *addr_pp = NULL;
- return KRB5_REALM_CANT_RESOLVE;
- }
- *master_index = 1;
- *nmasters = *naddrs;
- }
+ code = krb5_locate_srv_dns(realm,
+ get_masters ? "_kerberos-master" : "_kerberos",
+ "_udp", addr_pp, naddrs);
}
}
#endif /* KRB5_DNS_LOOKUP */
diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
index fed7a81..a6b67f1 100644
--- a/src/lib/krb5/os/os-proto.h
+++ b/src/lib/krb5/os/os-proto.h
@@ -36,8 +36,7 @@ krb5_error_code krb5_locate_kdc
const krb5_data *,
struct sockaddr **,
int *,
- int *,
- int *));
+ int));
#endif
#ifdef HAVE_NETINET_IN_H
diff --git a/src/lib/krb5/os/prompter.c b/src/lib/krb5/os/prompter.c
index 933ff2c..8dc985c 100644
--- a/src/lib/krb5/os/prompter.c
+++ b/src/lib/krb5/os/prompter.c
@@ -117,6 +117,18 @@ krb5_prompter_posix(krb5_context context,
cleanup:
(void) signal(SIGINT, ointrfunc);
+#ifndef ECHO_PASSWORD
+ if (i < num_prompts) {
+ if (prompts[i].hidden) {
+ (void)putchar('\n');
+ if (isatty(fd) == 1) {
+ if ((tcsetattr(fd, TCSANOW, &save_control) == -1
+ && errcode == 0))
+ return errno;
+ }
+ }
+ }
+#endif
return(errcode);
}
#else /* MSDOS */
@@ -235,7 +247,7 @@ krb5int_set_prompt_types(context, types)
krb5_context context;
krb5_prompt_type *types;
{
- context->prompt_types = 0;
+ context->prompt_types = types;
}
KRB5_DLLIMP
diff --git a/src/lib/krb5/os/promptusr.c b/src/lib/krb5/os/promptusr.c
index 3ac3d4f..a3a185b 100644
--- a/src/lib/krb5/os/promptusr.c
+++ b/src/lib/krb5/os/promptusr.c
@@ -162,4 +162,4 @@ main(int argc, char **argv)
#endif
-#endif /* !_MSODS || _!MACINTOSH */
+#endif /* !_MSDOS || _!MACINTOSH */
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
index 01b797e..47f2408 100644
--- a/src/lib/krb5/os/sendto_kdc.c
+++ b/src/lib/krb5/os/sendto_kdc.c
@@ -60,16 +60,16 @@ extern int krb5_skdc_timeout_shift;
extern int krb5_skdc_timeout_1;
krb5_error_code
-krb5_sendto_kdc (context, message, realm, reply, master)
+krb5_sendto_kdc (context, message, realm, reply, use_master)
krb5_context context;
const krb5_data * message;
const krb5_data * realm;
krb5_data * reply;
- int *master;
+ int use_master;
{
register int timeout, host, i;
struct sockaddr *addr;
- int naddr, master_index, nmasters;
+ int naddr;
int sent, nready;
krb5_error_code retval;
SOCKET *socklist;
@@ -81,14 +81,10 @@ krb5_sendto_kdc (context, message, realm, reply, master)
* find KDC location(s) for realm
*/
- if (retval = krb5_locate_kdc (context, realm, &addr, &naddr,
- master?&master_index:NULL,
- master?&nmasters:NULL))
+ if (retval = krb5_locate_kdc (context, realm, &addr, &naddr, use_master))
return retval;
if (naddr == 0)
- return KRB5_REALM_UNKNOWN;
- if (master && (*master == 1) && (nmasters == 0))
- return KRB5_KDC_UNREACH;
+ return (use_master ? KRB5_KDC_UNREACH : KRB5_REALM_UNKNOWN);
socklist = (SOCKET *)malloc(naddr * sizeof(SOCKET));
if (socklist == NULL) {
@@ -128,12 +124,6 @@ krb5_sendto_kdc (context, message, realm, reply, master)
timeout <<= krb5_skdc_timeout_shift) {
sent = 0;
for (host = 0; host < naddr; host++) {
- /* if a master kdc is required, skip the non-master kdc's */
-
- if (master && (*master == 1) &&
- ((host < master_index) || (host >= (master_index+nmasters))))
- continue;
-
/* send to the host, wait timeout seconds for a response,
then move on. */
/* cache some sockets for each host */
@@ -211,12 +201,6 @@ krb5_sendto_kdc (context, message, realm, reply, master)
reply->length = cc;
retval = 0;
- /* if the caller asked to be informed if it
- got a master kdc, tell it */
- if (master)
- *master = ((host >= master_index) &&
- (host < (master_index+nmasters)));
-
goto out;
} else if (nready == 0) {
/* timeout */
diff --git a/src/lib/krb5/os/t_std_conf.c b/src/lib/krb5/os/t_std_conf.c
index 0846b1c..a95c67a 100644
--- a/src/lib/krb5/os/t_std_conf.c
+++ b/src/lib/krb5/os/t_std_conf.c
@@ -110,14 +110,14 @@ void test_locate_kdc(ctx, realm)
struct sockaddr *addrs;
struct sockaddr_in *sin;
int i, naddrs;
- int master_index, nmasters;
+ int get_masters=0;
krb5_data rlm;
krb5_error_code retval;
rlm.data = realm;
rlm.length = strlen(realm);
retval = krb5_locate_kdc(ctx, &rlm, &addrs, &naddrs,
- &master_index, &nmasters);
+ get_masters);
if (retval) {
com_err("krb5_get_krbhst", retval, 0);
return;
diff --git a/src/lib/krb5/os/timeofday.c b/src/lib/krb5/os/timeofday.c
index 11dffd7..9ae528e 100644
--- a/src/lib/krb5/os/timeofday.c
+++ b/src/lib/krb5/os/timeofday.c
@@ -48,12 +48,12 @@ krb5_timeofday(context, timeret)
*timeret = os_ctx->time_offset;
return 0;
}
-#ifdef macintosh
+#if TARGET_OS_MAC
{
- long usecs;
+ krb5_int32 usecs;
krb5_error_code kret;
- if (kret = krb5_crypto_us_timeofday(&tval, &usecs))
+ if (kret = krb5_crypto_us_timeofday((krb5_int32 *)&tval, &usecs))
return kret;
}
#else
diff --git a/src/lib/krb5/os/toffset.c b/src/lib/krb5/os/toffset.c
index 72d301d..59c7252 100644
--- a/src/lib/krb5/os/toffset.c
+++ b/src/lib/krb5/os/toffset.c
@@ -91,7 +91,7 @@ krb5_use_natural_time(context)
/*
* This routine returns the current time offsets in use.
*/
-krb5_error_code
+krb5_error_code KRB5_CALLCONV
krb5_get_time_offsets(context, seconds, microseconds)
krb5_context context;
krb5_int32 *seconds, *microseconds;
diff --git a/src/lib/krb5/posix/ChangeLog b/src/lib/krb5/posix/ChangeLog
index e90e47b..c2527aa 100644
--- a/src/lib/krb5/posix/ChangeLog
+++ b/src/lib/krb5/posix/ChangeLog
@@ -1,3 +1,14 @@
+2002-02-28 Alexandra Ellwood <lxs@mit.edu>
+ * setenv.c: Updated macros to removed warning about prototype
+ with no function definition
+
+2000-04-28 Ken Raeburn <raeburn@mit.edu>
+ Nalin Dahyabhai <nalin@redhat.com>
+
+ * syslog.c (vsyslog): Use strncpy and strncat instead of strcpy
+ and strcat when adding to buffer "tbuf". If calling vsprintf,
+ abort if it appears to have overrun the buffer.
+
1999-10-26 Tom Yu <tlyu@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/krb5/posix/setenv.c b/src/lib/krb5/posix/setenv.c
index 7072d7e..422c962 100644
--- a/src/lib/krb5/posix/setenv.c
+++ b/src/lib/krb5/posix/setenv.c
@@ -45,7 +45,9 @@
#ifndef __P
#define __P(x) ()
#endif
+#if (!HAVE_GETENV || !HAVE_SETENV || !HAVE_UNSETENV)
static char *__findenv __P((const char *, int *));
+#endif
/*
* setenv --
diff --git a/src/lib/krb5/posix/syslog.c b/src/lib/krb5/posix/syslog.c
index 31e7874..f7ddbff 100644
--- a/src/lib/krb5/posix/syslog.c
+++ b/src/lib/krb5/posix/syslog.c
@@ -115,7 +115,7 @@ vsyslog(pri, fmt, ap)
(void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4);
for (p = tbuf; *p; ++p);
if (LogTag) {
- (void)strcpy(p, LogTag);
+ (void)strncpy(p, LogTag, sizeof(tbuf) - 1 - (p - tbuf));
for (; *p; ++p);
}
if (LogStat & LOG_PID) {
@@ -146,6 +146,11 @@ vsyslog(pri, fmt, ap)
}
(void)vsprintf(p, fmt_cpy, ap);
+ /* Bounds checking?? If a system doesn't have syslog, we
+ probably can't rely on it having vsnprintf either. Try not
+ to let a buffer overrun be exploited. */
+ if (strlen (tbuf) >= sizeof (tbuf))
+ abort ();
/* output the message to the local logger */
if (send(LogFile, tbuf, cnt = strlen(tbuf), 0) >= 0 ||
@@ -169,7 +174,8 @@ vsyslog(pri, fmt, ap)
if ((fd = open(CONSOLE, O_WRONLY, 0)) < 0)
return;
(void)alarm((u_int)0);
- (void)strcat(tbuf, "\r");
+ tbuf[sizeof(tbuf) - 1] = '\0';
+ (void)strncat(tbuf, "\r", sizeof(tbuf) - 1 - strlen(tbuf));
p = strchr(tbuf, '>') + 1;
(void)write(fd, p, cnt + 1 - (p - tbuf));
(void)close(fd);
diff --git a/src/lib/krb5/rcache/ChangeLog b/src/lib/krb5/rcache/ChangeLog
index a3b8b4f..9683a88 100644
--- a/src/lib/krb5/rcache/ChangeLog
+++ b/src/lib/krb5/rcache/ChangeLog
@@ -1,3 +1,25 @@
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * rc_io.c, rc_dfl.c: use "" includes for krb5.h and k5-int.h
+
+2001-01-23 Tom Yu <tlyu@mit.edu>
+
+ * rc_io.c (getdir, krb5_rc_io_creat): Undo prior fudge; dirlen
+ will now not include trailing NUL character.
+
+2001-01-17 Tom Yu <tlyu@mit.edu>
+
+ * rc_io.c (krb5_rc_io_creat): Fudge for dirlen including trailing
+ NUL character.
+ (krb5_rc_io_move): When renaming OLD to NEW, don't copy the
+ filename. This was causing temporary files to get leaked.
+ (krb5_rc_io_close): Don't FREE if d->fn is NULL.
+
+2000-04-28 Nalin Dahyabhai <nalin@redhat.com>
+
+ * rc_io.c (getdir): Don't check dirlen again, the call sites
+ always do. Fix dirlen calculation.
+
1999-10-26 Tom Yu <tlyu@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c
index a86f42e..4760e59 100644
--- a/src/lib/krb5/rcache/rc_dfl.c
+++ b/src/lib/krb5/rcache/rc_dfl.c
@@ -14,7 +14,7 @@
#include "rc_base.h"
#include "rc_dfl.h"
#include "rc_io.h"
-#include <k5-int.h>
+#include "k5-int.h"
/*
If NOIOSTUFF is defined at compile time, dfl rcaches will be per-process.
diff --git a/src/lib/krb5/rcache/rc_io.c b/src/lib/krb5/rcache/rc_io.c
index d45c7a1..f29c161 100644
--- a/src/lib/krb5/rcache/rc_io.c
+++ b/src/lib/krb5/rcache/rc_io.c
@@ -21,7 +21,7 @@
#define NEED_SOCKETS
#define NEED_LOWLEVEL_IO
-#include <krb5.h>
+#include "krb5.h"
#include <stdio.h> /* for P_tmpdir */
#include "rc_base.h"
#include "rc_dfl.h"
@@ -57,13 +57,11 @@ static char *dir;
static void getdir()
{
- if (!dirlen)
- {
if (!(dir = getenv("KRB5RCACHEDIR")))
#if defined(_MSDOS) || defined(_WIN32)
if (!(dir = getenv("TEMP")))
if (!(dir = getenv("TMP")))
- dir = "C:\\";
+ dir = "C:";
#else
if (!(dir = getenv("TMPDIR")))
#ifdef RCTMPDIR
@@ -72,8 +70,7 @@ static void getdir()
dir = "/tmp";
#endif
#endif
- dirlen = strlen(dir) + 1;
- }
+ dirlen = strlen(dir) + sizeof(PATH_SEPARATOR) - 1;
}
krb5_error_code krb5_rc_io_creat (context, d, fn)
@@ -245,33 +242,32 @@ krb5_error_code krb5_rc_io_move (context, new, old)
krb5_rc_iostuff *new;
krb5_rc_iostuff *old;
{
+ char *fn = NULL;
+
#if defined(_MSDOS) || defined(_WIN32)
/*
* Work around provided by Tom Sanfilippo to work around poor
* Windows emulation of POSIX functions. Rename and dup has
* different semantics!
*/
- char *fn = NULL;
GETDIR;
close(new->fd);
unlink(new->fn);
close(old->fd);
if (rename(old->fn,new->fn) == -1) /* MUST be atomic! */
return KRB5_RC_IO_UNKNOWN;
- if (!(fn = malloc(strlen(new->fn) - dirlen + 1)))
- return KRB5_RC_IO_MALLOC;
- strcpy(fn, new->fn + dirlen);
+ fn = new->fn;
+ new->fn = NULL; /* avoid clobbering */
krb5_rc_io_close(context, new);
krb5_rc_io_open(context, new, fn);
free(fn);
#else
if (rename(old->fn,new->fn) == -1) /* MUST be atomic! */
return KRB5_RC_IO_UNKNOWN;
+ fn = new->fn;
+ new->fn = NULL; /* avoid clobbering */
(void) krb5_rc_io_close(context, new);
- new->fn = malloc(strlen(old->fn)+1);
- if (new->fn == 0)
- return ENOMEM;
- strcpy(new->fn, old->fn);
+ new->fn = fn;
#ifdef macintosh
new->fd = fcntl(old->fd, F_DUPFD);
#else
@@ -342,7 +338,8 @@ krb5_error_code krb5_rc_io_close (context, d)
krb5_context context;
krb5_rc_iostuff *d;
{
- FREE(d->fn);
+ if (d->fn != NULL)
+ FREE(d->fn);
d->fn = NULL;
if (close(d->fd) == -1) /* can't happen */
return KRB5_RC_IO_UNKNOWN;
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
index 4c5f271..f4e1598 100644
--- a/src/lib/krb5_32.def
+++ b/src/lib/krb5_32.def
@@ -9,19 +9,84 @@
; Key:
;
-; gssapi - used by GSS API (not part of krb5 API)
-; !CALLCONV - entrypoint that should have used KRB5_CALLCONV, but did not due
-; developer error
-
-;LIBRARY KRB5
-DESCRIPTION 'DLL for Kerberos 5'
-HEAPSIZE 8192
+; PRIVATE - Private entrypoint. It should not be called by anything other
+; than gssapi32.dll or krb4_32.dll.
+; GSSAPI - Private entrypoint used by gssapi32.dll.
+; KRB4 - Private entrypoint used by krb4_32.dll.
+; KRB5_CALLCONV_WRONG - entrypoint that should have used KRB5_CALLCONV, but
+; did not due to developer error
EXPORTS
-; Kerberos 5
+
+ krb5_425_conv_principal
+ krb5_524_conv_principal
+ krb5_address_compare
+ krb5_address_order
+ krb5_address_search ; KRB5_CALLCONV_WRONG
+ krb5_aname_to_localname
+ krb5_appdefault_boolean
+ krb5_appdefault_string
+ krb5_auth_con_free
+ krb5_auth_con_genaddrs
+ krb5_auth_con_getaddrs
+ krb5_auth_con_getauthenticator
+ krb5_auth_con_getflags
+ krb5_auth_con_getkey
+ krb5_auth_con_getlocalseqnumber
+ krb5_auth_con_getlocalsubkey
+ krb5_auth_con_getrcache ; KRB5_CALLCONV_WRONG
+ krb5_auth_con_getremoteseqnumber
+ krb5_auth_con_getremotesubkey
+ krb5_auth_con_init
+ krb5_auth_con_initivector ; DEPRECATED
+ krb5_auth_con_setaddrs ; KRB5_CALLCONV_WRONG
+ krb5_auth_con_setflags
+ krb5_auth_con_setports
+ krb5_auth_con_setrcache
+ krb5_auth_con_setuseruserkey
krb5_build_principal
krb5_build_principal_ext
- krb5_copy_addr
+ krb5_build_principal_va
+ krb5_c_block_size
+ krb5_c_checksum_length
+ krb5_c_decrypt
+ krb5_c_encrypt
+ krb5_c_encrypt_length
+ krb5_c_enctype_compare
+ krb5_c_is_coll_proof_cksum
+ krb5_c_is_keyed_cksum
+ krb5_c_keyed_checksum_types
+ krb5_c_make_checksum
+ krb5_c_make_random_key
+ krb5_c_random_make_octets
+ krb5_c_random_seed
+ krb5_c_string_to_key
+ krb5_c_valid_cksumtype
+ krb5_c_valid_enctype
+ krb5_c_verify_checksum
+ krb5_calculate_checksum
+ krb5_cc_close
+ krb5_cc_copy_creds
+ krb5_cc_default
+ krb5_cc_default_name
+ krb5_cc_destroy
+ krb5_cc_end_seq_get
+ krb5_cc_gen_new
+ krb5_cc_get_name
+ krb5_cc_get_principal
+ krb5_cc_get_type
+ krb5_cc_initialize
+ krb5_cc_next_cred
+ krb5_cc_remove_cred
+ krb5_cc_resolve
+ krb5_cc_retrieve_cred
+ krb5_cc_set_default_name
+ krb5_cc_set_flags
+ krb5_cc_start_seq_get
+ krb5_cc_store_cred
+ krb5_change_password
+ krb5_checksum_size
+ krb5_cksumtype_to_string
krb5_copy_addresses
krb5_copy_authdata
krb5_copy_authenticator
@@ -32,75 +97,86 @@ EXPORTS
krb5_copy_keyblock_contents
krb5_copy_principal
krb5_copy_ticket
- krb5_decrypt_tkt_part
- krb5_free_address
+ krb5_decode_ticket
+ krb5_decrypt
+ krb5_deltat_to_string
+ krb5_eblock_enctype
+ krb5_encrypt
+ krb5_encrypt_size
+ krb5_enctype_to_string
+ krb5_finish_key
+ krb5_finish_random_key
krb5_free_addresses
- krb5_free_ap_rep
krb5_free_ap_rep_enc_part
- krb5_free_ap_req
krb5_free_authdata
krb5_free_authenticator
- krb5_free_authenticator_contents
krb5_free_checksum
- krb5_free_config_files
+ krb5_free_checksum_contents
+ krb5_free_cksumtypes
+ krb5_free_config_files
krb5_free_context
- krb5_free_cred
krb5_free_cred_contents
- krb5_free_cred_enc_part
krb5_free_creds
krb5_free_data
krb5_free_data_contents
- krb5_free_enc_kdc_rep_part
- krb5_free_enc_tkt_part
+ krb5_free_default_realm
krb5_free_error
krb5_free_host_realm
- krb5_free_kdc_rep
- krb5_free_kdc_req
krb5_free_keyblock
krb5_free_keyblock_contents
- krb5_free_last_req
- krb5_free_pa_data
+ krb5_free_keytab_entry_contents
krb5_free_principal
- krb5_free_priv
- krb5_free_priv_enc_part
- krb5_free_pwd_data
- krb5_free_pwd_sequences
- krb5_free_safe
krb5_free_tgt_creds
krb5_free_ticket
- krb5_free_tickets
- krb5_free_tkt_authent
- krb5_free_checksum_contents
- krb5_free_cksumtypes
+ krb5_free_unparsed_name
krb5_fwd_tgt_creds
krb5_get_credentials
krb5_get_credentials_renew
krb5_get_credentials_validate
- krb5_get_default_config_files
+ krb5_get_default_config_files
krb5_get_default_realm
krb5_get_host_realm
- krb5_get_realm_domain
- krb5_get_in_tkt
- krb5_get_in_tkt_with_keytab
- krb5_get_in_tkt_with_password
- krb5_get_in_tkt_with_skey
+ krb5_get_in_tkt ; DEPRECATED
+ krb5_get_in_tkt_with_keytab ; DEPRECATED
+ krb5_get_in_tkt_with_password ; DEPRECATED
+ krb5_get_in_tkt_with_skey ; DEPRECATED
+ krb5_get_init_creds_keytab
krb5_get_init_creds_opt_init
- krb5_get_init_creds_opt_set_tkt_life
- krb5_get_init_creds_opt_set_renew_life
- krb5_get_init_creds_opt_set_forwardable
- krb5_get_init_creds_opt_set_proxiable
- krb5_get_init_creds_opt_set_etype_list
krb5_get_init_creds_opt_set_address_list
+ krb5_get_init_creds_opt_set_etype_list
+ krb5_get_init_creds_opt_set_forwardable
krb5_get_init_creds_opt_set_preauth_list
+ krb5_get_init_creds_opt_set_proxiable
+ krb5_get_init_creds_opt_set_renew_life
krb5_get_init_creds_opt_set_salt
+ krb5_get_init_creds_opt_set_tkt_life
krb5_get_init_creds_password
- krb5_get_init_creds_keytab
- krb5_get_init_creds_opt_init
- krb5_get_validated_creds
+ krb5_get_prompt_types
krb5_get_renewed_creds
- krb5_get_notification_message
+ krb5_get_server_rcache
+ krb5_get_time_offsets
+ krb5_get_validated_creds
krb5_init_context
+ krb5_init_keyblock
+ krb5_init_random_key
+ krb5_init_secure_context
+ krb5_kt_add_entry
+ krb5_kt_close
+ krb5_kt_default
+ krb5_kt_default_name
+ krb5_kt_end_seq_get
+ krb5_kt_get_entry
+ krb5_kt_get_name
+ krb5_kt_get_type
+ krb5_kt_next_entry
+ krb5_kt_read_service_key
+ krb5_kt_remove_entry
+ krb5_kt_resolve
+ krb5_kt_start_seq_get
+ krb5_kuserok
+ krb5_mk_1cred
krb5_mk_error
+ krb5_mk_ncred
krb5_mk_priv
krb5_mk_rep
krb5_mk_req
@@ -109,8 +185,9 @@ EXPORTS
krb5_os_localaddr
krb5_parse_name
krb5_principal_compare
+ krb5_process_key
krb5_prompter_posix
- krb5_get_prompt_types
+ krb5_random_key
krb5_rd_cred
krb5_rd_error
krb5_rd_priv
@@ -118,136 +195,65 @@ EXPORTS
krb5_rd_req
krb5_rd_safe
krb5_read_password
+ krb5_realm_compare
krb5_recvauth
+ krb5_recvauth_version
+ krb5_salttype_to_string
krb5_sendauth
+ krb5_set_default_realm
+ krb5_set_default_tgs_enctypes
+ krb5_set_principal_realm
krb5_sname_to_principal
- krb5_timeofday
- krb5_unparse_name
- krb5_unparse_name_ext
- krb5_free_unparsed_name
- krb5_us_timeofday
- krb5_get_server_rcache
-;
- krb5_use_enctype
- krb5_checksum_size
- krb5_encrypt_size
- krb5_calculate_checksum
- krb5_verify_checksum
- krb5_eblock_enctype
-;
- krb5_decrypt
- krb5_encrypt
- krb5_string_to_key
- krb5_process_key
- krb5_finish_key
- krb5_init_random_key
- krb5_finish_random_key
- krb5_random_key
-;
- krb5_c_decrypt
- krb5_c_encrypt
- krb5_c_encrypt_length
- krb5_c_checksum_length
- krb5_c_block_size
- krb5_c_make_checksum
- krb5_c_verify_checksum
- krb5_c_random_make_octets
- krb5_c_keyed_checksum_types
-;
- krb5_425_conv_principal
- krb5_524_conv_principal
-;
- krb5_cksumtype_to_string
- krb5_deltat_to_string
- krb5_enctype_to_string
- krb5_salttype_to_string
krb5_string_to_cksumtype
krb5_string_to_deltat
krb5_string_to_enctype
+ krb5_string_to_key
krb5_string_to_salttype
krb5_string_to_timestamp
+ krb5_timeofday
krb5_timestamp_to_sfstring
krb5_timestamp_to_string
-;
- krb5_auth_con_free
- krb5_auth_con_genaddrs
- krb5_auth_con_getflags
- krb5_auth_con_getkey
- krb5_auth_con_getlocalsubkey
- krb5_auth_con_getremotesubkey
- krb5_auth_con_init
- krb5_auth_con_setaddrs ; !CALLCONV
- krb5_auth_con_setflags
- krb5_auth_con_getlocalseqnumber
- krb5_auth_con_getremoteseqnumber
- krb5_auth_con_setuseruserkey
- krb5_auth_con_getauthenticator
- krb5_auth_con_set_req_cksumtype
- krb5_auth_con_setrcache
-;
- krb5_cc_default
- krb5_cc_default_name
- krb5_cc_register
- krb5_cc_resolve
- krb5_cc_set_default_name
-;
- krb5_kt_default
- krb5_kt_register
- krb5_kt_resolve
- krb5_kt_add_entry
- krb5_kt_free_entry
- krb5_kt_read_service_key
- krb5_kt_remove_entry
+ krb5_unparse_name
+ krb5_unparse_name_ext
+ krb5_us_timeofday
+ krb5_use_enctype
+ krb5_verify_checksum
+ krb5_verify_init_creds
+ krb5_verify_init_creds_opt_init
+ krb5_verify_init_creds_opt_set_ap_req_nofail
-;Kadm routines
-; krb5_adm_connect
-; krb5_adm_disconnect
-; krb5_free_adm_data
-; krb5_read_adm_reply
-; krb5_send_adm_cmd
+; To Add (exported on Mac OS X):
+; krb5_get_profile
- krb5_change_password
-;
- krb5_write_message
- krb5_read_message
- krb5_net_write
- krb5_net_read
- krb5_encrypt
- krb5_decrypt
- krb5_encrypt_size
-;
-; Added for Kermit 95
- krb5_address_search ; !CALLCONV
- krb5_auth_con_getrcache ; !CALLCONV
- krb5_c_enctype_compare
-;
- krb5_kuserok
-;
-; Added for 1.2:
- krb5_decode_ticket
-;
; Temporary exports (DO NOT USE)
-; decode_krb5_ticket -- no longer in library
- des_ecb_encrypt
- des_new_random_key
- des_key_sched
- des_pcbc_encrypt
- des_quad_cksum
- des_string_to_key
-; des_set_random_generator_seed -- no longer in library
- des_init_random_number_generator
- krb5_random_confounder
- krb5_size_opaque
- krb5_internalize_opaque
- krb5_externalize_opaque
- krb5_ser_pack_int32
- krb5_ser_unpack_int32
- krb5_ser_pack_bytes
- krb5_ser_unpack_bytes
- krb5_ser_auth_context_init
- krb5_ser_context_init
- krb5_ser_ccache_init
- krb5_ser_keytab_init
- krb5_ser_rcache_init
- decode_krb5_ap_req ; gssapi
- krb5_mcc_ops
+
+; DO NOT USE -- Currently required for krb4_32.dll
+ des_ecb_encrypt ; PRIVATE KRB4
+ des_new_random_key ; PRIVATE KRB4
+ des_key_sched ; PRIVATE KRB4
+ des_pcbc_encrypt ; PRIVATE KRB4
+ des_quad_cksum ; PRIVATE KRB4
+ des_string_to_key ; PRIVATE KRB4
+ des_init_random_number_generator ; PRIVATE KRB4
+
+; DO NOT USE -- Currently required to implement gssapi32.dll
+ decode_krb5_ap_req ; PRIVATE GSSAPI k5-int.h KRB5_CALLCONV_WRONG
+ krb5_externalize_opaque ; PRIVATE GSSAPI k5-int.h
+ krb5_internalize_opaque ; PRIVATE GSSAPI k5-int.h
+ krb5_ser_auth_context_init ; PRIVATE GSSAPI k5-int.h
+ krb5_ser_ccache_init ; PRIVATE GSSAPI k5-int.h
+ krb5_ser_context_init ; PRIVATE GSSAPI k5-int.h
+ krb5_ser_keytab_init ; PRIVATE GSSAPI k5-int.h
+ krb5_ser_pack_bytes ; PRIVATE GSSAPI k5-int.h
+ krb5_ser_pack_int32 ; PRIVATE GSSAPI k5-int.h
+ krb5_ser_rcache_init ; PRIVATE GSSAPI k5-int.h
+ krb5_ser_unpack_bytes ; PRIVATE GSSAPI k5-int.h
+ krb5_ser_unpack_int32 ; PRIVATE GSSAPI k5-int.h
+ krb5_size_opaque ; PRIVATE GSSAPI k5-int.h
+ krb5int_cc_default ; PRIVATE GSSAPI k5-int.h
+
+ krb5_free_ap_req ; PRIVATE GSSAPI krb5.hin
+ krb5_free_ktypes ; PRIVATE GSSAPI krb5.hin
+ krb5_get_tgs_ktypes ; PRIVATE GSSAPI krb5.hin
+ krb5_auth_con_set_req_cksumtype ; PRIVATE GSSAPI krb5.hin
+ krb5_kt_free_entry ; PRIVATE GSSAPI krb5.hin
diff --git a/src/lib/krb5util/ChangeLog b/src/lib/krb5util/ChangeLog
index ec629cb..8f671a0 100644
--- a/src/lib/krb5util/ChangeLog
+++ b/src/lib/krb5util/ChangeLog
@@ -1,3 +1,8 @@
+2000-05-31 Ken Raeburn <raeburn@mit.edu>
+
+ * compat_recv.c (krb5_compat_recvauth_version): Variant of
+ krb5_compat_recvauth, similar to krb5_recvauth_version.
+
1999-10-26 Tom Yu <tlyu@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/krb5util/compat_recv.c b/src/lib/krb5util/compat_recv.c
index ec6b151..ee7df24 100644
--- a/src/lib/krb5util/compat_recv.c
+++ b/src/lib/krb5util/compat_recv.c
@@ -193,6 +193,151 @@ krb5_compat_recvauth(context, auth_context,
return retval;
}
+krb5_error_code
+krb5_compat_recvauth_version(context, auth_context,
+ /* IN */
+ fdp, server, flags, keytab,
+ v4_options, v4_service, v4_instance, v4_faddr,
+ v4_laddr,
+ v4_filename,
+ /* OUT */
+ ticket,
+ auth_sys, v4_kdata, v4_schedule,
+ version)
+ krb5_context context;
+ krb5_auth_context *auth_context;
+ krb5_pointer fdp;
+ krb5_principal server;
+ krb5_int32 flags;
+ krb5_keytab keytab;
+ krb5_ticket ** ticket;
+ krb5_int32 *auth_sys;
+
+ /*
+ * Version 4 arguments
+ */
+ krb5_int32 v4_options; /* bit-pattern of options */
+ char *v4_service; /* service expected */
+ char *v4_instance; /* inst expected (may be filled in) */
+ struct sockaddr_in *v4_faddr; /* foreign address */
+ struct sockaddr_in *v4_laddr; /* local address */
+ AUTH_DAT **v4_kdata; /* kerberos data (returned) */
+ char *v4_filename; /* name of file with service keys */
+ Key_schedule v4_schedule; /* key schedule (return) */
+ krb5_data *version; /* application version filled in */
+{
+ union verslen {
+ krb5_int32 len;
+ char vers[4];
+ } vers;
+ char *buf;
+ int len, length;
+ krb5_int32 retval;
+ int fd = *( (int *) fdp);
+#ifdef KRB5_KRB4_COMPAT
+ KTEXT v4_ticket; /* storage for client's ticket */
+#endif
+
+ if ((retval = krb5_net_read(context, fd, vers.vers, 4)) != 4)
+ return((retval < 0) ? errno : ECONNABORTED);
+
+#ifdef KRB5_KRB4_COMPAT
+ if (!strncmp(vers.vers, KRB_V4_SENDAUTH_VERS, 4)) {
+ /*
+ * We must be talking to a V4 sendauth; read in the
+ * rest of the version string and make sure.
+ */
+ if ((retval = krb5_net_read(context, fd, vers.vers, 4)) != 4)
+ return((retval < 0) ? errno : ECONNABORTED);
+
+ if (strncmp(vers.vers, KRB_V4_SENDAUTH_VERS+4, 4))
+ return KRB5_SENDAUTH_BADAUTHVERS;
+
+ *auth_sys = KRB5_RECVAUTH_V4;
+
+ *v4_kdata = (AUTH_DAT *) malloc( sizeof(AUTH_DAT) );
+ v4_ticket = (KTEXT) malloc(sizeof(KTEXT_ST));
+
+ version->length = KRB_SENDAUTH_VLEN; /* no trailing \0! */
+ version->data = malloc (KRB_SENDAUTH_VLEN + 1);
+ version->data[KRB_SENDAUTH_VLEN] = 0;
+ if (version->data == 0)
+ return errno;
+ retval = krb_v4_recvauth(v4_options, fd, v4_ticket,
+ v4_service, v4_instance, v4_faddr,
+ v4_laddr, *v4_kdata, v4_filename,
+ v4_schedule, version->data);
+ krb5_xfree(v4_ticket);
+ /*
+ * XXX error code translation?
+ */
+ switch (retval) {
+ case RD_AP_OK:
+ return 0;
+ case RD_AP_TIME:
+ return KRB5KRB_AP_ERR_SKEW;
+ case RD_AP_EXP:
+ return KRB5KRB_AP_ERR_TKT_EXPIRED;
+ case RD_AP_NYV:
+ return KRB5KRB_AP_ERR_TKT_NYV;
+ case RD_AP_NOT_US:
+ return KRB5KRB_AP_ERR_NOT_US;
+ case RD_AP_UNDEC:
+ return KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ case RD_AP_REPEAT:
+ return KRB5KRB_AP_ERR_REPEAT;
+ case RD_AP_MSG_TYPE:
+ return KRB5KRB_AP_ERR_MSG_TYPE;
+ case RD_AP_MODIFIED:
+ return KRB5KRB_AP_ERR_MODIFIED;
+ case RD_AP_ORDER:
+ return KRB5KRB_AP_ERR_BADORDER;
+ case RD_AP_BADD:
+ return KRB5KRB_AP_ERR_BADADDR;
+ default:
+ return KRB5_SENDAUTH_BADRESPONSE;
+ }
+ }
+#endif
+
+ /*
+ * Assume that we're talking to a V5 recvauth; read in the
+ * the version string, and make sure it matches.
+ */
+
+ len = (int) ntohl(vers.len);
+
+ if (len < 0 || len > 255)
+ return KRB5_SENDAUTH_BADAUTHVERS;
+
+ buf = malloc(len);
+ if (!buf)
+ return ENOMEM;
+
+ length = krb5_net_read(context, fd, buf, len);
+ if (len != length) {
+ krb5_xfree(buf);
+ if (len < 0)
+ return errno;
+ else
+ return ECONNABORTED;
+ }
+
+ if (strcmp(buf, KRB_V5_SENDAUTH_VERS)) {
+ krb5_xfree(buf);
+ return KRB5_SENDAUTH_BADAUTHVERS;
+ }
+ krb5_xfree(buf);
+
+ *auth_sys = KRB5_RECVAUTH_V5;
+
+ retval = krb5_recvauth_version(context, auth_context, fdp, server,
+ flags | KRB5_RECVAUTH_SKIP_VERSION,
+ keytab, ticket, version);
+
+ return retval;
+}
+
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
diff --git a/src/lib/rpc/ChangeLog b/src/lib/rpc/ChangeLog
index 8467267..f1ffbeb 100644
--- a/src/lib/rpc/ChangeLog
+++ b/src/lib/rpc/ChangeLog
@@ -1,3 +1,67 @@
+2003-03-24 Tom Yu <tlyu@mit.edu>
+
+ * xdr_mem.c (xdrmem_create): Perform some additional size checks.
+ (xdrmem_getlong, xdrmem_putlong, xdrmem_getbytes): Check x_handy
+ prior to decrementing it.
+
+2002-08-12 Tom Yu <tlyu@mit.edu>
+
+ * xdr.c (xdr_string): Fix off-by-one error; we're not vulnerable,
+ since we don't call it.
+
+ * xdr_array.c (xdr_array): Account for elsize when checking
+ encoded array count.
+
+ [pullups from trunk]
+
+2001-12-18 Ken Raeburn <raeburn@mit.edu>
+
+ * configure.in: Check for strerror.
+ * clnt_perror.c (strerror) [!HAVE_STRERROR]: Define, with
+ out-of-range check using sys_nerr.
+ (sys_nerr) [!HAVE_STRERROR]: Declare at top level instead of in
+ clnt_spcreateerror.
+ (clnt_sperror, clnt_spcreateerror): Use strerror always. Skip
+ range check.
+
+2000-06-21 Tom Yu <tlyu@mit.edu>
+
+ * svc_auth_gssapi.c (_svcauth_gssapi): Missed a rename. From
+ Nathan Neulinger.
+
+2000-05-31 Ken Raeburn <raeburn@mit.edu>
+
+ * pmap_rmt.c (GIFCONF_BUFSIZE): New macro.
+ (getbroadcastnets): Use it for buffer size.
+ (clnt_broadcast): Make buffer at least that big.
+
+ * get_myaddress.c (get_myaddress): Increase buffer size.
+
+2000-05-18 Ken Raeburn <raeburn@mit.edu>
+
+ * auth_gssapi_misc.c (auth_gssapi_display_status_1): Don't pass a
+ gss_buffer_desc to fprintf.
+
+ * clnt_tcp.c (clnttcp_create): Initialize "ct".
+ * clnt_udp.c (clntudp_bufcreate): Initialize "cu".
+
+ * svc_auth_gssapi.c (_svcauth_gssapi, create_client,
+ destroy_client, dump_db, clean_client): Use %p format for
+ displaying pointers. Remove unused variables.
+
+2000-05-17 Ken Raeburn <raeburn@mit.edu>
+ Nalin Dahyabhai <nalin@redhat.com>
+
+ * clnt_perror.c (clnt_sperror): Don't overflow buffer "str" beyond
+ known allocation size.
+ * clnt_simple.c (gssrpc_callrpc): Don't overfill buffer "crp->oldhost".
+
+2000-05-03 Nalin Dahyabhai <nalin@redhat.com>
+
+ * clnt_perror.c (_buf): Use bigger buffer.
+ (clnt_spcreateerror): Don't overflow buffer "buf" beyond known
+ allocation size.
+
2000-02-22 Donn Cave <donn@u.washington.edu>
* Makefile.in (includes): Extract basename of header file to be
diff --git a/src/lib/rpc/auth_gssapi_misc.c b/src/lib/rpc/auth_gssapi_misc.c
index fd9393c..e7c38a8 100644
--- a/src/lib/rpc/auth_gssapi_misc.c
+++ b/src/lib/rpc/auth_gssapi_misc.c
@@ -162,15 +162,17 @@ static void auth_gssapi_display_status_1(m, code, type, rec)
auth_gssapi_display_status_1(m,gssstat,GSS_C_GSS_CODE,1);
auth_gssapi_display_status_1(m, minor_stat,
GSS_C_MECH_CODE, 1);
- } else
- fprintf(stderr,
- "GSS-API authentication error %s: recursive failure!\n",
- msg);
+ } else {
+ fputs ("GSS-API authentication error ", stderr);
+ fwrite (msg.value, msg.length, 1, stderr);
+ fputs (": recursive failure!\n", stderr);
+ }
return;
}
-
- fprintf(stderr, "GSS-API authentication error %s: %s\n", m,
- (char *)msg.value);
+
+ fprintf (stderr, "GSS-API authentication error %s: ", m);
+ fwrite (msg.value, msg.length, 1, stderr);
+ putc ('\n', stderr);
(void) gss_release_buffer(&minor_stat, &msg);
if (!msg_ctx)
diff --git a/src/lib/rpc/clnt_perror.c b/src/lib/rpc/clnt_perror.c
index 560cb27..7d05cc4 100644
--- a/src/lib/rpc/clnt_perror.c
+++ b/src/lib/rpc/clnt_perror.c
@@ -45,9 +45,14 @@ static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
#include <gssrpc/auth.h>
#include <gssrpc/clnt.h>
+#ifndef HAVE_STRERROR
#ifdef NEED_SYS_ERRLIST
extern char *sys_errlist[];
#endif
+extern int sys_nerr;
+#undef strerror
+#define strerror(N) (((N) > 0 && (N) < sys_nerr) ? sys_errlist[N] : (char *)0)
+#endif /* HAVE_STRERROR */
static char *auth_errmsg();
@@ -57,9 +62,8 @@ static char *buf;
static char *
_buf()
{
-
- if (buf == 0)
- buf = (char *)malloc(256);
+ if (buf == NULL)
+ buf = (char *)malloc(BUFSIZ);
return (buf);
}
@@ -74,17 +78,20 @@ clnt_sperror(rpch, s)
struct rpc_err e;
void clnt_perrno();
char *err;
- char *str = _buf();
+ char *bufstart = _buf();
+ char *str = bufstart;
char *strstart = str;
if (str == 0)
return (0);
CLNT_GETERR(rpch, &e);
- (void) sprintf(str, "%s: ", s);
+ strncpy (str, s, BUFSIZ - 1);
+ str[BUFSIZ - 1] = 0;
+ strncat (str, ": ", BUFSIZ - 1 - strlen (bufstart));
str += strlen(str);
-
- (void) strcpy(str, clnt_sperrno(e.re_status));
+ strncat (str, clnt_sperrno(e.re_status), BUFSIZ - 1 - strlen (bufstart));
+ str[BUFSIZ - 1] = '\0';
str += strlen(str);
switch (e.re_status) {
@@ -105,47 +112,64 @@ clnt_sperror(rpch, s)
case RPC_CANTSEND:
case RPC_CANTRECV:
- (void) sprintf(str, "; errno = %s",
- sys_errlist[e.re_errno]);
+ /* 10 for the string */
+ if(str - bufstart + 10 + strlen(strerror(e.re_errno)) < BUFSIZ)
+ (void) sprintf(str, "; errno = %s",
+ strerror(e.re_errno));
str += strlen(str);
break;
case RPC_VERSMISMATCH:
- (void) sprintf(str,
- "; low version = %lu, high version = %lu",
- e.re_vers.low, e.re_vers.high);
+ /* 33 for the string, 22 for the numbers */
+ if(str - bufstart + 33 + 22 < BUFSIZ)
+ (void) sprintf(str,
+ "; low version = %lu, high version = %lu",
+ (unsigned long) e.re_vers.low,
+ (unsigned long) e.re_vers.high);
str += strlen(str);
break;
case RPC_AUTHERROR:
err = auth_errmsg(e.re_why);
- (void) sprintf(str,"; why = ");
+ /* 8 for the string */
+ if(str - bufstart + 8 < BUFSIZ)
+ (void) sprintf(str,"; why = ");
str += strlen(str);
if (err != NULL) {
- (void) sprintf(str, "%s",err);
+ if(str - bufstart + strlen(err) < BUFSIZ)
+ (void) sprintf(str, "%s",err);
} else {
+ /* 33 for the string, 11 for the number */
+ if(str - bufstart + 33 + 11 < BUFSIZ)
(void) sprintf(str,
- "(unknown authentication error - %d)",
- (int) e.re_why);
+ "(unknown authentication error - %d)",
+ (int) e.re_why);
}
str += strlen(str);
break;
case RPC_PROGVERSMISMATCH:
- (void) sprintf(str,
- "; low version = %lu, high version = %lu",
- e.re_vers.low, e.re_vers.high);
+ /* 33 for the string, 22 for the numbers */
+ if(str - bufstart + 33 + 22 < BUFSIZ)
+ (void) sprintf(str,
+ "; low version = %lu, high version = %lu",
+ (unsigned long) e.re_vers.low,
+ (unsigned long) e.re_vers.high);
str += strlen(str);
break;
default: /* unknown */
- (void) sprintf(str,
- "; s1 = %lu, s2 = %lu",
- e.re_lb.s1, e.re_lb.s2);
+ /* 14 for the string, 22 for the numbers */
+ if(str - bufstart + 14 + 22 < BUFSIZ)
+ (void) sprintf(str,
+ "; s1 = %lu, s2 = %lu",
+ (unsigned long) e.re_lb.s1,
+ (unsigned long) e.re_lb.s2);
str += strlen(str);
break;
}
- (void) sprintf(str, "\n");
+ if(str - bufstart + 1 < BUFSIZ)
+ (void) sprintf(str, "\n");
return(strstart) ;
}
@@ -232,32 +256,34 @@ char *
clnt_spcreateerror(s)
char *s;
{
- extern int sys_nerr;
char *str = _buf();
if (str == 0)
return(0);
(void) sprintf(str, "%s: ", s);
- (void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat));
+ str[BUFSIZ - 1] = '\0';
+ (void) strncat(str, clnt_sperrno(rpc_createerr.cf_stat), BUFSIZ - 1);
switch (rpc_createerr.cf_stat) {
case RPC_PMAPFAILURE:
- (void) strcat(str, " - ");
- (void) strcat(str,
- clnt_sperrno(rpc_createerr.cf_error.re_status));
+ (void) strncat(str, " - ", BUFSIZ - 1 - strlen(str));
+ (void) strncat(str,
+ clnt_sperrno(rpc_createerr.cf_error.re_status),
+ BUFSIZ - 1 - strlen(str));
break;
case RPC_SYSTEMERROR:
- (void) strcat(str, " - ");
- if (rpc_createerr.cf_error.re_errno > 0
- && rpc_createerr.cf_error.re_errno < sys_nerr)
- (void) strcat(str,
- sys_errlist[rpc_createerr.cf_error.re_errno]);
- else
+ (void) strncat(str, " - ", BUFSIZ - 1 - strlen(str));
+ {
+ const char *m = strerror(rpc_createerr.cf_error.re_errno);
+ if (m)
+ (void) strncat(str, m, BUFSIZ - 1 - strlen(str));
+ else
(void) sprintf(&str[strlen(str)], "Error %d",
- rpc_createerr.cf_error.re_errno);
+ rpc_createerr.cf_error.re_errno);
+ }
break;
}
- (void) strcat(str, "\n");
+ (void) strncat(str, "\n", BUFSIZ - 1 - strlen(str));
return (str);
}
diff --git a/src/lib/rpc/clnt_simple.c b/src/lib/rpc/clnt_simple.c
index b3d2eb3..2f203d7 100644
--- a/src/lib/rpc/clnt_simple.c
+++ b/src/lib/rpc/clnt_simple.c
@@ -70,6 +70,8 @@ gssrpc_callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
}
if (crp->oldhost == NULL) {
crp->oldhost = mem_alloc(256);
+ if (crp->oldhost == 0)
+ return 0;
crp->oldhost[0] = 0;
crp->socket = RPC_ANYSOCK;
}
@@ -98,7 +100,8 @@ gssrpc_callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
crp->valid = 1;
crp->oldprognum = prognum;
crp->oldversnum = versnum;
- (void) strcpy(crp->oldhost, host);
+ (void) strncpy(crp->oldhost, host, 255);
+ crp->oldhost[255] = '\0';
}
tottimeout.tv_sec = 25;
tottimeout.tv_usec = 0;
diff --git a/src/lib/rpc/clnt_tcp.c b/src/lib/rpc/clnt_tcp.c
index 4e10a48..f87da78 100644
--- a/src/lib/rpc/clnt_tcp.c
+++ b/src/lib/rpc/clnt_tcp.c
@@ -116,7 +116,7 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
unsigned int recvsz;
{
CLIENT *h;
- register struct ct_data *ct;
+ register struct ct_data *ct = 0;
struct timeval now;
struct rpc_msg call_msg;
diff --git a/src/lib/rpc/clnt_udp.c b/src/lib/rpc/clnt_udp.c
index 6046942..df3945a 100644
--- a/src/lib/rpc/clnt_udp.c
+++ b/src/lib/rpc/clnt_udp.c
@@ -117,7 +117,7 @@ clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
unsigned int recvsz;
{
CLIENT *cl;
- register struct cu_data *cu;
+ register struct cu_data *cu = 0;
struct timeval now;
struct rpc_msg call_msg;
diff --git a/src/lib/rpc/configure.in b/src/lib/rpc/configure.in
index f4b9f9e..a4e2cfd 100644
--- a/src/lib/rpc/configure.in
+++ b/src/lib/rpc/configure.in
@@ -49,6 +49,8 @@ AC_CHECK_SIZEOF(long)
SIZEOF_LONG=$ac_cv_sizeof_long
AC_SUBST(SIZEOF_LONG)
+AC_CHECK_FUNCS(strerror)
+
AC_MSG_CHECKING([return type of setrpcent])
AC_CACHE_VAL(k5_cv_type_setrpcent,
[AC_TRY_COMPILE([#include <netdb.h>
diff --git a/src/lib/rpc/get_myaddress.c b/src/lib/rpc/get_myaddress.c
index 4c9bf29..13bafa0 100644
--- a/src/lib/rpc/get_myaddress.c
+++ b/src/lib/rpc/get_myaddress.c
@@ -81,7 +81,7 @@ get_myaddress(addr)
struct sockaddr_in *addr;
{
int s;
- char buf[BUFSIZ];
+ char buf[256 * sizeof (struct ifconf)];
struct ifconf ifc;
struct ifreq ifreq, *ifr;
int len;
diff --git a/src/lib/rpc/pmap_rmt.c b/src/lib/rpc/pmap_rmt.c
index 7cafe6e..dc9735d 100644
--- a/src/lib/rpc/pmap_rmt.c
+++ b/src/lib/rpc/pmap_rmt.c
@@ -165,6 +165,8 @@ xdr_rmtcallres(xdrs, crp)
* routines which only support udp/ip .
*/
+#define GIFCONF_BUFSIZE (256 * sizeof (struct ifconf))
+
static int
getbroadcastnets(addrs, sock, buf)
struct in_addr *addrs;
@@ -176,8 +178,9 @@ getbroadcastnets(addrs, sock, buf)
struct sockaddr_in *sin;
int n, i;
- ifc.ifc_len = UDPMSGSIZE;
+ ifc.ifc_len = GIFCONF_BUFSIZE;
ifc.ifc_buf = buf;
+ memset (buf, 0, GIFCONF_BUFSIZE);
if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
perror("broadcast: ioctl (get interface configuration)");
return (0);
@@ -255,7 +258,11 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
struct rmtcallres r;
struct rpc_msg msg;
struct timeval t;
- char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
+ char outbuf[MAX_BROADCAST_SIZE];
+#ifndef MAX
+#define MAX(A,B) ((A)<(B)?(B):(A))
+#endif
+ char inbuf[MAX (UDPMSGSIZE, GIFCONF_BUFSIZE)];
/*
* initialization: create a socket, a broadcast address, and
diff --git a/src/lib/rpc/svc_auth_gssapi.c b/src/lib/rpc/svc_auth_gssapi.c
index 827596a..9d831ad 100644
--- a/src/lib/rpc/svc_auth_gssapi.c
+++ b/src/lib/rpc/svc_auth_gssapi.c
@@ -134,7 +134,6 @@ enum auth_stat _svcauth_gssapi(rqst, msg, no_dispatch)
svc_auth_gssapi_data *client_data;
int ret_flags, ret, i;
rpc_u_int32 seq_num;
- int flag;
PRINTF(("svcauth_gssapi: starting\n"));
@@ -307,8 +306,6 @@ enum auth_stat _svcauth_gssapi(rqst, msg, no_dispatch)
#endif
if (call_arg.version >= 3) {
- int len;
-
memset(&bindings, 0, sizeof(bindings));
bindings.application_data.length = 0;
bindings.initiator_addrtype = GSS_C_AF_INET;
@@ -551,7 +548,7 @@ enum auth_stat _svcauth_gssapi(rqst, msg, no_dispatch)
&call_arg)) {
PRINTF(("svcauth_gssapi: cannot decode args\n"));
LOG_MISCERR("protocol error in call arguments");
- xdr_free(xdr_authgssapi_init_arg, &call_arg);
+ gssrpc_xdr_free(xdr_authgssapi_init_arg, &call_arg);
ret = AUTH_BADCRED;
goto error;
}
@@ -657,7 +654,6 @@ static svc_auth_gssapi_data *create_client()
client_list *c;
svc_auth_gssapi_data *client_data;
static int client_key = 1;
- int ret;
PRINTF(("svcauth_gssapi: empty creds, creating\n"));
@@ -665,7 +661,7 @@ static svc_auth_gssapi_data *create_client()
if (client_data == NULL)
return NULL;
memset((char *) client_data, 0, sizeof(*client_data));
- L_PRINTF(2, ("create_client: new client_data = %#x\n", client_data));
+ L_PRINTF(2, ("create_client: new client_data = %p\n", client_data));
/* set up client data structure */
client_data->established = 0;
@@ -783,10 +779,9 @@ static void destroy_client(client_data)
OM_uint32 gssstat, minor_stat;
gss_buffer_desc out_buf;
client_list *c, *c2;
- int ret;
PRINTF(("destroy_client: destroying client_data\n"));
- L_PRINTF(2, ("destroy_client: client_data = %#x\n", client_data));
+ L_PRINTF(2, ("destroy_client: client_data = %p\n", client_data));
#ifdef DEBUG_GSSAPI
if (svc_debug_gssapi >= 3)
@@ -852,7 +847,7 @@ static void dump_db(msg)
c = clients;
while (c) {
client_data = c->client;
- L_PRINTF(3, ("\tclient_data = %#x, exp = %d\n",
+ L_PRINTF(3, ("\tclient_data = %p, exp = %d\n",
client_data, client_data->expiration));
c = c->next;
}
@@ -871,7 +866,7 @@ static void clean_client()
while (c) {
client_data = c->client;
- L_PRINTF(2, ("clean_client: client_data = %#x\n",
+ L_PRINTF(2, ("clean_client: client_data = %p\n",
client_data));
if (client_data->expiration < time(0)) {
@@ -884,7 +879,6 @@ static void clean_client()
}
}
-done:
PRINTF(("clean_client: done\n"));
}
diff --git a/src/lib/rpc/unit-test/ChangeLog b/src/lib/rpc/unit-test/ChangeLog
index 1c3d401..920304c 100644
--- a/src/lib/rpc/unit-test/ChangeLog
+++ b/src/lib/rpc/unit-test/ChangeLog
@@ -1,3 +1,22 @@
+2002-11-07 Tom Yu <tlyu@mit.edu>
+
+ * rpc_test.0/expire.exp (overlap): Add another call to
+ flush_server to make a race condition a little less likely. There
+ really should be better synchronization, as this test suite is
+ just full of race conditions waiting to happen.
+ [pullup from trunk]
+
+2000-06-21 Tom Yu <tlyu@mit.edu>
+
+ * server.c: Include gssrpc/pmap_clnt.h in order to get renaming of
+ pmap_unset(). From Nathan Neulinger.
+
+2000-06-08 Tom Yu <tlyu@mit.edu>
+
+ * lib/helpers.exp (kinit): Move "expect eof" into the commands
+ that send the prompt. Don't "expect eof" outside of the main
+ expect, as the main expect may have already read eof.
+
2000-02-15 Tom Yu <tlyu@mit.edu>
* server.c: Add code to set a signal handler for SIGHUP and a few
diff --git a/src/lib/rpc/unit-test/lib/helpers.exp b/src/lib/rpc/unit-test/lib/helpers.exp
index 3d7b167..c4b76aa 100644
--- a/src/lib/rpc/unit-test/lib/helpers.exp
+++ b/src/lib/rpc/unit-test/lib/helpers.exp
@@ -23,10 +23,10 @@ proc kinit {princ pass lifetime} {
spawn -noecho $kinit -5 -l $lifetime $princ
expect {
- -re "Password for $princ.*: " { send "$pass\n" }
+ -re "Password for $princ.*: " { send "$pass\n"; expect eof }
timeout { perror "Timeout waiting for kinit"; close }
+ eof
}
- expect { eof {} }
set ret [wait]
if {[lindex $ret $wait_error_index] == -1} {
@@ -117,7 +117,7 @@ proc wait_client {testname ccname id status} {
set env(KRB5CCNAME) FILE:/tmp/krb5cc_rpc_test_$ccname
if {[catch "exec $kdestroy -5"] != 0} {
- error "$testname: cannot destroy client $ccname ccache"
+ perror "$testname: cannot destroy client $ccname ccache"
}
unset env(KRB5CCNAME)
diff --git a/src/lib/rpc/unit-test/rpc_test.0/expire.exp b/src/lib/rpc/unit-test/rpc_test.0/expire.exp
index 6f7aa93..5c33ffd 100644
--- a/src/lib/rpc/unit-test/rpc_test.0/expire.exp
+++ b/src/lib/rpc/unit-test/rpc_test.0/expire.exp
@@ -38,6 +38,8 @@ proc overlap {} {
eof_client expire 1 $client1_id 0
eof_client expire 2 $client2_id 0
eof_client expire 3 $client3_id 0
+
+ flush_server
}
overlap
diff --git a/src/lib/rpc/unit-test/server.c b/src/lib/rpc/unit-test/server.c
index 7270ea4..32f5de3 100644
--- a/src/lib/rpc/unit-test/server.c
+++ b/src/lib/rpc/unit-test/server.c
@@ -14,6 +14,7 @@ static char *rcsid = "$Header$";
#include <string.h>
#include <signal.h>
#include <gssrpc/rpc.h>
+#include <gssrpc/pmap_clnt.h>
#include <arpa/inet.h> /* inet_ntoa */
#include <gssapi/gssapi.h>
#include <gssapi/gssapi_generic.h>
diff --git a/src/lib/rpc/xdr.c b/src/lib/rpc/xdr.c
index df277fe..168aba1 100644
--- a/src/lib/rpc/xdr.c
+++ b/src/lib/rpc/xdr.c
@@ -623,7 +623,7 @@ xdr_string(xdrs, cpp, maxsize)
if (! xdr_u_int(xdrs, &size)) {
return (FALSE);
}
- if (size > maxsize) {
+ if (size >= maxsize) {
return (FALSE);
}
nodesize = size + 1;
diff --git a/src/lib/rpc/xdr_array.c b/src/lib/rpc/xdr_array.c
index 7c4c70e..9d2674e 100644
--- a/src/lib/rpc/xdr_array.c
+++ b/src/lib/rpc/xdr_array.c
@@ -75,7 +75,8 @@ xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc)
return (FALSE);
}
c = *sizep;
- if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
+ if ((c > maxsize || c > LASTUNSIGNED / elsize)
+ && (xdrs->x_op != XDR_FREE)) {
return (FALSE);
}
nodesize = c * elsize;
diff --git a/src/lib/rpc/xdr_mem.c b/src/lib/rpc/xdr_mem.c
index d32b391..506bc75 100644
--- a/src/lib/rpc/xdr_mem.c
+++ b/src/lib/rpc/xdr_mem.c
@@ -47,6 +47,7 @@ static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
#include <gssrpc/xdr.h>
#include <netinet/in.h>
#include <stdio.h>
+#include <limits.h>
static bool_t xdrmem_getlong();
static bool_t xdrmem_putlong();
@@ -83,7 +84,7 @@ xdrmem_create(xdrs, addr, size, op)
xdrs->x_op = op;
xdrs->x_ops = &xdrmem_ops;
xdrs->x_private = xdrs->x_base = addr;
- xdrs->x_handy = size;
+ xdrs->x_handy = (size > INT_MAX) ? INT_MAX : size; /* XXX */
}
static void
@@ -98,8 +99,10 @@ xdrmem_getlong(xdrs, lp)
long *lp;
{
- if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0)
+ if (xdrs->x_handy < sizeof(rpc_int32))
return (FALSE);
+ else
+ xdrs->x_handy -= sizeof(rpc_int32);
*lp = (long)ntohl(*((rpc_u_int32 *)(xdrs->x_private)));
xdrs->x_private += sizeof(rpc_int32);
return (TRUE);
@@ -111,8 +114,10 @@ xdrmem_putlong(xdrs, lp)
long *lp;
{
- if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0)
+ if (xdrs->x_handy < sizeof(rpc_int32))
return (FALSE);
+ else
+ xdrs->x_handy -= sizeof(rpc_int32);
*(rpc_int32 *)xdrs->x_private = (rpc_int32)htonl((rpc_u_int32)(*lp));
xdrs->x_private += sizeof(rpc_int32);
return (TRUE);
@@ -125,8 +130,10 @@ xdrmem_getbytes(xdrs, addr, len)
register unsigned int len;
{
- if ((xdrs->x_handy -= len) < 0)
+ if (xdrs->x_handy < len)
return (FALSE);
+ else
+ xdrs->x_handy -= len;
memmove(addr, xdrs->x_private, len);
xdrs->x_private += len;
return (TRUE);
@@ -139,8 +146,10 @@ xdrmem_putbytes(xdrs, addr, len)
register unsigned int len;
{
- if ((xdrs->x_handy -= len) < 0)
+ if (xdrs->x_handy < len)
return (FALSE);
+ else
+ xdrs->x_handy -= len;
memmove(xdrs->x_private, addr, len);
xdrs->x_private += len;
return (TRUE);
@@ -179,7 +188,7 @@ xdrmem_inline(xdrs, len)
{
rpc_int32 *buf = 0;
- if (xdrs->x_handy >= len) {
+ if (len >= 0 && xdrs->x_handy >= len) {
xdrs->x_handy -= len;
buf = (rpc_int32 *) xdrs->x_private;
xdrs->x_private += len;
diff --git a/src/lib/win_glue.c b/src/lib/win_glue.c
index ab3e1a1..6dc9e10 100644
--- a/src/lib/win_glue.c
+++ b/src/lib/win_glue.c
@@ -90,8 +90,13 @@ extern void krb5_stdcc_shutdown();
* arbitrary third party applications. If there is an error, or we
* decide that we should not version check the calling application
* then VSflag will be FALSE when the function returns.
+ *
+ * The buffers passed into this function must be at least
+ * APPVERINFO_SIZE bytes long.
*/
-
+
+#define APPVERINFO_SIZE 256
+
void GetCallingAppVerInfo( char *AppTitle, char *AppVer, char *AppIni,
BOOL *VSflag)
{
@@ -187,11 +192,15 @@ void GetCallingAppVerInfo( char *AppTitle, char *AppVer, char *AppIni,
* We don't have a way to determine that INI file of the
* application at the moment so let's just use krb5.ini
*/
- strcpy( locAppIni, KERBEROS_INI );
+ strncpy( locAppIni, KERBEROS_INI, sizeof(locAppIni) - 1 );
+ locAppIni[ sizeof(locAppIni) - 1 ] = '\0';
- strcpy( AppTitle, locAppTitle);
- strcpy( AppVer, locAppVer);
- strcpy( AppIni, locAppIni);
+ strncpy( AppTitle, locAppTitle, APPVERINFO_SIZE);
+ AppTitle[APPVERINFO_SIZE - 1] = '\0';
+ strncpy( AppVer, locAppVer, APPVERINFO_SIZE);
+ AppVer[APPVERINFO_SIZE - 1] = '\0';
+ strncpy( AppIni, locAppIni, APPVERINFO_SIZE);
+ AppIni[APPVERINFO_SIZE - 1] = '\0';
/*
* We also need to determine if we want to suppress version
@@ -271,9 +280,10 @@ static krb5_error_code do_timebomb()
if (first_time) {
sprintf(buf, "Your version of %s has expired.\n",
TIMEBOMB_PRODUCT);
- strcat(buf, "Please upgrade it.");
+ buf[sizeof(buf) - 1] = '\0';
+ strncat(buf, "Please upgrade it.", sizeof(buf) - 1 - strlen(buf));
#ifdef TIMEBOMB_INFO
- strcat(buf, TIMEBOMB_INFO);
+ strncat(buf, TIMEBOMB_INFO, sizeof(buf) - 1 - strlen(buf));
#endif
MessageBox(NULL, buf, "", MB_OK);
first_time = 0;
@@ -285,9 +295,9 @@ static krb5_error_code do_timebomb()
if (first_time) {
sprintf(buf, "Your version of %s will expire in %ld days.\n",
TIMEBOMB_PRODUCT, timeleft);
- strcat(buf, "Please upgrade it soon.");
+ strncat(buf, "Please upgrade it soon.", sizeof(buf) - 1 - strlen(buf));
#ifdef TIMEBOMB_INFO
- strcat(buf, TIMEBOMB_INFO);
+ strncat(buf, TIMEBOMB_INFO, sizeof(buf) - 1 - strlen(buf));
#endif
MessageBox(NULL, buf, "", MB_OK);
first_time = 0;
@@ -323,9 +333,9 @@ krb5_error_code krb5_vercheck()
if (CallVersionServer(APP_TITLE, APP_VER, APP_INI, NULL))
return VERSERV_ERROR;
#else
- char AppTitle[256];
- char AppVer[256];
- char AppIni[256];
+ char AppTitle[APPVERINFO_SIZE];
+ char AppVer[APPVERINFO_SIZE];
+ char AppIni[APPVERINFO_SIZE];
BOOL VSflag=TRUE;
GetCallingAppVerInfo( AppTitle, AppVer, AppIni, &VSflag);