summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/cmd-inet/usr.bin/rdist/main.c5
-rw-r--r--usr/src/cmd/gss/etc/kdc.conf9
-rw-r--r--usr/src/cmd/krb5/kadmin/Makefile4
-rw-r--r--usr/src/cmd/krb5/kadmin/cli/kadmin.c14
-rw-r--r--usr/src/cmd/krb5/kadmin/cli/kadmin_rmt.c5
-rw-r--r--usr/src/cmd/krb5/kadmin/cli/keytab.c3
-rw-r--r--usr/src/cmd/krb5/kadmin/dbutil/dump.c4
-rw-r--r--usr/src/cmd/krb5/kadmin/dbutil/kadm5_create.c14
-rw-r--r--usr/src/cmd/krb5/kadmin/dbutil/kdb5_stash.c7
-rw-r--r--usr/src/cmd/krb5/kadmin/dbutil/kdb5_util.c22
-rw-r--r--[-rwxr-xr-x]usr/src/cmd/krb5/kadmin/kdcmgr/kdcmgr.sh25
-rw-r--r--usr/src/cmd/krb5/kadmin/kpasswd/kpasswd.c7
-rw-r--r--usr/src/cmd/krb5/kadmin/server/kadm_rpc_svc.c87
-rw-r--r--usr/src/cmd/krb5/kadmin/server/misc.c41
-rw-r--r--usr/src/cmd/krb5/kadmin/server/misc.h22
-rw-r--r--usr/src/cmd/krb5/kadmin/server/ovsec_kadmd.c870
-rw-r--r--usr/src/cmd/krb5/kadmin/server/server_stubs.c394
-rw-r--r--usr/src/cmd/krb5/kdestroy/kdestroy.c12
-rw-r--r--usr/src/cmd/krb5/kinit/kinit.c207
-rw-r--r--usr/src/cmd/krb5/klist/Makefile5
-rw-r--r--usr/src/cmd/krb5/krb5-config/krb5-config.sh5
-rw-r--r--usr/src/cmd/krb5/krb5kdc/dispatch.c11
-rw-r--r--usr/src/cmd/krb5/krb5kdc/do_as_req.c42
-rw-r--r--usr/src/cmd/krb5/krb5kdc/do_tgs_req.c35
-rw-r--r--usr/src/cmd/krb5/krb5kdc/kdc_preauth.c1001
-rw-r--r--usr/src/cmd/krb5/krb5kdc/kdc_util.c39
-rw-r--r--usr/src/cmd/krb5/krb5kdc/kdc_util.h31
-rw-r--r--usr/src/cmd/krb5/krb5kdc/main.c12
-rw-r--r--usr/src/cmd/krb5/krb5kdc/network.c65
-rw-r--r--usr/src/cmd/krb5/krb5kdc/replay.c20
-rw-r--r--usr/src/cmd/krb5/ldap_util/kdb5_ldap_util.c4
-rw-r--r--usr/src/cmd/krb5/slave/kpropd.c18
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/Makefile.com12
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/aes/aes_s2k.c29
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/coll_proof_cksum.c7
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/des/afsstring2key.c11
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/dk/stringtokey.c37
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/enctype_compare.c7
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/hash_provider/hash_md5.c25
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/hash_provider/hash_sha1.c14
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/keyed_checksum_types.c11
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/keyed_cksum.c26
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/keyhash_provider/hmac_md5.c28
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/keyhash_provider/k5_md5des.c27
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/keylengths.c62
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/make_random_key.c19
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/md4/md4.c45
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/old/des_stringtokey.c38
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/old_api_glue.c286
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/pbkdf2.c12
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/random_to_key.c75
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/state.c11
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/string_to_enctype.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/string_to_key.c54
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/crypto/valid_enctype.c15
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/et/com_err.c120
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/et/internal.h3
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/et/krb5_err.c44
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/et/mit-sipb-copyright.h4
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/autoconf.h20
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/cache-addrinfo.h129
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/cm.h45
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/db.h3
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/fake-addrinfo.h1186
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/k5-int-pkinit.h271
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/krb5/adm_proto.h161
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/krb5/kdb.h11
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/locate_plugin.h61
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/osconf.h120
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/port-sockets.h9
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/preauth_plugin.h508
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/include/socket-utils.h10
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_decode.c5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_encode.c68
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_get.c4
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_decode.c479
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_decode.h47
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_encode.c444
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_encode.h69
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krb5_decode.c157
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krb5_encode.c129
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krbasn1.h6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc-int.h3
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_file.c291
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_memory.c193
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_retr.c153
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccbase.c188
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccdefault.c85
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccdefops.c17
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccfns.c52
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_file.c49
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_srvtab.c8
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktadd.c13
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktbase.c25
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktdefault.c11
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktfns.c21
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktfr_entry.c14
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktremove.c13
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/read_servi.c36
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/addr_order.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/addr_srch.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/appdefault.c27
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/auth_con.c270
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/bld_pr_ext.c5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/bld_princ.c13
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/chk_trans.c139
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/chpw.c59
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/conv_princ.c67
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_addrs.c7
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_creds.c15
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_data.c13
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_tick.c11
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/cp_key_cnt.c11
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/decode_kdc.c5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/encode_kdc.c5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/free_rtree.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/fwd_tgt.c97
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gc_frm_kdc.c53
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gc_via_tkt.c30
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gen_seqnum.c7
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gen_subkey.c8
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/get_creds.c54
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/get_in_tkt.c593
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_keytab.c79
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_opt.c387
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_pwd.c260
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/int-proto.h12
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/kdc_rep_dc.c20
-rw-r--r--[-rwxr-xr-x]usr/src/lib/gss_mechs/mech_krb5/krb5/krb/krb5_libinit.c28
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_cred.c45
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_priv.c64
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_rep.c45
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_req.c19
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_req_ext.c91
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_safe.c70
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/pr_to_salt.c5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/preauth.c581
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/preauth2.c881
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_cred.c84
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_error.c4
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_priv.c53
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_rep.c50
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_req.c15
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_req_dec.c226
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_safe.c65
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/recvauth.c26
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/send_tgs.c43
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/sendauth.c55
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/set_realm.c7
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/srv_rcache.c16
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/str_conv.c21
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/tgtname.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/valid_times.c11
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/vfy_increds.c36
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/accessor.c32
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/an_to_ln.c79
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/changepw.c524
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/def_realm.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnsglue.c37
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnsglue.h15
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnssrv.c2
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/free_hstrl.c3
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/free_krbhs.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/full_ipadr.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/gen_rname.c7
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/genaddrs.c22
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/gmt_mktime.c46
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/hostaddr.c11
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/hst_realm.c13
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/krbfileio.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/ktdefname.c20
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/kuserok.c82
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/localaddr.c3
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/locate_kdc.c554
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/lock_file.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/mk_faddr.c4
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/net_read.c5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/net_write.c5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/os-proto.h5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/osconfig.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/port2ip.c4
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/prompter.c5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/read_msg.c15
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/read_pwd.c10
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/sendto_kdc.c584
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/sn2princ.c247
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/unlck_file.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/ustime.c5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/write_msg.c7
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/posix/daemon.c11
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc-int.h5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_base.c113
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_base.h2
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_conv.c5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_file.c203
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_file.h16
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_io.c227
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_mem.h5
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_none.c50
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rcdef.c16
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/ser_rc.c12
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mapfile-vers16
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/accept_sec_context.c422
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred.c64
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/add_cred.c8
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/disp_com_err_status.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/export_sec_context.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.c7
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/indicate_mechs.c4
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c48
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/inq_cred.c9
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/inq_names.c7
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/krb5_gss_glue.c9
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/process_context_token.c6
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid.c7
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/set_ccache.c4
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/profile/prof_file.c74
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/profile/prof_get.c19
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/profile/prof_init.c98
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/profile/prof_int.h50
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/profile/prof_parse.c23
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/profile/prof_tree.c20
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/support/fake-addrinfo.c1313
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/support/init-addrinfo.c70
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/support/plugins.c29
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/support/threads.c293
-rw-r--r--usr/src/lib/krb5/kadm5/adb.h28
-rw-r--r--usr/src/lib/krb5/kadm5/admin.h14
-rw-r--r--usr/src/lib/krb5/kadm5/admin_xdr.h7
-rw-r--r--usr/src/lib/krb5/kadm5/alt_prof.c223
-rw-r--r--usr/src/lib/krb5/kadm5/chpass_util.c22
-rw-r--r--usr/src/lib/krb5/kadm5/clnt/changepw.c13
-rw-r--r--usr/src/lib/krb5/kadm5/clnt/chpw.c373
-rw-r--r--usr/src/lib/krb5/kadm5/clnt/client_init.c46
-rw-r--r--usr/src/lib/krb5/kadm5/clnt/client_internal.h9
-rw-r--r--usr/src/lib/krb5/kadm5/clnt/client_principal.c40
-rw-r--r--usr/src/lib/krb5/kadm5/clnt/client_rpc.c372
-rw-r--r--usr/src/lib/krb5/kadm5/clnt/clnt_policy.c21
-rw-r--r--usr/src/lib/krb5/kadm5/clnt/clnt_privs.c63
-rw-r--r--usr/src/lib/krb5/kadm5/clnt/logger.c256
-rw-r--r--usr/src/lib/krb5/kadm5/clnt/mapfile-vers45
-rw-r--r--usr/src/lib/krb5/kadm5/get_admhst.c113
-rw-r--r--usr/src/lib/krb5/kadm5/kadm_host_srv_names.c3
-rw-r--r--usr/src/lib/krb5/kadm5/kadm_rpc.h240
-rw-r--r--usr/src/lib/krb5/kadm5/kadm_rpc_xdr.c19
-rw-r--r--usr/src/lib/krb5/kadm5/misc_free.c8
-rw-r--r--usr/src/lib/krb5/kadm5/server_internal.h13
-rw-r--r--usr/src/lib/krb5/kadm5/srv/adb_xdr.c10
-rw-r--r--usr/src/lib/krb5/kadm5/srv/logger.c183
-rw-r--r--usr/src/lib/krb5/kadm5/srv/server_acl.c13
-rw-r--r--usr/src/lib/krb5/kadm5/srv/server_acl.h10
-rw-r--r--usr/src/lib/krb5/kadm5/srv/server_dict.c9
-rw-r--r--usr/src/lib/krb5/kadm5/srv/server_init.c11
-rw-r--r--usr/src/lib/krb5/kadm5/srv/server_kdb.c15
-rw-r--r--usr/src/lib/krb5/kadm5/srv/server_misc.c5
-rw-r--r--usr/src/lib/krb5/kadm5/srv/svr_chpass_util.c6
-rw-r--r--usr/src/lib/krb5/kadm5/srv/svr_iters.c7
-rw-r--r--usr/src/lib/krb5/kadm5/srv/svr_misc_free.c6
-rw-r--r--usr/src/lib/krb5/kadm5/srv/svr_policy.c15
-rw-r--r--usr/src/lib/krb5/kadm5/srv/svr_principal.c512
-rw-r--r--usr/src/lib/krb5/kadm5/srv/xdr_alloc.c116
-rw-r--r--usr/src/lib/krb5/kadm5/str_conv.c5
-rw-r--r--usr/src/lib/krb5/kdb/decrypt_key.c14
-rw-r--r--usr/src/lib/krb5/kdb/encrypt_key.c16
-rw-r--r--usr/src/lib/krb5/kdb/kdb_cpw.c133
-rw-r--r--usr/src/lib/krb5/kdb/keytab.c7
-rw-r--r--usr/src/lib/krb5/plugins/Makefile6
-rw-r--r--usr/src/lib/krb5/plugins/kdb/db2/adb_policy.c5
-rw-r--r--usr/src/lib/krb5/plugins/kdb/db2/db2_exp.c3
-rw-r--r--usr/src/lib/krb5/plugins/kdb/db2/kdb_db2.c4
-rw-r--r--usr/src/lib/krb5/plugins/kdb/db2/libdb2/hash/dbm.c7
-rw-r--r--usr/src/lib/krb5/plugins/kdb/db2/libdb2/hash/hash.c8
-rw-r--r--usr/src/lib/krb5/plugins/kdb/db2/libdb2/include/db-int.h5
-rw-r--r--usr/src/lib/krb5/plugins/kdb/db2/libdb2/include/db-ndbm.h5
-rw-r--r--usr/src/lib/krb5/plugins/kdb/db2/libdb2/mpool/mpool.c7
-rw-r--r--usr/src/lib/krb5/plugins/kdb/db2/pol_xdr.c4
-rw-r--r--usr/src/lib/krb5/plugins/kdb/ldap/Makefile.com4
-rw-r--r--usr/src/lib/krb5/plugins/kdb/ldap/ldap_exp.c5
-rw-r--r--usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c6
-rw-r--r--usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h9
-rw-r--r--usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c8
-rw-r--r--usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c8
-rw-r--r--usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c16
-rw-r--r--usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c4
-rw-r--r--usr/src/lib/krb5/plugins/preauth/Makefile49
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/Makefile55
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/Makefile.com94
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/i386/Makefile29
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/mapfile-vers37
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit.h364
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_accessor.c118
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_accessor.h83
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_clnt.c1510
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto.h624
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c5982
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h273
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_identity.c685
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_lib.c479
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_matching.c843
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_profile.c380
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_srv.c1426
-rw-r--r--usr/src/lib/krb5/plugins/preauth/pkinit/sparc/Makefile29
-rw-r--r--usr/src/pkgdefs/SUNWkrbu/prototype_com7
-rw-r--r--usr/src/pkgdefs/etc/exception_list_i3862
-rw-r--r--usr/src/pkgdefs/etc/exception_list_sparc2
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/block_size.c7
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/checksum_length.c15
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/cksumtypes.c49
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/combine_keys.c10
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/decrypt.c15
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/default_state.c19
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/des/d3_cbc.c22
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_cbc.c5
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_cksum.c11
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_parity.c9
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/des/weak_key.c15
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/checksum.c10
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/derive.c10
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/dk_decrypt.c76
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/dk_encrypt.c30
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/enc_provider/des.c11
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/enc_provider/des3.c9
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/encrypt.c11
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/encrypt_length.c7
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/etypes.c106
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/hash_provider/hash_crc32.c14
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/hash_provider/hash_ksha1.c5
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/hmac.c25
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/keyhash_provider/descbc.c11
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/keyhash_provider/k5_kmd5des.c7
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/make_checksum.c25
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/mandatory_sumtype.c8
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/nfold.c16
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/old/old_decrypt.c22
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/old/old_encrypt.c26
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/raw/raw_decrypt.c24
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/raw/raw_encrypt.c21
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/crypto/verify_checksum.c11
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/aes_s2k.h4
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/auth_con.h5
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/cksumtypes.h3
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/crc-32.h38
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/des_int.h96
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/dk.h39
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/enc_provider.h11
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h19
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h12
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_generic.h6
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/hash_provider.h9
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h1238
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-load_16.h49
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-load_32.h49
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-load_64.h51
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-store_16.h50
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-store_32.h51
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-store_64.h56
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h175
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/k5-thread.h65
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/keyhash_provider.h17
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h694
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/old.h32
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/raw.h21
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_auth.c12
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_cksum.c10
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_key.c6
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_princ.c24
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/init_ctx.c159
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/kfree.c20
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/parse.c80
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_actx.c16
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_adata.c15
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_addr.c13
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_auth.c12
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_cksum.c13
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_ctx.c16
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_key.c8
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_princ.c19
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/serialize.c45
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/unparse.c13
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/os/c_ustime.c10
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/os/init_os_ctx.c116
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/os/timeofday.c29
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/os/toffset.c29
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c7
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c21
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/import_sec_context.c4
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/k5seal.c346
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/k5sealv3.c35
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/k5unseal.c95
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/ser_sctx.c9
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/sign.c7
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/unseal.c9
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/util_crypt.c42
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/util_ordering.c42
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/util_seed.c4
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/util_validate.c8
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/verify.c9
397 files changed, 31235 insertions, 9385 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.bin/rdist/main.c b/usr/src/cmd/cmd-inet/usr.bin/rdist/main.c
index bcd41aa064..0d96b1d348 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/rdist/main.c
+++ b/usr/src/cmd/cmd-inet/usr.bin/rdist/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -16,13 +16,12 @@
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include "defs.h"
#include <string.h>
#include <syslog.h>
-#include <krb5defs.h>
#include <k5-int.h>
+#include <krb5defs.h>
#include <priv_utils.h>
#define NHOSTS 100
diff --git a/usr/src/cmd/gss/etc/kdc.conf b/usr/src/cmd/gss/etc/kdc.conf
index 3248586f11..b5afae1d36 100644
--- a/usr/src/cmd/gss/etc/kdc.conf
+++ b/usr/src/cmd/gss/etc/kdc.conf
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,10 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 1998-2002 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
[kdcdefaults]
kdc_ports = 88,750
@@ -32,7 +30,6 @@
___default_realm___ = {
profile = /etc/krb5/krb5.conf
database_name = /var/krb5/principal
- admin_keytab = /etc/krb5/kadm5.keytab
acl_file = /etc/krb5/kadm5.acl
kadmind_port = 749
max_life = 8h 0m 0s
diff --git a/usr/src/cmd/krb5/kadmin/Makefile b/usr/src/cmd/krb5/kadmin/Makefile
index 73f1fb0eb4..22a8259cc5 100644
--- a/usr/src/cmd/krb5/kadmin/Makefile
+++ b/usr/src/cmd/krb5/kadmin/Makefile
@@ -18,11 +18,9 @@
#
# CDDL HEADER END
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# cmd/krb5/kadmin/Makefile
include ../../Makefile.cmd
diff --git a/usr/src/cmd/krb5/kadmin/cli/kadmin.c b/usr/src/cmd/krb5/kadmin/cli/kadmin.c
index 43ddd4b052..ab086d6eef 100644
--- a/usr/src/cmd/krb5/kadmin/cli/kadmin.c
+++ b/usr/src/cmd/krb5/kadmin/cli/kadmin.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1994 by the Massachusetts Institute of Technology.
@@ -32,7 +31,6 @@
* the OVSecure library
*/
-#include <krb5.h>
#include <kadm5/admin.h>
#include <krb5/adm_proto.h>
#include <stdio.h>
@@ -45,6 +43,7 @@
#include <time.h>
#include "kadmin.h"
#include <libintl.h>
+#include <krb5.h>
/*
* Solaris: the following are needed for paging
@@ -571,10 +570,11 @@ char *kadmin_startup(argc, argv)
/* register the WRFILE keytab type and set it as the default */
{
- /* XXX krb5_defkeyname is an internal library global and
- should go away */
- extern char *krb5_defkeyname;
- krb5_defkeyname = DEFAULT_KEYTAB;
+#define DEFAULT_KEYTAB "WRFILE:/etc/krb5/krb5.keytab"
+ /* XXX krb5_defkeyname is an internal library global and
+ should go away */
+ extern char *krb5_defkeyname;
+ krb5_defkeyname = DEFAULT_KEYTAB;
}
if ((retval = kadm5_init_iprop(handle)) != 0) {
diff --git a/usr/src/cmd/krb5/kadmin/cli/kadmin_rmt.c b/usr/src/cmd/krb5/kadmin/cli/kadmin_rmt.c
index a71ba1b348..8fd69e319d 100644
--- a/usr/src/cmd/krb5/kadmin/cli/kadmin_rmt.c
+++ b/usr/src/cmd/krb5/kadmin/cli/kadmin_rmt.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Contains remote client specific code.
@@ -12,8 +11,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <libintl.h>
-#include <krb5.h>
#include <k5-int.h>
+#include <krb5.h>
extern void *handle;
diff --git a/usr/src/cmd/krb5/kadmin/cli/keytab.c b/usr/src/cmd/krb5/kadmin/cli/keytab.c
index 2f25abe838..6bb61c1f5b 100644
--- a/usr/src/cmd/krb5/kadmin/cli/keytab.c
+++ b/usr/src/cmd/krb5/kadmin/cli/keytab.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
@@ -47,10 +46,10 @@ static char *rcsid = "$Header: /cvs/krbdev/krb5/src/kadmin/cli/keytab.c,v 1.28 2
#include <string.h>
#include <libintl.h>
-#include <krb5.h>
#include <kadm5/admin.h>
#include <krb5/adm_proto.h>
#include "kadmin.h"
+#include <krb5.h>
static int add_principal(void *lhandle, char *keytab_str, krb5_keytab keytab,
krb5_boolean keepold,
diff --git a/usr/src/cmd/krb5/kadmin/dbutil/dump.c b/usr/src/cmd/krb5/kadmin/dbutil/dump.c
index d3fc353757..77990f6f1f 100644
--- a/usr/src/cmd/krb5/kadmin/dbutil/dump.c
+++ b/usr/src/cmd/krb5/kadmin/dbutil/dump.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -2719,8 +2718,7 @@ load_db(argc, argv)
newparams.mask |= KADM5_CONFIG_DBNAME;
newparams.dbname = dbname_tmp;
- /* Solaris kerberos: using older kadm5_get_config_params interface */
- if ((kret = kadm5_get_config_params(kcontext, NULL, NULL,
+ if ((kret = kadm5_get_config_params(kcontext, 1,
&newparams, &newparams))) {
com_err(argv[0], kret,
gettext("while retreiving new "
diff --git a/usr/src/cmd/krb5/kadmin/dbutil/kadm5_create.c b/usr/src/cmd/krb5/kadmin/dbutil/kadm5_create.c
index dad8111110..67c21ff079 100644
--- a/usr/src/cmd/krb5/kadmin/dbutil/kadm5_create.c
+++ b/usr/src/cmd/krb5/kadmin/dbutil/kadm5_create.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
*
@@ -47,7 +46,6 @@
#include <kadm5/admin.h>
#include <krb5/adm_proto.h>
-
#include <krb5.h>
#include <krb5/kdb.h>
#include "kdb5_util.h"
@@ -100,7 +98,7 @@ int kadm5_create(kadm5_config_params *params)
* The lock file has to exist before calling kadm5_init, but
* params->admin_lockfile may not be set yet...
*/
- if ((retval = kadm5_get_config_params(context, NULL, NULL,
+ if ((retval = kadm5_get_config_params(context, 1,
params, &lparams))) {
com_err(progname, retval, gettext("while looking up the Kerberos configuration"));
return 1;
@@ -288,7 +286,7 @@ int add_admin_princ(void *handle, krb5_context context,
"to-be-random");
if (ret) {
if (ret != KADM5_DUP) {
- com_err(progname, ret,
+ com_err(progname, ret,
gettext(str_PUT_PRINC), fullname);
krb5_free_principal(context, ent.principal);
free(fullname);
@@ -296,9 +294,9 @@ int add_admin_princ(void *handle, krb5_context context,
}
} else {
/* only randomize key if we created the principal */
- ret = kadm5_randkey_principal(handle, ent.principal, NULL, NULL);
- if (ret) {
- com_err(progname, ret,
+ ret = kadm5_randkey_principal(handle, ent.principal, NULL, NULL);
+ if (ret) {
+ com_err(progname, ret,
gettext(str_RANDOM_KEY), fullname);
krb5_free_principal(context, ent.principal);
free(fullname);
diff --git a/usr/src/cmd/krb5/kadmin/dbutil/kdb5_stash.c b/usr/src/cmd/krb5/kadmin/dbutil/kdb5_stash.c
index ebbd4407e2..ead7968e52 100644
--- a/usr/src/cmd/krb5/kadmin/dbutil/kdb5_stash.c
+++ b/usr/src/cmd/krb5/kadmin/dbutil/kdb5_stash.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -78,8 +77,7 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-
-#include <k5-int.h>
+#include "k5-int.h"
#include <kadm5/admin.h>
#include "com_err.h"
#include <kadm5/admin.h>
@@ -145,7 +143,6 @@ kdb5_stash(argc, argv)
if (!krb5_c_valid_enctype(global_params.enctype)) {
char tmp[32];
-
if (krb5_enctype_to_string(global_params.enctype,
tmp, sizeof (tmp)))
com_err(argv[0], KRB5_PROG_KEYTYPE_NOSUPP,
diff --git a/usr/src/cmd/krb5/kadmin/dbutil/kdb5_util.c b/usr/src/cmd/krb5/kadmin/dbutil/kdb5_util.c
index 2837a4083f..7339f26d2e 100644
--- a/usr/src/cmd/krb5/kadmin/dbutil/kdb5_util.c
+++ b/usr/src/cmd/krb5/kadmin/dbutil/kdb5_util.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -326,10 +325,22 @@ int main(argc, argv)
if (cmd_argv[0] == NULL)
usage();
- retval = kadm5_get_config_params(util_context, NULL, NULL,
+ if( !util_context->default_realm )
+ {
+ char *temp = NULL;
+ retval = krb5_get_default_realm(util_context, &temp);
+ if( retval )
+ {
+ com_err (progname, retval, "while getting default realm");
+ exit(1);
+ }
+ util_context->default_realm = temp;
+ }
+
+ retval = kadm5_get_config_params(util_context, 1,
&global_params, &global_params);
if (retval) {
- com_err(argv[0], retval,
+ com_err(argv[0], retval,
gettext("while retreiving configuration parameters"));
exit(1);
}
@@ -491,9 +502,8 @@ static int open_db_and_mkey()
global_params.enctype);
}
- retval = krb5_c_string_to_key(util_context,
- global_params.enctype,
- &pwd, &scratch, &master_key);
+ retval = krb5_c_string_to_key(util_context, global_params.enctype,
+ &pwd, &scratch, &master_key);
if (retval) {
com_err(progname, retval,
gettext("while transforming master key from password"));
diff --git a/usr/src/cmd/krb5/kadmin/kdcmgr/kdcmgr.sh b/usr/src/cmd/krb5/kadmin/kdcmgr/kdcmgr.sh
index 9e5260ba04..1d9ec6cc35 100755..100644
--- a/usr/src/cmd/krb5/kadmin/kdcmgr/kdcmgr.sh
+++ b/usr/src/cmd/krb5/kadmin/kdcmgr/kdcmgr.sh
@@ -22,7 +22,6 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
#
# This command provides an simple interface to configure, destroy, and to obtain
@@ -180,7 +179,6 @@ function setup_kdc_conf {
printf "\t\tprofile = $KRB5_KRB_CONF\n" 1>&3
printf "\t\tdatabase_name = $PRINCDB\n" 1>&3
printf "\t\tmaster_key_type = $ENCTYPE\n" 1>&3
- printf "\t\tadmin_keytab = $KADM5KT\n" 1>&3
printf "\t\tacl_file = $KADM5ACL\n" 1>&3
printf "\t\tkadmind_port = 749\n" 1>&3
printf "\t\tmax_life = 8h 0m 0s\n" 1>&3
@@ -366,18 +364,6 @@ function setup_mkeytab {
check_ret $? $KADMINL
fi
- $KADMINL -q "ktadd -k $KADM5KT kadmin/$fqhn" 1>$TMP_FILE 2>&1
- check_ret $? $KADMINL
- $KADMINL -q "ktadd -k $KADM5KT changepw/$fqhn" 1>$TMP_FILE 2>&1
- check_ret $? $KADMINL
-
- # To support Horowitz change password protocol
- $KADMINL -q "ktadd -k $KADM5KT kadmin/changepw" 1>$TMP_FILE 2>&1
- check_ret $? $KADMINL
-
- $KADMINL -q "ktadd -k $KADM5KT kiprop/$fqhn" 1>$TMP_FILE 2>&1
- check_ret $? $KADMINL
-
$KADMINL -q "ank -randkey host/$fqhn" 1>$TMP_FILE 2>&1
check_ret $? $KADMINL
$KADMINL -q "ktadd host/$fqhn" 1>$TMP_FILE 2>&1
@@ -520,11 +506,11 @@ function setup_slave {
function destroy_kdc {
# Check first to see if this is an existing KDC or server
- if [[ -f $KRB5KT || -f $KADM5KT || -f $PRINCDB || -f $OLDPRINCDB ]]
+ if [[ -f $KRB5KT || -f $PRINCDB || -f $OLDPRINCDB ]]
then
if [[ -z $PWFILE ]]; then
printf "\n$(gettext "Some of the following files are present on this system"):\n"
- echo "\t$KRB5KT\n\t$KADM5KT\n\t$PRINCDB\n\t$OLDPRINCDB\n\t$STASH\n"
+ echo "\t$KRB5KT\n\t$PRINCDB\n\t$OLDPRINCDB\n\t$STASH\n"
if [[ -z $d_option ]]; then
printf "$(gettext "You must first run 'kdcmgr destroy' to remove all of these files before creating a KDC server").\n\n"
cleanup 1
@@ -541,7 +527,7 @@ function destroy_kdc {
fi
printf "$(gettext "yes")\n" | kdb5_util destroy > /dev/null 2>&1
- rm -f $KRB5KT $KADM5KT
+ rm -f $KRB5KT
}
function kadm5_acl_configed {
@@ -592,9 +578,7 @@ function status_kdc {
if [[ $is_master -eq 0 && ! -s $KPROPACL ]]; then
printf "$(gettext "%s not found").\n" $KPROPACL
fi
- if [[ $is_master -eq 1 && ! -s $KADM5KT ]]; then
- printf "$(gettext "%s not found").\n" $KADM5KT
- fi
+
test ! -s $STASH &&
printf "$(gettext "Stash file not found") (/var/krb5/.k5.*).\n"
echo
@@ -611,7 +595,6 @@ KADM5ACL=/etc/krb5/kadm5.acl
KPROPACL=/etc/krb5/kpropd.acl
KRB5KT=/etc/krb5/krb5.keytab
-KADM5KT=/etc/krb5/kadm5.keytab
PRINCDB=/var/krb5/principal
OLDPRINCDB=/var/krb5/principal.old
STASH=/var/krb5/.k5.*
diff --git a/usr/src/cmd/krb5/kadmin/kpasswd/kpasswd.c b/usr/src/cmd/krb5/kadmin/kpasswd/kpasswd.c
index 7544889580..7fe557bf1a 100644
--- a/usr/src/cmd/krb5/kadmin/kpasswd/kpasswd.c
+++ b/usr/src/cmd/krb5/kadmin/kpasswd/kpasswd.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -26,12 +25,12 @@
/*
* Copyright 1993-1994 OpenVision Technologies, Inc., All Rights Reserved.
*
- * $Header: /cvs/krbdev/krb5/src/kadmin/passwd/kpasswd.c,v 1.25 2001/02/26 18:22:08 epeisach Exp $
+ * $Header$
*
*
*/
-static char rcsid[] = "$Id: kpasswd.c,v 1.25 2001/02/26 18:22:08 epeisach Exp $";
+static char rcsid[] = "$Id: kpasswd.c 17258 2005-06-21 01:36:03Z raeburn $";
#include <kadm5/admin.h>
#include <krb5.h>
diff --git a/usr/src/cmd/krb5/kadmin/server/kadm_rpc_svc.c b/usr/src/cmd/krb5/kadmin/server/kadm_rpc_svc.c
index 2eab293cd3..69326f2d26 100644
--- a/usr/src/cmd/krb5/kadmin/server/kadm_rpc_svc.c
+++ b/usr/src/cmd/krb5/kadmin/server/kadm_rpc_svc.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -26,14 +25,9 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
*
- * $Id: kadm_rpc_svc.c,v 1.16 2000/02/19 02:05:52 tlyu Exp $
- *
*/
-#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/kadmin/server/kadm_rpc_svc.c,v 1.16 2000/02/19 02:05:52 tlyu Exp $";
-#endif
-
+#include <kadm5/admin.h>
#include <stdio.h>
#include <rpc/rpc.h> /* SUNWresync 121 XXX */
#include <gssapi_krb5.h> /* for gss_nt_krb5_name */
@@ -44,7 +38,6 @@ static char *rcsid = "$Header: /cvs/krbdev/krb5/src/kadmin/server/kadm_rpc_svc.c
#include <rpc/rpcsec_gss.h>
#include <kadm5/kadm_rpc.h>
#include <krb5.h>
-#include <kadm5/admin.h>
#include <libintl.h>
#include <krb5/adm_proto.h>
#ifdef HAVE_ARPA_INET_H
@@ -79,23 +72,23 @@ void kadm_1(rqstp, transp)
register SVCXPRT *transp;
{
union {
- cprinc_arg create_principal_1_arg;
- dprinc_arg delete_principal_1_arg;
- mprinc_arg modify_principal_1_arg;
- rprinc_arg rename_principal_1_arg;
- gprinc_arg get_principal_1_arg;
- chpass_arg chpass_principal_1_arg;
- chrand_arg chrand_principal_1_arg;
- cpol_arg create_policy_1_arg;
- dpol_arg delete_policy_1_arg;
- mpol_arg modify_policy_1_arg;
- gpol_arg get_policy_1_arg;
- setkey_arg setkey_principal_1_arg;
- setv4key_arg setv4key_principal_1_arg;
- cprinc3_arg create_principal3_1_arg;
- chpass3_arg chpass_principal3_1_arg;
- chrand3_arg chrand_principal3_1_arg;
- setkey3_arg setkey_principal3_1_arg;
+ cprinc_arg create_principal_2_arg;
+ dprinc_arg delete_principal_2_arg;
+ mprinc_arg modify_principal_2_arg;
+ rprinc_arg rename_principal_2_arg;
+ gprinc_arg get_principal_2_arg;
+ chpass_arg chpass_principal_2_arg;
+ chrand_arg chrand_principal_2_arg;
+ cpol_arg create_policy_2_arg;
+ dpol_arg delete_policy_2_arg;
+ mpol_arg modify_policy_2_arg;
+ gpol_arg get_policy_2_arg;
+ setkey_arg setkey_principal_2_arg;
+ setv4key_arg setv4key_principal_2_arg;
+ cprinc3_arg create_principal3_2_arg;
+ chpass3_arg chpass_principal3_2_arg;
+ chrand3_arg chrand_principal3_2_arg;
+ setkey3_arg setkey_principal3_2_arg;
} argument;
char *result;
bool_t (*xdr_argument)(), (*xdr_result)();
@@ -118,129 +111,129 @@ void kadm_1(rqstp, transp)
case CREATE_PRINCIPAL:
xdr_argument = xdr_cprinc_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) create_principal_1_svc;
+ local = (char *(*)()) create_principal_2_svc;
break;
case DELETE_PRINCIPAL:
xdr_argument = xdr_dprinc_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) delete_principal_1_svc;
+ local = (char *(*)()) delete_principal_2_svc;
break;
case MODIFY_PRINCIPAL:
xdr_argument = xdr_mprinc_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) modify_principal_1_svc;
+ local = (char *(*)()) modify_principal_2_svc;
break;
case RENAME_PRINCIPAL:
xdr_argument = xdr_rprinc_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) rename_principal_1_svc;
+ local = (char *(*)()) rename_principal_2_svc;
break;
case GET_PRINCIPAL:
xdr_argument = xdr_gprinc_arg;
xdr_result = xdr_gprinc_ret;
- local = (char *(*)()) get_principal_1_svc;
+ local = (char *(*)()) get_principal_2_svc;
break;
case GET_PRINCS:
xdr_argument = xdr_gprincs_arg;
xdr_result = xdr_gprincs_ret;
- local = (char *(*)()) get_princs_1_svc;
+ local = (char *(*)()) get_princs_2_svc;
break;
case CHPASS_PRINCIPAL:
xdr_argument = xdr_chpass_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) chpass_principal_1_svc;
+ local = (char *(*)()) chpass_principal_2_svc;
break;
#ifdef SUNWOFF
case SETV4KEY_PRINCIPAL:
xdr_argument = xdr_setv4key_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) setv4key_principal_1_svc;
+ local = (char *(*)()) setv4key_principal_2_svc;
break;
#endif
case SETKEY_PRINCIPAL:
xdr_argument = xdr_setkey_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) setkey_principal_1_svc;
+ local = (char *(*)()) setkey_principal_2_svc;
break;
case CHRAND_PRINCIPAL:
xdr_argument = xdr_chrand_arg;
xdr_result = xdr_chrand_ret;
- local = (char *(*)()) chrand_principal_1_svc;
+ local = (char *(*)()) chrand_principal_2_svc;
break;
case CREATE_POLICY:
xdr_argument = xdr_cpol_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) create_policy_1_svc;
+ local = (char *(*)()) create_policy_2_svc;
break;
case DELETE_POLICY:
xdr_argument = xdr_dpol_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) delete_policy_1_svc;
+ local = (char *(*)()) delete_policy_2_svc;
break;
case MODIFY_POLICY:
xdr_argument = xdr_mpol_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) modify_policy_1_svc;
+ local = (char *(*)()) modify_policy_2_svc;
break;
case GET_POLICY:
xdr_argument = xdr_gpol_arg;
xdr_result = xdr_gpol_ret;
- local = (char *(*)()) get_policy_1_svc;
+ local = (char *(*)()) get_policy_2_svc;
break;
case GET_POLS:
xdr_argument = xdr_gpols_arg;
xdr_result = xdr_gpols_ret;
- local = (char *(*)()) get_pols_1_svc;
+ local = (char *(*)()) get_pols_2_svc;
break;
case GET_PRIVS:
xdr_argument = xdr_u_int;
xdr_result = xdr_getprivs_ret;
- local = (char *(*)()) get_privs_1_svc;
+ local = (char *(*)()) get_privs_2_svc;
break;
case INIT:
xdr_argument = xdr_u_int;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) init_1_svc;
+ local = (char *(*)()) init_2_svc;
break;
case CREATE_PRINCIPAL3:
xdr_argument = xdr_cprinc3_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) create_principal3_1_svc;
+ local = (char *(*)()) create_principal3_2_svc;
break;
case CHPASS_PRINCIPAL3:
xdr_argument = xdr_chpass3_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) chpass_principal3_1_svc;
+ local = (char *(*)()) chpass_principal3_2_svc;
break;
case CHRAND_PRINCIPAL3:
xdr_argument = xdr_chrand3_arg;
xdr_result = xdr_chrand_ret;
- local = (char *(*)()) chrand_principal3_1_svc;
+ local = (char *(*)()) chrand_principal3_2_svc;
break;
case SETKEY_PRINCIPAL3:
xdr_argument = xdr_setkey3_arg;
xdr_result = xdr_generic_ret;
- local = (char *(*)()) setkey_principal3_1_svc;
+ local = (char *(*)()) setkey_principal3_2_svc;
break;
default:
diff --git a/usr/src/cmd/krb5/kadmin/server/misc.c b/usr/src/cmd/krb5/kadmin/server/misc.c
index 4daa87ee1a..40965ed1db 100644
--- a/usr/src/cmd/krb5/kadmin/server/misc.c
+++ b/usr/src/cmd/krb5/kadmin/server/misc.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -68,7 +67,7 @@ chpass_principal_wrapper_3(void *server_handle,
{
kadm5_ret_t ret;
- ret = check_min_life(server_handle, principal);
+ ret = check_min_life(server_handle, principal, NULL, 0);
if (ret)
return ret;
@@ -111,7 +110,7 @@ randkey_principal_wrapper_3(void *server_handle,
{
kadm5_ret_t ret;
- ret = check_min_life(server_handle, principal);
+ ret = check_min_life(server_handle, principal, NULL, 0);
if (ret)
return ret;
return kadm5_randkey_principal_3(server_handle, principal,
@@ -120,13 +119,13 @@ randkey_principal_wrapper_3(void *server_handle,
}
kadm5_ret_t
-chpass_util_wrapper(void *server_handle, krb5_principal princ,
- char *new_pw, char **ret_pw,
- char *msg_ret, unsigned int msg_len)
+schpw_util_wrapper(void *server_handle, krb5_principal princ,
+ char *new_pw, char **ret_pw,
+ char *msg_ret, unsigned int msg_len)
{
kadm5_ret_t ret;
- ret = check_min_life(server_handle, princ);
+ ret = check_min_life(server_handle, princ, msg_ret, msg_len);
if (ret)
return ret;
@@ -141,7 +140,7 @@ randkey_principal_wrapper(void *server_handle, krb5_principal princ,
{
kadm5_ret_t ret;
- ret = check_min_life(server_handle, princ);
+ ret = check_min_life(server_handle, princ, NULL, 0);
if (ret)
return ret;
@@ -149,7 +148,8 @@ randkey_principal_wrapper(void *server_handle, krb5_principal princ,
}
kadm5_ret_t
-check_min_life(void *server_handle, krb5_principal principal)
+check_min_life(void *server_handle, krb5_principal principal,
+ char *msg_ret, unsigned int msg_len)
{
krb5_int32 now;
kadm5_ret_t ret;
@@ -157,6 +157,9 @@ check_min_life(void *server_handle, krb5_principal principal)
kadm5_principal_ent_rec princ;
kadm5_server_handle_t handle = server_handle;
+ if (msg_ret != NULL)
+ *msg_ret = '\0';
+
ret = krb5_timeofday(handle->context, &now);
if (ret)
return ret;
@@ -173,6 +176,24 @@ check_min_life(void *server_handle, krb5_principal principal)
}
if((now - princ.last_pwd_change) < pol.pw_min_life &&
!(princ.attributes & KRB5_KDB_REQUIRES_PWCHANGE)) {
+ if (msg_ret != NULL) {
+ time_t until;
+ char *time_string, *ptr, *errstr;
+
+ until = princ.last_pwd_change + pol.pw_min_life;
+
+ time_string = ctime(&until);
+ errstr = (char *)error_message(CHPASS_UTIL_PASSWORD_TOO_SOON);
+
+ if (strlen(errstr) + strlen(time_string) >= msg_len) {
+ *errstr = '\0';
+ } else {
+ if (*(ptr = &time_string[strlen(time_string)-1]) == '\n')
+ *ptr = '\0';
+ sprintf(msg_ret, errstr, time_string);
+ }
+ }
+
(void) kadm5_free_policy_ent(handle->lhandle, &pol);
(void) kadm5_free_principal_ent(handle->lhandle, &princ);
return KADM5_PASS_TOOSOON;
diff --git a/usr/src/cmd/krb5/kadmin/server/misc.h b/usr/src/cmd/krb5/kadmin/server/misc.h
index bc6a749c74..2e3cacc468 100644
--- a/usr/src/cmd/krb5/kadmin/server/misc.h
+++ b/usr/src/cmd/krb5/kadmin/server/misc.h
@@ -1,12 +1,11 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _MISC_H
#define _MISC_H
-#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
@@ -52,11 +51,12 @@ randkey_principal_wrapper_3(void *server_handle,
krb5_keyblock **keys, int *n_keys);
kadm5_ret_t
-chpass_util_wrapper(void *server_handle, krb5_principal princ,
- char *new_pw, char **ret_pw,
- char *msg_ret, unsigned int msg_len);
+schpw_util_wrapper(void *server_handle, krb5_principal princ,
+ char *new_pw, char **ret_pw,
+ char *msg_ret, unsigned int msg_len);
-kadm5_ret_t check_min_life(void *server_handle, krb5_principal principal);
+kadm5_ret_t check_min_life(void *server_handle, krb5_principal principal,
+ char *msg_ret, unsigned int msg_len);
kadm5_ret_t kadm5_get_principal_v1(void *server_handle,
krb5_principal principal,
@@ -65,10 +65,20 @@ kadm5_ret_t kadm5_get_principal_v1(void *server_handle,
kadm5_ret_t kadm5_get_policy_v1(void *server_handle, kadm5_policy_t name,
kadm5_policy_ent_t *ent);
+
+krb5_error_code process_chpw_request(krb5_context context,
+ void *server_handle,
+ char *realm, int s,
+ krb5_keytab keytab,
+ struct sockaddr_in *sockin,
+ krb5_data *req, krb5_data *rep);
+
#ifdef SVC_GETARGS
void kadm_1(struct svc_req *, SVCXPRT *);
#endif
+void trunc_name(size_t *len, char **dots);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/krb5/kadmin/server/ovsec_kadmd.c b/usr/src/cmd/krb5/kadmin/server/ovsec_kadmd.c
index 432bf2cb32..cea2c13dd2 100644
--- a/usr/src/cmd/krb5/kadmin/server/ovsec_kadmd.c
+++ b/usr/src/cmd/krb5/kadmin/server/ovsec_kadmd.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -24,6 +23,7 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
+ *
*/
/*
@@ -72,11 +72,13 @@
#include <netinet/in.h>
#include <arpa/inet.h> /* inet_ntoa */
#include <gssapi/gssapi.h>
+#include "gssapiP_krb5.h" /* for kg_get_context */
#include <rpc/rpc.h>
#include <kadm5/admin.h>
#include <kadm5/kadm_rpc.h>
#include <server_acl.h>
#include <krb5/adm_proto.h>
+#include "kdb_kt.h" /* for krb5_ktkdb_set_context */
#include <string.h>
#include <kadm5/server_internal.h>
#include <gssapi_krb5.h>
@@ -89,6 +91,16 @@
#include <rpc/rpcsec_gss.h>
#include "misc.h"
+#ifdef PURIFY
+#include "purify.h"
+
+int signal_pure_report = 0;
+int signal_pure_clear = 0;
+void request_pure_report(int);
+void request_pure_clear(int);
+#endif /* PURIFY */
+
+
#ifndef FD_SETSIZE
#define FD_SETSIZE 256
#endif
@@ -101,16 +113,12 @@
extern int daemon(int, int);
#endif
-
-
-static int signal_request_exit = 0;
-static int schpw;
+static int signal_request_exit = 0;
kadm5_config_params chgpw_params;
-void kadm_svc_run(void);
-void setup_signal_handlers(iprop_role iproprole);
-void sig_exit(int);
-void sig_pipe(int);
-krb5_error_code log_kt_error(char*, char*);
+void setup_signal_handlers(iprop_role iproprole);
+void request_exit(int);
+void sig_pipe(int);
+void kadm_svc_run(void);
#ifdef POSIX_SIGNALS
static struct sigaction s_action;
@@ -132,15 +140,9 @@ void *global_server_handle;
* compatible with old clients. They are defined in <kadm5/admin.h>,
* but only if USE_KADM5_API_VERSION == 1.
*/
-#define OVSEC_KADM_ADMIN_SERVICE_P "ovsec_adm@admin"
-#define OVSEC_KADM_CHANGEPW_SERVICE_P "ovsec_adm@changepw"
+#define OVSEC_KADM_ADMIN_SERVICE_P "ovsec_adm@admin"
+#define OVSEC_KADM_CHANGEPW_SERVICE_P "ovsec_adm@changepw"
-/*
- * This enables us to set the keytab that gss_acquire_cred uses, but
- * it also restricts us to linking against the Kv5 GSS-API library.
- * Since this is *k*admind, that shouldn't be a problem.
- */
-extern char *krb5_overridekeyname;
extern void krb5_iprop_prog_1();
extern kadm5_ret_t kiprop_get_adm_host_srv_name(
@@ -148,9 +150,8 @@ extern kadm5_ret_t kiprop_get_adm_host_srv_name(
const char *,
char **);
-static krb5_context context; /* XXX yuck. the signal handlers need this */
+static int schpw;
-static krb5_context hctx;
in_port_t l_port = 0; /* global local port num, for BSM audits */
@@ -170,9 +171,9 @@ int nofork = 0; /* global; don't fork (debug mode) */
static void usage()
{
- fprintf(stderr, gettext("Usage: kadmind [-x db_args]* [-r realm] [-m] [-d] "
- "[-p port-number]\n"));
- exit(1);
+ fprintf(stderr, gettext("Usage: kadmind [-x db_args]* [-r realm] [-m] [-d] "
+ "[-p port-number]\n"));
+ exit(1);
}
/*
@@ -398,80 +399,83 @@ set_svc_domnames(char *svcname, char **dnames,
}
}
+/* XXX yuck. the signal handlers need this */
+static krb5_context context;
+static krb5_context hctx;
-
-int
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
{
- SVCXPRT *transp;
- extern char *optarg;
- extern int optind, opterr;
- int ret, rlen, oldnames = 0;
- OM_uint32 OMret, major_status, minor_status;
- char *whoami;
- FILE *acl_file;
- gss_buffer_desc in_buf;
- struct servent *srv;
- struct sockaddr_in addr;
- struct sockaddr_in *sin;
- int s;
- int optchar;
- struct netconfig *nconf;
- void *handlep;
- int fd;
- struct t_info tinfo;
- struct t_bind tbindstr, *tres;
-
- struct t_optmgmt req, resp;
- struct opthdr *opt;
- char reqbuf[128];
- struct rlimit rl;
-
- char *kiprop_name = NULL; /* IProp svc name */
- kdb_log_context *log_ctx;
- kadm5_server_handle_t handle;
- krb5_context ctx;
-
- kadm5_config_params params;
- char **db_args = NULL;
- int db_args_size = 0;
- auth_gssapi_name names[6];
- gss_buffer_desc gssbuf;
- gss_OID nt_krb5_name_oid;
-
- char **dnames = NULL;
- int retdn;
- int iprop_supported;
-
- /* Solaris Kerberos: Stores additional error messages */
- char *emsg = NULL;
-
- /* Solaris Kerberos: Indicates whether loalhost is master or not */
- krb5_boolean is_master;
-
- /* Solaris Kerberos: Used for checking acl file */
- gss_name_t name;
-
- /* This is OID value the Krb5_Name NameType */
- gssbuf.value = "{1 2 840 113554 1 2 2 1}";
- gssbuf.length = strlen(gssbuf.value);
- major_status = gss_str_to_oid(&minor_status, &gssbuf,
- &nt_krb5_name_oid);
- if (major_status != GSS_S_COMPLETE) {
- fprintf(stderr,
- gettext("Couldn't create KRB5 Name NameType OID\n"));
- display_status("str_to_oid", major_status, minor_status);
- exit(1);
- }
-
- names[0].name = names[1].name = names[2].name =
- names[3].name = names[4].name = names[5].name =NULL;
- names[0].type = names[1].type = names[2].type =
- names[3].type = names[4].type = names[5].type =
- (gss_OID) nt_krb5_name_oid;
-
- whoami = (strrchr(argv[0], '/') ? strrchr(argv[0], '/') + 1 : argv[0]);
+ register SVCXPRT *transp;
+ extern char *optarg;
+ extern int optind, opterr;
+ int ret, rlen, oldnames = 0;
+ OM_uint32 OMret, major_status, minor_status;
+ char *whoami;
+ FILE *acl_file;
+ gss_buffer_desc in_buf;
+ struct servent *srv;
+ struct sockaddr_in addr;
+ struct sockaddr_in *sin;
+ int s;
+ auth_gssapi_name names[6];
+ gss_buffer_desc gssbuf;
+ gss_OID nt_krb5_name_oid;
+ int optchar;
+ struct netconfig *nconf;
+ void *handlep;
+ int fd;
+ struct t_info tinfo;
+ struct t_bind tbindstr, *tres;
+
+ struct t_optmgmt req, resp;
+ struct opthdr *opt;
+ char reqbuf[128];
+ struct rlimit rl;
+
+ char *kiprop_name = NULL; /* IProp svc name */
+ kdb_log_context *log_ctx;
+ kadm5_server_handle_t handle;
+ krb5_context ctx;
+
+ kadm5_config_params params;
+ char **db_args = NULL;
+ int db_args_size = 0;
+ const char *errmsg;
+ char **dnames = NULL;
+ int retdn;
+ int iprop_supported;
+
+ /* Solaris Kerberos: Stores additional error messages */
+ char *emsg = NULL;
+
+ /* Solaris Kerberos: Indicates whether loalhost is master or not */
+ krb5_boolean is_master;
+
+ /* Solaris Kerberos: Used for checking acl file */
+ gss_name_t name;
+
+ /* This is OID value the Krb5_Name NameType */
+ gssbuf.value = "{1 2 840 113554 1 2 2 1}";
+ gssbuf.length = strlen(gssbuf.value);
+ major_status = gss_str_to_oid(&minor_status, &gssbuf, &nt_krb5_name_oid);
+ if (major_status != GSS_S_COMPLETE) {
+ fprintf(stderr,
+ gettext("Couldn't create KRB5 Name NameType OID\n"));
+ display_status("str_to_oid", major_status, minor_status);
+ exit(1);
+ }
+
+ names[0].name = names[1].name = names[2].name = names[3].name = NULL;
+ names[4].name = names[5].name =NULL;
+ names[0].type = names[1].type = names[2].type = names[3].type =
+ (gss_OID) nt_krb5_name_oid;
+ names[4].type = names[5].type = (gss_OID) nt_krb5_name_oid;
+
+#ifdef PURIFY
+ purify_start_batch();
+#endif /* PURIFY */
+ whoami = (strrchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]);
(void) setlocale(LC_ALL, "");
@@ -481,9 +485,9 @@ main(int argc, char *argv[])
(void) textdomain(TEXT_DOMAIN);
- nofork = 0;
+ nofork = 0;
- memset((char *) &params, 0, sizeof (params));
+ memset((char *) &params, 0, sizeof(params));
while ((optchar = getopt(argc, argv, "r:mdp:x:")) != EOF) {
switch (optchar) {
@@ -537,24 +541,70 @@ main(int argc, char *argv[])
(void) enable_extended_FILE_stdio(-1, -1);
}
- if (ret = krb5_init_context(&context)) {
- fprintf(stderr,
- gettext("%s: %s while initializing context, aborting\n"),
- whoami, error_message(ret));
- exit(1);
- }
-
- krb5_klog_init(context, "admin_server", whoami, 1);
- /* SUNW14resync */
-#if 0
- krb5_klog_syslog(LOG_INFO, "Seeding random number generator");
- ret = krb5_c_random_os_entropy(context, 1, NULL);
- if(ret) {
- krb5_klog_syslog(LOG_ERR, "Error getting random seed: %s, aborting",
- error_message(ret));
- exit(1);
- }
-#endif
+ if ((ret = kadm5_init_krb5_context(&context))) {
+ fprintf(stderr,
+ gettext("%s: %s while initializing context, aborting\n"),
+ whoami, error_message(ret));
+ exit(1);
+ }
+
+ krb5_klog_init(context, "admin_server", whoami, 1);
+
+ /* Solaris Kerberos */
+ if((ret = kadm5_init2("kadmind", NULL,
+ NULL, &params,
+ KADM5_STRUCT_VERSION,
+ KADM5_API_VERSION_2,
+ db_args,
+ &global_server_handle,
+ &emsg)) != KADM5_OK) {
+ krb5_klog_syslog(LOG_ERR,
+ gettext("%s while initializing, aborting"),
+ (emsg ? emsg : error_message(ret)));
+ fprintf(stderr,
+ gettext("%s: %s while initializing, aborting\n"),
+ whoami, (emsg ? emsg : error_message(ret)));
+ if (emsg)
+ free(emsg);
+ krb5_klog_close(context);
+ exit(1);
+ }
+
+ if( db_args )
+ {
+ free(db_args), db_args=NULL;
+ }
+
+ if ((ret = kadm5_get_config_params(context, 1, &params,
+ &params))) {
+ const char *e_txt = krb5_get_error_message (context, ret);
+ /* Solaris Kerberos: Remove double "whoami" */
+ krb5_klog_syslog(LOG_ERR, gettext("%s while initializing, aborting"),
+ e_txt);
+ fprintf(stderr,
+ gettext("%s: %s while initializing, aborting\n"),
+ whoami, e_txt);
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
+
+#define REQUIRED_PARAMS (KADM5_CONFIG_REALM | KADM5_CONFIG_ACL_FILE)
+
+ if ((params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
+ /* Solaris Kerberos: Keep error messages consistent */
+ krb5_klog_syslog(LOG_ERR,
+ gettext("Missing required configuration values (%lx)"
+ "while initializing, aborting"),
+ (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS);
+ fprintf(stderr,
+ gettext("%s: Missing required configuration values "
+ "(%lx) while initializing, aborting\n"), whoami,
+ (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS);
+ krb5_klog_close(context);
+ kadm5_destroy(global_server_handle);
+ exit(1);
+ }
/*
* When using the Horowitz/IETF protocol for
@@ -568,17 +618,17 @@ main(int argc, char *argv[])
chgpw_params.kpasswd_protocol = KRB5_CHGPWD_CHANGEPW_V2;
chgpw_params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
- if (ret = kadm5_get_config_params(context, NULL, NULL, &chgpw_params,
- &chgpw_params)) {
- /* Solaris Kerberos: Remove double "whoami" */
- krb5_klog_syslog(LOG_ERR, gettext("%s while initializing,"
- " aborting"), error_message(ret));
- fprintf(stderr,
- gettext("%s: %s while initializing, aborting\n"),
- whoami, error_message(ret));
- krb5_klog_close(context);
- exit(1);
- }
+ if (ret = kadm5_get_config_params(context, 1, &chgpw_params,
+ &chgpw_params)) {
+ /* Solaris Kerberos: Remove double "whoami" */
+ krb5_klog_syslog(LOG_ERR, gettext("%s while initializing,"
+ " aborting"), error_message(ret));
+ fprintf(stderr,
+ gettext("%s: %s while initializing, aborting\n"),
+ whoami, error_message(ret));
+ krb5_klog_close(context);
+ exit(1);
+ }
/*
* We now setup the socket and bind() to port 464, so that
@@ -586,76 +636,17 @@ main(int argc, char *argv[])
* from non-Solaris Kerberos V5 clients such as Microsoft,
* MIT, AIX, HP etc
*/
- if ((schpw = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- krb5_klog_syslog(LOG_ERR, gettext( "cannot create simple "
- "chpw socket: %s"), error_message(errno));
- fprintf(stderr, gettext("Cannot create simple chpw "
- "socket: %s"), error_message(errno));
- krb5_klog_close(context);
- exit(1);
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = htons(chgpw_params.kpasswd_port);
-
- if (bind(schpw, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- char portbuf[32];
- int oerrno = errno;
- fprintf(stderr, gettext("%s: Cannot bind socket.\n"), whoami);
- fprintf(stderr, gettext("bind: %s\n"), error_message(oerrno));
- errno = oerrno;
- (void) snprintf(portbuf, sizeof (portbuf), "%d",
- ntohs(addr.sin_port));
- krb5_klog_syslog(LOG_ERR, gettext("cannot bind simple "
- "chpw socket: %s"), error_message(oerrno));
- if(oerrno == EADDRINUSE) {
- char *w = strrchr(whoami, '/');
- if (w) {
- w++;
- }
- else {
- w = whoami;
- }
- fprintf(stderr, gettext(
- "This probably means that another %s process\n"
- "is already running, or that another program\n"
- "is using the server port (number %d).\n"
- "If another %s is already running, you should\n"
- "kill it before restarting the server.\n"),
- w, ntohs(addr.sin_port), w);
- }
- krb5_klog_close(context);
- exit(1);
- }
-
- if (ret = kadm5_get_config_params(context, NULL, NULL, &params,
- &params)) {
- /* Solaris Kerberos: Remove double "whoami" */
- krb5_klog_syslog(LOG_ERR, gettext("%s while initializing,"
- " aborting"), error_message(ret));
- fprintf(stderr,
- gettext("%s: %s while initializing, aborting\n"),
- whoami, error_message(ret));
- krb5_klog_close(context);
- exit(1);
- }
-#define REQUIRED_PARAMS (KADM5_CONFIG_REALM | KADM5_CONFIG_ACL_FILE)
-
- if ((params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
- /* Solaris Kerberos: Keep error messages consistent */
- krb5_klog_syslog(LOG_ERR,
- gettext("Missing required configuration values "
- "(%lx) while initializing, aborting"),
- (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS);
- fprintf(stderr,
- gettext("%s: Missing required configuration values "
- "(%lx) while initializing, aborting\n"), whoami,
- (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS);
- krb5_klog_close(context);
- exit(1);
- }
+ if ((schpw = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ const char *e_txt = krb5_get_error_message (context, ret);
+ krb5_klog_syslog(LOG_ERR,
+ gettext( "Cannot create simple " "chpw socket: %s"),
+ e_txt);
+ fprintf(stderr, gettext("Cannot create simple chpw socket: %s"),
+ e_txt);
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
/* Solaris Kerberos: Ensure that kadmind is only run on a master kdc */
if (ret = kadm5_is_master(context, params.realm, &is_master)){
@@ -687,11 +678,11 @@ main(int argc, char *argv[])
exit(1);
}
- memset((char *) &addr, 0, sizeof (struct sockaddr_in));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- l_port = addr.sin_port = htons(params.kadmind_port);
- sin = &addr;
+ memset((char *) &addr, 0, sizeof (struct sockaddr_in));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+ l_port = addr.sin_port = htons(params.kadmind_port);
+ sin = &addr;
if ((handlep = setnetconfig()) == (void *) NULL) {
(void) krb5_klog_syslog(LOG_ERR,
@@ -699,6 +690,7 @@ main(int argc, char *argv[])
krb5_klog_close(context);
exit(1);
}
+
while (nconf = getnetconfig(handlep)) {
if ((nconf->nc_semantics == NC_TPI_COTS_ORD) &&
(strcmp(nconf->nc_protofmly, NC_INET) == 0) &&
@@ -760,71 +752,92 @@ main(int argc, char *argv[])
sin = (struct sockaddr_in *) tbindstr.addr.buf;
/* SUNWresync121 XXX (void) memset(&addr, 0, sizeof(addr)); */
- if (t_bind(fd, &tbindstr, tres) < 0) {
- int oerrno = errno;
- fprintf(stderr, gettext("%s: Cannot bind socket.\n"), whoami);
- fprintf(stderr, gettext("bind: %s\n"), error_message(oerrno));
- errno = oerrno;
- krb5_klog_syslog(LOG_ERR, gettext("Cannot bind socket: %s"),
- error_message(errno));
- if (oerrno == EADDRINUSE) {
- char *w = strrchr(whoami, '/');
-
- if (w) {
- w++;
- } else {
- w = whoami;
- }
- fprintf(stderr, gettext(
- "This probably means that another %s "
- "process is already\n"
- "running, or that another program is using "
- "the server port (number %d)\n"
- "after being assigned it by the RPC "
- "portmap deamon. If another\n"
- "%s is already running, you should kill "
- "it before\n"
- "restarting the server. If, on the other hand, "
- "another program is\n"
- "using the server port, you should kill it "
- "before running\n"
- "%s, and ensure that the conflict does "
- "not occur in the\n"
- "future by making sure that %s is started "
- "on reboot\n"
- "before portmap.\n"),
- w, ntohs(addr.sin_port), w, w, w);
- krb5_klog_syslog(LOG_ERR,
- gettext("Check for already-running %s or for "
- "another process using port %d"), w,
- htons(addr.sin_port));
- }
- krb5_klog_close(context);
- exit(1);
- }
- transp = svc_tli_create(fd, nconf, NULL, 0, 0);
- (void) t_free((char *) tres, T_BIND);
- if (transp == NULL) {
- fprintf(stderr, gettext("%s: Cannot create RPC service.\n"),
- whoami);
- krb5_klog_syslog(LOG_ERR, gettext("Cannot create RPC service: %m"));
- krb5_klog_close(context);
- exit(1);
- }
- if (!svc_register(transp, KADM, KADMVERS, kadm_1, 0)) {
- fprintf(stderr,
- gettext("%s: Cannot register RPC service.\n"), whoami);
- krb5_klog_syslog(LOG_ERR,
- gettext("Cannot register RPC service, failing."));
- krb5_klog_close(context);
- exit(1);
- }
+ if (t_bind(fd, &tbindstr, tres) < 0) {
+ int oerrno = errno;
+ const char *e_txt = krb5_get_error_message (context, errno);
+ fprintf(stderr, gettext("%s: Cannot bind socket.\n"), whoami);
+ fprintf(stderr, gettext("bind: %s\n"), e_txt);
+ errno = oerrno;
+ krb5_klog_syslog(LOG_ERR, gettext("Cannot bind socket: %s"), e_txt);
+ if(oerrno == EADDRINUSE) {
+ char *w = strrchr(whoami, '/');
+ if (w) {
+ w++;
+ }
+ else {
+ w = whoami;
+ }
+ fprintf(stderr, gettext(
+"This probably means that another %s process is already\n"
+"running, or that another program is using the server port (number %d)\n"
+"after being assigned it by the RPC portmap daemon. If another\n"
+"%s is already running, you should kill it before\n"
+"restarting the server. If, on the other hand, another program is\n"
+"using the server port, you should kill it before running\n"
+"%s, and ensure that the conflict does not occur in the\n"
+"future by making sure that %s is started on reboot\n"
+ "before portmap.\n"), w, ntohs(addr.sin_port), w, w, w);
+ krb5_klog_syslog(LOG_ERR, gettext("Check for already-running %s or for "
+ "another process using port %d"), w,
+ htons(addr.sin_port));
+ }
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+
+ addr.sin_port = htons(chgpw_params.kpasswd_port);
+
+ if (bind(schpw, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ char portbuf[32];
+ int oerrno = errno;
+ const char *e_txt = krb5_get_error_message (context, errno);
+ fprintf(stderr, gettext("%s: Cannot bind socket.\n"), whoami);
+ fprintf(stderr, gettext("bind: %s\n"), e_txt);
+ errno = oerrno;
+ (void) snprintf(portbuf, sizeof (portbuf), "%d", ntohs(addr.sin_port));
+ krb5_klog_syslog(LOG_ERR, gettext("cannot bind simple chpw socket: %s"),
+ e_txt);
+ if(oerrno == EADDRINUSE) {
+ char *w = strrchr(whoami, '/');
+ if (w) {
+ w++;
+ }
+ else {
+ w = whoami;
+ }
+ fprintf(stderr, gettext(
+"This probably means that another %s process is already\n"
+"running, or that another program is using the server port (number %d).\n"
+"If another %s is already running, you should kill it before\n"
+"restarting the server.\n"),
+ w, ntohs(addr.sin_port), w);
+ }
+ krb5_klog_close(context);
+ exit(1);
+ }
+
+ transp = svc_tli_create(fd, nconf, NULL, 0, 0);
+ (void) t_free((char *) tres, T_BIND);
+ (void) endnetconfig(handlep);
+ if(transp == NULL) {
+ fprintf(stderr, gettext("%s: Cannot create RPC service.\n"), whoami);
+ krb5_klog_syslog(LOG_ERR, gettext("Cannot create RPC service: %m"));
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
+ if(!svc_register(transp, KADM, KADMVERS, kadm_1, 0)) {
+ fprintf(stderr, gettext("%s: Cannot register RPC service.\n"), whoami);
+ krb5_klog_syslog(LOG_ERR, gettext("Cannot register RPC service, failing."));
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
- /*
- * XXX krb5_defkeyname is an internal library global and should go
- * away
- */
- krb5_overridekeyname = params.admin_keytab;
/* Solaris Kerberos:
* The only service principals which matter here are
@@ -864,17 +877,69 @@ main(int argc, char *argv[])
krb5_klog_close(context);
exit(1);
}
-
names[2].name = KADM5_ADMIN_SERVICE_P;
names[3].name = KADM5_CHANGEPW_SERVICE_P;
names[4].name = OVSEC_KADM_ADMIN_SERVICE_P;
names[5].name = OVSEC_KADM_CHANGEPW_SERVICE_P;
- /*
- * Try to acquire creds for the old OV services as well as the new
- * names, but if that fails just fall back on the new names.
- */
-
+ if (names[0].name == NULL || names[1].name == NULL ||
+ names[2].name == NULL || names[3].name == NULL ||
+ names[4].name == NULL || names[5].name == NULL) {
+ krb5_klog_syslog(LOG_ERR,
+ gettext("Cannot initialize GSS-API authentication, "
+ "failing."));
+ fprintf(stderr,
+ gettext("%s: Cannot initialize "
+ "GSS-API authentication.\n"),
+ whoami);
+ krb5_klog_close(context);
+ exit(1);
+ }
+
+ /*
+ * Go through some contortions to point gssapi at a kdb keytab.
+ * This prevents kadmind from needing to use an actual file-based
+ * keytab.
+ */
+ /* XXX extract kadm5's krb5_context */
+ hctx = ((kadm5_server_handle_t)global_server_handle)->context;
+ /* Set ktkdb's internal krb5_context. */
+ ret = krb5_ktkdb_set_context(hctx);
+ if (ret) {
+ krb5_klog_syslog(LOG_ERR, "Can't set kdb keytab's internal context.");
+ goto kterr;
+ }
+ /* Solaris Kerberos */
+ ret = krb5_db_set_mkey(hctx, &((kadm5_server_handle_t)global_server_handle)->master_keyblock);
+ if (ret) {
+ krb5_klog_syslog(LOG_ERR, "Can't set master key for kdb keytab.");
+ goto kterr;
+ }
+ ret = krb5_kt_register(context, &krb5_kt_kdb_ops);
+ if (ret) {
+ krb5_klog_syslog(LOG_ERR, "Can't register kdb keytab.");
+ goto kterr;
+ }
+ /* Tell gssapi about the kdb keytab. */
+ ret = krb5_gss_register_acceptor_identity("KDB:");
+ if (ret) {
+ krb5_klog_syslog(LOG_ERR, "Can't register acceptor keytab.");
+ goto kterr;
+ }
+kterr:
+ if (ret) {
+ krb5_klog_syslog(LOG_ERR, "%s", krb5_get_error_message (context, ret));
+ fprintf(stderr, "%s: Can't set up keytab for RPC.\n", whoami);
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
+
+ /*
+ * Try to acquire creds for the old OV services as well as the
+ * new names, but if that fails just fall back on the new names.
+ */
+
if (rpc_gss_set_svc_name(names[5].name,
"kerberos_v5", 0, KADM, KADMVERS) &&
rpc_gss_set_svc_name(names[4].name,
@@ -894,13 +959,10 @@ main(int argc, char *argv[])
if (rpc_gss_set_svc_name(names[0].name,
"kerberos_v5", 0, KADM, KADMVERS))
oldnames++;
- else
- log_kt_error(names[0].name, whoami);
+
if (rpc_gss_set_svc_name(names[1].name,
"kerberos_v5", 0, KADM, KADMVERS))
oldnames++;
- else
- log_kt_error(names[1].name, whoami);
retdn = getdomnames(context, params.realm, &dnames);
if (retdn == 0 && dnames) {
@@ -915,26 +977,28 @@ main(int argc, char *argv[])
dnames, KADM, KADMVERS);
}
- /* if set_names succeeded, this will too */
- in_buf.value = names[1].name;
- in_buf.length = strlen(names[1].name) + 1;
- (void) gss_import_name(&OMret, &in_buf, (gss_OID) nt_krb5_name_oid,
- &gss_changepw_name);
- if (oldnames) {
- in_buf.value = names[3].name;
- in_buf.length = strlen(names[3].name) + 1;
- (void) gss_import_name(&OMret, &in_buf,
- (gss_OID) nt_krb5_name_oid,
- &gss_oldchangepw_name);
- }
- if (ret = kadm5int_acl_init(context, 0, params.acl_file)) {
- krb5_klog_syslog(LOG_ERR, gettext("Cannot initialize acl file: %s"),
- error_message(ret));
- fprintf(stderr, gettext("%s: Cannot initialize acl file: %s\n"),
- whoami, error_message(ret));
- krb5_klog_close(context);
- exit(1);
- }
+ /* if set_names succeeded, this will too */
+ in_buf.value = names[1].name;
+ in_buf.length = strlen(names[1].name) + 1;
+ (void) gss_import_name(&OMret, &in_buf, (gss_OID) nt_krb5_name_oid,
+ &gss_changepw_name);
+ if (oldnames) {
+ in_buf.value = names[3].name;
+ in_buf.length = strlen(names[3].name) + 1;
+ (void) gss_import_name(&OMret, &in_buf, (gss_OID) nt_krb5_name_oid,
+ &gss_oldchangepw_name);
+ }
+
+ if ((ret = kadm5int_acl_init(context, 0, params.acl_file))) {
+ errmsg = krb5_get_error_message (context, ret);
+ krb5_klog_syslog(LOG_ERR, gettext("Cannot initialize acl file: %s"),
+ errmsg);
+ fprintf(stderr, gettext("%s: Cannot initialize acl file: %s\n"),
+ whoami, errmsg);
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
/*
* Solaris Kerberos:
@@ -974,33 +1038,6 @@ main(int argc, char *argv[])
/*
* Solaris Kerberos:
- * Call a private version of kadm5_init which potentially returns an
- * additional error string in case of failure.
- */
- if ((ret = kadm5_init2("kadmind", NULL,
- NULL, &params,
- KADM5_STRUCT_VERSION,
- KADM5_API_VERSION_2,
- db_args,
- &global_server_handle,
- &emsg)) != KADM5_OK) {
-
- krb5_klog_syslog(LOG_ERR,
- gettext("%s while initializing, aborting"),
- (emsg ? emsg : error_message(ret)));
- fprintf(stderr,
- gettext("%s: %s while initializing, aborting\n"),
- whoami, (emsg ? emsg : error_message(ret)));
- if (emsg)
- free(emsg);
-
- krb5_klog_close(context);
- kadm5_destroy(context);
- exit(1);
- }
-
- /*
- * Solaris Kerberos:
* List the logs (FILE, STDERR, etc) which are currently being
* logged to and print to stderr. Useful when trying to
* track down a failure via SMF.
@@ -1012,21 +1049,31 @@ main(int argc, char *argv[])
error_message(ret));
}
- if (!nofork && (ret = daemon(0, 0))) {
- ret = errno;
- krb5_klog_syslog(LOG_ERR,
- gettext("Cannot detach from tty: %s"),
- error_message(ret));
- fprintf(stderr, gettext("%s: Cannot detach from tty: %s\n"),
- whoami, error_message(ret));
- krb5_klog_close(context);
- exit(1);
- }
-
- if( db_args )
- {
- free(db_args), db_args=NULL;
- }
+ if (!nofork && (ret = daemon(0, 0))) {
+ ret = errno;
+ errmsg = krb5_get_error_message (context, ret);
+ krb5_klog_syslog(LOG_ERR,
+ gettext("Cannot detach from tty: %s"), errmsg);
+ fprintf(stderr, gettext("%s: Cannot detach from tty: %s\n"),
+ whoami, errmsg);
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
+
+ /* SUNW14resync */
+#if 0
+ krb5_klog_syslog(LOG_INFO, "Seeding random number generator");
+ ret = krb5_c_random_os_entropy(context, 1, NULL);
+ if (ret) {
+ krb5_klog_syslog(LOG_ERR, "Error getting random seed: %s, aborting",
+ krb5_get_error_message(context, ret));
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
+#endif
+
handle = global_server_handle;
ctx = handle->context;
@@ -1117,10 +1164,6 @@ main(int argc, char *argv[])
rpc_gss_error_t err;
(void) rpc_gss_get_error(&err);
- /* Try to determine if the error was caused by a missing keytab or
- * missing keytab entries (and log it).
- */
- log_kt_error(kiprop_name, whoami);
krb5_klog_syslog(LOG_ERR,
gettext("Unable to set RPCSEC_GSS service name (`%s'), failing."),
kiprop_name ? kiprop_name : "<null>");
@@ -1191,7 +1234,6 @@ main(int argc, char *argv[])
exit(0);
}
-
/*
* Function: kadm_svc_run
*
@@ -1203,16 +1245,16 @@ main(int argc, char *argv[])
* Effects:
* Modifies:
*/
-void
-kadm_svc_run(void)
+
+void kadm_svc_run(void)
{
- struct pollfd *rfd = 0;
- struct timeval timeout;
- int pollret;
- int nfds = 0;
- int i;
+ struct pollfd *rfd = 0;
+ struct timeval timeout;
+ int pollret;
+ int nfds = 0;
+ int i;
- while(signal_request_exit == 0) {
+ while(signal_request_exit == 0) {
timeout.tv_sec = TIMEOUT;
timeout.tv_usec = 0;
@@ -1268,10 +1310,10 @@ kadm_svc_run(void)
* Purpose: Setup signal handling functions with System V's signal().
*/
void setup_signal_handlers(iprop_role iproprole) {
- signal(SIGINT, sig_exit);
- signal(SIGTERM, sig_exit);
- signal(SIGQUIT, sig_exit);
- signal(SIGPIPE, sig_pipe);
+ signal(SIGINT, request_exit);
+ signal(SIGTERM, request_exit);
+ signal(SIGQUIT, request_exit);
+ signal(SIGPIPE, sig_pipe);
/*
* IProp will fork for a full-resync, we don't want to
@@ -1285,125 +1327,41 @@ void setup_signal_handlers(iprop_role iproprole) {
/*
- * Function: sig_exit
- *
+ * Function: request_exit
+ *
* Purpose: sets flags saying the server got a signal and that it
- * should exit when convenient.
+ * should exit when convient.
*
+ * Arguments:
+ * Requires:
* Effects:
- * Modifies signal_request_exit which ideally makes the server exit
- * at some point.
+ * modifies signal_request_exit which ideally makes the server exit
+ * at some point.
*
* Modifies:
- * Signal_request_exit
+ * signal_request_exit
*/
-void sig_exit(int signum)
+
+void request_exit(int signum)
{
- krb5_klog_syslog(LOG_NOTICE, gettext("Got signal to request exit"));
- signal_request_exit = 1;
- return;
+ krb5_klog_syslog(LOG_NOTICE, gettext("Got signal to request exit"));
+ signal_request_exit = 1;
+ return;
}
-
/*
* Function: sig_pipe
*
* Purpose: SIGPIPE handler
*
- * Effects: krb5_klog_syslog a message that a SIGPIPE occurred and returns,
+ * Effects: krb5_klog_syslogs a message that a SIGPIPE occurred and returns,
* thus causing the read() or write() to fail and, presumable, the RPC
- * to recover. Otherwise, the process aborts.
+ * to recover. Otherwise, the process aborts.
*/
-void
-sig_pipe(int unused)
+void sig_pipe(int unused)
{
- krb5_klog_syslog(LOG_NOTICE, gettext("Warning: Received a SIGPIPE; "
- "probably a client aborted. Continuing."));
-}
-
-
-/*
- * Given a service name (s_name) determine if the keytab file exists
- * and if the keytab entry is present. Log missing keytab
- * at LOG_ERR and log missing keytab entries at LOG_WARNING.
- * If any of krb5_* (or strdup) fail it will return the failure.
- */
-krb5_error_code log_kt_error(char *s_name, char *whoami) {
- krb5_keytab kt;
- krb5_principal princ;
- krb5_keytab_entry entry;
- krb5_error_code code = 0;
- char kt_name[MAX_KEYTAB_NAME_LEN];
- char *service;
- char *host;
-
- service = strdup(s_name);
- if(!service)
- return ENOMEM;
-
- host = strchr(service, '@');
- *host++ = '\0';
- if (code = krb5_sname_to_principal(context, host,
- service, KRB5_NT_SRV_HST, &princ)) {
- krb5_klog_syslog(LOG_ERR,
- gettext("krb5_sname_to_principal failed: %s"),
- error_message(code));
- fprintf(stderr, gettext("%s: krb5_sname_to_principal failed: %s\n"),
- whoami, error_message(code));
- free(service);
- return code;
- }
-
- if (code = krb5_kt_default_name(context, kt_name, sizeof (kt_name))) {
- krb5_klog_syslog(LOG_ERR,
- gettext("krb5_kt_default_name failed: %s"),
- error_message(code));
- fprintf(stderr, gettext("%s: krb5_kt_default_name failed: %s\n"),
- whoami, error_message(code));
- krb5_free_principal(context, princ);
- free(service);
- return code;
- }
-
- if (code = krb5_kt_default(context, &kt)) {
- krb5_klog_syslog(LOG_ERR,
- gettext("krb5_kt_default failed: %s"),
- error_message(code));
- fprintf(stderr, gettext("%s: krb5_kt_default failed: %s\n"),
- whoami, error_message(code));
- krb5_free_principal(context, princ);
- free(service);
- return code;
- }
-
- code = krb5_kt_get_entry(context, kt, princ, 0, 0, &entry);
-
- switch (code) {
- case 0:
- krb5_kt_free_entry(context, &entry);
- break;
- case KRB5_KT_NOTFOUND:
- krb5_klog_syslog(LOG_WARNING,
- gettext("Keytab entry \"%s/%s\" is missing from \"%s\""),
- service, host,
- kt_name);
- fprintf(stderr, gettext("%s: Keytab entry \"%s/%s\" is missing from \"%s\".\n"),
- whoami,
- service, host,
- kt_name);
- break;
- case ENOENT:
- krb5_klog_syslog(LOG_ERR,
- gettext("Keytab file \"%s\" does not exist"),
- kt_name);
- fprintf(stderr, gettext("%s: Keytab file \"%s\" does not exist.\n"),
- whoami,
- kt_name);
- break;
- }
- krb5_kt_close(context,kt);
- krb5_free_principal(context, princ);
- free(service);
- return code;
+ krb5_klog_syslog(LOG_NOTICE, gettext("Warning: Received a SIGPIPE; "
+ "probably a client aborted. Continuing."));
+ return;
}
diff --git a/usr/src/cmd/krb5/kadmin/server/server_stubs.c b/usr/src/cmd/krb5/kadmin/server/server_stubs.c
index a9c46a49f4..5d36f5c2c5 100644
--- a/usr/src/cmd/krb5/kadmin/server/server_stubs.c
+++ b/usr/src/cmd/krb5/kadmin/server/server_stubs.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -28,10 +27,9 @@
*
*/
+#include <kadm5/admin.h>
#include <gssapi/gssapi.h>
#include <gssapi_krb5.h> /* for gss_nt_krb5_name */
-#include <krb5.h>
-#include <kadm5/admin.h>
#include <kadm5/kadm_rpc.h>
#include <kadm5/server_internal.h>
#include <kadm5/srv/server_acl.h>
@@ -41,6 +39,7 @@
#include <arpa/inet.h> /* inet_ntoa */
#include <krb5/adm_proto.h> /* krb5_klog_syslog */
#include <libintl.h>
+#include <krb5.h>
#include "misc.h"
#define LOG_UNAUTH gettext("Unauthorized request: %s, %s, " \
@@ -463,12 +462,12 @@ log_unauth(
trunc_name(&slen, &sdots);
return krb5_klog_syslog(LOG_NOTICE,
- "Unauthorized request: %s, %.*s%s, "
- "client=%.*s%s, service=%.*s%s, addr=%s",
- op, tlen, target, tdots,
- clen, client, cdots,
- slen, server, sdots,
- addr);
+ "Unauthorized request: %s, %.*s%s, "
+ "client=%.*s%s, service=%.*s%s, addr=%s",
+ op, tlen, target, tdots,
+ clen, client, cdots,
+ slen, server, sdots,
+ addr);
}
static int
@@ -491,16 +490,16 @@ log_done(
trunc_name(&slen, &sdots);
return krb5_klog_syslog(LOG_NOTICE,
- "Request: %s, %.*s%s, %s, "
- "client=%.*s%s, service=%.*s%s, addr=%s",
- op, tlen, target, tdots, errmsg,
- clen, client, cdots,
- slen, server, sdots,
- addr);
+ "Request: %s, %.*s%s, %s, "
+ "client=%.*s%s, service=%.*s%s, addr=%s",
+ op, tlen, target, tdots, errmsg,
+ clen, client, cdots,
+ slen, server, sdots,
+ addr);
}
generic_ret *
-create_principal_1_svc(cprinc_arg *arg, struct svc_req *rqstp)
+create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg = NULL;
@@ -511,6 +510,7 @@ create_principal_1_svc(cprinc_arg *arg, struct svc_req *rqstp)
kadm5_server_handle_t handle;
kadm5_ret_t retval;
restriction_t *rp;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_generic_ret, (char *) &ret);
@@ -558,14 +558,20 @@ create_principal_1_svc(cprinc_arg *arg, struct svc_req *rqstp)
ret.code = kadm5_create_principal((void *)handle,
&arg->rec, arg->mask,
arg->passwd);
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
audit_kadmind_auth(rqstp->rq_xprt, l_port,
"kadm5_create_principal",
prime_arg, client_name, ret.code);
log_done("kadm5_create_principal", prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
+ errmsg ? errmsg : "success",
client_name, service_name, client_addr(rqstp, buf));
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
+
if (policy_migrate && (ret.code == 0)) {
arg->rec.policy = strdup("default");
if ((arg->mask & KADM5_PW_EXPIRATION)) {
@@ -600,7 +606,7 @@ error:
}
generic_ret *
-create_principal3_1_svc(cprinc3_arg *arg, struct svc_req *rqstp)
+create_principal3_2_svc(cprinc3_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg = NULL;
@@ -611,6 +617,7 @@ create_principal3_1_svc(cprinc3_arg *arg, struct svc_req *rqstp)
kadm5_server_handle_t handle;
kadm5_ret_t retval;
restriction_t *rp;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_generic_ret, (char *) &ret);
@@ -649,16 +656,23 @@ create_principal3_1_svc(cprinc3_arg *arg, struct svc_req *rqstp)
&arg->rec, &arg->mask, rp)) {
ret.code = KADM5_AUTH_ADD;
log_unauth("kadm5_create_principal", prime_arg,
- client_name, service_name, client_addr(rqstp, buf));
+ client_name, service_name, client_addr(rqstp, buf));
} else {
ret.code = kadm5_create_principal_3((void *)handle,
&arg->rec, arg->mask,
arg->n_ks_tuple,
arg->ks_tuple,
arg->passwd);
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
+
log_done("kadm5_create_principal", prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
if (policy_migrate && (ret.code == 0)) {
arg->rec.policy = strdup("default");
@@ -693,15 +707,18 @@ error:
}
generic_ret *
-delete_principal_1_svc(dprinc_arg *arg, struct svc_req *rqstp)
+delete_principal_2_svc(dprinc_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg = NULL;
char *client_name = NULL, *service_name = NULL;
- OM_uint32 min_stat;
- kadm5_server_handle_t handle;
+ OM_uint32 min_stat;
+ kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
+
gss_name_t name = NULL;
+
xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
@@ -736,13 +753,20 @@ delete_principal_1_svc(dprinc_arg *arg, struct svc_req *rqstp)
service_name, client_addr(rqstp, buf));
} else {
ret.code = kadm5_delete_principal((void *)handle, arg->princ);
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
audit_kadmind_auth(rqstp->rq_xprt, l_port,
"kadm5_delete_principal",
prime_arg, client_name, ret.code);
- log_done("kadm5_delete_principal", prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ log_done("kadm5_delete_principal", prime_arg,
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
+
}
error:
@@ -759,7 +783,7 @@ error:
}
generic_ret *
-modify_principal_1_svc(mprinc_arg *arg, struct svc_req *rqstp)
+modify_principal_2_svc(mprinc_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg = NULL;
@@ -768,6 +792,7 @@ modify_principal_1_svc(mprinc_arg *arg, struct svc_req *rqstp)
kadm5_server_handle_t handle;
restriction_t *rp;
gss_name_t name = NULL;
+ const char *errmsg = NULL;
xdr_free(xdr_generic_ret, (char *) &ret);
@@ -804,13 +829,19 @@ modify_principal_1_svc(mprinc_arg *arg, struct svc_req *rqstp)
} else {
ret.code = kadm5_modify_principal((void *)handle, &arg->rec,
arg->mask);
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
audit_kadmind_auth(rqstp->rq_xprt, l_port,
"kadm5_modify_principal",
prime_arg, client_name, ret.code);
log_done("kadm5_modify_principal", prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -827,7 +858,7 @@ error:
}
generic_ret *
-rename_principal_1_svc(rprinc_arg *arg, struct svc_req *rqstp)
+rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg1 = NULL, *prime_arg2 = NULL;
@@ -836,6 +867,7 @@ rename_principal_1_svc(rprinc_arg *arg, struct svc_req *rqstp)
OM_uint32 min_stat;
kadm5_server_handle_t handle;
restriction_t *rp;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
size_t tlen1, tlen2, clen, slen;
char *tdots1, *tdots2, *cdots, *sdots;
@@ -906,19 +938,26 @@ rename_principal_1_svc(rprinc_arg *arg, struct svc_req *rqstp)
} else {
ret.code = kadm5_rename_principal((void *)handle, arg->src,
arg->dest);
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
audit_kadmind_auth(rqstp->rq_xprt, l_port,
"kadm5_rename_principal",
prime_arg, client_name, ret.code);
- krb5_klog_syslog(LOG_NOTICE,
- "Request: kadm5_rename_principal, "
- "%.*s%s to %.*s%s, %s, "
- "client=%.*s%s, service=%.*s%s, addr=%s",
- tlen1, prime_arg1, tdots1,
- tlen2, prime_arg2, tdots2,
- clen, client_name, cdots,
- slen, service_name, sdots,
- client_addr(rqstp, buf));
+ krb5_klog_syslog(LOG_NOTICE,
+ "Request: kadm5_rename_principal, "
+ "%.*s%s to %.*s%s, %s, "
+ "client=%.*s%s, service=%.*s%s, addr=%s",
+ tlen1, prime_arg1, tdots1,
+ tlen2, prime_arg2, tdots2,
+ errmsg ? errmsg : "success",
+ clen, client_name, cdots,
+ slen, service_name, sdots,
+ client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -937,7 +976,7 @@ error:
}
gprinc_ret *
-get_principal_1_svc(gprinc_arg *arg, struct svc_req *rqstp)
+get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp)
{
static gprinc_ret ret;
kadm5_principal_ent_t_v1 e;
@@ -945,6 +984,7 @@ get_principal_1_svc(gprinc_arg *arg, struct svc_req *rqstp)
char *client_name = NULL, *service_name = NULL;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_gprinc_ret, (char *) &ret);
@@ -999,12 +1039,18 @@ get_principal_1_svc(gprinc_arg *arg, struct svc_req *rqstp)
arg->mask);
}
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
+
audit_kadmind_auth(rqstp->rq_xprt, l_port,
funcname,
prime_arg, client_name, ret.code);
- log_done(funcname, prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ log_done(funcname, prime_arg, errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -1021,7 +1067,7 @@ error:
}
gprincs_ret *
-get_princs_1_svc(gprincs_arg *arg, struct svc_req *rqstp)
+get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp)
{
static gprincs_ret ret;
char *prime_arg = NULL;
@@ -1029,6 +1075,7 @@ get_princs_1_svc(gprincs_arg *arg, struct svc_req *rqstp)
OM_uint32 min_stat;
kadm5_server_handle_t handle;
gss_name_t name = NULL;
+ const char *errmsg = NULL;
xdr_free(xdr_gprincs_ret, (char *) &ret);
@@ -1068,13 +1115,19 @@ get_princs_1_svc(gprincs_arg *arg, struct svc_req *rqstp)
ret.code = kadm5_get_principals((void *)handle,
arg->exp, &ret.princs,
&ret.count);
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
audit_kadmind_auth(rqstp->rq_xprt, l_port,
"kadm5_get_principals",
prime_arg, client_name, ret.code);
- log_done("kadm5_get_principals", prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ log_done("kadm5_get_principals", prime_arg,
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -1089,13 +1142,14 @@ error:
}
generic_ret *
-chpass_principal_1_svc(chpass_arg *arg, struct svc_req *rqstp)
+chpass_principal_2_svc(chpass_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg = NULL;
char *client_name = NULL, *service_name = NULL;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_generic_ret, (char *) &ret);
@@ -1138,12 +1192,19 @@ chpass_principal_1_svc(chpass_arg *arg, struct svc_req *rqstp)
}
if(ret.code != KADM5_AUTH_CHANGEPW) {
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
+
audit_kadmind_auth(rqstp->rq_xprt, l_port,
"kadm5_chpass_principal",
prime_arg, client_name, ret.code);
log_done("kadm5_chpass_principal", prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -1160,7 +1221,7 @@ error:
}
generic_ret *
-chpass_principal3_1_svc(chpass3_arg *arg, struct svc_req *rqstp)
+chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg = NULL;
@@ -1168,6 +1229,7 @@ chpass_principal3_1_svc(chpass3_arg *arg, struct svc_req *rqstp)
*service_name = NULL;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_generic_ret, (char *) &ret);
@@ -1213,9 +1275,16 @@ chpass_principal3_1_svc(chpass3_arg *arg, struct svc_req *rqstp)
}
if(ret.code != KADM5_AUTH_CHANGEPW) {
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
+
log_done("kadm5_chpass_principal", prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
+ errmsg ? errmsg : "success",
client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -1233,7 +1302,7 @@ error:
#ifdef SUNWOFF
generic_ret *
-setv4key_principal_1_svc(setv4key_arg *arg, struct svc_req *rqstp)
+setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg = NULL;
@@ -1241,6 +1310,7 @@ setv4key_principal_1_svc(setv4key_arg *arg, struct svc_req *rqstp)
*service_name = NULL;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_generic_ret, (char *) &ret);
@@ -1277,9 +1347,16 @@ setv4key_principal_1_svc(setv4key_arg *arg, struct svc_req *rqstp)
}
if(ret.code != KADM5_AUTH_SETKEY) {
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
+
log_done("kadm5_setv4key_principal", prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -1297,7 +1374,7 @@ error:
#endif
generic_ret *
-setkey_principal_1_svc(setkey_arg *arg, struct svc_req *rqstp)
+setkey_principal_2_svc(setkey_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg;
@@ -1305,6 +1382,7 @@ setkey_principal_1_svc(setkey_arg *arg, struct svc_req *rqstp)
*service_name;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name;
xdr_free(xdr_generic_ret, (char *) &ret);
@@ -1340,9 +1418,16 @@ setkey_principal_1_svc(setkey_arg *arg, struct svc_req *rqstp)
}
if(ret.code != KADM5_AUTH_SETKEY) {
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
+
log_done("kadm5_setkey_principal", prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -1359,7 +1444,7 @@ error:
}
generic_ret *
-setkey_principal3_1_svc(setkey3_arg *arg, struct svc_req *rqstp)
+setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg = NULL;
@@ -1367,6 +1452,7 @@ setkey_principal3_1_svc(setkey3_arg *arg, struct svc_req *rqstp)
*service_name = NULL;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_generic_ret, (char *) &ret);
@@ -1406,9 +1492,16 @@ setkey_principal3_1_svc(setkey3_arg *arg, struct svc_req *rqstp)
}
if(ret.code != KADM5_AUTH_SETKEY) {
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
+
log_done("kadm5_setkey_principal", prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -1425,7 +1518,7 @@ error:
}
chrand_ret *
-chrand_principal_1_svc(chrand_arg *arg, struct svc_req *rqstp)
+chrand_principal_2_svc(chrand_arg *arg, struct svc_req *rqstp)
{
static chrand_ret ret;
krb5_keyblock *k;
@@ -1434,6 +1527,7 @@ chrand_principal_1_svc(chrand_arg *arg, struct svc_req *rqstp)
char *client_name = NULL, *service_name = NULL;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_chrand_ret, (char *) &ret);
@@ -1489,12 +1583,18 @@ chrand_principal_1_svc(chrand_arg *arg, struct svc_req *rqstp)
}
if(ret.code != KADM5_AUTH_CHANGEPW) {
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
+
audit_kadmind_auth(rqstp->rq_xprt, l_port,
funcname, prime_arg, client_name, ret.code);
- log_done(funcname, prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
- }
+ log_done(funcname, prime_arg, errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
+ }
error:
if (name)
@@ -1510,7 +1610,7 @@ error:
}
chrand_ret *
-chrand_principal3_1_svc(chrand3_arg *arg, struct svc_req *rqstp)
+chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req *rqstp)
{
static chrand_ret ret;
krb5_keyblock *k;
@@ -1520,6 +1620,7 @@ chrand_principal3_1_svc(chrand3_arg *arg, struct svc_req *rqstp)
*service_name = NULL;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_chrand_ret, (char *) &ret);
@@ -1578,10 +1679,15 @@ chrand_principal3_1_svc(chrand3_arg *arg, struct svc_req *rqstp)
}
if(ret.code != KADM5_AUTH_CHANGEPW) {
- /* Solaris Kerberos: Better error messages */
- log_done(funcname, prime_arg, ((ret.code == 0) ? "success" :
- krb5_get_error_message(handle->context, ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
+
+ log_done(funcname, prime_arg, errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -1598,13 +1704,14 @@ error:
}
generic_ret *
-create_policy_1_svc(cpol_arg *arg, struct svc_req *rqstp)
+create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg = NULL;
char *client_name = NULL, *service_name = NULL;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_generic_ret, (char *) &ret);
@@ -1637,19 +1744,25 @@ create_policy_1_svc(cpol_arg *arg, struct svc_req *rqstp)
"kadm5_create_policy",
prime_arg, client_name);
log_unauth("kadm5_create_policy", prime_arg,
- client_name, service_name, client_addr(rqstp, buf));
-
+ client_name, service_name, client_addr(rqstp, buf));
+
} else {
ret.code = kadm5_create_policy((void *)handle, &arg->rec,
arg->mask);
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
audit_kadmind_auth(rqstp->rq_xprt, l_port,
"kadm5_create_policy",
prime_arg, client_name, ret.code);
log_done("kadm5_create_policy",
- ((prime_arg == NULL) ? "(null)" : prime_arg),
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ ((prime_arg == NULL) ? "(null)" : prime_arg),
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -1664,13 +1777,14 @@ error:
}
generic_ret *
-delete_policy_1_svc(dpol_arg *arg, struct svc_req *rqstp)
+delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg = NULL;
char *client_name = NULL, *service_name = NULL;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_generic_ret, (char *) &ret);
@@ -1705,14 +1819,20 @@ delete_policy_1_svc(dpol_arg *arg, struct svc_req *rqstp)
ret.code = KADM5_AUTH_DELETE;
} else {
ret.code = kadm5_delete_policy((void *)handle, arg->name);
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
audit_kadmind_auth(rqstp->rq_xprt, l_port,
"kadm5_delete_policy",
prime_arg, client_name, ret.code);
log_done("kadm5_delete_policy",
- ((prime_arg == NULL) ? "(null)" : prime_arg),
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ ((prime_arg == NULL) ? "(null)" : prime_arg),
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -1727,13 +1847,14 @@ error:
}
generic_ret *
-modify_policy_1_svc(mpol_arg *arg, struct svc_req *rqstp)
+modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *prime_arg = NULL;
char *client_name = NULL, *service_name = NULL;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_generic_ret, (char *) &ret);
@@ -1769,15 +1890,21 @@ modify_policy_1_svc(mpol_arg *arg, struct svc_req *rqstp)
} else {
ret.code = kadm5_modify_policy((void *)handle, &arg->rec,
arg->mask);
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
audit_kadmind_auth(rqstp->rq_xprt, l_port,
"kadm5_modify_policy",
prime_arg, client_name, ret.code);
log_done("kadm5_modify_policy",
- ((prime_arg == NULL) ? "(null)" : prime_arg),
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
- }
+ ((prime_arg == NULL) ? "(null)" : prime_arg),
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
+ }
error:
if (name)
@@ -1791,7 +1918,7 @@ error:
}
gpol_ret *
-get_policy_1_svc(gpol_arg *arg, struct svc_req *rqstp)
+get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp)
{
static gpol_ret ret;
kadm5_ret_t ret2;
@@ -1802,6 +1929,7 @@ get_policy_1_svc(gpol_arg *arg, struct svc_req *rqstp)
kadm5_principal_ent_rec caller_ent;
krb5_principal caller;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_gpol_ret, (char *) &ret);
@@ -1861,16 +1989,25 @@ get_policy_1_svc(gpol_arg *arg, struct svc_req *rqstp)
&ret.rec);
}
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
+
audit_kadmind_auth(rqstp->rq_xprt, l_port,
funcname, prime_arg, client_name, ret.code);
- log_done(funcname, ((prime_arg == NULL) ? "(null)" : prime_arg),
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
- } else {
+ log_done(funcname,
+ ((prime_arg == NULL) ? "(null)" : prime_arg),
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
+
+ } else {
audit_kadmind_unauth(rqstp->rq_xprt, l_port,
funcname, prime_arg, client_name);
- log_unauth(funcname, prime_arg, client_name,
- service_name, client_addr(rqstp, buf));
+ log_unauth(funcname, prime_arg,
+ client_name, service_name, client_addr(rqstp, buf));
}
error:
@@ -1886,13 +2023,14 @@ error:
}
gpols_ret *
-get_pols_1_svc(gpols_arg *arg, struct svc_req *rqstp)
+get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp)
{
static gpols_ret ret;
char *prime_arg = NULL;
char *client_name = NULL, *service_name = NULL;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_gpols_ret, (char *) &ret);
@@ -1927,18 +2065,24 @@ get_pols_1_svc(gpols_arg *arg, struct svc_req *rqstp)
"kadm5_get_policies",
prime_arg, client_name);
log_unauth("kadm5_get_policies", prime_arg,
- client_name, service_name, client_addr(rqstp, buf));
+ client_name, service_name, client_addr(rqstp, buf));
} else {
ret.code = kadm5_get_policies((void *)handle,
- arg->exp, &ret.pols,
- &ret.count);
+ arg->exp, &ret.pols,
+ &ret.count);
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
audit_kadmind_auth(rqstp->rq_xprt, l_port,
"kadm5_get_policies",
prime_arg, client_name, ret.code);
- log_done("kadm5_get_policies", prime_arg,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
- client_name, service_name, client_addr(rqstp, buf));
+ log_done("kadm5_get_policies", prime_arg,
+ errmsg ? errmsg : "success",
+ client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
}
error:
@@ -1952,12 +2096,13 @@ error:
return (&ret);
}
-getprivs_ret * get_privs_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
+getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
{
static getprivs_ret ret;
char *client_name = NULL, *service_name = NULL;
OM_uint32 min_stat;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
gss_name_t name = NULL;
xdr_free(xdr_getprivs_ret, (char *) &ret);
@@ -1980,13 +2125,19 @@ getprivs_ret * get_privs_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
}
ret.code = __kadm5_get_priv((void *) handle, &ret.privs, name);
+ /* Solaris Kerberos */
+ if( ret.code != 0 )
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
audit_kadmind_auth(rqstp->rq_xprt, l_port,
"kadm5_get_privs", NULL, client_name,
ret.code);
log_done("kadm5_get_privs", client_name,
- ((ret.code == 0) ? "success" : error_message(ret.code)),
+ errmsg ? errmsg : "success",
client_name, service_name, client_addr(rqstp, buf));
+
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
error:
if (name)
@@ -1999,11 +2150,12 @@ error:
return (&ret);
}
-generic_ret *init_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
+generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
{
static generic_ret ret;
char *client_name, *service_name;
kadm5_server_handle_t handle;
+ const char *errmsg = NULL;
size_t clen, slen;
char *cdots, *sdots;
@@ -2022,25 +2174,31 @@ generic_ret *init_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
return &ret;
}
+ /* Solaris Kerberos */
+ if (ret.code != 0)
+ errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
+
audit_kadmind_auth(rqstp->rq_xprt, l_port,
(ret.api_version == KADM5_API_VERSION_1 ?
"kadm5_init (V1)" : "kadm5_init"),
NULL, client_name, ret.code);
- clen = strlen(client_name);
- trunc_name(&clen, &cdots);
- slen = strlen(service_name);
- trunc_name(&slen, &sdots);
- krb5_klog_syslog(LOG_NOTICE, "Request %s, %.*s%s, %s, "
- "client=%.*s%s, service=%.*s%s, addr=%s, flavor=%d",
- (ret.api_version == KADM5_API_VERSION_1 ?
- "kadm5_init (V1)" : "kadm5_init"),
- clen, client_name, cdots,
- (ret.code == 0) ? "success" : error_message(ret.code),
- clen, client_name, cdots,
- slen, service_name, sdots,
- client_addr(rqstp, buf),
- rqstp->rq_cred.oa_flavor);
+ clen = strlen(client_name);
+ trunc_name(&clen, &cdots);
+ slen = strlen(service_name);
+ trunc_name(&slen, &sdots);
+ krb5_klog_syslog(LOG_NOTICE, "Request: %s, %.*s%s, %s, "
+ "client=%.*s%s, service=%.*s%s, addr=%s, flavor=%d",
+ (ret.api_version == KADM5_API_VERSION_1 ?
+ "kadm5_init (V1)" : "kadm5_init"),
+ clen, client_name, cdots,
+ errmsg ? errmsg : "success",
+ clen, client_name, cdots,
+ slen, service_name, sdots,
+ client_addr(rqstp, buf),
+ rqstp->rq_cred.oa_flavor);
+ if (errmsg != NULL)
+ krb5_free_error_message(handle ? handle->context : NULL, errmsg);
free(client_name);
free(service_name);
diff --git a/usr/src/cmd/krb5/kdestroy/kdestroy.c b/usr/src/cmd/krb5/kdestroy/kdestroy.c
index df578d13e1..14c34c0d1c 100644
--- a/usr/src/cmd/krb5/kdestroy/kdestroy.c
+++ b/usr/src/cmd/krb5/kdestroy/kdestroy.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* clients/kdestroy/kdestroy.c
@@ -126,6 +125,7 @@ main(argc, argv)
int use_k5 = 0;
int use_k4 = 0;
+ progname = GET_PROGNAME(argv[0]);
/* set locale and domain for internationalization */
(void) setlocale(LC_ALL, "");
@@ -140,9 +140,8 @@ main(argc, argv)
got_k4 = 1;
#endif
- progname = (strrchr(*argv, '/') ? strrchr(*argv, '/')+1 : argv[0]);
-
- while ((c = getopt(argc, argv, "54qc:")) != -1) { switch (c) {
+ while ((c = getopt(argc, argv, "54qc:")) != -1) {
+ switch (c) {
case 'q':
quiet = 1;
break;
@@ -231,9 +230,6 @@ main(argc, argv)
}
if (cache_name) {
-
-
-
#ifdef KRB5_KRB4_COMPAT
v4 = 0; /* Don't do v4 if doing v5 and cache name given. */
#endif
diff --git a/usr/src/cmd/krb5/kinit/kinit.c b/usr/src/cmd/krb5/kinit/kinit.c
index c5e3030960..a09e7b1c93 100644
--- a/usr/src/cmd/krb5/kinit/kinit.c
+++ b/usr/src/cmd/krb5/kinit/kinit.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* clients/kinit/kinit.c
@@ -39,26 +38,31 @@
#include <libintl.h>
#include <krb5.h>
-
#ifdef KRB5_KRB4_COMPAT
#include <kerberosIV/krb.h>
#define HAVE_KRB524
#else
#undef HAVE_KRB524
-#endif /* KRB5_KRB4_COMPAT */
-
+#endif
#include <string.h>
#include <stdio.h>
#include <time.h>
+#include <errno.h>
+#include <com_err.h>
#include <netdb.h>
#include <locale.h>
#ifdef GETOPT_LONG
#include <getopt.h>
-#else /* GETOPT_LONG */
+#else
#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#else /* HAVE_UNISTD_H */
+#ifdef sun
+/* SunOS4 unistd didn't declare these; okay to make unconditional? */
+extern int optind;
+extern char *optarg;
+#endif /* sun */
+#else
extern int optind;
extern char *optarg;
extern int getopt();
@@ -67,9 +71,9 @@ extern int getopt();
#ifndef _WIN32
#define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x))
-#else /* _WIN32 */
+#else
#define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x))
-#endif /* _WIN32 */
+#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
@@ -108,7 +112,7 @@ static char* progname_v5 = 0;
#ifdef KRB5_KRB4_COMPAT
static char* progname_v4 = 0;
static char* progname_v524 = 0;
-#endif /* KRB5_KRB4_COMPAT */
+#endif
#include <locale.h>
static int got_k5 = 0;
@@ -117,9 +121,9 @@ static int got_k4 = 0;
static int default_k5 = 1;
#if defined(KRB5_KRB4_COMPAT) && defined(KINIT_DEFAULT_BOTH)
static int default_k4 = 1;
-#else /* KRB5_KRB4_COMPAT && KINIT_DEFAULT_BOTH */
+#else
static int default_k4 = 0;
-#endif /* KRB5_KRB4_COMPAT && KINIT_DEFAULT_BOTH */
+#endif
static int authed_k5 = 0;
static int authed_k4 = 0;
@@ -153,6 +157,9 @@ struct k_opts
char* k4_cache_name;
action_type action;
+
+ int num_pa_opts;
+ krb5_gic_opt_pa_data *pa_opts;
};
int forwardable_flag = 0;
@@ -193,7 +200,7 @@ struct k4_data
char inst[INST_SZ + 1];
char realm[REALM_SZ + 1];
char name[ANAME_SZ + 1 + INST_SZ + 1 + REALM_SZ + 1];
-#endif /*KRB5_KRB4_COMPAT */
+#endif
};
char *realmdef[] = { "realms", NULL, "kinit", NULL };
@@ -210,8 +217,8 @@ char *appdef[] = { "appdefaults", "kinit", NULL };
krb5_preauthtype * preauth = NULL;
krb5_preauthtype preauth_list[2] = { 0, -1 };
-static void _kwarnd_add_warning(char *, time_t);
-static void _kwarnd_del_warning(char *);
+static void _kwarnd_add_warning(char *, char *, time_t);
+static void _kwarnd_del_warning(char *, char *);
#ifdef GETOPT_LONG
/* if struct[2] == NULL, then long_getopt acts as if the short flag
@@ -230,15 +237,13 @@ struct option long_options[] = {
};
#define GETOPT(argc, argv, str) getopt_long(argc, argv, str, long_options, 0)
-#else /* GETOPT_LONG */
+#else
#define GETOPT(argc, argv, str) getopt(argc, argv, str)
-#endif /* GETOPT_LONG */
-
-/* Save the program name for the error messages */
-static char *progname;
+#endif
static void
usage(progname)
+ char *progname;
{
#define USAGE_BREAK "\n\t"
@@ -247,12 +252,12 @@ usage(progname)
#define USAGE_LONG_PROXIABLE " | --proxiable | --noproxiable"
#define USAGE_LONG_ADDRESSES " | --addresses | --noaddresses"
#define USAGE_BREAK_LONG USAGE_BREAK
-#else /* GETOPT_LONG */
+#else
#define USAGE_LONG_FORWARDABLE ""
#define USAGE_LONG_PROXIABLE ""
#define USAGE_LONG_ADDRESSES ""
#define USAGE_BREAK_LONG ""
-#endif /* GETOPT_LONG */
+#endif
fprintf(stderr, "%s : %s [-V] "
"[-l lifetime] [-s start_time] "
@@ -266,9 +271,10 @@ usage(progname)
USAGE_BREAK
"[-v] [-R] "
"[-k [-t keytab_file]] "
- USAGE_BREAK
"[-c cachename] "
- "[-S service_name] [principal]"
+ USAGE_BREAK
+ "[-S service_name]"
+ "[-X <attribute>[=<value>]] [principal]"
"\n\n",
gettext("Usage"), progname);
@@ -319,9 +325,53 @@ fprintf(stderr, USAGE_OPT_FMT, indent, col1)
/* This options is not yet available: */
/* ULINE("\t", "-C Kerberos 4 cache name", OPTTYPE_KRB4); */
ULINE("\t", gettext("-S service"), OPTTYPE_BOTH);
+ ULINE("\t", gettext("-X <attribute>[=<value>]"), OPTTYPE_KRB5);
exit(2);
}
+static krb5_context errctx;
+static void extended_com_err_fn (const char *myprog, errcode_t code,
+ const char *fmt, va_list args)
+{
+ const char *emsg;
+ emsg = krb5_get_error_message (errctx, code);
+ fprintf (stderr, "%s: %s ", myprog, emsg);
+ krb5_free_error_message (errctx, emsg);
+ vfprintf (stderr, fmt, args);
+ fprintf (stderr, "\n");
+}
+
+static int
+add_preauth_opt(struct k_opts *opts, char *av)
+{
+ char *sep, *v;
+ krb5_gic_opt_pa_data *p, *x;
+
+ if (opts->num_pa_opts == 0) {
+ opts->pa_opts = malloc(sizeof(krb5_gic_opt_pa_data));
+ if (opts->pa_opts == NULL)
+ return ENOMEM;
+ } else {
+ size_t newsize = (opts->num_pa_opts + 1) * sizeof(krb5_gic_opt_pa_data);
+ x = realloc(opts->pa_opts, newsize);
+ if (x == NULL)
+ return ENOMEM;
+ opts->pa_opts = x;
+ }
+ p = &opts->pa_opts[opts->num_pa_opts];
+ sep = strchr(av, '=');
+ if (sep) {
+ *sep = '\0';
+ v = ++sep;
+ p->value = v;
+ } else {
+ p->value = "yes";
+ }
+ p->attr = av;
+ opts->num_pa_opts++;
+ return 0;
+}
+
static char *
parse_options(argc, argv, opts, progname)
int argc;
@@ -335,7 +385,7 @@ parse_options(argc, argv, opts, progname)
int use_k5 = 0;
int i;
- while ((i = GETOPT(argc, argv, "r:fpFP54aAVl:s:c:kt:RS:v"))
+ while ((i = GETOPT(argc, argv, "r:fpFP54aAVl:s:c:kt:RS:vX:"))
!= -1) {
switch (i) {
case 'V':
@@ -420,6 +470,14 @@ parse_options(argc, argv, opts, progname)
opts->k5_cache_name = optarg;
}
break;
+ case 'X':
+ code = add_preauth_opt(opts, optarg);
+ if (code)
+ {
+ com_err(progname, code, "while adding preauth option");
+ errflg++;
+ }
+ break;
#if 0
/*
A little more work is needed before we can enable this
@@ -548,6 +606,7 @@ struct k4_data* k4;
com_err(progname, code, gettext("while initializing Kerberos 5 library"));
return 0;
}
+ errctx = k5->ctx;
if (opts->k5_cache_name)
{
code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc);
@@ -655,6 +714,7 @@ k5_end(k5)
krb5_cc_close(k5->ctx, k5->cc);
if (k5->ctx)
krb5_free_context(k5->ctx);
+ errctx = NULL;
memset(k5, 0, sizeof(*k5));
}
@@ -800,14 +860,17 @@ k5_kinit(opts, k5)
krb5_keytab keytab = 0;
krb5_creds my_creds;
krb5_error_code code = 0;
- krb5_get_init_creds_opt options;
+ krb5_get_init_creds_opt *options = NULL;
+ int i;
krb5_timestamp now;
krb5_deltat lifetime = 0, rlife = 0, krb5_max_duration;
if (!got_k5)
return 0;
- krb5_get_init_creds_opt_init(&options);
+ code = krb5_get_init_creds_opt_alloc(k5->ctx, &options);
+ if (code)
+ goto cleanup;
memset(&my_creds, 0, sizeof(my_creds));
/*
@@ -876,10 +939,10 @@ k5_kinit(opts, k5)
/* cmdline opts take precedence over krb5.conf file values */
if (!opts->not_proxiable && proxiable_flag) {
- krb5_get_init_creds_opt_set_proxiable(&options, 1);
+ krb5_get_init_creds_opt_set_proxiable(options, 1);
}
if (!opts->not_forwardable && forwardable_flag) {
- krb5_get_init_creds_opt_set_forwardable(&options, 1);
+ krb5_get_init_creds_opt_set_forwardable(options, 1);
}
if (renewable_flag) {
/*
@@ -890,7 +953,7 @@ k5_kinit(opts, k5)
}
if (no_address_flag) {
/* cmdline opts will overwrite this below if needbe */
- krb5_get_init_creds_opt_set_address_list(&options, NULL);
+ krb5_get_init_creds_opt_set_address_list(options, NULL);
}
@@ -900,17 +963,17 @@ k5_kinit(opts, k5)
*/
if (opts->lifetime)
- krb5_get_init_creds_opt_set_tkt_life(&options, opts->lifetime);
+ krb5_get_init_creds_opt_set_tkt_life(options, opts->lifetime);
if (opts->rlife)
- krb5_get_init_creds_opt_set_renew_life(&options, opts->rlife);
+ krb5_get_init_creds_opt_set_renew_life(options, opts->rlife);
if (opts->forwardable)
- krb5_get_init_creds_opt_set_forwardable(&options, 1);
+ krb5_get_init_creds_opt_set_forwardable(options, 1);
if (opts->not_forwardable)
- krb5_get_init_creds_opt_set_forwardable(&options, 0);
+ krb5_get_init_creds_opt_set_forwardable(options, 0);
if (opts->proxiable)
- krb5_get_init_creds_opt_set_proxiable(&options, 1);
+ krb5_get_init_creds_opt_set_proxiable(options, 1);
if (opts->not_proxiable)
- krb5_get_init_creds_opt_set_proxiable(&options, 0);
+ krb5_get_init_creds_opt_set_proxiable(options, 0);
if (opts->addresses)
{
krb5_address **addresses = NULL;
@@ -919,10 +982,10 @@ k5_kinit(opts, k5)
com_err(progname, code, gettext("getting local addresses"));
goto cleanup;
}
- krb5_get_init_creds_opt_set_address_list(&options, addresses);
+ krb5_get_init_creds_opt_set_address_list(options, addresses);
}
if (opts->no_addresses)
- krb5_get_init_creds_opt_set_address_list(&options, NULL);
+ krb5_get_init_creds_opt_set_address_list(options, NULL);
if ((opts->action == INIT_KT) && opts->keytab_name)
{
@@ -934,20 +997,31 @@ k5_kinit(opts, k5)
}
}
+ for (i = 0; i < opts->num_pa_opts; i++) {
+ code = krb5_get_init_creds_opt_set_pa(k5->ctx, options,
+ opts->pa_opts[i].attr,
+ opts->pa_opts[i].value);
+ if (code != 0) {
+ com_err(progname, code, "while setting '%s'='%s'",
+ opts->pa_opts[i].attr, opts->pa_opts[i].value);
+ goto cleanup;
+ }
+ }
+
switch (opts->action) {
case INIT_PW:
code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me,
0, kinit_prompter, 0,
opts->starttime,
opts->service_name,
- &options);
+ options);
break;
case INIT_KT:
code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me,
keytab,
opts->starttime,
opts->service_name,
- &options);
+ options);
break;
case VALIDATE:
code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->cc,
@@ -1007,52 +1081,26 @@ k5_kinit(opts, k5)
goto cleanup;
}
- /*
- * Solaris Kerberos:
- * The service ticket may or may not be host-based. If the requested
- * ticket is host-based and a "fallback" mechanism is being used to
- * determine the realm, subsequent searches by kerberos applications
- * will search for a service ticket with an empty server realm. If a
- * fallback mechanism is not being used, then it will search for a
- * service ticket with a server realm. By storing the credentials
- * twice (with and without a server realm), we ensure that the
- * credential will be found in both cases.
- */
- if (opts->service_name) {
-
- free(my_creds.server->realm.data);
- my_creds.server->realm.data =
- malloc(strlen(KRB5_REFERRAL_REALM) + 1);
- if (!my_creds.server->realm.data) {
- code = ENOMEM;
- goto cleanup;
- }
-
- strlcpy(my_creds.server->realm.data, KRB5_REFERRAL_REALM,
- strlen(KRB5_REFERRAL_REALM) + 1);
- my_creds.server->realm.length = strlen(KRB5_REFERRAL_REALM);
-
- code = krb5_cc_store_cred(k5->ctx, k5->cc, &my_creds);
- if (code) {
- com_err(progname, code,
- gettext("while storing credentials"));
- goto cleanup;
- }
- }
-
if (opts->action == RENEW) {
- _kwarnd_del_warning(opts->principal_name);
- _kwarnd_add_warning(opts->principal_name, my_creds.times.endtime);
+ _kwarnd_del_warning(progname, opts->principal_name);
+ _kwarnd_add_warning(progname, opts->principal_name, my_creds.times.endtime);
} else if ((opts->action == INIT_KT) || (opts->action == INIT_PW)) {
- _kwarnd_add_warning(opts->principal_name, my_creds.times.endtime);
+ _kwarnd_add_warning(progname, opts->principal_name, my_creds.times.endtime);
}
notix = 0;
cleanup:
+ if (options)
+ krb5_get_init_creds_opt_free(k5->ctx, options);
if (my_creds.client == k5->me) {
my_creds.client = 0;
}
+ if (opts->pa_opts) {
+ free(opts->pa_opts);
+ opts->pa_opts = NULL;
+ opts->num_pa_opts = 0;
+ }
krb5_free_cred_contents(k5->ctx, &my_creds);
if (keytab)
krb5_kt_close(k5->ctx, keytab);
@@ -1255,6 +1303,7 @@ main(argc, argv)
struct k_opts opts;
struct k5_data k5;
struct k4_data k4;
+ char *progname;
(void) setlocale(LC_ALL, "");
@@ -1294,6 +1343,8 @@ main(argc, argv)
memset(&k5, 0, sizeof(k5));
memset(&k4, 0, sizeof(k4));
+ set_com_err_hook (extended_com_err_fn);
+
parse_options(argc, argv, &opts, progname);
got_k5 = k5_begin(&opts, &k5, &k4);
@@ -1325,7 +1376,7 @@ main(argc, argv)
}
static void
-_kwarnd_add_warning(char *me, time_t endtime)
+_kwarnd_add_warning(char *progname, char *me, time_t endtime)
{
if (kwarn_add_warning(me, endtime) != 0)
fprintf(stderr, gettext(
@@ -1335,7 +1386,7 @@ _kwarnd_add_warning(char *me, time_t endtime)
static void
-_kwarnd_del_warning(char *me)
+_kwarnd_del_warning(char *progname, char *me)
{
if (kwarn_del_warning(me) != 0)
fprintf(stderr, gettext(
diff --git a/usr/src/cmd/krb5/klist/Makefile b/usr/src/cmd/krb5/klist/Makefile
index 70ddaa5208..f28e8a4367 100644
--- a/usr/src/cmd/krb5/klist/Makefile
+++ b/usr/src/cmd/krb5/klist/Makefile
@@ -1,8 +1,7 @@
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
#
PROG= klist
@@ -26,7 +25,7 @@ CPPFLAGS += -I$(SRC)/lib/gss_mechs/mech_krb5/include \
$(DEFS)
LDFLAGS += $(KRUNPATH)
-LDLIBS += $(KMECHLIB) -lsocket
+LDLIBS += $(KMECHLIB)
$(GPROGS) := CPPFLAGS += -DSYSV -DSunOS=50
diff --git a/usr/src/cmd/krb5/krb5-config/krb5-config.sh b/usr/src/cmd/krb5/krb5-config/krb5-config.sh
index 41075bd9e0..9ad5b9fb06 100644
--- a/usr/src/cmd/krb5/krb5-config/krb5-config.sh
+++ b/usr/src/cmd/krb5/krb5-config/krb5-config.sh
@@ -1,10 +1,9 @@
#!/bin/sh
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# pragma ident "%Z%%M% %I% %E% SMI"
#
# Copyright 2001, 2002, 2003 by the Massachusetts Institute of Technology.
# All Rights Reserved.
@@ -31,7 +30,7 @@
#
# Configurable parameters set by autoconf
-version_string="Solaris Kerberos (based on MIT Kerberos 5 release 1.4.0)"
+version_string="Solaris Kerberos (based on MIT Kerberos 5 release 1.6.3)"
prefix=/usr
exec_prefix=${prefix}
diff --git a/usr/src/cmd/krb5/krb5kdc/dispatch.c b/usr/src/cmd/krb5/krb5kdc/dispatch.c
index c1ccabe1f2..7e3e2c7e36 100644
--- a/usr/src/cmd/krb5/krb5kdc/dispatch.c
+++ b/usr/src/cmd/krb5/krb5kdc/dispatch.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,9 +31,7 @@
* Dispatch an incoming packet.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-#define NEED_SOCKETS
#include "k5-int.h"
#include <syslog.h>
#include "kdc_util.h"
@@ -43,7 +41,6 @@
#include <arpa/inet.h>
#include <string.h>
-extern krb5_error_code setup_server_realm(krb5_principal);
static krb5_int32 last_usec = 0, last_os_random = 0;
krb5_error_code
@@ -58,7 +55,7 @@ dispatch(krb5_data *pkt, const krb5_fulladdr *from, krb5_data **response)
#ifndef NOCACHE
/* try the replay lookaside buffer */
- if (kdc_check_lookaside(pkt, from, response)) {
+ if (kdc_check_lookaside(pkt, response)) {
/* a hit! */
const char *name = 0;
char buf[46];
@@ -106,7 +103,7 @@ dispatch(krb5_data *pkt, const krb5_fulladdr *from, krb5_data **response)
* pointer.
*/
if (!(retval = setup_server_realm(as_req->server))) {
- retval = process_as_req(as_req, from, response);
+ retval = process_as_req(as_req, pkt, from, response);
}
krb5_free_kdc_req(kdc_context, as_req);
}
@@ -120,7 +117,7 @@ dispatch(krb5_data *pkt, const krb5_fulladdr *from, krb5_data **response)
#ifndef NOCACHE
/* put the response into the lookaside buffer */
if (!retval)
- kdc_insert_lookaside(pkt, from, *response);
+ kdc_insert_lookaside(pkt, *response);
#endif
return retval;
diff --git a/usr/src/cmd/krb5/krb5kdc/do_as_req.c b/usr/src/cmd/krb5/krb5kdc/do_as_req.c
index 4751eb18e5..4c415006ad 100644
--- a/usr/src/cmd/krb5/krb5kdc/do_as_req.c
+++ b/usr/src/cmd/krb5/krb5kdc/do_as_req.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* kdc/do_as_req.c
@@ -58,8 +57,8 @@ static krb5_error_code prepare_error_as (krb5_kdc_req *, int, krb5_data *,
/*ARGSUSED*/
krb5_error_code
-process_as_req(krb5_kdc_req *request, const krb5_fulladdr *from,
- krb5_data **response)
+process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
+ const krb5_fulladdr *from, krb5_data **response)
{
krb5_db_entry client, server;
krb5_kdc_rep reply;
@@ -87,6 +86,7 @@ process_as_req(krb5_kdc_req *request, const krb5_fulladdr *from,
char ktypestr[128];
char rep_etypestr[128];
char fromstringbuf[70];
+ void *pa_context = NULL;
struct in_addr from_in4; /* IPv4 address of sender */
ticket_reply.enc_part.ciphertext.data = 0;
@@ -94,6 +94,7 @@ process_as_req(krb5_kdc_req *request, const krb5_fulladdr *from,
(void) memset(&encrypting_key, 0, sizeof(krb5_keyblock));
reply.padata = 0; /* avoid bogus free in error_out */
(void) memset(&session_key, 0, sizeof(krb5_keyblock));
+ enc_tkt_reply.authorization_data = NULL;
ktypes2str(ktypestr, sizeof(ktypestr),
request->nktypes, request->ktype);
@@ -289,7 +290,8 @@ process_as_req(krb5_kdc_req *request, const krb5_fulladdr *from,
* Check the preauthentication if it is there.
*/
if (request->padata) {
- errcode = check_padata(kdc_context, &client, request, &enc_tkt_reply);
+ errcode = check_padata(kdc_context, &client, req_pkt, request,
+ &enc_tkt_reply, &pa_context, &e_data);
if (errcode) {
#ifdef KRBCONF_KDC_MODIFIES_KDB
/*
@@ -419,8 +421,8 @@ process_as_req(krb5_kdc_req *request, const krb5_fulladdr *from,
reply_encpart.caddrs = enc_tkt_reply.caddrs;
/* Fetch the padata info to be returned */
- errcode = return_padata(kdc_context, &client, request, &reply, client_key,
- &encrypting_key);
+ errcode = return_padata(kdc_context, &client, req_pkt, request,
+ &reply, client_key, &encrypting_key, &pa_context);
if (errcode) {
status = "KDC_RETURN_PADATA";
goto errout;
@@ -471,7 +473,14 @@ process_as_req(krb5_kdc_req *request, const krb5_fulladdr *from,
#endif /* KRBCONF_KDC_MODIFIES_KDB */
errout:
+ if (pa_context)
+ free_padata_context(kdc_context, &pa_context);
+
if (status) {
+ const char * emsg = 0;
+ if (errcode)
+ emsg = krb5_get_error_message (kdc_context, errcode);
+
audit_krb5kdc_as_req(&from_in4, (in_port_t)from->port,
0, cname, sname, errcode);
krb5_klog_syslog(LOG_INFO, "AS_REQ (%s) %s: %s: %s for %s%s%s",
@@ -480,19 +489,30 @@ errout:
cname ? cname : "<unknown client>",
sname ? sname : "<unknown server>",
errcode ? ", " : "",
- errcode ? error_message(errcode) : "");
+ errcode ? emsg : "");
+ if (errcode)
+ krb5_free_error_message (kdc_context, emsg);
}
if (errcode) {
- if (status == 0)
- status = error_message (errcode);
+ int got_err = 0;
+ if (status == 0) {
+ status = krb5_get_error_message (kdc_context, errcode);
+ got_err = 1;
+ }
errcode -= ERROR_TABLE_BASE_krb5;
if (errcode < 0 || errcode > 128)
errcode = KRB_ERR_GENERIC;
errcode = prepare_error_as(request, errcode, &e_data, response,
status);
+ if (got_err) {
+ krb5_free_error_message (kdc_context, status);
+ status = 0;
+ }
}
+ if (enc_tkt_reply.authorization_data != NULL)
+ krb5_free_authdata(kdc_context, enc_tkt_reply.authorization_data);
if (encrypting_key.contents)
krb5_free_keyblock_contents(kdc_context, &encrypting_key);
if (reply.padata)
@@ -572,7 +592,7 @@ prepare_error_as (krb5_kdc_req *request, int error, krb5_data *e_data,
free(errpkt.text.data);
if (retval)
free(scratch);
- else
+ else
*response = scratch;
return retval;
diff --git a/usr/src/cmd/krb5/krb5kdc/do_tgs_req.c b/usr/src/cmd/krb5/krb5kdc/do_tgs_req.c
index d0c5ebba00..6a519ac595 100644
--- a/usr/src/cmd/krb5/krb5kdc/do_tgs_req.c
+++ b/usr/src/cmd/krb5/krb5kdc/do_tgs_req.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* kdc/do_tgs_req.c
@@ -34,7 +33,6 @@
* KDC Routines to deal with TGS_REQ's
*/
-#define NEED_SOCKETS
#include "k5-int.h"
#include "com_err.h"
@@ -504,6 +502,8 @@ tgt_again:
goto cleanup;
}
enc_tkt_transited.tr_type = KRB5_DOMAIN_X500_COMPRESS;
+ enc_tkt_transited.magic = 0;
+ enc_tkt_transited.tr_contents.magic = 0;
enc_tkt_transited.tr_contents.data = 0;
enc_tkt_transited.tr_contents.length = 0;
enc_tkt_reply.transited = enc_tkt_transited;
@@ -541,7 +541,8 @@ tgt_again:
tlen,
enc_tkt_reply.transited.tr_contents.data,
tdots);
- else
+ else {
+ const char *emsg = krb5_get_error_message(kdc_context, errcode);
krb5_klog_syslog (LOG_ERR,
"unexpected error checking transit from "
"'%s' to '%s' via '%.*s%s': %s",
@@ -549,7 +550,9 @@ tgt_again:
sname ? sname : "<unknown server>",
tlen,
enc_tkt_reply.transited.tr_contents.data,
- tdots, error_message (errcode));
+ tdots, emsg);
+ krb5_free_error_message(kdc_context, emsg);
+ }
} else
krb5_klog_syslog (LOG_INFO, "not checking transit path");
if (reject_bad_transit
@@ -578,7 +581,7 @@ tgt_again:
if ((errcode = krb5_unparse_name(kdc_context, client2, &tmp)))
tmp = 0;
if (tmp != NULL)
- limit_string(tmp);
+ limit_string(tmp);
audit_krb5kdc_tgs_req_2ndtktmm(
(struct in_addr *)from->address->contents,
(in_port_t)from->port,
@@ -695,6 +698,7 @@ tgt_again:
cleanup:
if (status) {
+ const char * emsg = NULL;
audit_krb5kdc_tgs_req((struct in_addr *)from->address->contents,
(in_port_t)from->port, 0,
cname ? cname : "<unknown client>",
@@ -702,7 +706,9 @@ cleanup:
errcode);
if (!errcode)
rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), &reply);
- krb5_klog_syslog(LOG_INFO,
+ if (errcode)
+ emsg = krb5_get_error_message (kdc_context, errcode);
+ krb5_klog_syslog(LOG_INFO,
"TGS_REQ (%s) %s: %s: authtime %d, "
"%s%s %s for %s%s%s",
ktypestr,
@@ -712,18 +718,27 @@ cleanup:
cname ? cname : "<unknown client>",
sname ? sname : "<unknown server>",
errcode ? ", " : "",
- errcode ? error_message(errcode) : "");
+ errcode ? emsg : "");
+ if (errcode)
+ krb5_free_error_message (kdc_context, emsg);
}
if (errcode) {
- if (status == 0)
- status = error_message (errcode);
+ int got_err = 0;
+ if (status == 0) {
+ status = krb5_get_error_message (kdc_context, errcode);
+ got_err = 1;
+ }
errcode -= ERROR_TABLE_BASE_krb5;
if (errcode < 0 || errcode > 128)
errcode = KRB_ERR_GENERIC;
retval = prepare_error_tgs(request, header_ticket, errcode,
fromstring, response, status);
+ if (got_err) {
+ krb5_free_error_message (kdc_context, status);
+ status = 0;
+ }
}
if (header_ticket)
diff --git a/usr/src/cmd/krb5/krb5kdc/kdc_preauth.c b/usr/src/cmd/krb5/krb5kdc/kdc_preauth.c
index bb16e1d53a..d29b216fa0 100644
--- a/usr/src/cmd/krb5/krb5kdc/kdc_preauth.c
+++ b/usr/src/cmd/krb5/krb5kdc/kdc_preauth.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* kdc/kdc_preauth.c
@@ -70,6 +69,13 @@
#include <syslog.h>
#include <assert.h>
+#include "preauth_plugin.h"
+
+#if TARGET_OS_MAC
+static const char *objdirs[] = { KRB5_PLUGIN_BUNDLE_DIR, LIBDIR "/krb5/plugins/preauth", NULL }; /* should be a list */
+#else
+static const char *objdirs[] = { LIBDIR "/krb5/plugins/preauth", NULL };
+#endif
/* XXX This is ugly and should be in a header file somewhere */
#ifndef KRB5INT_DES_TYPES_DEFINED
@@ -80,93 +86,125 @@ typedef des_cblock mit_des_cblock;
extern void mit_des_fixup_key_parity (mit_des_cblock );
extern int mit_des_is_weak_key (mit_des_cblock );
-typedef krb5_error_code (*verify_proc)
- (krb5_context, krb5_db_entry *client,
- krb5_kdc_req *request,
- krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data);
-
-typedef krb5_error_code (*edata_proc)
- (krb5_context, krb5_kdc_req *request,
- krb5_db_entry *client, krb5_db_entry *server,
- krb5_pa_data *data);
-
-typedef krb5_error_code (*return_proc)
- (krb5_context, krb5_pa_data * padata,
- krb5_db_entry *client,
- krb5_kdc_req *request, krb5_kdc_rep *reply,
- krb5_key_data *client_key,
- krb5_keyblock *encrypting_key,
- krb5_pa_data **send_pa);
-
typedef struct _krb5_preauth_systems {
- char * name;
+ const char *name;
int type;
int flags;
- edata_proc get_edata;
- verify_proc verify_padata;
- return_proc return_padata;
+ void *plugin_context;
+ preauth_server_init_proc init;
+ preauth_server_fini_proc fini;
+ preauth_server_edata_proc get_edata;
+ preauth_server_verify_proc verify_padata;
+ preauth_server_return_proc return_padata;
+ preauth_server_free_reqcontext_proc free_pa_reqctx;
} krb5_preauth_systems;
static krb5_error_code verify_enc_timestamp
(krb5_context, krb5_db_entry *client,
+ krb5_data *req_pkt,
krb5_kdc_req *request,
- krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data);
+ krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
+ preauth_get_entry_data_proc get_entry_data,
+ void *pa_system_context,
+ void **pa_request_context,
+ krb5_data **e_data,
+ krb5_authdata ***authz_data);
static krb5_error_code get_etype_info
(krb5_context, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
+ preauth_get_entry_data_proc get_entry_data,
+ void *pa_system_context,
krb5_pa_data *data);
static krb5_error_code
get_etype_info2(krb5_context context, krb5_kdc_req *request,
- krb5_db_entry *client, krb5_db_entry *server,
- krb5_pa_data *pa_data);
+ krb5_db_entry *client, krb5_db_entry *server,
+ preauth_get_entry_data_proc get_entry_data,
+ void *pa_system_context,
+ krb5_pa_data *pa_data);
+static krb5_error_code
+etype_info_as_rep_helper(krb5_context context, krb5_pa_data * padata,
+ krb5_db_entry *client,
+ krb5_kdc_req *request, krb5_kdc_rep *reply,
+ krb5_key_data *client_key,
+ krb5_keyblock *encrypting_key,
+ krb5_pa_data **send_pa,
+ int etype_info2);
+
+static krb5_error_code
+return_etype_info(krb5_context, krb5_pa_data * padata,
+ krb5_db_entry *client,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request, krb5_kdc_rep *reply,
+ krb5_key_data *client_key,
+ krb5_keyblock *encrypting_key,
+ krb5_pa_data **send_pa,
+ preauth_get_entry_data_proc get_entry_data,
+ void *pa_system_context,
+ void **pa_request_context);
+
static krb5_error_code
return_etype_info2(krb5_context, krb5_pa_data * padata,
krb5_db_entry *client,
+ krb5_data *req_pkt,
krb5_kdc_req *request, krb5_kdc_rep *reply,
krb5_key_data *client_key,
krb5_keyblock *encrypting_key,
- krb5_pa_data **send_pa);
+ krb5_pa_data **send_pa,
+ preauth_get_entry_data_proc get_entry_data,
+ void *pa_system_context,
+ void **pa_request_context);
static krb5_error_code return_pw_salt
(krb5_context, krb5_pa_data * padata,
krb5_db_entry *client,
+ krb5_data *req_pkt,
krb5_kdc_req *request, krb5_kdc_rep *reply,
krb5_key_data *client_key,
krb5_keyblock *encrypting_key,
- krb5_pa_data **send_pa);
+ krb5_pa_data **send_pa,
+ preauth_get_entry_data_proc get_entry_data,
+ void *pa_system_context,
+ void **pa_request_context);
/* SAM preauth support */
static krb5_error_code verify_sam_response
(krb5_context, krb5_db_entry *client,
+ krb5_data *req_pkt,
krb5_kdc_req *request,
- krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data);
+ krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
+ preauth_get_entry_data_proc get_entry_data,
+ void *pa_module_context,
+ void **pa_request_context,
+ krb5_data **e_data,
+ krb5_authdata ***authz_data);
static krb5_error_code get_sam_edata
(krb5_context, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
+ preauth_get_entry_data_proc get_entry_data,
+ void *pa_module_context,
krb5_pa_data *data);
static krb5_error_code return_sam_data
(krb5_context, krb5_pa_data * padata,
krb5_db_entry *client,
+ krb5_data *req_pkt,
krb5_kdc_req *request, krb5_kdc_rep *reply,
krb5_key_data *client_key,
krb5_keyblock *encrypting_key,
- krb5_pa_data **send_pa);
-/*
- * Preauth property flags
- */
-#define PA_HARDWARE 0x00000001
-#define PA_REQUIRED 0x00000002
-#define PA_SUFFICIENT 0x00000004
- /* Not really a padata, so don't include it in the etype list*/
-#define PA_PSEUDO 0x00000008
+ krb5_pa_data **send_pa,
+ preauth_get_entry_data_proc get_entry_data,
+ void *pa_module_context,
+ void **pa_request_context);
-static krb5_preauth_systems preauth_systems[] = {
+static krb5_preauth_systems static_preauth_systems[] = {
{
"timestamp",
KRB5_PADATA_ENC_TIMESTAMP,
0,
+ NULL,
+ NULL,
+ NULL,
0,
verify_enc_timestamp,
0
@@ -175,14 +213,20 @@ static krb5_preauth_systems preauth_systems[] = {
"etype-info",
KRB5_PADATA_ETYPE_INFO,
0,
+ NULL,
+ NULL,
+ NULL,
get_etype_info,
0,
- 0
+ return_etype_info
},
{
"etype-info2",
KRB5_PADATA_ETYPE_INFO2,
0,
+ NULL,
+ NULL,
+ NULL,
get_etype_info2,
0,
return_etype_info2
@@ -191,6 +235,9 @@ static krb5_preauth_systems preauth_systems[] = {
"pw-salt",
KRB5_PADATA_PW_SALT,
PA_PSEUDO, /* Don't include this in the error list */
+ NULL,
+ NULL,
+ NULL,
0,
0,
return_pw_salt
@@ -199,6 +246,9 @@ static krb5_preauth_systems preauth_systems[] = {
"sam-response",
KRB5_PADATA_SAM_RESPONSE,
0,
+ NULL,
+ NULL,
+ NULL,
0,
verify_sam_response,
return_sam_data
@@ -207,6 +257,9 @@ static krb5_preauth_systems preauth_systems[] = {
"sam-challenge",
KRB5_PADATA_SAM_CHALLENGE,
PA_HARDWARE, /* causes get_preauth_hint_list to use this */
+ NULL,
+ NULL,
+ NULL,
get_sam_edata,
0,
0
@@ -214,13 +267,391 @@ static krb5_preauth_systems preauth_systems[] = {
{ "[end]", -1,}
};
-#define MAX_PREAUTH_SYSTEMS (sizeof(preauth_systems)/sizeof(preauth_systems[0]))
+static krb5_preauth_systems *preauth_systems;
+static int n_preauth_systems;
+static struct plugin_dir_handle preauth_plugins;
+
+krb5_error_code
+load_preauth_plugins(krb5_context context)
+{
+ struct errinfo err;
+ void **preauth_plugins_ftables;
+ struct krb5plugin_preauth_server_ftable_v1 *ftable;
+ int module_count, i, j, k;
+ void *plugin_context;
+ preauth_server_init_proc server_init_proc = NULL;
+ char **kdc_realm_names = NULL;
+
+ memset(&err, 0, sizeof(err));
+
+ /* Attempt to load all of the preauth plugins we can find. */
+ PLUGIN_DIR_INIT(&preauth_plugins);
+ if (PLUGIN_DIR_OPEN(&preauth_plugins) == 0) {
+ if (krb5int_open_plugin_dirs(objdirs, NULL,
+ &preauth_plugins, &err) != 0) {
+ return KRB5_PLUGIN_NO_HANDLE;
+ }
+ }
+
+ /* Get the method tables provided by the loaded plugins. */
+ preauth_plugins_ftables = NULL;
+ if (krb5int_get_plugin_dir_data(&preauth_plugins,
+ "preauthentication_server_1",
+ &preauth_plugins_ftables, &err) != 0) {
+ return KRB5_PLUGIN_NO_HANDLE;
+ }
+
+ /* Count the valid modules. */
+ module_count = sizeof(static_preauth_systems)
+ / sizeof(static_preauth_systems[0]);
+ if (preauth_plugins_ftables != NULL) {
+ for (i = 0; preauth_plugins_ftables[i] != NULL; i++) {
+ ftable = preauth_plugins_ftables[i];
+ if ((ftable->flags_proc == NULL) &&
+ (ftable->edata_proc == NULL) &&
+ (ftable->verify_proc == NULL) &&
+ (ftable->return_proc == NULL)) {
+ continue;
+ }
+ for (j = 0;
+ ftable->pa_type_list != NULL &&
+ ftable->pa_type_list[j] > 0;
+ j++) {
+ module_count++;
+ }
+ }
+ }
+
+ /* Build the complete list of supported preauthentication options, and
+ * leave room for a terminator entry. */
+ preauth_systems = malloc(sizeof(krb5_preauth_systems) * (module_count + 1));
+ if (preauth_systems == NULL) {
+ krb5int_free_plugin_dir_data(preauth_plugins_ftables);
+ return ENOMEM;
+ }
+
+ /* Build a list of the names of the supported realms for this KDC.
+ * The list of names is terminated with a NULL. */
+ kdc_realm_names = malloc(sizeof(char *) * (kdc_numrealms + 1));
+ if (kdc_realm_names == NULL) {
+ krb5int_free_plugin_dir_data(preauth_plugins_ftables);
+ return ENOMEM;
+ }
+ for (i = 0; i < kdc_numrealms; i++) {
+ kdc_realm_names[i] = kdc_realmlist[i]->realm_name;
+ }
+ kdc_realm_names[i] = NULL;
+
+ /* Add the locally-supplied mechanisms to the dynamic list first. */
+ for (i = 0, k = 0;
+ i < sizeof(static_preauth_systems) / sizeof(static_preauth_systems[0]);
+ i++) {
+ if (static_preauth_systems[i].type == -1)
+ break;
+ preauth_systems[k] = static_preauth_systems[i];
+ /* Try to initialize the preauth system. If it fails, we'll remove it
+ * from the list of systems we'll be using. */
+ plugin_context = NULL;
+ server_init_proc = static_preauth_systems[i].init;
+ if ((server_init_proc != NULL) &&
+ ((*server_init_proc)(context, &plugin_context, (const char **)kdc_realm_names) != 0)) {
+ memset(&preauth_systems[k], 0, sizeof(preauth_systems[k]));
+ continue;
+ }
+ preauth_systems[k].plugin_context = plugin_context;
+ k++;
+ }
+
+ /* Now add the dynamically-loaded mechanisms to the list. */
+ if (preauth_plugins_ftables != NULL) {
+ for (i = 0; preauth_plugins_ftables[i] != NULL; i++) {
+ ftable = preauth_plugins_ftables[i];
+ if ((ftable->flags_proc == NULL) &&
+ (ftable->edata_proc == NULL) &&
+ (ftable->verify_proc == NULL) &&
+ (ftable->return_proc == NULL)) {
+ continue;
+ }
+ plugin_context = NULL;
+ for (j = 0;
+ ftable->pa_type_list != NULL &&
+ ftable->pa_type_list[j] > 0;
+ j++) {
+ /* Try to initialize the plugin. If it fails, we'll remove it
+ * from the list of modules we'll be using. */
+ if (j == 0) {
+ server_init_proc = ftable->init_proc;
+ if (server_init_proc != NULL) {
+ krb5_error_code initerr;
+ initerr = (*server_init_proc)(context, &plugin_context, (const char **)kdc_realm_names);
+ if (initerr) {
+ const char *emsg;
+ emsg = krb5_get_error_message(context, initerr);
+ if (emsg) {
+ krb5_klog_syslog(LOG_ERR,
+ "preauth %s failed to initialize: %s",
+ ftable->name, emsg);
+ krb5_free_error_message(context, emsg);
+ }
+ memset(&preauth_systems[k], 0, sizeof(preauth_systems[k]));
+
+ break; /* skip all modules in this plugin */
+ }
+ }
+ }
+ preauth_systems[k].name = ftable->name;
+ preauth_systems[k].type = ftable->pa_type_list[j];
+ if (ftable->flags_proc != NULL)
+ preauth_systems[k].flags = ftable->flags_proc(context, preauth_systems[k].type);
+ else
+ preauth_systems[k].flags = 0;
+ preauth_systems[k].plugin_context = plugin_context;
+ preauth_systems[k].init = server_init_proc;
+ /* Only call fini once for each plugin */
+ if (j == 0)
+ preauth_systems[k].fini = ftable->fini_proc;
+ else
+ preauth_systems[k].fini = NULL;
+ preauth_systems[k].get_edata = ftable->edata_proc;
+ preauth_systems[k].verify_padata = ftable->verify_proc;
+ preauth_systems[k].return_padata = ftable->return_proc;
+ preauth_systems[k].free_pa_reqctx =
+ ftable->freepa_reqcontext_proc;
+ k++;
+ }
+ }
+ krb5int_free_plugin_dir_data(preauth_plugins_ftables);
+ }
+ free(kdc_realm_names);
+ n_preauth_systems = k;
+ /* Add the end-of-list marker. */
+ preauth_systems[k].name = "[end]";
+ preauth_systems[k].type = -1;
+ return 0;
+}
+
+krb5_error_code
+unload_preauth_plugins(krb5_context context)
+{
+ int i;
+ if (preauth_systems != NULL) {
+ for (i = 0; i < n_preauth_systems; i++) {
+ if (preauth_systems[i].fini != NULL) {
+ (*preauth_systems[i].fini)(context,
+ preauth_systems[i].plugin_context);
+ }
+ memset(&preauth_systems[i], 0, sizeof(preauth_systems[i]));
+ }
+ free(preauth_systems);
+ preauth_systems = NULL;
+ n_preauth_systems = 0;
+ krb5int_close_plugin_dirs(&preauth_plugins);
+ }
+ return 0;
+}
+
+/*
+ * The make_padata_context() function creates a space for storing any context
+ * information which will be needed by return_padata() later. Each preauth
+ * type gets a context storage location of its own.
+ */
+struct request_pa_context {
+ int n_contexts;
+ struct {
+ krb5_preauth_systems *pa_system;
+ void *pa_context;
+ } *contexts;
+};
+
+static krb5_error_code
+make_padata_context(krb5_context context, void **padata_context)
+{
+ int i;
+ struct request_pa_context *ret;
+
+ ret = malloc(sizeof(*ret));
+ if (ret == NULL) {
+ return ENOMEM;
+ }
+
+ ret->n_contexts = n_preauth_systems;
+ ret->contexts = malloc(sizeof(ret->contexts[0]) * ret->n_contexts);
+ if (ret->contexts == NULL) {
+ free(ret);
+ return ENOMEM;
+ }
+
+ memset(ret->contexts, 0, sizeof(ret->contexts[0]) * ret->n_contexts);
+
+ for (i = 0; i < ret->n_contexts; i++) {
+ ret->contexts[i].pa_system = &preauth_systems[i];
+ ret->contexts[i].pa_context = NULL;
+ }
+
+ *padata_context = ret;
+
+ return 0;
+}
+
+/*
+ * The free_padata_context function frees any context information pointers
+ * which the check_padata() function created but which weren't already cleaned
+ * up by return_padata().
+ */
+krb5_error_code
+free_padata_context(krb5_context kcontext, void **padata_context)
+{
+ struct request_pa_context *context;
+ krb5_preauth_systems *preauth_system;
+ void **pctx, *mctx;
+ int i;
+
+ if (padata_context == NULL)
+ return 0;
+
+ context = *padata_context;
+
+ for (i = 0; i < context->n_contexts; i++) {
+ if (context->contexts[i].pa_context != NULL) {
+ preauth_system = context->contexts[i].pa_system;
+ mctx = preauth_system->plugin_context;
+ if (preauth_system->free_pa_reqctx != NULL) {
+ pctx = &context->contexts[i].pa_context;
+ (*preauth_system->free_pa_reqctx)(kcontext, mctx, pctx);
+ }
+ context->contexts[i].pa_context = NULL;
+ }
+ }
+
+ free(context->contexts);
+ free(context);
+
+ return 0;
+}
+
+/* Retrieve a specified tl_data item from the given entry, and return its
+ * contents in a new krb5_data, which must be freed by the caller. */
+static krb5_error_code
+get_entry_tl_data(krb5_context context, krb5_db_entry *entry,
+ krb5_int16 tl_data_type, krb5_data **result)
+{
+ krb5_tl_data *tl;
+ for (tl = entry->tl_data; tl != NULL; tl = tl->tl_data_next) {
+ if (tl->tl_data_type == tl_data_type) {
+ *result = malloc(sizeof(krb5_data));
+ if (*result == NULL) {
+ return ENOMEM;
+ }
+ (*result)->magic = KV5M_DATA;
+ (*result)->data = malloc(tl->tl_data_length);
+ if ((*result)->data == NULL) {
+ free(*result);
+ *result = NULL;
+ return ENOMEM;
+ }
+ memcpy((*result)->data, tl->tl_data_contents, tl->tl_data_length);
+ return 0;
+ }
+ }
+ return ENOENT;
+}
+
+/*
+ * Retrieve a specific piece of information pertaining to the entry or the
+ * request and return it in a new krb5_data item which the caller must free.
+ *
+ * This may require massaging data into a contrived format, but it will
+ * hopefully keep us from having to reveal library-internal functions to
+ * modules.
+ */
+static krb5_error_code
+get_entry_data(krb5_context context,
+ krb5_kdc_req *request, krb5_db_entry *entry,
+ krb5_int32 type,
+ krb5_data **result)
+{
+ int i, k;
+ krb5_data *ret;
+ krb5_deltat *delta;
+ krb5_keyblock *keys;
+ krb5_key_data *entry_key;
+
+ switch (type) {
+ case krb5plugin_preauth_entry_request_certificate:
+ return get_entry_tl_data(context, entry,
+ KRB5_TL_USER_CERTIFICATE, result);
+ break;
+ case krb5plugin_preauth_entry_max_time_skew:
+ ret = malloc(sizeof(krb5_data));
+ if (ret == NULL)
+ return ENOMEM;
+ delta = malloc(sizeof(krb5_deltat));
+ if (delta == NULL) {
+ free(ret);
+ return ENOMEM;
+ }
+ *delta = context->clockskew;
+ ret->data = (char *) delta;
+ ret->length = sizeof(*delta);
+ *result = ret;
+ return 0;
+ break;
+ case krb5plugin_preauth_keys:
+ ret = malloc(sizeof(krb5_data));
+ if (ret == NULL)
+ return ENOMEM;
+ keys = malloc(sizeof(krb5_keyblock) * (request->nktypes + 1));
+ if (keys == NULL) {
+ free(ret);
+ return ENOMEM;
+ }
+ ret->data = (char *) keys;
+ ret->length = sizeof(krb5_keyblock) * (request->nktypes + 1);
+ memset(ret->data, 0, ret->length);
+ k = 0;
+ for (i = 0; i < request->nktypes; i++) {
+ entry_key = NULL;
+ if (krb5_dbe_find_enctype(context, entry, request->ktype[i],
+ -1, 0, &entry_key) != 0)
+ continue;
+ if (krb5_dbekd_decrypt_key_data(context, &master_keyblock,
+ entry_key, &keys[k], NULL) != 0) {
+ if (keys[k].contents != NULL)
+ krb5_free_keyblock_contents(context, &keys[k]);
+ memset(&keys[k], 0, sizeof(keys[k]));
+ continue;
+ }
+ k++;
+ }
+ if (k > 0) {
+ *result = ret;
+ return 0;
+ } else {
+ free(keys);
+ free(ret);
+ }
+ break;
+ case krb5plugin_preauth_request_body:
+ ret = NULL;
+ encode_krb5_kdc_req_body(request, &ret);
+ if (ret != NULL) {
+ *result = ret;
+ return 0;
+ }
+ return ASN1_PARSE_ERROR;
+ break;
+ default:
+ break;
+ }
+ return ENOENT;
+}
static krb5_error_code
find_pa_system(int type, krb5_preauth_systems **preauth)
{
- krb5_preauth_systems *ap = preauth_systems;
-
+ krb5_preauth_systems *ap;
+
+ ap = preauth_systems ? preauth_systems : static_preauth_systems;
while ((ap->type != -1) && (ap->type != type))
ap++;
if (ap->type == -1)
@@ -229,6 +660,113 @@ find_pa_system(int type, krb5_preauth_systems **preauth)
return 0;
}
+static krb5_error_code
+find_pa_context(krb5_preauth_systems *pa_sys,
+ struct request_pa_context *context,
+ void ***pa_context)
+{
+ int i;
+
+ *pa_context = 0;
+
+ if (context == NULL)
+ return KRB5KRB_ERR_GENERIC;
+
+ for (i = 0; i < context->n_contexts; i++) {
+ if (context->contexts[i].pa_system == pa_sys) {
+ *pa_context = &context->contexts[i].pa_context;
+ return 0;
+ }
+ }
+
+ return KRB5KRB_ERR_GENERIC;
+}
+
+/*
+ * Create a list of indices into the preauth_systems array, sorted by order of
+ * preference.
+ */
+static krb5_boolean
+pa_list_includes(krb5_pa_data **pa_data, krb5_preauthtype pa_type)
+{
+ while (*pa_data != NULL) {
+ if ((*pa_data)->pa_type == pa_type)
+ return TRUE;
+ pa_data++;
+ }
+ return FALSE;
+}
+static void
+sort_pa_order(krb5_context context, krb5_kdc_req *request, int *pa_order)
+{
+ int i, j, k, n_repliers, n_key_replacers;
+
+ /* First, set up the default order. */
+ i = 0;
+ for (j = 0; j < n_preauth_systems; j++) {
+ if (preauth_systems[j].return_padata != NULL)
+ pa_order[i++] = j;
+ }
+ n_repliers = i;
+ pa_order[n_repliers] = -1;
+
+ /* Reorder so that PA_REPLACES_KEY modules are listed first. */
+ for (i = 0; i < n_repliers; i++) {
+ /* If this module replaces the key, then it's okay to leave it where it
+ * is in the order. */
+ if (preauth_systems[pa_order[i]].flags & PA_REPLACES_KEY)
+ continue;
+ /* If not, search for a module which does, and swap in the first one we
+ * find. */
+ for (j = i + 1; j < n_repliers; j++) {
+ if (preauth_systems[pa_order[j]].flags & PA_REPLACES_KEY) {
+ k = pa_order[j];
+ pa_order[j] = pa_order[i];
+ pa_order[i] = k;
+ break;
+ }
+ }
+ }
+
+ if (request->padata != NULL) {
+ /* Now reorder the subset of modules which replace the key,
+ * bubbling those which handle pa_data types provided by the
+ * client ahead of the others. */
+ for (i = 0; preauth_systems[pa_order[i]].flags & PA_REPLACES_KEY; i++) {
+ continue;
+ }
+ n_key_replacers = i;
+ for (i = 0; i < n_key_replacers; i++) {
+ if (pa_list_includes(request->padata,
+ preauth_systems[pa_order[i]].type))
+ continue;
+ for (j = i + 1; j < n_key_replacers; j++) {
+ if (pa_list_includes(request->padata,
+ preauth_systems[pa_order[j]].type)) {
+ k = pa_order[j];
+ pa_order[j] = pa_order[i];
+ pa_order[i] = k;
+ break;
+ }
+ }
+ }
+ }
+#ifdef DEBUG
+ krb5_klog_syslog(LOG_DEBUG, "original preauth mechanism list:");
+ for (i = 0; i < n_preauth_systems; i++) {
+ if (preauth_systems[i].return_padata != NULL)
+ krb5_klog_syslog(LOG_DEBUG, "... %s(%d)", preauth_systems[i].name,
+ preauth_systems[i].type);
+ }
+ krb5_klog_syslog(LOG_DEBUG, "sorted preauth mechanism list:");
+ for (i = 0; pa_order[i] != -1; i++) {
+ krb5_klog_syslog(LOG_DEBUG, "... %s(%d)",
+ preauth_systems[pa_order[i]].name,
+ preauth_systems[pa_order[i]].type);
+ }
+#endif
+}
+
const char *missing_required_preauth(krb5_db_entry *client,
krb5_db_entry *server,
krb5_enc_tkt_part *enc_tkt_reply)
@@ -280,10 +818,10 @@ void get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client,
e_data->data = 0;
hw_only = isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH);
- pa_data = malloc(sizeof(krb5_pa_data *) * (MAX_PREAUTH_SYSTEMS+1));
+ pa_data = malloc(sizeof(krb5_pa_data *) * (n_preauth_systems+1));
if (pa_data == 0)
return;
- memset(pa_data, 0, sizeof(krb5_pa_data *) * (MAX_PREAUTH_SYSTEMS+1));
+ memset(pa_data, 0, sizeof(krb5_pa_data *) * (n_preauth_systems+1));
pa = pa_data;
for (ap = preauth_systems; ap->type != -1; ap++) {
@@ -298,7 +836,8 @@ void get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client,
(*pa)->magic = KV5M_PA_DATA;
(*pa)->pa_type = ap->type;
if (ap->get_edata) {
- retval = (ap->get_edata)(kdc_context, request, client, server, *pa);
+ retval = (ap->get_edata)(kdc_context, request, client, server,
+ get_entry_data, ap->plugin_context, *pa);
if (retval) {
/* just failed on this type, continue */
free(*pa);
@@ -326,25 +865,85 @@ errout:
}
/*
+ * Add authorization data returned from preauth modules to the ticket
+ * It is assumed that ad is a "null-terminated" array of krb5_authdata ptrs
+ */
+static krb5_error_code
+add_authorization_data(krb5_enc_tkt_part *enc_tkt_part, krb5_authdata **ad)
+{
+ krb5_authdata **newad;
+ int oldones, newones;
+ int i;
+
+ if (enc_tkt_part == NULL || ad == NULL)
+ return EINVAL;
+
+ for (newones = 0; ad[newones] != NULL; newones++);
+ if (newones == 0)
+ return 0; /* nothing to add */
+
+ if (enc_tkt_part->authorization_data == NULL)
+ oldones = 0;
+ else
+ for (oldones = 0;
+ enc_tkt_part->authorization_data[oldones] != NULL; oldones++);
+
+ newad = malloc((oldones + newones + 1) * sizeof(krb5_authdata *));
+ if (newad == NULL)
+ return ENOMEM;
+
+ /* Copy any existing pointers */
+ for (i = 0; i < oldones; i++)
+ newad[i] = enc_tkt_part->authorization_data[i];
+
+ /* Add the new ones */
+ for (i = 0; i < newones; i++)
+ newad[oldones+i] = ad[i];
+
+ /* Terminate the new list */
+ newad[oldones+i] = NULL;
+
+ /* Free any existing list */
+ if (enc_tkt_part->authorization_data != NULL)
+ free(enc_tkt_part->authorization_data);
+
+ /* Install our new list */
+ enc_tkt_part->authorization_data = newad;
+
+ return 0;
+}
+
+/*
* This routine is called to verify the preauthentication information
* for a V5 request.
- *
+ *
* Returns 0 if the pre-authentication is valid, non-zero to indicate
* an error code of some sort.
*/
krb5_error_code
-check_padata (krb5_context context, krb5_db_entry *client,
- krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply)
+check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
+ krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
+ void **padata_context, krb5_data *e_data)
{
krb5_error_code retval = 0;
krb5_pa_data **padata;
krb5_preauth_systems *pa_sys;
- int pa_ok = 0, pa_found = 0;
+ void **pa_context;
+ krb5_data *pa_e_data = NULL, *tmp_e_data = NULL;
+ int pa_ok = 0, pa_found = 0;
+ krb5_error_code saved_retval = 0;
+ int use_saved_retval = 0;
+ const char *emsg;
+ krb5_authdata **tmp_authz_data = NULL;
if (request->padata == 0)
return 0;
+ if (make_padata_context(context, padata_context) != 0) {
+ return KRB5KRB_ERR_GENERIC;
+ }
+
#ifdef DEBUG
krb5_klog_syslog (LOG_DEBUG, "checking padata");
#endif
@@ -354,48 +953,140 @@ check_padata (krb5_context context, krb5_db_entry *client,
#endif
if (find_pa_system((*padata)->pa_type, &pa_sys))
continue;
+ if (find_pa_context(pa_sys, *padata_context, &pa_context))
+ continue;
#ifdef DEBUG
krb5_klog_syslog (LOG_DEBUG, ".. pa_type %s", pa_sys->name);
#endif
if (pa_sys->verify_padata == 0)
continue;
pa_found++;
- retval = pa_sys->verify_padata(context, client, request,
- enc_tkt_reply, *padata);
+ retval = pa_sys->verify_padata(context, client, req_pkt, request,
+ enc_tkt_reply, *padata,
+ get_entry_data, pa_sys->plugin_context,
+ pa_context, &tmp_e_data, &tmp_authz_data);
if (retval) {
+ emsg = krb5_get_error_message (context, retval);
krb5_klog_syslog (LOG_INFO, "preauth (%s) verify failure: %s",
- pa_sys->name, error_message (retval));
+ pa_sys->name, emsg);
+ krb5_free_error_message (context, emsg);
+ /* Ignore authorization data returned from modules that fail */
+ if (tmp_authz_data != NULL) {
+ krb5_free_authdata(context, tmp_authz_data);
+ tmp_authz_data = NULL;
+ }
if (pa_sys->flags & PA_REQUIRED) {
+ /* free up any previous edata we might have been saving */
+ if (pa_e_data != NULL)
+ krb5_free_data(context, pa_e_data);
+ pa_e_data = tmp_e_data;
+ tmp_e_data = NULL;
+ use_saved_retval = 0; /* Make sure we use the current retval */
pa_ok = 0;
break;
}
+ /*
+ * We'll return edata from either the first PA_REQUIRED module
+ * that fails, or the first non-PA_REQUIRED module that fails.
+ * Hang on to edata from the first non-PA_REQUIRED module.
+ * If we've already got one saved, simply discard this one.
+ */
+ if (tmp_e_data != NULL) {
+ if (pa_e_data == NULL) {
+ /* save the first error code and e-data */
+ pa_e_data = tmp_e_data;
+ tmp_e_data = NULL;
+ saved_retval = retval;
+ use_saved_retval = 1;
+ } else {
+ /* discard this extra e-data from non-PA_REQUIRED module */
+ krb5_free_data(context, tmp_e_data);
+ tmp_e_data = NULL;
+ }
+ }
} else {
#ifdef DEBUG
krb5_klog_syslog (LOG_DEBUG, ".. .. ok");
#endif
+ /* Ignore any edata returned on success */
+ if (tmp_e_data != NULL) {
+ krb5_free_data(context, tmp_e_data);
+ tmp_e_data = NULL;
+ }
+ /* Add any authorization data to the ticket */
+ if (tmp_authz_data != NULL) {
+ add_authorization_data(enc_tkt_reply, tmp_authz_data);
+ free(tmp_authz_data);
+ tmp_authz_data = NULL;
+ }
pa_ok = 1;
- if (pa_sys->flags & PA_SUFFICIENT)
+ if (pa_sys->flags & PA_SUFFICIENT)
break;
}
}
+
+ /* Don't bother copying and returning e-data on success */
+ if (pa_ok && pa_e_data != NULL) {
+ krb5_free_data(context, pa_e_data);
+ pa_e_data = NULL;
+ }
+ /* Return any e-data from the preauth that caused us to exit the loop */
+ if (pa_e_data != NULL) {
+ e_data->data = malloc(pa_e_data->length);
+ if (e_data->data == NULL) {
+ krb5_free_data(context, pa_e_data);
+ /* Solaris Kerberos */
+ return ENOMEM;
+ }
+ memcpy(e_data->data, pa_e_data->data, pa_e_data->length);
+ e_data->length = pa_e_data->length;
+ krb5_free_data(context, pa_e_data);
+ pa_e_data = NULL;
+ if (use_saved_retval != 0)
+ retval = saved_retval;
+ }
+
if (pa_ok)
return 0;
/* pa system was not found, but principal doesn't require preauth */
if (!pa_found &&
- !isflagset(client->attributes, KRB5_KDB_REQUIRES_PRE_AUTH) &&
- !isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH))
+ !isflagset(client->attributes, KRB5_KDB_REQUIRES_PRE_AUTH) &&
+ !isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH))
return 0;
- if (!pa_found)
- krb5_klog_syslog (LOG_INFO, "no valid preauth type found: %s",
- error_message (retval));
-/* The following switch statement allows us
- * to return some preauth system errors back to the client.
- */
- switch(retval) {
- case KRB5KRB_AP_ERR_BAD_INTEGRITY:
+ if (!pa_found) {
+ emsg = krb5_get_error_message(context, retval);
+ krb5_klog_syslog (LOG_INFO, "no valid preauth type found: %s", emsg);
+ krb5_free_error_message(context, emsg);
+ }
+ /* The following switch statement allows us
+ * to return some preauth system errors back to the client.
+ */
+ switch(retval) {
+ case KRB5KRB_AP_ERR_BAD_INTEGRITY:
case KRB5KRB_AP_ERR_SKEW:
+ case KRB5KDC_ERR_ETYPE_NOSUPP:
+ /* rfc 4556 */
+ case KRB5KDC_ERR_CLIENT_NOT_TRUSTED:
+ case KRB5KDC_ERR_INVALID_SIG:
+ case KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED:
+ case KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE:
+ case KRB5KDC_ERR_INVALID_CERTIFICATE:
+ case KRB5KDC_ERR_REVOKED_CERTIFICATE:
+ case KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN:
+ case KRB5KDC_ERR_CLIENT_NAME_MISMATCH:
+ case KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE:
+ case KRB5KDC_ERR_DIGEST_IN_CERT_NOT_ACCEPTED:
+ case KRB5KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED:
+ case KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED:
+ case KRB5KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED:
+ /* earlier drafts of what became rfc 4556 */
+ case KRB5KDC_ERR_CERTIFICATE_MISMATCH:
+ case KRB5KDC_ERR_KDC_NOT_TRUSTED:
+ case KRB5KDC_ERR_REVOCATION_STATUS_UNAVAILABLE:
+ /* This value is shared with KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED. */
+ /* case KRB5KDC_ERR_KEY_TOO_WEAK: */
return retval;
default:
return KRB5KDC_ERR_PREAUTH_FAILED;
@@ -407,9 +1098,10 @@ check_padata (krb5_context context, krb5_db_entry *client,
* structures which should be returned by the KDC to the client
*/
krb5_error_code
-return_padata(krb5_context context, krb5_db_entry *client,
+return_padata(krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
krb5_kdc_req *request, krb5_kdc_rep *reply,
- krb5_key_data *client_key, krb5_keyblock *encrypting_key)
+ krb5_key_data *client_key, krb5_keyblock *encrypting_key,
+ void **padata_context)
{
krb5_error_code retval;
krb5_pa_data ** padata;
@@ -417,7 +1109,15 @@ return_padata(krb5_context context, krb5_db_entry *client,
krb5_pa_data ** send_pa;
krb5_pa_data * pa = 0;
krb5_preauth_systems * ap;
+ int * pa_order;
+ int * pa_type;
int size = 0;
+ void ** pa_context;
+ krb5_boolean key_modified;
+ krb5_keyblock original_key;
+ if ((!*padata_context)&& (make_padata_context(context, padata_context) != 0)) {
+ return KRB5KRB_ERR_GENERIC;
+ }
for (ap = preauth_systems; ap->type != -1; ap++) {
if (ap->return_padata)
@@ -426,13 +1126,42 @@ return_padata(krb5_context context, krb5_db_entry *client,
if ((send_pa_list = malloc((size+1) * sizeof(krb5_pa_data *))) == NULL)
return ENOMEM;
+ if ((pa_order = malloc((size+1) * sizeof(int))) == NULL) {
+ free(send_pa_list);
+ return ENOMEM;
+ }
+ sort_pa_order(context, request, pa_order);
+
+ retval = krb5_copy_keyblock_contents(context, encrypting_key,
+ &original_key);
+ if (retval) {
+ free(send_pa_list);
+ free(pa_order);
+ return retval;
+ }
+ key_modified = FALSE;
send_pa = send_pa_list;
*send_pa = 0;
-
- for (ap = preauth_systems; ap->type != -1; ap++) {
+
+ for (pa_type = pa_order; *pa_type != -1; pa_type++) {
+ ap = &preauth_systems[*pa_type];
+ if (!key_modified)
+ if (original_key.enctype != encrypting_key->enctype)
+ key_modified = TRUE;
+ if (!key_modified)
+ if (original_key.length != encrypting_key->length)
+ key_modified = TRUE;
+ if (!key_modified)
+ if (memcmp(original_key.contents, encrypting_key->contents,
+ original_key.length) != 0)
+ key_modified = TRUE;
+ if (key_modified && (ap->flags & PA_REPLACES_KEY))
+ continue;
if (ap->return_padata == 0)
continue;
+ if (find_pa_context(ap, *padata_context, &pa_context))
+ continue;
pa = 0;
if (request->padata) {
for (padata = request->padata; *padata; padata++) {
@@ -442,9 +1171,12 @@ return_padata(krb5_context context, krb5_db_entry *client,
}
}
}
- if ((retval = ap->return_padata(context, pa, client, request, reply,
- client_key, encrypting_key, send_pa)))
+ if ((retval = ap->return_padata(context, pa, client, req_pkt, request, reply,
+ client_key, encrypting_key, send_pa,
+ get_entry_data, ap->plugin_context,
+ pa_context))) {
goto cleanup;
+ }
if (*send_pa)
send_pa++;
@@ -461,6 +1193,11 @@ return_padata(krb5_context context, krb5_db_entry *client,
cleanup:
if (send_pa_list)
krb5_free_pa_data(context, send_pa_list);
+
+ /* Solaris Kerberos */
+ krb5_free_keyblock_contents(context, &original_key);
+ free(pa_order);
+
return (retval);
}
@@ -497,8 +1234,14 @@ request_contains_enctype (krb5_context context, const krb5_kdc_req *request,
static krb5_error_code
verify_enc_timestamp(krb5_context context, krb5_db_entry *client,
+ krb5_data *req_pkt,
krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
- krb5_pa_data *pa)
+ krb5_pa_data *pa,
+ preauth_get_entry_data_proc ets_get_entry_data,
+ void *pa_system_context,
+ void **pa_request_context,
+ krb5_data **e_data,
+ krb5_authdata ***authz_data)
{
krb5_pa_enc_ts * pa_enc = 0;
krb5_error_code retval;
@@ -509,7 +1252,7 @@ verify_enc_timestamp(krb5_context context, krb5_db_entry *client,
krb5_key_data * client_key;
krb5_int32 start;
krb5_timestamp timenow;
- krb5_error_code decrypt_err;
+ krb5_error_code decrypt_err = 0;
(void) memset(&key, 0, sizeof(krb5_keyblock));
scratch.data = (char *) pa->contents;
@@ -726,10 +1469,6 @@ etype_info_helper(krb5_context context, krb5_kdc_req *request,
goto cleanup;
pa_data->contents = (unsigned char *)scratch->data;
pa_data->length = scratch->length;
- /*
- * note, don't free scratch->data as it is in use (don't use
- * krb5_free_data() either).
- */
free(scratch);
retval = 0;
@@ -743,6 +1482,8 @@ cleanup:
static krb5_error_code
get_etype_info(krb5_context context, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
+ preauth_get_entry_data_proc etype_get_entry_data,
+ void *pa_system_context,
krb5_pa_data *pa_data)
{
int i;
@@ -758,27 +1499,49 @@ get_etype_info(krb5_context context, krb5_kdc_req *request,
static krb5_error_code
get_etype_info2(krb5_context context, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
+ preauth_get_entry_data_proc etype_get_entry_data,
+ void *pa_system_context,
krb5_pa_data *pa_data)
{
return etype_info_helper( context, request, client, server, pa_data, 1);
}
static krb5_error_code
-return_etype_info2(krb5_context context, krb5_pa_data * padata,
- krb5_db_entry *client,
- krb5_kdc_req *request, krb5_kdc_rep *reply,
- krb5_key_data *client_key,
- krb5_keyblock *encrypting_key,
- krb5_pa_data **send_pa)
+etype_info_as_rep_helper(krb5_context context, krb5_pa_data * padata,
+ krb5_db_entry *client,
+ krb5_kdc_req *request, krb5_kdc_rep *reply,
+ krb5_key_data *client_key,
+ krb5_keyblock *encrypting_key,
+ krb5_pa_data **send_pa,
+ int etype_info2)
{
+ int i;
krb5_error_code retval;
krb5_pa_data *tmp_padata;
krb5_etype_info_entry **entry = NULL;
krb5_data *scratch = NULL;
+
+ /*
+ * Skip PA-ETYPE-INFO completely if AS-REQ lists any "newer"
+ * enctypes.
+ */
+ if (!etype_info2) {
+ for (i = 0; i < request->nktypes; i++) {
+ if (enctype_requires_etype_info_2(request->ktype[i])) {
+ *send_pa = NULL;
+ return 0;
+ }
+ }
+ }
+
tmp_padata = malloc( sizeof(krb5_pa_data));
if (tmp_padata == NULL)
return ENOMEM;
- tmp_padata->pa_type = KRB5_PADATA_ETYPE_INFO2;
+ if (etype_info2)
+ tmp_padata->pa_type = KRB5_PADATA_ETYPE_INFO2;
+ else
+ tmp_padata->pa_type = KRB5_PADATA_ETYPE_INFO;
+
entry = malloc(2 * sizeof(krb5_etype_info_entry *));
if (entry == NULL) {
retval = ENOMEM;
@@ -786,12 +1549,17 @@ return_etype_info2(krb5_context context, krb5_pa_data * padata,
}
entry[0] = NULL;
entry[1] = NULL;
- /* using encrypting_key->enctype as this is specified in rfc4120 */
- retval = _make_etype_info_entry(context, request, client_key, encrypting_key->enctype,
- entry, 1);
+ retval = _make_etype_info_entry(context, request,
+ client_key, encrypting_key->enctype,
+ entry, etype_info2);
if (retval)
goto cleanup;
- retval = encode_krb5_etype_info2((const krb5_etype_info_entry **) entry, &scratch);
+
+ if (etype_info2)
+ retval = encode_krb5_etype_info2((const krb5_etype_info_entry **) entry, &scratch);
+ else
+ retval = encode_krb5_etype_info((const krb5_etype_info_entry **) entry, &scratch);
+
if (retval)
goto cleanup;
tmp_padata->contents = (uchar_t *)scratch->data;
@@ -815,12 +1583,47 @@ return_etype_info2(krb5_context context, krb5_pa_data * padata,
return retval;
}
+static krb5_error_code
+return_etype_info2(krb5_context context, krb5_pa_data * padata,
+ krb5_db_entry *client,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request, krb5_kdc_rep *reply,
+ krb5_key_data *client_key,
+ krb5_keyblock *encrypting_key,
+ krb5_pa_data **send_pa,
+ preauth_get_entry_data_proc etype_get_entry_data,
+ void *pa_system_context,
+ void **pa_request_context)
+{
+ return etype_info_as_rep_helper(context, padata, client, request, reply,
+ client_key, encrypting_key, send_pa, 1);
+}
+
+
+static krb5_error_code
+return_etype_info(krb5_context context, krb5_pa_data * padata,
+ krb5_db_entry *client,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request, krb5_kdc_rep *reply,
+ krb5_key_data *client_key,
+ krb5_keyblock *encrypting_key,
+ krb5_pa_data **send_pa,
+ preauth_get_entry_data_proc etypeget_entry_data,
+ void *pa_system_context,
+ void **pa_request_context)
+{
+ return etype_info_as_rep_helper(context, padata, client, request, reply,
+ client_key, encrypting_key, send_pa, 0);
+}
static krb5_error_code
return_pw_salt(krb5_context context, krb5_pa_data *in_padata,
- krb5_db_entry *client, krb5_kdc_req *request,
+ krb5_db_entry *client, krb5_data *req_pkt, krb5_kdc_req *request,
krb5_kdc_rep *reply, krb5_key_data *client_key,
- krb5_keyblock *encrypting_key, krb5_pa_data **send_pa)
+ krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
+ preauth_get_entry_data_proc etype_get_entry_data,
+ void *pa_system_context,
+ void **pa_request_context)
{
krb5_error_code retval;
krb5_pa_data * padata;
@@ -905,9 +1708,12 @@ cleanup:
static krb5_error_code
return_sam_data(krb5_context context, krb5_pa_data *in_padata,
- krb5_db_entry *client, krb5_kdc_req *request,
+ krb5_db_entry *client, krb5_data *req_pkt, krb5_kdc_req *request,
krb5_kdc_rep *reply, krb5_key_data *client_key,
- krb5_keyblock *encrypting_key, krb5_pa_data **send_pa)
+ krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
+ preauth_get_entry_data_proc sam_get_entry_data,
+ void *pa_system_context,
+ void **pa_request_context)
{
krb5_error_code retval;
krb5_data scratch;
@@ -1049,7 +1855,8 @@ static struct {
static krb5_error_code
get_sam_edata(krb5_context context, krb5_kdc_req *request,
krb5_db_entry *client, krb5_db_entry *server,
- krb5_pa_data *pa_data)
+ preauth_get_entry_data_proc sam_get_entry_data,
+ void *pa_system_context, krb5_pa_data *pa_data)
{
krb5_error_code retval;
krb5_sam_challenge sc;
@@ -1434,8 +2241,14 @@ cleanup:
static krb5_error_code
verify_sam_response(krb5_context context, krb5_db_entry *client,
+ krb5_data *req_pkt,
krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
- krb5_pa_data *pa)
+ krb5_pa_data *pa,
+ preauth_get_entry_data_proc sam_get_entry_data,
+ void *pa_system_context,
+ void **pa_request_context,
+ krb5_data **e_data,
+ krb5_authdata ***authz_data)
{
krb5_error_code retval;
krb5_data scratch;
diff --git a/usr/src/cmd/krb5/krb5kdc/kdc_util.c b/usr/src/cmd/krb5/krb5kdc/kdc_util.c
index 468533a96e..a8488e2446 100644
--- a/usr/src/cmd/krb5/krb5kdc/kdc_util.c
+++ b/usr/src/cmd/krb5/krb5kdc/kdc_util.c
@@ -28,7 +28,6 @@
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include "k5-int.h"
#include "kdc_util.h"
@@ -552,6 +551,18 @@ subrealm(char *r1, char *r2)
* names.
*/
+static char *
+data2string (krb5_data *d)
+{
+ char *s;
+ s = malloc(d->length + 1);
+ if (s) {
+ memcpy(s, d->data, d->length);
+ s[d->length] = 0;
+ }
+ return s;
+}
+
krb5_error_code
add_to_transited(krb5_data *tgt_trans, krb5_data *new_trans,
krb5_principal tgs, krb5_principal client,
@@ -574,19 +585,15 @@ add_to_transited(krb5_data *tgt_trans, krb5_data *new_trans,
int pl, pl1; /* prefix length */
int added; /* TRUE = new realm has been added */
- if (!(realm = (char *) malloc(krb5_princ_realm(kdc_context, tgs)->length+1))) {
- return(ENOMEM);
- }
- memcpy(realm, krb5_princ_realm(kdc_context, tgs)->data,
- krb5_princ_realm(kdc_context, tgs)->length);
- realm[krb5_princ_realm(kdc_context, tgs)->length] = '\0';
+ realm = data2string(krb5_princ_realm(kdc_context, tgs));
+ if (realm == NULL)
+ return(ENOMEM);
- if (!(otrans = (char *) malloc(tgt_trans->length+1))) {
- free(realm);
- return(ENOMEM);
+ otrans = data2string(tgt_trans);
+ if (otrans == NULL) {
+ free(realm);
+ return(ENOMEM);
}
- memcpy(otrans, tgt_trans->data, tgt_trans->length);
- otrans[tgt_trans->length] = '\0';
/* Keep track of start so we can free */
otrans_ptr = otrans;
@@ -703,8 +710,12 @@ add_to_transited(krb5_data *tgt_trans, krb5_data *new_trans,
/* subrealm of the next field too, and we will catch */
/* it in a future iteration. */
- if ((next[nlst] != '.') && (next[0] != '/') &&
- (pl = subrealm(exp, realm))) {
+ /* Note that the second test here is an unsigned comparison,
+ so the first half (or a cast) is also required. */
+ assert(nlst < 0 || nlst < sizeof(next));
+ if ((nlst < 0 || next[nlst] != '.') &&
+ (next[0] != '/') &&
+ (pl = subrealm(exp, realm))) {
added = TRUE;
current[sizeof(current) - 1] = '\0';
if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) {
diff --git a/usr/src/cmd/krb5/krb5kdc/kdc_util.h b/usr/src/cmd/krb5/krb5kdc/kdc_util.h
index e0b96adc48..452dd8ad34 100644
--- a/usr/src/cmd/krb5/krb5kdc/kdc_util.h
+++ b/usr/src/cmd/krb5/krb5kdc/kdc_util.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,7 +34,6 @@
#ifndef __KRB5_KDC_UTIL__
#define __KRB5_KDC_UTIL__
-#pragma ident "%Z%%M% %I% %E% SMI"
#include "kdb.h"
@@ -118,7 +117,7 @@ void
rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep);
/* do_as_req.c */
-krb5_error_code process_as_req (krb5_kdc_req *,
+krb5_error_code process_as_req (krb5_kdc_req *, krb5_data *,
const krb5_fulladdr *,
krb5_data ** );
@@ -157,20 +156,26 @@ void get_preauth_hint_list (krb5_kdc_req * request,
krb5_db_entry *client,
krb5_db_entry *server,
krb5_data *e_data);
+krb5_error_code load_preauth_plugins(krb5_context context);
+krb5_error_code unload_preauth_plugins(krb5_context context);
+
krb5_error_code check_padata
- (krb5_context context, krb5_db_entry *client,
- krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply);
+ (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
+ krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
+ void **padata_context, krb5_data *e_data);
krb5_error_code return_padata
(krb5_context context, krb5_db_entry *client,
- krb5_kdc_req *request, krb5_kdc_rep *reply,
- krb5_key_data *client_key, krb5_keyblock *encrypting_key);
+ krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply,
+ krb5_key_data *client_key, krb5_keyblock *encrypting_key,
+ void **padata_context);
+krb5_error_code free_padata_context
+ (krb5_context context, void **padata_context);
+
/* replay.c */
-krb5_boolean kdc_check_lookaside (krb5_data *, const krb5_fulladdr *,
- krb5_data **);
-void kdc_insert_lookaside (krb5_data *, const krb5_fulladdr *,
- krb5_data *);
+krb5_boolean kdc_check_lookaside (krb5_data *, krb5_data **);
+void kdc_insert_lookaside (krb5_data *, krb5_data *);
void kdc_free_lookaside(krb5_context);
/* which way to convert key? */
@@ -204,6 +209,10 @@ void enable_v4_crossrealm(char *);
((X) == ADDRTYPE_INET ? AF_INET : -1)
#endif
+/* RFC 4120: KRB5KDC_ERR_KEY_TOO_WEAK
+ * RFC 4556: KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED */
+#define KRB5KDC_ERR_KEY_TOO_WEAK KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/krb5/krb5kdc/main.c b/usr/src/cmd/krb5/krb5kdc/main.c
index 3f88833225..c75f8d3994 100644
--- a/usr/src/cmd/krb5/krb5kdc/main.c
+++ b/usr/src/cmd/krb5/krb5kdc/main.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* kdc/main.c
@@ -188,7 +187,7 @@ init_realm(krb5_context kcontext, char *progname, kdc_realm_t *rdp, char *realm,
krb5_klog_set_context(rdp->realm_context);
kret = krb5_read_realm_params(rdp->realm_context, rdp->realm_name,
- (char *) NULL, (char *) NULL, &rparams);
+ &rparams);
if (kret) {
com_err(progname, kret, gettext("while reading realm parameters"));
goto whoops;
@@ -657,6 +656,9 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
}
kdc_realmlist[0] = rdatap;
kdc_numrealms++;
+ } else {
+ if (lrealm)
+ free(lrealm);
}
}
@@ -673,8 +675,7 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
/* Ensure that this is set for our first request. */
kdc_active_realm = kdc_realmlist[0];
- if (lrealm)
- free(lrealm);
+
if (default_udp_ports)
free(default_udp_ports);
if (default_tcp_ports)
@@ -784,6 +785,8 @@ int main(int argc, char **argv)
setup_signal_handlers();
+ load_preauth_plugins(kcontext);
+
retval = setup_sam();
if (retval) {
com_err(argv[0], retval, gettext("while initializing SAM"));
@@ -838,6 +841,7 @@ int main(int argc, char **argv)
errout++;
}
krb5_klog_syslog(LOG_INFO, "shutting down");
+ unload_preauth_plugins(kcontext);
krb5_klog_close(kdc_context);
finish_realms(argv[0]);
if (kdc_realmlist)
diff --git a/usr/src/cmd/krb5/krb5kdc/network.c b/usr/src/cmd/krb5/krb5kdc/network.c
index 0913e8ad87..fc16b38949 100644
--- a/usr/src/cmd/krb5/krb5kdc/network.c
+++ b/usr/src/cmd/krb5/krb5kdc/network.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,9 +30,7 @@
*
* Network code for Kerberos v5 KDC.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-#define NEED_SOCKETS
#include "k5-int.h"
#include "com_err.h"
#include "kdc_util.h"
@@ -44,8 +42,8 @@
#include <stddef.h>
#include <ctype.h>
-#include <port-sockets.h>
-/* #include <socket-utils.h> */
+#include "port-sockets.h"
+/* #include "socket-utils.h" */
#ifdef HAVE_NETINET_IN_H
#include <sys/types.h>
@@ -73,7 +71,7 @@
#include <sys/filio.h> /* FIONBIO */
#endif
-#include <fake-addrinfo.h>
+#include "fake-addrinfo.h"
/* Misc utility routines. */
static void
@@ -231,7 +229,7 @@ static SET(struct connection *) connections;
/* Set<u_short> udp_port_data, tcp_port_data; */
static SET(u_short) udp_port_data, tcp_port_data;
-#include <cm.h>
+#include "cm.h"
static struct select_state sstate;
@@ -911,6 +909,38 @@ kill_tcp_connection(struct connection *conn)
tcp_data_counter--;
}
+static krb5_error_code
+make_toolong_error (krb5_data **out)
+{
+ krb5_error errpkt;
+ krb5_error_code retval;
+ krb5_data *scratch;
+
+ retval = krb5_us_timeofday(kdc_context, &errpkt.stime, &errpkt.susec);
+ if (retval)
+ return retval;
+ errpkt.error = KRB_ERR_FIELD_TOOLONG;
+ errpkt.server = tgs_server;
+ errpkt.client = NULL;
+ errpkt.cusec = 0;
+ errpkt.ctime = 0;
+ errpkt.text.length = 0;
+ errpkt.text.data = 0;
+ errpkt.e_data.length = 0;
+ errpkt.e_data.data = 0;
+ scratch = malloc(sizeof(*scratch));
+ if (scratch == NULL)
+ return ENOMEM;
+ retval = krb5_mk_error(kdc_context, &errpkt, scratch);
+ if (retval) {
+ free(scratch);
+ return retval;
+ }
+
+ *out = scratch;
+ return 0;
+}
+
static void
process_tcp_connection(struct connection *conn, const char *prog, int selflags)
{
@@ -941,7 +971,10 @@ process_tcp_connection(struct connection *conn, const char *prog, int selflags)
}
if (conn->u.tcp.sgnum == 0) {
/* finished sending */
- /* should go back to reading */
+ /* We should go back to reading, though if we sent a
+ FIELD_TOOLONG error in reply to a length with the high
+ bit set, RFC 4120 says we have to close the TCP
+ stream. */
goto kill_tcp_connection;
}
} else if (selflags & SSF_READ) {
@@ -973,12 +1006,20 @@ process_tcp_connection(struct connection *conn, const char *prog, int selflags)
| (p[2] << 8)
| p[3]);
if (conn->u.tcp.msglen > conn->u.tcp.bufsiz - 4) {
+ krb5_error_code err;
/* message too big */
krb5_klog_syslog(LOG_ERR, "TCP client %s wants %lu bytes, cap is %lu",
conn->u.tcp.addrbuf, (unsigned long) conn->u.tcp.msglen,
(unsigned long) conn->u.tcp.bufsiz - 4);
/* XXX Should return an error. */
- goto kill_tcp_connection;
+ err = make_toolong_error (&conn->u.tcp.response);
+ if (err) {
+ krb5_klog_syslog(LOG_ERR,
+ "error constructing KRB_ERR_FIELD_TOOLONG error! %s",
+ error_message(err));
+ goto kill_tcp_connection;
+ }
+ goto have_response;
}
}
} else {
@@ -1007,6 +1048,7 @@ process_tcp_connection(struct connection *conn, const char *prog, int selflags)
com_err(prog, err, gettext("while dispatching (tcp)"));
goto kill_tcp_connection;
}
+ have_response:
conn->u.tcp.lenbuf[0] = 0xff & (conn->u.tcp.response->length >> 24);
conn->u.tcp.lenbuf[1] = 0xff & (conn->u.tcp.response->length >> 16);
conn->u.tcp.lenbuf[2] = 0xff & (conn->u.tcp.response->length >> 8);
@@ -1037,7 +1079,10 @@ krb5_error_code
listen_and_process(const char *prog)
{
int nfound;
- struct select_state sout;
+ /* This struct contains 3 fd_set objects; on some platforms, they
+ can be rather large. Making this static avoids putting all
+ that junk on the stack. */
+ static struct select_state sout;
int i, sret;
krb5_error_code err;
diff --git a/usr/src/cmd/krb5/krb5kdc/replay.c b/usr/src/cmd/krb5/krb5kdc/replay.c
index d944bbada7..83f1e68381 100644
--- a/usr/src/cmd/krb5/krb5kdc/replay.c
+++ b/usr/src/cmd/krb5/krb5kdc/replay.c
@@ -29,7 +29,6 @@
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include "k5-int.h"
#include "kdc_util.h"
@@ -44,7 +43,6 @@ typedef struct _krb5_kdc_replay_ent {
time_t db_age;
krb5_data *req_packet;
krb5_data *reply_packet;
- krb5_address *addr; /* XXX should these not be pointers? */
} krb5_kdc_replay_ent;
static krb5_kdc_replay_ent root_ptr = {0};
@@ -61,10 +59,6 @@ static int num_entries = 0;
#define MATCH(ptr) (((ptr)->req_packet->length == inpkt->length) && \
!memcmp((ptr)->req_packet->data, inpkt->data, \
inpkt->length) && \
- ((ptr)->addr->length == from->address->length) && \
- !memcmp((ptr)->addr->contents, \
- from->address->contents, \
- from->address->length)&& \
((ptr)->db_age == db_age))
/* XXX
Todo: quench the size of the queue...
@@ -74,8 +68,7 @@ static int num_entries = 0;
FALSE if the caller should do the work */
krb5_boolean
-kdc_check_lookaside(krb5_data *inpkt, const krb5_fulladdr *from,
- krb5_data **outpkt)
+kdc_check_lookaside(krb5_data *inpkt, krb5_data **outpkt)
{
krb5_int32 timenow;
register krb5_kdc_replay_ent *eptr, *last, *hold;
@@ -110,7 +103,6 @@ kdc_check_lookaside(krb5_data *inpkt, const krb5_fulladdr *from,
max_hits_per_entry = max(max_hits_per_entry, eptr->num_hits);
krb5_free_data(kdc_context, eptr->req_packet);
krb5_free_data(kdc_context, eptr->reply_packet);
- krb5_free_address(kdc_context, eptr->addr);
hold = eptr;
last->next = eptr->next;
eptr = last;
@@ -128,8 +120,7 @@ kdc_check_lookaside(krb5_data *inpkt, const krb5_fulladdr *from,
already there, and can fail softly due to other weird errors. */
void
-kdc_insert_lookaside(krb5_data *inpkt, const krb5_fulladdr *from,
- krb5_data *outpkt)
+kdc_insert_lookaside(krb5_data *inpkt, krb5_data *outpkt)
{
register krb5_kdc_replay_ent *eptr;
krb5_int32 timenow;
@@ -159,12 +150,6 @@ kdc_insert_lookaside(krb5_data *inpkt, const krb5_fulladdr *from,
free(eptr);
return;
}
- if (krb5_copy_addr(kdc_context, from->address, &eptr->addr)) {
- krb5_free_data(kdc_context, eptr->req_packet);
- krb5_free_data(kdc_context, eptr->reply_packet);
- free(eptr);
- return;
- }
eptr->next = root_ptr.next;
root_ptr.next = eptr;
num_entries++;
@@ -181,7 +166,6 @@ kdc_free_lookaside(krb5_context kcontext)
eptr; eptr = eptr->next) {
krb5_free_data(kcontext, eptr->req_packet);
krb5_free_data(kcontext, eptr->reply_packet);
- krb5_free_address(kcontext, eptr->addr);
hold = eptr;
last->next = eptr->next;
eptr = last;
diff --git a/usr/src/cmd/krb5/ldap_util/kdb5_ldap_util.c b/usr/src/cmd/krb5/ldap_util/kdb5_ldap_util.c
index d0d8b06dc0..c02bc2e1a4 100644
--- a/usr/src/cmd/krb5/ldap_util/kdb5_ldap_util.c
+++ b/usr/src/cmd/krb5/ldap_util/kdb5_ldap_util.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* kadmin/ldap_util/kdb5_ldap_util.c
@@ -480,8 +479,7 @@ int main(argc, argv)
}
if (realm_name_required) {
- /* Solaris kerberos: using older kadm5_get_config_params interface */
- retval = kadm5_get_config_params(util_context, NULL, NULL,
+ retval = kadm5_get_config_params(util_context, 1,
&global_params, &global_params);
if (retval) {
com_err(argv[0], retval, gettext("while retreiving configuration parameters"));
diff --git a/usr/src/cmd/krb5/slave/kpropd.c b/usr/src/cmd/krb5/slave/kpropd.c
index ab1536ae65..ce4e037164 100644
--- a/usr/src/cmd/krb5/slave/kpropd.c
+++ b/usr/src/cmd/krb5/slave/kpropd.c
@@ -25,7 +25,6 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* slave/kpropd.c
@@ -710,6 +709,21 @@ krb5_error_code do_iprop(kdb_log_context *log_ctx) {
exit(1);
}
+ /* Solaris Kerberos */
+ if (krb5_is_referral_realm(krb5_princ_realm(kpropd_context,
+ iprop_svc_principal))) {
+ krb5_data *r = krb5_princ_realm(kpropd_context,
+ iprop_svc_principal);
+ assert(def_realm != NULL);
+ r->length = strlen(def_realm);
+ r->data = strdup(def_realm);
+ if (r->data == NULL) {
+ com_err(progname, retval,
+ ("while determining local service principal name"));
+ exit(1);
+ }
+ }
+
if (retval = krb5_unparse_name(kpropd_context, iprop_svc_principal,
&iprop_svc_princstr)) {
com_err(progname, retval,
@@ -1251,7 +1265,7 @@ void PRS(argc,argv)
strcpy(temp_file_name, file);
strcat(temp_file_name, tmp);
- retval = kadm5_get_config_params(kpropd_context, NULL, NULL, &params,
+ retval = kadm5_get_config_params(kpropd_context, 1, NULL, &params,
&params);
if (retval) {
com_err(progname, retval, gettext("while initializing"));
diff --git a/usr/src/lib/gss_mechs/mech_krb5/Makefile.com b/usr/src/lib/gss_mechs/mech_krb5/Makefile.com
index 29ab0eda14..0405ef777a 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/Makefile.com
+++ b/usr/src/lib/gss_mechs/mech_krb5/Makefile.com
@@ -22,7 +22,6 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
#
#
@@ -49,7 +48,8 @@ CRYPTO = cksumtype_to_string.o \
keyed_checksum_types.o keyed_cksum.o \
make_random_key.o string_to_cksumtype.o \
string_to_enctype.o string_to_key.o valid_cksumtype.o \
- valid_enctype.o pkcs11slot.o state.o pbkdf2.o old_api_glue.o
+ valid_enctype.o pkcs11slot.o state.o pbkdf2.o old_api_glue.o \
+ keylengths.o random_to_key.o
CRYPTO_UTS= cksumtypes.o decrypt.o encrypt.o encrypt_length.o \
etypes.o nfold.o verify_checksum.o default_state.o \
@@ -136,7 +136,7 @@ K5_KRB= addr_comp.o addr_order.o addr_srch.o \
recvauth.o send_tgs.o sendauth.o srv_rcache.o str_conv.o \
tgtname.o valid_times.o walk_rtree.o appdefault.o deltat.o \
enc_helper.o gic_keytab.o gic_opt.o gic_pwd.o preauth2.o \
- vfy_increds.o vic_opt.o set_realm.o krb5_libinit.o chpw.o \
+ preauth.o vfy_increds.o vic_opt.o set_realm.o krb5_libinit.o chpw.o \
init_keyblock.o init_allocated_keyblock.o get_set_keyblock.o kerrs.o \
getuid.o
@@ -191,7 +191,7 @@ GSSAPI_UTS= gen_oids.o
PROFILE_OBJS= prof_tree.o prof_file.o prof_parse.o prof_init.o \
prof_set.o prof_get.o
-SUPPORT_OBJS= fake-addrinfo.o threads.o errors.o plugins.o
+SUPPORT_OBJS= fake-addrinfo.o init-addrinfo.o threads.o errors.o plugins.o
KWARN_OBJS= kwarnd_clnt_stubs.o kwarnd_clnt.o kwarnd_handle.o kwarnd_xdr.o
@@ -487,9 +487,9 @@ include $(REL_PATH)/../../Makefile.targ
OS_FLAGS = -DHAVE_LIBSOCKET -DHAVE_LIBNSL -DTIME_WITH_SYS_TIME \
-DHAVE_UNISTD_H -DHAVE_SYS_TIME_H -DHAVE_REGEX_H \
-DHAVE_REGEXP_H -DHAVE_RE_COMP -DHAVE_REGCOMP \
- -DPOSIX_TYPES -DNDBM -DAN_TO_LN_RULES \
+ -DPOSIX_TYPES -DNDBM \
-DHAVE_STDLIB_H -DHAVE_STDARG_H -DHAVE_SYS_TYPES_H \
- -DHAVE_NETINET_IN_H -DUSE_LOGIN_LIBRARY -DHAVE_SRAND48 \
+ -DHAVE_NETINET_IN_H -DHAVE_SRAND48 \
-DHAVE_SRAND -DHAVE_SRANDOM -DHAVE_GETPID \
-DHAVE_ERRNO -DHAVE_STRFTIME -DHAVE_STRPTIME -DHAVE_STRERROR \
-DHAVE_STAT -DSIZEOF_INT=4 -DPROVIDE_KERNEL_IMPORT \
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/aes/aes_s2k.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/aes/aes_s2k.c
index e0b7a2482b..9cb8c6ef36 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/aes/aes_s2k.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/aes/aes_s2k.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/crypto/aes/aes_s2k.c
@@ -34,31 +33,37 @@
* krb5int_aes_string_to_key
*/
-#include <k5-int.h>
-#include <dk.h>
+#include "k5-int.h"
+#include "dk.h"
+#include "aes_s2k.h"
#define DEFAULT_ITERATION_COUNT 4096 /* was 0xb000L in earlier drafts */
#define MAX_ITERATION_COUNT 0x1000000L
krb5_error_code
krb5int_aes_string_to_key(krb5_context context,
- const struct krb5_enc_provider *enc,
- const krb5_data *string,
- const krb5_data *salt,
- const krb5_data *params,
- krb5_keyblock *key)
+ const struct krb5_enc_provider *enc,
+ const krb5_data *string,
+ const krb5_data *salt,
+ const krb5_data *params,
+ krb5_keyblock *key)
{
unsigned long iter_count;
krb5_data out;
static const krb5_data usage = { KV5M_DATA, 8, "kerberos" };
krb5_error_code err;
+ /* Solaris Kerberos */
krb5_keyblock *inkey = NULL;
if (params) {
unsigned char *p = (unsigned char *) params->data;
if (params->length != 4)
return KRB5_ERR_BAD_S2K_PARAMS;
- iter_count = ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]));
+ /* The first two need casts in case 'int' is 16 bits. */
+ iter_count = (((unsigned long)p[0] << 24)
+ | ((unsigned long)p[1] << 16)
+ | (p[2] << 8)
+ | (p[3]));
if (iter_count == 0) {
/*
iter_count = (1L << 16) << 16;
@@ -80,11 +85,12 @@ krb5int_aes_string_to_key(krb5_context context,
* Dense key space, no parity bits or anything, so take a shortcut
* and use the key contents buffer for the generated bytes.
*/
+ /* Solaris Kerberos */
if (key->length != 16 && key->length != 32)
return KRB5_CRYPTO_INTERNAL;
out.data = (char *) key->contents;
out.length = key->length;
-
+ /* Solaris Kerberos */
err = krb5int_pbkdf2_hmac_sha1 (context, &out, iter_count, key->enctype,
string, salt);
if (err) {
@@ -93,6 +99,7 @@ krb5int_aes_string_to_key(krb5_context context,
}
/*
+ * Solaris Kerberos:
* The derive key operation below will not work correctly
* if the input and output key pointers are to the same
* data. This is because the key object handle (PKCS#11)
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/coll_proof_cksum.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/coll_proof_cksum.c
index 141e3c9cd5..5c3ea48d34 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/coll_proof_cksum.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/coll_proof_cksum.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -25,8 +24,8 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <cksumtypes.h>
+#include "k5-int.h"
+#include "cksumtypes.h"
krb5_boolean KRB5_CALLCONV
krb5_c_is_coll_proof_cksum(krb5_cksumtype ctype)
@@ -47,5 +46,5 @@ krb5_c_is_coll_proof_cksum(krb5_cksumtype ctype)
krb5_boolean KRB5_CALLCONV
is_coll_proof_cksum(krb5_cksumtype ctype)
{
- return krb5_c_is_coll_proof_cksum (ctype);
+ return krb5_c_is_coll_proof_cksum (ctype);
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/des/afsstring2key.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/des/afsstring2key.c
index c194ea6012..a0c7847296 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/des/afsstring2key.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/des/afsstring2key.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/crypto/des/string2key.c
@@ -80,6 +79,7 @@ mit_afs_string_to_key (krb5_context context,
krb5_keyblock *keyblock, const krb5_data *data,
const krb5_data *salt)
{
+ /* Solaris Kerberos */
krb5_error_code retval = KRB5_PROG_ETYPE_NOSUPP;
/* EXPORT DELETE START */
/* totally different approach from MIT string2key. */
@@ -90,6 +90,7 @@ mit_afs_string_to_key (krb5_context context,
char *realm = salt->data;
unsigned int i, j;
krb5_octet *key = keyblock->contents;
+ /* Solaris Kerberos */
krb5_keyblock usekey;
if (data->length <= 8) {
@@ -133,7 +134,6 @@ mit_afs_string_to_key (krb5_context context,
mit_des_cblock ikey, tkey;
unsigned int pw_len = salt->length+data->length;
unsigned char *password = malloc(pw_len+1);
-
if (!password) return ENOMEM;
/* Some bound checks from the original code are elided here as
@@ -149,6 +149,7 @@ mit_afs_string_to_key (krb5_context context,
memcpy (tkey, ikey, sizeof(tkey));
mit_des_fixup_key_parity (tkey);
+ /* Solaris Kerberos */
usekey.enctype = ENCTYPE_DES_CBC_CRC;
usekey.contents = tkey;
usekey.length = 8;
@@ -157,7 +158,7 @@ mit_afs_string_to_key (krb5_context context,
memcpy (ikey, tkey, sizeof(ikey));
mit_des_fixup_key_parity (tkey);
-
+ /* Solaris Kerberos */
if (usekey.hKey != CK_INVALID_HANDLE) {
(void) C_DestroyObject(krb_ctx_hSession(context), usekey.hKey);
usekey.hKey = CK_INVALID_HANDLE;
@@ -170,6 +171,7 @@ mit_afs_string_to_key (krb5_context context,
/* now fix up key parity again */
mit_des_fixup_key_parity(key);
+ /* Solaris Kerberos */
if (usekey.hKey != CK_INVALID_HANDLE) {
(void) C_DestroyObject(krb_ctx_hSession(context), usekey.hKey);
usekey.hKey = CK_INVALID_HANDLE;
@@ -383,6 +385,7 @@ char *afs_crypt(const char *pw, const char *salt,
for(i=0; i<66; i++)
block[i] = 0;
+ /* Solaris Kerberos */
for(i=0; ((c= *pw) != NULL) && i<64; pw++){
for(j=0; j<7; j++, i++)
block[i] = (c>>(6-j)) & 01;
@@ -435,7 +438,7 @@ char *afs_crypt(const char *pw, const char *salt,
static void krb5_afs_crypt_setkey(char *key, char *E, char (*KS)[48])
{
- int i, j, k;
+ register int i, j, k;
int t;
/*
* The C and D arrays used to calculate the key schedule.
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/dk/stringtokey.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/dk/stringtokey.c
index 6f97457c40..d8cea570eb 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/dk/stringtokey.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/dk/stringtokey.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,19 +30,17 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <dk.h>
+#include "dk.h"
-static unsigned char kerberos[] = "kerberos";
+static const unsigned char kerberos[] = "kerberos";
#define kerberos_len (sizeof(kerberos)-1)
krb5_error_code
-krb5_dk_string_to_key(
- krb5_context context,
- krb5_const struct krb5_enc_provider *enc,
- krb5_const krb5_data *string,
- krb5_const krb5_data *salt,
- krb5_const krb5_data *parms,
- krb5_keyblock *key)
+krb5int_dk_string_to_key(
+ krb5_context context,
+ const struct krb5_enc_provider *enc,
+ const krb5_data *string, const krb5_data *salt,
+ const krb5_data *parms, krb5_keyblock *key)
{
krb5_error_code ret;
size_t keybytes, keylength, concatlen;
@@ -72,35 +69,37 @@ krb5_dk_string_to_key(
/* construct input string ( = string + salt), fold it, make_key it */
- (void) memcpy(concat, string->data, string->length);
+ memcpy(concat, string->data, string->length);
if (salt)
- (void) memcpy(concat+string->length, salt->data, salt->length);
+ memcpy(concat+string->length, salt->data, salt->length);
krb5_nfold(concatlen*8, concat, keybytes*8, foldstring);
indata.length = keybytes;
- indata.data = (char *)foldstring;
+ indata.data = (char *) foldstring;
+ /* Solaris Kerberos */
memset(&foldkey, 0, sizeof (krb5_keyblock));
foldkey.enctype = key->enctype;
foldkey.length = keylength;
foldkey.contents = foldkeydata;
+ /* Solaris Kerberos */
(*(enc->make_key))(context, &indata, &foldkey);
/* now derive the key from this one */
indata.length = kerberos_len;
- indata.data = (char *)kerberos;
-
+ indata.data = (char *) kerberos;
+ /* Solaris Kerberos */
if ((ret = krb5_derive_key(context, enc, &foldkey, key, &indata)))
(void) memset(key->contents, 0, key->length);
/* ret is set correctly by the prior call */
- (void) memset(concat, 0, concatlen);
- (void) memset(foldstring, 0, keybytes);
- (void) memset(foldkeydata, 0, keylength);
+ memset(concat, 0, concatlen);
+ memset(foldstring, 0, keybytes);
+ memset(foldkeydata, 0, keylength);
free(foldkeydata);
free(foldstring);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/enctype_compare.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/enctype_compare.c
index 157c5b43ca..a2add40d48 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/enctype_compare.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/enctype_compare.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -25,13 +24,13 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <etypes.h>
+#include "k5-int.h"
+#include "etypes.h"
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
krb5_c_enctype_compare(krb5_context context, krb5_enctype e1, krb5_enctype e2,
- krb5_boolean *similar)
+ krb5_boolean *similar)
{
int i, j;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/hash_provider/hash_md5.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/hash_provider/hash_md5.c
index c8d7b89ca8..74e5bcc167 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/hash_provider/hash_md5.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/hash_provider/hash_md5.c
@@ -1,20 +1,19 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* 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
@@ -25,20 +24,25 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <hash_provider.h>
+#include "k5-int.h"
+/* Solaris Kerberos */
+#if 0
+#include "rsa-md5.h"
+#endif
+#include "hash_provider.h"
static krb5_error_code
k5_md5_hash(krb5_context context,
- unsigned int icount, krb5_const krb5_data *input,
- krb5_data *output)
+ unsigned int icount, krb5_const krb5_data *input,
+ krb5_data *output)
{
+ /* Solaris Kerberos */
CK_MECHANISM mechanism;
mechanism.mechanism = CKM_MD5;
@@ -48,6 +52,7 @@ k5_md5_hash(krb5_context context,
return(k5_ef_hash(context, &mechanism, icount, input, output));
}
+/* Solaris Kerberos */
const struct krb5_hash_provider krb5int_hash_md5 = {
MD5_CKSUM_LENGTH,
MD5_BLOCKSIZE,
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/hash_provider/hash_sha1.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/hash_provider/hash_sha1.c
index 71f441cbd4..c579c57c48 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/hash_provider/hash_sha1.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/hash_provider/hash_sha1.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,13 +30,14 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <hash_provider.h>
+#include "k5-int.h"
+#include "hash_provider.h"
+/* Solaris Kerberos */
static krb5_error_code
k5_sha1_hash(krb5_context context,
- unsigned int icount, krb5_const krb5_data *input,
- krb5_data *output)
+ unsigned int icount, krb5_const krb5_data *input,
+ krb5_data *output)
{
CK_MECHANISM mechanism;
@@ -50,7 +50,7 @@ k5_sha1_hash(krb5_context context,
return(0);
}
-const struct krb5_hash_provider krb5_hash_sha1 = {
+const struct krb5_hash_provider krb5int_hash_sha1 = {
SHS_DIGESTSIZE,
SHS_DATASIZE,
k5_sha1_hash
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/keyed_checksum_types.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/keyed_checksum_types.c
index f926c5b34a..f12b5865c6 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/keyed_checksum_types.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/keyed_checksum_types.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -25,12 +24,11 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <etypes.h>
-#include <cksumtypes.h>
+#include "k5-int.h"
+#include "etypes.h"
+#include "cksumtypes.h"
-static int etype_match(e1, e2)
- krb5_enctype e1, e2;
+static int etype_match(krb5_enctype e1, krb5_enctype e2)
{
int i1, i2;
@@ -48,7 +46,6 @@ static int etype_match(e1, e2)
}
/*ARGSUSED*/
-
krb5_error_code KRB5_CALLCONV
krb5_c_keyed_checksum_types(krb5_context context, krb5_enctype enctype,
unsigned int *count, krb5_cksumtype **cksumtypes)
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/keyed_cksum.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/keyed_cksum.c
index 8af42e9f4a..38529b2b4c 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/keyed_cksum.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/keyed_cksum.c
@@ -1,20 +1,14 @@
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* 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
@@ -25,14 +19,14 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <cksumtypes.h>
+#include "k5-int.h"
+#include "cksumtypes.h"
krb5_boolean KRB5_CALLCONV
krb5_c_is_keyed_cksum(krb5_cksumtype ctype)
@@ -52,5 +46,11 @@ krb5_c_is_keyed_cksum(krb5_cksumtype ctype)
/* ick, but it's better than coredumping, which is what the
old code would have done */
- return(0);
+ return 0; /* error case */
+}
+
+krb5_boolean KRB5_CALLCONV
+is_keyed_cksum(krb5_cksumtype ctype)
+{
+ return krb5_c_is_keyed_cksum (ctype);
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/keyhash_provider/hmac_md5.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/keyhash_provider/hmac_md5.c
index 55450c15dd..96e692cec4 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/keyhash_provider/hmac_md5.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/keyhash_provider/hmac_md5.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/crypto/keyhash_provider/hmac_md5.c
@@ -37,10 +36,10 @@
* Implemented based on draft-brezak-win2k-krb-rc4-hmac-03
*/
-#include <k5-int.h>
-#include <arcfour.h>
-#include <hash_provider.h>
-#include <keyhash_provider.h>
+#include "k5-int.h"
+#include "keyhash_provider.h"
+#include "arcfour.h"
+#include "hash_provider.h"
static krb5_error_code
k5_hmac_md5_hash (krb5_context context,
@@ -64,14 +63,15 @@ k5_hmac_md5_hash (krb5_context context,
ks.length = key->length;
ds.data = malloc(ds.length);
if (ds.data == NULL)
- return (ENOMEM);
+ return ENOMEM;
ks.contents = (void *) ds.data;
ks_constant.data = "signaturekey";
ks_constant.length = strlen(ks_constant.data)+1; /* Including null*/
+ /* Solaris Kerberos */
ret = krb5_hmac(context, &krb5int_hash_md5, key, 1,
- &ks_constant, &ds);
+ &ks_constant, &ds);
if (ret)
goto cleanup;
@@ -81,6 +81,7 @@ k5_hmac_md5_hash (krb5_context context,
t[2] = (ms_usage >>16) & 0xff;
t[3] = (ms_usage>>24) & 0XFF;
+ /* Solaris Kerberos */
mechanism.mechanism = CKM_MD5;
mechanism.pParameter = NULL_PTR;
mechanism.ulParameterLen = 0;
@@ -126,10 +127,11 @@ cleanup:
return (ret);
}
-const struct krb5_keyhash_provider
-krb5int_keyhash_hmac_md5 = {
- 16,
- k5_hmac_md5_hash,
- NULL /*checksum again*/
+
+
+const struct krb5_keyhash_provider krb5int_keyhash_hmac_md5 = {
+ 16,
+ k5_hmac_md5_hash,
+ NULL /*checksum again*/
};
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/keyhash_provider/k5_md5des.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/keyhash_provider/k5_md5des.c
index e347b062d2..9fc19a8882 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/keyhash_provider/k5_md5des.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/keyhash_provider/k5_md5des.c
@@ -1,20 +1,19 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* 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
@@ -25,15 +24,15 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <des_int.h>
-#include <keyhash_provider.h>
+#include "k5-int.h"
+#include "des_int.h"
+#include "keyhash_provider.h"
#define CONFLENGTH 8
@@ -47,11 +46,9 @@
/*ARGSUSED*/
static krb5_error_code
-k5_md5des_hash(krb5_context context,
- krb5_const krb5_keyblock *key,
- krb5_keyusage usage,
- krb5_const krb5_data *ivec,
- krb5_const krb5_data *input, krb5_data *output)
+k5_md5des_hash(krb5_context context, krb5_const krb5_keyblock *key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ const krb5_data *input, krb5_data *output)
{
krb5_error_code ret = 0;
krb5_data data;
@@ -274,7 +271,7 @@ cleanup:
return(ret);
}
-const struct krb5_keyhash_provider krb5_keyhash_md5des = {
+const struct krb5_keyhash_provider krb5int_keyhash_md5des = {
CONFLENGTH + MD5_CKSUM_LENGTH,
k5_md5des_hash,
k5_md5des_verify
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/keylengths.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/keylengths.c
new file mode 100644
index 0000000000..419638e470
--- /dev/null
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/keylengths.c
@@ -0,0 +1,62 @@
+/*
+ * COPYRIGHT (c) 2006
+ * The Regents of the University of Michigan
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+
+#include "k5-int.h"
+#include "etypes.h"
+
+/*
+ * keybytes is the number of bytes required as input to make a key,
+ * keylength is the length of the final key in bytes
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_c_keylengths(krb5_context context, krb5_enctype enctype,
+ size_t *keybytes, size_t *keylength)
+{
+ int i;
+
+ if (keybytes == NULL && keylength == NULL)
+ return(EINVAL);
+
+ for (i=0; i<krb5_enctypes_length; i++) {
+ if (krb5_enctypes_list[i].etype == enctype)
+ break;
+ }
+
+ if (i == krb5_enctypes_length)
+ return(KRB5_BAD_ENCTYPE);
+
+ if (keybytes)
+ *keybytes = krb5_enctypes_list[i].enc->keybytes;
+ if (keylength)
+ *keylength = krb5_enctypes_list[i].enc->keylength;
+
+ return(0);
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/make_random_key.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/make_random_key.c
index 1cdcf655fe..e6c6c9d4a2 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/make_random_key.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/make_random_key.c
@@ -3,18 +3,17 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* 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
@@ -25,18 +24,18 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <etypes.h>
+#include "k5-int.h"
+#include "etypes.h"
krb5_error_code KRB5_CALLCONV
krb5_c_make_random_key(krb5_context context, krb5_enctype enctype,
- krb5_keyblock *random_key)
+ krb5_keyblock *random_key)
{
int i;
krb5_error_code ret;
@@ -78,6 +77,8 @@ krb5_c_make_random_key(krb5_context context, krb5_enctype enctype,
random_key->magic = KV5M_KEYBLOCK;
random_key->enctype = enctype;
random_key->length = keylength;
+
+ /* Solaris Kerberos */
random_key->dk_list = NULL;
#ifdef _KERNEL
random_key->kef_key = NULL;
@@ -85,6 +86,7 @@ krb5_c_make_random_key(krb5_context context, krb5_enctype enctype,
random_key->hKey = CK_INVALID_HANDLE;
#endif
+ /* Solaris Kerberos */
ret = ((*(enc->make_key))(context, &random_data, random_key));
cleanup:
@@ -94,6 +96,7 @@ cleanup:
if (ret) {
memset(random_key->contents, 0, keylength);
free(random_key->contents);
+ /* Solaris Kerberos */
random_key->contents = NULL;
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/md4/md4.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/md4/md4.c
index adbd01186a..7541093805 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/md4/md4.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/md4/md4.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/crypto/md4/md4.c
@@ -42,8 +41,8 @@
**********************************************************************
*/
-#include <k5-int.h>
-#include <rsa-md4.h>
+#include "k5-int.h"
+#include "rsa-md4.h"
/* forward declaration */
static void Transform (krb5_ui_4 *, krb5_ui_4 *);
@@ -83,8 +82,7 @@ static const unsigned char PADDING[64] = {
(a) = ROTATE_LEFT ((a), (s));}
void
-krb5_MD4Init (mdContext)
-krb5_MD4_CTX *mdContext;
+krb5_MD4Init (krb5_MD4_CTX *mdContext)
{
mdContext->i[0] = mdContext->i[1] = (krb5_ui_4)0;
@@ -97,10 +95,7 @@ krb5_MD4_CTX *mdContext;
}
void
-krb5_MD4Update (mdContext, inBuf, inLen)
-krb5_MD4_CTX *mdContext;
-const unsigned char *inBuf;
-unsigned int inLen;
+krb5_MD4Update (krb5_MD4_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen)
{
krb5_ui_4 in[16];
int mdi;
@@ -133,8 +128,7 @@ unsigned int inLen;
}
void
-krb5_MD4Final (mdContext)
-krb5_MD4_CTX *mdContext;
+krb5_MD4Final (krb5_MD4_CTX *mdContext)
{
krb5_ui_4 in[16];
int mdi;
@@ -175,12 +169,32 @@ krb5_MD4_CTX *mdContext;
/* Basic MD4 step. Transform buf based on in.
*/
-static void Transform (buf, in)
-krb5_ui_4 *buf;
-krb5_ui_4 *in;
+static void Transform (krb5_ui_4 *buf, krb5_ui_4 *in)
{
register krb5_ui_4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+#ifdef CONFIG_SMALL
+ int i;
+#define ROTATE { krb5_ui_4 temp; temp = d, d = c, c = b, b = a, a = temp; }
+ for (i = 0; i < 16; i++) {
+ static const unsigned char round1consts[] = { 3, 7, 11, 19, };
+ FF (a, b, c, d, in[i], round1consts[i%4]); ROTATE;
+ }
+ for (i = 0; i < 16; i++) {
+ static const unsigned char round2indices[] = {
+ 0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15
+ };
+ static const unsigned char round2consts[] = { 3, 5, 9, 13 };
+ GG (a, b, c, d, in[round2indices[i]], round2consts[i%4]); ROTATE;
+ }
+ for (i = 0; i < 16; i++) {
+ static const unsigned char round3indices[] = {
+ 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
+ };
+ static const unsigned char round3consts[] = { 3, 9, 11, 15 };
+ HH (a, b, c, d, in[round3indices[i]], round3consts[i%4]); ROTATE;
+ }
+#else
/* Round 1 */
FF (a, b, c, d, in[ 0], 3);
FF (d, a, b, c, in[ 1], 7);
@@ -234,6 +248,7 @@ krb5_ui_4 *in;
HH (d, a, b, c, in[11], 9);
HH (c, d, a, b, in[ 7], 11);
HH (b, c, d, a, in[15], 15);
+#endif
buf[0] += a;
buf[1] += b;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/old/des_stringtokey.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/old/des_stringtokey.c
index 0b6fe20e5a..0100041540 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/old/des_stringtokey.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/old/des_stringtokey.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -25,39 +24,40 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <old.h>
+#include "k5-int.h"
+#include "old.h"
#include <des_int.h>
/* XXX */
extern krb5_error_code mit_des_string_to_key_int
(krb5_context context,
- krb5_keyblock * keyblock,
- const krb5_data * data,
- const krb5_data * salt);
+ krb5_keyblock * keyblock,
+ const krb5_data * data,
+ const krb5_data * salt);
/*ARGSUSED*/
krb5_error_code
-krb5_des_string_to_key(krb5_context context,
- const struct krb5_enc_provider *enc,
- const krb5_data *string,
- const krb5_data *salt,
- krb5_const krb5_data *parm,
- krb5_keyblock *key)
+krb5int_des_string_to_key(krb5_context context,
+ const struct krb5_enc_provider *enc,
+ const krb5_data *string,
+ const krb5_data *salt, const krb5_data *parm,
+ krb5_keyblock *key)
{
int type;
- if (parm) {
- if (parm->length != 1)
+ if (parm ) {
+ if (parm->length != 1)
return KRB5_ERR_BAD_S2K_PARAMS;
type = parm->data[0];
- } else type = 0;
-
+ }
+ else type = 0;
switch(type) {
case 0:
- return mit_des_string_to_key_int(context, key, string, salt);
+ /* Solaris Kerberos */
+ return(mit_des_string_to_key_int(context, key, string, salt));
case 1:
- return mit_afs_string_to_key(context, key, string, salt);
+ /* Solaris Kerberos */
+ return mit_afs_string_to_key(context, key, string, salt);
default:
- return KRB5_ERR_BAD_S2K_PARAMS;
+ return KRB5_ERR_BAD_S2K_PARAMS;
}
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/old_api_glue.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/old_api_glue.c
index 8b24096389..4bb7b0c6f5 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/old_api_glue.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/old_api_glue.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -39,6 +38,90 @@
*/
krb5_error_code KRB5_CALLCONV
+krb5_encrypt(krb5_context context, krb5_const_pointer inptr,
+ krb5_pointer outptr, size_t size, krb5_encrypt_block *eblock,
+ krb5_pointer ivec)
+{
+ krb5_data inputd, ivecd;
+ krb5_enc_data outputd;
+ size_t blocksize, outlen;
+ krb5_error_code ret;
+
+ if (ivec) {
+ if ((ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize)))
+ return(ret);
+
+ ivecd.length = blocksize;
+ ivecd.data = ivec;
+ }
+
+ /* size is the length of the input cleartext data */
+ inputd.length = size;
+ inputd.data = (char*)inptr;
+
+ /* The size of the output buffer isn't part of the old api. Not too
+ safe. So, we assume here that it's big enough. */
+ if ((ret = krb5_c_encrypt_length(context, eblock->key->enctype, size,
+ &outlen)))
+ return(ret);
+
+ outputd.ciphertext.length = outlen;
+ outputd.ciphertext.data = outptr;
+
+ return(krb5_c_encrypt(context, eblock->key, 0, ivec?&ivecd:0,
+ &inputd, &outputd));
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_decrypt(krb5_context context, krb5_const_pointer inptr,
+ krb5_pointer outptr, size_t size, krb5_encrypt_block *eblock,
+ krb5_pointer ivec)
+{
+ krb5_enc_data inputd;
+ krb5_data outputd, ivecd;
+ size_t blocksize;
+ krb5_error_code ret;
+
+ if (ivec) {
+ if ((ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize)))
+ return(ret);
+
+ ivecd.length = blocksize;
+ ivecd.data = ivec;
+ }
+
+ /* size is the length of the input ciphertext data */
+ inputd.enctype = eblock->key->enctype;
+ inputd.ciphertext.length = size;
+ /* Solaris Kerberos */
+ inputd.ciphertext.data = (char*)inptr;
+
+ /* we don't really know how big this is, but the code tends to assume
+ that the output buffer size should be the same as the input
+ buffer size */
+ outputd.length = size;
+ outputd.data = outptr;
+
+ return(krb5_c_decrypt(context, eblock->key, 0, ivec?&ivecd:0,
+ &inputd, &outputd));
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_process_key(krb5_context context, krb5_encrypt_block *eblock,
+ const krb5_keyblock *key)
+{
+ eblock->key = (krb5_keyblock *) key;
+
+ return(0);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_finish_key(krb5_context context, krb5_encrypt_block *eblock)
+{
+ return(0);
+}
+
+krb5_error_code KRB5_CALLCONV
krb5_string_to_key(krb5_context context, const krb5_encrypt_block *eblock,
krb5_keyblock *keyblock, const krb5_data *data,
const krb5_data *salt)
@@ -48,8 +131,51 @@ krb5_string_to_key(krb5_context context, const krb5_encrypt_block *eblock,
}
krb5_error_code KRB5_CALLCONV
+krb5_init_random_key(krb5_context context, const krb5_encrypt_block *eblock,
+ const krb5_keyblock *keyblock, krb5_pointer *ptr)
+{
+ krb5_data data;
+
+ data.length = keyblock->length;
+ data.data = (char *) keyblock->contents;
+
+ return(krb5_c_random_seed(context, &data));
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_finish_random_key(krb5_context context, const krb5_encrypt_block *eblock,
+ krb5_pointer *ptr)
+{
+ return(0);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_random_key(krb5_context context, const krb5_encrypt_block *eblock,
+ krb5_pointer ptr, krb5_keyblock **keyblock)
+{
+ krb5_keyblock *key;
+ krb5_error_code ret;
+
+ if ((key = (krb5_keyblock *) malloc(sizeof(krb5_keyblock))) == NULL)
+ return(ENOMEM);
+
+ if ((ret = krb5_c_make_random_key(context, eblock->crypto_entry, key)))
+ free(key);
+
+ *keyblock = key;
+
+ return(ret);
+}
+
+krb5_enctype KRB5_CALLCONV
+krb5_eblock_enctype(krb5_context context, const krb5_encrypt_block *eblock)
+{
+ return(eblock->crypto_entry);
+}
+
+krb5_error_code KRB5_CALLCONV
krb5_use_enctype(krb5_context context, krb5_encrypt_block *eblock,
- krb5_enctype enctype)
+ krb5_enctype enctype)
{
eblock->crypto_entry = enctype;
@@ -57,23 +183,161 @@ krb5_use_enctype(krb5_context context, krb5_encrypt_block *eblock,
}
size_t KRB5_CALLCONV
-krb5_checksum_size(krb5_context context, krb5_cksumtype ctype)
+krb5_encrypt_size(size_t length, krb5_enctype crypto)
{
- size_t ret;
+ size_t ret;
- if (krb5_c_checksum_length(context, ctype, &ret))
- return(-1); /* XXX */
+ if (krb5_c_encrypt_length(/* XXX */ 0, crypto, length, &ret))
+ return(-1); /* XXX */
- return(ret);
+ return(ret);
}
size_t KRB5_CALLCONV
-krb5_encrypt_size(size_t length, krb5_enctype crypto)
+krb5_checksum_size(krb5_context context, krb5_cksumtype ctype)
{
size_t ret;
- if (krb5_c_encrypt_length(/* XXX */ 0, crypto, length, &ret))
- return(-1); /* XXX */
+ if (krb5_c_checksum_length(context, ctype, &ret))
+ return(-1); /* XXX */
+
+ return(ret);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_calculate_checksum(krb5_context context, krb5_cksumtype ctype,
+ krb5_const_pointer in, size_t in_length,
+ krb5_const_pointer seed, size_t seed_length,
+ krb5_checksum *outcksum)
+{
+ krb5_data input;
+ krb5_keyblock key;
+ krb5_error_code ret;
+ krb5_checksum cksum;
+
+ /* Solaris Kerberos */
+ input.data = (char*)in;
+ input.length = in_length;
+
+ key.length = seed_length;
+ /* Solaris Kerberos */
+ key.contents = (unsigned char*)seed;
+
+ if ((ret = krb5_c_make_checksum(context, ctype, &key, 0, &input, &cksum)))
+ return(ret);
+
+ if (outcksum->length < cksum.length) {
+ memset(cksum.contents, 0, cksum.length);
+ free(cksum.contents);
+ return(KRB5_BAD_MSIZE);
+ }
+
+ outcksum->magic = cksum.magic;
+ outcksum->checksum_type = cksum.checksum_type;
+ memcpy(outcksum->contents, cksum.contents, cksum.length);
+ outcksum->length = cksum.length;
+
+ free(cksum.contents);
+
+ return(0);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_verify_checksum(krb5_context context, krb5_cksumtype ctype,
+ const krb5_checksum *cksum, krb5_const_pointer in,
+ size_t in_length, krb5_const_pointer seed,
+ size_t seed_length)
+{
+ krb5_data input;
+ krb5_keyblock key;
+ krb5_error_code ret;
+ krb5_boolean valid;
+
+ /* Solaris Kerberos */
+ input.data = (char*)in;
+ input.length = in_length;
+
+ key.length = seed_length;
+ /* Solaris Kerberos */
+ key.contents = (unsigned char*)seed;
+
+ if ((ret = krb5_c_verify_checksum(context, &key, 0, &input, cksum,
+ &valid)))
+ return(ret);
+
+ if (!valid)
+ return(KRB5KRB_AP_ERR_BAD_INTEGRITY);
+
+ return(0);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_random_confounder(size_t size, krb5_pointer ptr)
+{
+ krb5_data random_data;
+
+ random_data.length = size;
+ random_data.data = ptr;
+
+ return(krb5_c_random_make_octets(/* XXX */ 0, &random_data));
+}
+
+krb5_error_code krb5_encrypt_data(krb5_context context, krb5_keyblock *key,
+ krb5_pointer ivec, krb5_data *data,
+ krb5_enc_data *enc_data)
+{
+ krb5_error_code ret;
+ size_t enclen, blocksize;
+ krb5_data ivecd;
+
+ if ((ret = krb5_c_encrypt_length(context, key->enctype, data->length,
+ &enclen)))
+ return(ret);
+
+ if (ivec) {
+ if ((ret = krb5_c_block_size(context, key->enctype, &blocksize)))
+ return(ret);
+
+ ivecd.length = blocksize;
+ ivecd.data = ivec;
+ }
+
+ enc_data->magic = KV5M_ENC_DATA;
+ enc_data->kvno = 0;
+ enc_data->enctype = key->enctype;
+ enc_data->ciphertext.length = enclen;
+ if ((enc_data->ciphertext.data = malloc(enclen)) == NULL)
+ return(ENOMEM);
+
+ if ((ret = krb5_c_encrypt(context, key, 0, ivec?&ivecd:0, data, enc_data)))
+ free(enc_data->ciphertext.data);
+
+ return(ret);
+}
+
+krb5_error_code krb5_decrypt_data(krb5_context context, krb5_keyblock *key,
+ krb5_pointer ivec, krb5_enc_data *enc_data,
+ krb5_data *data)
+{
+ krb5_error_code ret;
+ krb5_data ivecd;
+ size_t blocksize;
+
+ if (ivec) {
+ if ((ret = krb5_c_block_size(context, key->enctype, &blocksize)))
+ return(ret);
+
+ ivecd.length = blocksize;
+ ivecd.data = ivec;
+ }
+
+ data->length = enc_data->ciphertext.length;
+ if ((data->data = (char *) malloc(data->length)) == NULL)
+ return(ENOMEM);
+
+ if ((ret = krb5_c_decrypt(context, key, 0, ivec?&ivecd:0, enc_data, data)))
+ free(data->data);
+ /* Solaris Kerberos */
return(ret);
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/pbkdf2.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/pbkdf2.c
index 10d65add12..666b04d43c 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/pbkdf2.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/pbkdf2.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/crypto/pbkdf2.c
@@ -15,7 +14,7 @@
* 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
@@ -29,7 +28,7 @@
* 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.
- *
+ *
*
* Implementation of PBKDF2 from RFC 2898.
* Not currently used; likely to be used when we get around to AES support.
@@ -38,10 +37,11 @@
#ifndef _KERNEL
#include <ctype.h>
-#include <k5-int.h>
-#include <hash_provider.h>
+#include "k5-int.h"
+#include "hash_provider.h"
/*
+ * Solaris Kerberos:
* MIT code ripped out, use PBKDF2 algorithm from PKCS#11
* provider.
*/
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/random_to_key.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/random_to_key.c
new file mode 100644
index 0000000000..41f27f5e39
--- /dev/null
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/random_to_key.c
@@ -0,0 +1,75 @@
+/*
+ * COPYRIGHT (c) 2006
+ * The Regents of the University of Michigan
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+
+/*
+ * Create a key given random data. It is assumed that random_key has
+ * already been initialized and random_key->contents have been allocated
+ * with the correct length.
+ */
+#include "k5-int.h"
+#include "etypes.h"
+
+krb5_error_code KRB5_CALLCONV
+krb5_c_random_to_key(krb5_context context, krb5_enctype enctype,
+ krb5_data *random_data, krb5_keyblock *random_key)
+{
+ int i;
+ krb5_error_code ret;
+ const struct krb5_enc_provider *enc;
+
+ if (random_data == NULL || random_key == NULL)
+ return(EINVAL);
+
+ if (random_key->contents == NULL)
+ return(EINVAL);
+
+ for (i=0; i<krb5_enctypes_length; i++) {
+ if (krb5_enctypes_list[i].etype == enctype)
+ break;
+ }
+
+ if (i == krb5_enctypes_length)
+ return(KRB5_BAD_ENCTYPE);
+
+ enc = krb5_enctypes_list[i].enc;
+
+ if (random_key->length != enc->keylength)
+ return(KRB5_BAD_KEYSIZE);
+
+ /* Solaris Kerberos */
+ ret = ((*(enc->make_key))(context, random_data, random_key));
+
+ if (ret) {
+ memset(random_key->contents, 0, random_key->length);
+ }
+
+ return(ret);
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/state.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/state.c
index 42463870e3..4c655f58df 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/state.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/state.c
@@ -1,8 +1,7 @@
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/crypto/state.c
@@ -38,8 +37,8 @@
* krb5_c_init_state and krb5_c_free_state used by clients of the
* Kerberos crypto library.
*/
-#include <k5-int.h>
-#include <etypes.h>
+#include "k5-int.h"
+#include "etypes.h"
krb5_error_code KRB5_CALLCONV
krb5_c_init_state (krb5_context context, const krb5_keyblock *key,
@@ -55,6 +54,7 @@ krb5_c_init_state (krb5_context context, const krb5_keyblock *key,
if (i == krb5_enctypes_length)
return(KRB5_BAD_ENCTYPE);
+ /* Solaris Kerberos */
return (*(krb5_enctypes_list[i].enc->init_state))
(context, key, keyusage, new_state);
}
@@ -73,6 +73,7 @@ krb5_c_free_state (krb5_context context, const krb5_keyblock *key,
if (i == krb5_enctypes_length)
return(KRB5_BAD_ENCTYPE);
- return (*(krb5_enctypes_list[i].enc->free_state))
+ /* Solaris Kerberos */
+ return (*(krb5_enctypes_list[i].enc->free_state))
(context, state);
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/string_to_enctype.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/string_to_enctype.c
index 5a52832f7d..9d3245bf01 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/string_to_enctype.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/string_to_enctype.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -25,8 +24,9 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <etypes.h>
+#include "k5-int.h"
+#include "etypes.h"
+
krb5_error_code KRB5_CALLCONV
krb5_string_to_enctype(char *string, krb5_enctype *enctypep)
{
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/string_to_key.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/string_to_key.c
index eb182f1736..9554a43fa5 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/string_to_key.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/string_to_key.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -30,22 +29,22 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <etypes.h>
+#include "k5-int.h"
+#include "etypes.h"
krb5_error_code KRB5_CALLCONV
krb5_c_string_to_key_with_params(krb5_context context,
- krb5_enctype enctype,
- const krb5_data *string,
- const krb5_data *salt,
- const krb5_data *params,
- krb5_keyblock *key);
+ krb5_enctype enctype,
+ const krb5_data *string,
+ const krb5_data *salt,
+ const krb5_data *params,
+ krb5_keyblock *key);
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
krb5_c_string_to_key(krb5_context context, krb5_enctype enctype,
- const krb5_data *string, const krb5_data *salt,
- krb5_keyblock *key)
+ const krb5_data *string, const krb5_data *salt,
+ krb5_keyblock *key)
{
return krb5_c_string_to_key_with_params(context, enctype, string, salt,
NULL, key);
@@ -53,7 +52,7 @@ krb5_c_string_to_key(krb5_context context, krb5_enctype enctype,
krb5_error_code KRB5_CALLCONV
krb5_c_string_to_key_with_params(krb5_context context, krb5_enctype enctype,
- const krb5_data *string,
+ const krb5_data *string,
const krb5_data *salt,
const krb5_data *params, krb5_keyblock *key)
{
@@ -64,7 +63,7 @@ krb5_c_string_to_key_with_params(krb5_context context, krb5_enctype enctype,
for (i=0; i<krb5_enctypes_length; i++) {
if (krb5_enctypes_list[i].etype == enctype)
- break;
+ break;
}
if (i == krb5_enctypes_length)
@@ -72,21 +71,21 @@ krb5_c_string_to_key_with_params(krb5_context context, krb5_enctype enctype,
enc = krb5_enctypes_list[i].enc;
/* xxx AFS string2key function is indicated by a special length in
-* the salt in much of the code. However only the DES enctypes can
-* deal with this. Using s2kparams would be a much better solution.*/
+ * the salt in much of the code. However only the DES enctypes can
+ * deal with this. Using s2kparams would be a much better solution.*/
if (salt && salt->length == SALT_TYPE_AFS_LENGTH) {
- switch (enctype) {
- case ENCTYPE_DES_CBC_CRC:
- case ENCTYPE_DES_CBC_MD4:
- case ENCTYPE_DES_CBC_MD5:
- break;
- default:
- return (KRB5_CRYPTO_INTERNAL);
- }
+ switch (enctype) {
+ case ENCTYPE_DES_CBC_CRC:
+ case ENCTYPE_DES_CBC_MD4:
+ case ENCTYPE_DES_CBC_MD5:
+ break;
+ default:
+ return (KRB5_CRYPTO_INTERNAL);
+ }
}
-
- keybytes = enc->keybytes;
- keylength = enc->keylength;
+
+ keybytes = enc->keybytes;
+ keylength = enc->keylength;
if ((key->contents = (krb5_octet *) malloc(keylength)) == NULL)
return(ENOMEM);
@@ -94,14 +93,17 @@ krb5_c_string_to_key_with_params(krb5_context context, krb5_enctype enctype,
key->magic = KV5M_KEYBLOCK;
key->enctype = enctype;
key->length = keylength;
+ /* Solaris Kerberos */
key->dk_list = NULL;
key->hKey = CK_INVALID_HANDLE;
+ /* Solaris Kerberos */
ret = (*krb5_enctypes_list[i].str2key)(context, enc, string, salt,
params, key);
if (ret) {
memset(key->contents, 0, keylength);
free(key->contents);
+ /* Solaris Kerberos */
key->contents = NULL;
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/crypto/valid_enctype.c b/usr/src/lib/gss_mechs/mech_krb5/crypto/valid_enctype.c
index 88ea50d0cc..d44cd0f7af 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/valid_enctype.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/valid_enctype.c
@@ -1,20 +1,19 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* 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
@@ -25,14 +24,14 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <etypes.h>
+#include "k5-int.h"
+#include "etypes.h"
krb5_boolean KRB5_CALLCONV
krb5_c_valid_enctype(krb5_enctype etype)
diff --git a/usr/src/lib/gss_mechs/mech_krb5/et/com_err.c b/usr/src/lib/gss_mechs/mech_krb5/et/com_err.c
index b6b3dfc04e..1f612f9755 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/et/com_err.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/et/com_err.c
@@ -3,11 +3,10 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1997 by Massachusetts Institute of Technology
- *
+ *
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
* Permission to use, copy, modify, and distribute this software
@@ -26,26 +25,34 @@
* provided "as is" without express or implied warranty.
*/
-
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include <locale.h>
#include "com_err.h"
#include "error_table.h"
-#if defined(_MSDOS) || defined(_WIN32)
+#if defined(_WIN32)
#include <io.h>
#endif
-#ifdef macintosh
-#include "icons.h"
-static void MacMessageBox(char *errbuf);
-#endif
+
+k5_mutex_t com_err_hook_lock = K5_MUTEX_PARTIAL_INITIALIZER;
static void default_com_err_proc
(const char *whoami, errcode_t code,
const char *fmt, va_list ap);
+#if defined(_WIN32)
+BOOL isGuiApp() {
+ DWORD mypid;
+ HANDLE myprocess;
+ mypid = GetCurrentProcessId();
+ myprocess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, mypid);
+ return GetGuiResources(myprocess, 1) > 0;
+ }
+#endif
+
/*
* Solaris Kerberos:
* It is sometimes desirable to have more than a single hook called
@@ -136,11 +143,9 @@ my_gettext(int msg_idx)
/* Solaris Kerberos: this code is significantly altered from
* the MIT 1.2.1 version to work with internationalization */
-static void default_com_err_proc(whoami, code, fmt, ap)
- const char *whoami;
- errcode_t code;
- const char *fmt;
- va_list ap;
+
+static void default_com_err_proc (const char *whoami, errcode_t code,
+ const char *fmt, va_list ap)
{
char whilebuf[1024] = "";
@@ -209,49 +214,70 @@ static void default_com_err_proc(whoami, code, fmt, ap)
fflush(stderr);
}
-void KRB5_CALLCONV com_err_va(whoami, code, fmt, ap)
- const char *whoami;
- errcode_t code;
- const char *fmt;
- va_list ap;
+void KRB5_CALLCONV com_err_va(const char *whoami,
+ errcode_t code,
+ const char *fmt,
+ va_list ap)
{
- int i;
-
- for (i = 0; i < hook_count; i++) {
- (com_err_hook[i])(whoami, code, fmt, ap);
- }
+ int err;
+ int i;
+ err = com_err_finish_init();
+ if (err)
+ goto best_try;
+ err = k5_mutex_lock(&com_err_hook_lock);
+ if (err)
+ goto best_try;
+ for (i = 0; i < hook_count; i++) {
+ (com_err_hook[i])(whoami, code, fmt, ap);
+ }
+ k5_mutex_unlock(&com_err_hook_lock);
+ return;
+
+best_try:
+ /* Yikes. Our library initialization failed or we couldn't lock
+ the lock we want. We could be in trouble. Gosh, we should
+ probably print an error message. Oh, wait. That's what we're
+ trying to do. In fact, if we're losing on initialization here,
+ there's a good chance it has to do with failed initialization
+ of the caller. */
+
+ for (i = 0; i < hook_count; i++) {
+ (com_err_hook[i])(whoami, code, fmt, ap);
+ }
+ assert(err == 0);
+ abort();
}
-#ifndef ET_VARARGS
-void KRB5_CALLCONV_C com_err(const char *whoami,
- errcode_t code,
- const char *fmt, ...)
-#else
-void KRB5_CALLCONV_C com_err(whoami, code, fmt, va_alist)
- const char *whoami;
- errcode_t code;
- const char *fmt;
- va_dcl
-#endif
+void KRB5_CALLCONV_C com_err(const char *whoami,
+ errcode_t code,
+ const char *fmt, ...)
{
va_list ap;
-#ifdef ET_VARARGS
- va_start(ap);
-#else
va_start(ap, fmt);
-#endif
com_err_va(whoami, code, fmt, ap);
va_end(ap);
}
-#if !(defined(_MSDOS)||defined(_WIN32))
-et_old_error_hook_func set_com_err_hook (new_proc)
- et_old_error_hook_func new_proc;
+/* Make a separate function because the assert invocations below
+ use the macro expansion on some platforms, which may be insanely
+ long and incomprehensible. */
+static int com_err_lock_hook_handle(void)
+{
+ return k5_mutex_lock(&com_err_hook_lock);
+}
+
+et_old_error_hook_func set_com_err_hook (et_old_error_hook_func new_proc)
{
int i;
- et_old_error_hook_func x = com_err_hook[0];
+ et_old_error_hook_func x;
+
+ /* Broken initialization? What can we do? */
+ assert(com_err_finish_init() == 0);
+ assert(com_err_lock_hook_handle() == 0);
+
+ x = com_err_hook[0];
for (i = 0; i < hook_count; i++)
com_err_hook[i] = NULL;
@@ -259,23 +285,27 @@ et_old_error_hook_func set_com_err_hook (new_proc)
com_err_hook[0] = new_proc;
hook_count = 1;
+ k5_mutex_unlock(&com_err_hook_lock);
return x;
}
et_old_error_hook_func reset_com_err_hook ()
{
int i;
- et_old_error_hook_func x = com_err_hook[0];
+ et_old_error_hook_func x;
+ /* Broken initialization? What can we do? */
+ assert(com_err_finish_init() == 0);
+ assert(com_err_lock_hook_handle() == 0);
+ x = com_err_hook[0];
for (i = 0; i < hook_count; i++)
com_err_hook[i] = NULL;
com_err_hook[0] = default_com_err_proc;
hook_count = 1;
-
+ k5_mutex_unlock(&com_err_hook_lock);
return x;
}
-#endif
/*
* Solaris Kerberos:
diff --git a/usr/src/lib/gss_mechs/mech_krb5/et/internal.h b/usr/src/lib/gss_mechs/mech_krb5/et/internal.h
index 27b329012a..57b5cd58e5 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/et/internal.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/et/internal.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* internal include file for com_err package
*/
@@ -11,6 +10,6 @@ extern char const * const sys_errlist[];
extern const int sys_nerr;
#endif
-#if defined(__STDC__) && !defined(HDR_HAS_PERROR) && !defined(_MSDOS) && !defined(WIN32)
+#if defined(__STDC__) && !defined(HDR_HAS_PERROR) && !defined(WIN32)
void perror (const char *);
#endif
diff --git a/usr/src/lib/gss_mechs/mech_krb5/et/krb5_err.c b/usr/src/lib/gss_mechs/mech_krb5/et/krb5_err.c
index f9017f813d..951a5b6e63 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/et/krb5_err.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/et/krb5_err.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include <locale.h>
#include <security/cryptoki.h>
@@ -102,7 +101,8 @@ switch (errorno) {
"KRB5 error code 28"));
case 29:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 29"));
+ "A service is not available that is required to "
+ "process the request"));
case 30:
return (dgettext(TEXT_DOMAIN,
"KRB5 error code 30"));
@@ -168,10 +168,10 @@ switch (errorno) {
"Inappropriate type of checksum in message"));
case 51:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 51"));
+ "Policy rejects transited path"));
case 52:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 52"));
+ "Response too big for UDP, retry with TCP"));
case 53:
return (dgettext(TEXT_DOMAIN,
"KRB5 error code 53"));
@@ -201,19 +201,19 @@ switch (errorno) {
"Field is too long for this implementation"));
case 62:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 62"));
+ "Client not trusted"));
case 63:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 63"));
+ "KDC not trusted"));
case 64:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 64"));
+ "Invalid signature"));
case 65:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 65"));
+ "Key parameters not accepted"));
case 66:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 66"));
+ "Certificate mismatch"));
case 67:
return (dgettext(TEXT_DOMAIN,
"KRB5 error code 67"));
@@ -225,40 +225,40 @@ switch (errorno) {
"KRB5 error code 69"));
case 70:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 70"));
+ "Can't verify certificate"));
case 71:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 71"));
+ "Invalid certificate"));
case 72:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 72"));
+ "Revoked certificate"));
case 73:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 73"));
+ "Revocation status unknown"));
case 74:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 74"));
+ "Revocation status unavailable"));
case 75:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 75"));
+ "Client name mismatch"));
case 76:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 76"));
+ "KDC name mismatch"));
case 77:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 77"));
+ "Inconsistent key purpose"));
case 78:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 78"));
+ "Digest in certificate not accepted"));
case 79:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 79"));
+ "Checksum must be included"));
case 80:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 80"));
+ "Digest in signed-data not accepted"));
case 81:
return (dgettext(TEXT_DOMAIN,
- "KRB5 error code 81"));
+ "Public key encryption not supported"));
case 82:
return (dgettext(TEXT_DOMAIN,
"KRB5 error code 82"));
diff --git a/usr/src/lib/gss_mechs/mech_krb5/et/mit-sipb-copyright.h b/usr/src/lib/gss_mechs/mech_krb5/et/mit-sipb-copyright.h
index d02d196bbb..d7c4ee096e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/et/mit-sipb-copyright.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/et/mit-sipb-copyright.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
Copyright 1987, 1988 by the Student Information Processing Board
@@ -12,6 +11,9 @@ this permission notice appear in supporting documentation,
and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
+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. and the M.I.T. S.I.P.B. make no representations about
the suitability of this software for any purpose. It is
provided "as is" without express or implied warranty.
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/autoconf.h b/usr/src/lib/gss_mechs/mech_krb5/include/autoconf.h
index 9266877ca7..932ed0c842 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/include/autoconf.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/autoconf.h
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/* autoconf.h. Generated automatically by configure. */
/* autoconf.h.in. Generated automatically from configure.in by autoheader. */
/* Edited to remove KRB4 compatible and SIZEOF_LONG
@@ -50,6 +49,23 @@
#define KRB5_USE_INET 1
#define KRB5_USE_INET6 1
+/* Solaris Kerberos - 163 Resync */
+#define LIBDIR "/usr/lib"
+
+/* Type of getpeername second argument. */
+#define GETPEERNAME_ARG2_TYPE GETSOCKNAME_ARG2_TYPE
+
+/* Type of getpeername second argument. */
+#define GETPEERNAME_ARG3_TYPE GETSOCKNAME_ARG3_TYPE
+
+/* Type of pointer target for argument 2 to getsockname */
+#define GETSOCKNAME_ARG2_TYPE struct sockaddr
+
+/* Type of pointer target for argument 3 to getsockname */
+#define GETSOCKNAME_ARG3_TYPE socklen_t
+
+#define HAVE_GETEUID 1
+
/* Define if you have the getaddrinfo function */
#define HAVE_GETADDRINFO 1
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/cache-addrinfo.h b/usr/src/lib/gss_mechs/mech_krb5/include/cache-addrinfo.h
new file mode 100644
index 0000000000..685a166327
--- /dev/null
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/cache-addrinfo.h
@@ -0,0 +1,129 @@
+
+/*
+ * Copyright (C) 2004 by the Massachusetts Institute of Technology,
+ * Cambridge, MA, USA. All Rights Reserved.
+ *
+ * This software is being provided to you, the LICENSEE, by the
+ * Massachusetts Institute of Technology (M.I.T.) under the following
+ * license. By obtaining, using and/or copying this software, you agree
+ * that you have read, understood, and will comply with these terms and
+ * conditions:
+ *
+ * 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 or
+ * royalty is hereby granted, provided that you agree to comply with the
+ * following copyright notice and statements, including the disclaimer, and
+ * that the same appear on ALL copies of the software and documentation,
+ * including modifications that you make for internal use or for
+ * distribution:
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS
+ * OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not
+ * limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF
+ * MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
+ * THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
+ * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+ *
+ * The name of the Massachusetts Institute of Technology or M.I.T. may NOT
+ * be used in advertising or publicity pertaining to distribution of the
+ * software. Title to copyright in this software and any associated
+ * documentation shall at all times remain with M.I.T., and USER agrees to
+ * preserve same.
+ *
+ * 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.
+ */
+
+/* Approach overview:
+
+ If a system version is available but buggy, save handles to it,
+ redefine the names to refer to static functions defined here, and
+ in those functions, call the system versions and fix up the
+ returned data. Use the native data structures and flag values.
+
+ If no system version exists, use gethostby* and fake it. Define
+ the data structures and flag values locally.
+
+
+ On Mac OS X, getaddrinfo results aren't cached (though
+ gethostbyname results are), so we need to build a cache here. Now
+ things are getting really messy. Because the cache is in use, we
+ use getservbyname, and throw away thread safety. (Not that the
+ cache is thread safe, but when we get locking support, that'll be
+ dealt with.) This code needs tearing down and rebuilding, soon.
+
+
+ Note that recent Windows developers' code has an interesting hack:
+ When you include the right header files, with the right set of
+ macros indicating system versions, you'll get an inline function
+ that looks for getaddrinfo (or whatever) in the system library, and
+ calls it if it's there. If it's not there, it fakes it with
+ gethostby* calls.
+
+ We're taking a simpler approach: A system provides these routines or
+ it does not.
+
+ Someday, we may want to take into account different versions (say,
+ different revs of GNU libc) where some are broken in one way, and
+ some work or are broken in another way. Cross that bridge when we
+ come to it. */
+
+/* To do, maybe:
+
+ + For AIX 4.3.3, using the RFC 2133 definition: Implement
+ AI_NUMERICHOST. It's not defined in the header file.
+
+ For certain (old?) versions of GNU libc, AI_NUMERICHOST is
+ defined but not implemented.
+
+ + Use gethostbyname2, inet_aton and other IPv6 or thread-safe
+ functions if available. But, see
+ http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=135182 for one
+ gethostbyname2 problem on Linux. And besides, if a platform is
+ supporting IPv6 at all, they really should be doing getaddrinfo
+ by now.
+
+ + inet_ntop, inet_pton
+
+ + Conditionally export/import the function definitions, so a
+ library can have a single copy instead of multiple.
+
+ + Upgrade host requirements to include working implementations of
+ these functions, and throw all this away. Pleeease? :-) */
+
+#include "port-sockets.h"
+#include "socket-utils.h"
+#include "k5-platform.h"
+#include "k5-thread.h"
+
+#include "fake-addrinfo.h"
+
+#if defined (__APPLE__) && defined (__MACH__)
+#define FAI_CACHE
+#endif
+
+struct face {
+ struct in_addr *addrs4;
+ struct in6_addr *addrs6;
+ unsigned int naddrs4, naddrs6;
+ time_t expiration;
+ char *canonname, *name;
+ struct face *next;
+};
+
+/* fake addrinfo cache */
+struct fac {
+ k5_mutex_t lock;
+ struct face *data;
+};
+
+extern struct fac krb5int_fac;
+
+extern int krb5int_init_fac (void);
+extern void krb5int_fini_fac (void);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/cm.h b/usr/src/lib/gss_mechs/mech_krb5/include/cm.h
index 6007790c63..716e6cb593 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/include/cm.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/cm.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* include/cm.h
*
@@ -25,16 +24,60 @@
* or implied warranty.
*/
+/* Since fd_set is large on some platforms (8K on AIX 5.2), this
+ probably shouldn't be allocated in automatic storage. */
struct select_state {
int max, nfds;
fd_set rfds, wfds, xfds;
struct timeval end_time; /* magic: tv_sec==0 => never time out */
};
+
/* Select state flags. */
#define SSF_READ 0x01
#define SSF_WRITE 0x02
#define SSF_EXCEPTION 0x04
+
+static const char *const state_strings[] = {
+ "INITIALIZING", "CONNECTING", "WRITING", "READING", "FAILED"
+};
+
+
+/* connection states */
+enum conn_states { INITIALIZING, CONNECTING, WRITING, READING, FAILED };
+struct incoming_krb5_message {
+ size_t bufsizebytes_read;
+ size_t bufsize;
+ char *buf;
+ char *pos;
+ unsigned char bufsizebytes[4];
+ size_t n_left;
+};
+struct conn_state {
+ SOCKET fd;
+ krb5_error_code err;
+ enum conn_states state;
+ unsigned int is_udp : 1;
+ int (*service)(struct conn_state *, struct select_state *, int);
+ struct addrinfo *addr;
+ struct {
+ struct {
+ sg_buf sgbuf[2];
+ sg_buf *sgp;
+ int sg_count;
+ unsigned char msg_len_buf[4];
+ } out;
+ struct incoming_krb5_message in;
+ } x;
+};
+
+struct sendto_callback_info {
+ int (*pfn_callback) (struct conn_state *, void *, krb5_data *);
+ void (*pfn_cleanup) (void *, krb5_data *);
+ void *context;
+};
+
+
krb5_error_code krb5int_cm_call_select (const struct select_state *,
struct select_state *, int *);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/db.h b/usr/src/lib/gss_mechs/mech_krb5/include/db.h
index 2b74608be6..ad86d0af9c 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/include/db.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/db.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
@@ -79,7 +78,7 @@ typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
* is so that the access methods can skip copying the key/data pair when
* the DB_LOCK flag isn't set.
*/
-#if SIZEOF_INT == 4
+#if UINT_MAX >= 0xffffffffUL
#define DB_LOCK 0x20000000 /* Do locking. */
#define DB_SHMEM 0x40000000 /* Use shared memory. */
#define DB_TXN 0x80000000 /* Do transactions. */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/fake-addrinfo.h b/usr/src/lib/gss_mechs/mech_krb5/include/fake-addrinfo.h
index dbc03de925..952b43f0bf 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/include/fake-addrinfo.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/fake-addrinfo.h
@@ -42,10 +42,10 @@
/* Approach overview:
If a system version is available but buggy, save handles to it (via
- inline functions), redefine the names to refer to static functions
- defined here, and in those functions, call the system versions and
- fix up the returned data. Use the native data structures and flag
- values.
+ inline functions in a support library), redefine the names to refer
+ to library functions, and in those functions, call the system
+ versions and fix up the returned data. Use the native data
+ structures and flag values.
If no system version exists, use gethostby* and fake it. Define
the data structures and flag values locally.
@@ -99,253 +99,11 @@
#ifndef FAI_DEFINED
#define FAI_DEFINED
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "port-sockets.h"
#include "socket-utils.h"
-#include "k5-platform.h"
-#include "k5-thread.h"
-
-#include <stdio.h> /* for sprintf */
-#include <errno.h>
-
-#ifdef S_SPLINT_S
-/*@-incondefs@*/
-extern int
-getaddrinfo (/*@in@*/ /*@null@*/ const char *,
- /*@in@*/ /*@null@*/ const char *,
- /*@in@*/ /*@null@*/ const struct addrinfo *,
- /*@out@*/ struct addrinfo **)
- ;
-extern void
-freeaddrinfo (/*@only@*/ /*@out@*/ struct addrinfo *)
- ;
-extern int
-getnameinfo (const struct sockaddr *addr, socklen_t addrsz,
- /*@out@*/ /*@null@*/ char *h, socklen_t hsz,
- /*@out@*/ /*@null@*/ char *s, socklen_t ssz,
- int flags)
- /*@requires (maxSet(h)+1) >= hsz /\ (maxSet(s)+1) >= ssz @*/
- /* too hard: maxRead(addr) >= (addrsz-1) */
- /*@modifies *h, *s@*/;
-extern /*@dependent@*/ char *gai_strerror (int code) /*@*/;
-/*@=incondefs@*/
-#endif
-
-
-#if defined (__APPLE__) && defined (__MACH__)
-#define FAI_CACHE
-#endif
-
-#if (defined (__linux__) && defined(HAVE_GETADDRINFO)) || defined (_AIX)
-/* See comments below. */
-# define WRAP_GETADDRINFO
-#endif
-
-#if defined (__linux__) && defined(HAVE_GETADDRINFO)
-# define COPY_FIRST_CANONNAME
-#endif
-
-#ifdef _AIX
-# define NUMERIC_SERVICE_BROKEN
-# define COPY_FIRST_CANONNAME
-#endif
-
-
-#ifdef COPY_FIRST_CANONNAME
-# include <string.h>
-#endif
-
-#ifdef NUMERIC_SERVICE_BROKEN
-# include <ctype.h> /* isdigit */
-# include <stdlib.h> /* strtoul */
-#endif
-
-#ifdef _WIN32
-#define HAVE_GETADDRINFO 1
-#define HAVE_GETNAMEINFO 1
-#endif
-
-
-/* Do we actually have *any* systems we care about that don't provide
- either getaddrinfo or one of these two flavors of
- gethostbyname_r? */
-#if !defined(HAVE_GETHOSTBYNAME_R) || defined(THREADSAFE_GETHOSTBYNAME)
-#define GET_HOST_BY_NAME(NAME, HP, ERR) \
- { (HP) = gethostbyname (NAME); (ERR) = h_errno; }
-#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \
- { (HP) = gethostbyaddr ((ADDR), (ADDRLEN), (FAMILY)); (ERR) = h_errno; }
-#else
-#ifdef _AIX /* XXX should have a feature test! */
-#define GET_HOST_BY_NAME(NAME, HP, ERR) \
- { \
- struct hostent my_h_ent; \
- struct hostent_data my_h_ent_data; \
- (HP) = (gethostbyname_r((NAME), &my_h_ent, &my_h_ent_data) \
- ? 0 \
- : &my_h_ent); \
- (ERR) = h_errno; \
- }
-/*
-#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \
- { \
- struct hostent my_h_ent; \
- struct hostent_data my_h_ent_data; \
- (HP) = (gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &my_h_ent, \
- &my_h_ent_data) \
- ? 0 \
- : &my_h_ent); \
- (ERR) = my_h_err; \
- }
-*/
-#else
-#ifdef GETHOSTBYNAME_R_RETURNS_INT
-#define GET_HOST_BY_NAME(NAME, HP, ERR) \
- { \
- struct hostent my_h_ent, *my_hp; \
- int my_h_err; \
- char my_h_buf[8192]; \
- (HP) = (gethostbyname_r((NAME), &my_h_ent, \
- my_h_buf, sizeof (my_h_buf), &my_hp, \
- &my_h_err) \
- ? 0 \
- : &my_h_ent); \
- (ERR) = my_h_err; \
- }
-#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \
- { \
- struct hostent my_h_ent, *my_hp; \
- int my_h_err; \
- char my_h_buf[8192]; \
- (HP) = (gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &my_h_ent, \
- my_h_buf, sizeof (my_h_buf), &my_hp, \
- &my_h_err) \
- ? 0 \
- : &my_h_ent); \
- (ERR) = my_h_err; \
- }
-#else
-#define GET_HOST_BY_NAME(NAME, HP, ERR) \
- { \
- struct hostent my_h_ent; \
- int my_h_err; \
- char my_h_buf[8192]; \
- (HP) = gethostbyname_r((NAME), &my_h_ent, \
- my_h_buf, sizeof (my_h_buf), &my_h_err); \
- (ERR) = my_h_err; \
- }
-#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \
- { \
- struct hostent my_h_ent; \
- int my_h_err; \
- char my_h_buf[8192]; \
- (HP) = gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &my_h_ent, \
- my_h_buf, sizeof (my_h_buf), &my_h_err); \
- (ERR) = my_h_err; \
- }
-#endif /* returns int? */
-#endif /* _AIX */
-#endif
-
-/* Now do the same for getservby* functions. */
-#ifndef HAVE_GETSERVBYNAME_R
-#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR) \
- ((SP) = getservbyname (NAME, PROTO), (ERR) = (SP) ? 0 : -1)
-#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR) \
- ((SP) = getservbyport (PORT, PROTO), (ERR) = (SP) ? 0 : -1)
-#else
-#ifdef GETSERVBYNAME_R_RETURNS_INT
-#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR) \
- { \
- struct servent my_s_ent, *my_sp; \
- int my_s_err; \
- char my_s_buf[8192]; \
- (SP) = (getservbyname_r((NAME), (PROTO), &my_s_ent, \
- my_s_buf, sizeof (my_s_buf), &my_sp, \
- &my_s_err) \
- ? 0 \
- : &my_s_ent); \
- (ERR) = my_s_err; \
- }
-#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR) \
- { \
- struct servent my_s_ent, *my_sp; \
- int my_s_err; \
- char my_s_buf[8192]; \
- (SP) = (getservbyport_r((PORT), (PROTO), &my_s_ent, \
- my_s_buf, sizeof (my_s_buf), &my_sp, \
- &my_s_err) \
- ? 0 \
- : &my_s_ent); \
- (ERR) = my_s_err; \
- }
-#else
-/* returns ptr -- IRIX? */
-#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR) \
- { \
- struct servent my_s_ent; \
- char my_s_buf[8192]; \
- (SP) = getservbyname_r((NAME), (PROTO), &my_s_ent, \
- my_s_buf, sizeof (my_s_buf)); \
- (ERR) = (SP) == NULL; \
- }
-
-#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR) \
- { \
- struct servent my_s_ent, *my_sp; \
- char my_s_buf[8192]; \
- my_sp = getservbyport_r((PORT), (PROTO), &my_s_ent, \
- my_s_buf, sizeof (my_s_buf)); \
- (SP) = my_sp; \
- (ERR) = my_sp == 0; \
- (ERR) = (ERR); /* avoid "unused" warning */ \
- }
-#endif
-#endif
-
-#if defined(WRAP_GETADDRINFO) || defined(FAI_CACHE)
-static inline int
-system_getaddrinfo (const char *name, const char *serv,
- const struct addrinfo *hint,
- struct addrinfo **res)
-{
- return getaddrinfo(name, serv, hint, res);
-}
-
-static inline void
-system_freeaddrinfo (struct addrinfo *ai)
-{
- freeaddrinfo(ai);
-}
-
-/* Note: Implementations written to RFC 2133 use size_t, while RFC
- 2553 implementations use socklen_t, for the second parameter.
-
- Mac OS X (10.2) and AIX 4.3.3 appear to be in the RFC 2133 camp,
- but we don't have an autoconf test for that right now. */
-static inline int
-system_getnameinfo (const struct sockaddr *sa, socklen_t salen,
- char *host, size_t hostlen, char *serv, size_t servlen,
- int flags)
-{
- return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
-}
-#endif
-
-#if !defined (HAVE_GETADDRINFO) || defined(WRAP_GETADDRINFO) || defined(FAI_CACHE)
-
-#undef getaddrinfo
-#define getaddrinfo my_fake_getaddrinfo
-#undef freeaddrinfo
-#define freeaddrinfo my_fake_freeaddrinfo
-
-#endif
#if !defined (HAVE_GETADDRINFO)
-#undef gai_strerror
-#define gai_strerror my_fake_gai_strerror
#undef addrinfo
#define addrinfo my_fake_addrinfo
@@ -423,144 +181,6 @@ struct addrinfo {
#endif /* ! HAVE_GETADDRINFO */
-#if (!defined (HAVE_GETADDRINFO) || defined (WRAP_GETADDRINFO)) && defined(DEBUG_ADDRINFO)
-/* Some debug routines. */
-
-static const char *protoname (int p, char *buf) {
-#define X(N) if (p == IPPROTO_ ## N) return #N
-
- X(TCP);
- X(UDP);
- X(ICMP);
- X(IPV6);
-#ifdef IPPROTO_GRE
- X(GRE);
-#endif
- X(NONE);
- X(RAW);
-#ifdef IPPROTO_COMP
- X(COMP);
-#endif
-
- sprintf(buf, " %-2d", p);
- return buf;
-}
-
-static const char *socktypename (int t, char *buf) {
- switch (t) {
- case SOCK_DGRAM: return "DGRAM";
- case SOCK_STREAM: return "STREAM";
- case SOCK_RAW: return "RAW";
- case SOCK_RDM: return "RDM";
- case SOCK_SEQPACKET: return "SEQPACKET";
- }
- sprintf(buf, " %-2d", t);
- return buf;
-}
-
-static const char *familyname (int f, char *buf) {
- switch (f) {
- default:
- sprintf(buf, "AF %d", f);
- return buf;
- case AF_INET: return "AF_INET";
- case AF_INET6: return "AF_INET6";
-#ifdef AF_UNIX
- case AF_UNIX: return "AF_UNIX";
-#endif
- }
-}
-
-static void debug_dump_getaddrinfo_args (const char *name, const char *serv,
- const struct addrinfo *hint)
-{
- const char *sep;
- fprintf(stderr,
- "getaddrinfo(hostname %s, service %s,\n"
- " hints { ",
- name ? name : "(null)", serv ? serv : "(null)");
- if (hint) {
- char buf[30];
- sep = "";
-#define Z(FLAG) if (hint->ai_flags & AI_##FLAG) fprintf(stderr, "%s%s", sep, #FLAG), sep = "|"
- Z(CANONNAME);
- Z(PASSIVE);
-#ifdef AI_NUMERICHOST
- Z(NUMERICHOST);
-#endif
- if (sep[0] == 0)
- fprintf(stderr, "no-flags");
- if (hint->ai_family)
- fprintf(stderr, " %s", familyname(hint->ai_family, buf));
- if (hint->ai_socktype)
- fprintf(stderr, " SOCK_%s", socktypename(hint->ai_socktype, buf));
- if (hint->ai_protocol)
- fprintf(stderr, " IPPROTO_%s", protoname(hint->ai_protocol, buf));
- } else
- fprintf(stderr, "(null)");
- fprintf(stderr, " }):\n");
-}
-
-static void debug_dump_error (int err)
-{
- fprintf(stderr, "error %d: %s\n", err, gai_strerror(err));
-}
-
-static void debug_dump_addrinfos (const struct addrinfo *ai)
-{
- int count = 0;
- fprintf(stderr, "addrinfos returned:\n");
- while (ai) {
- fprintf(stderr, "%p...", ai);
- fprintf(stderr, " socktype=%s", socktypename(ai->ai_socktype));
- fprintf(stderr, " ai_family=%s", familyname(ai->ai_family));
- if (ai->ai_family != ai->ai_addr->sa_family)
- fprintf(stderr, " sa_family=%s",
- familyname(ai->ai_addr->sa_family));
- fprintf(stderr, "\n");
- ai = ai->ai_next;
- count++;
- }
- fprintf(stderr, "end addrinfos returned (%d)\n");
-}
-
-#endif
-
-#if !defined (HAVE_GETADDRINFO) || defined (WRAP_GETADDRINFO)
-
-static
-int getaddrinfo (const char *name, const char *serv,
- const struct addrinfo *hint, struct addrinfo **result);
-
-static
-void freeaddrinfo (struct addrinfo *ai);
-
-#endif
-
-#if !defined (HAVE_GETADDRINFO)
-
-#define HAVE_FAKE_GETADDRINFO /* was not originally HAVE_GETADDRINFO */
-#define HAVE_GETADDRINFO
-#define NEED_FAKE_GETNAMEINFO
-#undef HAVE_GETNAMEINFO
-#define HAVE_GETNAMEINFO 1
-
-#undef getnameinfo
-#define getnameinfo my_fake_getnameinfo
-
-static
-char *gai_strerror (int code);
-
-#endif
-
-#if !defined (HAVE_GETADDRINFO)
-static
-int getnameinfo (const struct sockaddr *addr, socklen_t len,
- char *host, socklen_t hostlen,
- char *service, socklen_t servicelen,
- int flags);
-#endif
-
/* Fudge things on older gai implementations. */
/* AIX 4.3.3 is based on RFC 2133; no AI_NUMERICHOST. */
#ifndef AI_NUMERICHOST
@@ -582,790 +202,32 @@ int getnameinfo (const struct sockaddr *addr, socklen_t len,
# define AI_DEFAULT (AI_ADDRCONFIG|AI_V4MAPPED)
#endif
-#if defined(HAVE_FAKE_GETADDRINFO) || defined(FAI_CACHE)
-#define NEED_FAKE_GETADDRINFO
-#endif
-
-#if defined(NEED_FAKE_GETADDRINFO) || defined(WRAP_GETADDRINFO)
-#include <stdlib.h>
-#endif
-
-struct face {
- struct in_addr *addrs4;
- struct in6_addr *addrs6;
- unsigned int naddrs4, naddrs6;
- time_t expiration;
- char *canonname, *name;
- struct face *next;
-};
-
-/* fake addrinfo cache */
-struct fac {
- k5_mutex_t lock;
- struct face *data;
-};
-extern struct fac krb5int_fac;
-
-#ifdef NEED_FAKE_GETADDRINFO
-#include <string.h> /* for strspn */
-
-static inline int translate_h_errno (int h);
-
-static inline int fai_add_entry (struct addrinfo **result, void *addr,
- int port, const struct addrinfo *template)
-{
- struct addrinfo *n = malloc (sizeof (struct addrinfo));
- if (n == 0)
- return EAI_MEMORY;
- if (template->ai_family != AF_INET
-#ifdef KRB5_USE_INET6
- && template->ai_family != AF_INET6
-#endif
- )
- return EAI_FAMILY;
- *n = *template;
- if (template->ai_family == AF_INET) {
- struct sockaddr_in *sin4;
- sin4 = malloc (sizeof (struct sockaddr_in));
- if (sin4 == 0)
- return EAI_MEMORY;
- n->ai_addr = (struct sockaddr *) sin4;
- sin4->sin_family = AF_INET;
- sin4->sin_addr = *(struct in_addr *)addr;
- sin4->sin_port = port;
-#ifdef HAVE_SA_LEN
- sin4->sin_len = sizeof (struct sockaddr_in);
-#endif
- }
-#ifdef KRB5_USE_INET6
- if (template->ai_family == AF_INET6) {
- struct sockaddr_in6 *sin6;
- sin6 = malloc (sizeof (struct sockaddr_in6));
- if (sin6 == 0)
- return EAI_MEMORY;
- n->ai_addr = (struct sockaddr *) sin6;
- sin6->sin6_family = AF_INET6;
- sin6->sin6_addr = *(struct in6_addr *)addr;
- sin6->sin6_port = port;
-#ifdef HAVE_SA_LEN
- sin6->sin6_len = sizeof (struct sockaddr_in6);
-#endif
- }
-#endif
- n->ai_next = *result;
- *result = n;
- return 0;
-}
-
-#ifdef FAI_CACHE
-/* fake addrinfo cache entries */
-#define CACHE_ENTRY_LIFETIME 15 /* seconds */
-
-static void plant_face (const char *name, struct face *entry)
-{
- entry->name = strdup(name);
- if (entry->name == NULL)
- /* @@ Wastes memory. */
- return;
- k5_mutex_assert_locked(&krb5int_fac.lock);
- entry->next = krb5int_fac.data;
- entry->expiration = time(0) + CACHE_ENTRY_LIFETIME;
- krb5int_fac.data = entry;
-#ifdef DEBUG_ADDRINFO
- printf("added cache entry '%s' at %p: %d ipv4, %d ipv6; expire %d\n",
- name, entry, entry->naddrs4, entry->naddrs6, entry->expiration);
-#endif
-}
-
-static int find_face (const char *name, struct face **entry)
-{
- struct face *fp, **fpp;
- time_t now = time(0);
-
- /* First, scan for expired entries and free them.
- (Future improvement: Integrate these two loops.) */
-#ifdef DEBUG_ADDRINFO
- printf("scanning cache at %d for '%s'...\n", now, name);
-#endif
- k5_mutex_assert_locked(&krb5int_fac.lock);
- for (fpp = &krb5int_fac.data; *fpp; ) {
- fp = *fpp;
-#ifdef DEBUG_ADDRINFO
- printf(" checking expiration time of @%p: %d\n",
- fp, fp->expiration);
-#endif
- if (fp->expiration < now) {
-#ifdef DEBUG_ADDRINFO
- printf("\texpiring cache entry\n");
-#endif
- free(fp->name);
- free(fp->canonname);
- free(fp->addrs4);
- free(fp->addrs6);
- *fpp = fp->next;
- free(fp);
- /* Stay at this point in the list, and check again. */
- } else
- /* Move forward. */
- fpp = &(*fpp)->next;
- }
-
- for (fp = krb5int_fac.data; fp; fp = fp->next) {
-#ifdef DEBUG_ADDRINFO
- printf(" comparing entry @%p\n", fp);
-#endif
- if (!strcasecmp(fp->name, name)) {
-#ifdef DEBUG_ADDRINFO
- printf("\tMATCH!\n");
-#endif
- *entry = fp;
- return 1;
- }
- }
- return 0;
-}
-
-#endif
-
-extern int krb5int_lock_fac(void), krb5int_unlock_fac(void);
-
-static inline int fai_add_hosts_by_name (const char *name,
- struct addrinfo *template,
- int portnum, int flags,
- struct addrinfo **result)
-{
-#ifdef FAI_CACHE
-
- struct face *ce;
- int i, r, err;
-
- err = krb5int_lock_fac();
- if (err) {
- errno = err;
- return EAI_SYSTEM;
- }
- if (!find_face(name, &ce)) {
- struct addrinfo myhints = { 0 }, *ai, *ai2;
- int i4, i6, aierr;
-
-#ifdef DEBUG_ADDRINFO
- printf("looking up new data for '%s'...\n", name);
-#endif
- myhints.ai_socktype = SOCK_STREAM;
- myhints.ai_flags = AI_CANONNAME;
- /* Don't set ai_family -- we want to cache all address types,
- because the next lookup may not use the same constraints as
- the current one. We *could* cache them separately, so that
- we never have to look up an IPv6 address if we are always
- asked for IPv4 only, but let's deal with that later, if we
- have to. */
- aierr = system_getaddrinfo(name, "telnet", &myhints, &ai);
- if (aierr) {
- krb5int_unlock_fac();
- return aierr;
- }
- ce = malloc(sizeof(struct face));
- memset(ce, 0, sizeof(*ce));
- ce->expiration = time(0) + 30;
- for (ai2 = ai; ai2; ai2 = ai2->ai_next) {
-#ifdef DEBUG_ADDRINFO
- printf(" found an address in family %d...\n", ai2->ai_family);
-#endif
- switch (ai2->ai_family) {
- case AF_INET:
- ce->naddrs4++;
- break;
- case AF_INET6:
- ce->naddrs6++;
- break;
- default:
- break;
- }
- }
- ce->addrs4 = calloc(ce->naddrs4, sizeof(*ce->addrs4));
- if (ce->addrs4 == NULL && ce->naddrs4 != 0) {
- krb5int_unlock_fac();
- system_freeaddrinfo(ai);
- return EAI_MEMORY;
- }
- ce->addrs6 = calloc(ce->naddrs6, sizeof(*ce->addrs6));
- if (ce->addrs6 == NULL && ce->naddrs6 != 0) {
- krb5int_unlock_fac();
- free(ce->addrs4);
- system_freeaddrinfo(ai);
- return EAI_MEMORY;
- }
- for (ai2 = ai, i4 = i6 = 0; ai2; ai2 = ai2->ai_next) {
- switch (ai2->ai_family) {
- case AF_INET:
- ce->addrs4[i4++] = ((struct sockaddr_in *)ai2->ai_addr)->sin_addr;
- break;
- case AF_INET6:
- ce->addrs6[i6++] = ((struct sockaddr_in6 *)ai2->ai_addr)->sin6_addr;
- break;
- default:
- break;
- }
- }
- ce->canonname = ai->ai_canonname ? strdup(ai->ai_canonname) : 0;
- system_freeaddrinfo(ai);
- plant_face(name, ce);
- }
- template->ai_family = AF_INET6;
- template->ai_addrlen = sizeof(struct sockaddr_in6);
- for (i = 0; i < ce->naddrs6; i++) {
- r = fai_add_entry (result, &ce->addrs6[i], portnum, template);
- if (r) {
- krb5int_unlock_fac();
- return r;
- }
- }
- template->ai_family = AF_INET;
- template->ai_addrlen = sizeof(struct sockaddr_in);
- for (i = 0; i < ce->naddrs4; i++) {
- r = fai_add_entry (result, &ce->addrs4[i], portnum, template);
- if (r) {
- krb5int_unlock_fac();
- return r;
- }
- }
- if (*result && (flags & AI_CANONNAME))
- (*result)->ai_canonname = (ce->canonname
- ? strdup(ce->canonname)
- : NULL);
- krb5int_unlock_fac();
- return 0;
-
-#else
-
- struct hostent *hp;
- int i, r;
- int herr;
-
- GET_HOST_BY_NAME (name, hp, herr);
- if (hp == 0)
- return translate_h_errno (herr);
- for (i = 0; hp->h_addr_list[i]; i++) {
- r = fai_add_entry (result, hp->h_addr_list[i], portnum, template);
- if (r)
- return r;
- }
- if (*result && (flags & AI_CANONNAME))
- (*result)->ai_canonname = strdup (hp->h_name);
- return 0;
-
-#endif
-}
-
-static inline void
-fake_freeaddrinfo (struct addrinfo *ai)
-{
- struct addrinfo *next;
- while (ai) {
- next = ai->ai_next;
- if (ai->ai_canonname)
- free (ai->ai_canonname);
- if (ai->ai_addr)
- free (ai->ai_addr);
- free (ai);
- ai = next;
- }
-}
-
-static inline int
-fake_getaddrinfo (const char *name, const char *serv,
- const struct addrinfo *hint, struct addrinfo **result)
-{
- struct addrinfo *res = 0;
- int ret;
- int port = 0, socktype;
- int flags;
- struct addrinfo template;
-
-#ifdef DEBUG_ADDRINFO
- debug_dump_getaddrinfo_args(name, serv, hint);
-#endif
-
- if (hint != 0) {
- if (hint->ai_family != 0 && hint->ai_family != AF_INET)
- return EAI_NODATA;
- socktype = hint->ai_socktype;
- flags = hint->ai_flags;
- } else {
- socktype = 0;
- flags = 0;
- }
-
- if (serv) {
- size_t numlen = strspn (serv, "0123456789");
- if (serv[numlen] == '\0') {
- /* pure numeric */
- unsigned long p = strtoul (serv, 0, 10);
- if (p == 0 || p > 65535)
- return EAI_NONAME;
- port = htons (p);
- } else {
- struct servent *sp;
- int try_dgram_too = 0, s_err;
-
- if (socktype == 0) {
- try_dgram_too = 1;
- socktype = SOCK_STREAM;
- }
- try_service_lookup:
- GET_SERV_BY_NAME(serv, socktype == SOCK_STREAM ? "tcp" : "udp",
- sp, s_err);
- if (sp == 0) {
- if (try_dgram_too) {
- socktype = SOCK_DGRAM;
- goto try_service_lookup;
- }
- return EAI_SERVICE;
- }
- port = sp->s_port;
- }
- }
-
- if (name == 0) {
- name = (flags & AI_PASSIVE) ? "0.0.0.0" : "127.0.0.1";
- flags |= AI_NUMERICHOST;
- }
-
- template.ai_family = AF_INET;
- template.ai_addrlen = sizeof (struct sockaddr_in);
- template.ai_socktype = socktype;
- template.ai_protocol = 0;
- template.ai_flags = 0;
- template.ai_canonname = 0;
- template.ai_next = 0;
- template.ai_addr = 0;
-
- /* If NUMERICHOST is set, parse a numeric address.
- If it's not set, don't accept such names. */
- if (flags & AI_NUMERICHOST) {
- struct in_addr addr4;
-#if 0
- ret = inet_aton (name, &addr4);
- if (ret)
- return EAI_NONAME;
-#else
- addr4.s_addr = inet_addr (name);
- if (addr4.s_addr == 0xffffffff || addr4.s_addr == -1)
- /* 255.255.255.255 or parse error, both bad */
- return EAI_NONAME;
-#endif
- ret = fai_add_entry (&res, &addr4, port, &template);
- } else {
- ret = fai_add_hosts_by_name (name, &template, port, flags,
- &res);
- }
-
- if (ret && ret != NO_ADDRESS) {
- fake_freeaddrinfo (res);
- return ret;
- }
- if (res == 0)
- return NO_ADDRESS;
- *result = res;
- return 0;
-}
-
-#ifdef NEED_FAKE_GETNAMEINFO
-static inline int
-fake_getnameinfo (const struct sockaddr *sa, socklen_t len,
- char *host, socklen_t hostlen,
- char *service, socklen_t servicelen,
- int flags)
-{
- struct hostent *hp;
- const struct sockaddr_in *sinp;
- struct servent *sp;
- size_t hlen, slen;
-
- if (sa->sa_family != AF_INET) {
- return EAI_FAMILY;
- }
- sinp = (const struct sockaddr_in *) sa;
-
- hlen = hostlen;
- if (hostlen < 0 || hlen != hostlen) {
- errno = EINVAL;
- return EAI_SYSTEM;
- }
- slen = servicelen;
- if (servicelen < 0 || slen != servicelen) {
- errno = EINVAL;
- return EAI_SYSTEM;
- }
-
- if (host) {
- if (flags & NI_NUMERICHOST) {
-#if (defined(__GNUC__) && defined(__mips__)) || 1 /* thread safety always */
- /* The inet_ntoa call, passing a struct, fails on IRIX 6.5
- using gcc 2.95; we get back "0.0.0.0". Since this in a
- configuration still important at Athena, here's the
- workaround, which also happens to be thread-safe.... */
- const unsigned char *uc;
- char tmpbuf[20];
- numeric_host:
- uc = (const unsigned char *) &sinp->sin_addr;
- sprintf(tmpbuf, "%d.%d.%d.%d", uc[0], uc[1], uc[2], uc[3]);
- strncpy(host, tmpbuf, hlen);
-#else
- char *p;
- numeric_host:
- p = inet_ntoa (sinp->sin_addr);
- strncpy (host, p, hlen);
-#endif
- } else {
- int herr;
- GET_HOST_BY_ADDR((const char *) &sinp->sin_addr,
- sizeof (struct in_addr),
- sa->sa_family, hp, herr);
- if (hp == 0) {
- if (herr == NO_ADDRESS && !(flags & NI_NAMEREQD)) /* ??? */
- goto numeric_host;
- return translate_h_errno (herr);
- }
- /* According to the Open Group spec, getnameinfo can
- silently truncate, but must still return a
- null-terminated string. */
- strncpy (host, hp->h_name, hlen);
- }
- host[hostlen-1] = 0;
- }
-
- if (service) {
- if (flags & NI_NUMERICSERV) {
- char numbuf[10];
- int port;
- numeric_service:
- port = ntohs (sinp->sin_port);
- if (port < 0 || port > 65535)
- return EAI_FAIL;
- sprintf (numbuf, "%d", port);
- strncpy (service, numbuf, slen);
- } else {
- int serr;
- GET_SERV_BY_PORT(sinp->sin_port,
- (flags & NI_DGRAM) ? "udp" : "tcp",
- sp, serr);
- if (sp == 0)
- goto numeric_service;
- strncpy (service, sp->s_name, slen);
- }
- service[servicelen-1] = 0;
- }
-
- return 0;
-}
-#endif
-
-#if defined(HAVE_FAKE_GETADDRINFO) || defined(NEED_FAKE_GETNAMEINFO)
-
-static inline
-char *gai_strerror (int code)
-{
- switch (code) {
- case EAI_ADDRFAMILY: return "address family for nodename not supported";
- case EAI_AGAIN: return "temporary failure in name resolution";
- case EAI_BADFLAGS: return "bad flags to getaddrinfo/getnameinfo";
- case EAI_FAIL: return "non-recoverable failure in name resolution";
- case EAI_FAMILY: return "ai_family not supported";
- case EAI_MEMORY: return "out of memory";
- case EAI_NODATA: return "no address associated with hostname";
- case EAI_NONAME: return "name does not exist";
- case EAI_SERVICE: return "service name not supported for specified socket type";
- case EAI_SOCKTYPE: return "ai_socktype not supported";
- case EAI_SYSTEM: return strerror (errno);
- default: return "bogus getaddrinfo error?";
- }
-}
-#endif
-
-static inline int translate_h_errno (int h)
-{
- switch (h) {
- case 0:
- return 0;
-#ifdef NETDB_INTERNAL
- case NETDB_INTERNAL:
- if (errno == ENOMEM)
- return EAI_MEMORY;
- return EAI_SYSTEM;
-#endif
- case HOST_NOT_FOUND:
- return EAI_NONAME;
- case TRY_AGAIN:
- return EAI_AGAIN;
- case NO_RECOVERY:
- return EAI_FAIL;
- case NO_DATA:
-#if NO_DATA != NO_ADDRESS
- case NO_ADDRESS:
-#endif
- return EAI_NODATA;
- default:
- return EAI_SYSTEM;
- }
-}
-
-#if defined(HAVE_FAKE_GETADDRINFO) || defined(FAI_CACHE)
-static inline
-int getaddrinfo (const char *name, const char *serv,
- const struct addrinfo *hint, struct addrinfo **result)
-{
- return fake_getaddrinfo(name, serv, hint, result);
-}
-
-static inline
-void freeaddrinfo (struct addrinfo *ai)
-{
- fake_freeaddrinfo(ai);
-}
-
-#ifdef NEED_FAKE_GETNAMEINFO
-static inline
-int getnameinfo (const struct sockaddr *sa, socklen_t len,
- char *host, socklen_t hostlen,
- char *service, socklen_t servicelen,
- int flags)
-{
- return fake_getnameinfo(sa, len, host, hostlen, service, servicelen,
- flags);
-}
-#endif /* NEED_FAKE_GETNAMEINFO */
-#endif /* HAVE_FAKE_GETADDRINFO */
-#endif /* NEED_FAKE_GETADDRINFO */
-
-
-#ifdef WRAP_GETADDRINFO
-
-static inline
-int
-getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
- struct addrinfo **result)
-{
- int aierr;
-#if defined(_AIX) || defined(COPY_FIRST_CANONNAME)
- struct addrinfo *ai;
-#endif
-#ifdef NUMERIC_SERVICE_BROKEN
- int service_is_numeric = 0;
- int service_port = 0;
- int socket_type = 0;
-#endif
-
-#ifdef DEBUG_ADDRINFO
- debug_dump_getaddrinfo_args(name, serv, hint);
-#endif
-
-#ifdef NUMERIC_SERVICE_BROKEN
- /* AIX 4.3.3 is broken. (Or perhaps out of date?)
-
- If a numeric service is provided, and it doesn't correspond to
- a known service name for tcp or udp (as appropriate), an error
- code (for "host not found") is returned. If the port maps to a
- known service for both udp and tcp, all is well. */
- if (serv && serv[0] && isdigit(serv[0])) {
- unsigned long lport;
- char *end;
- lport = strtoul(serv, &end, 10);
- if (!*end) {
- if (lport > 65535)
- return EAI_SOCKTYPE;
- service_is_numeric = 1;
- service_port = htons(lport);
- serv = "discard"; /* defined for both udp and tcp */
- if (hint)
- socket_type = hint->ai_socktype;
- }
- }
-#endif
-
- aierr = system_getaddrinfo (name, serv, hint, result);
- if (aierr || *result == 0) {
-#ifdef DEBUG_ADDRINFO
- debug_dump_error(aierr);
-#endif
- return aierr;
- }
-
- /* Linux libc version 6 (libc-2.2.4.so on Debian) is broken.
-
- RFC 2553 says that when AI_CANONNAME is set, the ai_canonname
- flag of the first returned structure has the canonical name of
- the host. Instead, GNU libc sets ai_canonname in each returned
- structure to the name that the corresponding address maps to,
- if any, or a printable numeric form.
-
- RFC 2553 bis and the new Open Group spec say that field will be
- the canonical name if it can be determined, otherwise, the
- provided hostname or a copy of it.
-
- IMNSHO, "canonical name" means CNAME processing and not PTR
- processing, but I can see arguing it. Using the numeric form
- when that's not the form provided is just wrong. So, let's fix
- it.
-
- The glibc 2.2.5 sources indicate that the canonical name is
- *not* allocated separately, it's just some extra storage tacked
- on the end of the addrinfo structure. So, let's try this
- approach: If getaddrinfo sets ai_canonname, we'll replace the
- *first* one with allocated storage, and free up that pointer in
- freeaddrinfo if it's set; the other ai_canonname fields will be
- left untouched. And we'll just pray that the application code
- won't mess around with the list structure; if we start doing
- that, we'll have to start replacing and freeing all of the
- ai_canonname fields.
-
- Ref: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=133668 .
-
- Since it's dependent on the target hostname, it's hard to check
- for at configure time. Always do it on Linux for now. When
- they get around to fixing it, add a compile-time or run-time
- check for the glibc version in use.
-
- Some Windows documentation says that even when AI_CANONNAME is
- set, the returned ai_canonname field can be null. The NetBSD
- 1.5 implementation also does this, if the input hostname is a
- numeric host address string. That case isn't handled well at
- the moment.
-
- Libc version 5 didn't have getaddrinfo at all. */
-
-#ifdef COPY_FIRST_CANONNAME
- /*
- * This code must *always* return an error, return a null
- * ai_canonname, or return an ai_canonname allocated here using
- * malloc, so that freeaddrinfo can always free a non-null
- * ai_canonname. Note that it really doesn't matter if the
- * AI_CANONNAME flag was set.
- */
- ai = *result;
- if (ai->ai_canonname) {
- struct hostent *hp;
- const char *name2 = 0;
- int i, herr;
-
- /*
- * Current versions of GET_HOST_BY_NAME will fail if the
- * target hostname has IPv6 addresses only. Make sure it
- * fails fairly cleanly.
- */
- GET_HOST_BY_NAME (name, hp, herr);
- if (hp == 0) {
- /*
- * This case probably means it's an IPv6-only name. If
- * ai_canonname is a numeric address, get rid of it.
- */
- if (ai->ai_canonname && strchr(ai->ai_canonname, ':'))
- ai->ai_canonname = 0;
- name2 = ai->ai_canonname ? ai->ai_canonname : name;
- } else {
- /* Sometimes gethostbyname will be directed to /etc/hosts
- first, and sometimes that file will have entries with
- the unqualified name first. So take the first entry
- that looks like it could be a FQDN. */
- for (i = 0; hp->h_aliases[i]; i++) {
- if (strchr(hp->h_aliases[i], '.') != 0) {
- name2 = hp->h_aliases[i];
- break;
- }
- }
- /* Give up, just use the first name (h_name ==
- h_aliases[0] on all systems I've seen). */
- if (hp->h_aliases[i] == 0)
- name2 = hp->h_name;
- }
-
- ai->ai_canonname = strdup(name2);
- if (name2 != 0 && ai->ai_canonname == 0) {
- system_freeaddrinfo(ai);
- *result = 0;
-#ifdef DEBUG_ADDRINFO
- debug_dump_error(EAI_MEMORY);
-#endif
- return EAI_MEMORY;
- }
- /* Zap the remaining ai_canonname fields glibc fills in, in
- case the application messes around with the list
- structure. */
- while ((ai = ai->ai_next) != NULL)
- ai->ai_canonname = 0;
- }
-#endif
-
-#ifdef NUMERIC_SERVICE_BROKEN
- if (service_port != 0) {
- for (ai = *result; ai; ai = ai->ai_next) {
- if (socket_type != 0 && ai->ai_socktype == 0)
- /* Is this check actually needed? */
- ai->ai_socktype = socket_type;
- switch (ai->ai_family) {
- case AF_INET:
- ((struct sockaddr_in *)ai->ai_addr)->sin_port = service_port;
- break;
- case AF_INET6:
- ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = service_port;
- break;
- }
- }
- }
-#endif
-
-#ifdef _AIX
- for (ai = *result; ai; ai = ai->ai_next) {
- /* AIX 4.3.3 libc is broken. It doesn't set the family or len
- fields of the sockaddr structures. Usually, sa_family is
- zero, but I've seen it set to 1 in some cases also (maybe
- just leftover from previous contents of the memory
- block?). So, always override what libc returned. */
- ai->ai_addr->sa_family = ai->ai_family;
-#ifdef HAVE_SA_LEN /* always true on AIX, actually */
- ai->ai_addr->sa_len = ai->ai_addrlen;
-#endif
- }
-#endif
-
- /* Not dealt with currently:
-
- - Some versions of GNU libc can lose some IPv4 addresses in
- certain cases when multiple IPv4 and IPv6 addresses are
- available. */
-
-#ifdef DEBUG_ADDRINFO
- debug_dump_addrinfos(*result);
-#endif
-
- return 0;
-}
-
-static inline
-void freeaddrinfo (struct addrinfo *ai)
-{
-#ifdef COPY_FIRST_CANONNAME
- if (ai) {
- free(ai->ai_canonname);
- ai->ai_canonname = 0;
- system_freeaddrinfo(ai);
- }
-#else
- system_freeaddrinfo(ai);
-#endif
-}
-#endif /* WRAP_GETADDRINFO */
-
#if defined(KRB5_USE_INET6) && defined(NEED_INSIXADDR_ANY)
/* If compiling with IPv6 support and C library does not define in6addr_any */
+extern const struct in6_addr krb5int_in6addr_any;
#undef in6addr_any
#define in6addr_any krb5int_in6addr_any
-static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
#endif
-#ifdef ADDRINFO_UNDEF_INLINE
-# undef inline
-# undef ADDRINFO_UNDEF_INLINE
+/* Call out to stuff defined in libkrb5support. */
+extern int krb5int_getaddrinfo (const char *node, const char *service,
+ const struct addrinfo *hints,
+ struct addrinfo **aip);
+extern void krb5int_freeaddrinfo (struct addrinfo *ai);
+extern const char *krb5int_gai_strerror(int err);
+extern int krb5int_getnameinfo (const struct sockaddr *sa, socklen_t salen,
+ char *hbuf, size_t hbuflen,
+ char *sbuf, size_t sbuflen,
+ int flags);
+#ifndef IMPLEMENT_FAKE_GETADDRINFO
+#undef getaddrinfo
+#define getaddrinfo krb5int_getaddrinfo
+#undef freeaddrinfo
+#define freeaddrinfo krb5int_freeaddrinfo
+#undef gai_strerror
+#define gai_strerror krb5int_gai_strerror
+#undef getnameinfo
+#define getnameinfo krb5int_getnameinfo
#endif
#endif /* FAI_DEFINED */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/k5-int-pkinit.h b/usr/src/lib/gss_mechs/mech_krb5/include/k5-int-pkinit.h
new file mode 100644
index 0000000000..e6d65840eb
--- /dev/null
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/k5-int-pkinit.h
@@ -0,0 +1,271 @@
+
+/*
+ * COPYRIGHT (C) 2006
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#ifndef _KRB5_INT_PKINIT_H
+#define _KRB5_INT_PKINIT_H
+
+/*
+ * pkinit structures
+ */
+
+/* PKAuthenticator */
+typedef struct _krb5_pk_authenticator {
+ krb5_int32 cusec; /* (0..999999) */
+ krb5_timestamp ctime;
+ krb5_int32 nonce; /* (0..4294967295) */
+ krb5_checksum paChecksum;
+} krb5_pk_authenticator;
+
+/* PKAuthenticator draft9 */
+typedef struct _krb5_pk_authenticator_draft9 {
+ krb5_principal kdcName;
+ krb5_octet_data kdcRealm;
+ krb5_int32 cusec; /* (0..999999) */
+ krb5_timestamp ctime;
+ krb5_int32 nonce; /* (0..4294967295) */
+} krb5_pk_authenticator_draft9;
+
+/* AlgorithmIdentifier */
+typedef struct _krb5_algorithm_identifier {
+ krb5_octet_data algorithm; /* OID */
+ krb5_octet_data parameters; /* Optional */
+} krb5_algorithm_identifier;
+
+/* SubjectPublicKeyInfo */
+typedef struct _krb5_subject_pk_info {
+ krb5_algorithm_identifier algorithm;
+ krb5_octet_data subjectPublicKey; /* BIT STRING */
+} krb5_subject_pk_info;
+
+/* AuthPack */
+typedef struct _krb5_auth_pack {
+ krb5_pk_authenticator pkAuthenticator;
+ krb5_subject_pk_info *clientPublicValue; /* Optional */
+ krb5_algorithm_identifier **supportedCMSTypes; /* Optional */
+ krb5_octet_data clientDHNonce; /* Optional */
+} krb5_auth_pack;
+
+/* AuthPack draft9 */
+typedef struct _krb5_auth_pack_draft9 {
+ krb5_pk_authenticator_draft9 pkAuthenticator;
+ krb5_subject_pk_info *clientPublicValue; /* Optional */
+} krb5_auth_pack_draft9;
+
+/* ExternalPrincipalIdentifier */
+typedef struct _krb5_external_principal_identifier {
+ krb5_octet_data subjectName; /* Optional */
+ krb5_octet_data issuerAndSerialNumber; /* Optional */
+ krb5_octet_data subjectKeyIdentifier; /* Optional */
+} krb5_external_principal_identifier;
+
+/* TrustedCas */
+typedef struct _krb5_trusted_ca {
+ enum {
+ choice_trusted_cas_UNKNOWN = -1,
+ choice_trusted_cas_principalName = 0,
+ choice_trusted_cas_caName = 1,
+ choice_trusted_cas_issuerAndSerial = 2
+ } choice;
+ union {
+ krb5_principal principalName;
+ krb5_octet_data caName; /* fully-qualified X.500 "Name" as defined by X.509 (der-encoded) */
+ krb5_octet_data issuerAndSerial; /* Optional -- IssuerAndSerialNumber (der-encoded) */
+ } u;
+} krb5_trusted_ca;
+
+/* typed data */
+typedef struct _krb5_typed_data {
+ krb5_magic magic;
+ krb5_int32 type;
+ unsigned int length;
+ krb5_octet *data;
+} krb5_typed_data;
+
+/* PA-PK-AS-REQ (Draft 9 -- PA TYPE 14) */
+typedef struct _krb5_pa_pk_as_req_draft9 {
+ krb5_octet_data signedAuthPack;
+ krb5_trusted_ca **trustedCertifiers; /* Optional array */
+ krb5_octet_data kdcCert; /* Optional */
+ krb5_octet_data encryptionCert;
+} krb5_pa_pk_as_req_draft9;
+
+/* PA-PK-AS-REQ (rfc4556 -- PA TYPE 16) */
+typedef struct _krb5_pa_pk_as_req {
+ krb5_octet_data signedAuthPack;
+ krb5_external_principal_identifier **trustedCertifiers; /* Optional array */
+ krb5_octet_data kdcPkId; /* Optional */
+} krb5_pa_pk_as_req;
+
+/* DHRepInfo */
+typedef struct _krb5_dh_rep_info {
+ krb5_octet_data dhSignedData;
+ krb5_octet_data serverDHNonce; /* Optional */
+} krb5_dh_rep_info;
+
+/* KDCDHKeyInfo */
+typedef struct _krb5_kdc_dh_key_info {
+ krb5_octet_data subjectPublicKey; /* BIT STRING */
+ krb5_int32 nonce; /* (0..4294967295) */
+ krb5_timestamp dhKeyExpiration; /* Optional */
+} krb5_kdc_dh_key_info;
+
+/* KDCDHKeyInfo draft9*/
+typedef struct _krb5_kdc_dh_key_info_draft9 {
+ krb5_octet_data subjectPublicKey; /* BIT STRING */
+ krb5_int32 nonce; /* (0..4294967295) */
+} krb5_kdc_dh_key_info_draft9;
+
+/* ReplyKeyPack */
+typedef struct _krb5_reply_key_pack {
+ krb5_keyblock replyKey;
+ krb5_checksum asChecksum;
+} krb5_reply_key_pack;
+
+/* ReplyKeyPack */
+typedef struct _krb5_reply_key_pack_draft9 {
+ krb5_keyblock replyKey;
+ krb5_int32 nonce;
+} krb5_reply_key_pack_draft9;
+
+/* PA-PK-AS-REP (Draft 9 -- PA TYPE 15) */
+typedef struct _krb5_pa_pk_as_rep_draft9 {
+ enum {
+ choice_pa_pk_as_rep_draft9_UNKNOWN = -1,
+ choice_pa_pk_as_rep_draft9_dhSignedData = 0,
+ choice_pa_pk_as_rep_draft9_encKeyPack = 1
+ } choice;
+ union {
+ krb5_octet_data dhSignedData;
+ krb5_octet_data encKeyPack;
+ } u;
+} krb5_pa_pk_as_rep_draft9;
+
+/* PA-PK-AS-REP (rfc4556 -- PA TYPE 17) */
+typedef struct _krb5_pa_pk_as_rep {
+ enum {
+ choice_pa_pk_as_rep_UNKNOWN = -1,
+ choice_pa_pk_as_rep_dhInfo = 0,
+ choice_pa_pk_as_rep_encKeyPack = 1
+ } choice;
+ union {
+ krb5_dh_rep_info dh_Info;
+ krb5_octet_data encKeyPack;
+ } u;
+} krb5_pa_pk_as_rep;
+
+/*
+ * Begin "asn1.h"
+ */
+
+/*************************************************************************
+ * Prototypes for pkinit asn.1 encode routines
+ *************************************************************************/
+
+krb5_error_code encode_krb5_pa_pk_as_req
+ (const krb5_pa_pk_as_req *rep, krb5_data **code);
+
+krb5_error_code encode_krb5_pa_pk_as_req_draft9
+ (const krb5_pa_pk_as_req_draft9 *rep, krb5_data **code);
+
+krb5_error_code encode_krb5_pa_pk_as_rep
+ (const krb5_pa_pk_as_rep *rep, krb5_data **code);
+
+krb5_error_code encode_krb5_pa_pk_as_rep_draft9
+ (const krb5_pa_pk_as_rep_draft9 *rep, krb5_data **code);
+
+krb5_error_code encode_krb5_auth_pack
+ (const krb5_auth_pack *rep, krb5_data **code);
+
+krb5_error_code encode_krb5_auth_pack_draft9
+ (const krb5_auth_pack_draft9 *rep, krb5_data **code);
+
+krb5_error_code encode_krb5_kdc_dh_key_info
+ (const krb5_kdc_dh_key_info *rep, krb5_data **code);
+
+krb5_error_code encode_krb5_reply_key_pack
+ (const krb5_reply_key_pack *, krb5_data **code);
+
+krb5_error_code encode_krb5_reply_key_pack_draft9
+ (const krb5_reply_key_pack_draft9 *, krb5_data **code);
+
+krb5_error_code encode_krb5_typed_data
+ (const krb5_typed_data **, krb5_data **code);
+
+krb5_error_code encode_krb5_td_trusted_certifiers
+ (const krb5_external_principal_identifier **, krb5_data **code);
+
+krb5_error_code encode_krb5_td_dh_parameters
+ (const krb5_algorithm_identifier **, krb5_data **code);
+
+/*************************************************************************
+ * Prototypes for pkinit asn.1 decode routines
+ *************************************************************************/
+
+krb5_error_code decode_krb5_pa_pk_as_req
+ (const krb5_data *, krb5_pa_pk_as_req **);
+
+krb5_error_code decode_krb5_pa_pk_as_req_draft9
+ (const krb5_data *, krb5_pa_pk_as_req_draft9 **);
+
+krb5_error_code decode_krb5_pa_pk_as_rep
+ (const krb5_data *, krb5_pa_pk_as_rep **);
+
+krb5_error_code decode_krb5_pa_pk_as_rep_draft9
+ (const krb5_data *, krb5_pa_pk_as_rep_draft9 **);
+
+krb5_error_code decode_krb5_auth_pack
+ (const krb5_data *, krb5_auth_pack **);
+
+krb5_error_code decode_krb5_auth_pack_draft9
+ (const krb5_data *, krb5_auth_pack_draft9 **);
+
+krb5_error_code decode_krb5_kdc_dh_key_info
+ (const krb5_data *, krb5_kdc_dh_key_info **);
+
+krb5_error_code decode_krb5_principal_name
+ (const krb5_data *, krb5_principal_data **);
+
+krb5_error_code decode_krb5_reply_key_pack
+ (const krb5_data *, krb5_reply_key_pack **);
+
+krb5_error_code decode_krb5_reply_key_pack_draft9
+ (const krb5_data *, krb5_reply_key_pack_draft9 **);
+
+krb5_error_code decode_krb5_typed_data
+ (const krb5_data *, krb5_typed_data ***);
+
+krb5_error_code decode_krb5_td_trusted_certifiers
+ (const krb5_data *, krb5_external_principal_identifier ***);
+
+krb5_error_code decode_krb5_td_dh_parameters
+ (const krb5_data *, krb5_algorithm_identifier ***);
+
+#endif /* _KRB5_INT_PKINIT_H */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/krb5/adm_proto.h b/usr/src/lib/gss_mechs/mech_krb5/include/krb5/adm_proto.h
index 5f981669d7..f2bd465f73 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/include/krb5/adm_proto.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/krb5/adm_proto.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* include/krb5/adm_proto.h
*
@@ -36,7 +35,7 @@ struct _krb5_db_entry;
typedef struct _krb5_db_entry krb5_db_entry;
#endif /* KRB5_KDB5__ */
-/* Ditto for adm.h or kadm5/admin.h */
+/* Ditto for adm.h */
/*
* XXXX krb5_realm params is defined in two header files!!!!
@@ -56,96 +55,12 @@ typedef struct ___krb5_key_salt_tuple krb5_key_salt_tuple;
* Function prototypes.
*/
-/* adm_conn.c */
-krb5_error_code KRB5_CALLCONV krb5_adm_connect
- (krb5_context,
- char *,
- char *,
- char *,
- int *,
- krb5_auth_context *,
- krb5_ccache *,
- char *,
- krb5_timestamp);
- void KRB5_CALLCONV krb5_adm_disconnect
- (krb5_context,
- int *,
- krb5_auth_context,
- krb5_ccache);
-
-#if !defined(_MSDOS) && !defined(_WIN32) && !defined(macintosh)
-/* adm_kw_dec.c */
-krb5_error_code krb5_adm_proto_to_dbent
- (krb5_context,
- krb5_int32,
- krb5_data *,
- krb5_ui_4 *,
- krb5_db_entry *,
- char **);
-
-/* adm_kw_enc.c */
-krb5_error_code krb5_adm_dbent_to_proto
- (krb5_context,
- krb5_ui_4,
- krb5_db_entry *,
- char *,
- krb5_int32 *,
- krb5_data **);
-#endif /* !(windows or macintosh) */
-
-/* adm_kt_dec.c */
-krb5_error_code krb5_adm_proto_to_ktent
- (krb5_context,
- krb5_int32,
- krb5_data *,
- krb5_keytab_entry *);
-
-/* adm_kt_enc.c */
-krb5_error_code krb5_adm_ktent_to_proto
- (krb5_context,
- krb5_keytab_entry *,
- krb5_int32 *,
- krb5_data **);
-
-/* adm_rw.c */
-void KRB5_CALLCONV krb5_free_adm_data
- (krb5_context,
- krb5_int32,
- krb5_data *);
-
-krb5_error_code KRB5_CALLCONV krb5_send_adm_cmd
- (krb5_context,
- krb5_pointer,
- krb5_auth_context,
- krb5_int32,
- krb5_data *);
-krb5_error_code krb5_send_adm_reply
- (krb5_context,
- krb5_pointer,
- krb5_auth_context,
- krb5_int32,
- krb5_int32,
- krb5_data *);
-krb5_error_code krb5_read_adm_cmd
- (krb5_context,
- krb5_pointer,
- krb5_auth_context,
- krb5_int32 *,
- krb5_data **);
-krb5_error_code KRB5_CALLCONV krb5_read_adm_reply
- (krb5_context,
- krb5_pointer,
- krb5_auth_context,
- krb5_int32 *,
- krb5_int32 *,
- krb5_data **);
-
/* logger.c */
krb5_error_code krb5_klog_init
(krb5_context,
- char *,
- char *,
- krb5_boolean);
+ char *,
+ char *,
+ krb5_boolean);
void krb5_klog_close (krb5_context);
int krb5_klog_syslog (int, const char *, ...);
void krb5_klog_reopen (krb5_context);
@@ -155,65 +70,63 @@ krb5_error_code krb5_aprof_init
(char *, char *, krb5_pointer *);
krb5_error_code krb5_aprof_getvals
(krb5_pointer, const char **, char ***);
+krb5_error_code krb5_aprof_get_boolean
+ (krb5_pointer, const char **, int, krb5_boolean *);
krb5_error_code krb5_aprof_get_deltat
(krb5_pointer,
- const char **,
- krb5_boolean,
- krb5_deltat *);
+ const char **,
+ krb5_boolean,
+ krb5_deltat *);
krb5_error_code krb5_aprof_get_string
(krb5_pointer, const char **, krb5_boolean, char **);
krb5_error_code krb5_aprof_get_int32
(krb5_pointer,
- const char **,
- krb5_boolean,
- krb5_int32 *);
+ const char **,
+ krb5_boolean,
+ krb5_int32 *);
krb5_error_code krb5_aprof_finish (krb5_pointer);
krb5_error_code krb5_read_realm_params (krb5_context,
- char *,
- char *,
- char *,
- krb5_realm_params **);
+ char *,
+ krb5_realm_params **);
krb5_error_code krb5_free_realm_params (krb5_context,
- krb5_realm_params *);
+ krb5_realm_params *);
/* str_conv.c */
krb5_error_code
krb5_string_to_flags (char *,
- const char *,
- const char *,
- krb5_flags *);
+ const char *,
+ const char *,
+ krb5_flags *);
krb5_error_code
krb5_flags_to_string (krb5_flags,
- const char *,
- char *,
- size_t);
+ const char *,
+ char *,
+ size_t);
krb5_error_code
krb5_input_flag_to_string (int,
- char *,
- size_t);
+ char *,
+ size_t);
/* keysalt.c */
krb5_boolean
krb5_keysalt_is_present (krb5_key_salt_tuple *,
- krb5_int32,
- krb5_enctype,
- krb5_int32);
+ krb5_int32,
+ krb5_enctype,
+ krb5_int32);
krb5_error_code
-krb5_keysalt_iterate
- (krb5_key_salt_tuple *,
- krb5_int32,
- krb5_boolean,
- krb5_error_code (*)
- (krb5_key_salt_tuple *,
- krb5_pointer),
- krb5_pointer);
+krb5_keysalt_iterate (krb5_key_salt_tuple *,
+ krb5_int32,
+ krb5_boolean,
+ krb5_error_code (*) (krb5_key_salt_tuple *,
+ krb5_pointer),
+ krb5_pointer);
krb5_error_code
krb5_string_to_keysalts (char *,
- const char *,
- const char *,
- krb5_boolean,
- krb5_key_salt_tuple **,
- krb5_int32 *);
+ const char *,
+ const char *,
+ krb5_boolean,
+ krb5_key_salt_tuple **,
+ krb5_int32 *);
#endif /* KRB5_ADM_PROTO_H__ */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/krb5/kdb.h b/usr/src/lib/gss_mechs/mech_krb5/include/krb5/kdb.h
index a54eef98bd..c68914f143 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/include/krb5/kdb.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/krb5/kdb.h
@@ -61,9 +61,6 @@
#ifndef KRB5_KDB5__
#define KRB5_KDB5__
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-
/* Salt types */
#define KRB5_KDB_SALTTYPE_NORMAL 0
#define KRB5_KDB_SALTTYPE_V4 1
@@ -92,8 +89,6 @@
#define KRB5_KDB_CREATE_BTREE 0x00000001
#define KRB5_KDB_CREATE_HASH 0x00000002
-#if !defined(_WIN32)
-
/*
* Note --- these structures cannot be modified without changing the
* database version number in libkdb.a, but should be expandable by
@@ -138,7 +133,7 @@ typedef struct _krb5_keysalt {
typedef struct _krb5_db_entry_new {
krb5_magic magic; /* NOT saved */
krb5_ui_2 len;
- krb5_ui_4 mask; /* members currently changed/set */
+ krb5_ui_4 mask; /* members currently changed/set */
krb5_flags attributes;
krb5_deltat max_life;
krb5_deltat max_renewable_life;
@@ -174,6 +169,7 @@ typedef struct __krb5_key_salt_tuple {
#define KRB5_TL_SECURID_STATE 0x0006
#define KRB5_TL_DB_ARGS 0x7fff
#endif /* SECURID */
+#define KRB5_TL_USER_CERTIFICATE 0x0007
/*
* Determines the number of failed KDC requests before DISALLOW_ALL_TIX is set
@@ -188,6 +184,7 @@ typedef struct __krb5_key_salt_tuple {
#define KRB5_KDC_MKEY_1 "Enter KDC database master key"
#define KRB5_KDC_MKEY_2 "Re-enter KDC database master key to verify"
+
extern char *krb5_mkey_pwd_prompt1;
extern char *krb5_mkey_pwd_prompt2;
@@ -196,6 +193,7 @@ extern char *krb5_mkey_pwd_prompt2;
*
* Data encoding is little-endian.
*/
+#include "k5-platform.h"
#define krb5_kdb_decode_int16(cp, i16) \
*((krb5_int16 *) &(i16)) = (((krb5_int16) ((unsigned char) (cp)[0]))| \
((krb5_int16) ((unsigned char) (cp)[1]) << 8))
@@ -536,5 +534,4 @@ krb5_db_free_policy( krb5_context kcontext,
#define KRB5_KDB_DEF_FLAGS 0
-#endif /* !defined(_WIN32) */
#endif /* KRB5_KDB5__ */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/locate_plugin.h b/usr/src/lib/gss_mechs/mech_krb5/include/locate_plugin.h
new file mode 100644
index 0000000000..cec24c9fce
--- /dev/null
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/locate_plugin.h
@@ -0,0 +1,61 @@
+
+/*
+ * <krb5/locate_plugin.h>
+ *
+ * Copyright 2006 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.
+ *
+ *
+ * Service location plugin definitions for Kerberos 5.
+ */
+
+#ifndef KRB5_LOCATE_PLUGIN_H_INCLUDED
+#define KRB5_LOCATE_PLUGIN_H_INCLUDED
+#include <krb5.h>
+
+enum locate_service_type {
+ locate_service_kdc = 1,
+ locate_service_master_kdc,
+ locate_service_kadmin,
+ locate_service_krb524,
+ locate_service_kpasswd
+};
+
+typedef struct krb5plugin_service_locate_ftable {
+ int minor_version; /* currently 0 */
+ /* Per-context setup and teardown. Returned void* blob is
+ private to the plugin. */
+ krb5_error_code (*init)(krb5_context, void **);
+ void (*fini)(void *);
+ /* Callback function returns non-zero if the plugin function
+ should quit and return; this may be because of an error, or may
+ indicate we've already contacted the service, whatever. The
+ lookup function should only return an error if it detects a
+ problem, not if the callback function tells it to quit. */
+ krb5_error_code (*lookup)(void *,
+ enum locate_service_type svc, const char *realm,
+ int socktype, int family,
+ int (*cbfunc)(void *,int,struct sockaddr *),
+ void *cbdata);
+} krb5plugin_service_locate_ftable;
+/* extern krb5plugin_service_locate_ftable service_locator; */
+#endif
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/osconf.h b/usr/src/lib/gss_mechs/mech_krb5/include/osconf.h
index e16e3f5f2c..524bcdc4d1 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/include/osconf.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/osconf.h
@@ -1,28 +1,20 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#ifndef _KRB5_OSCONF_H
-#define _KRB5_OSCONF_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
/*
* include/krb5/stock/osconf.h
*
- * Copyright 1990, 1991 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
- *
+ *
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
@@ -30,39 +22,72 @@ extern "C" {
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
- *
+ *
*
* Site- and OS- dependant configuration.
*/
+#ifndef KRB5_OSCONF__
+#define KRB5_OSCONF__
-/* Don't try to pull in autoconf.h for Windows, since it's not used */
+#if !defined(_WIN32)
+ /* Don't try to pull in autoconf.h for Windows, since it's not used */
#ifndef KRB5_AUTOCONF__
-#define KRB5_AUTOCONF__
+#define KRB5_AUTOCONF__
#include "autoconf.h"
#endif
+#endif
+
+#if defined(__MACH__) && defined(__APPLE__)
+# include <TargetConditionals.h>
+#endif
-#define DEFAULT_SECURE_PROFILE_PATH "/etc/krb5/krb5.conf"
-#define DEFAULT_PROFILE_PATH DEFAULT_SECURE_PROFILE_PATH
+#if defined(_WIN32)
+#define DEFAULT_PROFILE_FILENAME "krb5.ini"
+#define DEFAULT_LNAME_FILENAME "/aname"
+#define DEFAULT_KEYTAB_NAME "FILE:%s\\krb5kt"
+#else /* !_WINDOWS */
+#if TARGET_OS_MAC
+#define DEFAULT_SECURE_PROFILE_PATH "/Library/Preferences/edu.mit.Kerberos:/etc/krb5.conf:@SYSCONFDIR/krb5.conf"
+#define DEFAULT_PROFILE_PATH ("~/Library/Preferences/edu.mit.Kerberos" ":" DEFAULT_SECURE_PROFILE_PATH)
+#define KRB5_PLUGIN_BUNDLE_DIR "/System/Library/KerberosPlugins/KerberosFrameworkPlugins"
+#define KDB5_PLUGIN_BUNDLE_DIR "/System/Library/KerberosPlugins/KerberosDatabasePlugins"
+#else
+/* Solaris Kerberos */
+#define DEFAULT_SECURE_PROFILE_PATH "/etc/krb5/krb5.conf"
+#define DEFAULT_PROFILE_PATH DEFAULT_SECURE_PROFILE_PATH
+#endif
+/* Solaris Kerberos */
#define DEFAULT_KEYTAB_NAME "FILE:/etc/krb5/krb5.keytab"
-#define DEFAULT_KEYTAB "WRFILE:/etc/krb5/krb5.keytab"
+#endif /* _WINDOWS */
/* Solaris Kerberos: default for where ldap bind passwds stored */
#define DEF_SERVICE_PASSWD_FILE "/var/krb5/service_passwd"
-
-#define DEFAULT_KDB_FILE "/var/krb5/principal"
+/* Solaris Kerberos */
+#define DEFAULT_KDB_FILE "/var/krb5/principal"
#define DEFAULT_KEYFILE_STUB "/var/krb5/.k5."
-#define KRB5_DEFAULT_ADMIN_ACL "/etc/krb5/krb5_adm.acl"
+#define KRB5_DEFAULT_ADMIN_ACL "/etc/krb5/krb5_adm.acl"
+
+#define DEFAULT_ADMIN_ACL "@LOCALSTATEDIR/krb5kdc/kadm_old.acl"
/* Location of KDC profile */
+/* Solaris Kerberos */
#define DEFAULT_KDC_PROFILE "/etc/krb5/kdc.conf"
#define KDC_PROFILE_ENV "KRB5_KDC_PROFILE"
+#if TARGET_OS_MAC
+#define DEFAULT_KDB_LIB_PATH { KDB5_PLUGIN_BUNDLE_DIR, "@MODULEDIR/kdb", NULL }
+#else
+/* Solaris Kerberos */
#define DEFAULT_KDB_LIB_PATH { "/usr/lib/krb5", NULL }
+#endif
/*
* SUNW14resync
@@ -72,20 +97,20 @@ extern "C" {
#define DEFAULT_KDC_ENCTYPE ENCTYPE_DES_CBC_CRC
#define KDCRCACHE "dfl:krb5kdc_rcache"
-#define KDC_PORTNAME "kerberos" /* for /etc/services or equiv. */
-#define KDC_SECONDARY_PORTNAME "kerberos-sec" /* For backwards */
+#define KDC_PORTNAME "kerberos" /* for /etc/services or equiv. */
+#define KDC_SECONDARY_PORTNAME "kerberos-sec" /* For backwards */
/* compatibility with */
/* port 750 clients */
-#define DEFAULT_KPASSWD_PORT 464 /* assigned by IANA */
-#define KPASSWD_PORTNAME "kpasswd"
+#define KRB5_DEFAULT_PORT 88
+#define KRB5_DEFAULT_SEC_PORT 750
-#define KRB5_DEFAULT_PORT 88
-#define KRB5_DEFAULT_SEC_PORT 750
+#define DEFAULT_KPASSWD_PORT 464
+#define KPASSWD_PORTNAME "kpasswd"
-#define DEFAULT_KDC_UDP_PORTLIST "88, 750"
+#define DEFAULT_KDC_UDP_PORTLIST "88,750"
/* Solaris Kerberos: enabled TCP by default on port 88 */
-#define DEFAULT_KDC_TCP_PORTLIST "88"
+#define DEFAULT_KDC_TCP_PORTLIST "88"
/* Solaris Kerberos: control # of kdc tcp connection */
#define DEFAULT_KDC_TCP_CONNECTIONS 30
@@ -94,31 +119,28 @@ extern "C" {
/*
* Defaults for the KADM5 admin system.
*/
-#define DEFAULT_KADM5_KEYTAB "/etc/krb5/kadm5.keytab"
-#define DEFAULT_KADM5_ACL_FILE "/etc/krb5/kadm5.acl"
-#define DEFAULT_KADM5_PORT 749 /* assigned by IANA */
+/* Solaris Kerberos */
+#define DEFAULT_KADM5_KEYTAB "/etc/krb5/kadm5.keytab"
+#define DEFAULT_KADM5_ACL_FILE "/etc/krb5/kadm5.acl"
+#define DEFAULT_KADM5_PORT 749 /* assigned by IANA */
-#define MAX_DGRAM_SIZE 4096
-#define MAX_SKDC_TIMEOUT 30
-#define SKDC_TIMEOUT_SHIFT 2 /* left shift of timeout for backoff */
-#define SKDC_TIMEOUT_1 1 /* seconds for first timeout */
+#define MAX_DGRAM_SIZE 4096
+#define MAX_SKDC_TIMEOUT 30
+#define SKDC_TIMEOUT_SHIFT 2 /* left shift of timeout for backoff */
+#define SKDC_TIMEOUT_1 1 /* seconds for first timeout */
-#define KRB5_ENV_CCNAME "KRB5CCNAME"
+#define KRB5_ENV_CCNAME "KRB5CCNAME"
/*
* krb5 slave support follows
*/
-#define KPROP_DEFAULT_FILE "/var/krb5/slave_datatrans"
-#define KPROPD_DEFAULT_FILE "/var/krb5/from_master"
-#define KPROPD_DEFAULT_KDB5_UTIL "/usr/sbin/kdb5_util"
-#define KPROPD_DEFAULT_KRB_DB DEFAULT_KDB_FILE
-#define KPROPD_ACL_FILE "/etc/krb5/kpropd.acl"
-
-#define HAVE_GETEUID 1
-
-#ifdef __cplusplus
-}
-#endif
+/* Solaris Kerberos */
+#define KPROP_DEFAULT_FILE "/var/krb5/slave_datatrans"
+#define KPROPD_DEFAULT_FILE "/var/krb5/from_master"
+#define KPROPD_DEFAULT_KDB5_UTIL "/usr/sbin/kdb5_util"
+#define KPROPD_DEFAULT_KDB5_EDIT "/usr/sbin/kdb5_edit"
+#define KPROPD_DEFAULT_KRB_DB DEFAULT_KDB_FILE
+#define KPROPD_ACL_FILE "/etc/krb5/kpropd.acl"
-#endif /* !_KRB5_OSCONF_H */
+#endif /* KRB5_OSCONF__ */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/port-sockets.h b/usr/src/lib/gss_mechs/mech_krb5/include/port-sockets.h
index 02b39d4e33..d901d3c5d5 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/include/port-sockets.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/port-sockets.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
#ifndef _PORT_SOCKET_H
#define _PORT_SOCKET_H
@@ -67,12 +66,18 @@ typedef WSABUF sg_buf;
#define ETIMEDOUT WSAETIMEDOUT
#endif
-#else /* not _WIN32 */
+#elif defined(__palmos__)
/* If this source file requires it, define struct sockaddr_in
(and possibly other things related to network I/O). */
#include "autoconf.h"
+#include <netdb.h>
+typedef int socklen_t;
+
+#else /* UNIX variants */
+
+#include "autoconf.h"
#include <sys/types.h>
#include <netinet/in.h> /* For struct sockaddr_in and in_addr */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/preauth_plugin.h b/usr/src/lib/gss_mechs/mech_krb5/include/preauth_plugin.h
new file mode 100644
index 0000000000..5b15ceedb5
--- /dev/null
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/preauth_plugin.h
@@ -0,0 +1,508 @@
+
+/*
+ * <krb5/preauth_plugin.h>
+ *
+ * Copyright (c) 2006 Red Hat, Inc.
+ * Portions copyright (c) 2006 Massachusetts Institute of Technology
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Red Hat, Inc., nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Preauthentication plugin definitions for Kerberos 5.
+ */
+
+#ifndef KRB5_PREAUTH_PLUGIN_H_INCLUDED
+#define KRB5_PREAUTH_PLUGIN_H_INCLUDED
+#include <krb5.h>
+
+/*
+ * While arguments of these types are passed-in, for the most part a preauth
+ * module can treat them as opaque. If we need keying data, we can ask for
+ * it directly.
+ */
+struct _krb5_db_entry_new;
+struct _krb5_key_data;
+struct _krb5_preauth_client_rock;
+
+/*
+ * Preauth mechanism property flags, unified from previous definitions in the
+ * KDC and libkrb5 sources.
+ */
+
+/* Provides a real answer which we can send back to the KDC (client-only). The
+ * client assumes that one real answer will be enough. */
+#define PA_REAL 0x00000001
+
+/* Doesn't provide a real answer, but must be given a chance to run before any
+ * REAL mechanism callbacks (client-only). */
+#define PA_INFO 0x00000002
+
+/* Causes the KDC to include this mechanism in a list of supported preauth
+ * types if the user's DB entry flags the user as requiring hardware-based
+ * preauthentication (server-only). */
+#define PA_HARDWARE 0x00000004
+
+/* Causes the KDC to include this mechanism in a list of supported preauth
+ * types if the user's DB entry flags the user as requiring preauthentication,
+ * and to fail preauthentication if we can't verify the client data. The
+ * flipside of PA_SUFFICIENT (server-only). */
+#define PA_REQUIRED 0x00000008
+
+/* Causes the KDC to include this mechanism in a list of supported preauth
+ * types if the user's DB entry flags the user as requiring preauthentication,
+ * and to mark preauthentication as successful if we can verify the client
+ * data. The flipside of PA_REQUIRED (server-only). */
+#define PA_SUFFICIENT 0x00000010
+
+/* Marks this preauthentication mechanism as one which changes the key which is
+ * used for encrypting the response to the client. Modules which have this
+ * flag have their server_return_proc called before modules which do not, and
+ * are passed over if a previously-called module has modified the encrypting
+ * key (server-only). */
+#define PA_REPLACES_KEY 0x00000020
+
+/* Causes the KDC to check with this preauthentication module even if the
+ * client has no entry in the realm database. If the module returns a success
+ * code, continue processing and assume that its return_padata callback will
+ * supply us with a key for encrypting the AS reply (server-only). */
+/* #define PA_VIRTUAL (0x00000040 | PA_REPLACES_KEY) */
+
+/* Not really a padata type, so don't include it in any list of preauth types
+ * which gets sent over the wire. */
+#define PA_PSEUDO 0x00000080
+
+
+/***************************************************************************
+ *
+ * Client-side preauthentication plugin interface definition.
+ *
+ ***************************************************************************/
+
+/*
+ * A callback which will obtain the user's long-term AS key by prompting the
+ * user for the password, then salting it properly, and so on. For the moment,
+ * it's identical to the get_as_key callback used inside of libkrb5, but we
+ * define a new typedef here instead of making the existing one public to
+ * isolate ourselves from potential future changes.
+ */
+typedef krb5_error_code
+(*preauth_get_as_key_proc)(krb5_context,
+ krb5_principal,
+ krb5_enctype,
+ krb5_prompter_fct,
+ void *prompter_data,
+ krb5_data *salt,
+ krb5_data *s2kparams,
+ krb5_keyblock *as_key,
+ void *gak_data);
+
+/*
+ * A client module's callback functions are allowed to request various
+ * information to enable it to process a request.
+ */
+enum krb5plugin_preauth_client_request_type {
+ /* The returned krb5_data item holds the enctype used to encrypt the
+ * encrypted portion of the AS_REP packet. */
+ krb5plugin_preauth_client_get_etype = 1,
+ /* Free the data returned from krb5plugin_preauth_client_req_get_etype */
+ krb5plugin_preauth_client_free_etype = 2
+};
+typedef krb5_error_code
+(*preauth_get_client_data_proc)(krb5_context,
+ struct _krb5_preauth_client_rock *,
+ krb5_int32 request_type,
+ krb5_data **);
+
+/* Per-plugin initialization/cleanup. The init function is called
+ * by libkrb5 when the plugin is loaded, and the fini function is
+ * called before the plugin is unloaded. Both are optional and
+ * may be called multiple times in case the plugin is used in
+ * multiple contexts. The returned context lives the lifetime of
+ * the krb5_context */
+typedef krb5_error_code
+(*preauth_client_plugin_init_proc)(krb5_context context,
+ void **plugin_context);
+typedef void
+(*preauth_client_plugin_fini_proc)(krb5_context context,
+ void *plugin_context);
+
+/* A callback which returns flags indicating if the module is a "real" or
+ * an "info" mechanism, and so on. This function is called for each entry
+ * in the client_pa_type_list. */
+typedef int
+(*preauth_client_get_flags_proc)(krb5_context context,
+ krb5_preauthtype pa_type);
+
+/* Per-request initialization/cleanup. The request_init function is
+ * called when beginning to process a get_init_creds request and the
+ * request_fini function is called when processing of the request is
+ * complete. This is optional. It may be called multiple times in
+ * the lifetime of a krb5_context. */
+typedef void
+(*preauth_client_request_init_proc)(krb5_context context,
+ void *plugin_context,
+ void **request_context);
+typedef void
+(*preauth_client_request_fini_proc)(krb5_context context,
+ void *plugin_context,
+ void *request_context);
+
+/* Client function which processes server-supplied data in pa_data,
+ * returns created data in out_pa_data, storing any of its own state in
+ * client_context if data for the associated preauthentication type is
+ * needed. It is also called after the AS-REP is received if the AS-REP
+ * includes preauthentication data of the associated type.
+ * NOTE! the encoded_previous_request will be NULL the first time this
+ * function is called, because it is expected to only ever contain the data
+ * obtained from a previous call to this function. */
+typedef krb5_error_code
+(*preauth_client_process_proc)(krb5_context context,
+ void *plugin_context,
+ void *request_context,
+ krb5_get_init_creds_opt *opt,
+ preauth_get_client_data_proc get_data_proc,
+ struct _krb5_preauth_client_rock *rock,
+ krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data *pa_data,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ preauth_get_as_key_proc gak_fct,
+ void *gak_data,
+ krb5_data *salt,
+ krb5_data *s2kparams,
+ krb5_keyblock *as_key,
+ krb5_pa_data ***out_pa_data);
+
+/* Client function which can attempt to use e-data in the error response to
+ * try to recover from the given error. If this function is not NULL, and
+ * it stores data in out_pa_data which is different data from the contents
+ * of in_pa_data, then the client library will retransmit the request. */
+typedef krb5_error_code
+(*preauth_client_tryagain_proc)(krb5_context context,
+ void *plugin_context,
+ void *request_context,
+ krb5_get_init_creds_opt *opt,
+ preauth_get_client_data_proc get_data_proc,
+ struct _krb5_preauth_client_rock *rock,
+ krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data *in_pa_data,
+ krb5_error *error,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ preauth_get_as_key_proc gak_fct,
+ void *gak_data,
+ krb5_data *salt,
+ krb5_data *s2kparams,
+ krb5_keyblock *as_key,
+ krb5_pa_data ***out_pa_data);
+
+/*
+ * Client function which receives krb5_get_init_creds_opt information.
+ * The attr and value information supplied should be copied locally by
+ * the module if it wishes to reference it after returning from this call.
+ */
+typedef krb5_error_code
+(*preauth_client_supply_gic_opts_proc)(krb5_context context,
+ void *plugin_context,
+ krb5_get_init_creds_opt *opt,
+ const char *attr,
+ const char *value);
+
+/*
+ * The function table / structure which a preauth client module must export as
+ * "preauthentication_client_0". If the interfaces work correctly, future
+ * versions of the table will add either more callbacks or more arguments to
+ * callbacks, and in both cases we'll be able to wrap the v0 functions.
+ */
+typedef struct krb5plugin_preauth_client_ftable_v1 {
+ /* Not-usually-visible name. */
+ char *name;
+
+ /* Pointer to zero-terminated list of pa_types which this module can
+ * provide services for. */
+ krb5_preauthtype *pa_type_list;
+
+ /* Pointer to zero-terminated list of enc_types which this module claims
+ * to add support for. */
+ krb5_enctype *enctype_list;
+
+ /* Per-plugin initialization/cleanup. The init function is called
+ * by libkrb5 when the plugin is loaded, and the fini function is
+ * called before the plugin is unloaded. Both are optional and
+ * may be called multiple times in case the plugin is used in
+ * multiple contexts. The returned context lives the lifetime of
+ * the krb5_context */
+ preauth_client_plugin_init_proc init;
+ preauth_client_plugin_fini_proc fini;
+
+ /* A callback which returns flags indicating if the module is a "real" or
+ * an "info" mechanism, and so on. This function is called for each entry
+ * in the client_pa_type_list. */
+ preauth_client_get_flags_proc flags;
+
+ /* Per-request initialization/cleanup. The request_init function is
+ * called when beginning to process a get_init_creds request and the
+ * request_fini function is called when processing of the request is
+ * complete. This is optional. It may be called multiple times in
+ * the lifetime of a krb5_context. */
+ preauth_client_request_init_proc request_init;
+ preauth_client_request_fini_proc request_fini;
+
+ /* Client function which processes server-supplied data in pa_data,
+ * returns created data in out_pa_data, storing any of its own state in
+ * client_context if data for the associated preauthentication type is
+ * needed. It is also called after the AS-REP is received if the AS-REP
+ * includes preauthentication data of the associated type.
+ * NOTE! the encoded_previous_request will be NULL the first time this
+ * function is called, because it is expected to only ever contain the data
+ * obtained from a previous call to this function. */
+ preauth_client_process_proc process;
+
+ /* Client function which can attempt to use e-data in the error response to
+ * try to recover from the given error. If this function is not NULL, and
+ * it stores data in out_pa_data which is different data from the contents
+ * of in_pa_data, then the client library will retransmit the request. */
+ preauth_client_tryagain_proc tryagain;
+
+ /*
+ * Client function which receives krb5_get_init_creds_opt information.
+ * The attr and value information supplied should be copied locally by
+ * the module if it wishes to reference it after returning from this call.
+ */
+ preauth_client_supply_gic_opts_proc gic_opts;
+
+} krb5plugin_preauth_client_ftable_v1;
+
+
+/***************************************************************************
+ *
+ * Server-side preauthentication plugin interface definition.
+ *
+ ***************************************************************************/
+
+/*
+ * A server module's callback functions are allowed to request specific types
+ * of information about the given client or server record or request, even
+ * though the database records themselves are opaque to the module.
+ */
+enum krb5plugin_preauth_entry_request_type {
+ /* The returned krb5_data item holds a DER-encoded X.509 certificate. */
+ krb5plugin_preauth_entry_request_certificate = 1,
+ /* The returned krb5_data_item holds a krb5_deltat. */
+ krb5plugin_preauth_entry_max_time_skew = 2,
+ /* The returned krb5_data_item holds an array of krb5_keyblock structures,
+ * terminated by an entry with key type = 0.
+ * Each keyblock should have its contents freed in turn, and then the data
+ * item itself should be freed. */
+ krb5plugin_preauth_keys = 3,
+ /* The returned krb5_data_item holds the request structure, re-encoded
+ * using DER. Unless the client implementation is the same as the server
+ * implementation, there's a good chance that the result will not match
+ * what the client sent, so don't go creating any fatal errors if it
+ * doesn't match up. */
+ krb5plugin_preauth_request_body = 4
+};
+
+typedef krb5_error_code
+(*preauth_get_entry_data_proc)(krb5_context,
+ krb5_kdc_req *,
+ struct _krb5_db_entry_new *,
+ krb5_int32 request_type,
+ krb5_data **);
+
+/* Preauth plugin initialization function */
+typedef krb5_error_code
+(*preauth_server_init_proc)(krb5_context context,
+ void **plugin_context,
+ const char** realmnames);
+
+/* Preauth plugin cleanup function */
+typedef void
+(*preauth_server_fini_proc)(krb5_context context, void *plugin_context);
+
+/* Return the flags which the KDC should use for this module. This is a
+ * callback instead of a static value because the module may or may not
+ * wish to count itself as a hardware preauthentication module (in other
+ * words, the flags may be affected by the configuration, for example if a
+ * site administrator can force a particular preauthentication type to be
+ * supported using only hardware). This function is called for each entry
+ * entry in the server_pa_type_list. */
+typedef int
+(*preauth_server_flags_proc)(krb5_context context, krb5_preauthtype patype);
+
+/* Get preauthentication data to send to the client as part of the "you
+ * need to use preauthentication" error. The module doesn't need to
+ * actually provide data if the protocol doesn't require it, but it should
+ * return either zero or non-zero to control whether its padata type is
+ * included in the list which is sent back to the client. Is not allowed
+ * to create a context because we have no guarantee that the client will
+ * ever call again (or that it will hit this server if it does), in which
+ * case a context might otherwise hang around forever. */
+typedef krb5_error_code
+(*preauth_server_edata_proc)(krb5_context,
+ krb5_kdc_req *request,
+ struct _krb5_db_entry_new *client,
+ struct _krb5_db_entry_new *server,
+ preauth_get_entry_data_proc,
+ void *pa_module_context,
+ krb5_pa_data *data);
+
+/* Verify preauthentication data sent by the client, setting the
+ * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags"
+ * field as appropriate, and returning nonzero on failure. Can create
+ * context data for consumption by the return_proc or freepa_proc below. */
+typedef krb5_error_code
+(*preauth_server_verify_proc)(krb5_context context,
+ struct _krb5_db_entry_new *client,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request,
+ krb5_enc_tkt_part *enc_tkt_reply,
+ krb5_pa_data *data,
+ preauth_get_entry_data_proc,
+ void *pa_module_context,
+ void **pa_request_context,
+ krb5_data **e_data,
+ krb5_authdata ***authz_data);
+
+/* Generate preauthentication response data to send to the client as part
+ * of the AS-REP. If it needs to override the key which is used to encrypt
+ * the response, it can do so. The module is expected (but not required,
+ * if a preauth_server_free_reqcontext_proc is also provided) to free any
+ * context data it saved in "pa_request_context". */
+typedef krb5_error_code
+(*preauth_server_return_proc)(krb5_context context,
+ krb5_pa_data * padata,
+ struct _krb5_db_entry_new *client,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request,
+ krb5_kdc_rep *reply,
+ struct _krb5_key_data *client_keys,
+ krb5_keyblock *encrypting_key,
+ krb5_pa_data **send_pa,
+ preauth_get_entry_data_proc,
+ void *pa_module_context,
+ void **pa_request_context);
+
+/* Free up the server-side per-request context, in cases where
+ * server_return_proc() didn't or for whatever reason was not called.
+ * Can be NULL. */
+typedef krb5_error_code
+(*preauth_server_free_reqcontext_proc)(krb5_context,
+ void *pa_module_context,
+ void **request_pa_context);
+
+/*
+ * The function table / structure which a preauth server module must export as
+ * "preauthentication_server_0". NOTE: replace "0" with "1" for the type and
+ * variable names if this gets picked up by upstream. If the interfaces work
+ * correctly, future versions of the table will add either more callbacks or
+ * more arguments to callbacks, and in both cases we'll be able to wrap the v0
+ * functions.
+ */
+typedef struct krb5plugin_preauth_server_ftable_v1 {
+ /* Not-usually-visible name. */
+ char *name;
+
+ /* Pointer to zero-terminated list of pa_types which this module can
+ * provide services for. */
+ krb5_preauthtype *pa_type_list;
+
+ /* Per-plugin initialization/cleanup. The init function is called by the
+ * KDC when the plugin is loaded, and the fini function is called before
+ * the plugin is unloaded. Both are optional. */
+ preauth_server_init_proc init_proc;
+ preauth_server_fini_proc fini_proc;
+
+ /* Return the flags which the KDC should use for this module. This is a
+ * callback instead of a static value because the module may or may not
+ * wish to count itself as a hardware preauthentication module (in other
+ * words, the flags may be affected by the configuration, for example if a
+ * site administrator can force a particular preauthentication type to be
+ * supported using only hardware). This function is called for each entry
+ * entry in the server_pa_type_list. */
+ preauth_server_flags_proc flags_proc;
+
+ /* Get preauthentication data to send to the client as part of the "you
+ * need to use preauthentication" error. The module doesn't need to
+ * actually provide data if the protocol doesn't require it, but it should
+ * return either zero or non-zero to control whether its padata type is
+ * included in the list which is sent back to the client. Is not allowed
+ * to create a context because we have no guarantee that the client will
+ * ever call again (or that it will hit this server if it does), in which
+ * case a context might otherwise hang around forever. */
+ preauth_server_edata_proc edata_proc;
+
+ /* Verify preauthentication data sent by the client, setting the
+ * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags"
+ * field as appropriate, and returning nonzero on failure. Can create
+ * context data for consumption by the return_proc or freepa_proc below. */
+ preauth_server_verify_proc verify_proc;
+
+ /* Generate preauthentication response data to send to the client as part
+ * of the AS-REP. If it needs to override the key which is used to encrypt
+ * the response, it can do so. The module is expected (but not required,
+ * if a freepa_proc is also provided) to free any context data it saved in
+ * "request_pa_context". */
+ preauth_server_return_proc return_proc;
+
+ /* Free up the server-side per-request context, in cases where
+ * server_return_proc() didn't or for whatever reason was not called.
+ * Can be NULL. */
+ preauth_server_free_reqcontext_proc freepa_reqcontext_proc;
+
+} krb5plugin_preauth_server_ftable_v1;
+
+
+/*
+ * This function allows a preauth plugin to obtain preauth
+ * options. The preauth_data returned from this function
+ * should be freed by calling krb5_get_init_creds_opt_free_pa().
+ *
+ * The 'opt' pointer supplied to this function must have been
+ * obtained using krb5_get_init_creds_opt_alloc()
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_opt_get_pa
+ (krb5_context context,
+ krb5_get_init_creds_opt *opt,
+ int *num_preauth_data,
+ krb5_gic_opt_pa_data **preauth_data);
+
+/*
+ * This function frees the preauth_data that was returned by
+ * krb5_get_init_creds_opt_get_pa().
+ */
+void KRB5_CALLCONV
+krb5_get_init_creds_opt_free_pa
+ (krb5_context context,
+ int num_preauth_data,
+ krb5_gic_opt_pa_data *preauth_data);
+
+#endif /* KRB5_PREAUTH_PLUGIN_H_INCLUDED */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/include/socket-utils.h b/usr/src/lib/gss_mechs/mech_krb5/include/socket-utils.h
index 8785c37a58..da9a2b4c8e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/include/socket-utils.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/include/socket-utils.h
@@ -1,12 +1,11 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
- * Copyright (C) 2001 by the Massachusetts Institute of Technology,
+ * Copyright (C) 2001,2005 by the Massachusetts Institute of Technology,
* Cambridge, MA, USA. All Rights Reserved.
*
* This software is being provided to you, the LICENSEE, by the
@@ -59,11 +58,10 @@
/* for HAVE_SOCKLEN_T, KRB5_USE_INET6, etc */
#include "autoconf.h"
-#if 0 /* SUNW14resync */
-#include "krb5/autoconf.h"
/* for sockaddr_storage */
#include "port-sockets.h"
-#endif /* SUNW14resync */
+/* for "inline" if needed */
+#include "k5-platform.h"
#if defined (__GNUC__)
/*
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_decode.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_decode.c
index 0c7996cc1b..b0ab134922 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_decode.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_decode.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* src/lib/krb5/asn.1/asn1_decode.c
@@ -57,7 +56,7 @@ if(asn1class != UNIVERSAL || construction != PRIMITIVE || tagnum != type)\
#define cleanup()\
return 0
-time_t gmt_mktime (struct tm *);
+extern time_t krb5int_gmt_mktime (struct tm *);
asn1_error_code asn1_decode_integer(asn1buf *buf, long int *val)
{
@@ -252,7 +251,7 @@ asn1_error_code asn1_decode_generaltime(asn1buf *buf, time_t *val)
ts.tm_min = 10*c2i(s[10]) + c2i(s[11]);
ts.tm_sec = 10*c2i(s[12]) + c2i(s[13]);
ts.tm_isdst = -1;
- t = gmt_mktime(&ts);
+ t = krb5int_gmt_mktime(&ts);
free(s);
if(t == -1) return ASN1_BAD_TIMEFORMAT;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_encode.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_encode.c
index 8c874a6116..1805b57028 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_encode.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_encode.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* src/lib/krb5/asn.1/asn1_encode.c
@@ -241,44 +240,49 @@ asn1_error_code asn1_encode_generaltime(asn1buf *buf, time_t val,
* Time encoding: YYYYMMDDhhmmssZ
*/
if (gmt_time == 0) {
- sp = "19700101000000Z";
- } else {
-
- /*
- * Sanity check this just to be paranoid, as gmtime can return NULL,
- * and some bogus implementations might overrun on the sprintf.
- */
+ sp = "19700101000000Z";
+ } else {
+
+ /*
+ * Sanity check this just to be paranoid, as gmtime can return NULL,
+ * and some bogus implementations might overrun on the sprintf.
+ */
#ifdef HAVE_GMTIME_R
- if (gmtime_r(&gmt_time, &gtimebuf) == NULL)
- return ASN1_BAD_GMTIME;
+# ifdef GMTIME_R_RETURNS_INT
+ if (gmtime_r(&gmt_time, &gtimebuf) != 0)
+ return ASN1_BAD_GMTIME;
+# else
+ if (gmtime_r(&gmt_time, &gtimebuf) == NULL)
+ return ASN1_BAD_GMTIME;
+# endif
#else
- gtime = gmtime(&gmt_time);
- if (gtime == NULL)
- return ASN1_BAD_GMTIME;
- memcpy(&gtimebuf, gtime, sizeof(gtimebuf));
+ gtime = gmtime(&gmt_time);
+ if (gtime == NULL)
+ return ASN1_BAD_GMTIME;
+ memcpy(&gtimebuf, gtime, sizeof(gtimebuf));
#endif
- gtime = &gtimebuf;
-
- if (gtime->tm_year > 8099 || gtime->tm_mon > 11 ||
- gtime->tm_mday > 31 || gtime->tm_hour > 23 ||
- gtime->tm_min > 59 || gtime->tm_sec > 59)
- return ASN1_BAD_GMTIME;
- sprintf(s, "%04d%02d%02d%02d%02d%02dZ",
- 1900+gtime->tm_year, gtime->tm_mon+1, gtime->tm_mday,
- gtime->tm_hour, gtime->tm_min, gtime->tm_sec);
- sp = s;
- }
+ gtime = &gtimebuf;
+
+ if (gtime->tm_year > 8099 || gtime->tm_mon > 11 ||
+ gtime->tm_mday > 31 || gtime->tm_hour > 23 ||
+ gtime->tm_min > 59 || gtime->tm_sec > 59)
+ return ASN1_BAD_GMTIME;
+ sprintf(s, "%04d%02d%02d%02d%02d%02dZ",
+ 1900+gtime->tm_year, gtime->tm_mon+1, gtime->tm_mday,
+ gtime->tm_hour, gtime->tm_min, gtime->tm_sec);
+ sp = s;
+ }
retval = asn1buf_insert_charstring(buf,15,sp);
if(retval) return retval;
sum = 15;
- retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_GENERALTIME,sum,&length);
- if(retval) return retval;
- sum += length;
-
- *retlen = sum;
- return 0;
+ retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_GENERALTIME,sum,&length);
+ if(retval) return retval;
+ sum += length;
+
+ *retlen = sum;
+ return 0;
}
asn1_error_code asn1_encode_generalstring(asn1buf *buf, unsigned int len,
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_get.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_get.c
index c55086cffe..8da5fd8806 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_get.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_get.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* src/lib/krb5/asn.1/asn1_get.c
*
@@ -66,7 +64,7 @@ asn1_get_tag_2(asn1buf *buf, taginfo *t)
retval = asn1buf_remove_octet(buf,&o);
if (retval) return retval;
tn = (tn<<7) + (asn1_tagnum)(o&0x7F);
- }while(tn&0x80);
+ }while(o&0x80);
t->tagnum = tn;
}
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_decode.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_decode.c
index bcbb78fca1..50084132f3 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_decode.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_decode.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* src/lib/krb5/asn.1/asn1_k_decode.c
*
@@ -166,6 +165,28 @@
} else { len = 0; var = 0; }
/*
+ * Deal with implicitly tagged fields
+ */
+#define get_implicit_octet_string(len, var, tagexpect) \
+ if (tagnum != (tagexpect)) return ASN1_MISSING_FIELD; \
+ if (asn1class != CONTEXT_SPECIFIC || construction != PRIMITIVE) \
+ return ASN1_BAD_ID; \
+ retval = asn1buf_remove_octetstring(&subbuf, taglen, &(var)); \
+ if (retval) return retval; \
+ (len) = taglen; \
+ next_tag()
+
+#define opt_implicit_octet_string(len, var, tagexpect) \
+ if (tagnum == (tagexpect)) { \
+ if (asn1class != CONTEXT_SPECIFIC || construction != PRIMITIVE) \
+ return ASN1_BAD_ID; \
+ retval = asn1buf_remove_octetstring(&subbuf, taglen, &(var)); \
+ if (retval) return retval; \
+ (len) = taglen; \
+ next_tag(); \
+ } else { (len) = 0; (var) = NULL; }
+
+/*
* begin_structure
*
* Declares some variables for decoding SEQUENCE types. This is meant
@@ -182,6 +203,20 @@
if (retval) return retval; \
next_tag()
+/*
+ * This is used for structures which have no tagging.
+ * It is the same as begin_structure() except next_tag()
+ * is not called.
+ */
+#define begin_structure_no_tag() \
+ asn1buf subbuf; \
+ int seqindef; \
+ int indef; \
+ retval = asn1_get_sequence(buf, &length, &seqindef); \
+ if (retval) return retval; \
+ retval = asn1buf_imbed(&subbuf, buf, length, seqindef); \
+ if (retval) return retval
+
/* skip trailing garbage */
#define end_structure() \
retval = asn1buf_sync(buf, &subbuf, asn1class, tagnum, \
@@ -189,6 +224,37 @@
if (retval) return retval
/*
+ * begin_choice
+ *
+ * Declares some variables for decoding CHOICE types. This is meant
+ * to be called in an inner block that ends with a call to
+ * end_choice().
+ */
+#define begin_choice() \
+ asn1buf subbuf; \
+ int seqindef; \
+ int indef; \
+ taginfo t; \
+ retval = asn1_get_tag_2(buf, &t); \
+ if (retval) return retval; \
+ tagnum = t.tagnum; \
+ taglen = t.length; \
+ indef = t.indef; \
+ length = t.length; \
+ seqindef = t.indef; \
+ asn1class = t.asn1class; \
+ construction = t.construction; \
+ retval = asn1buf_imbed(&subbuf, buf, length, seqindef); \
+ if (retval) return retval
+
+/* skip trailing garbage */
+#define end_choice() \
+ length -= t.length; \
+ retval = asn1buf_sync(buf, &subbuf, t.asn1class, t.tagnum, \
+ length, t.indef, seqindef); \
+ if (retval) return retval
+
+/*
* sequence_of
*
* Declares some variables for decoding SEQUENCE OF types. This is
@@ -375,7 +441,7 @@ asn1_error_code asn1_decode_principal_name(asn1buf *buf, krb5_principal *val)
if((*val)->data == NULL) return ENOMEM;
retval = asn1_decode_generalstring(&seqbuf,
&((*val)->data[size-1].length),
- &((*val)->data[size-1].data));
+ &((*val)->data[size-1].data));
if(retval) return retval;
}
(*val)->length = size;
@@ -535,7 +601,7 @@ asn1_error_code asn1_decode_ticket(asn1buf *buf, krb5_ticket *val)
taginfo t;
retval = asn1_get_tag_2(buf, &t);
if (retval) return retval;
- }
+ }
cleanup();
}
@@ -1107,3 +1173,408 @@ asn1_error_code asn1_decode_predicted_sam_response(asn1buf *buf, krb5_predicted_
}
cleanup();
}
+
+/* PKINIT */
+
+asn1_error_code asn1_decode_external_principal_identifier(asn1buf *buf, krb5_external_principal_identifier *val)
+{
+ setup();
+ {
+ begin_structure();
+ opt_implicit_octet_string(val->subjectName.length, val->subjectName.data, 0);
+ opt_implicit_octet_string(val->issuerAndSerialNumber.length, val->issuerAndSerialNumber.data, 1);
+ opt_implicit_octet_string(val->subjectKeyIdentifier.length, val->subjectKeyIdentifier.data, 2);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_sequence_of_external_principal_identifier(asn1buf *buf, krb5_external_principal_identifier ***val)
+{
+ decode_array_body(krb5_external_principal_identifier,asn1_decode_external_principal_identifier);
+}
+
+asn1_error_code asn1_decode_pa_pk_as_req(asn1buf *buf, krb5_pa_pk_as_req *val)
+{
+ setup();
+ {
+ begin_structure();
+ get_implicit_octet_string(val->signedAuthPack.length, val->signedAuthPack.data, 0);
+ opt_field(val->trustedCertifiers, 1, asn1_decode_sequence_of_external_principal_identifier, NULL);
+ opt_implicit_octet_string(val->kdcPkId.length, val->kdcPkId.data, 2);
+ end_structure();
+ }
+ cleanup();
+}
+
+#if 0 /* XXX This needs to be tested!!! XXX */
+asn1_error_code asn1_decode_trusted_ca(asn1buf *buf, krb5_trusted_ca *val)
+{
+ setup();
+ {
+ char *start, *end;
+ size_t alloclen;
+
+ begin_explicit_choice();
+ if (t.tagnum == choice_trusted_cas_principalName) {
+ val->choice = choice_trusted_cas_principalName;
+ } else if (t.tagnum == choice_trusted_cas_caName) {
+ val->choice = choice_trusted_cas_caName;
+ start = subbuf.next;
+ {
+ sequence_of_no_tagvars(&subbuf);
+ unused_var(size);
+ end_sequence_of_no_tagvars(&subbuf);
+ }
+ end = subbuf.next;
+ alloclen = end - start;
+ val->u.caName.data = malloc(alloclen);
+ if (val->u.caName.data == NULL)
+ return ENOMEM;
+ memcpy(val->u.caName.data, start, alloclen);
+ val->u.caName.length = alloclen;
+ next_tag();
+ } else if (t.tagnum == choice_trusted_cas_issuerAndSerial) {
+ val->choice = choice_trusted_cas_issuerAndSerial;
+ start = subbuf.next;
+ {
+ sequence_of_no_tagvars(&subbuf);
+ unused_var(size);
+ end_sequence_of_no_tagvars(&subbuf);
+ }
+ end = subbuf.next;
+ alloclen = end - start;
+ val->u.issuerAndSerial.data = malloc(alloclen);
+ if (val->u.issuerAndSerial.data == NULL)
+ return ENOMEM;
+ memcpy(val->u.issuerAndSerial.data, start, alloclen);
+ val->u.issuerAndSerial.length = alloclen;
+ next_tag();
+ } else return ASN1_BAD_ID;
+ end_explicit_choice();
+ }
+ cleanup();
+}
+#else
+asn1_error_code asn1_decode_trusted_ca(asn1buf *buf, krb5_trusted_ca *val)
+{
+ setup();
+ { begin_choice();
+ if (tagnum == choice_trusted_cas_principalName) {
+ val->choice = choice_trusted_cas_principalName;
+ asn1_decode_krb5_principal_name(&subbuf, &(val->u.principalName));
+ } else if (tagnum == choice_trusted_cas_caName) {
+ val->choice = choice_trusted_cas_caName;
+ get_implicit_octet_string(val->u.caName.length, val->u.caName.data, choice_trusted_cas_caName);
+ } else if (tagnum == choice_trusted_cas_issuerAndSerial) {
+ val->choice = choice_trusted_cas_issuerAndSerial;
+ get_implicit_octet_string(val->u.issuerAndSerial.length, val->u.issuerAndSerial.data,
+ choice_trusted_cas_issuerAndSerial);
+ } else return ASN1_BAD_ID;
+ end_choice();
+ }
+ cleanup();
+}
+#endif
+
+asn1_error_code asn1_decode_sequence_of_trusted_ca(asn1buf *buf, krb5_trusted_ca ***val)
+{
+ decode_array_body(krb5_trusted_ca, asn1_decode_trusted_ca);
+}
+
+asn1_error_code asn1_decode_pa_pk_as_req_draft9(asn1buf *buf, krb5_pa_pk_as_req_draft9 *val)
+{
+ setup();
+ { begin_structure();
+ get_implicit_octet_string(val->signedAuthPack.length, val->signedAuthPack.data, 0);
+ opt_field(val->trustedCertifiers, 1, asn1_decode_sequence_of_trusted_ca, NULL);
+ opt_lenfield(val->kdcCert.length, val->kdcCert.data, 2, asn1_decode_octetstring);
+ opt_lenfield(val->encryptionCert.length, val->encryptionCert.data, 2, asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_dh_rep_info(asn1buf *buf, krb5_dh_rep_info *val)
+{
+ setup();
+ { begin_structure();
+ get_implicit_octet_string(val->dhSignedData.length, val->dhSignedData.data, 0);
+
+ opt_lenfield(val->serverDHNonce.length, val->serverDHNonce.data, 1, asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_pk_authenticator(asn1buf *buf, krb5_pk_authenticator *val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->cusec, 0, asn1_decode_int32);
+ get_field(val->ctime, 1, asn1_decode_kerberos_time);
+ get_field(val->nonce, 2, asn1_decode_int32);
+ opt_lenfield(val->paChecksum.length, val->paChecksum.contents, 3, asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_pk_authenticator_draft9(asn1buf *buf, krb5_pk_authenticator_draft9 *val)
+{
+ setup();
+ { begin_structure();
+ alloc_field(val->kdcName,krb5_principal_data);
+ get_field(val->kdcName, 0, asn1_decode_principal_name);
+ get_field(val->kdcName, 1, asn1_decode_realm);
+ get_field(val->cusec, 2, asn1_decode_int32);
+ get_field(val->ctime, 3, asn1_decode_kerberos_time);
+ get_field(val->nonce, 4, asn1_decode_int32);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_algorithm_identifier(asn1buf *buf, krb5_algorithm_identifier *val) {
+
+ setup();
+ { begin_structure_no_tag();
+ /*
+ * Forbid indefinite encoding because we don't read enough tag
+ * information from the trailing octets ("ANY DEFINED BY") to
+ * synchronize EOC tags, etc.
+ */
+ if (seqindef) return ASN1_BAD_FORMAT;
+ /*
+ * Set up tag variables because we don't actually call anything
+ * that fetches tag info for us; it's all buried in the decoder
+ * primitives.
+ */
+ tagnum = ASN1_TAGNUM_CEILING;
+ asn1class = UNIVERSAL;
+ construction = PRIMITIVE;
+ taglen = 0;
+ indef = 0;
+ retval = asn1_decode_oid(&subbuf, &val->algorithm.length,
+ &val->algorithm.data);
+ if(retval) return retval;
+ val->parameters.length = 0;
+ val->parameters.data = NULL;
+
+ if(length > subbuf.next - subbuf.base) {
+ unsigned int size = length - (subbuf.next - subbuf.base);
+ retval = asn1buf_remove_octetstring(&subbuf, size,
+ &val->parameters.data);
+ if(retval) return retval;
+ val->parameters.length = size;
+ }
+
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_subject_pk_info(asn1buf *buf, krb5_subject_pk_info *val)
+{
+ asn1_octet unused;
+ setup();
+ { begin_structure_no_tag();
+
+ retval = asn1_decode_algorithm_identifier(&subbuf, &val->algorithm);
+ if (retval) return retval;
+
+ /* SubjectPublicKey encoded as a BIT STRING */
+ next_tag();
+ if (asn1class != UNIVERSAL || construction != PRIMITIVE ||
+ tagnum != ASN1_BITSTRING)
+ return ASN1_BAD_ID;
+
+ retval = asn1buf_remove_octet(&subbuf, &unused);
+ if(retval) return retval;
+
+ /* Number of unused bits must be between 0 and 7. */
+ /* What to do if unused is not zero? */
+ if (unused > 7) return ASN1_BAD_FORMAT;
+ taglen--;
+
+ val->subjectPublicKey.length = 0;
+ val->subjectPublicKey.data = NULL;
+ retval = asn1buf_remove_octetstring(&subbuf, taglen,
+ &val->subjectPublicKey.data);
+ if(retval) return retval;
+ val->subjectPublicKey.length = taglen;
+ /*
+ * We didn't call any macro that does next_tag(); do so now to
+ * preload tag of any trailing encodings.
+ */
+ next_tag();
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_sequence_of_algorithm_identifier(asn1buf *buf, krb5_algorithm_identifier ***val)
+{
+ decode_array_body(krb5_algorithm_identifier, asn1_decode_algorithm_identifier);
+}
+
+asn1_error_code asn1_decode_kdc_dh_key_info (asn1buf *buf, krb5_kdc_dh_key_info *val)
+{
+ setup();
+ { begin_structure();
+ retval = asn1buf_remove_octetstring(&subbuf, taglen, &val->subjectPublicKey.data);
+ if(retval) return retval;
+ val->subjectPublicKey.length = taglen;
+ next_tag();
+ get_field(val->nonce, 1, asn1_decode_int32);
+ opt_field(val->dhKeyExpiration, 2, asn1_decode_kerberos_time, 0);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_reply_key_pack (asn1buf *buf, krb5_reply_key_pack *val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->replyKey, 0, asn1_decode_encryption_key);
+ get_field(val->asChecksum, 1, asn1_decode_checksum);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_reply_key_pack_draft9 (asn1buf *buf, krb5_reply_key_pack_draft9 *val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->replyKey, 0, asn1_decode_encryption_key);
+ get_field(val->nonce, 1, asn1_decode_int32);
+ end_structure();
+ }
+ cleanup();
+}
+
+
+asn1_error_code asn1_decode_krb5_principal_name (asn1buf *buf, krb5_principal *val)
+{
+ setup();
+ { begin_structure();
+ get_field(*val, 0, asn1_decode_realm);
+ get_field(*val, 1, asn1_decode_principal_name);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_auth_pack(asn1buf *buf, krb5_auth_pack *val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->pkAuthenticator, 0, asn1_decode_pk_authenticator);
+ if (tagnum == 1) { alloc_field(val->clientPublicValue, krb5_subject_pk_info); }
+ /* can't call opt_field because it does decoder(&subbuf, &(val)); */
+ if (asn1buf_remains(&subbuf, seqindef)) {
+ if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)
+ && (tagnum || taglen || asn1class != UNIVERSAL))
+ return ASN1_BAD_ID;
+ if (tagnum == 1) {
+ retval = asn1_decode_subject_pk_info(&subbuf,
+ val->clientPublicValue);
+ if (!taglen && indef) { get_eoc(); }
+ next_tag();
+ } else val->clientPublicValue = NULL;
+ }
+ /* can't call opt_field because it does decoder(&subbuf, &(val)); */
+ if (asn1buf_remains(&subbuf, seqindef)) {
+ if (tagnum == 2) {
+ asn1_decode_sequence_of_algorithm_identifier(&subbuf, &val->supportedCMSTypes);
+ if (!taglen && indef) { get_eoc(); }
+ next_tag();
+ } else val->supportedCMSTypes = NULL;
+ }
+ opt_lenfield(val->clientDHNonce.length, val->clientDHNonce.data, 3, asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_auth_pack_draft9(asn1buf *buf, krb5_auth_pack_draft9 *val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->pkAuthenticator, 0, asn1_decode_pk_authenticator_draft9);
+ if (tagnum == 1) {
+ alloc_field(val->clientPublicValue, krb5_subject_pk_info);
+ /* can't call opt_field because it does decoder(&subbuf, &(val)); */
+ if (asn1buf_remains(&subbuf, seqindef)) {
+ if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)
+ && (tagnum || taglen || asn1class != UNIVERSAL))
+ return ASN1_BAD_ID;
+ if (tagnum == 1) {
+ retval = asn1_decode_subject_pk_info(&subbuf,
+ val->clientPublicValue);
+ if (!taglen && indef) { get_eoc(); }
+ next_tag();
+ } else val->clientPublicValue = NULL;
+ }
+ }
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_pa_pk_as_rep(asn1buf *buf, krb5_pa_pk_as_rep *val)
+{
+ setup();
+ { begin_choice();
+ if (tagnum == choice_pa_pk_as_rep_dhInfo) {
+ val->choice = choice_pa_pk_as_rep_dhInfo;
+ get_field_body(val->u.dh_Info, asn1_decode_dh_rep_info);
+ } else if (tagnum == choice_pa_pk_as_rep_encKeyPack) {
+ val->choice = choice_pa_pk_as_rep_encKeyPack;
+ get_implicit_octet_string(val->u.encKeyPack.length, val->u.encKeyPack.data,
+ choice_pa_pk_as_rep_encKeyPack);
+ } else {
+ val->choice = choice_pa_pk_as_rep_UNKNOWN;
+ }
+ end_choice();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_pa_pk_as_rep_draft9(asn1buf *buf, krb5_pa_pk_as_rep_draft9 *val)
+{
+ setup();
+ { begin_structure();
+ if (tagnum == choice_pa_pk_as_rep_draft9_dhSignedData) {
+ val->choice = choice_pa_pk_as_rep_draft9_dhSignedData;
+ get_lenfield(val->u.dhSignedData.length, val->u.dhSignedData.data,
+ choice_pa_pk_as_rep_draft9_dhSignedData, asn1_decode_octetstring);
+ } else if (tagnum == choice_pa_pk_as_rep_draft9_encKeyPack) {
+ val->choice = choice_pa_pk_as_rep_draft9_encKeyPack;
+ get_lenfield(val->u.encKeyPack.length, val->u.encKeyPack.data,
+ choice_pa_pk_as_rep_draft9_encKeyPack, asn1_decode_octetstring);
+ } else {
+ val->choice = choice_pa_pk_as_rep_draft9_UNKNOWN;
+ }
+ end_structure();
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_sequence_of_typed_data(asn1buf *buf, krb5_typed_data ***val)
+{
+ decode_array_body(krb5_typed_data,asn1_decode_typed_data);
+}
+
+asn1_error_code asn1_decode_typed_data(asn1buf *buf, krb5_typed_data *val)
+{
+ setup();
+ { begin_structure();
+ get_field(val->type,0,asn1_decode_int32);
+ get_lenfield(val->length,val->data,1,asn1_decode_octetstring);
+ end_structure();
+ }
+ cleanup();
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_decode.h b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_decode.h
index a93af704b0..72c4e293c0 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_decode.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_decode.h
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* src/lib/krb5/asn.1/asn1_k_decode.h
*
@@ -161,6 +159,44 @@ asn1_error_code asn1_decode_sam_response_2
(asn1buf *buf, krb5_sam_response_2 *val);
asn1_error_code asn1_decode_predicted_sam_response
(asn1buf *buf, krb5_predicted_sam_response *val);
+asn1_error_code asn1_decode_external_principal_identifier
+ (asn1buf *buf, krb5_external_principal_identifier *val);
+asn1_error_code asn1_decode_pa_pk_as_req
+ (asn1buf *buf, krb5_pa_pk_as_req *val);
+asn1_error_code asn1_decode_trusted_ca
+ (asn1buf *buf, krb5_trusted_ca *val);
+asn1_error_code asn1_decode_pa_pk_as_req_draft9
+ (asn1buf *buf, krb5_pa_pk_as_req_draft9 *val);
+asn1_error_code asn1_decode_dh_rep_info
+ (asn1buf *buf, krb5_dh_rep_info *val);
+asn1_error_code asn1_decode_pk_authenticator
+ (asn1buf *buf, krb5_pk_authenticator *val);
+asn1_error_code asn1_decode_pk_authenticator_draft9
+ (asn1buf *buf, krb5_pk_authenticator_draft9 *val);
+asn1_error_code asn1_decode_subject_pk_info
+ (asn1buf *buf, krb5_subject_pk_info *val);
+asn1_error_code asn1_decode_algorithm_identifier
+ (asn1buf *buf, krb5_algorithm_identifier *val);
+asn1_error_code asn1_decode_auth_pack
+ (asn1buf *buf, krb5_auth_pack *val);
+asn1_error_code asn1_decode_auth_pack_draft9
+ (asn1buf *buf, krb5_auth_pack_draft9 *val);
+asn1_error_code asn1_decode_pa_pk_as_rep
+ (asn1buf *buf, krb5_pa_pk_as_rep *val);
+asn1_error_code asn1_decode_pa_pk_as_rep_draft9
+ (asn1buf *buf, krb5_pa_pk_as_rep_draft9 *val);
+asn1_error_code asn1_decode_kdc_dh_key_info
+ (asn1buf *buf, krb5_kdc_dh_key_info *val);
+asn1_error_code asn1_decode_krb5_principal_name
+ (asn1buf *buf, krb5_principal *val);
+asn1_error_code asn1_decode_reply_key_pack
+ (asn1buf *buf, krb5_reply_key_pack *val);
+asn1_error_code asn1_decode_reply_key_pack_draft9
+ (asn1buf *buf, krb5_reply_key_pack_draft9 *val);
+asn1_error_code asn1_decode_sequence_of_typed_data
+ (asn1buf *buf, krb5_typed_data ***val);
+asn1_error_code asn1_decode_typed_data
+ (asn1buf *buf, krb5_typed_data *val);
/* arrays */
asn1_error_code asn1_decode_authorization_data
@@ -189,6 +225,11 @@ asn1_error_code asn1_decode_etype_info
(asn1buf *buf, krb5_etype_info_entry ***val);
asn1_error_code asn1_decode_etype_info2
(asn1buf *buf, krb5_etype_info_entry ***val, krb5_boolean v1_3_behavior);
-
+asn1_error_code asn1_decode_sequence_of_external_principal_identifier
+ (asn1buf *buf, krb5_external_principal_identifier ***val);
+asn1_error_code asn1_decode_sequence_of_trusted_ca
+ (asn1buf *buf, krb5_trusted_ca ***val);
+asn1_error_code asn1_decode_sequence_of_algorithm_identifier
+ (asn1buf *buf, krb5_algorithm_identifier ***val);
#endif
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_encode.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_encode.c
index f9ec0abc25..9e5cbaf3fd 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_encode.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_encode.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* src/lib/krb5/asn.1/asn1_k_encode.c
*
@@ -105,6 +103,50 @@
return retval; }\
sum += length; }
+/* asn1_addfield_implicit -- add an implicitly tagged field, or component, to the encoding */
+#define asn1_addfield_implicit(value,tag,encoder)\
+{ retval = encoder(buf,value,&length);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length;\
+ retval = asn1_make_tag(buf,CONTEXT_SPECIFIC,PRIMITIVE,tag,length,&length); \
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length; }
+
+/* asn1_insert_implicit_octetstring -- add an octet string with implicit tagging */
+#define asn1_insert_implicit_octetstring(len,value,tag)\
+{ retval = asn1buf_insert_octetstring(buf,len,value);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += len;\
+ retval = asn1_make_tag(buf,CONTEXT_SPECIFIC,PRIMITIVE,tag,len,&length); \
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length; }
+
+/* asn1_insert_implicit_bitstring -- add a bitstring with implicit tagging */
+#define asn1_insert_implicit_bitstring(len,value,tag)\
+{ retval = asn1buf_insert_octetstring(buf,len,value);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += len;\
+ retval = asn1buf_insert_octet(buf, 0);\
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum++;\
+ retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,tag,len+1,&length); \
+ if(retval){\
+ asn1buf_destroy(&buf);\
+ return retval; }\
+ sum += length; }
+
/* form a sequence (by adding a sequence header to the current encoding) */
#define asn1_makeseq()\
retval = asn1_make_sequence(buf,sum,&length);\
@@ -720,13 +762,17 @@ asn1_error_code asn1_encode_etype_info_entry(asn1buf *buf, const krb5_etype_info
if(val == NULL || (val->length > 0 && val->length != KRB5_ETYPE_NO_SALT &&
val->salt == NULL))
return ASN1_MISSING_FIELD;
- if(val->s2kparams.data != NULL)
+ if(val->s2kparams.data != NULL) {
+ /* Solaris Kerberos */
asn1_addlenfield(val->s2kparams.length, (const uchar_t *)val->s2kparams.data, 2,
asn1_encode_octetstring);
+ }
if (val->length >= 0 && val->length != KRB5_ETYPE_NO_SALT){
- if (etype_info2)
+ if (etype_info2) {
+ /* Solaris Kerberos */
asn1_addlenfield(val->length, (const char *)val->salt,1,
asn1_encode_generalstring)
+ }
else asn1_addlenfield(val->length,val->salt,1,
asn1_encode_octetstring);
}
@@ -961,3 +1007,393 @@ asn1_error_code asn1_encode_krb_saved_safe_body(asn1buf *buf, const krb5_data *b
*retlen = body->length;
return 0;
}
+
+/*
+ * PKINIT
+ */
+
+asn1_error_code asn1_encode_pk_authenticator(asn1buf *buf, const krb5_pk_authenticator *val, unsigned int *retlen)
+{
+ asn1_setup();
+ asn1_addlenfield(val->paChecksum.length, val->paChecksum.contents, 3, asn1_encode_octetstring);
+ asn1_addfield(val->nonce, 2, asn1_encode_integer);
+ asn1_addfield(val->ctime, 1, asn1_encode_kerberos_time);
+ asn1_addfield(val->cusec, 0, asn1_encode_integer);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_pk_authenticator_draft9(asn1buf *buf, const krb5_pk_authenticator_draft9 *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ asn1_addfield(val->nonce, 4, asn1_encode_integer);
+ asn1_addfield(val->ctime, 3, asn1_encode_kerberos_time);
+ asn1_addfield(val->cusec, 2, asn1_encode_integer);
+ asn1_addfield(val->kdcName, 1, asn1_encode_realm);
+ asn1_addfield(val->kdcName, 0, asn1_encode_principal_name);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+
+asn1_error_code asn1_encode_algorithm_identifier(asn1buf *buf, const krb5_algorithm_identifier *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->parameters.length != 0) {
+ retval = asn1buf_insert_octetstring(buf, val->parameters.length,
+ val->parameters.data);
+ if(retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ sum += val->parameters.length;
+ }
+
+ retval = asn1_encode_oid(buf, val->algorithm.length,
+ val->algorithm.data,
+ &length);
+
+ if(retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ sum += length;
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_subject_pk_info(asn1buf *buf, const krb5_subject_pk_info *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ asn1_insert_implicit_bitstring(val->subjectPublicKey.length,val->subjectPublicKey.data,ASN1_BITSTRING);
+
+ if (val->algorithm.parameters.length != 0) {
+ retval = asn1buf_insert_octetstring(buf, val->algorithm.parameters.length,
+ val->algorithm.parameters.data);
+ if(retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ sum += val->algorithm.parameters.length;
+ }
+
+ retval = asn1_encode_oid(buf, val->algorithm.algorithm.length,
+ val->algorithm.algorithm.data,
+ &length);
+
+ if(retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ sum += length;
+
+ retval = asn1_make_etag(buf, UNIVERSAL, ASN1_SEQUENCE,
+ val->algorithm.parameters.length + length,
+ &length);
+
+ if(retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ sum += length;
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_algorithm_identifier(asn1buf *buf, const krb5_algorithm_identifier **val, unsigned int *retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++);
+ for(i--; i>=0; i--){
+ retval = asn1_encode_algorithm_identifier(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_auth_pack(asn1buf *buf, const krb5_auth_pack *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->clientDHNonce.length != 0)
+ asn1_addlenfield(val->clientDHNonce.length, val->clientDHNonce.data, 3, asn1_encode_octetstring);
+ if (val->supportedCMSTypes != NULL)
+ asn1_addfield((const krb5_algorithm_identifier **)val->supportedCMSTypes,2,asn1_encode_sequence_of_algorithm_identifier);
+ if (val->clientPublicValue != NULL)
+ asn1_addfield(val->clientPublicValue,1,asn1_encode_subject_pk_info);
+ asn1_addfield(&(val->pkAuthenticator),0,asn1_encode_pk_authenticator);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_auth_pack_draft9(asn1buf *buf, const krb5_auth_pack_draft9 *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->clientPublicValue != NULL)
+ asn1_addfield(val->clientPublicValue, 1, asn1_encode_subject_pk_info);
+ asn1_addfield(&(val->pkAuthenticator), 0, asn1_encode_pk_authenticator_draft9);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_external_principal_identifier(asn1buf *buf, const krb5_external_principal_identifier *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ /* Verify there is something to encode */
+ if (val->subjectKeyIdentifier.length == 0 && val->issuerAndSerialNumber.length == 0 && val->subjectName.length == 0)
+ return ASN1_MISSING_FIELD;
+
+ if (val->subjectKeyIdentifier.length != 0)
+ asn1_insert_implicit_octetstring(val->subjectKeyIdentifier.length,val->subjectKeyIdentifier.data,2);
+
+ if (val->issuerAndSerialNumber.length != 0)
+ asn1_insert_implicit_octetstring(val->issuerAndSerialNumber.length,val->issuerAndSerialNumber.data,1);
+
+ if (val->subjectName.length != 0)
+ asn1_insert_implicit_octetstring(val->subjectName.length,val->subjectName.data,0);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_external_principal_identifier(asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++);
+ for(i--; i>=0; i--){
+ retval = asn1_encode_external_principal_identifier(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_pa_pk_as_req(asn1buf *buf, const krb5_pa_pk_as_req *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->kdcPkId.length != 0)
+ asn1_insert_implicit_octetstring(val->kdcPkId.length,val->kdcPkId.data,2);
+
+ if (val->trustedCertifiers != NULL)
+ asn1_addfield((const krb5_external_principal_identifier **)val->trustedCertifiers,1,asn1_encode_sequence_of_external_principal_identifier);
+
+ asn1_insert_implicit_octetstring(val->signedAuthPack.length,val->signedAuthPack.data,0);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_trusted_ca(asn1buf *buf, const krb5_trusted_ca *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ switch (val->choice) {
+ case choice_trusted_cas_issuerAndSerial:
+ asn1_insert_implicit_octetstring(val->u.issuerAndSerial.length,val->u.issuerAndSerial.data,2);
+ break;
+ case choice_trusted_cas_caName:
+ asn1_insert_implicit_octetstring(val->u.caName.length,val->u.caName.data,1);
+ break;
+ case choice_trusted_cas_principalName:
+ asn1_addfield_implicit(val->u.principalName,0,asn1_encode_principal_name);
+ break;
+ default:
+ return ASN1_MISSING_FIELD;
+ }
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_trusted_ca(asn1buf *buf, const krb5_trusted_ca **val, unsigned int *retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++);
+ for(i--; i>=0; i--){
+ retval = asn1_encode_trusted_ca(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_pa_pk_as_req_draft9(asn1buf *buf, const krb5_pa_pk_as_req_draft9 *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->encryptionCert.length != 0)
+ asn1_insert_implicit_octetstring(val->encryptionCert.length,val->encryptionCert.data,3);
+
+ if (val->kdcCert.length != 0)
+ asn1_insert_implicit_octetstring(val->kdcCert.length,val->kdcCert.data,2);
+
+ if (val->trustedCertifiers != NULL)
+ asn1_addfield((const krb5_trusted_ca **)val->trustedCertifiers,1,asn1_encode_sequence_of_trusted_ca);
+
+ asn1_insert_implicit_octetstring(val->signedAuthPack.length,val->signedAuthPack.data,0);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_dh_rep_info(asn1buf *buf, const krb5_dh_rep_info *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->serverDHNonce.length != 0)
+ asn1_insert_implicit_octetstring(val->serverDHNonce.length,val->serverDHNonce.data,1);
+
+ asn1_insert_implicit_octetstring(val->dhSignedData.length,val->dhSignedData.data,0);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_kdc_dh_key_info(asn1buf *buf, const krb5_kdc_dh_key_info *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ if (val->dhKeyExpiration != 0)
+ asn1_addfield(val->dhKeyExpiration, 2, asn1_encode_kerberos_time);
+ asn1_addfield(val->nonce, 1, asn1_encode_integer);
+
+ asn1_insert_implicit_bitstring(val->subjectPublicKey.length,val->subjectPublicKey.data,3);
+ retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, 0,
+ val->subjectPublicKey.length + 1 + length,
+ &length);
+ if(retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ sum += length;
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_reply_key_pack(asn1buf *buf, const krb5_reply_key_pack *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ asn1_addfield(&(val->asChecksum), 1, asn1_encode_checksum);
+ asn1_addfield(&(val->replyKey), 0, asn1_encode_encryption_key);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_reply_key_pack_draft9(asn1buf *buf, const krb5_reply_key_pack_draft9 *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ asn1_addfield(val->nonce, 1, asn1_encode_integer);
+ asn1_addfield(&(val->replyKey), 0, asn1_encode_encryption_key);
+
+ asn1_makeseq();
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_pa_pk_as_rep(asn1buf *buf, const krb5_pa_pk_as_rep *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ switch (val->choice)
+ {
+ case choice_pa_pk_as_rep_dhInfo:
+ asn1_addfield(&(val->u.dh_Info), choice_pa_pk_as_rep_dhInfo, asn1_encode_dh_rep_info);
+ break;
+ case choice_pa_pk_as_rep_encKeyPack:
+ asn1_insert_implicit_octetstring(val->u.encKeyPack.length,val->u.encKeyPack.data,1);
+ break;
+ default:
+ return ASN1_MISSING_FIELD;
+ }
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_pa_pk_as_rep_draft9(asn1buf *buf, const krb5_pa_pk_as_rep_draft9 *val, unsigned int *retlen)
+{
+ asn1_setup();
+
+ switch (val->choice)
+ {
+ case choice_pa_pk_as_rep_draft9_dhSignedData:
+ asn1_insert_implicit_octetstring(val->u.dhSignedData.length,val->u.dhSignedData.data,0);
+ break;
+ case choice_pa_pk_as_rep_encKeyPack:
+ asn1_insert_implicit_octetstring(val->u.encKeyPack.length,val->u.encKeyPack.data,1);
+ break;
+ default:
+ return ASN1_MISSING_FIELD;
+ }
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_td_trusted_certifiers(asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen)
+{
+ asn1_setup();
+ retval = asn1_encode_sequence_of_external_principal_identifier(buf, val, &length);
+ if (retval) {
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_sequence_of_typed_data(asn1buf *buf, const krb5_typed_data **val, unsigned int *retlen)
+{
+ asn1_setup();
+ int i;
+
+ if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD;
+
+ for(i=0; val[i] != NULL; i++);
+ for(i--; i>=0; i--){
+ retval = asn1_encode_typed_data(buf,val[i],&length);
+ if(retval) return retval;
+ sum += length;
+ }
+ asn1_makeseq();
+
+ asn1_cleanup();
+}
+
+asn1_error_code asn1_encode_typed_data(asn1buf *buf, const krb5_typed_data *val, unsigned int *retlen)
+{
+ asn1_setup();
+ asn1_addlenfield(val->length, val->data, 1, asn1_encode_octetstring);
+ asn1_addfield(val->type, 0, asn1_encode_integer);
+ asn1_makeseq();
+ asn1_cleanup();
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_encode.h b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_encode.h
index 546e72b1d6..b5f24c42b7 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_encode.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/asn1_k_encode.h
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* src/lib/krb5/asn.1/asn1_k_encode.h
*
@@ -271,4 +269,71 @@ asn1_error_code asn1_encode_predicted_sam_response
asn1_error_code asn1_encode_krb_saved_safe_body
(asn1buf *buf, const krb5_data *body, unsigned int *retlen);
+/* PKINIT */
+
+asn1_error_code asn1_encode_pk_authenticator
+ (asn1buf *buf, const krb5_pk_authenticator *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_pk_authenticator_draft9
+ (asn1buf *buf, const krb5_pk_authenticator_draft9 *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_algorithm_identifier
+ (asn1buf *buf, const krb5_algorithm_identifier *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_subject_pk_info
+ (asn1buf *buf, const krb5_subject_pk_info *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_sequence_of_algorithm_identifier
+ (asn1buf *buf, const krb5_algorithm_identifier **val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_auth_pack
+ (asn1buf *buf, const krb5_auth_pack *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_auth_pack_draft9
+ (asn1buf *buf, const krb5_auth_pack_draft9 *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_external_principal_identifier
+ (asn1buf *buf, const krb5_external_principal_identifier *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_sequence_of_external_principal_identifier
+ (asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_pa_pk_as_req
+ (asn1buf *buf, const krb5_pa_pk_as_req *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_trusted_ca
+ (asn1buf *buf, const krb5_trusted_ca *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_sequence_of_trusted_ca
+ (asn1buf *buf, const krb5_trusted_ca **val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_pa_pk_as_req_draft9
+ (asn1buf *buf, const krb5_pa_pk_as_req_draft9 *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_dh_rep_info
+ (asn1buf *buf, const krb5_dh_rep_info *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_kdc_dh_key_info
+ (asn1buf *buf, const krb5_kdc_dh_key_info *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_reply_key_pack
+ (asn1buf *buf, const krb5_reply_key_pack *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_reply_key_pack_draft9
+ (asn1buf *buf, const krb5_reply_key_pack_draft9 *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_pa_pk_as_rep
+ (asn1buf *buf, const krb5_pa_pk_as_rep *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_pa_pk_as_rep_draft9
+ (asn1buf *buf, const krb5_pa_pk_as_rep_draft9 *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_td_trusted_certifiers
+ (asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_typed_data
+ (asn1buf *buf, const krb5_typed_data *val, unsigned int *retlen);
+
+asn1_error_code asn1_encode_sequence_of_typed_data
+ (asn1buf *buf, const krb5_typed_data **val, unsigned int *retlen);
#endif
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krb5_decode.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krb5_decode.c
index 9fec5ecee1..cbd6a12941 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krb5_decode.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krb5_decode.c
@@ -1,11 +1,4 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* src/lib/krb5/asn.1/krb5_decode.c
*
* Copyright 1994 by the Massachusetts Institute of Technology.
@@ -31,7 +24,7 @@
* or implied warranty.
*/
-#include "krb5.h"
+#include "k5-int.h"
#include "krbasn1.h"
#include "asn1_k_decode.h"
#include "asn1_decode.h"
@@ -533,6 +526,7 @@ krb5_error_code decode_krb5_safe_with_body(
setup();
alloc_field(*rep,krb5_safe);
clear_field(rep,checksum);
+ tmpbody.magic = 0;
check_apptag(20);
{ begin_structure();
@@ -940,3 +934,150 @@ krb5_error_code decode_krb5_predicted_sam_response(const krb5_data *code, krb5_p
cleanup(free);
}
+krb5_error_code decode_krb5_pa_pk_as_req(const krb5_data *code, krb5_pa_pk_as_req **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_pa_pk_as_req);
+
+ retval = asn1_decode_pa_pk_as_req(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_pa_pk_as_req_draft9(const krb5_data *code, krb5_pa_pk_as_req_draft9 **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_pa_pk_as_req_draft9);
+
+ retval = asn1_decode_pa_pk_as_req_draft9(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_pa_pk_as_rep(const krb5_data *code, krb5_pa_pk_as_rep **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_pa_pk_as_rep);
+
+ retval = asn1_decode_pa_pk_as_rep(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_pa_pk_as_rep_draft9(const krb5_data *code, krb5_pa_pk_as_rep_draft9 **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_pa_pk_as_rep_draft9);
+
+ retval = asn1_decode_pa_pk_as_rep_draft9(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_auth_pack(const krb5_data *code, krb5_auth_pack **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_auth_pack);
+
+ retval = asn1_decode_auth_pack(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_auth_pack_draft9(const krb5_data *code, krb5_auth_pack_draft9 **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_auth_pack_draft9);
+
+ retval = asn1_decode_auth_pack_draft9(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_kdc_dh_key_info(const krb5_data *code, krb5_kdc_dh_key_info **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_kdc_dh_key_info);
+
+ retval = asn1_decode_kdc_dh_key_info(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_principal_name(const krb5_data *code, krb5_principal_data **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_principal_data);
+
+ retval = asn1_decode_krb5_principal_name(&buf, rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_reply_key_pack(const krb5_data *code, krb5_reply_key_pack **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_reply_key_pack);
+
+ retval = asn1_decode_reply_key_pack(&buf, *rep);
+ if (retval)
+ goto error_out;
+
+ cleanup_manual();
+error_out:
+ if (rep && *rep) {
+ if ((*rep)->replyKey.contents)
+ free((*rep)->replyKey.contents);
+ if ((*rep)->asChecksum.contents)
+ free((*rep)->asChecksum.contents);
+ free(*rep);
+ *rep = NULL;
+ }
+ return retval;
+}
+
+krb5_error_code decode_krb5_reply_key_pack_draft9(const krb5_data *code, krb5_reply_key_pack_draft9 **rep)
+{
+ setup_buf_only();
+ alloc_field(*rep, krb5_reply_key_pack_draft9);
+
+ retval = asn1_decode_reply_key_pack_draft9(&buf, *rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_typed_data(const krb5_data *code, krb5_typed_data ***rep)
+{
+ setup_buf_only();
+ retval = asn1_decode_sequence_of_typed_data(&buf, rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_td_trusted_certifiers(const krb5_data *code, krb5_external_principal_identifier ***rep)
+{
+ setup_buf_only();
+ retval = asn1_decode_sequence_of_external_principal_identifier(&buf, rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code decode_krb5_td_dh_parameters(const krb5_data *code, krb5_algorithm_identifier ***rep)
+{
+ setup_buf_only();
+ retval = asn1_decode_sequence_of_algorithm_identifier(&buf, rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krb5_encode.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krb5_encode.c
index 4b1d62dd9d..4cb800de6f 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krb5_encode.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krb5_encode.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* src/lib/krb5/asn.1/krb5_encode.c
@@ -26,7 +25,7 @@
* or implied warranty.
*/
-#include "krb5.h"
+#include "k5-int.h"
#include "asn1_k_encode.h"
#include "asn1_encode.h"
#include "krbasn1.h"
@@ -699,6 +698,23 @@ krb5_error_code encode_krb5_authdata(const krb5_authdata **rep, krb5_data **code
krb5_cleanup();
}
+krb5_error_code encode_krb5_authdata_elt(const krb5_authdata *rep, krb5_data **code)
+{
+ asn1_error_code retval;
+ asn1buf *buf=NULL;
+ unsigned int length;
+
+ if(rep == NULL) return ASN1_MISSING_FIELD;
+
+ retval = asn1buf_create(&buf);
+ if(retval) return retval;
+
+ retval = asn1_encode_krb5_authdata_elt(buf,rep, &length);
+ if(retval) return retval;
+
+ krb5_cleanup();
+}
+
krb5_error_code encode_krb5_alt_method(const krb5_alt_method *rep, krb5_data **code)
{
krb5_setup();
@@ -883,9 +899,118 @@ krb5_error_code encode_krb5_setpw_req(const krb5_principal target,
krb5_addfield(target,2,asn1_encode_realm);
krb5_addfield(target,1,asn1_encode_principal_name);
+ /* Solaris Kerberos */
krb5_addlenfield(strlen(password), (const unsigned char *)password,0,asn1_encode_octetstring);
krb5_makeseq();
krb5_cleanup();
}
+
+krb5_error_code encode_krb5_pa_pk_as_req(const krb5_pa_pk_as_req *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_pa_pk_as_req(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_pa_pk_as_req_draft9(const krb5_pa_pk_as_req_draft9 *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_pa_pk_as_req_draft9(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_pa_pk_as_rep(const krb5_pa_pk_as_rep *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_pa_pk_as_rep(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_pa_pk_as_rep_draft9(const krb5_pa_pk_as_rep_draft9 *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_pa_pk_as_rep_draft9(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_auth_pack(const krb5_auth_pack *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_auth_pack(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_auth_pack_draft9(const krb5_auth_pack_draft9 *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_auth_pack_draft9(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_kdc_dh_key_info(const krb5_kdc_dh_key_info *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_kdc_dh_key_info(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_reply_key_pack(const krb5_reply_key_pack *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_reply_key_pack(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_reply_key_pack_draft9(const krb5_reply_key_pack_draft9 *rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_reply_key_pack_draft9(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_td_trusted_certifiers(const krb5_external_principal_identifier **rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_td_trusted_certifiers(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_typed_data(const krb5_typed_data **rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_sequence_of_typed_data(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_td_dh_parameters(const krb5_algorithm_identifier **rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_sequence_of_algorithm_identifier(buf,rep,&length);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krbasn1.h b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krbasn1.h
index df3237260b..7a45298ada 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krbasn1.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/asn.1/krbasn1.h
@@ -1,9 +1,7 @@
#ifndef __KRBASN1_H__
#define __KRBASN1_H__
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <k5-int.h>
+#include "k5-int.h"
#include <stdio.h>
#include <errno.h>
#include <limits.h> /* For INT_MAX */
@@ -59,7 +57,7 @@ typedef int asn1_tagnum;
#define ASN1_OCTETSTRING 4
#define ASN1_NULL 5
#define ASN1_OBJECTIDENTIFIER 6
-#define ASN1_ENUMERATED 10
+#define ASN1_ENUMERATED 10
#define ASN1_SEQUENCE 16
#define ASN1_SET 17
#define ASN1_PRINTABLESTRING 19
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc-int.h b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc-int.h
index eac6ed7295..430e4c3755 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc-int.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc-int.h
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/krb5/ccache/file/cc-int.h
*
@@ -45,6 +43,7 @@ void
krb5int_cc_finalize(void);
extern k5_mutex_t krb5int_mcc_mutex;
+extern k5_mutex_t krb5int_krcc_mutex;
extern k5_mutex_t krb5int_cc_file_mutex;
#endif /* __KRB5_CCACHE_H__ */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_file.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_file.c
index 17302a9d38..724dacb24e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_file.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_file.c
@@ -34,8 +34,6 @@
* implementation of file-based credentials cache
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
If OPENCLOSE is defined, each of the functions opens and closes the
file whenever it needs to access it. Otherwise, the file is opened
@@ -86,8 +84,6 @@ etc.
#include <syslog.h> /* Solaris Kerberos */
#include <ctype.h>
-#define NEED_SOCKETS /* Only for ntohs, etc. */
-#define NEED_LOWLEVEL_IO
#include <stdio.h>
#include <errno.h>
@@ -443,9 +439,9 @@ krb5_fcc_read(krb5_context context, krb5_ccache id, krb5_pointer buf, unsigned i
* KRB5_CC_NOMEM
*/
-#define ALLOC(NUM,TYPE) \
- (((NUM) <= (((size_t)0-1)/ sizeof(TYPE))) \
- ? (TYPE *) calloc((NUM), sizeof(TYPE)) \
+#define ALLOC(NUM,TYPE) \
+ (((NUM) <= (((size_t)0-1)/ sizeof(TYPE))) \
+ ? (TYPE *) calloc((NUM), sizeof(TYPE)) \
: (errno = ENOMEM,(TYPE *) 0))
static krb5_error_code
@@ -458,7 +454,9 @@ krb5_fcc_read_principal(krb5_context context, krb5_ccache id, krb5_principal *pr
int i;
k5_assert_locked(&((krb5_fcc_data *) id->data)->lock);
-
+
+ *princ = NULL;
+
if (data->version == KRB5_FCC_FVNO_1) {
type = KRB5_NT_UNKNOWN;
} else {
@@ -554,15 +552,18 @@ krb5_fcc_read_addrs(krb5_context context, krb5_ccache id, krb5_address ***addrs)
if ((*addrs)[i] == NULL) {
krb5_free_addresses(context, *addrs);
return KRB5_CC_NOMEM;
- }
+ }
+ (*addrs)[i]->contents = NULL;
kret = krb5_fcc_read_addr(context, id, (*addrs)[i]);
CHECK(kret);
}
return KRB5_OK;
errout:
- if (*addrs)
+ if (*addrs) {
krb5_free_addresses(context, *addrs);
+ *addrs = NULL;
+ }
return kret;
}
@@ -599,6 +600,7 @@ krb5_fcc_read_keyblock(krb5_context context, krb5_ccache id, krb5_keyblock *keyb
return KRB5_CC_NOMEM;
if ( keyblock->length == 0 )
return KRB5_OK;
+ /* Solaris Kerberos */
keyblock->contents = calloc(keyblock->length, sizeof(krb5_octet));
if (keyblock->contents == NULL)
return KRB5_CC_NOMEM;
@@ -609,8 +611,10 @@ krb5_fcc_read_keyblock(krb5_context context, krb5_ccache id, krb5_keyblock *keyb
return KRB5_OK;
errout:
- if (keyblock->contents)
+ if (keyblock->contents) {
krb5_xfree(keyblock->contents);
+ keyblock->contents = NULL;
+ }
return kret;
}
@@ -648,8 +652,10 @@ krb5_fcc_read_data(krb5_context context, krb5_ccache id, krb5_data *data)
data->data[data->length] = 0; /* Null terminate, just in case.... */
return KRB5_OK;
errout:
- if (data->data)
+ if (data->data) {
krb5_xfree(data->data);
+ data->data = NULL;
+ }
return kret;
}
@@ -691,8 +697,10 @@ krb5_fcc_read_addr(krb5_context context, krb5_ccache id, krb5_address *addr)
return KRB5_OK;
errout:
- if (addr->contents)
+ if (addr->contents) {
krb5_xfree(addr->contents);
+ addr->contents = NULL;
+ }
return kret;
}
@@ -820,15 +828,18 @@ krb5_fcc_read_authdata(krb5_context context, krb5_ccache id, krb5_authdata ***a)
if ((*a)[i] == NULL) {
krb5_free_authdata(context, *a);
return KRB5_CC_NOMEM;
- }
+ }
+ (*a)[i]->contents = NULL;
kret = krb5_fcc_read_authdatum(context, id, (*a)[i]);
CHECK(kret);
}
return KRB5_OK;
errout:
- if (*a)
+ if (*a) {
krb5_free_authdata(context, *a);
+ *a = NULL;
+ }
return kret;
}
@@ -869,8 +880,10 @@ krb5_fcc_read_authdatum(krb5_context context, krb5_ccache id, krb5_authdata *a)
return KRB5_OK;
errout:
- if (a->contents)
+ if (a->contents) {
krb5_xfree(a->contents);
+ a->contents = NULL;
+ }
return kret;
}
@@ -1202,8 +1215,7 @@ krb5_fcc_close_file (krb5_context context, krb5_fcc_data *data)
((SIZE) < BUFSIZE ? (abort(),0) : setbuf(FILE, BUF))
#endif
-
-
+/* Solaris Kerberos */
static krb5_error_code
krb5_fcc_open_nounlink(char *filename, int open_flag, int *ret_fd, int *new)
{
@@ -1357,6 +1369,7 @@ krb5_fcc_open_file (krb5_context context, krb5_ccache id, int mode)
}
switch(mode) {
+ /* Solaris Kerberos */
case FCC_OPEN_AND_ERASE_NOUNLINK:
open_flag = O_RDWR;
break;
@@ -1397,9 +1410,8 @@ fcc_retry:
lock_flag = KRB5_LOCKMODE_SHARED;
else
lock_flag = KRB5_LOCKMODE_EXCLUSIVE;
-
if ((retval = krb5_lock_file(context, f, lock_flag))) {
- (void) close(f);
+ (void) close(f);
if (retval == EAGAIN && retries++ < LOCK_RETRIES) {
/* Solaris Kerberos wait some time before retrying */
if (poll(NULL, 0, WAIT_LENGTH) == 0)
@@ -1432,7 +1444,7 @@ fcc_retry:
KRB5_CC_IO);
goto done;
}
- data->file = f;
+ data->file = f;
if (data->version == KRB5_FCC_FVNO_4) {
/* V4 of the credentials cache format allows for header tags */
@@ -1983,13 +1995,13 @@ krb5_fcc_start_seq_get(krb5_context context, krb5_ccache id,
/* Make sure we start reading right after the primary principal */
kret = krb5_fcc_skip_header(context, id);
if (kret) {
- /* SUNW14resync - fix mem leak */
+ /* Solaris Kerberos - fix mem leak */
krb5_xfree(fcursor);
goto done;
}
kret = krb5_fcc_skip_principal(context, id);
if (kret) {
- /* SUNW14resync - fix mem leak */
+ /* Solaris Kerberos - fix mem leak */
krb5_xfree(fcursor);
goto done;
}
@@ -2132,115 +2144,165 @@ krb5_fcc_generate_new (krb5_context context, krb5_ccache *id)
{
krb5_ccache lid;
int ret;
- krb5_error_code retcode = 0;
+ krb5_error_code kret = 0;
char scratch[sizeof(TKT_ROOT)+6+1]; /* +6 for the scratch part, +1 for
NUL */
krb5_fcc_data *data;
+ krb5_int16 fcc_fvno = htons(context->fcc_default_format);
+ krb5_int16 fcc_flen = 0;
+ int errsave, cnt;
+ struct fcc_set *setptr;
- /* Allocate memory */
- lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
- if (lid == NULL)
- return KRB5_CC_NOMEM;
-
- lid->ops = &krb5_fcc_ops;
+ /* Set master lock */
+ kret = k5_mutex_lock(&krb5int_cc_file_mutex);
+ if (kret)
+ return kret;
(void) strcpy(scratch, TKT_ROOT);
(void) strcat(scratch, "XXXXXX");
#ifdef HAVE_MKSTEMP
ret = mkstemp(scratch);
if (ret == -1) {
+ k5_mutex_unlock(&krb5int_cc_file_mutex);
return krb5_fcc_interpret(context, errno);
- } else close(ret);
+ }
#else /*HAVE_MKSTEMP*/
mktemp(scratch);
+ /* Make sure the file name is reserved */
+ ret = THREEPARAMOPEN(scratch, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0);
+ if (ret == -1) {
+ return krb5_fcc_interpret(context, errno);
+ }
#endif
- lid->data = (krb5_pointer) malloc(sizeof(krb5_fcc_data));
- if (lid->data == NULL) {
- krb5_xfree(lid);
+ /* Allocate memory */
+ data = (krb5_pointer) malloc(sizeof(krb5_fcc_data));
+ if (data == NULL) {
+ close(ret);
+ unlink(scratch);
+ k5_mutex_unlock(&krb5int_cc_file_mutex);
return KRB5_CC_NOMEM;
}
- ((krb5_fcc_data *) lid->data)->filename = (char *)
- malloc(strlen(scratch) + 1);
- if (((krb5_fcc_data *) lid->data)->filename == NULL) {
- krb5_xfree(((krb5_fcc_data *) lid->data));
- krb5_xfree(lid);
+ data->filename = strdup(scratch);
+ if (data->filename == NULL) {
+ k5_mutex_unlock(&krb5int_cc_file_mutex);
+ free(data);
+ close(ret);
+ unlink(scratch);
+ k5_mutex_unlock(&krb5int_cc_file_mutex);
return KRB5_CC_NOMEM;
}
+ kret = k5_mutex_init(&data->lock);
+ if (kret) {
+ k5_mutex_unlock(&krb5int_cc_file_mutex);
+ free(data->filename);
+ free(data);
+ close(ret);
+ unlink(scratch);
+ return kret;
+ }
+ kret = k5_mutex_lock(&data->lock);
+ if (kret) {
+ k5_mutex_unlock(&krb5int_cc_file_mutex);
+ k5_mutex_destroy(&data->lock);
+ free(data->filename);
+ free(data);
+ close(ret);
+ unlink(scratch);
+ return kret;
+ }
+
/*
* The file is initially closed at the end of this call...
*/
- ((krb5_fcc_data *) lid->data)->flags = 0;
- ((krb5_fcc_data *) lid->data)->file = -1;
- ((krb5_fcc_data *) lid->data)->valid_bytes = 0;
- data = (krb5_fcc_data *) lid->data;
-
- retcode = k5_mutex_init(&data->lock);
- if (retcode)
- goto err_out;
+ data->flags = 0;
+ data->file = -1;
+ data->valid_bytes = 0;
+ /* data->version,mode filled in for real later */
+ data->version = data->mode = 0;
- /* Set up the filename */
- strcpy(((krb5_fcc_data *) lid->data)->filename, scratch);
- /* Make sure the file name is reserved */
- ret = THREEPARAMOPEN(((krb5_fcc_data *) lid->data)->filename,
- O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0);
- if (ret == -1) {
- retcode = krb5_fcc_interpret(context, errno);
- goto err_out;
- } else {
- krb5_int16 fcc_fvno = htons(context->fcc_default_format);
- krb5_int16 fcc_flen = 0;
- int errsave, cnt;
-
- /* Ignore user's umask, set mode = 0600 */
+ /* Ignore user's umask, set mode = 0600 */
#ifndef HAVE_FCHMOD
#ifdef HAVE_CHMOD
- chmod(((krb5_fcc_data *) lid->data)->filename, S_IRUSR | S_IWUSR);
+ chmod(data->filename, S_IRUSR | S_IWUSR);
#endif
#else
- fchmod(ret, S_IRUSR | S_IWUSR);
+ fchmod(ret, S_IRUSR | S_IWUSR);
#endif
- if ((cnt = write(ret, (char *)&fcc_fvno, sizeof(fcc_fvno)))
- != sizeof(fcc_fvno)) {
- errsave = errno;
- (void) close(ret);
- (void) unlink(((krb5_fcc_data *) lid->data)->filename);
- retcode = (cnt == -1) ? krb5_fcc_interpret(context, errsave) : KRB5_CC_IO;
- goto err_out;
- }
- /* For version 4 we save a length for the rest of the header */
- if (context->fcc_default_format == KRB5_FCC_FVNO_4) {
- if ((cnt = write(ret, (char *)&fcc_flen, sizeof(fcc_flen)))
- != sizeof(fcc_flen)) {
- errsave = errno;
- (void) close(ret);
- (void) unlink(((krb5_fcc_data *) lid->data)->filename);
- retcode = (cnt == -1) ? krb5_fcc_interpret(context, errsave) : KRB5_CC_IO;
- goto err_out;
- }
- }
- if (close(ret) == -1) {
- errsave = errno;
- (void) unlink(((krb5_fcc_data *) lid->data)->filename);
- retcode = krb5_fcc_interpret(context, errsave);
- goto err_out;
+ if ((cnt = write(ret, (char *)&fcc_fvno, sizeof(fcc_fvno)))
+ != sizeof(fcc_fvno)) {
+ errsave = errno;
+ (void) close(ret);
+ (void) unlink(data->filename);
+ kret = (cnt == -1) ? krb5_fcc_interpret(context, errsave) : KRB5_CC_IO;
+ goto err_out;
+ }
+ /* For version 4 we save a length for the rest of the header */
+ if (context->fcc_default_format == KRB5_FCC_FVNO_4) {
+ if ((cnt = write(ret, (char *)&fcc_flen, sizeof(fcc_flen)))
+ != sizeof(fcc_flen)) {
+ errsave = errno;
+ (void) close(ret);
+ (void) unlink(data->filename);
+ kret = (cnt == -1) ? krb5_fcc_interpret(context, errsave) : KRB5_CC_IO;
+ goto err_out;
}
- *id = lid;
- /* default to open/close on every trn - otherwise destroy
- will get as to state confused */
- ((krb5_fcc_data *) lid->data)->flags = KRB5_TC_OPENCLOSE;
- krb5_change_cache ();
- return KRB5_OK;
}
+ if (close(ret) == -1) {
+ errsave = errno;
+ (void) unlink(data->filename);
+ kret = krb5_fcc_interpret(context, errsave);
+ goto err_out;
+ }
+
+
+ setptr = malloc(sizeof(struct fcc_set));
+ if (setptr == NULL) {
+ k5_mutex_unlock(&krb5int_cc_file_mutex);
+ k5_mutex_destroy(&data->lock);
+ free(data->filename);
+ free(data);
+ (void) close(ret);
+ (void) unlink(scratch);
+ return KRB5_CC_NOMEM;
+ }
+ setptr->refcount = 1;
+ setptr->data = data;
+ setptr->next = fccs;
+ fccs = setptr;
+ k5_mutex_unlock(&krb5int_cc_file_mutex);
+
+ k5_mutex_assert_locked(&data->lock);
+ k5_mutex_unlock(&data->lock);
+ lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
+ if (lid == NULL) {
+ dereference(context, data);
+ return KRB5_CC_NOMEM;
+ }
+
+ lid->ops = &krb5_fcc_ops;
+ lid->data = data;
+ lid->magic = KV5M_CCACHE;
+
+ /* default to open/close on every trn - otherwise destroy
+ will get as to state confused */
+ ((krb5_fcc_data *) lid->data)->flags = KRB5_TC_OPENCLOSE;
+
+ *id = lid;
+
+
+ krb5_change_cache ();
+ return KRB5_OK;
err_out:
- krb5_xfree(((krb5_fcc_data *) lid->data)->filename);
- krb5_xfree(((krb5_fcc_data *) lid->data));
- krb5_xfree(lid);
- return retcode;
+ k5_mutex_unlock(&krb5int_cc_file_mutex);
+ k5_mutex_destroy(&data->lock);
+ free(data->filename);
+ free(data);
+ return kret;
}
/*
@@ -2412,6 +2474,30 @@ krb5_fcc_set_flags(krb5_context context, krb5_ccache id, krb5_flags flags)
return ret;
}
+/*
+ * Requires:
+ * id is a cred cache returned by krb5_fcc_resolve or
+ * krb5_fcc_generate_new, but has not been opened by krb5_fcc_initialize.
+ *
+ * Modifies:
+ * id (mutex only; temporary)
+ *
+ * Effects:
+ * Returns the operational flags of id.
+ */
+static krb5_error_code KRB5_CALLCONV
+krb5_fcc_get_flags(krb5_context context, krb5_ccache id, krb5_flags *flags)
+{
+ krb5_error_code ret = KRB5_OK;
+
+ ret = k5_mutex_lock(&((krb5_fcc_data *) id->data)->lock);
+ if (ret)
+ return ret;
+ *flags = ((krb5_fcc_data *) id->data)->flags;
+ k5_mutex_unlock(&((krb5_fcc_data *) id->data)->lock);
+ return ret;
+}
+
static krb5_error_code
krb5_fcc_interpret(krb5_context context, int errnum)
@@ -2459,6 +2545,9 @@ krb5_fcc_interpret(krb5_context context, int errnum)
case ENXIO:
default:
retval = KRB5_CC_IO; /* XXX */
+ krb5_set_error_message(context, retval,
+ "Credentials cache I/O operation failed (%s)",
+ strerror(errnum));
}
return retval;
}
@@ -2480,6 +2569,7 @@ const krb5_cc_ops krb5_fcc_ops = {
krb5_fcc_end_seq_get,
krb5_fcc_remove_cred,
krb5_fcc_set_flags,
+ krb5_fcc_get_flags,
};
#if defined(_WIN32)
@@ -2540,4 +2630,11 @@ const krb5_cc_ops krb5_cc_file_ops = {
krb5_fcc_end_seq_get,
krb5_fcc_remove_cred,
krb5_fcc_set_flags,
+ krb5_fcc_get_flags,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
};
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_memory.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_memory.c
index 0d7b7e02cd..6e6a9b4f15 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_memory.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_memory.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/ccache/cc_memory.c
@@ -82,6 +81,19 @@ static krb5_error_code KRB5_CALLCONV krb5_mcc_store
static krb5_error_code KRB5_CALLCONV krb5_mcc_set_flags
(krb5_context, krb5_ccache id , krb5_flags flags );
+static krb5_error_code KRB5_CALLCONV krb5_mcc_ptcursor_new(
+ krb5_context,
+ krb5_cc_ptcursor *);
+
+static krb5_error_code KRB5_CALLCONV krb5_mcc_ptcursor_next(
+ krb5_context,
+ krb5_cc_ptcursor,
+ krb5_ccache *);
+
+static krb5_error_code KRB5_CALLCONV krb5_mcc_ptcursor_free(
+ krb5_context,
+ krb5_cc_ptcursor *);
+
extern const krb5_cc_ops krb5_mcc_ops;
extern krb5_error_code krb5_change_cache (void);
@@ -104,6 +116,10 @@ typedef struct krb5_mcc_list_node {
krb5_mcc_data *cache;
} krb5_mcc_list_node;
+struct krb5_mcc_ptcursor_data {
+ struct krb5_mcc_list_node *cur;
+};
+
k5_mutex_t krb5int_mcc_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
static krb5_mcc_list_node *mcc_head = 0;
@@ -242,7 +258,7 @@ krb5_mcc_resolve (krb5_context context, krb5_ccache *id, const char *residual)
err = k5_mutex_lock(&krb5int_mcc_mutex);
if (err) {
- /* SUNW14resync - fix mem leak */
+ /* Solaris Kerberos - fix mem leak */
krb5_xfree(lid);
return err;
}
@@ -450,6 +466,8 @@ new_mcc_data (const char *name, krb5_mcc_data **dataptr)
return 0;
}
+static krb5_error_code random_string (krb5_context, char *, unsigned int);
+
/*
* Effects:
* Creates a new file cred cache whose name is guaranteed to be
@@ -464,11 +482,12 @@ new_mcc_data (const char *name, krb5_mcc_data **dataptr)
* krb5_ccache. id is undefined.
* system errors (from open)
*/
+
krb5_error_code KRB5_CALLCONV
krb5_mcc_generate_new (krb5_context context, krb5_ccache *id)
{
krb5_ccache lid;
- char scratch[6+1]; /* 6 for the scratch part, +1 for NUL */
+ char uniquename[8];
krb5_error_code err;
krb5_mcc_data *d;
@@ -478,27 +497,78 @@ krb5_mcc_generate_new (krb5_context context, krb5_ccache *id)
return KRB5_CC_NOMEM;
lid->ops = &krb5_mcc_ops;
-
- (void) strcpy(scratch, "XXXXXX");
- mktemp(scratch);
-
+
err = k5_mutex_lock(&krb5int_mcc_mutex);
if (err) {
free(lid);
return err;
}
- err = new_mcc_data(scratch, &d);
+
+ /* Check for uniqueness with mutex locked to avoid race conditions */
+ while (1) {
+ krb5_mcc_list_node *ptr;
+
+ random_string (context, uniquename, sizeof (uniquename));
+
+ for (ptr = mcc_head; ptr; ptr=ptr->next) {
+ if (!strcmp(ptr->cache->name, uniquename)) {
+ break; /* got a match, loop again */
+ }
+ }
+ if (!ptr) break; /* got to the end without finding a match */
+ }
+
+ err = new_mcc_data(uniquename, &d);
+
k5_mutex_unlock(&krb5int_mcc_mutex);
if (err) {
krb5_xfree(lid);
return err;
}
lid->data = d;
- *id = lid; /* SUNW14resync - fix to 1.4.2 */
+ *id = lid;
krb5_change_cache ();
return KRB5_OK;
}
+/* Utility routine: Creates a random memory ccache name.
+ * This algorithm was selected because it creates readable
+ * random ccache names in a fixed size buffer. */
+
+static krb5_error_code
+random_string (krb5_context context, char *string, unsigned int length)
+{
+ static const unsigned char charlist[] =
+ "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ krb5_error_code err = 0;
+ unsigned char *bytes = NULL;
+ unsigned int bytecount = length - 1;
+
+ if (!err) {
+ bytes = malloc (bytecount);
+ if (bytes == NULL) { err = ENOMEM; }
+ }
+
+ if (!err) {
+ krb5_data data;
+ data.length = bytecount;
+ data.data = (char *) bytes;
+ err = krb5_c_random_make_octets (context, &data);
+ }
+
+ if (!err) {
+ unsigned int i;
+ for (i = 0; i < bytecount; i++) {
+ string [i] = charlist[bytes[i] % (sizeof (charlist) - 1)];
+ }
+ string[length - 1] = '\0';
+ }
+
+ if (bytes != NULL) { free (bytes); }
+
+ return err;
+}
+
/*
* Requires:
* id is a file credential cache
@@ -575,6 +645,13 @@ krb5_mcc_set_flags(krb5_context context, krb5_ccache id, krb5_flags flags)
return KRB5_OK;
}
+static krb5_error_code KRB5_CALLCONV
+krb5_mcc_get_flags(krb5_context context, krb5_ccache id, krb5_flags *flags)
+{
+ *flags = 0;
+ return KRB5_OK;
+}
+
/* store: Save away creds in the ccache. */
krb5_error_code KRB5_CALLCONV
krb5_mcc_store(krb5_context ctx, krb5_ccache id, krb5_creds *creds)
@@ -593,7 +670,8 @@ krb5_mcc_store(krb5_context ctx, krb5_ccache id, krb5_creds *creds)
}
err = k5_mutex_lock(&mptr->lock);
if (err) {
- /* SUNW14resync - fix mem leak */
+ /* Solaris Kerberos - fix mem leaks */
+ krb5_free_creds(ctx, new_node->creds);
free(new_node);
return err;
}
@@ -603,6 +681,92 @@ krb5_mcc_store(krb5_context ctx, krb5_ccache id, krb5_creds *creds)
return 0;
}
+static krb5_error_code KRB5_CALLCONV
+krb5_mcc_ptcursor_new(
+ krb5_context context,
+ krb5_cc_ptcursor *cursor)
+{
+ krb5_error_code ret = 0;
+ krb5_cc_ptcursor n = NULL;
+ struct krb5_mcc_ptcursor_data *cdata = NULL;
+
+ *cursor = NULL;
+
+ n = malloc(sizeof(*n));
+ if (n == NULL)
+ return ENOMEM;
+ n->ops = &krb5_mcc_ops;
+ cdata = malloc(sizeof(struct krb5_mcc_ptcursor_data));
+ if (cdata == NULL) {
+ ret = ENOMEM;
+ goto errout;
+ }
+ n->data = cdata;
+ ret = k5_mutex_lock(&krb5int_mcc_mutex);
+ if (ret)
+ goto errout;
+ cdata->cur = mcc_head;
+ ret = k5_mutex_unlock(&krb5int_mcc_mutex);
+ if (ret)
+ goto errout;
+
+errout:
+ if (ret) {
+ krb5_mcc_ptcursor_free(context, &n);
+ }
+ *cursor = n;
+ return ret;
+}
+
+static krb5_error_code KRB5_CALLCONV
+krb5_mcc_ptcursor_next(
+ krb5_context context,
+ krb5_cc_ptcursor cursor,
+ krb5_ccache *ccache)
+{
+ krb5_error_code ret = 0;
+ struct krb5_mcc_ptcursor_data *cdata = NULL;
+
+ *ccache = NULL;
+ cdata = cursor->data;
+ if (cdata->cur == NULL)
+ return 0;
+
+ *ccache = malloc(sizeof(**ccache));
+ if (*ccache == NULL)
+ return ENOMEM;
+
+ (*ccache)->ops = &krb5_mcc_ops;
+ (*ccache)->data = cdata->cur->cache;
+ ret = k5_mutex_lock(&krb5int_mcc_mutex);
+ if (ret)
+ goto errout;
+ cdata->cur = cdata->cur->next;
+ ret = k5_mutex_unlock(&krb5int_mcc_mutex);
+ if (ret)
+ goto errout;
+errout:
+ if (ret && *ccache != NULL) {
+ free(*ccache);
+ *ccache = NULL;
+ }
+ return ret;
+}
+
+static krb5_error_code KRB5_CALLCONV
+krb5_mcc_ptcursor_free(
+ krb5_context context,
+ krb5_cc_ptcursor *cursor)
+{
+ if (*cursor == NULL)
+ return 0;
+ if ((*cursor)->data != NULL)
+ free((*cursor)->data);
+ free(*cursor);
+ *cursor = NULL;
+ return 0;
+}
+
const krb5_cc_ops krb5_mcc_ops = {
0,
"MEMORY",
@@ -620,4 +784,11 @@ const krb5_cc_ops krb5_mcc_ops = {
krb5_mcc_end_seq_get,
krb5_mcc_remove_cred,
krb5_mcc_set_flags,
+ krb5_mcc_get_flags,
+ krb5_mcc_ptcursor_new,
+ krb5_mcc_ptcursor_next,
+ krb5_mcc_ptcursor_free,
+ NULL,
+ NULL,
+ NULL,
};
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_retr.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_retr.c
index c1dd94d76d..7ba3a90909 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_retr.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/cc_retr.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/ccache/cc_retr.c
@@ -15,7 +14,7 @@
* 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
@@ -29,11 +28,11 @@
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
*
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "cc-int.h"
#define KRB5_OK 0
@@ -71,7 +70,7 @@ srvname_match(krb5_context context, const krb5_creds *mcreds, const krb5_creds *
{
krb5_boolean retval;
krb5_principal_data p1, p2;
-
+
retval = krb5_principal_compare(context, mcreds->client,creds->client);
if (retval != TRUE)
return retval;
@@ -85,7 +84,7 @@ srvname_match(krb5_context context, const krb5_creds *mcreds, const krb5_creds *
}
static krb5_boolean
-authdata_match(krb5_authdata *const *mdata, krb5_authdata *const *data)
+authdata_match(krb5_authdata *const *mdata, krb5_authdata *const *data)
{
const krb5_authdata *mdatap, *datap;
@@ -97,13 +96,13 @@ authdata_match(krb5_authdata *const *mdata, krb5_authdata *const *data)
if (data == NULL)
return *mdata == NULL;
-
+
/*LINTED*/
while ((mdatap = *mdata) && (datap = *data)) {
if ((mdatap->ad_type != datap->ad_type) ||
(mdatap->length != datap->length) ||
(memcmp ((char *)mdatap->contents,
- (char *)datap->contents, (unsigned) mdatap->length) != 0))
+ (char *)datap->contents, (unsigned) mdatap->length) != 0))
return FALSE;
mdata++;
data++;
@@ -125,8 +124,8 @@ data_match(const krb5_data *data1, const krb5_data *data2)
if (data1->length != data2->length)
return FALSE;
else
- return memcmp(data1->data, data2->data, (unsigned) data1->length)
- ? FALSE : TRUE;
+ return memcmp(data1->data, data2->data, (unsigned) data1->length)
+ ? FALSE : TRUE;
}
static int
@@ -145,7 +144,7 @@ pref (krb5_enctype my_ktype, int nktypes, krb5_enctype *ktypes)
* with the fields specified by whichfields. If one if found, it is
* returned in creds, which should be freed by the caller with
* krb5_free_credentials().
- *
+ *
* The fields are interpreted in the following way (all constants are
* preceded by KRB5_TC_). MATCH_IS_SKEY requires the is_skey field to
* match exactly. MATCH_TIMES requires the requested lifetime to be
@@ -201,7 +200,9 @@ krb5int_cc_creds_match_request(krb5_context context, krb5_flags whichfields, krb
}
static krb5_error_code
-krb5_cc_retrieve_cred_seq (krb5_context context, krb5_ccache id, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds, int nktypes, krb5_enctype *ktypes)
+krb5_cc_retrieve_cred_seq (krb5_context context, krb5_ccache id,
+ krb5_flags whichfields, krb5_creds *mcreds,
+ krb5_creds *creds, int nktypes, krb5_enctype *ktypes)
{
/* This function could be considerably faster if it kept indexing */
/* information.. sounds like a "next version" idea to me. :-) */
@@ -214,18 +215,28 @@ krb5_cc_retrieve_cred_seq (krb5_context context, krb5_ccache id, krb5_flags whic
int pref;
} fetched, best;
int have_creds = 0;
+ krb5_flags oflags = 0;
#define fetchcreds (fetched.creds)
+ /* Solaris Kerberos */
memset(&best, 0, sizeof (best));
memset(&fetched, 0, sizeof (fetched));
- kret = krb5_cc_start_seq_get(context, id, &cursor);
+ kret = krb5_cc_get_flags(context, id, &oflags);
if (kret != KRB5_OK)
return kret;
+ if (oflags & KRB5_TC_OPENCLOSE)
+ (void) krb5_cc_set_flags(context, id, oflags & ~KRB5_TC_OPENCLOSE);
+ kret = krb5_cc_start_seq_get(context, id, &cursor);
+ if (kret != KRB5_OK) {
+ if (oflags & KRB5_TC_OPENCLOSE)
+ krb5_cc_set_flags(context, id, oflags);
+ return kret;
+ }
while ((kret = krb5_cc_next_cred(context, id, &cursor, &fetchcreds)) == KRB5_OK) {
- if (krb5int_cc_creds_match_request(context, whichfields, mcreds, &fetchcreds))
- {
+ if (krb5int_cc_creds_match_request(context, whichfields, mcreds, &fetchcreds))
+ {
if (ktypes) {
fetched.pref = pref (fetchcreds.keyblock.enctype,
nktypes, ktypes);
@@ -240,9 +251,12 @@ krb5_cc_retrieve_cred_seq (krb5_context context, krb5_ccache id, krb5_flags whic
continue;
}
} else {
- (void) krb5_cc_end_seq_get(context, id, &cursor);
+ krb5_cc_end_seq_get(context, id, &cursor);
*creds = fetchcreds;
+ /* Solaris Kerberos */
creds->keyblock.hKey = CK_INVALID_HANDLE;
+ if (oflags & KRB5_TC_OPENCLOSE)
+ krb5_cc_set_flags(context, id, oflags);
return KRB5_OK;
}
}
@@ -252,9 +266,12 @@ krb5_cc_retrieve_cred_seq (krb5_context context, krb5_ccache id, krb5_flags whic
}
/* If we get here, a match wasn't found */
- (void) krb5_cc_end_seq_get(context, id, &cursor);
+ krb5_cc_end_seq_get(context, id, &cursor);
+ if (oflags & KRB5_TC_OPENCLOSE)
+ krb5_cc_set_flags(context, id, oflags);
if (have_creds) {
*creds = best.creds;
+ /* Solaris Kerberos */
creds->keyblock.hKey = CK_INVALID_HANDLE;
return KRB5_OK;
} else
@@ -281,7 +298,107 @@ krb5_cc_retrieve_cred_default (krb5_context context, krb5_ccache id, krb5_flags
free (ktypes);
return ret;
} else {
+ /* Solaris Kerberos */
return krb5_cc_retrieve_cred_seq (context, id, flags, mcreds, creds,
0, (krb5_enctype *)NULL);
}
}
+
+/* The following function duplicates some of the functionality above and */
+/* should probably be merged with it at some point. It is used by the */
+/* CCAPI krb5_cc_remove to figure out if the opaque credentials object */
+/* returned by the CCAPI is the same creds as the caller passed in. */
+/* Unlike the code above it requires that all structures be identical. */
+
+krb5_boolean KRB5_CALLCONV
+krb5_creds_compare (krb5_context in_context,
+ krb5_creds *in_creds,
+ krb5_creds *in_compare_creds)
+{
+ /* Set to 0 when we hit the first mismatch and then fall through */
+ int equal = 1;
+
+ if (equal) {
+ equal = krb5_principal_compare (in_context, in_creds->client,
+ in_compare_creds->client);
+ }
+
+ if (equal) {
+ equal = krb5_principal_compare (in_context, in_creds->server,
+ in_compare_creds->server);
+ }
+
+ if (equal) {
+ equal = (in_creds->keyblock.enctype == in_compare_creds->keyblock.enctype &&
+ in_creds->keyblock.length == in_compare_creds->keyblock.length &&
+ (!in_creds->keyblock.length ||
+ !memcmp (in_creds->keyblock.contents, in_compare_creds->keyblock.contents,
+ in_creds->keyblock.length)));
+ }
+
+ if (equal) {
+ equal = (in_creds->times.authtime == in_compare_creds->times.authtime &&
+ in_creds->times.starttime == in_compare_creds->times.starttime &&
+ in_creds->times.endtime == in_compare_creds->times.endtime &&
+ in_creds->times.renew_till == in_compare_creds->times.renew_till);
+ }
+
+ if (equal) {
+ equal = (in_creds->is_skey == in_compare_creds->is_skey);
+ }
+
+ if (equal) {
+ equal = (in_creds->ticket_flags == in_compare_creds->ticket_flags);
+ }
+
+ if (equal) {
+ krb5_address **addresses = in_creds->addresses;
+ krb5_address **compare_addresses = in_compare_creds->addresses;
+ unsigned int i;
+
+ if (addresses && compare_addresses) {
+ for (i = 0; (equal && addresses[i] && compare_addresses[i]); i++) {
+ equal = krb5_address_compare (in_context, addresses[i],
+ compare_addresses[i]);
+ }
+ if (equal) { equal = (!addresses[i] && !compare_addresses[i]); }
+ } else {
+ if (equal) { equal = (!addresses && !compare_addresses); }
+ }
+ }
+
+ if (equal) {
+ equal = (in_creds->ticket.length == in_compare_creds->ticket.length &&
+ (!in_creds->ticket.length ||
+ !memcmp (in_creds->ticket.data, in_compare_creds->ticket.data,
+ in_creds->ticket.length)));
+ }
+
+ if (equal) {
+ equal = (in_creds->second_ticket.length == in_compare_creds->second_ticket.length &&
+ (!in_creds->second_ticket.length ||
+ !memcmp (in_creds->second_ticket.data, in_compare_creds->second_ticket.data,
+ in_creds->second_ticket.length)));
+ }
+
+ if (equal) {
+ krb5_authdata **authdata = in_creds->authdata;
+ krb5_authdata **compare_authdata = in_compare_creds->authdata;
+ unsigned int i;
+
+ if (authdata && compare_authdata) {
+ for (i = 0; (equal && authdata[i] && compare_authdata[i]); i++) {
+ equal = (authdata[i]->ad_type == compare_authdata[i]->ad_type &&
+ authdata[i]->length == compare_authdata[i]->length &&
+ (!authdata[i]->length ||
+ !memcmp (authdata[i]->contents, compare_authdata[i]->contents,
+ authdata[i]->length)));
+ }
+ if (equal) { equal = (!authdata[i] && !compare_authdata[i]); }
+ } else {
+ if (equal) { equal = (!authdata && !compare_authdata); }
+ }
+ }
+
+ return equal;
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccbase.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccbase.c
index 7a9fb70d54..89ec1ad9ca 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccbase.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccbase.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/krb5/ccache/ccbase.c
*
@@ -30,7 +28,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,22 +43,53 @@ struct krb5_cc_typelist {
const krb5_cc_ops *ops;
struct krb5_cc_typelist *next;
};
+
+struct krb5_cc_typecursor {
+ struct krb5_cc_typelist *tptr;
+};
+/* typedef krb5_cc_typecursor in k5-int.h */
+
extern const krb5_cc_ops krb5_mcc_ops;
+#ifdef USE_KEYRING_CCACHE
+extern const krb5_cc_ops krb5_krcc_ops;
+#endif
#ifdef _WIN32
extern const krb5_cc_ops krb5_lcc_ops;
static struct krb5_cc_typelist cc_lcc_entry = { &krb5_lcc_ops, NULL };
static struct krb5_cc_typelist cc_mcc_entry = { &krb5_mcc_ops, &cc_lcc_entry };
#else
+
+#ifdef USE_CCAPI_V3
+extern const krb5_cc_ops krb5_cc_stdcc_ops;
+static struct krb5_cc_typelist cc_stdcc_entry = { &krb5_cc_stdcc_ops, NULL };
+static struct krb5_cc_typelist cc_mcc_entry = { &krb5_mcc_ops, &cc_stdcc_entry };
+#else
+
static struct krb5_cc_typelist cc_mcc_entry = { &krb5_mcc_ops, NULL };
+#endif /* USE_CCAPI_V3 */
+
+#ifdef USE_KEYRING_CCACHE
+static struct krb5_cc_typelist cc_file_entry = { &krb5_cc_file_ops,
+ &cc_mcc_entry };
+static struct krb5_cc_typelist cc_krcc_entry = { &krb5_krcc_ops,
+ &cc_file_entry };
+#endif /* USE_KEYRING_CCACHE */
#endif
static struct krb5_cc_typelist cc_fcc_entry = { &krb5_cc_file_ops,
&cc_mcc_entry };
-
-static struct krb5_cc_typelist *cc_typehead = &cc_fcc_entry;
+#ifdef USE_KEYRING_CCACHE
+#define INITIAL_TYPEHEAD (&cc_krcc_entry)
+#else
+#define INITIAL_TYPEHEAD (&cc_fcc_entry)
+#endif
+static struct krb5_cc_typelist *cc_typehead = INITIAL_TYPEHEAD;
static k5_mutex_t cc_typelist_lock = K5_MUTEX_PARTIAL_INITIALIZER;
+static krb5_error_code
+krb5int_cc_getops(krb5_context, const char *, const krb5_cc_ops **);
+
int
krb5int_cc_initialize(void)
{
@@ -75,6 +104,11 @@ krb5int_cc_initialize(void)
err = k5_mutex_finish_init(&krb5int_cc_file_mutex);
if (err)
return err;
+#ifdef USE_KEYRING_CCACHE
+ err = k5_mutex_finish_init(&krb5int_krcc_mutex);
+ if (err)
+ return err;
+#endif
return 0;
}
@@ -85,7 +119,10 @@ krb5int_cc_finalize(void)
k5_mutex_destroy(&cc_typelist_lock);
k5_mutex_destroy(&krb5int_cc_file_mutex);
k5_mutex_destroy(&krb5int_mcc_mutex);
- for (t = cc_typehead; t != &cc_fcc_entry; t = t_next) {
+#ifdef USE_KEYRING_CCACHE
+ k5_mutex_destroy(&krb5int_krcc_mutex);
+#endif
+ for (t = cc_typehead; t != INITIAL_TYPEHEAD; t = t_next) {
t_next = t->next;
free(t);
}
@@ -143,16 +180,17 @@ krb5_cc_register(krb5_context context, krb5_cc_ops *ops, krb5_boolean override)
krb5_error_code KRB5_CALLCONV
krb5_cc_resolve (krb5_context context, const char *name, krb5_ccache *cache)
{
- struct krb5_cc_typelist *tlist;
char *pfx, *cp;
const char *resid;
unsigned int pfxlen;
krb5_error_code err;
+ const krb5_cc_ops *ops;
/* Solaris Kerberos */
if (!name)
return KRB5_CC_BADNAME;
+ pfx = NULL;
cp = strchr (name, ':');
if (!cp) {
if (krb5_cc_dfl_ops)
@@ -163,9 +201,9 @@ krb5_cc_resolve (krb5_context context, const char *name, krb5_ccache *cache)
pfxlen = cp - name;
- if ( pfxlen == 1 && isalpha(name[0]) ) {
- /* We found a drive letter not a prefix - use FILE: */
- pfx = strdup("FILE:");
+ if ( pfxlen == 1 && isalpha((unsigned char) name[0]) ) {
+ /* We found a drive letter not a prefix - use FILE */
+ pfx = strdup("FILE");
if (!pfx)
return ENOMEM;
@@ -183,24 +221,136 @@ krb5_cc_resolve (krb5_context context, const char *name, krb5_ccache *cache)
*cache = (krb5_ccache) 0;
- err = k5_mutex_lock(&cc_typelist_lock);
- if (err) {
+ err = krb5int_cc_getops(context, pfx, &ops);
+ if (pfx != NULL)
free(pfx);
+ if (err)
return err;
- }
+
+ return ops->resolve(context, cache, resid);
+}
+
+/*
+ * cc_getops
+ *
+ * Internal function to return the ops vector for a given ccache
+ * prefix string.
+ */
+static krb5_error_code
+krb5int_cc_getops(
+ krb5_context context,
+ const char *pfx,
+ const krb5_cc_ops **ops)
+{
+ krb5_error_code err;
+ struct krb5_cc_typelist *tlist;
+
+ err = k5_mutex_lock(&cc_typelist_lock);
+ if (err)
+ return err;
+
for (tlist = cc_typehead; tlist; tlist = tlist->next) {
if (strcmp (tlist->ops->prefix, pfx) == 0) {
- krb5_error_code (KRB5_CALLCONV *ccresolver)() = tlist->ops->resolve;
+ *ops = tlist->ops;
k5_mutex_unlock(&cc_typelist_lock);
- free(pfx);
- return (*ccresolver)(context, cache, resid);
+ return 0;
}
}
k5_mutex_unlock(&cc_typelist_lock);
if (krb5_cc_dfl_ops && !strcmp (pfx, krb5_cc_dfl_ops->prefix)) {
- free (pfx);
- return (*krb5_cc_dfl_ops->resolve)(context, cache, resid);
+ *ops = krb5_cc_dfl_ops;
+ return 0;
}
- free(pfx);
return KRB5_CC_UNKNOWN_TYPE;
}
+
+/*
+ * cc_new_unique
+ *
+ * Generate a new unique ccache, given a ccache type and a hint
+ * string. Ignores the hint string for now.
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_cc_new_unique(
+ krb5_context context,
+ const char *type,
+ const char *hint,
+ krb5_ccache *id)
+{
+ const krb5_cc_ops *ops;
+ krb5_error_code err;
+
+ *id = NULL;
+
+ err = krb5int_cc_getops(context, type, &ops);
+ if (err)
+ return err;
+
+ return ops->gen_new(context, id);
+}
+
+/*
+ * cc_typecursor
+ *
+ * Note: to avoid copying the typelist at cursor creation time, among
+ * other things, we assume that the only additions ever occur to the
+ * typelist.
+ */
+krb5_error_code
+krb5int_cc_typecursor_new(krb5_context context, krb5_cc_typecursor *t)
+{
+ krb5_error_code err = 0;
+ krb5_cc_typecursor n = NULL;
+
+ *t = NULL;
+ n = malloc(sizeof(*n));
+ if (n == NULL)
+ return ENOMEM;
+
+ err = k5_mutex_lock(&cc_typelist_lock);
+ if (err)
+ goto errout;
+ n->tptr = cc_typehead;
+ err = k5_mutex_unlock(&cc_typelist_lock);
+ if (err)
+ goto errout;
+
+ *t = n;
+errout:
+ if (err)
+ free(n);
+ return err;
+}
+
+krb5_error_code
+krb5int_cc_typecursor_next(
+ krb5_context context,
+ krb5_cc_typecursor t,
+ const krb5_cc_ops **ops)
+{
+ krb5_error_code err = 0;
+
+ *ops = NULL;
+ if (t->tptr == NULL)
+ return 0;
+
+ err = k5_mutex_lock(&cc_typelist_lock);
+ if (err)
+ goto errout;
+ *ops = t->tptr->ops;
+ t->tptr = t->tptr->next;
+ err = k5_mutex_unlock(&cc_typelist_lock);
+ if (err)
+ goto errout;
+
+errout:
+ return err;
+}
+
+krb5_error_code
+krb5int_cc_typecursor_free(krb5_context context, krb5_cc_typecursor *t)
+{
+ free(*t);
+ *t = NULL;
+ return 0;
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccdefault.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccdefault.c
index 2c232ded50..d36b104749 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccdefault.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccdefault.c
@@ -1,11 +1,4 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* lib/krb5/ccache/ccdefault.c
*
* Copyright 1990 by the Massachusetts Institute of Technology.
@@ -15,7 +8,7 @@
* 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
@@ -29,24 +22,29 @@
* 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.
- *
+ *
*
* Find default credential cache
*/
-#include <k5-int.h>
+#include "k5-int.h"
-/*
- * Solaris Kerberos: the following is specific to the Macintosh
- */
-#if defined(USE_LOGIN_LIBRARY) && defined(macintosh)
-#include <KerberosLoginInternal.h>
+#if defined(USE_LOGIN_LIBRARY)
+#include "KerberosLoginPrivate.h"
+#elif defined(USE_LEASH)
+static void (*pLeash_AcquireInitialTicketsIfNeeded)(krb5_context,krb5_principal,char*,int) = NULL;
+static HANDLE hLeashDLL = INVALID_HANDLE_VALUE;
+#ifdef _WIN64
+#define LEASH_DLL "leashw64.dll"
+#else
+#define LEASH_DLL "leashw32.dll"
#endif
+#endif
+
krb5_error_code KRB5_CALLCONV
krb5_cc_default(krb5_context context, krb5_ccache *ccache)
{
- krb5_error_code retval;
krb5_os_context os_ctx;
if (!context || context->magic != KV5M_CONTEXT)
@@ -59,27 +57,58 @@ krb5_cc_default(krb5_context context, krb5_ccache *ccache)
/* 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.
-
+ 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_error_code KRB5_CALLCONV
krb5int_cc_default(krb5_context context, krb5_ccache *ccache)
{
+ if (!context || context->magic != KV5M_CONTEXT) {
+ return KV5M_CONTEXT;
+ }
- if (!context || context->magic != KV5M_CONTEXT) {
- return KV5M_CONTEXT;
- }
-
-/*
- * Solaris Kerberos: the following is specific to the Macintosh
- */
#ifdef USE_LOGIN_LIBRARY
-
- /* MIT14resync; not needed for Solaris Kerberos */
+ {
+ /* make sure the default cache has tix before you open it */
+ KLStatus err = klNoErr;
+ char *outCacheName = NULL;
+
+ /* Try to make sure a krb5 tgt is in the cache */
+ err = __KLInternalAcquireInitialTicketsForCache (krb5_cc_default_name (context), kerberosVersion_V5,
+ NULL, NULL, &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);
+ }
+ }
+#else
+#ifdef USE_LEASH
+ if ( hLeashDLL == INVALID_HANDLE_VALUE ) {
+ hLeashDLL = LoadLibrary(LEASH_DLL);
+ if ( hLeashDLL != INVALID_HANDLE_VALUE ) {
+ (FARPROC) pLeash_AcquireInitialTicketsIfNeeded =
+ GetProcAddress(hLeashDLL, "not_an_API_Leash_AcquireInitialTicketsIfNeeded");
+ }
+ }
+
+ if ( pLeash_AcquireInitialTicketsIfNeeded ) {
+ char ccname[256]="";
+ pLeash_AcquireInitialTicketsIfNeeded(context, NULL, ccname, sizeof(ccname));
+ if (ccname[0]) {
+ if (strcmp (krb5_cc_default_name (context),ccname) != 0) {
+ krb5_cc_set_default_name (context, ccname);
+ }
+ }
+ }
+#endif
#endif
-
return krb5_cc_default (context, ccache);
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccdefops.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccdefops.c
index b4dc34569f..cdeab0674c 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccdefops.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccdefops.c
@@ -1,11 +1,4 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* lib/krb5/ccache/ccdefops.c
*
* Copyright 1990 by the Massachusetts Institute of Technology.
@@ -15,7 +8,7 @@
* 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
@@ -29,20 +22,20 @@
* 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.
- *
+ *
*
* Default credentials cache determination. This is a separate file
* so that the user can more easily override it.
*/
-#include <k5-int.h>
+#include "k5-int.h"
#if defined(USE_CCAPI)
/*
* Macs use the shared, memory based credentials cache
* Windows may also use the ccapi cache, but only if the Krbcc32.dll
- * can be found; otherwise it falls back to using the old
+ * can be found; otherwise it falls back to using the old
* file-based ccache.
*/
#include "stdcc.h" /* from ccapi subdir */
@@ -51,7 +44,7 @@ const krb5_cc_ops *krb5_cc_dfl_ops = &krb5_cc_stdcc_ops;
#else
-#include "fcc.h" /* From file subdir */
+#include "fcc.h"
const krb5_cc_ops *krb5_cc_dfl_ops = &krb5_cc_file_ops;
#endif
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccfns.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccfns.c
index a40db67868..15bc87df6b 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccfns.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/ccache/ccfns.c
@@ -1,9 +1,7 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/krb5/ccache/ccfns.c
*
- * Copyright 2000 by the Massachusetts Institute of Technology.
+ * Copyright 2000, 2007 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -67,7 +65,29 @@ krb5_error_code KRB5_CALLCONV
krb5_cc_store_cred (krb5_context context, krb5_ccache cache,
krb5_creds *creds)
{
- return cache->ops->store(context, cache, creds);
+ krb5_error_code ret;
+ krb5_ticket *tkt;
+ krb5_principal s1, s2;
+
+ ret = cache->ops->store(context, cache, creds);
+ if (ret) return ret;
+
+ /*
+ * If creds->server and the server in the decoded ticket differ,
+ * store both principals.
+ */
+ s1 = creds->server;
+ ret = decode_krb5_ticket(&creds->ticket, &tkt);
+ /* Bail out on errors in case someone is storing a non-ticket. */
+ if (ret) return 0;
+ s2 = tkt->server;
+ if (!krb5_principal_compare(context, s1, s2)) {
+ creds->server = s2;
+ ret = cache->ops->store(context, cache, creds);
+ creds->server = s1;
+ }
+ krb5_free_ticket(context, tkt);
+ return ret;
}
krb5_error_code KRB5_CALLCONV
@@ -75,7 +95,23 @@ krb5_cc_retrieve_cred (krb5_context context, krb5_ccache cache,
krb5_flags flags, krb5_creds *mcreds,
krb5_creds *creds)
{
- return cache->ops->retrieve(context, cache, flags, mcreds, creds);
+ krb5_error_code ret;
+ krb5_data tmprealm;
+
+ ret = cache->ops->retrieve(context, cache, flags, mcreds, creds);
+ if (ret != KRB5_CC_NOTFOUND)
+ return ret;
+ if (!krb5_is_referral_realm(&mcreds->server->realm))
+ return ret;
+
+ /*
+ * Retry using client's realm if service has referral realm.
+ */
+ tmprealm = mcreds->server->realm;
+ mcreds->server->realm = mcreds->client->realm;
+ ret = cache->ops->retrieve(context, cache, flags, mcreds, creds);
+ mcreds->server->realm = tmprealm;
+ return ret;
}
krb5_error_code KRB5_CALLCONV
@@ -119,6 +155,12 @@ krb5_cc_set_flags (krb5_context context, krb5_ccache cache, krb5_flags flags)
return cache->ops->set_flags(context, cache, flags);
}
+krb5_error_code KRB5_CALLCONV
+krb5_cc_get_flags (krb5_context context, krb5_ccache cache, krb5_flags *flags)
+{
+ return cache->ops->get_flags(context, cache, flags);
+}
+
const char * KRB5_CALLCONV
krb5_cc_get_type (krb5_context context, krb5_ccache cache)
{
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_file.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_file.c
index dfbca86739..5677cd4496 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_file.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_file.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/keytab/kt_file.c
@@ -32,7 +31,6 @@
*
*/
-#define NEED_SOCKETS
#include "k5-int.h"
#include <stdio.h>
@@ -201,6 +199,7 @@ krb5_ktfile_resolve(krb5_context context, const char *name, krb5_keytab *id)
err = k5_mutex_init(&data->lock);
if (err) {
+ krb5_xfree(data);
krb5_xfree(*id);
return err;
}
@@ -415,6 +414,7 @@ krb5_ktfile_get_name(krb5_context context, krb5_keytab id, char *name, unsigned
name++;
len -= strlen(id->ops->prefix)+1;
+ /* Solaris Kerberos */
if (len < strlen(KTFILENAME(id))+1)
return(KRB5_KT_NAME_TOOLONG);
strcpy(name, KTFILENAME(id));
@@ -468,6 +468,10 @@ krb5_ktfile_get_next(krb5_context context, krb5_keytab id, krb5_keytab_entry *en
kerror = KTLOCK(id);
if (kerror)
return kerror;
+ if (KTFILEP(id) == NULL) {
+ KTUNLOCK(id);
+ return KRB5_KT_IOERR;
+ }
if (fseek(KTFILEP(id), *fileoff, 0) == -1) {
KTUNLOCK(id);
return KRB5_KT_END;
@@ -566,7 +570,8 @@ krb5_ktf_keytab_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
ktdata->name : ktfile_def_name);
kret = 0;
- *sizep += required;
+ if (!kret)
+ *sizep += required;
}
return(kret);
}
@@ -584,7 +589,7 @@ krb5_ktf_keytab_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet
size_t remain;
krb5_ktfile_data *ktdata;
krb5_int32 file_is_open;
- krb5_int32 file_pos[2];
+ krb5_int64 file_pos;
char *ktname;
size_t namelen;
const char *fnamep;
@@ -602,8 +607,7 @@ krb5_ktf_keytab_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet
ktdata = (krb5_ktfile_data *) keytab->data;
file_is_open = 0;
- file_pos[0] = 0;
- file_pos[1] = 0;
+ file_pos = 0;
/* Calculate the length of the name */
namelen = (keytab->ops && keytab->ops->prefix) ?
@@ -637,12 +641,7 @@ krb5_ktf_keytab_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet
file_is_open = 0;
#endif
fpos = ftell(ktdata->openf);
-#if SIZEOF_LONG == 4
- file_pos[0] = fpos;
-#else /* SIZEOF_LONG == 4 */
- file_pos[0] = fpos & 0xffffffff;
- file_pos[1] = (fpos >> 32) & 0xffffffff;
-#endif /* SIZEOF_LONG == 4 */
+ file_pos = fpos; /* XX range check? */
}
}
@@ -659,8 +658,7 @@ krb5_ktf_keytab_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet
(void) krb5_ser_pack_int32(file_is_open, &bp, &remain);
/* Put the file position */
- (void) krb5_ser_pack_int32(file_pos[0], &bp, &remain);
- (void) krb5_ser_pack_int32(file_pos[1], &bp, &remain);
+ (void) krb5_ser_pack_int64(file_pos, &bp, &remain);
/* Put the version */
(void) krb5_ser_pack_int32((krb5_int32) ((ktdata) ?
@@ -693,7 +691,7 @@ krb5_ktf_keytab_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octe
char *ktname;
krb5_ktfile_data *ktdata;
krb5_int32 file_is_open;
- krb5_int32 foffbuf[2];
+ krb5_int64 foff;
bp = *buffer;
remain = *lenremain;
@@ -731,10 +729,7 @@ krb5_ktf_keytab_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octe
if (remain >= (sizeof(krb5_int32)*5)) {
(void) krb5_ser_unpack_int32(&file_is_open,
&bp, &remain);
- (void) krb5_ser_unpack_int32(&foffbuf[0],
- &bp, &remain);
- (void) krb5_ser_unpack_int32(&foffbuf[1],
- &bp, &remain);
+ (void) krb5_ser_unpack_int64(&foff, &bp, &remain);
(void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
ktdata->version = (int) ibuf;
@@ -756,11 +751,7 @@ krb5_ktf_keytab_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octe
kret = krb5_ktfileint_openr(kcontext,
keytab);
if (!kret) {
-#if SIZEOF_LONG == 4
- fpos = foffbuf[0];
-#else /* SIZEOF_LONG == 4 */
- fpos = foffbuf[0] | ((long) foffbuf[1] << 32);
-#endif /* SIZEOF_LONG == 4 */
+ fpos = foff; /* XX range check? */
fseek(KTFILEP(keytab), fpos, SEEK_SET);
}
}
@@ -812,6 +803,7 @@ krb5_ktfile_wresolve(krb5_context context, const char *name, krb5_keytab *id)
err = k5_mutex_init(&data->lock);
if (err) {
+ krb5_xfree(data);
krb5_xfree(*id);
return err;
}
@@ -1061,9 +1053,11 @@ typedef krb5_int16 krb5_kt_vno;
#define xfread(a, b, c, d) fread((char *)a, b, (unsigned) c, d)
#ifdef ANSI_STDIO
+/* Solaris Kerberos */
static char *const fopen_mode_rbplus= "rb+F";
static char *const fopen_mode_rb = "rbF";
#else
+/* Solaris Kerberos */
static char *const fopen_mode_rbplus= "r+F";
static char *const fopen_mode_rb = "rF";
#endif
@@ -1113,7 +1107,10 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode)
} else {
/* gotta verify it instead... */
if (!xfread(&kt_vno, sizeof(kt_vno), 1, KTFILEP(id))) {
- kerror = errno;
+ if (feof(KTFILEP(id)))
+ kerror = KRB5_KEYTAB_BADVNO;
+ else
+ kerror = errno;
(void) krb5_unlock_file(context, fileno(KTFILEP(id)));
(void) fclose(KTFILEP(id));
return kerror;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_srvtab.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_srvtab.c
index 4738d80f80..7674ca345e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_srvtab.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_srvtab.c
@@ -1,8 +1,7 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/keytab/srvtab/kts_resolv.c
@@ -30,7 +29,6 @@
* or implied warranty.
*/
-#define NEED_SOCKETS
#include "k5-int.h"
#include <stdio.h>
@@ -126,6 +124,7 @@ krb5_ktsrvtab_resolve(krb5_context context, const char *name, krb5_keytab *id)
FILE *fp;
/* Make sure we can open the srvtab file for reading. */
+ /* Solaris Kerberos */
fp = fopen(name, "rF");
if (!fp)
return(errno);
@@ -273,6 +272,7 @@ krb5_ktsrvtab_get_name(krb5_context context, krb5_keytab id, char *name, unsigne
name++;
len -= strlen(id->ops->prefix)+1;
+ /* Solaris Kerberos */
if (len < strlen(KTFILENAME(id))+1)
return(KRB5_KT_NAME_TOOLONG);
strcpy(name, KTFILENAME(id));
@@ -391,8 +391,10 @@ const struct _krb5_kt_ops krb5_kts_ops = {
#include <stdio.h>
#ifdef ANSI_STDIO
+/* Solaris Kerberos */
#define READ_MODE "rbF"
#else
+/* Solaris Kerberos */
#define READ_MODE "rF"
#endif
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktadd.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktadd.c
index ec808596c2..b7c1b92164 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktadd.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktadd.c
@@ -1,11 +1,4 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* lib/krb5/keytab/ktadd.c
*
* Copyright 1990 by the Massachusetts Institute of Technology.
@@ -15,7 +8,7 @@
* 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
@@ -29,12 +22,12 @@
* 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_kt_add_entry()
*/
-#include <k5-int.h>
+#include "k5-int.h"
krb5_error_code KRB5_CALLCONV
krb5_kt_add_entry (krb5_context context, krb5_keytab id, krb5_keytab_entry *entry)
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktbase.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktbase.c
index fec98c2e42..b6edb7092d 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktbase.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktbase.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/keytab/ktbase.c
@@ -34,9 +33,9 @@
* Registration functions for keytab.
*/
-#include <k5-int.h>
-#include <k5-thread.h>
-#include <kt-int.h>
+#include "k5-int.h"
+#include "k5-thread.h"
+#include "kt-int.h"
extern const krb5_kt_ops krb5_ktf_ops;
extern const krb5_kt_ops krb5_ktf_writable_ops;
@@ -46,14 +45,17 @@ struct krb5_kt_typelist {
const krb5_kt_ops *ops;
const struct krb5_kt_typelist *next;
};
+/* Solaris Kerberos */
static const struct krb5_kt_typelist krb5_kt_typelist_wrfile = {
&krb5_ktf_writable_ops,
0
};
-static const struct krb5_kt_typelist krb5_kt_typelist_file = {
+/* Solaris Kerberos */
+static const struct krb5_kt_typelist krb5_kt_typelist_file = {
&krb5_ktf_ops,
&krb5_kt_typelist_wrfile
};
+/* Solaris Kerberos */
static const struct krb5_kt_typelist krb5_kt_typelist_srvtab = {
&krb5_kts_ops,
&krb5_kt_typelist_file
@@ -72,6 +74,7 @@ krb5int_kt_finalize(void)
{
struct krb5_kt_typelist *t, *t_next;
k5_mutex_destroy(&kt_typehead_lock);
+ /* Solaris Kerberos */
for (t = (struct krb5_kt_typelist *)kt_typehead; t != &krb5_kt_typelist_srvtab;
t = t_next) {
t_next = (struct krb5_kt_typelist *)t->next;
@@ -139,9 +142,9 @@ krb5_kt_resolve (krb5_context context, const char *name, krb5_keytab *ktid)
pfxlen = cp - name;
- if ( pfxlen == 1 && isalpha(name[0]) ) {
- /* We found a drive letter not a prefix - use FILE: */
- pfx = strdup("FILE:");
+ if ( pfxlen == 1 && isalpha((unsigned char) name[0]) ) {
+ /* We found a drive letter not a prefix - use FILE */
+ pfx = strdup("FILE");
if (!pfx)
return ENOMEM;
@@ -177,7 +180,6 @@ krb5_kt_resolve (krb5_context context, const char *name, krb5_keytab *ktid)
return KRB5_KT_UNKNOWN_TYPE;
}
-
/*
* Routines to deal with externalizingt krb5_keytab.
* krb5_keytab_size();
@@ -209,6 +211,7 @@ krb5_keytab_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
krb5_ser_handle shandle;
kret = EINVAL;
+ /* Solaris Kerberos */
keytab = (krb5_keytab) arg;
shandle = (krb5_ser_handle) keytab->ops->serializer;
if ((keytab != NULL) && (keytab->ops) &&
@@ -225,6 +228,7 @@ krb5_keytab_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **bu
krb5_ser_handle shandle;
kret = EINVAL;
+ /* Solaris Kerberos */
keytab = (krb5_keytab) arg;
shandle = (krb5_ser_handle) keytab->ops->serializer;
if ((keytab != NULL) && (keytab->ops) &&
@@ -240,6 +244,7 @@ krb5_keytab_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **
krb5_ser_handle shandle;
kret = EINVAL;
+ /* Solaris Kerberos */
shandle = (krb5_ser_handle) krb5_kt_dfl_ops.serializer;
if ((shandle != NULL) && (shandle->internalizer))
kret = (*shandle->internalizer)(kcontext, argp, buffer, lenremain);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktdefault.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktdefault.c
index 57c6b28505..971f29f599 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktdefault.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktdefault.c
@@ -1,11 +1,4 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* lib/krb5/keytab/ktdefault.c
*
* Copyright 1990 by the Massachusetts Institute of Technology.
@@ -29,12 +22,12 @@
* 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.
- *
+ *
*
* Get a default keytab.
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include <stdio.h>
krb5_error_code KRB5_CALLCONV
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktfns.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktfns.c
index 538b9b2dcf..63fa6399b6 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktfns.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktfns.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/krb5/keytab/ktfns.c
*
@@ -56,7 +54,24 @@ 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 err;
+ krb5_principal_data princ_data;
+
+ if (krb5_is_referral_realm(&principal->realm)) {
+ char *realm;
+ princ_data = *principal;
+ principal = &princ_data;
+ err = krb5_get_default_realm(context, &realm);
+ if (err)
+ return err;
+ princ_data.realm.data = realm;
+ princ_data.realm.length = strlen(realm);
+ }
+ err = krb5_x((keytab)->ops->get,(context, keytab, principal, vno, enctype,
+ entry));
+ if (principal == &princ_data)
+ krb5_free_default_realm(context, princ_data.realm.data);
+ return err;
}
krb5_error_code KRB5_CALLCONV
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktfr_entry.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktfr_entry.c
index e8dff34054..ab552a065c 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktfr_entry.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktfr_entry.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/keytab/ktfr_entry.c
@@ -29,25 +28,24 @@
* 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_kt_free_entry()
*/
-#include <k5-int.h>
+#include "k5-int.h"
krb5_error_code KRB5_CALLCONV
krb5_free_keytab_entry_contents (krb5_context context, krb5_keytab_entry *entry)
-
-
{
if (!entry)
return 0;
-
+
krb5_free_principal(context, entry->principal);
if (entry->key.contents) {
memset((char *)entry->key.contents, 0, entry->key.length);
- krb5_free_keyblock_contents(context, &entry->key);
+ /* Solaris Kerberos */
+ krb5_free_keyblock_contents(context, &entry->key);
}
return 0;
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktremove.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktremove.c
index a37418fb18..d101a70651 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktremove.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/ktremove.c
@@ -1,11 +1,4 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* lib/krb5/keytab/ktremove.c
*
* Copyright 1990 by the Massachusetts Institute of Technology.
@@ -15,7 +8,7 @@
* 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
@@ -29,12 +22,12 @@
* 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_kt_remove_entry()
*/
-#include <k5-int.h>
+#include "k5-int.h"
krb5_error_code KRB5_CALLCONV
krb5_kt_remove_entry (krb5_context context, krb5_keytab id, krb5_keytab_entry *entry)
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/read_servi.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/read_servi.c
index 47f2a8e753..c49abf6c5e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/read_servi.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/read_servi.c
@@ -1,11 +1,4 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* lib/krb5/keytab/read_servi.c
*
* Copyright 1990 by the Massachusetts Institute of Technology.
@@ -15,7 +8,7 @@
* 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
@@ -29,24 +22,24 @@
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
+ *
*
- *
- * This routine is designed to be passed to krb5_rd_req.
+ * This routine is designed to be passed to krb5_rd_req.
* It is a convenience function that reads a key out of a keytab.
- * It handles all of the opening and closing of the keytab
- * internally.
+ * It handles all of the opening and closing of the keytab
+ * internally.
*/
-#include <k5-int.h>
+#include "k5-int.h"
#define KSUCCESS 0
/*
- * effects: If keyprocarg is not NULL, it is taken to be the name of a
- * keytab. Otherwise, the default keytab will be used. This
+ * effects: If keyprocarg is not NULL, it is taken to be the name of a
+ * keytab. Otherwise, the default keytab will be used. This
* routine opens the keytab and finds the principal associated with
- * principal, vno, and enctype and returns the resulting key in *key
- * or returning an error code if it is not found.
+ * principal, vno, and enctype and returns the resulting key in *key
+ * or returning an error code if it is not found.
* returns: Either KSUCCESS or error code.
* errors: error code if not found or keyprocarg is invalid.
*/
@@ -57,17 +50,17 @@ krb5_kt_read_service_key(krb5_context context, krb5_pointer keyprocarg, krb5_pri
char keytabname[MAX_KEYTAB_NAME_LEN + 1]; /* + 1 for NULL termination */
krb5_keytab id;
krb5_keytab_entry entry;
-
+
/*
- * Get the name of the file that we should use.
+ * Get the name of the file that we should use.
*/
if (!keyprocarg) {
- if ((kerror = krb5_kt_default_name(context, (char *)keytabname,
+ if ((kerror = krb5_kt_default_name(context, (char *)keytabname,
sizeof(keytabname) - 1))!= KSUCCESS)
return (kerror);
} else {
memset(keytabname, 0, sizeof(keytabname));
- (void) strncpy(keytabname, (char *)keyprocarg,
+ (void) strncpy(keytabname, (char *)keyprocarg,
sizeof(keytabname) - 1);
}
@@ -75,6 +68,7 @@ krb5_kt_read_service_key(krb5_context context, krb5_pointer keyprocarg, krb5_pri
return (kerror);
kerror = krb5_kt_get_entry(context, id, principal, vno, enctype, &entry);
+ /* Solaris Kerberos */
(void) krb5_kt_close(context, id);
if (kerror)
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/addr_order.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/addr_order.c
index f70535d73b..de724acc9e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/addr_order.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/addr_order.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/addr_order.c
*
@@ -28,7 +27,7 @@
* krb5_address_order()
*/
-#include <k5-int.h>
+#include "k5-int.h"
#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
@@ -40,8 +39,7 @@
*/
/*ARGSUSED*/
int KRB5_CALLCONV
-krb5_address_order(krb5_context context, krb5_const krb5_address *addr1,
- krb5_const krb5_address *addr2)
+krb5_address_order(krb5_context context, const krb5_address *addr1, const krb5_address *addr2)
{
int dir;
register int i;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/addr_srch.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/addr_srch.c
index 820ce0781e..efab59f8fd 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/addr_srch.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/addr_srch.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/addr_srch.c
*
@@ -28,15 +27,14 @@
* krb5_address_search()
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
* if addr is listed in addrlist, or addrlist is null, return TRUE.
* if not listed, return FALSE
*/
krb5_boolean
-krb5_address_search(krb5_context context, krb5_const krb5_address *addr,
- krb5_address *krb5_const *addrlist)
+krb5_address_search(krb5_context context, const krb5_address *addr, krb5_address *const *addrlist)
{
if (!addrlist)
return TRUE;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/appdefault.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/appdefault.c
index 5a24a4c77c..94788899b6 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/appdefault.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/appdefault.c
@@ -1,27 +1,21 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* appdefault - routines designed to be called from applications to
* handle the [appdefaults] profile section
*/
+
#include <stdio.h>
#include <string.h>
-#include <k5-int.h>
+#include "k5-int.h"
/*xxx Duplicating this is annoying; try to work on a better way.*/
-static const char *conf_yes[] = {
+static const char *const conf_yes[] = {
"y", "yes", "true", "t", "1", "on",
0,
};
-static const char *conf_no[] = {
+static const char *const conf_no[] = {
"n", "no", "false", "nil", "0", "off",
0,
};
@@ -41,9 +35,7 @@ static int conf_boolean(char *s)
return 0;
}
-static krb5_error_code appdefault_get(krb5_context context,
- const char *appname, const krb5_data *realm,
- const char *option, char **ret_value)
+static krb5_error_code appdefault_get(krb5_context context, const char *appname, const krb5_data *realm, const char *option, char **ret_value)
{
profile_t profile;
const char *names[5];
@@ -144,10 +136,7 @@ goodbye:
}
void KRB5_CALLCONV
-krb5_appdefault_boolean(krb5_context context,
- const char *appname, const krb5_data *realm,
- const char *option, int default_value,
- int *ret_value)
+krb5_appdefault_boolean(krb5_context context, const char *appname, const krb5_data *realm, const char *option, int default_value, int *ret_value)
{
char *string = NULL;
krb5_error_code retval;
@@ -162,9 +151,7 @@ krb5_appdefault_boolean(krb5_context context,
}
void KRB5_CALLCONV
-krb5_appdefault_string(krb5_context context, const char *appname,
- const krb5_data *realm, const char *option,
- const char *default_value, char **ret_value)
+krb5_appdefault_string(krb5_context context, const char *appname, const krb5_data *realm, const char *option, const char *default_value, char **ret_value)
{
krb5_error_code retval;
char *string;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/auth_con.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/auth_con.c
index b4f6a8cb2a..b2fe350ef3 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/auth_con.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/auth_con.c
@@ -1,33 +1,28 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-#include <k5-int.h>
-#include <auth_con.h>
+#include "k5-int.h"
+#include "auth_con.h"
static krb5_boolean chk_heimdal_seqnum(krb5_ui_4, krb5_ui_4);
/*ARGSUSED*/
static krb5_error_code
-actx_copy_addr(krb5_context context, const krb5_address *inad,
- krb5_address **outad)
+actx_copy_addr(krb5_context context, const krb5_address *inad, krb5_address **outad)
{
krb5_address *tmpad;
- if (!(tmpad = (krb5_address *)MALLOC(sizeof(*tmpad))))
+ if (!(tmpad = (krb5_address *)malloc(sizeof(*tmpad))))
return ENOMEM;
-#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
*tmpad = *inad;
-#else
- (void) memcpy(tmpad, inad, sizeof(krb5_address));
-#endif
- if (!(tmpad->contents = (krb5_octet *)MALLOC(inad->length))) {
+ if (!(tmpad->contents = (krb5_octet *)malloc(inad->length))) {
krb5_xfree(tmpad);
return ENOMEM;
}
+ /* Solaris Kerberos */
(void) memcpy((char *)tmpad->contents, (char *)inad->contents, inad->length);
*outad = tmpad;
return 0;
@@ -40,11 +35,12 @@ krb5_auth_con_init(krb5_context context, krb5_auth_context *auth_context)
(krb5_auth_context)MALLOC(sizeof(struct _krb5_auth_context));
if (!*auth_context)
return ENOMEM;
-
+
+ /* Solaris Kerberos */
(void) memset(*auth_context, 0, sizeof(struct _krb5_auth_context));
/* Default flags, do time not seq */
- (*auth_context)->auth_context_flags =
+ (*auth_context)->auth_context_flags =
KRB5_AUTH_CONTEXT_DO_TIME | KRB5_AUTH_CONN_INITIALIZED;
(*auth_context)->req_cksumtype = context->default_ap_req_sumtype;
@@ -58,37 +54,35 @@ krb5_auth_con_init(krb5_context context, krb5_auth_context *auth_context)
krb5_error_code KRB5_CALLCONV
krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context)
{
- if (auth_context->local_addr)
+ if (auth_context->local_addr)
krb5_free_address(context, auth_context->local_addr);
- if (auth_context->remote_addr)
+ if (auth_context->remote_addr)
krb5_free_address(context, auth_context->remote_addr);
- if (auth_context->local_port)
+ if (auth_context->local_port)
krb5_free_address(context, auth_context->local_port);
- if (auth_context->remote_port)
+ if (auth_context->remote_port)
krb5_free_address(context, auth_context->remote_port);
- if (auth_context->authentp)
+ if (auth_context->authentp)
krb5_free_authenticator(context, auth_context->authentp);
- if (auth_context->keyblock)
+ if (auth_context->keyblock)
krb5_free_keyblock(context, auth_context->keyblock);
- if (auth_context->send_subkey)
+ if (auth_context->send_subkey)
krb5_free_keyblock(context, auth_context->send_subkey);
- if (auth_context->recv_subkey)
+ if (auth_context->recv_subkey)
krb5_free_keyblock(context, auth_context->recv_subkey);
+ /* Solaris Kerberos */
if (auth_context->rcache)
(void) krb5_rc_close(context, auth_context->rcache);
if (auth_context->permitted_etypes)
krb5_xfree(auth_context->permitted_etypes);
- FREE(auth_context, sizeof(krb5_auth_context));
+ free(auth_context);
return 0;
}
-krb5_error_code KRB5_CALLCONV
-krb5_auth_con_setaddrs(krb5_context context,
- krb5_auth_context auth_context,
- krb5_address *local_addr,
- krb5_address *remote_addr)
+krb5_error_code
+krb5_auth_con_setaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address *local_addr, krb5_address *remote_addr)
{
- krb5_error_code retval = 0;
+ krb5_error_code retval;
/* Free old addresses */
if (auth_context->local_addr)
@@ -96,6 +90,7 @@ krb5_auth_con_setaddrs(krb5_context context,
if (auth_context->remote_addr)
(void) krb5_free_address(context, auth_context->remote_addr);
+ retval = 0;
if (local_addr)
retval = actx_copy_addr(context,
local_addr,
@@ -113,11 +108,8 @@ krb5_auth_con_setaddrs(krb5_context context,
return retval;
}
-krb5_error_code
-krb5_auth_con_getaddrs(krb5_context context,
- krb5_auth_context auth_context,
- krb5_address **local_addr,
- krb5_address **remote_addr)
+krb5_error_code KRB5_CALLCONV
+krb5_auth_con_getaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address **local_addr, krb5_address **remote_addr)
{
krb5_error_code retval;
@@ -135,12 +127,8 @@ krb5_auth_con_getaddrs(krb5_context context,
return retval;
}
-krb5_error_code
-krb5_auth_con_setports(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_address * local_port,
- krb5_address * remote_port)
+krb5_error_code KRB5_CALLCONV
+krb5_auth_con_setports(krb5_context context, krb5_auth_context auth_context, krb5_address *local_port, krb5_address *remote_port)
{
krb5_error_code retval;
@@ -177,10 +165,7 @@ krb5_auth_con_setports(
* with the session key sent by the client.
*/
krb5_error_code KRB5_CALLCONV
-krb5_auth_con_setuseruserkey(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_keyblock * keyblock)
+krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock)
{
if (auth_context->keyblock)
krb5_free_keyblock(context, auth_context->keyblock);
@@ -188,10 +173,7 @@ krb5_auth_con_setuseruserkey(
}
krb5_error_code KRB5_CALLCONV
-krb5_auth_con_getkey(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_keyblock ** keyblock)
+krb5_auth_con_getkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
{
if (auth_context->keyblock)
return krb5_copy_keyblock(context, auth_context->keyblock, keyblock);
@@ -200,19 +182,13 @@ krb5_auth_con_getkey(
}
krb5_error_code KRB5_CALLCONV
-krb5_auth_con_getlocalsubkey(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_keyblock * * keyblock)
+krb5_auth_con_getlocalsubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
{
return krb5_auth_con_getsendsubkey(context, auth_context, keyblock);
}
krb5_error_code KRB5_CALLCONV
-krb5_auth_con_getremotesubkey(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_keyblock **keyblock)
+krb5_auth_con_getremotesubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
{
return krb5_auth_con_getrecvsubkey(context, auth_context, keyblock);
}
@@ -226,7 +202,7 @@ krb5_auth_con_setsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keybloc
if (keyblock !=NULL)
return krb5_copy_keyblock(ctx, keyblock, &ac->send_subkey);
else
- return 0;
+ return 0;
}
krb5_error_code KRB5_CALLCONV
@@ -238,7 +214,7 @@ krb5_auth_con_setrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keybloc
if (keyblock != NULL)
return krb5_copy_keyblock(ctx, keyblock, &ac->recv_subkey);
else
- return 0;
+ return 0;
}
krb5_error_code KRB5_CALLCONV
@@ -261,10 +237,7 @@ krb5_auth_con_getrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keybloc
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
-krb5_auth_con_set_req_cksumtype(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_cksumtype cksumtype)
+krb5_auth_con_set_req_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_cksumtype cksumtype)
{
auth_context->req_cksumtype = cksumtype;
return 0;
@@ -272,10 +245,7 @@ krb5_auth_con_set_req_cksumtype(
/*ARGSUSED*/
krb5_error_code
-krb5_auth_con_set_safe_cksumtype(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_cksumtype cksumtype)
+krb5_auth_con_set_safe_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_cksumtype cksumtype)
{
auth_context->safe_cksumtype = cksumtype;
return 0;
@@ -283,20 +253,14 @@ krb5_auth_con_set_safe_cksumtype(
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
-krb5_auth_con_getlocalseqnumber(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_int32 * seqnumber)
+krb5_auth_con_getlocalseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber)
{
*seqnumber = auth_context->local_seq_number;
return 0;
}
krb5_error_code KRB5_CALLCONV
-krb5_auth_con_getauthenticator(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_authenticator **authenticator)
+krb5_auth_con_getauthenticator(krb5_context context, krb5_auth_context auth_context, krb5_authenticator **authenticator)
{
return (krb5_copy_authenticator(context, auth_context->authentp,
authenticator));
@@ -304,19 +268,14 @@ krb5_auth_con_getauthenticator(
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
-krb5_auth_con_getremoteseqnumber(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_int32 * seqnumber)
+krb5_auth_con_getremoteseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber)
{
*seqnumber = auth_context->remote_seq_number;
return 0;
}
-krb5_error_code
-krb5_auth_con_initivector(
- krb5_context context,
- krb5_auth_context auth_context)
+krb5_error_code KRB5_CALLCONV
+krb5_auth_con_initivector(krb5_context context, krb5_auth_context auth_context)
{
krb5_error_code ret;
@@ -326,7 +285,7 @@ krb5_auth_con_initivector(
if ((ret = krb5_c_block_size(context, auth_context->keyblock->enctype,
&blocksize)))
return(ret);
- if ((auth_context->i_vector = (krb5_pointer)MALLOC(blocksize))) {
+ if ((auth_context->i_vector = (krb5_pointer)malloc(blocksize))) {
memset(auth_context->i_vector, 0, blocksize);
return 0;
}
@@ -337,10 +296,7 @@ krb5_auth_con_initivector(
/*ARGSUSED*/
krb5_error_code
-krb5_auth_con_setivector(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_pointer ivector)
+krb5_auth_con_setivector(krb5_context context, krb5_auth_context auth_context, krb5_pointer ivector)
{
auth_context->i_vector = ivector;
return 0;
@@ -348,10 +304,7 @@ krb5_auth_con_setivector(
/*ARGSUSED*/
krb5_error_code
-krb5_auth_con_getivector(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_pointer * ivector)
+krb5_auth_con_getivector(krb5_context context, krb5_auth_context auth_context, krb5_pointer *ivector)
{
*ivector = auth_context->i_vector;
return 0;
@@ -359,10 +312,7 @@ krb5_auth_con_getivector(
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
-krb5_auth_con_setflags(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_int32 flags)
+krb5_auth_con_setflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 flags)
{
auth_context->auth_context_flags = flags;
return 0;
@@ -370,10 +320,7 @@ krb5_auth_con_setflags(
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
-krb5_auth_con_getflags(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_int32 * flags)
+krb5_auth_con_getflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 *flags)
{
*flags = auth_context->auth_context_flags;
return 0;
@@ -381,32 +328,23 @@ krb5_auth_con_getflags(
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
-krb5_auth_con_setrcache(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_rcache rcache)
+krb5_auth_con_setrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache rcache)
{
auth_context->rcache = rcache;
return 0;
}
-
+
/*ARGSUSED*/
krb5_error_code
-krb5_auth_con_getrcache(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_rcache * rcache)
+krb5_auth_con_getrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache *rcache)
{
*rcache = auth_context->rcache;
return 0;
}
-
+
/*ARGSUSED*/
krb5_error_code
-krb5_auth_con_setpermetypes(
- krb5_context context,
- krb5_auth_context auth_context,
- const krb5_enctype * permetypes)
+krb5_auth_con_setpermetypes(krb5_context context, krb5_auth_context auth_context, const krb5_enctype *permetypes)
{
krb5_enctype * newpe;
int i;
@@ -415,7 +353,7 @@ krb5_auth_con_setpermetypes(
;
i++; /* include the zero */
- if ((newpe = (krb5_enctype *) MALLOC(i*sizeof(krb5_enctype)))
+ if ((newpe = (krb5_enctype *) malloc(i*sizeof(krb5_enctype)))
== NULL)
return(ENOMEM);
@@ -424,6 +362,7 @@ krb5_auth_con_setpermetypes(
auth_context->permitted_etypes = newpe;
+ /* Solaris Kerberos */
(void) memcpy(newpe, permetypes, i*sizeof(krb5_enctype));
return 0;
@@ -431,10 +370,7 @@ krb5_auth_con_setpermetypes(
/*ARGSUSED*/
krb5_error_code
-krb5_auth_con_getpermetypes(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_enctype ** permetypes)
+krb5_auth_con_getpermetypes(krb5_context context, krb5_auth_context auth_context, krb5_enctype **permetypes)
{
krb5_enctype * newpe;
int i;
@@ -448,7 +384,7 @@ krb5_auth_con_getpermetypes(
;
i++; /* include the zero */
- if ((newpe = (krb5_enctype *) MALLOC(i*sizeof(krb5_enctype)))
+ if ((newpe = (krb5_enctype *) malloc(i*sizeof(krb5_enctype)))
== NULL)
return(ENOMEM);
@@ -461,47 +397,26 @@ krb5_auth_con_getpermetypes(
krb5_error_code KRB5_CALLCONV
krb5_auth_con_set_checksum_func( krb5_context context,
- krb5_auth_context auth_context,
- krb5_mk_req_checksum_func func,
- void *data)
+ krb5_auth_context auth_context,
+ krb5_mk_req_checksum_func func,
+ void *data)
{
auth_context->checksum_func = func;
auth_context->checksum_func_data = data;
return 0;
}
-static krb5_boolean
-chk_heimdal_seqnum(krb5_ui_4 exp_seq, krb5_ui_4 in_seq)
-{
- if (( exp_seq & 0xFF800000) == 0x00800000
- && (in_seq & 0xFF800000) == 0xFF800000
- && (in_seq & 0x00FFFFFF) == exp_seq)
- return 1;
- else if (( exp_seq & 0xFFFF8000) == 0x00008000
- && (in_seq & 0xFFFF8000) == 0xFFFF8000
- && (in_seq & 0x0000FFFF) == exp_seq)
- return 1;
- else if (( exp_seq & 0xFFFFFF80) == 0x00000080
- && (in_seq & 0xFFFFFF80) == 0xFFFFFF80
- && (in_seq & 0x000000FF) == exp_seq)
- return 1;
- else
- return 0;
-}
-
-
krb5_error_code KRB5_CALLCONV
krb5_auth_con_get_checksum_func( krb5_context context,
- krb5_auth_context auth_context,
- krb5_mk_req_checksum_func *func,
- void **data)
+ krb5_auth_context auth_context,
+ krb5_mk_req_checksum_func *func,
+ void **data)
{
*func = auth_context->checksum_func;
*data = auth_context->checksum_func_data;
return 0;
}
-
/*
* krb5int_auth_con_chkseqnum
*
@@ -517,7 +432,7 @@ krb5_auth_con_get_checksum_func( krb5_context context,
* X.690 BER (and consequently DER, which are the required encoding
* rules in RFC1510) encode all integer types as signed integers.
* This means that the MSB being set on the first octet of the
- * contents of the encoding indicates a negative value. Heimdal does
+ * contents of the encoding indicates a negative value. Heimdal does
* not prepend the required zero octet to unsigned integer encodings
* which would otherwise have the MSB of the first octet of their
* encodings set.
@@ -544,10 +459,10 @@ krb5_auth_con_get_checksum_func( krb5_context context,
* only set after we can unambiguously determine the sanity of the
* sending implementation. Once one of these flags is set, we accept
* only the sequence numbers appropriate to the remote implementation
- * type. We can make the determination in two different ways. The
+ * type. We can make the determination in two different ways. The
* first is to note the receipt of a "negative" sequence number when a
- * "positive" one was expected. The second is to note the receipt of
- * a sequence number that wraps through "zero" in a weird way. The
+ * "positive" one was expected. The second is to note the receipt of
+ * a sequence number that wraps through "zero" in a weird way. The
* latter corresponds to the receipt of an initial sequence number in
* the ambiguous range.
*
@@ -559,7 +474,7 @@ krb5_auth_con_get_checksum_func( krb5_context context,
*
* We have to do special treatment when receiving sequence numbers
* between 0xFF800000..0xFFFFFFFF, or when wrapping through zero
- * weirdly (due to ambiguous initial sequence number). If we are
+ * weirdly (due to ambiguous initial sequence number). If we are
* expecting a value corresponding to an ambiguous Heimdal counter
* value, and we receive an exact match, we can mark the remote end as
* sane.
@@ -579,36 +494,37 @@ krb5int_auth_con_chkseqnum(
*/
if (ac->auth_context_flags & KRB5_AUTH_CONN_SANE_SEQ)
return in_seq == exp_seq;
+
/*
* If sender is not known to be sane, first check the ambiguous
* range of received values, 0xFF800000..0xFFFFFFFF.
*/
if ((in_seq & 0xFF800000) == 0xFF800000) {
/*
- * If expected sequence number is in the range
+ * If expected sequence number is in the range
* 0xFF800000..0xFFFFFFFF, then we can't make any
* determinations about the sanity of the sending
* implementation.
*/
if ((exp_seq & 0xFF800000) == 0xFF800000 && in_seq == exp_seq)
- return 1;
+ return 1;
/*
- * If sender is not known for certain to be a broken Heimdal
+ * If sender is not known for certain to be a broken Heimdal
* implementation, check for exact match.
*/
if (!(ac->auth_context_flags & KRB5_AUTH_CONN_HEIMDAL_SEQ)
- && in_seq == exp_seq)
- return 1;
+ && in_seq == exp_seq)
+ return 1;
/*
- * Now apply hairy algorithm for matching sequence numbers
+ * Now apply hairy algorithm for matching sequence numbers
* sent by broken Heimdal implementations. If it matches, we
* know for certain it's a broken Heimdal sender.
*/
if (chk_heimdal_seqnum(exp_seq, in_seq)) {
- ac->auth_context_flags |= KRB5_AUTH_CONN_HEIMDAL_SEQ;
- return 1;
+ ac->auth_context_flags |= KRB5_AUTH_CONN_HEIMDAL_SEQ;
+ return 1;
}
- return 0;
+ return 0;
}
/*
@@ -617,10 +533,10 @@ krb5int_auth_con_chkseqnum(
* it matches the received value, sender is known to be sane.
*/
if (in_seq == exp_seq) {
- if (( exp_seq & 0xFFFFFF80) == 0x00000080
- || (exp_seq & 0xFFFF8000) == 0x00008000
- || (exp_seq & 0xFF800000) == 0x00800000)
- ac->auth_context_flags |= KRB5_AUTH_CONN_SANE_SEQ;
+ if (( exp_seq & 0xFFFFFF80) == 0x00000080
+ || (exp_seq & 0xFFFF8000) == 0x00008000
+ || (exp_seq & 0xFF800000) == 0x00800000)
+ ac->auth_context_flags |= KRB5_AUTH_CONN_SANE_SEQ;
return 1;
}
@@ -636,13 +552,31 @@ krb5int_auth_con_chkseqnum(
case 0x100:
case 0x10000:
case 0x1000000:
- ac->auth_context_flags |= KRB5_AUTH_CONN_HEIMDAL_SEQ;
- exp_seq = in_seq;
- return 1;
+ ac->auth_context_flags |= KRB5_AUTH_CONN_HEIMDAL_SEQ;
+ exp_seq = in_seq;
+ return 1;
default:
- return 0;
+ return 0;
}
}
return 0;
}
+static krb5_boolean
+chk_heimdal_seqnum(krb5_ui_4 exp_seq, krb5_ui_4 in_seq)
+{
+ if (( exp_seq & 0xFF800000) == 0x00800000
+ && (in_seq & 0xFF800000) == 0xFF800000
+ && (in_seq & 0x00FFFFFF) == exp_seq)
+ return 1;
+ else if (( exp_seq & 0xFFFF8000) == 0x00008000
+ && (in_seq & 0xFFFF8000) == 0xFFFF8000
+ && (in_seq & 0x0000FFFF) == exp_seq)
+ return 1;
+ else if (( exp_seq & 0xFFFFFF80) == 0x00000080
+ && (in_seq & 0xFFFFFF80) == 0xFFFFFF80
+ && (in_seq & 0x000000FF) == exp_seq)
+ return 1;
+ else
+ return 0;
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/bld_pr_ext.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/bld_pr_ext.c
index ed7159a9cb..1b55a8c6d8 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/bld_pr_ext.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/bld_pr_ext.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/bld_pr_ext.c
*
@@ -28,14 +27,14 @@
* Build a principal from a list of lengths and strings
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include <stdarg.h>
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV_C
krb5_build_principal_ext(krb5_context context, krb5_principal * princ,
- unsigned int rlen, const char * realm, ...)
+ unsigned int rlen, const char * realm, ...)
{
va_list ap;
register int i, count = 0;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/bld_princ.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/bld_princ.c
index 62948a44e0..505bde065e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/bld_princ.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/bld_princ.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/bld_princ.c
*
@@ -29,12 +28,12 @@
*/
#include <stdarg.h>
-#include <k5-int.h>
+#include "k5-int.h"
/*ARGSUSED*/
krb5_error_code
-krb5_build_principal_va(krb5_context context, krb5_principal princ,
- unsigned int rlen, const char *realm, va_list ap)
+KRB5_CALLCONV
+krb5_build_principal_va(krb5_context context, krb5_principal princ, unsigned int rlen, const char *realm, va_list ap)
{
register int i, count = 0;
register char *next;
@@ -92,9 +91,9 @@ krb5_build_principal_va(krb5_context context, krb5_principal princ,
}
krb5_error_code KRB5_CALLCONV_C
-krb5_build_principal(krb5_context context, krb5_principal * princ,
- unsigned int rlen,
- const char * realm, ...)
+krb5_build_principal(krb5_context context, krb5_principal * princ,
+ unsigned int rlen,
+ const char * realm, ...)
{
va_list ap;
krb5_error_code retval;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/chk_trans.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/chk_trans.c
index 8e5dd23223..9fe73c878b 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/chk_trans.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/chk_trans.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/chk_trans.c
*
@@ -27,9 +26,22 @@
*
* krb5_check_transited_list()
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include <stdarg.h>
+#if defined (TEST) || defined (TEST2)
+# undef DEBUG
+# define DEBUG
+#endif
+
+#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
@@ -38,9 +50,13 @@ process_intermediates (krb5_error_code (*fn)(krb5_data *, void *), void *data,
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;
@@ -54,8 +70,11 @@ process_intermediates (krb5_error_code (*fn)(krb5_data *, void *), void *data,
/* 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. */
@@ -67,9 +86,13 @@ process_intermediates (krb5_error_code (*fn)(krb5_data *, void *), void *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++)
@@ -86,12 +109,17 @@ process_intermediates (krb5_error_code (*fn)(krb5_data *, void *), void *data,
} 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;
@@ -104,6 +132,7 @@ process_intermediates (krb5_error_code (*fn)(krb5_data *, void *), void *data,
}
}
}
+ Tprintf (("(end intermediates)\n"));
return 0;
}
@@ -114,6 +143,7 @@ maybe_join (krb5_data *last, krb5_data *buf, int bufsiz)
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);
@@ -124,6 +154,7 @@ maybe_join (krb5_data *last, krb5_data *buf, int bufsiz)
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);
@@ -164,7 +195,13 @@ foreach_realm (krb5_error_code (*fn)(krb5_data *comp,void *data), void *data,
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;
}
@@ -225,6 +262,8 @@ foreach_realm (krb5_error_code (*fn)(krb5_data *comp,void *data), void *data,
}
}
/* 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. */
@@ -266,10 +305,12 @@ 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;
}
@@ -281,30 +322,34 @@ krb5_check_transited_list (krb5_context ctx, const krb5_data *trans_in,
struct check_data cdata;
krb5_error_code r;
- /*
- * Work around buggy implementations that include NULL terminator in length.
- */
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"));
}
#endif
cdata.ctx = ctx;
@@ -312,3 +357,85 @@ krb5_check_transited_list (krb5_context ctx, const krb5_data *trans_in,
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 (argc != 4) {
+ usage:
+ printf ("usage: %s [-v] [-x] clientRealm serverRealm transitEncoding\n",
+ me);
+ return 1;
+ }
+
+ 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/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/chpw.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/chpw.c
index f964132e87..f9a26bf38d 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/chpw.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/chpw.c
@@ -1,22 +1,21 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
** set password functions added by Paul W. Nelson, Thursby Software Systems, Inc.
*/
#include <string.h>
#include "k5-int.h"
-/* #include "krb5_err.h" gtb */
+/* Solaris Kerberos */
+/* #include "krb5_err.h" */
#include "auth_con.h"
krb5_error_code
-krb5int_mk_chpw_req(krb5_context context, krb5_auth_context auth_context, krb5_data *ap_req, char *passwd, krb5_data *packet)
+krb5int_mk_chpw_req(
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_data *ap_req,
+ char *passwd,
+ krb5_data *packet)
{
krb5_error_code ret = 0;
krb5_data clearpw;
@@ -40,15 +39,15 @@ krb5int_mk_chpw_req(krb5_context context, krb5_auth_context auth_context, krb5_d
packet->length = 6 + ap_req->length + cipherpw.length;
packet->data = (char *) malloc(packet->length);
if (packet->data == NULL)
- {
+ {
ret = ENOMEM;
goto cleanup;
- }
+ }
ptr = packet->data;
/* length */
- *ptr++ = (packet->length>>8) & 0xff;
+ *ptr++ = (packet->length>> 8) & 0xff;
*ptr++ = packet->length & 0xff;
/* version == 0x0001 big-endian */
@@ -87,7 +86,8 @@ krb5int_rd_chpw_rep(krb5_context context, krb5_auth_context auth_context, krb5_d
krb5_error_code ret;
krb5_data cipherresult;
krb5_data clearresult;
- krb5_error *krberror;
+ /* Solaris Kerberos */
+ krb5_error *krberror = NULL;
krb5_replay_data replay;
krb5_keyblock *tmp;
@@ -103,8 +103,35 @@ krb5int_rd_chpw_rep(krb5_context context, krb5_auth_context auth_context, krb5_d
plen = (*ptr++ & 0xff);
plen = (plen<<8) | (*ptr++ & 0xff);
- if (plen != packet->length)
- return(KRB5KRB_AP_ERR_MODIFIED);
+ if (plen != packet->length)
+ {
+ /*
+ * MS KDCs *may* send back a KRB_ERROR. Although
+ * not 100% correct via RFC3244, it's something
+ * we can workaround here.
+ */
+ if (krb5_is_krb_error(packet)) {
+
+ if ((ret = krb5_rd_error(context, packet, &krberror)))
+ return(ret);
+
+ if (krberror->e_data.data == NULL) {
+ ret = ERROR_TABLE_BASE_krb5 + (krb5_error_code) krberror->error;
+ krb5_free_error(context, krberror);
+ return (ret);
+ }
+ }
+ else
+ {
+ return(KRB5KRB_AP_ERR_MODIFIED);
+ }
+ }
+
+ /* Solaris Kerberos */
+ if (krberror != NULL) {
+ krb5_free_error(context, krberror);
+ krberror = NULL;
+ }
/* verify version number */
@@ -374,7 +401,7 @@ krb5int_rd_setpw_rep( krb5_context context, krb5_auth_context auth_context, krb5
/*
** set password version is 0xff80, change password version is 1
*/
- if (version_number != 0xff80 && version_number != 1)
+ if (version_number != 1 && version_number != 0xff80)
return(KRB5KDC_ERR_BAD_PVNO);
/*
** now fill in ap_rep with the reply -
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/conv_princ.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/conv_princ.c
index a6d60ea88e..9c0d9fe47a 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/conv_princ.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/conv_princ.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/conv_princ.c
@@ -15,7 +14,7 @@
* 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
@@ -29,10 +28,10 @@
* 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.
- *
+ *
* Build a principal from a V4 specification, or separate a V5
* principal into name, instance, and realm.
- *
+ *
* NOTE: This is highly site specific, and is only really necessary
* for sites who need to convert from V4 to V5. It is used by both
* the KDC and the kdb5_convert program. Since its use is highly
@@ -40,7 +39,7 @@
* hard-coded in this file.
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include <string.h>
#include <ctype.h>
@@ -52,10 +51,10 @@
#define INST_SZ 40
struct krb_convert {
- char *v4_str;
- char *v5_str;
- unsigned int flags : 8;
- unsigned int len : 8;
+ char *v4_str;
+ char *v5_str;
+ unsigned int flags : 8;
+ unsigned int len : 8;
};
#define DO_REALM_CONVERSION 0x00000001
@@ -126,7 +125,7 @@ static const struct krb_convert sconv_list[] = {
* char *strnchr(s, c, n)
* char *s;
* char c;
- * int n;
+ * unsigned int n;
*
* returns a pointer to the first occurrence of character c in the
* string s, or a NULL pointer if c does not occur in in the string;
@@ -135,12 +134,12 @@ static const struct krb_convert sconv_list[] = {
* This falls in the "should have been in the ANSI C library"
* category. :-)
*/
-static char *strnchr(register char *s, register char c,
- register unsigned int n)
+static char *strnchr(register char *s, register char c,
+ register unsigned int n)
{
- if (n < 1)
+ if (n < 1)
return 0;
-
+
while (n-- && *s) {
if (*s == c)
return s;
@@ -156,13 +155,13 @@ static char *strnchr(register char *s, register char c,
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
krb5_524_conv_principal(krb5_context context, krb5_const_principal princ,
- char *name, char *inst, char *realm)
+ char *name, char *inst, char *realm)
{
const struct krb_convert *p;
const krb5_data *compo;
char *c, *tmp_realm, *tmp_prealm;
unsigned int tmp_realm_len;
- int retval;
+ int retval;
*name = *inst = '\0';
switch (krb5_princ_size(context, princ)) {
@@ -225,7 +224,7 @@ krb5_524_conv_principal(krb5_context context, krb5_const_principal princ,
strncpy(tmp_prealm, compo->data, compo->length);
tmp_prealm[compo->length] = '\0';
- /* Ask for v4_realm corresponding to
+ /* Ask for v4_realm corresponding to
krb5 principal realm from krb5.conf realms stanza */
if (context->profile == 0)
@@ -234,7 +233,7 @@ krb5_524_conv_principal(krb5_context context, krb5_const_principal princ,
tmp_prealm, "v4_realm", 0,
&tmp_realm);
free(tmp_prealm);
- if (retval) {
+ if (retval) {
return retval;
} else {
if (tmp_realm == 0) {
@@ -256,25 +255,27 @@ krb5_524_conv_principal(krb5_context context, krb5_const_principal princ,
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
-krb5_425_conv_principal(krb5_context context, const char *name, const char *instance, const char *realm, krb5_principal *princ)
+krb5_425_conv_principal(krb5_context context, const char *name,
+ const char *instance, const char *realm,
+ krb5_principal *princ)
{
const struct krb_convert *p;
char buf[256]; /* V4 instances are limited to 40 characters */
krb5_error_code retval;
- char **full_name = 0;
char *domain, *cp;
- const char *names[5];
+ char **full_name = 0;
+ const char *names[5], *names2[2];
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
+ 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);
+ names2 [0] = "realms";
+ names2 [1] = NULL;
+ retval = profile_iterator_create (context -> profile, names2, 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)) {
@@ -307,7 +308,7 @@ krb5_425_conv_principal(krb5_context context, const char *name, const char *inst
dummy_value = NULL;
}
}
-
+
if (instance) {
if (instance[0] == '\0') {
instance = 0;
@@ -315,7 +316,7 @@ krb5_425_conv_principal(krb5_context context, const char *name, const char *inst
}
p = sconv_list;
/*CONSTCOND*/
- while (TRUE) {
+ while (1) {
if (!p->v4_str)
goto not_service;
if (!strcmp(p->v4_str, name))
@@ -340,8 +341,8 @@ krb5_425_conv_principal(krb5_context context, const char *name, const char *inst
return retval;
if (domain) {
for (cp = domain; *cp; cp++)
- if (isupper((int) (*cp)))
- *cp = tolower((int) *cp);
+ if (isupper((unsigned char) (*cp)))
+ *cp = tolower((unsigned char) *cp);
strncat(buf, ".", sizeof(buf) - 1 - strlen(buf));
strncat(buf, domain, sizeof(buf) - 1 - strlen(buf));
krb5_xfree(domain);
@@ -350,8 +351,8 @@ krb5_425_conv_principal(krb5_context context, const char *name, const char *inst
}
}
}
-
-not_service:
+
+not_service:
retval = krb5_build_principal(context, princ, strlen(realm), realm, name,
instance, NULL);
if (iterator) profile_iterator_free (&iterator);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_addrs.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_addrs.c
index bc31ecab20..c8d38a2281 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_addrs.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_addrs.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/copy_addrs.c
*
@@ -28,7 +27,7 @@
* krb5_copy_addresses()
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
@@ -38,11 +37,7 @@ krb5_copy_addr(krb5_context context, const krb5_address *inad, krb5_address **ou
if (!(tmpad = (krb5_address *)malloc(sizeof(*tmpad))))
return ENOMEM;
-#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
*tmpad = *inad;
-#else
- memcpy(tmpad, inad, sizeof(krb5_address));
-#endif
if (!(tmpad->contents = (krb5_octet *)malloc(inad->length))) {
krb5_xfree(tmpad);
return ENOMEM;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_creds.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_creds.c
index d277543362..9f1429c08e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_creds.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_creds.c
@@ -1,11 +1,4 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* lib/krb5/krb/copy_creds.c
*
* Copyright 1990,1991 by the Massachusetts Institute of Technology.
@@ -34,7 +27,7 @@
* krb5_copy_cred()
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
* Copy credentials, allocating fresh storage where needed.
@@ -50,11 +43,7 @@ krb5_copy_creds(krb5_context context, const krb5_creds *incred, krb5_creds **out
if (!(tempcred = (krb5_creds *)malloc(sizeof(*tempcred))))
return ENOMEM;
-#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
- *tempcred = *incred; /* copy everything quickly */
-#else
- memcpy(tempcred, incred, sizeof(krb5_creds));
-#endif
+ *tempcred = *incred;
retval = krb5_copy_principal(context, incred->client, &tempcred->client);
if (retval)
goto cleanlast;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_data.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_data.c
index 183956a502..f7ac6388dd 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_data.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_data.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/copy_data.c
*
@@ -28,7 +27,7 @@
* krb5_copy_data()
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
* Copy a data structure, with fresh allocation.
@@ -61,7 +60,7 @@ krb5_copy_data(krb5_context context, const krb5_data *indata, krb5_data **outdat
return 0;
}
-krb5_error_code
+krb5_error_code
krb5int_copy_data_contents(krb5_context context, const krb5_data *indata, krb5_data *outdata)
{
if (!indata) {
@@ -71,14 +70,12 @@ krb5int_copy_data_contents(krb5_context context, const krb5_data *indata, krb5_d
outdata->length = indata->length;
if (outdata->length) {
if (!(outdata->data = malloc(outdata->length))) {
- krb5_xfree(outdata);
- return ENOMEM;
+ return ENOMEM;
}
- memcpy((char *)outdata->data, (char *)indata->data, outdata->length);
+ memcpy((char *)outdata->data, (char *)indata->data, outdata->length);
} else
- outdata->data = 0;
+ outdata->data = 0;
outdata->magic = KV5M_DATA;
return 0;
}
-
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_tick.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_tick.c
index 1fbeefa24c..43268e50f2 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_tick.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/copy_tick.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/copy_tick.c
*
@@ -28,7 +27,7 @@
* krb5_copy_ticket()
*/
-#include <k5-int.h>
+#include "k5-int.h"
static krb5_error_code
krb5_copy_enc_tkt_part(krb5_context context, const krb5_enc_tkt_part *partfrom, krb5_enc_tkt_part **partto)
@@ -38,11 +37,7 @@ krb5_copy_enc_tkt_part(krb5_context context, const krb5_enc_tkt_part *partfrom,
if (!(tempto = (krb5_enc_tkt_part *)malloc(sizeof(*tempto))))
return ENOMEM;
-#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
*tempto = *partfrom;
-#else
- memcpy(tempto, partfrom, sizeof(krb5_enc_tkt_part));
-#endif
retval = krb5_copy_keyblock(context, partfrom->session,
&tempto->session);
if (retval) {
@@ -105,11 +100,7 @@ krb5_copy_ticket(krb5_context context, const krb5_ticket *from, krb5_ticket **pt
if (!(tempto = (krb5_ticket *)malloc(sizeof(*tempto))))
return ENOMEM;
-#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
*tempto = *from;
-#else
- memcpy(tempto, from, sizeof(krb5_ticket));
-#endif
retval = krb5_copy_principal(context, from->server, &tempto->server);
if (retval) {
krb5_xfree(tempto);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/cp_key_cnt.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/cp_key_cnt.c
index f26a490e5d..6a623aa447 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/cp_key_cnt.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/cp_key_cnt.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/cp_key_cnt.c
*
@@ -33,18 +32,16 @@
* krb5_copy_keyblock()
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
* Copy a keyblock, including alloc'ed storage.
*/
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
-krb5_copy_keyblock_contents(
- krb5_context context,
- const krb5_keyblock *from,
- krb5_keyblock *to)
+krb5_copy_keyblock_contents(krb5_context context, const krb5_keyblock *from, krb5_keyblock *to)
{
+ /* Solaris Kerberos */
krb5_error_code ret = EINVAL;
if (to != NULL && from != NULL) {
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/decode_kdc.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/decode_kdc.c
index 8ce9e8d489..cdfc4ffbde 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/decode_kdc.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/decode_kdc.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/decode_kdc.c
*
@@ -28,7 +27,7 @@
* krb5_decode_kdc_rep() function.
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
Takes a KDC_REP message and decrypts encrypted part using etype and
@@ -69,7 +68,7 @@ krb5_decode_kdc_rep(krb5_context context, krb5_data *enc_rep, const krb5_keybloc
return retval;
if ((retval = krb5_kdc_rep_decrypt_proc(context, key, &usage,
- local_dec_rep)))
+ local_dec_rep)))
krb5_free_kdc_rep(context, local_dec_rep);
else
*dec_rep = local_dec_rep;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/encode_kdc.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/encode_kdc.c
index d0df5605e4..8b879c0159 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/encode_kdc.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/encode_kdc.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/encode_kdc.c
*
@@ -28,7 +27,7 @@
* krb5_encode_kdc_rep() function.
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
Takes KDC rep parts in *rep and *encpart, and formats it into *enc_rep,
@@ -55,7 +54,7 @@ krb5_encode_kdc_rep(krb5_context context, krb5_msgtype type,
krb5_enc_kdc_rep_part tmp_encpart;
krb5_keyusage usage;
- if (!valid_enctype(dec_rep->enc_part.enctype))
+ if (!krb5_c_valid_enctype(dec_rep->enc_part.enctype))
return KRB5_PROG_ETYPE_NOSUPP;
switch (type) {
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/free_rtree.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/free_rtree.c
index cc861b0652..7914d3f239 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/free_rtree.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/free_rtree.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/free_rtree.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/fwd_tgt.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/fwd_tgt.c
index 7a3944aa13..69ba165e54 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/fwd_tgt.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/fwd_tgt.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/get_in_tkt.c
@@ -31,31 +30,32 @@
* or implied warranty.
*/
-#define NEED_SOCKETS
-#include <k5-int.h>
+#include "k5-int.h"
+#ifdef HAVE_MEMORY_H
#include <memory.h>
+#endif
/* helper function: convert flags to necessary KDC options */
#define flags2options(flags) (flags & KDC_TKT_COMMON_MASK)
/* Get a TGT for use at the remote host */
krb5_error_code KRB5_CALLCONV
-krb5_fwd_tgt_creds(
- krb5_context context,
- krb5_auth_context auth_context,
- char *rhost,
- krb5_principal client,
- krb5_principal server,
- krb5_ccache cc,
- int forwardable, /* Should forwarded TGT also be forwardable? */
- krb5_data *outbuf)
+krb5_fwd_tgt_creds(krb5_context context, krb5_auth_context auth_context, char *rhost, krb5_principal client, krb5_principal server, krb5_ccache cc, int forwardable, krb5_data *outbuf)
+
+
+
+
+
+
+ /* Should forwarded TGT also be forwardable? */
+
{
krb5_replay_data replaydata;
krb5_data * scratch = 0;
- krb5_address **addrs = 0;
+ krb5_address **addrs = NULL;
krb5_error_code retval;
krb5_creds creds, tgt;
- krb5_creds *pcreds = 0;
+ krb5_creds *pcreds;
krb5_flags kdcoptions;
int close_cc = 0;
int free_rhost = 0;
@@ -67,13 +67,13 @@ krb5_fwd_tgt_creds(
memset((char *)&tgt, 0, sizeof(creds));
if (cc == 0) {
- if ((retval = krb5int_cc_default(context, &cc)))
+ if ((retval = krb5int_cc_default(context, &cc)))
goto errout;
- close_cc = 1;
+ close_cc = 1;
}
retval = krb5_auth_con_getkey (context, auth_context, &session_key);
if (retval)
- goto errout;
+ goto errout;
if (session_key) {
enctype = session_key->enctype;
krb5_free_keyblock (context, session_key);
@@ -86,19 +86,19 @@ krb5_fwd_tgt_creds(
retval = krb5_copy_principal (context, server, &in.server);
if (retval)
- goto punt;
+ goto punt;
retval = krb5_copy_principal (context, client, &in.client);
if (retval)
- goto punt;
+ goto punt;
retval = krb5_get_credentials (context, 0, cc, &in, &out);
if (retval)
- goto punt;
- /* Got the credentials. Okay, now record the enctype and
+ 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);
+ krb5_free_cred_contents (context, &in);
}
if ((retval = krb5_copy_principal(context, client, &creds.client)))
@@ -132,34 +132,35 @@ krb5_fwd_tgt_creds(
retval = KRB5_NO_TKT_SUPPLIED;
goto errout;
}
-
+
if (tgt.addresses && *tgt.addresses) {
- if (rhost == NULL) {
- if (krb5_princ_type(context, server) != KRB5_NT_SRV_HST) {
- retval = KRB5_FWD_BAD_PRINCIPAL;
- goto errout;
- }
-
- if (krb5_princ_size(context, server) < 2) {
- retval = KRB5_CC_BADNAME;
- goto errout;
- }
+ if (rhost == NULL) {
+ if (krb5_princ_type(context, server) != KRB5_NT_SRV_HST) {
+retval = KRB5_FWD_BAD_PRINCIPAL;
+ goto errout;
+ }
- rhost = malloc(server->data[1].length+1);
- if (!rhost) {
- retval = ENOMEM;
- goto errout;
- }
- free_rhost = 1;
- (void) memcpy(rhost, server->data[1].data, server->data[1].length);
- rhost[server->data[1].length] = '\0';
+ if (krb5_princ_size(context, server) < 2){
+ retval = KRB5_CC_BADNAME;
+ goto errout;
+ }
+
+ rhost = malloc(server->data[1].length+1);
+ if (!rhost) {
+ retval = ENOMEM;
+ goto errout;
}
+ free_rhost = 1;
+ /* Solaris Kerberos */
+ (void) memcpy(rhost, server->data[1].data, server->data[1].length);
+ rhost[server->data[1].length] = '\0';
+ }
retval = krb5_os_hostaddr(context, rhost, &addrs);
if (retval)
goto errout;
}
-
+
creds.keyblock.enctype = enctype;
creds.times = tgt.times;
creds.times.starttime = 0;
@@ -173,16 +174,17 @@ krb5_fwd_tgt_creds(
if (enctype) {
creds.keyblock.enctype = 0;
if ((retval = krb5_get_cred_via_tkt(context, &tgt, kdcoptions,
- addrs, &creds, &pcreds)))
+ addrs, &creds, &pcreds)))
goto errout;
- } else goto errout;
+ }
+ else goto errout;
}
-
retval = krb5_mk_1cred(context, auth_context, pcreds,
&scratch, &replaydata);
krb5_free_creds(context, pcreds);
- /* Solaris Kerberos: changed this logic from the MIT 1.2.1 version to be
+ /*
+ * Solaris Kerberos: changed this logic from the MIT 1.2.1 version to be
* more robust.
*/
if (scratch) {
@@ -197,6 +199,7 @@ krb5_fwd_tgt_creds(
errout:
if (addrs)
krb5_free_addresses(context, addrs);
+ /* Solaris Kerberos */
if (close_cc)
(void) krb5_cc_close(context, cc);
if (free_rhost)
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gc_frm_kdc.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gc_frm_kdc.c
index 07f853cb0d..bcd96cdd0e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gc_frm_kdc.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gc_frm_kdc.c
@@ -1,12 +1,11 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
- * Copyright (c) 1994,2003,2005,2007 by the Massachusetts Institute of Technology.
+ * Copyright (c) 1994,2003,2005 by the Massachusetts Institute of Technology.
* Copyright (c) 1994 CyberSAFE Corporation
* Copyright (c) 1993 Open Computing Security Group
* Copyright (c) 1990,1991 by the Massachusetts Institute of Technology.
@@ -38,7 +37,7 @@
* along the way.
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include <stdio.h>
#include "int-proto.h"
@@ -408,7 +407,7 @@ static krb5_error_code
try_ccache(struct tr_state *ts, krb5_creds *tgtq)
{
krb5_error_code retval;
- krb5_timestamp saved_endtime;
+ krb5_timestamp saved_endtime;
TR_DBG(ts, "try_ccache");
/*
@@ -547,10 +546,10 @@ try_kdc(struct tr_state *ts, krb5_creds *tgtq)
ts->cur_tgt->addresses,
&ltgtq, &tmp_out_cred);
if (retval) {
- ts->ntgts--;
- ts->nxt_tgt = ts->cur_tgt;
- TR_DBG_RET(ts, "try_kdc", retval);
- return retval;
+ ts->ntgts--;
+ ts->nxt_tgt = ts->cur_tgt;
+ TR_DBG_RET(ts, "try_kdc", retval);
+ return retval;
}
/*
@@ -903,7 +902,7 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache,
server->realm.data[server->realm.length] = 0;
}
/*
- * Retrieve initial TGT to match the specified server, either for the
+ * Retreive initial TGT to match the specified server, either for the
* local realm in the default (referral) case or for the remote
* realm if we're starting someplace non-local.
*/
@@ -983,7 +982,6 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache,
/* Whether or not that succeeded, we're done. */
goto cleanup;
}
- else {
/* Referral request succeeded; let's see what it is. */
if (krb5_principal_compare(context, in_cred->server,
(*out_cred)->server)) {
@@ -991,6 +989,38 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache,
"for requested server principal\n"));
DUMP_PRINC("gc_from_kdc final referred reply",
in_cred->server);
+
+ /*
+ * Check if the return enctype is one that we requested if
+ * needed.
+ */
+ if (old_use_conf_ktypes || context->tgs_ktype_count == 0)
+ goto cleanup;
+ for (i = 0; i < context->tgs_ktype_count; i++) {
+ if ((*out_cred)->keyblock.enctype == context->tgs_ktypes[i]) {
+ /* Found an allowable etype, so we're done */
+ goto cleanup;
+ }
+ }
+ /*
+ * We need to try again, but this time use the
+ * tgs_ktypes in the context. At this point we should
+ * have all the tgts to succeed.
+ */
+
+ /* Free "wrong" credential */
+ krb5_free_creds(context, *out_cred);
+ *out_cred = NULL;
+ /* Re-establish tgs etypes */
+ context->use_conf_ktypes = old_use_conf_ktypes;
+ retval = krb5_get_cred_via_tkt(context, tgtptr,
+ KDC_OPT_CANONICALIZE |
+ FLAGS2OPTS(tgtptr->ticket_flags) |
+ kdcopt |
+ (in_cred->second_ticket.length ?
+ KDC_OPT_ENC_TKT_IN_SKEY : 0),
+ tgtptr->addresses,
+ in_cred, out_cred);
goto cleanup;
}
else if (IS_TGS_PRINC(context, (*out_cred)->server)) {
@@ -1055,7 +1085,6 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache,
krb5_free_creds(context, *out_cred);
*out_cred = NULL;
break;
- }
}
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gc_via_tkt.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gc_via_tkt.c
index 93fb5f1a70..8ee5721a7c 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gc_via_tkt.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gc_via_tkt.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/gc_via_tgt.c
*
@@ -243,6 +242,35 @@ krb5_get_cred_via_tkt (krb5_context context, krb5_creds *tkt,
goto error_4;
retval = (krb5_error_code) err_reply->error + ERROR_TABLE_BASE_krb5;
+ if (err_reply->text.length > 0) {
+#if 0
+ const char *m;
+#endif
+ switch (err_reply->error) {
+ case KRB_ERR_GENERIC:
+ krb5_set_error_message(context, retval,
+ "KDC returned error string: %s",
+ err_reply->text.data);
+ break;
+ default:
+#if 0 /* We should stop the KDC from sending back this text, because
+ if the local language doesn't match the KDC's language, we'd
+ just wind up printing out the error message in two languages.
+ Well, when we get some localization. Which is already
+ happening in KfM. */
+ m = error_message(retval);
+ /* Special case: MIT KDC may return this same string
+ in the e-text field. */
+ if (strlen (m) == err_reply->text.length-1
+ && !strcmp(m, err_reply->text.data))
+ break;
+ krb5_set_error_message(context, retval,
+ "%s (KDC supplied additional data: %s)",
+ m, err_reply->text.data);
+#endif
+ break;
+ }
+ }
krb5_free_error(context, err_reply);
goto error_4;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gen_seqnum.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gen_seqnum.c
index 23a8a34ec8..815529cf53 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gen_seqnum.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gen_seqnum.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/gen_seqnum.c
*
@@ -35,7 +34,7 @@
* then taking the output and slicing it up.
*/
-#include <k5-int.h>
+#include "k5-int.h"
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -54,7 +53,7 @@ krb5_generate_seq_number(krb5_context context, const krb5_keyblock *key, krb5_ui
seed.length = key->length;
- seed.data = (char *)key->contents;
+ seed.data = key->contents;
if ((retval = krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed)))
return(retval);
#endif /* 0 */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gen_subkey.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gen_subkey.c
index 3fa1a80ce7..bc2ee772e6 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gen_subkey.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gen_subkey.c
@@ -1,8 +1,7 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/gen_subkey.c
*
- * Copyright 1991 by the Massachusetts Institute of Technology.
+ * Copyright 1991, 2002 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -28,7 +27,7 @@
* Routine to automatically generate a subsession key based on an input key.
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*ARGSUSED*/
krb5_error_code
@@ -45,7 +44,7 @@ krb5_generate_subkey(krb5_context context, const krb5_keyblock *key, krb5_keyblo
krb5_data seed;
seed.length = key->length;
- seed.data = (char *)key->contents;
+ seed.data = key->contents;
if ((retval = krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed)))
return(retval);
#endif /* 0 */
@@ -53,6 +52,7 @@ krb5_generate_subkey(krb5_context context, const krb5_keyblock *key, krb5_keyblo
if ((*subkey = (krb5_keyblock *) malloc(sizeof(krb5_keyblock))) == NULL)
return(ENOMEM);
+ /* Solaris Kerberos */
(void) memset(*subkey, 0, sizeof(krb5_keyblock));
if ((retval = krb5_c_make_random_key(context, key->enctype, *subkey))) {
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/get_creds.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/get_creds.c
index e0a9834271..202015ee36 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/get_creds.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/get_creds.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/get_creds.c
@@ -15,7 +14,7 @@
* 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
@@ -29,7 +28,7 @@
* 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_get_credentials()
*/
@@ -50,7 +49,7 @@
returns errors from encryption routines, system errors
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*ARGSUSED*/
static krb5_error_code
@@ -58,6 +57,7 @@ krb5_get_credentials_core(krb5_context context, krb5_flags options,
krb5_creds *in_creds, krb5_creds *mcreds,
krb5_flags *fields)
{
+ /* Solaris Kerberos */
krb5_error_code ret = 0;
if (!in_creds || !in_creds->server || !in_creds->client)
@@ -66,6 +66,7 @@ krb5_get_credentials_core(krb5_context context, krb5_flags options,
memset((char *)mcreds, 0, sizeof(krb5_creds));
mcreds->magic = KV5M_CREDS;
/*
+ * Solaris Kerberos:
* Set endtime appropriately to make sure we do not rope in
* expired creds. If endtime is set to 0 (which it almost always
* is, courtesy memset/calloc) the krb5_cc_retrieve_cred() call in
@@ -90,7 +91,7 @@ krb5_get_credentials_core(krb5_context context, krb5_flags options,
mcreds->authdata = in_creds->authdata;
mcreds->server = in_creds->server;
mcreds->client = in_creds->client;
-
+
*fields = KRB5_TC_MATCH_TIMES /*XXX |KRB5_TC_MATCH_SKEY_TYPE */
| KRB5_TC_MATCH_AUTHDATA
| KRB5_TC_SUPPORTED_KTYPES;
@@ -101,13 +102,13 @@ krb5_get_credentials_core(krb5_context context, krb5_flags options,
*fields |= KRB5_TC_MATCH_KTYPE;
ret = krb5_get_tgs_ktypes (context, mcreds->server, &ktypes);
for (i = 0; ktypes[i]; i++)
- if (ktypes[i] == mcreds->keyblock.enctype)
+ if (ktypes[i] == mcreds->keyblock.enctype)
break;
if (ktypes[i] == 0)
- ret = KRB5_CC_NOT_KTYPE;
+ ret = KRB5_CC_NOT_KTYPE;
free (ktypes);
if (ret)
- return ret;
+ return ret;
}
if (options & KRB5_GC_USER_USER) {
/* also match on identical 2nd tkt and tkt encrypted in a
@@ -147,6 +148,7 @@ krb5_get_credentials(krb5_context context, krb5_flags options,
ncreds->magic = KV5M_CREDS;
/* The caller is now responsible for cleaning up in_creds */
+ /* Solaris Kerberos */
if ((retval = krb5_cc_retrieve_cred(context, ccache, fields, &mcreds,
ncreds)) !=0) {
krb5_xfree(ncreds);
@@ -169,6 +171,7 @@ krb5_get_credentials(krb5_context context, krb5_flags options,
register int i = 0;
krb5_error_code rv2;
while (tgts[i]) {
+ /* Solaris Kerberos */
if ((rv2 = krb5_cc_store_cred(context, ccache, tgts[i])) != 0) {
retval = rv2;
break;
@@ -192,8 +195,16 @@ krb5_get_credentials(krb5_context context, krb5_flags options,
&& not_ktype)
retval = KRB5_CC_NOT_KTYPE;
- if (!retval)
+ if (!retval) {
+ /* the purpose of the krb5_get_credentials call is to
+ * obtain a set of credentials for the caller. the
+ * krb5_cc_store_cred() call is to optimize performance
+ * for future calls. Ignore any errors, since the credentials
+ * are still valid even if we fail to store them in the cache.
+ */
+ /* Solaris Kerberos */
retval = krb5_cc_store_cred(context, ccache, *out_creds);
+ }
return retval;
}
@@ -201,7 +212,7 @@ krb5_get_credentials(krb5_context context, krb5_flags options,
#define INT_GC_RENEW 2
/*ARGSUSED*/
-static krb5_error_code
+static krb5_error_code
krb5_get_credentials_val_renew_core(krb5_context context, krb5_flags options,
krb5_ccache ccache, krb5_creds *in_creds,
krb5_creds **out_creds, int which)
@@ -212,11 +223,11 @@ krb5_get_credentials_val_renew_core(krb5_context context, krb5_flags options,
switch(which) {
case INT_GC_VALIDATE:
- retval = krb5_get_cred_from_kdc_validate(context, ccache,
+ retval = krb5_get_cred_from_kdc_validate(context, ccache,
in_creds, out_creds, &tgts);
break;
case INT_GC_RENEW:
- retval = krb5_get_cred_from_kdc_renew(context, ccache,
+ retval = krb5_get_cred_from_kdc_renew(context, ccache,
in_creds, out_creds, &tgts);
break;
default:
@@ -229,8 +240,9 @@ krb5_get_credentials_val_renew_core(krb5_context context, krb5_flags options,
retval = krb5_cc_get_principal(context, ccache, &tmp);
if (retval) return retval;
-
+
retval = krb5_cc_initialize(context, ccache, tmp);
+ /* Solaris Kerberos */
if (retval) {
krb5_free_principal(context, tmp);
return retval;
@@ -246,8 +258,8 @@ krb5_get_credentials_validate(krb5_context context, krb5_flags options,
krb5_ccache ccache, krb5_creds *in_creds,
krb5_creds **out_creds)
{
- return(krb5_get_credentials_val_renew_core(context, options, ccache,
- in_creds, out_creds,
+ return(krb5_get_credentials_val_renew_core(context, options, ccache,
+ in_creds, out_creds,
INT_GC_VALIDATE));
}
@@ -257,8 +269,8 @@ krb5_get_credentials_renew(krb5_context context, krb5_flags options,
krb5_creds **out_creds)
{
- return(krb5_get_credentials_val_renew_core(context, options, ccache,
- in_creds, out_creds,
+ return(krb5_get_credentials_val_renew_core(context, options, ccache,
+ in_creds, out_creds,
INT_GC_RENEW));
}
@@ -313,12 +325,12 @@ krb5_validate_or_renew_creds(krb5_context context, krb5_creds *creds,
}
if (validate)
- ret = krb5_get_cred_from_kdc_validate(context, ccache,
+ ret = krb5_get_cred_from_kdc_validate(context, ccache,
&in_creds, &out_creds, &tgts);
else
- ret = krb5_get_cred_from_kdc_renew(context, ccache,
+ ret = krb5_get_cred_from_kdc_renew(context, ccache,
&in_creds, &out_creds, &tgts);
-
+
/* ick. copy the struct contents, free the container */
if (out_creds) {
*creds = *out_creds;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/get_in_tkt.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/get_in_tkt.c
index fec64093f2..130abeca1c 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/get_in_tkt.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/get_in_tkt.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"$
/*
* lib/krb5/krb/get_in_tkt.c
@@ -36,10 +35,9 @@
#include <string.h>
-#include <k5-int.h>
-#include <krb5.h>
-#include <int-proto.h>
-#include <os-proto.h>
+#include "k5-int.h"
+#include "int-proto.h"
+#include "os-proto.h"
/*
All-purpose initial ticket routine, usually called via
@@ -48,7 +46,7 @@
Attempts to get an initial ticket for creds->client to use server
creds->server, (realm is taken from creds->client), with options
options, and using creds->times.starttime, creds->times.endtime,
- creds->times.renew_till as from, till, and rtime.
+ creds->times.renew_till as from, till, and rtime.
creds->times.renew_till is ignored unless the RENEWABLE option is requested.
key_proc is called to fill in the key to be used for decryption.
@@ -69,6 +67,7 @@
*/
+/* Solaris Kerberos */
#define max(a, b) ((a) > (b) ? (a) : (b))
/* some typedef's for the function args to make things look a bit cleaner */
@@ -82,11 +81,14 @@ typedef krb5_error_code (*git_key_proc) (krb5_context,
typedef krb5_error_code (*git_decrypt_proc) (krb5_context,
const krb5_keyblock *,
krb5_const_pointer,
- krb5_kdc_rep *);
+ krb5_kdc_rep * );
-static krb5_error_code make_preauth_list (krb5_context,
+static krb5_error_code make_preauth_list (krb5_context,
krb5_preauthtype *,
int, krb5_pa_data ***);
+static krb5_error_code sort_krb5_padata_sequence(krb5_context context,
+ krb5_data *realm,
+ krb5_pa_data **padata);
/*
* This function performs 32 bit bounded addition so we can generate
@@ -114,10 +116,9 @@ static krb5_int32 krb5int_addint32 (krb5_int32 x, krb5_int32 y)
static krb5_error_code
send_as_request(krb5_context context,
krb5_kdc_req *request,
- krb5_timestamp *time_now,
krb5_error ** ret_err_reply,
krb5_kdc_rep ** ret_as_reply,
- int *use_master)
+ int *use_master)
{
krb5_kdc_rep *as_reply = 0;
krb5_error_code retval;
@@ -125,17 +126,16 @@ send_as_request(krb5_context context,
krb5_data reply;
char k4_version; /* same type as *(krb5_data::data) */
int tcp_only = 0;
+ krb5_timestamp time_now;
reply.data = 0;
-
- if ((retval = krb5_timeofday(context, time_now)))
- goto cleanup;
- /*
- * XXX we know they are the same size... and we should do
- * something better than just the current time
- */
- request->nonce = (krb5_int32) *time_now;
+ /* set the nonce if the caller expects us to do it */
+ if (request->nonce == 0) {
+ if ((retval = krb5_timeofday(context, &time_now)))
+ goto cleanup;
+ request->nonce = (krb5_int32) time_now;
+ }
/* encode & send to KDC */
if ((retval = encode_krb5_as_req(request, &packet)) != 0)
@@ -154,7 +154,7 @@ send_again:
krb5_error *err_reply;
if ((retval = decode_krb5_error(&reply, &err_reply)))
- /* some other error code--??? */
+ /* some other error code--??? */
goto cleanup;
if (ret_err_reply) {
@@ -235,18 +235,17 @@ decrypt_as_reply(krb5_context context,
krb5_error_code retval;
krb5_keyblock * decrypt_key = 0;
krb5_data salt;
-
- KRB5_LOG0(KRB5_INFO, "decrypt_as_reply() start");
-
+
if (as_reply->enc_part2)
return 0;
if (key)
decrypt_key = key;
+ /* Solaris Kerberos */
else if (request != NULL) {
if ((retval = krb5_principal2salt(context, request->client, &salt)))
return(retval);
-
+
retval = (*key_proc)(context, as_reply->enc_part.enctype,
&salt, keyseed, &decrypt_key);
krb5_xfree(salt.data);
@@ -258,7 +257,8 @@ decrypt_as_reply(krb5_context context,
return (EINVAL);
}
- /* Solaris kerberos: Overwriting the decrypt_key->enctype because the
+ /*
+ * Solaris kerberos: Overwriting the decrypt_key->enctype because the
* decrypt key's enctype may not be an exact match with the enctype that the
* KDC used to encrypt this part of the AS reply. This assumes the
* as_reply->enc_part.enctype has been validated which is done by checking
@@ -290,9 +290,6 @@ decrypt_as_reply(krb5_context context,
cleanup:
if (!key && decrypt_key)
krb5_free_keyblock(context, decrypt_key);
-
- KRB5_LOG(KRB5_INFO, "decrypt_as_reply() end, retval = %d", retval);
-
return (retval);
}
@@ -303,12 +300,12 @@ verify_as_reply(krb5_context context,
krb5_kdc_rep *as_reply)
{
krb5_error_code retval;
-
+
/* check the contents for sanity: */
if (!as_reply->enc_part2->times.starttime)
as_reply->enc_part2->times.starttime =
as_reply->enc_part2->times.authtime;
-
+
if (!krb5_principal_compare(context, as_reply->client, request->client)
|| !krb5_principal_compare(context, as_reply->enc_part2->server, request->server)
|| !krb5_principal_compare(context, as_reply->ticket->server, request->server)
@@ -387,7 +384,7 @@ stash_as_reply(krb5_context context,
goto cleanup;
/* fill in the credentials */
- if ((retval = krb5_copy_keyblock_contents(context,
+ if ((retval = krb5_copy_keyblock_contents(context,
as_reply->enc_part2->session,
&creds->keyblock)))
goto cleanup;
@@ -410,7 +407,7 @@ stash_as_reply(krb5_context context,
krb5_xfree(packet);
/* store it in the ccache! */
- if (ccache)
+ if (ccache) /* Solaris Kerberos */
if ((retval = krb5_cc_store_cred(context, ccache, creds)) !=0)
goto cleanup;
@@ -459,13 +456,13 @@ make_preauth_list(krb5_context context,
for (nptypes=0, ptypep = ptypes; *ptypep; ptypep++, nptypes++)
;
}
-
+
/* allocate space for a NULL to terminate the list */
-
+
if ((preauthp =
(krb5_pa_data **) malloc((nptypes+1)*sizeof(krb5_pa_data *))) == NULL)
return(ENOMEM);
-
+
for (i=0; i<nptypes; i++) {
if ((preauthp[i] =
(krb5_pa_data *) malloc(sizeof(krb5_pa_data))) == NULL) {
@@ -479,18 +476,16 @@ make_preauth_list(krb5_context context,
preauthp[i]->length = 0;
preauthp[i]->contents = 0;
}
-
+
/* fill in the terminating NULL */
-
+
preauthp[nptypes] = NULL;
-
+
*ret_list = preauthp;
return 0;
}
#define MAX_IN_TKT_LOOPS 16
-/* SUNW14resync - Solaris krb does not use this (appearently) */
-#if 0
static const krb5_enctype get_in_tkt_enctypes[] = {
ENCTYPE_DES3_CBC_SHA1,
ENCTYPE_ARCFOUR_HMAC,
@@ -499,7 +494,204 @@ static const krb5_enctype get_in_tkt_enctypes[] = {
ENCTYPE_DES_CBC_CRC,
0
};
-#endif
+
+krb5_error_code KRB5_CALLCONV
+krb5_get_in_tkt(krb5_context context,
+ const krb5_flags options,
+ krb5_address * const * addrs,
+ krb5_enctype * ktypes,
+ krb5_preauthtype * ptypes,
+ git_key_proc key_proc,
+ krb5_const_pointer keyseed,
+ git_decrypt_proc decrypt_proc,
+ krb5_const_pointer decryptarg,
+ krb5_creds * creds,
+ krb5_ccache ccache,
+ krb5_kdc_rep ** ret_as_reply)
+{
+ krb5_error_code retval;
+ krb5_timestamp time_now;
+ krb5_keyblock * decrypt_key = 0;
+ krb5_kdc_req request;
+ krb5_pa_data **padata = 0;
+ krb5_error * err_reply;
+ krb5_kdc_rep * as_reply = 0;
+ krb5_pa_data ** preauth_to_use = 0;
+ int loopcount = 0;
+ krb5_int32 do_more = 0;
+ int use_master = 0;
+
+ if (! krb5_realm_compare(context, creds->client, creds->server))
+ return KRB5_IN_TKT_REALM_MISMATCH;
+
+ if (ret_as_reply)
+ *ret_as_reply = 0;
+
+ /*
+ * Set up the basic request structure
+ */
+ request.magic = KV5M_KDC_REQ;
+ request.msg_type = KRB5_AS_REQ;
+ request.addresses = 0;
+ request.ktype = 0;
+ request.padata = 0;
+ if (addrs)
+ request.addresses = (krb5_address **) addrs;
+ else
+ if ((retval = krb5_os_localaddr(context, &request.addresses)))
+ goto cleanup;
+ request.kdc_options = options;
+ request.client = creds->client;
+ request.server = creds->server;
+ request.nonce = 0;
+ request.from = creds->times.starttime;
+ request.till = creds->times.endtime;
+ request.rtime = creds->times.renew_till;
+
+ request.ktype = malloc (sizeof(get_in_tkt_enctypes));
+ if (request.ktype == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ memcpy(request.ktype, get_in_tkt_enctypes, sizeof(get_in_tkt_enctypes));
+ 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;
+ request.second_ticket = 0;
+
+ /*
+ * If a list of preauth types are passed in, convert it to a
+ * preauth_to_use list.
+ */
+ if (ptypes) {
+ retval = make_preauth_list(context, ptypes, -1, &preauth_to_use);
+ if (retval)
+ goto cleanup;
+ }
+
+ while (1) {
+ if (loopcount++ > MAX_IN_TKT_LOOPS) {
+ retval = KRB5_GET_IN_TKT_LOOP;
+ goto cleanup;
+ }
+
+ if ((retval = krb5_obtain_padata(context, preauth_to_use, key_proc,
+ keyseed, creds, &request)) != 0)
+ goto cleanup;
+ if (preauth_to_use)
+ krb5_free_pa_data(context, preauth_to_use);
+ preauth_to_use = 0;
+
+ err_reply = 0;
+ as_reply = 0;
+
+ if ((retval = krb5_timeofday(context, &time_now)))
+ goto cleanup;
+
+ /*
+ * XXX we know they are the same size... and we should do
+ * something better than just the current time
+ */
+ request.nonce = (krb5_int32) time_now;
+
+ if ((retval = send_as_request(context, &request, &err_reply,
+ &as_reply, &use_master)))
+ goto cleanup;
+
+ if (err_reply) {
+ if (err_reply->error == KDC_ERR_PREAUTH_REQUIRED &&
+ err_reply->e_data.length > 0) {
+ retval = decode_krb5_padata_sequence(&err_reply->e_data,
+ &preauth_to_use);
+ krb5_free_error(context, err_reply);
+ if (retval)
+ goto cleanup;
+ retval = sort_krb5_padata_sequence(context,
+ &request.server->realm,
+ padata);
+ if (retval)
+ goto cleanup;
+ continue;
+ } else {
+ retval = (krb5_error_code) err_reply->error
+ + ERROR_TABLE_BASE_krb5;
+ krb5_free_error(context, err_reply);
+ goto cleanup;
+ }
+ } else if (!as_reply) {
+ retval = KRB5KRB_AP_ERR_MSG_TYPE;
+ goto cleanup;
+ }
+ if ((retval = krb5_process_padata(context, &request, as_reply,
+ key_proc, keyseed, decrypt_proc,
+ &decrypt_key, creds,
+ &do_more)) != 0)
+ goto cleanup;
+
+ if (!do_more)
+ break;
+ }
+
+ if ((retval = decrypt_as_reply(context, &request, as_reply, key_proc,
+ keyseed, decrypt_key, decrypt_proc,
+ decryptarg)))
+ goto cleanup;
+
+ if ((retval = verify_as_reply(context, time_now, &request, as_reply)))
+ goto cleanup;
+
+ if ((retval = stash_as_reply(context, time_now, &request, as_reply,
+ creds, ccache)))
+ goto cleanup;
+
+cleanup:
+ if (request.ktype)
+ free(request.ktype);
+ if (!addrs && request.addresses)
+ krb5_free_addresses(context, request.addresses);
+ if (request.padata)
+ krb5_free_pa_data(context, request.padata);
+ if (padata)
+ krb5_free_pa_data(context, padata);
+ if (preauth_to_use)
+ krb5_free_pa_data(context, preauth_to_use);
+ if (decrypt_key)
+ krb5_free_keyblock(context, decrypt_key);
+ if (as_reply) {
+ if (ret_as_reply)
+ *ret_as_reply = as_reply;
+ else
+ krb5_free_kdc_rep(context, as_reply);
+ }
+ return (retval);
+}
/* begin libdefaults parsing code. This should almost certainly move
somewhere else, but I don't know where the correct somewhere else
@@ -551,11 +743,12 @@ krb5_libdefault_string(krb5_context context, const krb5_data *realm,
strncpy(realmstr, realm->data, realm->length);
realmstr[realm->length] = '\0';
- if (!context || (context->magic != KV5M_CONTEXT))
+ if (!context || (context->magic != KV5M_CONTEXT))
return KV5M_CONTEXT;
profile = context->profile;
-
+
+ /* Solaris Kerberos */
names[0] = "realms";
/*
@@ -580,7 +773,7 @@ krb5_libdefault_string(krb5_context context, const krb5_data *realm,
* [libdefaults]
* option = <boolean>
*/
-
+
names[0] = "libdefaults";
names[1] = option;
names[2] = 0;
@@ -589,7 +782,7 @@ krb5_libdefault_string(krb5_context context, const krb5_data *realm,
goto goodbye;
goodbye:
- if (!nameval)
+ if (!nameval)
return(ENOENT);
if (!nameval[0]) {
@@ -628,6 +821,79 @@ krb5_libdefault_boolean(krb5_context context, const krb5_data *realm,
return(0);
}
+/* Sort a pa_data sequence so that types named in the "preferred_preauth_types"
+ * libdefaults entry are listed before any others. */
+static krb5_error_code
+sort_krb5_padata_sequence(krb5_context context, krb5_data *realm,
+ krb5_pa_data **padata)
+{
+ int i, j, base;
+ krb5_error_code ret;
+ const char *p;
+ long l;
+ char *q, *preauth_types = NULL;
+ krb5_pa_data *tmp;
+ int need_free_string = 1;
+
+ if ((padata == NULL) || (padata[0] == NULL)) {
+ return 0;
+ }
+
+ ret = krb5_libdefault_string(context, realm, "preferred_preauth_types",
+ &preauth_types);
+ if ((ret != 0) || (preauth_types == NULL)) {
+ /* Try to use PKINIT first. */
+ preauth_types = "17, 16, 15, 14";
+ need_free_string = 0;
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "preauth data types before sorting:");
+ for (i = 0; padata[i]; i++) {
+ fprintf (stderr, " %d", padata[i]->pa_type);
+ }
+ fprintf (stderr, "\n");
+#endif
+
+ base = 0;
+ for (p = preauth_types; *p != '\0';) {
+ /* skip whitespace to find an entry */
+ p += strspn(p, ", ");
+ if (*p != '\0') {
+ /* see if we can extract a number */
+ l = strtol(p, &q, 10);
+ if ((q != NULL) && (q > p)) {
+ /* got a valid number; search for a matchin entry */
+ for (i = base; padata[i] != NULL; i++) {
+ /* bubble the matching entry to the front of the list */
+ if (padata[i]->pa_type == l) {
+ tmp = padata[i];
+ for (j = i; j > base; j--)
+ padata[j] = padata[j - 1];
+ padata[base] = tmp;
+ base++;
+ break;
+ }
+ }
+ p = q;
+ } else {
+ break;
+ }
+ }
+ }
+ if (need_free_string)
+ free(preauth_types);
+
+#ifdef DEBUG
+ fprintf (stderr, "preauth data types after sorting:");
+ for (i = 0; padata[i]; i++)
+ fprintf (stderr, " %d", padata[i]->pa_type);
+ fprintf (stderr, "\n");
+#endif
+
+ return 0;
+}
+
krb5_error_code KRB5_CALLCONV
krb5_get_init_creds(krb5_context context,
krb5_creds *creds,
@@ -636,7 +902,7 @@ krb5_get_init_creds(krb5_context context,
void *prompter_data,
krb5_deltat start_time,
char *in_tkt_service,
- krb5_get_init_creds_opt *options,
+ krb5_gic_opt_ext *options,
krb5_gic_get_as_key_fct gak_fct,
void *gak_data,
int *use_master,
@@ -644,12 +910,12 @@ krb5_get_init_creds(krb5_context context,
{
krb5_error_code ret;
krb5_kdc_req request;
- krb5_pa_data **padata;
+ krb5_data *encoded_request_body, *encoded_previous_request;
+ krb5_pa_data **preauth_to_use, **kdc_padata;
int tempint;
char *tempstr = NULL;
krb5_deltat tkt_life;
krb5_deltat renew_life;
- krb5_deltat max_life;
int loopcount;
krb5_data salt;
krb5_data s2kparams;
@@ -658,6 +924,7 @@ krb5_get_init_creds(krb5_context context,
krb5_kdc_rep *local_as_reply;
krb5_timestamp time_now;
krb5_enctype etype = 0;
+ krb5_preauth_client_rock get_data_rock;
/* initialize everything which will be freed at cleanup */
@@ -667,13 +934,19 @@ krb5_get_init_creds(krb5_context context,
request.ktype = NULL;
request.addresses = NULL;
request.padata = NULL;
- padata = NULL;
+ encoded_request_body = NULL;
+ encoded_previous_request = NULL;
+ preauth_to_use = NULL;
+ kdc_padata = NULL;
+ as_key.length = 0;
salt.length = 0;
salt.data = NULL;
(void) memset(&as_key, 0, sizeof(as_key));
- local_as_reply = 0;
+ local_as_reply = 0;
+
+ err_reply = NULL;
/*
* Set up the basic request structure
@@ -681,6 +954,9 @@ krb5_get_init_creds(krb5_context context,
request.magic = KV5M_KDC_REQ;
request.msg_type = KRB5_AS_REQ;
+ /* request.nonce is filled in when we send a request to the kdc */
+ request.nonce = 0;
+
/* request.padata is filled in later */
request.kdc_options = context->kdc_default_options;
@@ -694,7 +970,7 @@ krb5_get_init_creds(krb5_context context,
/*EMPTY*/
;
else
- tempint = 0;
+ tempint = 0;
if (tempint)
request.kdc_options |= KDC_OPT_FORWARDABLE;
@@ -707,12 +983,12 @@ krb5_get_init_creds(krb5_context context,
/*EMPTY*/
;
else
- tempint = 0;
+ tempint = 0;
if (tempint)
request.kdc_options |= KDC_OPT_PROXIABLE;
/* allow_postdate */
-
+
if (start_time > 0)
request.kdc_options |= (KDC_OPT_ALLOW_POSTDATE|KDC_OPT_POSTDATED);
@@ -727,15 +1003,11 @@ krb5_get_init_creds(krb5_context context,
} else if ((ret = krb5_libdefault_string(context, &client->realm,
"ticket_lifetime", &tempstr))
== 0) {
- if ((ret = krb5_string_to_deltat(tempstr, &tkt_life))) {
- free(tempstr);
- tempstr = NULL;
+ ret = krb5_string_to_deltat(tempstr, &tkt_life);
+ free(tempstr);
+ if (ret) {
goto cleanup;
}
- if (tempstr) {
- free(tempstr);
- tempstr = NULL;
- }
} else {
/* this used to be hardcoded in kinit.c */
tkt_life = 24*60*60;
@@ -749,20 +1021,17 @@ krb5_get_init_creds(krb5_context context,
} else if ((ret = krb5_libdefault_string(context, &client->realm,
"renew_lifetime", &tempstr))
== 0) {
- if ((ret = krb5_string_to_deltat(tempstr, &renew_life))) {
- free(tempstr);
+ ret = krb5_string_to_deltat(tempstr, &renew_life);
+ free(tempstr);
+ if (ret) {
goto cleanup;
}
- if (tempstr) {
- free(tempstr);
- tempstr = NULL;
- }
} else {
renew_life = 0;
}
if (renew_life > 0)
request.kdc_options |= KDC_OPT_RENEWABLE;
-
+
if (renew_life > 0) {
request.rtime = krb5int_addint32(request.from, renew_life);
if (request.rtime < request.till) {
@@ -774,13 +1043,13 @@ krb5_get_init_creds(krb5_context context,
} else {
request.rtime = 0;
}
-
+
/* client */
request.client = client;
/* service */
-
+
if (in_tkt_service) {
/* this is ugly, because so are the data structures involved. I'm
in the library, so I'm going to manipulate the data structures
@@ -814,7 +1083,9 @@ krb5_get_init_creds(krb5_context context,
goto cleanup;
}
- /* nonce is filled in by send_as_request */
+ krb5_preauth_request_context_init(context);
+
+ /* nonce is filled in by send_as_request if we don't take care of it */
if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST)) {
request.ktype = options->etype_list;
@@ -859,8 +1130,8 @@ krb5_get_init_creds(krb5_context context,
if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST)) {
if ((ret = make_preauth_list(context, options->preauth_list,
- options->preauth_list_length,
- &padata)))
+ options->preauth_list_length,
+ &preauth_to_use)))
goto cleanup;
}
@@ -870,48 +1141,122 @@ krb5_get_init_creds(krb5_context context,
if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_SALT)) {
salt = *options->salt;
} else {
- salt.length = (unsigned int)-1;
+ salt.length = SALT_TYPE_AFS_LENGTH;
salt.data = NULL;
}
- /* now, loop processing preauth data and talking to the kdc */
+ /* set the request nonce */
+ if ((ret = krb5_timeofday(context, &time_now)))
+ goto cleanup;
+ /*
+ * XXX we know they are the same size... and we should do
+ * something better than just the current time
+ */
+ request.nonce = (krb5_int32) time_now;
+
+ /* give the preauth plugins a chance to prep the request body */
+ krb5_preauth_prepare_request(context, options, &request);
+ ret = encode_krb5_kdc_req_body(&request, &encoded_request_body);
+ if (ret)
+ goto cleanup;
+
+ get_data_rock.magic = CLIENT_ROCK_MAGIC;
+ get_data_rock.as_reply = NULL;
+
+ /* now, loop processing preauth data and talking to the kdc */
for (loopcount = 0; loopcount < MAX_IN_TKT_LOOPS; loopcount++) {
if (request.padata) {
krb5_free_pa_data(context, request.padata);
request.padata = NULL;
}
+ if (!err_reply) {
+ /* either our first attempt, or retrying after PREAUTH_NEEDED */
+ if ((ret = krb5_do_preauth(context,
+ &request,
+ encoded_request_body,
+ encoded_previous_request,
+ preauth_to_use, &request.padata,
+ &salt, &s2kparams, &etype, &as_key,
+ prompter, prompter_data,
+ gak_fct, gak_data,
+ &get_data_rock, options)))
+ goto cleanup;
+ } else {
+ if (preauth_to_use != NULL) {
+ /*
+ * Retry after an error other than PREAUTH_NEEDED,
+ * using e-data to figure out what to change.
+ */
+ ret = krb5_do_preauth_tryagain(context,
+ &request,
+ encoded_request_body,
+ encoded_previous_request,
+ preauth_to_use, &request.padata,
+ err_reply,
+ &salt, &s2kparams, &etype,
+ &as_key,
+ prompter, prompter_data,
+ gak_fct, gak_data,
+ &get_data_rock, options);
+ } else {
+ /* No preauth supplied, so can't query the plug-ins. */
+ ret = KRB5KRB_ERR_GENERIC;
+ }
+ if (ret) {
+ /* couldn't come up with anything better */
+ ret = err_reply->error + ERROR_TABLE_BASE_krb5;
+ }
+ krb5_free_error(context, err_reply);
+ err_reply = NULL;
+ if (ret)
+ goto cleanup;
+ }
- if ((ret = krb5_do_preauth(context, &request,
- padata, &request.padata,
- &salt, &s2kparams, &etype, &as_key, prompter,
- prompter_data, gak_fct, gak_data)))
+ if (encoded_previous_request != NULL) {
+ krb5_free_data(context, encoded_previous_request);
+ encoded_previous_request = NULL;
+ }
+ ret = encode_krb5_as_req(&request, &encoded_previous_request);
+ if (ret)
goto cleanup;
- if (padata) {
- krb5_free_pa_data(context, padata);
- padata = 0;
- }
-
err_reply = 0;
local_as_reply = 0;
- if ((ret = send_as_request(context, &request, &time_now, &err_reply,
+ if ((ret = send_as_request(context, &request, &err_reply,
&local_as_reply, use_master)))
goto cleanup;
if (err_reply) {
if (err_reply->error == KDC_ERR_PREAUTH_REQUIRED &&
err_reply->e_data.length > 0) {
+ /* reset the list of preauth types to try */
+ if (preauth_to_use) {
+ krb5_free_pa_data(context, preauth_to_use);
+ preauth_to_use = NULL;
+ }
ret = decode_krb5_padata_sequence(&err_reply->e_data,
- &padata);
+ &preauth_to_use);
krb5_free_error(context, err_reply);
+ err_reply = NULL;
+ if (ret)
+ goto cleanup;
+ ret = sort_krb5_padata_sequence(context,
+ &request.server->realm,
+ preauth_to_use);
if (ret)
goto cleanup;
+ /* continue to next iteration */
} else {
- ret = (krb5_error_code) err_reply->error
- + ERROR_TABLE_BASE_krb5;
- krb5_free_error(context, err_reply);
- goto cleanup;
+ if (err_reply->e_data.length > 0) {
+ /* continue to next iteration */
+ } else {
+ /* error + no hints = give up */
+ ret = (krb5_error_code) err_reply->error
+ + ERROR_TABLE_BASE_krb5;
+ krb5_free_error(context, err_reply);
+ goto cleanup;
+ }
}
} else if (local_as_reply) {
break;
@@ -927,22 +1272,26 @@ krb5_get_init_creds(krb5_context context,
}
/* process any preauth data in the as_reply */
-
- if ((ret = krb5_do_preauth(context, &request,
- local_as_reply->padata, &padata,
- &salt, &s2kparams, &etype, &as_key, prompter,
- prompter_data, gak_fct, gak_data)))
+ krb5_clear_preauth_context_use_counts(context);
+ if ((ret = sort_krb5_padata_sequence(context, &request.server->realm,
+ local_as_reply->padata)))
+ goto cleanup;
+ get_data_rock.as_reply = local_as_reply;
+ if ((ret = krb5_do_preauth(context,
+ &request,
+ encoded_request_body, encoded_previous_request,
+ local_as_reply->padata, &kdc_padata,
+ &salt, &s2kparams, &etype, &as_key, prompter,
+ prompter_data, gak_fct, gak_data,
+ &get_data_rock, options)))
goto cleanup;
-
- /* XXX if there's padata on output, something is wrong, but it's
- not obviously an error */
/* XXX For 1.1.1 and prior KDC's, when SAM is used w/ USE_SAD_AS_KEY,
the AS_REP comes back encrypted in the user's longterm key
instead of in the SAD. If there was a SAM preauth, there
will be an as_key here which will be the SAD. If that fails,
use the gak_fct to get the password, and try again. */
-
+
/* XXX because etypes are handled poorly (particularly wrt SAM,
where the etype is fixed by the kdc), we may want to try
decrypt_as_reply twice. If there's an as_key available, try
@@ -951,40 +1300,37 @@ krb5_get_init_creds(krb5_context context,
again. */
if (as_key.length)
- ret = decrypt_as_reply(context, (krb5_kdc_req *)NULL, local_as_reply,
- (git_key_proc)NULL, (krb5_const_pointer)NULL,
- &as_key, krb5_kdc_rep_decrypt_proc,
- (krb5_const_pointer)NULL);
+ ret = decrypt_as_reply(context, NULL, local_as_reply, NULL,
+ NULL, &as_key, krb5_kdc_rep_decrypt_proc,
+ NULL);
else
ret = -1;
-
+
if (ret) {
/* if we haven't get gotten a key, get it now */
if ((ret = ((*gak_fct)(context, request.client,
- local_as_reply->enc_part.enctype,
- prompter, prompter_data, &salt, &s2kparams,
- &as_key, gak_data))))
+ local_as_reply->enc_part.enctype,
+ prompter, prompter_data, &salt, &s2kparams,
+ &as_key, gak_data))))
goto cleanup;
- if ((ret=decrypt_as_reply(context, (krb5_kdc_req *)NULL,
- local_as_reply, (git_key_proc)NULL,
- (krb5_const_pointer)NULL, &as_key,
- krb5_kdc_rep_decrypt_proc,
- (krb5_const_pointer)NULL)))
+ if ((ret = decrypt_as_reply(context, NULL, local_as_reply, NULL,
+ NULL, &as_key, krb5_kdc_rep_decrypt_proc,
+ NULL)))
goto cleanup;
}
if ((ret = verify_as_reply(context, time_now, &request, local_as_reply)))
goto cleanup;
- /*
- * XXX this should be inside stash_as_reply, but as long as
- * get_in_tkt is still around using that arg as an in/out, I can't
- * do that
- */
+ /* XXX this should be inside stash_as_reply, but as long as
+ get_in_tkt is still around using that arg as an in/out, I can't
+ do that */
+ /* Solaris Kerberos */
(void) memset(creds, 0, sizeof(*creds));
+ /* Solaris Kerberos */
if ((ret = stash_as_reply(context, time_now, &request, local_as_reply,
creds, (krb5_ccache)NULL)))
goto cleanup;
@@ -994,6 +1340,15 @@ krb5_get_init_creds(krb5_context context,
ret = 0;
cleanup:
+ krb5_preauth_request_context_fini(context);
+ if (encoded_previous_request != NULL) {
+ krb5_free_data(context, encoded_previous_request);
+ encoded_previous_request = NULL;
+ }
+ if (encoded_request_body != NULL) {
+ krb5_free_data(context, encoded_request_body);
+ encoded_request_body = NULL;
+ }
if (request.server)
krb5_free_principal(context, request.server);
if (request.ktype &&
@@ -1003,8 +1358,10 @@ cleanup:
(!(options &&
(options->flags & KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST))))
krb5_free_addresses(context, request.addresses);
- if (padata)
- krb5_free_pa_data(context, padata);
+ if (preauth_to_use)
+ krb5_free_pa_data(context, preauth_to_use);
+ if (kdc_padata)
+ krb5_free_pa_data(context, kdc_padata);
if (request.padata)
krb5_free_pa_data(context, request.padata);
if (as_key.length)
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_keytab.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_keytab.c
index d2c90b6e76..351d5917ae 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_keytab.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_keytab.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/gic_keytab.c
@@ -31,20 +30,20 @@
* or implied warranty.
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*ARGSUSED*/
static krb5_error_code
krb5_get_as_key_keytab(
- krb5_context context,
- krb5_principal client,
- krb5_enctype etype,
- krb5_prompter_fct prompter,
- void *prompter_data,
- krb5_data *salt,
- krb5_data *params,
- krb5_keyblock *as_key,
- void *gak_data)
+ krb5_context context,
+ krb5_principal client,
+ krb5_enctype etype,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ krb5_data *salt,
+ krb5_data *params,
+ krb5_keyblock *as_key,
+ void *gak_data)
{
krb5_keytab keytab = (krb5_keytab) gak_data;
krb5_error_code ret;
@@ -66,6 +65,7 @@ krb5_get_as_key_keytab(
if (!krb5_c_valid_enctype(etype))
return(KRB5_PROG_ETYPE_NOSUPP);
+ /* Solaris Kerberos */
if ((ret = krb5_kt_get_entry(context, keytab, client,
0, /* don't have vno available */
etype, &kt_ent)) != NULL)
@@ -84,32 +84,37 @@ krb5_get_as_key_keytab(
}
krb5_error_code KRB5_CALLCONV
-krb5_get_init_creds_keytab(
- krb5_context context,
- krb5_creds *creds,
- krb5_principal client,
- krb5_keytab arg_keytab,
- krb5_deltat start_time,
- char *in_tkt_service,
- krb5_get_init_creds_opt *options)
+krb5_get_init_creds_keytab(krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ krb5_keytab arg_keytab,
+ krb5_deltat start_time,
+ char *in_tkt_service,
+ krb5_get_init_creds_opt *options)
{
krb5_error_code ret, ret2;
int use_master;
krb5_keytab keytab;
+ krb5_gic_opt_ext *opte = NULL;
if (arg_keytab == NULL) {
- if ((ret = krb5_kt_default(context, &keytab)))
- return ret;
+ if ((ret = krb5_kt_default(context, &keytab)))
+ return ret;
} else {
- keytab = arg_keytab;
+ keytab = arg_keytab;
}
+ ret = krb5int_gic_opt_to_opte(context, options, &opte, 1,
+ "krb5_get_init_creds_keytab");
+ if (ret)
+ return ret;
+
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,
+ start_time, in_tkt_service, opte,
krb5_get_as_key_keytab, (void *) keytab,
&use_master,NULL);
@@ -130,7 +135,7 @@ krb5_get_init_creds_keytab(
use_master = 1;
ret2 = krb5_get_init_creds(context, creds, client, NULL, NULL,
- start_time, in_tkt_service, options,
+ start_time, in_tkt_service, opte,
krb5_get_as_key_keytab, (void *) keytab,
&use_master, NULL);
@@ -142,7 +147,9 @@ krb5_get_init_creds_keytab(
/* if the master is unreachable, return the error from the
slave we were able to contact */
- if ((ret2 == KRB5_KDC_UNREACH) || (ret2 == KRB5_REALM_CANT_RESOLVE))
+ if ((ret2 == KRB5_KDC_UNREACH) ||
+ (ret2 == KRB5_REALM_CANT_RESOLVE) ||
+ (ret2 == KRB5_REALM_UNKNOWN))
goto cleanup;
ret = ret2;
@@ -152,12 +159,13 @@ krb5_get_init_creds_keytab(
do any prompting or changing for keytabs, that's it. */
cleanup:
+ if (opte && krb5_gic_opt_is_shadowed(opte))
+ krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte);
if (arg_keytab == NULL)
- (void) krb5_kt_close(context, keytab);
+ (void) krb5_kt_close(context, keytab); /* Solaris Kerberos */
return(ret);
}
-
krb5_error_code KRB5_CALLCONV
krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options,
krb5_address *const *addrs, krb5_enctype *ktypes,
@@ -166,15 +174,18 @@ krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options,
krb5_creds *creds, krb5_kdc_rep **ret_as_reply)
{
krb5_error_code retval;
- krb5_get_init_creds_opt opt;
+ krb5_gic_opt_ext *opte;
char * server = NULL;
krb5_keytab keytab;
krb5_principal client_princ, server_princ;
int use_master = 0;
- krb5int_populate_gic_opt(context, &opt,
- options, addrs, ktypes,
- pre_auth_types, creds);
+ retval = krb5int_populate_gic_opt(context, &opte,
+ options, addrs, ktypes,
+ pre_auth_types, creds);
+ if (retval)
+ return retval;
+
if (arg_keytab == NULL) {
retval = krb5_kt_default(context, &keytab);
if (retval)
@@ -190,10 +201,11 @@ krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options,
retval = krb5_get_init_creds (context,
creds, creds->client,
krb5_prompter_posix, NULL,
- 0, server, &opt,
+ 0, server, opte,
krb5_get_as_key_keytab, (void *)keytab,
&use_master, ret_as_reply);
krb5_free_unparsed_name( context, server);
+ krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte);
if (retval) {
goto cleanup;
}
@@ -212,3 +224,4 @@ krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options,
krb5_kt_close(context, keytab);
return retval;
}
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_opt.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_opt.c
index 87e92d7b75..227391ae42 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_opt.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_opt.c
@@ -1,10 +1,17 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-#include <k5-int.h>
+#include "k5-int.h"
+#include "int-proto.h"
+
+static void
+init_common(krb5_get_init_creds_opt *opt)
+{
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT;
+}
void KRB5_CALLCONV
krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
{
- opt->flags = 0;
+ opt->flags = 0;
+ init_common(opt);
}
void KRB5_CALLCONV
@@ -64,3 +71,377 @@ krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt *opt, krb5_data *salt)
opt->flags |= KRB5_GET_INIT_CREDS_OPT_SALT;
opt->salt = salt;
}
+
+void KRB5_CALLCONV
+krb5_get_init_creds_opt_set_change_password_prompt(krb5_get_init_creds_opt *opt, int prompt)
+{
+ if (prompt)
+ opt->flags |= KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT;
+ else
+ opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT;
+}
+
+/*
+ * Extending the krb5_get_init_creds_opt structure. The original
+ * krb5_get_init_creds_opt structure is defined publicly. The
+ * new extended version is private. The original interface
+ * assumed a pre-allocated structure which was passed to
+ * krb5_get_init_creds_init(). The new interface assumes that
+ * the caller will call krb5_get_init_creds_alloc() and
+ * krb5_get_init_creds_free().
+ *
+ * Callers MUST NOT call krb5_get_init_creds_init() after allocating an
+ * opts structure using krb5_get_init_creds_alloc(). To do so will
+ * introduce memory leaks. Unfortunately, there is no way to enforce
+ * this behavior.
+ *
+ * Two private flags are added for backward compatibility.
+ * KRB5_GET_INIT_CREDS_OPT_EXTENDED says that the structure was allocated
+ * with the new krb5_get_init_creds_opt_alloc() function.
+ * KRB5_GET_INIT_CREDS_OPT_SHADOWED is set to indicate that the extended
+ * structure is a shadow copy of an original krb5_get_init_creds_opt
+ * structure.
+ * If KRB5_GET_INIT_CREDS_OPT_SHADOWED is set after a call to
+ * krb5int_gic_opt_to_opte(), the resulting extended structure should be
+ * freed (using krb5_get_init_creds_free). Otherwise, the original
+ * structure was already extended and there is no need to free it.
+ */
+
+/* Forward prototype */
+static void
+free_gic_opt_ext_preauth_data(krb5_context context,
+ krb5_gic_opt_ext *opte);
+
+static krb5_error_code
+krb5int_gic_opte_private_alloc(krb5_context context, krb5_gic_opt_ext *opte)
+{
+ if (NULL == opte || !krb5_gic_opt_is_extended(opte))
+ return EINVAL;
+
+ opte->opt_private = calloc(1, sizeof(*opte->opt_private));
+ if (NULL == opte->opt_private) {
+ return ENOMEM;
+ }
+ /* Allocate any private stuff */
+ opte->opt_private->num_preauth_data = 0;
+ opte->opt_private->preauth_data = NULL;
+ return 0;
+}
+
+static krb5_error_code
+krb5int_gic_opte_private_free(krb5_context context, krb5_gic_opt_ext *opte)
+{
+ if (NULL == opte || !krb5_gic_opt_is_extended(opte))
+ return EINVAL;
+
+ /* Free up any private stuff */
+ if (opte->opt_private->preauth_data != NULL)
+ free_gic_opt_ext_preauth_data(context, opte);
+ free(opte->opt_private);
+ opte->opt_private = NULL;
+ return 0;
+}
+
+static krb5_gic_opt_ext *
+krb5int_gic_opte_alloc(krb5_context context)
+{
+ krb5_gic_opt_ext *opte;
+ krb5_error_code code;
+
+ opte = calloc(1, sizeof(*opte));
+ if (NULL == opte)
+ return NULL;
+ opte->flags = KRB5_GET_INIT_CREDS_OPT_EXTENDED;
+
+ code = krb5int_gic_opte_private_alloc(context, opte);
+ if (code) {
+ krb5int_set_error(&context->err, code,
+ "krb5int_gic_opte_alloc: krb5int_gic_opte_private_alloc failed");
+ free(opte);
+ return NULL;
+ }
+ return(opte);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_opt_alloc(krb5_context context,
+ krb5_get_init_creds_opt **opt)
+{
+ krb5_gic_opt_ext *opte;
+
+ if (NULL == opt)
+ return EINVAL;
+ *opt = NULL;
+
+ /*
+ * We return a new extended structure cast as a krb5_get_init_creds_opt
+ */
+ opte = krb5int_gic_opte_alloc(context);
+ if (NULL == opte)
+ return ENOMEM;
+
+ *opt = (krb5_get_init_creds_opt *) opte;
+ init_common(*opt);
+ return 0;
+}
+
+void KRB5_CALLCONV
+krb5_get_init_creds_opt_free(krb5_context context,
+ krb5_get_init_creds_opt *opt)
+{
+ krb5_gic_opt_ext *opte;
+
+ if (NULL == opt)
+ return;
+
+ /* Don't touch it if we didn't allocate it */
+ if (!krb5_gic_opt_is_extended(opt))
+ return;
+
+ opte = (krb5_gic_opt_ext *)opt;
+ if (opte->opt_private)
+ krb5int_gic_opte_private_free(context, opte);
+
+ free(opte);
+}
+
+static krb5_error_code
+krb5int_gic_opte_copy(krb5_context context,
+ krb5_get_init_creds_opt *opt,
+ krb5_gic_opt_ext **opte)
+{
+ krb5_gic_opt_ext *oe;
+
+ oe = krb5int_gic_opte_alloc(context);
+ if (NULL == oe)
+ return ENOMEM;
+
+ if (opt)
+ memcpy(oe, opt, sizeof(*opt));
+
+ /*
+ * Fix the flags -- the EXTENDED flag would have been
+ * overwritten by the copy if there was one. The
+ * SHADOWED flag is necessary to ensure that the
+ * krb5_gic_opt_ext structure that was allocated
+ * here will be freed by the library because the
+ * application is unaware of its existence.
+ */
+ oe->flags |= ( KRB5_GET_INIT_CREDS_OPT_EXTENDED |
+ KRB5_GET_INIT_CREDS_OPT_SHADOWED);
+
+ *opte = oe;
+ return 0;
+}
+
+/*
+ * Convert a krb5_get_init_creds_opt pointer to a pointer to
+ * an extended, krb5_gic_opt_ext pointer. If the original
+ * pointer already points to an extended structure, then simply
+ * return the original pointer. Otherwise, if 'force' is non-zero,
+ * allocate an extended structure and copy the original over it.
+ * If the original pointer did not point to an extended structure
+ * and 'force' is zero, then return an error. This is used in
+ * cases where the original *should* be an extended structure.
+ */
+krb5_error_code
+krb5int_gic_opt_to_opte(krb5_context context,
+ krb5_get_init_creds_opt *opt,
+ krb5_gic_opt_ext **opte,
+ unsigned int force,
+ const char *where)
+{
+ if (!krb5_gic_opt_is_extended(opt)) {
+ if (force) {
+ return krb5int_gic_opte_copy(context, opt, opte);
+ } else {
+ krb5int_set_error(&context->err, EINVAL,
+ "%s: attempt to convert non-extended krb5_get_init_creds_opt",
+ where);
+ return EINVAL;
+ }
+ }
+ /* If it is already extended, just return it */
+ *opte = (krb5_gic_opt_ext *)opt;
+ return 0;
+}
+
+static void
+free_gic_opt_ext_preauth_data(krb5_context context,
+ krb5_gic_opt_ext *opte)
+{
+ int i;
+
+ if (NULL == opte || !krb5_gic_opt_is_extended(opte))
+ return;
+ if (NULL == opte->opt_private || NULL == opte->opt_private->preauth_data)
+ return;
+
+ for (i = 0; i < opte->opt_private->num_preauth_data; i++) {
+ if (opte->opt_private->preauth_data[i].attr != NULL)
+ free(opte->opt_private->preauth_data[i].attr);
+ if (opte->opt_private->preauth_data[i].value != NULL)
+ free(opte->opt_private->preauth_data[i].value);
+ }
+ free(opte->opt_private->preauth_data);
+ opte->opt_private->preauth_data = NULL;
+ opte->opt_private->num_preauth_data = 0;
+}
+
+static krb5_error_code
+add_gic_opt_ext_preauth_data(krb5_context context,
+ krb5_gic_opt_ext *opte,
+ const char *attr,
+ const char *value)
+{
+ size_t newsize;
+ int i;
+ krb5_gic_opt_pa_data *newpad;
+
+ newsize = opte->opt_private->num_preauth_data + 1;
+ newsize = newsize * sizeof(*opte->opt_private->preauth_data);
+ if (opte->opt_private->preauth_data == NULL)
+ newpad = malloc(newsize);
+ else
+ newpad = realloc(opte->opt_private->preauth_data, newsize);
+ if (newpad == NULL)
+ return ENOMEM;
+
+ i = opte->opt_private->num_preauth_data;
+ newpad[i].attr = strdup(attr);
+ if (newpad[i].attr == NULL)
+ return ENOMEM;
+ newpad[i].value = strdup(value);
+ if (newpad[i].value == NULL) {
+ free(newpad[i].attr);
+ return ENOMEM;
+ }
+ opte->opt_private->num_preauth_data += 1;
+ opte->opt_private->preauth_data = newpad;
+ return 0;
+}
+
+/*
+ * This function allows the caller to supply options to preauth
+ * plugins. Preauth plugin modules are given a chance to look
+ * at each option at the time this function is called in ordre
+ * to check the validity of the option.
+ * The 'opt' pointer supplied to this function must have been
+ * obtained using krb5_get_init_creds_opt_alloc()
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_opt_set_pa(krb5_context context,
+ krb5_get_init_creds_opt *opt,
+ const char *attr,
+ const char *value)
+{
+ krb5_error_code retval;
+ krb5_gic_opt_ext *opte;
+
+ retval = krb5int_gic_opt_to_opte(context, opt, &opte, 0,
+ "krb5_get_init_creds_opt_set_pa");
+ if (retval)
+ return retval;
+
+ /*
+ * Copy the option into the extended get_init_creds_opt structure
+ */
+ retval = add_gic_opt_ext_preauth_data(context, opte, attr, value);
+ if (retval)
+ return retval;
+
+ /*
+ * Give the plugins a chance to look at the option now.
+ */
+ retval = krb5_preauth_supply_preauth_data(context, opte, attr, value);
+ return retval;
+}
+
+/*
+ * This function allows a preauth plugin to obtain preauth
+ * options. The preauth_data returned from this function
+ * should be freed by calling krb5_get_init_creds_opt_free_pa().
+ *
+ * The 'opt' pointer supplied to this function must have been
+ * obtained using krb5_get_init_creds_opt_alloc()
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_opt_get_pa(krb5_context context,
+ krb5_get_init_creds_opt *opt,
+ int *num_preauth_data,
+ krb5_gic_opt_pa_data **preauth_data)
+{
+ krb5_error_code retval;
+ krb5_gic_opt_ext *opte;
+ krb5_gic_opt_pa_data *p = NULL;
+ int i;
+ size_t allocsize;
+
+ retval = krb5int_gic_opt_to_opte(context, opt, &opte, 0,
+ "krb5_get_init_creds_opt_get_pa");
+ if (retval)
+ return retval;
+
+ if (num_preauth_data == NULL || preauth_data == NULL)
+ return EINVAL;
+
+ *num_preauth_data = 0;
+ *preauth_data = NULL;
+
+ if (opte->opt_private->num_preauth_data == 0)
+ return 0;
+
+ allocsize =
+ opte->opt_private->num_preauth_data * sizeof(krb5_gic_opt_pa_data);
+ p = malloc(allocsize);
+ if (p == NULL)
+ return ENOMEM;
+
+ /* Init these to make cleanup easier */
+ for (i = 0; i < opte->opt_private->num_preauth_data; i++) {
+ p[i].attr = NULL;
+ p[i].value = NULL;
+ }
+
+ for (i = 0; i < opte->opt_private->num_preauth_data; i++) {
+ p[i].attr = strdup(opte->opt_private->preauth_data[i].attr);
+ p[i].value = strdup(opte->opt_private->preauth_data[i].value);
+ if (p[i].attr == NULL || p[i].value == NULL)
+ goto cleanup;
+ }
+ *num_preauth_data = i;
+ *preauth_data = p;
+ return 0;
+cleanup:
+ for (i = 0; i < opte->opt_private->num_preauth_data; i++) {
+ if (p[i].attr != NULL)
+ free(p[i].attr);
+ if (p[i].value != NULL)
+ free(p[i].value);
+ }
+ free(p);
+ return ENOMEM;
+}
+
+/*
+ * This function frees the preauth_data that was returned by
+ * krb5_get_init_creds_opt_get_pa().
+ */
+void KRB5_CALLCONV
+krb5_get_init_creds_opt_free_pa(krb5_context context,
+ int num_preauth_data,
+ krb5_gic_opt_pa_data *preauth_data)
+{
+ int i;
+
+ if (num_preauth_data <= 0 || preauth_data == NULL)
+ return;
+
+ for (i = 0; i < num_preauth_data; i++) {
+ if (preauth_data[i].attr != NULL)
+ free(preauth_data[i].attr);
+ if (preauth_data[i].value != NULL)
+ free(preauth_data[i].value);
+ }
+ free(preauth_data);
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_pwd.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_pwd.c
index 2df0f4e512..1deca3028e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_pwd.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_pwd.c
@@ -1,16 +1,11 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-/*
- * Gets initial credentials upon authentication
- */
-
-#include <k5-int.h>
-#include <com_err.h>
+#include "k5-int.h"
+#include "com_err.h"
#include <admin.h>
#include <locale.h>
#include <syslog.h>
@@ -46,15 +41,15 @@ krb5_error_code __krb5_get_init_creds_password(krb5_context,
static krb5_error_code
krb5_get_as_key_password(
- krb5_context context,
- krb5_principal client,
- krb5_enctype etype,
- krb5_prompter_fct prompter,
- void *prompter_data,
- krb5_data *salt,
- krb5_data *params,
- krb5_keyblock *as_key,
- void *gak_data)
+ krb5_context context,
+ krb5_principal client,
+ krb5_enctype etype,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ krb5_data *salt,
+ krb5_data *params,
+ krb5_keyblock *as_key,
+ void *gak_data)
{
krb5_data *password;
krb5_error_code ret;
@@ -83,10 +78,10 @@ krb5_get_as_key_password(
if (password->data[0] == '\0') {
if (prompter == NULL)
- prompter = krb5_prompter_posix;
+ prompter = krb5_prompter_posix; /* Solaris Kerberos */
if ((ret = krb5_unparse_name(context, client, &clientstr)))
- return(ret);
+ return(ret);
strcpy(promptstr, "Password for ");
strncat(promptstr, clientstr, sizeof(promptstr)-strlen(promptstr)-1);
@@ -109,8 +104,7 @@ krb5_get_as_key_password(
krb5int_set_prompt_types(context, 0);
}
- if ((salt->length == -1 || salt->length == SALT_TYPE_AFS_LENGTH) &&
- (salt->data == NULL)) {
+ if ((salt->length == -1 || salt->length == SALT_TYPE_AFS_LENGTH) && (salt->data == NULL)) {
if ((ret = krb5_principal2salt(context, client, &defsalt)))
return(ret);
@@ -120,7 +114,7 @@ krb5_get_as_key_password(
}
ret = krb5_c_string_to_key_with_params(context, etype, password, salt,
- params->data?params:NULL, as_key);
+ params->data?params:NULL, as_key);
if (defsalt.length)
krb5_xfree(defsalt.data);
@@ -129,16 +123,15 @@ krb5_get_as_key_password(
}
krb5_error_code KRB5_CALLCONV
-krb5_get_init_creds_password(
- krb5_context context,
- krb5_creds *creds,
- krb5_principal client,
- char *password,
- krb5_prompter_fct prompter,
- void *data,
- krb5_deltat start_time,
- char *in_tkt_service,
- krb5_get_init_creds_opt *options)
+krb5_get_init_creds_password(krb5_context context,
+ krb5_creds *creds,
+ krb5_principal client,
+ char *password,
+ krb5_prompter_fct prompter,
+ void *data,
+ krb5_deltat start_time,
+ char *in_tkt_service,
+ krb5_get_init_creds_opt *options)
{
/*
* Solaris Kerberos:
@@ -176,11 +169,13 @@ __krb5_get_init_creds_password(
krb5_kdc_rep *as_reply;
int tries;
krb5_creds chpw_creds;
- krb5_get_init_creds_opt chpw_opts;
+ krb5_get_init_creds_opt *chpw_opts = NULL;
krb5_data pw0, pw1;
char banner[1024], pw0array[1024], pw1array[1024];
krb5_prompt prompt[2];
krb5_prompt_type prompt_types[sizeof(prompt)/sizeof(prompt[0])];
+ krb5_gic_opt_ext *opte = NULL;
+ krb5_gic_opt_ext *chpw_opte = NULL;
char admin_realm[1024], *cpw_service=NULL, *princ_str=NULL;
kadm5_config_params params;
@@ -192,7 +187,7 @@ __krb5_get_init_creds_password(
pw0.data = pw0array;
- if (password) {
+ if (password && password[0]) {
if ((pw0.length = strlen(password)) > sizeof(pw0array)) {
ret = EINVAL;
goto cleanup;
@@ -207,10 +202,15 @@ __krb5_get_init_creds_password(
pw1.data[0] = '\0';
pw1.length = sizeof(pw1array);
+ ret = krb5int_gic_opt_to_opte(context, options, &opte, 1,
+ "krb5_get_init_creds_password");
+ if (ret)
+ goto cleanup;
+
/* first try: get the requested tkt from any kdc */
ret = krb5_get_init_creds(context, creds, client, prompter, data,
- start_time, in_tkt_service, options,
+ start_time, in_tkt_service, opte,
krb5_get_as_key_password, (void *) &pw0,
&use_master, &as_reply);
@@ -235,35 +235,35 @@ __krb5_get_init_creds_password(
use_master = 1;
if (as_reply) {
- krb5_free_kdc_rep( context, as_reply);
- as_reply = NULL;
+ krb5_free_kdc_rep( context, as_reply);
+ as_reply = NULL;
}
-
ret2 = krb5_get_init_creds(context, creds, client, prompter, data,
- start_time, in_tkt_service, options,
+ start_time, in_tkt_service, opte,
krb5_get_as_key_password, (void *) &pw0,
&use_master, &as_reply);
-
+
if (ret2 == 0) {
ret = 0;
goto cleanup;
}
/* if the master is unreachable, return the error from the
- slave we were able to contact */
-
- if ((ret2 == KRB5_KDC_UNREACH) ||
- (ret2 == KRB5_REALM_CANT_RESOLVE) ||
- (ret2 == KRB5_REALM_UNKNOWN))
- goto cleanup;
-
- ret = ret2;
+ slave we were able to contact or reset the use_master flag */
+
+ if ((ret2 != KRB5_KDC_UNREACH) &&
+ (ret2 != KRB5_REALM_CANT_RESOLVE) &&
+ (ret2 != KRB5_REALM_UNKNOWN))
+ ret = ret2;
+ else
+ use_master = 0;
}
-#ifdef USE_LOGIN_LIBRARY
+/* Solaris Kerberos: 163 resync */
+/* #ifdef USE_LOGIN_LIBRARY */
if (ret == KRB5KDC_ERR_KEY_EXP)
- goto cleanup; /* Login library will deal appropriately with this error */
-#endif
+ 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,
@@ -273,12 +273,20 @@ __krb5_get_init_creds_password(
(prompter == NULL))
goto cleanup;
- /* ok, we have an expired password. Give the user a few chances
+ /* historically the default has been to prompt for password change.
+ * if the change password prompt option has not been set, we continue
+ * to prompt. Prompting is only disabled if the option has been set
+ * and the value has been set to false.
+ */
+ if (!(options->flags & KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT))
+ goto cleanup;
+
+ /* ok, we have an expired password. Give the user a few chances
to change it */
- /* Solaris Kerberos:
- *
+ /*
+ * Solaris Kerberos:
* Get the correct change password service principal name to use.
* This is necessary because SEAM based admin servers require
* a slightly different service principal name than MIT/MS servers.
@@ -324,7 +332,7 @@ __krb5_get_init_creds_password(
prompt[1].reply = &pw1;
prompt_types[1] = KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN;
- strcpy(banner, "Password expired. You must change it now.");
+ strcpy(banner, "Password expired. You must change it now.");
for (tries = 3; tries; tries--) {
pw0.length = sizeof(pw0array);
@@ -333,7 +341,7 @@ __krb5_get_init_creds_password(
/* PROMPTER_INVOCATION */
krb5int_set_prompt_types(context, prompt_types);
if ((ret = ((*prompter)(context, data, 0, banner,
- sizeof(prompt)/sizeof(prompt[0]), prompt))))
+ sizeof(prompt)/sizeof(prompt[0]), prompt))))
goto cleanup;
krb5int_set_prompt_types(context, 0);
@@ -346,16 +354,18 @@ __krb5_get_init_creds_password(
sprintf(banner, "%s. Please try again.", error_message(ret));
} else {
int result_code;
+ krb5_data code_string;
+ krb5_data result_string;
- result_code = kadm5_chpass_principal_util(server_handle, client,
- pw0.data,
- NULL /* don't need pw back */,
- banner,
- sizeof(banner));
+ if ((ret = krb5_change_password(context, &chpw_creds, pw0array,
+ &result_code, &code_string,
+ &result_string)))
+ goto cleanup;
/* the change succeeded. go on */
if (result_code == 0) {
+ krb5_xfree(result_string.data);
break;
}
@@ -364,8 +374,26 @@ __krb5_get_init_creds_password(
ret = KRB5_CHPW_FAIL;
if (result_code != KRB5_KPASSWD_SOFTERROR) {
+ krb5_xfree(result_string.data);
goto cleanup;
}
+
+ /* the error was soft, so try again */
+
+ /* 100 is I happen to know that no code_string will be longer
+ than 100 chars */
+
+ if (result_string.length > (sizeof(banner)-100))
+ result_string.length = sizeof(banner)-100;
+
+ sprintf(banner, "%.*s%s%.*s. Please try again.\n",
+ (int) code_string.length, code_string.data,
+ result_string.length ? ": " : "",
+ (int) result_string.length,
+ result_string.data ? result_string.data : "");
+
+ krb5_xfree(code_string.data);
+ krb5_xfree(result_string.data);
}
}
@@ -377,7 +405,7 @@ __krb5_get_init_creds_password(
is final. */
ret = krb5_get_init_creds(context, creds, client, prompter, data,
- start_time, in_tkt_service, options,
+ start_time, in_tkt_service, opte,
krb5_get_as_key_password, (void *) &pw0,
&use_master, &as_reply);
@@ -415,45 +443,46 @@ cleanup:
/* ignore an error here */
/* PROMPTER_INVOCATION */
(*prompter)(context, data, 0, banner, 0, 0);
- } else if (prompter &&
- (!in_tkt_service ||
- (strcmp(in_tkt_service, "kadmin/changepw") != 0)) &&
- as_reply->enc_part2 && as_reply->enc_part2->last_req) {
- /*
- * Check the last_req fields
- */
-
- for (last_req = as_reply->enc_part2->last_req; *last_req; last_req++)
- if ((*last_req)->lr_type == KRB5_LRQ_ALL_PW_EXPTIME ||
- (*last_req)->lr_type == KRB5_LRQ_ONE_PW_EXPTIME) {
- krb5_deltat delta;
- char ts[256];
-
- if ((ret = krb5_timeofday(context, &now)))
- break;
-
- if ((ret = krb5_timestamp_to_string((*last_req)->value,
- ts, sizeof(ts))))
- break;
- delta = (*last_req)->value - now;
-
- if (delta < 3600)
- sprintf(banner,
- "Warning: Your password will expire in less than one "
- "hour on %s", ts);
- else if (delta < 86400*2)
- sprintf(banner,
- "Warning: Your password will expire in %d hour%s on %s",
- delta / 3600, delta < 7200 ? "" : "s", ts);
- else
- sprintf(banner,
- "Warning: Your password will expire in %d days on %s",
- delta / 86400, ts);
- /* ignore an error here */
- /* PROMPTER_INVOCATION */
- (*prompter)(context, data, 0, banner, 0, 0);
- }
- } /* prompter && !in_tkt_service */
+ } else if (prompter &&
+ (!in_tkt_service ||
+ (strcmp(in_tkt_service, "kadmin/changepw") != 0)) &&
+ as_reply->enc_part2 && as_reply->enc_part2->last_req) {
+ /*
+ * Check the last_req fields
+ */
+
+ for (last_req = as_reply->enc_part2->last_req; *last_req; last_req++)
+ if ((*last_req)->lr_type == KRB5_LRQ_ALL_PW_EXPTIME ||
+ (*last_req)->lr_type == KRB5_LRQ_ONE_PW_EXPTIME) {
+ krb5_deltat delta;
+ char ts[256];
+
+ if ((ret = krb5_timeofday(context, &now)))
+ break;
+
+ if ((ret = krb5_timestamp_to_string((*last_req)->value,
+ ts, sizeof(ts))))
+ break;
+
+ delta = (*last_req)->value - now;
+
+ if (delta < 3600)
+ sprintf(banner,
+ "Warning: Your password will expire in less than one "
+ "hour on %s", ts);
+ else if (delta < 86400*2)
+ sprintf(banner,
+ "Warning: Your password will expire in %d hour%s on %s",
+ delta / 3600, delta < 7200 ? "" : "s", ts);
+ else
+ sprintf(banner,
+ "Warning: Your password will expire in %d days on %s",
+ delta / 86400, ts);
+ /* ignore an error here */
+ /* PROMPTER_INVOCATION */
+ (*prompter)(context, data, 0, banner, 0, 0);
+ }
+ }
}
free(cpw_service);
@@ -474,14 +503,15 @@ cleanup:
return(ret);
}
-
-void krb5int_populate_gic_opt (
- krb5_context context, krb5_get_init_creds_opt *opt,
+krb5_error_code krb5int_populate_gic_opt (
+ krb5_context context, krb5_gic_opt_ext **opte,
krb5_flags options, krb5_address * const *addrs, krb5_enctype *ktypes,
krb5_preauthtype *pre_auth_types, krb5_creds *creds)
{
int i;
krb5_int32 starttime;
+ krb5_get_init_creds_opt *opt;
+
krb5_get_init_creds_opt_init(opt);
if (addrs)
@@ -507,6 +537,8 @@ void krb5int_populate_gic_opt (
if (creds->times.starttime) starttime = creds->times.starttime;
krb5_get_init_creds_opt_set_tkt_life(opt, creds->times.endtime - starttime);
}
+ return krb5int_gic_opt_to_opte(context, opt, opte, 0,
+ "krb5int_populate_gic_opt");
}
/*
@@ -539,10 +571,10 @@ krb5_get_in_tkt_with_password(krb5_context context, krb5_flags options,
krb5_error_code retval;
krb5_data pw0;
char pw0array[1024];
- krb5_get_init_creds_opt opt;
char * server;
krb5_principal server_princ, client_princ;
int use_master = 0;
+ krb5_gic_opt_ext *opte = NULL;
pw0array[0] = '\0';
pw0.data = pw0array;
@@ -556,21 +588,26 @@ krb5_get_in_tkt_with_password(krb5_context context, krb5_flags options,
} else {
pw0.length = sizeof(pw0array);
}
- krb5int_populate_gic_opt(context, &opt,
- options, addrs, ktypes,
- pre_auth_types, creds);
- retval = krb5_unparse_name( context, creds->server, &server);
+ retval = krb5int_populate_gic_opt(context, &opte,
+ options, addrs, ktypes,
+ pre_auth_types, creds);
if (retval)
return (retval);
+ retval = krb5_unparse_name( context, creds->server, &server);
+ if (retval) {
+ return (retval);
+ krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte);
+ }
server_princ = creds->server;
client_princ = creds->client;
retval = krb5_get_init_creds (context,
creds, creds->client,
krb5_prompter_posix, NULL,
- 0, server, &opt,
+ 0, server, opte,
krb5_get_as_key_password, &pw0,
&use_master, ret_as_reply);
krb5_free_unparsed_name( context, server);
+ krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte);
if (retval) {
return (retval);
}
@@ -585,4 +622,5 @@ krb5_get_in_tkt_with_password(krb5_context context, krb5_flags options,
if ((retval = krb5_cc_store_cred(context, ccache, creds)))
return (retval);
return retval;
-}
+ }
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/int-proto.h b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/int-proto.h
index e0f1ba1a8a..5c576c3fd6 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/int-proto.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/int-proto.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/int-proto.h
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -46,5 +48,11 @@ krb5_error_code krb5_ser_checksum_init (krb5_context);
krb5_error_code krb5_ser_keyblock_init (krb5_context);
krb5_error_code krb5_ser_principal_init (krb5_context);
+krb5_error_code
+krb5_preauth_supply_preauth_data(krb5_context context,
+ krb5_gic_opt_ext *opte,
+ const char *attr,
+ const char *value);
+
#endif /* KRB5_INT_FUNC_PROTO__ */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/kdc_rep_dc.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/kdc_rep_dc.c
index 60104c0a65..42559b2f17 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/kdc_rep_dc.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/kdc_rep_dc.c
@@ -1,11 +1,4 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* lib/krb5/krb/kdc_rep_dc.c
*
* Copyright 1990 by the Massachusetts Institute of Technology.
@@ -15,7 +8,7 @@
* 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
@@ -29,12 +22,12 @@
* 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_kdc_rep_decrypt_proc()
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
* Decrypt the encrypted portion of the KDC_REP message, using the key
@@ -64,11 +57,10 @@ krb5_kdc_rep_decrypt_proc(krb5_context context, const krb5_keyblock *key, krb5_c
return(ENOMEM);
}
- /*(void) (dec_rep->enc_part.enctype);*/
+ /*dec_rep->enc_part.enctype;*/
- retval = krb5_c_decrypt(context, key, usage, 0, &dec_rep->enc_part,
- &scratch);
- if (retval) {
+ if ((retval = krb5_c_decrypt(context, key, usage, 0, &dec_rep->enc_part,
+ &scratch))) {
free(scratch.data);
return(retval);
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/krb5_libinit.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/krb5_libinit.c
index 3b65992775..45658709e7 100755..100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/krb5_libinit.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/krb5_libinit.c
@@ -1,16 +1,15 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include <assert.h>
#include "autoconf.h"
#include "com_err.h"
-#include "krb5.h"
-#if 0 /* SUNW14resync */
+#include "k5-int.h"
+#if 0 /* Solaris Kerberos */
#include "krb5_err.h"
#include "kv5m_err.h"
#include "asn1_err.h"
@@ -42,6 +41,10 @@ int krb5int_lib_init(void)
krb5int_set_error_info_callout_fn (error_message);
+#ifdef SHOW_INITFINI_FUNCS
+ printf("krb5int_lib_init\n");
+#endif
+
#if !USE_BUNDLE_ERROR_STRINGS
add_error_table(&et_krb5_error_table);
add_error_table(&et_kv5m_error_table);
@@ -62,6 +65,7 @@ int krb5int_lib_init(void)
err = k5_mutex_finish_init(&krb5int_us_time_mutex);
if (err)
return err;
+
return 0;
}
@@ -77,12 +81,22 @@ krb5_error_code krb5int_initialize_library (void)
void krb5int_lib_fini(void)
{
- if (!INITIALIZER_RAN(krb5int_lib_init) || PROGRAM_EXITING())
+ if (!INITIALIZER_RAN(krb5int_lib_init) || PROGRAM_EXITING()) {
+#ifdef SHOW_INITFINI_FUNCS
+ printf("krb5int_lib_fini: skipping\n");
+#endif
return;
+ }
+
+#ifdef SHOW_INITFINI_FUNCS
+ printf("krb5int_lib_fini\n");
+#endif
+
+ k5_mutex_destroy(&krb5int_us_time_mutex);
- krb5int_rc_terminate();
- krb5int_kt_finalize();
krb5int_cc_finalize();
+ krb5int_kt_finalize();
+ krb5int_rc_terminate();
#if defined(_WIN32) || defined(USE_CCAPI)
krb5_stdcc_shutdown();
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_cred.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_cred.c
index ad63f299a6..cfe825b1ea 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_cred.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_cred.c
@@ -1,22 +1,21 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* NAME
* cred.c
- *
+ *
* DESCRIPTION
* Provide an interface to assemble and disassemble krb5_cred
* structures.
*
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "cleanup.h"
-#include <auth_con.h>
+#include "auth_con.h"
#include <stddef.h> /* NULL */
#include <stdlib.h> /* malloc */
@@ -61,7 +60,7 @@ encrypt_credencpart(krb5_context context, krb5_cred_enc_part *pcredpart, krb5_ke
pencdata->ciphertext.data = 0;
}
- memset(scratch->data, 0, scratch->length);
+ memset(scratch->data, 0, scratch->length);
krb5_free_data(context, scratch);
return retval;
@@ -94,7 +93,7 @@ krb5_mk_ncred_basic(krb5_context context, krb5_creds **ppcreds, krb5_int32 nppcr
if (credenc.ticket_info == NULL)
return ENOMEM;
memset(credenc.ticket_info, 0, size);
-
+
/*
* For each credential in the list, initialize a cred info
* structure and copy the ticket into the ticket list.
@@ -111,7 +110,7 @@ krb5_mk_ncred_basic(krb5_context context, krb5_creds **ppcreds, krb5_int32 nppcr
credenc.ticket_info[i]->times = ppcreds[i]->times;
credenc.ticket_info[i]->flags = ppcreds[i]->ticket_flags;
- if ((retval = decode_krb5_ticket(&ppcreds[i]->ticket,
+ if ((retval = decode_krb5_ticket(&ppcreds[i]->ticket,
&pcred->tickets[i])))
goto cleanup;
@@ -155,8 +154,8 @@ cleanup:
krb5_error_code KRB5_CALLCONV
krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, krb5_creds **ppcreds, krb5_data **ppdata, krb5_replay_data *outdata)
{
- krb5_address * premote_fulladdr = NULL;
- krb5_address * plocal_fulladdr = NULL;
+ krb5_address * premote_fulladdr = NULL;
+ krb5_address * plocal_fulladdr = NULL;
krb5_address remote_fulladdr;
krb5_address local_fulladdr;
krb5_error_code retval;
@@ -178,11 +177,11 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, krb5_creds *
*/
for (ncred = 0; ppcreds[ncred]; ncred++);
- if ((pcred = (krb5_cred *)malloc(sizeof(krb5_cred))) == NULL)
+ if ((pcred = (krb5_cred *)malloc(sizeof(krb5_cred))) == NULL)
return ENOMEM;
memset(pcred, 0, sizeof(krb5_cred));
- if ((pcred->tickets
+ if ((pcred->tickets
= (krb5_ticket **)malloc(sizeof(krb5_ticket *) * (ncred + 1))) == NULL) {
retval = ENOMEM;
free(pcred);
@@ -190,8 +189,8 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, krb5_creds *
memset(pcred->tickets, 0, sizeof(krb5_ticket *) * (ncred +1));
/* Get keyblock */
- if ((keyblock = auth_context->send_subkey) == NULL)
- keyblock = auth_context->keyblock;
+ if ((keyblock = auth_context->send_subkey) == NULL)
+ keyblock = auth_context->keyblock;
/* Get replay info */
if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) &&
@@ -224,7 +223,7 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, krb5_creds *
if (auth_context->local_addr) {
if (auth_context->local_port) {
if ((retval = krb5_make_fulladdr(context, auth_context->local_addr,
- auth_context->local_port,
+ auth_context->local_port,
&local_fulladdr)))
goto error;
plocal_fulladdr = &local_fulladdr;
@@ -236,7 +235,7 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, krb5_creds *
if (auth_context->remote_addr) {
if (auth_context->remote_port) {
if ((retval = krb5_make_fulladdr(context,auth_context->remote_addr,
- auth_context->remote_port,
+ auth_context->remote_port,
&remote_fulladdr)))
goto error;
premote_fulladdr = &remote_fulladdr;
@@ -247,7 +246,7 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, krb5_creds *
/* Setup creds structure */
if ((retval = krb5_mk_ncred_basic(context, ppcreds, ncred, keyblock,
- &replaydata, plocal_fulladdr,
+ &replaydata, plocal_fulladdr,
premote_fulladdr, pcred))) {
goto error;
}
@@ -262,8 +261,7 @@ krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, krb5_creds *
replay.server = ""; /* XXX */
replay.cusec = replaydata.usec;
replay.ctime = replaydata.timestamp;
- retval = krb5_rc_store(context, auth_context->rcache, &replay);
- if (retval) {
+ if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {
/* should we really error out here? XXX */
krb5_xfree(replay.client);
goto error;
@@ -282,7 +280,7 @@ error:
krb5_free_cred(context, pcred);
if (retval) {
- if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE)
+ if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE)
|| (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE))
auth_context->local_seq_number--;
}
@@ -298,9 +296,9 @@ krb5_error_code KRB5_CALLCONV
krb5_mk_1cred(krb5_context context, krb5_auth_context auth_context, krb5_creds *pcreds, krb5_data **ppdata, krb5_replay_data *outdata)
{
krb5_error_code retval;
- krb5_creds **ppcreds;
+ krb5_creds **ppcreds;
- if ((ppcreds = (krb5_creds **)malloc(sizeof(*ppcreds) * 2)) == NULL) {
+ if ((ppcreds = (krb5_creds **)malloc(sizeof(*ppcreds) * 2)) == NULL) {
return ENOMEM;
}
@@ -309,7 +307,8 @@ krb5_mk_1cred(krb5_context context, krb5_auth_context auth_context, krb5_creds *
retval = krb5_mk_ncred(context, auth_context, ppcreds,
ppdata, outdata);
-
+
free(ppcreds);
return retval;
}
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_priv.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_priv.c
index 591e8c943f..7ba03d6135 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_priv.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_priv.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/mk_priv.c
@@ -15,7 +14,7 @@
* 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
@@ -29,26 +28,18 @@
* 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_mk_priv()
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "cleanup.h"
-#include <auth_con.h>
+#include "auth_con.h"
/*ARGSUSED*/
static krb5_error_code
-krb5_mk_priv_basic(
- krb5_context context,
- const krb5_data * userdata,
- const krb5_keyblock * keyblock,
- krb5_replay_data * replaydata,
- krb5_address * local_addr,
- krb5_address * remote_addr,
- krb5_pointer i_vector,
- krb5_data * outbuf)
+krb5_mk_priv_basic(krb5_context context, const krb5_data *userdata, const krb5_keyblock *keyblock, krb5_replay_data *replaydata, krb5_address *local_addr, krb5_address *remote_addr, krb5_pointer i_vector, krb5_data *outbuf)
{
krb5_error_code retval;
krb5_priv privmsg;
@@ -57,7 +48,7 @@ krb5_mk_priv_basic(
size_t blocksize, enclen;
privmsg.enc_part.kvno = 0; /* XXX allow user-set? */
- privmsg.enc_part.enctype = keyblock->enctype;
+ privmsg.enc_part.enctype = keyblock->enctype;
privmsg_enc_part.user_data = *userdata;
privmsg_enc_part.s_address = local_addr;
@@ -94,13 +85,13 @@ krb5_mk_priv_basic(
ivdata.data = i_vector;
}
- retval = krb5_c_encrypt(context, keyblock, KRB5_KEYUSAGE_KRB_PRIV_ENCPART,
- i_vector?&ivdata:0, scratch1, &privmsg.enc_part);
- if (retval)
+ if ((retval = krb5_c_encrypt(context, keyblock,
+ KRB5_KEYUSAGE_KRB_PRIV_ENCPART,
+ i_vector?&ivdata:0,
+ scratch1, &privmsg.enc_part)))
goto clean_encpart;
- retval = encode_krb5_priv(&privmsg, &scratch2);
- if (retval)
+ if ((retval = encode_krb5_priv(&privmsg, &scratch2)))
goto clean_encpart;
*outbuf = *scratch2;
@@ -108,27 +99,24 @@ krb5_mk_priv_basic(
retval = 0;
clean_encpart:
- memset(privmsg.enc_part.ciphertext.data, 0,
- privmsg.enc_part.ciphertext.length);
- free(privmsg.enc_part.ciphertext.data);
+ memset(privmsg.enc_part.ciphertext.data, 0,
+ privmsg.enc_part.ciphertext.length);
+ free(privmsg.enc_part.ciphertext.data);
privmsg.enc_part.ciphertext.length = 0;
privmsg.enc_part.ciphertext.data = 0;
clean_scratch:
memset(scratch1->data, 0, scratch1->length);
- krb5_free_data(context, scratch1);
+ krb5_free_data(context, scratch1);
return retval;
}
krb5_error_code KRB5_CALLCONV
-krb5_mk_priv(
- krb5_context context,
- krb5_auth_context auth_context,
- const krb5_data *userdata,
- krb5_data *outbuf,
- krb5_replay_data *outdata)
+krb5_mk_priv(krb5_context context, krb5_auth_context auth_context,
+ const krb5_data *userdata, krb5_data *outbuf,
+ krb5_replay_data *outdata)
{
krb5_error_code retval;
krb5_keyblock * keyblock;
@@ -170,7 +158,7 @@ krb5_mk_priv(
} else {
outdata->seq = replaydata.seq;
}
- }
+ }
{
krb5_address * premote_fulladdr = NULL;
@@ -182,7 +170,7 @@ krb5_mk_priv(
if (auth_context->local_addr) {
if (auth_context->local_port) {
if (!(retval = krb5_make_fulladdr(context, auth_context->local_addr,
- auth_context->local_port,
+ auth_context->local_port,
&local_fulladdr))) {
CLEANUP_PUSH(local_fulladdr.contents, free);
plocal_fulladdr = &local_fulladdr;
@@ -197,7 +185,7 @@ krb5_mk_priv(
if (auth_context->remote_addr) {
if (auth_context->remote_port) {
if (!(retval = krb5_make_fulladdr(context,auth_context->remote_addr,
- auth_context->remote_port,
+ auth_context->remote_port,
&remote_fulladdr))){
CLEANUP_PUSH(remote_fulladdr.contents, free);
premote_fulladdr = &remote_fulladdr;
@@ -210,7 +198,7 @@ krb5_mk_priv(
}
}
- if ((retval = krb5_mk_priv_basic(context, userdata, keyblock, &replaydata,
+ if ((retval = krb5_mk_priv_basic(context, userdata, keyblock, &replaydata,
plocal_fulladdr, premote_fulladdr,
auth_context->i_vector, outbuf))) {
CLEANUP_DONE();
@@ -223,7 +211,7 @@ krb5_mk_priv(
if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) {
krb5_donot_replay replay;
- if ((retval = krb5_gen_replay_name(context, auth_context->local_addr,
+ if ((retval = krb5_gen_replay_name(context, auth_context->local_addr,
"_priv", &replay.client))) {
krb5_xfree(outbuf);
goto error;
@@ -232,8 +220,7 @@ krb5_mk_priv(
replay.server = ""; /* XXX */
replay.cusec = replaydata.usec;
replay.ctime = replaydata.timestamp;
- retval = krb5_rc_store(context, auth_context->rcache, &replay);
- if (retval) {
+ if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {
/* should we really error out here? XXX */
krb5_xfree(replay.client);
goto error;
@@ -250,3 +237,4 @@ error:
return retval;
}
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_rep.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_rep.c
index 9f85f73066..393f634bb1 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_rep.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_rep.c
@@ -1,11 +1,4 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* lib/krb5/krb/mk_rep.c
*
* Copyright 1990 by the Massachusetts Institute of Technology.
@@ -15,7 +8,7 @@
* 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
@@ -29,13 +22,13 @@
* 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_mk_rep()
*/
-#include <k5-int.h>
-#include <auth_con.h>
+#include "k5-int.h"
+#include "auth_con.h"
/*
Formats a KRB_AP_REP message into outbuf.
@@ -64,43 +57,39 @@ krb5_mk_rep(krb5_context context, krb5_auth_context auth_context, krb5_data *out
return(retval);
}
- repl.ctime = auth_context->authentp->ctime;
- repl.cusec = auth_context->authentp->cusec;
+ repl.ctime = auth_context->authentp->ctime;
+ repl.cusec = auth_context->authentp->cusec;
if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_USE_SUBKEY) {
retval = krb5int_generate_and_save_subkey (context, auth_context,
- auth_context->keyblock);
+ auth_context->keyblock);
if (retval)
- return retval;
+ return retval;
repl.subkey = auth_context->send_subkey;
} else
- repl.subkey = auth_context->authentp->subkey;
-
+ repl.subkey = auth_context->authentp->subkey;
repl.seq_number = auth_context->local_seq_number;
/* encode it before encrypting */
- retval = encode_krb5_ap_rep_enc_part(&repl, &scratch);
- if (retval)
+ if ((retval = encode_krb5_ap_rep_enc_part(&repl, &scratch)))
return retval;
- retval = krb5_encrypt_helper(context, auth_context->keyblock,
- KRB5_KEYUSAGE_AP_REP_ENCPART,
- scratch, &reply.enc_part);
- if (retval)
+ if ((retval = krb5_encrypt_helper(context, auth_context->keyblock,
+ KRB5_KEYUSAGE_AP_REP_ENCPART,
+ scratch, &reply.enc_part)))
goto cleanup_scratch;
- retval = encode_krb5_ap_rep(&reply, &toutbuf);
- if (!retval) {
+ if (!(retval = encode_krb5_ap_rep(&reply, &toutbuf))) {
*outbuf = *toutbuf;
krb5_xfree(toutbuf);
}
memset(reply.enc_part.ciphertext.data, 0, reply.enc_part.ciphertext.length);
- free(reply.enc_part.ciphertext.data);
- reply.enc_part.ciphertext.length = 0;
+ free(reply.enc_part.ciphertext.data);
+ reply.enc_part.ciphertext.length = 0;
reply.enc_part.ciphertext.data = 0;
cleanup_scratch:
- memset(scratch->data, 0, scratch->length);
+ memset(scratch->data, 0, scratch->length);
krb5_free_data(context, scratch);
return retval;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_req.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_req.c
index 50aa32e7e1..8c800adefa 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_req.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_req.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/mk_req.c
@@ -15,7 +14,7 @@
* 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
@@ -29,13 +28,13 @@
* 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_mk_req() routine.
*/
-#include <k5-int.h>
-#include <auth_con.h>
+#include "k5-int.h"
+#include "auth_con.h"
/*
Formats a KRB_AP_REQ message into outbuf.
@@ -45,7 +44,7 @@
TGS request with default parameters is used in an attempt to obtain
such credentials, and they are stored in ccache.
- kdc_options specifies the options requested for the
+ kdc_options specifies the options requested for the
ap_req_options specifies the KRB_AP_REQ options desired.
checksum specifies the checksum to be used in the authenticator.
@@ -66,7 +65,7 @@ krb5_mk_req(krb5_context context, krb5_auth_context *auth_context,
krb5_creds * credsp;
krb5_creds creds;
- retval = krb5_sname_to_principal(context, hostname, service,
+ retval = krb5_sname_to_principal(context, hostname, service,
KRB5_NT_SRV_HST, &server);
if (retval)
return retval;
@@ -76,14 +75,16 @@ krb5_mk_req(krb5_context context, krb5_auth_context *auth_context,
if ((retval = krb5_copy_principal(context, server, &creds.server)))
goto cleanup_princ;
+ /* Solaris Kerberos */
if ((retval = krb5_cc_get_principal(context, ccache, &creds.client)) != 0)
goto cleanup_creds;
+ /* Solaris Kerberos */
if ((retval = krb5_get_credentials(context, 0,
ccache, &creds, &credsp)) != 0)
goto cleanup_creds;
- retval = krb5_mk_req_extended(context, auth_context, ap_req_options,
+ retval = krb5_mk_req_extended(context, auth_context, ap_req_options,
in_data, credsp, outbuf);
krb5_free_creds(context, credsp);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_req_ext.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_req_ext.c
index f09ae4843c..a83a1efcda 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_req_ext.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_req_ext.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/mk_req_ext.c
@@ -15,7 +14,7 @@
* 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
@@ -29,14 +28,14 @@
* 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_mk_req_extended()
*/
-#include <k5-int.h>
-#include <auth_con.h>
+#include "k5-int.h"
+#include "auth_con.h"
/*
Formats a KRB_AP_REQ message into outbuf, with more complete options than
@@ -71,7 +70,7 @@
returns system errors
*/
-static krb5_error_code
+static krb5_error_code
krb5_generate_authenticator (krb5_context,
krb5_authenticator *, krb5_principal,
krb5_checksum *, krb5_keyblock *,
@@ -88,9 +87,9 @@ krb5int_generate_and_save_subkey (krb5_context context,
* we have /dev/random and PKCS#11 to handle Random Numbers.
*/
/* 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. */
+ 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;
@@ -103,6 +102,7 @@ krb5int_generate_and_save_subkey (krb5_context context,
#endif
krb5_error_code retval;
+ /* Solaris Kerberos */
if (auth_context->send_subkey != NULL) {
krb5_free_keyblock(context, auth_context->send_subkey);
auth_context->send_subkey = NULL;
@@ -111,6 +111,7 @@ krb5int_generate_and_save_subkey (krb5_context context,
if ((retval = krb5_generate_subkey(context, keyblock, &auth_context->send_subkey)))
return retval;
+ /* Solaris Kerberos */
if (auth_context->recv_subkey != NULL) {
krb5_free_keyblock(context, auth_context->recv_subkey);
auth_context->recv_subkey = NULL;
@@ -126,13 +127,9 @@ krb5int_generate_and_save_subkey (krb5_context context,
}
krb5_error_code KRB5_CALLCONV
-krb5_mk_req_extended(
- krb5_context context,
- krb5_auth_context * auth_context,
- const krb5_flags ap_req_options,
- krb5_data * in_data,
- krb5_creds * in_creds,
- krb5_data * outbuf)
+krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context,
+ krb5_flags ap_req_options, krb5_data *in_data,
+ krb5_creds *in_creds, krb5_data *outbuf)
{
krb5_error_code retval;
krb5_checksum checksum;
@@ -146,16 +143,16 @@ krb5_mk_req_extended(
request.ap_options = ap_req_options & AP_OPTS_WIRE_MASK;
request.authenticator.ciphertext.data = 0;
request.ticket = 0;
-
- if (!in_creds->ticket.length)
+
+ if (!in_creds->ticket.length)
return(KRB5_NO_TKT_SUPPLIED);
/* we need a native ticket */
if ((retval = decode_krb5_ticket(&(in_creds)->ticket, &request.ticket)))
return(retval);
-
+
/* verify that the ticket is not expired */
- if ((retval = krb5_validate_times(context, &in_creds->times)))
+ if ((retval = krb5_validate_times(context, &in_creds->times)) != 0)
goto cleanup;
/* generate auth_context if needed */
@@ -165,19 +162,20 @@ krb5_mk_req_extended(
*auth_context = new_auth_context;
}
- /* set auth context keyblock */
if ((*auth_context)->keyblock != NULL) {
krb5_free_keyblock(context, (*auth_context)->keyblock);
(*auth_context)->keyblock = NULL;
}
- if ((retval = krb5_copy_keyblock(context, &in_creds->keyblock,
+
+ /* set auth context keyblock */
+ if ((retval = krb5_copy_keyblock(context, &in_creds->keyblock,
&((*auth_context)->keyblock))))
goto cleanup;
/* generate seq number if needed */
if ((((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE)
|| ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE))
- && ((*auth_context)->local_seq_number == 0))
+ && ((*auth_context)->local_seq_number == 0))
if ((retval = krb5_generate_seq_number(context, &in_creds->keyblock,
&(*auth_context)->local_seq_number)))
goto cleanup;
@@ -185,34 +183,35 @@ krb5_mk_req_extended(
/* generate subkey if needed */
if (!in_data &&(*auth_context)->checksum_func) {
- retval = (*auth_context)->checksum_func(context,
- *auth_context,
- (*auth_context)->checksum_func_data,
- &in_data);
+ retval = (*auth_context)->checksum_func( context,
+ *auth_context,
+ (*auth_context)->checksum_func_data,
+ &in_data);
if (retval)
- goto cleanup;
+ goto cleanup;
}
if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->send_subkey)) {
retval = krb5int_generate_and_save_subkey (context, *auth_context,
- &in_creds->keyblock);
+ &in_creds->keyblock);
if (retval)
- goto cleanup;
+ goto cleanup;
}
+
if (in_data) {
- if ((*auth_context)->req_cksumtype == 0x8003) {
+
+ if ((*auth_context)->req_cksumtype == 0x8003) {
/* XXX Special hack for GSSAPI */
checksum.checksum_type = 0x8003;
checksum.length = in_data->length;
checksum.contents = (krb5_octet *) in_data->data;
} else {
- retval = krb5_c_make_checksum(context,
+ if ((retval = krb5_c_make_checksum(context,
(*auth_context)->req_cksumtype,
(*auth_context)->keyblock,
KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
- in_data, &checksum);
- if (retval)
+ in_data, &checksum)))
goto cleanup_cksum;
}
checksump = &checksum;
@@ -237,7 +236,7 @@ krb5_mk_req_extended(
if ((retval = encode_krb5_authenticator((*auth_context)->authentp,
&scratch)))
goto cleanup_cksum;
-
+
/* Null out these fields, to prevent pointer sharing problems;
* they were supplied by the caller
*/
@@ -246,19 +245,14 @@ krb5_mk_req_extended(
(*auth_context)->authentp->authorization_data = NULL;
/* call the encryption routine */
- retval = krb5_encrypt_helper(context, &in_creds->keyblock,
+ if ((retval = krb5_encrypt_helper(context, &in_creds->keyblock,
KRB5_KEYUSAGE_AP_REQ_AUTH,
- scratch, &request.authenticator);
- if (retval)
+ scratch, &request.authenticator)))
goto cleanup_cksum;
if ((retval = encode_krb5_ap_req(&request, &toutbuf)))
goto cleanup_cksum;
-#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
*outbuf = *toutbuf;
-#else
- memcpy(outbuf, toutbuf, sizeof(krb5_data));
-#endif
krb5_xfree(toutbuf);
@@ -283,17 +277,10 @@ cleanup:
}
static krb5_error_code
-krb5_generate_authenticator(
- krb5_context context,
- krb5_authenticator *authent,
- krb5_principal client,
- krb5_checksum *cksum,
- krb5_keyblock *key,
- krb5_ui_4 seq_number,
- krb5_authdata **authorization)
+krb5_generate_authenticator(krb5_context context, krb5_authenticator *authent, krb5_principal client, krb5_checksum *cksum, krb5_keyblock *key, krb5_ui_4 seq_number, krb5_authdata **authorization)
{
krb5_error_code retval;
-
+
authent->client = client;
authent->checksum = cksum;
if (key) {
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_safe.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_safe.c
index 22b179ca50..7c2accf9af 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_safe.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/mk_safe.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/mk_safe.c
@@ -15,7 +14,7 @@
* 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
@@ -29,14 +28,14 @@
* 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_mk_safe()
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "cleanup.h"
-#include <auth_con.h>
+#include "auth_con.h"
#ifdef KRB5_DEBUG
#include <sys/types.h>
@@ -62,15 +61,10 @@
*/
/*ARGSUSED*/
static krb5_error_code
-krb5_mk_safe_basic(
- krb5_context context,
- const krb5_data * userdata,
- const krb5_keyblock * keyblock,
- krb5_replay_data * replaydata,
- const krb5_address * local_addr,
- const krb5_address * remote_addr,
- const krb5_cksumtype sumtype,
- krb5_data * outbuf)
+krb5_mk_safe_basic(krb5_context context, const krb5_data *userdata,
+ const krb5_keyblock *keyblock, krb5_replay_data *replaydata,
+ krb5_address *local_addr, krb5_address *remote_addr,
+ krb5_cksumtype sumtype, krb5_data *outbuf)
{
krb5_error_code retval;
krb5_safe safemsg;
@@ -78,12 +72,13 @@ krb5_mk_safe_basic(
krb5_checksum safe_checksum;
krb5_data *scratch1, *scratch2;
+ /* Solaris Kerberos */
KRB5_LOG0(KRB5_INFO, "krb5_mk_safe_basic() start");
if (!krb5_c_valid_cksumtype(sumtype))
return KRB5_PROG_SUMTYPE_NOSUPP;
- if (!krb5_c_is_coll_proof_cksum(sumtype) ||
- !krb5_c_is_keyed_cksum(sumtype))
+ if (!krb5_c_is_coll_proof_cksum(sumtype)
+ || !krb5_c_is_keyed_cksum(sumtype))
return KRB5KRB_AP_ERR_INAPP_CKSUM;
safemsg.user_data = *userdata;
@@ -95,10 +90,10 @@ krb5_mk_safe_basic(
safemsg.usec = replaydata->usec;
safemsg.seq_number = replaydata->seq;
- /*
+ /*
* To do the checksum stuff, we need to encode the message with a
* zero-length zero-type checksum, then checksum the encoding, then
- * re-encode with the checksum.
+ * re-encode with the checksum.
*/
safe_checksum.length = 0;
@@ -107,11 +102,13 @@ krb5_mk_safe_basic(
safemsg.checksum = &safe_checksum;
+ /* Solaris Kerberos */
if ((retval = encode_krb5_safe(&safemsg, &scratch1))){
KRB5_LOG(KRB5_ERR, "krb5_mk_safe_basic() end, error retval=%d", retval);
return retval;
}
+ /* Solaris Kerberos */
if ((retval = krb5_c_make_checksum(context, sumtype, keyblock,
KRB5_KEYUSAGE_KRB_SAFE_CKSUM,
scratch1, &safe_checksum)) != 0){
@@ -120,6 +117,8 @@ krb5_mk_safe_basic(
}
safemsg.checksum = &safe_checksum;
+
+ /* Solaris Kerberos */
if ((retval = encode_krb5_safe(&safemsg, &scratch2))) {
KRB5_LOG(KRB5_ERR, "krb5_mk_safe_basic() error retval=%d", retval);
goto cleanup_checksum;
@@ -131,25 +130,21 @@ krb5_mk_safe_basic(
cleanup_checksum:
krb5_xfree(safe_checksum.contents);
-cleanup_scratch:
- memset((char *)scratch1->data, 0, scratch1->length);
+ memset((char *)scratch1->data, 0, scratch1->length);
krb5_free_data(context, scratch1);
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_INFO, "krb5_mk_safe_basic() end, retval=%d", retval);
return retval;
}
krb5_error_code KRB5_CALLCONV
-krb5_mk_safe(
- krb5_context context,
- krb5_auth_context auth_context,
- const krb5_data *userdata,
- krb5_data *outbuf,
- krb5_replay_data *outdata)
+krb5_mk_safe(krb5_context context, krb5_auth_context auth_context, const krb5_data *userdata, krb5_data *outbuf, krb5_replay_data *outdata)
{
krb5_error_code retval;
krb5_keyblock * keyblock;
krb5_replay_data replaydata;
+ /* Solaris Kerberos */
KRB5_LOG0(KRB5_INFO, "krb5_mk_safe() start");
/* Clear replaydata block */
@@ -160,6 +155,7 @@ krb5_mk_safe(
keyblock = auth_context->keyblock;
/* Get replay info */
+ /* Solaris Kerberos */
if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) &&
(auth_context->rcache == NULL)){
KRB5_LOG(KRB5_ERR, "krb5_mk_safe() end error retval=%d", KRB5_RC_REQUIRED);
@@ -170,6 +166,7 @@ krb5_mk_safe(
(auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) &&
(outdata == NULL)){
/* Need a better error */
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_mk_safe() end error retval=%d", KRB5_RC_REQUIRED);
return KRB5_RC_REQUIRED;
}
@@ -178,6 +175,7 @@ krb5_mk_safe(
(auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME)) {
if ((retval = krb5_us_timeofday(context, &replaydata.timestamp,
&replaydata.usec))){
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_mk_safe() end error retval=%d", retval);
return retval;
}
@@ -192,7 +190,7 @@ krb5_mk_safe(
if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE) {
outdata->seq = replaydata.seq;
}
- }
+ }
{
krb5_address * premote_fulladdr = NULL;
@@ -206,7 +204,7 @@ krb5_mk_safe(
if (auth_context->local_addr) {
if (auth_context->local_port) {
if (!(retval = krb5_make_fulladdr(context, auth_context->local_addr,
- auth_context->local_port,
+ auth_context->local_port,
&local_fulladdr))){
CLEANUP_PUSH(local_fulladdr.contents, free);
plocal_fulladdr = &local_fulladdr;
@@ -222,7 +220,7 @@ krb5_mk_safe(
if (auth_context->remote_addr) {
if (auth_context->remote_port) {
if (!(retval = krb5_make_fulladdr(context,auth_context->remote_addr,
- auth_context->remote_port,
+ auth_context->remote_port,
&remote_fulladdr))){
CLEANUP_PUSH(remote_fulladdr.contents, free);
premote_fulladdr = &remote_fulladdr;
@@ -259,8 +257,7 @@ krb5_mk_safe(
sumtype = sumtypes[i];
krb5_free_cksumtypes (context, sumtypes);
}
-
- if ((retval = krb5_mk_safe_basic(context, userdata, keyblock, &replaydata,
+ if ((retval = krb5_mk_safe_basic(context, userdata, keyblock, &replaydata,
plocal_fulladdr, premote_fulladdr,
sumtype, outbuf))) {
CLEANUP_DONE();
@@ -273,7 +270,7 @@ krb5_mk_safe(
if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) {
krb5_donot_replay replay;
- if ((retval = krb5_gen_replay_name(context, auth_context->local_addr,
+ if ((retval = krb5_gen_replay_name(context, auth_context->local_addr,
"_safe", &replay.client))) {
krb5_xfree(outbuf);
goto error;
@@ -282,6 +279,7 @@ krb5_mk_safe(
replay.server = ""; /* XXX */
replay.cusec = replaydata.usec;
replay.ctime = replaydata.timestamp;
+ /* Solaris Kerberos */
if ((retval = krb5_rc_store(context, auth_context->rcache, &replay)) != 0) {
/* should we really error out here? XXX */
krb5_xfree(outbuf);
@@ -289,15 +287,17 @@ krb5_mk_safe(
}
krb5_xfree(replay.client);
}
-
+ /* Solaris Kerberos */
KRB5_LOG0(KRB5_INFO, "krb5_mk_safe() end");
return 0;
error:
if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) ||
- (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE))
+ (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE))
auth_context->local_seq_number--;
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_mk_safe() end error retval=%d", retval);
return retval;
}
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/pr_to_salt.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/pr_to_salt.c
index b476817ff6..4aadba6cbb 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/pr_to_salt.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/pr_to_salt.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/pr_to_salt.c
*
@@ -28,7 +27,7 @@
* krb5_principal2salt()
*/
-#include <k5-int.h>
+#include "k5-int.h"
static krb5_error_code krb5_principal2salt_internal
(krb5_context, krb5_const_principal, krb5_data *ret, int);
@@ -40,7 +39,7 @@ static krb5_error_code krb5_principal2salt_internal
static krb5_error_code
krb5_principal2salt_internal(krb5_context context, register krb5_const_principal pr, krb5_data *ret, int use_realm)
{
- unsigned int size = 0, offset = 0;
+ unsigned int size = 0, offset=0;
krb5_int32 nelem;
register int i;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/preauth.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/preauth.c
new file mode 100644
index 0000000000..0e7c279e14
--- /dev/null
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/preauth.c
@@ -0,0 +1,581 @@
+/*
+ * Copyright 1995 by the Massachusetts Institute of Technology. All
+ * Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. 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.
+ *
+ */
+
+/*
+ * This file contains routines for establishing, verifying, and any other
+ * necessary functions, for utilizing the pre-authentication field of the
+ * kerberos kdc request, with various hardware/software verification devices.
+ */
+
+#include "k5-int.h"
+#include <stdio.h>
+#include <time.h>
+
+static krb5_error_code obtain_enc_ts_padata
+ (krb5_context,
+ krb5_pa_data *,
+ krb5_etype_info,
+ krb5_keyblock *,
+ krb5_error_code ( * )(krb5_context,
+ const krb5_enctype,
+ krb5_data *,
+ krb5_const_pointer,
+ krb5_keyblock **),
+ krb5_const_pointer,
+ krb5_creds *,
+ krb5_kdc_req *,
+ krb5_pa_data **);
+
+static krb5_error_code process_pw_salt
+ (krb5_context,
+ krb5_pa_data *,
+ krb5_kdc_req *,
+ krb5_kdc_rep *,
+ krb5_error_code ( * )(krb5_context,
+ const krb5_enctype,
+ krb5_data *,
+ krb5_const_pointer,
+ krb5_keyblock **),
+ krb5_const_pointer,
+ krb5_error_code ( * )(krb5_context,
+ const krb5_keyblock *,
+ krb5_const_pointer,
+ krb5_kdc_rep * ),
+ krb5_keyblock **,
+ krb5_creds *,
+ krb5_int32 *,
+ krb5_int32 *);
+
+static krb5_error_code obtain_sam_padata
+ (krb5_context,
+ krb5_pa_data *,
+ krb5_etype_info,
+ krb5_keyblock *,
+ krb5_error_code ( * )(krb5_context,
+ const krb5_enctype,
+ krb5_data *,
+ krb5_const_pointer,
+ krb5_keyblock **),
+ krb5_const_pointer,
+ krb5_creds *,
+ krb5_kdc_req *,
+ krb5_pa_data **);
+
+static const krb5_preauth_ops preauth_systems[] = {
+ {
+ KV5M_PREAUTH_OPS,
+ KRB5_PADATA_ENC_TIMESTAMP,
+ 0,
+ obtain_enc_ts_padata,
+ 0,
+ },
+ {
+ KV5M_PREAUTH_OPS,
+ KRB5_PADATA_PW_SALT,
+ 0,
+ 0,
+ process_pw_salt,
+ },
+ {
+ KV5M_PREAUTH_OPS,
+ KRB5_PADATA_AFS3_SALT,
+ 0,
+ 0,
+ process_pw_salt,
+ },
+ {
+ KV5M_PREAUTH_OPS,
+ KRB5_PADATA_SAM_CHALLENGE,
+ 0,
+ obtain_sam_padata,
+ 0,
+ },
+ { KV5M_PREAUTH_OPS, -1 }
+};
+
+static krb5_error_code find_pa_system
+ (krb5_preauthtype type, const krb5_preauth_ops **Preauth_proc);
+
+/* some typedef's for the function args to make things look a bit cleaner */
+
+typedef krb5_error_code (*git_key_proc) (krb5_context,
+ const krb5_enctype,
+ krb5_data *,
+ krb5_const_pointer,
+ krb5_keyblock **);
+
+typedef krb5_error_code (*git_decrypt_proc) (krb5_context,
+ const krb5_keyblock *,
+ krb5_const_pointer,
+ krb5_kdc_rep *);
+
+krb5_error_code krb5_obtain_padata(krb5_context context, krb5_pa_data **preauth_to_use, git_key_proc key_proc, krb5_const_pointer key_seed, krb5_creds *creds, krb5_kdc_req *request)
+{
+ krb5_error_code retval;
+ krb5_etype_info etype_info = 0;
+ krb5_pa_data ** pa;
+ krb5_pa_data ** send_pa_list;
+ krb5_pa_data ** send_pa;
+ const krb5_preauth_ops *ops;
+ krb5_keyblock * def_enc_key = 0;
+ krb5_enctype enctype;
+ krb5_data salt;
+ krb5_data scratch;
+ int size;
+ int f_salt = 0;
+
+ if (preauth_to_use == NULL)
+ return 0;
+
+ for (pa = preauth_to_use, size=0; *pa; pa++, size++) {
+ if ((*pa)->pa_type == KRB5_PADATA_ETYPE_INFO) {
+ /* XXX use the first one. Is there another way to disambiguate? */
+ if (etype_info)
+ continue;
+
+ scratch.length = (*pa)->length;
+ scratch.data = (char *) (*pa)->contents;
+ retval = decode_krb5_etype_info(&scratch, &etype_info);
+ if (retval)
+ return retval;
+ if (etype_info[0] == NULL) {
+ krb5_free_etype_info(context, etype_info);
+ etype_info = NULL;
+ }
+ }
+ }
+
+ if ((send_pa_list = malloc((size+1) * sizeof(krb5_pa_data *))) == NULL)
+ return ENOMEM;
+
+ send_pa = send_pa_list;
+ *send_pa = 0;
+
+ enctype = request->ktype[0];
+ salt.data = 0;
+ salt.length = SALT_TYPE_NO_LENGTH;
+ if (etype_info) {
+ enctype = etype_info[0]->etype;
+ salt.data = (char *) etype_info[0]->salt;
+ if(etype_info[0]->length == KRB5_ETYPE_NO_SALT)
+ salt.length = SALT_TYPE_NO_LENGTH; /* XXX */
+ else
+ salt.length = etype_info[0]->length;
+ }
+ if (salt.length == SALT_TYPE_NO_LENGTH) {
+ /*
+ * This will set the salt length
+ */
+ if ((retval = krb5_principal2salt(context, request->client, &salt)))
+ return(retval);
+ f_salt = 1;
+ }
+
+ if ((retval = (*key_proc)(context, enctype, &salt, key_seed,
+ &def_enc_key)))
+ goto cleanup;
+
+
+ for (pa = preauth_to_use; *pa; pa++) {
+ if (find_pa_system((*pa)->pa_type, &ops))
+ continue;
+
+ if (ops->obtain == 0)
+ continue;
+
+ retval = ((ops)->obtain)(context, *pa, etype_info, def_enc_key,
+ key_proc, key_seed, creds,
+ request, send_pa);
+ if (retval)
+ goto cleanup;
+
+ if (*send_pa)
+ send_pa++;
+ *send_pa = 0;
+ }
+
+ retval = 0;
+
+ if (send_pa_list[0]) {
+ request->padata = send_pa_list;
+ send_pa_list = 0;
+ }
+
+cleanup:
+ if (etype_info)
+ krb5_free_etype_info(context, etype_info);
+ if (f_salt)
+ krb5_xfree(salt.data);
+ if (send_pa_list)
+ krb5_free_pa_data(context, send_pa_list);
+ if (def_enc_key)
+ krb5_free_keyblock(context, def_enc_key);
+ return retval;
+
+}
+
+krb5_error_code
+krb5_process_padata(krb5_context context, krb5_kdc_req *request, krb5_kdc_rep *as_reply, git_key_proc key_proc, krb5_const_pointer keyseed, git_decrypt_proc decrypt_proc, krb5_keyblock **decrypt_key, krb5_creds *creds, krb5_int32 *do_more)
+{
+ krb5_error_code retval = 0;
+ const krb5_preauth_ops * ops;
+ krb5_pa_data ** pa;
+ krb5_int32 done = 0;
+
+ *do_more = 0; /* By default, we don't need to repeat... */
+ if (as_reply->padata == 0)
+ return 0;
+
+ for (pa = as_reply->padata; *pa; pa++) {
+ if (find_pa_system((*pa)->pa_type, &ops))
+ continue;
+
+ if (ops->process == 0)
+ continue;
+
+ retval = ((ops)->process)(context, *pa, request, as_reply,
+ key_proc, keyseed, decrypt_proc,
+ decrypt_key, creds, do_more, &done);
+ if (retval)
+ goto cleanup;
+ if (done)
+ break;
+ }
+
+cleanup:
+ return retval;
+}
+
+/*
+ * This routine is the "obtain" function for the ENC_TIMESTAMP
+ * preauthentication type. It take the current time and encrypts it
+ * in the user's key.
+ */
+static krb5_error_code
+obtain_enc_ts_padata(krb5_context context, krb5_pa_data *in_padata, krb5_etype_info etype_info, krb5_keyblock *def_enc_key, git_key_proc key_proc, krb5_const_pointer key_seed, krb5_creds *creds, krb5_kdc_req *request, krb5_pa_data **out_padata)
+{
+ krb5_pa_enc_ts pa_enc;
+ krb5_error_code retval;
+ krb5_data * scratch;
+ krb5_enc_data enc_data;
+ krb5_pa_data * pa;
+
+ retval = krb5_us_timeofday(context, &pa_enc.patimestamp, &pa_enc.pausec);
+ if (retval)
+ return retval;
+
+ if ((retval = encode_krb5_pa_enc_ts(&pa_enc, &scratch)) != 0)
+ return retval;
+
+ enc_data.ciphertext.data = 0;
+
+ if ((retval = krb5_encrypt_helper(context, def_enc_key,
+ KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS,
+ scratch, &enc_data)))
+ goto cleanup;
+
+ krb5_free_data(context, scratch);
+ scratch = 0;
+
+ if ((retval = encode_krb5_enc_data(&enc_data, &scratch)) != 0)
+ goto cleanup;
+
+ if ((pa = malloc(sizeof(krb5_pa_data))) == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+
+ pa->magic = KV5M_PA_DATA;
+ pa->pa_type = KRB5_PADATA_ENC_TIMESTAMP;
+ pa->length = scratch->length;
+ pa->contents = (krb5_octet *) scratch->data;
+
+ *out_padata = pa;
+
+ krb5_xfree(scratch);
+ scratch = 0;
+
+ retval = 0;
+
+cleanup:
+ if (scratch)
+ krb5_free_data(context, scratch);
+ if (enc_data.ciphertext.data)
+ krb5_xfree(enc_data.ciphertext.data);
+ return retval;
+}
+
+static krb5_error_code
+process_pw_salt(krb5_context context, krb5_pa_data *padata, krb5_kdc_req *request, krb5_kdc_rep *as_reply, git_key_proc key_proc, krb5_const_pointer keyseed, git_decrypt_proc decrypt_proc, krb5_keyblock **decrypt_key, krb5_creds *creds, krb5_int32 *do_more, krb5_int32 *done)
+{
+ krb5_error_code retval;
+ krb5_data salt;
+
+ if (*decrypt_key != 0)
+ return 0;
+
+ salt.data = (char *) padata->contents;
+ salt.length =
+ (padata->pa_type == KRB5_PADATA_AFS3_SALT)?(SALT_TYPE_AFS_LENGTH):(padata->length);
+
+ if ((retval = (*key_proc)(context, as_reply->enc_part.enctype,
+ &salt, keyseed, decrypt_key))) {
+ *decrypt_key = 0;
+ return retval;
+ }
+
+ return 0;
+}
+
+static krb5_error_code
+find_pa_system(krb5_preauthtype type, const krb5_preauth_ops **preauth)
+{
+ const krb5_preauth_ops *ap = preauth_systems;
+
+ while ((ap->type != -1) && (ap->type != type))
+ ap++;
+ if (ap->type == -1)
+ return(KRB5_PREAUTH_BAD_TYPE);
+ *preauth = ap;
+ return 0;
+}
+
+
+extern const char *krb5_default_pwd_prompt1;
+
+static krb5_error_code
+sam_get_pass_from_user(krb5_context context, krb5_etype_info etype_info, git_key_proc key_proc, krb5_const_pointer key_seed, krb5_kdc_req *request, krb5_keyblock **new_enc_key, const char *prompt)
+{
+ krb5_enctype enctype;
+ krb5_error_code retval;
+ const char *oldprompt;
+
+ /* enctype = request->ktype[0]; */
+ enctype = ENCTYPE_DES_CBC_MD5;
+/* hack with this first! */
+ oldprompt = krb5_default_pwd_prompt1;
+ krb5_default_pwd_prompt1 = prompt;
+ {
+ krb5_data newpw;
+ newpw.data = 0; newpw.length = 0;
+ /* we don't keep the new password, just the key... */
+ retval = (*key_proc)(context, enctype, 0,
+ (krb5_const_pointer)&newpw, new_enc_key);
+ krb5_xfree(newpw.data);
+ }
+ krb5_default_pwd_prompt1 = oldprompt;
+ return retval;
+}
+static
+char *handle_sam_labels(krb5_sam_challenge *sc)
+{
+ char *label = sc->sam_challenge_label.data;
+ unsigned int label_len = sc->sam_challenge_label.length;
+ char *prompt = sc->sam_response_prompt.data;
+ unsigned int prompt_len = sc->sam_response_prompt.length;
+ char *challenge = sc->sam_challenge.data;
+ unsigned int challenge_len = sc->sam_challenge.length;
+ char *prompt1, *p;
+ char *sep1 = ": [";
+ char *sep2 = "]\n";
+ char *sep3 = ": ";
+
+ if (sc->sam_cksum.length == 0) {
+ /* or invalid -- but lets just handle presence now XXX */
+ switch (sc->sam_type) {
+ case PA_SAM_TYPE_ENIGMA: /* Enigma Logic */
+ label = "Challenge for Enigma Logic mechanism";
+ break;
+ case PA_SAM_TYPE_DIGI_PATH: /* Digital Pathways */
+ case PA_SAM_TYPE_DIGI_PATH_HEX: /* Digital Pathways */
+ label = "Challenge for Digital Pathways mechanism";
+ break;
+ case PA_SAM_TYPE_ACTIVCARD_DEC: /* Digital Pathways */
+ case PA_SAM_TYPE_ACTIVCARD_HEX: /* Digital Pathways */
+ label = "Challenge for Activcard mechanism";
+ break;
+ case PA_SAM_TYPE_SKEY_K0: /* S/key where KDC has key 0 */
+ label = "Challenge for Enhanced S/Key mechanism";
+ break;
+ case PA_SAM_TYPE_SKEY: /* Traditional S/Key */
+ label = "Challenge for Traditional S/Key mechanism";
+ break;
+ case PA_SAM_TYPE_SECURID: /* Security Dynamics */
+ label = "Challenge for Security Dynamics mechanism";
+ break;
+ case PA_SAM_TYPE_SECURID_PREDICT: /* predictive Security Dynamics */
+ label = "Challenge for Security Dynamics mechanism";
+ break;
+ }
+ prompt = "Passcode";
+ label_len = strlen(label);
+ prompt_len = strlen(prompt);
+ }
+
+ /* example:
+ Challenge for Digital Pathways mechanism: [134591]
+ Passcode:
+ */
+ p = prompt1 = malloc(label_len + strlen(sep1) +
+ challenge_len + strlen(sep2) +
+ prompt_len+ strlen(sep3) + 1);
+ if (p == NULL)
+ return NULL;
+ if (challenge_len) {
+ strncpy(p, label, label_len); p += label_len;
+ strcpy(p, sep1); p += strlen(sep1);
+ strncpy(p, challenge, challenge_len); p += challenge_len;
+ strcpy(p, sep2); p += strlen(sep2);
+ }
+ strncpy(p, prompt, prompt_len); p += prompt_len;
+ strcpy(p, sep3); /* p += strlen(sep3); */
+ return prompt1;
+}
+
+/*
+ * This routine is the "obtain" function for the SAM_CHALLENGE
+ * preauthentication type. It presents the challenge...
+ */
+static krb5_error_code
+obtain_sam_padata(krb5_context context, krb5_pa_data *in_padata, krb5_etype_info etype_info, krb5_keyblock *def_enc_key, git_key_proc key_proc, krb5_const_pointer key_seed, krb5_creds *creds, krb5_kdc_req *request, krb5_pa_data **out_padata)
+{
+ krb5_error_code retval;
+ krb5_data * scratch;
+ krb5_data tmpsam;
+ krb5_pa_data * pa;
+ krb5_sam_challenge *sam_challenge = 0;
+ krb5_sam_response sam_response;
+ /* these two get encrypted and stuffed in to sam_response */
+ krb5_enc_sam_response_enc enc_sam_response_enc;
+ krb5_keyblock * sam_use_key = 0;
+ char * prompt;
+
+ tmpsam.length = in_padata->length;
+ tmpsam.data = (char *) in_padata->contents;
+ retval = decode_krb5_sam_challenge(&tmpsam, &sam_challenge);
+ if (retval)
+ return retval;
+
+ if (sam_challenge->sam_flags & KRB5_SAM_MUST_PK_ENCRYPT_SAD) {
+ return KRB5_SAM_UNSUPPORTED;
+ }
+
+ enc_sam_response_enc.sam_nonce = sam_challenge->sam_nonce;
+ if (!sam_challenge->sam_nonce) {
+ retval = krb5_us_timeofday(context,
+ &enc_sam_response_enc.sam_timestamp,
+ &enc_sam_response_enc.sam_usec);
+ sam_response.sam_patimestamp = enc_sam_response_enc.sam_timestamp;
+ }
+ if (retval)
+ return retval;
+ if (sam_challenge->sam_flags & KRB5_SAM_SEND_ENCRYPTED_SAD) {
+ /* encrypt passcode in key by stuffing it here */
+ unsigned int pcsize = 256;
+ char *passcode = malloc(pcsize+1);
+ if (passcode == NULL)
+ return ENOMEM;
+ prompt = handle_sam_labels(sam_challenge);
+ if (prompt == NULL) {
+ free(passcode);
+ return ENOMEM;
+ }
+ retval = krb5_read_password(context, prompt, 0, passcode, &pcsize);
+ free(prompt);
+
+ if (retval) {
+ free(passcode);
+ return retval;
+ }
+ enc_sam_response_enc.sam_sad.data = passcode;
+ enc_sam_response_enc.sam_sad.length = pcsize;
+ } else if (sam_challenge->sam_flags & KRB5_SAM_USE_SAD_AS_KEY) {
+ prompt = handle_sam_labels(sam_challenge);
+ if (prompt == NULL)
+ return ENOMEM;
+ retval = sam_get_pass_from_user(context, etype_info, key_proc,
+ key_seed, request, &sam_use_key,
+ prompt);
+ free(prompt);
+ if (retval)
+ return retval;
+ enc_sam_response_enc.sam_sad.length = 0;
+ } else {
+ /* what *was* it? */
+ return KRB5_SAM_UNSUPPORTED;
+ }
+
+ /* so at this point, either sam_use_key is generated from the passcode
+ * or enc_sam_response_enc.sam_sad is set to it, and we use
+ * def_enc_key instead. */
+ /* encode the encoded part of the response */
+ if ((retval = encode_krb5_enc_sam_response_enc(&enc_sam_response_enc,
+ &scratch)) != 0)
+ return retval;
+
+ if ((retval = krb5_encrypt_data(context,
+ sam_use_key?sam_use_key:def_enc_key,
+ 0, scratch,
+ &sam_response.sam_enc_nonce_or_ts)))
+ goto cleanup;
+
+ krb5_free_data(context, scratch);
+ scratch = 0;
+
+ /* sam_enc_key is reserved for future use */
+ sam_response.sam_enc_key.ciphertext.length = 0;
+
+ /* copy things from the challenge */
+ sam_response.sam_nonce = sam_challenge->sam_nonce;
+ sam_response.sam_flags = sam_challenge->sam_flags;
+ sam_response.sam_track_id = sam_challenge->sam_track_id;
+ sam_response.sam_type = sam_challenge->sam_type;
+ sam_response.magic = KV5M_SAM_RESPONSE;
+
+ if ((retval = encode_krb5_sam_response(&sam_response, &scratch)) != 0)
+ return retval;
+
+ if ((pa = malloc(sizeof(krb5_pa_data))) == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+
+ pa->magic = KV5M_PA_DATA;
+ pa->pa_type = KRB5_PADATA_SAM_RESPONSE;
+ pa->length = scratch->length;
+ pa->contents = (krb5_octet *) scratch->data;
+ scratch = 0; /* so we don't free it! */
+
+ *out_padata = pa;
+
+ retval = 0;
+
+cleanup:
+ if (scratch)
+ krb5_free_data(context, scratch);
+ if (sam_challenge)
+ krb5_xfree(sam_challenge);
+ return retval;
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/preauth2.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/preauth2.c
index f1e2794d44..033ae15cc5 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/preauth2.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/preauth2.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1995, 2003 by the Massachusetts Institute of Technology. All
@@ -36,14 +35,27 @@
* kerberos kdc request, with various hardware/software verification devices.
*/
-#include <k5-int.h>
+#include "k5-int.h"
+#include "osconf.h"
+#include <preauth_plugin.h>
+#include "int-proto.h"
+
+#if !defined(_WIN32)
+#include <unistd.h>
+#endif
+
+#if TARGET_OS_MAC
+static const char *objdirs[] = { KRB5_PLUGIN_BUNDLE_DIR, LIBDIR "/krb5/plugins/preauth", NULL }; /* should be a list */
+#else
+/* Solaris Kerberos */
+static const char *objdirs[] = { LIBDIR "/krb5/plugins/preauth", NULL };
+#endif
typedef krb5_error_code (*pa_function)(krb5_context,
krb5_kdc_req *request,
krb5_pa_data *in_padata,
krb5_pa_data **out_padata,
- krb5_data *salt,
- krb5_data *s2kparams,
+ krb5_data *salt, krb5_data *s2kparams,
krb5_enctype *etype,
krb5_keyblock *as_key,
krb5_prompter_fct prompter_fct,
@@ -57,17 +69,528 @@ typedef struct _pa_types_t {
int flags;
} pa_types_t;
-#define PA_REAL 0x0001
-#define PA_INFO 0x0002
+/* Create the per-krb5_context context. This means loading the modules
+ * if we haven't done that yet (applications which never obtain initial
+ * credentials should never hit this routine), breaking up the module's
+ * list of support pa_types so that we can iterate over the modules more
+ * easily, and copying over the relevant parts of the module's table. */
+void KRB5_CALLCONV
+krb5_init_preauth_context(krb5_context kcontext)
+{
+ int n_modules, n_tables, i, j, k;
+ void **tables;
+ struct krb5plugin_preauth_client_ftable_v1 *table;
+ krb5_preauth_context *context = NULL;
+ void *plugin_context;
+ krb5_preauthtype pa_type;
+ void **rcpp;
+
+ /* Only do this once for each krb5_context */
+ if (kcontext->preauth_context != NULL)
+ return;
+
+ /* load the plugins for the current context */
+ if (PLUGIN_DIR_OPEN(&kcontext->preauth_plugins) == 0) {
+ if (krb5int_open_plugin_dirs(objdirs, NULL,
+ &kcontext->preauth_plugins,
+ &kcontext->err) != 0) {
+ return;
+ }
+ }
+
+ /* pull out the module function tables for all of the modules */
+ tables = NULL;
+ if (krb5int_get_plugin_dir_data(&kcontext->preauth_plugins,
+ "preauthentication_client_1",
+ &tables,
+ &kcontext->err) != 0) {
+ return;
+ }
+ if (tables == NULL) {
+ return;
+ }
+
+ /* count how many modules we ended up loading, and how many preauth
+ * types we may claim to support as a result */
+ n_modules = 0;
+ for (n_tables = 0;
+ (tables != NULL) && (tables[n_tables] != NULL);
+ n_tables++) {
+ table = tables[n_tables];
+ if ((table->pa_type_list != NULL) && (table->process != NULL)) {
+ for (j = 0; table->pa_type_list[j] > 0; j++) {
+ n_modules++;
+ }
+ }
+ }
+
+ /* allocate the space we need */
+ context = malloc(sizeof(*context));
+ if (context == NULL) {
+ krb5int_free_plugin_dir_data(tables);
+ return;
+ }
+ context->modules = malloc(sizeof(context->modules[0]) * n_modules);
+ if (context->modules == NULL) {
+ krb5int_free_plugin_dir_data(tables);
+ free(context);
+ return;
+ }
+ memset(context->modules, 0, sizeof(context->modules[0]) * n_modules);
+ context->n_modules = n_modules;
+
+ /* fill in the structure */
+ k = 0;
+ for (i = 0; i < n_tables; i++) {
+ table = tables[i];
+ if ((table->pa_type_list != NULL) && (table->process != NULL)) {
+ plugin_context = NULL;
+ if ((table->init != NULL) &&
+ ((*table->init)(kcontext, &plugin_context) != 0)) {
+#ifdef DEBUG
+ fprintf (stderr, "init err, skipping module \"%s\"\n",
+ table->name);
+#endif
+ continue;
+ }
+
+ rcpp = NULL;
+ for (j = 0; table->pa_type_list[j] > 0; j++) {
+ pa_type = table->pa_type_list[j];
+ context->modules[k].pa_type = pa_type;
+ context->modules[k].enctypes = table->enctype_list;
+ context->modules[k].plugin_context = plugin_context;
+ /* Only call client_fini once per plugin */
+ if (j == 0)
+ context->modules[k].client_fini = table->fini;
+ else
+ context->modules[k].client_fini = NULL;
+ context->modules[k].ftable = table;
+ context->modules[k].name = table->name;
+ context->modules[k].flags = (*table->flags)(kcontext, pa_type);
+ context->modules[k].use_count = 0;
+ context->modules[k].client_process = table->process;
+ context->modules[k].client_tryagain = table->tryagain;
+ if (j == 0)
+ context->modules[k].client_supply_gic_opts = table->gic_opts;
+ else
+ context->modules[k].client_supply_gic_opts = NULL;
+ context->modules[k].request_context = NULL;
+ /*
+ * Only call request_init and request_fini once per plugin.
+ * Only the first module within each plugin will ever
+ * have request_context filled in. Every module within
+ * the plugin will have its request_context_pp pointing
+ * to that entry's request_context. That way all the
+ * modules within the plugin share the same request_context
+ */
+ if (j == 0) {
+ context->modules[k].client_req_init = table->request_init;
+ context->modules[k].client_req_fini = table->request_fini;
+ rcpp = &context->modules[k].request_context;
+ } else {
+ context->modules[k].client_req_init = NULL;
+ context->modules[k].client_req_fini = NULL;
+ }
+ context->modules[k].request_context_pp = rcpp;
+#ifdef DEBUG
+ fprintf (stderr, "init module \"%s\", pa_type %d, flag %d\n",
+ context->modules[k].name,
+ context->modules[k].pa_type,
+ context->modules[k].flags);
+#endif
+ k++;
+ }
+ }
+ }
+ krb5int_free_plugin_dir_data(tables);
+
+ /* return the result */
+ kcontext->preauth_context = context;
+}
+
+/* Zero the use counts for the modules herein. Usually used before we
+ * start processing any data from the server, at which point every module
+ * will again be able to take a crack at whatever the server sent. */
+void KRB5_CALLCONV
+krb5_clear_preauth_context_use_counts(krb5_context context)
+{
+ int i;
+ if (context->preauth_context != NULL) {
+ for (i = 0; i < context->preauth_context->n_modules; i++) {
+ context->preauth_context->modules[i].use_count = 0;
+ }
+ }
+}
+
+/*
+ * Give all the preauth plugins a look at the preauth option which
+ * has just been set
+ */
+krb5_error_code
+krb5_preauth_supply_preauth_data(krb5_context context,
+ krb5_gic_opt_ext *opte,
+ const char *attr,
+ const char *value)
+{
+ krb5_error_code retval;
+ int i;
+ void *pctx;
+ const char *emsg = NULL;
+
+ if (context->preauth_context == NULL)
+ krb5_init_preauth_context(context);
+ if (context->preauth_context == NULL) {
+ retval = EINVAL;
+ krb5int_set_error(&context->err, retval,
+ "krb5_preauth_supply_preauth_data: "
+ "Unable to initialize preauth context");
+ return retval;
+ }
+
+ /*
+ * Go down the list of preauth modules, and supply them with the
+ * attribute/value pair.
+ */
+ for (i = 0; i < context->preauth_context->n_modules; i++) {
+ if (context->preauth_context->modules[i].client_supply_gic_opts == NULL)
+ continue;
+ pctx = context->preauth_context->modules[i].plugin_context;
+ retval = (*context->preauth_context->modules[i].client_supply_gic_opts)
+ (context, pctx,
+ (krb5_get_init_creds_opt *)opte, attr, value);
+ if (retval) {
+ emsg = krb5_get_error_message(context, retval);
+ krb5int_set_error(&context->err, retval, "Preauth plugin %s: %s",
+ context->preauth_context->modules[i].name, emsg);
+ break;
+ }
+ }
+ return retval;
+}
+
+/* Free the per-krb5_context preauth_context. This means clearing any
+ * plugin-specific context which may have been created, and then
+ * freeing the context itself. */
+void KRB5_CALLCONV
+krb5_free_preauth_context(krb5_context context)
+{
+ int i;
+ void *pctx;
+ if (context->preauth_context != NULL) {
+ for (i = 0; i < context->preauth_context->n_modules; i++) {
+ pctx = context->preauth_context->modules[i].plugin_context;
+ if (context->preauth_context->modules[i].client_fini != NULL) {
+ (*context->preauth_context->modules[i].client_fini)(context, pctx);
+ }
+ memset(&context->preauth_context->modules[i], 0,
+ sizeof(context->preauth_context->modules[i]));
+ }
+ if (context->preauth_context->modules != NULL) {
+ free(context->preauth_context->modules);
+ context->preauth_context->modules = NULL;
+ }
+ free(context->preauth_context);
+ context->preauth_context = NULL;
+ }
+}
+
+/* Initialize the per-AS-REQ context. This means calling the client_req_init
+ * function to give the plugin a chance to allocate a per-request context. */
+void KRB5_CALLCONV
+krb5_preauth_request_context_init(krb5_context context)
+{
+ int i;
+ void *rctx, *pctx;
+
+ /* Limit this to only one attempt per context? */
+ if (context->preauth_context == NULL)
+ krb5_init_preauth_context(context);
+ if (context->preauth_context != NULL) {
+ for (i = 0; i < context->preauth_context->n_modules; i++) {
+ pctx = context->preauth_context->modules[i].plugin_context;
+ if (context->preauth_context->modules[i].client_req_init != NULL) {
+ rctx = context->preauth_context->modules[i].request_context_pp;
+ (*context->preauth_context->modules[i].client_req_init) (context, pctx, rctx);
+ }
+ }
+ }
+}
+
+/* Free the per-AS-REQ context. This means clearing any request-specific
+ * context which the plugin may have created. */
+void KRB5_CALLCONV
+krb5_preauth_request_context_fini(krb5_context context)
+{
+ int i;
+ void *rctx, *pctx;
+ if (context->preauth_context != NULL) {
+ for (i = 0; i < context->preauth_context->n_modules; i++) {
+ pctx = context->preauth_context->modules[i].plugin_context;
+ rctx = context->preauth_context->modules[i].request_context;
+ if (rctx != NULL) {
+ if (context->preauth_context->modules[i].client_req_fini != NULL) {
+ (*context->preauth_context->modules[i].client_req_fini)(context, pctx, rctx);
+ }
+ context->preauth_context->modules[i].request_context = NULL;
+ }
+ }
+ }
+}
+
+/* Add the named encryption type to the existing list of ktypes. */
+static void
+grow_ktypes(krb5_enctype **out_ktypes, int *out_nktypes, krb5_enctype ktype)
+{
+ int i;
+ krb5_enctype *ktypes;
+ for (i = 0; i < *out_nktypes; i++) {
+ if ((*out_ktypes)[i] == ktype)
+ return;
+ }
+ ktypes = malloc((*out_nktypes + 2) * sizeof(ktype));
+ if (ktypes) {
+ for (i = 0; i < *out_nktypes; i++)
+ ktypes[i] = (*out_ktypes)[i];
+ ktypes[i++] = ktype;
+ ktypes[i] = 0;
+ free(*out_ktypes);
+ *out_ktypes = ktypes;
+ *out_nktypes = i;
+ }
+}
+
+/*
+ * Add the given list of pa_data items to the existing list of items.
+ * Factored out here to make reading the do_preauth logic easier to read.
+ */
+static int
+grow_pa_list(krb5_pa_data ***out_pa_list, int *out_pa_list_size,
+ krb5_pa_data **addition, int num_addition)
+{
+ krb5_pa_data **pa_list;
+ int i, j;
+
+ if (out_pa_list == NULL || addition == NULL) {
+ return EINVAL;
+ }
+
+ if (*out_pa_list == NULL) {
+ /* Allocate room for the new additions and a NULL terminator. */
+ pa_list = malloc((num_addition + 1) * sizeof(krb5_pa_data *));
+ if (pa_list == NULL)
+ return ENOMEM;
+ for (i = 0; i < num_addition; i++)
+ pa_list[i] = addition[i];
+ pa_list[i] = NULL;
+ *out_pa_list = pa_list;
+ *out_pa_list_size = num_addition;
+ } else {
+ /*
+ * Allocate room for the existing entries plus
+ * the new additions and a NULL terminator.
+ */
+ pa_list = malloc((*out_pa_list_size + num_addition + 1)
+ * sizeof(krb5_pa_data *));
+ if (pa_list == NULL)
+ return ENOMEM;
+ for (i = 0; i < *out_pa_list_size; i++)
+ pa_list[i] = (*out_pa_list)[i];
+ for (j = 0; j < num_addition;)
+ pa_list[i++] = addition[j++];
+ pa_list[i] = NULL;
+ free(*out_pa_list);
+ *out_pa_list = pa_list;
+ *out_pa_list_size = i;
+ }
+ return 0;
+}
+
+/*
+ * Retrieve a specific piece of information required by the plugin and
+ * return it in a new krb5_data item. There are separate request_types
+ * to obtain the data and free it.
+ *
+ * This may require massaging data into a contrived format, but it will
+ * hopefully keep us from having to reveal library-internal functions
+ * or data to the plugin modules.
+ */
+
+static krb5_error_code
+client_data_proc(krb5_context kcontext,
+ krb5_preauth_client_rock *rock,
+ krb5_int32 request_type,
+ krb5_data **retdata)
+{
+ krb5_data *ret;
+ char *data;
+
+ if (rock->magic != CLIENT_ROCK_MAGIC)
+ return EINVAL;
+ if (retdata == NULL)
+ return EINVAL;
+
+ switch (request_type) {
+ case krb5plugin_preauth_client_get_etype:
+ {
+ krb5_enctype *eptr;
+ if (rock->as_reply == NULL)
+ return ENOENT;
+ ret = malloc(sizeof(krb5_data));
+ if (ret == NULL)
+ return ENOMEM;
+ data = malloc(sizeof(krb5_enctype));
+ if (data == NULL) {
+ free(ret);
+ return ENOMEM;
+ }
+ ret->data = data;
+ ret->length = sizeof(krb5_enctype);
+ eptr = (krb5_enctype *)data;
+ *eptr = rock->as_reply->enc_part.enctype;
+ *retdata = ret;
+ return 0;
+ }
+ break;
+ case krb5plugin_preauth_client_free_etype:
+ ret = *retdata;
+ if (ret == NULL)
+ return 0;
+ if (ret->data)
+ free(ret->data);
+ free(ret);
+ return 0;
+ break;
+ default:
+ return EINVAL;
+ }
+}
+
+/* Tweak the request body, for now adding any enctypes which the module claims
+ * to add support for to the list, but in the future perhaps doing more
+ * involved things. */
+void KRB5_CALLCONV
+krb5_preauth_prepare_request(krb5_context kcontext,
+ krb5_gic_opt_ext *opte,
+ krb5_kdc_req *request)
+{
+ int i, j;
+
+ if (kcontext->preauth_context == NULL) {
+ return;
+ }
+ /* Add the module-specific enctype list to the request, but only if
+ * it's something we can safely modify. */
+ if (!(opte && (opte->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST))) {
+ for (i = 0; i < kcontext->preauth_context->n_modules; i++) {
+ if (kcontext->preauth_context->modules[i].enctypes == NULL)
+ continue;
+ for (j = 0; kcontext->preauth_context->modules[i].enctypes[j] != 0; j++) {
+ grow_ktypes(&request->ktype, &request->nktypes,
+ kcontext->preauth_context->modules[i].enctypes[j]);
+ }
+ }
+ }
+}
+
+/* Find the first module which provides for the named preauth type which also
+ * hasn't had a chance to run yet (INFO modules don't count, because as a rule
+ * they don't generate preauth data), and run it. */
+static krb5_error_code
+krb5_run_preauth_plugins(krb5_context kcontext,
+ int module_required_flags,
+ krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data *in_padata,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ preauth_get_as_key_proc gak_fct,
+ krb5_data *salt,
+ krb5_data *s2kparams,
+ void *gak_data,
+ krb5_preauth_client_rock *get_data_rock,
+ krb5_keyblock *as_key,
+ krb5_pa_data ***out_pa_list,
+ int *out_pa_list_size,
+ int *module_ret,
+ int *module_flags,
+ krb5_gic_opt_ext *opte)
+{
+ int i;
+ krb5_pa_data **out_pa_data;
+ krb5_error_code ret;
+ struct _krb5_preauth_context_module *module;
+
+ if (kcontext->preauth_context == NULL) {
+ return ENOENT;
+ }
+ /* iterate over all loaded modules */
+ for (i = 0; i < kcontext->preauth_context->n_modules; i++) {
+ module = &kcontext->preauth_context->modules[i];
+ /* skip over those which don't match the preauth type */
+ if (module->pa_type != in_padata->pa_type)
+ continue;
+ /* skip over those which don't match the flags (INFO vs REAL, mainly) */
+ if ((module->flags & module_required_flags) == 0)
+ continue;
+ /* if it's a REAL module, try to call it only once per library call */
+ if (module_required_flags & PA_REAL) {
+ if (module->use_count > 0) {
+#ifdef DEBUG
+ fprintf(stderr, "skipping already-used module \"%s\"(%d)\n",
+ module->name, module->pa_type);
+#endif
+ continue;
+ }
+ module->use_count++;
+ }
+ /* run the module's callback function */
+ out_pa_data = NULL;
+#ifdef DEBUG
+ fprintf(stderr, "using module \"%s\" (%d), flags = %d\n",
+ module->name, module->pa_type, module->flags);
+#endif
+ ret = module->client_process(kcontext,
+ module->plugin_context,
+ *module->request_context_pp,
+ (krb5_get_init_creds_opt *)opte,
+ client_data_proc,
+ get_data_rock,
+ request,
+ encoded_request_body,
+ encoded_previous_request,
+ in_padata,
+ prompter, prompter_data,
+ gak_fct, gak_data, salt, s2kparams,
+ as_key,
+ &out_pa_data);
+ /* Make note of the module's flags and status. */
+ *module_flags = module->flags;
+ *module_ret = ret;
+ /* Save the new preauth data item. */
+ if (out_pa_data != NULL) {
+ int j;
+ for (j = 0; out_pa_data[j] != NULL; j++);
+ ret = grow_pa_list(out_pa_list, out_pa_list_size, out_pa_data, j);
+ free(out_pa_data);
+ if (ret != 0)
+ return ret;
+ }
+ break;
+ }
+ if (i >= kcontext->preauth_context->n_modules) {
+ return ENOENT;
+ }
+ return 0;
+}
-/*ARGSUSED*/
static
krb5_error_code pa_salt(krb5_context context,
krb5_kdc_req *request,
krb5_pa_data *in_padata,
krb5_pa_data **out_padata,
- krb5_data *salt,
- krb5_data *s2kparams,
+ krb5_data *salt, krb5_data *s2kparams,
krb5_enctype *etype,
krb5_keyblock *as_key,
krb5_prompter_fct prompter, void *prompter_data,
@@ -75,13 +598,15 @@ krb5_error_code pa_salt(krb5_context context,
{
krb5_data tmp;
+ /* Solaris Kerberos - resync */
tmp.data = (char *)in_padata->contents;
tmp.length = in_padata->length;
krb5_free_data_contents(context, salt);
krb5int_copy_data_contents(context, &tmp, salt);
+
if (in_padata->pa_type == KRB5_PADATA_AFS3_SALT)
- salt->length = -1;
+ salt->length = SALT_TYPE_AFS_LENGTH;
return(0);
}
@@ -109,19 +634,20 @@ krb5_error_code pa_enc_timestamp(krb5_context context,
if (as_key->length == 0) {
#ifdef DEBUG
+ /* Solaris Kerberos */
if (salt != NULL && salt->data != NULL) {
- fprintf (stderr, "%s:%d: salt len=%d", __FILE__, __LINE__,
+ fprintf (stderr, "%s:%d: salt len=%d", __FILE__, __LINE__,
salt->length);
- if (salt->length > 0)
- fprintf (stderr, " '%*s'", salt->length, salt->data);
+ if ((int) salt->length > 0)
+ fprintf (stderr, " '%.*s'", salt->length, salt->data);
fprintf (stderr, "; *etype=%d request->ktype[0]=%d\n",
*etype, request->ktype[0]);
}
#endif
if ((ret = ((*gak_fct)(context, request->client,
- *etype ? *etype : request->ktype[0],
- prompter, prompter_data,
- salt, s2kparams, as_key, gak_data))))
+ *etype ? *etype : request->ktype[0],
+ prompter, prompter_data,
+ salt, s2kparams, as_key, gak_data))))
return(ret);
}
@@ -258,11 +784,13 @@ krb5_error_code pa_sam(krb5_context context,
krb5_enc_sam_response_enc enc_sam_response_enc;
krb5_data * scratch;
krb5_pa_data * pa;
+
+ /* Solaris Kerberos */
krb5_enc_data * enc_data;
size_t enclen;
if (prompter == NULL)
- return (EIO);
+ return EIO;
tmpsam.length = in_padata->length;
tmpsam.data = (char *) in_padata->contents;
@@ -273,25 +801,25 @@ krb5_error_code pa_sam(krb5_context context,
krb5_xfree(sam_challenge);
return(KRB5_SAM_UNSUPPORTED);
}
+
/* If we need the password from the user (USE_SAD_AS_KEY not set), */
- /* then get it here. Exception for "old" KDCs with CryptoCard */
- /* support which uses the USE_SAD_AS_KEY flag, but still needs pwd */
+ /* then get it here. Exception for "old" KDCs with CryptoCard */
+ /* support which uses the USE_SAD_AS_KEY flag, but still needs pwd */
if (!(sam_challenge->sam_flags & KRB5_SAM_USE_SAD_AS_KEY) ||
(sam_challenge->sam_type == PA_SAM_TYPE_CRYPTOCARD)) {
/* etype has either been set by caller or by KRB5_PADATA_ETYPE_INFO */
/* message from the KDC. If it is not set, pick an enctype that we */
- /* think the KDC will have for us. */
+ /* think the KDC will have for us. */
if (etype && *etype == 0)
- *etype = ENCTYPE_DES_CBC_CRC;
+ *etype = ENCTYPE_DES_CBC_CRC;
if ((ret = (gak_fct)(context, request->client, *etype, prompter,
prompter_data, salt, s2kparams, as_key, gak_data)))
return(ret);
}
-
sprintf(name, "%.*s",
SAMDATA(sam_challenge->sam_type_name, "SAM Authentication",
sizeof(name) - 1));
@@ -341,7 +869,7 @@ krb5_error_code pa_sam(krb5_context context,
/* XXX What if more than one flag is set? */
if (sam_challenge->sam_flags & KRB5_SAM_SEND_ENCRYPTED_SAD) {
- /* Most of this should be taken care of before we get here. We */
+ /* Most of this should be taken care of before we get here. We */
/* will need the user's password and as_key to encrypt the SAD */
/* and we want to preserve ordering of user prompts (first */
/* password, then SAM data) so that user's won't be confused. */
@@ -353,7 +881,7 @@ krb5_error_code pa_sam(krb5_context context,
/* generate a salt using the requested principal */
- if ((salt->length == -1) && (salt->data == NULL)) {
+ if ((salt->length == -1 || salt->length == SALT_TYPE_AFS_LENGTH) && (salt->data == NULL)) {
if ((ret = krb5_principal2salt(context, request->client,
&defsalt))) {
krb5_xfree(sam_challenge);
@@ -391,7 +919,7 @@ krb5_error_code pa_sam(krb5_context context,
}
#if 0
- if ((salt->length == -1) && (salt->data == NULL)) {
+ if ((salt->length == SALT_TYPE_AFS_LENGTH) && (salt->data == NULL)) {
if (ret = krb5_principal2salt(context, request->client,
&defsalt)) {
krb5_xfree(sam_challenge);
@@ -440,7 +968,7 @@ krb5_error_code pa_sam(krb5_context context,
/* encode the encoded part of the response */
if ((ret = encode_krb5_enc_sam_response_enc(&enc_sam_response_enc,
- &scratch)))
+ &scratch)))
return(ret);
/*
@@ -569,7 +1097,7 @@ krb5_error_code pa_sam_2(krb5_context context,
/* most likely go on to try the AS_REQ against master KDC */
if (!(sc2b->sam_flags & KRB5_SAM_USE_SAD_AS_KEY)) {
- /* We will need the password to obtain the key used for */
+ /* We will need the password to obtain the key used for */
/* the checksum, and encryption of the sam_response. */
/* Go ahead and get it now, preserving the ordering of */
/* prompts for the user. */
@@ -620,13 +1148,13 @@ krb5_error_code pa_sam_2(krb5_context context,
/* Generate salt used by string_to_key() */
if ((salt->length == -1) && (salt->data == NULL)) {
- if ((retval =
- krb5_principal2salt(context, request->client, &defsalt))) {
+ if ((retval =
+ krb5_principal2salt(context, request->client, &defsalt))) {
krb5_free_sam_challenge_2(context, sc2);
krb5_free_sam_challenge_2_body(context, sc2b);
return(retval);
}
- salt = &defsalt;
+ salt = &defsalt;
} else {
defsalt.length = 0;
}
@@ -640,7 +1168,7 @@ krb5_error_code pa_sam_2(krb5_context context,
as_key->length = 0;
}
- /* generate a key using the supplied password */
+ /* generate a key using the supplied password */
retval = krb5_c_string_to_key(context, sc2b->sam_etype,
(krb5_data *)gak_data, salt, as_key);
@@ -651,33 +1179,34 @@ krb5_error_code pa_sam_2(krb5_context context,
return(retval);
}
- if (!(sc2b->sam_flags & KRB5_SAM_SEND_ENCRYPTED_SAD)) {
+ if (!(sc2b->sam_flags & KRB5_SAM_SEND_ENCRYPTED_SAD)) {
/* as_key = combine_key (as_key, string_to_key(SAD)) */
krb5_keyblock tmp_kb;
- retval = krb5_c_string_to_key(context, sc2b->sam_etype,
+ retval = krb5_c_string_to_key(context, sc2b->sam_etype,
&response_data, salt, &tmp_kb);
- if (retval) {
+ if (retval) {
krb5_free_sam_challenge_2(context, sc2);
- krb5_free_sam_challenge_2_body(context, sc2b);
+ krb5_free_sam_challenge_2_body(context, sc2b);
if (defsalt.length) krb5_xfree(defsalt.data);
return(retval);
}
- /* This should be a call to the crypto library some day */
+ /* This should be a call to the crypto library some day */
/* key types should already match the sam_etype */
retval = krb5int_c_combine_keys(context, as_key, &tmp_kb, as_key);
- if (retval) {
+ if (retval) {
krb5_free_sam_challenge_2(context, sc2);
- krb5_free_sam_challenge_2_body(context, sc2b);
+ krb5_free_sam_challenge_2_body(context, sc2b);
if (defsalt.length) krb5_xfree(defsalt.data);
return(retval);
}
- krb5_free_keyblock_contents(context, &tmp_kb);
+ krb5_free_keyblock_contents(context, &tmp_kb);
}
- if (defsalt.length)
+
+ if (defsalt.length)
krb5_xfree(defsalt.data);
} else {
@@ -688,7 +1217,7 @@ krb5_error_code pa_sam_2(krb5_context context,
as_key->length = 0;
}
- /* generate a key using the supplied password */
+ /* generate a key using the supplied password */
retval = krb5_c_string_to_key(context, sc2b->sam_etype,
&response_data, salt, as_key);
@@ -705,7 +1234,7 @@ krb5_error_code pa_sam_2(krb5_context context,
/* Now we have a key, verify the checksum on the sam_challenge */
cksum = sc2->sam_cksum;
-
+
while (*cksum) {
/* Check this cksum */
retval = krb5_c_verify_checksum(context, as_key,
@@ -718,14 +1247,14 @@ krb5_error_code pa_sam_2(krb5_context context,
krb5_free_sam_challenge_2_body(context, sc2b);
return(retval);
}
- if (valid_cksum)
+ if (valid_cksum)
break;
cksum++;
}
if (!valid_cksum) {
- /* If KRB5_SAM_SEND_ENCRYPTED_SAD is set, then password is only */
+ /* If KRB5_SAM_SEND_ENCRYPTED_SAD is set, then password is only */
/* source for checksum key. Therefore, a bad checksum means a */
/* bad password. Don't give that direct feedback to someone */
/* trying to brute-force passwords. */
@@ -734,13 +1263,13 @@ krb5_error_code pa_sam_2(krb5_context context,
krb5_free_sam_challenge_2(context, sc2);
krb5_free_sam_challenge_2_body(context, sc2b);
/*
- * Note: We return AP_ERR_BAD_INTEGRITY so upper-level applications
+ * Note: We return AP_ERR_BAD_INTEGRITY so upper-level applications
* can interpret that as "password incorrect", which is probably
* the best error we can return in this situation.
*/
return(KRB5KRB_AP_ERR_BAD_INTEGRITY);
}
-
+
/* fill in enc_sam_response_enc_2 */
enc_sam_response_enc_2.magic = KV5M_ENC_SAM_RESPONSE_ENC_2;
enc_sam_response_enc_2.sam_nonce = sc2b->sam_nonce;
@@ -771,7 +1300,7 @@ krb5_error_code pa_sam_2(krb5_context context,
/* enc_sam_response_enc_2 from above */
retval = krb5_c_encrypt_length(context, as_key->enctype, scratch->length,
- &ciph_len);
+ &ciph_len);
if (retval) {
krb5_free_sam_challenge_2(context, sc2);
krb5_free_sam_challenge_2_body(context, sc2b);
@@ -810,7 +1339,7 @@ krb5_error_code pa_sam_2(krb5_context context,
return (retval);
}
- /* Almost there, just need to make padata ! */
+ /* Almost there, just need to make padata ! */
sam_padata = malloc(sizeof(krb5_pa_data));
if (sam_padata == NULL) {
krb5_free_data(context, scratch);
@@ -827,8 +1356,7 @@ krb5_error_code pa_sam_2(krb5_context context,
return(0);
}
-
-static pa_types_t pa_types[] = {
+static const pa_types_t pa_types[] = {
{
KRB5_PADATA_PW_SALT,
pa_salt,
@@ -845,7 +1373,7 @@ static pa_types_t pa_types[] = {
PA_REAL,
},
{
- KRB5_PADATA_SAM_CHALLENGE_2,
+ KRB5_PADATA_SAM_CHALLENGE_2,
pa_sam_2,
PA_REAL,
},
@@ -861,15 +1389,95 @@ static pa_types_t pa_types[] = {
},
};
-krb5_error_code
+/*
+ * If one of the modules can adjust its AS_REQ data using the contents of the
+ * err_reply, return 0. If it's the sort of correction which requires that we
+ * ask the user another question, we let the calling application deal with it.
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_do_preauth_tryagain(krb5_context kcontext,
+ krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data **padata,
+ krb5_pa_data ***return_padata,
+ krb5_error *err_reply,
+ krb5_data *salt, krb5_data *s2kparams,
+ krb5_enctype *etype,
+ krb5_keyblock *as_key,
+ krb5_prompter_fct prompter, void *prompter_data,
+ krb5_gic_get_as_key_fct gak_fct, void *gak_data,
+ krb5_preauth_client_rock *get_data_rock,
+ krb5_gic_opt_ext *opte)
+{
+ krb5_error_code ret;
+ krb5_pa_data **out_padata;
+ krb5_preauth_context *context;
+ struct _krb5_preauth_context_module *module;
+ int i, j;
+ int out_pa_list_size = 0;
+
+ ret = KRB5KRB_ERR_GENERIC;
+ if (kcontext->preauth_context == NULL) {
+ return KRB5KRB_ERR_GENERIC;
+ }
+ context = kcontext->preauth_context;
+ if (context == NULL) {
+ return KRB5KRB_ERR_GENERIC;
+ }
+
+ for (i = 0; padata[i] != NULL && padata[i]->pa_type != 0; i++) {
+ out_padata = NULL;
+ for (j = 0; j < context->n_modules; j++) {
+ module = &context->modules[j];
+ if (module->pa_type != padata[i]->pa_type) {
+ continue;
+ }
+ if (module->client_tryagain == NULL) {
+ continue;
+ }
+ if ((*module->client_tryagain)(kcontext,
+ module->plugin_context,
+ *module->request_context_pp,
+ (krb5_get_init_creds_opt *)opte,
+ client_data_proc,
+ get_data_rock,
+ request,
+ encoded_request_body,
+ encoded_previous_request,
+ padata[i],
+ err_reply,
+ prompter, prompter_data,
+ gak_fct, gak_data, salt, s2kparams,
+ as_key,
+ &out_padata) == 0) {
+ if (out_padata != NULL) {
+ int k;
+ for (k = 0; out_padata[k] != NULL; k++);
+ grow_pa_list(return_padata, &out_pa_list_size,
+ out_padata, k);
+ free(out_padata);
+ return 0;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+krb5_error_code KRB5_CALLCONV
krb5_do_preauth(krb5_context context,
krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
krb5_pa_data **in_padata, krb5_pa_data ***out_padata,
krb5_data *salt, krb5_data *s2kparams,
krb5_enctype *etype,
krb5_keyblock *as_key,
krb5_prompter_fct prompter, void *prompter_data,
- krb5_gic_get_as_key_fct gak_fct, void *gak_data)
+ krb5_gic_get_as_key_fct gak_fct, void *gak_data,
+ krb5_preauth_client_rock *get_data_rock,
+ krb5_gic_opt_ext *opte)
{
int h, i, j, out_pa_list_size;
int seen_etype_info2 = 0;
@@ -880,6 +1488,7 @@ krb5_do_preauth(krb5_context context,
static const int paorder[] = { PA_INFO, PA_REAL };
int realdone;
+ /* Solaris Kerberos */
KRB5_LOG0(KRB5_INFO, "krb5_do_preauth() start");
if (in_padata == NULL) {
@@ -888,9 +1497,10 @@ krb5_do_preauth(krb5_context context,
}
#ifdef DEBUG
+ /* Solaris Kerberos */
if (salt && salt->data && salt->length > 0) {
fprintf (stderr, "salt len=%d", salt->length);
- if (salt->length > 0)
+ if ((int) salt->length > 0)
fprintf (stderr, " '%*s'", salt->length, salt->data);
fprintf (stderr, "; preauth data types:");
for (i = 0; in_padata[i]; i++) {
@@ -911,7 +1521,7 @@ krb5_do_preauth(krb5_context context,
int k, l, etype_found, valid_etype_found;
/*
* This is really gross, but is necessary to prevent
- * lossge when talking to a 1.0.x KDC, which returns an
+ * lossage when talking to a 1.0.x KDC, which returns an
* erroneous PA-PW-SALT when it returns a KRB-ERROR
* requiring additional preauth.
*/
@@ -924,23 +1534,24 @@ krb5_do_preauth(krb5_context context,
if (seen_etype_info2 || pa_type != KRB5_PADATA_ETYPE_INFO2)
continue;
if (pa_type == KRB5_PADATA_ETYPE_INFO2) {
- krb5_free_etype_info( context, etype_info);
+ krb5_free_etype_info( context, etype_info);
etype_info = NULL;
- }
+ }
}
scratch.length = in_padata[i]->length;
scratch.data = (char *) in_padata[i]->contents;
if (pa_type == KRB5_PADATA_ETYPE_INFO2) {
- seen_etype_info2++;
- ret = decode_krb5_etype_info2(&scratch, &etype_info);
+ seen_etype_info2++;
+ ret = decode_krb5_etype_info2(&scratch, &etype_info);
}
else ret = decode_krb5_etype_info(&scratch, &etype_info);
if (ret) {
- ret = 0; /*Ignore error and etype_info element*/
- krb5_free_etype_info( context, etype_info);
- etype_info = NULL;
- continue;
+ ret = 0; /*Ignore error and etype_info element*/
+ if (etype_info)
+ krb5_free_etype_info( context, etype_info);
+ etype_info = NULL;
+ continue;
}
if (etype_info[0] == NULL) {
krb5_free_etype_info(context, etype_info);
@@ -952,7 +1563,7 @@ krb5_do_preauth(krb5_context context,
* etype-info (preferring client request ktype order).
*/
for (etype_found = 0, valid_etype_found = 0, k = 0;
- !etype_found && k < request->nktypes; k++) {
+ !etype_found && k < request->nktypes; k++) {
for (l = 0; etype_info[l]; l++) {
if (etype_info[l]->etype == request->ktype[k]) {
etype_found++;
@@ -966,36 +1577,46 @@ krb5_do_preauth(krb5_context context,
}
}
if (!etype_found) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "error !etype_found, "
"valid_etype_found = %d",
valid_etype_found);
- if (valid_etype_found) {
+ if (valid_etype_found) {
/* supported enctype but not requested */
- ret = KRB5_CONFIG_ETYPE_NOSUPP;
- goto cleanup;
- }
- else {
- /* unsupported enctype */
- ret = KRB5_PROG_ETYPE_NOSUPP;
- goto cleanup;
- }
+ ret = KRB5_CONFIG_ETYPE_NOSUPP;
+ goto cleanup;
+ }
+ else {
+ /* unsupported enctype */
+ ret = KRB5_PROG_ETYPE_NOSUPP;
+ goto cleanup;
+ }
}
scratch.data = (char *) etype_info[l]->salt;
scratch.length = etype_info[l]->length;
krb5_free_data_contents(context, salt);
- if (scratch.length == KRB5_ETYPE_NO_SALT)
+ if (scratch.length == KRB5_ETYPE_NO_SALT)
salt->data = NULL;
else
- if ((ret = krb5int_copy_data_contents( context,
- &scratch, salt)) != 0)
- goto cleanup;
+ if ((ret = krb5int_copy_data_contents( context, &scratch, salt)) != 0)
+ goto cleanup;
*etype = etype_info[l]->etype;
krb5_free_data_contents(context, s2kparams);
if ((ret = krb5int_copy_data_contents(context,
- &etype_info[l]->s2kparams,
- s2kparams)) != 0)
+ &etype_info[l]->s2kparams,
+ s2kparams)) != 0)
goto cleanup;
+#ifdef DEBUG
+ for (j = 0; etype_info[j]; j++) {
+ krb5_etype_info_entry *e = etype_info[j];
+ fprintf (stderr, "etype info %d: etype %d salt len=%d",
+ j, e->etype, e->length);
+ if (e->length > 0 && e->length != KRB5_ETYPE_NO_SALT)
+ fprintf (stderr, " '%.*s'", e->length, e->salt);
+ fprintf (stderr, "\n");
+ }
+#endif
break;
}
case KRB5_PADATA_PW_SALT:
@@ -1006,69 +1627,89 @@ krb5_do_preauth(krb5_context context,
default:
;
}
- for (j=0; pa_types[j].type >= 0; j++) {
+ /* Try the internally-provided preauth type list. */
+ if (!realdone) for (j=0; pa_types[j].type >= 0; j++) {
if ((in_padata[i]->pa_type == pa_types[j].type) &&
(pa_types[j].flags & paorder[h])) {
+#ifdef DEBUG
+ fprintf (stderr, "calling internal function for pa_type "
+ "%d, flag %d\n", pa_types[j].type, paorder[h]);
+#endif
out_pa = NULL;
if ((ret = ((*pa_types[j].fct)(context, request,
- in_padata[i], &out_pa,
- salt, s2kparams, etype, as_key,
- prompter, prompter_data,
- gak_fct, gak_data)))) {
- goto cleanup;
+ in_padata[i], &out_pa,
+ salt, s2kparams, etype, as_key,
+ prompter, prompter_data,
+ gak_fct, gak_data)))) {
+ goto cleanup;
}
- if (out_pa) {
- if (out_pa_list == NULL) {
- if ((out_pa_list =
- (krb5_pa_data **)
- malloc(2*sizeof(krb5_pa_data *)))
- == NULL) {
- ret = ENOMEM;
- goto cleanup;
- }
- } else {
- if ((out_pa_list =
- (krb5_pa_data **)
- realloc(out_pa_list,
- (out_pa_list_size+2)*
- sizeof(krb5_pa_data *)))
- == NULL) {
- /* XXX this will leak the pointers which
- have already been allocated. oh well. */
- ret = ENOMEM;
- goto cleanup;
- }
- }
-
- out_pa_list[out_pa_list_size++] = out_pa;
+ ret = grow_pa_list(&out_pa_list, &out_pa_list_size,
+ &out_pa, 1);
+ if (ret != 0) {
+ goto cleanup;
}
if (paorder[h] == PA_REAL)
realdone = 1;
}
}
+
+ /* Try to use plugins now. */
+ if (!realdone) {
+ krb5_init_preauth_context(context);
+ if (context->preauth_context != NULL) {
+ int module_ret, module_flags;
+#ifdef DEBUG
+ fprintf (stderr, "trying modules for pa_type %d, flag %d\n",
+ in_padata[i]->pa_type, paorder[h]);
+#endif
+ ret = krb5_run_preauth_plugins(context,
+ paorder[h],
+ request,
+ encoded_request_body,
+ encoded_previous_request,
+ in_padata[i],
+ prompter,
+ prompter_data,
+ gak_fct,
+ salt, s2kparams,
+ gak_data,
+ get_data_rock,
+ as_key,
+ &out_pa_list,
+ &out_pa_list_size,
+ &module_ret,
+ &module_flags,
+ opte);
+ if (ret == 0) {
+ if (module_ret == 0) {
+ if (paorder[h] == PA_REAL) {
+ realdone = 1;
+ }
+ }
+ }
+ }
+ }
}
}
- if (out_pa_list)
- out_pa_list[out_pa_list_size++] = NULL;
-
*out_padata = out_pa_list;
if (etype_info)
- krb5_free_etype_info(context, etype_info);
-
+ krb5_free_etype_info(context, etype_info);
+
+ /* Solaris Kerberos */
KRB5_LOG0(KRB5_INFO, "krb5_do_preauth() end");
return(0);
-cleanup:
+ cleanup:
if (out_pa_list) {
- out_pa_list[out_pa_list_size++] = NULL;
- krb5_free_pa_data(context, out_pa_list);
+ out_pa_list[out_pa_list_size++] = NULL;
+ krb5_free_pa_data(context, out_pa_list);
}
if (etype_info)
- krb5_free_etype_info(context, etype_info);
+ krb5_free_etype_info(context, etype_info);
+ /* Solaris Kerberos */
KRB5_LOG0(KRB5_INFO, "krb5_do_preauth() end");
return (ret);
-
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_cred.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_cred.c
index c2e2db769d..bbaf5f5f8c 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_cred.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_cred.c
@@ -1,13 +1,12 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-#include <k5-int.h>
+#include "k5-int.h"
#include "cleanup.h"
-#include <auth_con.h>
+#include "auth_con.h"
#include <stddef.h> /* NULL */
#include <stdlib.h> /* malloc */
@@ -19,27 +18,24 @@
* decrypt the enc_part of a krb5_cred
*/
/*ARGSUSED*/
-static krb5_error_code
-decrypt_credencdata(
- krb5_context context,
- krb5_cred * pcred,
- krb5_keyblock * pkeyblock,
- krb5_cred_enc_part * pcredenc)
+static krb5_error_code
+decrypt_credencdata(krb5_context context, krb5_cred *pcred, krb5_keyblock *pkeyblock, krb5_cred_enc_part *pcredenc)
{
krb5_cred_enc_part * ppart = NULL;
krb5_error_code retval;
krb5_data scratch;
scratch.length = pcred->enc_part.ciphertext.length;
- if (!(scratch.data = (char *)malloc(scratch.length)))
+ if (!(scratch.data = (char *)malloc(scratch.length)))
return ENOMEM;
if (pkeyblock != NULL) {
- if ((retval = krb5_c_decrypt(context, pkeyblock,
- KRB5_KEYUSAGE_KRB_CRED_ENCPART, 0,
- &pcred->enc_part, &scratch)))
- goto cleanup;
+ if ((retval = krb5_c_decrypt(context, pkeyblock,
+ KRB5_KEYUSAGE_KRB_CRED_ENCPART, 0,
+ &pcred->enc_part, &scratch)))
+ goto cleanup;
} else {
+ /* Solaris Kerberos */
(void) memcpy(scratch.data, pcred->enc_part.ciphertext.data, scratch.length);
}
@@ -47,7 +43,6 @@ decrypt_credencdata(
if ((retval = decode_krb5_enc_cred_part(&scratch, &ppart)))
goto cleanup;
- /* this is a struct copy so ppart must be freed */
*pcredenc = *ppart;
retval = 0;
@@ -56,6 +51,7 @@ cleanup:
memset(ppart, 0, sizeof(*ppart));
krb5_xfree(ppart);
}
+ /* Solaris Kerberos */
(void) memset(scratch.data, 0, scratch.length);
krb5_xfree(scratch.data);
@@ -63,13 +59,8 @@ cleanup:
}
/*----------------------- krb5_rd_cred_basic -----------------------*/
-static krb5_error_code
-krb5_rd_cred_basic(
- krb5_context context,
- krb5_data * pcreddata,
- krb5_keyblock * pkeyblock,
- krb5_replay_data * replaydata,
- krb5_creds *** pppcreds)
+static krb5_error_code
+krb5_rd_cred_basic(krb5_context context, krb5_data *pcreddata, krb5_keyblock *pkeyblock, krb5_replay_data *replaydata, krb5_creds ***pppcreds)
{
krb5_error_code retval;
krb5_cred * pcred;
@@ -81,11 +72,13 @@ krb5_rd_cred_basic(
if ((retval = decode_krb5_cred(pcreddata, &pcred)))
return retval;
+ /* Solaris Kerberos */
(void) memset(&encpart, 0, sizeof(encpart));
if ((retval = decrypt_credencdata(context, pcred, pkeyblock, &encpart)))
goto cleanup_cred;
+
replaydata->timestamp = encpart.timestamp;
replaydata->usec = encpart.usec;
replaydata->seq = encpart.nonce;
@@ -96,7 +89,7 @@ krb5_rd_cred_basic(
*/
for (ncreds = 0; pcred->tickets[ncreds]; ncreds++);
- if ((*pppcreds =
+ if ((*pppcreds =
(krb5_creds **)malloc((size_t)(sizeof(krb5_creds *) *
(ncreds + 1)))) == NULL) {
retval = ENOMEM;
@@ -121,6 +114,7 @@ krb5_rd_cred_basic(
(*pppcreds)[i] = pcur;
(*pppcreds)[i+1] = 0;
pinfo = encpart.ticket_info[i++];
+ /* Solaris Kerberos */
(void) memset(pcur, 0, sizeof(krb5_creds));
if ((retval = krb5_copy_principal(context, pinfo->client,
@@ -135,7 +129,7 @@ krb5_rd_cred_basic(
&pcur->keyblock)))
goto cleanup;
- if ((retval = krb5_copy_addresses(context, pinfo->caddrs,
+ if ((retval = krb5_copy_addresses(context, pinfo->caddrs,
&pcur->addresses)))
goto cleanup;
@@ -151,6 +145,7 @@ krb5_rd_cred_basic(
pcur->times = pinfo->times;
pcur->ticket_flags = pinfo->flags;
pcur->authdata = NULL; /* not used */
+ /* Solaris Kerberos */
(void) memset(&pcur->second_ticket, 0, sizeof(pcur->second_ticket));
}
@@ -179,12 +174,7 @@ cleanup_cred:
* outputs the nonce and an array of the forwarded credentials.
*/
krb5_error_code KRB5_CALLCONV
-krb5_rd_cred(
- krb5_context context,
- krb5_auth_context auth_context,
- krb5_data * pcreddata,
- krb5_creds * * * pppcreds,
- krb5_replay_data * outdata)
+krb5_rd_cred(krb5_context context, krb5_auth_context auth_context, krb5_data *pcreddata, krb5_creds ***pppcreds, krb5_replay_data *outdata)
{
krb5_error_code retval;
krb5_keyblock * keyblock;
@@ -204,21 +194,20 @@ krb5_rd_cred(
(auth_context->rcache == NULL))
return KRB5_RC_REQUIRED;
- /*
- * If decrypting with the first keyblock we try fails, perhaps the
- * credentials are stored in the session key so try decrypting with
- * that.
- */
+
+/* If decrypting with the first keyblock we try fails, perhaps the
+ * credentials are stored in the session key so try decrypting with
+ * that.
+*/
if ((retval = krb5_rd_cred_basic(context, pcreddata, keyblock,
- &replaydata, pppcreds))) {
+ &replaydata, pppcreds))) {
if ((retval = krb5_rd_cred_basic(context, pcreddata,
- auth_context->keyblock,
- &replaydata, pppcreds))) {
- return retval;
- }
+ auth_context->keyblock,
+ &replaydata, pppcreds))) {
+ return retval;
}
-
-
+ }
+
if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) {
krb5_donot_replay replay;
krb5_timestamp currenttime;
@@ -239,8 +228,8 @@ krb5_rd_cred(
replay.cusec = replaydata.usec;
replay.ctime = replaydata.timestamp;
if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {
- krb5_xfree(replay.client);
- goto error;
+ krb5_xfree(replay.client);
+ goto error;
}
krb5_xfree(replay.client);
}
@@ -260,10 +249,11 @@ krb5_rd_cred(
outdata->seq = replaydata.seq;
}
-error:
+error:;
if (retval) {
- krb5_free_tgt_creds(context, *pppcreds);
+ krb5_free_tgt_creds(context, *pppcreds);
*pppcreds = NULL;
}
return retval;
}
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_error.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_error.c
index e3fe0e47a2..8060cb70ef 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_error.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_error.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/rd_error.c
*
@@ -28,7 +27,7 @@
* krb5_rd_error() routine
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
* Parses an error message from enc_errbuf and returns an allocated
@@ -48,3 +47,4 @@ krb5_rd_error(krb5_context context, const krb5_data *enc_errbuf, krb5_error **de
return KRB5KRB_AP_ERR_MSG_TYPE;
return(decode_krb5_error(enc_errbuf, dec_error));
}
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_priv.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_priv.c
index 585ea34593..ab4fc40ad8 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_priv.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_priv.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/rd_priv.c
@@ -15,7 +14,7 @@
* 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
@@ -29,14 +28,14 @@
* 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_rd_priv()
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "cleanup.h"
-#include <auth_con.h>
+#include "auth_con.h"
#define in_clock_skew(date) (labs((date)-currenttime) < context->clockskew)
@@ -46,7 +45,7 @@ Parses a KRB_PRIV message from inbuf, placing the confidential user
data in *outbuf.
key specifies the key to be used for decryption of the message.
-
+
remote_addr and local_addr specify the full
addresses (host and port) of the sender and receiver.
@@ -62,15 +61,7 @@ Returns system errors, integrity errors.
*/
static krb5_error_code
-krb5_rd_priv_basic(
- krb5_context context,
- const krb5_data * inbuf,
- const krb5_keyblock * keyblock,
- const krb5_address * local_addr,
- const krb5_address * remote_addr,
- krb5_pointer i_vector,
- krb5_replay_data * replaydata,
- krb5_data * outbuf)
+krb5_rd_priv_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyblock *keyblock, const krb5_address *local_addr, const krb5_address *remote_addr, krb5_pointer i_vector, krb5_replay_data *replaydata, krb5_data *outbuf)
{
krb5_error_code retval;
krb5_priv * privmsg;
@@ -85,7 +76,7 @@ krb5_rd_priv_basic(
/* decode private message */
if ((retval = decode_krb5_priv(inbuf, &privmsg)))
return retval;
-
+
if (i_vector) {
if ((retval = krb5_c_block_size(context, keyblock->enctype,
&blocksize)))
@@ -102,7 +93,7 @@ krb5_rd_priv_basic(
}
if ((retval = krb5_c_decrypt(context, keyblock,
- KRB5_KEYUSAGE_KRB_PRIV_ENCPART,
+ KRB5_KEYUSAGE_KRB_PRIV_ENCPART,
i_vector?&ivdata:0,
&privmsg->enc_part, &scratch)))
goto cleanup_scratch;
@@ -115,7 +106,7 @@ krb5_rd_priv_basic(
retval = KRB5KRB_AP_ERR_BADADDR;
goto cleanup_data;
}
-
+
if (privmsg_enc_part->r_address) {
if (local_addr) {
if (!krb5_address_compare(context, local_addr,
@@ -129,7 +120,7 @@ krb5_rd_priv_basic(
if ((retval = krb5_os_localaddr(context, &our_addrs))) {
goto cleanup_data;
}
- if (!krb5_address_search(context, privmsg_enc_part->r_address,
+ if (!krb5_address_search(context, privmsg_enc_part->r_address,
our_addrs)) {
krb5_free_addresses(context, our_addrs);
retval = KRB5KRB_AP_ERR_BADADDR;
@@ -153,23 +144,19 @@ cleanup_data:;
krb5_free_priv_enc_part(context, privmsg_enc_part);
cleanup_scratch:;
- (void) memset(scratch.data, 0, scratch.length);
+ /* Solaris Kerberos */
+ (void) memset(scratch.data, 0, scratch.length);
krb5_xfree(scratch.data);
cleanup_privmsg:;
- krb5_xfree(privmsg->enc_part.ciphertext.data);
+ krb5_xfree(privmsg->enc_part.ciphertext.data);
krb5_xfree(privmsg);
return retval;
}
krb5_error_code KRB5_CALLCONV
-krb5_rd_priv(
- krb5_context context,
- krb5_auth_context auth_context,
- const krb5_data * inbuf,
- krb5_data * outbuf,
- krb5_replay_data * outdata)
+krb5_rd_priv(krb5_context context, krb5_auth_context auth_context, const krb5_data *inbuf, krb5_data *outbuf, krb5_replay_data *outdata)
{
krb5_error_code retval;
krb5_keyblock * keyblock;
@@ -199,7 +186,7 @@ krb5_rd_priv(
if (auth_context->local_addr) {
if (auth_context->local_port) {
if (!(retval = krb5_make_fulladdr(context, auth_context->local_addr,
- auth_context->local_port,
+ auth_context->local_port,
&local_fulladdr))){
CLEANUP_PUSH(local_fulladdr.contents, free);
plocal_fulladdr = &local_fulladdr;
@@ -214,7 +201,7 @@ krb5_rd_priv(
if (auth_context->remote_addr) {
if (auth_context->remote_port) {
if (!(retval = krb5_make_fulladdr(context,auth_context->remote_addr,
- auth_context->remote_port,
+ auth_context->remote_port,
&remote_fulladdr))){
CLEANUP_PUSH(remote_fulladdr.contents, free);
premote_fulladdr = &remote_fulladdr;
@@ -251,15 +238,14 @@ krb5_rd_priv(
goto error;
}
- if ((retval = krb5_gen_replay_name(context, auth_context->remote_addr,
+ if ((retval = krb5_gen_replay_name(context, auth_context->remote_addr,
"_priv", &replay.client)))
goto error;
replay.server = ""; /* XXX */
replay.cusec = replaydata.usec;
replay.ctime = replaydata.timestamp;
- retval = krb5_rc_store(context, auth_context->rcache, &replay);
- if (retval) {
+ if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {
krb5_xfree(replay.client);
goto error;
}
@@ -290,3 +276,4 @@ error:;
return retval;
}
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_rep.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_rep.c
index 45c48383db..6742d8a038 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_rep.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_rep.c
@@ -1,11 +1,4 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* lib/krb5/krb/rd_rep.c
*
* Copyright 1990,1991 by the Massachusetts Institute of Technology.
@@ -15,7 +8,7 @@
* 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
@@ -29,31 +22,27 @@
* 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_rd_rep()
*/
-#include <k5-int.h>
-#include <auth_con.h>
+#include "k5-int.h"
+#include "auth_con.h"
/*
* Parses a KRB_AP_REP message, returning its contents.
- *
+ *
* repl is filled in with with a pointer to allocated memory containing
- * the fields from the encrypted response.
- *
+ * the fields from the encrypted response.
+ *
* the key in kblock is used to decrypt the message.
- *
+ *
* returns system errors, encryption errors, replay errors
*/
krb5_error_code KRB5_CALLCONV
-krb5_rd_rep(
- krb5_context context,
- krb5_auth_context auth_context,
- const krb5_data * inbuf,
- krb5_ap_rep_enc_part * *repl)
+krb5_rd_rep(krb5_context context, krb5_auth_context auth_context, const krb5_data *inbuf, krb5_ap_rep_enc_part **repl)
{
krb5_error_code retval;
krb5_ap_rep * reply;
@@ -75,15 +64,13 @@ krb5_rd_rep(
return(ENOMEM);
}
- retval = krb5_c_decrypt(context, auth_context->keyblock,
+ if ((retval = krb5_c_decrypt(context, auth_context->keyblock,
KRB5_KEYUSAGE_AP_REP_ENCPART, 0,
- &reply->enc_part, &scratch);
- if (retval)
+ &reply->enc_part, &scratch)))
goto clean_scratch;
/* now decode the decrypted stuff */
retval = decode_krb5_ap_rep_enc_part(&scratch, repl);
-
if (retval)
goto clean_scratch;
@@ -99,28 +86,29 @@ krb5_rd_rep(
if (auth_context->recv_subkey) {
krb5_free_keyblock(context, auth_context->recv_subkey);
auth_context->recv_subkey = NULL;
- }
+ }
retval = krb5_copy_keyblock(context, (*repl)->subkey,
- &auth_context->recv_subkey);
+ &auth_context->recv_subkey);
if (retval)
goto clean_scratch;
if (auth_context->send_subkey) {
krb5_free_keyblock(context, auth_context->send_subkey);
auth_context->send_subkey = NULL;
- }
+ }
retval = krb5_copy_keyblock(context, (*repl)->subkey,
- &auth_context->send_subkey);
+ &auth_context->send_subkey);
if (retval) {
krb5_free_keyblock(context, auth_context->send_subkey);
auth_context->send_subkey = NULL;
- }
+ }
}
+
/* Get remote sequence number */
auth_context->remote_seq_number = (*repl)->seq_number;
clean_scratch:
- memset(scratch.data, 0, scratch.length);
-errout:
+ memset(scratch.data, 0, scratch.length);
+
krb5_free_ap_rep(context, reply);
free(scratch.data);
return retval;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_req.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_req.c
index 425b75fba3..9a2f4589d7 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_req.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_req.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/rd_req.c
*
@@ -28,8 +27,8 @@
* krb5_rd_req()
*/
-#include <k5-int.h>
-#include <auth_con.h>
+#include "k5-int.h"
+#include "auth_con.h"
/*
* Parses a KRB_AP_REQ message, returning its contents.
@@ -45,8 +44,16 @@
*
* returns system errors, encryption errors, replay errors
*/
+
krb5_error_code KRB5_CALLCONV
krb5_rd_req(krb5_context context, krb5_auth_context *auth_context, const krb5_data *inbuf, krb5_const_principal server, krb5_keytab keytab, krb5_flags *ap_req_options, krb5_ticket **ticket)
+
+
+
+ /* XXX do we really need this */
+
+
+
{
krb5_error_code retval;
krb5_ap_req * request;
@@ -78,7 +85,7 @@ krb5_rd_req(krb5_context context, krb5_auth_context *auth_context, const krb5_da
/* Get an rcache if necessary. */
if (((*auth_context)->rcache == NULL)
&& ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME)
- && server) {
+&& server) {
if ((retval = krb5_get_server_rcache(context,
krb5_princ_component(context,server,0), &(*auth_context)->rcache)))
goto cleanup_auth_context;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_req_dec.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_req_dec.c
index 625cc8ce53..54df8db453 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_req_dec.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_req_dec.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/rd_req_dec.c
@@ -16,7 +15,7 @@
* 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
@@ -31,13 +30,13 @@
* CyberSAFE Corporation make any representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
*
* krb5_rd_req_decoded()
*/
-#include <k5-int.h>
-#include <auth_con.h>
+#include "k5-int.h"
+#include "auth_con.h"
/*
* essentially the same as krb_rd_req, but uses a decoded AP_REQ as
@@ -45,24 +44,24 @@
*/
/*
* Parses a KRB_AP_REQ message, returning its contents.
- *
+ *
* server specifies the expected server's name for the ticket; if NULL, then
* any server will be accepted if the key can be found, and the caller should
* verify that the principal is something it trusts.
- *
+ *
* rcache specifies a replay detection cache used to store authenticators and
* server names
- *
+ *
* keyproc specifies a procedure to generate a decryption key for the
* ticket. If keyproc is non-NULL, keyprocarg is passed to it, and the result
* used as a decryption key. If keyproc is NULL, then fetchfrom is checked;
* if it is non-NULL, it specifies a parameter name from which to retrieve the
* decryption key. If fetchfrom is NULL, then the default key store is
* consulted.
- *
+ *
* authdat is set to point at allocated storage structures; the caller
- * should free them when finished.
- *
+ * should free them when finished.
+ *
* returns system errors, encryption errors, replay errors
*/
@@ -73,11 +72,7 @@ static krb5_error_code decrypt_authenticator
#define in_clock_skew(date) (labs((date)-currenttime) < context->clockskew)
static krb5_error_code
-krb5_rd_req_decrypt_tkt_part(
- krb5_context context,
- const krb5_ap_req * req,
- krb5_keytab keytab)
-
+krb5_rd_req_decrypt_tkt_part(krb5_context context, const krb5_ap_req *req, krb5_keytab keytab)
{
krb5_error_code retval;
krb5_enctype enctype;
@@ -85,13 +80,16 @@ krb5_rd_req_decrypt_tkt_part(
enctype = req->ticket->enc_part.enctype;
+ /* Solaris Kerberos: */
memset(&ktent, 0, sizeof(krb5_keytab_entry));
- retval = krb5_kt_get_entry(context, keytab, req->ticket->server,
- req->ticket->enc_part.kvno, enctype, &ktent);
- if (retval)
+ if ((retval = krb5_kt_get_entry(context, keytab, req->ticket->server,
+ req->ticket->enc_part.kvno,
+ enctype, &ktent)))
return retval;
+
/*
+ * Solaris Kerberos:
* If we get this far then we know that the enc types are similar,
* therefore we should change the enc type to match that of what
* we are decrypting.
@@ -99,27 +97,45 @@ krb5_rd_req_decrypt_tkt_part(
ktent.key.enctype = enctype;
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;
}
static krb5_error_code
-krb5_rd_req_decoded_opt(
- krb5_context context,
- krb5_auth_context * auth_context,
- const krb5_ap_req * req,
- krb5_const_principal server,
- krb5_keytab keytab,
- krb5_flags * ap_req_options,
- krb5_ticket ** ticket,
- int check_valid_flag)
+krb5_rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context,
+ const krb5_ap_req *req, krb5_const_principal server,
+ krb5_keytab keytab, krb5_flags *ap_req_options,
+ krb5_ticket **ticket, int check_valid_flag)
{
krb5_error_code retval = 0;
krb5_timestamp currenttime;
-
- if (server && !krb5_principal_compare(context, server, req->ticket->server))
- return KRB5KRB_AP_WRONG_PRINC;
+ krb5_principal_data princ_data;
+
+ req->ticket->enc_part2 == NULL;
+ if (server && krb5_is_referral_realm(&server->realm)) {
+ char *realm;
+ princ_data = *server;
+ server = &princ_data;
+ retval = krb5_get_default_realm(context, &realm);
+ if (retval)
+ return retval;
+ princ_data.realm.data = realm;
+ princ_data.realm.length = strlen(realm);
+ }
+ if (server && !krb5_principal_compare(context, server, req->ticket->server)) {
+ char *found_name = 0, *wanted_name = 0;
+ if (krb5_unparse_name(context, server, &wanted_name) == 0
+ && krb5_unparse_name(context, req->ticket->server, &found_name) == 0)
+ krb5_set_error_message(context, KRB5KRB_AP_WRONG_PRINC,
+ "Wrong principal in request (found %s, wanted %s)",
+ found_name, wanted_name);
+ krb5_free_unparsed_name(context, wanted_name);
+ krb5_free_unparsed_name(context, found_name);
+ retval = KRB5KRB_AP_WRONG_PRINC;
+ goto cleanup;
+ }
/* if (req->ap_options & AP_OPTS_USE_SESSION_KEY)
do we need special processing here ? */
@@ -128,18 +144,18 @@ krb5_rd_req_decoded_opt(
if ((*auth_context)->keyblock) { /* User to User authentication */
if ((retval = krb5_decrypt_tkt_part(context, (*auth_context)->keyblock,
req->ticket)))
- return retval;
+goto cleanup;
krb5_free_keyblock(context, (*auth_context)->keyblock);
(*auth_context)->keyblock = NULL;
} else {
if ((retval = krb5_rd_req_decrypt_tkt_part(context, req, keytab)))
- return retval;
+ goto cleanup;
}
/* XXX this is an evil hack. check_valid_flag is set iff the call
is not from inside the kdc. we can use this to determine which
key usage to use */
- if ((retval = decrypt_authenticator(context, req,
+ if ((retval = decrypt_authenticator(context, req,
&((*auth_context)->authentp),
check_valid_flag)))
goto cleanup;
@@ -150,8 +166,8 @@ krb5_rd_req_decoded_opt(
goto cleanup;
}
- if ((*auth_context)->remote_addr &&
- !krb5_address_search(context, (*auth_context)->remote_addr,
+ if ((*auth_context)->remote_addr &&
+ !krb5_address_search(context, (*auth_context)->remote_addr,
req->ticket->enc_part2->caddrs)) {
retval = KRB5KRB_AP_ERR_BADADDR;
goto cleanup;
@@ -163,7 +179,7 @@ krb5_rd_req_decoded_opt(
/* Single hop cross-realm tickets only */
- {
+ {
krb5_transited *trans = &(req->ticket->enc_part2->transited);
/* If the transited list is empty, then we have at most one hop */
@@ -175,17 +191,17 @@ krb5_rd_req_decoded_opt(
/* No cross-realm tickets */
- {
+ {
char * lrealm;
krb5_data * realm;
krb5_transited * trans;
-
+
realm = krb5_princ_realm(context, req->ticket->enc_part2->client);
trans = &(req->ticket->enc_part2->transited);
/*
- * If the transited list is empty, then we have at most one hop
- * So we also have to check that the client's realm is the local one
+ * If the transited list is empty, then we have at most one hop
+ * So we also have to check that the client's realm is the local one
*/
krb5_get_default_realm(context, &lrealm);
if ((trans->tr_contents.data && trans->tr_contents.data[0]) ||
@@ -199,25 +215,25 @@ krb5_rd_req_decoded_opt(
#else
/* Hierarchical Cross-Realm */
-
+
{
- krb5_data * realm;
- krb5_transited * trans;
-
+ krb5_data * realm;
+ krb5_transited * trans;
+
realm = krb5_princ_realm(context, req->ticket->enc_part2->client);
trans = &(req->ticket->enc_part2->transited);
/*
- * If the transited list is not empty, then check that all realms
- * transited are within the hierarchy between the client's realm
- * and the local realm.
- */
+ * If the transited list is not empty, then check that all realms
+ * transited are within the hierarchy between the client's realm
+ * and the local realm.
+ */
if (trans->tr_contents.data && trans->tr_contents.data[0]) {
- retval = krb5_check_transited_list(context, &(trans->tr_contents),
- realm,
- krb5_princ_realm (context,
- server));
- }
+ retval = krb5_check_transited_list(context, &(trans->tr_contents),
+ realm,
+ krb5_princ_realm (context,
+ server));
+ }
}
#endif
@@ -269,15 +285,21 @@ krb5_rd_req_decoded_opt(
/*EMPTY*/
;
} else if ((*auth_context)->permitted_etypes == NULL) {
+ int etype;
/* check against the default set */
if ((!krb5_is_permitted_enctype(context,
- req->ticket->enc_part.enctype)) ||
+ etype = req->ticket->enc_part.enctype)) ||
(!krb5_is_permitted_enctype(context,
- req->ticket->enc_part2->session->enctype)) ||
+ etype = req->ticket->enc_part2->session->enctype)) ||
(((*auth_context)->authentp->subkey) &&
!krb5_is_permitted_enctype(context,
- (*auth_context)->authentp->subkey->enctype))) {
+ etype = (*auth_context)->authentp->subkey->enctype))) {
+ char enctype_name[30];
retval = KRB5_NOPERM_ETYPE;
+ if (krb5_enctype_to_string(etype, enctype_name, sizeof(enctype_name)) == 0)
+ krb5_set_error_message(context, retval,
+ "Encryption type %s not permitted",
+ enctype_name);
goto cleanup;
}
} else {
@@ -289,7 +311,13 @@ krb5_rd_req_decoded_opt(
req->ticket->enc_part.enctype)
break;
if (!(*auth_context)->permitted_etypes[i]) {
+ char enctype_name[30];
retval = KRB5_NOPERM_ETYPE;
+ if (krb5_enctype_to_string(req->ticket->enc_part.enctype,
+ enctype_name, sizeof(enctype_name)) == 0)
+ krb5_set_error_message(context, retval,
+ "Encryption type %s not permitted",
+ enctype_name);
goto cleanup;
}
@@ -298,7 +326,13 @@ krb5_rd_req_decoded_opt(
req->ticket->enc_part2->session->enctype)
break;
if (!(*auth_context)->permitted_etypes[i]) {
+ char enctype_name[30];
retval = KRB5_NOPERM_ETYPE;
+ if (krb5_enctype_to_string(req->ticket->enc_part2->session->enctype,
+ enctype_name, sizeof(enctype_name)) == 0)
+ krb5_set_error_message(context, retval,
+ "Encryption type %s not permitted",
+ enctype_name);
goto cleanup;
}
@@ -308,16 +342,22 @@ krb5_rd_req_decoded_opt(
(*auth_context)->authentp->subkey->enctype)
break;
if (!(*auth_context)->permitted_etypes[i]) {
+ char enctype_name[30];
retval = KRB5_NOPERM_ETYPE;
+ if (krb5_enctype_to_string((*auth_context)->authentp->subkey->enctype,
+ enctype_name,
+ sizeof(enctype_name)) == 0)
+ krb5_set_error_message(context, retval,
+ "Encryption type %s not permitted",
+ enctype_name);
goto cleanup;
}
}
}
(*auth_context)->remote_seq_number = (*auth_context)->authentp->seq_number;
-
if ((*auth_context)->authentp->subkey) {
-
+ /* Solaris Kerberos */
if ((*auth_context)->recv_subkey != NULL) {
krb5_free_keyblock(context, (*auth_context)->recv_subkey);
(*auth_context)->recv_subkey = NULL;
@@ -327,24 +367,24 @@ krb5_rd_req_decoded_opt(
(*auth_context)->authentp->subkey,
&((*auth_context)->recv_subkey))))
goto cleanup;
-
+ /* Solaris Kerberos */
if ((*auth_context)->send_subkey != NULL) {
krb5_free_keyblock(context, (*auth_context)->send_subkey);
(*auth_context)->send_subkey = NULL;
}
retval = krb5_copy_keyblock(context, (*auth_context)->authentp->subkey,
- &((*auth_context)->send_subkey));
+ &((*auth_context)->send_subkey));
if (retval) {
- krb5_free_keyblock(context, (*auth_context)->recv_subkey);
- (*auth_context)->recv_subkey = NULL;
- goto cleanup;
+ krb5_free_keyblock(context, (*auth_context)->recv_subkey);
+ (*auth_context)->recv_subkey = NULL;
+ goto cleanup;
}
} else {
(*auth_context)->recv_subkey = 0;
(*auth_context)->send_subkey = 0;
}
-
+ /* Solaris Kerberos */
if ((*auth_context)->keyblock != NULL) {
krb5_free_keyblock(context, (*auth_context)->keyblock);
(*auth_context)->keyblock = NULL;
@@ -354,13 +394,13 @@ krb5_rd_req_decoded_opt(
goto cleanup;
/*
- * If not AP_OPTS_MUTUAL_REQUIRED then and sequence numbers are used
+ * If not AP_OPTS_MUTUAL_REQUIRED then and sequence numbers are used
* then the default sequence number is the one's complement of the
* sequence number sent ot us.
*/
- if ((!(req->ap_options & AP_OPTS_MUTUAL_REQUIRED)) &&
+ if ((!(req->ap_options & AP_OPTS_MUTUAL_REQUIRED)) &&
(*auth_context)->remote_seq_number) {
- (*auth_context)->local_seq_number ^=
+ (*auth_context)->local_seq_number ^=
(*auth_context)->remote_seq_number;
}
@@ -370,48 +410,44 @@ krb5_rd_req_decoded_opt(
if (ap_req_options)
*ap_req_options = req->ap_options;
retval = 0;
-
+
cleanup:
+ if (server == &princ_data)
+ krb5_free_default_realm(context, princ_data.realm.data);
if (retval) {
/* only free if we're erroring out...otherwise some
applications will need the output. */
- krb5_free_enc_tkt_part(context, req->ticket->enc_part2);
+ if (req->ticket->enc_part2)
+ krb5_free_enc_tkt_part(context, req->ticket->enc_part2);
req->ticket->enc_part2 = NULL;
}
return retval;
}
krb5_error_code
-krb5_rd_req_decoded(
- krb5_context context,
- krb5_auth_context * auth_context,
- const krb5_ap_req * req,
- krb5_const_principal server,
- krb5_keytab keytab,
- krb5_flags * ap_req_options,
- krb5_ticket ** ticket)
+krb5_rd_req_decoded(krb5_context context, krb5_auth_context *auth_context,
+ const krb5_ap_req *req, krb5_const_principal server,
+ krb5_keytab keytab, krb5_flags *ap_req_options,
+ krb5_ticket **ticket)
{
krb5_error_code retval;
retval = krb5_rd_req_decoded_opt(context, auth_context,
- req, server, keytab,
+ req, server, keytab,
ap_req_options, ticket,
1); /* check_valid_flag */
return retval;
}
krb5_error_code
-krb5_rd_req_decoded_anyflag(
- krb5_context context,
- krb5_auth_context * auth_context,
- const krb5_ap_req * req,
- krb5_const_principal server,
- krb5_keytab keytab,
- krb5_flags * ap_req_options,
- krb5_ticket ** ticket)
+krb5_rd_req_decoded_anyflag(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_ap_req *req,
+ krb5_const_principal server, krb5_keytab keytab,
+ krb5_flags *ap_req_options, krb5_ticket **ticket)
{
krb5_error_code retval;
retval = krb5_rd_req_decoded_opt(context, auth_context,
- req, server, keytab,
+ req, server, keytab,
ap_req_options, ticket,
0); /* don't check_valid_flag */
return retval;
@@ -419,11 +455,8 @@ krb5_rd_req_decoded_anyflag(
/*ARGSUSED*/
static krb5_error_code
-decrypt_authenticator(
- krb5_context context,
- const krb5_ap_req *request,
- krb5_authenticator **authpp,
- int is_ap_req)
+decrypt_authenticator(krb5_context context, const krb5_ap_req *request,
+ krb5_authenticator **authpp, int is_ap_req)
{
krb5_authenticator *local_auth;
krb5_error_code retval;
@@ -436,11 +469,10 @@ decrypt_authenticator(
if (!(scratch.data = malloc(scratch.length)))
return(ENOMEM);
- retval = krb5_c_decrypt(context, sesskey,
+ if ((retval = krb5_c_decrypt(context, sesskey,
is_ap_req?KRB5_KEYUSAGE_AP_REQ_AUTH:
KRB5_KEYUSAGE_TGS_REQ_AUTH, 0,
- &request->authenticator, &scratch);
- if (retval) {
+ &request->authenticator, &scratch))) {
free(scratch.data);
return(retval);
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_safe.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_safe.c
index f07523a9f2..17d3046478 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_safe.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/rd_safe.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/rd_safe.c
@@ -15,7 +14,7 @@
* 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
@@ -29,14 +28,14 @@
* 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_rd_safe()
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "cleanup.h"
-#include <auth_con.h>
+#include "auth_con.h"
#define in_clock_skew(date) (labs((date)-currenttime) < context->clockskew)
@@ -45,7 +44,7 @@
data in *outbuf.
key specifies the key to be used for decryption of the message.
-
+
sender_addr and recv_addr specify the full addresses (host and port) of
the sender and receiver.
@@ -64,15 +63,18 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyb
krb5_data *scratch;
krb5_boolean valid;
+ /* Solaris Kerberos */
KRB5_LOG0(KRB5_INFO, "krb5_rd_safe_basic() start");
- if (!krb5_is_krb_safe(inbuf)){
+ if (!krb5_is_krb_safe(inbuf)) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_rd_safe_basic() end, error retval=%d",
KRB5KRB_AP_ERR_MSG_TYPE);
return KRB5KRB_AP_ERR_MSG_TYPE;
}
- if ((retval = decode_krb5_safe_with_body(inbuf, &message, &safe_body))){
+ if ((retval = decode_krb5_safe_with_body(inbuf, &message, &safe_body))) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_rd_safe_basic() end, error retval=%d",
retval);
return retval;
@@ -80,6 +82,7 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyb
if (!krb5_c_valid_cksumtype(message->checksum->checksum_type)) {
retval = KRB5_PROG_SUMTYPE_NOSUPP;
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_rd_safe_basic() error retval=%d",
retval);
goto cleanup;
@@ -87,6 +90,7 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyb
if (!krb5_c_is_coll_proof_cksum(message->checksum->checksum_type) ||
!krb5_c_is_keyed_cksum(message->checksum->checksum_type)) {
retval = KRB5KRB_AP_ERR_INAPP_CKSUM;
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_rd_safe_basic() error retval=%d",
retval);
goto cleanup;
@@ -94,6 +98,7 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyb
if (!krb5_address_compare(context, sender_addr, message->s_address)) {
retval = KRB5KRB_AP_ERR_BADADDR;
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_rd_safe_basic() error retval=%d",
retval);
goto cleanup;
@@ -103,6 +108,7 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyb
if (recv_addr) {
if (!krb5_address_compare(context, recv_addr, message->r_address)) {
retval = KRB5KRB_AP_ERR_BADADDR;
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_rd_safe_basic() error retval=%d",
retval);
goto cleanup;
@@ -110,15 +116,16 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyb
} else {
krb5_address **our_addrs;
- if ((retval = krb5_os_localaddr(context, &our_addrs))){
+ if ((retval = krb5_os_localaddr(context, &our_addrs))) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_rd_safe_basic() error retval=%d",
retval);
goto cleanup;
}
-
if (!krb5_address_search(context, message->r_address, our_addrs)) {
krb5_free_addresses(context, our_addrs);
retval = KRB5KRB_AP_ERR_BADADDR;
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_rd_safe_basic() error retval=%d",
retval);
goto cleanup;
@@ -142,34 +149,36 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyb
message->checksum = &our_cksum;
- if ((retval = encode_krb5_safe_with_body(message, &safe_body, &scratch))){
+ if ((retval = encode_krb5_safe_with_body(message, &safe_body, &scratch))) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_rd_safe_basic() error retval=%d",
retval);
goto cleanup;
}
message->checksum = his_cksum;
-
+
retval = krb5_c_verify_checksum(context, keyblock,
KRB5_KEYUSAGE_KRB_SAFE_CKSUM,
scratch, his_cksum, &valid);
(void) memset((char *)scratch->data, 0, scratch->length);
krb5_free_data(context, scratch);
-
+
if (!valid) {
/*
- * Checksum over only the KRB-SAFE-BODY, like RFC 1510 says, in
+ * Checksum over only the KRB-SAFE-BODY, like RFC 1510 says, in
* case someone actually implements it correctly.
*/
retval = krb5_c_verify_checksum(context, keyblock,
- KRB5_KEYUSAGE_KRB_SAFE_CKSUM,
- &safe_body, his_cksum, &valid);
+ KRB5_KEYUSAGE_KRB_SAFE_CKSUM,
+ &safe_body, his_cksum, &valid);
if (!valid) {
- retval = KRB5KRB_AP_ERR_MODIFIED;
- KRB5_LOG(KRB5_ERR, "krb5_rd_safe_basic() error retval=%d",
+ retval = KRB5KRB_AP_ERR_MODIFIED;
+ /* Solaris Kerberos */
+ KRB5_LOG(KRB5_ERR, "krb5_rd_safe_basic() error retval=%d",
retval);
- goto cleanup;
+ goto cleanup;
}
}
@@ -180,9 +189,10 @@ krb5_rd_safe_basic(krb5_context context, const krb5_data *inbuf, const krb5_keyb
*outbuf = message->user_data;
message->user_data.data = NULL;
retval = 0;
-
+
cleanup:
krb5_free_safe(context, message);
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_INFO, "krb5_rd_safe_basic() end, retval=%d",
retval);
return retval;
@@ -197,12 +207,12 @@ krb5_rd_safe(krb5_context context, krb5_auth_context auth_context, const krb5_da
if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) ||
(auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) &&
- (outdata == NULL))
+ (outdata == NULL))
/* Need a better error */
return KRB5_RC_REQUIRED;
if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) &&
- (auth_context->rcache == NULL))
+ (auth_context->rcache == NULL))
return KRB5_RC_REQUIRED;
/* Get keyblock */
@@ -219,7 +229,7 @@ krb5_rd_safe(krb5_context context, krb5_auth_context auth_context, const krb5_da
if (auth_context->local_addr) {
if (auth_context->local_port) {
if (!(retval = krb5_make_fulladdr(context, auth_context->local_addr,
- auth_context->local_port,
+ auth_context->local_port,
&local_fulladdr))){
CLEANUP_PUSH(local_fulladdr.contents, free);
plocal_fulladdr = &local_fulladdr;
@@ -234,7 +244,7 @@ krb5_rd_safe(krb5_context context, krb5_auth_context auth_context, const krb5_da
if (auth_context->remote_addr) {
if (auth_context->remote_port) {
if (!(retval = krb5_make_fulladdr(context,auth_context->remote_addr,
- auth_context->remote_port,
+ auth_context->remote_port,
&remote_fulladdr))){
CLEANUP_PUSH(remote_fulladdr.contents, free);
premote_fulladdr = &remote_fulladdr;
@@ -269,14 +279,14 @@ krb5_rd_safe(krb5_context context, krb5_auth_context auth_context, const krb5_da
goto error;
}
- if ((retval = krb5_gen_replay_name(context, auth_context->remote_addr,
+ if ((retval = krb5_gen_replay_name(context, auth_context->remote_addr,
"_safe", &replay.client)))
goto error;
replay.server = ""; /* XXX */
replay.cusec = replaydata.usec;
replay.ctime = replaydata.timestamp;
- if ((retval = krb5_rc_store(context, auth_context->rcache, &replay)) != 0) {
+ if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {
krb5_xfree(replay.client);
goto error;
}
@@ -307,3 +317,4 @@ error:
return retval;
}
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/recvauth.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/recvauth.c
index b09e4101de..6a5973f8ec 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/recvauth.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/recvauth.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/recvauth.c
@@ -15,7 +14,7 @@
* 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
@@ -29,15 +28,14 @@
* 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.
- *
+ *
*
* convenience sendauth/recvauth functions
*/
-#define NEED_SOCKETS
-#include <k5-int.h>
-#include <auth_con.h>
-#include <com_err.h>
+#include "k5-int.h"
+#include "auth_con.h"
+#include "com_err.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>
@@ -159,14 +157,14 @@ recvauth_common(krb5_context context,
* Setup the replay cache.
*/
if (server) {
- problem = krb5_get_server_rcache(context,
+ problem = krb5_get_server_rcache(context,
krb5_princ_component(context, server, 0), &rcache);
} else {
null_server.length = 7;
null_server.data = "default";
problem = krb5_get_server_rcache(context, &null_server, &rcache);
}
- if (!problem)
+ if (!problem)
problem = krb5_auth_con_setrcache(context, *auth_context, rcache);
local_rcache = 1;
}
@@ -187,7 +185,7 @@ recvauth_common(krb5_context context,
memset((char *)&error, 0, sizeof(error));
krb5_us_timeofday(context, &error.stime, &error.susec);
- if(server)
+ if(server)
error.server = server;
else {
/* If this fails - ie. ENOMEM we are hosed
@@ -206,12 +204,13 @@ recvauth_common(krb5_context context,
goto cleanup;
}
strcpy(error.text.data, message);
+ /* Solaris Kerberos */
if ((retval = krb5_mk_error(context, &error, &outbuf)) != 0) {
free(error.text.data);
goto cleanup;
}
free(error.text.data);
- if(need_error_free)
+ if(need_error_free)
krb5_free_principal(context, error.server);
} else {
@@ -243,6 +242,7 @@ cleanup:;
if (local_authcon) {
krb5_auth_con_free(context, *auth_context);
} else if (local_rcache && rcache != NULL) {
+ /* Solaris Kerberos */
(void) krb5_rc_close(context, rcache);
krb5_auth_con_setrcache(context, *auth_context, NULL);
}
@@ -253,7 +253,7 @@ cleanup:;
krb5_error_code KRB5_CALLCONV
krb5_recvauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointer fd, char *appl_version, krb5_principal server, krb5_int32 flags, krb5_keytab keytab, krb5_ticket **ticket)
{
- return recvauth_common(context, auth_context, fd, appl_version,
+ return recvauth_common (context, auth_context, fd, appl_version,
server, flags, keytab, ticket, 0);
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/send_tgs.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/send_tgs.c
index 6fd00f6ae4..c08c6b9bc3 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/send_tgs.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/send_tgs.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/send_tgs.c
@@ -15,7 +14,7 @@
* 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
@@ -29,34 +28,34 @@
* 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_send_tgs()
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
Sends a request to the TGS and waits for a response.
options is used for the options in the KRB_TGS_REQ.
timestruct values are used for from, till, rtime " " "
- enctype is used for enctype " " ", and to encrypt the authorization data,
+ enctype is used for enctype " " ", and to encrypt the authorization data,
sname is used for sname " " "
addrs, if non-NULL, is used for addresses " " "
authorization_dat, if non-NULL, is used for authorization_dat " " "
second_ticket, if required by options, is used for the 2nd ticket in the req.
in_cred is used for the ticket & session key in the KRB_AP_REQ header " " "
(the KDC realm is extracted from in_cred->server's realm)
-
+
The response is placed into *rep.
rep->response.data is set to point at allocated storage which should be
freed by the caller when finished.
returns system errors
*/
-static krb5_error_code
+static krb5_error_code
krb5_send_tgs_basic(krb5_context context, krb5_data *in_data, krb5_creds *in_cred, krb5_data *outbuf)
-{
+{
krb5_error_code retval;
krb5_checksum checksum;
krb5_authenticator authent;
@@ -65,11 +64,10 @@ krb5_send_tgs_basic(krb5_context context, krb5_data *in_data, krb5_creds *in_cre
krb5_data * toutbuf;
/* Generate checksum */
- retval = krb5_c_make_checksum(context, context->kdc_req_sumtype,
+ if ((retval = krb5_c_make_checksum(context, context->kdc_req_sumtype,
&in_cred->keyblock,
KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM,
- in_data, &checksum);
- if (retval) {
+ in_data, &checksum))) {
free(checksum.contents);
return(retval);
}
@@ -103,7 +101,7 @@ krb5_send_tgs_basic(krb5_context context, krb5_data *in_data, krb5_creds *in_cre
/* Cleanup scratch and scratch data */
goto cleanup_data;
- /* call the encryption routine */
+ /* call the encryption routine */
if ((retval = krb5_encrypt_helper(context, &in_cred->keyblock,
KRB5_KEYUSAGE_TGS_REQ_AUTH,
scratch, &request.authenticator)))
@@ -113,7 +111,7 @@ krb5_send_tgs_basic(krb5_context context, krb5_data *in_data, krb5_creds *in_cre
*outbuf = *toutbuf;
krb5_xfree(toutbuf);
-cleanup:
+
memset(request.authenticator.ciphertext.data, 0,
request.authenticator.ciphertext.length);
free(request.authenticator.ciphertext.data);
@@ -125,7 +123,6 @@ cleanup_data:
memset(scratch->data, 0, scratch->length);
free(scratch->data);
-cleanup_scratch:
free(scratch);
return retval;
@@ -149,7 +146,7 @@ krb5_send_tgs(krb5_context context, krb5_flags kdcoptions,
krb5_pa_data ap_req_padata;
int tcp_only = 0, use_master;
- /*
+ /*
* in_creds MUST be a valid credential NOT just a partially filled in
* place holder for us to get credentials for the caller.
*/
@@ -180,10 +177,10 @@ krb5_send_tgs(krb5_context context, krb5_flags kdcoptions,
&scratch)))
return(retval);
- retval = krb5_encrypt_helper(context, &in_cred->keyblock,
+ if ((retval = krb5_encrypt_helper(context, &in_cred->keyblock,
KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY,
- scratch, &tgsreq.authorization_data);
- if (retval) {
+ scratch,
+ &tgsreq.authorization_data))) {
krb5_xfree(tgsreq.authorization_data.ciphertext.data);
krb5_free_data(context, scratch);
return retval;
@@ -237,7 +234,7 @@ krb5_send_tgs(krb5_context context, krb5_flags kdcoptions,
krb5_pa_data * const * counter;
register unsigned int i = 0;
for (counter = padata; *counter; counter++, i++);
- combined_padata = (krb5_pa_data **)malloc(i+2);
+ combined_padata = malloc((i+2) * sizeof(*combined_padata));
if (!combined_padata) {
krb5_xfree(ap_req_padata.contents);
retval = ENOMEM;
@@ -279,6 +276,7 @@ send_again:
if (!tcp_only) {
krb5_error *err_reply;
retval = decode_krb5_error(&rep->response, &err_reply);
+ /* Solaris Kerberos */
if (retval == 0) {
if (err_reply->error == KRB_ERR_RESPONSE_TOO_BIG) {
tcp_only = 1;
@@ -299,7 +297,7 @@ send_again:
krb5_free_data(context, scratch);
send_tgs_error_2:;
- if (sec_ticket)
+ if (sec_ticket)
krb5_free_ticket(context, sec_ticket);
send_tgs_error_1:;
@@ -307,10 +305,9 @@ send_tgs_error_1:;
krb5_xfree(tgsreq.ktype);
if (tgsreq.authorization_data.ciphertext.data) {
memset(tgsreq.authorization_data.ciphertext.data, 0,
- tgsreq.authorization_data.ciphertext.length);
+ tgsreq.authorization_data.ciphertext.length);
krb5_xfree(tgsreq.authorization_data.ciphertext.data);
}
-
return retval;
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/sendauth.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/sendauth.c
index 5498150ba3..f3f51d32f6 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/sendauth.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/sendauth.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/sendauth.c
@@ -15,7 +14,7 @@
* 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
@@ -29,16 +28,15 @@
* 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.
- *
+ *
*
* convenience sendauth/recvauth functions
*/
-#define NEED_SOCKETS
-#include <k5-int.h>
-#include <com_err.h>
-#include <auth_con.h>
+#include "k5-int.h"
+#include "com_err.h"
+#include "auth_con.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>
@@ -50,8 +48,8 @@ krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointe
{
krb5_octet result;
krb5_creds creds;
- krb5_creds * credsp = NULL;
- krb5_creds * credspout = NULL;
+ krb5_creds * credsp = NULL;
+ krb5_creds * credspout = NULL;
krb5_error_code retval = 0;
krb5_data inbuf, outbuf;
int len;
@@ -64,7 +62,7 @@ krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointe
* First, send over the length of the sendauth version string;
* then, we send over the sendauth version. Next, we send
* over the length of the application version strings followed
- * by the string itself.
+ * by the string itself.
*/
outbuf.length = strlen(sendauth_version) + 1;
outbuf.data = (char *) sendauth_version;
@@ -103,6 +101,7 @@ krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointe
if (!in_creds || !in_creds->ticket.length) {
if (ccache)
use_ccache = ccache;
+ /* Solaris Kerberos */
else if ((retval = krb5int_cc_default(context, &use_ccache)) != 0)
goto error_return;
}
@@ -111,7 +110,7 @@ krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointe
&creds.server)))
goto error_return;
if (client)
- retval = krb5_copy_principal(context, client,
+ retval = krb5_copy_principal(context, client,
&creds.client);
else
retval = krb5_cc_get_principal(context, use_ccache,
@@ -128,6 +127,7 @@ krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointe
in_creds = &creds;
}
if (!in_creds->ticket.length) {
+ /* Solaris Kerberos */
if ((retval = krb5_get_credentials(context, 0,
use_ccache, in_creds, &credsp)) != 0)
goto error_return;
@@ -142,22 +142,27 @@ krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointe
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;
+ GETPEERNAME_ARG3_TYPE len2;
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;
+ len2 = sizeof (rnd_data);
+ if (getpeername (*(int*)fd, (GETPEERNAME_ARG2_TYPE *) rnd_data,
+ &len2) == 0) {
+ d.length = len2;
+ /* Solaris Kerberos */
(void) krb5_c_random_seed (context, &d);
}
- len = sizeof (rnd_data);
- if (getsockname (*(int*)fd, (struct sockaddr *) rnd_data, &len) == 0) {
- d.length = len;
+ len2 = sizeof (rnd_data);
+ if (getsockname (*(int*)fd, (GETSOCKNAME_ARG2_TYPE *) rnd_data,
+ &len2) == 0) {
+ d.length = len2;
+ /* Solaris Kerberos */
(void) krb5_c_random_seed (context, &d);
}
}
+ /* Solaris Kerberos */
if ((retval = krb5_mk_req_extended(context, auth_context,
ap_req_options, in_data, credsp,
&outbuf)) != 0)
@@ -178,11 +183,13 @@ krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointe
* authentication was rejected, and we need to return the
* error structure.
*/
+ /* Solaris Kerberos */
if ((retval = krb5_read_message(context, fd, &inbuf)) != 0)
goto error_return;
if (inbuf.length) {
if (error) {
+ /* Solaris Kerberos */
if ((retval = krb5_rd_error(context, &inbuf, error)) != 0) {
krb5_xfree(inbuf.data);
goto error_return;
@@ -199,10 +206,11 @@ krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointe
*/
if ((ap_req_options & AP_OPTS_MUTUAL_REQUIRED)) {
krb5_ap_rep_enc_part *repl = 0;
-
+ /* Solaris Kerberos */
if ((retval = krb5_read_message(context, fd, &inbuf)) != 0)
goto error_return;
+ /* Solaris Kerberos */
if ((retval = krb5_rd_rep(context, *auth_context, &inbuf,
&repl)) != 0) {
if (repl)
@@ -216,7 +224,7 @@ krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointe
* If the user wants to look at the AP_REP message,
* copy it for him
*/
- if (rep_result)
+ if (rep_result)
*rep_result = repl;
else
krb5_free_ap_rep_enc_part(context, repl);
@@ -230,8 +238,11 @@ krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointe
error_return:
krb5_free_cred_contents(context, &creds);
if (credspout != NULL)
- krb5_free_creds(context, credspout);
+ krb5_free_creds(context, credspout);
+ /* Solaris Kerberos */
if (!ccache && use_ccache)
(void) krb5_cc_close(context, use_ccache);
return(retval);
}
+
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/set_realm.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/set_realm.c
index d6f856faf3..08d71b9131 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/set_realm.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/set_realm.c
@@ -1,6 +1,5 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
@@ -38,12 +37,12 @@ krb5_set_principal_realm(krb5_context context, krb5_principal principal, const c
char *newrealm;
if (!realm || !*realm)
- return EINVAL;
+ return EINVAL; /* Solaris Kerberos */
length = strlen(realm);
newrealm = malloc(length+1); /* Include room for the null */
if (!newrealm)
- return ENOMEM;
+ return ENOMEM; /* Solaris Kerberos */
strcpy(newrealm, realm);
(void) krb5_xfree(krb5_princ_realm(context,principal)->data);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/srv_rcache.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/srv_rcache.c
index 15cfc31871..645d815a75 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/srv_rcache.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/srv_rcache.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/srv_rcache.c
@@ -15,7 +14,7 @@
* 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
@@ -29,15 +28,16 @@
* 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.
- *
+ *
*
* Allocate & prepare a default replay cache for a server.
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include <ctype.h>
#include <stdio.h>
+/* Macro for valid RC name characters*/
#define isvalidrcname(x) ((!ispunct(x))&&isgraph(x))
krb5_error_code KRB5_CALLCONV
krb5_get_server_rcache(krb5_context context, const krb5_data *piece,
@@ -57,12 +57,12 @@ krb5_get_server_rcache(krb5_context context, const krb5_data *piece,
if (piece == NULL)
return ENOMEM;
-
+
cachetype = krb5_rc_default_type(context);
/*
- * Solaris: Check to see if something other than the default replay cache
- * name will be used. If so then skip over the construction of
+ * Solaris Kerberos: Check to see if something other than the default replay
+ * cache name will be used. If so then skip over the construction of
* said name.
*/
if ((def_env = krb5_rc_default_name(context)) != 0) {
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/str_conv.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/str_conv.c
index 33fdecb546..bd4664a865 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/str_conv.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/str_conv.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/kadm/str_conv.c
@@ -70,7 +69,8 @@ struct salttype_lookup_entry {
/*
* Lookup tables.
*/
-#include <krb5/kdb.h>
+
+#include "kdb.h"
static const struct salttype_lookup_entry salttype_table[] = {
/* salt type input specifier output string */
/*----------------------------- --------------- ---------------*/
@@ -161,18 +161,14 @@ krb5_string_to_timestamp(char *string, krb5_timestamp *timestampp)
struct tm timebuf;
time_t now, ret_time;
char *s;
-/*
- * Solaris Kerberos:
- * The format strings shouldn't conflict with SCCS keywords
- */
static const char * const atime_format_table[] = {
- "%Y" "%m" "%d" "%H" "%M" "%S", /* yyyymmddhhmmss */
+ "%Y%m%d%H%M%S", /* yyyymmddhhmmss */
"%Y.%m.%d.%H.%M.%S", /* yyyy.mm.dd.hh.mm.ss */
- "%y" "%m" "%d" "%H" "%M" "%S", /* yymmddhhmmss */
+ "%y%m%d%H%M%S", /* yymmddhhmmss */
"%y.%m.%d.%H.%M.%S", /* yy.mm.dd.hh.mm.ss */
- "%y" "%m" "%d" "%H" "%M", /* yymmddhhmm */
- "%H" "%M" "%S", /* hhmmss */
- "%H" "%M", /* hhmm */
+ "%y%m%d%H%M", /* yymmddhhmm */
+ "%H%M%S", /* hhmmss */
+ "%H%M", /* hhmm */
"%T", /* hh:mm:ss */
"%R", /* hh:mm */
/* The following not really supported unless native strptime present */
@@ -279,6 +275,7 @@ krb5_timestamp_to_sfstring(krb5_timestamp timestamp, char *buffer, size_t buflen
return((ndone) ? 0 : ENOMEM);
}
+/* Solaris Kerberos */
#ifdef SUNW_INC_DEAD_CODE
/* relative time (delta-t) conversions */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/tgtname.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/tgtname.c
index 2df606adb6..4ca2416233 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/tgtname.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/tgtname.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/tgtname.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/valid_times.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/valid_times.c
index 4da220ae31..9c53d7d919 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/valid_times.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/valid_times.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/valid_times.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -34,9 +36,8 @@
* field in a krb5_ticket.
*/
-krb5_error_code krb5_validate_times(context, times)
- krb5_context context;
- krb5_ticket_times * times;
+krb5_error_code
+krb5_validate_times(krb5_context context, krb5_ticket_times *times)
{
krb5_timestamp currenttime, starttime;
krb5_error_code retval;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/vfy_increds.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/vfy_increds.c
index e86e2eb49c..d3720d3eaa 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/vfy_increds.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/vfy_increds.c
@@ -1,12 +1,12 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "int-proto.h"
+/* Solaris Kerberos */
extern krb5_error_code krb5_libdefault_boolean();
static krb5_error_code
@@ -18,14 +18,18 @@ krb5_cc_copy_creds_except(krb5_context context, krb5_ccache incc, krb5_ccache ou
krb5_creds creds;
flags = 0; /* turns off OPENCLOSE mode */
+ /* Solaris Kerberos */
if ((code = krb5_cc_set_flags(context, incc, flags)) != NULL)
return(code);
+ /* Solaris Kerberos */
if ((code = krb5_cc_set_flags(context, outcc, flags)) != NULL)
return(code);
+ /* Solaris Kerberos */
if ((code = krb5_cc_start_seq_get(context, incc, &cur)) != NULL)
goto cleanup;
+ /* Solaris Kerberos */
while ((code = krb5_cc_next_cred(context, incc, &cur, &creds)) == NULL) {
if (krb5_principal_compare(context, princ, creds.server))
continue;
@@ -44,11 +48,13 @@ krb5_cc_copy_creds_except(krb5_context context, krb5_ccache incc, krb5_ccache ou
cleanup:
flags = KRB5_TC_OPENCLOSE;
+ /* Solaris Kerberos */
if (code)
(void) krb5_cc_set_flags(context, incc, flags);
else
code = krb5_cc_set_flags(context, incc, flags);
+ /* Solaris Kerberos */
if (code)
(void) krb5_cc_set_flags(context, outcc, flags);
else
@@ -83,6 +89,7 @@ krb5_verify_init_creds(krb5_context context,
authcon = NULL;
ap_req.data = NULL;
+ /* Solaris Kerberos */
if (server_arg)
server = server_arg;
else if (ret = krb5_sname_to_principal(context, NULL, NULL,
@@ -101,12 +108,15 @@ krb5_verify_init_creds(krb5_context context,
ret = krb5_kt_default(context, &keytab);
}
- /* Warning: be very, very careful when modifying the logic here */
+ /*
+ * Solaris Kerberos:
+ * Warning: be very, very careful when modifying the logic here
+ */
if (keytab == NULL ||
(ret = krb5_kt_get_entry(context, keytab, server, 0, 0, &kte))) {
/* this means there is no keying material. This is ok, as long as
it is not prohibited by the configuration */
-
+ /* Solaris Kerberos */
int nofail = 1; /* Solaris Kerberos: default return error if keytab problems */
if (options &&
@@ -115,6 +125,7 @@ krb5_verify_init_creds(krb5_context context,
nofail = options->ap_req_nofail;
} else {
/*
+ * Solaris Kerberos:
* Check verify_ap_req_nofail if set in config file. Note this logic
* assumes that krb5_libdefault_boolean will not set nofail to a
* default value if verify_ap_req_nofail is not explictly set in
@@ -139,7 +150,7 @@ krb5_verify_init_creds(krb5_context context,
if (krb5_principal_compare(context, server, creds->server)) {
/* make an ap_req */
if ((ret = krb5_mk_req_extended(context, &authcon, 0, NULL, creds,
- &ap_req)))
+ &ap_req)))
goto cleanup;
} else {
/* this is unclean, but it's the easiest way without ripping the
@@ -153,10 +164,11 @@ krb5_verify_init_creds(krb5_context context,
if ((ret = krb5_cc_resolve(context, "MEMORY:rd_req", &ccache)))
goto cleanup;
-
+ /* Solaris Kerberos */
if ((ret = krb5_cc_initialize(context, ccache, creds->client)) != NULL)
goto cleanup;
+ /* Solaris Kerberos */
if ((ret = krb5_cc_store_cred(context, ccache, creds)) != NULL)
goto cleanup;
@@ -169,12 +181,12 @@ krb5_verify_init_creds(krb5_context context,
in_creds.times.endtime += 5*60;
if ((ret = krb5_get_credentials(context, 0, ccache, &in_creds,
- &out_creds)))
+ &out_creds)))
goto cleanup;
/* make an ap_req */
if ((ret = krb5_mk_req_extended(context, &authcon, 0, NULL, out_creds,
- &ap_req)))
+ &ap_req)))
goto cleanup;
}
@@ -187,7 +199,7 @@ krb5_verify_init_creds(krb5_context context,
/* verify the ap_req */
if ((ret = krb5_rd_req(context, &authcon, &ap_req, server, keytab,
- NULL, NULL)))
+ NULL, NULL)))
goto cleanup;
/* if we get this far, then the verification succeeded. We can
@@ -199,10 +211,12 @@ krb5_verify_init_creds(krb5_context context,
retcc = NULL;
+ /* Solaris Kerberos */
if (((ret = krb5_cc_resolve(context, "MEMORY:rd_req2", &retcc)) != NULL) ||
((ret = krb5_cc_initialize(context, retcc, creds->client)) != NULL) ||
((ret = krb5_cc_copy_creds_except(context, ccache, retcc,
creds->server)) != NULL)) {
+ /* Solaris Kerberos */
if (retcc)
(void) krb5_cc_destroy(context, retcc);
} else {
@@ -220,8 +234,10 @@ krb5_verify_init_creds(krb5_context context,
cleanup:
if (!server_arg && server)
krb5_free_principal(context, server);
+ /* Solaris Kerberos */
if (!keytab_arg && keytab)
(void) krb5_kt_close(context, keytab);
+ /* Solaris Kerberos */
if (ccache)
(void) krb5_cc_destroy(context, ccache);
if (out_creds)
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/accessor.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/accessor.c
index 7540d0386d..a6b1c9c680 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/accessor.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/accessor.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/krb5/os/accessor.c
*
@@ -79,6 +77,36 @@ krb5int_accessor(krb5int_access *internals, krb5_int32 version)
S (krb5_ser_unpack_int64, krb5_ser_unpack_int64),
S (asn1_ldap_encode_sequence_of_keys, krb5int_ldap_encode_sequence_of_keys),
S (asn1_ldap_decode_sequence_of_keys, krb5int_ldap_decode_sequence_of_keys),
+ S (encode_krb5_pa_pk_as_req, encode_krb5_pa_pk_as_req),
+ S (encode_krb5_pa_pk_as_req_draft9, encode_krb5_pa_pk_as_req_draft9),
+ S (encode_krb5_pa_pk_as_rep, encode_krb5_pa_pk_as_rep),
+ S (encode_krb5_pa_pk_as_rep_draft9, encode_krb5_pa_pk_as_rep_draft9),
+ S (encode_krb5_auth_pack, encode_krb5_auth_pack),
+ S (encode_krb5_auth_pack_draft9, encode_krb5_auth_pack_draft9),
+ S (encode_krb5_kdc_dh_key_info, encode_krb5_kdc_dh_key_info),
+ S (encode_krb5_reply_key_pack, encode_krb5_reply_key_pack),
+ S (encode_krb5_reply_key_pack_draft9, encode_krb5_reply_key_pack_draft9),
+ S (encode_krb5_typed_data, encode_krb5_typed_data),
+ S (encode_krb5_td_trusted_certifiers, encode_krb5_td_trusted_certifiers),
+ S (encode_krb5_td_dh_parameters, encode_krb5_td_dh_parameters),
+ S (decode_krb5_pa_pk_as_req, decode_krb5_pa_pk_as_req),
+ S (decode_krb5_pa_pk_as_req_draft9, decode_krb5_pa_pk_as_req_draft9),
+ S (decode_krb5_pa_pk_as_rep, decode_krb5_pa_pk_as_rep),
+ S (decode_krb5_pa_pk_as_rep_draft9, decode_krb5_pa_pk_as_rep_draft9),
+ S (decode_krb5_auth_pack, decode_krb5_auth_pack),
+ S (decode_krb5_auth_pack_draft9, decode_krb5_auth_pack_draft9),
+ S (decode_krb5_kdc_dh_key_info, decode_krb5_kdc_dh_key_info),
+ S (decode_krb5_principal_name, decode_krb5_principal_name),
+ S (decode_krb5_reply_key_pack, decode_krb5_reply_key_pack),
+ S (decode_krb5_reply_key_pack_draft9, decode_krb5_reply_key_pack_draft9),
+ S (decode_krb5_typed_data, decode_krb5_typed_data),
+ S (decode_krb5_td_trusted_certifiers, decode_krb5_td_trusted_certifiers),
+ S (decode_krb5_td_dh_parameters, decode_krb5_td_dh_parameters),
+ S (decode_krb5_as_req, decode_krb5_as_req),
+ S (encode_krb5_kdc_req_body, encode_krb5_kdc_req_body),
+ S (krb5_free_kdc_req, krb5_free_kdc_req),
+ S (krb5int_set_prompt_types, krb5int_set_prompt_types),
+ S (encode_krb5_authdata_elt, encode_krb5_authdata_elt),
#if DESIGNATED_INITIALIZERS
};
#else
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/an_to_ln.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/an_to_ln.c
index 6296380170..0a42126049 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/an_to_ln.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/an_to_ln.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/an_to_ln.c
@@ -15,7 +14,7 @@
* 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
@@ -29,21 +28,18 @@
* 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_aname_to_localname()
*/
-
/*
* We're only to AN_TO_LN rules at this point, and not doing the
* database lookup (moved from configure script)
*/
-#ifndef AN_TO_LN_RULES
#define AN_TO_LN_RULES
-#endif
-#include <k5-int.h>
+#include "k5-int.h"
#include <ctype.h>
#if HAVE_REGEX_H
#include <regex.h>
@@ -68,13 +64,6 @@
#define KDBM_OPEN(db, fl, mo) dbm_open(db, fl, mo)
#define KDBM_CLOSE(db) dbm_close(db)
#define KDBM_FETCH(db, key) dbm_fetch(db, key)
-#else /*ANAME_DB*/
-extern DBM *db_dbm_open (char *, int, int);
-extern void db_dbm_close (DBM *);
-extern datum db_dbm_fetch (DBM *, datum);
-#define KDBM_OPEN(db, fl, mo) db_dbm_open(db, fl, mo)
-#define KDBM_CLOSE(db) db_dbm_close(db)
-#define KDBM_FETCH(db, key) db_dbm_fetch(db, key)
#endif /*ANAME_DB*/
/*
@@ -198,7 +187,7 @@ db_an_to_ln(context, dbname, aname, lnsize, lname)
* <rule> ...
* Where: <rule> is of the form:
* "s/" <regexp> "/" <text> "/" ["g"]
- *
+ *
* In order to be able to select rule validity, the native system must support
* one of compile(3), re_comp(3) or regcomp(3). In order to be able to
* transform (e.g. substitute), the native system must support regcomp(3) or
@@ -208,7 +197,7 @@ db_an_to_ln(context, dbname, aname, lnsize, lname)
/*
* aname_do_match() - Does our name match the parenthesized regular
* expression?
- *
+ *
* Chew up the match portion of the regular expression and update *contextp.
* If no re_comp() or regcomp(), then always return a match.
*/
@@ -256,8 +245,7 @@ aname_do_match(char *string, char **contextp)
#elif HAVE_REGEXPR_H
compile(regexp,
regexp_buffer,
- &regexp_buffer[RE_BUF_SIZE],
- '\0');
+ &regexp_buffer[RE_BUF_SIZE]);
if (step(string, regexp_buffer)) {
if ((loc1 == string) &&
(loc2 == &string[strlen(string)]))
@@ -290,8 +278,8 @@ aname_do_match(char *string, char **contextp)
* string.
*/
#define use_bytes(x) \
- out_used += (x); \
- if (out_used > MAX_FORMAT_BUFFER) goto mem_err
+ out_used += (x); \
+ if (out_used > MAX_FORMAT_BUFFER) goto mem_err
static int
do_replacement(char *regexp, char *repl, int doall, char *in, char *out)
@@ -342,8 +330,7 @@ do_replacement(char *regexp, char *repl, int doall, char *in, char *out)
compile(regexp,
regexp_buffer,
- &regexp_buffer[RE_BUF_SIZE],
- '\0');
+ &regexp_buffer[RE_BUF_SIZE]);
cp = in;
op = out;
matched = 0;
@@ -406,6 +393,7 @@ aname_replacer(char *string, char **contextp, char **result)
kret = ENOMEM;
*result = (char *) NULL;
/* Allocate the formatting buffers */
+ /* Solaris Kerberos */
if (((in = (char *) malloc(MAX_FORMAT_BUFFER)) != NULL) &&
((out = (char *) malloc(MAX_FORMAT_BUFFER)) != NULL)) {
/*
@@ -421,10 +409,11 @@ aname_replacer(char *string, char **contextp, char **result)
*/
for (cp = *contextp; *cp; ) {
/* Skip leading whitespace */
- while (isspace(*cp))
+ while (isspace((int) (*cp)))
cp++;
/*
+ * Solaris Kerberos
* Find our separators. First two characters must be "s<sep>"
* We must also find another "<sep>" followed by another * "<sep>".
*/
@@ -446,6 +435,7 @@ aname_replacer(char *string, char **contextp, char **result)
/* Figure out sizes of strings and allocate them */
rule_size = (size_t) (ep - &cp[2]);
repl_size = (size_t) (tp - &ep[1]);
+ /* Solaris Kerberos */
if (((rule = (char *) malloc(rule_size+1)) != NULL) &&
((repl = (char *) malloc(repl_size+1)) != NULL)) {
@@ -511,8 +501,7 @@ aname_replacer(char *string, char **contextp, char **result)
* the principal name.
*/
static krb5_error_code
-rule_an_to_ln(krb5_context context, char *rule,
- krb5_const_principal aname, const int lnsize, char *lname)
+rule_an_to_ln(krb5_context context, char *rule, krb5_const_principal aname, const unsigned int lnsize, char *lname)
{
krb5_error_code kret;
char *current;
@@ -555,9 +544,12 @@ rule_an_to_ln(krb5_context context, char *rule,
if (*current == '$') {
if ((sscanf(current+1, "%d", &compind) == 1) &&
(compind <= num_comps) &&
- (datap = (compind > 0) ?
- krb5_princ_component(context, aname, compind-1) :
- krb5_princ_realm(context, aname))) {
+ (datap =
+ (compind > 0)
+ ? krb5_princ_component(context, aname,
+ compind-1)
+ : krb5_princ_realm(context, aname))
+ ) {
if ((datap->length < MAX_FORMAT_BUFFER)
&& (selstring_used+datap->length
< MAX_FORMAT_BUFFER)) {
@@ -573,7 +565,7 @@ rule_an_to_ln(krb5_context context, char *rule,
*cout = '\0';
current++;
/* Point past number */
- while (isdigit((int) *current))
+ while (isdigit((int) (*current)))
current++;
}
else
@@ -691,20 +683,18 @@ an_to_ln_realm_chk(
* that name is returned as the lname.
*/
static krb5_error_code
-default_an_to_ln(krb5_context context, krb5_const_principal aname,
- const int lnsize, char *lname)
+default_an_to_ln(krb5_context context, krb5_const_principal aname, const unsigned int lnsize, char *lname)
{
krb5_error_code retval;
char *def_realm;
unsigned int realm_length;
realm_length = krb5_princ_realm(context, aname)->length;
-
-
+
if ((retval = krb5_get_default_realm(context, &def_realm))) {
return(retval);
}
-
+ /* Solaris Kerberos */
/* compare against default realm and auth_to_local_realm(s) */
if ((((size_t) realm_length != strlen(def_realm)) ||
(memcmp(def_realm, krb5_princ_realm(context, aname)->data,
@@ -718,11 +708,11 @@ default_an_to_ln(krb5_context context, krb5_const_principal aname,
if (krb5_princ_size(context, aname) != 1) {
if (krb5_princ_size(context, aname) == 2 ) {
/* Check to see if 2nd component is the local realm. */
- if (strncmp(krb5_princ_component(context, aname, 1)->data,
- def_realm, realm_length) ||
- realm_length !=
- krb5_princ_component(context, aname, 1)->length) {
+ if ( strncmp(krb5_princ_component(context, aname,1)->data,def_realm,
+ realm_length) ||
+ realm_length != krb5_princ_component(context, aname,1)->length) {
/* XXX an_to_ln_realm_chk ? */
+ /* Solaris Kerberos */
free(def_realm);
return KRB5_LNAME_NOTRANS;
}
@@ -730,13 +720,14 @@ default_an_to_ln(krb5_context context, krb5_const_principal aname,
else {
/* no components or more than one component to non-realm part of name
--no translation. */
+ /* Solaris Kerberos */
free(def_realm);
return KRB5_LNAME_NOTRANS;
}
}
free(def_realm);
- strncpy(lname, krb5_princ_component(context, aname,0)->data,
+ strncpy(lname, krb5_princ_component(context, aname,0)->data,
min(krb5_princ_component(context, aname,0)->length,lnsize));
if (lnsize <= krb5_princ_component(context, aname,0)->length ) {
retval = KRB5_CONFIG_NOTENUFSPACE;
@@ -759,9 +750,8 @@ default_an_to_ln(krb5_context context, krb5_const_principal aname,
returns system errors, NOT_ENOUGH_SPACE
*/
-krb5_error_code
-krb5_aname_to_localname(krb5_context context,
- krb5_const_principal aname, const int lnsize_in, char *lname)
+krb5_error_code KRB5_CALLCONV
+krb5_aname_to_localname(krb5_context context, krb5_const_principal aname, const int lnsize_in, char *lname)
{
krb5_error_code kret;
char *realm;
@@ -775,7 +765,7 @@ krb5_aname_to_localname(krb5_context context,
unsigned int lnsize;
if (lnsize_in < 0)
- return KRB5_CONFIG_NOTENUFSPACE;
+ return KRB5_CONFIG_NOTENUFSPACE;
lnsize = lnsize_in; /* Unsigned */
@@ -914,3 +904,4 @@ krb5_aname_to_localname(krb5_context context,
}
return(kret);
}
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/changepw.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/changepw.c
index 760f47e1e9..816713dc44 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/changepw.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/changepw.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/krb5/os/changepw.c
*
@@ -29,12 +27,13 @@
/*
* krb5_set_password - Implements set password per RFC 3244
* Added by Paul W. Nelson, Thursby Software Systems, Inc.
+ * Modified by Todd Stecher, Isilon Systems, to use krb1.4 socket infrastructure
*/
-#define NEED_SOCKETS
#include "fake-addrinfo.h"
#include "k5-int.h"
#include "os-proto.h"
+#include "cm.h"
#include <stdio.h>
#include <errno.h>
@@ -43,31 +42,42 @@
#define GETSOCKNAME_ARG3_TYPE int
#endif
+struct sendto_callback_context {
+ krb5_context context;
+ krb5_auth_context auth_context;
+ krb5_principal set_password_for;
+ char *newpw;
+ krb5_data ap_req;
+};
+
+
/*
* Wrapper function for the two backends
*/
static krb5_error_code
krb5_locate_kpasswd(krb5_context context, const krb5_data *realm,
- struct addrlist *addrlist)
+ struct addrlist *addrlist, krb5_boolean useTcp)
{
krb5_error_code code;
+ int sockType = (useTcp ? SOCK_STREAM : SOCK_DGRAM);
+
+ code = krb5int_locate_server (context, realm, addrlist,
+ locate_service_kpasswd, sockType, 0);
- code = krb5int_locate_server (context, realm, addrlist, 0,
- "kpasswd_server", "_kpasswd", 0,
- htons(DEFAULT_KPASSWD_PORT), 0, 0);
if (code == KRB5_REALM_CANT_RESOLVE || code == KRB5_REALM_UNKNOWN) {
- code = krb5int_locate_server (context, realm, addrlist, 0,
- "admin_server", "_kerberos-adm", 1,
- DEFAULT_KPASSWD_PORT, 0, 0);
+ code = krb5int_locate_server (context, realm, addrlist,
+ locate_service_kadmin, SOCK_STREAM, 0);
if (!code) {
/* Success with admin_server but now we need to change the
- port number to use DEFAULT_KPASSWD_PORT. */
+ port number to use DEFAULT_KPASSWD_PORT and the socktype. */
int i;
- for ( i=0;i<addrlist->naddrs;i++ ) {
- struct addrinfo *a = addrlist->addrs[i];
+ for (i=0; i<addrlist->naddrs; i++) {
+ struct addrinfo *a = addrlist->addrs[i].ai;
if (a->ai_family == AF_INET)
sa2sin (a->ai_addr)->sin_port = htons(DEFAULT_KPASSWD_PORT);
+ if (sockType != SOCK_STREAM)
+ a->ai_socktype = sockType;
}
}
}
@@ -75,252 +85,227 @@ krb5_locate_kpasswd(krb5_context context, const krb5_data *realm,
}
-/*
-** The logic for setting and changing a password is mostly the same
-** krb5_change_set_password handles both cases
-** if set_password_for is NULL, then a password change is performed,
-** otherwise, the password is set for the principal indicated in set_password_for
-*/
-krb5_error_code KRB5_CALLCONV
-krb5_change_set_password(
- krb5_context context, krb5_creds *creds, char *newpw, krb5_principal set_password_for,
- int *result_code, krb5_data *result_code_string, krb5_data *result_string)
+/**
+ * This routine is used for a callback in sendto_kdc.c code. Simply
+ * put, we need the client addr to build the krb_priv portion of the
+ * password request.
+ */
+
+
+static void kpasswd_sendto_msg_cleanup (void* callback_context, krb5_data* message)
{
- krb5_auth_context auth_context;
- krb5_data ap_req, chpw_req, chpw_rep;
- krb5_address local_kaddr, remote_kaddr;
- char *code_string;
- krb5_error_code code = 0;
- int i;
- GETSOCKNAME_ARG3_TYPE addrlen;
- struct sockaddr_storage local_addr, remote_addr, tmp_addr;
- int cc, local_result_code;
- /* platforms seem to be consistant and use the same types */
- GETSOCKNAME_ARG3_TYPE tmp_len;
- SOCKET s1 = INVALID_SOCKET, s2 = INVALID_SOCKET;
- int tried_one = 0;
- struct addrlist al = ADDRLIST_INIT;
-
-
- /* Initialize values so that cleanup call can safely check for NULL */
- auth_context = NULL;
- memset(&chpw_req, 0, sizeof(krb5_data));
- memset(&chpw_rep, 0, sizeof(krb5_data));
- memset(&ap_req, 0, sizeof(krb5_data));
-
- /* initialize auth_context so that we know we have to free it */
- if ((code = krb5_auth_con_init(context, &auth_context)))
- goto cleanup;
-
- if ((code = krb5_mk_req_extended(context, &auth_context,
- AP_OPTS_USE_SUBKEY,
- NULL, creds, &ap_req)))
- goto cleanup;
-
- if ((code = krb5_locate_kpasswd(context,
- krb5_princ_realm(context, creds->server),
- &al)))
- goto cleanup;
-
- /* this is really obscure. s1 is used for all communications. it
- is left unconnected in case the server is multihomed and routes
- are asymmetric. s2 is connected to resolve routes and get
- addresses. this is the *only* way to get proper addresses for
- multihomed hosts if routing is asymmetric.
-
- A related problem in the server, but not the client, is that
- many os's have no way to disconnect a connected udp socket, so
- the s2 socket needs to be closed and recreated for each
- request. The s1 socket must not be closed, or else queued
- requests will be lost.
-
- A "naive" client implementation (one socket, no connect,
- hostname resolution to get the local ip addr) will work and
- interoperate if the client is single-homed. */
-
- if ((s1 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
- code = SOCKET_ERRNO;
- goto cleanup;
- }
+ struct sendto_callback_context *ctx = callback_context;
+ krb5_free_data_contents(ctx->context, message);
+}
+
+
+static int kpasswd_sendto_msg_callback(struct conn_state *conn, void *callback_context, krb5_data* message)
+{
+ krb5_error_code code = 0;
+ struct sockaddr_storage local_addr;
+ krb5_address local_kaddr;
+ struct sendto_callback_context *ctx = callback_context;
+ GETSOCKNAME_ARG3_TYPE addrlen;
+ krb5_data output;
+
+ memset (message, 0, sizeof(krb5_data));
+
+ /*
+ * We need the local addr from the connection socket
+ */
+ addrlen = sizeof(local_addr);
- if ((s2 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
+ if (getsockname(conn->fd, ss2sa(&local_addr), &addrlen) < 0) {
code = SOCKET_ERRNO;
goto cleanup;
}
- /*
- * This really should try fallback addresses in cases of timeouts.
- * For now, where the MIT KDC implementation only supports one
- * kpasswd server machine anyways, we'll only try the first IPv4
- * address we can connect() to. This isn't right for multi-homed
- * servers; oh well.
- */
- for (i=0; i<al.naddrs; i++) {
- fd_set fdset;
- struct timeval timeout;
+ /* some brain-dead OS's don't return useful information from
+ * the getsockname call. Namely, windows and solaris. */
- /* XXX Now the locate_ functions can return IPv6 addresses. */
- if (al.addrs[i]->ai_family != AF_INET)
- continue;
+ if (ss2sin(&local_addr)->sin_addr.s_addr != 0) {
+ local_kaddr.addrtype = ADDRTYPE_INET;
+ local_kaddr.length = sizeof(ss2sin(&local_addr)->sin_addr);
+ local_kaddr.contents = (krb5_octet *) &ss2sin(&local_addr)->sin_addr;
+ } else {
+ krb5_address **addrs;
- tried_one = 1;
- if (connect(s2, al.addrs[i]->ai_addr, al.addrs[i]->ai_addrlen) == SOCKET_ERROR) {
- if (SOCKET_ERRNO == ECONNREFUSED || SOCKET_ERRNO == EHOSTUNREACH)
- continue; /* try the next addr */
+ code = krb5_os_localaddr(ctx->context, &addrs);
+ if (code)
+ goto cleanup;
- code = SOCKET_ERRNO;
+ local_kaddr.magic = addrs[0]->magic;
+ local_kaddr.addrtype = addrs[0]->addrtype;
+ local_kaddr.length = addrs[0]->length;
+ local_kaddr.contents = malloc(addrs[0]->length);
+ if (local_kaddr.contents == NULL && addrs[0]->length != 0) {
+ code = errno;
+ krb5_free_addresses(ctx->context, addrs);
goto cleanup;
}
+ memcpy(local_kaddr.contents, addrs[0]->contents, addrs[0]->length);
- addrlen = sizeof(local_addr);
+ krb5_free_addresses(ctx->context, addrs);
+ }
- if (getsockname(s2, ss2sa(&local_addr), &addrlen) < 0) {
- if (SOCKET_ERRNO == ECONNREFUSED || SOCKET_ERRNO == EHOSTUNREACH)
- continue; /* try the next addr */
- code = SOCKET_ERRNO;
- goto cleanup;
- }
+ /*
+ * TBD: Does this tamper w/ the auth context in such a way
+ * to break us? Yes - provide 1 per conn-state / host...
+ */
- /* some brain-dead OS's don't return useful information from
- * the getsockname call. Namely, windows and solaris. */
- if (ss2sin(&local_addr)->sin_addr.s_addr != 0) {
- local_kaddr.addrtype = ADDRTYPE_INET;
- local_kaddr.length = sizeof(ss2sin(&local_addr)->sin_addr);
- local_kaddr.contents = (krb5_octet *) &ss2sin(&local_addr)->sin_addr;
- } else {
- krb5_address **addrs;
+ if ((code = krb5_auth_con_setaddrs(ctx->context, ctx->auth_context,
+ &local_kaddr, NULL)))
+ goto cleanup;
- krb5_os_localaddr(context, &addrs);
+ if (ctx->set_password_for)
+ code = krb5int_mk_setpw_req(ctx->context,
+ ctx->auth_context,
+ &ctx->ap_req,
+ ctx->set_password_for,
+ ctx->newpw,
+ &output);
+ else
+ code = krb5int_mk_chpw_req(ctx->context,
+ ctx->auth_context,
+ &ctx->ap_req,
+ ctx->newpw,
+ &output);
+ if (code)
+ goto cleanup;
- local_kaddr.magic = addrs[0]->magic;
- local_kaddr.addrtype = addrs[0]->addrtype;
- local_kaddr.length = addrs[0]->length;
- local_kaddr.contents = malloc(addrs[0]->length);
- memcpy(local_kaddr.contents, addrs[0]->contents, addrs[0]->length);
+ message->length = output.length;
+ message->data = output.data;
- krb5_free_addresses(context, addrs);
- }
+cleanup:
+ return code;
+}
+
+
+/*
+** The logic for setting and changing a password is mostly the same
+** krb5_change_set_password handles both cases
+** if set_password_for is NULL, then a password change is performed,
+** otherwise, the password is set for the principal indicated in set_password_for
+*/
+krb5_error_code KRB5_CALLCONV
+krb5_change_set_password(krb5_context context, krb5_creds *creds, char *newpw,
+ krb5_principal set_password_for,
+ int *result_code, krb5_data *result_code_string,
+ krb5_data *result_string)
+{
+ krb5_data chpw_rep;
+ krb5_address remote_kaddr;
+ krb5_boolean useTcp = 0;
+ GETSOCKNAME_ARG3_TYPE addrlen;
+ krb5_error_code code = 0;
+ char *code_string;
+ int local_result_code;
+
+ struct sendto_callback_context callback_ctx;
+ struct sendto_callback_info callback_info;
+ struct sockaddr_storage remote_addr;
+ struct addrlist al = ADDRLIST_INIT;
+
+ memset( &callback_ctx, 0, sizeof(struct sendto_callback_context));
+ callback_ctx.context = context;
+ callback_ctx.newpw = newpw;
+ callback_ctx.set_password_for = set_password_for;
+
+ if ((code = krb5_auth_con_init(callback_ctx.context,
+ &callback_ctx.auth_context)))
+ goto cleanup;
+
+ if ((code = krb5_mk_req_extended(callback_ctx.context,
+ &callback_ctx.auth_context,
+ AP_OPTS_USE_SUBKEY,
+ NULL,
+ creds,
+ &callback_ctx.ap_req)))
+ goto cleanup;
+
+ do {
+ if ((code = krb5_locate_kpasswd(callback_ctx.context,
+ krb5_princ_realm(callback_ctx.context,
+ creds->server),
+ &al, useTcp)))
+ break;
addrlen = sizeof(remote_addr);
- if (getpeername(s2, ss2sa(&remote_addr), &addrlen) < 0) {
- if (SOCKET_ERRNO == ECONNREFUSED || SOCKET_ERRNO == EHOSTUNREACH)
- continue; /* try the next addr */
- code = SOCKET_ERRNO;
- goto cleanup;
+ callback_info.context = (void*) &callback_ctx;
+ callback_info.pfn_callback = kpasswd_sendto_msg_callback;
+ callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup;
+
+ if ((code = krb5int_sendto(callback_ctx.context,
+ NULL,
+ &al,
+ &callback_info,
+ &chpw_rep,
+ NULL,
+ NULL,
+ ss2sa(&remote_addr),
+ &addrlen,
+ NULL,
+ NULL,
+ NULL
+ ))) {
+
+ /*
+ * Here we may want to switch to TCP on some errors.
+ * right?
+ */
+ break;
}
remote_kaddr.addrtype = ADDRTYPE_INET;
remote_kaddr.length = sizeof(ss2sin(&remote_addr)->sin_addr);
remote_kaddr.contents = (krb5_octet *) &ss2sin(&remote_addr)->sin_addr;
- /* mk_priv requires that the local address be set.
- getsockname is used for this. rd_priv requires that the
- remote address be set. recvfrom is used for this. If
- rd_priv is given a local address, and the message has the
- recipient addr in it, this will be checked. However, there
- is simply no way to know ahead of time what address the
- message will be delivered *to*. Therefore, it is important
- that either no recipient address is in the messages when
- mk_priv is called, or that no local address is passed to
- rd_priv. Both is a better idea, and I have done that. In
- summary, when mk_priv is called, *only* a local address is
- specified. when rd_priv is called, *only* a remote address
- is specified. Are we having fun yet? */
-
- if ((code = krb5_auth_con_setaddrs(context, auth_context,
- &local_kaddr, NULL))) {
- goto cleanup;
- }
-
- if( set_password_for )
- code = krb5int_mk_setpw_req(context, auth_context, &ap_req, set_password_for, newpw, &chpw_req);
+ if ((code = krb5_auth_con_setaddrs(callback_ctx.context,
+ callback_ctx.auth_context,
+ NULL,
+ &remote_kaddr)))
+ break;
+
+ if (set_password_for)
+ code = krb5int_rd_setpw_rep(callback_ctx.context,
+ callback_ctx.auth_context,
+ &chpw_rep,
+ &local_result_code,
+ result_string);
else
- code = krb5int_mk_chpw_req(context, auth_context, &ap_req, newpw, &chpw_req);
- if (code)
- {
- goto cleanup;
- }
-
- if ((cc = sendto(s1, chpw_req.data,
- (GETSOCKNAME_ARG3_TYPE) chpw_req.length, 0,
- al.addrs[i]->ai_addr, al.addrs[i]->ai_addrlen)) != chpw_req.length)
- {
- if ((cc < 0) && ((SOCKET_ERRNO == ECONNREFUSED) ||
- (SOCKET_ERRNO == EHOSTUNREACH)))
- continue; /* try the next addr */
-
- code = (cc < 0) ? SOCKET_ERRNO : ECONNABORTED;
- goto cleanup;
- }
-
- chpw_rep.length = 1500;
- chpw_rep.data = (char *) malloc(chpw_rep.length);
-
- /* XXX need a timeout/retry loop here */
- FD_ZERO (&fdset);
- FD_SET (s1, &fdset);
- timeout.tv_sec = 120;
- timeout.tv_usec = 0;
- switch (select (s1 + 1, &fdset, 0, 0, &timeout)) {
- case -1:
- code = SOCKET_ERRNO;
- goto cleanup;
- case 0:
- code = ETIMEDOUT;
- goto cleanup;
- default:
- /* fall through */
- ;
- }
+ code = krb5int_rd_chpw_rep(callback_ctx.context,
+ callback_ctx.auth_context,
+ &chpw_rep,
+ &local_result_code,
+ result_string);
+
+ if (code) {
+ if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !useTcp ) {
+ krb5int_free_addrlist (&al);
+ useTcp = 1;
+ continue;
+ }
- /* "recv" would be good enough here... except that Windows/NT
- commits the atrocity of returning -1 to indicate failure,
- but leaving errno set to 0.
-
- "recvfrom(...,NULL,NULL)" would seem to be a good enough
- alternative, and it works on NT, but it doesn't work on
- SunOS 4.1.4 or Irix 5.3. Thus we must actually accept the
- value and discard it. */
- tmp_len = sizeof(tmp_addr);
- if ((cc = recvfrom(s1, chpw_rep.data,
- (GETSOCKNAME_ARG3_TYPE) chpw_rep.length,
- 0, ss2sa(&tmp_addr), &tmp_len)) < 0)
- {
- code = SOCKET_ERRNO;
- goto cleanup;
+ break;
}
- closesocket(s1);
- s1 = INVALID_SOCKET;
- closesocket(s2);
- s2 = INVALID_SOCKET;
-
- chpw_rep.length = cc;
-
- if ((code = krb5_auth_con_setaddrs(context, auth_context,
- NULL, &remote_kaddr)))
- goto cleanup;
-
- if( set_password_for )
- code = krb5int_rd_setpw_rep(context, auth_context, &chpw_rep, &local_result_code, result_string);
- else
- code = krb5int_rd_chpw_rep(context, auth_context, &chpw_rep, &local_result_code, result_string);
- if (code)
- goto cleanup;
-
if (result_code)
*result_code = local_result_code;
-
+
if (result_code_string) {
- if( set_password_for )
- code = krb5int_setpw_result_code_string(context, local_result_code, (const char **)&code_string);
- else
- code = krb5_chpw_result_code_string(context, local_result_code, &code_string);
- if(code)
- goto cleanup;
+ if (set_password_for)
+ code = krb5int_setpw_result_code_string(callback_ctx.context,
+ local_result_code,
+ (const char **)&code_string);
+ else
+ code = krb5_chpw_result_code_string(callback_ctx.context,
+ local_result_code,
+ &code_string);
+ if(code)
+ goto cleanup;
result_code_string->length = strlen(code_string);
result_code_string->data = malloc(result_code_string->length);
@@ -331,34 +316,20 @@ krb5_change_set_password(
strncpy(result_code_string->data, code_string, result_code_string->length);
}
- code = 0;
- goto cleanup;
- }
-
- if (tried_one)
- /* Got some non-fatal errors, but didn't get any successes. */
- code = SOCKET_ERRNO;
- else
- /* Had some addresses, but didn't try any because they weren't
- AF_INET addresses and we don't support AF_INET6 addresses
- here yet. */
- code = EHOSTUNREACH;
+ if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !useTcp ) {
+ krb5int_free_addrlist (&al);
+ useTcp = 1;
+ } else {
+ break;
+ }
+ } while (TRUE);
cleanup:
- if (auth_context != NULL)
- krb5_auth_con_free(context, auth_context);
+ if (callback_ctx.auth_context != NULL)
+ krb5_auth_con_free(callback_ctx.context, callback_ctx.auth_context);
krb5int_free_addrlist (&al);
-
- if (s1 != INVALID_SOCKET)
- closesocket(s1);
-
- if (s2 != INVALID_SOCKET)
- closesocket(s2);
-
- krb5_free_data_contents(context, &chpw_req);
- krb5_free_data_contents(context, &chpw_rep);
- krb5_free_data_contents(context, &ap_req);
+ krb5_free_data_contents(callback_ctx.context, &callback_ctx.ap_req);
return(code);
}
@@ -397,36 +368,33 @@ krb5_set_password_using_ccache(
int *result_code, krb5_data *result_code_string, krb5_data *result_string
)
{
- krb5_creds creds;
- krb5_creds *credsp;
- krb5_error_code code;
+ krb5_creds creds;
+ krb5_creds *credsp;
+ krb5_error_code code;
-/*
-** get the proper creds for use with krb5_set_password -
-*/
- memset( &creds, 0, sizeof(creds) );
-/*
-** first get the principal for the password service -
-*/
- code = krb5_cc_get_principal( context, ccache, &creds.client );
- if( !code )
- {
- code = krb5_build_principal( context, &creds.server,
- krb5_princ_realm(context, change_password_for)->length,
- krb5_princ_realm(context, change_password_for)->data,
- "kadmin", "changepw", NULL );
- if(!code)
- {
- code = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
- if( ! code )
- {
- code = krb5_set_password(context, credsp, newpw, change_password_for,
- result_code, result_code_string,
- result_string);
- krb5_free_creds(context, credsp);
- }
- }
- krb5_free_cred_contents(context, &creds);
+ /*
+ ** get the proper creds for use with krb5_set_password -
+ */
+ memset (&creds, 0, sizeof(creds));
+ /*
+ ** first get the principal for the password service -
+ */
+ code = krb5_cc_get_principal (context, ccache, &creds.client);
+ if (!code) {
+ code = krb5_build_principal(context, &creds.server,
+ krb5_princ_realm(context, change_password_for)->length,
+ krb5_princ_realm(context, change_password_for)->data,
+ "kadmin", "changepw", NULL);
+ if (!code) {
+ code = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
+ if (!code) {
+ code = krb5_set_password(context, credsp, newpw, change_password_for,
+ result_code, result_code_string,
+ result_string);
+ krb5_free_creds(context, credsp);
+ }
}
- return code;
+ krb5_free_cred_contents(context, &creds);
+ }
+ return code;
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/def_realm.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/def_realm.c
index 8c63a4746d..c94bf33608 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/def_realm.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/def_realm.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/krb5/os/def_realm.c
*
@@ -31,11 +29,11 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "os-proto.h"
#include <stdio.h>
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnsglue.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnsglue.c
index fec3936685..04b1d84e8a 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnsglue.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnsglue.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/dnsglue.c
*
@@ -30,11 +29,24 @@
* or implied warranty.
*
*/
+#include "autoconf.h"
#ifdef KRB5_DNS_LOOKUP
#include "dnsglue.h"
/*
+ * Only use res_ninit() if there's also a res_ndestroy(), to avoid
+ * memory leaks (Linux & Solaris) and outright corruption (AIX 4.x,
+ * 5.x). While we're at it, make sure res_nsearch() is there too.
+ *
+ * In any case, it is probable that platforms having broken
+ * res_ninit() will have thread safety hacks for res_init() and _res.
+ */
+#if HAVE_RES_NINIT && HAVE_RES_NDESTROY && HAVE_RES_NSEARCH
+#define USE_RES_NINIT 1
+#endif
+
+/*
* Opaque handle
*/
struct krb5int_dns_state {
@@ -59,7 +71,7 @@ static int initparse(struct krb5int_dns_state *);
/*
* krb5int_dns_init()
*
- * Initialize an opaue handl. Do name lookup and initial parsing of
+ * Initialize an opaque handle. Do name lookup and initial parsing of
* reply, skipping question section. Prepare to iterate over answer
* section. Returns -1 on error, 0 on success.
*/
@@ -67,7 +79,7 @@ int
krb5int_dns_init(struct krb5int_dns_state **dsp,
char *host, int nclass, int ntype)
{
-#if HAVE_RES_NSEARCH
+#if USE_RES_NINIT
struct __res_state statbuf;
#endif
struct krb5int_dns_state *ds;
@@ -92,12 +104,14 @@ krb5int_dns_init(struct krb5int_dns_state **dsp,
ds->cur_ans = 0;
#endif
-#if HAVE_RES_NSEARCH
+#if USE_RES_NINIT
memset(&statbuf, 0, sizeof(statbuf));
ret = res_ninit(&statbuf);
+#else
+ ret = res_init();
+#endif
if (ret < 0)
return -1;
-#endif
do {
p = (ds->ansp == NULL)
@@ -110,7 +124,7 @@ krb5int_dns_init(struct krb5int_dns_state **dsp,
ds->ansp = p;
ds->ansmax = nextincr;
-#if HAVE_RES_NSEARCH
+#if USE_RES_NINIT
len = res_nsearch(&statbuf, host, ds->nclass, ds->ntype,
ds->ansp, ds->ansmax);
#else
@@ -141,12 +155,8 @@ krb5int_dns_init(struct krb5int_dns_state **dsp,
ret = 0;
errout:
-#if HAVE_RES_NSEARCH
-#if HAVE_RES_NDESTROY
+#if USE_RES_NINIT
res_ndestroy(&statbuf);
-#else
- res_nclose(&statbuf);
-#endif
#endif
if (ret < 0) {
if (ds->ansp != NULL) {
@@ -310,6 +320,11 @@ krb5int_dns_nextans(struct krb5int_dns_state *ds,
if (!INCR_OK(ds->ansp, ds->anslen, p, rdlen))
return -1;
+/* Solaris Kerberos - resync */
+#if 0
+ if (rdlen > INT_MAX)
+ return -1;
+#endif
if (nclass == ds->nclass && ntype == ds->ntype) {
*pp = p;
*lenp = rdlen;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnsglue.h b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnsglue.h
index fd4950bf42..dc36200551 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnsglue.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnsglue.h
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/dnsglue.h
*
@@ -49,9 +48,9 @@
#ifndef KRB5_DNSGLUE_H
#define KRB5_DNSGLUE_H
+#include "autoconf.h"
#ifdef KRB5_DNS_LOOKUP
-#define NEED_SOCKETS
#include "k5-int.h"
#include "os-proto.h"
#ifdef WSHELPER
@@ -86,6 +85,15 @@
#endif
+#if HAVE_NS_INITPARSE
+/*
+ * Solaris 7 has ns_rr_cl rather than ns_rr_class.
+ */
+#if !defined(ns_rr_class) && defined(ns_rr_cl)
+#define ns_rr_class ns_rr_cl
+#endif
+#endif
+
#if HAVE_RES_NSEARCH
/*
* Some BIND 8 / BIND 9 implementations disable the BIND 4 style
@@ -133,6 +141,7 @@
* failure, goto LABEL.
*/
+/* Solaris Kerberos */
#define SAFE_GETUINT16(base, max, ptr, incr, s, label) \
do { \
if (!INCR_OK(base, max, ptr, incr)) goto label; \
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnssrv.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnssrv.c
index d865522fc4..d1c96b291c 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnssrv.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/dnssrv.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/dnssrv.c
*
@@ -28,6 +27,7 @@
* do DNS SRV RR queries
*/
+#include "autoconf.h"
#ifdef KRB5_DNS_LOOKUP
#include "dnsglue.h"
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/free_hstrl.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/free_hstrl.c
index 159f371a50..4900fce9be 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/free_hstrl.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/free_hstrl.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/free_hstrl.c
*
@@ -32,7 +31,7 @@
#include <stdio.h>
/*
- Frees the storage taken by a realm list returned by krb5_get_local_realm.
+ Frees the storage taken by a realm list returned by krb5_get_host_realm.
*/
krb5_error_code KRB5_CALLCONV
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/free_krbhs.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/free_krbhs.c
index e84875666c..a10db910c9 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/free_krbhs.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/free_krbhs.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/free_krbhs.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/full_ipadr.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/full_ipadr.c
index 73ea02f0ab..c72daa8c95 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/full_ipadr.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/full_ipadr.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/full_ipadr.c
*
@@ -28,15 +27,14 @@
* Take an IP addr & port and generate a full IP address.
*/
-#define NEED_SOCKETS
-#include <k5-int.h>
+#include "k5-int.h"
#ifdef HAVE_NETINET_IN_H
#include "os-proto.h"
krb5_error_code
-krb5_make_full_ipaddr(krb5_context context, krb5_int32 adr,
+krb5_make_full_ipaddr(krb5_context context, krb5_int32 adr,
/*krb5_int16*/int port, krb5_address **outaddr)
{
unsigned long smushaddr = (unsigned long) adr; /* already in net order */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/gen_rname.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/gen_rname.c
index df4d692e9f..28e1803818 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/gen_rname.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/gen_rname.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/gen_rname.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -26,7 +28,6 @@
* a replay cache tag string.
*/
-#define NEED_SOCKETS
#include "k5-int.h"
#include "os-proto.h"
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/genaddrs.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/genaddrs.c
index 51469e3760..b5d6c6e746 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/genaddrs.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/genaddrs.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/genaddrs.c
@@ -29,29 +28,17 @@
* Take an IP addr & port and generate a full IP address.
*/
-#define NEED_SOCKETS
-#include <k5-int.h>
+#include "k5-int.h"
#include "os-proto.h"
-#if !defined(_WINSOCKAPI_) && !defined(HAVE_MACSOCK_H)
+#if !defined(_WINSOCKAPI_)
#include <netinet/in.h>
#endif
+
+/* Solaris Kerberos */
#include <inet/ip.h>
#include <inet/ip6.h>
-#ifndef GETPEERNAME_ARG2_TYPE
-#define GETPEERNAME_ARG2_TYPE struct sockaddr
-#endif
-#ifndef GETPEERNAME_ARG3_TYPE
-#define GETPEERNAME_ARG3_TYPE size_t
-#endif
-#ifndef GETSOCKNAME_ARG2_TYPE
-#define GETSOCKNAME_ARG2_TYPE struct sockaddr
-#endif
-#ifndef GETSOCKNAME_ARG3_TYPE
-#define GETSOCKNAME_ARG3_TYPE size_t
-#endif
-
struct addrpair {
krb5_address addr, port;
};
@@ -73,6 +60,7 @@ static void *cvtaddr (struct sockaddr_storage *a, struct addrpair *ap)
SET (ap->port, ss2sin6(a)->sin6_port, ADDRTYPE_IPPORT);
if (IN6_IS_ADDR_V4MAPPED (&ss2sin6(a)->sin6_addr)) {
ap->addr.addrtype = ADDRTYPE_INET;
+ /* Solaris Kerberos */
ap->addr.contents = (IPV6_ADDR_LEN - IPV4_ADDR_LEN) +
(krb5_octet *) &ss2sin6(a)->sin6_addr;
ap->addr.length = IPV4_ADDR_LEN;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/gmt_mktime.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/gmt_mktime.c
index b55e0946c9..65ab87349b 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/gmt_mktime.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/gmt_mktime.c
@@ -1,14 +1,7 @@
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* This code placed in the public domain by Mark W. Eichin */
#include <stdio.h>
-#include <k5-int.h>
+#include "autoconf.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -43,7 +36,7 @@ static const int days_in_month[12] = {
#define hasleapday(year) (year%400?(year%100?(year%4?0:1):0):1)
-time_t gmt_mktime(struct tm *t)
+time_t krb5int_gmt_mktime(struct tm *t)
{
time_t accum;
@@ -60,6 +53,7 @@ time_t gmt_mktime(struct tm *t)
*/
assert_time(t->tm_year>=1);
assert_time(t->tm_year<=138);
+
assert_time(t->tm_mon>=0);
assert_time(t->tm_mon<=11);
assert_time(t->tm_mday>=1);
@@ -97,3 +91,37 @@ time_t gmt_mktime(struct tm *t)
return accum;
}
+
+#ifdef TEST_LEAP
+int
+main (int argc, char *argv[])
+{
+ int yr;
+ time_t t;
+ struct tm tm = {
+ .tm_mon = 0, .tm_mday = 1,
+ .tm_hour = 0, .tm_min = 0, .tm_sec = 0,
+ };
+ for (yr = 60; yr <= 104; yr++)
+ {
+ printf ("1/1/%d%c -> ", 1900 + yr, hasleapday((1900+yr)) ? '*' : ' ');
+ tm.tm_year = yr;
+ t = gmt_mktime (&tm);
+ if (t == (time_t) -1)
+ printf ("-1\n");
+ else
+ {
+ long u;
+ if (t % (24 * 60 * 60))
+ printf ("(not integral multiple of days) ");
+ u = t / (24 * 60 * 60);
+ printf ("%3ld*365%+ld\t0x%08lx\n",
+ (long) (u / 365), (long) (u % 365),
+ (long) t);
+ }
+ }
+ t = 0x80000000, printf ("time 0x%lx -> %s", t, ctime (&t));
+ t = 0x7fffffff, printf ("time 0x%lx -> %s", t, ctime (&t));
+ return 0;
+}
+#endif
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/hostaddr.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/hostaddr.c
index 48b259595c..1d11db138d 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/hostaddr.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/hostaddr.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/krb5/os/hostaddr.c
*
@@ -29,15 +27,12 @@
*
*/
-#define NEED_SOCKETS
-#include <k5-int.h>
+#include "k5-int.h"
-#include <fake-addrinfo.h>
-#include <socket-utils.h>
+#include "fake-addrinfo.h"
krb5_error_code
-krb5_os_hostaddr(krb5_context context, const char *name,
- krb5_address ***ret_addrs)
+krb5_os_hostaddr(krb5_context context, const char *name, krb5_address ***ret_addrs)
{
krb5_error_code retval;
krb5_address **addrs;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/hst_realm.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/hst_realm.c
index be1b541d07..7ef9fe6758 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/hst_realm.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/hst_realm.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/krb5/os/hst_realm.c
*
@@ -30,7 +28,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -82,7 +80,7 @@
#include <strings.h>
#endif
-#include <fake-addrinfo.h>
+#include "fake-addrinfo.h"
#ifdef KRB5_DNS_LOOKUP
@@ -309,12 +307,16 @@ krb5int_translate_gai_error (int num)
return EAFNOSUPPORT;
case EAI_MEMORY:
return ENOMEM;
-#if EAI_NODATA != EAI_NONAME
+#if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME
case EAI_NODATA:
return KRB5_EAI_NODATA;
#endif
case EAI_NONAME:
return KRB5_EAI_NONAME;
+#if defined(EAI_OVERFLOW)
+ case EAI_OVERFLOW:
+ return EINVAL; /* XXX */
+#endif
case EAI_SERVICE:
return KRB5_EAI_SERVICE;
case EAI_SOCKTYPE:
@@ -324,6 +326,7 @@ krb5int_translate_gai_error (int num)
return errno;
#endif
}
+ /* Solaris Kerberos */
/* abort (); */
return -1;
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/krbfileio.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/krbfileio.c
index bad3ee0671..e135b27aad 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/krbfileio.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/krbfileio.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include "k5-int.h"
@@ -11,12 +10,11 @@
#include <fcntl.h>
#ifndef O_BINARY
-#define O_BINARY 0
+#define O_BINARY 0
#endif
krb5_error_code
krb5_create_secure_file(krb5_context context, const char *pathname)
-
{
int fd;
int open_flag;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/ktdefname.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/ktdefname.c
index bd0628fb18..5f1dce5836 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/ktdefname.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/ktdefname.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/ktdefname.c
@@ -15,7 +14,7 @@
* 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
@@ -29,14 +28,14 @@
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
*
* Return default keytab file name.
*/
#define NEED_WINDOWS
-#include <k5-int.h>
+#include "k5-int.h"
extern char *krb5_defkeyname;
@@ -52,19 +51,22 @@ krb5_kt_default_name(krb5_context context, char *name, int namesize)
if (krb5_overridekeyname) {
if ((size_t) namesize < (strlen(krb5_overridekeyname)+1))
return KRB5_CONFIG_NOTENUFSPACE;
+ /* Solaris Kerberos */
strncpy(name, krb5_overridekeyname, namesize);
} else if ((context->profile_secure == FALSE) &&
(cp = getenv("KRB5_KTNAME"))) {
if ((size_t) namesize < (strlen(cp)+1))
return KRB5_CONFIG_NOTENUFSPACE;
+ /* Solaris Kerberos */
strncpy(name, cp, namesize);
} else if ((profile_get_string(context->profile,
- "libdefaults",
- "default_keytab_name", NULL,
- NULL, &retval) == 0) &&
+ "libdefaults",
+ "default_keytab_name", NULL,
+ NULL, &retval) == 0) &&
retval) {
if ((size_t) namesize < (strlen(retval)+1))
return KRB5_CONFIG_NOTENUFSPACE;
+ /* Solaris Kerberos */
strncpy(name, retval, namesize);
profile_release_string(retval);
} else {
@@ -82,8 +84,10 @@ krb5_kt_default_name(krb5_context context, char *name, int namesize)
#else
if ((size_t) namesize < (strlen(krb5_defkeyname)+1))
return KRB5_CONFIG_NOTENUFSPACE;
+ /* Solaris Kerberos */
strncpy(name, krb5_defkeyname, namesize);
#endif
}
return 0;
}
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/kuserok.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/kuserok.c
index f98ff26ca1..b9da89278f 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/kuserok.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/kuserok.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/kuserok.c
@@ -15,7 +14,7 @@
* 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
@@ -23,16 +22,19 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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_kuserok()
*/
#include "k5-int.h"
-/* #if !defined(_WIN32) Not yet for Windows */
+#if !defined(_WIN32) /* Not yet for Windows */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -44,6 +46,23 @@
#include <gssapiP_krb5.h>
#include <syslog.h>
+#if defined(_AIX) && defined(_IBMR2)
+#include <sys/access.h>
+/* xlc has a bug with "const" */
+#define getpwnam(user) getpwnam((char *)user)
+#endif
+
+#define MAX_USERNAME 65
+#define CACHE_FILENAME_LEN 35
+
+#if defined(__APPLE__) && defined(__MACH__)
+#include <hfs/hfs_mount.h> /* XXX */
+#define FILE_OWNER_OK(UID) ((UID) == 0 || (UID) == UNKNOWNUID)
+#else
+#define FILE_OWNER_OK(UID) ((UID) == 0)
+#endif
+
+/* Solaris Kerberos */
extern void
gsscred_set_options();
@@ -55,8 +74,6 @@ safechown(const char *src, uid_t uid, gid_t gid, int mode);
extern const char *error_message(long);
-#define MAX_USERNAME 65
-#define CACHE_FILENAME_LEN 35
krb5_data tgtname = {
0,
@@ -64,6 +81,7 @@ krb5_data tgtname = {
KRB5_TGS_NAME
};
+/* Solaris Kerberos */
static krb5_error_code
krb5_move_ccache(krb5_context kcontext, krb5_principal client,
struct passwd *pwd)
@@ -182,6 +200,7 @@ krb5_move_ccache(krb5_context kcontext, krb5_principal client,
/*
+ * Solaris Kerberos:
* krb5_gsscred: Given a kerberos principal try to find the corresponding
* local uid via the gss cred table. Return TRUE if the uid was found in the
* cred table, otherwise return FALSE.
@@ -254,33 +273,20 @@ krb5_kuserok(krb5_context context, krb5_principal principal, const char *luser)
char *princname;
char linebuf[BUFSIZ];
char *newline;
+ /* Solaris Kerberos */
uid_t uid;
int gobble;
/* no account => no access */
-#ifdef HAVE_GETPWNAM_R
char pwbuf[BUFSIZ];
struct passwd pwx;
-#if !defined(GETPWNAM_R_4_ARGS)
- /* POSIX */
- if (getpwnam_r(luser, &pwx, pwbuf, sizeof(pwbuf), &pwd) != 0)
- pwd = NULL;
-#else
- /* draft POSIX */
- pwd = getpwnam_r(luser, &pwx, pwbuf, sizeof(pwbuf));
-#endif
-#else
- pwd = getpwnam(luser);
-#endif
- if (pwd == NULL)
+ if (k5_getpwnam_r(luser, &pwx, pwbuf, sizeof(pwbuf), &pwd) != 0)
return(FALSE);
-
(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 */
-
/*
* if he's trying to log in as himself, and there is no .k5login file,
* let him. First, have krb5 check it's rules. If no success,
@@ -290,6 +296,7 @@ krb5_kuserok(krb5_context context, krb5_principal principal, const char *luser)
if (!(krb5_aname_to_localname(context, principal,
sizeof(kuser), kuser))
&& (strcmp(kuser, luser) == 0)) {
+ /* Solaris Kerberos */
if (krb5_move_ccache(context, principal, pwd))
return (FALSE);
return(TRUE);
@@ -316,6 +323,7 @@ krb5_kuserok(krb5_context context, krb5_principal principal, const char *luser)
return(FALSE); /* no hope of matching */
/* open ~/.k5login */
+ /* Solaris Kerberos */
if ((fp = fopen(pbuf, "rF")) == NULL) {
free(princname);
return(FALSE);
@@ -329,7 +337,7 @@ krb5_kuserok(krb5_context context, krb5_principal principal, const char *luser)
free(princname);
return(FALSE);
}
- if ((sbuf.st_uid != pwd->pw_uid) && sbuf.st_uid) {
+ if (sbuf.st_uid != pwd->pw_uid && !FILE_OWNER_OK(sbuf.st_uid)) {
fclose(fp);
free(princname);
return(FALSE);
@@ -345,6 +353,7 @@ krb5_kuserok(krb5_context context, krb5_principal principal, const char *luser)
*newline = '\0';
if (!strcmp(linebuf, princname)) {
isok = TRUE;
+ /* Solaris Kerberos */
if (krb5_move_ccache(context, principal, pwd))
return (FALSE);
continue;
@@ -358,6 +367,7 @@ krb5_kuserok(krb5_context context, krb5_principal principal, const char *luser)
return(isok);
}
+/* Solaris Kerberos */
OM_uint32
krb5_gss_userok(OM_uint32 *minor,
const gss_name_t pname,
@@ -394,3 +404,27 @@ krb5_gss_userok(OM_uint32 *minor,
krb5_free_context(ctxt);
return (GSS_S_COMPLETE);
}
+
+#else /* _WIN32 */
+
+/*
+ * If the given Kerberos name "server" translates to the same name as "luser"
+ * (using * krb5_aname_to_lname()), returns TRUE.
+ */
+krb5_boolean KRB5_CALLCONV
+krb5_kuserok(context, principal, luser)
+ krb5_context context;
+ krb5_principal principal;
+ const char *luser;
+{
+ char kuser[50];
+
+ if (krb5_aname_to_localname(context, principal, sizeof(kuser), kuser))
+ return FALSE;
+
+ if (strcmp(kuser, luser) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+#endif /* _WIN32 */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/localaddr.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/localaddr.c
index 189b9bb897..75953b1f36 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/localaddr.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/localaddr.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/krb5/os/localaddr.c
*
@@ -35,7 +33,6 @@
* XNS support is untested, but "Should just work". (Hah!)
*/
-#define NEED_SOCKETS
#include "k5-int.h"
#if !defined(_WIN32)
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/locate_kdc.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/locate_kdc.c
index a3f369c3b9..0d127d4eea 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/locate_kdc.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/locate_kdc.c
@@ -1,13 +1,12 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/locate_kdc.c
*
- * Copyright 1990,2000,2001,2002 by the Massachusetts Institute of Technology.
+ * Copyright 1990,2000,2001,2002,2003,2004,2006 Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -33,7 +32,6 @@
* get socket addresses for KDC.
*/
-#define NEED_SOCKETS
#include "fake-addrinfo.h"
#include "k5-int.h"
#include "os-proto.h"
@@ -63,27 +61,6 @@
#define DEFAULT_LOOKUP_KDC 1
#define DEFAULT_LOOKUP_REALM 0
-#ifdef DEBUG
-/* Solaris Kerberos: want dbg messages to syslog */
-
-#define fprintf krbint_dbg_syslog
-#include <stdarg.h>
-#include <com_err.h>
-static int
-krbint_dbg_syslog(FILE *file, const char *fmt, ...)
-{
- va_list args;
- char err_str[2048];
-
- va_start(args, fmt);
- vsnprintf(err_str, sizeof (err_str), fmt, args);
- syslog(LOG_DEBUG, err_str);
- va_end(args);
-
- return (0);
-}
-#endif
-
static int
maybe_use_dns (krb5_context context, const char *name, int defalt)
{
@@ -121,53 +98,23 @@ _krb5_use_dns_realm(krb5_context context)
#endif /* KRB5_DNS_LOOKUP */
-/*ARGSUSED*/
-static int get_port (const char *service, int stream, int defalt)
-{
-#if 0 /* Only used for "kerberos" and "kerberos-sec", and we want the
- right port numbers even on the OSes that botch the entries in
- /etc/services. So don't bother with the lookup, except maybe
- to produce a warning. */
- struct addrinfo hints = { 0 };
- struct addrinfo *ai;
- int err;
-
- hints.ai_family = PF_INET;
- hints.ai_socktype = stream ? SOCK_STREAM : SOCK_DGRAM;
- err = getaddrinfo (NULL, service, &hints, &ai);
- if (err == 0 && ai != 0) {
- if (ai->ai_addr->sa_family == AF_INET) {
- int port = ((struct sockaddr_in *)ai->ai_addr)->sin_port;
- freeaddrinfo (ai);
- return port;
- }
- freeaddrinfo (ai);
- }
-#endif
- /* Any error - don't complain, just use default. */
- return htons (defalt);
-}
-
int
krb5int_grow_addrlist (struct addrlist *lp, int nmore)
{
int i;
int newspace = lp->space + nmore;
- size_t newsize = newspace * sizeof (struct addrlist);
- struct addrinfo **newaddrs;
-
- /* NULL check a concession to SunOS4 compatibility for now; not
- required for pure ANSI support. */
- if (lp->addrs)
- newaddrs = realloc (lp->addrs, newsize);
- else
- newaddrs = malloc (newsize);
+ size_t newsize = newspace * sizeof (*lp->addrs);
+ void *newaddrs;
+ newaddrs = realloc (lp->addrs, newsize);
if (newaddrs == NULL)
return errno;
- for (i = lp->space; i < newspace; i++)
- newaddrs[i] = NULL;
lp->addrs = newaddrs;
+ for (i = lp->space; i < newspace; i++) {
+ lp->addrs[i].ai = NULL;
+ lp->addrs[i].freefn = NULL;
+ lp->addrs[i].data = NULL;
+ }
lp->space = newspace;
return 0;
}
@@ -180,7 +127,8 @@ krb5int_free_addrlist (struct addrlist *lp)
{
int i;
for (i = 0; i < lp->naddrs; i++)
- freeaddrinfo (lp->addrs[i]);
+ if (lp->addrs[i].freefn)
+ (lp->addrs[i].freefn)(lp->addrs[i].data);
free (lp->addrs);
lp->addrs = NULL;
lp->naddrs = lp->space = 0;
@@ -207,13 +155,18 @@ static int translate_ai_error (int err)
#ifdef EAI_ADDRFAMILY
case EAI_ADDRFAMILY:
#endif
-#if EAI_NODATA != EAI_NONAME
+#if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME
case EAI_NODATA:
#endif
case EAI_NONAME:
/* Name not known or no address data, but no error. Do
nothing more. */
return 0;
+#ifdef EAI_OVERFLOW
+ case EAI_OVERFLOW:
+ /* An argument buffer overflowed. */
+ return EINVAL; /* XXX */
+#endif
#ifdef EAI_SYSTEM
case EAI_SYSTEM:
/* System error, obviously. */
@@ -225,48 +178,67 @@ static int translate_ai_error (int err)
}
}
-static int add_addrinfo_to_list (struct addrlist *lp, struct addrinfo *a)
+/* Solaris Kerberos: want dbg messages to syslog */
+#include <stdarg.h>
+static inline void Tprintf(const char *fmt, ...)
{
- int err;
+#ifdef TEST
+ va_list ap;
+ char err_str[2048];
-#ifdef DEBUG
- switch (a->ai_socktype) {
- case SOCK_DGRAM:
- fprintf(stderr, "\tdgram\n");
- break;
- case SOCK_STREAM:
- fprintf(stderr, "\tstream\n");
- break;
- case SOCK_RAW:
- fprintf(stderr, "\traw\n");
- break;
- case 0:
- break;
- default:
- fprintf(stderr, "\tsocket type %d\n", a->ai_socktype);
- break;
- }
+ va_start(ap, fmt);
+ vsnprintf(err_str, sizeof (err_str), fmt, args);
+ syslog(LOG_DEBUG, err_str);
+ va_end(ap);
#endif
+}
+
+#if 0
+extern void krb5int_debug_fprint(const char *, ...);
+#define dprint krb5int_debug_fprint
+#define print_addrlist krb5int_print_addrlist
+extern void print_addrlist (const struct addrlist *a);
+#else
+static inline void dprint(const char *fmt, ...) { }
+static inline void print_addrlist(const struct addrlist *a) { }
+#endif
+
+static int add_addrinfo_to_list (struct addrlist *lp, struct addrinfo *a,
+ void (*freefn)(void *), void *data)
+{
+ int err;
+
+ dprint("\tadding %p=%A to %p (naddrs=%d space=%d)\n", a, a, lp,
+ lp->naddrs, lp->space);
if (lp->naddrs == lp->space) {
err = grow_list (lp, 1);
if (err) {
-#ifdef DEBUG
- fprintf (stderr, "grow_list failed %d\n", err);
-#endif
+ Tprintf ("grow_list failed %d\n", err);
return err;
}
}
- lp->addrs[lp->naddrs++] = a;
- a->ai_next = 0;
-#ifdef DEBUG
- fprintf (stderr, "count is now %d\n", lp->naddrs);
-#endif
+ Tprintf("setting element %d\n", lp->naddrs);
+ lp->addrs[lp->naddrs].ai = a;
+ lp->addrs[lp->naddrs].freefn = freefn;
+ lp->addrs[lp->naddrs].data = data;
+ lp->naddrs++;
+ Tprintf ("\tcount is now %d: ", lp->naddrs);
+ print_addrlist(lp);
+ Tprintf("\n");
return 0;
}
#define add_host_to_list krb5int_add_host_to_list
+static void call_freeaddrinfo(void *data)
+{
+ /* Strict interpretation of the C standard says we can't assume
+ that the ABI for f(void*) and f(struct foo *) will be
+ compatible. Use this stub just to be paranoid. */
+ freeaddrinfo(data);
+}
+
int
krb5int_add_host_to_list (struct addrlist *lp, const char *hostname,
int port, int secport,
@@ -275,24 +247,31 @@ krb5int_add_host_to_list (struct addrlist *lp, const char *hostname,
struct addrinfo *addrs, *a, *anext, hint;
int err;
char portbuf[10], secportbuf[10];
+ void (*freefn)(void *);
-#ifdef DEBUG
- fprintf (stderr, "adding hostname %s, ports %d,%d\n", hostname,
- ntohs (port), ntohs (secport));
-#endif
+ Tprintf ("adding hostname %s, ports %d,%d, family %d, socktype %d\n",
+ hostname, ntohs (port), ntohs (secport),
+ family, socktype);
memset(&hint, 0, sizeof(hint));
hint.ai_family = family;
hint.ai_socktype = socktype;
+#ifdef AI_NUMERICSERV
+ hint.ai_flags = AI_NUMERICSERV;
+#endif
sprintf(portbuf, "%d", ntohs(port));
sprintf(secportbuf, "%d", ntohs(secport));
err = getaddrinfo (hostname, portbuf, &hint, &addrs);
- if (err)
+ if (err) {
+ Tprintf ("\tgetaddrinfo(\"%s\", \"%s\", ...)\n\treturns %d: %s\n",
+ hostname, portbuf, err, gai_strerror (err));
return translate_ai_error (err);
+ }
+ freefn = call_freeaddrinfo;
anext = 0;
- for (a = addrs; a != 0 && err == 0; a = anext) {
+ for (a = addrs; a != 0 && err == 0; a = anext, freefn = 0) {
anext = a->ai_next;
- err = add_addrinfo_to_list (lp, a);
+ err = add_addrinfo_to_list (lp, a, freefn, a);
}
if (err || secport == 0)
goto egress;
@@ -306,11 +285,13 @@ krb5int_add_host_to_list (struct addrlist *lp, const char *hostname,
err = translate_ai_error (err);
goto egress;
}
- for (a = addrs; a != 0 && err == 0; a = anext) {
+ freefn = call_freeaddrinfo;
+ for (a = addrs; a != 0 && err == 0; a = anext, freefn = 0) {
anext = a->ai_next;
- err = add_addrinfo_to_list (lp, a);
+ err = add_addrinfo_to_list (lp, a, freefn, a);
}
egress:
+ /* Solaris Kerberos */
if (anext)
freeaddrinfo (anext);
return err;
@@ -333,11 +314,8 @@ krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm,
krb5_error_code code;
int i, j, count, ismaster;
-#ifdef DEBUG
- fprintf (stderr,
- "looking in krb5.conf for realm %s entry %s; ports %d,%d\n",
+ Tprintf ("looking in krb5.conf for realm %s entry %s; ports %d,%d\n",
realm->data, name, ntohs (udpport), ntohs (sec_udpport));
-#endif
if ((host = malloc(realm->length + 1)) == NULL)
return ENOMEM;
@@ -356,10 +334,8 @@ krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm,
code = profile_get_values(context->profile, realm_srv_names, &hostlist);
if (code) {
-#ifdef DEBUG
- fprintf (stderr, "config file lookup failed: %s\n",
+ Tprintf ("config file lookup failed: %s\n",
error_message(code));
-#endif
if (code == PROF_NO_SECTION || code == PROF_NO_RELATION)
code = KRB5_REALM_UNKNOWN;
krb5_xfree(host);
@@ -369,9 +345,7 @@ krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm,
count = 0;
while (hostlist && hostlist[count])
count++;
-#ifdef DEBUG
- fprintf (stderr, "found %d entries under 'kdc'\n", count);
-#endif
+ Tprintf ("found %d entries under 'kdc'\n", count);
if (count == 0) {
profile_free_list(hostlist);
@@ -426,9 +400,7 @@ krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm,
int p1, p2;
host = hostlist[i];
-#ifdef DEBUG
- fprintf (stderr, "entry %d is '%s'\n", i, host);
-#endif
+ Tprintf ("entry %d is '%s'\n", i, host);
/*
* Strip off excess whitespace
*/
@@ -487,9 +459,8 @@ krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm,
SOCK_STREAM, family);
}
if (code) {
-#ifdef DEBUG
- fprintf (stderr, "error %d returned from add_host_to_list\n", code);
-#endif
+ Tprintf ("error %d (%s) returned from add_host_to_list\n", code,
+ error_message (code));
if (hostlist)
profile_free_list (hostlist);
if (masterlist)
@@ -506,10 +477,25 @@ krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm,
return 0;
}
-#ifdef KRB5_DNS_LOOKUP
+#ifdef TEST
+static krb5_error_code
+krb5_locate_srv_conf(krb5_context context, const krb5_data *realm,
+ const char *name, struct addrlist *al, int get_masters,
+ int udpport, int sec_udpport)
+{
+ krb5_error_code ret;
-#define make_srv_query_realm krb5int_make_srv_query_realm
+ ret = krb5_locate_srv_conf_1 (context, realm, name, al,
+ get_masters, 0, udpport, sec_udpport, 0);
+ if (ret)
+ return ret;
+ if (al->naddrs == 0) /* Couldn't resolve any KDC names */
+ return KRB5_REALM_CANT_RESOLVE;
+ return 0;
+}
+#endif
+#ifdef KRB5_DNS_LOOKUP
static krb5_error_code
krb5_locate_srv_dns_1 (const krb5_data *realm,
const char *service,
@@ -521,7 +507,7 @@ krb5_locate_srv_dns_1 (const krb5_data *realm,
struct srv_dns_entry *entry = NULL, *next;
krb5_error_code code = 0;
- code = make_srv_query_realm(realm, service, protocol, &head);
+ code = krb5int_make_srv_query_realm(realm, service, protocol, &head);
if (code)
return 0;
@@ -541,20 +527,17 @@ krb5_locate_srv_dns_1 (const krb5_data *realm,
return KRB5_ERR_NO_SERVICE;
}
-#ifdef DEBUG
- fprintf (stderr, "walking answer list:\n");
-#endif
+ Tprintf ("walking answer list:\n");
for (entry = head; entry != NULL; entry = next) {
-#ifdef DEBUG
- fprintf (stderr, "\tport=%d host=%s\n", entry->port, entry->host);
-#endif
+ Tprintf ("\tport=%d host=%s\n", entry->port, entry->host);
next = entry->next;
code = add_host_to_list (addrlist, entry->host, htons (entry->port), 0,
(strcmp("_tcp", protocol)
? SOCK_DGRAM
: SOCK_STREAM), family);
- if (code)
+ if (code) {
break;
+ }
if (entry == head) {
free(entry->host);
free(entry);
@@ -562,77 +545,276 @@ krb5_locate_srv_dns_1 (const krb5_data *realm,
entry = 0;
}
}
-#ifdef DEBUG
- fprintf (stderr, "[end]\n");
-#endif
+ Tprintf ("[end]\n");
krb5int_free_srv_dns_data(head);
return code;
}
-#endif /* KRB5_DNS_LOOKUP */
+#endif
+
+#include <locate_plugin.h>
+
+#if TARGET_OS_MAC
+static const char *objdirs[] = { KRB5_PLUGIN_BUNDLE_DIR, LIBDIR "/krb5/plugins/libkrb5", NULL }; /* should be a list */
+#else
+static const char *objdirs[] = { LIBDIR "/krb5/plugins/libkrb5", NULL };
+#endif
+
+struct module_callback_data {
+ int out_of_mem;
+ struct addrlist *lp;
+};
+
+static int
+module_callback (void *cbdata, int socktype, struct sockaddr *sa)
+{
+ struct module_callback_data *d = cbdata;
+ struct {
+ struct addrinfo ai;
+ union {
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ } u;
+ } *x;
+
+ if (socktype != SOCK_STREAM && socktype != SOCK_DGRAM)
+ return 0;
+ if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
+ return 0;
+ x = malloc (sizeof (*x));
+ if (x == 0) {
+ d->out_of_mem = 1;
+ return 1;
+ }
+ memset(x, 0, sizeof (*x));
+ x->ai.ai_addr = (struct sockaddr *) &x->u;
+ x->ai.ai_socktype = socktype;
+ x->ai.ai_family = sa->sa_family;
+ if (sa->sa_family == AF_INET) {
+ x->u.sin = *(struct sockaddr_in *)sa;
+ x->ai.ai_addrlen = sizeof(struct sockaddr_in);
+ }
+ if (sa->sa_family == AF_INET6) {
+ x->u.sin6 = *(struct sockaddr_in6 *)sa;
+ x->ai.ai_addrlen = sizeof(struct sockaddr_in6);
+ }
+ if (add_addrinfo_to_list (d->lp, &x->ai, free, x) != 0) {
+ /* Assumes only error is ENOMEM. */
+ d->out_of_mem = 1;
+ return 1;
+ }
+ return 0;
+}
+
+static krb5_error_code
+module_locate_server (krb5_context ctx, const krb5_data *realm,
+ struct addrlist *addrlist,
+ enum locate_service_type svc, int socktype, int family)
+{
+ struct krb5plugin_service_locate_result *res = NULL;
+ krb5_error_code code;
+ struct krb5plugin_service_locate_ftable *vtbl = NULL;
+ void **ptrs;
+ int i;
+ struct module_callback_data cbdata = { 0, };
+
+ Tprintf("in module_locate_server\n");
+ cbdata.lp = addrlist;
+ if (!PLUGIN_DIR_OPEN (&ctx->libkrb5_plugins)) {
+
+ code = krb5int_open_plugin_dirs (objdirs, NULL, &ctx->libkrb5_plugins,
+ &ctx->err);
+ if (code)
+ return KRB5_PLUGIN_NO_HANDLE;
+ }
+
+ code = krb5int_get_plugin_dir_data (&ctx->libkrb5_plugins,
+ "service_locator", &ptrs, &ctx->err);
+ if (code) {
+ Tprintf("error looking up plugin symbols: %s\n",
+ krb5_get_error_message(ctx, code));
+ return KRB5_PLUGIN_NO_HANDLE;
+ }
+
+ for (i = 0; ptrs[i]; i++) {
+ void *blob;
+
+ vtbl = ptrs[i];
+ Tprintf("element %d is %p\n", i, ptrs[i]);
+
+ /* For now, don't keep the plugin data alive. For long-lived
+ contexts, it may be desirable to change that later. */
+ code = vtbl->init(ctx, &blob);
+ if (code)
+ continue;
+
+ code = vtbl->lookup(blob, svc, realm->data, socktype, family,
+ module_callback, &cbdata);
+ vtbl->fini(blob);
+ if (code == KRB5_PLUGIN_NO_HANDLE) {
+ /* Module passes, keep going. */
+ /* XXX */
+ Tprintf("plugin doesn't handle this realm (KRB5_PLUGIN_NO_HANDLE)\n");
+ continue;
+ }
+ if (code != 0) {
+ /* Module encountered an actual error. */
+ Tprintf("plugin lookup routine returned error %d: %s\n",
+ code, error_message(code));
+ krb5int_free_plugin_dir_data (ptrs);
+ return code;
+ }
+ break;
+ }
+ if (ptrs[i] == NULL) {
+ Tprintf("ran off end of plugin list\n");
+ krb5int_free_plugin_dir_data (ptrs);
+ return KRB5_PLUGIN_NO_HANDLE;
+ }
+ Tprintf("stopped with plugin #%d, res=%p\n", i, res);
+
+ /* Got something back, yippee. */
+ Tprintf("now have %d addrs in list %p\n", addrlist->naddrs, addrlist);
+ print_addrlist(addrlist);
+ krb5int_free_plugin_dir_data (ptrs);
+ return 0;
+}
+
+static krb5_error_code
+prof_locate_server (krb5_context context, const krb5_data *realm,
+ struct addrlist *addrlist,
+ enum locate_service_type svc, int socktype, int family)
+{
+ const char *profname;
+ int dflport1, dflport2 = 0;
+ struct servent *serv;
+
+ switch (svc) {
+ case locate_service_kdc:
+ profname = "kdc";
+ /* We used to use /etc/services for these, but enough systems
+ have old, crufty, wrong settings that this is probably
+ better. */
+ kdc_ports:
+ dflport1 = htons(KRB5_DEFAULT_PORT);
+ dflport2 = htons(KRB5_DEFAULT_SEC_PORT);
+ break;
+ case locate_service_master_kdc:
+ profname = "master_kdc";
+ goto kdc_ports;
+ case locate_service_kadmin:
+ profname = "admin_server";
+ dflport1 = htons(DEFAULT_KADM5_PORT);
+ break;
+ case locate_service_krb524:
+ profname = "krb524_server";
+ serv = getservbyname(KRB524_SERVICE, "udp");
+ dflport1 = serv ? serv->s_port : htons (KRB524_PORT);
+ break;
+ case locate_service_kpasswd:
+ profname = "kpasswd_server";
+ dflport1 = htons(DEFAULT_KPASSWD_PORT);
+ break;
+ default:
+ return EBUSY; /* XXX */
+ }
+
+ return krb5_locate_srv_conf_1 (context, realm, profname, addrlist,
+ 0, socktype,
+ dflport1, dflport2, family);
+}
+
+static krb5_error_code
+dns_locate_server (krb5_context context, const krb5_data *realm,
+ struct addrlist *addrlist,
+ enum locate_service_type svc, int socktype, int family)
+{
+ const char *dnsname;
+ int use_dns = _krb5_use_dns_kdc(context);
+ krb5_error_code code;
+
+ if (!use_dns)
+ return KRB5_PLUGIN_NO_HANDLE;
+
+ switch (svc) {
+ case locate_service_kdc:
+ dnsname = "_kerberos";
+ break;
+ case locate_service_master_kdc:
+ dnsname = "_kerberos-master";
+ break;
+ case locate_service_kadmin:
+ dnsname = "_kerberos-adm";
+ break;
+ case locate_service_krb524:
+ dnsname = "_krb524";
+ break;
+ case locate_service_kpasswd:
+ dnsname = "_kpasswd";
+ break;
+ default:
+ return KRB5_PLUGIN_NO_HANDLE;
+ }
+
+ code = 0;
+ if (socktype == SOCK_DGRAM || socktype == 0) {
+ code = krb5_locate_srv_dns_1(realm, dnsname, "_udp", addrlist, family);
+ if (code)
+ Tprintf("dns udp lookup returned error %d\n", code);
+ }
+ if ((socktype == SOCK_STREAM || socktype == 0) && code == 0) {
+ code = krb5_locate_srv_dns_1(realm, dnsname, "_tcp", addrlist, family);
+ if (code)
+ Tprintf("dns tcp lookup returned error %d\n", code);
+ }
+ return code;
+}
/*
- * Wrapper function for the two backends
+ * Wrapper function for the various backends
*/
krb5_error_code
krb5int_locate_server (krb5_context context, const krb5_data *realm,
struct addrlist *addrlist,
- int get_masters,
- const char *profname, const char *dnsname,
- int socktype,
- /* network order port numbers! */
- int dflport1, int dflport2,
- int family)
+ enum locate_service_type svc,
+ int socktype, int family)
{
krb5_error_code code;
struct addrlist al = ADDRLIST_INIT;
*addrlist = al;
- /* Solaris Kerberos: skip local file search if profname == NULL */
- if (profname != NULL) {
+ code = module_locate_server(context, realm, &al, svc, socktype, family);
+ Tprintf("module_locate_server returns %d\n", code);
+ if (code == KRB5_PLUGIN_NO_HANDLE) {
/*
- * We always try the local file first
+ * We always try the local file before DNS. Note that there
+ * is no way to indicate "service not available" via the
+ * config file.
*/
- code = krb5_locate_srv_conf_1(context, realm, profname, &al,
- get_masters, socktype, dflport1, dflport2, family);
- }
+
+ code = prof_locate_server(context, realm, &al, svc, socktype, family);
#ifdef KRB5_DNS_LOOKUP
- if (code && dnsname != 0) {
- int use_dns = _krb5_use_dns_kdc(context);
- if (use_dns) {
- code = 0;
- if (socktype == SOCK_DGRAM || socktype == 0) {
- code = krb5_locate_srv_dns_1(realm, dnsname, "_udp",
- &al, family);
-#ifdef DEBUG
- if (code)
- fprintf(stderr, "dns udp lookup returned error %d\n",
- code);
-#endif
- }
- if ((socktype == SOCK_STREAM || socktype == 0) && code == 0) {
- code = krb5_locate_srv_dns_1(realm, dnsname, "_tcp",
- &al, family);
-#ifdef DEBUG
- if (code)
- fprintf(stderr, "dns tcp lookup returned error %d\n",
- code);
-#endif
- }
+ if (code) { /* Try DNS for all profile errors? */
+ krb5_error_code code2;
+ code2 = dns_locate_server(context, realm, &al, svc, socktype,
+ family);
+ if (code2 != KRB5_PLUGIN_NO_HANDLE)
+ code = code2;
}
- }
#endif /* KRB5_DNS_LOOKUP */
-#ifdef DEBUG
+
+ /* We could put more heuristics here, like looking up a hostname
+ of "kerberos."+REALM, etc. */
+ }
if (code == 0)
- fprintf (stderr, "krb5int_locate_server found %d addresses\n",
+ Tprintf ("krb5int_locate_server found %d addresses\n",
al.naddrs);
else
- fprintf (stderr, "krb5int_locate_server returning error code %d\n",
- code);
-#endif
+ Tprintf ("krb5int_locate_server returning error code %d/%s\n",
+ code, error_message(code));
if (code != 0) {
if (al.space)
free_list (&al);
@@ -641,6 +823,10 @@ krb5int_locate_server (krb5_context context, const krb5_data *realm,
if (al.naddrs == 0) { /* No good servers */
if (al.space)
free_list (&al);
+ krb5_set_error_message(context, KRB5_REALM_CANT_RESOLVE,
+ "Cannot resolve network address for KDC in realm %.*s",
+ realm->length, realm->data);
+
return KRB5_REALM_CANT_RESOLVE;
}
*addrlist = al;
@@ -652,25 +838,11 @@ krb5_locate_kdc(krb5_context context, const krb5_data *realm,
struct addrlist *addrlist,
int get_masters, int socktype, int family)
{
- int udpport, sec_udpport;
-
- udpport = get_port (KDC_PORTNAME, 0, KRB5_DEFAULT_PORT);
- if (socktype == SOCK_STREAM)
- sec_udpport = 0;
- else {
- sec_udpport = get_port (KDC_SECONDARY_PORTNAME, 0,
- (udpport == htons (KRB5_DEFAULT_PORT)
- ? KRB5_DEFAULT_SEC_PORT
- : KRB5_DEFAULT_PORT));
- if (sec_udpport == udpport)
- sec_udpport = 0;
- }
-
- return krb5int_locate_server(context, realm, addrlist, get_masters, "kdc",
+ return krb5int_locate_server(context, realm, addrlist,
(get_masters
- ? "_kerberos-master"
- : "_kerberos"),
- socktype, udpport, sec_udpport, family);
+ ? locate_service_master_kdc
+ : locate_service_kdc),
+ socktype, family);
}
/*
@@ -693,7 +865,7 @@ krb5_get_servername(krb5_context context,
if (use_dns) {
struct srv_dns_entry *head = NULL;
- code = make_srv_query_realm(realm, name, proto, &head);
+ code = krb5int_make_srv_query_realm(realm, name, proto, &head);
if (code)
return (code);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/lock_file.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/lock_file.c
index 3766136f07..7bbd3e9d65 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/lock_file.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/lock_file.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/lock_file.c
*
@@ -28,7 +27,7 @@
* libos: krb5_lock_file routine
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include <stdio.h>
#if !defined(_WIN32)
@@ -69,10 +68,7 @@ krb5_lock_file(krb5_context context, int fd, int mode)
krb5_error_code retval = 0;
#ifdef POSIX_FILE_LOCKS
int lock_cmd = F_SETLKW;
- static struct flock flock_zero;
struct flock lock_arg = { 0 };
-
- lock_arg = flock_zero;
#endif
switch (mode & ~KRB5_LOCKMODE_DONTBLOCK) {
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/mk_faddr.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/mk_faddr.c
index d18564100e..7caa8a8cf6 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/mk_faddr.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/mk_faddr.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/full_ipadr.c
*
@@ -28,8 +27,7 @@
* Take an IP addr & port and generate a full IP address.
*/
-#define NEED_SOCKETS
-#include <k5-int.h>
+#include "k5-int.h"
#ifdef HAVE_NETINET_IN_H
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/net_read.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/net_read.c
index cb90e81ba8..e90c6c30cb 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/net_read.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/net_read.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/net_read.c
*
@@ -26,9 +25,7 @@
*
*/
-#define NEED_LOWLEVEL_IO
-#define NEED_SOCKETS
-#include <k5-int.h>
+#include "k5-int.h"
/*
* krb5_net_read() reads from the file descriptor "fd" to the buffer
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/net_write.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/net_write.c
index 6f973b315b..5cff017619 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/net_write.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/net_write.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/net_write.c
*
@@ -26,9 +25,7 @@
*
*/
-#define NEED_LOWLEVEL_IO
-#define NEED_SOCKETS
-#include <k5-int.h>
+#include "k5-int.h"
/*
* krb5_net_write() writes "len" bytes from "buf" to the file
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/os-proto.h b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/os-proto.h
index c93da827b8..39dae84be5 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/os-proto.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/os-proto.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/os-proto.h
*
@@ -35,7 +34,7 @@ struct addrlist;
krb5_error_code krb5_locate_kdc
(krb5_context, const krb5_data *, struct addrlist *, int, int, int);
-/* Solaris/SUNW14resync */
+/* Solaris Kerberos */
krb5_error_code krb5_get_servername
(krb5_context,
const krb5_data *,
@@ -66,6 +65,8 @@ krb5_error_code krb5_try_realm_txt_rr(const char *, const char *,
/* Obsolete interface - leave prototype here until code removed */
krb5_error_code krb5_secure_config_files(krb5_context ctx);
+void krb5int_debug_fprint (const char *fmt, ...);
+
int _krb5_use_dns_realm (krb5_context);
int _krb5_use_dns_kdc (krb5_context);
int _krb5_conf_boolean (const char *);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/osconfig.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/osconfig.c
index a36e578d7a..dec5cac77a 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/osconfig.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/osconfig.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/osconfig.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/port2ip.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/port2ip.c
index ad9e6ce805..037e8b1e94 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/port2ip.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/port2ip.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/port2ip.c
*
@@ -28,8 +27,7 @@
* Take an ADDRPORT address and split into IP addr & port.
*/
-#define NEED_SOCKETS
-#include <k5-int.h>
+#include "k5-int.h"
#ifdef HAVE_NETINET_IN_H
#include "os-proto.h"
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/prompter.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/prompter.c
index 24613a73b2..739c8c747d 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/prompter.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/prompter.c
@@ -1,6 +1,5 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-#include <k5-int.h>
-#if (!defined(_WIN32) || (defined(_WIN32) && defined(__CYGWIN32__))) && !defined(macintosh)
+#include "k5-int.h"
+#if !defined(_WIN32) || (defined(_WIN32) && defined(__CYGWIN32__))
#include <stdio.h>
#include <errno.h>
#include <signal.h>
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/read_msg.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/read_msg.c
index c9b86e1932..77cda8032a 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/read_msg.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/read_msg.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/read_msg.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -25,7 +27,6 @@
* Write a message to the network
*/
-#define NEED_SOCKETS
#include "k5-int.h"
#include <errno.h>
@@ -33,7 +34,7 @@ krb5_error_code
krb5_read_message(krb5_context context, krb5_pointer fdp, krb5_data *inbuf)
{
krb5_int32 len;
- int len2, ilen;
+ int len2, ilen;
char *buf = NULL;
int fd = *( (int *) fdp);
@@ -41,15 +42,15 @@ krb5_read_message(krb5_context context, krb5_pointer fdp, krb5_data *inbuf)
return((len2 < 0) ? errno : ECONNABORTED);
len = ntohl(len);
- if ((len & VALID_UINT_BITS) != len) /* Overflow size_t??? */
- return ENOMEM;
+ if ((len & VALID_UINT_BITS) != len) /* Overflow size_t??? */
+ return ENOMEM;
inbuf->length = ilen = (int) len;
if (ilen) {
/*
* We may want to include a sanity check here someday....
*/
- if (!(buf = malloc(ilen))) {
+ if (!(buf = malloc(inbuf->length))) {
return(ENOMEM);
}
if ((len2 = krb5_net_read(context, fd, buf, ilen)) != ilen) {
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/read_pwd.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/read_pwd.c
index be00932936..6f2868da7c 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/read_pwd.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/read_pwd.c
@@ -1,10 +1,4 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-/*
* lib/krb5/os/read_pwd.c
*
* Copyright 1990,1991 by the Massachusetts Institute of Technology.
@@ -215,7 +209,7 @@ read_pwd_proc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
switch(msg) {
case WM_INITDIALOG:
dp = (pwd_params *) lParam;
- SetWindowLong(hdlg, DWL_USER, lParam);
+ SetWindowLongPtr(hdlg, DWLP_USER, lParam);
SetDlgItemText(hdlg, ID_READ_PWD_PROMPT, dp->pwd_prompt);
SetDlgItemText(hdlg, ID_READ_PWD_PROMPT2, dp->pwd_prompt2);
SetDlgItemText(hdlg, ID_READ_PWD_PWD, "");
@@ -223,7 +217,7 @@ read_pwd_proc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
return TRUE;
case WM_COMMAND:
- dp = (pwd_params *) GetWindowLong(hdlg, DWL_USER);
+ dp = (pwd_params *) GetWindowLongPtr(hdlg, DWLP_USER);
switch (wParam) {
case IDOK:
*(dp->pwd_size_return) =
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/sendto_kdc.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/sendto_kdc.c
index 9a57749fb2..88cece63d3 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/sendto_kdc.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/sendto_kdc.c
@@ -1,12 +1,11 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/sendto_kdc.c
*
- * Copyright 1990,1991,2001,2002 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,2001,2002,2004,2005,2007 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -33,10 +32,11 @@
* as necessary.
*/
-#define NEED_SOCKETS
-#define NEED_LOWLEVEL_IO
-#include <fake-addrinfo.h>
-#include <k5-int.h>
+#include "fake-addrinfo.h"
+#include "k5-int.h"
+
+/* Solaris Kerberos */
+#include <syslog.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
@@ -44,27 +44,46 @@
#include <time.h>
#endif
#include "os-proto.h"
+#ifdef _WIN32
+#include <sys/timeb.h>
+#endif
#ifdef _AIX
#include <sys/select.h>
#endif
+#ifndef _WIN32
/* For FIONBIO. */
#include <sys/ioctl.h>
#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h>
#endif
+#endif
#define MAX_PASS 3
/* Solaris Kerberos: moved to k5-int.h */
/* #define DEFAULT_UDP_PREF_LIMIT 1465 */
#define HARD_UDP_LIMIT 32700 /* could probably do 64K-epsilon ? */
-/* Solaris kerberos: leaving this here because other code depends on this. */
+#undef DEBUG
+
+#ifdef DEBUG
+int krb5int_debug_sendto_kdc = 0;
+#define debug krb5int_debug_sendto_kdc
+
static void default_debug_handler (const void *data, size_t len)
{
+#if 0
+ FILE *logfile;
+ logfile = fopen("/tmp/sendto_kdc.log", "a");
+ if (logfile == NULL)
+ return;
+ fwrite(data, 1, len, logfile);
+ fclose(logfile);
+#else
fwrite(data, 1, len, stderr);
/* stderr is unbuffered */
+#endif
}
void (*krb5int_sendtokdc_debug_handler) (const void *, size_t) = default_debug_handler;
@@ -73,26 +92,30 @@ void (*krb5int_sendtokdc_debug_handler) (const void *, size_t) = default_debug_h
* Solaris Kerberos: only including the debug stuff if DEBUG defined outside
* this file.
*/
-#ifdef DEBUG
-
static char global_err_str[NI_MAXHOST + NI_MAXSERV + 1024];
/* Solaris kerberos: removed put() since it isn't needed. */
+#if 0
+static void put(const void *ptr, size_t len)
+{
+ (*krb5int_sendtokdc_debug_handler)(ptr, len);
+}
+#endif
static void putstr(const char *str)
{
/* Solaris kerberos: build the string which will be passed to syslog later */
strlcat(global_err_str, str, sizeof (global_err_str));
}
+#else
+void (*krb5int_sendtokdc_debug_handler) (const void *, size_t) = 0;
+#endif
#define dprint krb5int_debug_fprint
-#define dperror dprint
-
-#include <com_err.h>
-
-static void
+ void
krb5int_debug_fprint (const char *fmt, ...)
{
+#ifdef DEBUG
va_list args;
/* Temporaries for variable arguments, etc. */
@@ -106,7 +129,10 @@ krb5int_debug_fprint (const char *fmt, ...)
const krb5_data *d;
char addrbuf[NI_MAXHOST], portbuf[NI_MAXSERV];
const char *p;
- char tmpbuf[NI_MAXHOST + NI_MAXSERV + 30];
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+ char tmpbuf[max(NI_MAXHOST + NI_MAXSERV + 30, 200)];
/*
* Solaris kerberos: modified this function to create a string to pass to
@@ -131,7 +157,6 @@ krb5int_debug_fprint (const char *fmt, ...)
case 0:
default:
abort();
- break;
case 'E':
/* %E => krb5_error_code */
kerr = va_arg(args, krb5_error_code);
@@ -146,7 +171,13 @@ krb5int_debug_fprint (const char *fmt, ...)
rather than the current value. */
err = va_arg(args, int);
putf("%d/", err);
- p = strerror(err);
+ p = NULL;
+#ifdef HAVE_STRERROR_R
+ if (strerror_r(err, tmpbuf, sizeof(tmpbuf)) == 0)
+ p = tmpbuf;
+#endif
+ if (p == NULL)
+ p = strerror(err);
putstr(p);
break;
case 'F':
@@ -198,24 +229,28 @@ krb5int_debug_fprint (const char *fmt, ...)
case 'A':
/* %A => addrinfo */
ai = va_arg(args, struct addrinfo *);
+ if (ai->ai_socktype == SOCK_DGRAM)
+ strcpy(tmpbuf, "dgram");
+ else if (ai->ai_socktype == SOCK_STREAM)
+ strcpy(tmpbuf, "stream");
+ else
+ sprintf(tmpbuf, "socktype%d", ai->ai_socktype);
if (0 != getnameinfo (ai->ai_addr, ai->ai_addrlen,
addrbuf, sizeof (addrbuf),
portbuf, sizeof (portbuf),
- NI_NUMERICHOST | NI_NUMERICSERV))
- /*LINTED*/
- strcpy (addrbuf, "??"), strcpy (portbuf, "??");
- sprintf(tmpbuf, "%s %s.%s",
- (ai->ai_socktype == SOCK_DGRAM
- ? "udp"
- : ai->ai_socktype == SOCK_STREAM
- ? "tcp"
- : "???"),
- addrbuf, portbuf);
+ NI_NUMERICHOST | NI_NUMERICSERV)) {
+ if (ai->ai_addr->sa_family == AF_UNSPEC)
+ strcpy(tmpbuf + strlen(tmpbuf), " AF_UNSPEC");
+ else
+ sprintf(tmpbuf + strlen(tmpbuf), " af%d", ai->ai_addr->sa_family);
+ } else
+ sprintf(tmpbuf + strlen(tmpbuf), " %s.%s", addrbuf, portbuf);
putstr(tmpbuf);
break;
case 'D':
/* %D => krb5_data * */
d = va_arg(args, krb5_data *);
+ /* Solaris Kerberos */
p = d->data;
putstr("0x");
for (i = 0; i < d->length; i++) {
@@ -228,29 +263,39 @@ krb5int_debug_fprint (const char *fmt, ...)
/* Solaris kerberos: use syslog() for debug output */
syslog(LOG_DEBUG, global_err_str);
+#endif
}
-#else
-#define dprint (void)
-#define dperror(MSG) ((void)(MSG))
-#endif
+#define print_addrlist krb5int_print_addrlist
+static void
+print_addrlist (const struct addrlist *a)
+{
+ int i;
+ dprint("%d{", a->naddrs);
+ for (i = 0; i < a->naddrs; i++)
+ dprint("%s%p=%A", i ? "," : "", (void*)a->addrs[i].ai, a->addrs[i].ai);
+ dprint("}");
+}
static int
merge_addrlists (struct addrlist *dest, struct addrlist *src)
{
+ /* Wouldn't it be nice if we could filter out duplicates? The
+ alloc/free handling makes that pretty difficult though. */
int err, i;
+/* Solaris Kerberos */
#ifdef DEBUG
/*LINTED*/
dprint("merging addrlists:\n\tlist1: ");
for (i = 0; i < dest->naddrs; i++)
/*LINTED*/
- dprint(" %A", dest->addrs[i]);
+ dprint(" %A", dest->addrs[i].ai);
/*LINTED*/
dprint("\n\tlist2: ");
for (i = 0; i < src->naddrs; i++)
/*LINTED*/
- dprint(" %A", src->addrs[i]);
+ dprint(" %A", src->addrs[i].ai);
/*LINTED*/
dprint("\n");
#endif
@@ -260,17 +305,19 @@ merge_addrlists (struct addrlist *dest, struct addrlist *src)
return err;
for (i = 0; i < src->naddrs; i++) {
dest->addrs[dest->naddrs + i] = src->addrs[i];
- src->addrs[i] = 0;
+ src->addrs[i].ai = 0;
+ src->addrs[i].freefn = 0;
}
dest->naddrs += i;
src->naddrs = 0;
+/* Solaris Kerberos */
#ifdef DEBUG
/*LINTED*/
dprint("\tout: ");
for (i = 0; i < dest->naddrs; i++)
/*LINTED*/
- dprint(" %A", dest->addrs[i]);
+ dprint(" %A", dest->addrs[i].ai);
/*LINTED*/
dprint("\n");
#endif
@@ -278,6 +325,43 @@ merge_addrlists (struct addrlist *dest, struct addrlist *src)
return 0;
}
+static int
+in_addrlist (struct addrinfo *thisaddr, struct addrlist *list)
+{
+ int i;
+ for (i = 0; i < list->naddrs; i++) {
+ if (thisaddr->ai_addrlen == list->addrs[i].ai->ai_addrlen
+ && !memcmp(thisaddr->ai_addr, list->addrs[i].ai->ai_addr,
+ thisaddr->ai_addrlen))
+ return 1;
+ }
+ return 0;
+}
+
+static int
+check_for_svc_unavailable (krb5_context context,
+ const krb5_data *reply,
+ void *msg_handler_data)
+{
+ krb5_error_code *retval = (krb5_error_code *)msg_handler_data;
+
+ *retval = 0;
+
+ if (krb5_is_krb_error(reply)) {
+ krb5_error *err_reply;
+
+ if (decode_krb5_error(reply, &err_reply) == 0) {
+ *retval = err_reply->error;
+ krb5_free_error(context, err_reply);
+
+ /* Returning 0 means continue to next KDC */
+ return (*retval != KDC_ERR_SVC_UNAVAILABLE);
+ }
+ }
+
+ return 1;
+}
+
/*
* send the formatted request 'message' to a KDC for realm 'realm' and
* return the response (if any) in 'reply'.
@@ -294,7 +378,7 @@ krb5_sendto_kdc (krb5_context context, const krb5_data *message,
const krb5_data *realm, krb5_data *reply,
int *use_master, int tcp_only)
{
- krb5_error_code retval;
+ krb5_error_code retval, retval2;
struct addrlist addrs;
int socktype1 = 0, socktype2 = 0, addr_used;
@@ -346,50 +430,85 @@ krb5_sendto_kdc (krb5_context context, const krb5_data *message,
if (socktype2) {
struct addrlist addrs2;
- retval = krb5_locate_kdc(context, realm, &addrs2, *use_master,
- socktype2, 0);
+ retval2 = krb5_locate_kdc(context, realm, &addrs2, *use_master,
+ socktype2, 0);
+#if 0
+ if (retval2 == 0) {
+ (void) merge_addrlists(&addrs, &addrs2);
+ krb5int_free_addrlist(&addrs2);
+ retval = 0;
+ } else if (retval == KRB5_REALM_CANT_RESOLVE) {
+ retval = retval2;
+ }
+#else
+ retval = retval2;
if (retval == 0) {
(void) merge_addrlists(&addrs, &addrs2);
krb5int_free_addrlist(&addrs2);
}
+#endif
}
+
if (addrs.naddrs > 0) {
- retval = krb5int_sendto (context, message, &addrs, reply, 0, 0,
- &addr_used);
- if (retval == 0) {
+ krb5_error_code err = 0;
+
+ retval = krb5int_sendto (context, message, &addrs, 0, reply, 0, 0,
+ 0, 0, &addr_used, check_for_svc_unavailable, &err);
+ switch (retval) {
+ case 0:
/*
- * Set use_master to 1 if we ended up talking to a master when
- * didn't explicitly request to
- */
-
- if (*use_master == 0) {
- struct addrlist addrs3;
- retval = krb5_locate_kdc(context, realm, &addrs3, 1,
- addrs.addrs[addr_used]->ai_socktype,
- addrs.addrs[addr_used]->ai_family);
- if (retval == 0) {
- int i;
- for (i = 0; i < addrs3.naddrs; i++) {
- if (addrs.addrs[addr_used]->ai_addrlen ==
- addrs3.addrs[i]->ai_addrlen &&
- memcmp(addrs.addrs[addr_used]->ai_addr,
- addrs3.addrs[i]->ai_addr,
- addrs.addrs[addr_used]->ai_addrlen) == 0) {
- *use_master = 1;
- break;
- }
- }
- krb5int_free_addrlist (&addrs3);
- }
+ * Set use_master to 1 if we ended up talking to a master when
+ * we didn't explicitly request to
+ */
+ if (*use_master == 0) {
+ struct addrlist addrs3;
+ retval = krb5_locate_kdc(context, realm, &addrs3, 1,
+ addrs.addrs[addr_used].ai->ai_socktype,
+ addrs.addrs[addr_used].ai->ai_family);
+ if (retval == 0) {
+ if (in_addrlist(addrs.addrs[addr_used].ai, &addrs3))
+ *use_master = 1;
+ krb5int_free_addrlist (&addrs3);
+ }
+ }
+ krb5int_free_addrlist (&addrs);
+ return 0;
+ default:
+ break;
+ /* Cases here are for constructing useful error messages. */
+ case KRB5_KDC_UNREACH:
+ if (err == KDC_ERR_SVC_UNAVAILABLE) {
+ retval = KRB5KDC_ERR_SVC_UNAVAILABLE;
+ } else {
+ krb5_set_error_message(context, retval,
+ "Cannot contact any KDC for realm '%.*s'",
+ realm->length, realm->data);
}
- krb5int_free_addrlist (&addrs);
- return 0;
+ break;
}
- krb5int_free_addrlist (&addrs);
+ krb5int_free_addrlist (&addrs);
}
return retval;
}
+#ifdef DEBUG
+
+#ifdef _WIN32
+#define dperror(MSG) \
+ dprint("%s: an error occurred ... " \
+ "\tline=%d errno=%m socketerrno=%m\n", \
+ (MSG), __LINE__, errno, SOCKET_ERRNO)
+#else
+#define dperror(MSG) dprint("%s: %m\n", MSG, errno)
+#endif
+#define dfprintf(ARGLIST) (debug ? fprintf ARGLIST : 0)
+
+#else /* ! DEBUG */
+
+#define dperror(MSG) ((void)(MSG))
+#define dfprintf(ARGLIST) ((void)0)
+
+#endif
/*
* Notes:
@@ -411,44 +530,24 @@ krb5_sendto_kdc (krb5_context context, const krb5_data *message,
* connections already in progress
*/
-#include <cm.h>
-
-static const char *const state_strings[] = {
- "INITIALIZING", "CONNECTING", "WRITING", "READING", "FAILED"
-};
-enum conn_states { INITIALIZING, CONNECTING, WRITING, READING, FAILED };
-struct incoming_krb5_message {
- size_t bufsizebytes_read;
- size_t bufsize;
- char *buf;
- char *pos;
- unsigned char bufsizebytes[4];
- size_t n_left;
-};
-struct conn_state {
- SOCKET fd;
- krb5_error_code err;
- enum conn_states state;
- unsigned int is_udp : 1;
- int (*service)(struct conn_state *, struct select_state *, int);
- struct addrinfo *addr;
- struct {
- struct {
- sg_buf sgbuf[2];
- sg_buf *sgp;
- int sg_count;
- } out;
- struct incoming_krb5_message in;
- } x;
-};
+#include "cm.h"
static int getcurtime (struct timeval *tvp)
{
+#ifdef _WIN32
+ struct _timeb tb;
+ _ftime(&tb);
+ tvp->tv_sec = tb.time;
+ tvp->tv_usec = tb.millitm * 1000;
+ /* Can _ftime fail? */
+ return 0;
+#else
if (gettimeofday(tvp, 0)) {
dperror("gettimeofday");
return errno;
}
return 0;
+#endif
}
/*
@@ -486,10 +585,13 @@ krb5int_cm_call_select (const struct select_state *in,
/*LINTED*/
dprint("selecting on max=%d sockets [%F] timeout %t\n",
/*LINTED*/
- out->max, &out->rfds, &out->wfds, &out->xfds, out->max, timo);
+ out->max,
+ &out->rfds, &out->wfds, &out->xfds, out->max,
+ timo);
*sret = select(out->max, &out->rfds, &out->wfds, &out->xfds, timo);
e = SOCKET_ERRNO;
+/* Solaris Kerberos */
#ifdef DEBUG
/*LINTED*/
dprint("select returns %d", *sret);
@@ -514,11 +616,37 @@ static int service_tcp_fd (struct conn_state *conn,
static int service_udp_fd (struct conn_state *conn,
struct select_state *selstate, int ssflags);
+static void
+set_conn_state_msg_length (struct conn_state *state, const krb5_data *message)
+{
+ if (!message || message->length == 0)
+ return;
+
+ if (!state->is_udp) {
+
+ state->x.out.msg_len_buf[0] = (message->length >> 24) & 0xff;
+ state->x.out.msg_len_buf[1] = (message->length >> 16) & 0xff;
+ state->x.out.msg_len_buf[2] = (message->length >> 8) & 0xff;
+ state->x.out.msg_len_buf[3] = message->length & 0xff;
+
+ SG_SET(&state->x.out.sgbuf[0], state->x.out.msg_len_buf, 4);
+ SG_SET(&state->x.out.sgbuf[1], message->data, message->length);
+ state->x.out.sg_count = 2;
+
+ } else {
+
+ SG_SET(&state->x.out.sgbuf[0], message->data, message->length);
+ SG_SET(&state->x.out.sgbuf[1], 0, 0);
+ state->x.out.sg_count = 1;
+
+ }
+}
+
+
static int
setup_connection (struct conn_state *state, struct addrinfo *ai,
- const krb5_data *message, unsigned char *message_len_buf,
- char **udpbufp)
+ const krb5_data *message, char **udpbufp)
{
state->state = INITIALIZING;
state->err = 0;
@@ -527,17 +655,25 @@ setup_connection (struct conn_state *state, struct addrinfo *ai,
state->fd = INVALID_SOCKET;
SG_SET(&state->x.out.sgbuf[1], 0, 0);
if (ai->ai_socktype == SOCK_STREAM) {
+ /*
SG_SET(&state->x.out.sgbuf[0], message_len_buf, 4);
SG_SET(&state->x.out.sgbuf[1], message->data, message->length);
state->x.out.sg_count = 2;
+ */
+
state->is_udp = 0;
state->service = service_tcp_fd;
+ set_conn_state_msg_length (state, message);
} else {
+ /*
SG_SET(&state->x.out.sgbuf[0], message->data, message->length);
SG_SET(&state->x.out.sgbuf[1], 0, 0);
state->x.out.sg_count = 1;
+ */
+
state->is_udp = 1;
state->service = service_udp_fd;
+ set_conn_state_msg_length (state, message);
if (*udpbufp == 0) {
*udpbufp = malloc(krb5_max_dgram_size);
@@ -556,7 +692,10 @@ setup_connection (struct conn_state *state, struct addrinfo *ai,
}
static int
-start_connection (struct conn_state *state, struct select_state *selstate)
+start_connection (struct conn_state *state,
+ struct select_state *selstate,
+ struct sendto_callback_info* callback_info,
+ krb5_data* callback_buffer)
{
int fd, e;
struct addrinfo *ai = state->addr;
@@ -594,9 +733,11 @@ start_connection (struct conn_state *state, struct select_state *selstate)
*/
if (SOCKET_ERRNO == EINPROGRESS || SOCKET_ERRNO == EWOULDBLOCK) {
state->state = CONNECTING;
+ state->fd = fd;
} else {
/*LINTED*/
dprint("connect failed: %m\n", SOCKET_ERRNO);
+ (void) closesocket(fd);
state->err = SOCKET_ERRNO;
state->state = FAILED;
return -2;
@@ -609,11 +750,37 @@ start_connection (struct conn_state *state, struct select_state *selstate)
* stack is broken, but if they gave us a connection, use it.
*/
state->state = WRITING;
+ state->fd = fd;
}
/*LINTED*/
dprint("new state = %s\n", state_strings[state->state]);
- state->fd = fd;
+
+ /*
+ * Here's where KPASSWD callback gets the socket information it needs for
+ * a kpasswd request
+ */
+ if (callback_info) {
+
+ e = callback_info->pfn_callback(state,
+ callback_info->context,
+ callback_buffer);
+ if (e != 0) {
+ dprint("callback failed: %m\n", e);
+ (void) closesocket(fd);
+ state->err = e;
+ state->fd = INVALID_SOCKET;
+ state->state = FAILED;
+ return -3;
+ }
+
+ dprint("callback %p (message=%d@%p)\n",
+ state,
+ callback_buffer->length,
+ callback_buffer->data);
+
+ set_conn_state_msg_length( state, callback_buffer );
+ }
if (ai->ai_socktype == SOCK_DGRAM) {
/* Send it now. */
@@ -628,12 +795,26 @@ start_connection (struct conn_state *state, struct select_state *selstate)
(void) closesocket(state->fd);
state->fd = INVALID_SOCKET;
state->state = FAILED;
- return -3;
+ return -4;
} else {
state->state = READING;
}
}
-
+#ifdef DEBUG
+ if (debug) {
+ struct sockaddr_storage ss;
+ socklen_t sslen = sizeof(ss);
+ if (getsockname(state->fd, (struct sockaddr *)&ss, &sslen) == 0) {
+ struct addrinfo hack_ai;
+ memset(&hack_ai, 0, sizeof(hack_ai));
+ hack_ai.ai_addr = (struct sockaddr *) &ss;
+ hack_ai.ai_addrlen = sslen;
+ hack_ai.ai_socktype = SOCK_DGRAM;
+ hack_ai.ai_family = ai->ai_family;
+ dprint("local socket address is %A\n", &hack_ai);
+ }
+ }
+#endif
FD_SET(state->fd, &selstate->rfds);
if (state->state == CONNECTING || state->state == WRITING)
FD_SET(state->fd, &selstate->wfds);
@@ -655,16 +836,20 @@ start_connection (struct conn_state *state, struct select_state *selstate)
Otherwise, the caller should immediately move on to process the
next connection. */
static int
-maybe_send (struct conn_state *conn, struct select_state *selstate)
+maybe_send (struct conn_state *conn,
+ struct select_state *selstate,
+ struct sendto_callback_info* callback_info,
+ krb5_data* callback_buffer)
{
sg_buf *sg;
/*LINTED*/
dprint("maybe_send(@%p) state=%s type=%s\n", conn,
/*LINTED*/
- state_strings[conn->state], conn->is_udp ? "udp" : "tcp");
+ state_strings[conn->state],
+ conn->is_udp ? "udp" : "tcp");
if (conn->state == INITIALIZING)
- return start_connection(conn, selstate);
+ return start_connection(conn, selstate, callback_info, callback_buffer);
/* Did we already shut down this channel? */
if (conn->state == FAILED) {
@@ -720,6 +905,25 @@ kill_conn(struct conn_state *conn, struct select_state *selstate, int err)
selstate->nfds--;
}
+/* Check socket for error. */
+static int
+get_so_error(int fd)
+{
+ int e, sockerr;
+ socklen_t sockerrlen;
+
+ sockerr = 0;
+ sockerrlen = sizeof(sockerr);
+ e = getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &sockerrlen);
+ if (e != 0) {
+ /* What to do now? */
+ e = SOCKET_ERRNO;
+ dprint("getsockopt(SO_ERROR) on fd failed: %m\n", e);
+ return e;
+ }
+ return sockerr;
+}
+
/* Return nonzero only if we're finished and the caller should exit
its loop. This happens in two cases: We have a complete message,
or the socket has closed and no others are open. */
@@ -750,15 +954,28 @@ service_tcp_fd (struct conn_state *conn, struct select_state *selstate,
}
if (ssflags & SSF_EXCEPTION) {
handle_exception:
- e = 1; /* need only be non-zero */
+ e = get_so_error(conn->fd);
+ if (e)
+ dprint("socket error on exception fd: %m", e);
+ else
+ dprint("no socket error info available on exception fd");
goto kill_conn;
}
/*
* Connect finished -- but did it succeed or fail?
* UNIX sets can_write if failed.
- * Try writing, I guess, and find out.
+ * Call getsockopt to see if error pending.
+ *
+ * (For most UNIX systems it works to just try writing the
+ * first time and detect an error. But Bill Dodd at IBM
+ * reports that some version of AIX, SIGPIPE can result.)
*/
+ e = get_so_error(conn->fd);
+ if (e) {
+ dprint("socket error on write fd: %m", e);
+ goto kill_conn;
+ }
conn->state = WRITING;
goto try_writing;
@@ -847,6 +1064,7 @@ service_tcp_fd (struct conn_state *conn, struct select_state *selstate,
}
conn->x.in.n_left -= nread;
conn->x.in.pos += nread;
+ /* Solaris Kerberos */
if ((long)conn->x.in.n_left <= 0) {
/* We win! */
return 1;
@@ -915,15 +1133,18 @@ service_udp_fd(struct conn_state *conn, struct select_state *selstate,
}
static int
-service_fds (struct select_state *selstate,
- struct conn_state *conns, size_t n_conns, int *winning_conn)
+service_fds (krb5_context context,
+ struct select_state *selstate,
+ struct conn_state *conns, size_t n_conns, int *winning_conn,
+ struct select_state *seltemp,
+ int (*msg_handler)(krb5_context, const krb5_data *, void *),
+ void *msg_handler_data)
{
int e, selret;
- struct select_state sel_results;
e = 0;
while (selstate->nfds > 0
- && (e = krb5int_cm_call_select(selstate, &sel_results, &selret)) == 0) {
+ && (e = krb5int_cm_call_select(selstate, seltemp, &selret)) == 0) {
int i;
/*LINTED*/
@@ -940,11 +1161,11 @@ service_fds (struct select_state *selstate,
if (conns[i].fd == INVALID_SOCKET)
continue;
ssflags = 0;
- if (FD_ISSET(conns[i].fd, &sel_results.rfds))
+ if (FD_ISSET(conns[i].fd, &seltemp->rfds))
ssflags |= SSF_READ, selret--;
- if (FD_ISSET(conns[i].fd, &sel_results.wfds))
+ if (FD_ISSET(conns[i].fd, &seltemp->wfds))
ssflags |= SSF_WRITE, selret--;
- if (FD_ISSET(conns[i].fd, &sel_results.xfds))
+ if (FD_ISSET(conns[i].fd, &seltemp->xfds))
ssflags |= SSF_EXCEPTION, selret--;
if (!ssflags)
continue;
@@ -962,9 +1183,22 @@ service_fds (struct select_state *selstate,
state_strings[(int) conns[i].state]);
if (conns[i].service (&conns[i], selstate, ssflags)) {
- dprint("fd service routine says we're done\n");
- *winning_conn = i;
- return 1;
+ int stop = 1;
+
+ if (msg_handler != NULL) {
+ krb5_data reply;
+
+ reply.data = conns[i].x.in.buf;
+ reply.length = conns[i].x.in.pos - conns[i].x.in.buf;
+
+ stop = (msg_handler(context, &reply, msg_handler_data) != 0);
+ }
+
+ if (stop) {
+ dprint("fd service routine says we're done\n");
+ *winning_conn = i;
+ return 1;
+ }
}
}
}
@@ -1002,23 +1236,32 @@ service_fds (struct select_state *selstate,
krb5_error_code
/*ARGSUSED*/
krb5int_sendto (krb5_context context, const krb5_data *message,
- const struct addrlist *addrs, krb5_data *reply,
- struct sockaddr_storage *localaddr, socklen_t *localaddrlen,
- int *addr_used)
+ const struct addrlist *addrs,
+ struct sendto_callback_info* callback_info, krb5_data *reply,
+ struct sockaddr *localaddr, socklen_t *localaddrlen,
+ struct sockaddr *remoteaddr, socklen_t *remoteaddrlen,
+ int *addr_used,
+ /* return 0 -> keep going, 1 -> quit */
+ int (*msg_handler)(krb5_context, const krb5_data *, void *),
+ void *msg_handler_data)
{
int i, pass;
int delay_this_pass = 2;
krb5_error_code retval;
struct conn_state *conns;
+ krb5_data *callback_data = 0;
size_t n_conns, host;
- struct select_state select_state;
+ struct select_state *sel_state;
struct timeval now;
int winning_conn = -1, e = 0;
- unsigned char message_len_buf[4];
char *udpbuf = 0;
- /*LINTED*/
- dprint("krb5int_sendto(message=%d@%p)\n", message->length, message->data);
+ if (message)
+ dprint("krb5int_sendto(message=%d@%p, addrlist=", message->length, message->data);
+ else
+ dprint("krb5int_sendto(callback=%p, addrlist=", callback_info);
+ print_addrlist(addrs);
+ dprint(")\n");
reply->data = 0;
reply->length = 0;
@@ -1028,26 +1271,43 @@ krb5int_sendto (krb5_context context, const krb5_data *message,
if (conns == NULL) {
return ENOMEM;
}
- memset(conns, 0, n_conns * sizeof(conns[i]));
+
+ memset(conns, 0, n_conns * sizeof(struct conn_state));
+
+ if (callback_info) {
+ callback_data = malloc(n_conns * sizeof(krb5_data));
+ if (callback_data == NULL) {
+ return ENOMEM;
+ }
+
+ memset(callback_data, 0, n_conns * sizeof(krb5_data));
+ }
+
for (i = 0; i < n_conns; i++) {
conns[i].fd = INVALID_SOCKET;
}
- select_state.max = 0;
- select_state.nfds = 0;
- FD_ZERO(&select_state.rfds);
- FD_ZERO(&select_state.wfds);
- FD_ZERO(&select_state.xfds);
+ /* One for use here, listing all our fds in use, and one for
+ temporary use in service_fds, for the fds of interest. */
+ sel_state = malloc(2 * sizeof(*sel_state));
+ if (sel_state == NULL) {
+ free(conns);
+ return ENOMEM;
+ }
+ sel_state->max = 0;
+ sel_state->nfds = 0;
+ sel_state->end_time.tv_sec = sel_state->end_time.tv_usec = 0;
+ FD_ZERO(&sel_state->rfds);
+ FD_ZERO(&sel_state->wfds);
+ FD_ZERO(&sel_state->xfds);
- message_len_buf[0] = (message->length >> 24) & 0xff;
- message_len_buf[1] = (message->length >> 16) & 0xff;
- message_len_buf[2] = (message->length >> 8) & 0xff;
- message_len_buf[3] = message->length & 0xff;
/* Set up connections. */
for (host = 0; host < n_conns; host++) {
- retval = setup_connection (&conns[host], addrs->addrs[host],
- message, message_len_buf, &udpbuf);
+ retval = setup_connection(&conns[host],
+ addrs->addrs[host].ai,
+ message,
+ &udpbuf);
if (retval)
continue;
}
@@ -1061,18 +1321,22 @@ krb5int_sendto (krb5_context context, const krb5_data *message,
dprint("host %d\n", host);
/* Send to the host, wait for a response, then move on. */
- if (maybe_send(&conns[host], &select_state))
+ if (maybe_send(&conns[host],
+ sel_state,
+ callback_info,
+ (callback_info ? &callback_data[host] : NULL)))
continue;
retval = getcurtime(&now);
if (retval)
goto egress;
- select_state.end_time = now;
- select_state.end_time.tv_sec += 1;
- e = service_fds(&select_state, conns, host+1, &winning_conn);
+ sel_state->end_time = now;
+ sel_state->end_time.tv_sec += 1;
+ e = service_fds(context, sel_state, conns, host+1, &winning_conn,
+ sel_state+1, msg_handler, msg_handler_data);
if (e)
break;
- if (pass > 0 && select_state.nfds == 0)
+ if (pass > 0 && sel_state->nfds == 0)
/*
* After the first pass, if we close all fds, break
* out right away. During the first pass, it's okay,
@@ -1088,16 +1352,17 @@ krb5int_sendto (krb5_context context, const krb5_data *message,
/* Possible optimization: Find a way to integrate this select
call with the last one from the above loop, if the loop
actually calls select. */
- select_state.end_time.tv_sec += delay_this_pass;
- e = service_fds(&select_state, conns, host+1, &winning_conn);
+ sel_state->end_time.tv_sec += delay_this_pass;
+ e = service_fds(context, sel_state, conns, host+1, &winning_conn,
+ sel_state+1, msg_handler, msg_handler_data);
if (e)
break;
- if (select_state.nfds == 0)
+ if (sel_state->nfds == 0)
break;
delay_this_pass *= 2;
}
- if (select_state.nfds == 0) {
+ if (sel_state->nfds == 0) {
/* No addresses? */
retval = KRB5_KDC_UNREACH;
goto egress;
@@ -1111,26 +1376,37 @@ krb5int_sendto (krb5_context context, const krb5_data *message,
reply->length = (conns[winning_conn].x.in.pos
- conns[winning_conn].x.in.buf);
/*LINTED*/
- dprint("returning %d bytes in buffer %p (winning_conn=%d)\n",
- (int) reply->length, reply->data, winning_conn);
+ dprint("returning %d bytes in buffer %p\n",
+ (int) reply->length, reply->data);
retval = 0;
conns[winning_conn].x.in.buf = 0;
if (addr_used)
- *addr_used = winning_conn;
+ *addr_used = winning_conn;
if (localaddr != 0 && localaddrlen != 0 && *localaddrlen > 0)
- (void) getsockname(conns[winning_conn].fd, (struct sockaddr *)localaddr,
- localaddrlen);
+ (void) getsockname(conns[winning_conn].fd, localaddr, localaddrlen);
+
+ if (remoteaddr != 0 && remoteaddrlen != 0 && *remoteaddrlen > 0)
+ (void) getpeername(conns[winning_conn].fd, remoteaddr, remoteaddrlen);
+
egress:
for (i = 0; i < n_conns; i++) {
if (conns[i].fd != INVALID_SOCKET)
- close(conns[i].fd);
+ closesocket(conns[i].fd);
if (conns[i].state == READING
&& conns[i].x.in.buf != 0
&& conns[i].x.in.buf != udpbuf)
free(conns[i].x.in.buf);
+ if (callback_info) {
+ callback_info->pfn_cleanup( callback_info->context, &callback_data[i]);
+ }
}
+
+ if (callback_data)
+ free(callback_data);
+
free(conns);
if (reply->data != udpbuf)
free(udpbuf);
+ free(sel_state);
return retval;
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/sn2princ.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/sn2princ.c
index ac2fcc09aa..a865683b5e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/sn2princ.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/sn2princ.c
@@ -33,14 +33,19 @@
* form.
*/
-#include <k5-int.h>
+#include "k5-int.h"
+#include "os-proto.h"
#include "fake-addrinfo.h"
#include <ctype.h>
-#include <netdb.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
+#if !defined(DEFAULT_RDNS_LOOKUP)
+/* Solaris Kerberos */
+#define DEFAULT_RDNS_LOOKUP 0
+#endif
+
/*
* Solaris Kerberos:
* The following prototypes are needed because these are
@@ -50,25 +55,41 @@ extern struct hostent *res_getipnodebyname(const char *, int, int, int *);
extern struct hostent *res_getipnodebyaddr(const void *, size_t, int, int *);
extern void res_freehostent(struct hostent *);
+static int
+maybe_use_reverse_dns (krb5_context context, int defalt)
+{
+ krb5_error_code code;
+ char * value = NULL;
+ int use_rdns = 0;
+
+ code = profile_get_string(context->profile, "libdefaults",
+ "rdns", 0, 0, &value);
+ if (code)
+ return defalt;
+
+ if (value == 0)
+ return defalt;
+
+ use_rdns = _krb5_conf_boolean(value);
+ profile_release_string(value);
+ return use_rdns;
+}
+
+
/*
+ * Solaris Kerberos:
* Note, krb5_sname_to_principal() allocates memory for ret_princ. Be sure to
* use krb5_free_principal() on ret_princ to free it when done referencing it.
*/
-krb5_error_code KRB5_CALLCONV
+krb5_error_code KRB5_CALLCONV
krb5_sname_to_principal(krb5_context context, const char *hostname, const char *sname, krb5_int32 type, krb5_principal *ret_princ)
{
char **hrealms, *realm, *remote_host;
krb5_error_code retval;
register char *cp;
char localname[MAXHOSTNAMELEN];
- /*
- * Solaris Kerberos:
- * Indicate whether or not to do a reverse lookup on a hostname for a host
- * based principal.
- */
- int rev_lookup = NO_REV_LOOKUP;
-
- KRB5_LOG0(KRB5_INFO, "krb5_sname_to_principal() start");
+ /* Solaris Kerberos */
+ KRB5_LOG0(KRB5_INFO, "krb5_sname_to_principal() start");
#ifdef DEBUG_REFERRALS
printf("krb5_sname_to_principal(host=%s, sname=%s, type=%d)\n",hostname,sname,type);
printf(" name types: 0=unknown, 3=srv_host\n");
@@ -80,6 +101,7 @@ krb5_sname_to_principal(krb5_context context, const char *hostname, const char *
/* if hostname is NULL, use local hostname */
if (! hostname) {
if (gethostname(localname, MAXHOSTNAMELEN)) {
+ /* Solaris Kerberos */
KRB5_LOG0(KRB5_ERR, "krb5_sname_to_principal()"
" gethostname failed");
return SOCKET_ERRNO;
@@ -92,19 +114,97 @@ krb5_sname_to_principal(krb5_context context, const char *hostname, const char *
sname = "host";
/* copy the hostname into non-volatile storage */
+
if (type == KRB5_NT_SRV_HST) {
- /* Solaris Kerberos: don't want to do reverse lookup at this point
- * as this will introduce a behavior change. ifdef'ing this out in
- * case we want to allow reverse lookup as a compile option.
- */
-#ifdef KRB5_SNAME_TO_PRINCIPAL_REV_LOOKUP
- rev_lookup = REV_LOOKUP;
+ /* Solaris Kerberos */
+ struct hostent *hp = NULL;
+ struct hostent *hp2 = NULL;
+ int err;
+ int addr_family;
+
+ /* Note that the old code would accept numeric addresses,
+ and if the gethostbyaddr step could convert them to
+ real hostnames, you could actually get reasonable
+ results. If the mapping failed, you'd get dotted
+ triples as realm names. *sigh*
+
+ The latter has been fixed in hst_realm.c, but we should
+ keep supporting numeric addresses if they do have
+ hostnames associated. */
+
+ /*
+ * Solaris kerberos: using res_getipnodebyname() to force dns name
+ * resolution. Note, res_getaddrinfo() isn't exported by libreolv
+ * so we use res_getipnodebyname() (MIT uses getaddrinfo()).
+ */
+ KRB5_LOG(KRB5_INFO, "krb5_sname_to_principal() hostname %s",
+ hostname);
+
+ addr_family = AF_INET;
+ try_getipnodebyname_again:
+ hp = res_getipnodebyname(hostname, addr_family, 0, &err);
+ if (!hp) {
+#ifdef DEBUG_REFERRALS
+ printf("sname_to_princ: probably punting due to bad hostname of %s\n",hostname);
#endif
- if (retval = krb5int_lookup_host(rev_lookup, hostname, &remote_host)) {
- return retval;
- }
+ if (addr_family == AF_INET) {
+ KRB5_LOG(KRB5_INFO, "krb5_sname_to_principal()"
+ " can't get AF_INET addr, err = %d", err);
+ /* Just in case it's an IPv6-only name. */
+ addr_family = AF_INET6;
+ goto try_getipnodebyname_again;
+ }
+ KRB5_LOG(KRB5_ERR, "krb5_sname_to_principal()"
+ " can't get AF_INET or AF_INET6 addr,"
+ " err = %d", err);
+ return KRB5_ERR_BAD_HOSTNAME;
+ }
+ remote_host = strdup(hp ? hp->h_name : hostname);
+ if (!remote_host) {
+ if (hp != NULL)
+ res_freehostent(hp);
+ return ENOMEM;
+ }
+
+ if (maybe_use_reverse_dns(context, DEFAULT_RDNS_LOOKUP)) {
+ /*
+ * Do a reverse resolution to get the full name, just in
+ * case there's some funny business going on. If there
+ * isn't an in-addr record, give up.
+ */
+ /* XXX: This is *so* bogus. There are several cases where
+ this won't get us the canonical name of the host, but
+ this is what we've trained people to expect. We'll
+ probably fix it at some point, but let's try to
+ preserve the current behavior and only shake things up
+ once when it comes time to fix this lossage. */
+ hp2 = res_getipnodebyaddr(hp->h_addr, hp->h_length,
+ hp->h_addrtype, &err);
+
+ if (hp2 != NULL) {
+ free(remote_host);
+ remote_host = strdup(hp2->h_name);
+ if (!remote_host) {
+ res_freehostent(hp2);
+ if (hp != NULL)
+ res_freehostent(hp);
+ return ENOMEM;
+ }
+ KRB5_LOG(KRB5_INFO, "krb5_sname_to_principal() remote_host %s",
+ remote_host);
+ }
+ }
+
+ if (hp != NULL) {
+ res_freehostent(hp);
+ }
+
+ if (hp2 != NULL) {
+ res_freehostent(hp2);
+ }
+
} else /* type == KRB5_NT_UNKNOWN */ {
- remote_host = strdup((char *) hostname);
+ remote_host = strdup(hostname);
}
if (!remote_host)
return ENOMEM;
@@ -114,8 +214,8 @@ krb5_sname_to_principal(krb5_context context, const char *hostname, const char *
if (type == KRB5_NT_SRV_HST)
for (cp = remote_host; *cp; cp++)
- if (isupper((int) *cp))
- *cp = tolower((int) *cp);
+ if (isupper((unsigned char) (*cp)))
+ *cp = tolower((unsigned char) (*cp));
/*
* Windows NT5's broken resolver gratuitously tacks on a
@@ -123,12 +223,13 @@ krb5_sname_to_principal(krb5_context context, const char *hostname, const char *
* Beta2). Find and remove it.
*/
if (remote_host[0]) {
- cp = remote_host + strlen(remote_host)-1;
- if (*cp == '.')
- *cp = 0;
+ cp = remote_host + strlen(remote_host)-1;
+ if (*cp == '.')
+ *cp = 0;
}
- if (retval = krb5_get_host_realm(context, remote_host, &hrealms)) {
+
+ if ((retval = krb5_get_host_realm(context, remote_host, &hrealms))) {
free(remote_host);
return retval;
}
@@ -166,95 +267,3 @@ krb5_sname_to_principal(krb5_context context, const char *hostname, const char *
}
}
-/*
- * Solaris Kerberos:
- * Lookup a host in DNS. If hostname cannot be resolved in DNS return
- * KRB5_ERR_BAD_HOSTNAME.
- * If "rev_lookup" is non-zero a reverse lookup will be performed.
- * "remote_host" will point to the resolved hostname.
- * Code taken from krb5_sname_to_principal().
- */
-krb5_error_code
-krb5int_lookup_host(int rev_lookup, const char *hostname, char **remote_host) {
- struct hostent *hp = NULL;
- struct hostent *hp2 = NULL;
- int addr_family;
- int err;
-
- /* Note that the old code would accept numeric addresses,
- and if the gethostbyaddr step could convert them to
- real hostnames, you could actually get reasonable
- results. If the mapping failed, you'd get dotted
- triples as realm names. *sigh*
-
- The latter has been fixed in hst_realm.c, but we should
- keep supporting numeric addresses if they do have
- hostnames associated. */
-
- /*
- * Solaris kerberos: using res_getipnodebyname() to force dns name
- * resolution. Note, res_getaddrinfo() isn't exported by libreolv
- * so we use res_getipnodebyname() (MIT uses getaddrinfo()).
- */
- KRB5_LOG(KRB5_INFO, "krb5int_lookup_host() hostname %s",
- hostname);
-
- addr_family = AF_INET;
-try_getipnodebyname_again:
- hp = res_getipnodebyname(hostname, addr_family, 0, &err);
- if (!hp) {
- if (addr_family == AF_INET) {
- KRB5_LOG(KRB5_INFO, "krb5int_lookup_host()"
- " can't get AF_INET addr, err = %d", err);
- /* Just in case it's an IPv6-only name. */
- addr_family = AF_INET6;
- goto try_getipnodebyname_again;
- }
- KRB5_LOG(KRB5_ERR, "krb5int_lookup_host()"
- " can't get AF_INET or AF_INET6 addr,"
- " err = %d", err);
- return (KRB5_ERR_BAD_HOSTNAME);
- }
- *remote_host = strdup(hp ? hp->h_name : hostname);
- if (!*remote_host) {
- if (hp != NULL)
- res_freehostent(hp);
- return ENOMEM;
- }
-
- if (rev_lookup) {
- /*
- * Do a reverse resolution to get the full name, just in
- * case there's some funny business going on. If there
- * isn't an in-addr record, give up.
- */
- /* XXX: This is *so* bogus. There are several cases where
- this won't get us the canonical name of the host, but
- this is what we've trained people to expect. We'll
- probably fix it at some point, but let's try to
- preserve the current behavior and only shake things up
- once when it comes time to fix this lossage. */
-
- hp2 = res_getipnodebyaddr(hp->h_addr, hp->h_length,
- hp->h_addrtype, &err);
- if (hp2 != NULL) {
- free(*remote_host);
- *remote_host = strdup(hp2->h_name);
- if (!*remote_host) {
- res_freehostent(hp2);
- if (hp != NULL)
- res_freehostent(hp);
- return ENOMEM;
- }
- KRB5_LOG(KRB5_INFO, "krb5int_lookup_host() remote_host %s",
- *remote_host);
- }
- }
- if (hp != NULL) {
- res_freehostent(hp);
- }
- if (hp2 != NULL) {
- res_freehostent(hp2);
- }
- return (0);
-}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/unlck_file.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/unlck_file.c
index cdfb6b2e6f..0bbf7ce316 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/unlck_file.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/unlck_file.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/unlck_file.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/ustime.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/ustime.c
index e38005d7bc..ef923d387c 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/ustime.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/ustime.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/ustime.c
*
@@ -32,10 +31,10 @@
* this time adjustment be done.
*/
-#include <k5-int.h>
+#include "k5-int.h"
krb5_error_code KRB5_CALLCONV
-krb5_us_timeofday(krb5_context context, krb5_int32 *seconds, krb5_int32 *microseconds)
+krb5_us_timeofday(krb5_context context, krb5_timestamp *seconds, krb5_int32 *microseconds)
{
krb5_os_context os_ctx = context->os_context;
krb5_int32 sec, usec;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/write_msg.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/write_msg.c
index c767b63c0f..d75a32796d 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/write_msg.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/write_msg.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/write_msg.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -25,7 +27,6 @@
* convenience sendauth/recvauth functions
*/
-#define NEED_SOCKETS
#include "k5-int.h"
#include <errno.h>
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/posix/daemon.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/posix/daemon.c
index a173270d33..00dde4882e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/posix/daemon.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/posix/daemon.c
@@ -1,10 +1,3 @@
-/*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -38,7 +31,7 @@
* SUCH DAMAGE.
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include <fcntl.h>
#include <sys/types.h>
#include <sys/file.h>
@@ -69,7 +62,7 @@ daemon(nochdir, noclose)
#else
{
int n;
-
+
/*
* The open below may hang on pseudo ttys if the person
* who starts named logs out before this point. Thus,
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc-int.h b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc-int.h
index 00db4e386f..ad3e343fe1 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc-int.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc-int.h
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/krb5/keytab/rc-int.h
*
@@ -73,7 +71,8 @@ typedef struct _krb5_rc_ops krb5_rc_ops;
krb5_error_code krb5_rc_register_type (krb5_context, const krb5_rc_ops *);
-extern krb5_rc_ops *krb5_rc_dfl_ops;
+/* Solaris Kerberos */
+extern krb5_rc_ops const *krb5_rc_dfl_ops;
extern const krb5_rc_ops krb5_rc_none_ops;
#endif /* __KRB5_RCACHE_INT_H__ */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_base.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_base.c
index f589e32c02..76f20be357 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_base.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_base.c
@@ -1,15 +1,15 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/rcache/rc_base.c
*
* This file of the Kerberos V5 software is derived from public-domain code
* contributed by Daniel J. Bernstein, <brnstnd@acf10.nyu.edu>.
+ *
*/
@@ -21,26 +21,24 @@
#include "rc_common.h"
#include "rc_mem.h"
#include "rc_file.h"
-#include <k5-thread.h>
+#include "k5-thread.h"
+/* Solaris Kerberos */
#define FREE_RC(x) ((void) free((char *) (x)))
-struct krb5_rc_typelist
- {
- const krb5_rc_ops *ops;
- struct krb5_rc_typelist *next;
- };
-
-static struct krb5_rc_typelist rc_none_type = { &krb5_rc_none_ops, 0 };
-static struct krb5_rc_typelist rc_mem_type =
- { &krb5_rc_mem_ops, &rc_none_type };
-static struct krb5_rc_typelist krb5_rc_typelist_dfl =
- { &krb5_rc_file_ops, &rc_mem_type };
+struct krb5_rc_typelist {
+ const krb5_rc_ops *ops;
+ struct krb5_rc_typelist *next;
+};
+static struct krb5_rc_typelist none = { &krb5_rc_none_ops, 0 };
+static struct krb5_rc_typelist rc_mem_type = { &krb5_rc_mem_ops, &none };
+static struct krb5_rc_typelist krb5_rc_typelist_dfl = { &krb5_rc_file_ops, &rc_mem_type };
static struct krb5_rc_typelist *typehead = &krb5_rc_typelist_dfl;
static k5_mutex_t rc_typelist_lock = K5_MUTEX_PARTIAL_INITIALIZER;
int krb5int_rc_finish_init(void)
{
+ /* Solaris Kerberos */
int retval;
retval = k5_mutex_finish_init(&grcache.lock);
@@ -52,6 +50,7 @@ int krb5int_rc_finish_init(void)
void krb5int_rc_terminate(void)
{
struct krb5_rc_typelist *t, *t_next;
+ /* Solaris Kerberos */
struct mem_data *tgr = (struct mem_data *)grcache.data;
struct authlist *q, *qt;
int i;
@@ -84,31 +83,27 @@ void krb5int_rc_terminate(void)
krb5_error_code krb5_rc_register_type(krb5_context context,
const krb5_rc_ops *ops)
{
- struct krb5_rc_typelist *t;
- krb5_error_code err;
-
- err = k5_mutex_lock(&rc_typelist_lock);
- if (err)
+ struct krb5_rc_typelist *t;
+ krb5_error_code err;
+ err = k5_mutex_lock(&rc_typelist_lock);
+ if (err)
return err;
-
- for (t = typehead;t && strcmp(t->ops->type,ops->type);t = t->next)
- ;
- if (t) {
- k5_mutex_unlock(&rc_typelist_lock);
- return KRB5_RC_TYPE_EXISTS;
- }
-
- t = (struct krb5_rc_typelist *) malloc(sizeof(struct krb5_rc_typelist));
- if (t == NULL) {
+ for (t = typehead;t && strcmp(t->ops->type,ops->type);t = t->next)
+ ;
+ if (t) {
+ k5_mutex_unlock(&rc_typelist_lock);
+ return KRB5_RC_TYPE_EXISTS;
+ }
+ t = (struct krb5_rc_typelist *) malloc(sizeof(struct krb5_rc_typelist));
+ if (t == NULL) {
k5_mutex_unlock(&rc_typelist_lock);
return KRB5_RC_MALLOC;
- }
- t->next = typehead;
- t->ops = ops;
- typehead = t;
-
- k5_mutex_unlock(&rc_typelist_lock);
- return 0;
+ }
+ t->next = typehead;
+ t->ops = ops;
+ typehead = t;
+ k5_mutex_unlock(&rc_typelist_lock);
+ return 0;
}
/*ARGSUSED*/
@@ -135,10 +130,10 @@ krb5_error_code krb5_rc_resolve_type(krb5_context context, krb5_rcache *id,
/*ARGSUSED*/
char * krb5_rc_get_type(krb5_context context, krb5_rcache id)
{
- return id->ops->type;
+ return id->ops->type;
}
-char * krb5_rc_default_type(krb5_context context)
+char * krb5_rc_default_type(krb5_context context)
{
/*
* Solaris Kerberos/SUNW14resync
@@ -151,11 +146,11 @@ char * krb5_rc_default_type(krb5_context context)
/*ARGSUSED*/
char * krb5_rc_default_name(krb5_context context)
{
- char *s;
- if ((s = getenv("KRB5RCNAME")))
- return s;
- else
- return (char *) 0;
+ char *s;
+ if ((s = getenv("KRB5RCNAME")))
+ return s;
+ else
+ return (char *) 0;
}
krb5_error_code
@@ -166,18 +161,14 @@ krb5_rc_default(krb5_context context, krb5_rcache *id)
if (!(*id = (krb5_rcache )malloc(sizeof(**id))))
return KRB5_RC_MALLOC;
- retval = krb5_rc_resolve_type(context, id, krb5_rc_default_type(context));
- if (retval != 0) {
- /*
- * k5_mutex_destroy() is not called here, because the mutex had
- * not been successfully initialized by krb5_rc_resolve_type().
- */
+ if ((retval = krb5_rc_resolve_type(context, id,
+ krb5_rc_default_type(context)))) {
FREE_RC(*id);
- return (retval);
+ return retval;
}
- retval = krb5_rc_resolve(context, *id, krb5_rc_default_name(context));
- if (retval) {
- k5_mutex_destroy(&(*id)->lock);
+ if ((retval = krb5_rc_resolve(context, *id,
+ krb5_rc_default_name(context)))) {
+ k5_mutex_destroy(&(*id)->lock);
FREE_RC(*id);
return retval;
}
@@ -185,6 +176,7 @@ krb5_rc_default(krb5_context context, krb5_rcache *id)
return retval;
}
+
krb5_error_code krb5_rc_resolve_full(krb5_context context, krb5_rcache *id, char *string_name)
{
char *type;
@@ -194,7 +186,7 @@ krb5_error_code krb5_rc_resolve_full(krb5_context context, krb5_rcache *id, char
if (!(residual = strchr(string_name,':')))
return KRB5_RC_PARSE;
-
+
diff = residual - string_name;
if (!(type = malloc(diff + 1)))
return KRB5_RC_MALLOC;
@@ -206,23 +198,18 @@ krb5_error_code krb5_rc_resolve_full(krb5_context context, krb5_rcache *id, char
return KRB5_RC_MALLOC;
}
- retval = krb5_rc_resolve_type(context, id, type);
- if (retval != 0) {
- /*
- * k5_mutex_destroy() is not called here, because the mutex had
- * not been successfully initialized by krb5_rc_resolve_type().
- */
+ if ((retval = krb5_rc_resolve_type(context, id,type))) {
FREE_RC(type);
FREE_RC(*id);
return retval;
}
FREE_RC(type);
- retval = krb5_rc_resolve(context, *id, residual + 1);
- if (retval) {
- k5_mutex_destroy(&(*id)->lock);
+ if ((retval = krb5_rc_resolve(context, *id,residual + 1))) {
+ k5_mutex_destroy(&(*id)->lock);
FREE_RC(*id);
return retval;
}
(*id)->magic = KV5M_RCACHE;
return retval;
}
+
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_base.h b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_base.h
index 69e3411308..e2e27677ec 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_base.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_base.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/rcache/rc_base.h
*
@@ -9,7 +8,6 @@
#ifndef KRB5_RC_H
#define KRB5_RC_H
-#include <stdlib.h>
#include "k5-int.h"
/* all the stuff that was here is now in rcache.h, included by krb5/krb5.h */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_conv.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_conv.c
index 111cec388e..02bbf81233 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_conv.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_conv.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/rcache/rc_conv.c
*
@@ -12,6 +11,8 @@
* An implementation for the default replay cache type.
*/
+/* Solaris Kerberos - resync */
+#define FREE_RC(x) ((void) free((char *) (x)))
#include "rc_base.h"
@@ -31,7 +32,7 @@ krb5_auth_to_rep(krb5_context context, krb5_tkt_authent *auth, krb5_donot_replay
return retval; /* shouldn't happen */
if ((retval = krb5_unparse_name(context, auth->authenticator->client,
&rep->client))) {
- free(rep->server);
+ FREE_RC(rep->server);
return retval; /* shouldn't happen. */
}
return 0;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_file.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_file.c
index be81658f9f..c0ade20886 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_file.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_file.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/rcache/rc_file.c
@@ -13,9 +12,12 @@
*
*/
+
/*
* An implementation for the default replay cache type.
*/
+/* Solaris Kerberos */
+#define FREE_RC(x) ((void) free((char *) (x)))
#include "rc_common.h"
#include "rc_file.h"
@@ -27,17 +29,15 @@
/* of course, list is backwards from file */
/* hash could be forwards since we have to search on match, but naaaah */
-static int rc_store(context, id, rep)
- krb5_context context;
- krb5_rcache id;
- krb5_donot_replay *rep;
+static int
+rc_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep)
{
struct file_data *t = (struct file_data *)id->data;
int rephash;
struct authlist *ta;
krb5_int32 time;
- rephash = hash(rep,t->hsize);
+ rephash = hash(rep, t->hsize);
/* Solaris: calling krb_timeofday() here, once for better perf. */
krb5_timeofday(context, &time);
@@ -49,29 +49,32 @@ static int rc_store(context, id, rep)
return CMP_EXPIRED;
}
- for (ta = t->h[rephash]; ta; ta = ta->nh)
+ for (ta = t->h[rephash]; ta; ta = ta->nh) {
switch(cmp(&ta->rep, rep))
{
- case CMP_REPLAY: return CMP_REPLAY;
- case CMP_HOHUM: if (alive(context, &ta->rep, t->lifespan, time)
- == CMP_EXPIRED)
- t->nummisses++;
- else
- t->numhits++;
- break;
- default: ; /* wtf? */
+ case CMP_REPLAY:
+ return CMP_REPLAY;
+ case CMP_HOHUM:
+ if (alive(context, &ta->rep, t->lifespan, time) == CMP_EXPIRED)
+ t->nummisses++;
+ else
+ t->numhits++;
+ break;
+ default:
+ ; /* wtf? */
}
+ }
if (!(ta = (struct authlist *) malloc(sizeof(struct authlist))))
return CMP_MALLOC;
ta->rep = *rep;
if (!(ta->rep.client = strdup(rep->client))) {
- free(ta);
+ FREE_RC(ta);
return CMP_MALLOC;
}
if (!(ta->rep.server = strdup(rep->server))) {
- free(ta->rep.client);
- free(ta);
+ FREE_RC(ta->rep.client);
+ FREE_RC(ta);
return CMP_MALLOC;
}
ta->na = t->a; t->a = ta;
@@ -82,19 +85,15 @@ static int rc_store(context, id, rep)
/*ARGSUSED*/
char * KRB5_CALLCONV
-krb5_rc_file_get_name(context, id)
- krb5_context context;
- krb5_rcache id;
+krb5_rc_file_get_name(krb5_context context, krb5_rcache id)
{
return ((struct file_data *) (id->data))->name;
}
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
-krb5_rc_file_get_span(context, id, lifespan)
- krb5_context context;
- krb5_rcache id;
- krb5_deltat *lifespan;
+krb5_rc_file_get_span(krb5_context context, krb5_rcache id,
+ krb5_deltat *lifespan)
{
krb5_error_code err;
struct file_data *t;
@@ -108,23 +107,22 @@ krb5_rc_file_get_span(context, id, lifespan)
return 0;
}
-krb5_error_code KRB5_CALLCONV
-krb5_rc_file_init_locked(context, id, lifespan)
- krb5_context context;
- krb5_rcache id;
- krb5_deltat lifespan;
+static krb5_error_code KRB5_CALLCONV
+krb5_rc_file_init_locked(krb5_context context, krb5_rcache id, krb5_deltat lifespan)
{
struct file_data *t = (struct file_data *)id->data;
krb5_error_code retval;
t->lifespan = lifespan ? lifespan : context->clockskew;
/* default to clockskew from the context */
- if ((retval = krb5_rc_io_creat(context, &t->d, &t->name)))
+ if ((retval = krb5_rc_io_creat(context, &t->d, &t->name))) {
return retval;
+ }
if ((krb5_rc_io_write(context, &t->d,
(krb5_pointer) &t->lifespan, sizeof(t->lifespan))
- || krb5_rc_io_sync(context, &t->d)))
+ || krb5_rc_io_sync(context, &t->d))) {
return KRB5_RC_IO;
+ }
return 0;
}
@@ -141,36 +139,33 @@ krb5_rc_file_init(krb5_context context, krb5_rcache id, krb5_deltat lifespan)
return retval;
}
-krb5_error_code krb5_rc_file_close_no_free(context, id)
- krb5_context context;
- krb5_rcache id;
+/* Called with the mutex already locked. */
+krb5_error_code
+krb5_rc_file_close_no_free(krb5_context context, krb5_rcache id)
{
- struct file_data *t = (struct file_data *)id->data;
- struct authlist *q;
-
- if (t->h)
- free(t->h);
- if (t->name)
- free(t->name);
-
- while ((q = t->a) != NULL)
- {
- t->a = q->na;
- free(q->rep.client);
- free(q->rep.server);
- free(q);
- }
+ struct file_data *t = (struct file_data *)id->data;
+ struct authlist *q;
+
+ if (t->h)
+ FREE_RC(t->h);
+ if (t->name)
+ FREE_RC(t->name);
+ while ((q = t->a))
+ {
+ t->a = q->na;
+ FREE_RC(q->rep.client);
+ FREE_RC(q->rep.server);
+ FREE_RC(q);
+ }
if (t->d.fd >= 0)
(void) krb5_rc_io_close(context, &t->d);
- free(t);
- id->data = NULL;
- return 0;
+ FREE_RC(t);
+ id->data = NULL;
+ return 0;
}
krb5_error_code KRB5_CALLCONV
-krb5_rc_file_close(context, id)
- krb5_context context;
- krb5_rcache id;
+krb5_rc_file_close(krb5_context context, krb5_rcache id)
{
krb5_error_code retval;
retval = k5_mutex_lock(&id->lock);
@@ -184,9 +179,7 @@ krb5_rc_file_close(context, id)
}
krb5_error_code KRB5_CALLCONV
-krb5_rc_file_destroy(context, id)
- krb5_context context;
- krb5_rcache id;
+krb5_rc_file_destroy(krb5_context context, krb5_rcache id)
{
if (krb5_rc_io_destroy(context, &((struct file_data *) (id->data))->d))
return KRB5_RC_IO;
@@ -195,10 +188,7 @@ krb5_rc_file_destroy(context, id)
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
-krb5_rc_file_resolve(context, id, name)
- krb5_context context;
- krb5_rcache id;
- char *name;
+krb5_rc_file_resolve(krb5_context context, krb5_rcache id, char *name)
{
struct file_data *t = 0;
krb5_error_code retval;
@@ -243,9 +233,8 @@ cleanup:
}
/*ARGSUSED*/
-void krb5_rc_free_entry (context, rep)
- krb5_context context;
- krb5_donot_replay **rep;
+void
+krb5_rc_free_entry(krb5_context context, krb5_donot_replay **rep)
{
krb5_donot_replay *rp = *rep;
@@ -263,18 +252,17 @@ void krb5_rc_free_entry (context, rep)
}
}
-static krb5_error_code krb5_rc_io_fetch(context, t, rep, maxlen)
- krb5_context context;
- struct file_data *t;
- krb5_donot_replay *rep;
- int maxlen;
+static krb5_error_code
+krb5_rc_io_fetch(krb5_context context, struct file_data *t,
+ krb5_donot_replay *rep, int maxlen)
{
- int len;
+ unsigned int len;
krb5_error_code retval;
rep->client = rep->server = 0;
- retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) &len, sizeof(len));
+ retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &len,
+ sizeof(len));
if (retval)
return retval;
@@ -285,11 +273,12 @@ static krb5_error_code krb5_rc_io_fetch(context, t, rep, maxlen)
if (!rep->client)
return KRB5_RC_MALLOC;
- retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) rep->client, len);
+ retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) rep->client, len);
if (retval)
goto errout;
- retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) &len, sizeof(len));
+ retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &len,
+ sizeof(len));
if (retval)
goto errout;
@@ -304,15 +293,17 @@ static krb5_error_code krb5_rc_io_fetch(context, t, rep, maxlen)
goto errout;
}
- retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) rep->server, len);
+ retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) rep->server, len);
if (retval)
goto errout;
- retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) &rep->cusec, sizeof(rep->cusec));
+ retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &rep->cusec,
+ sizeof(rep->cusec));
if (retval)
goto errout;
- retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) &rep->ctime, sizeof(rep->ctime));
+ retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &rep->ctime,
+ sizeof(rep->ctime));
if (retval)
goto errout;
@@ -327,13 +318,12 @@ errout:
return retval;
}
+
static krb5_error_code
krb5_rc_file_expunge_locked(krb5_context context, krb5_rcache id);
static krb5_error_code
-krb5_rc_file_recover_locked(context, id)
- krb5_context context;
- krb5_rcache id;
+krb5_rc_file_recover_locked(krb5_context context, krb5_rcache id)
{
struct file_data *t = (struct file_data *)id->data;
krb5_donot_replay *rep = 0;
@@ -341,15 +331,17 @@ krb5_rc_file_recover_locked(context, id)
long max_size;
int expired_entries = 0;
- if ((retval = krb5_rc_io_open(context, &t->d, t->name)))
+ if ((retval = krb5_rc_io_open(context, &t->d, t->name))) {
return retval;
+ }
t->recovering = 1;
max_size = krb5_rc_io_size(context, &t->d);
rep = NULL;
- if (krb5_rc_io_read(context, &t->d,(krb5_pointer) &t->lifespan,sizeof(t->lifespan))) {
+ if (krb5_rc_io_read(context, &t->d, (krb5_pointer) &t->lifespan,
+ sizeof(t->lifespan))) {
retval = KRB5_RC_IO;
goto io_fail;
}
@@ -388,8 +380,8 @@ krb5_rc_file_recover_locked(context, id)
/*
* free fields allocated by rc_io_fetch
*/
- free(rep->server);
- free(rep->client);
+ FREE_RC(rep->server);
+ FREE_RC(rep->client);
rep->server = 0;
rep->client = 0;
}
@@ -409,7 +401,6 @@ io_fail:
return retval;
}
-
krb5_error_code KRB5_CALLCONV
krb5_rc_file_recover(krb5_context context, krb5_rcache id)
{
@@ -438,22 +429,19 @@ krb5_rc_file_recover_or_init(krb5_context context, krb5_rcache id,
return retval;
}
-
static krb5_error_code
-krb5_rc_io_store (context, t, rep)
- krb5_context context;
- struct file_data *t;
- krb5_donot_replay *rep;
+krb5_rc_io_store(krb5_context context, struct file_data *t,
+ krb5_donot_replay *rep)
{
int clientlen, serverlen, len;
char *buf, *ptr;
krb5_error_code ret;
- clientlen = strlen (rep->client) + 1;
- serverlen = strlen (rep->server) + 1;
+ clientlen = strlen(rep->client) + 1;
+ serverlen = strlen(rep->server) + 1;
len = sizeof(clientlen) + clientlen + sizeof(serverlen) + serverlen +
sizeof(rep->cusec) + sizeof(rep->ctime);
- buf = malloc (len);
+ buf = malloc(len);
if (buf == 0)
return KRB5_RC_MALLOC;
ptr = buf;
@@ -472,10 +460,7 @@ krb5_rc_io_store (context, t, rep)
static krb5_error_code krb5_rc_file_expunge_locked(krb5_context, krb5_rcache);
krb5_error_code KRB5_CALLCONV
-krb5_rc_file_store(context, id, rep)
- krb5_context context;
- krb5_rcache id;
- krb5_donot_replay *rep;
+krb5_rc_file_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep)
{
krb5_error_code ret;
struct file_data *t;
@@ -504,8 +489,8 @@ krb5_rc_file_store(context, id, rep)
k5_mutex_unlock(&id->lock);
return ret;
}
- /* Shall we automatically expunge? */
- if (t->nummisses > t->numhits + EXCESSREPS)
+ /* Shall we automatically expunge? */
+ if (t->nummisses > t->numhits + EXCESSREPS)
{
ret = krb5_rc_file_expunge_locked(context, id);
k5_mutex_unlock(&id->lock);
@@ -518,14 +503,12 @@ krb5_rc_file_store(context, id, rep)
return KRB5_RC_IO;
}
}
- k5_mutex_unlock(&id->lock);
- return 0;
+ k5_mutex_unlock(&id->lock);
+ return 0;
}
static krb5_error_code
-krb5_rc_file_expunge_locked(context, id)
- krb5_context context;
- krb5_rcache id;
+krb5_rc_file_expunge_locked(krb5_context context, krb5_rcache id)
{
struct file_data *t = (struct file_data *)id->data;
struct authlist *q;
@@ -537,8 +520,8 @@ krb5_rc_file_expunge_locked(context, id)
if (! t->recovering) {
name = t->name;
t->name = 0; /* Clear name so it isn't freed */
- (void) krb5_rc_file_close_no_free(context, id);
- retval = krb5_rc_file_resolve(context, id, name);
+ (void) krb5_rc_file_close_no_free(context, id);
+ retval = krb5_rc_file_resolve(context, id, name);
free(name);
if (retval)
return retval;
@@ -554,8 +537,8 @@ krb5_rc_file_expunge_locked(context, id)
retval = k5_mutex_init(&tmp->lock);
if (retval) {
- free (tmp);
- return retval;
+ free(tmp);
+ return retval;
}
tmp->ops = &krb5_rc_file_ops;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_file.h b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_file.h
index 0a670f4cac..8c4991760a 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_file.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_file.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
@@ -7,6 +7,7 @@
*
* This file of the Kerberos V5 software is derived from public-domain code
* contributed by Daniel J. Bernstein, <brnstnd@acf10.nyu.edu>.
+ *
*/
/*
@@ -16,11 +17,8 @@
#ifndef _KRB5_RC_FILE_H
#define _KRB5_RC_FILE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-#ifdef __cplusplus
-extern "C" {
-#endif
+/* Solaris Kerberos */
#include "rc_common.h"
#include "rc_io.h"
@@ -54,7 +52,7 @@ struct file_data {
char recovering;
};
-extern krb5_rc_ops krb5_rc_file_ops;
+extern const krb5_rc_ops krb5_rc_file_ops;
krb5_error_code KRB5_CALLCONV krb5_rc_file_init
(krb5_context,
@@ -62,7 +60,7 @@ krb5_error_code KRB5_CALLCONV krb5_rc_file_init
krb5_deltat);
krb5_error_code KRB5_CALLCONV krb5_rc_file_recover
(krb5_context,
- krb5_rcache);
+ krb5_rcache);
krb5_error_code KRB5_CALLCONV krb5_rc_file_recover_or_init
(krb5_context,
krb5_rcache,
@@ -97,9 +95,5 @@ krb5_error_code krb5_rc_file_close_no_free
void krb5_rc_free_entry
(krb5_context,
krb5_donot_replay **);
-
-#ifdef __cplusplus
-}
#endif
-#endif /* !_KRB5_RC_FILE_H */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_io.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_io.c
index 94d401f7a6..bf4e13a223 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_io.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_io.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/rcache/rc_io.c
@@ -13,6 +12,7 @@
*
*/
+
/*
* I/O functions for the replay cache default implementation.
*/
@@ -24,10 +24,9 @@
#endif
#define KRB5_RC_VNO 0x0501 /* krb5, rcache v 1 */
-#define NEED_SOCKETS
-#define NEED_LOWLEVEL_IO
-#include <krb5.h>
+#include "k5-int.h"
+#include <stdio.h> /* for P_tmpdir */
#include <sys/types.h>
#include <unistd.h>
#include <syslog.h> /* SUNW */
@@ -47,7 +46,8 @@
#error find some way to use net-byte-order file version numbers.
#endif
-#define free(x) ((void) free((char *) (x)))
+/* Solaris Kerberos */
+#define FREE_RC(x) ((void) free((char *) (x)))
#define UNIQUE getpid() /* hopefully unique number */
#define GETDIR (dir = getdir(), dirlen = strlen(dir) + sizeof(PATH_SEPARATOR) - 1)
@@ -55,13 +55,14 @@
static char *
getdir(void)
{
- char *dir;
+ char *dir;
#if defined(_WIN32)
- if (!(dir = getenv("TEMP")))
- if (!(dir = getenv("TMP")))
- dir = "C:";
+ if (!(dir = getenv("TEMP")))
+ if (!(dir = getenv("TMP")))
+ dir = "C:";
#else
+ /* Solaris Kerberos */
if (geteuid() == 0)
dir = "/var/krb5/rcache/root";
else
@@ -73,63 +74,67 @@ getdir(void)
krb5_error_code
krb5_rc_io_creat(krb5_context context, krb5_rc_iostuff *d, char **fn)
{
- char *c;
- krb5_int16 rc_vno = htons(KRB5_RC_VNO);
- krb5_error_code retval = 0;
- int do_not_unlink = 0;
- char *dir;
- size_t dirlen;
-
- GETDIR;
- if (fn && *fn)
- {
+ char *c;
+ krb5_int16 rc_vno = htons(KRB5_RC_VNO);
+ krb5_error_code retval = 0;
+ int do_not_unlink = 0;
+ char *dir;
+ size_t dirlen;
+
+ GETDIR;
+ if (fn && *fn)
+ {
+ /* Solaris Kerberos */
if (*fn[0] == '/') {
d->fn = strdup(*fn);
if (d->fn == NULL)
return (KRB5_RC_IO_MALLOC);
} else {
if (!(d->fn = malloc(strlen(*fn) + dirlen + 1)))
- return KRB5_RC_IO_MALLOC;
+ return KRB5_RC_IO_MALLOC;
(void) strcpy(d->fn, dir);
(void) strcat(d->fn, PATH_SEPARATOR);
(void) strcat(d->fn, *fn);
}
- d->fd = THREEPARAMOPEN(d->fn, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL | O_BINARY, 0600);
- }
- else
- {
- /* %d is max 11 digits (-, 10 digits of 32-bit number)
- * 11 + /krb5_RC + aaa = 24, +6 for slop */
- if (!(d->fn = malloc(30 + dirlen)))
- return KRB5_RC_IO_MALLOC;
- if (fn)
- if (!(*fn = malloc(35))) {
- free(d->fn);
- return KRB5_RC_IO_MALLOC;
- }
- (void) sprintf(d->fn, "%s%skrb5_RC%d", dir, PATH_SEPARATOR, (int) UNIQUE);
- c = d->fn + strlen(d->fn);
- (void) strcpy(c, "aaa");
- while ((d->fd = THREEPARAMOPEN(d->fn, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL | O_BINARY, 0600)) == -1)
+ d->fd = THREEPARAMOPEN(d->fn, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL |
+ O_BINARY, 0600);
+ }
+ else
{
- if ((c[2]++) == 'z')
- {
- c[2] = 'a';
- if ((c[1]++) == 'z')
+ /* %d is max 11 digits (-, 10 digits of 32-bit number)
+ * 11 + /krb5_RC + aaa = 24, +6 for slop */
+ if (!(d->fn = malloc(30 + dirlen)))
+ return KRB5_RC_IO_MALLOC;
+ if (fn)
+ if (!(*fn = malloc(35))) {
+ FREE_RC(d->fn);
+ return KRB5_RC_IO_MALLOC;
+ }
+ (void) sprintf(d->fn, "%s%skrb5_RC%d", dir, PATH_SEPARATOR,
+ (int) UNIQUE);
+ c = d->fn + strlen(d->fn);
+ (void) strcpy(c, "aaa");
+ while ((d->fd = THREEPARAMOPEN(d->fn, O_WRONLY | O_CREAT | O_TRUNC |
+ O_EXCL | O_BINARY, 0600)) == -1)
{
- c[1] = 'a';
- if ((c[0]++) == 'z')
- break; /* sigh */
- }
- }
+ if ((c[2]++) == 'z')
+ {
+ c[2] = 'a';
+ if ((c[1]++) == 'z')
+ {
+ c[1] = 'a';
+ if ((c[0]++) == 'z')
+ break; /* sigh */
+ }
+ }
+ }
+ if (fn)
+ (void) strcpy(*fn, d->fn + dirlen);
}
- if (fn)
- (void) strcpy(*fn, d->fn + dirlen);
- }
- if (d->fd == -1)
- {
- switch(errno)
+ if (d->fd == -1)
{
+ switch(errno)
+ {
case EFBIG:
#ifdef EDQUOT
case EDQUOT:
@@ -137,6 +142,7 @@ krb5_rc_io_creat(krb5_context context, krb5_rc_iostuff *d, char **fn)
case ENOSPC:
retval = KRB5_RC_IO_SPACE;
goto cleanup;
+
case EIO:
retval = KRB5_RC_IO_IO;
goto cleanup;
@@ -146,15 +152,20 @@ krb5_rc_io_creat(krb5_context context, krb5_rc_iostuff *d, char **fn)
case EROFS:
case EEXIST:
retval = KRB5_RC_IO_PERM;
+ krb5_set_error_message(context, retval,
+ "Cannot create replay cache: %s",
+ strerror(errno));
do_not_unlink = 1;
goto cleanup;
default:
retval = KRB5_RC_IO_UNKNOWN;
+ krb5_set_error_message(context, retval,
+ "Cannot create replay cache: %s",
+ strerror(errno));
goto cleanup;
+ }
}
- }
-
retval = krb5_rc_io_write(context, d, (krb5_pointer)&rc_vno,
sizeof(rc_vno));
if (retval)
@@ -167,17 +178,19 @@ krb5_rc_io_creat(krb5_context context, krb5_rc_iostuff *d, char **fn)
if (d->fn) {
if (!do_not_unlink)
(void) unlink(d->fn);
- free(d->fn);
+ FREE_RC(d->fn);
d->fn = NULL;
}
- (void) close(d->fd);
+ if (d->fd != -1) {
+ (void) close(d->fd);
+ }
}
return retval;
}
static krb5_error_code
krb5_rc_io_open_internal(krb5_context context, krb5_rc_iostuff *d, char *fn,
-char* full_pathname)
+ char* full_pathname)
{
krb5_int16 rc_vno;
krb5_error_code retval = 0;
@@ -194,7 +207,7 @@ char* full_pathname)
return (KRB5_RC_IO_MALLOC);
} else {
if (!(d->fn = malloc(strlen(fn) + dirlen + 1)))
- return KRB5_RC_IO_MALLOC;
+ return KRB5_RC_IO_MALLOC;
(void) strcpy(d->fn, dir);
(void) strcat(d->fn, PATH_SEPARATOR);
(void) strcat(d->fn, fn);
@@ -223,6 +236,7 @@ char* full_pathname)
/* make sure the rcache is a regular file */
if (((fstatb.st_mode & S_IFMT) != S_IFREG)) {
retval = KRB5_RC_IO_PERM;
+
goto cleanup;
}
#endif
@@ -254,14 +268,14 @@ char* full_pathname)
do_not_unlink = 0;
retval = krb5_rc_io_read(context, d, (krb5_pointer) &rc_vno,
- sizeof(rc_vno));
+ sizeof(rc_vno));
if (retval)
goto cleanup;
if (ntohs(rc_vno) != KRB5_RC_VNO)
retval = KRB5_RCACHE_BADVNO;
-cleanup:
+ cleanup:
if (use_errno) {
switch(errno)
{
@@ -281,23 +295,28 @@ cleanup:
case EACCES:
case EROFS:
retval = KRB5_RC_IO_PERM;
+ krb5_set_error_message (context, retval,
+ "Cannot open replay cache %s: %s",
+ d->fn, strerror(errno));
break;
default:
retval = KRB5_RC_IO_UNKNOWN;
+ krb5_set_error_message (context, retval,
+ "Cannot open replay cache %s: %s",
+ d->fn, strerror(errno));
}
}
/* Solaris: END made changes to be safer and better code structure */
if (retval) {
if (d->fn) {
- if (!do_not_unlink) {
- /* unlink in case there is a bogus RC. */
+ if (!do_not_unlink)
(void) unlink(d->fn);
- }
- free(d->fn);
+ FREE_RC(d->fn);
d->fn = NULL;
}
- (void) close(d->fd);
+ if (d->fd >= 0)
+ (void) close(d->fd);
}
return retval;
}
@@ -312,7 +331,7 @@ krb5_error_code
krb5_rc_io_move(krb5_context context, krb5_rc_iostuff *new1,
krb5_rc_iostuff *old)
{
-#if defined(_WIN32)
+#if defined(_WIN32) || defined(__CYGWIN__)
char *new_fn = NULL;
char *old_fn = NULL;
off_t offset = 0;
@@ -391,14 +410,26 @@ krb5_rc_io_write(krb5_context context, krb5_rc_iostuff *d, krb5_pointer buf,
if (write(d->fd, (char *) buf, num) == -1)
switch(errno)
{
- case EBADF: return KRB5_RC_IO_UNKNOWN;
- case EFBIG: return KRB5_RC_IO_SPACE;
#ifdef EDQUOT
- case EDQUOT: return KRB5_RC_IO_SPACE;
+ case EDQUOT:
#endif
- case ENOSPC: return KRB5_RC_IO_SPACE;
- case EIO: return KRB5_RC_IO_IO;
- default: return KRB5_RC_IO_UNKNOWN;
+ case EFBIG:
+ case ENOSPC:
+ krb5_set_error_message (context, KRB5_RC_IO_SPACE,
+ "Can't write to replay cache: %s",
+ strerror(errno));
+ return KRB5_RC_IO_SPACE;
+ case EIO:
+ krb5_set_error_message (context, KRB5_RC_IO_IO,
+ "Can't write to replay cache: %s",
+ strerror(errno));
+ return KRB5_RC_IO_IO;
+ case EBADF:
+ default:
+ krb5_set_error_message (context, KRB5_RC_IO_UNKNOWN,
+ "Can't write to replay cache: %s",
+ strerror(errno));
+ return KRB5_RC_IO_UNKNOWN;
}
return 0;
}
@@ -416,7 +447,11 @@ krb5_rc_io_sync(krb5_context context, krb5_rc_iostuff *d)
{
case EBADF: return KRB5_RC_IO_UNKNOWN;
case EIO: return KRB5_RC_IO_IO;
- default: return KRB5_RC_IO_UNKNOWN;
+ default:
+ krb5_set_error_message(context, KRB5_RC_IO_UNKNOWN,
+ "Cannot sync replay cache file: %s",
+ strerror(errno));
+ return KRB5_RC_IO_UNKNOWN;
}
}
return 0;
@@ -431,9 +466,13 @@ krb5_rc_io_read(krb5_context context, krb5_rc_iostuff *d, krb5_pointer buf,
if ((count = read(d->fd, (char *) buf, num)) == -1)
switch(errno)
{
- case EBADF: return KRB5_RC_IO_UNKNOWN;
case EIO: return KRB5_RC_IO_IO;
- default: return KRB5_RC_IO_UNKNOWN;
+ case EBADF:
+ default:
+ krb5_set_error_message(context, KRB5_RC_IO_UNKNOWN,
+ "Can't read from replay cache: %s",
+ strerror(errno));
+ return KRB5_RC_IO_UNKNOWN;
}
if (count == 0)
return KRB5_RC_IO_EOF;
@@ -445,7 +484,7 @@ krb5_error_code
krb5_rc_io_close(krb5_context context, krb5_rc_iostuff *d)
{
if (d->fn != NULL) {
- free(d->fn);
+ FREE_RC(d->fn);
d->fn = NULL;
}
if (d->fd != -1) {
@@ -460,17 +499,29 @@ krb5_rc_io_close(krb5_context context, krb5_rc_iostuff *d)
krb5_error_code
krb5_rc_io_destroy(krb5_context context, krb5_rc_iostuff *d)
{
- if (unlink(d->fn) == -1)
- switch(errno)
- {
- case EBADF: return KRB5_RC_IO_UNKNOWN;
- case EIO: return KRB5_RC_IO_IO;
- case EPERM: return KRB5_RC_IO_PERM;
- case EBUSY: return KRB5_RC_IO_PERM;
- case EROFS: return KRB5_RC_IO_PERM;
- default: return KRB5_RC_IO_UNKNOWN;
- }
- return 0;
+ if (unlink(d->fn) == -1)
+ switch(errno)
+ {
+ case EIO:
+ krb5_set_error_message(context, KRB5_RC_IO_IO,
+ "Can't destroy replay cache: %s",
+ strerror(errno));
+ return KRB5_RC_IO_IO;
+ case EPERM:
+ case EBUSY:
+ case EROFS:
+ krb5_set_error_message(context, KRB5_RC_IO_PERM,
+ "Can't destroy replay cache: %s",
+ strerror(errno));
+ return KRB5_RC_IO_PERM;
+ case EBADF:
+ default:
+ krb5_set_error_message(context, KRB5_RC_IO_UNKNOWN,
+ "Can't destroy replay cache: %s",
+ strerror(errno));
+ return KRB5_RC_IO_UNKNOWN;
+ }
+ return 0;
}
/*ARGSUSED*/
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_mem.h b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_mem.h
index 1b8171858c..80e920da9d 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_mem.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_mem.h
@@ -1,12 +1,11 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _KRB5_RC_MEM_H
#define _KRB5_RC_MEM_H
-#pragma ident "%Z%%M% %I% %E% SMI"
#include "rc-int.h"
@@ -40,7 +39,7 @@ struct global_rcache {
extern struct global_rcache grcache;
-extern krb5_rc_ops krb5_rc_mem_ops;
+extern const krb5_rc_ops krb5_rc_mem_ops;
krb5_error_code KRB5_CALLCONV krb5_rc_mem_init
(krb5_context, krb5_rcache, krb5_deltat);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_none.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_none.c
index 250b8f3753..93de67f5cb 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_none.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rc_none.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/krb5/rcache/rc_none.c
*
@@ -7,9 +5,9 @@
* 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.
+ * 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
@@ -18,7 +16,7 @@
* 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
+ * 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
@@ -33,16 +31,16 @@
#include "rc-int.h"
static krb5_error_code KRB5_CALLCONV
-krb5_rc_none_init(krb5_context ctx, krb5_rcache rc, krb5_deltat lifespan)
+krb5_rc_none_init(krb5_context ctx, krb5_rcache rc, krb5_deltat d)
{
- return (0);
+ return 0;
}
#define krb5_rc_none_recover_or_init krb5_rc_none_init
static krb5_error_code KRB5_CALLCONV
krb5_rc_none_noargs(krb5_context ctx, krb5_rcache rc)
{
- return (0);
+ return 0;
}
#define krb5_rc_none_recover krb5_rc_none_noargs
#define krb5_rc_none_destroy krb5_rc_none_noargs
@@ -52,39 +50,39 @@ krb5_rc_none_noargs(krb5_context ctx, krb5_rcache rc)
static krb5_error_code KRB5_CALLCONV
krb5_rc_none_store(krb5_context ctx, krb5_rcache rc, krb5_donot_replay *r)
{
- return (0);
+ return 0;
}
static krb5_error_code KRB5_CALLCONV
krb5_rc_none_get_span(krb5_context ctx, krb5_rcache rc, krb5_deltat *d)
{
- return (0);
+ return 0;
}
static char * KRB5_CALLCONV
krb5_rc_none_get_name(krb5_context ctx, krb5_rcache rc)
{
- return ("");
+ return "";
}
static krb5_error_code KRB5_CALLCONV
krb5_rc_none_resolve(krb5_context ctx, krb5_rcache rc, char *name)
{
- rc->data = "NONE";
- return (0);
+ rc->data = "NONE";
+ return 0;
}
const krb5_rc_ops krb5_rc_none_ops = {
- (0),
- "NONE",
- krb5_rc_none_init,
- krb5_rc_none_recover,
- krb5_rc_none_recover_or_init,
- krb5_rc_none_destroy,
- krb5_rc_none_close,
- krb5_rc_none_store,
- krb5_rc_none_expunge,
- krb5_rc_none_get_span,
- krb5_rc_none_get_name,
- krb5_rc_none_resolve
+ 0,
+ "NONE",
+ krb5_rc_none_init,
+ krb5_rc_none_recover,
+ krb5_rc_none_recover_or_init,
+ krb5_rc_none_destroy,
+ krb5_rc_none_close,
+ krb5_rc_none_store,
+ krb5_rc_none_expunge,
+ krb5_rc_none_get_span,
+ krb5_rc_none_get_name,
+ krb5_rc_none_resolve
};
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rcdef.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rcdef.c
index 8dc9fd0418..570e5636c7 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rcdef.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/rcdef.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/rcache/rcdef.c
@@ -23,12 +22,15 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
*
- * replay cache default set of operation vectors.
+ * replay cache default operationvectors.
*/
#include "k5-int.h"
@@ -40,7 +42,7 @@
* Solaris Kerberos
* MIT 1.4 just has "dfl" while we now have "FILE" and "MEMORY".
*/
-krb5_rc_ops krb5_rc_file_ops = {
+const krb5_rc_ops krb5_rc_file_ops = {
0,
"FILE",
krb5_rc_file_init,
@@ -55,7 +57,7 @@ krb5_rc_ops krb5_rc_file_ops = {
krb5_rc_file_resolve
};
-krb5_rc_ops krb5_rc_mem_ops = {
+const krb5_rc_ops krb5_rc_mem_ops = {
0,
"MEMORY",
krb5_rc_mem_init,
@@ -71,4 +73,4 @@ krb5_rc_ops krb5_rc_mem_ops = {
krb5_rc_mem_resolve
};
-krb5_rc_ops *krb5_rc_dfl_ops = &krb5_rc_file_ops;
+krb5_rc_ops const *krb5_rc_dfl_ops = &krb5_rc_file_ops;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/ser_rc.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/ser_rc.c
index 06bb7a7831..dc58c32c99 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/ser_rc.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/rcache/ser_rc.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/rcache/ser_rc.c
@@ -35,7 +34,7 @@
/*
* ser_rcdfl.c - Serialize replay cache context.
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include "rc-int.h"
/*
@@ -73,6 +72,7 @@ krb5_rcache_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
size_t required;
kret = EINVAL;
+ /* Solaris Kerberos */
if ((rcache = (krb5_rcache) arg) != NULL) {
/*
* Saving FILE: variants of krb5_rcache requires at minimum:
@@ -115,6 +115,7 @@ krb5_rcache_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **bu
bp = *buffer;
remain = *lenremain;
kret = EINVAL;
+ /* Solaris Kerberos */
if ((rcache = (krb5_rcache) arg) != NULL) {
kret = ENOMEM;
if (!krb5_rcache_size(kcontext, arg, &required) &&
@@ -188,16 +189,15 @@ krb5_rcache_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **
&bp, &remain))) {
rcname[ibuf] = '\0';
if (!(kret = krb5_rc_resolve_full(kcontext, &rcache, rcname))) {
- (void) krb5_rc_close(kcontext, rcache);
(void) krb5_rc_recover(kcontext, rcache);
- if (!kret &&
+ if (!kret &&
!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) &&
(ibuf == KV5M_RCACHE)) {
*buffer = bp;
*lenremain = remain;
*argp = (krb5_pointer) rcache;
}
- else
+ else /* Solaris Kerberos */
(void)krb5_rc_close(kcontext, rcache);
}
free(rcname);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers b/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers
index 69486fc940..b7793492f2 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers
+++ b/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers
@@ -22,7 +22,6 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
#
# Due to mistakes made early in the history of this library, there are
@@ -249,7 +248,6 @@ SUNWprivate_1.1 {
encode_krb5_ticket;
error_message;
ggss_error_table;
- gmt_mktime;
gss_krb5int_get_tkt_flags;
gss_krb5_ccache_name;
gss_krb5_copy_ccache;
@@ -337,10 +335,12 @@ SUNWprivate_1.1 {
krb5_c_is_coll_proof_cksum;
krb5_c_is_keyed_cksum;
krb5_c_keyed_checksum_types;
+ krb5_c_keylengths;
krb5_c_make_checksum;
krb5_c_make_random_key;
krb5_c_random_make_octets;
krb5_c_random_seed;
+ krb5_c_random_to_key;
krb5_c_string_to_key;
krb5_c_string_to_key_with_params;
krb5_c_valid_cksumtype;
@@ -487,10 +487,13 @@ SUNWprivate_1.1 {
krb5_get_host_realm;
krb5_get_init_creds;
krb5_get_init_creds_keytab;
+ krb5_get_init_creds_opt_alloc;
+ krb5_get_init_creds_opt_free;
krb5_get_init_creds_opt_init;
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_pa;
krb5_get_init_creds_opt_set_preauth_list;
krb5_get_init_creds_opt_set_proxiable;
krb5_get_init_creds_opt_set_renew_life;
@@ -517,6 +520,7 @@ SUNWprivate_1.1 {
krb5_gss_import_name;
krb5_gss_oid_array;
krb5_gss_userok;
+ krb5_gss_register_acceptor_identity;
krb5_hmac;
krb5_init_allocated_keyblock;
krb5_init_context;
@@ -600,6 +604,7 @@ SUNWprivate_1.1 {
krb5_principal2salt_norealm;
krb5_principal_compare;
krb5_privacy_allowed;
+ krb5_process_padata;
krb5_prompter_posix;
krb5_raw_decrypt;
krb5_raw_encrypt;
@@ -730,16 +735,23 @@ SUNWprivate_1.1 {
krb5int_clear_error;
krb5int_close_plugin_dirs;
krb5int_cm_call_select;
+ krb5int_fini_fac;
krb5int_foreach_localaddr;
krb5int_free_error;
krb5int_free_plugin_dir_data;
+ krb5int_gai_strerror;
krb5int_get_error;
+ krb5int_getnameinfo;
krb5int_get_plugin_dir_data;
+ krb5int_gmt_mktime;
+ krb5int_hash_sha1;
krb5int_init_context_kdc;
+ krb5int_init_fac;
krb5int_mutex_alloc;
krb5int_mutex_free;
krb5int_open_plugin_dirs;
krb5int_pbkdf2_hmac_sha1;
+ krb5int_pthread_loaded;
krb5int_sendtokdc_debug_handler;
krb5int_vset_error;
kwarn_add_warning;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/accept_sec_context.c b/usr/src/lib/gss_mechs/mech_krb5/mech/accept_sec_context.c
index ffb57ceb52..5f773d91c2 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/accept_sec_context.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/accept_sec_context.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 2000, 2004 by the Massachusetts Institute of Technology.
@@ -13,7 +12,7 @@
* 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
@@ -27,11 +26,11 @@
* 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
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
@@ -41,7 +40,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
@@ -53,14 +52,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
@@ -71,24 +70,19 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <auth_con.h>
-#include <gssapiP_krb5.h>
+#include "k5-int.h"
+#include "gssapiP_krb5.h"
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
#include <assert.h>
-
-/* Solaris kerberos: XXX kludgy but there is no include file for the
- * krb5_fcc_ops extern declaration.
- */
-extern krb5_cc_ops krb5_fcc_ops;
+#include "auth_con.h"
#ifdef CFX_EXERCISE
#define CFX_ACCEPTOR_SUBKEY (time(0) & 1)
@@ -104,34 +98,35 @@ extern krb5_cc_ops krb5_fcc_ops;
static krb5_error_code
rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
krb5_context context;
- krb5_auth_context auth_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 template_ccache = NULL;
krb5_ccache ccache = NULL;
krb5_gss_cred_id_t cred = NULL;
krb5_auth_context new_auth_ctx = NULL;
- krb5_int32 flags_org;
+ krb5_int32 flags_org;
+ /* Solaris Kerberos */
KRB5_LOG0(KRB5_INFO, "rd_and_store_for_creds() start");
- if ((retval = krb5_auth_con_getflags(context, auth_context, &flags_org)))
- return retval;
- krb5_auth_con_setflags(context, auth_context, 0);
+ 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
+ * 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
- * "recv_subkey" field might contain a session subkey. Either of
+ * "recv_subkey" field might contain a session subkey. Either of
* these (the "recv_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
+ * 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
@@ -139,10 +134,11 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
* 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
+ * 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.)
*/
+ /* Solaris Kerberos */
if ((retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL))) {
krb5_enctype enctype = ENCTYPE_NULL;
/*
@@ -165,45 +161,32 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
}
/* Try to krb5_rd_cred() likely unencrypted KRB-CRED */
- 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))) {
- KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
- "krb5_rd_cred() retval = %d\n", retval);
- goto cleanup;
- }
- }
-
- /* Lots of kludging going on here... Some day the ccache interface
- will be rewritten though */
-
- retval = krb5_cc_resolve(context, "MEMORY:GSSAPI", &template_ccache);
- if (retval) {
- KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
- "krb5_cc_resolve() retval = %d\n", retval);
- goto cleanup;
+ 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))) {
+ /* Solaris Kerberos */
+ KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
+ "krb5_rd_cred() retval = %d\n", retval);
+ goto cleanup;
+ }
}
- ccache = template_ccache; /* krb5_cc_gen_new will replace so make a copy */
-
- retval = krb5_cc_gen_new(context, &ccache);
- if (retval) {
- KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
- "krb5_cc_gen_new() retval = %d\n", retval);
+ if ((retval = krb5_cc_new_unique(context, "MEMORY", NULL, &ccache))) {
+ ccache = NULL;
goto cleanup;
}
- retval = krb5_cc_initialize(context, ccache, creds[0]->client);
- if (retval != 0) {
+ if ((retval = krb5_cc_initialize(context, ccache, creds[0]->client))) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
"krb5_cc_initialize() retval = %d\n", retval);
goto cleanup;
}
- retval = krb5_cc_store_cred(context, ccache, creds[0]);
- if (retval != 0){
+ if ((retval = krb5_cc_store_cred(context, ccache, creds[0]))) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
"krb5_cc_store_cred() retval = %d\n", retval);
goto cleanup;
@@ -213,16 +196,17 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
if (out_cred) {
/* allocate memory for a cred_t... */
if (!(cred =
- (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec)))) {
+ (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec)))) {
retval = ENOMEM; /* out of memory? */
*out_cred = NULL;
goto cleanup;
}
/* zero it out... */
+ /* Solaris Kerberos */
(void) memset(cred, 0, sizeof(krb5_gss_cred_id_rec));
- retval = k5_mutex_init(&cred->lock);
+ retval = k5_mutex_init(&cred->lock);
if (retval) {
xfree(cred);
cred = NULL;
@@ -230,14 +214,15 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
}
/* copy the client principle into it... */
- if ((retval = krb5_copy_principal(context, creds[0]->client,
- &(cred->princ)))) {
+ if ((retval =
+ krb5_copy_principal(context, creds[0]->client, &(cred->princ)))) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
"krb5_copy_principal() retval = %d\n", retval);
k5_mutex_destroy(&cred->lock);
retval = ENOMEM; /* out of memory? */
xfree(cred); /* clean up memory on failure */
- *out_cred = cred = NULL;
+ cred = NULL;
goto cleanup;
}
@@ -246,8 +231,7 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
cred->prerfc_mech = 1; /* this cred will work with all three mechs */
cred->rfc_mech = 1;
cred->keytab = NULL; /* no keytab associated with this... */
- /* The cred expires when the original cred was set to expire */
- cred->tgt_expire = creds[0]->times.endtime;
+ cred->tgt_expire = creds[0]->times.endtime; /* store the end time */
cred->ccache = ccache; /* the ccache containing the credential */
ccache = NULL; /* cred takes ownership so don't destroy */
}
@@ -259,19 +243,11 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
*/
cleanup:
if (creds)
- krb5_free_tgt_creds(context, creds);
+ krb5_free_tgt_creds(context, creds);
if (ccache)
(void)krb5_cc_destroy(context, ccache);
- /*
- * SUNW15resync
- * Added this cc_destroy for template_cache, w/out it causes memory
- * leak via "ssh -o gssapidelegatecredentials=yes ..."
- */
- if (template_ccache)
- (void)krb5_cc_destroy(context, template_ccache);
-
if (out_cred)
*out_cred = cred; /* return credential */
@@ -280,6 +256,7 @@ cleanup:
krb5_auth_con_setflags(context, auth_context, flags_org);
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_INFO, "rd_and_store_for_creds() end retval %d", retval);
return retval;
}
@@ -290,7 +267,7 @@ cleanup:
* does not have yet
*/
OM_uint32
-krb5_gss_accept_sec_context(minor_status, context_handle,
+krb5_gss_accept_sec_context(minor_status, context_handle,
verifier_cred_handle, input_token,
input_chan_bindings, src_name, mech_type,
output_token, ret_flags, time_rec,
@@ -364,10 +341,9 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
reqcksum.contents = 0;
ap_req.data = 0;
ap_rep.data = 0;
-
+
if (mech_type)
*mech_type = GSS_C_NULL_OID;
-
/* initialize the delegated cred handle to NO_CREDENTIAL for now */
if (delegated_cred_handle)
*delegated_cred_handle = GSS_C_NO_CREDENTIAL;
@@ -406,9 +382,9 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
mech_used = gss_mech_krb5;
} else if ((code == G_WRONG_MECH) &&
!(code = g_verify_token_header(gss_mech_krb5_old,
- (uint32_t *)&(ap_req.length),
- &ptr, KG_TOK_CTX_AP_REQ,
- input_token->length, 1))) {
+ (uint32_t *)&(ap_req.length),
+ &ptr, KG_TOK_CTX_AP_REQ,
+ input_token->length, 1))) {
/*
* Previous versions of this library used the old mech_id
* and some broken behavior (wrong IV on checksum
@@ -547,6 +523,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
if ((code = krb5_auth_con_init(context, &auth_context))) {
major_status = GSS_S_FAILURE;
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() "
"krb5_auth_con_init() error code %d", code);
goto fail;
@@ -558,14 +535,16 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
if (cred->rcache) {
cred_rcache = 1;
if ((code = krb5_auth_con_setrcache(context, auth_context, cred->rcache))) {
- major_status = GSS_S_FAILURE;
- KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() "
+ major_status = GSS_S_FAILURE;
+ /* Solaris Kerberos */
+ KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() "
"krb5_auth_con_setrcache() error code %d", code);
- goto fail;
+ goto fail;
}
}
if ((code = krb5_auth_con_setaddrs(context, auth_context, NULL, paddr))) {
major_status = GSS_S_FAILURE;
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() "
"krb5_auth_con_setaddrs() error code %d", code);
goto fail;
@@ -589,6 +568,8 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
major_status = GSS_S_FAILURE;
goto fail;
}
+ krb5_auth_con_setflags(context, auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE);
krb5_auth_con_getauthenticator(context, auth_context, &authdat);
@@ -607,8 +588,9 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
/* gss krb5 v1 */
/* stash this now, for later. */
- if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5,
- &md5len)) {
+ code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &md5len);
+ if (code) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() "
"krb5_c_checksum_length() error code %d", code);
major_status = GSS_S_FAILURE;
@@ -661,34 +643,38 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
/* at this point, bigend is set according to the initiator's
byte order */
- /*
+
+ /*
The following section of code attempts to implement the
- optional channel binding facility as described in RFC2743.
-
- Since this facility is optional channel binding may or may
- not have been provided by either the client or the server.
-
- If the server has specified input_chan_bindings equal to
- GSS_C_NO_CHANNEL_BINDINGS then we skip the check. If
- the server does provide channel bindings then we compute
- a checksum and compare against those provided by the
- client. If the check fails we test the clients checksum
- to see whether the client specified GSS_C_NO_CHANNEL_BINDINGS.
- If either test succeeds we continue without error.
- */
- if ((code = kg_checksum_channel_bindings(context, input_chan_bindings,
+ optional channel binding facility as described in RFC2743.
+
+ Since this facility is optional channel binding may or may
+ not have been provided by either the client or the server.
+
+ If the server has specified input_chan_bindings equal to
+ GSS_C_NO_CHANNEL_BINDINGS then we skip the check. If
+ the server does provide channel bindings then we compute
+ a checksum and compare against those provided by the
+ client. If the check fails we test the clients checksum
+ to see whether the client specified GSS_C_NO_CHANNEL_BINDINGS.
+ If either test succeeds we continue without error.
+ */
+ if ((code = kg_checksum_channel_bindings(context,
+ input_chan_bindings,
&reqcksum, bigend))) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() "
"kg_checksum_channel_bindings() error code %d", code);
- major_status = GSS_S_BAD_BINDINGS;
- goto fail;
+ major_status = GSS_S_BAD_BINDINGS;
+ goto fail;
}
- TREAD_STR(ptr, ptr2, reqcksum.length);
- if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
- if (memcmp(ptr2, reqcksum.contents, reqcksum.length) != 0) {
- xfree(reqcksum.contents);
- reqcksum.contents = 0;
+ TREAD_STR(ptr, ptr2, reqcksum.length);
+
+ if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS ) {
+ if (memcmp(ptr2, reqcksum.contents, reqcksum.length) != 0) {
+ xfree(reqcksum.contents);
+ reqcksum.contents = 0;
if ((code = kg_checksum_channel_bindings(context,
GSS_C_NO_CHANNEL_BINDINGS,
&reqcksum, bigend))) {
@@ -701,54 +687,86 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
goto fail;
}
}
+
}
TREAD_INT(ptr, gss_flags, bigend);
/* if the checksum length > 24, there are options to process */
- if (authdat->checksum->length > 24 &&
- (gss_flags & GSS_C_DELEG_FLAG)) {
+ if(authdat->checksum->length > 24 && (gss_flags & GSS_C_DELEG_FLAG)) {
+
i = authdat->checksum->length - 24;
if (i >= 4) {
+
TREAD_INT16(ptr, option_id, bigend);
TREAD_INT16(ptr, option.length, bigend);
- i -= 4;
- if (i < option.length || option.length < 0) {
- code = KG_BAD_LENGTH;
- major_status = GSS_S_FAILURE;
- goto fail;
- }
+ i -= 4;
- /* have to use ptr2, since option.data is wrong type and
+ if (i < option.length || option.length < 0) {
+ code = KG_BAD_LENGTH;
+ major_status = GSS_S_FAILURE;
+ goto fail;
+ }
+
+ /* have to use ptr2, since option.data is wrong type and
macro uses ptr as both lvalue and rvalue */
- TREAD_STR(ptr, ptr2, option.length);
- option.data = (char *) ptr2;
+ TREAD_STR(ptr, ptr2, option.length);
+ option.data = (char *) ptr2;
- i -= option.length;
+ i -= option.length;
- if (option_id != KRB5_GSS_FOR_CREDS_OPTION) {
- major_status = GSS_S_FAILURE;
- goto fail;
- }
+ if (option_id != KRB5_GSS_FOR_CREDS_OPTION) {
+ major_status = GSS_S_FAILURE;
+ goto fail;
+ }
- /* store the delegated credential */
+ /* store the delegated credential */
code = rd_and_store_for_creds(context, auth_context, &option,
- (delegated_cred_handle) ? &deleg_cred : NULL);
+ (delegated_cred_handle) ?
+ &deleg_cred : NULL);
if (code) {
major_status = GSS_S_FAILURE;
goto fail;
- }
+ }
- } /* if i >= 4 */
- /* ignore any additional trailing data, for now */
- } /* if */
- } /* krb5 gssapi v1 */
+ } /* if i >= 4 */
+ /* ignore any additional trailing data, for now */
+#ifdef CFX_EXERCISE
+ {
+ FILE *f = fopen("/tmp/gsslog", "a");
+ if (f) {
+ fprintf(f,
+ "initial context token with delegation, %d extra bytes\n",
+ i);
+ fclose(f);
+ }
+ }
+#endif
+ } else {
+#ifdef CFX_EXERCISE
+ {
+ FILE *f = fopen("/tmp/gsslog", "a");
+ if (f) {
+ if (gss_flags & GSS_C_DELEG_FLAG)
+ fprintf(f,
+ "initial context token, delegation flag but too small\n");
+ else
+ /* no deleg flag, length might still be too big */
+ fprintf(f,
+ "initial context token, %d extra bytes\n",
+ authdat->checksum->length - 24);
+ fclose(f);
+ }
+ }
+#endif
+ }
+ }
/* create the ctx struct and start filling it in */
@@ -760,14 +778,13 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
}
memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
-
ctx->mech_used = (gss_OID) mech_used;
ctx->auth_context = auth_context;
ctx->initiate = 0;
ctx->gss_flags = (GSS_C_TRANS_FLAG |
- ((gss_flags) & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |
- GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
- GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG)));
+ ((gss_flags) & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |
+ GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
+ GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG)));
ctx->seed_init = 0;
ctx->big_endian = bigend;
ctx->cred_rcache = cred_rcache;
@@ -777,6 +794,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
xfree(ctx);
ctx = 0;
+ /* Solaris Kerberos */
KRB5_LOG0(KRB5_ERR, "krb5_gss_accept_sec_context() "
"kg_save_ctx_id() error");
code = G_VALIDATE_FAILED;
@@ -785,6 +803,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
}
if ((code = krb5_copy_principal(context, cred->princ, &ctx->here))) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() "
"krb5_copy_principal() error code %d", code);
major_status = GSS_S_FAILURE;
@@ -792,6 +811,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
}
if ((code = krb5_copy_principal(context, authdat->client, &ctx->there))) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() "
"krb5_copy_principal() 2 error code %d", code);
major_status = GSS_S_FAILURE;
@@ -799,10 +819,11 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
}
if ((code = krb5_auth_con_getrecvsubkey(context, auth_context,
- &ctx->subkey))) {
+ &ctx->subkey))) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() "
"krb5_auth_con_getremotesubkey() error code %d", code);
- major_status = GSS_S_FAILURE;
+ major_status = GSS_S_FAILURE;
goto fail;
}
@@ -811,6 +832,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
if (ctx->subkey == NULL) {
if ((code = krb5_auth_con_getkey(context, auth_context,
&ctx->subkey))) {
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() "
"krb5_auth_con_getkey() error code %d", code);
*minor_status = (OM_uint32) KRB5KDC_ERR_NULL_KEY;
@@ -827,6 +849,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
goto fail;
}
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR,"krb5_gss_accept_sec_context() "
"ctx->subkey->enctype=%d", ctx->subkey->enctype);
@@ -860,42 +883,41 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
ctx->sealalg = SEAL_ALG_DES3KD;
/* fill in the encryption descriptors */
-
copy_subkey:
if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) {
major_status = GSS_S_FAILURE;
goto fail;
}
-
copy_subkey_to_seq:
if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) {
major_status = GSS_S_FAILURE;
goto fail;
}
-
break;
+
case ENCTYPE_ARCFOUR_HMAC:
- ctx->signalg = SGN_ALG_HMAC_MD5 ;
- ctx->cksum_size = 8;
- ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ;
- goto copy_subkey;
+ ctx->signalg = SGN_ALG_HMAC_MD5 ;
+ ctx->cksum_size = 8;
+ ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ;
+ goto copy_subkey;
default:
- ctx->signalg = -1;
- ctx->sealalg = -1;
- ctx->proto = 1;
- code = krb5int_c_mandatory_cksumtype(context, ctx->subkey->enctype,
- &ctx->cksumtype);
- if (code)
- goto fail;
- code = krb5_c_checksum_length(context, ctx->cksumtype,
+ ctx->signalg = -1;
+ ctx->sealalg = -1;
+ ctx->proto = 1;
+ code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, ctx->subkey->enctype,
+ &ctx->cksumtype);
+ if (code)
+ goto fail;
+ code = krb5_c_checksum_length(context, ctx->cksumtype,
(size_t *)&ctx->cksum_size);
- if (code)
- goto fail;
- ctx->have_acceptor_subkey = 0;
- goto copy_subkey;
+ if (code)
+ goto fail;
+ ctx->have_acceptor_subkey = 0;
+ goto copy_subkey;
}
+ /* Solaris Kerberos */
KRB5_LOG1(KRB5_ERR, "accept_sec_context: subkey enctype = %d proto = %d",
ctx->subkey->enctype, ctx->proto);
@@ -903,11 +925,12 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
ctx->krb_flags = ticket->enc_part2->flags;
krb5_free_ticket(context, ticket); /* Done with ticket */
+
{
- krb5_ui_4 seq_temp;
- krb5_auth_con_getremoteseqnumber(context, auth_context,
+ krb5_ui_4 seq_temp;
+ krb5_auth_con_getremoteseqnumber(context, auth_context,
(krb5_int32 *)&seq_temp);
- ctx->seq_recv = seq_temp;
+ ctx->seq_recv = seq_temp;
}
if ((code = krb5_timeofday(context, &now))) {
@@ -925,31 +948,31 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
(ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
(ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0, ctx->proto);
- /* at this point, the entire context structure is filled in,
+ /* at this point, the entire context structure is filled in,
so it can be released. */
/* generate an AP_REP if necessary */
if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) {
unsigned char * ptr3;
- krb5_ui_4 seq_temp;
- int cfx_generate_subkey;
+ krb5_ui_4 seq_temp;
+ int cfx_generate_subkey;
- if (ctx->proto == 1)
+ if (ctx->proto == 1)
cfx_generate_subkey = CFX_ACCEPTOR_SUBKEY;
- else
+ else
cfx_generate_subkey = 0;
- if (cfx_generate_subkey) {
+ if (cfx_generate_subkey) {
krb5_int32 acflags;
code = krb5_auth_con_getflags(context, auth_context, &acflags);
if (code == 0) {
- acflags |= KRB5_AUTH_CONTEXT_USE_SUBKEY;
- code = krb5_auth_con_setflags(context, auth_context, acflags);
+ acflags |= KRB5_AUTH_CONTEXT_USE_SUBKEY;
+ code = krb5_auth_con_setflags(context, auth_context, acflags);
}
- if (code) {
- major_status = GSS_S_FAILURE;
- goto fail;
+ if (code) {
+ major_status = GSS_S_FAILURE;
+ goto fail;
}
}
@@ -962,28 +985,29 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
(krb5_int32 *)&seq_temp);
ctx->seq_send = seq_temp & 0xffffffffL;
- if (cfx_generate_subkey) {
+ if (cfx_generate_subkey) {
/* Get the new acceptor subkey. With the code above, there
- should always be one if we make it to this point. */
+ should always be one if we make it to this point. */
code = krb5_auth_con_getsendsubkey(context, auth_context,
- &ctx->acceptor_subkey);
+ &ctx->acceptor_subkey);
if (code != 0) {
- major_status = GSS_S_FAILURE;
- goto fail;
+ major_status = GSS_S_FAILURE;
+ goto fail;
}
- code = krb5int_c_mandatory_cksumtype(context,
- ctx->acceptor_subkey->enctype,
- &ctx->acceptor_subkey_cksumtype);
+ code = (*kaccess.krb5int_c_mandatory_cksumtype)(context,
+ ctx->acceptor_subkey->enctype,
+ &ctx->acceptor_subkey_cksumtype);
if (code) {
- major_status = GSS_S_FAILURE;
- goto fail;
+ major_status = GSS_S_FAILURE;
+ goto fail;
}
- ctx->have_acceptor_subkey = 1;
- }
+ ctx->have_acceptor_subkey = 1;
+ }
/* the reply token hasn't been sent yet, but that's ok. */
ctx->gss_flags |= GSS_C_PROT_READY_FLAG;
ctx->established = 1;
+
token.length = g_token_size(mech_used, ap_rep.length);
if ((token.value = (unsigned char *) xmalloc(token.length))
@@ -992,17 +1016,21 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
code = ENOMEM;
goto fail;
}
- ptr = token.value;
+ ptr3 = token.value;
g_make_token_header(mech_used, ap_rep.length,
- &ptr, KG_TOK_CTX_AP_REP);
+ &ptr3, KG_TOK_CTX_AP_REP);
+
+ TWRITE_STR(ptr3, ap_rep.data, ap_rep.length);
+
+ ctx->established = 1;
- TWRITE_STR(ptr, ap_rep.data, ap_rep.length);
} else {
token.length = 0;
token.value = NULL;
ctx->seq_send = ctx->seq_recv;
+
+ ctx->established = 1;
}
- ctx->established = 1;
/* set the return arguments */
@@ -1028,20 +1056,21 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
if (ret_flags)
*ret_flags = ctx->gss_flags;
- *context_handle = (gss_ctx_id_t) ctx;
+ *context_handle = (gss_ctx_id_t)ctx;
*output_token = token;
if (src_name)
*src_name = (gss_name_t) name;
if (delegated_cred_handle && deleg_cred) {
- if (!kg_save_cred_id((gss_cred_id_t) deleg_cred)) {
+ if (!kg_save_cred_id((gss_cred_id_t) deleg_cred)) {
+ /* Solaris Kerberos */
KRB5_LOG0(KRB5_ERR, "krb5_gss_accept_sec_context() "
"kg_save_cred_id() error");
major_status = GSS_S_FAILURE;
code = (OM_uint32) G_VALIDATE_FAILED;
- goto fail;
- }
+ goto fail;
+ }
*delegated_cred_handle = (gss_cred_id_t) deleg_cred;
}
@@ -1086,7 +1115,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
/* from here on is the real "fail" code */
if (ctx)
- (void) krb5_gss_delete_sec_context(minor_status,
+ (void) krb5_gss_delete_sec_context(minor_status,
(gss_ctx_id_t *) &ctx, NULL);
if (deleg_cred) { /* free memory associated with the deleg credential */
if (deleg_cred->ccache)
@@ -1107,8 +1136,9 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
if (saved_ap_options & AP_OPTS_MUTUAL_REQUIRED)
gss_flags |= GSS_C_MUTUAL_FLAG;
- if (cred && ((gss_flags & GSS_C_MUTUAL_FLAG) ||
- (major_status == GSS_S_CONTINUE_NEEDED))) {
+ if (cred
+ && ((gss_flags & GSS_C_MUTUAL_FLAG)
+ || (major_status == GSS_S_CONTINUE_NEEDED))) {
unsigned int tmsglen;
int toktype;
@@ -1118,7 +1148,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
*/
memset(&krb_error_data, 0, sizeof(krb_error_data));
- code -= ERROR_TABLE_BASE_krb5;
+ code -= ERROR_TABLE_BASE_krb5;
if (code < 0 || code > 128)
code = 60 /* KRB_ERR_GENERIC */;
@@ -1126,7 +1156,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
(void) krb5_us_timeofday(context, &krb_error_data.stime,
&krb_error_data.susec);
krb_error_data.server = cred->princ;
-
+
code = krb5_mk_error(context, &krb_error_data, &scratch);
if (code)
goto cleanup;
@@ -1150,11 +1180,11 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
cleanup:
if (!verifier_cred_handle && cred_handle) {
- krb5_gss_release_cred(minor_status, &cred_handle);
+ krb5_gss_release_cred(minor_status, &cred_handle);
}
-
krb5_free_context(context);
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_ERR,"krb5_gss_accept_sec_context() end, "
"major_status = %d", major_status);
return (major_status);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred.c b/usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred.c
index a916cc2b0e..16fe5c0b04 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 2000 by the Massachusetts Institute of Technology.
@@ -87,14 +86,14 @@
#include <strings.h>
#endif
-/* SUNW15resync - Solaris kerberos does not need this feature in this file */
-#ifdef USE_LOGIN_LIBRARY
-#undef USE_LOGIN_LIBRARY
-#endif
-
#if defined(USE_LOGIN_LIBRARY)
#include <Kerberos/KerberosLoginPrivate.h>
#elif defined(USE_LEASH)
+#ifdef _WIN64
+#define LEASH_DLL "leashw64.dll"
+#else
+#define LEASH_DLL "leashw32.dll"
+#endif
static void (*pLeash_AcquireInitialTicketsIfNeeded)(krb5_context,krb5_principal,char*,int) = NULL;
static HANDLE hLeashDLL = INVALID_HANDLE_VALUE;
#endif
@@ -237,6 +236,7 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
krb5_cc_cursor cur;
krb5_creds creds;
int got_endtime;
+ int caller_provided_ccache_name = 0;
cred->ccache = NULL;
@@ -245,36 +245,41 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
if (GSS_ERROR(kg_sync_ccache_name(context, minor_status)))
return(GSS_S_FAILURE);
+ /* check to see if the caller provided a ccache name if so
+ * we will just use that and not search the cache collection */
+ if (GSS_ERROR(kg_caller_provided_ccache_name (minor_status, &caller_provided_ccache_name))) {
+ return(GSS_S_FAILURE);
+ }
+
#if defined(USE_LOGIN_LIBRARY) || defined(USE_LEASH)
- if (desired_name != NULL) {
+ if (desired_name && !caller_provided_ccache_name) {
#if defined(USE_LOGIN_LIBRARY)
+ KLStatus err = klNoErr;
char *ccache_name = NULL;
KLPrincipal kl_desired_princ = NULL;
+
+ err = __KLCreatePrincipalFromKerberos5Principal ((krb5_principal) desired_name,
+ &kl_desired_princ);
- if ((code = __KLCreatePrincipalFromKerberos5Principal ((krb5_principal) desired_name,
- &kl_desired_princ))) {
- *minor_status = code;
- return(GSS_S_NO_CRED);
+ if (!err) {
+ err = KLAcquireInitialTickets (kl_desired_princ, NULL, NULL, &ccache_name);
}
-
- if ((code = KLAcquireInitialTickets (kl_desired_princ, NULL, NULL, &ccache_name))) {
- KLDisposePrincipal (kl_desired_princ);
- *minor_status = code;
- return(GSS_S_NO_CRED);
+
+ if (!err) {
+ err = krb5_cc_resolve (context, ccache_name, &ccache);
}
- if ((code = krb5_cc_resolve (context, ccache_name, &ccache))) {
- KLDisposeString (ccache_name);
- KLDisposePrincipal (kl_desired_princ);
- *minor_status = code;
- return(GSS_S_NO_CRED);
+ if (err) {
+ *minor_status = err;
+ return(GSS_S_CRED_UNAVAIL);
}
-
+
if (kl_desired_princ != NULL) { KLDisposePrincipal (kl_desired_princ); }
if (ccache_name != NULL) { KLDisposeString (ccache_name); }
+
#elif defined(USE_LEASH)
if ( hLeashDLL == INVALID_HANDLE_VALUE ) {
- hLeashDLL = LoadLibrary("leashw32.dll");
+ hLeashDLL = LoadLibrary(LEASH_DLL);
if ( hLeashDLL != INVALID_HANDLE_VALUE ) {
(FARPROC) pLeash_AcquireInitialTicketsIfNeeded =
GetProcAddress(hLeashDLL, "not_an_API_Leash_AcquireInitialTicketsIfNeeded");
@@ -330,6 +335,7 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
/* get out the principal name and see if it matches */
if ((code = krb5_cc_get_principal(context, ccache, &princ))) {
+ /* Solaris Kerberos */
(void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
(void)krb5_cc_close(context, ccache);
*minor_status = code;
@@ -339,6 +345,7 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
if (desired_name != (gss_name_t) NULL) {
if (! krb5_principal_compare(context, princ, (krb5_principal) desired_name)) {
(void)krb5_free_principal(context, princ);
+ /* Solaris Kerberos */
(void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
(void)krb5_cc_close(context, ccache);
*minor_status = KG_CCACHE_NOMATCH;
@@ -353,6 +360,7 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
/* iterate over the ccache, find the tgt */
if ((code = krb5_cc_start_seq_get(context, ccache, &cur))) {
+ /* Solaris Kerberos */
(void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
(void)krb5_cc_close(context, ccache);
*minor_status = code;
@@ -373,6 +381,7 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
krb5_princ_realm(context, princ)->data,
0);
if (code) {
+ /* Solaris Kerberos */
(void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
(void)krb5_cc_close(context, ccache);
*minor_status = code;
@@ -398,6 +407,7 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
if (code && code != KRB5_CC_END) {
/* this means some error occurred reading the ccache */
(void)krb5_cc_end_seq_get(context, ccache, &cur);
+ /* Solaris Kerberos */
(void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
(void)krb5_cc_close(context, ccache);
*minor_status = code;
@@ -405,6 +415,7 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
} else if (! got_endtime) {
/* this means the ccache was entirely empty */
(void)krb5_cc_end_seq_get(context, ccache, &cur);
+ /* Solaris Kerberos */
(void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
(void)krb5_cc_close(context, ccache);
*minor_status = KG_EMPTY_CCACHE;
@@ -412,6 +423,7 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
} else {
/* this means that we found an endtime to use. */
if ((code = krb5_cc_end_seq_get(context, ccache, &cur))) {
+ /* Solaris Kerberos */
(void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
(void)krb5_cc_close(context, ccache);
*minor_status = code;
@@ -640,11 +652,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,
- (const gss_OID) gss_mech_krb5_old,
+ (const gss_OID) gss_mech_krb5_old,
&ret_mechs))) ||
(cred->rfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- (const gss_OID) gss_mech_krb5,
+ (const gss_OID) gss_mech_krb5,
&ret_mechs)))) {
if (cred->ccache)
(void)krb5_cc_close(context, cred->ccache);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/add_cred.c b/usr/src/lib/gss_mechs/mech_krb5/mech/add_cred.c
index b24d1496ca..d401785b93 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/add_cred.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/add_cred.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Copyright 2000 by the Massachusetts Institute of Technology.
* All Rights Reserved.
@@ -58,7 +56,7 @@
#endif
/*
- * $Id: add_cred.c 18015 2006-05-17 05:26:12Z raeburn $
+ * $Id: add_cred.c 18396 2006-07-25 20:29:43Z lxs $
*/
/* V2 interface */
@@ -345,7 +343,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
/* set the outputs */
if (GSS_ERROR(major_status = krb5_gss_inquire_cred(minor_status,
- (gss_cred_id_t) cred,
+ (gss_cred_id_t)cred,
NULL, &lifetime,
NULL, actual_mechs))) {
OM_uint32 dummy;
@@ -363,7 +361,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
*acceptor_time_rec = lifetime;
if (output_cred_handle)
- *output_cred_handle = (gss_cred_id_t) cred;
+ *output_cred_handle = (gss_cred_id_t)cred;
krb5_free_context(context);
*minor_status = 0;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/disp_com_err_status.c b/usr/src/lib/gss_mechs/mech_krb5/mech/disp_com_err_status.c
index 150f30ec20..ab49803169 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/disp_com_err_status.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/disp_com_err_status.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
@@ -23,12 +21,12 @@
*/
/*
- * $Id: disp_com_err_status.c 16391 2004-06-02 23:40:12Z raeburn $
+ * $Id: disp_com_err_status.c 18721 2006-10-16 16:18:29Z epeisach $
*/
#include "gssapiP_generic.h"
-#include "com_err.h"
#include "gss_libinit.h"
+#include "com_err.h"
/* XXXX internationalization!! */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/export_sec_context.c b/usr/src/lib/gss_mechs/mech_krb5/mech/export_sec_context.c
index 4460c2b486..fb57b882a2 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/export_sec_context.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/export_sec_context.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/gssapi/krb5/export_sec_context.c
*
@@ -62,10 +60,6 @@ krb5_gss_export_sec_context(minor_status, context_handle, interprocess_token)
if (kret)
goto error_out;
- { gss_OID go = ctx->mech_used;
- printf("export ctx len=%lu\n", go->length);
- }
-
/* Determine size needed for externalization of context */
bufsize = 0;
if ((kret = kg_ctx_size(context, (krb5_pointer) ctx,
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.c b/usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.c
index a410640031..ee98ce3188 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include <assert.h>
@@ -49,7 +48,7 @@ int gssint_lib_init(void)
err = k5_key_register(K5_KEY_GSS_KRB5_CCACHE_NAME, free);
if (err)
return err;
-#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */
+#ifndef _WIN32
err = k5_mutex_finish_init(&kg_kdc_flag_mutex);
if (err)
return err;
@@ -75,7 +74,7 @@ void gssint_lib_fini(void)
k5_key_delete(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME);
k5_key_delete(K5_KEY_GSS_KRB5_CCACHE_NAME);
k5_mutex_destroy(&kg_vdb.mutex);
-#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */
+#ifndef _WIN32
k5_mutex_destroy(&kg_kdc_flag_mutex);
#endif
k5_mutex_destroy(&gssint_krb5_keytab_lock);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/indicate_mechs.c b/usr/src/lib/gss_mechs/mech_krb5/mech/indicate_mechs.c
index 060ac76ace..f10077a77e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/indicate_mechs.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/indicate_mechs.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
@@ -23,7 +21,7 @@
*/
/*
- * $Id: indicate_mechs.c 18131 2006-06-14 22:27:54Z tlyu $
+ * $Id: indicate_mechs.c 18330 2006-07-17 16:39:35Z tlyu $
*/
#include "gssapiP_krb5.h"
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c b/usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c
index 7a0015abf9..811de69cf4 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 2000,2002, 2003 by the Massachusetts Institute of Technology.
@@ -78,8 +77,8 @@
*/
#include "k5-int.h"
-#include "gssapiP_krb5.h"
#include "gss_libinit.h"
+#include "gssapiP_krb5.h"
#include "mglueP.h"
#ifdef HAVE_MEMORY_H
#include <memory.h>
@@ -92,7 +91,7 @@ static OM_uint32 get_default_cred(OM_uint32 *, void *, gss_cred_id_t *);
/* Solaris Kerberos end */
/*
- * $Id: init_sec_context.c 18131 2006-06-14 22:27:54Z tlyu $
+ * $Id: init_sec_context.c 18721 2006-10-16 16:18:29Z epeisach $
*/
/* XXX This is for debugging only!!! Should become a real bitfield
@@ -232,7 +231,7 @@ make_gss_checksum (krb5_context context, krb5_auth_context auth_context,
krb5_free_data_contents(context, &credmsg);
return(ENOMEM);
}
-
+ /* Solaris Kerberos */
ptr = (uchar_t *)data->checksum_data.data; /* SUNW15resync */
TWRITE_INT(ptr, data->md5.length, 0);
@@ -370,9 +369,7 @@ setup_enc(
krb5_gss_ctx_id_rec *ctx,
krb5_context context)
{
-
krb5_error_code code;
- OM_uint32 ret = GSS_S_COMPLETE;
int i;
krb5int_access kaccess;
@@ -446,7 +443,6 @@ setup_enc(
goto fail;
goto copy_subkey;
}
-
fail:
/* SUNW15resync - (as in prev snv code) add if-code and success label fix */
if (code) {
@@ -455,7 +451,7 @@ fail:
}
success:
- return (ret);
+ return (GSS_S_COMPLETE);
}
/*
@@ -711,7 +707,7 @@ mutual_auth(
return(GSS_S_NO_CONTEXT);
}
- ctx = (krb5_gss_ctx_id_rec *)*context_handle; /* SUNW15resync */
+ ctx = (krb5_gss_ctx_id_t) *context_handle;
/* make sure the context is non-established, and that certain
arguments are unchanged */
@@ -999,7 +995,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
return(major_status);
}
-#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */
+#ifndef _WIN32
k5_mutex_t kg_kdc_flag_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
static int kdc_flag = 0;
#endif
@@ -1008,12 +1004,14 @@ krb5_error_code
krb5_gss_init_context (krb5_context *ctxp)
{
krb5_error_code err;
+#ifndef _WIN32
int is_kdc;
+#endif
err = gssint_initialize_library();
if (err)
return err;
-#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */
+#ifndef _WIN32
err = k5_mutex_lock(&kg_kdc_flag_mutex);
if (err)
return err;
@@ -1022,14 +1020,12 @@ krb5_gss_init_context (krb5_context *ctxp)
if (is_kdc)
return krb5int_init_context_kdc(ctxp);
- else
- return krb5_init_context(ctxp);
#endif
- return krb5_init_context(ctxp);
+ return krb5_init_context(ctxp);
}
-#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */
+#ifndef _WIN32
krb5_error_code
krb5_gss_use_kdc_context()
{
@@ -1396,26 +1392,6 @@ load_root_cred_using_keytab(
*minor_status = code;
return (GSS_S_FAILURE);
}
- /*
- * Solaris Kerberos:
- * If the client's realm is empty (using a fallback method to determine
- * the realm) then make sure to set the client's realm to the default
- * realm. This ensures that the TGT is built correctly.
- */
- if (krb5_is_referral_realm(&(me->realm))) {
- char *realm;
-
- free(me->realm.data);
- code = krb5_get_default_realm(context, &realm);
- if (code) {
- (void) krb5_kt_close(context, keytab);
- *minor_status = code;
- return (GSS_S_FAILURE);
- }
-
- me->realm.data = realm;
- me->realm.length = strlen(realm);
- }
my_creds.client = me;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/inq_cred.c b/usr/src/lib/gss_mechs/mech_krb5/mech/inq_cred.c
index 9460971297..43954f7e3a 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/inq_cred.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/inq_cred.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Copyright 2000 by the Massachusetts Institute of Technology.
* All Rights Reserved.
@@ -157,15 +155,16 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
}
if (mechanisms) {
+ /* Solaris Kerberos */
if (GSS_ERROR(ret = generic_gss_create_empty_oid_set(minor_status,
&mechs)) ||
(cred->prerfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- (const gss_OID) gss_mech_krb5_old,
+ (const gss_OID) gss_mech_krb5_old,
&mechs))) ||
(cred->rfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- (const gss_OID) gss_mech_krb5,
+ (const gss_OID) gss_mech_krb5,
&mechs)))) {
k5_mutex_unlock(&cred->lock);
if (ret_name)
@@ -176,7 +175,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
}
if (name) {
- if (ret_name != NULL && ! kg_save_name((gss_name_t) ret_name)) {
+ if (ret_name != NULL && ! kg_save_name((gss_name_t) ret_name)) {
k5_mutex_unlock(&cred->lock);
if (cred_handle == GSS_C_NO_CREDENTIAL)
krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/inq_names.c b/usr/src/lib/gss_mechs/mech_krb5/mech/inq_names.c
index e5fbfa5b87..cf53719b45 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/inq_names.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/inq_names.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/gssapi/krb5/inq_names.c
*
@@ -81,12 +79,13 @@ krb5_gss_inquire_names_for_mech(minor_status, mechanism, name_types)
name_types)
) == GSS_S_COMPLETE) &&
((major = generic_gss_add_oid_set_member(minor_status,
- (const gss_OID) gss_nt_krb5_name,
+ (const gss_OID) gss_nt_krb5_name, /* Solaris Kerberos */
name_types)
) == GSS_S_COMPLETE)
) {
+ /* Solaris Kerberos */
major = generic_gss_add_oid_set_member(minor_status,
- (const gss_OID) gss_nt_krb5_principal,
+ (const gss_OID) gss_nt_krb5_principal,
name_types);
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/krb5_gss_glue.c b/usr/src/lib/gss_mechs/mech_krb5/mech/krb5_gss_glue.c
index a63be60ffd..d04f7182f5 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/krb5_gss_glue.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/krb5_gss_glue.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1993 by OpenVision Technologies, Inc.
@@ -28,7 +27,7 @@
*/
/*
- * $Id: krb5_gss_glue.c 18268 2006-06-29 19:44:34Z tlyu $
+ * $Id: krb5_gss_glue.c 18262 2006-06-29 04:38:48Z tlyu $
*/
#include "gssapiP_krb5.h"
@@ -42,7 +41,7 @@ static OM_uint32 k5glue_acquire_cred
gss_name_t, /* desired_name */
OM_uint32, /* time_req */
gss_OID_set, /* desired_mechs */
- gss_cred_usage_t, /* cred_usage */
+ gss_cred_usage_t, /* cred_usage */
gss_cred_id_t*, /* output_cred_handle */
gss_OID_set*, /* actual_mechs */
OM_uint32* /* time_rec */
@@ -616,7 +615,7 @@ k5glue_acquire_cred(ctx, minor_status, desired_name, time_req, desired_mechs,
gss_name_t desired_name;
OM_uint32 time_req;
gss_OID_set desired_mechs;
- gss_cred_usage_t cred_usage;
+ gss_cred_usage_t cred_usage;
gss_cred_id_t *output_cred_handle;
gss_OID_set *actual_mechs;
OM_uint32 *time_rec;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/process_context_token.c b/usr/src/lib/gss_mechs/mech_krb5/mech/process_context_token.c
index 9e312adbf5..292b3e3f08 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/process_context_token.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/process_context_token.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
@@ -25,7 +23,7 @@
#include "gssapiP_krb5.h"
/*
- * $Id: process_context_token.c 16171 2004-03-15 17:45:01Z raeburn $
+ * $Id: process_context_token.c 18396 2006-07-25 20:29:43Z lxs $
*/
OM_uint32
@@ -54,7 +52,7 @@ krb5_gss_process_context_token(minor_status, context_handle,
/* "unseal" the token */
if (GSS_ERROR(majerr = kg_unseal(minor_status, context_handle,
- token_buffer,
+ token_buffer,
GSS_C_NO_BUFFER, NULL, NULL,
KG_TOK_DEL_CTX)))
return(majerr);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid.c b/usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid.c
index 395ba68818..5b6d9a6cdd 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/gssapi/krb5/rel_oid.c
*
@@ -31,7 +29,10 @@
* rel_oid.c - Release an OID.
*/
#include "gssapiP_krb5.h"
-#include "mglueP.h"
+
+/* Solaris Kerberos - resync 163 */
+OM_uint32 generic_gss_release_oid (OM_uint32 *, gss_OID *);
+
OM_uint32 krb5_gss_internal_release_oid (OM_uint32 *, /* minor_status */
gss_OID * /* oid */
diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/set_ccache.c b/usr/src/lib/gss_mechs/mech_krb5/mech/set_ccache.c
index e6f784c049..929749d978 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/set_ccache.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/set_ccache.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/gssapi/krb5/set_ccache.c
@@ -65,6 +64,7 @@ gss_krb5_ccache_name(minor_status, name, out_name)
}
if (!err) {
old_name = gss_out_name;
+ /* Solaris Kerberos */
gss_out_name = (char *)tmp_name;
}
}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/profile/prof_file.c b/usr/src/lib/gss_mechs/mech_krb5/profile/prof_file.c
index 3b33f25ccf..893cdfc6d5 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/profile/prof_file.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/profile/prof_file.c
@@ -1,8 +1,7 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* prof_file.c ---- routines that manipulate an individual profile file.
*/
@@ -55,6 +54,9 @@ MAKE_FINI_FUNCTION(profile_library_finalizer);
int profile_library_initializer(void)
{
+#ifdef SHOW_INITFINI_FUNCS
+ printf("profile_library_initializer\n");
+#endif
#if !USE_BUNDLE_ERROR_STRINGS
add_error_table(&et_prof_error_table);
#endif
@@ -62,8 +64,15 @@ int profile_library_initializer(void)
}
void profile_library_finalizer(void)
{
- if (! INITIALIZER_RAN(profile_library_initializer) || PROGRAM_EXITING())
+ if (! INITIALIZER_RAN(profile_library_initializer) || PROGRAM_EXITING()) {
+#ifdef SHOW_INITFINI_FUNCS
+ printf("profile_library_finalizer: skipping\n");
+#endif
return;
+ }
+#ifdef SHOW_INITFINI_FUNCS
+ printf("profile_library_finalizer\n");
+#endif
k5_mutex_destroy(&g_shared_trees_mutex);
#if !USE_BUNDLE_ERROR_STRINGS
remove_error_table(&et_prof_error_table);
@@ -85,6 +94,7 @@ static void profile_free_file_data(prf_data_t);
assert(d->fslen <= 1000); /* XXX */ \
assert(d->filespec[d->fslen] == 0); \
assert(d->fslen = strlen(d->filespec)); \
+ assert(d->root != NULL); \
} \
}
@@ -118,7 +128,7 @@ static int rw_access(const_profile_filespec_t filespec)
* checks the r/w permissions.
*/
FILE *f;
-
+ /* Solaris Kerberos */
f = fopen(filespec, "r+F");
if (f) {
fclose(f);
@@ -143,6 +153,7 @@ static int r_access(const_profile_filespec_t filespec)
*/
FILE *f;
+ /* Solaris Kerberos */
f = fopen(filespec, "rF");
if (f) {
fclose(f);
@@ -196,7 +207,7 @@ errcode_t profile_open_file(const_profile_filespec_t filespec,
scan_shared_trees_unlocked();
- prf = (prf_file_t) malloc(sizeof(struct _prf_file_t));
+ prf = malloc(sizeof(struct _prf_file_t));
if (!prf)
return ENOMEM;
memset(prf, 0, sizeof(struct _prf_file_t));
@@ -208,25 +219,12 @@ errcode_t profile_open_file(const_profile_filespec_t filespec,
#ifdef HAVE_PWD_H
if (home_env == NULL) {
uid_t uid;
- struct passwd *pw;
-#ifdef HAVE_GETPWUID_R
- struct passwd pwx;
+ struct passwd *pw, pwx;
char pwbuf[BUFSIZ];
-#endif
uid = getuid();
-#ifndef HAVE_GETPWUID_R
- pw = getpwuid(uid);
-#elif defined(GETPWUID_R_4_ARGS)
- /* earlier POSIX drafts */
- pw = getpwuid_r(uid, &pwx, pwbuf, sizeof(pwbuf));
-#else
- /* POSIX */
- if (getpwuid_r(uid, &pwx, pwbuf, sizeof(pwbuf), &pw) != 0)
- /* Probably already null, but let's make sure. */
- pw = NULL;
-#endif /* getpwuid variants */
- if (pw != NULL && pw->pw_dir[0] != 0)
+ if (!k5_getpwuid_r(uid, &pwx, pwbuf, sizeof(pwbuf), &pw)
+ && pw != NULL && pw->pw_dir[0] != 0)
home_env = pw->pw_dir;
}
#endif
@@ -257,9 +255,9 @@ errcode_t profile_open_file(const_profile_filespec_t filespec,
break;
}
if (data) {
- retval = profile_update_file_data(data);
data->refcount++;
(void) k5_mutex_unlock(&g_shared_trees_mutex);
+ retval = profile_update_file_data(data);
free(expanded_filename);
prf->data = data;
*ret_prof = prf;
@@ -311,10 +309,9 @@ errcode_t profile_update_file_data(prf_data_t data)
errcode_t retval;
#ifdef HAVE_STAT
struct stat st;
-#ifdef STAT_ONCE_PER_SECOND
+ unsigned long frac;
time_t now;
#endif
-#endif
FILE *f;
retval = k5_mutex_lock(&data->lock);
@@ -322,22 +319,29 @@ errcode_t profile_update_file_data(prf_data_t data)
return retval;
#ifdef HAVE_STAT
-#ifdef STAT_ONCE_PER_SECOND
now = time(0);
- if (now == data->last_stat) {
+ if (now == data->last_stat && data->root != NULL) {
k5_mutex_unlock(&data->lock);
return 0;
}
-#endif
if (stat(data->filespec, &st)) {
retval = errno;
k5_mutex_unlock(&data->lock);
return retval;
}
-#ifdef STAT_ONCE_PER_SECOND
data->last_stat = now;
+#if defined HAVE_STRUCT_STAT_ST_MTIMENSEC
+ frac = st.st_mtimensec;
+#elif defined HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
+ frac = st.st_mtimespec.tv_nsec;
+#elif defined HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+ frac = st.st_mtim.tv_nsec;
+#else
+ frac = 0;
#endif
- if (st.st_mtime == data->timestamp) {
+ if (st.st_mtime == data->timestamp
+ && frac == data->frac_ts
+ && data->root != NULL) {
k5_mutex_unlock(&data->lock);
return 0;
}
@@ -361,6 +365,7 @@ errcode_t profile_update_file_data(prf_data_t data)
}
#endif
errno = 0;
+ /* Solaris Kerberos */
f = fopen(data->filespec, "rF");
if (f == NULL) {
retval = errno;
@@ -379,8 +384,10 @@ errcode_t profile_update_file_data(prf_data_t data)
k5_mutex_unlock(&data->lock);
return retval;
}
+ assert(data->root != NULL);
#ifdef HAVE_STAT
data->timestamp = st.st_mtime;
+ data->frac_ts = frac;
#endif
k5_mutex_unlock(&data->lock);
return 0;
@@ -407,10 +414,10 @@ static errcode_t write_data_to_file(prf_data_t data, const char *outfile,
retval = ENOMEM;
new_file = old_file = 0;
- new_file = (char *) malloc(strlen(outfile) + 5);
+ new_file = malloc(strlen(outfile) + 5);
if (!new_file)
goto errout;
- old_file = (char *) malloc(strlen(outfile) + 5);
+ old_file = malloc(strlen(outfile) + 5);
if (!old_file)
goto errout;
@@ -419,6 +426,7 @@ static errcode_t write_data_to_file(prf_data_t data, const char *outfile,
errno = 0;
+ /* Solaris Kerberos */
f = fopen(new_file, "wF");
if (!f) {
retval = errno;
@@ -533,19 +541,19 @@ errcode_t profile_flush_file_data_to_file(prf_data_t data, const char *outfile)
void profile_dereference_data(prf_data_t data)
{
int err;
- scan_shared_trees_unlocked();
err = k5_mutex_lock(&g_shared_trees_mutex);
if (err)
return;
profile_dereference_data_locked(data);
(void) k5_mutex_unlock(&g_shared_trees_mutex);
- scan_shared_trees_unlocked();
}
void profile_dereference_data_locked(prf_data_t data)
{
+ scan_shared_trees_locked();
data->refcount--;
if (data->refcount == 0)
profile_free_file_data(data);
+ scan_shared_trees_locked();
}
int profile_lock_global()
diff --git a/usr/src/lib/gss_mechs/mech_krb5/profile/prof_get.c b/usr/src/lib/gss_mechs/mech_krb5/profile/prof_get.c
index fdf4470087..08fac7f06f 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/profile/prof_get.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/profile/prof_get.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* prof_get.c --- routines that expose the public interfaces for
* querying items from the profile.
@@ -40,7 +39,7 @@ static errcode_t init_list(struct profile_string_list *list)
{
list->num = 0;
list->max = 10;
- list->list = (char **) malloc(list->max * sizeof(char *));
+ list->list = malloc(list->max * sizeof(char *));
if (list->list == 0)
return ENOMEM;
list->list[0] = 0;
@@ -80,13 +79,13 @@ static errcode_t add_to_list(struct profile_string_list *list, const char *str)
if (list->num+1 >= list->max) {
newmax = list->max + 10;
- newlist = (char **) realloc(list->list, newmax * sizeof(char *));
+ newlist = realloc(list->list, newmax * sizeof(char *));
if (newlist == 0)
return ENOMEM;
list->max = newmax;
list->list = newlist;
}
- newstr = (char *) malloc(strlen(str)+1);
+ newstr = malloc(strlen(str)+1);
if (newstr == 0)
return ENOMEM;
strcpy(newstr, str);
@@ -162,7 +161,7 @@ profile_get_values(profile_t profile, const char *const *names,
return 0;
cleanup:
- end_list(&values, (char ***)NULL);
+ end_list(&values, 0);
return retval;
}
@@ -218,7 +217,7 @@ profile_get_string(profile_t profile, const char *name, const char *subname,
value = def_val;
if (value) {
- *ret_string = (char *) malloc(strlen(value)+1);
+ *ret_string = malloc(strlen(value)+1);
if (*ret_string == 0)
return ENOMEM;
strcpy(*ret_string, value);
@@ -367,7 +366,7 @@ profile_get_subsection_names(profile_t profile, const char **names,
return 0;
cleanup:
- end_list(&values, (char ***)NULL);
+ end_list(&values, 0);
return retval;
}
@@ -403,7 +402,7 @@ profile_get_relation_names(profile_t profile, const char **names,
return 0;
cleanup:
- end_list(&values, (char ***)NULL);
+ end_list(&values, 0);
return retval;
}
@@ -432,7 +431,7 @@ profile_iterator(void **iter_p, char **ret_name, char **ret_value)
if (ret_name) {
if (name) {
- *ret_name = (char *) malloc(strlen(name)+1);
+ *ret_name = malloc(strlen(name)+1);
if (!*ret_name)
return ENOMEM;
strcpy(*ret_name, name);
@@ -441,7 +440,7 @@ profile_iterator(void **iter_p, char **ret_name, char **ret_value)
}
if (ret_value) {
if (value) {
- *ret_value = (char *) malloc(strlen(value)+1);
+ *ret_value = malloc(strlen(value)+1);
if (!*ret_value) {
if (ret_name) {
free(*ret_name);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/profile/prof_init.c b/usr/src/lib/gss_mechs/mech_krb5/profile/prof_init.c
index 2ee24b3aa9..3cb35924ce 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/profile/prof_init.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/profile/prof_init.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* prof_init.c --- routines that manipulate the user-visible profile_t
@@ -19,16 +18,13 @@
#endif
#include <errno.h>
-/* Find a 4-byte integer type */
-#if (SIZEOF_SHORT == 4)
-typedef short prof_int32;
-#elif (SIZEOF_INT == 4)
-typedef int prof_int32;
-#elif (SIZEOF_LONG == 4)
-typedef long prof_int32;
-#else /* SIZEOF_LONG == 4 */
-error(do not have a 4-byte integer type)
-#endif /* SIZEOF_LONG == 4 */
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+typedef int32_t prof_int32;
errcode_t KRB5_CALLCONV
profile_init(const_profile_filespec_t *files, profile_t *ret_profile)
@@ -76,6 +72,39 @@ profile_init(const_profile_filespec_t *files, profile_t *ret_profile)
return 0;
}
+#define COUNT_LINKED_LIST(COUNT, PTYPE, START, FIELD) \
+ { \
+ int cll_counter = 0; \
+ PTYPE cll_ptr = (START); \
+ while (cll_ptr != NULL) { \
+ cll_counter++; \
+ cll_ptr = cll_ptr->FIELD; \
+ } \
+ (COUNT) = cll_counter; \
+ }
+
+errcode_t KRB5_CALLCONV
+profile_copy(profile_t old_profile, profile_t *new_profile)
+{
+ size_t size, i;
+ const_profile_filespec_t *files;
+ prf_file_t file;
+ errcode_t err;
+
+ /* The fields we care about are read-only after creation, so
+ no locking is needed. */
+ COUNT_LINKED_LIST (size, prf_file_t, old_profile->first_file, next);
+ files = malloc ((size+1) * sizeof(*files));
+ if (files == NULL)
+ return errno;
+ for (i = 0, file = old_profile->first_file; i < size; i++, file = file->next)
+ files[i] = file->data->filespec;
+ files[size] = NULL;
+ err = profile_init (files, new_profile);
+ free (files);
+ return err;
+}
+
errcode_t KRB5_CALLCONV
profile_init_path(const_profile_filespec_list_t filepath,
profile_t *ret_profile)
@@ -98,6 +127,7 @@ profile_init_path(const_profile_filespec_list_t filepath,
return ENOMEM;
/* measure, copy, and skip each one */
+ /* Solaris Kerberos */
for(s = filepath, i=0; ((t = strchr(s, ':')) != NULL) ||
((t=s+strlen(s)) != NULL); s=t+1, i++) {
ent_len = t-s;
@@ -131,31 +161,31 @@ profile_init_path(const_profile_filespec_list_t filepath,
errcode_t KRB5_CALLCONV
profile_is_writable(profile_t profile, int *writable)
{
- if (!profile || profile->magic != PROF_MAGIC_PROFILE)
- return PROF_MAGIC_PROFILE;
-
- if (!writable)
- return EINVAL;
-
- if (profile->first_file)
- *writable = (profile->first_file->data->flags & PROFILE_FILE_RW);
-
- return 0;
+ if (!profile || profile->magic != PROF_MAGIC_PROFILE)
+ return PROF_MAGIC_PROFILE;
+
+ if (!writable)
+ return EINVAL;
+
+ if (profile->first_file)
+ *writable = (profile->first_file->data->flags & PROFILE_FILE_RW);
+
+ return 0;
}
errcode_t KRB5_CALLCONV
profile_is_modified(profile_t profile, int *modified)
{
- if (!profile || profile->magic != PROF_MAGIC_PROFILE)
- return PROF_MAGIC_PROFILE;
-
- if (!modified)
- return EINVAL;
-
- if (profile->first_file)
- *modified = (profile->first_file->data->flags & PROFILE_FILE_DIRTY);
-
- return 0;
+ if (!profile || profile->magic != PROF_MAGIC_PROFILE)
+ return PROF_MAGIC_PROFILE;
+
+ if (!modified)
+ return EINVAL;
+
+ if (profile->first_file)
+ *modified = (profile->first_file->data->flags & PROFILE_FILE_DIRTY);
+
+ return 0;
}
errcode_t KRB5_CALLCONV
@@ -277,7 +307,7 @@ errcode_t profile_ser_externalize(const char *unused, profile_t profile,
fcount = 0;
for (pfp = profile->first_file; pfp; pfp = pfp->next)
fcount++;
- pack_int32((prof_int32)PROF_MAGIC_PROFILE, &bp, &remain);
+ pack_int32(PROF_MAGIC_PROFILE, &bp, &remain);
pack_int32(fcount, &bp, &remain);
for (pfp = profile->first_file; pfp; pfp = pfp->next) {
slen = (prof_int32) strlen(pfp->data->filespec);
@@ -288,7 +318,7 @@ errcode_t profile_ser_externalize(const char *unused, profile_t profile,
remain -= (size_t) slen;
}
}
- pack_int32((prof_int32)PROF_MAGIC_PROFILE, &bp, &remain);
+ pack_int32(PROF_MAGIC_PROFILE, &bp, &remain);
retval = 0;
*bufpp = bp;
*remainp = remain;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/profile/prof_int.h b/usr/src/lib/gss_mechs/mech_krb5/profile/prof_int.h
index 26721834d5..eed3c8533e 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/profile/prof_int.h
+++ b/usr/src/lib/gss_mechs/mech_krb5/profile/prof_int.h
@@ -1,14 +1,14 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* prof-int.h
*/
+/* Solaris Kerberos */
#ifndef __PROF_INT_H
#include <time.h>
@@ -19,20 +19,10 @@
#define PROFILE_SUPPORTS_FOREIGN_NEWLINES
#endif
-#include <k5-thread.h>
-#include <com_err.h>
-#include <profile.h>
-#include "prof_err.h" /* SUNW14resync */
-#include "osconf.h" /* SUNW14resync */
-
-
-#define STAT_ONCE_PER_SECOND
-
-#if defined(_WIN32)
-#define SIZEOF_INT 4
-#define SIZEOF_SHORT 2
-#define SIZEOF_LONG 4
-#endif
+#include "k5-thread.h"
+#include "k5-platform.h"
+#include "com_err.h"
+#include "profile.h"
typedef long prf_magic_t;
@@ -41,28 +31,41 @@ typedef long prf_magic_t;
* particular configuration file.
*
* Locking strategy:
- * - filespec is fixed after creation
+ * - filespec, fslen are fixed after creation
* - refcount and next should only be tweaked with the global lock held
* - other fields can be tweaked after grabbing the in-struct lock
*/
struct _prf_data_t {
prf_magic_t magic;
k5_mutex_t lock;
- char *comment;
struct profile_node *root;
-#ifdef STAT_ONCE_PER_SECOND
time_t last_stat;
-#endif
time_t timestamp; /* time tree was last updated from file */
+ unsigned long frac_ts; /* fractional part of timestamp, if any */
int flags; /* r/w, dirty */
int upd_serial; /* incremented when data changes */
+ char *comment;
+
+ size_t fslen;
+
+ /* Some separation between fields controlled by different
+ mutexes. Theoretically, both could be accessed at the same
+ time from different threads on different CPUs with separate
+ caches. Don't let the threads clobber each other's
+ changes. One mutex controlling the whole thing would be
+ better, but sufficient separation might suffice.
+
+ This is icky. I just hope it's adequate.
+
+ For next major release, fix this. */
+ union { double d; void *p; UINT64_TYPE ll; k5_mutex_t m; } pad;
+
int refcount; /* prf_file_t references */
struct _prf_data_t *next;
/* Was: "profile_filespec_t filespec". Now: flexible char
array ... except, we need to work in C89, so an array
length must be specified. */
- size_t fslen;
- const char filespec[sizeof(DEFAULT_SECURE_PROFILE_PATH)];
+ const char filespec[sizeof("/etc/krb5.conf")];
};
typedef struct _prf_data_t *prf_data_t;
@@ -210,6 +213,8 @@ errcode_t profile_rename_node
/* prof_file.c */
+errcode_t KRB5_CALLCONV profile_copy (profile_t, profile_t *);
+
errcode_t profile_open_file
(const_profile_filespec_t file, prf_file_t *ret_prof);
@@ -259,5 +264,6 @@ errcode_t profile_get_value
/* prof_set.c -- included from profile.h */
+/* Solaris Kerberos */
#define __PROF_INT_H
#endif
diff --git a/usr/src/lib/gss_mechs/mech_krb5/profile/prof_parse.c b/usr/src/lib/gss_mechs/mech_krb5/profile/prof_parse.c
index 33dd13b2c0..4200bc5098 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/profile/prof_parse.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/profile/prof_parse.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include "prof_int.h"
@@ -91,10 +90,10 @@ static errcode_t parse_std_line(char *line, struct parse_state *state)
if (*line == 0)
return 0;
- if (line[0] == ';' || line[0] == '#')
- return 0;
- strip_line(line);
cp = skip_over_blanks(line);
+ if (cp[0] == ';' || cp[0] == '#')
+ return 0;
+ strip_line(cp);
ch = *cp;
if (ch == 0)
return 0;
@@ -122,7 +121,6 @@ static errcode_t parse_std_line(char *line, struct parse_state *state)
* Finish off the rest of the line.
*/
cp = p+1;
-
if (*cp == '*') {
profile_make_node_final(state->current_section);
cp++;
@@ -182,9 +180,6 @@ static errcode_t parse_std_line(char *line, struct parse_state *state)
} else if (value[0] == '{' && *(skip_over_blanks(value+1)) == 0)
do_subsection++;
else {
- /*
- * Skip over trailing whitespace characters
- */
cp = value + strlen(value) - 1;
while ((cp > value) && isspace((int) (*cp)))
*cp-- = 0;
@@ -240,7 +235,7 @@ errcode_t profile_parse_file(FILE *f, struct profile_node **root)
errcode_t retval;
struct parse_state state;
- bptr = (char *) malloc (BUF_SIZE);
+ bptr = malloc (BUF_SIZE);
if (!bptr)
return ENOMEM;
@@ -255,7 +250,7 @@ errcode_t profile_parse_file(FILE *f, struct profile_node **root)
#ifndef PROFILE_SUPPORTS_FOREIGN_NEWLINES
retval = parse_line(bptr, &state);
if (retval) {
- /* check if an unconfigured file */
+ /* Solaris Kerberos: check if an unconfigured file */
if (strstr(bptr, "___"))
retval = PROF_NO_PROFILE;
free (bptr);
@@ -322,8 +317,10 @@ errcode_t profile_parse_file(FILE *f, struct profile_node **root)
*/
static int need_double_quotes(char *str)
{
- if (!str || !*str)
- return 0;
+ if (!str)
+ return 0;
+ if (str[0] == '\0')
+ return 1;
if (isspace((int) (*str)) ||isspace((int) (*(str + strlen(str) - 1))))
return 1;
if (strchr(str, '\n') || strchr(str, '\t') || strchr(str, '\b'))
diff --git a/usr/src/lib/gss_mechs/mech_krb5/profile/prof_tree.c b/usr/src/lib/gss_mechs/mech_krb5/profile/prof_tree.c
index 398a979d89..f0ff7f56e1 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/profile/prof_tree.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/profile/prof_tree.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* prof_tree.c --- these routines maintain the parse tree of the
@@ -95,17 +94,17 @@ errcode_t profile_create_node(const char *name, const char *value,
{
struct profile_node *new;
- new = (struct profile_node *)malloc(sizeof(struct profile_node));
+ new = malloc(sizeof(struct profile_node));
if (!new)
return ENOMEM;
memset(new, 0, sizeof(struct profile_node));
- new->name = (char *) strdup(name);
+ new->name = strdup(name);
if (new->name == 0) {
profile_free_node(new);
return ENOMEM;
}
if (value) {
- new->value = (char *) strdup(value);
+ new->value = strdup(value);
if (new->value == 0) {
profile_free_node(new);
return ENOMEM;
@@ -360,6 +359,7 @@ errcode_t profile_find_node_subsection(struct profile_node *section,
struct profile_node *p;
errcode_t retval;
+ /* Solaris Kerberos */
if (section == (struct profile_node *)NULL)
return (PROF_NO_PROFILE);
@@ -422,8 +422,7 @@ errcode_t profile_node_iterator_create(profile_t profile,
done_idx = 1;
}
- if ((iter = (struct profile_iterator *)
- malloc(sizeof(struct profile_iterator))) == NULL)
+ if ((iter = malloc(sizeof(struct profile_iterator))) == NULL)
return ENOMEM;
iter->magic = PROF_MAGIC_ITERATOR;
@@ -538,6 +537,7 @@ get_new_file:
* or find the containing section if not.
*/
section = iter->file->data->root;
+ assert(section != NULL);
for (cpp = iter->names; cpp[iter->done_idx]; cpp++) {
for (p=section->first_child; p; p = p->next) {
if (!strcmp(p->name, *cpp) && !p->value)
@@ -584,6 +584,8 @@ get_new_file:
skip_num--;
continue;
}
+ if (p->deleted)
+ continue;
break;
}
iter->num++;
@@ -645,7 +647,7 @@ errcode_t profile_set_relation_value(struct profile_node *node,
if (!node->value)
return PROF_SET_SECTION_VALUE;
- cp = (char *) malloc(strlen(new_value)+1);
+ cp = malloc(strlen(new_value)+1);
if (!cp)
return ENOMEM;
@@ -674,7 +676,7 @@ errcode_t profile_rename_node(struct profile_node *node, const char *new_name)
/*
* Make sure we can allocate memory for the new name, first!
*/
- new_string = (char *) malloc(strlen(new_name)+1);
+ new_string = malloc(strlen(new_name)+1);
if (!new_string)
return ENOMEM;
strcpy(new_string, new_name);
diff --git a/usr/src/lib/gss_mechs/mech_krb5/support/fake-addrinfo.c b/usr/src/lib/gss_mechs/mech_krb5/support/fake-addrinfo.c
index d768762dfc..3254189832 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/support/fake-addrinfo.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/support/fake-addrinfo.c
@@ -1,7 +1,5 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
- * Copyright (C) 2004 by the Massachusetts Institute of Technology,
+ * Copyright (C) 2001,2002,2003,2004,2005,2006 by the Massachusetts Institute of Technology,
* Cambridge, MA, USA. All Rights Reserved.
*
* This software is being provided to you, the LICENSEE, by the
@@ -41,24 +39,1283 @@
* fashion that it might be confused with the original M.I.T. software.
*/
-#include <fake-addrinfo.h>
-#include <k5-thread.h>
+/* Approach overview:
+
+ If a system version is available but buggy, save handles to it,
+ redefine the names to refer to static functions defined here, and
+ in those functions, call the system versions and fix up the
+ returned data. Use the native data structures and flag values.
+
+ If no system version exists, use gethostby* and fake it. Define
+ the data structures and flag values locally.
+
+
+ On Mac OS X, getaddrinfo results aren't cached (though
+ gethostbyname results are), so we need to build a cache here. Now
+ things are getting really messy. Because the cache is in use, we
+ use getservbyname, and throw away thread safety. (Not that the
+ cache is thread safe, but when we get locking support, that'll be
+ dealt with.) This code needs tearing down and rebuilding, soon.
+
+
+ Note that recent Windows developers' code has an interesting hack:
+ When you include the right header files, with the right set of
+ macros indicating system versions, you'll get an inline function
+ that looks for getaddrinfo (or whatever) in the system library, and
+ calls it if it's there. If it's not there, it fakes it with
+ gethostby* calls.
+
+ We're taking a simpler approach: A system provides these routines or
+ it does not.
+
+ Someday, we may want to take into account different versions (say,
+ different revs of GNU libc) where some are broken in one way, and
+ some work or are broken in another way. Cross that bridge when we
+ come to it. */
+
+/* To do, maybe:
+
+ + For AIX 4.3.3, using the RFC 2133 definition: Implement
+ AI_NUMERICHOST. It's not defined in the header file.
+
+ For certain (old?) versions of GNU libc, AI_NUMERICHOST is
+ defined but not implemented.
+
+ + Use gethostbyname2, inet_aton and other IPv6 or thread-safe
+ functions if available. But, see
+ http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=135182 for one
+ gethostbyname2 problem on Linux. And besides, if a platform is
+ supporting IPv6 at all, they really should be doing getaddrinfo
+ by now.
+
+ + inet_ntop, inet_pton
+
+ + Conditionally export/import the function definitions, so a
+ library can have a single copy instead of multiple.
+
+ + Upgrade host requirements to include working implementations of
+ these functions, and throw all this away. Pleeease? :-) */
+
+#include "port-sockets.h"
+#include "socket-utils.h"
+#include "k5-platform.h"
+#include "k5-thread.h"
+#include "supp-int.h"
+
+#include <stdio.h> /* for sprintf */
+#include <errno.h>
+
+#define IMPLEMENT_FAKE_GETADDRINFO
+#include "fake-addrinfo.h"
+
+#ifdef S_SPLINT_S
+/*@-incondefs@*/
+extern int
+getaddrinfo (/*@in@*/ /*@null@*/ const char *,
+ /*@in@*/ /*@null@*/ const char *,
+ /*@in@*/ /*@null@*/ const struct addrinfo *,
+ /*@out@*/ struct addrinfo **)
+ ;
+extern void
+freeaddrinfo (/*@only@*/ /*@out@*/ struct addrinfo *)
+ ;
+extern int
+getnameinfo (const struct sockaddr *addr, socklen_t addrsz,
+ /*@out@*/ /*@null@*/ char *h, socklen_t hsz,
+ /*@out@*/ /*@null@*/ char *s, socklen_t ssz,
+ int flags)
+ /*@requires (maxSet(h)+1) >= hsz /\ (maxSet(s)+1) >= ssz @*/
+ /* too hard: maxRead(addr) >= (addrsz-1) */
+ /*@modifies *h, *s@*/;
+extern /*@dependent@*/ char *gai_strerror (int code) /*@*/;
+/*@=incondefs@*/
+#endif
+
+
+#include "cache-addrinfo.h"
+
+#if (defined (__linux__) && defined(HAVE_GETADDRINFO)) || defined (_AIX)
+/* See comments below. */
+# define WRAP_GETADDRINFO
+#endif
+
+#if defined (__linux__) && defined(HAVE_GETADDRINFO)
+# define COPY_FIRST_CANONNAME
+#endif
-/* Allocate the storage here. */
-struct fac krb5int_fac = { K5_MUTEX_PARTIAL_INITIALIZER, 0 };
+#ifdef _AIX
+# define NUMERIC_SERVICE_BROKEN
+# define COPY_FIRST_CANONNAME
+#endif
-int krb5int_init_fac (void)
+
+#ifdef COPY_FIRST_CANONNAME
+# include <string.h>
+#endif
+
+#ifdef NUMERIC_SERVICE_BROKEN
+# include <ctype.h> /* isdigit */
+# include <stdlib.h> /* strtoul */
+#endif
+
+
+/* Do we actually have *any* systems we care about that don't provide
+ either getaddrinfo or one of these two flavors of
+ gethostbyname_r? */
+#if !defined(HAVE_GETHOSTBYNAME_R) || defined(THREADSAFE_GETHOSTBYNAME)
+typedef struct hostent *GET_HOST_TMP;
+#define GET_HOST_BY_NAME(NAME, HP, ERR, TMP) \
+ { TMP = gethostbyname (NAME); (ERR) = h_errno; (HP) = TMP; }
+#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR, TMP) \
+ { TMP = gethostbyaddr ((ADDR), (ADDRLEN), (FAMILY)); (ERR) = h_errno; (HP) = TMP; }
+#else
+#ifdef _AIX /* XXX should have a feature test! */
+typedef struct {
+ struct hostent ent;
+ struct hostent_data data;
+} GET_HOST_TMP;
+#define GET_HOST_BY_NAME(NAME, HP, ERR, TMP) \
+ { \
+ (HP) = (gethostbyname_r((NAME), &TMP.ent, &TMP.data) \
+ ? 0 \
+ : &TMP.ent); \
+ (ERR) = h_errno; \
+ }
+/*
+#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR) \
+ { \
+ struct hostent my_h_ent; \
+ struct hostent_data my_h_ent_data; \
+ (HP) = (gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &my_h_ent, \
+ &my_h_ent_data) \
+ ? 0 \
+ : &my_h_ent); \
+ (ERR) = my_h_err; \
+ }
+*/
+#else
+#ifdef GETHOSTBYNAME_R_RETURNS_INT
+typedef struct {
+ struct hostent ent;
+ char buf[8192];
+} GET_HOST_TMP;
+#define GET_HOST_BY_NAME(NAME, HP, ERR, TMP) \
+ { \
+ struct hostent *my_hp = NULL; \
+ int my_h_err, my_ret; \
+ my_ret = gethostbyname_r((NAME), &TMP.ent, \
+ TMP.buf, sizeof (TMP.buf), &my_hp, \
+ &my_h_err); \
+ (HP) = (((my_ret != 0) || (my_hp != &TMP.ent)) \
+ ? 0 \
+ : &TMP.ent); \
+ (ERR) = my_h_err; \
+ }
+#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR, TMP) \
+ { \
+ struct hostent *my_hp; \
+ int my_h_err, my_ret; \
+ my_ret = gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &TMP.ent, \
+ TMP.buf, sizeof (TMP.buf), &my_hp, \
+ &my_h_err); \
+ (HP) = (((my_ret != 0) || (my_hp != &TMP.ent)) \
+ ? 0 \
+ : &TMP.ent); \
+ (ERR) = my_h_err; \
+ }
+#else
+typedef struct {
+ struct hostent ent;
+ char buf[8192];
+} GET_HOST_TMP;
+#define GET_HOST_BY_NAME(NAME, HP, ERR, TMP) \
+ { \
+ int my_h_err; \
+ (HP) = gethostbyname_r((NAME), &TMP.ent, \
+ TMP.buf, sizeof (TMP.buf), &my_h_err); \
+ (ERR) = my_h_err; \
+ }
+#define GET_HOST_BY_ADDR(ADDR, ADDRLEN, FAMILY, HP, ERR, TMP) \
+ { \
+ int my_h_err; \
+ (HP) = gethostbyaddr_r((ADDR), (ADDRLEN), (FAMILY), &TMP.ent, \
+ TMP.buf, sizeof (TMP.buf), &my_h_err); \
+ (ERR) = my_h_err; \
+ }
+#endif /* returns int? */
+#endif /* _AIX */
+#endif
+
+/* Now do the same for getservby* functions. */
+#ifndef HAVE_GETSERVBYNAME_R
+typedef struct servent *GET_SERV_TMP;
+#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR, TMP) \
+ (TMP = getservbyname (NAME, PROTO), (SP) = TMP, (ERR) = (SP) ? 0 : -1)
+#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR, TMP) \
+ (TMP = getservbyport (PORT, PROTO), (SP) = TMP, (ERR) = (SP) ? 0 : -1)
+#else
+#ifdef GETSERVBYNAME_R_RETURNS_INT
+typedef struct {
+ struct servent ent;
+ char buf[8192];
+} GET_SERV_TMP;
+#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR, TMP) \
+ { \
+ struct servent *my_sp; \
+ int my_s_err; \
+ (SP) = (getservbyname_r((NAME), (PROTO), &TMP.ent, \
+ TMP.buf, sizeof (TMP.buf), &my_sp, \
+ &my_s_err) \
+ ? 0 \
+ : &TMP.ent); \
+ (ERR) = my_s_err; \
+ }
+#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR, TMP) \
+ { \
+ struct servent *my_sp; \
+ int my_s_err; \
+ (SP) = (getservbyport_r((PORT), (PROTO), &TMP.ent, \
+ TMP.buf, sizeof (TMP.buf), &my_sp, \
+ &my_s_err) \
+ ? 0 \
+ : &TMP.ent); \
+ (ERR) = my_s_err; \
+ }
+#else
+/* returns ptr -- IRIX? */
+typedef struct {
+ struct servent ent;
+ char buf[8192];
+} GET_SERV_TMP;
+#define GET_SERV_BY_NAME(NAME, PROTO, SP, ERR, TMP) \
+ { \
+ (SP) = getservbyname_r((NAME), (PROTO), &TMP.ent, \
+ TMP.buf, sizeof (TMP.buf)); \
+ (ERR) = (SP) == NULL; \
+ }
+
+#define GET_SERV_BY_PORT(PORT, PROTO, SP, ERR, TMP) \
+ { \
+ struct servent *my_sp; \
+ my_sp = getservbyport_r((PORT), (PROTO), &TMP.ent, \
+ TMP.buf, sizeof (TMP.buf)); \
+ (SP) = my_sp; \
+ (ERR) = my_sp == 0; \
+ (ERR) = (ERR); /* avoid "unused" warning */ \
+ }
+#endif
+#endif
+
+#if defined(WRAP_GETADDRINFO) || defined(FAI_CACHE)
+static inline int
+system_getaddrinfo (const char *name, const char *serv,
+ const struct addrinfo *hint,
+ struct addrinfo **res)
{
- return k5_mutex_finish_init(&krb5int_fac.lock);
+ return getaddrinfo(name, serv, hint, res);
}
-void krb5int_fini_fac (void)
+static inline void
+system_freeaddrinfo (struct addrinfo *ai)
{
- k5_mutex_destroy(&krb5int_fac.lock);
+ freeaddrinfo(ai);
}
-extern int krb5int_call_thread_support_init(void);
-int krb5int_lock_fac (void)
+/* Note: Implementations written to RFC 2133 use size_t, while RFC
+ 2553 implementations use socklen_t, for the second parameter.
+
+ Mac OS X (10.2) and AIX 4.3.3 appear to be in the RFC 2133 camp,
+ but we don't have an autoconf test for that right now. */
+static inline int
+system_getnameinfo (const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen, char *serv, size_t servlen,
+ int flags)
+{
+ return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
+}
+#endif
+
+#if !defined (HAVE_GETADDRINFO) || defined(WRAP_GETADDRINFO) || defined(FAI_CACHE)
+
+#undef getaddrinfo
+#define getaddrinfo my_fake_getaddrinfo
+#undef freeaddrinfo
+#define freeaddrinfo my_fake_freeaddrinfo
+
+#endif
+
+#if !defined (HAVE_GETADDRINFO)
+
+#undef gai_strerror
+#define gai_strerror my_fake_gai_strerror
+
+#endif /* ! HAVE_GETADDRINFO */
+
+#if (!defined (HAVE_GETADDRINFO) || defined (WRAP_GETADDRINFO)) && defined(DEBUG_ADDRINFO)
+/* Some debug routines. */
+
+static const char *protoname (int p, char *buf) {
+#define X(N) if (p == IPPROTO_ ## N) return #N
+
+ X(TCP);
+ X(UDP);
+ X(ICMP);
+ X(IPV6);
+#ifdef IPPROTO_GRE
+ X(GRE);
+#endif
+ X(NONE);
+ X(RAW);
+#ifdef IPPROTO_COMP
+ X(COMP);
+#endif
+#ifdef IPPROTO_IGMP
+ X(IGMP);
+#endif
+
+ sprintf(buf, " %-2d", p);
+ return buf;
+}
+
+static const char *socktypename (int t, char *buf) {
+ switch (t) {
+ case SOCK_DGRAM: return "DGRAM";
+ case SOCK_STREAM: return "STREAM";
+ case SOCK_RAW: return "RAW";
+ case SOCK_RDM: return "RDM";
+ case SOCK_SEQPACKET: return "SEQPACKET";
+ }
+ sprintf(buf, " %-2d", t);
+ return buf;
+}
+
+static const char *familyname (int f, char *buf) {
+ switch (f) {
+ default:
+ sprintf(buf, "AF %d", f);
+ return buf;
+ case AF_INET: return "AF_INET";
+ case AF_INET6: return "AF_INET6";
+#ifdef AF_UNIX
+ case AF_UNIX: return "AF_UNIX";
+#endif
+ }
+}
+
+static void debug_dump_getaddrinfo_args (const char *name, const char *serv,
+ const struct addrinfo *hint)
+{
+ const char *sep;
+ fprintf(stderr,
+ "getaddrinfo(hostname %s, service %s,\n"
+ " hints { ",
+ name ? name : "(null)", serv ? serv : "(null)");
+ if (hint) {
+ char buf[30];
+ sep = "";
+#define Z(FLAG) if (hint->ai_flags & AI_##FLAG) fprintf(stderr, "%s%s", sep, #FLAG), sep = "|"
+ Z(CANONNAME);
+ Z(PASSIVE);
+#ifdef AI_NUMERICHOST
+ Z(NUMERICHOST);
+#endif
+ if (sep[0] == 0)
+ fprintf(stderr, "no-flags");
+ if (hint->ai_family)
+ fprintf(stderr, " %s", familyname(hint->ai_family, buf));
+ if (hint->ai_socktype)
+ fprintf(stderr, " SOCK_%s", socktypename(hint->ai_socktype, buf));
+ if (hint->ai_protocol)
+ fprintf(stderr, " IPPROTO_%s", protoname(hint->ai_protocol, buf));
+ } else
+ fprintf(stderr, "(null)");
+ fprintf(stderr, " }):\n");
+}
+
+static void debug_dump_error (int err)
+{
+ fprintf(stderr, "error %d: %s\n", err, gai_strerror(err));
+}
+
+static void debug_dump_addrinfos (const struct addrinfo *ai)
+{
+ int count = 0;
+ char buf[10];
+ fprintf(stderr, "addrinfos returned:\n");
+ while (ai) {
+ fprintf(stderr, "%p...", ai);
+ fprintf(stderr, " socktype=%s", socktypename(ai->ai_socktype, buf));
+ fprintf(stderr, " ai_family=%s", familyname(ai->ai_family, buf));
+ if (ai->ai_family != ai->ai_addr->sa_family)
+ fprintf(stderr, " sa_family=%s",
+ familyname(ai->ai_addr->sa_family, buf));
+ fprintf(stderr, "\n");
+ ai = ai->ai_next;
+ count++;
+ }
+ fprintf(stderr, "end addrinfos returned (%d)\n");
+}
+
+#endif
+
+#if !defined (HAVE_GETADDRINFO) || defined (WRAP_GETADDRINFO)
+
+static
+int getaddrinfo (const char *name, const char *serv,
+ const struct addrinfo *hint, struct addrinfo **result);
+
+static
+void freeaddrinfo (struct addrinfo *ai);
+
+#endif
+
+#if !defined (HAVE_GETADDRINFO)
+
+#define HAVE_FAKE_GETADDRINFO /* was not originally HAVE_GETADDRINFO */
+#define HAVE_GETADDRINFO
+#define NEED_FAKE_GETNAMEINFO
+#undef HAVE_GETNAMEINFO
+#define HAVE_GETNAMEINFO 1
+
+#undef getnameinfo
+#define getnameinfo my_fake_getnameinfo
+
+static
+char *gai_strerror (int code);
+
+#endif
+
+#if !defined (HAVE_GETADDRINFO)
+static
+int getnameinfo (const struct sockaddr *addr, socklen_t len,
+ char *host, socklen_t hostlen,
+ char *service, socklen_t servicelen,
+ int flags);
+#endif
+
+/* Fudge things on older gai implementations. */
+/* AIX 4.3.3 is based on RFC 2133; no AI_NUMERICHOST. */
+#ifndef AI_NUMERICHOST
+# define AI_NUMERICHOST 0
+#endif
+/* Partial RFC 2553 implementations may not have AI_ADDRCONFIG and
+ friends, which RFC 3493 says are now part of the getaddrinfo
+ interface, and we'll want to use. */
+#ifndef AI_ADDRCONFIG
+# define AI_ADDRCONFIG 0
+#endif
+#ifndef AI_V4MAPPED
+# define AI_V4MAPPED 0
+#endif
+#ifndef AI_ALL
+# define AI_ALL 0
+#endif
+#ifndef AI_DEFAULT
+# define AI_DEFAULT (AI_ADDRCONFIG|AI_V4MAPPED)
+#endif
+
+#if defined(HAVE_FAKE_GETADDRINFO) || defined(FAI_CACHE)
+#define NEED_FAKE_GETADDRINFO
+#endif
+
+#if defined(NEED_FAKE_GETADDRINFO) || defined(WRAP_GETADDRINFO)
+#include <stdlib.h>
+#endif
+
+#ifdef NEED_FAKE_GETADDRINFO
+#include <string.h> /* for strspn */
+
+static inline int translate_h_errno (int h);
+
+static inline int fai_add_entry (struct addrinfo **result, void *addr,
+ int port, const struct addrinfo *template)
+{
+ struct addrinfo *n = malloc (sizeof (struct addrinfo));
+ if (n == 0)
+ return EAI_MEMORY;
+ if (template->ai_family != AF_INET
+#ifdef KRB5_USE_INET6
+ && template->ai_family != AF_INET6
+#endif
+ )
+ return EAI_FAMILY;
+ *n = *template;
+ if (template->ai_family == AF_INET) {
+ struct sockaddr_in *sin4;
+ sin4 = malloc (sizeof (struct sockaddr_in));
+ if (sin4 == 0)
+ return EAI_MEMORY;
+ memset (sin4, 0, sizeof (struct sockaddr_in)); /* for sin_zero */
+ n->ai_addr = (struct sockaddr *) sin4;
+ sin4->sin_family = AF_INET;
+ sin4->sin_addr = *(struct in_addr *)addr;
+ sin4->sin_port = port;
+#ifdef HAVE_SA_LEN
+ sin4->sin_len = sizeof (struct sockaddr_in);
+#endif
+ }
+#ifdef KRB5_USE_INET6
+ if (template->ai_family == AF_INET6) {
+ struct sockaddr_in6 *sin6;
+ sin6 = malloc (sizeof (struct sockaddr_in6));
+ if (sin6 == 0)
+ return EAI_MEMORY;
+ memset (sin6, 0, sizeof (struct sockaddr_in6)); /* for sin_zero */
+ n->ai_addr = (struct sockaddr *) sin6;
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_addr = *(struct in6_addr *)addr;
+ sin6->sin6_port = port;
+#ifdef HAVE_SA_LEN
+ sin6->sin6_len = sizeof (struct sockaddr_in6);
+#endif
+ }
+#endif
+ n->ai_next = *result;
+ *result = n;
+ return 0;
+}
+
+#ifdef FAI_CACHE
+/* fake addrinfo cache entries */
+#define CACHE_ENTRY_LIFETIME 15 /* seconds */
+
+static void plant_face (const char *name, struct face *entry)
+{
+ entry->name = strdup(name);
+ if (entry->name == NULL)
+ /* @@ Wastes memory. */
+ return;
+ k5_mutex_assert_locked(&krb5int_fac.lock);
+ entry->next = krb5int_fac.data;
+ entry->expiration = time(0) + CACHE_ENTRY_LIFETIME;
+ krb5int_fac.data = entry;
+#ifdef DEBUG_ADDRINFO
+ printf("added cache entry '%s' at %p: %d ipv4, %d ipv6; expire %d\n",
+ name, entry, entry->naddrs4, entry->naddrs6, entry->expiration);
+#endif
+}
+
+static int find_face (const char *name, struct face **entry)
+{
+ struct face *fp, **fpp;
+ time_t now = time(0);
+
+ /* First, scan for expired entries and free them.
+ (Future improvement: Integrate these two loops.) */
+#ifdef DEBUG_ADDRINFO
+ printf("scanning cache at %d for '%s'...\n", now, name);
+#endif
+ k5_mutex_assert_locked(&krb5int_fac.lock);
+ for (fpp = &krb5int_fac.data; *fpp; ) {
+ fp = *fpp;
+#ifdef DEBUG_ADDRINFO
+ printf(" checking expiration time of @%p: %d\n",
+ fp, fp->expiration);
+#endif
+ if (fp->expiration < now) {
+#ifdef DEBUG_ADDRINFO
+ printf("\texpiring cache entry\n");
+#endif
+ free(fp->name);
+ free(fp->canonname);
+ free(fp->addrs4);
+ free(fp->addrs6);
+ *fpp = fp->next;
+ free(fp);
+ /* Stay at this point in the list, and check again. */
+ } else
+ /* Move forward. */
+ fpp = &(*fpp)->next;
+ }
+
+ for (fp = krb5int_fac.data; fp; fp = fp->next) {
+#ifdef DEBUG_ADDRINFO
+ printf(" comparing entry @%p\n", fp);
+#endif
+ if (!strcasecmp(fp->name, name)) {
+#ifdef DEBUG_ADDRINFO
+ printf("\tMATCH!\n");
+#endif
+ *entry = fp;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#endif
+
+static int krb5int_lock_fac(void), krb5int_unlock_fac(void);
+
+static inline int fai_add_hosts_by_name (const char *name,
+ struct addrinfo *template,
+ int portnum, int flags,
+ struct addrinfo **result)
+{
+#ifdef FAI_CACHE
+
+ struct face *ce;
+ int i, r, err;
+
+ err = krb5int_lock_fac();
+ if (err) {
+ errno = err;
+ return EAI_SYSTEM;
+ }
+ if (!find_face(name, &ce)) {
+ struct addrinfo myhints = { 0 }, *ai, *ai2;
+ int i4, i6, aierr;
+
+#ifdef DEBUG_ADDRINFO
+ printf("looking up new data for '%s'...\n", name);
+#endif
+ myhints.ai_socktype = SOCK_STREAM;
+ myhints.ai_flags = AI_CANONNAME;
+ /* Don't set ai_family -- we want to cache all address types,
+ because the next lookup may not use the same constraints as
+ the current one. We *could* cache them separately, so that
+ we never have to look up an IPv6 address if we are always
+ asked for IPv4 only, but let's deal with that later, if we
+ have to. */
+ /* Try NULL for the service for now.
+
+ It would be nice to use the requested service name, and not
+ have to patch things up, but then we'd be doing multiple
+ queries for the same host when we get different services.
+ We were using "telnet" for a little more confidence that
+ getaddrinfo would heed the hints to only give us stream
+ socket types (with no socket type and null service name, we
+ might get stream *and* dgram *and* raw, for each address,
+ or only raw). The RFC 3493 description of ai_socktype
+ sometimes associates it with the specified service,
+ sometimes not.
+
+ But on Mac OS X (10.3, 10.4) they've "extended" getaddrinfo
+ to make SRV RR queries. (Please, somebody, show me
+ something in the specs that actually supports this? RFC
+ 3493 says nothing about it, but it does say getaddrinfo is
+ the new way to look up hostnames. RFC 2782 says SRV
+ records should *not* be used unless the application
+ protocol spec says to do so. The Telnet spec does not say
+ to do it.) And then they complain when our code
+ "unexpectedly" seems to use this "extension" in cases where
+ they don't want it to be used.
+
+ Fortunately, it appears that if we specify ai_socktype as
+ SOCK_STREAM and use a null service name, we only get one
+ copy of each address on all the platforms I've tried,
+ although it may not have ai_socktype filled in properly.
+ So, we'll fudge it with that for now. */
+ aierr = system_getaddrinfo(name, NULL, &myhints, &ai);
+ if (aierr) {
+ krb5int_unlock_fac();
+ return aierr;
+ }
+ ce = malloc(sizeof(struct face));
+ memset(ce, 0, sizeof(*ce));
+ ce->expiration = time(0) + 30;
+ for (ai2 = ai; ai2; ai2 = ai2->ai_next) {
+#ifdef DEBUG_ADDRINFO
+ printf(" found an address in family %d...\n", ai2->ai_family);
+#endif
+ switch (ai2->ai_family) {
+ case AF_INET:
+ ce->naddrs4++;
+ break;
+ case AF_INET6:
+ ce->naddrs6++;
+ break;
+ default:
+ break;
+ }
+ }
+ ce->addrs4 = calloc(ce->naddrs4, sizeof(*ce->addrs4));
+ if (ce->addrs4 == NULL && ce->naddrs4 != 0) {
+ krb5int_unlock_fac();
+ system_freeaddrinfo(ai);
+ return EAI_MEMORY;
+ }
+ ce->addrs6 = calloc(ce->naddrs6, sizeof(*ce->addrs6));
+ if (ce->addrs6 == NULL && ce->naddrs6 != 0) {
+ krb5int_unlock_fac();
+ free(ce->addrs4);
+ system_freeaddrinfo(ai);
+ return EAI_MEMORY;
+ }
+ for (ai2 = ai, i4 = i6 = 0; ai2; ai2 = ai2->ai_next) {
+ switch (ai2->ai_family) {
+ case AF_INET:
+ ce->addrs4[i4++] = ((struct sockaddr_in *)ai2->ai_addr)->sin_addr;
+ break;
+ case AF_INET6:
+ ce->addrs6[i6++] = ((struct sockaddr_in6 *)ai2->ai_addr)->sin6_addr;
+ break;
+ default:
+ break;
+ }
+ }
+ ce->canonname = ai->ai_canonname ? strdup(ai->ai_canonname) : 0;
+ system_freeaddrinfo(ai);
+ plant_face(name, ce);
+ }
+ template->ai_family = AF_INET6;
+ template->ai_addrlen = sizeof(struct sockaddr_in6);
+ for (i = 0; i < ce->naddrs6; i++) {
+ r = fai_add_entry (result, &ce->addrs6[i], portnum, template);
+ if (r) {
+ krb5int_unlock_fac();
+ return r;
+ }
+ }
+ template->ai_family = AF_INET;
+ template->ai_addrlen = sizeof(struct sockaddr_in);
+ for (i = 0; i < ce->naddrs4; i++) {
+ r = fai_add_entry (result, &ce->addrs4[i], portnum, template);
+ if (r) {
+ krb5int_unlock_fac();
+ return r;
+ }
+ }
+ if (*result && (flags & AI_CANONNAME))
+ (*result)->ai_canonname = (ce->canonname
+ ? strdup(ce->canonname)
+ : NULL);
+ krb5int_unlock_fac();
+ return 0;
+
+#else
+
+ struct hostent *hp;
+ int i, r;
+ int herr;
+ GET_HOST_TMP htmp;
+
+ GET_HOST_BY_NAME (name, hp, herr, htmp);
+ if (hp == 0)
+ return translate_h_errno (herr);
+ for (i = 0; hp->h_addr_list[i]; i++) {
+ r = fai_add_entry (result, hp->h_addr_list[i], portnum, template);
+ if (r)
+ return r;
+ }
+ if (*result && (flags & AI_CANONNAME))
+ (*result)->ai_canonname = strdup (hp->h_name);
+ return 0;
+
+#endif
+}
+
+static inline void
+fake_freeaddrinfo (struct addrinfo *ai)
+{
+ struct addrinfo *next;
+ while (ai) {
+ next = ai->ai_next;
+ if (ai->ai_canonname)
+ free (ai->ai_canonname);
+ if (ai->ai_addr)
+ free (ai->ai_addr);
+ free (ai);
+ ai = next;
+ }
+}
+
+static inline int
+fake_getaddrinfo (const char *name, const char *serv,
+ const struct addrinfo *hint, struct addrinfo **result)
+{
+ struct addrinfo *res = 0;
+ int ret;
+ int port = 0, socktype;
+ int flags;
+ struct addrinfo template;
+
+#ifdef DEBUG_ADDRINFO
+ debug_dump_getaddrinfo_args(name, serv, hint);
+#endif
+
+ if (hint != 0) {
+ if (hint->ai_family != 0 && hint->ai_family != AF_INET)
+ return EAI_NODATA;
+ socktype = hint->ai_socktype;
+ flags = hint->ai_flags;
+ } else {
+ socktype = 0;
+ flags = 0;
+ }
+
+ if (serv) {
+ size_t numlen = strspn (serv, "0123456789");
+ if (serv[numlen] == '\0') {
+ /* pure numeric */
+ unsigned long p = strtoul (serv, 0, 10);
+ if (p == 0 || p > 65535)
+ return EAI_NONAME;
+ port = htons (p);
+ } else {
+ struct servent *sp;
+ int try_dgram_too = 0, s_err;
+ GET_SERV_TMP stmp;
+
+ if (socktype == 0) {
+ try_dgram_too = 1;
+ socktype = SOCK_STREAM;
+ }
+ try_service_lookup:
+ GET_SERV_BY_NAME(serv, socktype == SOCK_STREAM ? "tcp" : "udp",
+ sp, s_err, stmp);
+ if (sp == 0) {
+ if (try_dgram_too) {
+ socktype = SOCK_DGRAM;
+ goto try_service_lookup;
+ }
+ return EAI_SERVICE;
+ }
+ port = sp->s_port;
+ }
+ }
+
+ if (name == 0) {
+ name = (flags & AI_PASSIVE) ? "0.0.0.0" : "127.0.0.1";
+ flags |= AI_NUMERICHOST;
+ }
+
+ template.ai_family = AF_INET;
+ template.ai_addrlen = sizeof (struct sockaddr_in);
+ template.ai_socktype = socktype;
+ template.ai_protocol = 0;
+ template.ai_flags = 0;
+ template.ai_canonname = 0;
+ template.ai_next = 0;
+ template.ai_addr = 0;
+
+ /* If NUMERICHOST is set, parse a numeric address.
+ If it's not set, don't accept such names. */
+ if (flags & AI_NUMERICHOST) {
+ struct in_addr addr4;
+#if 0
+ ret = inet_aton (name, &addr4);
+ if (ret)
+ return EAI_NONAME;
+#else
+ addr4.s_addr = inet_addr (name);
+ if (addr4.s_addr == 0xffffffff || addr4.s_addr == -1)
+ /* 255.255.255.255 or parse error, both bad */
+ return EAI_NONAME;
+#endif
+ ret = fai_add_entry (&res, &addr4, port, &template);
+ } else {
+ ret = fai_add_hosts_by_name (name, &template, port, flags,
+ &res);
+ }
+
+ if (ret && ret != NO_ADDRESS) {
+ fake_freeaddrinfo (res);
+ return ret;
+ }
+ if (res == 0)
+ return NO_ADDRESS;
+ *result = res;
+ return 0;
+}
+
+#ifdef NEED_FAKE_GETNAMEINFO
+static inline int
+fake_getnameinfo (const struct sockaddr *sa, socklen_t len,
+ char *host, socklen_t hostlen,
+ char *service, socklen_t servicelen,
+ int flags)
+{
+ struct hostent *hp;
+ const struct sockaddr_in *sinp;
+ struct servent *sp;
+ size_t hlen, slen;
+
+ if (sa->sa_family != AF_INET) {
+ return EAI_FAMILY;
+ }
+ sinp = (const struct sockaddr_in *) sa;
+
+ hlen = hostlen;
+ if (hostlen < 0 || hlen != hostlen) {
+ errno = EINVAL;
+ return EAI_SYSTEM;
+ }
+ slen = servicelen;
+ if (servicelen < 0 || slen != servicelen) {
+ errno = EINVAL;
+ return EAI_SYSTEM;
+ }
+
+ if (host) {
+ if (flags & NI_NUMERICHOST) {
+#if (defined(__GNUC__) && defined(__mips__)) || 1 /* thread safety always */
+ /* The inet_ntoa call, passing a struct, fails on IRIX 6.5
+ using gcc 2.95; we get back "0.0.0.0". Since this in a
+ configuration still important at Athena, here's the
+ workaround, which also happens to be thread-safe.... */
+ const unsigned char *uc;
+ char tmpbuf[20];
+ numeric_host:
+ uc = (const unsigned char *) &sinp->sin_addr;
+ sprintf(tmpbuf, "%d.%d.%d.%d", uc[0], uc[1], uc[2], uc[3]);
+ strncpy(host, tmpbuf, hlen);
+#else
+ char *p;
+ numeric_host:
+ p = inet_ntoa (sinp->sin_addr);
+ strncpy (host, p, hlen);
+#endif
+ } else {
+ int herr;
+ GET_HOST_TMP htmp;
+
+ GET_HOST_BY_ADDR((const char *) &sinp->sin_addr,
+ sizeof (struct in_addr),
+ sa->sa_family, hp, herr, htmp);
+ if (hp == 0) {
+ if (herr == NO_ADDRESS && !(flags & NI_NAMEREQD)) /* ??? */
+ goto numeric_host;
+ return translate_h_errno (herr);
+ }
+ /* According to the Open Group spec, getnameinfo can
+ silently truncate, but must still return a
+ null-terminated string. */
+ strncpy (host, hp->h_name, hlen);
+ }
+ host[hostlen-1] = 0;
+ }
+
+ if (service) {
+ if (flags & NI_NUMERICSERV) {
+ char numbuf[10];
+ int port;
+ numeric_service:
+ port = ntohs (sinp->sin_port);
+ if (port < 0 || port > 65535)
+ return EAI_FAIL;
+ sprintf (numbuf, "%d", port);
+ strncpy (service, numbuf, slen);
+ } else {
+ int serr;
+ GET_SERV_TMP stmp;
+
+ GET_SERV_BY_PORT(sinp->sin_port,
+ (flags & NI_DGRAM) ? "udp" : "tcp",
+ sp, serr, stmp);
+ if (sp == 0)
+ goto numeric_service;
+ strncpy (service, sp->s_name, slen);
+ }
+ service[servicelen-1] = 0;
+ }
+
+ return 0;
+}
+#endif
+
+#if defined(HAVE_FAKE_GETADDRINFO) || defined(NEED_FAKE_GETNAMEINFO)
+
+static inline
+char *gai_strerror (int code)
+{
+ switch (code) {
+ case EAI_ADDRFAMILY: return "address family for nodename not supported";
+ case EAI_AGAIN: return "temporary failure in name resolution";
+ case EAI_BADFLAGS: return "bad flags to getaddrinfo/getnameinfo";
+ case EAI_FAIL: return "non-recoverable failure in name resolution";
+ case EAI_FAMILY: return "ai_family not supported";
+ case EAI_MEMORY: return "out of memory";
+ case EAI_NODATA: return "no address associated with hostname";
+ case EAI_NONAME: return "name does not exist";
+ case EAI_SERVICE: return "service name not supported for specified socket type";
+ case EAI_SOCKTYPE: return "ai_socktype not supported";
+ case EAI_SYSTEM: return strerror (errno);
+ default: return "bogus getaddrinfo error?";
+ }
+}
+#endif
+
+static inline int translate_h_errno (int h)
+{
+ switch (h) {
+ case 0:
+ return 0;
+#ifdef NETDB_INTERNAL
+ case NETDB_INTERNAL:
+ if (errno == ENOMEM)
+ return EAI_MEMORY;
+ return EAI_SYSTEM;
+#endif
+ case HOST_NOT_FOUND:
+ return EAI_NONAME;
+ case TRY_AGAIN:
+ return EAI_AGAIN;
+ case NO_RECOVERY:
+ return EAI_FAIL;
+ case NO_DATA:
+#if NO_DATA != NO_ADDRESS
+ case NO_ADDRESS:
+#endif
+ return EAI_NODATA;
+ default:
+ return EAI_SYSTEM;
+ }
+}
+
+#if defined(HAVE_FAKE_GETADDRINFO) || defined(FAI_CACHE)
+static inline
+int getaddrinfo (const char *name, const char *serv,
+ const struct addrinfo *hint, struct addrinfo **result)
+{
+ return fake_getaddrinfo(name, serv, hint, result);
+}
+
+static inline
+void freeaddrinfo (struct addrinfo *ai)
+{
+ fake_freeaddrinfo(ai);
+}
+
+#ifdef NEED_FAKE_GETNAMEINFO
+static inline
+int getnameinfo (const struct sockaddr *sa, socklen_t len,
+ char *host, socklen_t hostlen,
+ char *service, socklen_t servicelen,
+ int flags)
+{
+ return fake_getnameinfo(sa, len, host, hostlen, service, servicelen,
+ flags);
+}
+#endif /* NEED_FAKE_GETNAMEINFO */
+#endif /* HAVE_FAKE_GETADDRINFO */
+#endif /* NEED_FAKE_GETADDRINFO */
+
+
+#ifdef WRAP_GETADDRINFO
+
+static inline
+int
+getaddrinfo (const char *name, const char *serv, const struct addrinfo *hint,
+ struct addrinfo **result)
+{
+ int aierr;
+#if defined(_AIX) || defined(COPY_FIRST_CANONNAME)
+ struct addrinfo *ai;
+#endif
+#ifdef NUMERIC_SERVICE_BROKEN
+ int service_is_numeric = 0;
+ int service_port = 0;
+ int socket_type = 0;
+#endif
+
+#ifdef DEBUG_ADDRINFO
+ debug_dump_getaddrinfo_args(name, serv, hint);
+#endif
+
+#ifdef NUMERIC_SERVICE_BROKEN
+ /* AIX 4.3.3 is broken. (Or perhaps out of date?)
+
+ If a numeric service is provided, and it doesn't correspond to
+ a known service name for tcp or udp (as appropriate), an error
+ code (for "host not found") is returned. If the port maps to a
+ known service for both udp and tcp, all is well. */
+ if (serv && serv[0] && isdigit(serv[0])) {
+ unsigned long lport;
+ char *end;
+ lport = strtoul(serv, &end, 10);
+ if (!*end) {
+ if (lport > 65535)
+ return EAI_SOCKTYPE;
+ service_is_numeric = 1;
+ service_port = htons(lport);
+#ifdef AI_NUMERICSERV
+ if (hint && hint->ai_flags & AI_NUMERICSERV)
+ serv = "9";
+ else
+#endif
+ serv = "discard"; /* defined for both udp and tcp */
+ if (hint)
+ socket_type = hint->ai_socktype;
+ }
+ }
+#endif
+
+ aierr = system_getaddrinfo (name, serv, hint, result);
+ if (aierr || *result == 0) {
+#ifdef DEBUG_ADDRINFO
+ debug_dump_error(aierr);
+#endif
+ return aierr;
+ }
+
+ /* Linux libc version 6 (libc-2.2.4.so on Debian) is broken.
+
+ RFC 2553 says that when AI_CANONNAME is set, the ai_canonname
+ flag of the first returned structure has the canonical name of
+ the host. Instead, GNU libc sets ai_canonname in each returned
+ structure to the name that the corresponding address maps to,
+ if any, or a printable numeric form.
+
+ RFC 2553 bis and the new Open Group spec say that field will be
+ the canonical name if it can be determined, otherwise, the
+ provided hostname or a copy of it.
+
+ IMNSHO, "canonical name" means CNAME processing and not PTR
+ processing, but I can see arguing it. Using the numeric form
+ when that's not the form provided is just wrong. So, let's fix
+ it.
+
+ The glibc 2.2.5 sources indicate that the canonical name is
+ *not* allocated separately, it's just some extra storage tacked
+ on the end of the addrinfo structure. So, let's try this
+ approach: If getaddrinfo sets ai_canonname, we'll replace the
+ *first* one with allocated storage, and free up that pointer in
+ freeaddrinfo if it's set; the other ai_canonname fields will be
+ left untouched. And we'll just pray that the application code
+ won't mess around with the list structure; if we start doing
+ that, we'll have to start replacing and freeing all of the
+ ai_canonname fields.
+
+ Ref: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=133668 .
+
+ Since it's dependent on the target hostname, it's hard to check
+ for at configure time. Always do it on Linux for now. When
+ they get around to fixing it, add a compile-time or run-time
+ check for the glibc version in use.
+
+ Some Windows documentation says that even when AI_CANONNAME is
+ set, the returned ai_canonname field can be null. The NetBSD
+ 1.5 implementation also does this, if the input hostname is a
+ numeric host address string. That case isn't handled well at
+ the moment.
+
+ Libc version 5 didn't have getaddrinfo at all. */
+
+#ifdef COPY_FIRST_CANONNAME
+ /*
+ * This code must *always* return an error, return a null
+ * ai_canonname, or return an ai_canonname allocated here using
+ * malloc, so that freeaddrinfo can always free a non-null
+ * ai_canonname. Note that it really doesn't matter if the
+ * AI_CANONNAME flag was set.
+ */
+ ai = *result;
+ if (ai->ai_canonname) {
+ struct hostent *hp;
+ const char *name2 = 0;
+ int i, herr;
+ GET_HOST_TMP htmp;
+
+ /*
+ * Current versions of GET_HOST_BY_NAME will fail if the
+ * target hostname has IPv6 addresses only. Make sure it
+ * fails fairly cleanly.
+ */
+ GET_HOST_BY_NAME (name, hp, herr, htmp);
+ if (hp == 0) {
+ /*
+ * This case probably means it's an IPv6-only name. If
+ * ai_canonname is a numeric address, get rid of it.
+ */
+ if (ai->ai_canonname && strchr(ai->ai_canonname, ':'))
+ ai->ai_canonname = 0;
+ name2 = ai->ai_canonname ? ai->ai_canonname : name;
+ } else {
+ /* Sometimes gethostbyname will be directed to /etc/hosts
+ first, and sometimes that file will have entries with
+ the unqualified name first. So take the first entry
+ that looks like it could be a FQDN. */
+ for (i = 0; hp->h_aliases[i]; i++) {
+ if (strchr(hp->h_aliases[i], '.') != 0) {
+ name2 = hp->h_aliases[i];
+ break;
+ }
+ }
+ /* Give up, just use the first name (h_name ==
+ h_aliases[0] on all systems I've seen). */
+ if (hp->h_aliases[i] == 0)
+ name2 = hp->h_name;
+ }
+
+ ai->ai_canonname = strdup(name2);
+ if (name2 != 0 && ai->ai_canonname == 0) {
+ system_freeaddrinfo(ai);
+ *result = 0;
+#ifdef DEBUG_ADDRINFO
+ debug_dump_error(EAI_MEMORY);
+#endif
+ return EAI_MEMORY;
+ }
+ /* Zap the remaining ai_canonname fields glibc fills in, in
+ case the application messes around with the list
+ structure. */
+ while ((ai = ai->ai_next) != NULL)
+ ai->ai_canonname = 0;
+ }
+#endif
+
+#ifdef NUMERIC_SERVICE_BROKEN
+ if (service_port != 0) {
+ for (ai = *result; ai; ai = ai->ai_next) {
+ if (socket_type != 0 && ai->ai_socktype == 0)
+ /* Is this check actually needed? */
+ ai->ai_socktype = socket_type;
+ switch (ai->ai_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)ai->ai_addr)->sin_port = service_port;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = service_port;
+ break;
+ }
+ }
+ }
+#endif
+
+#ifdef _AIX
+ for (ai = *result; ai; ai = ai->ai_next) {
+ /* AIX 4.3.3 libc is broken. It doesn't set the family or len
+ fields of the sockaddr structures. Usually, sa_family is
+ zero, but I've seen it set to 1 in some cases also (maybe
+ just leftover from previous contents of the memory
+ block?). So, always override what libc returned. */
+ ai->ai_addr->sa_family = ai->ai_family;
+#ifdef HAVE_SA_LEN /* always true on AIX, actually */
+ ai->ai_addr->sa_len = ai->ai_addrlen;
+#endif
+ }
+#endif
+
+ /* Not dealt with currently:
+
+ - Some versions of GNU libc can lose some IPv4 addresses in
+ certain cases when multiple IPv4 and IPv6 addresses are
+ available. */
+
+#ifdef DEBUG_ADDRINFO
+ debug_dump_addrinfos(*result);
+#endif
+
+ return 0;
+}
+
+static inline
+void freeaddrinfo (struct addrinfo *ai)
+{
+#ifdef COPY_FIRST_CANONNAME
+ if (ai) {
+ free(ai->ai_canonname);
+ ai->ai_canonname = 0;
+ system_freeaddrinfo(ai);
+ }
+#else
+ system_freeaddrinfo(ai);
+#endif
+}
+#endif /* WRAP_GETADDRINFO */
+
+static int krb5int_lock_fac (void)
{
int err;
err = krb5int_call_thread_support_init();
@@ -67,7 +1324,35 @@ int krb5int_lock_fac (void)
return k5_mutex_lock(&krb5int_fac.lock);
}
-int krb5int_unlock_fac (void)
+static int krb5int_unlock_fac (void)
{
return k5_mutex_unlock(&krb5int_fac.lock);
}
+
+/* Some systems don't define in6addr_any. */
+const struct in6_addr krb5int_in6addr_any = IN6ADDR_ANY_INIT;
+
+int krb5int_getaddrinfo (const char *node, const char *service,
+ const struct addrinfo *hints,
+ struct addrinfo **aip)
+{
+ return getaddrinfo(node, service, hints, aip);
+}
+
+void krb5int_freeaddrinfo (struct addrinfo *ai)
+{
+ freeaddrinfo(ai);
+}
+
+const char *krb5int_gai_strerror(int err)
+{
+ return gai_strerror(err);
+}
+
+int krb5int_getnameinfo (const struct sockaddr *sa, socklen_t salen,
+ char *hbuf, size_t hbuflen,
+ char *sbuf, size_t sbuflen,
+ int flags)
+{
+ return getnameinfo(sa, salen, hbuf, hbuflen, sbuf, sbuflen, flags);
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/support/init-addrinfo.c b/usr/src/lib/gss_mechs/mech_krb5/support/init-addrinfo.c
new file mode 100644
index 0000000000..4c94dc7434
--- /dev/null
+++ b/usr/src/lib/gss_mechs/mech_krb5/support/init-addrinfo.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2004 by the Massachusetts Institute of Technology,
+ * Cambridge, MA, USA. All Rights Reserved.
+ *
+ * This software is being provided to you, the LICENSEE, by the
+ * Massachusetts Institute of Technology (M.I.T.) under the following
+ * license. By obtaining, using and/or copying this software, you agree
+ * that you have read, understood, and will comply with these terms and
+ * conditions:
+ *
+ * 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 or
+ * royalty is hereby granted, provided that you agree to comply with the
+ * following copyright notice and statements, including the disclaimer, and
+ * that the same appear on ALL copies of the software and documentation,
+ * including modifications that you make for internal use or for
+ * distribution:
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS
+ * OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not
+ * limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF
+ * MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
+ * THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
+ * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+ *
+ * The name of the Massachusetts Institute of Technology or M.I.T. may NOT
+ * be used in advertising or publicity pertaining to distribution of the
+ * software. Title to copyright in this software and any associated
+ * documentation shall at all times remain with M.I.T., and USER agrees to
+ * preserve same.
+ *
+ * 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.
+ */
+
+/* Stuff that needs initialization for fake-addrinfo.c.
+
+ Separated out, so that static linking against this library doesn't
+ require pulling in socket/nsl/whatever libraries for code not using
+ getaddrinfo. */
+
+#include "port-sockets.h"
+#include "socket-utils.h"
+#include "k5-platform.h"
+#include "k5-thread.h"
+
+#include <stdio.h> /* for sprintf */
+#include <errno.h>
+
+#define IMPLEMENT_FAKE_GETADDRINFO
+#include "fake-addrinfo.h"
+#include "cache-addrinfo.h"
+
+struct fac krb5int_fac = { K5_MUTEX_PARTIAL_INITIALIZER, 0 };
+
+int krb5int_init_fac (void)
+{
+ return k5_mutex_finish_init(&krb5int_fac.lock);
+}
+
+void krb5int_fini_fac (void)
+{
+ k5_mutex_destroy(&krb5int_fac.lock);
+}
diff --git a/usr/src/lib/gss_mechs/mech_krb5/support/plugins.c b/usr/src/lib/gss_mechs/mech_krb5/support/plugins.c
index ec7b116407..4a3a41d23b 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/support/plugins.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/support/plugins.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* util/support/plugins.c
*
@@ -29,6 +27,12 @@
* Plugin module support, and shims around dlopen/whatever.
*/
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
#include "k5-plugin.h"
#if USE_DLOPEN
#include <dlfcn.h>
@@ -462,20 +466,13 @@ krb5int_open_plugin_dirs (const char * const *dirnames,
} else {
/* load all plugins in each directory */
#ifndef _WIN32
- DIR *dir = NULL;
+ DIR *dir = opendir (dirnames[i]);
- if (!err) {
- dir = opendir(dirnames[i]);
- if (dir == NULL) {
- err = errno;
- Tprintf ("-> error %d/%s\n", err, strerror (err));
- }
- }
-
- while (!err) {
+ while (dir != NULL && !err) {
struct dirent *d = NULL;
char *filepath = NULL;
struct plugin_file_handle *handle = NULL;
+ int len;
d = readdir (dir);
if (d == NULL) { break; }
@@ -484,9 +481,13 @@ krb5int_open_plugin_dirs (const char * const *dirnames,
(strcmp (d->d_name, "..") == 0)) {
continue;
}
-
+
+ /* Solaris Kerberos: Only open files with a .so extension */
+ len = NAMELEN (d);
+ if (len < 3 || strcmp(".so", d->d_name + len - 3 ) != 0)
+ continue;
+
if (!err) {
- int len = NAMELEN (d);
filepath = malloc (dirnamelen + len + 1); /* NULL */
if (filepath == NULL) {
err = errno;
diff --git a/usr/src/lib/gss_mechs/mech_krb5/support/threads.c b/usr/src/lib/gss_mechs/mech_krb5/support/threads.c
index b03f4e6253..f81af831e4 100644
--- a/usr/src/lib/gss_mechs/mech_krb5/support/threads.c
+++ b/usr/src/lib/gss_mechs/mech_krb5/support/threads.c
@@ -1,9 +1,7 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* util/support/threads.c
*
- * Copyright 2004 by the Massachusetts Institute of Technology.
+ * Copyright 2004,2005,2006 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -32,8 +30,9 @@
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
-#include <k5-thread.h>
-#include <k5-platform.h>
+#include "k5-thread.h"
+#include "k5-platform.h"
+#include "supp-int.h"
MAKE_INIT_FUNCTION(krb5int_thread_support_init);
MAKE_FINI_FUNCTION(krb5int_thread_support_fini);
@@ -45,6 +44,11 @@ struct tsd_block { void *values[K5_KEY_MAX]; };
static struct tsd_block tsd_no_threads;
static unsigned char destructors_set[K5_KEY_MAX];
+int krb5int_pthread_loaded (void)
+{
+ return 0;
+}
+
#elif defined(_WIN32)
static DWORD tls_idx;
@@ -78,6 +82,11 @@ void krb5int_thread_detach_hook (void)
}
}
+/* Stub function not used on Windows. */
+int krb5int_pthread_loaded (void)
+{
+ return 0;
+}
#else /* POSIX threads */
/* Must support register/delete/register sequence, e.g., if krb5 is
@@ -108,6 +117,56 @@ struct tsd_block {
# pragma weak pthread_setspecific
# pragma weak pthread_key_create
# pragma weak pthread_key_delete
+# pragma weak pthread_create
+# pragma weak pthread_join
+static volatile int flag_pthread_loaded = -1;
+static void loaded_test_aux(void)
+{
+ if (flag_pthread_loaded == -1)
+ flag_pthread_loaded = 1;
+ else
+ /* Could we have been called twice? */
+ flag_pthread_loaded = 0;
+}
+static pthread_once_t loaded_test_once = PTHREAD_ONCE_INIT;
+int krb5int_pthread_loaded (void)
+{
+ int x = flag_pthread_loaded;
+ if (x != -1)
+ return x;
+ if (&pthread_getspecific == 0
+ || &pthread_setspecific == 0
+ || &pthread_key_create == 0
+ || &pthread_key_delete == 0
+ || &pthread_once == 0
+ || &pthread_mutex_lock == 0
+ || &pthread_mutex_unlock == 0
+ || &pthread_mutex_destroy == 0
+ || &pthread_mutex_init == 0
+ || &pthread_self == 0
+ || &pthread_equal == 0
+ /* Any program that's really multithreaded will have to be
+ able to create threads. */
+ || &pthread_create == 0
+ || &pthread_join == 0
+ /* Okay, all the interesting functions -- or stubs for them --
+ seem to be present. If we call pthread_once, does it
+ actually seem to cause the indicated function to get called
+ exactly one time? */
+ || pthread_once(&loaded_test_once, loaded_test_aux) != 0
+ || pthread_once(&loaded_test_once, loaded_test_aux) != 0
+ /* This catches cases where pthread_once does nothing, and
+ never causes the function to get called. That's a pretty
+ clear violation of the POSIX spec, but hey, it happens. */
+ || flag_pthread_loaded < 0) {
+ flag_pthread_loaded = 0;
+ return 0;
+ }
+ /* If we wanted to be super-paranoid, we could try testing whether
+ pthread_get/setspecific work, too. I don't know -- so far --
+ of any system with non-functional stubs for those. */
+ return flag_pthread_loaded;
+}
static struct tsd_block tsd_if_single;
# define GET_NO_PTHREAD_TSD() (&tsd_if_single)
#else
@@ -119,30 +178,36 @@ static void thread_termination(void *);
static void thread_termination (void *tptr)
{
- int i, pass, none_found;
- struct tsd_block *t = tptr;
-
- /* Make multiple passes in case, for example, a libkrb5 cleanup
- function wants to print out an error message, which causes
- com_err to allocate a thread-specific buffer, after we just
- freed up the old one.
-
- Shouldn't actually happen, if we're careful, but check just in
- case. */
-
- pass = 0;
- none_found = 0;
- while (pass < 4 && !none_found) {
- none_found = 1;
- for (i = 0; i < K5_KEY_MAX; i++) {
- if (destructors_set[i] && destructors[i] && t->values[i]) {
- void *v = t->values[i];
- t->values[i] = 0;
- (*destructors[i])(v);
- none_found = 0;
- }
- }
- }
+ int err = k5_mutex_lock(&key_lock);
+ if (err == 0) {
+ int i, pass, none_found;
+ struct tsd_block *t = tptr;
+
+ /* Make multiple passes in case, for example, a libkrb5 cleanup
+ function wants to print out an error message, which causes
+ com_err to allocate a thread-specific buffer, after we just
+ freed up the old one.
+
+ Shouldn't actually happen, if we're careful, but check just in
+ case. */
+
+ pass = 0;
+ none_found = 0;
+ while (pass < 4 && !none_found) {
+ none_found = 1;
+ for (i = 0; i < K5_KEY_MAX; i++) {
+ if (destructors_set[i] && destructors[i] && t->values[i]) {
+ void *v = t->values[i];
+ t->values[i] = 0;
+ (*destructors[i])(v);
+ none_found = 0;
+ }
+ }
+ }
+ free (t);
+ err = k5_mutex_unlock(&key_lock);
+ }
+
/* remove thread from global linked list */
}
@@ -211,9 +276,9 @@ int k5_setspecific (k5_key_t keynum, void *value)
/* add to global linked list */
/* t->next = 0; */
err = TlsSetValue(tls_idx, t);
- if (err) {
+ if (!err) {
free(t);
- return err;
+ return GetLastError();
}
}
@@ -307,12 +372,28 @@ int k5_key_delete (k5_key_t keynum)
/* XXX Memory leak here!
Need to destroy the associated data for all threads.
But watch for race conditions in case threads are going away too. */
+ assert(destructors_set[keynum] == 1);
+ destructors_set[keynum] = 0;
+ destructors[keynum] = 0;
LeaveCriticalSection(&key_lock);
#else /* POSIX */
- /* Not written yet. */
- abort();
+ {
+ int err;
+
+ /* XXX RESOURCE LEAK:
+
+ Need to destroy the allocated objects first! */
+
+ err = k5_mutex_lock(&key_lock);
+ if (err == 0) {
+ assert(destructors_set[keynum] == 1);
+ destructors_set[keynum] = 0;
+ destructors[keynum] = NULL;
+ k5_mutex_unlock(&key_lock);
+ }
+ }
#endif
@@ -324,13 +405,28 @@ int krb5int_call_thread_support_init (void)
return CALL_INIT_FUNCTION(krb5int_thread_support_init);
}
-extern int krb5int_init_fac(void);
-extern void krb5int_fini_fac(void);
+#include "cache-addrinfo.h"
+
+#ifdef DEBUG_THREADS_STATS
+#include <stdio.h>
+static FILE *stats_logfile;
+#endif
int krb5int_thread_support_init (void)
{
int err;
+#ifdef SHOW_INITFINI_FUNCS
+ printf("krb5int_thread_support_init\n");
+#endif
+
+#ifdef DEBUG_THREADS_STATS
+ /* stats_logfile = stderr; */
+ stats_logfile = fopen("/dev/tty", "w+");
+ if (stats_logfile == NULL)
+ stats_logfile = stderr;
+#endif
+
#ifndef ENABLE_THREADS
/* Nothing to do for TLS initialization. */
@@ -358,6 +454,10 @@ int krb5int_thread_support_init (void)
if (err)
return err;
+ err = krb5int_err_init();
+ if (err)
+ return err;
+
return 0;
}
@@ -366,6 +466,10 @@ void krb5int_thread_support_fini (void)
if (! INITIALIZER_RAN (krb5int_thread_support_init))
return;
+#ifdef SHOW_INITFINI_FUNCS
+ printf("krb5int_thread_support_fini\n");
+#endif
+
#ifndef ENABLE_THREADS
/* Do nothing. */
@@ -387,8 +491,127 @@ void krb5int_thread_support_fini (void)
#endif
+#ifdef DEBUG_THREADS_STATS
+ fflush(stats_logfile);
+ /* XXX Should close if not stderr, in case unloading library but
+ not exiting. */
+#endif
+
krb5int_fini_fac();
}
+
+#ifdef DEBUG_THREADS_STATS
+void KRB5_CALLCONV
+k5_mutex_lock_update_stats(k5_debug_mutex_stats *m,
+ k5_mutex_stats_tmp startwait)
+{
+ k5_debug_time_t now;
+ k5_debug_timediff_t tdiff, tdiff2;
+
+ now = get_current_time();
+ (void) krb5int_call_thread_support_init();
+ m->count++;
+ m->time_acquired = now;
+ tdiff = timediff(now, startwait);
+ tdiff2 = tdiff * tdiff;
+ if (m->count == 1 || m->lockwait.valmin > tdiff)
+ m->lockwait.valmin = tdiff;
+ if (m->count == 1 || m->lockwait.valmax < tdiff)
+ m->lockwait.valmax = tdiff;
+ m->lockwait.valsum += tdiff;
+ m->lockwait.valsqsum += tdiff2;
+}
+
+void KRB5_CALLCONV
+krb5int_mutex_unlock_update_stats(k5_debug_mutex_stats *m)
+{
+ k5_debug_time_t now = get_current_time();
+ k5_debug_timediff_t tdiff, tdiff2;
+ tdiff = timediff(now, m->time_acquired);
+ tdiff2 = tdiff * tdiff;
+ if (m->count == 1 || m->lockheld.valmin > tdiff)
+ m->lockheld.valmin = tdiff;
+ if (m->count == 1 || m->lockheld.valmax < tdiff)
+ m->lockheld.valmax = tdiff;
+ m->lockheld.valsum += tdiff;
+ m->lockheld.valsqsum += tdiff2;
+}
+
+#include <math.h>
+static double
+get_stddev(struct k5_timediff_stats sp, int count)
+{
+ long double mu, mu_squared, rho_squared;
+ mu = (long double) sp.valsum / count;
+ mu_squared = mu * mu;
+ /* SUM((x_i - mu)^2)
+ = SUM(x_i^2 - 2*mu*x_i + mu^2)
+ = SUM(x_i^2) - 2*mu*SUM(x_i) + N*mu^2
+
+ Standard deviation rho^2 = SUM(...) / N. */
+ rho_squared = (sp.valsqsum - 2 * mu * sp.valsum + count * mu_squared) / count;
+ return sqrt(rho_squared);
+}
+
+void KRB5_CALLCONV
+krb5int_mutex_report_stats(k5_mutex_t *m)
+{
+ char *p;
+
+ /* Tweak this to only record data on "interesting" locks. */
+ if (m->stats.count < 10)
+ return;
+ if (m->stats.lockwait.valsum < 10 * m->stats.count)
+ return;
+
+ p = strrchr(m->loc_created.filename, '/');
+ if (p == NULL)
+ p = m->loc_created.filename;
+ else
+ p++;
+ fprintf(stats_logfile, "mutex @%p: created at line %d of %s\n",
+ (void *) m, m->loc_created.lineno, p);
+ if (m->stats.count == 0)
+ fprintf(stats_logfile, "\tnever locked\n");
+ else {
+ double sd_wait, sd_hold;
+ sd_wait = get_stddev(m->stats.lockwait, m->stats.count);
+ sd_hold = get_stddev(m->stats.lockheld, m->stats.count);
+ fprintf(stats_logfile,
+ "\tlocked %d time%s; wait %lu/%f/%lu/%fus, hold %lu/%f/%lu/%fus\n",
+ m->stats.count, m->stats.count == 1 ? "" : "s",
+ (unsigned long) m->stats.lockwait.valmin,
+ (double) m->stats.lockwait.valsum / m->stats.count,
+ (unsigned long) m->stats.lockwait.valmax,
+ sd_wait,
+ (unsigned long) m->stats.lockheld.valmin,
+ (double) m->stats.lockheld.valsum / m->stats.count,
+ (unsigned long) m->stats.lockheld.valmax,
+ sd_hold);
+ }
+}
+#else
+/* On Windows, everything defined in the export list must be defined.
+ The UNIX systems where we're using the export list don't seem to
+ care. */
+#undef krb5int_mutex_lock_update_stats
+void KRB5_CALLCONV
+krb5int_mutex_lock_update_stats(k5_debug_mutex_stats *m,
+ k5_mutex_stats_tmp startwait)
+{
+}
+#undef krb5int_mutex_unlock_update_stats
+void KRB5_CALLCONV
+krb5int_mutex_unlock_update_stats(k5_debug_mutex_stats *m)
+{
+}
+#undef krb5int_mutex_report_stats
+void KRB5_CALLCONV
+krb5int_mutex_report_stats(k5_mutex_t *m)
+{
+}
+#endif
+
/* Mutex allocation functions, for use in plugins that may not know
what options a given set of libraries was compiled with. */
int KRB5_CALLCONV
diff --git a/usr/src/lib/krb5/kadm5/adb.h b/usr/src/lib/krb5/kadm5/adb.h
index de5650eb89..95a042c55e 100644
--- a/usr/src/lib/krb5/kadm5/adb.h
+++ b/usr/src/lib/krb5/kadm5/adb.h
@@ -1,33 +1,14 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
- * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ * Data Types for policy and principal information that
+ * exists in the respective databases.
*
- * Openvision retains the copyright to derivative works of
- * this source code. Do *NOT* create a derivative of this
- * source code before consulting with your legal department.
- * Do *NOT* integrate *ANY* of this source code into another
- * product before consulting with your legal department.
- *
- * For further information, read the top-level Openvision
- * copyright which is contained in the top-level MIT Kerberos
- * copyright.
- *
- * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
- *
- */
-
-
-/*
- * Data Types for policys, and principal information that
- * exist in the respective databases.
- *
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/adb.h,v 1.21 1998/02/14 02:34:09 tlyu Exp $
+ * $Header$
*
* This file was originally created with rpcgen.
* It has been hacked up since then.
@@ -104,6 +85,7 @@ typedef struct _osa_policy_ent_t {
typedef void (*osa_adb_iter_princ_func) (void *, osa_princ_ent_t);
typedef void (*osa_adb_iter_policy_func) (void *, osa_policy_ent_t);
+
/*
* Return Code (the rest are in adb_err.h)
diff --git a/usr/src/lib/krb5/kadm5/admin.h b/usr/src/lib/krb5/kadm5/admin.h
index 1494a6a1f6..90f582e843 100644
--- a/usr/src/lib/krb5/kadm5/admin.h
+++ b/usr/src/lib/krb5/kadm5/admin.h
@@ -6,7 +6,6 @@
#ifndef __KADM5_ADMIN_H__
#define __KADM5_ADMIN_H__
-#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
@@ -63,8 +62,8 @@ extern "C" {
#include <sys/types.h>
#include <rpc/types.h>
#include <rpc/rpc.h>
-#include <krb5.h>
#include <k5-int.h>
+#include <krb5.h>
#include <krb5/kdb.h>
#include <com_err.h>
#include <kadm5/kadm_err.h>
@@ -274,13 +273,6 @@ typedef struct _kadm5_policy_ent_t {
long policy_refcnt;
} kadm5_policy_ent_rec, *kadm5_policy_ent_t;
-#if 0 /************** Begin IFDEF'ed OUT *******************************/
-typedef struct __krb5_key_salt_tuple {
- krb5_enctype ks_enctype;
- krb5_int32 ks_salttype;
-} krb5_key_salt_tuple;
-#endif /**************** END IFDEF'ed OUT *******************************/
-
/*
* New types to indicate which protocol to use when sending
* password change requests
@@ -296,7 +288,6 @@ typedef enum {
typedef struct _kadm5_config_params {
long mask;
char * realm;
- char * profile;
int kadmind_port;
int kpasswd_port;
@@ -379,7 +370,7 @@ kadm5_get_cpw_host_srv_name(krb5_context context,
#if USE_KADM5_API_VERSION > 1
krb5_error_code kadm5_get_config_params(krb5_context context,
- char *kdcprofile, char *kdcenv,
+ int use_kdc_config,
kadm5_config_params *params_in,
kadm5_config_params *params_out);
@@ -404,7 +395,6 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass,
krb5_ui_4 api_version,
char **db_args,
void **server_handle);
-
kadm5_ret_t kadm5_init_with_password(char *client_name,
char *pass,
char *service_name,
diff --git a/usr/src/lib/krb5/kadm5/admin_xdr.h b/usr/src/lib/krb5/kadm5/admin_xdr.h
index 8eff0ca9f1..d3af4727e6 100644
--- a/usr/src/lib/krb5/kadm5/admin_xdr.h
+++ b/usr/src/lib/krb5/kadm5/admin_xdr.h
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
@@ -21,12 +19,13 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/admin_xdr.h,v 1.7 2001/07/25 19:02:29 epeisach Exp $
+ * $Header$
*
*/
#include <kadm5/admin.h>
#include "kadm_rpc.h"
+#include "server_internal.h"
bool_t xdr_ui_4(XDR *xdrs, krb5_ui_4 *objp);
bool_t xdr_nullstring(XDR *xdrs, char **objp);
@@ -79,3 +78,5 @@ bool_t xdr_krb5_int32(XDR *xdrs, krb5_int32 *objp);
bool_t xdr_krb5_enctype(XDR *xdrs, krb5_enctype *objp);
bool_t xdr_krb5_salttype(XDR *xdrs, krb5_int32 *objp);
bool_t xdr_krb5_keyblock(XDR *xdrs, krb5_keyblock *objp);
+bool_t xdr_krb5_key_data(XDR *xdrs, krb5_key_data *objp);
+bool_t xdr_osa_pw_hist_ent(XDR *xdrs, osa_pw_hist_ent *objp);
diff --git a/usr/src/lib/krb5/kadm5/alt_prof.c b/usr/src/lib/krb5/kadm5/alt_prof.c
index b76339b7a5..2469fe4562 100644
--- a/usr/src/lib/krb5/kadm5/alt_prof.c
+++ b/usr/src/lib/krb5/kadm5/alt_prof.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -53,9 +52,9 @@
/*
* alt_prof.c - Implement alternate profile file handling.
*/
-#include <k5-int.h>
+#include "k5-int.h"
#include <kadm5/admin.h>
-#include <adm_proto.h>
+#include "adm_proto.h"
#include <stdio.h>
#include <ctype.h>
#include <os-proto.h>
@@ -104,30 +103,50 @@ krb5_aprof_init(fname, envname, acontextp)
krb5_pointer *acontextp;
{
krb5_error_code kret;
- const_profile_filespec_t namelist[2];
profile_t profile;
-
- namelist[1] = (profile_filespec_t) NULL;
- profile = (profile_t) NULL;
- if (envname) {
- if ((namelist[0] = getenv(envname))) {
- kret = profile_init(namelist, &profile);
- if (kret)
- return kret;
- *acontextp = (krb5_pointer) profile;
- return 0;
- }
+ const char *kdc_config;
+ size_t krb5_config_len, kdc_config_len;
+ char *profile_path;
+ char **filenames;
+ int i;
+
+ kret = krb5_get_default_config_files (&filenames);
+ if (kret)
+ return kret;
+ krb5_config_len = 0;
+ for (i = 0; filenames[i] != NULL; i++)
+ krb5_config_len += strlen(filenames[i]) + 1;
+ if (i > 0)
+ krb5_config_len--;
+ if (envname == NULL
+ || (kdc_config = getenv(envname)) == NULL)
+ kdc_config = fname;
+ if (kdc_config == NULL)
+ kdc_config_len = 0;
+ else
+ kdc_config_len = strlen(kdc_config);
+ profile_path = malloc(2 + krb5_config_len + kdc_config_len);
+ if (profile_path == NULL) {
+ krb5_free_config_files(filenames);
+ return errno;
}
+ if (kdc_config_len)
+ strcpy(profile_path, kdc_config);
+ else
+ profile_path[0] = 0;
+ if (krb5_config_len)
+ for (i = 0; filenames[i] != NULL; i++) {
+ if (kdc_config_len || i)
+ strcat(profile_path, ":");
+ strcat(profile_path, filenames[i]);
+ }
+ krb5_free_config_files(filenames);
profile = (profile_t) NULL;
- if (fname) {
- kret = profile_init_path(fname, &profile);
- if (kret == ENOENT) {
- profile = 0;
- } else if (kret)
- return kret;
- *acontextp = (krb5_pointer) profile;
- return 0;
- }
+ kret = profile_init_path(profile_path, &profile);
+ free(profile_path);
+ if (kret)
+ return kret;
+ *acontextp = profile;
return 0;
}
@@ -387,11 +406,10 @@ krb5_aprof_finish(acontext)
* in params_in for which the mask is set will be re-assigned to newly copied
* versions, overwriting the old pointer value.
*/
-krb5_error_code kadm5_get_config_params(context, kdcprofile, kdcenv,
+krb5_error_code kadm5_get_config_params(context, use_kdc_config,
params_in, params_out)
krb5_context context;
- char *kdcprofile;
- char *kdcenv;
+ int use_kdc_config;
kadm5_config_params *params_in, *params_out;
{
char *filename;
@@ -404,7 +422,7 @@ krb5_error_code kadm5_get_config_params(context, kdcprofile, kdcenv,
kadm5_config_params params, empty_params;
krb5_error_code kret = 0;
- krb5_error_code dnsret = 1;
+ krb5_error_code dnsret = 1;
#ifdef KRB5_DNS_LOOKUP
char dns_host[MAX_DNS_NAMELEN];
@@ -429,22 +447,20 @@ krb5_error_code kadm5_get_config_params(context, kdcprofile, kdcenv,
params.realm = lrealm;
params.mask |= KADM5_CONFIG_REALM;
}
- if (params_in->mask & KADM5_CONFIG_PROFILE) {
- filename = params.profile = strdup(params_in->profile);
- if (params.profile)
- params.mask |= KADM5_CONFIG_PROFILE;
- envname = NULL;
+ /*
+ * XXX These defaults should to work on both client and
+ * server. kadm5_get_config_params can be implemented as a
+ * wrapper function in each library that provides correct
+ * defaults for NULL values.
+ */
+ if (use_kdc_config) {
+ filename = DEFAULT_KDC_PROFILE;
+ envname = KDC_PROFILE_ENV;
} else {
- /*
- * XXX These defaults should to work on both client and
- * server. kadm5_get_config_params can be implemented as a
- * wrapper function in each library that provides correct
- * defaults for NULL values.
- */
- filename = (kdcprofile) ? kdcprofile : DEFAULT_KDC_PROFILE;
- envname = (kdcenv) ? kdcenv : KDC_PROFILE_ENV;
- if (context->profile_secure == TRUE) envname = 0;
+ filename = DEFAULT_PROFILE_PATH;
+ envname = "KRB5_CONFIG";
}
+ if (context->profile_secure == TRUE) envname = 0;
kret = krb5_aprof_init(filename, envname, &aprofile);
if (kret)
@@ -671,7 +687,8 @@ krb5_error_code kadm5_get_config_params(context, kdcprofile, kdcenv,
params.stash_file = svalue;
}
- /*
+ /*
+ * Solaris Kerberos
* Get the value for maximum ticket lifetime.
* See SEAM documentation or the Bug ID 4184504
* We have changed the logic so that the entries are
@@ -1001,63 +1018,59 @@ kadm5_free_config_params(context, params)
kadm5_config_params *params;
{
if (params) {
- if (params->profile) {
- krb5_xfree(params->profile);
- params->profile = NULL;
- }
- if (params->dbname) {
- krb5_xfree(params->dbname);
- params->dbname = NULL;
- }
- if (params->mkey_name) {
- krb5_xfree(params->mkey_name);
- params->mkey_name = NULL;
- }
- if (params->stash_file) {
- krb5_xfree(params->stash_file);
- params->stash_file = NULL;
- }
- if (params->keysalts) {
- krb5_xfree(params->keysalts);
- params->keysalts = NULL;
- params->num_keysalts = 0;
- }
- if (params->admin_keytab) {
- free(params->admin_keytab);
- params->admin_keytab = NULL;
- }
- if (params->dict_file) {
- free(params->dict_file);
- params->dict_file = NULL;
- }
- if (params->acl_file) {
- free(params->acl_file);
- params->acl_file = NULL;
- }
- if (params->realm) {
- free(params->realm);
- params->realm = NULL;
- }
- if (params->admin_dbname) {
- free(params->admin_dbname);
- params->admin_dbname = NULL;
- }
- if (params->admin_lockfile) {
- free(params->admin_lockfile);
- params->admin_lockfile = NULL;
- }
- if (params->admin_server) {
- free(params->admin_server);
- params->admin_server = NULL;
- }
- if (params->kpasswd_server) {
- free(params->kpasswd_server);
- params->kpasswd_server = NULL;
- }
- if (params->iprop_polltime) {
- free(params->iprop_polltime);
- params->iprop_polltime = NULL;
- }
+ if (params->dbname) {
+ krb5_xfree(params->dbname);
+ params->dbname = NULL;
+ }
+ if (params->mkey_name) {
+ krb5_xfree(params->mkey_name);
+ params->mkey_name = NULL;
+ }
+ if (params->stash_file) {
+ krb5_xfree(params->stash_file);
+ params->stash_file = NULL;
+ }
+ if (params->keysalts) {
+ krb5_xfree(params->keysalts);
+ params->keysalts = NULL;
+ params->num_keysalts = 0;
+ }
+ if (params->admin_keytab) {
+ free(params->admin_keytab);
+ params->admin_keytab = NULL;
+ }
+ if (params->dict_file) {
+ free(params->dict_file);
+ params->dict_file = NULL;
+ }
+ if (params->acl_file) {
+ free(params->acl_file);
+ params->acl_file = NULL;
+ }
+ if (params->realm) {
+ free(params->realm);
+ params->realm = NULL;
+ }
+ if (params->admin_dbname) {
+ free(params->admin_dbname);
+ params->admin_dbname = NULL;
+ }
+ if (params->admin_lockfile) {
+ free(params->admin_lockfile);
+ params->admin_lockfile = NULL;
+ }
+ if (params->admin_server) {
+ free(params->admin_server);
+ params->admin_server = NULL;
+ }
+ if (params->kpasswd_server) {
+ free(params->kpasswd_server);
+ params->kpasswd_server = NULL;
+ }
+ if (params->iprop_polltime) {
+ free(params->iprop_polltime);
+ params->iprop_polltime = NULL;
+ }
}
return (0);
}
@@ -1077,8 +1090,7 @@ kadm5_get_admin_service_name(krb5_context ctx,
params_in.mask |= KADM5_CONFIG_REALM;
params_in.realm = realm_in;
- ret = kadm5_get_config_params(ctx, DEFAULT_PROFILE_PATH,
- "KRB5_CONFIG", &params_in, &params_out);
+ ret = kadm5_get_config_params(ctx, 0, &params_in, &params_out);
if (ret)
return ret;
@@ -1114,11 +1126,9 @@ err_params:
* alternate profile.
*/
krb5_error_code
-krb5_read_realm_params(kcontext, realm, kdcprofile, kdcenv, rparamp)
+krb5_read_realm_params(kcontext, realm, rparamp)
krb5_context kcontext;
char *realm;
- char *kdcprofile;
- char *kdcenv;
krb5_realm_params **rparamp;
{
char *filename;
@@ -1132,6 +1142,9 @@ krb5_read_realm_params(kcontext, realm, kdcprofile, kdcenv, rparamp)
krb5_boolean bvalue;
krb5_deltat dtvalue;
+ char *kdcprofile = 0;
+ char *kdcenv = 0;
+
krb5_error_code kret;
filename = (kdcprofile) ? kdcprofile : DEFAULT_KDC_PROFILE;
diff --git a/usr/src/lib/krb5/kadm5/chpass_util.c b/usr/src/lib/krb5/kadm5/chpass_util.c
index 18422e0924..d1c7039ddc 100644
--- a/usr/src/lib/krb5/kadm5/chpass_util.c
+++ b/usr/src/lib/krb5/kadm5/chpass_util.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -25,10 +24,6 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
- *
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/chpass_util.c,v 1.18.18.1 2000/05/19 22:24:14 raeburn Exp $
- *
- *
*/
@@ -43,6 +38,7 @@
#include "admin_internal.h"
#include <krb5.h>
+#include <strings.h>
#define string_text error_message
@@ -112,7 +108,7 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
} else { /* read the password */
krb5_context context;
- if ((code = (int) krb5_init_context(&context)) == 0) {
+ if ((code = (int) kadm5_init_krb5_context(&context)) == 0) {
pwsize = sizeof(buffer);
code = krb5_read_password(context, KADM5_PW_FIRST_PROMPT,
KADM5_PW_SECOND_PROMPT,
@@ -127,16 +123,16 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
memset(buffer, 0, sizeof(buffer));
#endif
if (code == KRB5_LIBOS_BADPWDMATCH) {
- strncpy(msg_ret, string_text(CHPASS_UTIL_NEW_PASSWORD_MISMATCH),
+ (void) strncpy(msg_ret, string_text(CHPASS_UTIL_NEW_PASSWORD_MISMATCH),
msg_len - 1);
msg_ret[msg_len - 1] = '\0';
return(code);
} else {
- 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),
+ (void) strncpy(msg_ret, error_message(code), msg_len - 1);
+ (void) strncat(msg_ret, " ", msg_len - 1);
+ (void) strncat(msg_ret, string_text(CHPASS_UTIL_WHILE_READING_PASSWORD),
msg_len - 1);
- strncat(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
+ (void) strncat(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
msg_len - 1);
msg_ret[msg_len - 1] = '\0';
return(code);
@@ -298,7 +294,7 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
(void) kadm5_free_principal_ent(lhandle, &princ_ent);
(void) kadm5_free_policy_ent(lhandle, &policy_ent);
return(code);
- } else {
+ } else {
/* We should never get here, but just in case ... */
sprintf(buffer, "%s %s", error_message(code),
diff --git a/usr/src/lib/krb5/kadm5/clnt/changepw.c b/usr/src/lib/krb5/kadm5/clnt/changepw.c
index 48d4d130aa..7d79d4ccba 100644
--- a/usr/src/lib/krb5/kadm5/clnt/changepw.c
+++ b/usr/src/lib/krb5/kadm5/clnt/changepw.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/changepw.c
@@ -33,24 +32,24 @@
*/
#define NEED_SOCKETS
-#include <krb5.h>
#include <k5-int.h>
#include <kadm5/admin.h>
#include <client_internal.h>
#include <gssapi/gssapi.h>
#include <gssapi_krb5.h>
#include <gssapiP_krb5.h>
+#include <krb5.h>
/* #include "adm_err.h" */
#include <stdio.h>
#include <errno.h>
-extern krb5_error_code krb5_mk_chpw_req(krb5_context context,
+extern krb5_error_code krb5int_mk_chpw_req(krb5_context context,
krb5_auth_context auth_context,
krb5_data *ap_req, char *passwd,
krb5_data *packet);
-extern krb5_error_code krb5_rd_chpw_rep(krb5_context context,
+extern krb5_error_code krb5int_rd_chpw_rep(krb5_context context,
krb5_auth_context auth_context,
krb5_data *packet, int *result_code,
krb5_data *result_data);
@@ -268,7 +267,7 @@ krb5_data *srvr_msg;
goto cleanup;
}
- if (code = krb5_mk_chpw_req(context, auth_context,
+ if (code = krb5int_mk_chpw_req(context, auth_context,
&ap_req, newpw, &chpw_req))
{
code = errno;
@@ -326,7 +325,7 @@ krb5_data *srvr_msg;
NULL, &remote_kaddr))
goto cleanup;
- if (code = krb5_rd_chpw_rep(context, auth_context, &chpw_rep,
+ if (code = krb5int_rd_chpw_rep(context, auth_context, &chpw_rep,
&local_result_code, srvr_msg))
goto cleanup;
diff --git a/usr/src/lib/krb5/kadm5/clnt/chpw.c b/usr/src/lib/krb5/kadm5/clnt/chpw.c
index 246dfc8dc9..543f6a51ab 100644
--- a/usr/src/lib/krb5/kadm5/clnt/chpw.c
+++ b/usr/src/lib/krb5/kadm5/clnt/chpw.c
@@ -1,140 +1,144 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include <string.h>
-#include <k5-int.h>
+#include "k5-int.h"
#include <kadm5/admin.h>
#include <client_internal.h>
-#include <auth_con.h>
+#include "auth_con.h"
#include <locale.h>
-/*
- * krb5_mk_chpw_req
- *
- * Generate a CHANGEPW request packet to send to a
- * password server.
- * The format of the packet used here is defined in the
- * Marc Horowitz Password change protocol document (1998)
- * (expired).
- * It is also defined in the latest kerberos passwd set/change
- * protocol IETF draft document by UMich, Cisco, and MS.
- */
-krb5_error_code KRB5_CALLCONV
-krb5_mk_chpw_req(context, auth_context, ap_req, passwd, packet)
-krb5_context context;
-krb5_auth_context auth_context;
-krb5_data *ap_req;
-char *passwd;
-krb5_data *packet;
+
+krb5_error_code
+krb5int_mk_chpw_req(
+ krb5_context context,
+ krb5_auth_context auth_context,
+ krb5_data *ap_req,
+ char *passwd,
+ krb5_data *packet)
{
- krb5_error_code ret = 0;
- krb5_data clearpw;
- krb5_data cipherpw;
- krb5_replay_data replay;
- char *ptr;
+ krb5_error_code ret = 0;
+ krb5_data clearpw;
+ krb5_data cipherpw;
+ krb5_replay_data replay;
+ char *ptr;
- cipherpw.data = NULL;
+ cipherpw.data = NULL;
- if (ret = krb5_auth_con_setflags(context, auth_context,
- KRB5_AUTH_CONTEXT_DO_SEQUENCE))
- goto cleanup;
+ if ((ret = krb5_auth_con_setflags(context, auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE)))
+ goto cleanup;
- clearpw.length = strlen(passwd);
- clearpw.data = passwd;
+ clearpw.length = strlen(passwd);
+ clearpw.data = passwd;
- if (ret = krb5_mk_priv(context, auth_context,
- &clearpw, &cipherpw, &replay))
- goto cleanup;
+ if ((ret = krb5_mk_priv(context, auth_context,
+ &clearpw, &cipherpw, &replay)))
+ goto cleanup;
- packet->length = 6 + ap_req->length + cipherpw.length;
- packet->data = (char *)malloc(packet->length);
- if (packet->data == NULL)
+ packet->length = 6 + ap_req->length + cipherpw.length;
+ packet->data = (char *) malloc(packet->length);
+ if (packet->data == NULL)
{
- ret = ENOMEM;
- goto cleanup;
+ ret = ENOMEM;
+ goto cleanup;
}
- ptr = packet->data;
+ ptr = packet->data;
- /* length */
- *ptr++ = (packet->length>>8) & 0xff;
- *ptr++ = packet->length & 0xff;
+ /* length */
- /*
- * version == 0x0001 big-endian
- * NOTE: when MS and MIT start supporting the latest
- * version of the passwd change protocol (v2),
- * this value will change to 2.
- */
- *ptr++ = 0;
- *ptr++ = 1;
+ *ptr++ = (packet->length>> 8) & 0xff;
+ *ptr++ = packet->length & 0xff;
- /* ap_req length, big-endian */
- *ptr++ = (ap_req->length>>8) & 0xff;
- *ptr++ = ap_req->length & 0xff;
+ /* version == 0x0001 big-endian
+ * NOTE: when MS and MIT start supporting the latest
+ * version of the passwd change protocol (v2),
+ * this value will change to 2.
+ */
+ *ptr++ = 0;
+ *ptr++ = 1;
- /* ap-req data */
- memcpy(ptr, ap_req->data, ap_req->length);
- ptr += ap_req->length;
+ /* ap_req length, big-endian */
- /* krb-priv of password */
- memcpy(ptr, cipherpw.data, cipherpw.length);
+ *ptr++ = (ap_req->length>>8) & 0xff;
+ *ptr++ = ap_req->length & 0xff;
-cleanup:
- if (cipherpw.data != NULL) /* allocated by krb5_mk_priv */
- free(cipherpw.data);
+ /* ap-req data */
+
+ memcpy(ptr, ap_req->data, ap_req->length);
+ ptr += ap_req->length;
+
+ /* krb-priv of password */
- return (ret);
+ memcpy(ptr, cipherpw.data, cipherpw.length);
+
+cleanup:
+ if(cipherpw.data != NULL) /* allocated by krb5_mk_priv */
+ free(cipherpw.data);
+
+ return(ret);
}
-/*
- * krb5_rd_chpw_rep
- *
- * Decode and parse the reply from the CHANGEPW request.
- */
-krb5_error_code KRB5_CALLCONV
-krb5_rd_chpw_rep(context, auth_context, packet, result_code, result_data)
-krb5_context context;
-krb5_auth_context auth_context;
-krb5_data *packet;
-int *result_code;
-krb5_data *result_data;
+krb5_error_code
+krb5int_rd_chpw_rep(krb5_context context, krb5_auth_context auth_context, krb5_data *packet, int *result_code, krb5_data *result_data)
{
- char *ptr;
- int plen, vno;
- krb5_data ap_rep;
- krb5_ap_rep_enc_part *ap_rep_enc;
- krb5_error_code ret;
- krb5_data cipherresult;
- krb5_data clearresult;
- krb5_error *krberror;
- krb5_replay_data replay;
- krb5_keyblock *tmp;
- int local_result_code;
-
- if (packet->length < 4)
+ char *ptr;
+ int plen, vno;
+ krb5_data ap_rep;
+ krb5_ap_rep_enc_part *ap_rep_enc;
+ krb5_error_code ret;
+ krb5_data cipherresult;
+ krb5_data clearresult;
+ krb5_error *krberror;
+ krb5_replay_data replay;
+ krb5_keyblock *tmp;
+ int local_result_code;
+
+ if (packet->length < 4)
+ /* either this, or the server is printing bad messages,
+ or the caller passed in garbage */
+ return(KRB5KRB_AP_ERR_MODIFIED);
+
+ ptr = packet->data;
+
+ /* verify length */
+
+ plen = (*ptr++ & 0xff);
+ plen = (plen<<8) | (*ptr++ & 0xff);
+
+ if (plen != packet->length)
+ {
/*
- * either this, or the server is printing bad messages,
- * or the caller passed in garbage
+ * MS KDCs *may* send back a KRB_ERROR. Although
+ * not 100% correct via RFC3244, it's something
+ * we can workaround here.
*/
- return (KRB5KRB_AP_ERR_MODIFIED);
+ if (krb5_is_krb_error(packet)) {
- ptr = packet->data;
+ if ((ret = krb5_rd_error(context, packet, &krberror)))
+ return(ret);
- /* verify length */
- plen = (*ptr++ & 0xff);
- plen = (plen<<8) | (*ptr++ & 0xff);
+ if (krberror->e_data.data == NULL) {
+ ret = ERROR_TABLE_BASE_krb5 + (krb5_error_code) krberror->error;
+ krb5_free_error(context, krberror);
+ return (ret);
+ }
+ }
+ else
+ {
+ return(KRB5KRB_AP_ERR_MODIFIED);
+ }
+ }
+
- if (plen != packet->length)
- return (KRB5KRB_AP_ERR_MODIFIED);
+ /* verify version number */
- /* verify version number */
- vno = (*ptr++ & 0xff);
- vno = (vno<<8) | (*ptr++ & 0xff);
+ vno = (*ptr++ & 0xff);
+ vno = (vno<<8) | (*ptr++ & 0xff);
/*
* when the servers update to v2 of the protocol,
@@ -143,69 +147,71 @@ krb5_data *result_data;
if (vno != 1 && vno != 2)
return (KRB5KDC_ERR_BAD_PVNO);
- /* read, check ap-rep length */
- ap_rep.length = (*ptr++ & 0xff);
- ap_rep.length = (ap_rep.length<<8) | (*ptr++ & 0xff);
+ /* read, check ap-rep length */
- if (ptr + ap_rep.length >= packet->data + packet->length)
- return (KRB5KRB_AP_ERR_MODIFIED);
+ ap_rep.length = (*ptr++ & 0xff);
+ ap_rep.length = (ap_rep.length<<8) | (*ptr++ & 0xff);
- if (ap_rep.length) {
- /* verify ap_rep */
- ap_rep.data = ptr;
- ptr += ap_rep.length;
+ if (ptr + ap_rep.length >= packet->data + packet->length)
+ return(KRB5KRB_AP_ERR_MODIFIED);
- /*
- * Save send_subkey to later smash recv_subkey.
- */
- ret = krb5_auth_con_getsendsubkey(context, auth_context, &tmp);
- if (ret)
- return (ret);
-
- if (ret = krb5_rd_rep(context, auth_context, &ap_rep,
- &ap_rep_enc)) {
- krb5_free_keyblock(context, tmp);
- return (ret);
- }
+ if (ap_rep.length) {
+ /* verify ap_rep */
+ ap_rep.data = ptr;
+ ptr += ap_rep.length;
- krb5_free_ap_rep_enc_part(context, ap_rep_enc);
+ /*
+ * Save send_subkey to later smash recv_subkey.
+ */
+ ret = krb5_auth_con_getsendsubkey(context, auth_context, &tmp);
+ if (ret)
+ return ret;
+
+ ret = krb5_rd_rep(context, auth_context, &ap_rep, &ap_rep_enc);
+ if (ret) {
+ krb5_free_keyblock(context, tmp);
+ return(ret);
+ }
- /* extract and decrypt the result */
- cipherresult.data = ptr;
- cipherresult.length = (packet->data + packet->length) - ptr;
+ krb5_free_ap_rep_enc_part(context, ap_rep_enc);
- /*
- * Smash recv_subkey to be send_subkey, per spec.
- */
- ret = krb5_auth_con_setrecvsubkey(context, auth_context, tmp);
- krb5_free_keyblock(context, tmp);
- if (ret)
- return (ret);
+ /* extract and decrypt the result */
- ret = krb5_rd_priv(context, auth_context, &cipherresult,
- &clearresult, &replay);
+ cipherresult.data = ptr;
+ cipherresult.length = (packet->data + packet->length) - ptr;
- if (ret)
- return (ret);
- } else {
- cipherresult.data = ptr;
- cipherresult.length = (packet->data + packet->length) - ptr;
+ /*
+ * Smash recv_subkey to be send_subkey, per spec.
+ */
+ ret = krb5_auth_con_setrecvsubkey(context, auth_context, tmp);
+ krb5_free_keyblock(context, tmp);
+ if (ret)
+ return ret;
- if (ret = krb5_rd_error(context, &cipherresult, &krberror))
- return (ret);
+ ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult,
+ &replay);
- clearresult = krberror->e_data;
- }
+ if (ret)
+ return(ret);
+ } else {
+ cipherresult.data = ptr;
+ cipherresult.length = (packet->data + packet->length) - ptr;
- if (clearresult.length < 2) {
- ret = KRB5KRB_AP_ERR_MODIFIED;
- goto cleanup;
- }
+ if ((ret = krb5_rd_error(context, &cipherresult, &krberror)))
+ return(ret);
+
+ clearresult = krberror->e_data;
+ }
- ptr = clearresult.data;
+ if (clearresult.length < 2) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto cleanup;
+ }
- local_result_code = (*ptr++ & 0xff);
- local_result_code = (local_result_code<<8) | (*ptr++ & 0xff);
+ ptr = clearresult.data;
+
+ local_result_code = (*ptr++ & 0xff);
+ local_result_code = (local_result_code<<8) | (*ptr++ & 0xff);
if (result_code)
*result_code = local_result_code;
@@ -214,41 +220,40 @@ krb5_data *result_data;
* Make sure the result code is in range for this
* protocol.
*/
- if ((local_result_code < KRB5_KPASSWD_SUCCESS) ||
- (local_result_code > KRB5_KPASSWD_ETYPE_NOSUPP)) {
- ret = KRB5KRB_AP_ERR_MODIFIED;
- goto cleanup;
+ if ((local_result_code < KRB5_KPASSWD_SUCCESS) ||
+ (local_result_code > KRB5_KPASSWD_ETYPE_NOSUPP)) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto cleanup;
+ }
+
+ /* all success replies should be authenticated/encrypted */
+
+ if ((ap_rep.length == 0) && (local_result_code == KRB5_KPASSWD_SUCCESS)) {
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ goto cleanup;
+ }
+
+ result_data->length = (clearresult.data + clearresult.length) - ptr;
+
+ if (result_data->length) {
+ result_data->data = (char *) malloc(result_data->length);
+ if (result_data->data == NULL) {
+ ret = ENOMEM;
+ goto cleanup;
}
+ memcpy(result_data->data, ptr, result_data->length);
+ } else {
+ result_data->data = NULL;
+ }
-
- /* all success replies should be authenticated/encrypted */
- if ((ap_rep.length == 0) &&
- (local_result_code == KRB5_KPASSWD_SUCCESS)) {
- ret = KRB5KRB_AP_ERR_MODIFIED;
- goto cleanup;
- }
-
- result_data->length = (clearresult.data + clearresult.length) - ptr;
-
- if (result_data->length) {
- result_data->data = (char *)malloc(result_data->length);
- if (result_data->data == NULL) {
- ret = ENOMEM;
- goto cleanup;
- }
- memcpy(result_data->data, ptr, result_data->length);
- } else {
- result_data->data = NULL;
- }
-
- ret = 0;
+ ret = 0;
cleanup:
- if (ap_rep.length) {
- krb5_xfree(clearresult.data);
- } else {
- krb5_free_error(context, krberror);
- }
+ if (ap_rep.length) {
+ krb5_xfree(clearresult.data);
+ } else {
+ krb5_free_error(context, krberror);
+ }
- return (ret);
+ return(ret);
}
diff --git a/usr/src/lib/krb5/kadm5/clnt/client_init.c b/usr/src/lib/krb5/kadm5/clnt/client_init.c
index b7d186701e..15fdbebea8 100644
--- a/usr/src/lib/krb5/kadm5/clnt/client_init.c
+++ b/usr/src/lib/krb5/kadm5/clnt/client_init.c
@@ -1,11 +1,13 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- *
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/clnt/client_init.c,v 1.13.2.2 2000/05/09 13:17:14 raeburn Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
+ */
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -33,13 +35,6 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-
-/*
- * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
- *
- * $Header: /afs/athena.mit.edu/astaff/project/krbdev/.cvsroot/src/lib/kadm5/clnt/client_init.c,v 1.6 1996/11/07 17:13:44 tytso Exp $
- */
-
#include <stdio.h>
#include <netdb.h>
#include "autoconf.h"
@@ -545,27 +540,15 @@ _kadm5_initialize_rpcsec_gss_handle(kadm5_server_handle_t handle,
goto cleanup;
}
- r = init_1(&handle->api_version, handle->clnt, &rpc_err_code);
+ r = init_2(&handle->api_version, handle->clnt);
+ /* Solaris Kerberos: 163 resync */
if (r == NULL) {
ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
"error during admin api initialization\n"));
-
- if (rpc_err_code == RPC_CANTENCODEARGS) {
- ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
- "encryption needed to encode RPC data may not be "
- "installed/configured on this system"));
- code = KADM5_RPC_ERROR_CANTENCODEARGS;
- } else if (rpc_err_code == RPC_CANTDECODEARGS) {
- ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
- "encryption needed to decode RPC data may not be "
- "installed/configured on the server"));
- code = KADM5_RPC_ERROR_CANTDECODEARGS;
- } else
- code = KADM5_RPC_ERROR;
-
+ code = KADM5_RPC_ERROR;
goto error;
-
}
+
if (r->code) {
code = r->code;
ADMIN_LOG(LOG_ERR,
@@ -701,11 +684,8 @@ static kadm5_ret_t _kadm5_init_any(char *client_name,
return KADM5_BAD_CLIENT_PARAMS;
}
- if ((code = kadm5_get_config_params(handle->context,
- DEFAULT_PROFILE_PATH,
- "KRB5_CONFIG",
- params_in,
- &handle->params))) {
+ if ((code = kadm5_get_config_params(handle->context, 0,
+ params_in, &handle->params))) {
krb5_free_context(handle->context);
free(handle->lhandle);
free(handle);
@@ -959,8 +939,10 @@ static kadm5_ret_t _kadm5_init_any(char *client_name,
* to prevent a double free in the "error" code.
*/
if (code != 0) {
- if (init_type != INIT_CREDS)
+ if (init_type != INIT_CREDS) {
krb5_cc_close(handle->context, ccache);
+ ccache = NULL;
+ }
goto error;
}
}
diff --git a/usr/src/lib/krb5/kadm5/clnt/client_internal.h b/usr/src/lib/krb5/kadm5/clnt/client_internal.h
index ff739b4b91..d8e9f885da 100644
--- a/usr/src/lib/krb5/kadm5/clnt/client_internal.h
+++ b/usr/src/lib/krb5/kadm5/clnt/client_internal.h
@@ -1,12 +1,11 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef __KADM5_CLIENT_INTERNAL_H__
#define __KADM5_CLIENT_INTERNAL_H__
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -29,9 +28,9 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/clnt/client_internal.h,v 1.1 1996/07/24 22:22:43 tlyu Exp $
+ * $Header$
*
- * $Log: client_internal.h,v $
+ * $Log$
* Revision 1.1 1996/07/24 22:22:43 tlyu
* * Makefile.in, configure.in: break out client lib into a
* subdirectory
@@ -91,6 +90,7 @@
extern "C" {
#endif
+
#include "admin_internal.h"
typedef struct _kadm5_server_handle_t {
@@ -101,6 +101,7 @@ typedef struct _kadm5_server_handle_t {
int destroy_cache;
CLIENT * clnt;
krb5_context context;
+ /* Solaris Kerberos */
gss_cred_id_t my_cred;
kadm5_config_params params;
struct _kadm5_server_handle_t *lhandle;
diff --git a/usr/src/lib/krb5/kadm5/clnt/client_principal.c b/usr/src/lib/krb5/kadm5/clnt/client_principal.c
index dc06bc5fe7..9aea25ff56 100644
--- a/usr/src/lib/krb5/kadm5/clnt/client_principal.c
+++ b/usr/src/lib/krb5/kadm5/clnt/client_principal.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -26,11 +25,11 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/clnt/client_principal.c,v 1.11 2004/06/16 03:11:53 tlyu Exp $
+ * $Header$
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/clnt/client_principal.c,v 1.11 2004/06/16 03:11:53 tlyu Exp $";
+static char *rcsid = "$Header$";
#endif
#include <rpc/rpc.h> /* SUNWresync121 XXX */
@@ -39,6 +38,7 @@ static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/clnt/client_princi
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
+#include <errno.h>
#include "client_internal.h"
#ifdef DEBUG /* SUNWresync14 XXX */
@@ -95,7 +95,7 @@ kadm5_create_principal(void *server_handle,
arg.rec.tl_data = NULL;
}
- r = create_principal_1(&arg, handle->clnt);
+ r = create_principal_2(&arg, handle->clnt);
if (handle->api_version == KADM5_API_VERSION_1)
krb5_free_principal(handle->context, arg.rec.mod_name);
@@ -156,7 +156,7 @@ kadm5_create_principal_3(void *server_handle,
arg.rec.tl_data = NULL;
}
- r = create_principal3_1(&arg, handle->clnt);
+ r = create_principal3_2(&arg, handle->clnt);
if (handle->api_version == KADM5_API_VERSION_1)
krb5_free_principal(handle->context, arg.rec.mod_name);
@@ -179,7 +179,7 @@ kadm5_delete_principal(void *server_handle, krb5_principal principal)
return EINVAL;
arg.princ = principal;
arg.api_version = handle->api_version;
- r = delete_principal_1(&arg, handle->clnt);
+ r = delete_principal_2(&arg, handle->clnt);
if(r == NULL)
eret();
return r->code;
@@ -228,7 +228,7 @@ kadm5_modify_principal(void *server_handle,
} else
arg.rec.mod_name = NULL;
- r = modify_principal_1(&arg, handle->clnt);
+ r = modify_principal_2(&arg, handle->clnt);
if (handle->api_version == KADM5_API_VERSION_1)
krb5_free_principal(handle->context, arg.rec.mod_name);
@@ -257,7 +257,7 @@ kadm5_get_principal(void *server_handle,
else
arg.mask = mask;
arg.api_version = handle->api_version;
- r = get_principal_1(&arg, handle->clnt);
+ r = get_principal_2(&arg, handle->clnt);
if(r == NULL)
eret();
if (handle->api_version == KADM5_API_VERSION_1) {
@@ -297,7 +297,7 @@ kadm5_get_principals(void *server_handle,
return EINVAL;
arg.exp = exp;
arg.api_version = handle->api_version;
- r = get_princs_1(&arg, handle->clnt);
+ r = get_princs_2(&arg, handle->clnt);
if(r == NULL)
eret();
if(r->code == 0) {
@@ -326,7 +326,7 @@ kadm5_rename_principal(void *server_handle,
arg.api_version = handle->api_version;
if (source == NULL || dest == NULL)
return EINVAL;
- r = rename_principal_1(&arg, handle->clnt);
+ r = rename_principal_2(&arg, handle->clnt);
if(r == NULL)
eret();
return r->code;
@@ -348,7 +348,7 @@ kadm5_chpass_principal(void *server_handle,
if(princ == NULL)
return EINVAL;
- r = chpass_principal_1(&arg, handle->clnt);
+ r = chpass_principal_2(&arg, handle->clnt);
if(r == NULL)
eret();
return r->code;
@@ -375,7 +375,7 @@ kadm5_chpass_principal_3(void *server_handle,
if(princ == NULL)
return EINVAL;
- r = chpass_principal3_1(&arg, handle->clnt);
+ r = chpass_principal3_2(&arg, handle->clnt);
if(r == NULL)
eret();
return r->code;
@@ -398,7 +398,7 @@ kadm5_setv4key_principal(void *server_handle,
if(princ == NULL || keyblock == NULL)
return EINVAL;
- r = setv4key_principal_1(&arg, handle->clnt);
+ r = setv4key_principal_2(&arg, handle->clnt);
if(r == NULL)
eret();
return r->code;
@@ -423,7 +423,7 @@ kadm5_setkey_principal(void *server_handle,
if(princ == NULL || keyblocks == NULL)
return EINVAL;
- r = setkey_principal_1(&arg, handle->clnt);
+ r = setkey_principal_2(&arg, handle->clnt);
if(r == NULL)
eret();
return r->code;
@@ -453,7 +453,7 @@ kadm5_setkey_principal_3(void *server_handle,
if(princ == NULL || keyblocks == NULL)
return EINVAL;
- r = setkey_principal3_1(&arg, handle->clnt);
+ r = setkey_principal3_2(&arg, handle->clnt);
if(r == NULL)
eret();
return r->code;
@@ -497,7 +497,7 @@ kadm5_randkey_principal_old(void *server_handle,
if(princ == NULL)
return EINVAL;
- r = chrand_principal_1(&arg, handle->clnt);
+ r = chrand_principal_2(&arg, handle->clnt);
if (r == NULL)
return KADM5_RPC_ERROR;
if (handle->api_version == KADM5_API_VERSION_1) {
@@ -537,7 +537,7 @@ kadm5_randkey_principal_3(void *server_handle,
kadm5_server_handle_t handle = server_handle;
int i, ret;
- /* For safety */
+ /* Solaris Kerberos - For safety */
if (n_keys)
*n_keys = 0;
if (key)
@@ -553,7 +553,7 @@ kadm5_randkey_principal_3(void *server_handle,
if(princ == NULL)
return EINVAL;
- r = chrand_principal3_1(&arg, handle->clnt);
+ r = chrand_principal3_2(&arg, handle->clnt);
if(r == NULL)
eret();
if (handle->api_version == KADM5_API_VERSION_1) {
@@ -589,7 +589,7 @@ kadm5_randkey_principal(void *server_handle,
krb5_principal princ,
krb5_keyblock **key, int *n_keys)
{
-
+ /* Solaris Kerberos */
kadm5_ret_t kret;
/*
diff --git a/usr/src/lib/krb5/kadm5/clnt/client_rpc.c b/usr/src/lib/krb5/kadm5/clnt/client_rpc.c
index 1e029e1bf7..407c85b4cd 100644
--- a/usr/src/lib/krb5/kadm5/clnt/client_rpc.c
+++ b/usr/src/lib/krb5/kadm5/clnt/client_rpc.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -35,375 +34,380 @@
static struct timeval TIMEOUT = { 25, 0 };
generic_ret *
-create_principal_1(argp, clnt)
- cprinc_arg *argp;
- CLIENT *clnt;
+create_principal_2(cprinc_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, CREATE_PRINCIPAL, (xdrproc_t) xdr_cprinc_arg,
- (caddr_t) argp, (xdrproc_t) xdr_generic_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, CREATE_PRINCIPAL,
+ (xdrproc_t) xdr_cprinc_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-create_principal3_1(argp, clnt)
- cprinc3_arg *argp;
- CLIENT *clnt;
+create_principal3_2(cprinc3_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, CREATE_PRINCIPAL3, xdr_cprinc3_arg,
- (caddr_t) argp, /* SUNWresync121 XXX */
- xdr_generic_ret,
- (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, CREATE_PRINCIPAL3,
+ (xdrproc_t) xdr_cprinc3_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-delete_principal_1(argp, clnt)
- dprinc_arg *argp;
- CLIENT *clnt;
+delete_principal_2(dprinc_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, DELETE_PRINCIPAL, xdr_dprinc_arg, (caddr_t) argp,
- xdr_generic_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, DELETE_PRINCIPAL,
+ (xdrproc_t) xdr_dprinc_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-modify_principal_1(argp, clnt)
- mprinc_arg *argp;
- CLIENT *clnt;
+modify_principal_2(mprinc_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, MODIFY_PRINCIPAL, xdr_mprinc_arg, (caddr_t) argp,
- xdr_generic_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, MODIFY_PRINCIPAL,
+ (xdrproc_t) xdr_mprinc_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-rename_principal_1(argp, clnt)
- rprinc_arg *argp;
- CLIENT *clnt;
+rename_principal_2(rprinc_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, RENAME_PRINCIPAL, xdr_rprinc_arg, (caddr_t) argp,
- xdr_generic_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, RENAME_PRINCIPAL,
+ (xdrproc_t) xdr_rprinc_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
gprinc_ret *
-get_principal_1(argp, clnt)
- gprinc_arg *argp;
- CLIENT *clnt;
+get_principal_2(gprinc_arg *argp, CLIENT *clnt)
{
- static gprinc_ret res;
+ static gprinc_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, GET_PRINCIPAL, xdr_gprinc_arg, (caddr_t) argp,
- xdr_gprinc_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, GET_PRINCIPAL,
+ (xdrproc_t) xdr_gprinc_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_gprinc_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
gprincs_ret *
-get_princs_1(argp, clnt)
- gprincs_arg *argp;
- CLIENT *clnt;
+get_princs_2(gprincs_arg *argp, CLIENT *clnt)
{
- static gprincs_ret res;
+ static gprincs_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, GET_PRINCS, xdr_gprincs_arg, (caddr_t) argp,
- xdr_gprincs_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, GET_PRINCS,
+ (xdrproc_t) xdr_gprincs_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_gprincs_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-chpass_principal_1(argp, clnt)
- chpass_arg *argp;
- CLIENT *clnt;
+chpass_principal_2(chpass_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, CHPASS_PRINCIPAL, xdr_chpass_arg, (caddr_t) argp,
- xdr_generic_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, CHPASS_PRINCIPAL,
+ (xdrproc_t) xdr_chpass_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-chpass_principal3_1(argp, clnt)
- chpass3_arg *argp;
- CLIENT *clnt;
+chpass_principal3_2(chpass3_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, CHPASS_PRINCIPAL3, xdr_chpass3_arg,
- (caddr_t) argp, /* SUNWresync 121 XXX */
- xdr_generic_ret, (caddr_t) &res,
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, CHPASS_PRINCIPAL3,
+ (xdrproc_t) xdr_chpass3_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-setv4key_principal_1(argp, clnt)
- setv4key_arg *argp;
- CLIENT *clnt;
+setv4key_principal_2(setv4key_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, SETV4KEY_PRINCIPAL, xdr_setv4key_arg,
- (caddr_t) argp, /* SUNWresync121 XXX */
- xdr_generic_ret, (caddr_t) &res,
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, SETV4KEY_PRINCIPAL,
+ (xdrproc_t) xdr_setv4key_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-setkey_principal_1(argp, clnt)
- setkey_arg *argp;
- CLIENT *clnt;
+setkey_principal_2(setkey_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, SETKEY_PRINCIPAL, xdr_setkey_arg,
- (caddr_t) argp, /* SUNWresync121 XXX */
- xdr_generic_ret, (caddr_t) &res,
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, SETKEY_PRINCIPAL,
+ (xdrproc_t) xdr_setkey_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-setkey_principal3_1(argp, clnt)
- setkey3_arg *argp;
- CLIENT *clnt;
+setkey_principal3_2(setkey3_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, SETKEY_PRINCIPAL3, xdr_setkey3_arg,
- (caddr_t) argp, /* SUNWresync121 XXX */
- xdr_generic_ret, (caddr_t) &res,
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, SETKEY_PRINCIPAL3,
+ (xdrproc_t) xdr_setkey3_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
chrand_ret *
-chrand_principal_1(argp, clnt)
- chrand_arg *argp;
- CLIENT *clnt;
+chrand_principal_2(chrand_arg *argp, CLIENT *clnt)
{
- static chrand_ret res;
+ static chrand_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, CHRAND_PRINCIPAL, xdr_chrand_arg, (caddr_t) argp,
- xdr_chrand_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, CHRAND_PRINCIPAL,
+ (xdrproc_t) xdr_chrand_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_chrand_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
chrand_ret *
-chrand_principal3_1(argp, clnt)
- chrand3_arg *argp;
- CLIENT *clnt;
+chrand_principal3_2(chrand3_arg *argp, CLIENT *clnt)
{
- static chrand_ret res;
+ static chrand_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, CHRAND_PRINCIPAL3, xdr_chrand3_arg,
- (caddr_t) argp, /* SUNWresync121 XXX */
- xdr_chrand_ret, (caddr_t) &res,
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, CHRAND_PRINCIPAL3,
+ (xdrproc_t) xdr_chrand3_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_chrand_ret, (caddr_t) &clnt_res,
TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-create_policy_1(argp, clnt)
- cpol_arg *argp;
- CLIENT *clnt;
+create_policy_2(cpol_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, CREATE_POLICY, xdr_cpol_arg, (caddr_t) argp,
- xdr_generic_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, CREATE_POLICY,
+ (xdrproc_t) xdr_cpol_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-delete_policy_1(argp, clnt)
- dpol_arg *argp;
- CLIENT *clnt;
+delete_policy_2(dpol_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, DELETE_POLICY, xdr_dpol_arg, (caddr_t) argp,
- xdr_generic_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, DELETE_POLICY,
+ (xdrproc_t) xdr_dpol_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-modify_policy_1(argp, clnt)
- mpol_arg *argp;
- CLIENT *clnt;
+modify_policy_2(mpol_arg *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, MODIFY_POLICY, xdr_mpol_arg, (caddr_t) argp,
- xdr_generic_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, MODIFY_POLICY,
+ (xdrproc_t) xdr_mpol_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
gpol_ret *
-get_policy_1(argp, clnt)
- gpol_arg *argp;
- CLIENT *clnt;
+get_policy_2(gpol_arg *argp, CLIENT *clnt)
{
- static gpol_ret res;
+ static gpol_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, GET_POLICY, xdr_gpol_arg, (caddr_t) argp,
- xdr_gpol_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, GET_POLICY,
+ (xdrproc_t) xdr_gpol_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_gpol_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
gpols_ret *
-get_pols_1(argp, clnt)
- gpols_arg *argp;
- CLIENT *clnt;
+get_pols_2(gpols_arg *argp, CLIENT *clnt)
{
- static gpols_ret res;
+ static gpols_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, GET_POLS, xdr_gpols_arg, (caddr_t) argp,
- xdr_gpols_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, GET_POLS,
+ (xdrproc_t) xdr_gpols_arg, (caddr_t) argp,
+ (xdrproc_t) xdr_gpols_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
-getprivs_ret *get_privs_1(argp, clnt)
- void *argp;
- CLIENT *clnt;
+getprivs_ret *
+get_privs_2(void *argp, CLIENT *clnt)
{
- static getprivs_ret res;
+ static getprivs_ret clnt_res;
+ /* Solaris Kerberos */
if (clnt == NULL)
return (NULL);
- memset((char *)&res, 0, sizeof(res));
- if (clnt_call(clnt, GET_PRIVS, xdr_u_int, (caddr_t) argp,
- xdr_getprivs_ret, (caddr_t) &res, TIMEOUT) != RPC_SUCCESS) {
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, GET_PRIVS,
+ (xdrproc_t) xdr_u_int, (caddr_t) argp,
+ (xdrproc_t) xdr_getprivs_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
generic_ret *
-init_1(argp, clnt, rpc_err_code)
- void *argp;
- CLIENT *clnt;
- enum clnt_stat *rpc_err_code;
+init_2(void *argp, CLIENT *clnt)
{
- static generic_ret res;
+ static generic_ret clnt_res;
- enum clnt_stat retval;
-
- if (clnt == NULL)
- return (NULL);
- memset((char *)&res, 0, sizeof(res));
- retval = clnt_call(clnt, INIT, xdr_u_int, (caddr_t) argp,
- xdr_generic_ret, (caddr_t) &res, TIMEOUT);
+ /* Solaris Kerberos */
+ if (clnt == NULL)
+ return (NULL);
- if (retval != RPC_SUCCESS) {
- *rpc_err_code = retval;
+ memset((char *)&clnt_res, 0, sizeof(clnt_res));
+ if (clnt_call(clnt, INIT,
+ (xdrproc_t) xdr_u_int, (caddr_t) argp,
+ (xdrproc_t) xdr_generic_ret, (caddr_t) &clnt_res,
+ TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
- return (&res);
+ return (&clnt_res);
}
diff --git a/usr/src/lib/krb5/kadm5/clnt/clnt_policy.c b/usr/src/lib/krb5/kadm5/clnt/clnt_policy.c
index 15ee88ef8a..2c97b16723 100644
--- a/usr/src/lib/krb5/kadm5/clnt/clnt_policy.c
+++ b/usr/src/lib/krb5/kadm5/clnt/clnt_policy.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -26,11 +25,11 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/clnt/clnt_policy.c,v 1.4 2004/02/19 01:22:26 raeburn Exp $
+ * $Header$
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/clnt/clnt_policy.c,v 1.2 1998/02/14 02:32:57 tlyu Exp $";
+static char *rcsid = "$Header$";
#endif
#include <rpc/rpc.h> /* SUNWresync121 XXX */
@@ -39,6 +38,7 @@ static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/clnt/clnt_policy.c
#include "client_internal.h"
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
kadm5_ret_t
kadm5_create_policy(void *server_handle,
@@ -56,9 +56,10 @@ kadm5_create_policy(void *server_handle,
arg.mask = mask;
arg.api_version = handle->api_version;
memcpy(&arg.rec, policy, sizeof(kadm5_policy_ent_rec));
- r = create_policy_1(&arg, handle->clnt);
+ r = create_policy_2(&arg, handle->clnt);
if(r == NULL)
return KADM5_RPC_ERROR;
+
return r->code;
}
@@ -77,9 +78,10 @@ kadm5_delete_policy(void *server_handle, char *name)
arg.name = name;
arg.api_version = handle->api_version;
- r = delete_policy_1(&arg, handle->clnt);
+ r = delete_policy_2(&arg, handle->clnt);
if(r == NULL)
return KADM5_RPC_ERROR;
+
return r->code;
}
@@ -100,9 +102,10 @@ kadm5_modify_policy(void *server_handle,
arg.api_version = handle->api_version;
memcpy(&arg.rec, policy, sizeof(kadm5_policy_ent_rec));
- r = modify_policy_1(&arg, handle->clnt);
+ r = modify_policy_2(&arg, handle->clnt);
if(r == NULL)
return KADM5_RPC_ERROR;
+
return r->code;
}
@@ -121,7 +124,7 @@ kadm5_get_policy(void *server_handle, char *name, kadm5_policy_ent_t ent)
if(name == NULL)
return EINVAL;
- r = get_policy_1(&arg, handle->clnt);
+ r = get_policy_2(&arg, handle->clnt);
if(r == NULL)
return KADM5_RPC_ERROR;
if (handle->api_version == KADM5_API_VERSION_1) {
@@ -158,7 +161,7 @@ kadm5_get_policies(void *server_handle,
return EINVAL;
arg.exp = exp;
arg.api_version = handle->api_version;
- r = get_pols_1(&arg, handle->clnt);
+ r = get_pols_2(&arg, handle->clnt);
if(r == NULL)
return KADM5_RPC_ERROR;
if(r->code == 0) {
diff --git a/usr/src/lib/krb5/kadm5/clnt/clnt_privs.c b/usr/src/lib/krb5/kadm5/clnt/clnt_privs.c
index 0552198f4a..9fab0e48bd 100644
--- a/usr/src/lib/krb5/kadm5/clnt/clnt_privs.c
+++ b/usr/src/lib/krb5/kadm5/clnt/clnt_privs.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -26,64 +25,13 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
*
- * $Id: clnt_privs.c,v 1.2 1998/02/14 02:32:58 tlyu Exp $
- * $Source: /cvs/krbdev/krb5/src/lib/kadm5/clnt/clnt_privs.c,v $
+ * $Id: clnt_privs.c 18130 2006-06-14 21:42:02Z raeburn $
+ * $Source$
*
- * $Log: clnt_privs.c,v $
- * Revision 1.2 1998/02/14 02:32:58 tlyu
- * * client_init.c:
- * * client_principal.c:
- * * client_rpc.c:
- * * clnt_policy.c:
- * * clnt_privs.c: Update header locations.
- *
- * * Makefile.in (LIBMAJOR): Bump major version to reflect change in
- * rpc library.
- *
- * Revision 1.1 1996/07/24 22:22:48 tlyu
- * * Makefile.in, configure.in: break out client lib into a
- * subdirectory
- *
- * Revision 1.6 1996/07/22 20:35:57 marc
- * this commit includes all the changes on the OV_9510_INTEGRATION and
- * OV_MERGE branches. This includes, but is not limited to, the new openvision
- * admin system, and major changes to gssapi to add functionality, and bring
- * the implementation in line with rfc1964. before committing, the
- * code was built and tested for netbsd and solaris.
- *
- * Revision 1.5.4.1 1996/07/18 03:08:45 marc
- * merged in changes from OV_9510_BP to OV_9510_FINAL1
- *
- * Revision 1.5.2.1 1996/06/20 02:16:53 marc
- * File added to the repository on a branch
- *
- * Revision 1.5 1996/05/17 21:36:50 bjaspan
- * rename to kadm5, begin implementing version 2
- *
- * Revision 1.4 1996/05/16 21:45:51 bjaspan
- * u_int32 -> long, add krb5_context
- *
- * Revision 1.3 1994/09/20 16:25:05 bjaspan
- * [secure-admin/2436: API versioning fixes to various admin files]
- * [secure-releng/2502: audit secure-admin/2436: random API versioning fixes]
- *
- * Sandbox:
- *
- * Unnecessary variable initialization removed.
- *
- * Revision 1.3 1994/09/12 20:26:39 jik
- * Unnecessary variable initialization removed.
- *
- * Revision 1.2 1994/08/16 18:52:02 jik
- * Versioning changes.
- *
- * Revision 1.1 1993/11/10 23:10:39 bjaspan
- * Initial revision
- *
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/clnt/clnt_privs.c,v 1.2 1998/02/14 02:32:58 tlyu Exp $";
+static char *rcsid = "$Header$";
#endif
#include <rpc/rpc.h> /* SUNWresync121 XXX */
@@ -96,10 +44,11 @@ kadm5_ret_t kadm5_get_privs(void *server_handle, long *privs)
getprivs_ret *r;
kadm5_server_handle_t handle = server_handle;
- r = get_privs_1(&handle->api_version, handle->clnt);
+ r = get_privs_2(&handle->api_version, handle->clnt);
if (r == NULL)
return KADM5_RPC_ERROR;
else if (r->code == KADM5_OK)
*privs = r->privs;
+
return r->code;
}
diff --git a/usr/src/lib/krb5/kadm5/clnt/logger.c b/usr/src/lib/krb5/kadm5/clnt/logger.c
index 8dcc0326bd..db4325f699 100644
--- a/usr/src/lib/krb5/kadm5/clnt/logger.c
+++ b/usr/src/lib/krb5/kadm5/clnt/logger.c
@@ -1,4 +1,9 @@
/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
* lib/kadm/logger.c
*
* Copyright 1995 by the Massachusetts Institute of Technology.
@@ -16,20 +21,15 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-
/* KADM5 wants non-syslog log files to contain syslog-like entries */
#define VERBOSE_LOGS
@@ -41,9 +41,18 @@
#include "com_err.h"
#include <stdio.h>
#include <ctype.h>
+#include <ctype.h>
+#ifdef HAVE_SYSLOG_H
#include <syslog.h>
+#endif /* HAVE_SYSLOG_H */
+#ifdef HAVE_STDARG_H
#include <stdarg.h>
+#else /* HAVE_STDARG_H */
+#include <varargs.h>
+#endif /* HAVE_STDARG_H */
#include <libintl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#define KRB5_KLOG_MAX_ERRMSG_SIZE 2048
#ifndef MAXHOSTNAMELEN
@@ -196,7 +205,6 @@ struct log_control {
char *log_whoami;
char *log_hostname;
krb5_boolean log_opened;
-
};
static struct log_control log_control = {
@@ -214,8 +222,8 @@ static struct log_entry def_log_entry;
*/
#define DEVICE_OPEN(d, m) fopen(d, m)
#define CONSOLE_OPEN(m) fopen("/dev/console", m)
-#define DEVICE_PRINT(f, m) ((fprintf(f, m) >= 0) ? \
- (fprintf(f, "\r\n"), fflush(f), 0) : \
+#define DEVICE_PRINT(f, m) ((fprintf(f, "%s\r\n", m) >= 0) ? \
+ (fflush(f), 0) : \
-1)
#define DEVICE_CLOSE(d) fclose(d)
@@ -236,6 +244,8 @@ klog_rotate(struct log_entry *le)
char *tmp;
FILE *fp;
int num_vers;
+ mode_t old_umask;
+
/*
* By default we don't rotate.
@@ -304,17 +314,18 @@ klog_rotate(struct log_entry *le)
*/
le->lfu_last_rotated = t;
+ /*
+ * Default log file creation mode should be read-only
+ * by owner(root), but the admin can override with
+ * chmod(1) if desired.
+ */
+
+ old_umask = umask(077);
fp = fopen(old_name, le->lfu_fopen_mode);
- if (fp != NULL) {
+ umask(old_umask);
- /* Set the permissions to 644 */
- if (fchmod(fileno(fp),
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1) {
- fprintf(stderr,
-gettext("During rotate, couldn't set permissions for log file %s: %s\n"),
- old_name, error_message(errno));
- }
+ if (fp != NULL) {
(void) fclose(le->lfu_filep);
le->lfu_filep = fp;
@@ -347,17 +358,16 @@ gettext("During rotate, couldn't set permissions for log file %s: %s\n"),
* klog_com_err_proc() - Handle com_err(3) messages as specified by the
* profile.
*/
+static krb5_context err_context;
static void
-klog_com_err_proc(whoami, code, format, ap)
- const char *whoami;
- long code;
- const char *format;
- va_list ap;
+klog_com_err_proc(const char *whoami, long code, const char *format, va_list ap)
{
char outbuf[KRB5_KLOG_MAX_ERRMSG_SIZE];
int lindex;
- char *actual_format;
+ const char *actual_format;
+#ifdef HAVE_SYSLOG
int log_pri = -1;
+#endif /* HAVE_SYSLOG */
char *cp;
char *syslogp;
@@ -371,15 +381,18 @@ klog_com_err_proc(whoami, code, format, ap)
/* If reporting an error message, separate it. */
if (code) {
- outbuf[sizeof(outbuf) - 1] = '\0';
+ const char *emsg;
+ outbuf[sizeof(outbuf) - 1] = '\0';
- strncat(outbuf, error_message(code),
- sizeof(outbuf) - 1 - strlen(outbuf));
+ emsg = krb5_get_error_message (err_context, code);
+ strncat(outbuf, emsg, sizeof(outbuf) - 1 - strlen(outbuf));
strncat(outbuf, " - ", sizeof(outbuf) - 1 - strlen(outbuf));
+ krb5_free_error_message(err_context, emsg);
}
cp = &outbuf[strlen(outbuf)];
- actual_format = (char *) format;
+ actual_format = format;
+#ifdef HAVE_SYSLOG
/*
* This is an unpleasant hack. If the first character is less than
* 8, then we assume that it is a priority.
@@ -389,38 +402,61 @@ klog_com_err_proc(whoami, code, format, ap)
* intermediate representation.
*/
if ((((unsigned char) *format) > 0) && (((unsigned char) *format) <= 8)) {
- actual_format = (char *) (format + 1);
+ actual_format = (format + 1);
switch ((unsigned char) *format) {
+#ifdef LOG_EMERG
case 1:
log_pri = LOG_EMERG;
break;
+#endif /* LOG_EMERG */
+#ifdef LOG_ALERT
case 2:
log_pri = LOG_ALERT;
break;
+#endif /* LOG_ALERT */
+#ifdef LOG_CRIT
case 3:
log_pri = LOG_CRIT;
break;
+#endif /* LOG_CRIT */
default:
case 4:
log_pri = LOG_ERR;
break;
+#ifdef LOG_WARNING
case 5:
log_pri = LOG_WARNING;
break;
+#endif /* LOG_WARNING */
+#ifdef LOG_NOTICE
case 6:
log_pri = LOG_NOTICE;
break;
+#endif /* LOG_NOTICE */
+#ifdef LOG_INFO
case 7:
log_pri = LOG_INFO;
break;
+#endif /* LOG_INFO */
+#ifdef LOG_DEBUG
case 8:
log_pri = LOG_DEBUG;
break;
+#endif /* LOG_DEBUG */
}
}
+#endif /* HAVE_SYSLOG */
/* Now format the actual message */
- vsnprintf(cp, sizeof (outbuf) - (cp - outbuf), actual_format, ap);
+#if HAVE_VSNPRINTF
+ vsnprintf(cp, sizeof(outbuf) - (cp - outbuf), actual_format, ap);
+#elif HAVE_VSPRINTF
+ vsprintf(cp, actual_format, ap);
+#else /* HAVE_VSPRINTF */
+ sprintf(cp, actual_format, ((int *) ap)[0], ((int *) ap)[1],
+ ((int *) ap)[2], ((int *) ap)[3],
+ ((int *) ap)[4], ((int *) ap)[5]);
+#endif /* HAVE_VSPRINTF */
/*
* Now that we have the message formatted, perform the output to each
@@ -436,14 +472,13 @@ klog_com_err_proc(whoami, code, format, ap)
/*
* Files/standard error.
*/
- if (fprintf(log_control.log_entries[lindex].lfu_filep,
+ if (fprintf(log_control.log_entries[lindex].lfu_filep, "%s\n",
outbuf) < 0) {
/* Attempt to report error */
fprintf(stderr, krb5_log_error_table(LOG_FILE_ERR), whoami,
log_control.log_entries[lindex].lfu_fname);
}
else {
- fprintf(log_control.log_entries[lindex].lfu_filep, "\n");
fflush(log_control.log_entries[lindex].lfu_filep);
}
break;
@@ -459,6 +494,7 @@ klog_com_err_proc(whoami, code, format, ap)
log_control.log_entries[lindex].ldu_devname);
}
break;
+#ifdef HAVE_SYSLOG
case K_LOG_SYSLOG:
/*
* System log.
@@ -476,6 +512,7 @@ klog_com_err_proc(whoami, code, format, ap)
/* Log the message with our header trimmed off */
syslog(log_pri, syslogp);
break;
+#endif /* HAVE_SYSLOG */
default:
break;
}
@@ -504,26 +541,25 @@ klog_com_err_proc(whoami, code, format, ap)
* where/how to send output.
*/
krb5_error_code
-krb5_klog_init(kcontext, ename, whoami, do_com_err)
- krb5_context kcontext;
- char *ename;
- char *whoami;
- krb5_boolean do_com_err;
+krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do_com_err)
{
const char *logging_profent[3];
const char *logging_defent[3];
char **logging_specs;
int i, ngood;
char *cp, *cp2;
- char savec;
+ char savec = '\0';
int error;
int do_openlog, log_facility;
FILE *f;
+ mode_t old_umask;
/* Initialize */
do_openlog = 0;
log_facility = 0;
+ err_context = kcontext;
+
/*
* Look up [logging]-><ename> in the profile. If that doesn't
* succeed, then look for [logging]->default.
@@ -567,9 +603,9 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
* <whitespace><data><whitespace>
* so, trim off the leading and trailing whitespace here.
*/
- for (cp = logging_specs[i]; isspace(*cp); cp++);
+ for (cp = logging_specs[i]; isspace((int) *cp); cp++);
for (cp2 = &logging_specs[i][strlen(logging_specs[i])-1];
- isspace(*cp2); cp2--);
+ isspace((int) *cp2); cp2--);
cp2++;
*cp2 = '\0';
/*
@@ -582,16 +618,13 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
if (cp[4] == ':' || cp[4] == '=') {
log_control.log_entries[i].lfu_fopen_mode =
(cp[4] == ':') ? "a+F" : "wF";
+ old_umask = umask(077);
f = fopen(&cp[5],
log_control.log_entries[i].lfu_fopen_mode);
+ umask(old_umask);
if (f) {
- char rotate_kw[128];
- /* Set the permissions to 644 */
- if (fchmod(fileno(f),
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1) {
- fprintf(stderr,gettext("Couldn't set permissions for log file %s: %s\n"),
- &cp[5], error_message(errno));
- }
+ char rotate_kw[128];
+
log_control.log_entries[i].lfu_filep = f;
log_control.log_entries[i].log_type = K_LOG_FILE;
log_control.log_entries[i].lfu_fname = &cp[5];
@@ -642,12 +675,13 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
}
} else {
- fprintf(stderr,gettext("Couldn't open log file %s: %s\n"),
+ fprintf(stderr, gettext("Couldn't open log file %s: %s\n"),
&cp[5], error_message(errno));
continue;
}
}
}
+#ifdef HAVE_SYSLOG
/*
* Is this a syslog?
*/
@@ -662,7 +696,8 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
/*
* Find the end of the severity.
*/
- if (cp2 = strchr(&cp[7], ':')) {
+ cp2 = strchr(&cp[7], ':');
+ if (cp2) {
savec = *cp2;
*cp2 = '\0';
cp2++;
@@ -674,32 +709,46 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
if (!strcasecmp(&cp[7], "ERR")) {
log_control.log_entries[i].lsu_severity = LOG_ERR;
}
+#ifdef LOG_EMERG
else if (!strcasecmp(&cp[7], "EMERG")) {
log_control.log_entries[i].lsu_severity =
LOG_EMERG;
}
+#endif /* LOG_EMERG */
+#ifdef LOG_ALERT
else if (!strcasecmp(&cp[7], "ALERT")) {
log_control.log_entries[i].lsu_severity =
LOG_ALERT;
}
+#endif /* LOG_ALERT */
+#ifdef LOG_CRIT
else if (!strcasecmp(&cp[7], "CRIT")) {
log_control.log_entries[i].lsu_severity = LOG_CRIT;
}
+#endif /* LOG_CRIT */
+#ifdef LOG_WARNING
else if (!strcasecmp(&cp[7], "WARNING")) {
log_control.log_entries[i].lsu_severity =
LOG_WARNING;
}
+#endif /* LOG_WARNING */
+#ifdef LOG_NOTICE
else if (!strcasecmp(&cp[7], "NOTICE")) {
log_control.log_entries[i].lsu_severity =
LOG_NOTICE;
}
+#endif /* LOG_NOTICE */
+#ifdef LOG_INFO
else if (!strcasecmp(&cp[7], "INFO")) {
log_control.log_entries[i].lsu_severity = LOG_INFO;
}
+#endif /* LOG_INFO */
+#ifdef LOG_DEBUG
else if (!strcasecmp(&cp[7], "DEBUG")) {
log_control.log_entries[i].lsu_severity =
LOG_DEBUG;
}
+#endif /* LOG_DEBUG */
else
error = 1;
@@ -771,12 +820,14 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
log_facility = log_control.log_entries[i].lsu_facility;
}
}
+#endif /* HAVE_SYSLOG */
/*
* Is this a standard error specification?
*/
else if (!strcasecmp(cp, "STDERR")) {
- if (log_control.log_entries[i].lfu_filep =
- fdopen(fileno(stderr), "a+F")) {
+ log_control.log_entries[i].lfu_filep =
+ fdopen(fileno(stderr), "a+F");
+ if (log_control.log_entries[i].lfu_filep) {
log_control.log_entries[i].log_type = K_LOG_STDERR;
log_control.log_entries[i].lfu_fname =
"standard error";
@@ -786,8 +837,9 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
* Is this a specification of the console?
*/
else if (!strcasecmp(cp, "CONSOLE")) {
- if (log_control.log_entries[i].ldu_filep =
- CONSOLE_OPEN("a+F")) {
+ log_control.log_entries[i].ldu_filep =
+ CONSOLE_OPEN("a+F");
+ if (log_control.log_entries[i].ldu_filep) {
log_control.log_entries[i].log_type = K_LOG_CONSOLE;
log_control.log_entries[i].ldu_devname = "console";
}
@@ -800,8 +852,9 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
* We handle devices very similarly to files.
*/
if (cp[6] == '=') {
- if (log_control.log_entries[i].ldu_filep =
- DEVICE_OPEN(&cp[7], "wF")) {
+ log_control.log_entries[i].ldu_filep =
+ DEVICE_OPEN(&cp[7], "wF");
+ if (log_control.log_entries[i].ldu_filep) {
log_control.log_entries[i].log_type = K_LOG_DEVICE;
log_control.log_entries[i].ldu_devname = &cp[7];
}
@@ -843,14 +896,21 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
log_control.log_nentries = 1;
}
if (log_control.log_nentries) {
- if (log_control.log_whoami = (char *) malloc(strlen(whoami)+1))
+ log_control.log_whoami = (char *) malloc(strlen(whoami)+1);
+ if (log_control.log_whoami)
strcpy(log_control.log_whoami, whoami);
- if (log_control.log_hostname = (char *) malloc(MAXHOSTNAMELEN))
+
+ log_control.log_hostname = (char *) malloc(MAXHOSTNAMELEN + 1);
+ if (log_control.log_hostname) {
gethostname(log_control.log_hostname, MAXHOSTNAMELEN);
+ log_control.log_hostname[MAXHOSTNAMELEN] = '\0';
+ }
+#ifdef HAVE_OPENLOG
if (do_openlog) {
openlog(whoami, LOG_NDELAY|LOG_PID, log_facility);
log_control.log_opened = 1;
}
+#endif /* HAVE_OPENLOG */
if (do_com_err)
(void) set_com_err_hook(klog_com_err_proc);
}
@@ -861,8 +921,7 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
* krb5_klog_close() - Close the logging context and free all data.
*/
void
-krb5_klog_close(kcontext)
- krb5_context kcontext;
+krb5_klog_close(krb5_context kcontext)
{
int lindex;
(void) reset_com_err_hook();
@@ -882,11 +941,13 @@ krb5_klog_close(kcontext)
*/
DEVICE_CLOSE(log_control.log_entries[lindex].ldu_filep);
break;
+#ifdef HAVE_SYSLOG
case K_LOG_SYSLOG:
/*
* System log.
*/
break;
+#endif /* HAVE_SYSLOG */
default:
break;
}
@@ -903,16 +964,17 @@ krb5_klog_close(kcontext)
if (log_control.log_hostname)
free(log_control.log_hostname);
log_control.log_hostname = (char *) NULL;
+#ifdef HAVE_CLOSELOG
if (log_control.log_opened)
closelog();
+#endif /* HAVE_CLOSELOG */
}
/*
* severity2string() - Convert a severity to a string.
*/
-static char *
-severity2string(severity)
- int severity;
+static const char *
+severity2string(int severity)
{
int s;
const char *ss;
@@ -920,30 +982,44 @@ severity2string(severity)
s = severity & LOG_PRIMASK;
ss = krb5_log_error_table(LOG_UFO_STRING);
switch (s) {
+#ifdef LOG_EMERG
case LOG_EMERG:
ss = krb5_log_error_table(LOG_EMERG_STRING);
break;
+#endif /* LOG_EMERG */
+#ifdef LOG_ALERT
case LOG_ALERT:
ss = krb5_log_error_table(LOG_ALERT_STRING);
break;
+#endif /* LOG_ALERT */
+#ifdef LOG_CRIT
case LOG_CRIT:
ss = krb5_log_error_table(LOG_CRIT_STRING);
break;
+#endif /* LOG_CRIT */
case LOG_ERR:
ss = krb5_log_error_table(LOG_ERR_STRING);
break;
+#ifdef LOG_WARNING
case LOG_WARNING:
ss = krb5_log_error_table(LOG_WARNING_STRING);
break;
+#endif /* LOG_WARNING */
+#ifdef LOG_NOTICE
case LOG_NOTICE:
ss = krb5_log_error_table(LOG_NOTICE_STRING);
break;
+#endif /* LOG_NOTICE */
+#ifdef LOG_INFO
case LOG_INFO:
ss = krb5_log_error_table(LOG_INFO_STRING);
break;
+#endif /* LOG_INFO */
+#ifdef LOG_DEBUG
case LOG_DEBUG:
ss = krb5_log_error_table(LOG_DEBUG_STRING);
break;
+#endif /* LOG_DEBUG */
}
return((char *) ss);
}
@@ -954,17 +1030,16 @@ severity2string(severity)
* by krb5_klog_init().
*/
static int
-klog_vsyslog(priority, format, arglist)
- int priority;
- const char *format;
- va_list arglist;
+klog_vsyslog(int priority, const char *format, va_list arglist)
{
char outbuf[KRB5_KLOG_MAX_ERRMSG_SIZE];
int lindex;
char *syslogp;
char *cp;
time_t now;
+#ifdef HAVE_STRFTIME
size_t soff;
+#endif /* HAVE_STRFTIME */
/*
* Format a syslog-esque message of the format:
@@ -977,6 +1052,7 @@ klog_vsyslog(priority, format, arglist)
*/
cp = outbuf;
(void) time(&now);
+#ifdef HAVE_STRFTIME
/*
* Format the date: mon dd hh:mm:ss
*/
@@ -985,9 +1061,19 @@ klog_vsyslog(priority, format, arglist)
cp += soff;
else
return(-1);
+#else /* HAVE_STRFTIME */
+ /*
+ * Format the date:
+ * We ASSUME here that the output of ctime is of the format:
+ * dow mon dd hh:mm:ss tzs yyyy\n
+ * 012345678901234567890123456789
+ */
+ strncpy(outbuf, ctime(&now) + 4, 15);
+ cp += 15;
+#endif /* HAVE_STRFTIME */
#ifdef VERBOSE_LOGS
- sprintf(cp, " %s %s[%d](%s): ",
- log_control.log_hostname, log_control.log_whoami, getpid(),
+ sprintf(cp, " %s %s[%ld](%s): ",
+ log_control.log_hostname, log_control.log_whoami, (long) getpid(),
severity2string(priority));
#else
sprintf(cp, " ");
@@ -995,7 +1081,26 @@ klog_vsyslog(priority, format, arglist)
syslogp = &outbuf[strlen(outbuf)];
/* Now format the actual message */
- vsnprintf(syslogp, sizeof (outbuf) - (syslogp - outbuf), format, arglist);
+#ifdef HAVE_VSNPRINTF
+ vsnprintf(syslogp, sizeof(outbuf) - (syslogp - outbuf), format, arglist);
+#elif HAVE_VSPRINTF
+ vsprintf(syslogp, format, arglist);
+#else /* HAVE_VSPRINTF */
+ sprintf(syslogp, format, ((int *) arglist)[0], ((int *) arglist)[1],
+ ((int *) arglist)[2], ((int *) arglist)[3],
+ ((int *) arglist)[4], ((int *) arglist)[5]);
+#endif /* HAVE_VSPRINTF */
+
+ /*
+ * If the user did not use krb5_klog_init() instead of dropping
+ * the request on the floor, syslog it - if it exists
+ */
+#ifdef HAVE_SYSLOG
+ if (log_control.log_nentries == 0) {
+ /* Log the message with our header trimmed off */
+ syslog(priority, "%s", syslogp);
+ }
+#endif
/*
* Now that we have the message formatted, perform the output to each
@@ -1011,14 +1116,14 @@ klog_vsyslog(priority, format, arglist)
/*
* Files/standard error.
*/
- if (fprintf(log_control.log_entries[lindex].lfu_filep,
+ if (fprintf(log_control.log_entries[lindex].lfu_filep, "%s\n",
outbuf) < 0) {
/* Attempt to report error */
fprintf(stderr, krb5_log_error_table(LOG_FILE_ERR),
+ log_control.log_whoami,
log_control.log_entries[lindex].lfu_fname);
}
else {
- fprintf(log_control.log_entries[lindex].lfu_filep, "\n");
fflush(log_control.log_entries[lindex].lfu_filep);
}
break;
@@ -1031,17 +1136,20 @@ klog_vsyslog(priority, format, arglist)
outbuf) < 0) {
/* Attempt to report error */
fprintf(stderr, krb5_log_error_table(LOG_DEVICE_ERR),
+ log_control.log_whoami,
log_control.log_entries[lindex].ldu_devname);
}
break;
+#ifdef HAVE_SYSLOG
case K_LOG_SYSLOG:
/*
* System log.
*/
/* Log the message with our header trimmed off */
- syslog(priority, syslogp);
+ syslog(priority, "%s", syslogp);
break;
+#endif /* HAVE_SYSLOG */
default:
break;
}
diff --git a/usr/src/lib/krb5/kadm5/clnt/mapfile-vers b/usr/src/lib/krb5/kadm5/clnt/mapfile-vers
index 4ee6d71f5c..a796ee01ab 100644
--- a/usr/src/lib/krb5/kadm5/clnt/mapfile-vers
+++ b/usr/src/lib/krb5/kadm5/clnt/mapfile-vers
@@ -22,29 +22,28 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
#
SUNWprivate_1.1 {
global:
_kadm5_get_kpasswd_protocol;
- chpass_principal3_1;
- chpass_principal_1;
+ chpass_principal3_2;
+ chpass_principal_2;
chpw_error_message;
- chrand_principal3_1;
- chrand_principal_1;
- create_policy_1;
- create_principal3_1;
- create_principal_1;
- delete_policy_1;
- delete_principal_1;
+ chrand_principal3_2;
+ chrand_principal_2;
+ create_policy_2;
+ create_principal3_2;
+ create_principal_2;
+ delete_policy_2;
+ delete_principal_2;
display_status;
- get_policy_1;
- get_pols_1;
- get_principal_1;
- get_princs_1;
- get_privs_1;
- init_1;
+ get_policy_2;
+ get_pols_2;
+ get_principal_2;
+ get_princs_2;
+ get_privs_2;
+ init_2;
kadm5_chpass_principal;
kadm5_chpass_principal_3;
kadm5_chpass_principal_util;
@@ -106,16 +105,16 @@ SUNWprivate_1.1 {
krb5_klog_init;
krb5_klog_syslog;
krb5_log_error_table;
- krb5_mk_chpw_req;
- krb5_rd_chpw_rep;
+ krb5int_mk_chpw_req;
+ krb5int_rd_chpw_rep;
krb5_read_realm_params;
krb5_string_to_flags;
krb5_string_to_keysalts;
- modify_policy_1;
- modify_principal_1;
- rename_principal_1;
- setkey_principal3_1;
- setkey_principal_1;
+ modify_policy_2;
+ modify_principal_2;
+ rename_principal_2;
+ setkey_principal3_2;
+ setkey_principal_2;
xdr_chpass3_arg;
xdr_chpass_arg;
xdr_chrand3_arg;
diff --git a/usr/src/lib/krb5/kadm5/get_admhst.c b/usr/src/lib/krb5/kadm5/get_admhst.c
deleted file mode 100644
index 577abd2b8d..0000000000
--- a/usr/src/lib/krb5/kadm5/get_admhst.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
- *
- * Openvision retains the copyright to derivative works of
- * this source code. Do *NOT* create a derivative of this
- * source code before consulting with your legal department.
- * Do *NOT* integrate *ANY* of this source code into another
- * product before consulting with your legal department.
- *
- * For further information, read the top-level Openvision
- * copyright which is contained in the top-level MIT Kerberos
- * copyright.
- *
- * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
- *
- */
-
-
-/*
- * $Source: /afs/athena.mit.edu/astaff/project/krbdev/.cvsroot/src/lib/kadm5/get_admhst.c,v $
- * $Author: marc $
- *
- * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
- * of Technology.
- *
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
- */
-
-#ifndef lint
-static char *rcsid =
-"$Header: /cvs/krbdev/krb5/src/lib/kadm5/get_admhst.c,v 1.8 1996/07/22 20:36:00 marc Exp $";
-#endif /* lint */
-
-#include <stdio.h>
-#include <krb5/osconf.h>
-#include <string.h>
-
-/*
- * Given a Kerberos realm, find a host on which the Kerberos database
- * administration server can be found.
- *
- * krb5_get_admhst takes a pointer to be filled in, a pointer to the name
- * of the realm for which a server is desired, and an integer n, and
- * returns (in h) the nth administrative host entry from the configuration
- * file DEFAULT_CONFIG_FILENAME.
- *
- * If the realm is NULL, the default realm is used.
- *
- * On error, get_admhst returns 0. If all goes well, the routine
- * returns 1.
- *
- * This is a temporary hack to allow us to find the nearest system running
- * a Kerberos admin server. In the long run, this functionality will be
- * provided by a nameserver.
- */
-int
-krb5_get_admhst(char *h, char *r, int n)
-{
- FILE *cnffile;
- char *realm = NULL;
- char tr[BUFSIZ];
- char linebuf[BUFSIZ];
- char scratch[64];
- register int i;
- int ret;
-
- if(r == NULL) {
- if((ret = krb5_get_default_realm(&realm)) != 0)
- return ret;
- r = realm;
- }
- if ((cnffile = fopen(DEFAULT_CONFIG_FILENAME, "rF")) == NULL) {
- return(0);
- }
- if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
- /* error reading */
- (void) fclose(cnffile);
- return(0);
- }
- if (!strchr(linebuf, '\n')) {
- /* didn't all fit into buffer, punt */
- (void) fclose(cnffile);
- if(realm)
- free(realm);
- return(0);
- }
- for (i = 0; i < n; ) {
- /* run through the file, looking for admin host */
- if (fgets(linebuf, BUFSIZ, cnffile) == NULL) {
- (void) fclose(cnffile);
- if(realm)
- free(realm);
- return(0);
- }
- /* need to scan for a token after 'admin' to make sure that
- admin matched correctly */
- if (sscanf(linebuf, "%s %s admin %s", tr, h, scratch) != 3)
- continue;
- if (!strcmp(tr,r))
- i++;
- }
- (void) fclose(cnffile);
- if(realm)
- free(realm);
- return(1);
-}
diff --git a/usr/src/lib/krb5/kadm5/kadm_host_srv_names.c b/usr/src/lib/krb5/kadm5/kadm_host_srv_names.c
index 9abe0fe842..a6c15849fc 100644
--- a/usr/src/lib/krb5/kadm5/kadm_host_srv_names.c
+++ b/usr/src/lib/krb5/kadm5/kadm_host_srv_names.c
@@ -3,16 +3,17 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/kad5/kadm_host_srv_names.c
*/
+#include <k5-int.h>
#include "admin.h"
#include <stdio.h>
#include <os-proto.h>
+
#define KADM5_MASTER "admin_server"
#define KADM5_KPASSWD "kpasswd_server"
diff --git a/usr/src/lib/krb5/kadm5/kadm_rpc.h b/usr/src/lib/krb5/kadm5/kadm_rpc.h
index 9521c9f923..c204c8f6db 100644
--- a/usr/src/lib/krb5/kadm5/kadm_rpc.h
+++ b/usr/src/lib/krb5/kadm5/kadm_rpc.h
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
@@ -22,8 +20,8 @@
#include <rpc/types.h>
-#include <krb5.h>
#include <kadm5/admin.h>
+#include <krb5.h>
struct cprinc_arg {
krb5_ui_4 api_version;
@@ -32,7 +30,6 @@ struct cprinc_arg {
char *passwd;
};
typedef struct cprinc_arg cprinc_arg;
-bool_t xdr_cprinc_arg();
struct cprinc3_arg {
krb5_ui_4 api_version;
@@ -43,21 +40,18 @@ struct cprinc3_arg {
char *passwd;
};
typedef struct cprinc3_arg cprinc3_arg;
-bool_t xdr_cprinc3_arg();
struct generic_ret {
krb5_ui_4 api_version;
kadm5_ret_t code;
};
typedef struct generic_ret generic_ret;
-bool_t xdr_generic_ret();
struct dprinc_arg {
krb5_ui_4 api_version;
krb5_principal princ;
};
typedef struct dprinc_arg dprinc_arg;
-bool_t xdr_dprinc_arg();
struct mprinc_arg {
krb5_ui_4 api_version;
@@ -65,7 +59,6 @@ struct mprinc_arg {
long mask;
};
typedef struct mprinc_arg mprinc_arg;
-bool_t xdr_mprinc_arg();
struct rprinc_arg {
krb5_ui_4 api_version;
@@ -73,14 +66,12 @@ struct rprinc_arg {
krb5_principal dest;
};
typedef struct rprinc_arg rprinc_arg;
-bool_t xdr_rprinc_arg();
struct gprincs_arg {
krb5_ui_4 api_version;
char *exp;
};
typedef struct gprincs_arg gprincs_arg;
-bool_t xdr_gprincs_arg();
struct gprincs_ret {
krb5_ui_4 api_version;
@@ -89,7 +80,6 @@ struct gprincs_ret {
int count;
};
typedef struct gprincs_ret gprincs_ret;
-bool_t xdr_gprincs_ret();
struct chpass_arg {
krb5_ui_4 api_version;
@@ -97,7 +87,6 @@ struct chpass_arg {
char *pass;
};
typedef struct chpass_arg chpass_arg;
-bool_t xdr_chpass_arg();
struct chpass3_arg {
krb5_ui_4 api_version;
@@ -108,7 +97,6 @@ struct chpass3_arg {
char *pass;
};
typedef struct chpass3_arg chpass3_arg;
-bool_t xdr_chpass3_arg();
struct setv4key_arg {
krb5_ui_4 api_version;
@@ -116,7 +104,6 @@ struct setv4key_arg {
krb5_keyblock *keyblock;
};
typedef struct setv4key_arg setv4key_arg;
-bool_t xdr_setv4key_arg();
struct setkey_arg {
krb5_ui_4 api_version;
@@ -125,7 +112,6 @@ struct setkey_arg {
int n_keys;
};
typedef struct setkey_arg setkey_arg;
-bool_t xdr_setkey_arg();
struct setkey3_arg {
krb5_ui_4 api_version;
@@ -137,14 +123,12 @@ struct setkey3_arg {
int n_keys;
};
typedef struct setkey3_arg setkey3_arg;
-bool_t xdr_setkey3_arg();
struct chrand_arg {
krb5_ui_4 api_version;
krb5_principal princ;
};
typedef struct chrand_arg chrand_arg;
-bool_t xdr_chrand_arg();
struct chrand3_arg {
krb5_ui_4 api_version;
@@ -154,7 +138,6 @@ struct chrand3_arg {
krb5_key_salt_tuple *ks_tuple;
};
typedef struct chrand3_arg chrand3_arg;
-bool_t xdr_chrand3_arg();
struct chrand_ret {
krb5_ui_4 api_version;
@@ -164,7 +147,6 @@ struct chrand_ret {
int n_keys;
};
typedef struct chrand_ret chrand_ret;
-bool_t xdr_chrand_ret();
struct gprinc_arg {
krb5_ui_4 api_version;
@@ -172,7 +154,6 @@ struct gprinc_arg {
long mask;
};
typedef struct gprinc_arg gprinc_arg;
-bool_t xdr_gprinc_arg();
struct gprinc_ret {
krb5_ui_4 api_version;
@@ -180,16 +161,6 @@ struct gprinc_ret {
kadm5_principal_ent_rec rec;
};
typedef struct gprinc_ret gprinc_ret;
-bool_t xdr_gprinc_ret();
-bool_t xdr_kadm5_ret_t();
-bool_t xdr_kadm5_principal_ent_rec();
-bool_t xdr_kadm5_policy_ent_rec();
-bool_t xdr_krb5_keyblock();
-bool_t xdr_krb5_principal();
-bool_t xdr_krb5_enctype();
-bool_t xdr_krb5_octet();
-bool_t xdr_krb5_int32();
-bool_t xdr_u_int32();
struct cpol_arg {
krb5_ui_4 api_version;
@@ -197,14 +168,12 @@ struct cpol_arg {
long mask;
};
typedef struct cpol_arg cpol_arg;
-bool_t xdr_cpol_arg();
struct dpol_arg {
krb5_ui_4 api_version;
char *name;
};
typedef struct dpol_arg dpol_arg;
-bool_t xdr_dpol_arg();
struct mpol_arg {
krb5_ui_4 api_version;
@@ -212,14 +181,12 @@ struct mpol_arg {
long mask;
};
typedef struct mpol_arg mpol_arg;
-bool_t xdr_mpol_arg();
struct gpol_arg {
krb5_ui_4 api_version;
char *name;
};
typedef struct gpol_arg gpol_arg;
-bool_t xdr_gpol_arg();
struct gpol_ret {
krb5_ui_4 api_version;
@@ -227,14 +194,12 @@ struct gpol_ret {
kadm5_policy_ent_rec rec;
};
typedef struct gpol_ret gpol_ret;
-bool_t xdr_gpol_ret();
struct gpols_arg {
krb5_ui_4 api_version;
char *exp;
};
typedef struct gpols_arg gpols_arg;
-bool_t xdr_gpols_arg();
struct gpols_ret {
krb5_ui_4 api_version;
@@ -243,7 +208,6 @@ struct gpols_ret {
int count;
};
typedef struct gpols_ret gpols_ret;
-bool_t xdr_gpols_ret();
struct getprivs_ret {
krb5_ui_4 api_version;
@@ -251,104 +215,108 @@ struct getprivs_ret {
long privs;
};
typedef struct getprivs_ret getprivs_ret;
-bool_t xdr_getprivs_ret();
-
-#define KADM ((krb5_ui_4)2112)
-#define KADMVERS ((krb5_ui_4)2)
-#define CREATE_PRINCIPAL ((krb5_ui_4)1)
-extern generic_ret *create_principal_1_svc(cprinc_arg *arg,
- struct svc_req *rqstp);
-extern generic_ret *create_principal_1(cprinc_arg *argp, CLIENT *clnt);
-
-#define DELETE_PRINCIPAL ((krb5_ui_4)2)
-extern generic_ret *delete_principal_1_svc(dprinc_arg *arg,
- struct svc_req *rqstp);
-extern generic_ret *delete_principal_1(dprinc_arg *argp, CLIENT *clnt);
-
-#define MODIFY_PRINCIPAL ((krb5_ui_4)3)
-extern generic_ret *modify_principal_1_svc(mprinc_arg *arg,
- struct svc_req *rqstp);
-extern generic_ret *modify_principal_1(mprinc_arg *argp, CLIENT *clnt);
-
-#define RENAME_PRINCIPAL ((krb5_ui_4)4)
-extern generic_ret *rename_principal_1_svc(rprinc_arg *arg,
- struct svc_req *rqstp);
-extern generic_ret *rename_principal_1(rprinc_arg *argp, CLIENT *clnt);
-
-#define GET_PRINCIPAL ((krb5_ui_4)5)
-extern gprinc_ret *get_principal_1_svc(gprinc_arg *arg, struct svc_req *rqstp);
-extern gprinc_ret *get_principal_1(gprinc_arg *argp, CLIENT *clnt);
-
-#define CHPASS_PRINCIPAL ((krb5_ui_4)6)
-extern generic_ret *chpass_principal_1_svc(chpass_arg *arg,
- struct svc_req *rqstp);
-extern generic_ret *chpass_principal_1(chpass_arg *argp, CLIENT *clnt);
-
-#define CHRAND_PRINCIPAL ((krb5_ui_4)7)
-extern chrand_ret *chrand_principal_1_svc(chrand_arg *arg,
- struct svc_req *rqstp);
-extern chrand_ret *chrand_principal_1(chrand_arg *argp, CLIENT *clnt);
-
-#define CREATE_POLICY ((krb5_ui_4)8)
-extern generic_ret *create_policy_1_svc(cpol_arg *arg, struct svc_req *rqstp);
-extern generic_ret *create_policy_1(cpol_arg *argp, CLIENT *clnt);
-
-#define DELETE_POLICY ((krb5_ui_4)9)
-extern generic_ret *delete_policy_1_svc(dpol_arg *arg, struct svc_req *rqstp);
-extern generic_ret *delete_policy_1(dpol_arg *argp, CLIENT *clnt);
-
-#define MODIFY_POLICY ((krb5_ui_4)10)
-extern generic_ret *modify_policy_1_svc(mpol_arg *arg, struct svc_req *rqstp);
-extern generic_ret *modify_policy_1(mpol_arg *argp, CLIENT *clnt);
-
-#define GET_POLICY ((krb5_ui_4)11)
-extern gpol_ret *get_policy_1_svc(gpol_arg *arg, struct svc_req *rqstp);
-extern gpol_ret *get_policy_1(gpol_arg *argp, CLIENT *clnt);
-
-#define GET_PRIVS ((krb5_ui_4)12)
-extern getprivs_ret *get_privs_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp);
-extern getprivs_ret *get_privs_1(void *argp, CLIENT *clnt);
-
-#define INIT ((krb5_ui_4)13)
-extern generic_ret *init_1_svc(krb5_ui_4 *arg, struct svc_req *rqstp);
-extern generic_ret *init_1();
-
-#define GET_PRINCS ((krb5_ui_4) 14)
-extern gprincs_ret *get_princs_1_svc(gprincs_arg *arg, struct svc_req *rqstp);
-extern gprincs_ret *get_princs_1(gprincs_arg *argp, CLIENT *clnt);
-
-#define GET_POLS ((krb5_ui_4) 15)
-extern gpols_ret *get_pols_1_svc(gpols_arg *arg, struct svc_req *rqstp);
-extern gpols_ret *get_pols_1(gpols_arg *argp, CLIENT *clnt);
-
-#define SETKEY_PRINCIPAL ((krb5_ui_4) 16)
-extern generic_ret *setkey_principal_1_svc(setkey_arg *arg,
- struct svc_req *rqstp);
-extern generic_ret *setkey_principal_1(setkey_arg *argp, CLIENT *clnt);
-
-#define SETV4KEY_PRINCIPAL ((krb5_ui_4) 17)
-extern generic_ret *setv4key_principal_1_svc(setv4key_arg *arg,
- struct svc_req *rqstp);
-extern generic_ret *setv4key_principal_1(setv4key_arg *argp, CLIENT *clnt);
-
-#define CREATE_PRINCIPAL3 ((krb5_ui_4) 18)
-extern generic_ret *create_principal3_1_svc(cprinc3_arg *arg,
- struct svc_req *rqstp);
-extern generic_ret *create_principal3_1(cprinc3_arg *argp, CLIENT *clnt);
-
-#define CHPASS_PRINCIPAL3 ((krb5_ui_4) 19)
-extern generic_ret *chpass_principal3_1_svc(chpass3_arg *arg,
- struct svc_req *rqstp);
-extern generic_ret *chpass_principal3_1(chpass3_arg *argp, CLIENT *clnt);
-
-#define CHRAND_PRINCIPAL3 ((krb5_ui_4) 20)
-extern chrand_ret *chrand_principal3_1_svc(chrand3_arg *arg,
- struct svc_req *rqstp);
-extern chrand_ret *chrand_principal3_1(chrand3_arg *argp, CLIENT *clnt);
-
-#define SETKEY_PRINCIPAL3 ((krb5_ui_4) 21)
-extern generic_ret *setkey_principal3_1_svc(setkey3_arg *arg,
- struct svc_req *rqstp);
-extern generic_ret *setkey_principal3_1(setkey3_arg *argp, CLIENT *clnt);
+
+#define KADM 2112
+#define KADMVERS 2
+#define CREATE_PRINCIPAL 1
+extern generic_ret * create_principal_2(cprinc_arg *, CLIENT *);
+extern generic_ret * create_principal_2_svc(cprinc_arg *, struct svc_req *);
+#define DELETE_PRINCIPAL 2
+extern generic_ret * delete_principal_2(dprinc_arg *, CLIENT *);
+extern generic_ret * delete_principal_2_svc(dprinc_arg *, struct svc_req *);
+#define MODIFY_PRINCIPAL 3
+extern generic_ret * modify_principal_2(mprinc_arg *, CLIENT *);
+extern generic_ret * modify_principal_2_svc(mprinc_arg *, struct svc_req *);
+#define RENAME_PRINCIPAL 4
+extern generic_ret * rename_principal_2(rprinc_arg *, CLIENT *);
+extern generic_ret * rename_principal_2_svc(rprinc_arg *, struct svc_req *);
+#define GET_PRINCIPAL 5
+extern gprinc_ret * get_principal_2(gprinc_arg *, CLIENT *);
+extern gprinc_ret * get_principal_2_svc(gprinc_arg *, struct svc_req *);
+#define CHPASS_PRINCIPAL 6
+extern generic_ret * chpass_principal_2(chpass_arg *, CLIENT *);
+extern generic_ret * chpass_principal_2_svc(chpass_arg *, struct svc_req *);
+#define CHRAND_PRINCIPAL 7
+extern chrand_ret * chrand_principal_2(chrand_arg *, CLIENT *);
+extern chrand_ret * chrand_principal_2_svc(chrand_arg *, struct svc_req *);
+#define CREATE_POLICY 8
+extern generic_ret * create_policy_2(cpol_arg *, CLIENT *);
+extern generic_ret * create_policy_2_svc(cpol_arg *, struct svc_req *);
+#define DELETE_POLICY 9
+extern generic_ret * delete_policy_2(dpol_arg *, CLIENT *);
+extern generic_ret * delete_policy_2_svc(dpol_arg *, struct svc_req *);
+#define MODIFY_POLICY 10
+extern generic_ret * modify_policy_2(mpol_arg *, CLIENT *);
+extern generic_ret * modify_policy_2_svc(mpol_arg *, struct svc_req *);
+#define GET_POLICY 11
+extern gpol_ret * get_policy_2(gpol_arg *, CLIENT *);
+extern gpol_ret * get_policy_2_svc(gpol_arg *, struct svc_req *);
+#define GET_PRIVS 12
+extern getprivs_ret * get_privs_2(void *, CLIENT *);
+extern getprivs_ret * get_privs_2_svc(krb5_ui_4 *, struct svc_req *);
+#define INIT 13
+extern generic_ret * init_2(void *, CLIENT *);
+extern generic_ret * init_2_svc(krb5_ui_4 *, struct svc_req *);
+#define GET_PRINCS 14
+extern gprincs_ret * get_princs_2(gprincs_arg *, CLIENT *);
+extern gprincs_ret * get_princs_2_svc(gprincs_arg *, struct svc_req *);
+#define GET_POLS 15
+extern gpols_ret * get_pols_2(gpols_arg *, CLIENT *);
+extern gpols_ret * get_pols_2_svc(gpols_arg *, struct svc_req *);
+#define SETKEY_PRINCIPAL 16
+extern generic_ret * setkey_principal_2(setkey_arg *, CLIENT *);
+extern generic_ret * setkey_principal_2_svc(setkey_arg *, struct svc_req *);
+#define SETV4KEY_PRINCIPAL 17
+extern generic_ret * setv4key_principal_2(setv4key_arg *, CLIENT *);
+extern generic_ret * setv4key_principal_2_svc(setv4key_arg *, struct svc_req *);
+#define CREATE_PRINCIPAL3 18
+extern generic_ret * create_principal3_2(cprinc3_arg *, CLIENT *);
+extern generic_ret * create_principal3_2_svc(cprinc3_arg *, struct svc_req *);
+#define CHPASS_PRINCIPAL3 19
+extern generic_ret * chpass_principal3_2(chpass3_arg *, CLIENT *);
+extern generic_ret * chpass_principal3_2_svc(chpass3_arg *, struct svc_req *);
+#define CHRAND_PRINCIPAL3 20
+extern chrand_ret * chrand_principal3_2(chrand3_arg *, CLIENT *);
+extern chrand_ret * chrand_principal3_2_svc(chrand3_arg *, struct svc_req *);
+#define SETKEY_PRINCIPAL3 21
+extern generic_ret * setkey_principal3_2(setkey3_arg *, CLIENT *);
+extern generic_ret * setkey_principal3_2_svc(setkey3_arg *, struct svc_req *);
+
+extern bool_t xdr_cprinc_arg ();
+extern bool_t xdr_cprinc3_arg ();
+extern bool_t xdr_generic_ret ();
+extern bool_t xdr_dprinc_arg ();
+extern bool_t xdr_mprinc_arg ();
+extern bool_t xdr_rprinc_arg ();
+extern bool_t xdr_gprincs_arg ();
+extern bool_t xdr_gprincs_ret ();
+extern bool_t xdr_chpass_arg ();
+extern bool_t xdr_chpass3_arg ();
+extern bool_t xdr_setv4key_arg ();
+extern bool_t xdr_setkey_arg ();
+extern bool_t xdr_setkey3_arg ();
+extern bool_t xdr_chrand_arg ();
+extern bool_t xdr_chrand3_arg ();
+extern bool_t xdr_chrand_ret ();
+extern bool_t xdr_gprinc_arg ();
+extern bool_t xdr_gprinc_ret ();
+extern bool_t xdr_kadm5_ret_t ();
+extern bool_t xdr_kadm5_principal_ent_rec ();
+extern bool_t xdr_kadm5_policy_ent_rec ();
+extern bool_t xdr_krb5_keyblock ();
+extern bool_t xdr_krb5_principal ();
+extern bool_t xdr_krb5_enctype ();
+extern bool_t xdr_krb5_octet ();
+extern bool_t xdr_krb5_int32 ();
+extern bool_t xdr_u_int32 ();
+extern bool_t xdr_cpol_arg ();
+extern bool_t xdr_dpol_arg ();
+extern bool_t xdr_mpol_arg ();
+extern bool_t xdr_gpol_arg ();
+extern bool_t xdr_gpol_ret ();
+extern bool_t xdr_gpols_arg ();
+extern bool_t xdr_gpols_ret ();
+extern bool_t xdr_getprivs_ret ();
+
#endif /* __KADM_RPC_H__ */
diff --git a/usr/src/lib/krb5/kadm5/kadm_rpc_xdr.c b/usr/src/lib/krb5/kadm5/kadm_rpc_xdr.c
index d9d5697458..c4600dbee6 100644
--- a/usr/src/lib/krb5/kadm5/kadm_rpc_xdr.c
+++ b/usr/src/lib/krb5/kadm5/kadm_rpc_xdr.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -28,10 +27,10 @@
*/
#include <rpc/rpc.h>
-#include <krb5.h>
-#include <k5-int.h>
+#include <errno.h>
#include <kadm5/admin.h>
#include <kadm5/kadm_rpc.h>
+#include <krb5.h>
#include <stdlib.h>
#include <string.h>
@@ -571,6 +570,7 @@ xdr_generic_ret(XDR *xdrs, generic_ret *objp)
if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
return (FALSE);
}
+
return(TRUE);
}
@@ -653,6 +653,7 @@ xdr_gprincs_ret(XDR *xdrs, gprincs_ret *objp)
return (FALSE);
}
}
+
return (TRUE);
}
@@ -812,7 +813,7 @@ xdr_chrand_ret(XDR *xdrs, chrand_ret *objp)
return FALSE;
}
}
-
+
return (TRUE);
}
@@ -853,6 +854,7 @@ xdr_gprinc_ret(XDR *xdrs, gprinc_ret *objp)
}
}
}
+
return (TRUE);
}
@@ -923,6 +925,7 @@ xdr_gpol_ret(XDR *xdrs, gpol_ret *objp)
if (!xdr_kadm5_policy_ent_rec(xdrs, &objp->rec))
return (FALSE);
}
+
return (TRUE);
}
@@ -957,6 +960,7 @@ xdr_gpols_ret(XDR *xdrs, gpols_ret *objp)
return (FALSE);
}
}
+
return (TRUE);
}
@@ -968,6 +972,7 @@ bool_t xdr_getprivs_ret(XDR *xdrs, getprivs_ret *objp)
if (! xdr_kadm5_ret_t(xdrs, &objp->code) ||
! xdr_long(xdrs, &objp->privs))
return FALSE;
+
return TRUE;
}
@@ -983,7 +988,7 @@ xdr_krb5_principal(XDR *xdrs, krb5_principal *objp)
ok, and the other solutions are even uglier */
if (!context &&
- krb5_init_context(&context))
+ kadm5_init_krb5_context(&context))
return(FALSE);
switch(xdrs->x_op) {
@@ -1045,7 +1050,7 @@ xdr_krb5_enctype(XDR *xdrs, krb5_enctype *objp)
bool_t
xdr_krb5_salttype(XDR *xdrs, krb5_int32 *objp)
{
- if (!xdr_int(xdrs, (int32_t *) objp)) /* SUNWresync121 XXX */
+ if (!xdr_int(xdrs, (int32_t *) objp))
return FALSE;
return TRUE;
}
diff --git a/usr/src/lib/krb5/kadm5/misc_free.c b/usr/src/lib/krb5/kadm5/misc_free.c
index 53c5ae5562..0a064b6872 100644
--- a/usr/src/lib/krb5/kadm5/misc_free.c
+++ b/usr/src/lib/krb5/kadm5/misc_free.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
@@ -21,15 +19,15 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/misc_free.c,v 1.18 1997/05/28 17:35:05 bjaspan Exp $
+ * $Header$
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/misc_free.c,v 1.18 1997/05/28 17:35:05 bjaspan Exp $";
+static char *rcsid = "$Header$";
#endif
+#include "server_internal.h"
#include <kadm5/admin.h>
#include <stdlib.h>
-#include "server_internal.h"
kadm5_ret_t
kadm5_free_policy_ent(void *server_handle, kadm5_policy_ent_t val)
diff --git a/usr/src/lib/krb5/kadm5/server_internal.h b/usr/src/lib/krb5/kadm5/server_internal.h
index 3a0303e2ce..e87268aa0c 100644
--- a/usr/src/lib/krb5/kadm5/server_internal.h
+++ b/usr/src/lib/krb5/kadm5/server_internal.h
@@ -1,8 +1,7 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -25,7 +24,7 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/server_internal.h,v 1.31 2001/07/08 12:24:56 epeisach Exp $
+ * $Header$
*/
/*
@@ -41,6 +40,7 @@
#include <memory.h>
#endif
#include <stdlib.h>
+#include <errno.h>
#include "k5-int.h"
#include <krb5/kdb.h>
#include <kadm5/admin.h>
@@ -55,7 +55,7 @@ typedef struct _kadm5_server_handle_t {
krb5_principal current_caller;
kadm5_config_params params;
struct _kadm5_server_handle_t *lhandle;
- char **db_args;
+ char **db_args;
krb5_keyblock master_keyblock;
} kadm5_server_handle_rec, *kadm5_server_handle_t;
@@ -76,6 +76,7 @@ typedef struct _osa_princ_ent_t {
osa_pw_hist_ent *old_keys;
} osa_princ_ent_rec, *osa_princ_ent_t;
+
kadm5_ret_t adb_policy_init(kadm5_server_handle_t handle);
kadm5_ret_t adb_policy_close(kadm5_server_handle_t handle);
kadm5_ret_t passwd_check(kadm5_server_handle_t handle,
@@ -96,7 +97,8 @@ krb5_error_code kdb_put_entry(kadm5_server_handle_t handle,
krb5_db_entry *kdb, osa_princ_ent_rec *adb);
krb5_error_code kdb_delete_entry(kadm5_server_handle_t handle,
krb5_principal name);
-krb5_error_code kdb_iter_entry(kadm5_server_handle_t handle, char *,
+krb5_error_code kdb_iter_entry(kadm5_server_handle_t handle,
+ char *match_entry,
void (*iter_fct)(void *, krb5_principal),
void *data);
@@ -161,4 +163,5 @@ bool_t xdr_osa_princ_ent_rec(XDR *xdrs, osa_princ_ent_t objp);
void
osa_free_princ_ent(osa_princ_ent_t val);
+
#endif /* __KADM5_SERVER_INTERNAL_H__ */
diff --git a/usr/src/lib/krb5/kadm5/srv/adb_xdr.c b/usr/src/lib/krb5/kadm5/srv/adb_xdr.c
index 7b554d72f1..cb5e4e705f 100644
--- a/usr/src/lib/krb5/kadm5/srv/adb_xdr.c
+++ b/usr/src/lib/krb5/kadm5/srv/adb_xdr.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -26,17 +25,17 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/adb_xdr.c,v 1.4 2001/07/25 19:03:35 epeisach Exp $
+ * $Header$
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/adb_xdr.c,v 1.2 1998/02/14 02:31:34 tlyu Exp $";
+static char *rcsid = "$Header$";
#endif
#include <sys/types.h>
+#include "server_internal.h"
#include <krb5.h>
#include <rpc/rpc.h> /* SUNWresync121 XXX */
-#include "server_internal.h"
#include "admin_xdr.h"
#ifdef HAVE_MEMORY_H
#include <memory.h>
@@ -133,3 +132,4 @@ osa_free_princ_ent(osa_princ_ent_t val)
xdr_osa_princ_ent_rec(&xdrs, val);
free(val);
}
+
diff --git a/usr/src/lib/krb5/kadm5/srv/logger.c b/usr/src/lib/krb5/kadm5/srv/logger.c
index 1887746824..8722275935 100644
--- a/usr/src/lib/krb5/kadm5/srv/logger.c
+++ b/usr/src/lib/krb5/kadm5/srv/logger.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/kadm/logger.c
*
@@ -31,7 +30,6 @@
*
*/
-
/* KADM5 wants non-syslog log files to contain syslog-like entries */
#define VERBOSE_LOGS
@@ -44,8 +42,14 @@
#include <stdio.h>
#include <ctype.h>
#include <ctype.h>
+#ifdef HAVE_SYSLOG_H
#include <syslog.h>
+#endif /* HAVE_SYSLOG_H */
+#ifdef HAVE_STDARG_H
#include <stdarg.h>
+#else /* HAVE_STDARG_H */
+#include <varargs.h>
+#endif /* HAVE_STDARG_H */
#include <libintl.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -201,7 +205,6 @@ struct log_control {
char *log_whoami;
char *log_hostname;
krb5_boolean log_opened;
-
};
static struct log_control log_control = {
@@ -357,16 +360,14 @@ klog_rotate(struct log_entry *le)
*/
static krb5_context err_context;
static void
-klog_com_err_proc(whoami, code, format, ap)
- const char *whoami;
- long code;
- const char *format;
- va_list ap;
+klog_com_err_proc(const char *whoami, long code, const char *format, va_list ap)
{
char outbuf[KRB5_KLOG_MAX_ERRMSG_SIZE];
int lindex;
- char *actual_format;
+ const char *actual_format;
+#ifdef HAVE_SYSLOG
int log_pri = -1;
+#endif /* HAVE_SYSLOG */
char *cp;
char *syslogp;
@@ -380,17 +381,19 @@ klog_com_err_proc(whoami, code, format, ap)
/* If reporting an error message, separate it. */
if (code) {
+ /* Solaris Kerberos */
const char *emsg;
outbuf[sizeof(outbuf) - 1] = '\0';
emsg = krb5_get_error_message (err_context, code);
strncat(outbuf, emsg, sizeof(outbuf) - 1 - strlen(outbuf));
- strncat(outbuf, " ", sizeof(outbuf) - 1 - strlen(outbuf));
+ strncat(outbuf, " - ", sizeof(outbuf) - 1 - strlen(outbuf));
krb5_free_error_message(err_context, emsg);
}
cp = &outbuf[strlen(outbuf)];
- actual_format = (char *) format;
+ actual_format = format;
+#ifdef HAVE_SYSLOG
/*
* This is an unpleasant hack. If the first character is less than
* 8, then we assume that it is a priority.
@@ -400,38 +403,61 @@ klog_com_err_proc(whoami, code, format, ap)
* intermediate representation.
*/
if ((((unsigned char) *format) > 0) && (((unsigned char) *format) <= 8)) {
- actual_format = (char *) (format + 1);
+ actual_format = (format + 1);
switch ((unsigned char) *format) {
+#ifdef LOG_EMERG
case 1:
log_pri = LOG_EMERG;
break;
+#endif /* LOG_EMERG */
+#ifdef LOG_ALERT
case 2:
log_pri = LOG_ALERT;
break;
+#endif /* LOG_ALERT */
+#ifdef LOG_CRIT
case 3:
log_pri = LOG_CRIT;
break;
+#endif /* LOG_CRIT */
default:
case 4:
log_pri = LOG_ERR;
break;
+#ifdef LOG_WARNING
case 5:
log_pri = LOG_WARNING;
break;
+#endif /* LOG_WARNING */
+#ifdef LOG_NOTICE
case 6:
log_pri = LOG_NOTICE;
break;
+#endif /* LOG_NOTICE */
+#ifdef LOG_INFO
case 7:
log_pri = LOG_INFO;
break;
+#endif /* LOG_INFO */
+#ifdef LOG_DEBUG
case 8:
log_pri = LOG_DEBUG;
break;
+#endif /* LOG_DEBUG */
}
}
+#endif /* HAVE_SYSLOG */
/* Now format the actual message */
- vsnprintf(cp, sizeof (outbuf) - (cp - outbuf), actual_format, ap);
+#if HAVE_VSNPRINTF
+ vsnprintf(cp, sizeof(outbuf) - (cp - outbuf), actual_format, ap);
+#elif HAVE_VSPRINTF
+ vsprintf(cp, actual_format, ap);
+#else /* HAVE_VSPRINTF */
+ sprintf(cp, actual_format, ((int *) ap)[0], ((int *) ap)[1],
+ ((int *) ap)[2], ((int *) ap)[3],
+ ((int *) ap)[4], ((int *) ap)[5]);
+#endif /* HAVE_VSPRINTF */
/*
* Now that we have the message formatted, perform the output to each
@@ -469,6 +495,7 @@ klog_com_err_proc(whoami, code, format, ap)
log_control.log_entries[lindex].ldu_devname);
}
break;
+#ifdef HAVE_SYSLOG
case K_LOG_SYSLOG:
/*
* System log.
@@ -486,6 +513,7 @@ klog_com_err_proc(whoami, code, format, ap)
/* Log the message with our header trimmed off */
syslog(log_pri, "%s", syslogp);
break;
+#endif /* HAVE_SYSLOG */
default:
break;
}
@@ -514,18 +542,14 @@ klog_com_err_proc(whoami, code, format, ap)
* where/how to send output.
*/
krb5_error_code
-krb5_klog_init(kcontext, ename, whoami, do_com_err)
- krb5_context kcontext;
- char *ename;
- char *whoami;
- krb5_boolean do_com_err;
+krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do_com_err)
{
const char *logging_profent[3];
const char *logging_defent[3];
char **logging_specs;
int i, ngood;
char *cp, *cp2;
- char savec;
+ char savec = '\0';
int error;
int do_openlog, log_facility;
FILE *f;
@@ -580,9 +604,9 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
* <whitespace><data><whitespace>
* so, trim off the leading and trailing whitespace here.
*/
- for (cp = logging_specs[i]; isspace(*cp); cp++);
+ for (cp = logging_specs[i]; isspace((int) *cp); cp++);
for (cp2 = &logging_specs[i][strlen(logging_specs[i])-1];
- isspace(*cp2); cp2--);
+ isspace((int) *cp2); cp2--);
cp2++;
*cp2 = '\0';
/*
@@ -652,12 +676,13 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
}
} else {
- fprintf(stderr,gettext("Couldn't open log file %s: %s\n"),
+ fprintf(stderr, gettext("Couldn't open log file %s: %s\n"),
&cp[5], error_message(errno));
continue;
}
}
}
+#ifdef HAVE_SYSLOG
/*
* Is this a syslog?
*/
@@ -672,7 +697,8 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
/*
* Find the end of the severity.
*/
- if (cp2 = strchr(&cp[7], ':')) {
+ cp2 = strchr(&cp[7], ':');
+ if (cp2) {
savec = *cp2;
*cp2 = '\0';
cp2++;
@@ -684,32 +710,46 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
if (!strcasecmp(&cp[7], "ERR")) {
log_control.log_entries[i].lsu_severity = LOG_ERR;
}
+#ifdef LOG_EMERG
else if (!strcasecmp(&cp[7], "EMERG")) {
log_control.log_entries[i].lsu_severity =
LOG_EMERG;
}
+#endif /* LOG_EMERG */
+#ifdef LOG_ALERT
else if (!strcasecmp(&cp[7], "ALERT")) {
log_control.log_entries[i].lsu_severity =
LOG_ALERT;
}
+#endif /* LOG_ALERT */
+#ifdef LOG_CRIT
else if (!strcasecmp(&cp[7], "CRIT")) {
log_control.log_entries[i].lsu_severity = LOG_CRIT;
}
+#endif /* LOG_CRIT */
+#ifdef LOG_WARNING
else if (!strcasecmp(&cp[7], "WARNING")) {
log_control.log_entries[i].lsu_severity =
LOG_WARNING;
}
+#endif /* LOG_WARNING */
+#ifdef LOG_NOTICE
else if (!strcasecmp(&cp[7], "NOTICE")) {
log_control.log_entries[i].lsu_severity =
LOG_NOTICE;
}
+#endif /* LOG_NOTICE */
+#ifdef LOG_INFO
else if (!strcasecmp(&cp[7], "INFO")) {
log_control.log_entries[i].lsu_severity = LOG_INFO;
}
+#endif /* LOG_INFO */
+#ifdef LOG_DEBUG
else if (!strcasecmp(&cp[7], "DEBUG")) {
log_control.log_entries[i].lsu_severity =
LOG_DEBUG;
}
+#endif /* LOG_DEBUG */
else
error = 1;
@@ -778,12 +818,14 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
log_facility = log_control.log_entries[i].lsu_facility;
}
}
+#endif /* HAVE_SYSLOG */
/*
* Is this a standard error specification?
*/
else if (!strcasecmp(cp, "STDERR")) {
- if (log_control.log_entries[i].lfu_filep =
- fdopen(fileno(stderr), "a+F")) {
+ log_control.log_entries[i].lfu_filep =
+ fdopen(fileno(stderr), "a+F");
+ if (log_control.log_entries[i].lfu_filep) {
log_control.log_entries[i].log_type = K_LOG_STDERR;
log_control.log_entries[i].lfu_fname =
"standard error";
@@ -793,8 +835,9 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
* Is this a specification of the console?
*/
else if (!strcasecmp(cp, "CONSOLE")) {
- if (log_control.log_entries[i].ldu_filep =
- CONSOLE_OPEN("a+F")) {
+ log_control.log_entries[i].ldu_filep =
+ CONSOLE_OPEN("a+F");
+ if (log_control.log_entries[i].ldu_filep) {
log_control.log_entries[i].log_type = K_LOG_CONSOLE;
log_control.log_entries[i].ldu_devname = "console";
}
@@ -807,8 +850,9 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
* We handle devices very similarly to files.
*/
if (cp[6] == '=') {
- if (log_control.log_entries[i].ldu_filep =
- DEVICE_OPEN(&cp[7], "wF")) {
+ log_control.log_entries[i].ldu_filep =
+ DEVICE_OPEN(&cp[7], "wF");
+ if (log_control.log_entries[i].ldu_filep) {
log_control.log_entries[i].log_type = K_LOG_DEVICE;
log_control.log_entries[i].ldu_devname = &cp[7];
}
@@ -850,14 +894,21 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
log_control.log_nentries = 1;
}
if (log_control.log_nentries) {
- if (log_control.log_whoami = (char *) malloc(strlen(whoami)+1))
+ log_control.log_whoami = (char *) malloc(strlen(whoami)+1);
+ if (log_control.log_whoami)
strcpy(log_control.log_whoami, whoami);
- if (log_control.log_hostname = (char *) malloc(MAXHOSTNAMELEN))
+
+ log_control.log_hostname = (char *) malloc(MAXHOSTNAMELEN + 1);
+ if (log_control.log_hostname) {
gethostname(log_control.log_hostname, MAXHOSTNAMELEN);
+ log_control.log_hostname[MAXHOSTNAMELEN] = '\0';
+ }
+#ifdef HAVE_OPENLOG
if (do_openlog) {
openlog(whoami, LOG_NDELAY|LOG_PID, log_facility);
log_control.log_opened = 1;
}
+#endif /* HAVE_OPENLOG */
if (do_com_err)
(void) set_com_err_hook(klog_com_err_proc);
}
@@ -868,8 +919,7 @@ krb5_klog_init(kcontext, ename, whoami, do_com_err)
* krb5_klog_close() - Close the logging context and free all data.
*/
void
-krb5_klog_close(kcontext)
- krb5_context kcontext;
+krb5_klog_close(krb5_context kcontext)
{
int lindex;
(void) reset_com_err_hook();
@@ -889,11 +939,13 @@ krb5_klog_close(kcontext)
*/
DEVICE_CLOSE(log_control.log_entries[lindex].ldu_filep);
break;
+#ifdef HAVE_SYSLOG
case K_LOG_SYSLOG:
/*
* System log.
*/
break;
+#endif /* HAVE_SYSLOG */
default:
break;
}
@@ -910,16 +962,17 @@ krb5_klog_close(kcontext)
if (log_control.log_hostname)
free(log_control.log_hostname);
log_control.log_hostname = (char *) NULL;
+#ifdef HAVE_CLOSELOG
if (log_control.log_opened)
closelog();
+#endif /* HAVE_CLOSELOG */
}
/*
* severity2string() - Convert a severity to a string.
*/
-static char *
-severity2string(severity)
- int severity;
+static const char *
+severity2string(int severity)
{
int s;
const char *ss;
@@ -927,30 +980,44 @@ severity2string(severity)
s = severity & LOG_PRIMASK;
ss = krb5_log_error_table(LOG_UFO_STRING);
switch (s) {
+#ifdef LOG_EMERG
case LOG_EMERG:
ss = krb5_log_error_table(LOG_EMERG_STRING);
break;
+#endif /* LOG_EMERG */
+#ifdef LOG_ALERT
case LOG_ALERT:
ss = krb5_log_error_table(LOG_ALERT_STRING);
break;
+#endif /* LOG_ALERT */
+#ifdef LOG_CRIT
case LOG_CRIT:
ss = krb5_log_error_table(LOG_CRIT_STRING);
break;
+#endif /* LOG_CRIT */
case LOG_ERR:
ss = krb5_log_error_table(LOG_ERR_STRING);
break;
+#ifdef LOG_WARNING
case LOG_WARNING:
ss = krb5_log_error_table(LOG_WARNING_STRING);
break;
+#endif /* LOG_WARNING */
+#ifdef LOG_NOTICE
case LOG_NOTICE:
ss = krb5_log_error_table(LOG_NOTICE_STRING);
break;
+#endif /* LOG_NOTICE */
+#ifdef LOG_INFO
case LOG_INFO:
ss = krb5_log_error_table(LOG_INFO_STRING);
break;
+#endif /* LOG_INFO */
+#ifdef LOG_DEBUG
case LOG_DEBUG:
ss = krb5_log_error_table(LOG_DEBUG_STRING);
break;
+#endif /* LOG_DEBUG */
}
return((char *) ss);
}
@@ -961,17 +1028,16 @@ severity2string(severity)
* by krb5_klog_init().
*/
static int
-klog_vsyslog(priority, format, arglist)
- int priority;
- const char *format;
- va_list arglist;
+klog_vsyslog(int priority, const char *format, va_list arglist)
{
char outbuf[KRB5_KLOG_MAX_ERRMSG_SIZE];
int lindex;
char *syslogp;
char *cp;
time_t now;
+#ifdef HAVE_STRFTIME
size_t soff;
+#endif /* HAVE_STRFTIME */
/*
* Format a syslog-esque message of the format:
@@ -984,6 +1050,7 @@ klog_vsyslog(priority, format, arglist)
*/
cp = outbuf;
(void) time(&now);
+#ifdef HAVE_STRFTIME
/*
* Format the date: mon dd hh:mm:ss
*/
@@ -992,6 +1059,16 @@ klog_vsyslog(priority, format, arglist)
cp += soff;
else
return(-1);
+#else /* HAVE_STRFTIME */
+ /*
+ * Format the date:
+ * We ASSUME here that the output of ctime is of the format:
+ * dow mon dd hh:mm:ss tzs yyyy\n
+ * 012345678901234567890123456789
+ */
+ strncpy(outbuf, ctime(&now) + 4, 15);
+ cp += 15;
+#endif /* HAVE_STRFTIME */
#ifdef VERBOSE_LOGS
sprintf(cp, " %s %s[%ld](%s): ",
log_control.log_hostname, log_control.log_whoami, (long) getpid(),
@@ -1002,7 +1079,26 @@ klog_vsyslog(priority, format, arglist)
syslogp = &outbuf[strlen(outbuf)];
/* Now format the actual message */
- vsnprintf(syslogp, sizeof (outbuf) - (syslogp - outbuf), format, arglist);
+#ifdef HAVE_VSNPRINTF
+ vsnprintf(syslogp, sizeof(outbuf) - (syslogp - outbuf), format, arglist);
+#elif HAVE_VSPRINTF
+ vsprintf(syslogp, format, arglist);
+#else /* HAVE_VSPRINTF */
+ sprintf(syslogp, format, ((int *) arglist)[0], ((int *) arglist)[1],
+ ((int *) arglist)[2], ((int *) arglist)[3],
+ ((int *) arglist)[4], ((int *) arglist)[5]);
+#endif /* HAVE_VSPRINTF */
+
+ /*
+ * If the user did not use krb5_klog_init() instead of dropping
+ * the request on the floor, syslog it - if it exists
+ */
+#ifdef HAVE_SYSLOG
+ if (log_control.log_nentries == 0) {
+ /* Log the message with our header trimmed off */
+ syslog(priority, "%s", syslogp);
+ }
+#endif
/*
* Now that we have the message formatted, perform the output to each
@@ -1042,6 +1138,7 @@ klog_vsyslog(priority, format, arglist)
log_control.log_entries[lindex].ldu_devname);
}
break;
+#ifdef HAVE_SYSLOG
case K_LOG_SYSLOG:
/*
* System log.
@@ -1050,6 +1147,7 @@ klog_vsyslog(priority, format, arglist)
/* Log the message with our header trimmed off */
syslog(priority, "%s", syslogp);
break;
+#endif /* HAVE_SYSLOG */
default:
break;
}
@@ -1077,8 +1175,7 @@ krb5_klog_syslog(int priority, const char *format, ...)
* a new file descriptor for the give filename.
*/
void
-krb5_klog_reopen(kcontext)
-krb5_context kcontext;
+krb5_klog_reopen(krb5_context kcontext)
{
int lindex;
FILE *f;
diff --git a/usr/src/lib/krb5/kadm5/srv/server_acl.c b/usr/src/lib/krb5/kadm5/srv/server_acl.c
index df25e8ad65..513a65dacb 100644
--- a/usr/src/lib/krb5/kadm5/srv/server_acl.c
+++ b/usr/src/lib/krb5/kadm5/srv/server_acl.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -56,8 +55,8 @@
#include <stdio.h>
#include <syslog.h>
#include <sys/param.h>
-#include <gssapi_krb5.h>
#include "k5-int.h"
+#include <gssapi_krb5.h>
#include <kadm5/server_internal.h>
#include <kadm5/admin.h>
#include <adm_proto.h> /* SUNWresync121 XXX */
@@ -118,6 +117,7 @@ static int acl_debug_level = 0;
*/
static const char *acl_catchall_entry = NULL;
+/* Solaris Kerberos */
#define ACL_LINE2LONG_MSG dgettext(TEXT_DOMAIN, \
"%s: line %d too long, truncated\n")
#define ACL_OP_BAD_MSG dgettext(TEXT_DOMAIN, \
@@ -229,7 +229,7 @@ kadm5int_acl_parse_line(lp)
for (op=acle_ops; *op; op++) {
char rop;
- rop = (isupper((int) *op)) ? tolower((int) *op) : *op;
+ rop = (isupper((unsigned char) *op)) ? tolower((unsigned char) *op) : *op;
found = 0;
for (t=0; acl_op_table[t].ao_op; t++) {
if (rop == acl_op_table[t].ao_op) {
@@ -514,7 +514,7 @@ kadm5int_acl_load_acl_file()
DPRINT(DEBUG_CALLS, acl_debug_level, ("* kadm5int_acl_load_acl_file()\n"));
/* Open the ACL file for read */
- afp = fopen(acl_acl_file, "rF");
+ afp = fopen(acl_acl_file, "rF"); /* Solaris Kerberos */
if (afp) {
alineno = 1;
aentpp = &acl_list_head;
@@ -592,6 +592,7 @@ kadm5int_acl_match_data(e1, e2, targetflag, ws)
retval = 1;
if (ws && !targetflag) {
if (ws->nwild >= 9) {
+ /* Solaris Kerberos */
DPRINT(DEBUG_ACL, acl_debug_level,
("Too many wildcards in ACL entry %s\n", e1->data));
}
@@ -603,6 +604,7 @@ kadm5int_acl_match_data(e1, e2, targetflag, ws)
(e1->data[1] >= '1') && (e1->data[1] <= '9')) {
int n = e1->data[1] - '1';
if (n >= ws->nwild) {
+ /* Solaris Kerberos */
DPRINT(DEBUG_ACL, acl_debug_level,
("Too many backrefs in ACL entry %s\n", e1->data));
}
@@ -790,6 +792,7 @@ kadm5int_acl_check(kcontext, caller, opmask, principal, restrictions)
DPRINT(DEBUG_CALLS, acl_debug_level, ("* acl_op_permitted()\n"));
+ /* Solaris Kerberos */
if (restrictions)
*restrictions = NULL;
diff --git a/usr/src/lib/krb5/kadm5/srv/server_acl.h b/usr/src/lib/krb5/kadm5/srv/server_acl.h
index ffe618c82c..5676328c96 100644
--- a/usr/src/lib/krb5/kadm5/srv/server_acl.h
+++ b/usr/src/lib/krb5/kadm5/srv/server_acl.h
@@ -1,12 +1,9 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#ifndef _SERVER_ACL_H
-#define _SERVER_ACL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
@@ -58,6 +55,9 @@ extern "C" {
*
*/
+#ifndef SERVER_ACL_H__
+#define SERVER_ACL_H__
+
#include <admin.h> /* SUNWresync121 XXX */
/*
@@ -136,8 +136,8 @@ krb5_error_code kadm5int_acl_impose_restrictions
kadm5_principal_ent_rec *,
long *,
restriction_t *);
+#endif /* SERVER_ACL_H__ */
#ifdef __cplusplus
}
#endif
-#endif /* !_SERVER_ACL_H */
diff --git a/usr/src/lib/krb5/kadm5/srv/server_dict.c b/usr/src/lib/krb5/kadm5/srv/server_dict.c
index f79262da8c..23567e361d 100644
--- a/usr/src/lib/krb5/kadm5/srv/server_dict.c
+++ b/usr/src/lib/krb5/kadm5/srv/server_dict.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -21,11 +20,11 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_dict.c,v 1.7 2003/01/05 23:27:59 hartmans Exp $
+ * $Header$
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_dict.c,v 1.7 2003/01/05 23:27:59 hartmans Exp $";
+static char *rcsid = "$Header$";
#endif
#include <sys/types.h>
@@ -34,6 +33,7 @@ static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_dict.c,
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
+#include "server_internal.h"
#include <kadm5/admin.h>
#include <stdlib.h>
#include <stdio.h>
@@ -44,7 +44,6 @@ static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_dict.c,
#include "adm_proto.h"
#include <syslog.h>
#include <libintl.h>
-#include "server_internal.h"
static char **word_list = NULL; /* list of word pointers */
static char *word_block = NULL; /* actual word data */
@@ -110,6 +109,7 @@ int init_dict(kadm5_config_params *params)
if(word_list != NULL && word_block != NULL)
return KADM5_OK;
if (! (params->mask & KADM5_CONFIG_DICT_FILE)) {
+ /* Solaris Kerberos */
krb5_klog_syslog(LOG_INFO,
dgettext(TEXT_DOMAIN,
"No dictionary file specified, continuing "
@@ -118,6 +118,7 @@ int init_dict(kadm5_config_params *params)
}
if ((fd = open(params->dict_file, O_RDONLY)) == -1) {
if (errno == ENOENT) {
+ /* Solaris Kerberos */
krb5_klog_syslog(LOG_ERR,
dgettext(TEXT_DOMAIN,
"WARNING! Cannot find dictionary file %s, "
diff --git a/usr/src/lib/krb5/kadm5/srv/server_init.c b/usr/src/lib/krb5/kadm5/srv/server_init.c
index 5cb20542fe..45a7c95bf0 100644
--- a/usr/src/lib/krb5/kadm5/srv/server_init.c
+++ b/usr/src/lib/krb5/kadm5/srv/server_init.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -26,8 +25,8 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
*
- * $Id: server_init.c,v 1.8 2002/10/15 15:40:49 epeisach Exp $
- * $Source: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_init.c,v $
+ * $Id: server_init.c 18584 2006-09-13 20:30:23Z raeburn $
+ * $Source$
*/
#if !defined(lint) && !defined(__CODECENTER__)
@@ -36,7 +35,9 @@ static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_init.c,
#include <stdio.h>
#include <stdlib.h>
+#include <errno.h>
#include <com_err.h>
+#include "k5-int.h" /* needed for gssapiP_krb5.h */
#include <kadm5/admin.h>
#include <krb5.h>
#include "server_internal.h"
@@ -251,10 +252,8 @@ kadm5_ret_t kadm5_init2(char *client_name, char *pass,
}
#endif
- ret = kadm5_get_config_params(handle->context, (char *) NULL,
- (char *) NULL, params_in,
+ ret = kadm5_get_config_params(handle->context, 1, params_in,
&handle->params);
-
if (ret) {
krb5_free_context(handle->context);
free_db_args(handle);
diff --git a/usr/src/lib/krb5/kadm5/srv/server_kdb.c b/usr/src/lib/krb5/kadm5/srv/server_kdb.c
index 2ad4f184b4..f32b432ccb 100644
--- a/usr/src/lib/krb5/kadm5/srv/server_kdb.c
+++ b/usr/src/lib/krb5/kadm5/srv/server_kdb.c
@@ -2,7 +2,6 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -25,11 +24,11 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_kdb.c,v 1.4 2003/06/13 22:30:59 tlyu Exp $
+ * $Header$
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_kdb.c,v 1.4 2003/06/13 22:30:59 tlyu Exp $";
+static char *rcsid = "$Header$";
#endif
#include <stdio.h>
@@ -73,8 +72,12 @@ krb5_error_code kdb_init_master(kadm5_server_handle_t handle,
handle->params.mkey_name,
realm, NULL, &master_princ)))
goto done;
+/* Solaris Kerberos */
+#if 0
+ master_keyblock.enctype = handle->params.enctype;
+#endif
-
+ /* Solaris Kerberos */
ret = krb5_db_fetch_mkey(handle->context, master_princ,
handle->params.enctype, from_kbd,
FALSE /* only prompt once */,
@@ -85,6 +88,7 @@ krb5_error_code kdb_init_master(kadm5_server_handle_t handle,
if (ret)
goto done;
+ /* Solaris Kerberos */
if ((ret = krb5_db_verify_master_key(handle->context, master_princ,
&handle->master_keyblock))) {
krb5_db_fini(handle->context);
@@ -202,6 +206,7 @@ krb5_error_code kdb_init_hist(kadm5_server_handle_t handle, char *r)
if (ret)
goto done;
+ /* Solaris Kerberos */
ret = krb5_dbekd_decrypt_key_data(handle->context,
&handle->master_keyblock, key_data, &hist_key, NULL);
if (ret)
@@ -281,6 +286,7 @@ kdb_get_entry(kadm5_server_handle_t handle,
return(ret);
}
+ /* Solaris Kerberos */
xdrmem_create(&xdrs, (caddr_t)tl_data.tl_data_contents,
tl_data.tl_data_length, XDR_DECODE);
if (! xdr_osa_princ_ent_rec(&xdrs, adb)) {
@@ -372,6 +378,7 @@ kdb_put_entry(kadm5_server_handle_t handle,
}
tl_data.tl_data_type = KRB5_TL_KADM_DATA;
tl_data.tl_data_length = xdr_getpos(&xdrs);
+ /* Solaris Kerberos */
tl_data.tl_data_contents = (unsigned char *) xdralloc_getdata(&xdrs);
ret = krb5_dbe_update_tl_data(handle->context, kdb, &tl_data);
diff --git a/usr/src/lib/krb5/kadm5/srv/server_misc.c b/usr/src/lib/krb5/kadm5/srv/server_misc.c
index cbe227e89b..06cf637dcc 100644
--- a/usr/src/lib/krb5/kadm5/srv/server_misc.c
+++ b/usr/src/lib/krb5/kadm5/srv/server_misc.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -21,11 +20,11 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_misc.c,v 1.4 2001/06/18 18:58:00 epeisach Exp $
+ * $Header$
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_misc.c,v 1.4 2001/06/18 18:58:00 epeisach Exp $";
+static char *rcsid = "$Header$";
#endif
#include "k5-int.h"
diff --git a/usr/src/lib/krb5/kadm5/srv/svr_chpass_util.c b/usr/src/lib/krb5/kadm5/srv/svr_chpass_util.c
index e010d27f68..0fe0d016a1 100644
--- a/usr/src/lib/krb5/kadm5/srv/svr_chpass_util.c
+++ b/usr/src/lib/krb5/kadm5/srv/svr_chpass_util.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -22,9 +21,8 @@
*
*/
-
-#include <kadm5/admin.h>
#include "server_internal.h"
+#include <kadm5/admin.h>
kadm5_ret_t kadm5_chpass_principal_util(void *server_handle,
krb5_principal princ,
diff --git a/usr/src/lib/krb5/kadm5/srv/svr_iters.c b/usr/src/lib/krb5/kadm5/srv/svr_iters.c
index 722a695272..87f5094bed 100644
--- a/usr/src/lib/krb5/kadm5/srv/svr_iters.c
+++ b/usr/src/lib/krb5/kadm5/srv/svr_iters.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -21,11 +20,11 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/svr_iters.c,v 1.6 2003/01/12 18:17:02 epeisach Exp $
+ * $Header$
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/svr_iters.c,v 1.6 2003/01/12 18:17:02 epeisach Exp $";
+static char *rcsid = "$Header$";
#endif
#include "autoconf.h"
@@ -41,6 +40,7 @@ static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/svr_iters.c,v
#include <sys/types.h>
#include <string.h>
+#include "server_internal.h"
#include <kadm5/admin.h>
#ifdef SOLARIS_REGEXPS
#include <regexpr.h>
@@ -50,7 +50,6 @@ static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/svr_iters.c,v
#endif
#include <stdlib.h>
-#include "server_internal.h"
struct iter_data {
krb5_context context;
diff --git a/usr/src/lib/krb5/kadm5/srv/svr_misc_free.c b/usr/src/lib/krb5/kadm5/srv/svr_misc_free.c
index a552c4e2b4..645eaa2854 100644
--- a/usr/src/lib/krb5/kadm5/srv/svr_misc_free.c
+++ b/usr/src/lib/krb5/kadm5/srv/svr_misc_free.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
@@ -21,12 +19,12 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/svr_misc_free.c,v 1.2 1996/10/18 19:45:53 bjaspan Exp $
+ * $Header$
*
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/svr_misc_free.c,v 1.2 1996/10/18 19:45:53 bjaspan Exp $";
+static char *rcsid = "$Header$";
#endif
#include <kadm5/admin.h>
#include <stdlib.h>
diff --git a/usr/src/lib/krb5/kadm5/srv/svr_policy.c b/usr/src/lib/krb5/kadm5/srv/svr_policy.c
index 8aa9604b98..d6c739b2a2 100644
--- a/usr/src/lib/krb5/kadm5/srv/svr_policy.c
+++ b/usr/src/lib/krb5/kadm5/srv/svr_policy.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
@@ -21,17 +19,18 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/svr_policy.c,v 1.2 2001/06/20 05:01:37 mitchb Exp $
+ * $Header$
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/svr_policy.c,v 1.2 2001/06/20 05:01:37 mitchb Exp $";
+static char *rcsid = "$Header$";
#endif
+#include "server_internal.h"
#include <sys/types.h>
#include <kadm5/admin.h>
-#include "server_internal.h"
#include <stdlib.h>
+#include <errno.h>
#define MAX_PW_HISTORY 10
#define MIN_PW_HISTORY 1
@@ -182,7 +181,7 @@ kadm5_delete_policy(void *server_handle, kadm5_policy_t name)
return EINVAL;
if(strlen(name) == 0)
return KADM5_BAD_POLICY;
- if((ret = krb5_db_get_policy(handle->context, name, &entry, &cnt)))
+ if((ret = krb5_db_get_policy(handle->context, name, &entry,&cnt)))
return ret;
if( cnt != 1 )
return KADM5_UNK_POLICY;
@@ -230,9 +229,9 @@ kadm5_modify_policy_internal(void *server_handle,
if((mask & KADM5_POLICY))
return KADM5_BAD_MASK;
- if((ret = krb5_db_get_policy(handle->context, entry->policy, &p, &cnt)))
+ if ((ret = krb5_db_get_policy(handle->context, entry->policy, &p, &cnt)))
return ret;
- if( cnt != 1 )
+ if (cnt != 1)
return KADM5_UNK_POLICY;
if ((mask & KADM5_PW_MAX_LIFE))
diff --git a/usr/src/lib/krb5/kadm5/srv/svr_principal.c b/usr/src/lib/krb5/kadm5/srv/svr_principal.c
index f4faf5e17f..f02deb362b 100644
--- a/usr/src/lib/krb5/kadm5/srv/svr_principal.c
+++ b/usr/src/lib/krb5/kadm5/srv/svr_principal.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -26,20 +25,21 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/svr_principal.c,v 1.30.8.1 2004/12/20 21:16:20 tlyu Exp $
+ * $Header$
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/svr_principal.c,v 1.30.8.1 2004/12/20 21:16:20 tlyu Exp $";
+static char *rcsid = "$Header$";
#endif
#include <sys/types.h>
#include <sys/time.h>
+#include <errno.h>
+#include "server_internal.h"
#include <kadm5/admin.h>
#include <kdb.h>
#include <stdio.h>
#include <string.h>
-#include "server_internal.h"
#include <stdarg.h>
#include <stdlib.h>
#ifdef USE_PASSWORD_SERVER
@@ -202,10 +202,6 @@ kadm5_create_principal(void *server_handle,
kadm5_principal_ent_t entry, long mask,
char *password)
{
- /*
- * Default to using the new API with the default set of
- * key/salt combinations.
- */
return
kadm5_create_principal_3(server_handle, entry, mask,
0, NULL, password);
@@ -250,6 +246,7 @@ kadm5_create_principal_3(void *server_handle,
switch(ret) {
case KADM5_UNK_PRINC:
+ /* Solaris Kerberos */
memset(&kdb, 0, sizeof(krb5_db_entry));
memset(&adb, 0, sizeof(osa_princ_ent_rec));
break;
@@ -311,6 +308,7 @@ kadm5_create_principal_3(void *server_handle,
kdb.len = KRB5_KDB_V1_BASE_LENGTH; /* gag me with a chainsaw */
/*
+ * Solaris Kerberos:
* If KADM5_ATTRIBUTES is set, we want to rope in not only
* entry->attributes, but also the generic params.flags
* obtained previously via kadm5_get_config_params.
@@ -1122,106 +1120,214 @@ static kadm5_ret_t add_to_history(krb5_context context,
osa_pw_hist_ent *pw)
{
osa_pw_hist_ent *histp;
- int i;
+ uint32_t nhist;
+ unsigned int i, knext, nkeys;
+
+ nhist = pol->pw_history_num;
+ /* A history of 1 means just check the current password */
+ if (nhist <= 1)
+ return 0;
+
+ nkeys = adb->old_key_len;
+ knext = adb->old_key_next;
+ /* resize the adb->old_keys array if necessary */
+ if (nkeys + 1 < nhist) {
+ if (adb->old_keys == NULL) {
+ adb->old_keys = (osa_pw_hist_ent *)
+ malloc((nkeys + 1) * sizeof (osa_pw_hist_ent));
+ } else {
+ adb->old_keys = (osa_pw_hist_ent *)
+ realloc(adb->old_keys,
+ (nkeys + 1) * sizeof (osa_pw_hist_ent));
+ }
+ if (adb->old_keys == NULL)
+ return(ENOMEM);
+
+ memset(&adb->old_keys[nkeys], 0, sizeof(osa_pw_hist_ent));
+ nkeys = ++adb->old_key_len;
+ /*
+ * To avoid losing old keys, shift forward each entry after
+ * knext.
+ */
+ for (i = nkeys - 1; i > knext; i--) {
+ adb->old_keys[i] = adb->old_keys[i - 1];
+ }
+ memset(&adb->old_keys[knext], 0, sizeof(osa_pw_hist_ent));
+ } else if (nkeys + 1 > nhist) {
+ /*
+ * 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
+ */
+ /*
+ * M = adb->old_key_len, N = pol->pw_history_num - 1
+ *
+ * tmp[0] .. tmp[N-1] = old[(knext-N)%M] .. old[(knext-1)%M]
+ */
+ int j;
+ osa_pw_hist_t tmp;
+
+ tmp = (osa_pw_hist_ent *)
+ malloc((nhist - 1) * sizeof (osa_pw_hist_ent));
+ if (tmp == NULL)
+ return ENOMEM;
+ for (i = 0; i < nhist - 1; i++) {
+ /*
+ * Add nkeys once before taking remainder to avoid
+ * negative values.
+ */
+ j = (i + nkeys + knext - (nhist - 1)) % nkeys;
+ tmp[i] = adb->old_keys[j];
+ }
+ /* Now free the ones we don't keep (the oldest ones) */
+ for (i = 0; i < nkeys - (nhist - 1); i++) {
+ j = (i + nkeys + knext) % nkeys;
+ histp = &adb->old_keys[j];
+ for (j = 0; j < histp->n_key_data; j++) {
+ krb5_free_key_data_contents(context, &histp->key_data[j]);
+ }
+ free(histp->key_data);
+ }
+ free((void *)adb->old_keys);
+ adb->old_keys = tmp;
+ nkeys = adb->old_key_len = nhist - 1;
+ knext = adb->old_key_next = 0;
+ }
- /* A history of 1 means just check the current password */
- if (pol->pw_history_num == 1)
- return (0);
-
- /* resize the adb->old_keys array if necessary */
- if (adb->old_key_len < pol->pw_history_num-1) {
- if (adb->old_keys == NULL) {
- adb->old_keys = (osa_pw_hist_ent *)
- malloc((adb->old_key_len + 1) *
- sizeof (osa_pw_hist_ent));
- } else {
- adb->old_keys = (osa_pw_hist_ent *)
- realloc(adb->old_keys,
- (adb->old_key_len + 1) *
- sizeof (osa_pw_hist_ent));
- }
- if (adb->old_keys == NULL)
- return (ENOMEM);
-
- memset(&adb->old_keys[adb->old_key_len], 0,
- sizeof (osa_pw_hist_ent));
- adb->old_key_len++;
- for (i = adb->old_key_len - 1; i > adb->old_key_next; i--)
- adb->old_keys[i] = adb->old_keys[i - 1];
- memset(&adb->old_keys[adb->old_key_next], 0,
- sizeof (osa_pw_hist_ent));
- } 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(adb->old_keys[KADM_MOD(i)].key_data);
- }
- 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);
- }
- }
+ /*
+ * If nhist decreased since the last password change, and nkeys+1
+ * is less than the previous nhist, it is possible for knext to
+ * index into unallocated space. This condition would not be
+ * caught by the resizing code above.
+ */
+ if (knext + 1 > nkeys)
+ knext = adb->old_key_next = 0;
+ /* free the old pw history entry if it contains data */
+ histp = &adb->old_keys[knext];
+ for (i = 0; i < histp->n_key_data; i++)
+ krb5_free_key_data_contents(context, &histp->key_data[i]);
+ free(histp->key_data);
+
+ /* store the new entry */
+ adb->old_keys[knext] = *pw;
+
+ /* update the next pointer */
+ if (++adb->old_key_next == nhist - 1)
+ adb->old_key_next = 0;
+
+ return(0);
+}
+#undef KADM_MOD
+
+#ifdef USE_PASSWORD_SERVER
+/* FIXME: don't use global variable for this */
+krb5_boolean use_password_server = 0;
- if (adb->old_key_next + 1 > adb->old_key_len)
- adb->old_key_next = 0;
+static krb5_boolean
+kadm5_use_password_server (void)
+{
+ return use_password_server;
+}
- /* free the old pw history entry if it contains data */
- histp = &adb->old_keys[adb->old_key_next];
- for (i = 0; i < histp->n_key_data; i++)
- krb5_free_key_data_contents(context, &histp->key_data[i]);
- free(histp->key_data);
+void
+kadm5_set_use_password_server (void)
+{
+ use_password_server = 1;
+}
+#endif
- /* store the new entry */
- adb->old_keys[adb->old_key_next] = *pw;
+#ifdef USE_PASSWORD_SERVER
- /* update the next pointer */
- if (++adb->old_key_next == pol->pw_history_num-1)
- adb->old_key_next = 0;
+/*
+ * kadm5_launch_task () runs a program (task_path) to synchronize the
+ * Apple password server with the Kerberos database. Password server
+ * programs can receive arguments on the command line (task_argv)
+ * and a block of data via stdin (data_buffer).
+ *
+ * Because a failure to communicate with the tool results in the
+ * password server falling out of sync with the database,
+ * kadm5_launch_task() always fails if it can't talk to the tool.
+ */
- return (0);
+static kadm5_ret_t
+kadm5_launch_task (krb5_context context,
+ const char *task_path, char * const task_argv[],
+ const char *data_buffer)
+{
+ kadm5_ret_t ret = 0;
+ int data_pipe[2];
+
+ if (data_buffer != NULL) {
+ ret = pipe (data_pipe);
+ if (ret) { ret = errno; }
+ }
+
+ if (!ret) {
+ pid_t pid = fork ();
+ if (pid == -1) {
+ ret = errno;
+ } else if (pid == 0) {
+ /* The child: */
+
+ if (data_buffer != NULL) {
+ if (dup2 (data_pipe[0], STDIN_FILENO) == -1) {
+ _exit (1);
+ }
+ } else {
+ close (data_pipe[0]);
+ }
+
+ close (data_pipe[1]);
+
+ execv (task_path, task_argv);
+
+ _exit (1); /* Fail if execv fails */
+ } else {
+ /* The parent: */
+ int status;
+
+ if (data_buffer != NULL) {
+ /* Write out the buffer to the child */
+ if (krb5_net_write (context, data_pipe[1],
+ data_buffer, strlen (data_buffer)) < 0) {
+ /* kill the child to make sure waitpid() won't hang later */
+ ret = errno;
+ kill (pid, SIGKILL);
+ }
+ }
+
+ close (data_buffer[0]);
+ close (data_buffer[1]);
+
+ waitpid (pid, &status, 0);
+
+ if (!ret) {
+ if (WIFEXITED (status)) {
+ /* child read password and exited. Check the return value. */
+ if ((WEXITSTATUS (status) != 0) && (WEXITSTATUS (status) != 252)) {
+ ret = KRB5KDC_ERR_POLICY; /* password change rejected */
+ }
+ } else {
+ /* child read password but crashed or was killed */
+ ret = KRB5KRB_ERR_GENERIC; /* FIXME: better error */
+ }
+ }
+ }
+ }
+
+ return ret;
}
-#undef KADM_MOD
+
+#endif
kadm5_ret_t
kadm5_chpass_principal(void *server_handle,
krb5_principal principal, char *password)
{
- /*
- * Default to using the new API with the default set of
- * key/salt combinations.
- */
return
kadm5_chpass_principal_3(server_handle, principal, FALSE,
0, NULL, password);
@@ -1352,6 +1458,42 @@ kadm5_chpass_principal_3(void *server_handle,
kdb.pw_expiration = 0;
}
+#ifdef USE_PASSWORD_SERVER
+ if (kadm5_use_password_server () &&
+ (krb5_princ_size (handle->context, principal) == 1)) {
+ krb5_data *princ = krb5_princ_component (handle->context, principal, 0);
+ const char *path = "/usr/sbin/mkpassdb";
+ char *argv[] = { "mkpassdb", "-setpassword", NULL, NULL };
+ char *pstring = NULL;
+ char pwbuf[256];
+ int pwlen = strlen (password);
+
+ if (pwlen > 254) pwlen = 254;
+ strncpy (pwbuf, password, pwlen);
+ pwbuf[pwlen] = '\n';
+ pwbuf[pwlen + 1] = '\0';
+
+ if (!ret) {
+ pstring = malloc ((princ->length + 1) * sizeof (char));
+ if (pstring == NULL) { ret = errno; }
+ }
+
+ if (!ret) {
+ memcpy (pstring, princ->data, princ->length);
+ pstring [princ->length] = '\0';
+ argv[2] = pstring;
+
+ ret = kadm5_launch_task (handle->context, path, argv, pwbuf);
+ }
+
+ if (pstring != NULL)
+ free (pstring);
+
+ if (ret)
+ goto done;
+ }
+#endif
+
ret = krb5_dbe_update_last_pwd_change(handle->context, &kdb, now);
if (ret)
goto done;
@@ -1388,6 +1530,7 @@ kadm5_randkey_principal(void *server_handle,
krb5_keyblock **keyblocks,
int *n_keys)
{
+ /* Solaris Kerberos: */
krb5_key_salt_tuple keysalts[2];
/*
@@ -1406,7 +1549,6 @@ kadm5_randkey_principal(void *server_handle,
return (kadm5_randkey_principal_3(server_handle, principal,
FALSE, 2, keysalts, keyblocks, n_keys));
}
-
kadm5_ret_t
kadm5_randkey_principal_3(void *server_handle,
krb5_principal principal,
@@ -1544,6 +1686,175 @@ done:
return ret;
}
+#if 0 /* Solaris Kerberos */
+/*
+ * kadm5_setv4key_principal:
+ *
+ * Set only ONE key of the principal, removing all others. This key
+ * must have the DES_CBC_CRC enctype and is entered as having the
+ * krb4 salttype. This is to enable things like kadmind4 to work.
+ */
+kadm5_ret_t
+kadm5_setv4key_principal(void *server_handle,
+ krb5_principal principal,
+ krb5_keyblock *keyblock)
+{
+ krb5_db_entry kdb;
+ osa_princ_ent_rec adb;
+ krb5_int32 now;
+ kadm5_policy_ent_rec pol;
+ krb5_keysalt keysalt;
+ int i, k, kvno, ret, have_pol = 0;
+#if 0
+ int last_pwd;
+#endif
+ kadm5_server_handle_t handle = server_handle;
+ krb5_key_data tmp_key_data;
+
+ memset( &tmp_key_data, 0, sizeof(tmp_key_data));
+
+ CHECK_HANDLE(server_handle);
+
+ krb5_clear_error_message(handle->context);
+
+ if (principal == NULL || keyblock == NULL)
+ return EINVAL;
+ if (hist_princ && /* this will be NULL when initializing the databse */
+ ((krb5_principal_compare(handle->context,
+ principal, hist_princ)) == TRUE))
+ return KADM5_PROTECT_PRINCIPAL;
+
+ if (keyblock->enctype != ENCTYPE_DES_CBC_CRC)
+ return KADM5_SETV4KEY_INVAL_ENCTYPE;
+
+ if ((ret = kdb_get_entry(handle, principal, &kdb, &adb)))
+ return(ret);
+
+ for (kvno = 0, i=0; i<kdb.n_key_data; i++)
+ if (kdb.key_data[i].key_data_kvno > kvno)
+ kvno = kdb.key_data[i].key_data_kvno;
+
+ if (kdb.key_data != NULL)
+ cleanup_key_data(handle->context, kdb.n_key_data, kdb.key_data);
+
+ kdb.key_data = (krb5_key_data*)krb5_db_alloc(handle->context, NULL, sizeof(krb5_key_data));
+ if (kdb.key_data == NULL)
+ return ENOMEM;
+ memset(kdb.key_data, 0, sizeof(krb5_key_data));
+ kdb.n_key_data = 1;
+ keysalt.type = KRB5_KDB_SALTTYPE_V4;
+ /* XXX data.magic? */
+ keysalt.data.length = 0;
+ keysalt.data.data = NULL;
+
+ /* use tmp_key_data as temporary location and reallocate later */
+ ret = krb5_dbekd_encrypt_key_data(handle->context, &master_keyblock,
+ keyblock, &keysalt, kvno + 1,
+ &tmp_key_data);
+ if (ret) {
+ goto done;
+ }
+
+ for (k = 0; k < tmp_key_data.key_data_ver; k++) {
+ kdb.key_data->key_data_type[k] = tmp_key_data.key_data_type[k];
+ kdb.key_data->key_data_length[k] = tmp_key_data.key_data_length[k];
+ if (tmp_key_data.key_data_contents[k]) {
+ kdb.key_data->key_data_contents[k] = krb5_db_alloc(handle->context, NULL, tmp_key_data.key_data_length[k]);
+ if (kdb.key_data->key_data_contents[k] == NULL) {
+ cleanup_key_data(handle->context, kdb.n_key_data, kdb.key_data);
+ kdb.key_data = NULL;
+ kdb.n_key_data = 0;
+ ret = ENOMEM;
+ goto done;
+ }
+ memcpy (kdb.key_data->key_data_contents[k], tmp_key_data.key_data_contents[k], tmp_key_data.key_data_length[k]);
+
+ memset (tmp_key_data.key_data_contents[k], 0, tmp_key_data.key_data_length[k]);
+ free (tmp_key_data.key_data_contents[k]);
+ tmp_key_data.key_data_contents[k] = NULL;
+ }
+ }
+
+
+
+ kdb.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE;
+
+ ret = krb5_timeofday(handle->context, &now);
+ if (ret)
+ goto done;
+
+ if ((adb.aux_attributes & KADM5_POLICY)) {
+ if ((ret = kadm5_get_policy(handle->lhandle, adb.policy,
+ &pol)) != KADM5_OK)
+ goto done;
+ have_pol = 1;
+
+#if 0
+ /*
+ * The spec says this check is overridden if the caller has
+ * modify privilege. The admin server therefore makes this
+ * check itself (in chpass_principal_wrapper, misc.c). A
+ * local caller implicitly has all authorization bits.
+ */
+ if (ret = krb5_dbe_lookup_last_pwd_change(handle->context,
+ &kdb, &last_pwd))
+ goto done;
+ if((now - last_pwd) < pol.pw_min_life &&
+ !(kdb.attributes & KRB5_KDB_REQUIRES_PWCHANGE)) {
+ ret = KADM5_PASS_TOOSOON;
+ goto done;
+ }
+#endif
+#if 0
+ /*
+ * Should we be checking/updating pw history here?
+ */
+ if(pol.pw_history_num > 1) {
+ if(adb.admin_history_kvno != hist_kvno) {
+ ret = KADM5_BAD_HIST_KEY;
+ goto done;
+ }
+
+ if (ret = check_pw_reuse(handle->context,
+ &hist_key,
+ kdb.n_key_data, kdb.key_data,
+ adb.old_key_len, adb.old_keys))
+ goto done;
+ }
+#endif
+
+ if (pol.pw_max_life)
+ kdb.pw_expiration = now + pol.pw_max_life;
+ else
+ kdb.pw_expiration = 0;
+ } else {
+ kdb.pw_expiration = 0;
+ }
+
+ ret = krb5_dbe_update_last_pwd_change(handle->context, &kdb, now);
+ if (ret)
+ goto done;
+
+ if ((ret = kdb_put_entry(handle, &kdb, &adb)))
+ goto done;
+
+ ret = KADM5_OK;
+done:
+ for (i = 0; i < tmp_key_data.key_data_ver; i++) {
+ if (tmp_key_data.key_data_contents[i]) {
+ memset (tmp_key_data.key_data_contents[i], 0, tmp_key_data.key_data_length[i]);
+ free (tmp_key_data.key_data_contents[i]);
+ }
+ }
+
+ kdb_free_entry(handle, &kdb, &adb);
+ if (have_pol)
+ kadm5_free_policy_ent(handle->lhandle, &pol);
+
+ return ret;
+}
+#endif
+
kadm5_ret_t
kadm5_setkey_principal(void *server_handle,
krb5_principal principal,
@@ -1870,6 +2181,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/usr/src/lib/krb5/kadm5/srv/xdr_alloc.c b/usr/src/lib/krb5/kadm5/srv/xdr_alloc.c
index 9bc36b9e37..db3aa953af 100644
--- a/usr/src/lib/krb5/kadm5/srv/xdr_alloc.c
+++ b/usr/src/lib/krb5/kadm5/srv/xdr_alloc.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -54,65 +53,29 @@ static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
*
- * $Header: /afs/athena.mit.edu/astaff/project/krbdev/.cvsroot/src/lib/rpc/xdr_alloc.c,v 1.6 1996/07/22 20:41:21 marc Exp $
- *
- * $Log: xdr_alloc.c,v $
- * Revision 1.6 1996/07/22 20:41:21 marc
- * this commit includes all the changes on the OV_9510_INTEGRATION and
- * OV_MERGE branches. This includes, but is not limited to, the new openvision
- * admin system, and major changes to gssapi to add functionality, and bring
- * the implementation in line with rfc1964. before committing, the
- * code was built and tested for netbsd and solaris.
- *
- * Revision 1.5.4.1 1996/07/18 04:19:49 marc
- * merged in changes from OV_9510_BP to OV_9510_FINAL1
- *
- * Revision 1.5.2.1 1996/06/20 23:40:30 marc
- * File added to the repository on a branch
- *
- * Revision 1.5 1996/05/12 06:19:25 marc
- * renamed lots of types: u_foo to unsigned foo, and foo32 to rpc_foo32. This is to make autoconfiscation less painful.
- *
- * Revision 1.4 1995/12/13 14:03:14 grier
- * Longs to ints for Alpha
- *
- * Revision 1.3 1993/12/09 18:57:25 bjaspan
- * [secure-releng/833] misc bugfixes to admin library
- *
- * Revision 1.3 1993/12/06 21:23:08 bjaspan
- * add xdralloc_release
- *
- * Revision 1.2 1993/10/26 21:13:19 bjaspan
- * add casts for correctness
- *
- * Revision 1.1 1993/10/19 03:11:39 bjaspan
- * Initial revision
- *
*/
-#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /afs/athena.mit.edu/astaff/project/krbdev/.cvsroot/src/lib/rpc/xdr_alloc.c,v 1.6 1996/07/22 20:41:21 marc Exp $";
-#endif
-
#include "admin.h"
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <dyn/dyn.h>
+/* Solaris Kerberos - 116 resync */
static bool_t xdralloc_putlong();
static bool_t xdralloc_putbytes();
static unsigned int xdralloc_getpos();
static rpc_inline_t * xdralloc_inline();
static void xdralloc_destroy();
-static bool_t xdralloc_notsup();
-
+static bool_t xdralloc_notsup_getlong();
+static bool_t xdralloc_notsup_getbytes();
+static bool_t xdralloc_notsup_setpos();
static struct xdr_ops xdralloc_ops = {
- xdralloc_notsup,
+ xdralloc_notsup_getlong,
xdralloc_putlong,
- xdralloc_notsup,
+ xdralloc_notsup_getbytes,
xdralloc_putbytes,
xdralloc_getpos,
- xdralloc_notsup,
+ xdralloc_notsup_setpos,
xdralloc_inline,
xdralloc_destroy,
};
@@ -121,9 +84,7 @@ static struct xdr_ops xdralloc_ops = {
* The procedure xdralloc_create initializes a stream descriptor for a
* memory buffer.
*/
-void xdralloc_create(xdrs, op)
- register XDR *xdrs;
- enum xdr_op op;
+void xdralloc_create(XDR *xdrs, enum xdr_op op)
{
xdrs->x_op = op;
xdrs->x_ops = &xdralloc_ops;
@@ -131,35 +92,35 @@ void xdralloc_create(xdrs, op)
/* not allowed to fail */
}
-caddr_t xdralloc_getdata(xdrs)
- XDR *xdrs;
+caddr_t xdralloc_getdata(XDR *xdrs)
{
return (caddr_t) DynGet((DynObject) xdrs->x_private, 0);
}
-void xdralloc_release(xdrs)
- XDR *xdrs;
+void xdralloc_release(XDR *xdrs)
{
DynRelease((DynObject) xdrs->x_private);
}
-static void xdralloc_destroy(xdrs)
- XDR *xdrs;
+static void xdralloc_destroy(XDR *xdrs)
{
DynDestroy((DynObject) xdrs->x_private);
}
-static bool_t xdralloc_notsup()
+static bool_t xdralloc_notsup_getlong(
+ register XDR *xdrs,
+ long *lp)
{
return FALSE;
}
-static bool_t xdralloc_putlong(xdrs, lp)
- register XDR *xdrs;
- rpc_int32 *lp;
+static bool_t xdralloc_putlong(
+ register XDR *xdrs,
+ long *lp)
{
- int l = htonl((rpc_u_int32) *(int *)lp);
-
+ int l = htonl((uint32_t) *lp); /* XXX need bounds checking */
+
+ /* XXX assumes sizeof(int)==4 */
if (DynInsert((DynObject) xdrs->x_private,
DynSize((DynObject) xdrs->x_private), &l,
sizeof(int)) != DYN_OK)
@@ -167,28 +128,45 @@ static bool_t xdralloc_putlong(xdrs, lp)
return (TRUE);
}
-static bool_t xdralloc_putbytes(xdrs, addr, len)
- register XDR *xdrs;
- caddr_t addr;
- register unsigned int len;
+
+static bool_t xdralloc_notsup_getbytes(
+ register XDR *xdrs,
+ caddr_t addr,
+ register unsigned int len)
+{
+ return FALSE;
+}
+
+
+static bool_t xdralloc_putbytes(
+ register XDR *xdrs,
+ caddr_t addr,
+ register unsigned int len)
{
if (DynInsert((DynObject) xdrs->x_private,
DynSize((DynObject) xdrs->x_private),
- addr, len) != DYN_OK)
+ addr, (int) len) != DYN_OK)
return FALSE;
return TRUE;
}
-static unsigned int xdralloc_getpos(xdrs)
- register XDR *xdrs;
+static unsigned int xdralloc_getpos(XDR *xdrs)
{
return DynSize((DynObject) xdrs->x_private);
}
+static bool_t xdralloc_notsup_setpos(
+ register XDR *xdrs,
+ unsigned int lp)
+{
+ return FALSE;
+}
+
+
-static rpc_inline_t *xdralloc_inline(xdrs, len)
- register XDR *xdrs;
- int len;
+static rpc_inline_t *xdralloc_inline(
+ register XDR *xdrs,
+ int len)
{
return (rpc_inline_t *) 0;
}
diff --git a/usr/src/lib/krb5/kadm5/str_conv.c b/usr/src/lib/krb5/kadm5/str_conv.c
index 62cb897d49..5d003cf7c8 100644
--- a/usr/src/lib/krb5/kadm5/str_conv.c
+++ b/usr/src/lib/krb5/kadm5/str_conv.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -335,7 +334,7 @@ krb5_string_to_keysalts(string, tupleseps, ksaltseps, dups, ksaltp, nksaltp)
septmp = ksseplist;
for (sp = strchr(kp, (int) *septmp);
*(++septmp) && !sp;
- sp = strchr(kp, (int)*septmp));
+ sp = strchr(kp, (int)*septmp)); /* Solaris Kerberos */
if (sp) {
/* Separate enctype from salttype */
diff --git a/usr/src/lib/krb5/kdb/decrypt_key.c b/usr/src/lib/krb5/kdb/decrypt_key.c
index 73b748c53c..1a04a4a906 100644
--- a/usr/src/lib/krb5/kdb/decrypt_key.c
+++ b/usr/src/lib/krb5/kdb/decrypt_key.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/kdb/decrypt_key.c
@@ -70,12 +69,11 @@
*/
krb5_error_code
-krb5_dbekd_decrypt_key_data(context, mkey, key_data, dbkey, keysalt)
- krb5_context context;
- const krb5_keyblock * mkey;
- const krb5_key_data * key_data;
- krb5_keyblock * dbkey;
- krb5_keysalt * keysalt;
+krb5_dbekd_decrypt_key_data( krb5_context context,
+ const krb5_keyblock * mkey,
+ const krb5_key_data * key_data,
+ krb5_keyblock * dbkey,
+ krb5_keysalt * keysalt)
{
krb5_error_code retval = 0;
krb5_int16 tmplen;
diff --git a/usr/src/lib/krb5/kdb/encrypt_key.c b/usr/src/lib/krb5/kdb/encrypt_key.c
index e5751dc98c..0f69baddec 100644
--- a/usr/src/lib/krb5/kdb/encrypt_key.c
+++ b/usr/src/lib/krb5/kdb/encrypt_key.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/kdb/encrypt_key.c
@@ -70,13 +69,12 @@
*/
krb5_error_code
-krb5_dbekd_encrypt_key_data(context, mkey, dbkey, keysalt, keyver, key_data)
- krb5_context context;
- const krb5_keyblock * mkey;
- const krb5_keyblock * dbkey;
- const krb5_keysalt * keysalt;
- int keyver;
- krb5_key_data * key_data;
+krb5_dbekd_encrypt_key_data( krb5_context context,
+ const krb5_keyblock * mkey,
+ const krb5_keyblock * dbkey,
+ const krb5_keysalt * keysalt,
+ int keyver,
+ krb5_key_data * key_data)
{
krb5_error_code retval;
krb5_octet * ptr;
diff --git a/usr/src/lib/krb5/kdb/kdb_cpw.c b/usr/src/lib/krb5/kdb/kdb_cpw.c
index f44cd9c21d..1e0d781cef 100644
--- a/usr/src/lib/krb5/kdb/kdb_cpw.c
+++ b/usr/src/lib/krb5/kdb/kdb_cpw.c
@@ -1,8 +1,7 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/kdb/kdb_cpw.c
@@ -58,7 +57,7 @@
*/
#include "k5-int.h"
-#include <kdb.h>
+#include "kdb.h"
#include <stdio.h>
#include <errno.h>
@@ -92,11 +91,11 @@ cleanup_key_data(context, count, data)
for (i = 0; i < count; i++) {
for (j = 0; j < data[i].key_data_ver; j++) {
if (data[i].key_data_length[j]) {
- free(data[i].key_data_contents[j]);
+ krb5_db_free(context, data[i].key_data_contents[j]);
}
}
}
- free(data);
+ krb5_db_free(context, data);
}
static krb5_error_code
@@ -112,8 +111,13 @@ add_key_rnd(context, master_key, ks_tuple, ks_tuple_count, db_entry, kvno)
krb5_keyblock key;
krb5_db_entry krbtgt_entry;
krb5_boolean more;
- int max_kvno, one, i, j;
+ int max_kvno, one, i, j, k;
krb5_error_code retval;
+ krb5_key_data tmp_key_data;
+ krb5_key_data *tptr;
+
+ memset( &tmp_key_data, 0, sizeof(tmp_key_data));
+
retval = krb5_build_principal_ext(context, &krbtgt_princ,
db_entry->princ->realm.length,
@@ -182,19 +186,59 @@ add_key_rnd(context, master_key, ks_tuple, ks_tuple_count, db_entry, kvno)
&key)))
goto add_key_rnd_err;
+
+ /* db library will free this. Since, its a so, it could actually be using different memory management
+ function. So, its better if the memory is allocated by the db's malloc. So, a temporary memory is used
+ here which will later be copied to the db_entry */
retval = krb5_dbekd_encrypt_key_data(context, master_key,
&key, NULL, kvno,
- &db_entry->key_data[db_entry->n_key_data-1]);
+ &tmp_key_data);
krb5_free_keyblock_contents(context, &key);
-
- if (retval)
+ if( retval )
goto add_key_rnd_err;
+
+ tptr = &db_entry->key_data[db_entry->n_key_data-1];
+
+ tptr->key_data_ver = tmp_key_data.key_data_ver;
+ tptr->key_data_kvno = tmp_key_data.key_data_kvno;
+
+ for( k = 0; k < tmp_key_data.key_data_ver; k++ )
+ {
+ tptr->key_data_type[k] = tmp_key_data.key_data_type[k];
+ tptr->key_data_length[k] = tmp_key_data.key_data_length[k];
+ if( tmp_key_data.key_data_contents[k] )
+ {
+ tptr->key_data_contents[k] = krb5_db_alloc(context, NULL, tmp_key_data.key_data_length[k]);
+ if( tptr->key_data_contents[k] == NULL )
+ {
+ cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data);
+ db_entry->key_data = NULL;
+ db_entry->n_key_data = 0;
+ retval = ENOMEM;
+ goto add_key_rnd_err;
+ }
+ memcpy( tptr->key_data_contents[k], tmp_key_data.key_data_contents[k], tmp_key_data.key_data_length[k]);
+
+ memset( tmp_key_data.key_data_contents[k], 0, tmp_key_data.key_data_length[k]);
+ free( tmp_key_data.key_data_contents[k] );
+ tmp_key_data.key_data_contents[k] = NULL;
+ }
+ }
+
}
add_key_rnd_err:
krb5_db_free_principal(context, &krbtgt_entry, one);
+ for( i = 0; i < tmp_key_data.key_data_ver; i++ )
+ {
+ if( tmp_key_data.key_data_contents[i] )
+ {
+ memset( tmp_key_data.key_data_contents[i], 0, tmp_key_data.key_data_length[i]);
+ free( tmp_key_data.key_data_contents[i] );
+ }
+ }
return(retval);
}
@@ -248,6 +292,7 @@ krb5_dbe_crk(context, master_key, ks_tuple, ks_tuple_count, keepold, db_entry)
db_entry->key_data[i+n_new_key_data] = key_data[i];
memset(&key_data[i], 0, sizeof(krb5_key_data));
}
+ krb5_db_free(context, key_data); /* we moved the cotents to new memory. But, the original block which contained the data */
} else {
cleanup_key_data(context, key_data_count, key_data);
}
@@ -327,7 +372,11 @@ add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd,
krb5_keysalt key_salt;
krb5_keyblock key;
krb5_data pwd;
- int i, j;
+ int i, j, k;
+ krb5_key_data tmp_key_data;
+ krb5_key_data *tptr;
+
+ memset( &tmp_key_data, 0, sizeof(tmp_key_data));
retval = 0;
@@ -418,8 +467,10 @@ add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd,
pwd.data = passwd;
pwd.length = strlen(passwd);
+ /* Solaris Kerberos */
memset(&key, 0, sizeof (krb5_keyblock));
-
+
+ /* AFS string to key will happen here */
if ((retval = krb5_c_string_to_key(context, ks_tuple[i].ks_enctype,
&pwd, &key_salt.data, &key))) {
if (key_salt.data.data)
@@ -431,20 +482,58 @@ add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd,
key_salt.data.length =
krb5_princ_realm(context, db_entry->princ)->length;
- if ((retval = krb5_dbekd_encrypt_key_data(context, master_key, &key,
- (const krb5_keysalt *)&key_salt,
- kvno, &db_entry->key_data[db_entry->n_key_data-1]))) {
- if (key_salt.data.data)
- free(key_salt.data.data);
-
- krb5_free_keyblock_contents(context, &key);
- return(retval);
- }
+ /* memory allocation to be done by db. So, use temporary block and later copy
+ it to the memory allocated by db */
+ retval = krb5_dbekd_encrypt_key_data(context, master_key, &key,
+ (const krb5_keysalt *)&key_salt,
+ kvno, &tmp_key_data);
if (key_salt.data.data)
- free(key_salt.data.data);
+ free(key_salt.data.data);
+ /* Solaris Kerberos */
krb5_free_keyblock_contents(context, &key);
+
+ if( retval )
+ return retval;
+
+ tptr = &db_entry->key_data[db_entry->n_key_data-1];
+
+ tptr->key_data_ver = tmp_key_data.key_data_ver;
+ tptr->key_data_kvno = tmp_key_data.key_data_kvno;
+
+ for( k = 0; k < tmp_key_data.key_data_ver; k++ )
+ {
+ tptr->key_data_type[k] = tmp_key_data.key_data_type[k];
+ tptr->key_data_length[k] = tmp_key_data.key_data_length[k];
+ if( tmp_key_data.key_data_contents[k] )
+ {
+ tptr->key_data_contents[k] = krb5_db_alloc(context, NULL, tmp_key_data.key_data_length[k]);
+ if( tptr->key_data_contents[k] == NULL )
+ {
+ cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data);
+ db_entry->key_data = NULL;
+ db_entry->n_key_data = 0;
+ retval = ENOMEM;
+ goto add_key_pwd_err;
+ }
+ memcpy( tptr->key_data_contents[k], tmp_key_data.key_data_contents[k], tmp_key_data.key_data_length[k]);
+
+ memset( tmp_key_data.key_data_contents[k], 0, tmp_key_data.key_data_length[k]);
+ free( tmp_key_data.key_data_contents[k] );
+ tmp_key_data.key_data_contents[k] = NULL;
+ }
+ }
+ }
+ add_key_pwd_err:
+ for( i = 0; i < tmp_key_data.key_data_ver; i++ )
+ {
+ if( tmp_key_data.key_data_contents[i] )
+ {
+ memset( tmp_key_data.key_data_contents[i], 0, tmp_key_data.key_data_length[i]);
+ free( tmp_key_data.key_data_contents[i] );
+ }
}
+
return(retval);
}
@@ -566,3 +655,5 @@ krb5_dbe_apw(context, master_key, ks_tuple, ks_tuple_count, passwd, db_entry)
}
return(retval);
}
+
+
diff --git a/usr/src/lib/krb5/kdb/keytab.c b/usr/src/lib/krb5/kdb/keytab.c
index fbf259a80c..08fb55cfdf 100644
--- a/usr/src/lib/krb5/kdb/keytab.c
+++ b/usr/src/lib/krb5/kdb/keytab.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* kadmin/v5server/keytab.c
*
@@ -150,11 +149,11 @@ krb5_ktkdb_get_entry(in_context, id, principal, kvno, enctype, entry)
kerror = krb5_db_get_principal(context, principal, &
db_entry, &n, &more);
if (kerror) {
- /* krb5_db_close_database(context); */
+ /* krb5_db_close_database(context); */
return(kerror);
}
if (n != 1) {
- /* krb5_db_close_database(context); */
+ /* krb5_db_close_database(context); */
return KRB5_KT_NOTFOUND;
}
@@ -209,7 +208,7 @@ krb5_ktkdb_get_entry(in_context, id, principal, kvno, enctype, entry)
/* Close database */
error:
krb5_db_free_principal(context, &db_entry, 1);
- /* krb5_db_close_database(context); */
+ /* krb5_db_close_database(context); */
return(kerror);
}
diff --git a/usr/src/lib/krb5/plugins/Makefile b/usr/src/lib/krb5/plugins/Makefile
index fcd16e242b..baeda9e18e 100644
--- a/usr/src/lib/krb5/plugins/Makefile
+++ b/usr/src/lib/krb5/plugins/Makefile
@@ -18,10 +18,9 @@
#
# CDDL HEADER END
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
#
# include global definitions
include ../../../Makefile.master
@@ -31,7 +30,8 @@ include ../../../Makefile.master
.PARALLEL:
SUBDIRS= \
- kdb
+ kdb \
+ preauth
all := TARGET= all
install := TARGET= install
diff --git a/usr/src/lib/krb5/plugins/kdb/db2/adb_policy.c b/usr/src/lib/krb5/plugins/kdb/db2/adb_policy.c
index 2d473e0b98..9b503f3f95 100644
--- a/usr/src/lib/krb5/plugins/kdb/db2/adb_policy.c
+++ b/usr/src/lib/krb5/plugins/kdb/db2/adb_policy.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -21,11 +20,11 @@
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
- * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/adb_policy.c,v 1.7 2003/01/05 23:27:59 hartmans Exp $
+ * $Header$
*/
#if !defined(lint) && !defined(__CODECENTER__)
-static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/adb_policy.c,v 1.7 2003/01/05 23:27:59 hartmans Exp $";
+static char *rcsid = "$Header$";
#endif
#include <sys/file.h>
diff --git a/usr/src/lib/krb5/plugins/kdb/db2/db2_exp.c b/usr/src/lib/krb5/plugins/kdb/db2/db2_exp.c
index df7b42b51f..653e70f8d4 100644
--- a/usr/src/lib/krb5/plugins/kdb/db2/db2_exp.c
+++ b/usr/src/lib/krb5/plugins/kdb/db2/db2_exp.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 2006 by the Massachusetts Institute of Technology.
@@ -264,6 +263,6 @@ kdb_vftabl kdb_function_table = {
/* db_free */ wrap_krb5_db2_free,
/* set_master_key */ wrap_krb5_db2_set_master_key_ext,
/* get_master_key */ wrap_krb5_db2_db_get_mkey,
- /* blah blah blah */ 0,0,0,0,0,0,
+ /* blah blah blah */ 0,0,0,0,0,0,
/* promote_db */ wrap_krb5_db2_promote_db,
};
diff --git a/usr/src/lib/krb5/plugins/kdb/db2/kdb_db2.c b/usr/src/lib/krb5/plugins/kdb/db2/kdb_db2.c
index 75676df92e..536b31ee4f 100644
--- a/usr/src/lib/krb5/plugins/kdb/db2/kdb_db2.c
+++ b/usr/src/lib/krb5/plugins/kdb/db2/kdb_db2.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/kdb/kdb_db2.c
@@ -69,7 +68,7 @@
#include <stdio.h>
#include <errno.h>
#include <utime.h>
-#include <kdb5.h>
+#include "kdb5.h"
#include "kdb_db2.h"
#include "kdb_xdr.h"
#include "policy_db.h"
@@ -938,7 +937,6 @@ krb5_db2_db_destroy(krb5_context context, char *dbname)
if (retval1 || retval2)
return (retval1 ? retval1 : retval2);
-
assert (strlen(dbname) + strlen("%s.kadm5") < sizeof(policy_db_name));
sprintf(policy_db_name, "%s.kadm5", dbname);
/* XXX finish this */
diff --git a/usr/src/lib/krb5/plugins/kdb/db2/libdb2/hash/dbm.c b/usr/src/lib/krb5/plugins/kdb/db2/libdb2/hash/dbm.c
index cdae51c0a3..9d6c7012a5 100644
--- a/usr/src/lib/krb5/plugins/kdb/db2/libdb2/hash/dbm.c
+++ b/usr/src/lib/krb5/plugins/kdb/db2/libdb2/hash/dbm.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*-
* Copyright (c) 1990, 1993
@@ -52,6 +51,7 @@ static char sccsid[] = "@(#)dbm.c 8.6 (Berkeley) 11/7/95";
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
+
#include <libintl.h>
#include "db-ndbm.h"
#include "hash.h"
@@ -96,6 +96,7 @@ kdb2_fetch(key)
if (__cur_db == NULL) {
no_open_db();
item.dptr = 0;
+ item.dsize = 0;
return (item);
}
return (kdb2_dbm_fetch(__cur_db, key));
@@ -109,6 +110,7 @@ kdb2_firstkey()
if (__cur_db == NULL) {
no_open_db();
item.dptr = 0;
+ item.dsize = 0;
return (item);
}
return (kdb2_dbm_firstkey(__cur_db));
@@ -123,6 +125,7 @@ kdb2_nextkey(key)
if (__cur_db == NULL) {
no_open_db();
item.dptr = 0;
+ item.dsize = 0;
return (item);
}
return (kdb2_dbm_nextkey(__cur_db));
diff --git a/usr/src/lib/krb5/plugins/kdb/db2/libdb2/hash/hash.c b/usr/src/lib/krb5/plugins/kdb/db2/libdb2/hash/hash.c
index 87fdffae7b..7df1c536e9 100644
--- a/usr/src/lib/krb5/plugins/kdb/db2/libdb2/hash/hash.c
+++ b/usr/src/lib/krb5/plugins/kdb/db2/libdb2/hash/hash.c
@@ -1,6 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
@@ -114,10 +111,8 @@ __kdb2_hash_open(file, flags, mode, info, dflags)
errno = EINVAL;
return (NULL);
}
- if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB)))) {
- errno = ENOMEM;
+ if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB))))
return (NULL);
- }
hashp->fp = -1;
/* set this now, before file goes away... */
@@ -276,6 +271,7 @@ __kdb2_hash_open(file, flags, mode, info, dflags)
return (dbp);
error2:
+ save_errno = errno;
hdestroy(hashp);
errno = save_errno;
return (NULL);
diff --git a/usr/src/lib/krb5/plugins/kdb/db2/libdb2/include/db-int.h b/usr/src/lib/krb5/plugins/kdb/db2/libdb2/include/db-int.h
index c5c43a481a..694f1c0a41 100644
--- a/usr/src/lib/krb5/plugins/kdb/db2/libdb2/include/db-int.h
+++ b/usr/src/lib/krb5/plugins/kdb/db2/libdb2/include/db-int.h
@@ -1,12 +1,11 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _KRB5_DB2_MISC_H
#define _KRB5_DB2_MISC_H
-#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
@@ -50,7 +49,7 @@ extern "C" {
#ifndef _DB_INT_H_
#define _DB_INT_H_
-#include <db.h>
+#include "db.h"
/* deal with autoconf-based stuff */
diff --git a/usr/src/lib/krb5/plugins/kdb/db2/libdb2/include/db-ndbm.h b/usr/src/lib/krb5/plugins/kdb/db2/libdb2/include/db-ndbm.h
index b1ff3e38e1..e99f46fdc9 100644
--- a/usr/src/lib/krb5/plugins/kdb/db2/libdb2/include/db-ndbm.h
+++ b/usr/src/lib/krb5/plugins/kdb/db2/libdb2/include/db-ndbm.h
@@ -1,6 +1,3 @@
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -73,7 +70,7 @@ typedef DB DBM;
#define dbm_nextkey kdb2_dbm_nextkey
#define dbm_open kdb2_dbm_open
#define dbm_store kdb2_dbm_store
-#define dbm_dirinfo kdb2_dbm_dirinfo
+#define dbm_dirfno kdb2_dbm_dirfno
#define dbm_error kdb2_dbm_error
#define dbm_clearerr kdb2_dbm_clearerr
diff --git a/usr/src/lib/krb5/plugins/kdb/db2/libdb2/mpool/mpool.c b/usr/src/lib/krb5/plugins/kdb/db2/libdb2/mpool/mpool.c
index 2881fb813a..56f2749a92 100644
--- a/usr/src/lib/krb5/plugins/kdb/db2/libdb2/mpool/mpool.c
+++ b/usr/src/lib/krb5/plugins/kdb/db2/libdb2/mpool/mpool.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
@@ -395,7 +393,7 @@ new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL)
#ifdef STATISTICS
++mp->pagealloc;
#endif
-#if defined(DEBUG) || defined(PURIFY)
+#if defined(DEBUG) || defined(PURIFY) || 1
memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
#endif
bp->page = (char *)bp + sizeof(BKT);
@@ -453,8 +451,7 @@ mpool_look(mp, pgno)
head = &mp->hqh[HASHKEY(pgno)];
for (bp = head->cqh_first; bp != (void *)head; bp = bp->hq.cqe_next)
- if ((bp->pgno == pgno) &&
- (bp->flags & MPOOL_INUSE == MPOOL_INUSE)) {
+ if ((bp->pgno == pgno) && (bp->flags & MPOOL_INUSE)) {
#ifdef STATISTICS
++mp->cachehit;
#endif
diff --git a/usr/src/lib/krb5/plugins/kdb/db2/pol_xdr.c b/usr/src/lib/krb5/plugins/kdb/db2/pol_xdr.c
index 83991cd27a..c174490702 100644
--- a/usr/src/lib/krb5/plugins/kdb/db2/pol_xdr.c
+++ b/usr/src/lib/krb5/plugins/kdb/db2/pol_xdr.c
@@ -1,7 +1,4 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
-#include <krb5.h>
/* Solaris Kerberos: gssrpc not supported */
#if 0 /************** Begin IFDEF'ed OUT *******************************/
#include <gssrpc/rpc.h>
@@ -14,6 +11,7 @@
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
+#include <krb5.h>
#include <strings.h>
/* Solaris Kerberos: this function taken from MIT's src/lib/rpc/xdr.c */
diff --git a/usr/src/lib/krb5/plugins/kdb/ldap/Makefile.com b/usr/src/lib/krb5/plugins/kdb/ldap/Makefile.com
index 6d7d551406..b92f19520a 100644
--- a/usr/src/lib/krb5/plugins/kdb/ldap/Makefile.com
+++ b/usr/src/lib/krb5/plugins/kdb/ldap/Makefile.com
@@ -22,7 +22,6 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
#
LIBRARY= kldap.a
@@ -64,7 +63,8 @@ CFLAGS += $(CCVERBOSE)
DYNFLAGS += $(KERBRUNPATH)
# setting -L $(ROOT)/usr/lib/gss because libkdb_ldap needs mech_krb5
-LDLIBS += -L $(ROOT)/usr/lib/gss -L $(ROOTLIBDIR) -lkdb_ldap -lc
+LDLIBS += -L $(ROOT)/usr/lib/gss -L $(ROOTLIBDIR) -lkdb_ldap \
+ -lc
.KEEP_STATE:
diff --git a/usr/src/lib/krb5/plugins/kdb/ldap/ldap_exp.c b/usr/src/lib/krb5/plugins/kdb/ldap/ldap_exp.c
index 9cf8b6fcdb..0245e05268 100644
--- a/usr/src/lib/krb5/plugins/kdb/ldap/ldap_exp.c
+++ b/usr/src/lib/krb5/plugins/kdb/ldap/ldap_exp.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/kdb/kdb_ldap/ldap_exp.c
@@ -94,6 +93,6 @@ kdb_vftabl kdb_function_table = {
/* fetch_master_key */ NULL /* krb5_ldap_fetch_mkey */,
/* verify_master_key */ NULL /* krb5_ldap_verify_master_key */,
/* Search enc type */ NULL,
- /* db_change_pwd */ NULL
+ /* Change pwd */ NULL
};
diff --git a/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c b/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c
index 546a6455c5..017b1706bf 100644
--- a/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c
+++ b/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/kdb/kdb_ldap/kdb_ldap.c
@@ -133,12 +132,7 @@ krb5_ldap_read_startup_information(krb5_context context)
memset((char *) &params_in, 0, sizeof(params_in));
memset((char *) &params_out, 0, sizeof(params_out));
- /* Solaris Kerberos: not supported yet */
-#if 0 /************** Begin IFDEF'ed OUT *******************************/
retval = kadm5_get_config_params(context, 1, &params_in, &params_out);
-#else
- retval = kadm5_get_config_params(context, NULL, NULL, &params_in, &params_out);
-#endif /**************** END IFDEF'ed OUT *******************************/
if (retval) {
if ((mask & LDAP_REALM_MAXTICKETLIFE) == 0) {
ldap_context->lrparams->max_life = 24 * 60 * 60; /* 1 day */
diff --git a/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h b/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h
index 9fc00f6a87..1d6ffdfc2f 100644
--- a/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h
+++ b/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,8 +37,6 @@
#ifndef _KDB_LDAP_H
#define _KDB_LDAP_H 1
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* We want the interfaces marked "deprecated" in OpenLDAP. */
#define LDAP_DEPRECATED 1
#include <ldap.h>
@@ -60,6 +58,11 @@
#include <k5-thread.h>
#include <k5-platform.h> /* Solaris Kerberos */
+#include <k5-platform-store_16.h>
+#include <k5-platform-store_32.h>
+#include <k5-platform-load_16.h>
+#include <k5-platform-load_32.h>
+
#include <kdb5.h>
#include "k5-int.h"
#include "ldap_krbcontainer.h"
diff --git a/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c b/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c
index bbdff731e1..c7f871ec3a 100644
--- a/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c
+++ b/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c
@@ -3,7 +3,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/kdb/kdb_ldap/kdb_ldap_conn.c
@@ -65,10 +64,8 @@ krb5_validate_ldap_context(krb5_context context, krb5_ldap_context *ldap_context
goto err_out;
}
- if (ldap_context->bind_pwd == NULL &&
- ldap_context->service_password_file != NULL &&
- ldap_context->service_cert_path == NULL) {
-
+ if (ldap_context->bind_pwd == NULL && ldap_context->service_password_file !=
+ NULL && ldap_context->service_cert_path == NULL) {
if ((st=krb5_ldap_readpassword(context, ldap_context, &password)) != 0) {
prepend_err_str(context, gettext("Error reading password from stash: "), st, st);
goto err_out;
@@ -169,6 +166,7 @@ krb5_ldap_initialize(ldap_context, server_info)
krb5_ldap_server_handle *ldap_server_handle=NULL;
char *errstr = NULL;
+
ldap_server_handle = calloc(1, sizeof(krb5_ldap_server_handle));
if (ldap_server_handle == NULL) {
st = ENOMEM;
diff --git a/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c b/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
index a5ab9834ca..6e498a62ac 100644
--- a/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
+++ b/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/kdb/kdb_ldap/ldap_misc.c
*
@@ -1267,12 +1266,9 @@ getepochtime(strtime, epochtime)
*epochtime = 0;
return EINVAL;
}
- /* Solaris kerberos: don't have krb5int_gmt_mktime at this point */
-#if 0 /************** Begin IFDEF'ed OUT *******************************/
+
*epochtime = krb5int_gmt_mktime(&tme);
-#else
- *epochtime = gmt_mktime(&tme);
-#endif /**************** END IFDEF'ed OUT *******************************/
+
return 0;
}
diff --git a/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
index 9355fd9d2b..6f22fe2e56 100644
--- a/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
+++ b/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/kdb/kdb_ldap/ldap_principal.c
*
@@ -30,7 +28,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -140,13 +138,13 @@ krb5_ldap_free_principal(kcontext , entries, nentries)
}
krb5_error_code
-krb5_ldap_iterate(
- krb5_context context,
- char *match_expr,
- krb5_error_code (*func) (krb5_pointer, krb5_db_entry *),
- krb5_pointer func_arg,
+krb5_ldap_iterate(context, match_expr, func, func_arg, db_args)
+ krb5_context context;
+ char *match_expr;
+ krb5_error_code (*func) (krb5_pointer, krb5_db_entry *);
+ krb5_pointer func_arg;
/* Solaris Kerberos: adding support for -rev/recurse flags */
- char **db_args)
+ char **db_args;
{
krb5_db_entry entry;
krb5_principal principal;
diff --git a/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c b/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c
index abe747a5ee..4bfd0ffef5 100644
--- a/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c
+++ b/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* lib/kdb/kdb_ldap/ldap_tkt_policy.c
*
@@ -303,7 +301,7 @@ krb5_ldap_delete_policy(context, policyname)
krb5_ldap_context *ldap_context=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
- if (policyname == NULL) {
+ if (policyname == NULL) {
st = EINVAL;
prepend_err_str (context, gettext("Ticket Policy Object DN missing"),st,st);
goto cleanup;
diff --git a/usr/src/lib/krb5/plugins/preauth/Makefile b/usr/src/lib/krb5/plugins/preauth/Makefile
new file mode 100644
index 0000000000..884a2af6ff
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/Makefile
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#
+# include global definitions
+include ../../../../Makefile.master
+
+#
+# Build everything in parallel; use .WAIT for dependencies
+.PARALLEL:
+
+SUBDIRS= \
+ pkinit
+
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+lint := TARGET= lint
+_msg := TARGET= _msg
+
+.KEEP_STATE:
+
+all install clean clobber lint _msg: $(SUBDIRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/Makefile b/usr/src/lib/krb5/plugins/preauth/pkinit/Makefile
new file mode 100644
index 0000000000..84965753db
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/Makefile
@@ -0,0 +1,55 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include $(SRC)/lib/krb5/Makefile.lib
+
+include $(SRC)/lib/gss_mechs/mech_krb5/Makefile.mech_krb5
+
+SUBDIRS= $(MACH)
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+install := TARGET= install
+lint := TARGET= lint
+_msg := TARGET= _msg
+
+.KEEP_STATE:
+
+all clean clobber lint _msg: $(SUBDIRS)
+
+$(ROOTLIBDIR):
+ $(INS.dir)
+
+$(ROOTLIBDIR)/%: %
+ $(INS.file)
+
+install: $(ROOTLIBDIR) $(SUBDIRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/Makefile.com b/usr/src/lib/krb5/plugins/preauth/pkinit/Makefile.com
new file mode 100644
index 0000000000..cc5516bf7c
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/Makefile.com
@@ -0,0 +1,94 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+LIBRARY= pkinit.a
+VERS= .1
+
+PKINIT_OBJS= \
+ pkinit_accessor.o \
+ pkinit_clnt.o \
+ pkinit_crypto_openssl.o \
+ pkinit_identity.o \
+ pkinit_lib.o \
+ pkinit_matching.o \
+ pkinit_profile.o \
+ pkinit_srv.o
+
+
+OBJECTS= $(PKINIT_OBJS)
+
+# include library definitions
+include $(SRC)/lib/krb5/Makefile.lib
+
+SRCS= $(PKINIT_OBJS:%.o=../%.c)
+
+LIBS= $(DYNLIB)
+
+include $(SRC)/lib/gss_mechs/mech_krb5/Makefile.mech_krb5
+
+POFILE = $(LIBRARY:%.a=%.po)
+POFILES = generic.po
+
+#override liblink
+INS.liblink= -$(RM) $@; $(SYMLINK) $(LIBLINKS)$(VERS) $@
+
+include $(SRC)/lib/openssl/Makefile.openssl
+
+CPPFLAGS += $(OPENSSL_CPPFLAGS) \
+ -I$(SRC)/lib/krb5 \
+ -I$(SRC)/lib/krb5/kdb \
+ -I$(SRC)/lib/gss_mechs/mech_krb5/include \
+ -I$(SRC)/lib/gss_mechs/mech_krb5/krb5/os \
+ -I$(SRC)/lib/gss_mechs/mech_krb5/include/krb5 \
+ -I$(SRC)/uts/common/gssapi/include/ \
+ -I$(SRC)/uts/common/gssapi/mechs/krb5/include \
+ -I$(SRC)
+
+CFLAGS += $(CCVERBOSE) -I..
+DYNFLAGS += $(KRUNPATH) $(KMECHLIB) $(OPENSSL_DYNFLAGS)
+LDLIBS += -L $(ROOTLIBDIR) $(OPENSSL_LDFLAGS) -lcrypto -lc
+
+ROOTLIBDIR= $(ROOT)/usr/lib/krb5/plugins/preauth
+
+$(ROOTLIBDIR):
+ $(INS.dir)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+# include library targets
+include $(SRC)/lib/krb5/Makefile.targ
+
+FRC:
+
+generic.po: FRC
+ $(RM) messages.po
+ $(XGETTEXT) $(XGETFLAGS) `$(GREP) -l gettext ../*.[ch]`
+ $(SED) "/^domain/d" messages.po > $@
+ $(RM) messages.po
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/i386/Makefile b/usr/src/lib/krb5/plugins/preauth/pkinit/i386/Makefile
new file mode 100644
index 0000000000..8bc3adb7c7
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/i386/Makefile
@@ -0,0 +1,29 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/mapfile-vers b/usr/src/lib/krb5/plugins/preauth/pkinit/mapfile-vers
new file mode 100644
index 0000000000..5e2c0307bd
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/mapfile-vers
@@ -0,0 +1,37 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+# Due to mistakes made early in the history of this library, there are
+# no SUNW_1.1 symbols, but the version is now kept as a placeholder.
+# Don't add any symbols to this version.
+
+SUNWprivate_1.1 {
+ global:
+ preauthentication_client_1;
+ preauthentication_server_1;
+ local:
+ *;
+};
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit.h b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit.h
new file mode 100644
index 0000000000..9ae77a2a5f
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit.h
@@ -0,0 +1,364 @@
+/*
+ * COPYRIGHT (C) 2006,2007
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#ifndef _PKINIT_H
+#define _PKINIT_H
+
+/* Solaris Kerberos */
+#include <preauth_plugin.h>
+#include <k5-int-pkinit.h>
+#include <profile.h>
+#include "pkinit_accessor.h"
+
+/*
+ * It is anticipated that all the special checks currently
+ * required when talking to a Longhorn server will go away
+ * by the time it is officially released and all references
+ * to the longhorn global can be removed and any code
+ * #ifdef'd with LONGHORN_BETA_COMPAT can be removed.
+ * And this #define!
+ */
+#define LONGHORN_BETA_COMPAT 1
+#ifdef LONGHORN_BETA_COMPAT
+extern int longhorn; /* XXX Talking to a Longhorn server? */
+#endif
+
+
+#ifndef WITHOUT_PKCS11
+/* Solaris Kerberos */
+#include <security/cryptoki.h>
+#include <security/pkcs11.h>
+
+/* Solaris Kerberos */
+#define PKCS11_MODNAME "/usr/lib/libpkcs11.so"
+
+#define PK_SIGLEN_GUESS 1000
+#define PK_NOSLOT 999999
+#endif
+
+#define DH_PROTOCOL 1
+#define RSA_PROTOCOL 2
+
+#define TD_TRUSTED_CERTIFIERS 104
+#define TD_INVALID_CERTIFICATES 105
+#define TD_DH_PARAMETERS 109
+
+#define PKINIT_CTX_MAGIC 0x05551212
+#define PKINIT_REQ_CTX_MAGIC 0xdeadbeef
+
+#define PKINIT_DEFAULT_DH_MIN_BITS 2048
+
+/* Make pkiDebug(fmt,...) print, or not. */
+#ifdef DEBUG
+#define pkiDebug printf
+#else
+/* Still evaluates for side effects. */
+/* ARGSUSED */
+static void pkiDebug (const char *fmt, ...) { }
+/* This is better if the compiler doesn't inline variadic functions
+ well, but gcc will warn about "left-hand operand of comma
+ expression has no effect". Still evaluates for side effects. */
+/* #define pkiDebug (void) */
+#endif
+
+/* Solaris Kerberos */
+#if (__STDC_VERSION__ >= 199901L) || \
+ (defined(__SUNPRO_C) && defined(__C99FEATURES__))
+#define __FUNCTION__ __func__
+#else
+#define __FUNCTION__ ""
+#endif
+
+
+/* Macros to deal with converting between various data types... */
+#define PADATA_TO_KRB5DATA(pad, k5d) \
+ (k5d)->length = (pad)->length; (k5d)->data = (char *)(pad)->contents;
+#define OCTETDATA_TO_KRB5DATA(octd, k5d) \
+ (k5d)->length = (octd)->length; (k5d)->data = (char *)(octd)->data;
+
+extern const krb5_octet_data dh_oid;
+
+/*
+ * notes about crypto contexts:
+ *
+ * the basic idea is that there are crypto contexts that live at
+ * both the plugin level and request level. the identity context (that
+ * keeps info about your own certs and such) is separate because
+ * it is needed at different levels for the kdc and and the client.
+ * (the kdc's identity is at the plugin level, the client's identity
+ * information could change per-request.)
+ * the identity context is meant to have the entity's cert,
+ * a list of trusted and intermediate cas, a list of crls, and any
+ * pkcs11 information. the req context is meant to have the
+ * received certificate and the DH related information. the plugin
+ * context is meant to have global crypto information, i.e., OIDs
+ * and constant DH parameter information.
+ */
+
+/*
+ * plugin crypto context should keep plugin common information,
+ * eg., OIDs, known DHparams
+ */
+typedef struct _pkinit_plg_crypto_context *pkinit_plg_crypto_context;
+
+/*
+ * request crypto context should keep reqyest common information,
+ * eg., received credentials, DH parameters of this request
+ */
+typedef struct _pkinit_req_crypto_context *pkinit_req_crypto_context;
+
+/*
+ * identity context should keep information about credentials
+ * for the request, eg., my credentials, trusted ca certs,
+ * intermediate ca certs, crls, pkcs11 info
+ */
+typedef struct _pkinit_identity_crypto_context *pkinit_identity_crypto_context;
+
+/*
+ * this structure keeps information about the config options
+ */
+typedef struct _pkinit_plg_opts {
+ int require_eku; /* require EKU checking (default is true) */
+ int accept_secondary_eku;/* accept secondary EKU (default is false) */
+ int allow_upn; /* allow UPN-SAN instead of pkinit-SAN */
+ int dh_or_rsa; /* selects DH or RSA based pkinit */
+ int require_crl_checking; /* require CRL for a CA (default is false) */
+ int dh_min_bits; /* minimum DH modulus size allowed */
+} pkinit_plg_opts;
+
+/*
+ * this structure keeps options used for a given request
+ */
+typedef struct _pkinit_req_opts {
+ int require_eku;
+ int accept_secondary_eku;
+ int allow_upn;
+ int dh_or_rsa;
+ int require_crl_checking;
+ int dh_size; /* initial request DH modulus size (default=1024) */
+ int require_hostname_match;
+ int win2k_target;
+ int win2k_require_cksum;
+} pkinit_req_opts;
+
+/*
+ * information about identity from config file or command line
+ */
+
+#define PKINIT_ID_OPT_USER_IDENTITY 1
+#define PKINIT_ID_OPT_ANCHOR_CAS 2
+#define PKINIT_ID_OPT_INTERMEDIATE_CAS 3
+#define PKINIT_ID_OPT_CRLS 4
+#define PKINIT_ID_OPT_OCSP 5
+#define PKINIT_ID_OPT_DN_MAPPING 6 /* XXX ? */
+
+typedef struct _pkinit_identity_opts {
+ char *identity;
+ char **identity_alt;
+ char **anchors;
+ char **intermediates;
+ char **crls;
+ char *ocsp;
+ char *dn_mapping_file;
+ int idtype;
+ char *cert_filename;
+ char *key_filename;
+#ifndef WITHOUT_PKCS11
+ char *p11_module_name;
+ CK_SLOT_ID slotid;
+ char *token_label;
+ char *cert_id_string;
+ char *cert_label;
+#endif
+} pkinit_identity_opts;
+
+
+/*
+ * Client's plugin context
+ */
+struct _pkinit_context {
+ int magic;
+ pkinit_plg_crypto_context cryptoctx;
+ pkinit_plg_opts *opts;
+ pkinit_identity_opts *idopts;
+};
+typedef struct _pkinit_context *pkinit_context;
+
+/*
+ * Client's per-request context
+ */
+struct _pkinit_req_context {
+ int magic;
+ pkinit_req_crypto_context cryptoctx;
+ pkinit_req_opts *opts;
+ pkinit_identity_crypto_context idctx;
+ pkinit_identity_opts *idopts;
+ krb5_preauthtype pa_type;
+};
+typedef struct _pkinit_kdc_context *pkinit_kdc_context;
+
+/*
+ * KDC's (per-realm) plugin context
+ */
+struct _pkinit_kdc_context {
+ int magic;
+ pkinit_plg_crypto_context cryptoctx;
+ pkinit_plg_opts *opts;
+ pkinit_identity_crypto_context idctx;
+ pkinit_identity_opts *idopts;
+ char *realmname;
+ unsigned int realmname_len;
+};
+typedef struct _pkinit_req_context *pkinit_req_context;
+
+/*
+ * KDC's per-request context
+ */
+struct _pkinit_kdc_req_context {
+ int magic;
+ pkinit_req_crypto_context cryptoctx;
+ krb5_auth_pack *rcv_auth_pack;
+ krb5_auth_pack_draft9 *rcv_auth_pack9;
+ krb5_preauthtype pa_type;
+};
+typedef struct _pkinit_kdc_req_context *pkinit_kdc_req_context;
+
+/*
+ * Functions in pkinit_lib.c
+ */
+
+krb5_error_code pkinit_init_req_opts(pkinit_req_opts **);
+void pkinit_fini_req_opts(pkinit_req_opts *);
+
+krb5_error_code pkinit_init_plg_opts(pkinit_plg_opts **);
+void pkinit_fini_plg_opts(pkinit_plg_opts *);
+
+krb5_error_code pkinit_init_identity_opts(pkinit_identity_opts **idopts);
+void pkinit_fini_identity_opts(pkinit_identity_opts *idopts);
+krb5_error_code pkinit_dup_identity_opts(pkinit_identity_opts *src_opts,
+ pkinit_identity_opts **dest_opts);
+
+/*
+ * Functions in pkinit_identity.c
+ */
+char * idtype2string(int idtype);
+char * catype2string(int catype);
+
+krb5_error_code pkinit_identity_initialize
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_opts *idopts, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN/OUT */
+ int do_matching, /* IN */
+ krb5_principal princ); /* IN (optional) */
+
+krb5_error_code pkinit_cert_matching
+ (krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_principal princ);
+
+/*
+ * initialization and free functions
+ */
+void init_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in);
+void init_krb5_pa_pk_as_req_draft9(krb5_pa_pk_as_req_draft9 **in);
+void init_krb5_reply_key_pack(krb5_reply_key_pack **in);
+void init_krb5_reply_key_pack_draft9(krb5_reply_key_pack_draft9 **in);
+
+void init_krb5_auth_pack(krb5_auth_pack **in);
+void init_krb5_auth_pack_draft9(krb5_auth_pack_draft9 **in);
+void init_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in);
+void init_krb5_pa_pk_as_rep_draft9(krb5_pa_pk_as_rep_draft9 **in);
+void init_krb5_typed_data(krb5_typed_data **in);
+void init_krb5_subject_pk_info(krb5_subject_pk_info **in);
+
+void free_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in);
+void free_krb5_pa_pk_as_req_draft9(krb5_pa_pk_as_req_draft9 **in);
+void free_krb5_reply_key_pack(krb5_reply_key_pack **in);
+void free_krb5_reply_key_pack_draft9(krb5_reply_key_pack_draft9 **in);
+void free_krb5_auth_pack(krb5_auth_pack **in);
+void free_krb5_auth_pack_draft9(krb5_context, krb5_auth_pack_draft9 **in);
+void free_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in);
+void free_krb5_pa_pk_as_rep_draft9(krb5_pa_pk_as_rep_draft9 **in);
+void free_krb5_external_principal_identifier(krb5_external_principal_identifier ***in);
+void free_krb5_trusted_ca(krb5_trusted_ca ***in);
+void free_krb5_typed_data(krb5_typed_data ***in);
+void free_krb5_algorithm_identifiers(krb5_algorithm_identifier ***in);
+void free_krb5_algorithm_identifier(krb5_algorithm_identifier *in);
+void free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in);
+void free_krb5_subject_pk_info(krb5_subject_pk_info **in);
+krb5_error_code pkinit_copy_krb5_octet_data(krb5_octet_data *dst, const krb5_octet_data *src);
+
+
+/*
+ * Functions in pkinit_profile.c
+ */
+krb5_error_code pkinit_kdcdefault_strings
+ (krb5_context context, const char *realmname, const char *option,
+ char ***ret_value);
+krb5_error_code pkinit_kdcdefault_string
+ (krb5_context context, const char *realmname, const char *option,
+ char **ret_value);
+krb5_error_code pkinit_kdcdefault_boolean
+ (krb5_context context, const char *realmname, const char *option,
+ int default_value, int *ret_value);
+krb5_error_code pkinit_kdcdefault_integer
+ (krb5_context context, const char *realmname, const char *option,
+ int default_value, int *ret_value);
+
+
+krb5_error_code pkinit_libdefault_strings
+ (krb5_context context, const krb5_data *realm,
+ const char *option, char ***ret_value);
+krb5_error_code pkinit_libdefault_string
+ (krb5_context context, const krb5_data *realm,
+ const char *option, char **ret_value);
+krb5_error_code pkinit_libdefault_boolean
+ (krb5_context context, const krb5_data *realm, const char *option,
+ int default_value, int *ret_value);
+krb5_error_code pkinit_libdefault_integer
+ (krb5_context context, const krb5_data *realm, const char *option,
+ int default_value, int *ret_value);
+
+/*
+ * debugging functions
+ */
+void print_buffer(unsigned char *, unsigned int);
+void print_buffer_bin(unsigned char *, unsigned int, char *);
+
+/*
+ * Now get crypto function declarations
+ */
+#include "pkinit_crypto.h"
+
+#endif /* _PKINIT_H */
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_accessor.c b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_accessor.c
new file mode 100644
index 0000000000..e954ca361c
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_accessor.c
@@ -0,0 +1,118 @@
+/*
+ * COPYRIGHT (C) 2006,2007
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#include <k5-int.h>
+#include "pkinit_accessor.h"
+
+#define DEF_FUNC_PTRS(type) \
+krb5_error_code (*k5int_encode_##type)(const type *, krb5_data **); \
+krb5_error_code (*k5int_decode_##type)(const krb5_data *, type **)
+
+#define DEF_FUNC_PTRS_ARRAY(type) \
+krb5_error_code (*k5int_encode_##type)(const type **, krb5_data **); \
+krb5_error_code (*k5int_decode_##type)(const krb5_data *, type ***)
+
+DEF_FUNC_PTRS(krb5_auth_pack);
+DEF_FUNC_PTRS(krb5_auth_pack_draft9);
+DEF_FUNC_PTRS(krb5_kdc_dh_key_info);
+DEF_FUNC_PTRS(krb5_pa_pk_as_rep);
+DEF_FUNC_PTRS(krb5_pa_pk_as_rep_draft9);
+DEF_FUNC_PTRS(krb5_pa_pk_as_req);
+DEF_FUNC_PTRS(krb5_pa_pk_as_req_draft9);
+DEF_FUNC_PTRS(krb5_reply_key_pack);
+DEF_FUNC_PTRS(krb5_reply_key_pack_draft9);
+DEF_FUNC_PTRS_ARRAY(krb5_typed_data);
+
+/* special cases... */
+krb5_error_code (*k5int_decode_krb5_principal_name)
+ (const krb5_data *, krb5_principal_data **);
+
+krb5_error_code (*k5int_encode_krb5_td_dh_parameters)
+ (const krb5_algorithm_identifier **, krb5_data **code);
+krb5_error_code (*k5int_decode_krb5_td_dh_parameters)
+ (const krb5_data *, krb5_algorithm_identifier ***);
+
+krb5_error_code (*k5int_encode_krb5_td_trusted_certifiers)
+ (const krb5_external_principal_identifier **, krb5_data **code);
+krb5_error_code (*k5int_decode_krb5_td_trusted_certifiers)
+ (const krb5_data *, krb5_external_principal_identifier ***);
+
+krb5_error_code (*k5int_decode_krb5_as_req)
+ (const krb5_data *output, krb5_kdc_req **rep);
+krb5_error_code (*k5int_encode_krb5_kdc_req_body)
+ (const krb5_kdc_req *rep, krb5_data **code);
+void KRB5_CALLCONV (*k5int_krb5_free_kdc_req)
+ (krb5_context, krb5_kdc_req * );
+void (*k5int_set_prompt_types)
+ (krb5_context, krb5_prompt_type *);
+krb5_error_code (*k5int_encode_krb5_authdata_elt)
+ (const krb5_authdata *rep, krb5_data **code);
+
+
+
+/*
+ * Grab internal function pointers from the krb5int_accessor
+ * structure and make them available
+ */
+krb5_error_code
+pkinit_accessor_init(void)
+{
+ krb5_error_code retval;
+ krb5int_access k5int;
+
+ retval = krb5int_accessor(&k5int, KRB5INT_ACCESS_VERSION);
+ if (retval)
+ return retval;
+#define SET_PTRS(type) \
+k5int_encode_##type = k5int.encode_##type; \
+k5int_decode_##type = k5int.decode_##type;
+
+ SET_PTRS(krb5_auth_pack);
+ SET_PTRS(krb5_auth_pack_draft9);
+ SET_PTRS(krb5_kdc_dh_key_info);
+ SET_PTRS(krb5_pa_pk_as_rep);
+ SET_PTRS(krb5_pa_pk_as_rep_draft9);
+ SET_PTRS(krb5_pa_pk_as_req);
+ SET_PTRS(krb5_pa_pk_as_req_draft9);
+ SET_PTRS(krb5_reply_key_pack);
+ SET_PTRS(krb5_reply_key_pack_draft9);
+ SET_PTRS(krb5_td_dh_parameters);
+ SET_PTRS(krb5_td_trusted_certifiers);
+ SET_PTRS(krb5_typed_data);
+
+ /* special cases... */
+ k5int_decode_krb5_principal_name = k5int.decode_krb5_principal_name;
+ k5int_decode_krb5_as_req = k5int.decode_krb5_as_req;
+ k5int_encode_krb5_kdc_req_body = k5int.encode_krb5_kdc_req_body;
+ k5int_krb5_free_kdc_req = k5int.krb5_free_kdc_req;
+ k5int_set_prompt_types = k5int.krb5int_set_prompt_types;
+ k5int_encode_krb5_authdata_elt = k5int.encode_krb5_authdata_elt;
+ return 0;
+}
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_accessor.h b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_accessor.h
new file mode 100644
index 0000000000..ba82533c8c
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_accessor.h
@@ -0,0 +1,83 @@
+/*
+ * COPYRIGHT (C) 2006,2007
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#ifndef _PKINIT_ACCESSOR_H
+#define _PKINIT_ACCESSOR_H
+
+/*
+ * Function prototypes
+ */
+krb5_error_code pkinit_accessor_init(void);
+
+#define DEF_EXT_FUNC_PTRS(type) \
+extern krb5_error_code (*k5int_encode_##type)(const type *, krb5_data **); \
+extern krb5_error_code (*k5int_decode_##type)(const krb5_data *, type **)
+
+#define DEF_EXT_FUNC_PTRS_ARRAY(type) \
+extern krb5_error_code (*k5int_encode_##type)(const type **, krb5_data **); \
+extern krb5_error_code (*k5int_decode_##type)(const krb5_data *, type ***)
+
+DEF_EXT_FUNC_PTRS(krb5_auth_pack);
+DEF_EXT_FUNC_PTRS(krb5_auth_pack_draft9);
+DEF_EXT_FUNC_PTRS(krb5_kdc_dh_key_info);
+DEF_EXT_FUNC_PTRS(krb5_pa_pk_as_rep);
+DEF_EXT_FUNC_PTRS(krb5_pa_pk_as_rep_draft9);
+DEF_EXT_FUNC_PTRS(krb5_pa_pk_as_req);
+DEF_EXT_FUNC_PTRS(krb5_pa_pk_as_req_draft9);
+DEF_EXT_FUNC_PTRS(krb5_reply_key_pack);
+DEF_EXT_FUNC_PTRS(krb5_reply_key_pack_draft9);
+DEF_EXT_FUNC_PTRS_ARRAY(krb5_typed_data);
+
+/* special cases... */
+extern krb5_error_code (*k5int_decode_krb5_principal_name)
+ (const krb5_data *, krb5_principal_data **);
+
+extern krb5_error_code (*k5int_encode_krb5_td_dh_parameters)
+ (const krb5_algorithm_identifier **, krb5_data **code);
+extern krb5_error_code (*k5int_decode_krb5_td_dh_parameters)
+ (const krb5_data *, krb5_algorithm_identifier ***);
+
+extern krb5_error_code (*k5int_encode_krb5_td_trusted_certifiers)
+ (const krb5_external_principal_identifier **, krb5_data **code);
+extern krb5_error_code (*k5int_decode_krb5_td_trusted_certifiers)
+ (const krb5_data *, krb5_external_principal_identifier ***);
+
+extern krb5_error_code (*k5int_decode_krb5_as_req)
+ (const krb5_data *output, krb5_kdc_req **rep);
+extern krb5_error_code (*k5int_encode_krb5_kdc_req_body)
+ (const krb5_kdc_req *rep, krb5_data **code);
+extern void KRB5_CALLCONV (*k5int_krb5_free_kdc_req)
+ (krb5_context, krb5_kdc_req * );
+extern void (*k5int_set_prompt_types)
+ (krb5_context, krb5_prompt_type *);
+extern krb5_error_code (*k5int_encode_krb5_authdata_elt)
+ (const krb5_authdata *rep, krb5_data **code);
+
+#endif /* _PKINIT_ACCESSOR_H */
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_clnt.c b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_clnt.c
new file mode 100644
index 0000000000..296d051708
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_clnt.c
@@ -0,0 +1,1510 @@
+/*
+ * COPYRIGHT (C) 2006,2007
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <dlfcn.h>
+#include <sys/stat.h>
+
+#include "pkinit.h"
+
+#ifdef LONGHORN_BETA_COMPAT
+/*
+ * It is anticipated that all the special checks currently
+ * required when talking to a Longhorn server will go away
+ * by the time it is officially released and all references
+ * to the longhorn global can be removed and any code
+ * #ifdef'd with LONGHORN_BETA_COMPAT can be removed.
+ *
+ * Current testing (20070620) is against a patched Beta 3
+ * version of Longhorn. Most, if not all, problems should
+ * be fixed in SP1 of Longhorn.
+ */
+int longhorn = 0; /* Talking to a Longhorn server? */
+#endif
+
+krb5_error_code pkinit_client_process
+ (krb5_context context, void *plugin_context, void *request_context,
+ krb5_get_init_creds_opt *gic_opt,
+ preauth_get_client_data_proc get_data_proc,
+ struct _krb5_preauth_client_rock *rock,
+ krb5_kdc_req * request, krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request, krb5_pa_data *in_padata,
+ krb5_prompter_fct prompter, void *prompter_data,
+ preauth_get_as_key_proc gak_fct, void *gak_data,
+ krb5_data * salt, krb5_data * s2kparams,
+ krb5_keyblock * as_key, krb5_pa_data *** out_padata);
+
+krb5_error_code pkinit_client_tryagain
+ (krb5_context context, void *plugin_context, void *request_context,
+ krb5_get_init_creds_opt *gic_opt,
+ preauth_get_client_data_proc get_data_proc,
+ struct _krb5_preauth_client_rock *rock,
+ krb5_kdc_req * request, krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data *in_padata, krb5_error *err_reply,
+ krb5_prompter_fct prompter, void *prompter_data,
+ preauth_get_as_key_proc gak_fct, void *gak_data,
+ krb5_data * salt, krb5_data * s2kparams,
+ krb5_keyblock * as_key, krb5_pa_data *** out_padata);
+
+void pkinit_client_req_init
+ (krb5_context contex, void *plugin_context, void **request_context);
+
+void pkinit_client_req_fini
+ (krb5_context context, void *plugin_context, void *request_context);
+
+krb5_error_code pa_pkinit_gen_req
+ (krb5_context context, pkinit_context plgctx,
+ pkinit_req_context reqctx, krb5_kdc_req * request,
+ krb5_pa_data * in_padata, krb5_pa_data *** out_padata,
+ krb5_prompter_fct prompter, void *prompter_data,
+ krb5_get_init_creds_opt *gic_opt);
+
+krb5_error_code pkinit_as_req_create
+ (krb5_context context, pkinit_context plgctx,
+ pkinit_req_context reqctx, krb5_timestamp ctsec,
+ krb5_int32 cusec, krb5_ui_4 nonce,
+ const krb5_checksum * cksum, krb5_principal server,
+ krb5_data ** as_req);
+
+krb5_error_code pkinit_as_rep_parse
+ (krb5_context context, pkinit_context plgctx,
+ pkinit_req_context reqctx, krb5_preauthtype pa_type,
+ krb5_kdc_req * request, const krb5_data * as_rep,
+ krb5_keyblock * key_block, krb5_enctype etype, krb5_data *);
+
+krb5_error_code pa_pkinit_parse_rep
+ (krb5_context context, pkinit_context plgctx,
+ pkinit_req_context reqcxt, krb5_kdc_req * request,
+ krb5_pa_data * in_padata, krb5_enctype etype,
+ krb5_keyblock * as_key, krb5_data *);
+
+static int pkinit_client_plugin_init(krb5_context context, void **blob);
+static void pkinit_client_plugin_fini(krb5_context context, void *blob);
+
+/* ARGSUSED */
+krb5_error_code
+pa_pkinit_gen_req(krb5_context context,
+ pkinit_context plgctx,
+ pkinit_req_context reqctx,
+ krb5_kdc_req * request,
+ krb5_pa_data * in_padata,
+ krb5_pa_data *** out_padata,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ krb5_get_init_creds_opt *gic_opt)
+{
+
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ krb5_data *out_data = NULL;
+ krb5_timestamp ctsec = 0;
+ krb5_int32 cusec = 0;
+ krb5_ui_4 nonce = 0;
+ krb5_checksum cksum;
+ krb5_data *der_req = NULL;
+ krb5_pa_data **return_pa_data = NULL;
+
+ cksum.contents = NULL;
+ reqctx->pa_type = in_padata->pa_type;
+
+ pkiDebug("kdc_options = 0x%x till = %d\n",
+ request->kdc_options, request->till);
+ /* If we don't have a client, we're done */
+ if (request->client == NULL) {
+ pkiDebug("No request->client; aborting PKINIT\n");
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ retval = pkinit_get_kdc_cert(context, plgctx->cryptoctx, reqctx->cryptoctx,
+ reqctx->idctx, request->server);
+ if (retval) {
+ pkiDebug("pkinit_get_kdc_cert returned %d\n", retval);
+ goto cleanup;
+ }
+
+ /* checksum of the encoded KDC-REQ-BODY */
+ retval = k5int_encode_krb5_kdc_req_body(request, &der_req);
+ if (retval) {
+ pkiDebug("encode_krb5_kdc_req_body returned %d\n", (int) retval);
+ goto cleanup;
+ }
+
+ retval = krb5_c_make_checksum(context, CKSUMTYPE_NIST_SHA, NULL, 0,
+ der_req, &cksum);
+ if (retval)
+ goto cleanup;
+#ifdef DEBUG_CKSUM
+ pkiDebug("calculating checksum on buf size (%d)\n", der_req->length);
+ print_buffer(der_req->data, der_req->length);
+#endif
+
+ retval = krb5_us_timeofday(context, &ctsec, &cusec);
+ if (retval)
+ goto cleanup;
+
+ /* XXX PKINIT RFC says that nonce in PKAuthenticator doesn't have be the
+ * same as in the AS_REQ. However, if we pick a different nonce, then we
+ * need to remember that info when AS_REP is returned. I'm choosing to
+ * reuse the AS_REQ nonce.
+ */
+ nonce = request->nonce;
+
+ retval = pkinit_as_req_create(context, plgctx, reqctx, ctsec, cusec,
+ nonce, &cksum, request->server, &out_data);
+ if (retval || !out_data->length) {
+ pkiDebug("error %d on pkinit_as_req_create; aborting PKINIT\n",
+ (int) retval);
+ goto cleanup;
+ }
+ retval = ENOMEM;
+ /*
+ * The most we'll return is two pa_data, normally just one.
+ * We need to make room for the NULL terminator.
+ */
+ return_pa_data = (krb5_pa_data **) malloc(3 * sizeof(krb5_pa_data *));
+ if (return_pa_data == NULL)
+ goto cleanup;
+
+ return_pa_data[1] = NULL; /* in case of an early trip to cleanup */
+ return_pa_data[2] = NULL; /* Terminate the list */
+
+ return_pa_data[0] = (krb5_pa_data *) malloc(sizeof(krb5_pa_data));
+ if (return_pa_data[0] == NULL)
+ goto cleanup;
+
+ return_pa_data[1] = (krb5_pa_data *) malloc(sizeof(krb5_pa_data));
+ if (return_pa_data[1] == NULL)
+ goto cleanup;
+
+ return_pa_data[0]->magic = KV5M_PA_DATA;
+
+ if (in_padata->pa_type == KRB5_PADATA_PK_AS_REQ_OLD)
+ return_pa_data[0]->pa_type = KRB5_PADATA_PK_AS_REP_OLD;
+ else
+ return_pa_data[0]->pa_type = in_padata->pa_type;
+ return_pa_data[0]->length = out_data->length;
+ return_pa_data[0]->contents = (krb5_octet *) out_data->data;
+
+#ifdef LONGHORN_BETA_COMPAT
+ /*
+ * LH Beta 3 requires the extra pa-data, even for RFC requests,
+ * in order to get the Checksum rather than a Nonce in the reply.
+ * This can be removed when LH SP1 is released.
+ */
+ if ((return_pa_data[0]->pa_type == KRB5_PADATA_PK_AS_REP_OLD
+ && reqctx->opts->win2k_require_cksum) || (longhorn == 1)) {
+#else
+ if ((return_pa_data[0]->pa_type == KRB5_PADATA_PK_AS_REP_OLD
+ && reqctx->opts->win2k_require_cksum)) {
+#endif
+ return_pa_data[1]->pa_type = 132;
+ return_pa_data[1]->length = 0;
+ return_pa_data[1]->contents = NULL;
+ } else {
+ free(return_pa_data[1]);
+ return_pa_data[1] = NULL; /* Move the list terminator */
+ }
+ *out_padata = return_pa_data;
+ retval = 0;
+
+ cleanup:
+ if (der_req != NULL)
+ krb5_free_data(context, der_req);
+
+ if (out_data != NULL)
+ free(out_data);
+
+ if (retval) {
+ if (return_pa_data) {
+ if (return_pa_data[0] != NULL)
+ free(return_pa_data[0]);
+ if (return_pa_data[1] != NULL)
+ free(return_pa_data[1]);
+ free(return_pa_data);
+ }
+ if (out_data) {
+ free(out_data->data);
+ free(out_data);
+ }
+ }
+ return retval;
+}
+
+krb5_error_code
+pkinit_as_req_create(krb5_context context,
+ pkinit_context plgctx,
+ pkinit_req_context reqctx,
+ krb5_timestamp ctsec,
+ krb5_int32 cusec,
+ krb5_ui_4 nonce,
+ const krb5_checksum * cksum,
+ krb5_principal server,
+ krb5_data ** as_req)
+{
+ krb5_error_code retval = ENOMEM;
+ krb5_subject_pk_info *info = NULL;
+ krb5_data *coded_auth_pack = NULL;
+ krb5_auth_pack *auth_pack = NULL;
+ krb5_pa_pk_as_req *req = NULL;
+ krb5_auth_pack_draft9 *auth_pack9 = NULL;
+ krb5_pa_pk_as_req_draft9 *req9 = NULL;
+ int protocol = reqctx->opts->dh_or_rsa;
+
+ pkiDebug("pkinit_as_req_create pa_type = %d\n", reqctx->pa_type);
+
+ /* Create the authpack */
+ switch((int)reqctx->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ protocol = RSA_PROTOCOL;
+ init_krb5_auth_pack_draft9(&auth_pack9);
+ if (auth_pack9 == NULL)
+ goto cleanup;
+ auth_pack9->pkAuthenticator.ctime = ctsec;
+ auth_pack9->pkAuthenticator.cusec = cusec;
+ auth_pack9->pkAuthenticator.nonce = nonce;
+ auth_pack9->pkAuthenticator.kdcName = server;
+ auth_pack9->pkAuthenticator.kdcRealm.magic = 0;
+ auth_pack9->pkAuthenticator.kdcRealm.data =
+ (unsigned char *)server->realm.data;
+ auth_pack9->pkAuthenticator.kdcRealm.length = server->realm.length;
+ free(cksum->contents);
+ break;
+ case KRB5_PADATA_PK_AS_REQ:
+ init_krb5_subject_pk_info(&info);
+ if (info == NULL)
+ goto cleanup;
+ init_krb5_auth_pack(&auth_pack);
+ if (auth_pack == NULL)
+ goto cleanup;
+ auth_pack->pkAuthenticator.ctime = ctsec;
+ auth_pack->pkAuthenticator.cusec = cusec;
+ auth_pack->pkAuthenticator.nonce = nonce;
+ auth_pack->pkAuthenticator.paChecksum = *cksum;
+ auth_pack->clientDHNonce.length = 0;
+ auth_pack->clientPublicValue = info;
+
+ /* add List of CMS algorithms */
+ retval = create_krb5_supportedCMSTypes(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx,
+ &auth_pack->supportedCMSTypes);
+ if (retval)
+ goto cleanup;
+ break;
+ default:
+ pkiDebug("as_req: unrecognized pa_type = %d\n",
+ (int)reqctx->pa_type);
+ retval = -1;
+ goto cleanup;
+ }
+
+ switch(protocol) {
+ case DH_PROTOCOL:
+ pkiDebug("as_req: DH key transport algorithm\n");
+ retval = pkinit_copy_krb5_octet_data(&info->algorithm.algorithm, &dh_oid);
+ if (retval) {
+ pkiDebug("failed to copy dh_oid\n");
+ goto cleanup;
+ }
+
+ /* create client-side DH keys */
+ if ((retval = client_create_dh(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx, reqctx->opts->dh_size,
+ &info->algorithm.parameters.data,
+ &info->algorithm.parameters.length,
+ &info->subjectPublicKey.data,
+ &info->subjectPublicKey.length)) != 0) {
+ pkiDebug("failed to create dh parameters\n");
+ goto cleanup;
+ }
+ break;
+ case RSA_PROTOCOL:
+ pkiDebug("as_req: RSA key transport algorithm\n");
+ switch((int)reqctx->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ auth_pack9->clientPublicValue = NULL;
+ break;
+ case KRB5_PADATA_PK_AS_REQ:
+ free_krb5_subject_pk_info(&info);
+ auth_pack->clientPublicValue = NULL;
+ break;
+ }
+ break;
+ default:
+ pkiDebug("as_req: unknown key transport protocol %d\n",
+ protocol);
+ retval = -1;
+ goto cleanup;
+ }
+
+ /* Encode the authpack */
+ switch((int)reqctx->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ retval = k5int_encode_krb5_auth_pack(auth_pack, &coded_auth_pack);
+ break;
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ retval = k5int_encode_krb5_auth_pack_draft9(auth_pack9,
+ &coded_auth_pack);
+ break;
+ }
+ if (retval) {
+ pkiDebug("failed to encode the AuthPack %d\n", retval);
+ goto cleanup;
+ }
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)coded_auth_pack->data,
+ coded_auth_pack->length,
+ "/tmp/client_auth_pack");
+#endif
+
+ /* create PKCS7 object from authpack */
+ switch((int)reqctx->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ init_krb5_pa_pk_as_req(&req);
+ if (req == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ retval = cms_signeddata_create(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx, CMS_SIGN_CLIENT, 1,
+ (unsigned char *)coded_auth_pack->data, coded_auth_pack->length,
+ &req->signedAuthPack.data, &req->signedAuthPack.length);
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)req->signedAuthPack.data,
+ req->signedAuthPack.length,
+ "/tmp/client_signed_data");
+#endif
+ break;
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ init_krb5_pa_pk_as_req_draft9(&req9);
+ if (req9 == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ retval = cms_signeddata_create(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx, CMS_SIGN_DRAFT9, 1,
+ (unsigned char *)coded_auth_pack->data, coded_auth_pack->length,
+ &req9->signedAuthPack.data, &req9->signedAuthPack.length);
+ break;
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)req9->signedAuthPack.data,
+ req9->signedAuthPack.length,
+ "/tmp/client_signed_data_draft9");
+#endif
+ }
+ krb5_free_data(context, coded_auth_pack);
+ if (retval) {
+ pkiDebug("failed to create pkcs7 signed data\n");
+ goto cleanup;
+ }
+
+ /* create a list of trusted CAs */
+ switch((int)reqctx->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ retval = create_krb5_trustedCertifiers(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx, &req->trustedCertifiers);
+ if (retval)
+ goto cleanup;
+ retval = create_issuerAndSerial(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx, &req->kdcPkId.data,
+ &req->kdcPkId.length);
+ if (retval)
+ goto cleanup;
+
+ /* Encode the as-req */
+ retval = k5int_encode_krb5_pa_pk_as_req(req, as_req);
+ break;
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+#if 0
+ /* W2K3 KDC doesn't like this */
+ retval = create_krb5_trustedCas(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx, 1, &req9->trustedCertifiers);
+ if (retval)
+ goto cleanup;
+
+#endif
+ retval = create_issuerAndSerial(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx, &req9->kdcCert.data,
+ &req9->kdcCert.length);
+ if (retval)
+ goto cleanup;
+ /* Encode the as-req */
+ retval = k5int_encode_krb5_pa_pk_as_req_draft9(req9, as_req);
+ break;
+ }
+#ifdef DEBUG_ASN1
+ if (!retval)
+ print_buffer_bin((unsigned char *)(*as_req)->data, (*as_req)->length,
+ "/tmp/client_as_req");
+#endif
+
+cleanup:
+ switch((int)reqctx->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ free_krb5_auth_pack(&auth_pack);
+ free_krb5_pa_pk_as_req(&req);
+ break;
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ free_krb5_pa_pk_as_req_draft9(&req9);
+ free(auth_pack9);
+ break;
+ }
+
+
+ pkiDebug("pkinit_as_req_create retval=%d\n", (int) retval);
+
+ return retval;
+}
+
+krb5_error_code
+pa_pkinit_parse_rep(krb5_context context,
+ pkinit_context plgctx,
+ pkinit_req_context reqctx,
+ krb5_kdc_req * request,
+ krb5_pa_data * in_padata,
+ krb5_enctype etype,
+ krb5_keyblock * as_key,
+ krb5_data *encoded_request)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ krb5_data asRep = { 0, 0, NULL};
+
+ /*
+ * One way or the other - success or failure - no other PA systems can
+ * work if the server sent us a PKINIT reply, since only we know how to
+ * decrypt the key.
+ */
+ if ((in_padata == NULL) || (in_padata->length == 0)) {
+ pkiDebug("pa_pkinit_parse_rep: no in_padata\n");
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ asRep.data = (char *) in_padata->contents;
+ asRep.length = in_padata->length;
+
+ retval =
+ pkinit_as_rep_parse(context, plgctx, reqctx, in_padata->pa_type,
+ request, &asRep, as_key, etype, encoded_request);
+ if (retval) {
+ pkiDebug("pkinit_as_rep_parse returned %d (%s)\n",
+ retval, error_message(retval));
+ goto cleanup;
+ }
+
+ retval = 0;
+
+cleanup:
+
+ return retval;
+}
+
+static krb5_error_code
+verify_kdc_san(krb5_context context,
+ pkinit_context plgctx,
+ pkinit_req_context reqctx,
+ krb5_principal kdcprinc,
+ int *valid_san,
+ int *need_eku_checking)
+{
+ krb5_error_code retval;
+ char **certhosts = NULL, **cfghosts = NULL;
+ krb5_principal *princs = NULL;
+ unsigned char ***get_dns;
+ int i, j;
+
+ *valid_san = 0;
+ *need_eku_checking = 1;
+
+ retval = pkinit_libdefault_strings(context,
+ krb5_princ_realm(context, kdcprinc),
+ "pkinit_kdc_hostname",
+ &cfghosts);
+ if (retval || cfghosts == NULL) {
+ pkiDebug("%s: No pkinit_kdc_hostname values found in config file\n",
+ __FUNCTION__);
+ get_dns = NULL;
+ } else {
+ pkiDebug("%s: pkinit_kdc_hostname values found in config file\n",
+ __FUNCTION__);
+ get_dns = (unsigned char ***)&certhosts;
+ }
+
+ retval = crypto_retrieve_cert_sans(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx,
+ &princs, NULL, get_dns);
+ if (retval) {
+ pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__);
+ retval = KRB5KDC_ERR_KDC_NAME_MISMATCH;
+ goto out;
+ }
+#if 0
+ retval = call_san_checking_plugins(context, plgctx, reqctx, idctx,
+ princs, hosts, &plugin_decision,
+ need_eku_checking);
+ pkiDebug("%s: call_san_checking_plugins() returned retval %d\n",
+ __FUNCTION__);
+ if (retval) {
+ retval = KRB5KDC_ERR_KDC_NAME_MISMATCH;
+ goto out;
+ }
+ pkiDebug("%s: call_san_checking_plugins() returned decision %d and "
+ "need_eku_checking %d\n",
+ __FUNCTION__, plugin_decision, *need_eku_checking);
+ if (plugin_decision != NO_DECISION) {
+ retval = plugin_decision;
+ goto out;
+ }
+#endif
+
+ pkiDebug("%s: Checking pkinit sans\n", __FUNCTION__);
+ for (i = 0; princs != NULL && princs[i] != NULL; i++) {
+ if (krb5_principal_compare(context, princs[i], kdcprinc)) {
+ pkiDebug("%s: pkinit san match found\n", __FUNCTION__);
+ *valid_san = 1;
+ *need_eku_checking = 0;
+ retval = 0;
+ goto out;
+ }
+ }
+ pkiDebug("%s: no pkinit san match found\n", __FUNCTION__);
+
+ if (certhosts == NULL) {
+ pkiDebug("%s: no certhosts (or we wouldn't accept them anyway)\n",
+ __FUNCTION__);
+ retval = KRB5KDC_ERR_KDC_NAME_MISMATCH;
+ goto out;
+ }
+
+ for (i = 0; certhosts[i] != NULL; i++) {
+ for (j = 0; cfghosts != NULL && cfghosts[j] != NULL; j++) {
+ pkiDebug("%s: comparing cert name '%s' with config name '%s'\n",
+ __FUNCTION__, certhosts[i], cfghosts[j]);
+ if (strcmp(certhosts[i], cfghosts[j]) == 0) {
+ pkiDebug("%s: we have a dnsName match\n", __FUNCTION__);
+ *valid_san = 1;
+ retval = 0;
+ goto out;
+ }
+ }
+ }
+ pkiDebug("%s: no dnsName san match found\n", __FUNCTION__);
+
+ /* We found no match */
+ retval = 0;
+
+out:
+ if (princs != NULL) {
+ for (i = 0; princs[i] != NULL; i++)
+ krb5_free_principal(context, princs[i]);
+ free(princs);
+ }
+ if (certhosts != NULL) {
+ for (i = 0; certhosts[i] != NULL; i++)
+ free(certhosts[i]);
+ free(certhosts);
+ }
+ if (cfghosts != NULL)
+ profile_free_list(cfghosts);
+
+ pkiDebug("%s: returning retval %d, valid_san %d, need_eku_checking %d\n",
+ __FUNCTION__, retval, *valid_san, *need_eku_checking);
+ return retval;
+}
+
+static krb5_error_code
+verify_kdc_eku(krb5_context context,
+ pkinit_context plgctx,
+ pkinit_req_context reqctx,
+ int *eku_accepted)
+{
+ krb5_error_code retval;
+
+ *eku_accepted = 0;
+
+ if (reqctx->opts->require_eku == 0) {
+ pkiDebug("%s: configuration requests no EKU checking\n", __FUNCTION__);
+ *eku_accepted = 1;
+ retval = 0;
+ goto out;
+ }
+ retval = crypto_check_cert_eku(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx,
+ 1, /* kdc cert */
+ reqctx->opts->accept_secondary_eku,
+ eku_accepted);
+ if (retval) {
+ pkiDebug("%s: Error from crypto_check_cert_eku %d (%s)\n",
+ __FUNCTION__, retval, error_message(retval));
+ goto out;
+ }
+
+out:
+ pkiDebug("%s: returning retval %d, eku_accepted %d\n",
+ __FUNCTION__, retval, *eku_accepted);
+ return retval;
+}
+
+/*
+ * Parse PA-PK-AS-REP message. Optionally evaluates the message's
+ * certificate chain.
+ * Optionally returns various components.
+ */
+krb5_error_code
+pkinit_as_rep_parse(krb5_context context,
+ pkinit_context plgctx,
+ pkinit_req_context reqctx,
+ krb5_preauthtype pa_type,
+ krb5_kdc_req *request,
+ const krb5_data *as_rep,
+ krb5_keyblock *key_block,
+ krb5_enctype etype,
+ krb5_data *encoded_request)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ krb5_pa_pk_as_rep *kdc_reply = NULL;
+ krb5_kdc_dh_key_info *kdc_dh = NULL;
+ krb5_reply_key_pack *key_pack = NULL;
+ krb5_reply_key_pack_draft9 *key_pack9 = NULL;
+ krb5_octet_data dh_data = { 0, 0, NULL };
+ unsigned char *client_key = NULL, *kdc_hostname = NULL;
+ unsigned int client_key_len = 0;
+ krb5_checksum cksum = {0, 0, 0, NULL};
+ krb5_data k5data;
+ int valid_san = 0;
+ int valid_eku = 0;
+ int need_eku_checking = 1;
+
+ assert((as_rep != NULL) && (key_block != NULL));
+
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)as_rep->data, as_rep->length,
+ "/tmp/client_as_rep");
+#endif
+
+ if ((retval = k5int_decode_krb5_pa_pk_as_rep(as_rep, &kdc_reply))) {
+ pkiDebug("decode_krb5_as_rep failed %d\n", retval);
+ return retval;
+ }
+
+ switch(kdc_reply->choice) {
+ case choice_pa_pk_as_rep_dhInfo:
+ pkiDebug("as_rep: DH key transport algorithm\n");
+#ifdef DEBUG_ASN1
+ print_buffer_bin(kdc_reply->u.dh_Info.dhSignedData.data,
+ kdc_reply->u.dh_Info.dhSignedData.length, "/tmp/client_kdc_signeddata");
+#endif
+ if ((retval = cms_signeddata_verify(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx, CMS_SIGN_SERVER,
+ reqctx->opts->require_crl_checking,
+ kdc_reply->u.dh_Info.dhSignedData.data,
+ kdc_reply->u.dh_Info.dhSignedData.length,
+ &dh_data.data, &dh_data.length, NULL, NULL)) != 0) {
+ pkiDebug("failed to verify pkcs7 signed data\n");
+ goto cleanup;
+ }
+
+ break;
+ case choice_pa_pk_as_rep_encKeyPack:
+ pkiDebug("as_rep: RSA key transport algorithm\n");
+ if ((retval = cms_envelopeddata_verify(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx, pa_type,
+ reqctx->opts->require_crl_checking,
+ kdc_reply->u.encKeyPack.data,
+ kdc_reply->u.encKeyPack.length,
+ &dh_data.data, &dh_data.length)) != 0) {
+ pkiDebug("failed to verify pkcs7 enveloped data\n");
+ goto cleanup;
+ }
+ break;
+ default:
+ pkiDebug("unknown as_rep type %d\n", kdc_reply->choice);
+ retval = -1;
+ goto cleanup;
+ }
+
+ retval = verify_kdc_san(context, plgctx, reqctx, request->server,
+ &valid_san, &need_eku_checking);
+ if (retval)
+ goto cleanup;
+ if (!valid_san) {
+ pkiDebug("%s: did not find an acceptable SAN in KDC certificate\n",
+ __FUNCTION__);
+ retval = KRB5KDC_ERR_KDC_NAME_MISMATCH;
+ goto cleanup;
+ }
+
+ if (need_eku_checking) {
+ retval = verify_kdc_eku(context, plgctx, reqctx,
+ &valid_eku);
+ if (retval)
+ goto cleanup;
+ if (!valid_eku) {
+ pkiDebug("%s: did not find an acceptable EKU in KDC certificate\n",
+ __FUNCTION__);
+ retval = KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE;
+ goto cleanup;
+ }
+ } else
+ pkiDebug("%s: skipping EKU check\n", __FUNCTION__);
+
+ OCTETDATA_TO_KRB5DATA(&dh_data, &k5data);
+
+ switch(kdc_reply->choice) {
+ case choice_pa_pk_as_rep_dhInfo:
+#ifdef DEBUG_ASN1
+ print_buffer_bin(dh_data.data, dh_data.length,
+ "/tmp/client_dh_key");
+#endif
+ if ((retval = k5int_decode_krb5_kdc_dh_key_info(&k5data,
+ &kdc_dh)) != 0) {
+ pkiDebug("failed to decode kdc_dh_key_info\n");
+ goto cleanup;
+ }
+
+ /* client after KDC reply */
+ if ((retval = client_process_dh(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx,
+ kdc_dh->subjectPublicKey.data,
+ kdc_dh->subjectPublicKey.length,
+ &client_key, &client_key_len)) != 0) {
+ pkiDebug("failed to process dh params\n");
+ goto cleanup;
+ }
+
+ retval = pkinit_octetstring2key(context, etype, client_key,
+ client_key_len, key_block);
+ if (retval) {
+ pkiDebug("failed to create key pkinit_octetstring2key %s\n",
+ error_message(retval));
+ goto cleanup;
+ }
+
+ break;
+ case choice_pa_pk_as_rep_encKeyPack:
+#ifdef DEBUG_ASN1
+ print_buffer_bin(dh_data.data, dh_data.length,
+ "/tmp/client_key_pack");
+#endif
+ if ((retval = k5int_decode_krb5_reply_key_pack(&k5data,
+ &key_pack)) != 0) {
+ pkiDebug("failed to decode reply_key_pack\n");
+#ifdef LONGHORN_BETA_COMPAT
+ /*
+ * LH Beta 3 requires the extra pa-data, even for RFC requests,
+ * in order to get the Checksum rather than a Nonce in the reply.
+ * This can be removed when LH SP1 is released.
+ */
+ if (pa_type == KRB5_PADATA_PK_AS_REP && longhorn == 0)
+#else
+ if (pa_type == KRB5_PADATA_PK_AS_REP)
+#endif
+ goto cleanup;
+ else {
+ if ((retval =
+ k5int_decode_krb5_reply_key_pack_draft9(&k5data,
+ &key_pack9)) != 0) {
+ pkiDebug("failed to decode reply_key_pack_draft9\n");
+ goto cleanup;
+ }
+ pkiDebug("decode reply_key_pack_draft9\n");
+ if (key_pack9->nonce != request->nonce) {
+ pkiDebug("nonce in AS_REP=%d doesn't match AS_REQ=%d\n", key_pack9->nonce, request->nonce);
+ retval = -1;
+ goto cleanup;
+ }
+ krb5_copy_keyblock_contents(context, &key_pack9->replyKey,
+ key_block);
+ break;
+ }
+ }
+ /*
+ * This is hack but Windows sends back SHA1 checksum
+ * with checksum type of 14. There is currently no
+ * checksum type of 14 defined.
+ */
+ if (key_pack->asChecksum.checksum_type == 14)
+ key_pack->asChecksum.checksum_type = CKSUMTYPE_NIST_SHA;
+ retval = krb5_c_make_checksum(context,
+ key_pack->asChecksum.checksum_type,
+ &key_pack->replyKey,
+ KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM,
+ encoded_request, &cksum);
+ if (retval) {
+ pkiDebug("failed to make a checksum\n");
+ goto cleanup;
+ }
+
+ if ((cksum.length != key_pack->asChecksum.length) ||
+ memcmp(cksum.contents, key_pack->asChecksum.contents,
+ cksum.length)) {
+ pkiDebug("failed to match the checksums\n");
+#ifdef DEBUG_CKSUM
+ pkiDebug("calculating checksum on buf size (%d)\n",
+ encoded_request->length);
+ print_buffer(encoded_request->data, encoded_request->length);
+ pkiDebug("encrypting key (%d)\n", key_pack->replyKey.length);
+ print_buffer(key_pack->replyKey.contents,
+ key_pack->replyKey.length);
+ pkiDebug("received checksum type=%d size=%d ",
+ key_pack->asChecksum.checksum_type,
+ key_pack->asChecksum.length);
+ print_buffer(key_pack->asChecksum.contents,
+ key_pack->asChecksum.length);
+ pkiDebug("expected checksum type=%d size=%d ",
+ cksum.checksum_type, cksum.length);
+ print_buffer(cksum.contents, cksum.length);
+#endif
+ goto cleanup;
+ } else
+ pkiDebug("checksums match\n");
+
+ krb5_copy_keyblock_contents(context, &key_pack->replyKey,
+ key_block);
+
+ break;
+ default:
+ pkiDebug("unknow as_rep type %d\n", kdc_reply->choice);
+ goto cleanup;
+ }
+
+ retval = 0;
+
+cleanup:
+ if (dh_data.data != NULL)
+ free(dh_data.data);
+ if (client_key != NULL)
+ free(client_key);
+ free_krb5_kdc_dh_key_info(&kdc_dh);
+ free_krb5_pa_pk_as_rep(&kdc_reply);
+
+ if (key_pack != NULL) {
+ free_krb5_reply_key_pack(&key_pack);
+ if (cksum.contents != NULL)
+ free(cksum.contents);
+ }
+ if (key_pack9 != NULL)
+ free_krb5_reply_key_pack_draft9(&key_pack9);
+
+ if (kdc_hostname != NULL)
+ free(kdc_hostname);
+
+ pkiDebug("pkinit_as_rep_parse returning %d (%s)\n",
+ retval, error_message(retval));
+ return retval;
+}
+
+static void
+pkinit_client_profile(krb5_context context,
+ pkinit_context plgctx,
+ pkinit_req_context reqctx,
+ krb5_kdc_req *request)
+{
+ char *eku_string = NULL;
+
+ pkiDebug("pkinit_client_profile %p %p %p %p\n",
+ context, plgctx, reqctx, request);
+
+ (void) pkinit_libdefault_boolean(context, &request->server->realm,
+ "pkinit_win2k",
+ reqctx->opts->win2k_target,
+ &reqctx->opts->win2k_target);
+ (void) pkinit_libdefault_boolean(context, &request->server->realm,
+ "pkinit_win2k_require_binding",
+ reqctx->opts->win2k_require_cksum,
+ &reqctx->opts->win2k_require_cksum);
+ (void) pkinit_libdefault_boolean(context, &request->server->realm,
+ "pkinit_require_crl_checking",
+ reqctx->opts->require_crl_checking,
+ &reqctx->opts->require_crl_checking);
+ (void) pkinit_libdefault_integer(context, &request->server->realm,
+ "pkinit_dh_min_bits",
+ reqctx->opts->dh_size,
+ &reqctx->opts->dh_size);
+ if (reqctx->opts->dh_size != 1024 && reqctx->opts->dh_size != 2048
+ && reqctx->opts->dh_size != 4096) {
+ pkiDebug("%s: invalid value (%d) for pkinit_dh_min_bits, "
+ "using default value (%d) instead\n", __FUNCTION__,
+ reqctx->opts->dh_size, PKINIT_DEFAULT_DH_MIN_BITS);
+ reqctx->opts->dh_size = PKINIT_DEFAULT_DH_MIN_BITS;
+ }
+ (void) pkinit_libdefault_string(context, &request->server->realm,
+ "pkinit_eku_checking",
+ &eku_string);
+ if (eku_string != NULL) {
+ if (strcasecmp(eku_string, "kpKDC") == 0) {
+ reqctx->opts->require_eku = 1;
+ reqctx->opts->accept_secondary_eku = 0;
+ } else if (strcasecmp(eku_string, "kpServerAuth") == 0) {
+ reqctx->opts->require_eku = 1;
+ reqctx->opts->accept_secondary_eku = 1;
+ } else if (strcasecmp(eku_string, "none") == 0) {
+ reqctx->opts->require_eku = 0;
+ reqctx->opts->accept_secondary_eku = 0;
+ } else {
+ pkiDebug("%s: Invalid value for pkinit_eku_checking: '%s'\n",
+ __FUNCTION__, eku_string);
+ }
+ free(eku_string);
+ }
+#ifdef LONGHORN_BETA_COMPAT
+ /* Temporarily just set global flag from config file */
+ (void) pkinit_libdefault_boolean(context, &request->server->realm,
+ "pkinit_longhorn",
+ 0,
+ &longhorn);
+#endif
+
+ /* Only process anchors here if they were not specified on command line */
+ if (reqctx->idopts->anchors == NULL)
+ (void) pkinit_libdefault_strings(context, &request->server->realm,
+ "pkinit_anchors",
+ &reqctx->idopts->anchors);
+ /* Solaris Kerberos */
+ (void) pkinit_libdefault_strings(context, &request->server->realm,
+ "pkinit_pool",
+ &reqctx->idopts->intermediates);
+ (void) pkinit_libdefault_strings(context, &request->server->realm,
+ "pkinit_revoke",
+ &reqctx->idopts->crls);
+ (void) pkinit_libdefault_strings(context, &request->server->realm,
+ "pkinit_identities",
+ &reqctx->idopts->identity_alt);
+}
+
+/* ARGSUSED */
+krb5_error_code
+pkinit_client_process(krb5_context context,
+ void *plugin_context,
+ void *request_context,
+ krb5_get_init_creds_opt *gic_opt,
+ preauth_get_client_data_proc get_data_proc,
+ struct _krb5_preauth_client_rock *rock,
+ krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data *in_padata,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ preauth_get_as_key_proc gak_fct,
+ void *gak_data,
+ krb5_data *salt,
+ krb5_data *s2kparams,
+ krb5_keyblock *as_key,
+ krb5_pa_data ***out_padata)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ krb5_enctype enctype = -1;
+ krb5_data *cdata = NULL;
+ int processing_request = 0;
+ pkinit_context plgctx = (pkinit_context)plugin_context;
+ pkinit_req_context reqctx = (pkinit_req_context)request_context;
+
+ pkiDebug("pkinit_client_process %p %p %p %p\n",
+ context, plgctx, reqctx, request);
+
+ if (plgctx == NULL || reqctx == NULL)
+ return EINVAL;
+
+ switch ((int) in_padata->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ pkiDebug("processing KRB5_PADATA_PK_AS_REQ\n");
+ processing_request = 1;
+ break;
+
+ case KRB5_PADATA_PK_AS_REP:
+ pkiDebug("processing KRB5_PADATA_PK_AS_REP\n");
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ if (in_padata->length == 0) {
+ pkiDebug("processing KRB5_PADATA_PK_AS_REQ_OLD\n");
+ in_padata->pa_type = KRB5_PADATA_PK_AS_REQ_OLD;
+ processing_request = 1;
+ } else {
+ pkiDebug("processing KRB5_PADATA_PK_AS_REP_OLD\n");
+ in_padata->pa_type = KRB5_PADATA_PK_AS_REP_OLD;
+ }
+ break;
+ default:
+ pkiDebug("unrecognized patype = %d for PKINIT\n",
+ in_padata->pa_type);
+ return EINVAL;
+ }
+
+ if (processing_request) {
+ pkinit_client_profile(context, plgctx, reqctx, request);
+ /* Solaris Kerberos */
+ retval = pkinit_identity_set_prompter(reqctx->idctx, prompter, prompter_data);
+ if (retval) {
+ pkiDebug("pkinit_identity_set_prompter returned %d (%s)\n",
+ retval, error_message(retval));
+ return retval;
+ }
+
+ retval = pkinit_identity_initialize(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idopts,
+ reqctx->idctx, 1, request->client);
+ if (retval) {
+ pkiDebug("pkinit_identity_initialize returned %d (%s)\n",
+ retval, error_message(retval));
+ return retval;
+ }
+ retval = pa_pkinit_gen_req(context, plgctx, reqctx, request,
+ in_padata, out_padata, prompter,
+ prompter_data, gic_opt);
+ } else {
+ /*
+ * Get the enctype of the reply.
+ */
+ retval = (*get_data_proc)(context, rock,
+ krb5plugin_preauth_client_get_etype, &cdata);
+ if (retval) {
+ pkiDebug("get_data_proc returned %d (%s)\n",
+ retval, error_message(retval));
+ return retval;
+ }
+ enctype = *((krb5_enctype *)cdata->data);
+ (*get_data_proc)(context, rock,
+ krb5plugin_preauth_client_free_etype, &cdata);
+ retval = pa_pkinit_parse_rep(context, plgctx, reqctx, request,
+ in_padata, enctype, as_key,
+ encoded_previous_request);
+ }
+
+ pkiDebug("pkinit_client_process: returning %d (%s)\n",
+ retval, error_message(retval));
+ return retval;
+}
+
+/* ARGSUSED */
+krb5_error_code
+pkinit_client_tryagain(krb5_context context,
+ void *plugin_context,
+ void *request_context,
+ krb5_get_init_creds_opt *gic_opt,
+ preauth_get_client_data_proc get_data_proc,
+ struct _krb5_preauth_client_rock *rock,
+ krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data *in_padata,
+ krb5_error *err_reply,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ preauth_get_as_key_proc gak_fct,
+ void *gak_data,
+ krb5_data *salt,
+ krb5_data *s2kparams,
+ krb5_keyblock *as_key,
+ krb5_pa_data ***out_padata)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ pkinit_context plgctx = (pkinit_context)plugin_context;
+ pkinit_req_context reqctx = (pkinit_req_context)request_context;
+ krb5_typed_data **typed_data = NULL;
+ krb5_data scratch;
+ krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
+ krb5_algorithm_identifier **algId = NULL;
+ int do_again = 0;
+
+ pkiDebug("pkinit_client_tryagain %p %p %p %p\n",
+ context, plgctx, reqctx, request);
+
+ if (reqctx->pa_type != in_padata->pa_type)
+ return retval;
+
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)err_reply->e_data.data,
+ err_reply->e_data.length, "/tmp/client_edata");
+#endif
+ retval = k5int_decode_krb5_typed_data(&err_reply->e_data, &typed_data);
+ if (retval) {
+ pkiDebug("decode_krb5_typed_data failed\n");
+ goto cleanup;
+ }
+#ifdef DEBUG_ASN1
+ print_buffer_bin(typed_data[0]->data, typed_data[0]->length,
+ "/tmp/client_typed_data");
+#endif
+ OCTETDATA_TO_KRB5DATA(typed_data[0], &scratch);
+
+ switch(typed_data[0]->type) {
+ case TD_TRUSTED_CERTIFIERS:
+ case TD_INVALID_CERTIFICATES:
+ retval = k5int_decode_krb5_td_trusted_certifiers(&scratch,
+ &krb5_trusted_certifiers);
+ if (retval) {
+ pkiDebug("failed to decode sequence of trusted certifiers\n");
+ goto cleanup;
+ }
+ retval = pkinit_process_td_trusted_certifiers(context,
+ plgctx->cryptoctx, reqctx->cryptoctx, reqctx->idctx,
+ krb5_trusted_certifiers, typed_data[0]->type);
+ if (!retval)
+ do_again = 1;
+ break;
+ case TD_DH_PARAMETERS:
+ retval = k5int_decode_krb5_td_dh_parameters(&scratch, &algId);
+ if (retval) {
+ pkiDebug("failed to decode td_dh_parameters\n");
+ goto cleanup;
+ }
+ retval = pkinit_process_td_dh_params(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, reqctx->idctx, algId,
+ &reqctx->opts->dh_size);
+ if (!retval)
+ do_again = 1;
+ break;
+ default:
+ break;
+ }
+
+ if (do_again) {
+ retval = pa_pkinit_gen_req(context, plgctx, reqctx, request, in_padata,
+ out_padata, prompter, prompter_data, gic_opt);
+ if (retval)
+ goto cleanup;
+ }
+
+ retval = 0;
+cleanup:
+ if (krb5_trusted_certifiers != NULL)
+ free_krb5_external_principal_identifier(&krb5_trusted_certifiers);
+
+ if (typed_data != NULL)
+ free_krb5_typed_data(&typed_data);
+
+ if (algId != NULL)
+ free_krb5_algorithm_identifiers(&algId);
+
+ pkiDebug("pkinit_client_tryagain: returning %d (%s)\n",
+ retval, error_message(retval));
+ return retval;
+}
+
+/* ARGSUSED */
+static int
+pkinit_client_get_flags(krb5_context kcontext, krb5_preauthtype patype)
+{
+ return PA_REAL;
+}
+
+static krb5_preauthtype supported_client_pa_types[] = {
+ KRB5_PADATA_PK_AS_REP,
+ KRB5_PADATA_PK_AS_REQ,
+ KRB5_PADATA_PK_AS_REP_OLD,
+ KRB5_PADATA_PK_AS_REQ_OLD,
+ 0
+};
+
+/* ARGSUSED */
+void
+pkinit_client_req_init(krb5_context context,
+ void *plugin_context,
+ void **request_context)
+{
+ krb5_error_code retval = ENOMEM;
+ struct _pkinit_req_context *reqctx = NULL;
+ struct _pkinit_context *plgctx = (struct _pkinit_context *)plugin_context;
+
+ *request_context = NULL;
+
+ reqctx = (struct _pkinit_req_context *) malloc(sizeof(*reqctx));
+ if (reqctx == NULL)
+ return;
+ (void) memset(reqctx, 0, sizeof(*reqctx));
+
+ reqctx->magic = PKINIT_REQ_CTX_MAGIC;
+ reqctx->cryptoctx = NULL;
+ reqctx->opts = NULL;
+ reqctx->idctx = NULL;
+ reqctx->idopts = NULL;
+
+ retval = pkinit_init_req_opts(&reqctx->opts);
+ if (retval)
+ goto cleanup;
+
+ reqctx->opts->require_eku = plgctx->opts->require_eku;
+ reqctx->opts->accept_secondary_eku = plgctx->opts->accept_secondary_eku;
+ reqctx->opts->dh_or_rsa = plgctx->opts->dh_or_rsa;
+ reqctx->opts->allow_upn = plgctx->opts->allow_upn;
+ reqctx->opts->require_crl_checking = plgctx->opts->require_crl_checking;
+
+ retval = pkinit_init_req_crypto(&reqctx->cryptoctx);
+ if (retval)
+ goto cleanup;
+
+ retval = pkinit_init_identity_crypto(&reqctx->idctx);
+ if (retval)
+ goto cleanup;
+
+ retval = pkinit_dup_identity_opts(plgctx->idopts, &reqctx->idopts);
+ if (retval)
+ goto cleanup;
+
+ *request_context = (void *) reqctx;
+ pkiDebug("%s: returning reqctx at %p\n", __FUNCTION__, reqctx);
+
+cleanup:
+ if (retval) {
+ if (reqctx->idctx != NULL)
+ pkinit_fini_identity_crypto(reqctx->idctx);
+ if (reqctx->cryptoctx != NULL)
+ pkinit_fini_req_crypto(reqctx->cryptoctx);
+ if (reqctx->opts != NULL)
+ pkinit_fini_req_opts(reqctx->opts);
+ if (reqctx->idopts != NULL)
+ pkinit_fini_identity_opts(reqctx->idopts);
+ free(reqctx);
+ }
+
+ return;
+}
+
+/* ARGSUSED */
+void
+pkinit_client_req_fini(krb5_context context,
+ void *plugin_context,
+ void *request_context)
+{
+ struct _pkinit_req_context *reqctx =
+ (struct _pkinit_req_context *)request_context;
+
+ pkiDebug("%s: received reqctx at %p\n", __FUNCTION__, reqctx);
+ if (reqctx == NULL)
+ return;
+ if (reqctx->magic != PKINIT_REQ_CTX_MAGIC) {
+ pkiDebug("%s: Bad magic value (%x) in req ctx\n",
+ __FUNCTION__, reqctx->magic);
+ return;
+ }
+ if (reqctx->opts != NULL)
+ pkinit_fini_req_opts(reqctx->opts);
+
+ if (reqctx->cryptoctx != NULL)
+ pkinit_fini_req_crypto(reqctx->cryptoctx);
+
+ if (reqctx->idctx != NULL)
+ pkinit_fini_identity_crypto(reqctx->idctx);
+
+ if (reqctx->idopts != NULL)
+ pkinit_fini_identity_opts(reqctx->idopts);
+
+ free(reqctx);
+ return;
+}
+
+/* ARGSUSED */
+static void
+pkinit_fini_client_profile(krb5_context context, pkinit_context plgctx)
+{
+ /* This should clean up anything allocated in pkinit_init_client_profile */
+}
+
+/* ARGSUSED */
+static krb5_error_code
+pkinit_init_client_profile(krb5_context context, pkinit_context plgctx)
+{
+ return 0;
+}
+
+static int
+pkinit_client_plugin_init(krb5_context context, void **blob)
+{
+ krb5_error_code retval = ENOMEM;
+ struct _pkinit_context *ctx = NULL;
+
+ ctx = (struct _pkinit_context *)calloc(1, sizeof(*ctx));
+ if (ctx == NULL)
+ return ENOMEM;
+ (void) memset(ctx, 0, sizeof(*ctx));
+ ctx->magic = PKINIT_CTX_MAGIC;
+ ctx->opts = NULL;
+ ctx->cryptoctx = NULL;
+ ctx->idopts = NULL;
+
+ retval = pkinit_accessor_init();
+ if (retval)
+ goto errout;
+
+ retval = pkinit_init_plg_opts(&ctx->opts);
+ if (retval)
+ goto errout;
+
+ retval = pkinit_init_plg_crypto(&ctx->cryptoctx);
+ if (retval)
+ goto errout;
+
+ retval = pkinit_init_identity_opts(&ctx->idopts);
+ if (retval)
+ goto errout;
+
+ retval = pkinit_init_client_profile(context, ctx);
+ if (retval)
+ goto errout;
+
+ *blob = ctx;
+
+ pkiDebug("%s: returning plgctx at %p\n", __FUNCTION__, ctx);
+
+errout:
+ if (retval)
+ pkinit_client_plugin_fini(context, ctx);
+
+ return retval;
+}
+
+static void
+pkinit_client_plugin_fini(krb5_context context, void *blob)
+{
+ struct _pkinit_context *ctx = (struct _pkinit_context *)blob;
+
+ if (ctx == NULL || ctx->magic != PKINIT_CTX_MAGIC) {
+ pkiDebug("pkinit_lib_fini: got bad plgctx (%p)!\n", ctx);
+ return;
+ }
+ pkiDebug("%s: got plgctx at %p\n", __FUNCTION__, ctx);
+
+ pkinit_fini_client_profile(context, ctx);
+ pkinit_fini_identity_opts(ctx->idopts);
+ pkinit_fini_plg_crypto(ctx->cryptoctx);
+ pkinit_fini_plg_opts(ctx->opts);
+ free(ctx);
+
+}
+
+/* ARGSUSED */
+static krb5_error_code
+add_string_to_array(krb5_context context, char ***array, const char *addition)
+{
+ char **out = NULL;
+
+ if (*array == NULL) {
+ out = malloc(2 * sizeof(char *));
+ if (out == NULL)
+ return ENOMEM;
+ out[1] = NULL;
+ out[0] = strdup(addition);
+ if (out[0] == NULL) {
+ free(out);
+ return ENOMEM;
+ }
+ } else {
+ int i;
+ char **a = *array;
+ for (i = 0; a[i] != NULL; i++);
+ out = malloc( (i + 2) * sizeof(char *));
+ if (out == NULL)
+ return ENOMEM;
+ for (i = 0; a[i] != NULL; i++) {
+ out[i] = a[i];
+ }
+ out[i++] = strdup(addition);
+ if (out == NULL) {
+ free(out);
+ return ENOMEM;
+ }
+ out[i] = NULL;
+ free(*array);
+ }
+ *array = out;
+
+ return 0;
+}
+static krb5_error_code
+handle_gic_opt(krb5_context context,
+ struct _pkinit_context *plgctx,
+ const char *attr,
+ const char *value)
+{
+ krb5_error_code retval;
+
+ if (strcmp(attr, "X509_user_identity") == 0) {
+ if (plgctx->idopts->identity != NULL) {
+ krb5_set_error_message(context, KRB5_PREAUTH_FAILED,
+ "X509_user_identity can not be given twice\n");
+ return KRB5_PREAUTH_FAILED;
+ }
+ plgctx->idopts->identity = strdup(value);
+ if (plgctx->idopts->identity == NULL) {
+ krb5_set_error_message(context, ENOMEM,
+ "Could not duplicate X509_user_identity value\n");
+ return ENOMEM;
+ }
+ } else if (strcmp(attr, "X509_anchors") == 0) {
+ retval = add_string_to_array(context, &plgctx->idopts->anchors, value);
+ if (retval)
+ return retval;
+ } else if (strcmp(attr, "flag_RSA_PROTOCOL") == 0) {
+ if (strcmp(value, "yes") == 0) {
+ pkiDebug("Setting flag to use RSA_PROTOCOL\n");
+ plgctx->opts->dh_or_rsa = RSA_PROTOCOL;
+ }
+ }
+ return 0;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+pkinit_client_gic_opt(krb5_context context,
+ void *plugin_context,
+ krb5_get_init_creds_opt *gic_opt,
+ const char *attr,
+ const char *value)
+{
+ krb5_error_code retval;
+ struct _pkinit_context *plgctx = (struct _pkinit_context *)plugin_context;
+
+ pkiDebug("(pkinit) received '%s' = '%s'\n", attr, value);
+ retval = handle_gic_opt(context, plgctx, attr, value);
+ if (retval)
+ return retval;
+
+ return 0;
+}
+
+struct krb5plugin_preauth_client_ftable_v1 preauthentication_client_1 = {
+ "pkinit", /* name */
+ supported_client_pa_types, /* pa_type_list */
+ NULL, /* enctype_list */
+ pkinit_client_plugin_init, /* (*init) */
+ pkinit_client_plugin_fini, /* (*fini) */
+ pkinit_client_get_flags, /* (*flags) */
+ pkinit_client_req_init, /* (*client_req_init) */
+ pkinit_client_req_fini, /* (*client_req_fini) */
+ pkinit_client_process, /* (*process) */
+ pkinit_client_tryagain, /* (*tryagain) */
+ pkinit_client_gic_opt /* (*gic_opt) */
+};
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto.h b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto.h
new file mode 100644
index 0000000000..292325b7eb
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto.h
@@ -0,0 +1,624 @@
+/*
+ * COPYRIGHT (C) 2007
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+/*
+ * This header defines the cryptographic interface
+ */
+
+#ifndef _PKINIT_CRYPTO_H
+#define _PKINIT_CRYPTO_H
+
+/* Solaris Kerberos */
+#include <krb5.h>
+#include <preauth_plugin.h>
+#include <k5-int-pkinit.h>
+#include <profile.h>
+#include "pkinit_accessor.h"
+
+/*
+ * these describe the CMS message types
+ */
+enum cms_msg_types {
+ CMS_SIGN_CLIENT,
+ CMS_SIGN_DRAFT9,
+ CMS_SIGN_SERVER,
+ CMS_ENVEL_SERVER
+};
+
+/*
+ * storage types for identity information
+ */
+#define IDTYPE_FILE 1
+#define IDTYPE_DIR 2
+#define IDTYPE_PKCS11 3
+#define IDTYPE_ENVVAR 4
+#define IDTYPE_PKCS12 5
+
+/*
+ * ca/crl types
+ */
+#define CATYPE_ANCHORS 1
+#define CATYPE_INTERMEDIATES 2
+#define CATYPE_CRLS 3
+
+/*
+ * The following represent Key Usage values that we
+ * may care about in a certificate
+ */
+#define PKINIT_KU_DIGITALSIGNATURE 0x80000000
+#define PKINIT_KU_KEYENCIPHERMENT 0x40000000
+
+/*
+ * The following represent Extended Key Usage oid values
+ * that we may care about in a certificate
+ */
+#define PKINIT_EKU_PKINIT 0x80000000
+#define PKINIT_EKU_MSSCLOGIN 0x40000000
+#define PKINIT_EKU_CLIENTAUTH 0x20000000
+#define PKINIT_EKU_EMAILPROTECTION 0x10000000
+
+
+/* Handle to cert, opaque above crypto interface */
+typedef struct _pkinit_cert_info *pkinit_cert_handle;
+
+/* Handle to cert iteration information, opaque above crypto interface */
+typedef struct _pkinit_cert_iter_info *pkinit_cert_iter_handle;
+
+#define PKINIT_ITER_NO_MORE 0x11111111 /* XXX */
+
+typedef struct _pkinit_cert_matching_data {
+ pkinit_cert_handle ch; /* cert handle for this certificate */
+ char *subject_dn; /* rfc2253-style subject name string */
+ char *issuer_dn; /* rfc2253-style issuer name string */
+ unsigned int ku_bits; /* key usage information */
+ unsigned int eku_bits; /* extended key usage information */
+ krb5_principal *sans; /* Null-terminated array of subject alternative
+ name info (pkinit and ms-upn) */
+} pkinit_cert_matching_data;
+
+/*
+ * Functions to initialize and cleanup crypto contexts
+ */
+krb5_error_code pkinit_init_plg_crypto(pkinit_plg_crypto_context *);
+void pkinit_fini_plg_crypto(pkinit_plg_crypto_context);
+
+krb5_error_code pkinit_init_req_crypto(pkinit_req_crypto_context *);
+void pkinit_fini_req_crypto(pkinit_req_crypto_context);
+
+krb5_error_code pkinit_init_identity_crypto(pkinit_identity_crypto_context *);
+void pkinit_fini_identity_crypto(pkinit_identity_crypto_context);
+
+/*
+ * this function creates a CMS message where eContentType is SignedData
+ */
+krb5_error_code cms_signeddata_create
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ int cms_msg_type, /* IN
+ specifies CMS_SIGN_CLIENT for client-side CMS message
+ and CMS_SIGN_SERVER for kdc-side */
+ int include_certchain, /* IN
+ specifies where certificates field in SignedData
+ should contain certificate path */
+ unsigned char *auth_pack, /* IN
+ contains DER encoded AuthPack (CMS_SIGN_CLIENT)
+ or DER encoded DHRepInfo (CMS_SIGN_SERVER) */
+ unsigned int auth_pack_len, /* IN
+ contains length of auth_pack */
+ unsigned char **signed_data, /* OUT
+ for CMS_SIGN_CLIENT receives DER encoded
+ SignedAuthPack (CMS_SIGN_CLIENT) or DER
+ encoded DHInfo (CMS_SIGN_SERVER) */
+ unsigned int *signed_data_len); /* OUT
+ receives length of signed_data */
+
+/*
+ * this function verifies a CMS message where eContentType is SignedData
+ */
+krb5_error_code cms_signeddata_verify
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ int cms_msg_type, /* IN
+ specifies CMS_SIGN_CLIENT for client-side
+ CMS message and CMS_SIGN_SERVER for kdc-side */
+ int require_crl_checking, /* IN
+ specifies whether CRL checking should be
+ strictly enforced, i.e. if no CRLs available
+ for the CA then fail verification.
+ note, if the value is 0, crls are still
+ checked if present */
+ unsigned char *signed_data, /* IN
+ contains DER encoded SignedAuthPack (CMS_SIGN_CLIENT)
+ or DER encoded DHInfo (CMS_SIGN_SERVER) */
+ unsigned int signed_data_len, /* IN
+ contains length of signed_data*/
+ unsigned char **auth_pack, /* OUT
+ receives DER encoded AuthPack (CMS_SIGN_CLIENT)
+ or DER encoded DHRepInfo (CMS_SIGN_SERVER)*/
+ unsigned int *auth_pack_len, /* OUT
+ receives length of auth_pack */
+ unsigned char **authz_data, /* OUT
+ receives required authorization data that
+ contains the verified certificate chain
+ (only used by the KDC) */
+ unsigned int *authz_data_len); /* OUT
+ receives length of authz_data */
+
+/*
+ * this function creates a CMS message where eContentType is EnvelopedData
+ */
+krb5_error_code cms_envelopeddata_create
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ krb5_preauthtype pa_type, /* IN */
+ int include_certchain, /* IN
+ specifies whether the certificates field in
+ SignedData should contain certificate path */
+ unsigned char *key_pack, /* IN
+ contains DER encoded ReplyKeyPack */
+ unsigned int key_pack_len, /* IN
+ contains length of key_pack */
+ unsigned char **envel_data, /* OUT
+ receives DER encoded encKeyPack */
+ unsigned int *envel_data_len); /* OUT
+ receives length of envel_data */
+
+/*
+ * this function creates a CMS message where eContentType is EnvelopedData
+ */
+krb5_error_code cms_envelopeddata_verify
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ krb5_preauthtype pa_type, /* IN */
+ int require_crl_checking, /* IN
+ specifies whether CRL checking should be
+ strictly enforced */
+ unsigned char *envel_data, /* IN
+ contains DER encoded encKeyPack */
+ unsigned int envel_data_len, /* IN
+ contains length of envel_data */
+ unsigned char **signed_data, /* OUT
+ receives ReplyKeyPack */
+ unsigned int *signed_data_len); /* OUT
+ receives length of signed_data */
+
+/*
+ * this function returns SAN information found in the
+ * received certificate. at least one of pkinit_sans,
+ * upn_sans, or kdc_hostnames must be non-NULL.
+ */
+krb5_error_code crypto_retrieve_cert_sans
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ krb5_principal **pkinit_sans, /* OUT
+ if non-NULL, a null-terminated array of
+ id-pkinit-san values found in the certificate
+ are returned */
+ krb5_principal **upn_sans, /* OUT
+ if non-NULL, a null-terminated array of
+ id-ms-upn-san values found in the certificate
+ are returned */
+ unsigned char ***kdc_hostname); /* OUT
+ if non-NULL, a null-terminated array of
+ dNSName (hostname) SAN values found in the
+ certificate are returned */
+
+/*
+ * this function checks for acceptable key usage values
+ * in the received certificate.
+ *
+ * when checking a received kdc certificate, it looks for
+ * the kpKdc key usage. if allow_secondary_usage is
+ * non-zero, it will also accept kpServerAuth.
+ *
+ * when checking a received user certificate, it looks for
+ * kpClientAuth key usage. if allow_secondary_usage is
+ * non-zero, it will also accept id-ms-sc-logon EKU.
+ *
+ * this function must also assert that the digitalSignature
+ * key usage is consistent.
+ */
+krb5_error_code crypto_check_cert_eku
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ int checking_kdc_cert, /* IN
+ specifies if the received certificate is
+ a KDC certificate (non-zero),
+ or a user certificate (zero) */
+ int allow_secondary_usage, /* IN
+ specifies if the secondary key usage
+ should be accepted or not (see above) */
+ int *eku_valid); /* OUT
+ receives non-zero if an acceptable EKU was found */
+
+/*
+ * this functions takes in generated DH secret key and converts
+ * it in to a kerberos session key. it takes into the account the
+ * enc type and then follows the procedure specified in the RFC p 22.
+ */
+krb5_error_code pkinit_octetstring2key
+ (krb5_context context, /* IN */
+ krb5_enctype etype, /* IN
+ specifies the enc type */
+ unsigned char *key, /* IN
+ contains the DH secret key */
+ unsigned int key_len, /* IN
+ contains length of key */
+ krb5_keyblock * krb5key); /* OUT
+ receives kerberos session key */
+
+/*
+ * this function implements clients first part of the DH protocol.
+ * client selects its DH parameters and pub key
+ */
+krb5_error_code client_create_dh
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ int dh_size, /* IN
+ specifies the DH modulous, eg 1024, 2048, or 4096 */
+ unsigned char **dh_paramas, /* OUT
+ contains DER encoded DH params */
+ unsigned int *dh_params_len, /* OUT
+ contains length of dh_parmas */
+ unsigned char **dh_pubkey, /* OUT
+ receives DER encoded DH pub key */
+ unsigned int *dh_pubkey_len); /* OUT
+ receives length of dh_pubkey */
+
+/*
+ * this function completes client's the DH protocol. client
+ * processes received DH pub key from the KDC and computes
+ * the DH secret key
+ */
+krb5_error_code client_process_dh
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ unsigned char *dh_pubkey, /* IN
+ contains client's DER encoded DH pub key */
+ unsigned int dh_pubkey_len, /* IN
+ contains length of dh_pubkey */
+ unsigned char **dh_session_key, /* OUT
+ receives DH secret key */
+ unsigned int *dh_session_key_len); /* OUT
+ receives length of dh_session_key */
+
+/*
+ * this function implements the KDC first part of the DH protocol.
+ * it decodes the client's DH parameters and pub key and checks
+ * if they are acceptable.
+ */
+krb5_error_code server_check_dh
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ krb5_octet_data *dh_params, /* IN
+ ???? */
+ int minbits); /* IN
+ the mininum number of key bits acceptable */
+
+/*
+ * this function completes the KDC's DH protocol. The KDC generates
+ * its DH pub key and computes the DH secret key
+ */
+krb5_error_code server_process_dh
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ unsigned char *received_pubkey, /* IN
+ contains client's DER encoded DH pub key */
+ unsigned int received_pub_len, /* IN
+ contains length of received_pubkey */
+ unsigned char **dh_pubkey, /* OUT
+ receives KDC's DER encoded DH pub key */
+ unsigned int *dh_pubkey_len, /* OUT
+ receives length of dh_pubkey */
+ unsigned char **server_key, /* OUT
+ receives DH secret key */
+ unsigned int *server_key_len); /* OUT
+ receives length of server_key */
+
+/*
+ * this functions takes in crypto specific representation of
+ * supportedCMSTypes and creates a list of
+ * krb5_algorithm_identifier
+ */
+krb5_error_code create_krb5_supportedCMSTypes
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ krb5_algorithm_identifier ***supportedCMSTypes); /* OUT */
+
+/*
+ * this functions takes in crypto specific representation of
+ * trustedCertifiers and creates a list of
+ * krb5_external_principal_identifier
+ */
+krb5_error_code create_krb5_trustedCertifiers
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ krb5_external_principal_identifier ***trustedCertifiers); /* OUT */
+
+/*
+ * this functions takes in crypto specific representation of
+ * trustedCas (draft9) and creates a list of krb5_trusted_ca (draft9).
+ * draft9 trustedCAs is a CHOICE. we only support choices for
+ * [1] caName and [2] issuerAndSerial. there is no config
+ * option available to select the choice yet. default = 1.
+ */
+krb5_error_code create_krb5_trustedCas
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ int flag, /* IN
+ specifies the tag of the CHOICE */
+ krb5_trusted_ca ***trustedCas); /* OUT */
+
+/*
+ * this functions takes in crypto specific representation of the
+ * KDC's certificate and creates a DER encoded kdcPKId
+ */
+krb5_error_code create_issuerAndSerial
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ unsigned char **kdcId_buf, /* OUT
+ receives DER encoded kdcPKId */
+ unsigned int *kdcId_len); /* OUT
+ receives length of encoded kdcPKId */
+
+/*
+ * process the values from idopts and obtain the cert(s)
+ * specified by those options, populating the id_cryptoctx.
+ */
+krb5_error_code crypto_load_certs
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_opts *idopts, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN/OUT */
+ krb5_principal princ); /* IN */
+
+/*
+ * Free up information held from crypto_load_certs()
+ */
+krb5_error_code crypto_free_cert_info
+ (krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx);
+
+
+/*
+ * Get number of certificates available after crypto_load_certs()
+ */
+krb5_error_code crypto_cert_get_count
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ int *cert_count); /* OUT */
+
+/*
+ * Begin iteration over the certs loaded in crypto_load_certs()
+ */
+krb5_error_code crypto_cert_iteration_begin
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ pkinit_cert_iter_handle *iter_handle); /* OUT */
+
+/*
+ * End iteration over the certs loaded in crypto_load_certs()
+ */
+krb5_error_code crypto_cert_iteration_end
+ (krb5_context context, /* IN */
+ pkinit_cert_iter_handle iter_handle); /* IN */
+
+/*
+ * Get next certificate handle
+ */
+krb5_error_code crypto_cert_iteration_next
+ (krb5_context context, /* IN */
+ pkinit_cert_iter_handle iter_handle, /* IN */
+ pkinit_cert_handle *cert_handle); /* OUT */
+
+/*
+ * Release cert handle
+ */
+krb5_error_code crypto_cert_release
+ (krb5_context context, /* IN */
+ pkinit_cert_handle cert_handle); /* IN */
+
+/*
+ * Get certificate matching information
+ */
+krb5_error_code crypto_cert_get_matching_data
+ (krb5_context context, /* IN */
+ pkinit_cert_handle cert_handle, /* IN */
+ pkinit_cert_matching_data **ret_data); /* OUT */
+
+/*
+ * Free certificate information
+ */
+krb5_error_code crypto_cert_free_matching_data
+ (krb5_context context, /* IN */
+ pkinit_cert_matching_data *data); /* IN */
+
+/*
+ * Make the given certificate "the chosen one"
+ */
+krb5_error_code crypto_cert_select
+ (krb5_context context, /* IN */
+ pkinit_cert_matching_data *data); /* IN */
+
+/*
+ * Select the default certificate as "the chosen one"
+ */
+krb5_error_code crypto_cert_select_default
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx); /* IN */
+
+/*
+ * process the values from idopts and obtain the anchor or
+ * intermediate certificates, or crls specified by idtype,
+ * catype, and id
+ */
+krb5_error_code crypto_load_cas_and_crls
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_opts *idopts, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN/OUT */
+ int idtype, /* IN
+ defines the storage type (file, directory, etc) */
+ int catype, /* IN
+ defines the ca type (anchor, intermediate, crls) */
+ char *id); /* IN
+ defines the location (filename, directory name, etc) */
+
+/*
+ * on the client, obtain the kdc's certificate to include
+ * in a request
+ */
+krb5_error_code pkinit_get_kdc_cert
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN/OUT */
+ krb5_principal princ); /* IN */
+
+/*
+ * this function creates edata that contains TD-DH-PARAMETERS
+ */
+krb5_error_code pkinit_create_td_dh_parameters
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ pkinit_plg_opts *opts, /* IN */
+ krb5_data **edata); /* OUT */
+
+/*
+ * this function processes edata that contains TD-DH-PARAMETERS.
+ * the client processes the received acceptable by KDC DH
+ * parameters and picks the first acceptable to it. it matches
+ * them against the known DH parameters.
+ */
+krb5_error_code pkinit_process_td_dh_params
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ krb5_algorithm_identifier **algId, /* IN */
+ int *new_dh_size); /* OUT
+ receives the new DH modulus to use in the new AS-REQ */
+
+/*
+ * this function creates edata that contains TD-INVALID-CERTIFICATES
+ */
+krb5_error_code pkinit_create_td_invalid_certificate
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ krb5_data **edata); /* OUT */
+
+/*
+ * this function creates edata that contains TD-TRUSTED-CERTIFIERS
+ */
+krb5_error_code pkinit_create_td_trusted_certifiers
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ krb5_data **edata); /* OUT */
+
+/*
+ * this function processes edata that contains either
+ * TD-TRUSTED-CERTIFICATES or TD-INVALID-CERTIFICATES.
+ * current implementation only decodes the received message
+ * but does not act on it
+ */
+krb5_error_code pkinit_process_td_trusted_certifiers
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ krb5_external_principal_identifier **trustedCertifiers, /* IN */
+ int td_type); /* IN */
+
+/*
+ * this function checks if the received kdcPKId matches
+ * the KDC's certificate
+ */
+krb5_error_code pkinit_check_kdc_pkid
+ (krb5_context context, /* IN */
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */
+ pkinit_req_crypto_context req_cryptoctx, /* IN */
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ unsigned char *pdid_buf, /* IN
+ contains DER encoded kdcPKId */
+ unsigned int pkid_len, /* IN
+ contains length of pdid_buf */
+ int *valid_kdcPkId); /* OUT
+ 1 if kdcPKId matches, otherwise 0 */
+
+krb5_error_code pkinit_identity_set_prompter
+ (pkinit_identity_crypto_context id_cryptoctx, /* IN */
+ krb5_prompter_fct prompter, /* IN */
+ void *prompter_data); /* IN */
+
+#endif /* _PKINIT_CRYPTO_H */
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c
new file mode 100644
index 0000000000..25bd44acc3
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -0,0 +1,5982 @@
+/*
+ * COPYRIGHT (C) 2006,2007
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#include <dirent.h>
+
+/* Solaris Kerberos */
+#include <libintl.h>
+
+/*
+ * Q: What is this SILLYDECRYPT stuff about?
+ * A: When using the ActivCard Linux pkcs11 library (v2.0.1),
+ * the decrypt function fails. By inserting an extra
+ * function call, which serves nothing but to change the
+ * stack, we were able to work around the issue. If the
+ * ActivCard library is fixed in the future, this
+ * definition and related code can be removed.
+ */
+#define SILLYDECRYPT
+
+#include "pkinit_crypto_openssl.h"
+
+/*
+ * Solaris Kerberos:
+ * Changed to a switch statement so gettext() can be used
+ * for internationization.
+ * Use defined constants rather than raw numbers for error codes.
+ */
+static char *
+pkcs11_error_table(short code) {
+ switch (code) {
+ case CKR_OK:
+ return (gettext("ok"));
+ case CKR_CANCEL:
+ return (gettext("cancel"));
+ case CKR_HOST_MEMORY:
+ return (gettext("host memory"));
+ case CKR_SLOT_ID_INVALID:
+ return (gettext("slot id invalid"));
+ case CKR_GENERAL_ERROR:
+ return (gettext("general error"));
+ case CKR_FUNCTION_FAILED:
+ return (gettext("function failed"));
+ case CKR_ARGUMENTS_BAD:
+ return (gettext("arguments bad"));
+ case CKR_NO_EVENT:
+ return (gettext("no event"));
+ case CKR_NEED_TO_CREATE_THREADS:
+ return (gettext("need to create threads"));
+ case CKR_CANT_LOCK:
+ return (gettext("cant lock"));
+ case CKR_ATTRIBUTE_READ_ONLY:
+ return (gettext("attribute read only"));
+ case CKR_ATTRIBUTE_SENSITIVE:
+ return (gettext("attribute sensitive"));
+ case CKR_ATTRIBUTE_TYPE_INVALID:
+ return (gettext("attribute type invalid"));
+ case CKR_ATTRIBUTE_VALUE_INVALID:
+ return (gettext("attribute value invalid"));
+ case CKR_DATA_INVALID:
+ return (gettext("data invalid"));
+ case CKR_DATA_LEN_RANGE:
+ return (gettext("data len range"));
+ case CKR_DEVICE_ERROR:
+ return (gettext("device error"));
+ case CKR_DEVICE_MEMORY:
+ return (gettext("device memory"));
+ case CKR_DEVICE_REMOVED:
+ return (gettext("device removed"));
+ case CKR_ENCRYPTED_DATA_INVALID:
+ return (gettext("encrypted data invalid"));
+ case CKR_ENCRYPTED_DATA_LEN_RANGE:
+ return (gettext("encrypted data len range"));
+ case CKR_FUNCTION_CANCELED:
+ return (gettext("function canceled"));
+ case CKR_FUNCTION_NOT_PARALLEL:
+ return (gettext("function not parallel"));
+ case CKR_FUNCTION_NOT_SUPPORTED:
+ return (gettext("function not supported"));
+ case CKR_KEY_HANDLE_INVALID:
+ return (gettext("key handle invalid"));
+ case CKR_KEY_SIZE_RANGE:
+ return (gettext("key size range"));
+ case CKR_KEY_TYPE_INCONSISTENT:
+ return (gettext("key type inconsistent"));
+ case CKR_KEY_NOT_NEEDED:
+ return (gettext("key not needed"));
+ case CKR_KEY_CHANGED:
+ return (gettext("key changed"));
+ case CKR_KEY_NEEDED:
+ return (gettext("key needed"));
+ case CKR_KEY_INDIGESTIBLE:
+ return (gettext("key indigestible"));
+ case CKR_KEY_FUNCTION_NOT_PERMITTED:
+ return (gettext("key function not permitted"));
+ case CKR_KEY_NOT_WRAPPABLE:
+ return (gettext("key not wrappable"));
+ case CKR_KEY_UNEXTRACTABLE:
+ return (gettext("key unextractable"));
+ case CKR_MECHANISM_INVALID:
+ return (gettext("mechanism invalid"));
+ case CKR_MECHANISM_PARAM_INVALID:
+ return (gettext("mechanism param invalid"));
+ case CKR_OBJECT_HANDLE_INVALID:
+ return (gettext("object handle invalid"));
+ case CKR_OPERATION_ACTIVE:
+ return (gettext("operation active"));
+ case CKR_OPERATION_NOT_INITIALIZED:
+ return (gettext("operation not initialized"));
+ case CKR_PIN_INCORRECT:
+ return (gettext("pin incorrect"));
+ case CKR_PIN_INVALID:
+ return (gettext("pin invalid"));
+ case CKR_PIN_LEN_RANGE:
+ return (gettext("pin len range"));
+ case CKR_PIN_EXPIRED:
+ return (gettext("pin expired"));
+ case CKR_PIN_LOCKED:
+ return (gettext("pin locked"));
+ case CKR_SESSION_CLOSED:
+ return (gettext("session closed"));
+ case CKR_SESSION_COUNT:
+ return (gettext("session count"));
+ case CKR_SESSION_HANDLE_INVALID:
+ return (gettext("session handle invalid"));
+ case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
+ return (gettext("session parallel not supported"));
+ case CKR_SESSION_READ_ONLY:
+ return (gettext("session read only"));
+ case CKR_SESSION_EXISTS:
+ return (gettext("session exists"));
+ case CKR_SESSION_READ_ONLY_EXISTS:
+ return (gettext("session read only exists"));
+ case CKR_SESSION_READ_WRITE_SO_EXISTS:
+ return (gettext("session read write so exists"));
+ case CKR_SIGNATURE_INVALID:
+ return (gettext("signature invalid"));
+ case CKR_SIGNATURE_LEN_RANGE:
+ return (gettext("signature len range"));
+ case CKR_TEMPLATE_INCOMPLETE:
+ return (gettext("template incomplete"));
+ case CKR_TEMPLATE_INCONSISTENT:
+ return (gettext("template inconsistent"));
+ case CKR_TOKEN_NOT_PRESENT:
+ return (gettext("token not present"));
+ case CKR_TOKEN_NOT_RECOGNIZED:
+ return (gettext("token not recognized"));
+ case CKR_TOKEN_WRITE_PROTECTED:
+ return (gettext("token write protected"));
+ case CKR_UNWRAPPING_KEY_HANDLE_INVALID:
+ return (gettext("unwrapping key handle invalid"));
+ case CKR_UNWRAPPING_KEY_SIZE_RANGE:
+ return (gettext("unwrapping key size range"));
+ case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT:
+ return (gettext("unwrapping key type inconsistent"));
+ case CKR_USER_ALREADY_LOGGED_IN:
+ return (gettext("user already logged in"));
+ case CKR_USER_NOT_LOGGED_IN:
+ return (gettext("user not logged in"));
+ case CKR_USER_PIN_NOT_INITIALIZED:
+ return (gettext("user pin not initialized"));
+ case CKR_USER_TYPE_INVALID:
+ return (gettext("user type invalid"));
+ case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
+ return (gettext("user another already logged in"));
+ case CKR_USER_TOO_MANY_TYPES:
+ return (gettext("user too many types"));
+ case CKR_WRAPPED_KEY_INVALID:
+ return (gettext("wrapped key invalid"));
+ case CKR_WRAPPED_KEY_LEN_RANGE:
+ return (gettext("wrapped key len range"));
+ case CKR_WRAPPING_KEY_HANDLE_INVALID:
+ return (gettext("wrapping key handle invalid"));
+ case CKR_WRAPPING_KEY_SIZE_RANGE:
+ return (gettext("wrapping key size range"));
+ case CKR_WRAPPING_KEY_TYPE_INCONSISTENT:
+ return (gettext("wrapping key type inconsistent"));
+ case CKR_RANDOM_SEED_NOT_SUPPORTED:
+ return (gettext("random seed not supported"));
+ case CKR_RANDOM_NO_RNG:
+ return (gettext("random no rng"));
+ case CKR_DOMAIN_PARAMS_INVALID:
+ return (gettext("domain params invalid"));
+ case CKR_BUFFER_TOO_SMALL:
+ return (gettext("buffer too small"));
+ case CKR_SAVED_STATE_INVALID:
+ return (gettext("saved state invalid"));
+ case CKR_INFORMATION_SENSITIVE:
+ return (gettext("information sensitive"));
+ case CKR_STATE_UNSAVEABLE:
+ return (gettext("state unsaveable"));
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ return (gettext("cryptoki not initialized"));
+ case CKR_CRYPTOKI_ALREADY_INITIALIZED:
+ return (gettext("cryptoki already initialized"));
+ case CKR_MUTEX_BAD:
+ return (gettext("mutex bad"));
+ case CKR_MUTEX_NOT_LOCKED:
+ return (gettext("mutex not locked"));
+ case CKR_FUNCTION_REJECTED:
+ return (gettext("function rejected"));
+ default:
+ return (gettext("unknown error"));
+ }
+}
+
+/* DH parameters */
+unsigned char pkinit_1024_dhprime[128] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+unsigned char pkinit_2048_dhprime[2048/8] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+ 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+ 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+ 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+ 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+unsigned char pkinit_4096_dhprime[4096/8] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+ 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+ 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+ 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+ 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+ 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+ 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+ 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+ 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+ 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+ 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+ 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+ 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+ 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+ 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+ 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+ 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+ 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+ 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+ 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+ 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+ 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+ 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+ 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+ 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+ 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+ 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+ 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+ 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+ 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+ 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+ 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+ 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+ 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+ 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+ 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+ 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+/* Solaris Kerberos: May not be thread safe! */
+static int pkinit_oids_refs = 0;
+
+krb5_error_code
+pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) {
+
+ krb5_error_code retval = ENOMEM;
+ pkinit_plg_crypto_context ctx = NULL;
+
+ /* initialize openssl routines */
+ openssl_init();
+
+ ctx = (pkinit_plg_crypto_context)malloc(sizeof(*ctx));
+ if (ctx == NULL)
+ goto out;
+ (void) memset(ctx, 0, sizeof(*ctx));
+
+ pkiDebug("%s: initializing openssl crypto context at %p\n",
+ __FUNCTION__, ctx);
+ retval = pkinit_init_pkinit_oids(ctx);
+ if (retval)
+ goto out;
+
+ retval = pkinit_init_dh_params(ctx);
+ if (retval)
+ goto out;
+
+ *cryptoctx = ctx;
+
+out:
+ if (retval && ctx != NULL)
+ pkinit_fini_plg_crypto(ctx);
+
+ return retval;
+}
+
+void
+pkinit_fini_plg_crypto(pkinit_plg_crypto_context cryptoctx)
+{
+ pkiDebug("%s: freeing context at %p\n", __FUNCTION__, cryptoctx);
+
+ if (cryptoctx == NULL)
+ return;
+ pkinit_fini_pkinit_oids(cryptoctx);
+ pkinit_fini_dh_params(cryptoctx);
+ free(cryptoctx);
+}
+
+krb5_error_code
+pkinit_init_identity_crypto(pkinit_identity_crypto_context *idctx)
+{
+ krb5_error_code retval = ENOMEM;
+ pkinit_identity_crypto_context ctx = NULL;
+
+ ctx = (pkinit_identity_crypto_context)malloc(sizeof(*ctx));
+ if (ctx == NULL)
+ goto out;
+ (void) memset(ctx, 0, sizeof(*ctx));
+
+ retval = pkinit_init_certs(ctx);
+ if (retval)
+ goto out;
+
+ retval = pkinit_init_pkcs11(ctx);
+ if (retval)
+ goto out;
+
+ pkiDebug("%s: returning ctx at %p\n", __FUNCTION__, ctx);
+ *idctx = ctx;
+
+out:
+ if (retval) {
+ if (ctx)
+ pkinit_fini_identity_crypto(ctx);
+ }
+
+ return retval;
+}
+
+void
+pkinit_fini_identity_crypto(pkinit_identity_crypto_context idctx)
+{
+ if (idctx == NULL)
+ return;
+
+ pkiDebug("%s: freeing ctx at %p\n", __FUNCTION__, idctx);
+ pkinit_fini_certs(idctx);
+ pkinit_fini_pkcs11(idctx);
+ free(idctx);
+}
+
+krb5_error_code
+pkinit_init_req_crypto(pkinit_req_crypto_context *cryptoctx)
+{
+
+ pkinit_req_crypto_context ctx = NULL;
+
+ /* Solaris Kerberos */
+ if (cryptoctx == NULL)
+ return EINVAL;
+
+ ctx = (pkinit_req_crypto_context)malloc(sizeof(*ctx));
+ if (ctx == NULL)
+ return ENOMEM;
+ (void) memset(ctx, 0, sizeof(*ctx));
+
+ ctx->dh = NULL;
+ ctx->received_cert = NULL;
+
+ *cryptoctx = ctx;
+
+ pkiDebug("%s: returning ctx at %p\n", __FUNCTION__, ctx);
+
+ return 0;
+}
+
+void
+pkinit_fini_req_crypto(pkinit_req_crypto_context req_cryptoctx)
+{
+ if (req_cryptoctx == NULL)
+ return;
+
+ pkiDebug("%s: freeing ctx at %p\n", __FUNCTION__, req_cryptoctx);
+ if (req_cryptoctx->dh != NULL)
+ DH_free(req_cryptoctx->dh);
+ if (req_cryptoctx->received_cert != NULL)
+ X509_free(req_cryptoctx->received_cert);
+
+ free(req_cryptoctx);
+}
+
+static krb5_error_code
+pkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx)
+{
+ krb5_error_code retval = ENOMEM;
+ int nid = 0;
+
+ /*
+ * If OpenSSL already knows about the OID, use the
+ * existing definition. Otherwise, create an OID object.
+ */
+ #define CREATE_OBJ_IF_NEEDED(oid, vn, sn, ln) \
+ nid = OBJ_txt2nid(oid); \
+ if (nid == NID_undef) { \
+ nid = OBJ_create(oid, sn, ln); \
+ if (nid == NID_undef) { \
+ pkiDebug("Error creating oid object for '%s'\n", oid); \
+ goto out; \
+ } \
+ } \
+ ctx->vn = OBJ_nid2obj(nid);
+
+ CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.2", id_pkinit_san,
+ "id-pkinit-san", "KRB5PrincipalName");
+
+ CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.1", id_pkinit_authData,
+ "id-pkinit-authdata", "PKINIT signedAuthPack");
+
+ CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.2", id_pkinit_DHKeyData,
+ "id-pkinit-DHKeyData", "PKINIT dhSignedData");
+
+ CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.3", id_pkinit_rkeyData,
+ "id-pkinit-rkeyData", "PKINIT encKeyPack");
+
+ CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.4", id_pkinit_KPClientAuth,
+ "id-pkinit-KPClientAuth", "PKINIT Client EKU");
+
+ CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.5", id_pkinit_KPKdc,
+ "id-pkinit-KPKdc", "KDC EKU");
+
+#if 0
+ CREATE_OBJ_IF_NEEDED("1.2.840.113549.1.7.1", id_pkinit_authData9,
+ "id-pkcs7-data", "PKCS7 data");
+#else
+ /* See note in pkinit_pkcs7type2oid() */
+ ctx->id_pkinit_authData9 = NULL;
+#endif
+
+ CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.2", id_ms_kp_sc_logon,
+ "id-ms-kp-sc-logon EKU", "Microsoft SmartCard Login EKU");
+
+ CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.3", id_ms_san_upn,
+ "id-ms-san-upn", "Microsoft Universal Principal Name");
+
+ CREATE_OBJ_IF_NEEDED("1.3.6.1.5.5.7.3.1", id_kp_serverAuth,
+ "id-kp-serverAuth EKU", "Server Authentication EKU");
+
+ /* Success */
+ retval = 0;
+
+ /* Solaris Kerberos: May not be thread safe! */
+ pkinit_oids_refs++;
+
+out:
+ return retval;
+}
+
+static krb5_error_code
+get_cert(char *filename, X509 **retcert)
+{
+ X509 *cert = NULL;
+ BIO *tmp = NULL;
+ int code;
+ krb5_error_code retval;
+
+ if (filename == NULL || retcert == NULL)
+ return EINVAL;
+
+ *retcert = NULL;
+
+ tmp = BIO_new(BIO_s_file());
+ if (tmp == NULL)
+ return ENOMEM;
+
+ code = BIO_read_filename(tmp, filename);
+ if (code == 0) {
+ retval = errno;
+ goto cleanup;
+ }
+
+ cert = (X509 *) PEM_read_bio_X509(tmp, NULL, NULL, NULL);
+ if (cert == NULL) {
+ retval = EIO;
+ pkiDebug("failed to read certificate from %s\n", filename);
+ goto cleanup;
+ }
+ *retcert = cert;
+ retval = 0;
+cleanup:
+ if (tmp != NULL)
+ BIO_free(tmp);
+ return retval;
+}
+
+static krb5_error_code
+get_key(char *filename, EVP_PKEY **retkey)
+{
+ EVP_PKEY *pkey = NULL;
+ BIO *tmp = NULL;
+ int code;
+ krb5_error_code retval;
+
+ if (filename == NULL || retkey == NULL)
+ return EINVAL;
+
+ tmp = BIO_new(BIO_s_file());
+ if (tmp == NULL)
+ return ENOMEM;
+
+ code = BIO_read_filename(tmp, filename);
+ if (code == 0) {
+ retval = errno;
+ goto cleanup;
+ }
+ pkey = (EVP_PKEY *) PEM_read_bio_PrivateKey(tmp, NULL, NULL, NULL);
+ if (pkey == NULL) {
+ retval = EIO;
+ pkiDebug("failed to read private key from %s\n", filename);
+ goto cleanup;
+ }
+ *retkey = pkey;
+ retval = 0;
+cleanup:
+ if (tmp != NULL)
+ BIO_free(tmp);
+ return retval;
+}
+
+static void
+pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx)
+{
+ if (ctx == NULL)
+ return;
+
+ /* Only call OBJ_cleanup once! */
+ if (--pkinit_oids_refs == 0) /* Solaris Kerberos: May not be thread safe! */
+ OBJ_cleanup();
+}
+
+static krb5_error_code
+pkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
+{
+ krb5_error_code retval = ENOMEM;
+
+ plgctx->dh_1024 = DH_new();
+ if (plgctx->dh_1024 == NULL)
+ goto cleanup;
+ plgctx->dh_1024->p = BN_bin2bn(pkinit_1024_dhprime,
+ sizeof(pkinit_1024_dhprime), NULL);
+ if ((plgctx->dh_1024->g = BN_new()) == NULL ||
+ (plgctx->dh_1024->q = BN_new()) == NULL)
+ goto cleanup;
+ BN_set_word(plgctx->dh_1024->g, DH_GENERATOR_2);
+ BN_rshift1(plgctx->dh_1024->q, plgctx->dh_1024->p);
+
+ plgctx->dh_2048 = DH_new();
+ if (plgctx->dh_2048 == NULL)
+ goto cleanup;
+ plgctx->dh_2048->p = BN_bin2bn(pkinit_2048_dhprime,
+ sizeof(pkinit_2048_dhprime), NULL);
+ if ((plgctx->dh_2048->g = BN_new()) == NULL ||
+ (plgctx->dh_2048->q = BN_new()) == NULL)
+ goto cleanup;
+ BN_set_word(plgctx->dh_2048->g, DH_GENERATOR_2);
+ BN_rshift1(plgctx->dh_2048->q, plgctx->dh_2048->p);
+
+ plgctx->dh_4096 = DH_new();
+ if (plgctx->dh_4096 == NULL)
+ goto cleanup;
+ plgctx->dh_4096->p = BN_bin2bn(pkinit_4096_dhprime,
+ sizeof(pkinit_4096_dhprime), NULL);
+ if ((plgctx->dh_4096->g = BN_new()) == NULL ||
+ (plgctx->dh_4096->q = BN_new()) == NULL)
+ goto cleanup;
+ BN_set_word(plgctx->dh_4096->g, DH_GENERATOR_2);
+ BN_rshift1(plgctx->dh_4096->q, plgctx->dh_4096->p);
+
+ retval = 0;
+
+cleanup:
+ if (retval)
+ pkinit_fini_dh_params(plgctx);
+
+ return retval;
+}
+
+static void
+pkinit_fini_dh_params(pkinit_plg_crypto_context plgctx)
+{
+ if (plgctx->dh_1024 != NULL)
+ DH_free(plgctx->dh_1024);
+ if (plgctx->dh_2048 != NULL)
+ DH_free(plgctx->dh_2048);
+ if (plgctx->dh_4096 != NULL)
+ DH_free(plgctx->dh_4096);
+
+ plgctx->dh_1024 = plgctx->dh_2048 = plgctx->dh_4096 = NULL;
+}
+
+static krb5_error_code
+pkinit_init_certs(pkinit_identity_crypto_context ctx)
+{
+ /* Solaris Kerberos */
+ int i;
+
+ for (i = 0; i < MAX_CREDS_ALLOWED; i++)
+ ctx->creds[i] = NULL;
+ ctx->my_certs = NULL;
+ ctx->cert_index = 0;
+ ctx->my_key = NULL;
+ ctx->trustedCAs = NULL;
+ ctx->intermediateCAs = NULL;
+ ctx->revoked = NULL;
+
+ return 0;
+}
+
+static void
+pkinit_fini_certs(pkinit_identity_crypto_context ctx)
+{
+ if (ctx == NULL)
+ return;
+
+ if (ctx->my_certs != NULL)
+ sk_X509_pop_free(ctx->my_certs, X509_free);
+
+ if (ctx->my_key != NULL)
+ EVP_PKEY_free(ctx->my_key);
+
+ if (ctx->trustedCAs != NULL)
+ sk_X509_pop_free(ctx->trustedCAs, X509_free);
+
+ if (ctx->intermediateCAs != NULL)
+ sk_X509_pop_free(ctx->intermediateCAs, X509_free);
+
+ if (ctx->revoked != NULL)
+ sk_X509_CRL_pop_free(ctx->revoked, X509_CRL_free);
+}
+
+static krb5_error_code
+pkinit_init_pkcs11(pkinit_identity_crypto_context ctx)
+{
+ /* Solaris Kerberos */
+
+#ifndef WITHOUT_PKCS11
+ ctx->p11_module_name = strdup(PKCS11_MODNAME);
+ if (ctx->p11_module_name == NULL)
+ return ENOMEM;
+ ctx->p11_module = NULL;
+ ctx->slotid = PK_NOSLOT;
+ ctx->token_label = NULL;
+ ctx->cert_label = NULL;
+ ctx->session = CK_INVALID_HANDLE;
+ ctx->p11 = NULL;
+#endif
+ ctx->pkcs11_method = 0;
+
+ return 0;
+}
+
+static void
+pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx)
+{
+#ifndef WITHOUT_PKCS11
+ if (ctx == NULL)
+ return;
+
+ if (ctx->p11 != NULL) {
+ if (ctx->session) {
+ ctx->p11->C_CloseSession(ctx->session);
+ ctx->session = CK_INVALID_HANDLE;
+ }
+ /*
+ * Solaris Kerberos:
+ * Only call C_Finalize if the process was not already using pkcs11.
+ */
+ if (ctx->finalize_pkcs11 == TRUE)
+ ctx->p11->C_Finalize(NULL_PTR);
+
+ ctx->p11 = NULL;
+ }
+ if (ctx->p11_module != NULL) {
+ pkinit_C_UnloadModule(ctx->p11_module);
+ ctx->p11_module = NULL;
+ }
+ if (ctx->p11_module_name != NULL)
+ free(ctx->p11_module_name);
+ if (ctx->token_label != NULL)
+ free(ctx->token_label);
+ if (ctx->cert_id != NULL)
+ free(ctx->cert_id);
+ if (ctx->cert_label != NULL)
+ free(ctx->cert_label);
+#endif
+}
+
+krb5_error_code
+pkinit_identity_set_prompter(pkinit_identity_crypto_context id_cryptoctx,
+ krb5_prompter_fct prompter,
+ void *prompter_data)
+{
+ id_cryptoctx->prompter = prompter;
+ id_cryptoctx->prompter_data = prompter_data;
+
+ return 0;
+}
+
+/* ARGSUSED */
+krb5_error_code
+cms_signeddata_create(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ int cms_msg_type,
+ int include_certchain,
+ unsigned char *data,
+ unsigned int data_len,
+ unsigned char **signed_data,
+ unsigned int *signed_data_len)
+{
+ /* Solaris Kerberos */
+ krb5_error_code retval = KRB5KRB_ERR_GENERIC;
+ PKCS7 *p7 = NULL, *inner_p7 = NULL;
+ PKCS7_SIGNED *p7s = NULL;
+ PKCS7_SIGNER_INFO *p7si = NULL;
+ unsigned char *p;
+ ASN1_TYPE *pkinit_data = NULL;
+ STACK_OF(X509) * cert_stack = NULL;
+ ASN1_OCTET_STRING *digest_attr = NULL;
+ EVP_MD_CTX ctx, ctx2;
+ const EVP_MD *md_tmp = NULL;
+ unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE];
+ unsigned char *digestInfo_buf = NULL, *abuf = NULL;
+ unsigned int md_len, md_len2, alen, digestInfo_len;
+ STACK_OF(X509_ATTRIBUTE) * sk;
+ unsigned char *sig = NULL;
+ unsigned int sig_len = 0;
+ X509_ALGOR *alg = NULL;
+ ASN1_OCTET_STRING *digest = NULL;
+ unsigned int alg_len = 0, digest_len = 0;
+ unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL;
+ X509 *cert = NULL;
+ ASN1_OBJECT *oid = NULL;
+
+ /* Solaris Kerberos */
+ if (signed_data == NULL)
+ return EINVAL;
+
+ if (signed_data_len == NULL)
+ return EINVAL;
+
+ /* start creating PKCS7 data */
+ if ((p7 = PKCS7_new()) == NULL)
+ goto cleanup;
+ p7->type = OBJ_nid2obj(NID_pkcs7_signed);
+
+ if ((p7s = PKCS7_SIGNED_new()) == NULL)
+ goto cleanup;
+ p7->d.sign = p7s;
+ if (!ASN1_INTEGER_set(p7s->version, 3))
+ goto cleanup;
+
+ /* create a cert chain that has at least the signer's certificate */
+ if ((cert_stack = sk_X509_new_null()) == NULL)
+ goto cleanup;
+
+ cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
+ if (!include_certchain) {
+ pkiDebug("only including signer's certificate\n");
+ sk_X509_push(cert_stack, X509_dup(cert));
+ } else {
+ /* create a cert chain */
+ X509_STORE *certstore = NULL;
+ X509_STORE_CTX certctx;
+ STACK_OF(X509) *certstack = NULL;
+ char buf[DN_BUF_LEN];
+ int i = 0, size = 0;
+
+ if ((certstore = X509_STORE_new()) == NULL)
+ goto cleanup;
+ pkiDebug("building certificate chain\n");
+ X509_STORE_set_verify_cb_func(certstore, openssl_callback);
+ X509_STORE_CTX_init(&certctx, certstore, cert,
+ id_cryptoctx->intermediateCAs);
+ X509_STORE_CTX_trusted_stack(&certctx, id_cryptoctx->trustedCAs);
+ if (!X509_verify_cert(&certctx)) {
+ pkiDebug("failed to create a certificate chain: %s\n",
+ X509_verify_cert_error_string(X509_STORE_CTX_get_error(&certctx)));
+ if (!sk_X509_num(id_cryptoctx->trustedCAs))
+ pkiDebug("No trusted CAs found. Check your X509_anchors\n");
+ goto cleanup;
+ }
+ certstack = X509_STORE_CTX_get1_chain(&certctx);
+ size = sk_X509_num(certstack);
+ pkiDebug("size of certificate chain = %d\n", size);
+ for(i = 0; i < size - 1; i++) {
+ X509 *x = sk_X509_value(certstack, i);
+ X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
+ pkiDebug("cert #%d: %s\n", i, buf);
+ sk_X509_push(cert_stack, X509_dup(x));
+ }
+ X509_STORE_CTX_cleanup(&certctx);
+ X509_STORE_free(certstore);
+ sk_X509_pop_free(certstack, X509_free);
+ }
+ p7s->cert = cert_stack;
+
+ /* fill-in PKCS7_SIGNER_INFO */
+ if ((p7si = PKCS7_SIGNER_INFO_new()) == NULL)
+ goto cleanup;
+ if (!ASN1_INTEGER_set(p7si->version, 1))
+ goto cleanup;
+ if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
+ X509_get_issuer_name(cert)))
+ goto cleanup;
+ /* because ASN1_INTEGER_set is used to set a 'long' we will do
+ * things the ugly way. */
+ M_ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
+ if (!(p7si->issuer_and_serial->serial =
+ M_ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
+ goto cleanup;
+
+ /* will not fill-out EVP_PKEY because it's on the smartcard */
+
+ /* Set digest algs */
+ p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
+
+ if (p7si->digest_alg->parameter != NULL)
+ ASN1_TYPE_free(p7si->digest_alg->parameter);
+ if ((p7si->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
+ goto cleanup;
+ p7si->digest_alg->parameter->type = V_ASN1_NULL;
+
+ /* Set sig algs */
+ if (p7si->digest_enc_alg->parameter != NULL)
+ ASN1_TYPE_free(p7si->digest_enc_alg->parameter);
+ p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption);
+ if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new()))
+ goto cleanup;
+ p7si->digest_enc_alg->parameter->type = V_ASN1_NULL;
+
+ /* pick the correct oid for the eContentInfo */
+ oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type);
+ if (oid == NULL)
+ goto cleanup;
+
+ if (cms_msg_type == CMS_SIGN_DRAFT9) {
+ /* don't include signed attributes for pa-type 15 request */
+ abuf = data;
+ alen = data_len;
+ } else {
+ /* add signed attributes */
+ /* compute sha1 digest over the EncapsulatedContentInfo */
+ EVP_MD_CTX_init(&ctx);
+ EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
+ EVP_DigestUpdate(&ctx, data, data_len);
+ md_tmp = EVP_MD_CTX_md(&ctx);
+ EVP_DigestFinal_ex(&ctx, md_data, &md_len);
+
+ /* create a message digest attr */
+ digest_attr = ASN1_OCTET_STRING_new();
+ ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len);
+ PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
+ V_ASN1_OCTET_STRING, (char *) digest_attr);
+
+ /* create a content-type attr */
+ PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
+ V_ASN1_OBJECT, oid);
+
+ /* create the signature over signed attributes. get DER encoded value */
+ /* This is the place where smartcard signature needs to be calculated */
+ sk = p7si->auth_attr;
+ alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf,
+ ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
+ if (abuf == NULL)
+ goto cleanup2;
+ }
+
+#ifndef WITHOUT_PKCS11
+ /* Some tokens can only do RSAEncryption without sha1 hash */
+ /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
+ * function and the hash value into an ASN.1 value of type DigestInfo
+ * DigestInfo::=SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING }
+ */
+ if (id_cryptoctx->pkcs11_method == 1 &&
+ id_cryptoctx->mech == CKM_RSA_PKCS) {
+ pkiDebug("mech = CKM_RSA_PKCS\n");
+ EVP_MD_CTX_init(&ctx2);
+ /* if this is not draft9 request, include digest signed attribute */
+ if (cms_msg_type != CMS_SIGN_DRAFT9)
+ EVP_DigestInit_ex(&ctx2, md_tmp, NULL);
+ else
+ EVP_DigestInit_ex(&ctx2, EVP_sha1(), NULL);
+ EVP_DigestUpdate(&ctx2, abuf, alen);
+ EVP_DigestFinal_ex(&ctx2, md_data2, &md_len2);
+
+ alg = X509_ALGOR_new();
+ if (alg == NULL)
+ goto cleanup2;
+ alg->algorithm = OBJ_nid2obj(NID_sha1);
+ alg->parameter = NULL;
+ alg_len = i2d_X509_ALGOR(alg, NULL);
+ alg_buf = (unsigned char *)malloc(alg_len);
+ if (alg_buf == NULL)
+ goto cleanup2;
+
+ digest = ASN1_OCTET_STRING_new();
+ if (digest == NULL)
+ goto cleanup2;
+ ASN1_OCTET_STRING_set(digest, md_data2, (int)md_len2);
+ digest_len = i2d_ASN1_OCTET_STRING(digest, NULL);
+ digest_buf = (unsigned char *)malloc(digest_len);
+ if (digest_buf == NULL)
+ goto cleanup2;
+
+ digestInfo_len = ASN1_object_size(1, (int)(alg_len + digest_len),
+ V_ASN1_SEQUENCE);
+ y = digestInfo_buf = (unsigned char *)malloc(digestInfo_len);
+ if (digestInfo_buf == NULL)
+ goto cleanup2;
+ ASN1_put_object(&y, 1, (int)(alg_len + digest_len), V_ASN1_SEQUENCE,
+ V_ASN1_UNIVERSAL);
+ i2d_X509_ALGOR(alg, &y);
+ i2d_ASN1_OCTET_STRING(digest, &y);
+#ifdef DEBUG_SIG
+ pkiDebug("signing buffer\n");
+ print_buffer(digestInfo_buf, digestInfo_len);
+ print_buffer_bin(digestInfo_buf, digestInfo_len, "/tmp/pkcs7_tosign");
+#endif
+ retval = pkinit_sign_data(context, id_cryptoctx, digestInfo_buf,
+ digestInfo_len, &sig, &sig_len);
+ } else
+#endif
+ {
+ pkiDebug("mech = %s\n",
+ id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA1_RSA_PKCS" : "FS");
+ retval = pkinit_sign_data(context, id_cryptoctx, abuf, alen,
+ &sig, &sig_len);
+ }
+#ifdef DEBUG_SIG
+ print_buffer(sig, sig_len);
+#endif
+ if (cms_msg_type != CMS_SIGN_DRAFT9)
+ free(abuf);
+ if (retval)
+ goto cleanup2;
+
+ /* Add signature */
+ if (!ASN1_STRING_set(p7si->enc_digest, (unsigned char *) sig,
+ (int)sig_len)) {
+ unsigned long err = ERR_peek_error();
+ retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ krb5_set_error_message(context, retval, "%s\n",
+ ERR_error_string(err, NULL));
+ pkiDebug("failed to add a signed digest attribute\n");
+ goto cleanup2;
+ }
+ /* adder signer_info to pkcs7 signed */
+ if (!PKCS7_add_signer(p7, p7si))
+ goto cleanup2;
+
+ /* start on adding data to the pkcs7 signed */
+ if ((inner_p7 = PKCS7_new()) == NULL)
+ goto cleanup2;
+ if ((pkinit_data = ASN1_TYPE_new()) == NULL)
+ goto cleanup2;
+ pkinit_data->type = V_ASN1_OCTET_STRING;
+ if ((pkinit_data->value.octet_string = ASN1_OCTET_STRING_new()) == NULL)
+ goto cleanup2;
+ if (!ASN1_OCTET_STRING_set(pkinit_data->value.octet_string, data,
+ (int)data_len)) {
+ unsigned long err = ERR_peek_error();
+ retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ krb5_set_error_message(context, retval, "%s\n",
+ ERR_error_string(err, NULL));
+ pkiDebug("failed to add pkcs7 data\n");
+ goto cleanup2;
+ }
+
+ if (!PKCS7_set0_type_other(inner_p7, OBJ_obj2nid(oid), pkinit_data))
+ goto cleanup2;
+
+ if (p7s->contents != NULL)
+ PKCS7_free(p7s->contents);
+ p7s->contents = inner_p7;
+
+ *signed_data_len = i2d_PKCS7(p7, NULL);
+ if (!(*signed_data_len)) {
+ unsigned long err = ERR_peek_error();
+ retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ krb5_set_error_message(context, retval, "%s\n",
+ ERR_error_string(err, NULL));
+ pkiDebug("failed to der encode pkcs7\n");
+ goto cleanup2;
+ }
+ if ((p = *signed_data =
+ (unsigned char *) malloc((size_t)*signed_data_len)) == NULL)
+ goto cleanup2;
+
+ /* DER encode PKCS7 data */
+ retval = i2d_PKCS7(p7, &p);
+ if (!retval) {
+ unsigned long err = ERR_peek_error();
+ retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ krb5_set_error_message(context, retval, "%s\n",
+ ERR_error_string(err, NULL));
+ pkiDebug("failed to der encode pkcs7\n");
+ goto cleanup2;
+ }
+ retval = 0;
+
+#ifdef DEBUG_ASN1
+ if (cms_msg_type == CMS_SIGN_CLIENT) {
+ print_buffer_bin(*signed_data, *signed_data_len,
+ "/tmp/client_pkcs7_signeddata");
+ } else {
+ if (cms_msg_type == CMS_SIGN_SERVER) {
+ print_buffer_bin(*signed_data, *signed_data_len,
+ "/tmp/kdc_pkcs7_signeddata");
+ } else {
+ print_buffer_bin(*signed_data, *signed_data_len,
+ "/tmp/draft9_pkcs7_signeddata");
+ }
+ }
+#endif
+
+ cleanup2:
+ if (cms_msg_type != CMS_SIGN_DRAFT9)
+ EVP_MD_CTX_cleanup(&ctx);
+#ifndef WITHOUT_PKCS11
+ if (id_cryptoctx->pkcs11_method == 1 &&
+ id_cryptoctx->mech == CKM_RSA_PKCS) {
+ EVP_MD_CTX_cleanup(&ctx2);
+ if (digest_buf != NULL)
+ free(digest_buf);
+ if (digestInfo_buf != NULL)
+ free(digestInfo_buf);
+ if (alg_buf != NULL)
+ free(alg_buf);
+ if (digest != NULL)
+ ASN1_OCTET_STRING_free(digest);
+ }
+#endif
+ if (alg != NULL)
+ X509_ALGOR_free(alg);
+ cleanup:
+ if (p7 != NULL)
+ PKCS7_free(p7);
+ if (sig != NULL)
+ free(sig);
+
+ return retval;
+}
+
+krb5_error_code
+cms_signeddata_verify(krb5_context context,
+ pkinit_plg_crypto_context plgctx,
+ pkinit_req_crypto_context reqctx,
+ pkinit_identity_crypto_context idctx,
+ int cms_msg_type,
+ int require_crl_checking,
+ unsigned char *signed_data,
+ unsigned int signed_data_len,
+ unsigned char **data,
+ unsigned int *data_len,
+ unsigned char **authz_data,
+ unsigned int *authz_data_len)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ PKCS7 *p7 = NULL;
+ BIO *out = NULL;
+ int flags = PKCS7_NOVERIFY, i = 0;
+ unsigned int vflags = 0, size = 0;
+ const unsigned char *p = signed_data;
+ STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
+ PKCS7_SIGNER_INFO *si = NULL;
+ X509 *x = NULL;
+ X509_STORE *store = NULL;
+ X509_STORE_CTX cert_ctx;
+ STACK_OF(X509) *intermediateCAs = NULL;
+ STACK_OF(X509_CRL) *revoked = NULL;
+ STACK_OF(X509) *verified_chain = NULL;
+ ASN1_OBJECT *oid = NULL;
+ krb5_external_principal_identifier **krb5_verified_chain = NULL;
+ krb5_data *authz = NULL;
+ char buf[DN_BUF_LEN];
+
+#ifdef DEBUG_ASN1
+ print_buffer_bin(signed_data, signed_data_len,
+ "/tmp/client_received_pkcs7_signeddata");
+#endif
+
+ /* Do this early enough to create the shadow OID for pkcs7-data if needed */
+ oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type);
+ if (oid == NULL)
+ goto cleanup;
+
+ /* decode received PKCS7 message */
+ if ((p7 = d2i_PKCS7(NULL, &p, (int)signed_data_len)) == NULL) {
+ unsigned long err = ERR_peek_error();
+ krb5_set_error_message(context, retval, "%s\n",
+ ERR_error_string(err, NULL));
+ pkiDebug("%s: failed to decode message: %s\n",
+ __FUNCTION__, ERR_error_string(err, NULL));
+ goto cleanup;
+ }
+
+ /* verify that the received message is PKCS7 SignedData message */
+ if (OBJ_obj2nid(p7->type) != NID_pkcs7_signed) {
+ pkiDebug("Expected id-signedData PKCS7 msg (received type = %d)\n",
+ OBJ_obj2nid(p7->type));
+ krb5_set_error_message(context, retval, "wrong oid\n");
+ goto cleanup;
+ }
+
+ /* setup to verify X509 certificate used to sign PKCS7 message */
+ if (!(store = X509_STORE_new()))
+ goto cleanup;
+
+ /* check if we are inforcing CRL checking */
+ vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
+ if (require_crl_checking)
+ X509_STORE_set_verify_cb_func(store, openssl_callback);
+ else
+ X509_STORE_set_verify_cb_func(store, openssl_callback_ignore_crls);
+ X509_STORE_set_flags(store, vflags);
+
+ /* get the signer's information from the PKCS7 message */
+ if ((si_sk = PKCS7_get_signer_info(p7)) == NULL)
+ goto cleanup;
+ if ((si = sk_PKCS7_SIGNER_INFO_value(si_sk, 0)) == NULL)
+ goto cleanup;
+ if ((x = PKCS7_cert_from_signer_info(p7, si)) == NULL)
+ goto cleanup;
+
+ /* create available CRL information (get local CRLs and include CRLs
+ * received in the PKCS7 message
+ */
+ if (idctx->revoked == NULL)
+ revoked = p7->d.sign->crl;
+ else if (p7->d.sign->crl == NULL)
+ revoked = idctx->revoked;
+ else {
+ size = sk_X509_CRL_num(idctx->revoked);
+ revoked = sk_X509_CRL_new_null();
+ for (i = 0; i < size; i++)
+ sk_X509_CRL_push(revoked, sk_X509_CRL_value(idctx->revoked, i));
+ size = sk_X509_num(p7->d.sign->crl);
+ for (i = 0; i < size; i++)
+ sk_X509_CRL_push(revoked, sk_X509_CRL_value(p7->d.sign->crl, i));
+ }
+
+ /* create available intermediate CAs chains (get local intermediateCAs and
+ * include the CA chain received in the PKCS7 message
+ */
+ if (idctx->intermediateCAs == NULL)
+ intermediateCAs = p7->d.sign->cert;
+ else if (p7->d.sign->cert == NULL)
+ intermediateCAs = idctx->intermediateCAs;
+ else {
+ size = sk_X509_num(idctx->intermediateCAs);
+ intermediateCAs = sk_X509_new_null();
+ for (i = 0; i < size; i++) {
+ sk_X509_push(intermediateCAs,
+ sk_X509_value(idctx->intermediateCAs, i));
+ }
+ size = sk_X509_num(p7->d.sign->cert);
+ for (i = 0; i < size; i++) {
+ sk_X509_push(intermediateCAs, sk_X509_value(p7->d.sign->cert, i));
+ }
+ }
+
+ /* initialize x509 context with the received certificate and
+ * trusted and intermediate CA chains and CRLs
+ */
+ if (!X509_STORE_CTX_init(&cert_ctx, store, x, intermediateCAs))
+ goto cleanup;
+
+ X509_STORE_CTX_set0_crls(&cert_ctx, revoked);
+
+ /* add trusted CAs certificates for cert verification */
+ if (idctx->trustedCAs != NULL)
+ X509_STORE_CTX_trusted_stack(&cert_ctx, idctx->trustedCAs);
+ else {
+ pkiDebug("unable to find any trusted CAs\n");
+ goto cleanup;
+ }
+#ifdef DEBUG_CERTCHAIN
+ if (intermediateCAs != NULL) {
+ size = sk_X509_num(intermediateCAs);
+ pkiDebug("untrusted cert chain of size %d\n", size);
+ for (i = 0; i < size; i++) {
+ X509_NAME_oneline(X509_get_subject_name(
+ sk_X509_value(intermediateCAs, i)), buf, sizeof(buf));
+ pkiDebug("cert #%d: %s\n", i, buf);
+ }
+ }
+ if (idctx->trustedCAs != NULL) {
+ size = sk_X509_num(idctx->trustedCAs);
+ pkiDebug("trusted cert chain of size %d\n", size);
+ for (i = 0; i < size; i++) {
+ X509_NAME_oneline(X509_get_subject_name(
+ sk_X509_value(idctx->trustedCAs, i)), buf, sizeof(buf));
+ pkiDebug("cert #%d: %s\n", i, buf);
+ }
+ }
+ if (revoked != NULL) {
+ size = sk_X509_CRL_num(revoked);
+ pkiDebug("CRL chain of size %d\n", size);
+ for (i = 0; i < size; i++) {
+ X509_CRL *crl = sk_X509_CRL_value(revoked, i);
+ X509_NAME_oneline(X509_CRL_get_issuer(crl), buf, sizeof(buf));
+ pkiDebug("crls by CA #%d: %s\n", i , buf);
+ }
+ }
+#endif
+
+ i = X509_verify_cert(&cert_ctx);
+ if (i <= 0) {
+ int j = X509_STORE_CTX_get_error(&cert_ctx);
+
+ reqctx->received_cert = X509_dup(cert_ctx.current_cert);
+ switch(j) {
+ case X509_V_ERR_CERT_REVOKED:
+ retval = KRB5KDC_ERR_REVOKED_CERTIFICATE;
+ break;
+ case X509_V_ERR_UNABLE_TO_GET_CRL:
+ retval = KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN;
+ break;
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+ retval = KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE;
+ break;
+ default:
+ retval = KRB5KDC_ERR_INVALID_CERTIFICATE;
+ }
+ X509_NAME_oneline(X509_get_subject_name(
+ reqctx->received_cert), buf, sizeof(buf));
+ pkiDebug("problem with cert DN = %s (error=%d) %s\n", buf, j,
+ X509_verify_cert_error_string(j));
+ krb5_set_error_message(context, retval, "%s\n",
+ X509_verify_cert_error_string(j));
+#ifdef DEBUG_CERTCHAIN
+ size = sk_X509_num(p7->d.sign->cert);
+ pkiDebug("received cert chain of size %d\n", size);
+ for (j = 0; j < size; j++) {
+ X509 *tmp_cert = sk_X509_value(p7->d.sign->cert, j);
+ X509_NAME_oneline(X509_get_subject_name(tmp_cert), buf, sizeof(buf));
+ pkiDebug("cert #%d: %s\n", j, buf);
+ }
+#endif
+ } else {
+ /* retrieve verified certificate chain */
+ if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9)
+ verified_chain = X509_STORE_CTX_get1_chain(&cert_ctx);
+ }
+ X509_STORE_CTX_cleanup(&cert_ctx);
+ if (i <= 0)
+ goto cleanup;
+
+ out = BIO_new(BIO_s_mem());
+ if (cms_msg_type == CMS_SIGN_DRAFT9)
+ flags |= PKCS7_NOATTR;
+ if (PKCS7_verify(p7, NULL, store, NULL, out, flags)) {
+ int valid_oid = 0;
+
+ if (!OBJ_cmp(p7->d.sign->contents->type, oid))
+ valid_oid = 1;
+ else if (cms_msg_type == CMS_SIGN_DRAFT9) {
+ /*
+ * Various implementations of the pa-type 15 request use
+ * different OIDS. We check that the returned object
+ * has any of the acceptable OIDs
+ */
+ ASN1_OBJECT *client_oid = NULL, *server_oid = NULL, *rsa_oid = NULL;
+ client_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_CLIENT);
+ server_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_SERVER);
+ rsa_oid = pkinit_pkcs7type2oid(plgctx, CMS_ENVEL_SERVER);
+ if (!OBJ_cmp(p7->d.sign->contents->type, client_oid) ||
+ !OBJ_cmp(p7->d.sign->contents->type, server_oid) ||
+ !OBJ_cmp(p7->d.sign->contents->type, rsa_oid))
+ valid_oid = 1;
+ }
+
+ if (valid_oid)
+ pkiDebug("PKCS7 Verification successful\n");
+ else {
+ pkiDebug("wrong oid in eContentType\n");
+ print_buffer(p7->d.sign->contents->type->data,
+ (unsigned int)p7->d.sign->contents->type->length);
+ retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ krb5_set_error_message(context, retval, "wrong oid\n");
+ goto cleanup;
+ }
+ }
+ else {
+ unsigned long err = ERR_peek_error();
+ switch(ERR_GET_REASON(err)) {
+ case PKCS7_R_DIGEST_FAILURE:
+ retval = KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED;
+ break;
+ case PKCS7_R_SIGNATURE_FAILURE:
+ default:
+ retval = KRB5KDC_ERR_INVALID_SIG;
+ }
+ pkiDebug("PKCS7 Verification failure\n");
+ krb5_set_error_message(context, retval, "%s\n",
+ ERR_error_string(err, NULL));
+ goto cleanup;
+ }
+
+ /* transfer the data from PKCS7 message into return buffer */
+ for (size = 0;;) {
+ if ((*data = realloc(*data, size + 1024 * 10)) == NULL)
+ goto cleanup;
+ i = BIO_read(out, &((*data)[size]), 1024 * 10);
+ if (i <= 0)
+ break;
+ else
+ size += i;
+ }
+ *data_len = size;
+
+ reqctx->received_cert = X509_dup(x);
+
+ /* generate authorization data */
+ if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) {
+
+ if (authz_data == NULL || authz_data_len == NULL)
+ goto out;
+
+ *authz_data = NULL;
+ retval = create_identifiers_from_stack(verified_chain,
+ &krb5_verified_chain);
+ if (retval) {
+ pkiDebug("create_identifiers_from_stack failed\n");
+ goto cleanup;
+ }
+
+ retval = k5int_encode_krb5_td_trusted_certifiers((const krb5_external_principal_identifier **)krb5_verified_chain, &authz);
+ if (retval) {
+ pkiDebug("encode_krb5_td_trusted_certifiers failed\n");
+ goto cleanup;
+ }
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)authz->data, authz->length,
+ "/tmp/kdc_ad_initial_verified_cas");
+#endif
+ *authz_data = (unsigned char *)malloc(authz->length);
+ if (*authz_data == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ (void) memcpy(*authz_data, authz->data, authz->length);
+ *authz_data_len = authz->length;
+ }
+ out:
+ retval = 0;
+
+ cleanup:
+ if (out != NULL)
+ BIO_free(out);
+ if (store != NULL)
+ X509_STORE_free(store);
+ if (p7 != NULL) {
+ if (idctx->intermediateCAs != NULL && p7->d.sign->cert)
+ sk_X509_free(intermediateCAs);
+ if (idctx->revoked != NULL && p7->d.sign->crl)
+ sk_X509_CRL_free(revoked);
+ PKCS7_free(p7);
+ }
+ if (verified_chain != NULL)
+ sk_X509_pop_free(verified_chain, X509_free);
+ if (krb5_verified_chain != NULL)
+ free_krb5_external_principal_identifier(&krb5_verified_chain);
+ if (authz != NULL)
+ krb5_free_data(context, authz);
+
+ return retval;
+}
+
+krb5_error_code
+cms_envelopeddata_create(krb5_context context,
+ pkinit_plg_crypto_context plgctx,
+ pkinit_req_crypto_context reqctx,
+ pkinit_identity_crypto_context idctx,
+ krb5_preauthtype pa_type,
+ int include_certchain,
+ unsigned char *key_pack,
+ unsigned int key_pack_len,
+ unsigned char **out,
+ unsigned int *out_len)
+{
+
+ /* Solaris Kerberos */
+ krb5_error_code retval = KRB5KRB_ERR_GENERIC;
+ PKCS7 *p7 = NULL;
+ BIO *in = NULL;
+ unsigned char *p = NULL, *signed_data = NULL, *enc_data = NULL;
+ int signed_data_len = 0, enc_data_len = 0, flags = PKCS7_BINARY;
+ STACK_OF(X509) *encerts = NULL;
+ const EVP_CIPHER *cipher = NULL;
+ int cms_msg_type;
+
+ /* create the PKCS7 SignedData portion of the PKCS7 EnvelopedData */
+ switch ((int)pa_type) {
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ cms_msg_type = CMS_SIGN_DRAFT9;
+ break;
+ case KRB5_PADATA_PK_AS_REQ:
+ cms_msg_type = CMS_ENVEL_SERVER;
+ break;
+ default:
+ /* Solaris Kerberos */
+ retval = EINVAL;
+ goto cleanup;
+ }
+
+ retval = cms_signeddata_create(context, plgctx, reqctx, idctx,
+ cms_msg_type, include_certchain, key_pack, key_pack_len,
+ &signed_data, (unsigned int *)&signed_data_len);
+ if (retval) {
+ pkiDebug("failed to create pkcs7 signed data\n");
+ goto cleanup;
+ }
+
+ /* check we have client's certificate */
+ if (reqctx->received_cert == NULL) {
+ retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ goto cleanup;
+ }
+ encerts = sk_X509_new_null();
+ sk_X509_push(encerts, reqctx->received_cert);
+
+ cipher = EVP_des_ede3_cbc();
+ in = BIO_new(BIO_s_mem());
+ switch (pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ prepare_enc_data(signed_data, signed_data_len, &enc_data,
+ &enc_data_len);
+ retval = BIO_write(in, enc_data, enc_data_len);
+ if (retval != enc_data_len) {
+ pkiDebug("BIO_write only wrote %d\n", retval);
+ goto cleanup;
+ }
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ retval = BIO_write(in, signed_data, signed_data_len);
+ if (retval != signed_data_len) {
+ pkiDebug("BIO_write only wrote %d\n", retval);
+ /* Solaris Kerberos */
+ retval = KRB5KRB_ERR_GENERIC;
+ goto cleanup;
+ }
+ break;
+ default:
+ retval = -1;
+ goto cleanup;
+ }
+
+ p7 = PKCS7_encrypt(encerts, in, cipher, flags);
+ if (p7 == NULL) {
+ pkiDebug("failed to encrypt PKCS7 object\n");
+ retval = -1;
+ goto cleanup;
+ }
+ switch (pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ p7->d.enveloped->enc_data->content_type =
+ OBJ_nid2obj(NID_pkcs7_signed);
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ p7->d.enveloped->enc_data->content_type =
+ OBJ_nid2obj(NID_pkcs7_data);
+ break;
+ }
+
+ *out_len = i2d_PKCS7(p7, NULL);
+ if (!*out_len || (p = *out = (unsigned char *)malloc(*out_len)) == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ retval = i2d_PKCS7(p7, &p);
+ if (!retval) {
+ pkiDebug("unable to write pkcs7 object\n");
+ goto cleanup;
+ }
+ retval = 0;
+
+#ifdef DEBUG_ASN1
+ print_buffer_bin(*out, *out_len, "/tmp/kdc_enveloped_data");
+#endif
+
+cleanup:
+ if (p7 != NULL)
+ PKCS7_free(p7);
+ if (in != NULL)
+ BIO_free(in);
+ if (signed_data != NULL)
+ free(signed_data);
+ if (enc_data != NULL)
+ free(enc_data);
+ if (encerts != NULL)
+ sk_X509_free(encerts);
+
+ return retval;
+}
+
+krb5_error_code
+cms_envelopeddata_verify(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_preauthtype pa_type,
+ int require_crl_checking,
+ unsigned char *enveloped_data,
+ unsigned int enveloped_data_len,
+ unsigned char **data,
+ unsigned int *data_len)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ PKCS7 *p7 = NULL;
+ BIO *out = NULL;
+ int i = 0;
+ unsigned int size = 0;
+ const unsigned char *p = enveloped_data;
+ unsigned int tmp_buf_len = 0, tmp_buf2_len = 0, vfy_buf_len = 0;
+ unsigned char *tmp_buf = NULL, *tmp_buf2 = NULL, *vfy_buf = NULL;
+ int msg_type = 0;
+
+#ifdef DEBUG_ASN1
+ print_buffer_bin(enveloped_data, enveloped_data_len,
+ "/tmp/client_envelopeddata");
+#endif
+ /* decode received PKCS7 message */
+ if ((p7 = d2i_PKCS7(NULL, &p, (int)enveloped_data_len)) == NULL) {
+ unsigned long err = ERR_peek_error();
+ pkiDebug("failed to decode pkcs7\n");
+ krb5_set_error_message(context, retval, "%s\n",
+ ERR_error_string(err, NULL));
+ goto cleanup;
+ }
+
+ /* verify that the received message is PKCS7 EnvelopedData message */
+ if (OBJ_obj2nid(p7->type) != NID_pkcs7_enveloped) {
+ pkiDebug("Expected id-enveloped PKCS7 msg (received type = %d)\n",
+ OBJ_obj2nid(p7->type));
+ krb5_set_error_message(context, retval, "wrong oid\n");
+ goto cleanup;
+ }
+
+ /* decrypt received PKCS7 message */
+ out = BIO_new(BIO_s_mem());
+ if (pkcs7_decrypt(context, id_cryptoctx, p7, out)) {
+ pkiDebug("PKCS7 decryption successful\n");
+ } else {
+ unsigned long err = ERR_peek_error();
+ if (err != 0)
+ krb5_set_error_message(context, retval, "%s\n",
+ ERR_error_string(err, NULL));
+ pkiDebug("PKCS7 decryption failed\n");
+ goto cleanup;
+ }
+
+ /* transfer the decoded PKCS7 SignedData message into a separate buffer */
+ for (;;) {
+ if ((tmp_buf = realloc(tmp_buf, size + 1024 * 10)) == NULL)
+ goto cleanup;
+ i = BIO_read(out, &(tmp_buf[size]), 1024 * 10);
+ if (i <= 0)
+ break;
+ else
+ size += i;
+ }
+ tmp_buf_len = size;
+
+#ifdef DEBUG_ASN1
+ print_buffer_bin(tmp_buf, tmp_buf_len, "/tmp/client_enc_keypack");
+#endif
+ /* verify PKCS7 SignedData message */
+ switch (pa_type) {
+ case KRB5_PADATA_PK_AS_REP:
+ msg_type = CMS_ENVEL_SERVER;
+
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ msg_type = CMS_SIGN_DRAFT9;
+ break;
+ default:
+ pkiDebug("%s: unrecognized pa_type = %d\n", __FUNCTION__, pa_type);
+ retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ goto cleanup;
+ }
+ /*
+ * If this is the RFC style, wrap the signed data to make
+ * decoding easier in the verify routine.
+ * For draft9-compatible, we don't do anything because it
+ * is already wrapped.
+ */
+#ifdef LONGHORN_BETA_COMPAT
+ /*
+ * The Longhorn server returns the expected RFC-style data, but
+ * it is missing the sequence tag and length, so it requires
+ * special processing when wrapping.
+ * This will hopefully be fixed before the final release and
+ * this can all be removed.
+ */
+ if (msg_type == CMS_ENVEL_SERVER || longhorn == 1) {
+ retval = wrap_signeddata(tmp_buf, tmp_buf_len,
+ &tmp_buf2, &tmp_buf2_len, longhorn);
+ if (retval) {
+ pkiDebug("failed to encode signeddata\n");
+ goto cleanup;
+ }
+ vfy_buf = tmp_buf2;
+ vfy_buf_len = tmp_buf2_len;
+
+ } else {
+ vfy_buf = tmp_buf;
+ vfy_buf_len = tmp_buf_len;
+ }
+#else
+ if (msg_type == CMS_ENVEL_SERVER) {
+ retval = wrap_signeddata(tmp_buf, tmp_buf_len,
+ &tmp_buf2, &tmp_buf2_len);
+ if (retval) {
+ pkiDebug("failed to encode signeddata\n");
+ goto cleanup;
+ }
+ vfy_buf = tmp_buf2;
+ vfy_buf_len = tmp_buf2_len;
+
+ } else {
+ vfy_buf = tmp_buf;
+ vfy_buf_len = tmp_buf_len;
+ }
+#endif
+
+#ifdef DEBUG_ASN1
+ print_buffer_bin(vfy_buf, vfy_buf_len, "/tmp/client_enc_keypack2");
+#endif
+
+ retval = cms_signeddata_verify(context, plg_cryptoctx, req_cryptoctx,
+ id_cryptoctx, msg_type,
+ require_crl_checking,
+ vfy_buf, vfy_buf_len,
+ data, data_len, NULL, NULL);
+
+ if (!retval)
+ pkiDebug("PKCS7 Verification Success\n");
+ else {
+ pkiDebug("PKCS7 Verification Failure\n");
+ goto cleanup;
+ }
+
+ retval = 0;
+
+ cleanup:
+
+ if (p7 != NULL)
+ PKCS7_free(p7);
+ if (out != NULL)
+ BIO_free(out);
+ if (tmp_buf != NULL)
+ free(tmp_buf);
+ if (tmp_buf2 != NULL)
+ free(tmp_buf2);
+
+ return retval;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+crypto_retrieve_X509_sans(krb5_context context,
+ pkinit_plg_crypto_context plgctx,
+ pkinit_req_crypto_context reqctx,
+ X509 *cert,
+ krb5_principal **princs_ret,
+ krb5_principal **upn_ret,
+ unsigned char ***dns_ret)
+{
+ krb5_error_code retval = EINVAL;
+ char buf[DN_BUF_LEN];
+ int p = 0, u = 0, d = 0;
+ krb5_principal *princs = NULL;
+ krb5_principal *upns = NULL;
+ unsigned char **dnss = NULL;
+ int i, num_found = 0;
+
+ if (princs_ret == NULL && upn_ret == NULL && dns_ret == NULL) {
+ pkiDebug("%s: nowhere to return any values!\n", __FUNCTION__);
+ return retval;
+ }
+
+ if (cert == NULL) {
+ pkiDebug("%s: no certificate!\n", __FUNCTION__);
+ return retval;
+ }
+
+ X509_NAME_oneline(X509_get_subject_name(cert),
+ buf, sizeof(buf));
+ pkiDebug("%s: looking for SANs in cert = %s\n", __FUNCTION__, buf);
+
+ if ((i = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1)) >= 0) {
+ X509_EXTENSION *ext = NULL;
+ GENERAL_NAMES *ialt = NULL;
+ GENERAL_NAME *gen = NULL;
+ int ret = 0;
+ unsigned int num_sans = 0;
+
+ if (!(ext = X509_get_ext(cert, i)) || !(ialt = X509V3_EXT_d2i(ext))) {
+ pkiDebug("%s: found no subject alt name extensions\n",
+ __FUNCTION__);
+ goto cleanup;
+ }
+ num_sans = sk_GENERAL_NAME_num(ialt);
+
+ pkiDebug("%s: found %d subject alt name extension(s)\n",
+ __FUNCTION__, num_sans);
+
+ /* OK, we're likely returning something. Allocate return values */
+ if (princs_ret != NULL) {
+ princs = calloc(num_sans + 1, sizeof(krb5_principal));
+ if (princs == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ }
+ if (upn_ret != NULL) {
+ upns = calloc(num_sans + 1, sizeof(krb5_principal));
+ if (upns == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ }
+ if (dns_ret != NULL) {
+ dnss = calloc(num_sans + 1, sizeof(*dnss));
+ if (dnss == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ }
+
+ for (i = 0; i < num_sans; i++) {
+ krb5_data name = { 0, 0, NULL };
+
+ gen = sk_GENERAL_NAME_value(ialt, i);
+ switch (gen->type) {
+ case GEN_OTHERNAME:
+ name.length = gen->d.otherName->value->value.sequence->length;
+ name.data = (char *)gen->d.otherName->value->value.sequence->data;
+ if (princs != NULL
+ && OBJ_cmp(plgctx->id_pkinit_san,
+ gen->d.otherName->type_id) == 0) {
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)name.data, name.length,
+ "/tmp/pkinit_san");
+#endif
+ ret = k5int_decode_krb5_principal_name(&name, &princs[p]);
+ if (ret) {
+ pkiDebug("%s: failed decoding pkinit san value\n",
+ __FUNCTION__);
+ } else {
+ p++;
+ num_found++;
+ }
+ } else if (upns != NULL
+ && OBJ_cmp(plgctx->id_ms_san_upn,
+ gen->d.otherName->type_id) == 0) {
+ ret = krb5_parse_name(context, name.data, &upns[u]);
+ if (ret) {
+ pkiDebug("%s: failed parsing ms-upn san value\n",
+ __FUNCTION__);
+ } else {
+ u++;
+ num_found++;
+ }
+ } else {
+ pkiDebug("%s: unrecognized othername oid in SAN\n",
+ __FUNCTION__);
+ continue;
+ }
+
+ break;
+ case GEN_DNS:
+ if (dnss != NULL) {
+ pkiDebug("%s: found dns name = %s\n",
+ __FUNCTION__, gen->d.dNSName->data);
+ dnss[d] = (unsigned char *)
+ strdup((char *)gen->d.dNSName->data);
+ if (dnss[d] == NULL) {
+ pkiDebug("%s: failed to duplicate dns name\n",
+ __FUNCTION__);
+ } else {
+ d++;
+ num_found++;
+ }
+ }
+ break;
+ default:
+ pkiDebug("%s: SAN type = %d expecting %d\n",
+ __FUNCTION__, gen->type, GEN_OTHERNAME);
+ }
+ }
+ sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free);
+ }
+
+ retval = 0;
+ if (princs)
+ *princs_ret = princs;
+ if (upns)
+ *upn_ret = upns;
+ if (dnss)
+ *dns_ret = dnss;
+
+ cleanup:
+ if (retval) {
+ if (princs != NULL) {
+ for (i = 0; princs[i] != NULL; i++)
+ krb5_free_principal(context, princs[i]);
+ free(princs);
+ }
+ if (upns != NULL) {
+ for (i = 0; upns[i] != NULL; i++)
+ krb5_free_principal(context, upns[i]);
+ free(upns);
+ }
+ if (dnss != NULL) {
+ for (i = 0; dnss[i] != NULL; i++)
+ free(dnss[i]);
+ free(dnss);
+ }
+ }
+ return retval;
+}
+
+/* ARGSUSED */
+krb5_error_code
+crypto_retrieve_cert_sans(krb5_context context,
+ pkinit_plg_crypto_context plgctx,
+ pkinit_req_crypto_context reqctx,
+ pkinit_identity_crypto_context idctx,
+ krb5_principal **princs_ret,
+ krb5_principal **upn_ret,
+ unsigned char ***dns_ret)
+{
+ krb5_error_code retval = EINVAL;
+
+ if (reqctx->received_cert == NULL) {
+ pkiDebug("%s: No certificate!\n", __FUNCTION__);
+ return retval;
+ }
+
+ return crypto_retrieve_X509_sans(context, plgctx, reqctx,
+ reqctx->received_cert, princs_ret,
+ upn_ret, dns_ret);
+}
+
+/* ARGSUSED */
+krb5_error_code
+crypto_check_cert_eku(krb5_context context,
+ pkinit_plg_crypto_context plgctx,
+ pkinit_req_crypto_context reqctx,
+ pkinit_identity_crypto_context idctx,
+ int checking_kdc_cert,
+ int allow_secondary_usage,
+ int *valid_eku)
+{
+ char buf[DN_BUF_LEN];
+ int found_eku = 0;
+ krb5_error_code retval = EINVAL;
+ int i;
+
+ /* Solaris Kerberos */
+ if (valid_eku == NULL)
+ return retval;
+
+ *valid_eku = 0;
+ if (reqctx->received_cert == NULL)
+ goto cleanup;
+
+ X509_NAME_oneline(X509_get_subject_name(reqctx->received_cert),
+ buf, sizeof(buf));
+ pkiDebug("%s: looking for EKUs in cert = %s\n", __FUNCTION__, buf);
+
+ if ((i = X509_get_ext_by_NID(reqctx->received_cert,
+ NID_ext_key_usage, -1)) >= 0) {
+ EXTENDED_KEY_USAGE *extusage;
+
+ extusage = X509_get_ext_d2i(reqctx->received_cert, NID_ext_key_usage,
+ NULL, NULL);
+ if (extusage) {
+ pkiDebug("%s: found eku info in the cert\n", __FUNCTION__);
+ for (i = 0; found_eku == 0 && i < sk_ASN1_OBJECT_num(extusage); i++) {
+ ASN1_OBJECT *tmp_oid;
+
+ tmp_oid = sk_ASN1_OBJECT_value(extusage, i);
+ pkiDebug("%s: checking eku %d of %d, allow_secondary = %d\n",
+ __FUNCTION__, i+1, sk_ASN1_OBJECT_num(extusage),
+ allow_secondary_usage);
+ if (checking_kdc_cert) {
+ if ((OBJ_cmp(tmp_oid, plgctx->id_pkinit_KPKdc) == 0)
+ || (allow_secondary_usage
+ && OBJ_cmp(tmp_oid, plgctx->id_kp_serverAuth) == 0))
+ found_eku = 1;
+ } else {
+ if ((OBJ_cmp(tmp_oid, plgctx->id_pkinit_KPClientAuth) == 0)
+ || (allow_secondary_usage
+ && OBJ_cmp(tmp_oid, plgctx->id_ms_kp_sc_logon) == 0))
+ found_eku = 1;
+ }
+ }
+ }
+ EXTENDED_KEY_USAGE_free(extusage);
+
+ if (found_eku) {
+ ASN1_BIT_STRING *usage = NULL;
+ pkiDebug("%s: found acceptable EKU, checking for digitalSignature\n", __FUNCTION__);
+
+ /* check that digitalSignature KeyUsage is present */
+ if ((usage = X509_get_ext_d2i(reqctx->received_cert,
+ NID_key_usage, NULL, NULL))) {
+
+ if (!ku_reject(reqctx->received_cert,
+ X509v3_KU_DIGITAL_SIGNATURE)) {
+ pkiDebug("%s: found digitalSignature KU\n",
+ __FUNCTION__);
+ *valid_eku = 1;
+ } else
+ pkiDebug("%s: didn't find digitalSignature KU\n",
+ __FUNCTION__);
+ }
+ ASN1_BIT_STRING_free(usage);
+ }
+ }
+ retval = 0;
+cleanup:
+ pkiDebug("%s: returning retval %d, valid_eku %d\n",
+ __FUNCTION__, retval, *valid_eku);
+ return retval;
+}
+
+krb5_error_code
+pkinit_octetstring2key(krb5_context context,
+ krb5_enctype etype,
+ unsigned char *key,
+ unsigned int dh_key_len,
+ krb5_keyblock * key_block)
+{
+ krb5_error_code retval;
+ unsigned char *buf = NULL;
+ unsigned char md[SHA_DIGEST_LENGTH];
+ unsigned char counter;
+ size_t keybytes, keylength, offset;
+ krb5_data random_data;
+
+
+ if ((buf = (unsigned char *) malloc(dh_key_len)) == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ (void) memset(buf, 0, dh_key_len);
+
+ counter = 0;
+ offset = 0;
+ do {
+ SHA_CTX c;
+
+ SHA1_Init(&c);
+ SHA1_Update(&c, &counter, 1);
+ SHA1_Update(&c, key, dh_key_len);
+ SHA1_Final(md, &c);
+
+ if (dh_key_len - offset < sizeof(md))
+ (void) memcpy(buf + offset, md, dh_key_len - offset);
+ else
+ (void) memcpy(buf + offset, md, sizeof(md));
+
+ offset += sizeof(md);
+ counter++;
+ } while (offset < dh_key_len);
+
+ /* Solaris Kerberos */
+ key_block->magic = KV5M_KEYBLOCK;
+ key_block->enctype = etype;
+
+ retval = krb5_c_keylengths(context, etype, &keybytes, &keylength);
+ if (retval)
+ goto cleanup;
+
+ key_block->length = keylength;
+ key_block->contents = calloc(keylength, sizeof(unsigned char *));
+ if (key_block->contents == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+
+ random_data.length = keybytes;
+ random_data.data = (char *)buf;
+
+ retval = krb5_c_random_to_key(context, etype, &random_data, key_block);
+
+ cleanup:
+ if (buf != NULL)
+ free(buf);
+ if (retval && key_block->contents != NULL && key_block->length != 0) {
+ (void) memset(key_block->contents, 0, key_block->length);
+ key_block->length = 0;
+ }
+
+ return retval;
+}
+
+/* ARGSUSED */
+krb5_error_code
+client_create_dh(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ int dh_size,
+ unsigned char **dh_params,
+ unsigned int *dh_params_len,
+ unsigned char **dh_pubkey,
+ unsigned int *dh_pubkey_len)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ unsigned char *buf = NULL;
+ int dh_err = 0;
+ ASN1_INTEGER *pub_key = NULL;
+
+ if (cryptoctx->dh == NULL) {
+ if ((cryptoctx->dh = DH_new()) == NULL)
+ goto cleanup;
+ if ((cryptoctx->dh->g = BN_new()) == NULL ||
+ (cryptoctx->dh->q = BN_new()) == NULL)
+ goto cleanup;
+
+ switch(dh_size) {
+ case 1024:
+ pkiDebug("client uses 1024 DH keys\n");
+ cryptoctx->dh->p = get_rfc2409_prime_1024(NULL);
+ break;
+ case 2048:
+ pkiDebug("client uses 2048 DH keys\n");
+ cryptoctx->dh->p = BN_bin2bn(pkinit_2048_dhprime,
+ sizeof(pkinit_2048_dhprime), NULL);
+ break;
+ case 4096:
+ pkiDebug("client uses 4096 DH keys\n");
+ cryptoctx->dh->p = BN_bin2bn(pkinit_4096_dhprime,
+ sizeof(pkinit_4096_dhprime), NULL);
+ break;
+ default:
+ goto cleanup;
+ }
+
+ BN_set_word((cryptoctx->dh->g), DH_GENERATOR_2);
+ BN_rshift1(cryptoctx->dh->q, cryptoctx->dh->p);
+ }
+
+ DH_generate_key(cryptoctx->dh);
+/* Solaris Kerberos */
+#ifdef DEBUG
+ DH_check(cryptoctx->dh, &dh_err);
+ if (dh_err != 0) {
+ pkiDebug("Warning: dh_check failed with %d\n", dh_err);
+ if (dh_err & DH_CHECK_P_NOT_PRIME)
+ pkiDebug("p value is not prime\n");
+ if (dh_err & DH_CHECK_P_NOT_SAFE_PRIME)
+ pkiDebug("p value is not a safe prime\n");
+ if (dh_err & DH_UNABLE_TO_CHECK_GENERATOR)
+ pkiDebug("unable to check the generator value\n");
+ if (dh_err & DH_NOT_SUITABLE_GENERATOR)
+ pkiDebug("the g value is not a generator\n");
+ }
+#endif
+#ifdef DEBUG_DH
+ print_dh(cryptoctx->dh, "client's DH params\n");
+ print_pubkey(cryptoctx->dh->pub_key, "client's pub_key=");
+#endif
+
+ DH_check_pub_key(cryptoctx->dh, cryptoctx->dh->pub_key, &dh_err);
+ if (dh_err != 0) {
+ pkiDebug("dh_check_pub_key failed with %d\n", dh_err);
+ goto cleanup;
+ }
+
+ /* pack DHparams */
+ /* aglo: usually we could just call i2d_DHparams to encode DH params
+ * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3.
+ */
+ retval = pkinit_encode_dh_params(cryptoctx->dh->p, cryptoctx->dh->g,
+ cryptoctx->dh->q, dh_params, dh_params_len);
+ if (retval)
+ goto cleanup;
+
+ /* pack DH public key */
+ /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
+ * encoding shall be used as the contents (the value) of the
+ * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
+ * data element
+ */
+ if ((pub_key = BN_to_ASN1_INTEGER(cryptoctx->dh->pub_key, NULL)) == NULL)
+ goto cleanup;
+ *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
+ if ((buf = *dh_pubkey = (unsigned char *)
+ malloc((size_t) *dh_pubkey_len)) == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ i2d_ASN1_INTEGER(pub_key, &buf);
+
+ if (pub_key != NULL)
+ ASN1_INTEGER_free(pub_key);
+
+ retval = 0;
+ return retval;
+
+ cleanup:
+ if (cryptoctx->dh != NULL)
+ DH_free(cryptoctx->dh);
+ cryptoctx->dh = NULL;
+ if (*dh_params != NULL)
+ free(*dh_params);
+ *dh_params = NULL;
+ if (*dh_pubkey != NULL)
+ free(*dh_pubkey);
+ *dh_pubkey = NULL;
+ if (pub_key != NULL)
+ ASN1_INTEGER_free(pub_key);
+
+ return retval;
+}
+
+/* ARGSUSED */
+krb5_error_code
+client_process_dh(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *subjectPublicKey_data,
+ unsigned int subjectPublicKey_length,
+ unsigned char **client_key,
+ unsigned int *client_key_len)
+{
+ /* Solaris Kerberos */
+ krb5_error_code retval = KRB5_PREAUTH_FAILED;
+ BIGNUM *server_pub_key = NULL;
+ ASN1_INTEGER *pub_key = NULL;
+ const unsigned char *p = NULL;
+ unsigned char *data = NULL;
+ long data_len;
+
+ /* decode subjectPublicKey (retrieve INTEGER from OCTET_STRING) */
+
+ if (der_decode_data(subjectPublicKey_data, (long)subjectPublicKey_length,
+ &data, &data_len) != 0) {
+ pkiDebug("failed to decode subjectPublicKey\n");
+ /* Solaris Kerberos */
+ retval = KRB5_PREAUTH_FAILED;
+ goto cleanup;
+ }
+
+ *client_key_len = DH_size(cryptoctx->dh);
+ if ((*client_key = (unsigned char *)
+ malloc((size_t) *client_key_len)) == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ p = data;
+ if ((pub_key = d2i_ASN1_INTEGER(NULL, &p, data_len)) == NULL)
+ goto cleanup;
+ if ((server_pub_key = ASN1_INTEGER_to_BN(pub_key, NULL)) == NULL)
+ goto cleanup;
+
+ DH_compute_key(*client_key, server_pub_key, cryptoctx->dh);
+#ifdef DEBUG_DH
+ print_pubkey(server_pub_key, "server's pub_key=");
+ pkiDebug("client secret key (%d)= ", *client_key_len);
+ print_buffer(*client_key, *client_key_len);
+#endif
+
+ retval = 0;
+ if (server_pub_key != NULL)
+ BN_free(server_pub_key);
+ if (pub_key != NULL)
+ ASN1_INTEGER_free(pub_key);
+ if (data != NULL)
+ free (data);
+
+ return retval;
+
+ cleanup:
+ if (*client_key != NULL)
+ free(*client_key);
+ *client_key = NULL;
+ if (pub_key != NULL)
+ ASN1_INTEGER_free(pub_key);
+ if (data != NULL)
+ free (data);
+
+ return retval;
+}
+
+/* ARGSUSED */
+krb5_error_code
+server_check_dh(krb5_context context,
+ pkinit_plg_crypto_context cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_octet_data *dh_params,
+ int minbits)
+{
+ DH *dh = NULL;
+ unsigned char *tmp = NULL;
+ int dh_prime_bits;
+ krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
+
+ tmp = dh_params->data;
+ dh = DH_new();
+ dh = pkinit_decode_dh_params(&dh, &tmp, dh_params->length);
+ if (dh == NULL) {
+ pkiDebug("failed to decode dhparams\n");
+ goto cleanup;
+ }
+
+ /* KDC SHOULD check to see if the key parameters satisfy its policy */
+ dh_prime_bits = BN_num_bits(dh->p);
+ if (minbits && dh_prime_bits < minbits) {
+ pkiDebug("client sent dh params with %d bits, we require %d\n",
+ dh_prime_bits, minbits);
+ goto cleanup;
+ }
+
+ /* check dhparams is group 2 */
+ if (pkinit_check_dh_params(cryptoctx->dh_1024->p,
+ dh->p, dh->g, dh->q) == 0) {
+ retval = 0;
+ goto cleanup;
+ }
+
+ /* check dhparams is group 14 */
+ if (pkinit_check_dh_params(cryptoctx->dh_2048->p,
+ dh->p, dh->g, dh->q) == 0) {
+ retval = 0;
+ goto cleanup;
+ }
+
+ /* check dhparams is group 16 */
+ if (pkinit_check_dh_params(cryptoctx->dh_4096->p,
+ dh->p, dh->g, dh->q) == 0) {
+ retval = 0;
+ goto cleanup;
+ }
+
+ cleanup:
+ if (retval == 0)
+ req_cryptoctx->dh = dh;
+ else
+ DH_free(dh);
+
+ return retval;
+}
+
+/* kdc's dh function */
+/* ARGSUSED */
+krb5_error_code
+server_process_dh(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *data,
+ unsigned int data_len,
+ unsigned char **dh_pubkey,
+ unsigned int *dh_pubkey_len,
+ unsigned char **server_key,
+ unsigned int *server_key_len)
+{
+ /* Solaris Kerberos */
+ krb5_error_code retval = KRB5KRB_ERR_GENERIC;
+ DH *dh = NULL, *dh_server = NULL;
+ unsigned char *p = NULL;
+ ASN1_INTEGER *pub_key = NULL;
+
+ /* get client's received DH parameters that we saved in server_check_dh */
+ dh = cryptoctx->dh;
+
+ dh_server = DH_new();
+ if (dh_server == NULL)
+ goto cleanup;
+ dh_server->p = BN_dup(dh->p);
+ dh_server->g = BN_dup(dh->g);
+ dh_server->q = BN_dup(dh->q);
+
+ /* decode client's public key */
+ p = data;
+ pub_key = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&p, (int)data_len);
+ if (pub_key == NULL)
+ goto cleanup;
+ dh->pub_key = ASN1_INTEGER_to_BN(pub_key, NULL);
+ if (dh->pub_key == NULL)
+ goto cleanup;
+ ASN1_INTEGER_free(pub_key);
+
+ if (!DH_generate_key(dh_server))
+ goto cleanup;
+
+ /* generate DH session key */
+ *server_key_len = DH_size(dh_server);
+ if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len)) == NULL)
+ goto cleanup;
+ DH_compute_key(*server_key, dh->pub_key, dh_server);
+
+#ifdef DEBUG_DH
+ print_dh(dh_server, "client&server's DH params\n");
+ print_pubkey(dh->pub_key, "client's pub_key=");
+ print_pubkey(dh_server->pub_key, "server's pub_key=");
+ pkiDebug("server secret key=");
+ print_buffer(*server_key, *server_key_len);
+#endif
+
+ /* KDC reply */
+ /* pack DH public key */
+ /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
+ * encoding shall be used as the contents (the value) of the
+ * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
+ * data element
+ */
+ if ((pub_key = BN_to_ASN1_INTEGER(dh_server->pub_key, NULL)) == NULL)
+ goto cleanup;
+ *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
+ if ((p = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len)) == NULL)
+ goto cleanup;
+ i2d_ASN1_INTEGER(pub_key, &p);
+ if (pub_key != NULL)
+ ASN1_INTEGER_free(pub_key);
+
+ retval = 0;
+
+ if (dh_server != NULL)
+ DH_free(dh_server);
+ return retval;
+
+ cleanup:
+ if (dh_server != NULL)
+ DH_free(dh_server);
+ if (*dh_pubkey != NULL)
+ free(*dh_pubkey);
+ if (*server_key != NULL)
+ free(*server_key);
+
+ return retval;
+}
+
+static void
+openssl_init()
+{
+ static int did_init = 0;
+
+ if (!did_init) {
+ /* initialize openssl routines */
+ CRYPTO_malloc_init();
+ ERR_load_crypto_strings();
+ OpenSSL_add_all_algorithms();
+ did_init++;
+ }
+}
+
+static krb5_error_code
+pkinit_encode_dh_params(BIGNUM *p, BIGNUM *g, BIGNUM *q,
+ unsigned char **buf, unsigned int *buf_len)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ int bufsize = 0, r = 0;
+ unsigned char *tmp = NULL;
+ ASN1_INTEGER *ap = NULL, *ag = NULL, *aq = NULL;
+
+ if ((ap = BN_to_ASN1_INTEGER(p, NULL)) == NULL)
+ goto cleanup;
+ if ((ag = BN_to_ASN1_INTEGER(g, NULL)) == NULL)
+ goto cleanup;
+ if ((aq = BN_to_ASN1_INTEGER(q, NULL)) == NULL)
+ goto cleanup;
+ bufsize = i2d_ASN1_INTEGER(ap, NULL);
+ bufsize += i2d_ASN1_INTEGER(ag, NULL);
+ bufsize += i2d_ASN1_INTEGER(aq, NULL);
+
+ r = ASN1_object_size(1, bufsize, V_ASN1_SEQUENCE);
+
+ tmp = *buf = (unsigned char *)malloc((size_t) r);
+ if (tmp == NULL)
+ goto cleanup;
+
+ ASN1_put_object(&tmp, 1, bufsize, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+
+ i2d_ASN1_INTEGER(ap, &tmp);
+ i2d_ASN1_INTEGER(ag, &tmp);
+ i2d_ASN1_INTEGER(aq, &tmp);
+
+ *buf_len = r;
+
+ retval = 0;
+
+cleanup:
+ if (ap != NULL)
+ ASN1_INTEGER_free(ap);
+ if (ag != NULL)
+ ASN1_INTEGER_free(ag);
+ if (aq != NULL)
+ ASN1_INTEGER_free(aq);
+
+ return retval;
+}
+
+static DH *
+pkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len)
+{
+ ASN1_INTEGER ai, *aip = NULL;
+ long length = (long) len;
+
+ M_ASN1_D2I_vars(a, DH *, DH_new);
+
+ M_ASN1_D2I_Init();
+ M_ASN1_D2I_start_sequence();
+ aip = &ai;
+ ai.data = NULL;
+ ai.length = 0;
+ M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
+ if (aip == NULL)
+ return NULL;
+ else {
+ (*a)->p = ASN1_INTEGER_to_BN(aip, NULL);
+ if ((*a)->p == NULL)
+ return NULL;
+ if (ai.data != NULL) {
+ OPENSSL_free(ai.data);
+ ai.data = NULL;
+ ai.length = 0;
+ }
+ }
+ M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
+ if (aip == NULL)
+ return NULL;
+ else {
+ (*a)->g = ASN1_INTEGER_to_BN(aip, NULL);
+ if ((*a)->g == NULL)
+ return NULL;
+ if (ai.data != NULL) {
+ OPENSSL_free(ai.data);
+ ai.data = NULL;
+ ai.length = 0;
+ }
+
+ }
+ M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
+ if (aip == NULL)
+ return NULL;
+ else {
+ (*a)->q = ASN1_INTEGER_to_BN(aip, NULL);
+ if ((*a)->q == NULL)
+ return NULL;
+ if (ai.data != NULL) {
+ OPENSSL_free(ai.data);
+ ai.data = NULL;
+ ai.length = 0;
+ }
+
+ }
+ M_ASN1_D2I_end_sequence();
+ M_ASN1_D2I_Finish(a, DH_free, 0);
+
+}
+
+static krb5_error_code
+pkinit_create_sequence_of_principal_identifiers(
+ krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ int type,
+ krb5_data **out_data)
+{
+ krb5_error_code retval = KRB5KRB_ERR_GENERIC;
+ krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
+ krb5_data *td_certifiers = NULL, *data = NULL;
+ krb5_typed_data **typed_data = NULL;
+
+ switch(type) {
+ case TD_TRUSTED_CERTIFIERS:
+ retval = create_krb5_trustedCertifiers(context, plg_cryptoctx,
+ req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers);
+ if (retval) {
+ pkiDebug("create_krb5_trustedCertifiers failed\n");
+ goto cleanup;
+ }
+ break;
+ case TD_INVALID_CERTIFICATES:
+ retval = create_krb5_invalidCertificates(context, plg_cryptoctx,
+ req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers);
+ if (retval) {
+ pkiDebug("create_krb5_invalidCertificates failed\n");
+ goto cleanup;
+ }
+ break;
+ default:
+ retval = -1;
+ goto cleanup;
+ }
+
+ retval = k5int_encode_krb5_td_trusted_certifiers((const krb5_external_principal_identifier **)krb5_trusted_certifiers, &td_certifiers);
+ if (retval) {
+ pkiDebug("encode_krb5_td_trusted_certifiers failed\n");
+ goto cleanup;
+ }
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)td_certifiers->data,
+ td_certifiers->length, "/tmp/kdc_td_certifiers");
+#endif
+ typed_data = malloc (2 * sizeof(krb5_typed_data *));
+ if (typed_data == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ typed_data[1] = NULL;
+ init_krb5_typed_data(&typed_data[0]);
+ if (typed_data[0] == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ typed_data[0]->type = type;
+ typed_data[0]->length = td_certifiers->length;
+ typed_data[0]->data = (unsigned char *)td_certifiers->data;
+ retval = k5int_encode_krb5_typed_data((const krb5_typed_data **)typed_data,
+ &data);
+ if (retval) {
+ pkiDebug("encode_krb5_typed_data failed\n");
+ goto cleanup;
+ }
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)data->data, data->length,
+ "/tmp/kdc_edata");
+#endif
+ *out_data = (krb5_data *)malloc(sizeof(krb5_data));
+ (*out_data)->length = data->length;
+ (*out_data)->data = (char *)malloc(data->length);
+ (void) memcpy((*out_data)->data, data->data, data->length);
+
+ retval = 0;
+
+cleanup:
+ if (krb5_trusted_certifiers != NULL)
+ free_krb5_external_principal_identifier(&krb5_trusted_certifiers);
+
+ if (data != NULL) {
+ if (data->data != NULL)
+ free(data->data);
+ free(data);
+ }
+
+ if (td_certifiers != NULL)
+ free(td_certifiers);
+
+ if (typed_data != NULL)
+ free_krb5_typed_data(&typed_data);
+
+ return retval;
+}
+
+krb5_error_code
+pkinit_create_td_trusted_certifiers(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_data **out_data)
+{
+ krb5_error_code retval = KRB5KRB_ERR_GENERIC;
+
+ retval = pkinit_create_sequence_of_principal_identifiers(context,
+ plg_cryptoctx, req_cryptoctx, id_cryptoctx,
+ TD_TRUSTED_CERTIFIERS, out_data);
+
+ return retval;
+}
+
+krb5_error_code
+pkinit_create_td_invalid_certificate(
+ krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_data **out_data)
+{
+ krb5_error_code retval = KRB5KRB_ERR_GENERIC;
+
+ retval = pkinit_create_sequence_of_principal_identifiers(context,
+ plg_cryptoctx, req_cryptoctx, id_cryptoctx,
+ TD_INVALID_CERTIFICATES, out_data);
+
+ return retval;
+}
+
+/* ARGSUSED */
+krb5_error_code
+pkinit_create_td_dh_parameters(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ pkinit_plg_opts *opts,
+ krb5_data **out_data)
+{
+ /* Solaris Kerberos */
+ krb5_error_code retval = KRB5KRB_ERR_GENERIC;
+ unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0;
+ unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL;
+ krb5_typed_data **typed_data = NULL;
+ krb5_data *data = NULL, *encoded_algId = NULL;
+ krb5_algorithm_identifier **algId = NULL;
+
+ /* Solaris Kerberos */
+ if (opts->dh_min_bits > 4096) {
+ retval = EINVAL;
+ goto cleanup;
+ }
+
+ if (opts->dh_min_bits <= 1024) {
+ retval = pkinit_encode_dh_params(plg_cryptoctx->dh_1024->p,
+ plg_cryptoctx->dh_1024->g, plg_cryptoctx->dh_1024->q,
+ &buf1, &buf1_len);
+ if (retval)
+ goto cleanup;
+ }
+ if (opts->dh_min_bits <= 2048) {
+ retval = pkinit_encode_dh_params(plg_cryptoctx->dh_2048->p,
+ plg_cryptoctx->dh_2048->g, plg_cryptoctx->dh_2048->q,
+ &buf2, &buf2_len);
+ if (retval)
+ goto cleanup;
+ }
+ retval = pkinit_encode_dh_params(plg_cryptoctx->dh_4096->p,
+ plg_cryptoctx->dh_4096->g, plg_cryptoctx->dh_4096->q,
+ &buf3, &buf3_len);
+ if (retval)
+ goto cleanup;
+
+ if (opts->dh_min_bits <= 1024) {
+ algId = malloc(4 * sizeof(krb5_algorithm_identifier *));
+ if (algId == NULL)
+ goto cleanup;
+ algId[3] = NULL;
+ algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
+ if (algId[0] == NULL)
+ goto cleanup;
+ algId[0]->parameters.data = (unsigned char *)malloc(buf2_len);
+ if (algId[0]->parameters.data == NULL)
+ goto cleanup;
+ (void) memcpy(algId[0]->parameters.data, buf2, buf2_len);
+ algId[0]->parameters.length = buf2_len;
+ algId[0]->algorithm = dh_oid;
+
+ algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
+ if (algId[1] == NULL)
+ goto cleanup;
+ algId[1]->parameters.data = (unsigned char *)malloc(buf3_len);
+ if (algId[1]->parameters.data == NULL)
+ goto cleanup;
+ (void) memcpy(algId[1]->parameters.data, buf3, buf3_len);
+ algId[1]->parameters.length = buf3_len;
+ algId[1]->algorithm = dh_oid;
+
+ algId[2] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
+ if (algId[2] == NULL)
+ goto cleanup;
+ algId[2]->parameters.data = (unsigned char *)malloc(buf1_len);
+ if (algId[2]->parameters.data == NULL)
+ goto cleanup;
+ (void) memcpy(algId[2]->parameters.data, buf1, buf1_len);
+ algId[2]->parameters.length = buf1_len;
+ algId[2]->algorithm = dh_oid;
+
+ } else if (opts->dh_min_bits <= 2048) {
+ algId = malloc(3 * sizeof(krb5_algorithm_identifier *));
+ if (algId == NULL)
+ goto cleanup;
+ algId[2] = NULL;
+ algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
+ if (algId[0] == NULL)
+ goto cleanup;
+ algId[0]->parameters.data = (unsigned char *)malloc(buf2_len);
+ if (algId[0]->parameters.data == NULL)
+ goto cleanup;
+ (void) memcpy(algId[0]->parameters.data, buf2, buf2_len);
+ algId[0]->parameters.length = buf2_len;
+ algId[0]->algorithm = dh_oid;
+
+ algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
+ if (algId[1] == NULL)
+ goto cleanup;
+ algId[1]->parameters.data = (unsigned char *)malloc(buf3_len);
+ if (algId[1]->parameters.data == NULL)
+ goto cleanup;
+ (void) memcpy(algId[1]->parameters.data, buf3, buf3_len);
+ algId[1]->parameters.length = buf3_len;
+ algId[1]->algorithm = dh_oid;
+
+ } else if (opts->dh_min_bits <= 4096) {
+ algId = malloc(2 * sizeof(krb5_algorithm_identifier *));
+ if (algId == NULL)
+ goto cleanup;
+ algId[1] = NULL;
+ algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
+ if (algId[0] == NULL)
+ goto cleanup;
+ algId[0]->parameters.data = (unsigned char *)malloc(buf3_len);
+ if (algId[0]->parameters.data == NULL)
+ goto cleanup;
+ (void) memcpy(algId[0]->parameters.data, buf3, buf3_len);
+ algId[0]->parameters.length = buf3_len;
+ algId[0]->algorithm = dh_oid;
+
+ }
+ retval = k5int_encode_krb5_td_dh_parameters((const krb5_algorithm_identifier **)algId, &encoded_algId);
+ if (retval)
+ goto cleanup;
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)encoded_algId->data,
+ encoded_algId->length, "/tmp/kdc_td_dh_params");
+#endif
+ typed_data = malloc (2 * sizeof(krb5_typed_data *));
+ if (typed_data == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ typed_data[1] = NULL;
+ init_krb5_typed_data(&typed_data[0]);
+ if (typed_data == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ typed_data[0]->type = TD_DH_PARAMETERS;
+ typed_data[0]->length = encoded_algId->length;
+ typed_data[0]->data = (unsigned char *)encoded_algId->data;
+ retval = k5int_encode_krb5_typed_data((const krb5_typed_data**)typed_data,
+ &data);
+ if (retval) {
+ pkiDebug("encode_krb5_typed_data failed\n");
+ goto cleanup;
+ }
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)data->data, data->length,
+ "/tmp/kdc_edata");
+#endif
+ *out_data = (krb5_data *)malloc(sizeof(krb5_data));
+ if (*out_data == NULL)
+ goto cleanup;
+ (*out_data)->length = data->length;
+ (*out_data)->data = (char *)malloc(data->length);
+ if ((*out_data)->data == NULL) {
+ free(*out_data);
+ *out_data = NULL;
+ goto cleanup;
+ }
+ (void) memcpy((*out_data)->data, data->data, data->length);
+
+ retval = 0;
+cleanup:
+
+ if (buf1 != NULL)
+ free(buf1);
+ if (buf2 != NULL)
+ free(buf2);
+ if (buf3 != NULL)
+ free(buf3);
+ if (data != NULL) {
+ if (data->data != NULL)
+ free(data->data);
+ free(data);
+ }
+ if (typed_data != NULL)
+ free_krb5_typed_data(&typed_data);
+ if (encoded_algId != NULL)
+ free(encoded_algId);
+
+ if (algId != NULL) {
+ while(algId[i] != NULL) {
+ if (algId[i]->parameters.data != NULL)
+ free(algId[i]->parameters.data);
+ free(algId[i]);
+ i++;
+ }
+ free(algId);
+ }
+
+ return retval;
+}
+
+/* ARGSUSED */
+krb5_error_code
+pkinit_check_kdc_pkid(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *pdid_buf,
+ unsigned int pkid_len,
+ int *valid_kdcPkId)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ PKCS7_ISSUER_AND_SERIAL *is = NULL;
+ const unsigned char *p = pdid_buf;
+ int status = 1;
+ X509 *kdc_cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
+
+ *valid_kdcPkId = 0;
+ pkiDebug("found kdcPkId in AS REQ\n");
+ is = d2i_PKCS7_ISSUER_AND_SERIAL(NULL, &p, (int)pkid_len);
+ if (is == NULL)
+ goto cleanup;
+
+ status = X509_NAME_cmp(X509_get_issuer_name(kdc_cert), is->issuer);
+ if (!status) {
+ status = ASN1_INTEGER_cmp(X509_get_serialNumber(kdc_cert), is->serial);
+ if (!status)
+ *valid_kdcPkId = 1;
+ }
+
+ retval = 0;
+cleanup:
+ X509_NAME_free(is->issuer);
+ ASN1_INTEGER_free(is->serial);
+ free(is);
+
+ return retval;
+}
+
+static int
+pkinit_check_dh_params(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1)
+{
+ BIGNUM *g2 = NULL, *q2 = NULL;
+ /* Solaris Kerberos */
+ int retval = EINVAL;
+
+ if (!BN_cmp(p1, p2)) {
+ g2 = BN_new();
+ BN_set_word(g2, DH_GENERATOR_2);
+ if (!BN_cmp(g1, g2)) {
+ q2 = BN_new();
+ BN_rshift1(q2, p1);
+ if (!BN_cmp(q1, q2)) {
+ pkiDebug("good %d dhparams\n", BN_num_bits(p1));
+ retval = 0;
+ } else
+ pkiDebug("bad group 2 q dhparameter\n");
+ BN_free(q2);
+ } else
+ pkiDebug("bad g dhparameter\n");
+ BN_free(g2);
+ } else
+ pkiDebug("p is not well-known group 2 dhparameter\n");
+
+ return retval;
+}
+
+/* ARGSUSED */
+krb5_error_code
+pkinit_process_td_dh_params(krb5_context context,
+ pkinit_plg_crypto_context cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_algorithm_identifier **algId,
+ int *new_dh_size)
+{
+ krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
+ int i = 0, use_sent_dh = 0, ok = 0;
+
+ pkiDebug("dh parameters\n");
+
+ while (algId[i] != NULL) {
+ DH *dh = NULL;
+ unsigned char *tmp = NULL;
+ int dh_prime_bits = 0;
+
+ if (algId[i]->algorithm.length != dh_oid.length ||
+ memcmp(algId[i]->algorithm.data, dh_oid.data, dh_oid.length))
+ goto cleanup;
+
+ tmp = algId[i]->parameters.data;
+ dh = DH_new();
+ dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length);
+ dh_prime_bits = BN_num_bits(dh->p);
+ pkiDebug("client sent %d DH bits server prefers %d DH bits\n",
+ *new_dh_size, dh_prime_bits);
+ switch(dh_prime_bits) {
+ case 1024:
+ if (pkinit_check_dh_params(cryptoctx->dh_1024->p, dh->p,
+ dh->g, dh->q) == 0) {
+ *new_dh_size = 1024;
+ ok = 1;
+ }
+ break;
+ case 2048:
+ if (pkinit_check_dh_params(cryptoctx->dh_2048->p, dh->p,
+ dh->g, dh->q) == 0) {
+ *new_dh_size = 2048;
+ ok = 1;
+ }
+ break;
+ case 4096:
+ if (pkinit_check_dh_params(cryptoctx->dh_4096->p, dh->p,
+ dh->g, dh->q) == 0) {
+ *new_dh_size = 4096;
+ ok = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ if (!ok) {
+ DH_check(dh, &retval);
+ if (retval != 0) {
+ pkiDebug("DH parameters provided by server are unacceptable\n");
+ retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
+ }
+ else {
+ use_sent_dh = 1;
+ ok = 1;
+ }
+ }
+ if (!use_sent_dh)
+ DH_free(dh);
+ if (ok) {
+ if (req_cryptoctx->dh != NULL) {
+ DH_free(req_cryptoctx->dh);
+ req_cryptoctx->dh = NULL;
+ }
+ if (use_sent_dh)
+ req_cryptoctx->dh = dh;
+ break;
+ }
+ i++;
+ }
+
+ if (ok)
+ retval = 0;
+
+cleanup:
+ return retval;
+}
+
+/* ARGSUSED */
+static int
+openssl_callback(int ok, X509_STORE_CTX * ctx)
+{
+#ifdef DEBUG
+ if (!ok) {
+ char buf[DN_BUF_LEN];
+
+ X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf));
+ pkiDebug("cert = %s\n", buf);
+ pkiDebug("callback function: %d (%s)\n", ctx->error,
+ X509_verify_cert_error_string(ctx->error));
+ }
+#endif
+ return ok;
+}
+
+static int
+openssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx)
+{
+ if (!ok) {
+ switch (ctx->error) {
+ case X509_V_ERR_UNABLE_TO_GET_CRL:
+ return 1;
+ default:
+ return 0;
+ }
+ }
+ return ok;
+}
+
+static ASN1_OBJECT *
+pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
+{
+ int nid;
+
+ switch (pkcs7_type) {
+ case CMS_SIGN_CLIENT:
+ return cryptoctx->id_pkinit_authData;
+ case CMS_SIGN_DRAFT9:
+ /*
+ * Delay creating this OID until we know we need it.
+ * It shadows an existing OpenSSL oid. If it
+ * is created too early, it breaks things like
+ * the use of pkcs12 (which uses pkcs7 structures).
+ * We need this shadow version because our code
+ * depends on the "other" type to be unknown to the
+ * OpenSSL code.
+ */
+ if (cryptoctx->id_pkinit_authData9 == NULL) {
+ pkiDebug("%s: Creating shadow instance of pkcs7-data oid\n",
+ __FUNCTION__);
+ nid = OBJ_create("1.2.840.113549.1.7.1", "id-pkcs7-data",
+ "PKCS7 data");
+ if (nid == NID_undef)
+ return NULL;
+ cryptoctx->id_pkinit_authData9 = OBJ_nid2obj(nid);
+ }
+ return cryptoctx->id_pkinit_authData9;
+ case CMS_SIGN_SERVER:
+ return cryptoctx->id_pkinit_DHKeyData;
+ case CMS_ENVEL_SERVER:
+ return cryptoctx->id_pkinit_rkeyData;
+ default:
+ return NULL;
+ }
+
+}
+
+#ifdef LONGHORN_BETA_COMPAT
+#if 0
+/*
+ * This is a version that worked with Longhorn Beta 3.
+ */
+static int
+wrap_signeddata(unsigned char *data, unsigned int data_len,
+ unsigned char **out, unsigned int *out_len,
+ int is_longhorn_server)
+{
+
+ unsigned int orig_len = 0, oid_len = 0, tot_len = 0;
+ ASN1_OBJECT *oid = NULL;
+ unsigned char *p = NULL;
+
+ pkiDebug("%s: This is the Longhorn version and is_longhorn_server = %d\n",
+ __FUNCTION__, is_longhorn_server);
+
+ /* Get length to wrap the original data with SEQUENCE tag */
+ tot_len = orig_len = ASN1_object_size(1, (int)data_len, V_ASN1_SEQUENCE);
+
+ if (is_longhorn_server == 0) {
+ /* Add the signedData OID and adjust lengths */
+ oid = OBJ_nid2obj(NID_pkcs7_signed);
+ oid_len = i2d_ASN1_OBJECT(oid, NULL);
+
+ tot_len = ASN1_object_size(1, (int)(orig_len+oid_len), V_ASN1_SEQUENCE);
+ }
+
+ p = *out = (unsigned char *)malloc(tot_len);
+ if (p == NULL) return -1;
+
+ if (is_longhorn_server == 0) {
+ ASN1_put_object(&p, 1, (int)(orig_len+oid_len),
+ V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+
+ i2d_ASN1_OBJECT(oid, &p);
+
+ ASN1_put_object(&p, 1, (int)data_len, 0, V_ASN1_CONTEXT_SPECIFIC);
+ } else {
+ ASN1_put_object(&p, 1, (int)data_len, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+ }
+ memcpy(p, data, data_len);
+
+ *out_len = tot_len;
+
+ return 0;
+}
+#else
+/*
+ * This is a version that works with a patched Longhorn KDC.
+ * (Which should match SP1 ??).
+ */
+static int
+wrap_signeddata(unsigned char *data, unsigned int data_len,
+ unsigned char **out, unsigned int *out_len,
+ int is_longhorn_server)
+{
+
+ unsigned int oid_len = 0, tot_len = 0, wrap_len = 0, tag_len = 0;
+ ASN1_OBJECT *oid = NULL;
+ unsigned char *p = NULL;
+
+ pkiDebug("%s: This is the Longhorn version and is_longhorn_server = %d\n",
+ __FUNCTION__, is_longhorn_server);
+
+ /* New longhorn is missing another sequence */
+ if (is_longhorn_server == 1)
+ wrap_len = ASN1_object_size(1, (int)(data_len), V_ASN1_SEQUENCE);
+ else
+ wrap_len = data_len;
+
+ /* Get length to wrap the original data with SEQUENCE tag */
+ tag_len = ASN1_object_size(1, (int)wrap_len, V_ASN1_SEQUENCE);
+
+ /* Always add oid */
+ oid = OBJ_nid2obj(NID_pkcs7_signed);
+ oid_len = i2d_ASN1_OBJECT(oid, NULL);
+ oid_len += tag_len;
+
+ tot_len = ASN1_object_size(1, (int)(oid_len), V_ASN1_SEQUENCE);
+
+ p = *out = (unsigned char *)malloc(tot_len);
+ if (p == NULL)
+ return -1;
+
+ ASN1_put_object(&p, 1, (int)(oid_len),
+ V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+
+ i2d_ASN1_OBJECT(oid, &p);
+
+ ASN1_put_object(&p, 1, (int)wrap_len, 0, V_ASN1_CONTEXT_SPECIFIC);
+
+ /* Wrap in extra seq tag */
+ if (is_longhorn_server == 1) {
+ ASN1_put_object(&p, 1, (int)data_len, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+ }
+ (void) memcpy(p, data, data_len);
+
+ *out_len = tot_len;
+
+ return 0;
+}
+
+#endif
+#else
+static int
+wrap_signeddata(unsigned char *data, unsigned int data_len,
+ unsigned char **out, unsigned int *out_len)
+{
+
+ unsigned int orig_len = 0, oid_len = 0, tot_len = 0;
+ ASN1_OBJECT *oid = NULL;
+ unsigned char *p = NULL;
+
+ /* Get length to wrap the original data with SEQUENCE tag */
+ tot_len = orig_len = ASN1_object_size(1, (int)data_len, V_ASN1_SEQUENCE);
+
+ /* Add the signedData OID and adjust lengths */
+ oid = OBJ_nid2obj(NID_pkcs7_signed);
+ oid_len = i2d_ASN1_OBJECT(oid, NULL);
+
+ tot_len = ASN1_object_size(1, (int)(orig_len+oid_len), V_ASN1_SEQUENCE);
+
+ p = *out = (unsigned char *)malloc(tot_len);
+ if (p == NULL) return -1;
+
+ ASN1_put_object(&p, 1, (int)(orig_len+oid_len),
+ V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+
+ i2d_ASN1_OBJECT(oid, &p);
+
+ ASN1_put_object(&p, 1, (int)data_len, 0, V_ASN1_CONTEXT_SPECIFIC);
+ (void) memcpy(p, data, data_len);
+
+ *out_len = tot_len;
+
+ return 0;
+}
+#endif
+
+static int
+prepare_enc_data(unsigned char *indata,
+ int indata_len,
+ unsigned char **outdata,
+ int *outdata_len)
+{
+ /* Solaris Kerberos */
+ ASN1_const_CTX c;
+ long length = indata_len;
+ int Ttag, Tclass;
+ long Tlen;
+
+ c.pp = (const unsigned char **)&indata;
+ c.q = *(const unsigned char **)&indata;
+ c.error = ERR_R_NESTED_ASN1_ERROR;
+ c.p= *(const unsigned char **)&indata;
+ c.max = (length == 0)?0:(c.p+length);
+
+ asn1_GetSequence(&c,&length);
+
+ ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
+ c.p += Tlen;
+ ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
+
+ asn1_const_Finish(&c);
+
+ *outdata = (unsigned char *)malloc((size_t)Tlen);
+ /* Solaris Kerberos */
+ if (outdata == NULL)
+ return ENOMEM;
+
+ (void) memcpy(*outdata, c.p, (size_t)Tlen);
+ *outdata_len = Tlen;
+
+ return 0;
+}
+
+#ifndef WITHOUT_PKCS11
+static void *
+pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p)
+{
+ void *handle;
+ CK_RV (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
+
+ pkiDebug("loading module \"%s\"... ", modname);
+ /* Solaris Kerberos */
+ handle = dlopen(modname, RTLD_NOW | RTLD_GROUP);
+ if (handle == NULL) {
+ pkiDebug("not found\n");
+ return NULL;
+ }
+ getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) dlsym(handle, "C_GetFunctionList");
+ if (getflist == NULL || (*getflist)(p11p) != CKR_OK) {
+ (void) dlclose(handle);
+ pkiDebug("failed\n");
+ return NULL;
+ }
+ pkiDebug("ok\n");
+ return handle;
+}
+
+static CK_RV
+pkinit_C_UnloadModule(void *handle)
+{
+ /* Solaris Kerberos */
+ if (dlclose(handle) != 0)
+ return CKR_GENERAL_ERROR;
+
+ return CKR_OK;
+}
+
+static krb5_error_code
+pkinit_login(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
+ CK_TOKEN_INFO *tip)
+{
+ krb5_data rdat;
+ char *prompt;
+ int prompt_len;
+ krb5_prompt kprompt;
+ krb5_prompt_type prompt_type;
+ int r = 0;
+
+ if (tip->flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
+ rdat.data = NULL;
+ rdat.length = 0;
+ } else {
+ /* Solaris Kerberos - Changes for gettext() */
+ prompt_len = sizeof (tip->label) + 256;
+ if ((prompt = (char *) malloc(prompt_len)) == NULL)
+ return ENOMEM;
+ (void) snprintf(prompt, prompt_len, gettext("%.*s PIN"), sizeof (tip->label), tip->label);
+ /* Solaris Kerberos */
+ if (tip->flags & CKF_USER_PIN_LOCKED)
+ (void) strlcat(prompt, gettext(" (Warning: PIN locked)"), prompt_len);
+ else if (tip->flags & CKF_USER_PIN_FINAL_TRY)
+ (void) strlcat(prompt, gettext(" (Warning: PIN final try)"), prompt_len);
+ else if (tip->flags & CKF_USER_PIN_COUNT_LOW)
+ (void) strlcat(prompt, gettext(" (Warning: PIN count low)"), prompt_len);
+ rdat.data = (char *)malloc(tip->ulMaxPinLen + 2);
+ rdat.length = tip->ulMaxPinLen + 1;
+
+ kprompt.prompt = prompt;
+ kprompt.hidden = 1;
+ kprompt.reply = &rdat;
+ prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
+
+ /* PROMPTER_INVOCATION */
+ k5int_set_prompt_types(context, &prompt_type);
+ r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
+ NULL, NULL, 1, &kprompt);
+ k5int_set_prompt_types(context, 0);
+ free(prompt);
+ }
+
+ if (r == 0) {
+ r = id_cryptoctx->p11->C_Login(id_cryptoctx->session, CKU_USER,
+ (u_char *) rdat.data, rdat.length);
+
+ if (r != CKR_OK) {
+ pkiDebug("C_Login: %s\n", pkinit_pkcs11_code_to_text(r));
+ /* Solaris Kerberos: Improved error messages */
+ krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
+ gettext("failed to log into token: %s"),
+ pkinit_pkcs11_code_to_text(r));
+ r = KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+ }
+ if (rdat.data)
+ free(rdat.data);
+
+ return r;
+}
+
+static krb5_error_code
+pkinit_open_session(krb5_context context,
+ pkinit_identity_crypto_context cctx)
+{
+ int i, r;
+ unsigned char *cp;
+ CK_ULONG count = 0;
+ CK_SLOT_ID_PTR slotlist;
+ CK_TOKEN_INFO tinfo;
+
+ if (cctx->p11_module != NULL)
+ return 0; /* session already open */
+
+ /* Load module */
+ cctx->p11_module =
+ pkinit_C_LoadModule(cctx->p11_module_name, &cctx->p11);
+ if (cctx->p11_module == NULL)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+
+ /* Init */
+ /* Solaris Kerberos: Don't fail if cryptoki is already initialized */
+ r = cctx->p11->C_Initialize(NULL);
+ if (r != CKR_OK && r != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
+ pkiDebug("C_Initialize: %s\n", pkinit_pkcs11_code_to_text(r));
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ /*
+ * Solaris Kerberos:
+ * If C_Initialize was already called by the process before the pkinit
+ * module was loaded then record that fact.
+ * "finalize_pkcs11" is used by pkinit_fini_pkcs11 to determine whether
+ * or not C_Finalize() should be called.
+ */
+ cctx->finalize_pkcs11 =
+ (r == CKR_CRYPTOKI_ALREADY_INITIALIZED ? FALSE : TRUE);
+
+ /* Get the list of available slots */
+ if (cctx->slotid != PK_NOSLOT) {
+ /* A slot was specified, so that's the only one in the list */
+ count = 1;
+ slotlist = (CK_SLOT_ID_PTR) malloc(sizeof (CK_SLOT_ID));
+ slotlist[0] = cctx->slotid;
+ } else {
+ if (cctx->p11->C_GetSlotList(TRUE, NULL, &count) != CKR_OK)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ if (count == 0)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ slotlist = (CK_SLOT_ID_PTR) malloc(count * sizeof (CK_SLOT_ID));
+ if (cctx->p11->C_GetSlotList(TRUE, slotlist, &count) != CKR_OK)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ /* Look for the given token label, or if none given take the first one */
+ for (i = 0; i < count; i++) {
+ /* Open session */
+ if ((r = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION,
+ NULL, NULL, &cctx->session)) != CKR_OK) {
+ pkiDebug("C_OpenSession: %s\n", pkinit_pkcs11_code_to_text(r));
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ /* Get token info */
+ if ((r = cctx->p11->C_GetTokenInfo(slotlist[i], &tinfo)) != CKR_OK) {
+ pkiDebug("C_GetTokenInfo: %s\n", pkinit_pkcs11_code_to_text(r));
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+ for (cp = tinfo.label + sizeof (tinfo.label) - 1;
+ *cp == '\0' || *cp == ' '; cp--)
+ *cp = '\0';
+ pkiDebug("open_session: slotid %d token \"%s\"\n",
+ (int) slotlist[i], tinfo.label);
+ if (cctx->token_label == NULL ||
+ !strcmp((char *) cctx->token_label, (char *) tinfo.label))
+ break;
+ cctx->p11->C_CloseSession(cctx->session);
+ }
+ if (i >= count) {
+ free(slotlist);
+ pkiDebug("open_session: no matching token found\n");
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+ cctx->slotid = slotlist[i];
+ free(slotlist);
+ pkiDebug("open_session: slotid %d (%d of %d)\n", (int) cctx->slotid,
+ i + 1, (int) count);
+
+ /* Login if needed */
+ if (tinfo.flags & CKF_LOGIN_REQUIRED)
+ r = pkinit_login(context, cctx, &tinfo);
+
+ return r;
+}
+
+/*
+ * Look for a key that's:
+ * 1. private
+ * 2. capable of the specified operation (usually signing or decrypting)
+ * 3. RSA (this may be wrong but it's all we can do for now)
+ * 4. matches the id of the cert we chose
+ *
+ * You must call pkinit_get_certs before calling pkinit_find_private_key
+ * (that's because we need the ID of the private key)
+ *
+ * pkcs11 says the id of the key doesn't have to match that of the cert, but
+ * I can't figure out any other way to decide which key to use.
+ *
+ * We should only find one key that fits all the requirements.
+ * If there are more than one, we just take the first one.
+ */
+
+/* ARGSUSED */
+krb5_error_code
+pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
+ CK_ATTRIBUTE_TYPE usage,
+ CK_OBJECT_HANDLE *objp)
+{
+ CK_OBJECT_CLASS cls;
+ CK_ATTRIBUTE attrs[4];
+ CK_ULONG count;
+ CK_KEY_TYPE keytype;
+ unsigned int nattrs = 0;
+ int r;
+#ifdef PKINIT_USE_KEY_USAGE
+ CK_BBOOL true_false;
+#endif
+
+ cls = CKO_PRIVATE_KEY;
+ attrs[nattrs].type = CKA_CLASS;
+ attrs[nattrs].pValue = &cls;
+ attrs[nattrs].ulValueLen = sizeof cls;
+ nattrs++;
+
+#ifdef PKINIT_USE_KEY_USAGE
+ /*
+ * Some cards get confused if you try to specify a key usage,
+ * so don't, and hope for the best. This will fail if you have
+ * several keys with the same id and different usages but I have
+ * not seen this on real cards.
+ */
+ true_false = TRUE;
+ attrs[nattrs].type = usage;
+ attrs[nattrs].pValue = &true_false;
+ attrs[nattrs].ulValueLen = sizeof true_false;
+ nattrs++;
+#endif
+
+ keytype = CKK_RSA;
+ attrs[nattrs].type = CKA_KEY_TYPE;
+ attrs[nattrs].pValue = &keytype;
+ attrs[nattrs].ulValueLen = sizeof keytype;
+ nattrs++;
+
+ attrs[nattrs].type = CKA_ID;
+ attrs[nattrs].pValue = id_cryptoctx->cert_id;
+ attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len;
+ nattrs++;
+
+ r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
+ if (r != CKR_OK) {
+ pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
+ pkinit_pkcs11_code_to_text(r));
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
+ id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
+ pkiDebug("found %d private keys (%s)\n", (int) count, pkinit_pkcs11_code_to_text(r));
+
+ /*
+ * Solaris Kerberos:
+ * The CKA_ID may not be correctly set for the private key. For e.g. when
+ * storing a private key in softtoken pktool(1) doesn't generate or store
+ * a CKA_ID for the private key. Another way to identify the private key is
+ * to look for a private key with the same RSA modulus as the public key
+ * in the certificate.
+ */
+ if (r == CKR_OK && count != 1) {
+
+ EVP_PKEY *priv;
+ X509 *cert;
+ unsigned int n_len;
+ unsigned char *n_bytes;
+
+ cert = sk_X509_value(id_cryptoctx->my_certs, 0);
+ priv = X509_get_pubkey(cert);
+ if (priv == NULL) {
+ pkiDebug("Failed to extract pub key from cert\n");
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ nattrs = 0;
+ cls = CKO_PRIVATE_KEY;
+ attrs[nattrs].type = CKA_CLASS;
+ attrs[nattrs].pValue = &cls;
+ attrs[nattrs].ulValueLen = sizeof cls;
+ nattrs++;
+
+#ifdef PKINIT_USE_KEY_USAGE
+ true_false = TRUE;
+ attrs[nattrs].type = usage;
+ attrs[nattrs].pValue = &true_false;
+ attrs[nattrs].ulValueLen = sizeof true_false;
+ nattrs++;
+#endif
+
+ keytype = CKK_RSA;
+ attrs[nattrs].type = CKA_KEY_TYPE;
+ attrs[nattrs].pValue = &keytype;
+ attrs[nattrs].ulValueLen = sizeof keytype;
+ nattrs++;
+
+ n_len = BN_num_bytes(priv->pkey.rsa->n);
+ n_bytes = (unsigned char *) malloc((size_t) n_len);
+ if (n_bytes == NULL) {
+ return (ENOMEM);
+ }
+
+ if (BN_bn2bin(priv->pkey.rsa->n, n_bytes) == 0) {
+ free (n_bytes);
+ pkiDebug("zero-byte key modulus\n");
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ attrs[nattrs].type = CKA_MODULUS;
+ attrs[nattrs].ulValueLen = n_len;
+ attrs[nattrs].pValue = n_bytes;
+
+ nattrs++;
+
+ r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
+ free (n_bytes);
+ if (r != CKR_OK) {
+ pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
+ pkinit_pkcs11_code_to_text(r));
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
+ id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
+ pkiDebug("found %d private keys (%s)\n", (int) count, pkinit_pkcs11_code_to_text(r));
+
+ }
+
+ if (r != CKR_OK || count < 1)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ return 0;
+}
+#endif
+
+/* ARGSUSED */
+static krb5_error_code
+pkinit_decode_data_fs(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *data,
+ unsigned int data_len,
+ unsigned char **decoded_data,
+ unsigned int *decoded_data_len)
+{
+ if (decode_data(decoded_data, decoded_data_len, data, data_len,
+ id_cryptoctx->my_key, sk_X509_value(id_cryptoctx->my_certs,
+ id_cryptoctx->cert_index)) <= 0) {
+ pkiDebug("failed to decode data\n");
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+ return 0;
+}
+
+#ifndef WITHOUT_PKCS11
+#ifdef SILLYDECRYPT
+CK_RV
+pkinit_C_Decrypt(pkinit_identity_crypto_context id_cryptoctx,
+ CK_BYTE_PTR pEncryptedData,
+ CK_ULONG ulEncryptedDataLen,
+ CK_BYTE_PTR pData,
+ CK_ULONG_PTR pulDataLen)
+{
+ CK_RV rv = CKR_OK;
+
+ rv = id_cryptoctx->p11->C_Decrypt(id_cryptoctx->session, pEncryptedData,
+ ulEncryptedDataLen, pData, pulDataLen);
+ if (rv == CKR_OK) {
+ pkiDebug("pData %x *pulDataLen %d\n", (int) pData, (int) *pulDataLen);
+ }
+ return rv;
+}
+#endif
+
+static krb5_error_code
+pkinit_decode_data_pkcs11(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *data,
+ unsigned int data_len,
+ unsigned char **decoded_data,
+ unsigned int *decoded_data_len)
+{
+ CK_OBJECT_HANDLE obj;
+ CK_ULONG len;
+ CK_MECHANISM mech;
+ unsigned char *cp;
+ int r;
+
+ if (pkinit_open_session(context, id_cryptoctx)) {
+ pkiDebug("can't open pkcs11 session\n");
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ /* Solaris Kerberos */
+ r = pkinit_find_private_key(id_cryptoctx, CKA_DECRYPT, &obj);
+ if (r != 0)
+ return r;
+
+ mech.mechanism = CKM_RSA_PKCS;
+ mech.pParameter = NULL;
+ mech.ulParameterLen = 0;
+
+ if ((r = id_cryptoctx->p11->C_DecryptInit(id_cryptoctx->session, &mech,
+ obj)) != CKR_OK) {
+ pkiDebug("C_DecryptInit: 0x%x\n", (int) r);
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+ pkiDebug("data_len = %d\n", data_len);
+ cp = (unsigned char *)malloc((size_t) data_len);
+ if (cp == NULL)
+ return ENOMEM;
+ len = data_len;
+#ifdef SILLYDECRYPT
+ pkiDebug("session %x edata %x edata_len %d data %x datalen @%x %d\n",
+ (int) id_cryptoctx->session, (int) data, (int) data_len, (int) cp,
+ (int) &len, (int) len);
+ if ((r = pkinit_C_Decrypt(id_cryptoctx, data, (CK_ULONG) data_len,
+ cp, &len)) != CKR_OK) {
+#else
+ if ((r = id_cryptoctx->p11->C_Decrypt(id_cryptoctx->session, data,
+ (CK_ULONG) data_len, cp, &len)) != CKR_OK) {
+#endif
+ pkiDebug("C_Decrypt: %s\n", pkinit_pkcs11_code_to_text(r));
+ if (r == CKR_BUFFER_TOO_SMALL)
+ pkiDebug("decrypt %d needs %d\n", (int) data_len, (int) len);
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+ pkiDebug("decrypt %d -> %d\n", (int) data_len, (int) len);
+ *decoded_data_len = len;
+ *decoded_data = cp;
+
+ return 0;
+}
+#endif
+
+krb5_error_code
+pkinit_decode_data(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *data,
+ unsigned int data_len,
+ unsigned char **decoded_data,
+ unsigned int *decoded_data_len)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+
+ if (id_cryptoctx->pkcs11_method != 1)
+ retval = pkinit_decode_data_fs(context, id_cryptoctx, data, data_len,
+ decoded_data, decoded_data_len);
+#ifndef WITHOUT_PKCS11
+ else
+ retval = pkinit_decode_data_pkcs11(context, id_cryptoctx, data,
+ data_len, decoded_data, decoded_data_len);
+#endif
+
+ return retval;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+pkinit_sign_data_fs(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *data,
+ unsigned int data_len,
+ unsigned char **sig,
+ unsigned int *sig_len)
+{
+ if (create_signature(sig, sig_len, data, data_len,
+ id_cryptoctx->my_key) != 0) {
+ pkiDebug("failed to create the signature\n");
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+ return 0;
+}
+
+#ifndef WITHOUT_PKCS11
+static krb5_error_code
+pkinit_sign_data_pkcs11(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *data,
+ unsigned int data_len,
+ unsigned char **sig,
+ unsigned int *sig_len)
+{
+ CK_OBJECT_HANDLE obj;
+ CK_ULONG len;
+ CK_MECHANISM mech;
+ unsigned char *cp;
+ int r;
+
+ if (pkinit_open_session(context, id_cryptoctx)) {
+ pkiDebug("can't open pkcs11 session\n");
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ /* Solaris Kerberos */
+ r = pkinit_find_private_key(id_cryptoctx, CKA_SIGN, &obj);
+ if (r != 0 )
+ return r;
+
+ mech.mechanism = id_cryptoctx->mech;
+ mech.pParameter = NULL;
+ mech.ulParameterLen = 0;
+
+ if ((r = id_cryptoctx->p11->C_SignInit(id_cryptoctx->session, &mech,
+ obj)) != CKR_OK) {
+ pkiDebug("C_SignInit: %s\n", pkinit_pkcs11_code_to_text(r));
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ /*
+ * Key len would give an upper bound on sig size, but there's no way to
+ * get that. So guess, and if it's too small, re-malloc.
+ */
+ len = PK_SIGLEN_GUESS;
+ cp = (unsigned char *)malloc((size_t) len);
+ if (cp == NULL)
+ return ENOMEM;
+
+ r = id_cryptoctx->p11->C_Sign(id_cryptoctx->session, data,
+ (CK_ULONG) data_len, cp, &len);
+ if (r == CKR_BUFFER_TOO_SMALL || (r == CKR_OK && len >= PK_SIGLEN_GUESS)) {
+ free(cp);
+ pkiDebug("C_Sign realloc %d\n", (int) len);
+ cp = (unsigned char *)malloc((size_t) len);
+ r = id_cryptoctx->p11->C_Sign(id_cryptoctx->session, data,
+ (CK_ULONG) data_len, cp, &len);
+ }
+ if (r != CKR_OK) {
+ pkiDebug("C_Sign: %s\n", pkinit_pkcs11_code_to_text(r));
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+ pkiDebug("sign %d -> %d\n", (int) data_len, (int) len);
+ *sig_len = len;
+ *sig = cp;
+
+ return 0;
+}
+#endif
+
+krb5_error_code
+pkinit_sign_data(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *data,
+ unsigned int data_len,
+ unsigned char **sig,
+ unsigned int *sig_len)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+
+ if (id_cryptoctx == NULL || id_cryptoctx->pkcs11_method != 1)
+ retval = pkinit_sign_data_fs(context, id_cryptoctx, data, data_len,
+ sig, sig_len);
+#ifndef WITHOUT_PKCS11
+ else
+ retval = pkinit_sign_data_pkcs11(context, id_cryptoctx, data, data_len,
+ sig, sig_len);
+#endif
+
+ return retval;
+}
+
+
+static krb5_error_code
+decode_data(unsigned char **out_data, unsigned int *out_data_len,
+ unsigned char *data, unsigned int data_len,
+ EVP_PKEY *pkey, X509 *cert)
+{
+ /* Solaris Kerberos */
+ int len;
+ unsigned char *buf = NULL;
+ int buf_len = 0;
+
+ /* Solaris Kerberos */
+ if (out_data == NULL || out_data_len == NULL)
+ return EINVAL;
+
+ if (cert && !X509_check_private_key(cert, pkey)) {
+ pkiDebug("private key does not match certificate\n");
+ /* Solaris Kerberos */
+ return EINVAL;
+ }
+
+ buf_len = EVP_PKEY_size(pkey);
+ buf = (unsigned char *)malloc((size_t) buf_len + 10);
+ if (buf == NULL)
+ return ENOMEM;
+
+ len = EVP_PKEY_decrypt(buf, data, (int)data_len, pkey);
+ if (len <= 0) {
+ pkiDebug("unable to decrypt received data (len=%d)\n", data_len);
+ /* Solaris Kerberos */
+ free(buf);
+ return KRB5KRB_ERR_GENERIC;
+ }
+ *out_data = buf;
+ *out_data_len = len;
+
+ return 0;
+}
+
+static krb5_error_code
+create_signature(unsigned char **sig, unsigned int *sig_len,
+ unsigned char *data, unsigned int data_len, EVP_PKEY *pkey)
+{
+ krb5_error_code retval = ENOMEM;
+ EVP_MD_CTX md_ctx;
+
+ if (pkey == NULL)
+ /* Solaris Kerberos */
+ return EINVAL;
+
+ EVP_VerifyInit(&md_ctx, EVP_sha1());
+ EVP_SignUpdate(&md_ctx, data, data_len);
+ *sig_len = EVP_PKEY_size(pkey);
+ if ((*sig = (unsigned char *) malloc((size_t) *sig_len)) == NULL)
+ goto cleanup;
+ EVP_SignFinal(&md_ctx, *sig, sig_len, pkey);
+
+ retval = 0;
+
+ cleanup:
+ EVP_MD_CTX_cleanup(&md_ctx);
+
+ return retval;
+}
+
+/*
+ * Note:
+ * This is not the routine the KDC uses to get its certificate.
+ * This routine is intended to be called by the client
+ * to obtain the KDC's certificate from some local storage
+ * to be sent as a hint in its request to the KDC.
+ */
+/* ARGSUSED */
+krb5_error_code
+pkinit_get_kdc_cert(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_principal princ)
+{
+ /* Solaris Kerberos */
+ if (req_cryptoctx == NULL)
+ return EINVAL;
+
+ req_cryptoctx->received_cert = NULL;
+ return 0;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+pkinit_get_certs_pkcs12(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_opts *idopts,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_principal princ)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ X509 *x = NULL;
+ PKCS12 *p12 = NULL;
+ int ret;
+ FILE *fp;
+ EVP_PKEY *y = NULL;
+
+ if (idopts->cert_filename == NULL) {
+ /* Solaris Kerberos: Improved error messages */
+ krb5_set_error_message(context, retval,
+ gettext("failed to get certificate location"));
+ pkiDebug("%s: failed to get user's cert location\n", __FUNCTION__);
+ goto cleanup;
+ }
+
+ if (idopts->key_filename == NULL) {
+ /* Solaris Kerberos: Improved error messages */
+ krb5_set_error_message(context, retval,
+ gettext("failed to get private key location"));
+ pkiDebug("%s: failed to get user's private key location\n", __FUNCTION__);
+ goto cleanup;
+ }
+
+ fp = fopen(idopts->cert_filename, "rb");
+ if (fp == NULL) {
+ /* Solaris Kerberos: Improved error messages */
+ krb5_set_error_message(context, retval,
+ gettext("failed to open PKCS12 file '%s': %s"),
+ idopts->cert_filename, error_message(errno));
+ pkiDebug("Failed to open PKCS12 file '%s', error %d\n",
+ idopts->cert_filename, errno);
+ goto cleanup;
+ }
+
+ p12 = d2i_PKCS12_fp(fp, NULL);
+ (void) fclose(fp);
+ if (p12 == NULL) {
+ krb5_set_error_message(context, retval,
+ gettext("failed to decode PKCS12 file '%s' contents"),
+ idopts->cert_filename);
+ pkiDebug("Failed to decode PKCS12 file '%s' contents\n",
+ idopts->cert_filename);
+ goto cleanup;
+ }
+ /*
+ * Try parsing with no pass phrase first. If that fails,
+ * prompt for the pass phrase and try again.
+ */
+ ret = PKCS12_parse(p12, NULL, &y, &x, NULL);
+ if (ret == 0) {
+ krb5_data rdat;
+ krb5_prompt kprompt;
+ krb5_prompt_type prompt_type;
+ int r = 0;
+ char prompt_string[128];
+ char prompt_reply[128];
+ /* Solaris Kerberos */
+ char *prompt_prefix = gettext("Pass phrase for");
+
+ pkiDebug("Initial PKCS12_parse with no password failed\n");
+
+ (void) memset(prompt_reply, '\0', sizeof(prompt_reply));
+ rdat.data = prompt_reply;
+ rdat.length = sizeof(prompt_reply);
+
+ r = snprintf(prompt_string, sizeof(prompt_string), "%s %s",
+ prompt_prefix, idopts->cert_filename);
+ if (r >= sizeof(prompt_string)) {
+ pkiDebug("Prompt string, '%s %s', is too long!\n",
+ prompt_prefix, idopts->cert_filename);
+ goto cleanup;
+ }
+ kprompt.prompt = prompt_string;
+ kprompt.hidden = 1;
+ kprompt.reply = &rdat;
+ prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
+
+ /* PROMPTER_INVOCATION */
+ k5int_set_prompt_types(context, &prompt_type);
+ r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
+ NULL, NULL, 1, &kprompt);
+ k5int_set_prompt_types(context, 0);
+
+ ret = PKCS12_parse(p12, rdat.data, &y, &x, NULL);
+ if (ret == 0) {
+ /* Solaris Kerberos: Improved error messages */
+ krb5_set_error_message(context, retval,
+ gettext("failed to parse PKCS12 file '%s' with password"),
+ idopts->cert_filename);
+ pkiDebug("Seconde PKCS12_parse with password failed\n");
+ goto cleanup;
+ }
+ }
+ id_cryptoctx->creds[0] = malloc(sizeof(struct _pkinit_cred_info));
+ if (id_cryptoctx->creds[0] == NULL)
+ goto cleanup;
+ id_cryptoctx->creds[0]->cert = x;
+#ifndef WITHOUT_PKCS11
+ id_cryptoctx->creds[0]->cert_id = NULL;
+ id_cryptoctx->creds[0]->cert_id_len = 0;
+#endif
+ id_cryptoctx->creds[0]->key = y;
+ id_cryptoctx->creds[1] = NULL;
+
+ retval = 0;
+
+cleanup:
+ if (p12)
+ PKCS12_free(p12);
+ if (retval) {
+ if (x != NULL)
+ X509_free(x);
+ if (y != NULL)
+ EVP_PKEY_free(y);
+ }
+ return retval;
+}
+
+static krb5_error_code
+pkinit_load_fs_cert_and_key(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
+ char *certname,
+ char *keyname,
+ int cindex)
+{
+ krb5_error_code retval;
+ X509 *x = NULL;
+ EVP_PKEY *y = NULL;
+
+ /* load the certificate */
+ retval = get_cert(certname, &x);
+ if (retval != 0 || x == NULL) {
+ /* Solaris Kerberos: Improved error messages */
+ krb5_set_error_message(context, retval,
+ gettext("failed to load user's certificate from %s: %s"),
+ certname, error_message(retval));
+ pkiDebug("failed to load user's certificate from '%s'\n", certname);
+ goto cleanup;
+ }
+ retval = get_key(keyname, &y);
+ if (retval != 0 || y == NULL) {
+ /* Solaris Kerberos: Improved error messages */
+ krb5_set_error_message(context, retval,
+ gettext("failed to load user's private key from %s: %s"),
+ keyname, error_message(retval));
+ pkiDebug("failed to load user's private key from '%s'\n", keyname);
+ goto cleanup;
+ }
+
+ id_cryptoctx->creds[cindex] = malloc(sizeof(struct _pkinit_cred_info));
+ if (id_cryptoctx->creds[cindex] == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ id_cryptoctx->creds[cindex]->cert = x;
+#ifndef WITHOUT_PKCS11
+ id_cryptoctx->creds[cindex]->cert_id = NULL;
+ id_cryptoctx->creds[cindex]->cert_id_len = 0;
+#endif
+ id_cryptoctx->creds[cindex]->key = y;
+ id_cryptoctx->creds[cindex+1] = NULL;
+
+ retval = 0;
+
+cleanup:
+ if (retval) {
+ if (x != NULL)
+ X509_free(x);
+ if (y != NULL)
+ EVP_PKEY_free(y);
+ }
+ return retval;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+pkinit_get_certs_fs(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_opts *idopts,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_principal princ)
+{
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+
+ if (idopts->cert_filename == NULL) {
+ pkiDebug("%s: failed to get user's cert location\n", __FUNCTION__);
+ goto cleanup;
+ }
+
+ if (idopts->key_filename == NULL) {
+ pkiDebug("%s: failed to get user's private key location\n",
+ __FUNCTION__);
+ goto cleanup;
+ }
+
+ retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx,
+ idopts->cert_filename,
+ idopts->key_filename, 0);
+cleanup:
+ return retval;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+pkinit_get_certs_dir(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_opts *idopts,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_principal princ)
+{
+ /* Solaris Kerberos */
+ krb5_error_code retval = KRB5KRB_ERR_GENERIC;
+ DIR *d = NULL;
+ struct dirent *dentry = NULL;
+ char certname[1024];
+ char keyname[1024];
+ int i = 0, len;
+ char *dirname, *suf;
+
+ /* Solaris Kerberos */
+ if (idopts == NULL)
+ return EINVAL;
+
+ if (idopts->cert_filename == NULL) {
+ pkiDebug("%s: failed to get user's certificate directory location\n",
+ __FUNCTION__);
+ return ENOENT;
+ }
+
+ dirname = idopts->cert_filename;
+ d = opendir(dirname);
+ if (d == NULL) {
+ /* Solaris Kerberos: Improved error messages */
+ krb5_set_error_message(context, errno,
+ gettext("failed to open directory \"%s\": %s"),
+ dirname, error_message(errno));
+ return errno;
+ }
+
+ /*
+ * We'll assume that certs are named XXX.crt and the corresponding
+ * key is named XXX.key
+ */
+ while ((i < MAX_CREDS_ALLOWED) && (dentry = readdir(d)) != NULL) {
+ /* Ignore subdirectories and anything starting with a dot */
+#ifdef DT_DIR
+ if (dentry->d_type == DT_DIR)
+ continue;
+#endif
+ if (dentry->d_name[0] == '.')
+ continue;
+ len = strlen(dentry->d_name);
+ if (len < 5)
+ continue;
+ suf = dentry->d_name + (len - 4);
+ if (strncmp(suf, ".crt", 4) != 0)
+ continue;
+
+ /* Checked length */
+ if (strlen(dirname) + strlen(dentry->d_name) + 2 > sizeof(certname)) {
+ pkiDebug("%s: Path too long -- directory '%s' and file '%s'\n",
+ __FUNCTION__, dirname, dentry->d_name);
+ continue;
+ }
+ (void) snprintf(certname, sizeof(certname), "%s/%s", dirname, dentry->d_name);
+ (void) snprintf(keyname, sizeof(keyname), "%s/%s", dirname, dentry->d_name);
+ len = strlen(keyname);
+ keyname[len - 3] = 'k';
+ keyname[len - 2] = 'e';
+ keyname[len - 1] = 'y';
+
+ retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx,
+ certname, keyname, i);
+ if (retval == 0) {
+ pkiDebug("%s: Successfully loaded cert (and key) for %s\n",
+ __FUNCTION__, dentry->d_name);
+ i++;
+ }
+ else
+ continue;
+ }
+
+ if (i == 0) {
+ /* Solaris Kerberos: Improved error messages */
+ krb5_set_error_message(context, ENOENT,
+ gettext("No suitable cert/key pairs found in directory '%s'"),
+ idopts->cert_filename);
+ pkiDebug("%s: No cert/key pairs found in directory '%s'\n",
+ __FUNCTION__, idopts->cert_filename);
+ retval = ENOENT;
+ goto cleanup;
+ }
+
+ retval = 0;
+
+ cleanup:
+ if (d)
+ (void) closedir(d);
+
+ return retval;
+}
+
+#ifndef WITHOUT_PKCS11
+/* ARGSUSED */
+static krb5_error_code
+pkinit_get_certs_pkcs11(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_opts *idopts,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_principal princ)
+{
+#ifdef PKINIT_USE_MECH_LIST
+ CK_MECHANISM_TYPE_PTR mechp;
+ CK_MECHANISM_INFO info;
+#endif
+ CK_OBJECT_CLASS cls;
+ CK_OBJECT_HANDLE obj;
+ CK_ATTRIBUTE attrs[4];
+ CK_ULONG count;
+ CK_CERTIFICATE_TYPE certtype;
+ CK_BYTE_PTR cert = NULL, cert_id;
+ const unsigned char *cp;
+ int i, r;
+ unsigned int nattrs;
+ X509 *x = NULL;
+
+ /* Copy stuff from idopts -> id_cryptoctx */
+ if (idopts->p11_module_name != NULL) {
+ id_cryptoctx->p11_module_name = strdup(idopts->p11_module_name);
+ if (id_cryptoctx->p11_module_name == NULL)
+ return ENOMEM;
+ }
+ if (idopts->token_label != NULL) {
+ id_cryptoctx->token_label = strdup(idopts->token_label);
+ if (id_cryptoctx->token_label == NULL)
+ return ENOMEM;
+ }
+ if (idopts->cert_label != NULL) {
+ id_cryptoctx->cert_label = strdup(idopts->cert_label);
+ if (id_cryptoctx->cert_label == NULL)
+ return ENOMEM;
+ }
+ /* Convert the ascii cert_id string into a binary blob */
+ /*
+ * Solaris Kerberos:
+ * If the cert_id_string is empty then behave in a similar way to how
+ * an empty certlabel is treated - i.e. don't fail now but rather continue
+ * as though the certid wasn't specified.
+ */
+ if (idopts->cert_id_string != NULL && strlen(idopts->cert_id_string) != 0) {
+ BIGNUM *bn = NULL;
+ BN_hex2bn(&bn, idopts->cert_id_string);
+ if (bn == NULL)
+ return ENOMEM;
+ id_cryptoctx->cert_id_len = BN_num_bytes(bn);
+ id_cryptoctx->cert_id = malloc((size_t) id_cryptoctx->cert_id_len);
+ if (id_cryptoctx->cert_id == NULL) {
+ BN_free(bn);
+ return ENOMEM;
+ }
+ BN_bn2bin(bn, id_cryptoctx->cert_id);
+ BN_free(bn);
+ }
+ id_cryptoctx->slotid = idopts->slotid;
+ id_cryptoctx->pkcs11_method = 1;
+
+
+
+ if (pkinit_open_session(context, id_cryptoctx)) {
+ pkiDebug("can't open pkcs11 session\n");
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+#ifndef PKINIT_USE_MECH_LIST
+ /*
+ * We'd like to use CKM_SHA1_RSA_PKCS for signing if it's available, but
+ * many cards seems to be confused about whether they are capable of
+ * this or not. The safe thing seems to be to ignore the mechanism list,
+ * always use CKM_RSA_PKCS and calculate the sha1 digest ourselves.
+ */
+
+ id_cryptoctx->mech = CKM_RSA_PKCS;
+#else
+ if ((r = id_cryptoctx->p11->C_GetMechanismList(id_cryptoctx->slotid, NULL,
+ &count)) != CKR_OK || count <= 0) {
+ pkiDebug("C_GetMechanismList: %s\n", pkinit_pkcs11_code_to_text(r));
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+ mechp = (CK_MECHANISM_TYPE_PTR) malloc(count * sizeof (CK_MECHANISM_TYPE));
+ if (mechp == NULL)
+ return ENOMEM;
+ if ((r = id_cryptoctx->p11->C_GetMechanismList(id_cryptoctx->slotid,
+ mechp, &count)) != CKR_OK)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ for (i = 0; i < count; i++) {
+ if ((r = id_cryptoctx->p11->C_GetMechanismInfo(id_cryptoctx->slotid,
+ mechp[i], &info)) != CKR_OK)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+#ifdef DEBUG_MECHINFO
+ pkiDebug("mech %x flags %x\n", (int) mechp[i], (int) info.flags);
+ if ((info.flags & (CKF_SIGN|CKF_DECRYPT)) == (CKF_SIGN|CKF_DECRYPT))
+ pkiDebug(" this mech is good for sign & decrypt\n");
+#endif
+ if (mechp[i] == CKM_RSA_PKCS) {
+ /* This seems backwards... */
+ id_cryptoctx->mech =
+ (info.flags & CKF_SIGN) ? CKM_SHA1_RSA_PKCS : CKM_RSA_PKCS;
+ }
+ }
+ free(mechp);
+
+ pkiDebug("got %d mechs from card\n", (int) count);
+#endif
+
+ cls = CKO_CERTIFICATE;
+ attrs[0].type = CKA_CLASS;
+ attrs[0].pValue = &cls;
+ attrs[0].ulValueLen = sizeof cls;
+
+ certtype = CKC_X_509;
+ attrs[1].type = CKA_CERTIFICATE_TYPE;
+ attrs[1].pValue = &certtype;
+ attrs[1].ulValueLen = sizeof certtype;
+
+ nattrs = 2;
+
+ /* If a cert id and/or label were given, use them too */
+ if (id_cryptoctx->cert_id_len > 0) {
+ attrs[nattrs].type = CKA_ID;
+ attrs[nattrs].pValue = id_cryptoctx->cert_id;
+ attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len;
+ nattrs++;
+ }
+ if (id_cryptoctx->cert_label != NULL) {
+ attrs[nattrs].type = CKA_LABEL;
+ attrs[nattrs].pValue = id_cryptoctx->cert_label;
+ attrs[nattrs].ulValueLen = strlen(id_cryptoctx->cert_label);
+ nattrs++;
+ }
+
+ r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
+ if (r != CKR_OK) {
+ pkiDebug("C_FindObjectsInit: %s\n", pkinit_pkcs11_code_to_text(r));
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ for (i = 0; ; i++) {
+ if (i >= MAX_CREDS_ALLOWED)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+
+ /* Look for x.509 cert */
+ /* Solaris Kerberos */
+ if ((r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session,
+ &obj, 1, &count)) != CKR_OK || count == 0) {
+ id_cryptoctx->creds[i] = NULL;
+ break;
+ }
+
+ /* Get cert and id len */
+ attrs[0].type = CKA_VALUE;
+ attrs[0].pValue = NULL;
+ attrs[0].ulValueLen = 0;
+
+ attrs[1].type = CKA_ID;
+ attrs[1].pValue = NULL;
+ attrs[1].ulValueLen = 0;
+
+ if ((r = id_cryptoctx->p11->C_GetAttributeValue(id_cryptoctx->session,
+ obj, attrs, 2)) != CKR_OK && r != CKR_BUFFER_TOO_SMALL) {
+ pkiDebug("C_GetAttributeValue: %s\n", pkinit_pkcs11_code_to_text(r));
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+ cert = (CK_BYTE_PTR) malloc((size_t) attrs[0].ulValueLen + 1);
+ cert_id = (CK_BYTE_PTR) malloc((size_t) attrs[1].ulValueLen + 1);
+ if (cert == NULL || cert_id == NULL)
+ return ENOMEM;
+
+ /* Read the cert and id off the card */
+
+ attrs[0].type = CKA_VALUE;
+ attrs[0].pValue = cert;
+
+ attrs[1].type = CKA_ID;
+ attrs[1].pValue = cert_id;
+
+ if ((r = id_cryptoctx->p11->C_GetAttributeValue(id_cryptoctx->session,
+ obj, attrs, 2)) != CKR_OK) {
+ pkiDebug("C_GetAttributeValue: %s\n", pkinit_pkcs11_code_to_text(r));
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+
+ pkiDebug("cert %d size %d id %d idlen %d\n", i,
+ (int) attrs[0].ulValueLen, (int) cert_id[0],
+ (int) attrs[1].ulValueLen);
+
+ cp = (unsigned char *) cert;
+ x = d2i_X509(NULL, &cp, (int) attrs[0].ulValueLen);
+ if (x == NULL)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ id_cryptoctx->creds[i] = malloc(sizeof(struct _pkinit_cred_info));
+ if (id_cryptoctx->creds[i] == NULL)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ id_cryptoctx->creds[i]->cert = x;
+ id_cryptoctx->creds[i]->key = NULL;
+ id_cryptoctx->creds[i]->cert_id = cert_id;
+ id_cryptoctx->creds[i]->cert_id_len = attrs[1].ulValueLen;
+ free(cert);
+ }
+ id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
+ /* Solaris Kerberos: Improved error messages */
+ if (cert == NULL) {
+ if (r != CKR_OK) {
+ krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
+ gettext("pkcs11 error while searching for certificates: %s"),
+ pkinit_pkcs11_code_to_text(r));
+ } else {
+ BIGNUM *cid = BN_bin2bn(id_cryptoctx->cert_id,
+ id_cryptoctx->cert_id_len, NULL);
+ char *cidstr = BN_bn2hex(cid);
+ char *printstr = id_cryptoctx->cert_id_len ? cidstr : "<none>";
+
+ krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
+ gettext("failed to find any suitable certificates "
+ "(certlabel: %s, certid: %s)"),
+ id_cryptoctx->cert_label ? id_cryptoctx->cert_label : "<none>",
+ cidstr ? printstr : "<unknown>");
+
+ if (cidstr != NULL)
+ OPENSSL_free(cidstr);
+ BN_free(cid);
+ }
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
+ return 0;
+}
+#endif
+
+/* ARGSUSED */
+static void
+free_cred_info(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
+ struct _pkinit_cred_info *cred)
+{
+ if (cred != NULL) {
+ if (cred->cert != NULL)
+ X509_free(cred->cert);
+ if (cred->key != NULL)
+ EVP_PKEY_free(cred->key);
+#ifndef WITHOUT_PKCS11
+ if (cred->cert_id != NULL)
+ free(cred->cert_id);
+#endif
+ free(cred);
+ }
+}
+
+/* ARGSUSED */
+krb5_error_code
+crypto_free_cert_info(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx)
+{
+ int i;
+
+ if (id_cryptoctx == NULL)
+ return EINVAL;
+
+ for (i = 0; i < MAX_CREDS_ALLOWED; i++) {
+ if (id_cryptoctx->creds[i] != NULL) {
+ free_cred_info(context, id_cryptoctx, id_cryptoctx->creds[i]);
+ id_cryptoctx->creds[i] = NULL;
+ }
+ }
+ return 0;
+}
+
+krb5_error_code
+crypto_load_certs(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_opts *idopts,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_principal princ)
+{
+ krb5_error_code retval;
+
+ switch(idopts->idtype) {
+ case IDTYPE_FILE:
+ retval = pkinit_get_certs_fs(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx, princ);
+ break;
+ case IDTYPE_DIR:
+ retval = pkinit_get_certs_dir(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx, princ);
+ break;
+#ifndef WITHOUT_PKCS11
+ case IDTYPE_PKCS11:
+ retval = pkinit_get_certs_pkcs11(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx, princ);
+ break;
+#endif
+ case IDTYPE_PKCS12:
+ retval = pkinit_get_certs_pkcs12(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx, princ);
+ break;
+ default:
+ retval = EINVAL;
+ }
+/* Solaris Kerberos */
+
+ return retval;
+}
+
+/*
+ * Get number of certificates available after crypto_load_certs()
+ */
+/* ARGSUSED */
+krb5_error_code
+crypto_cert_get_count(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ int *cert_count)
+{
+ int count;
+
+ if (id_cryptoctx == NULL || id_cryptoctx->creds[0] == NULL)
+ return EINVAL;
+
+ for (count = 0;
+ count <= MAX_CREDS_ALLOWED && id_cryptoctx->creds[count] != NULL;
+ count++);
+ *cert_count = count;
+ return 0;
+}
+
+
+/*
+ * Begin iteration over the certs loaded in crypto_load_certs()
+ */
+/* ARGSUSED */
+krb5_error_code
+crypto_cert_iteration_begin(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ pkinit_cert_iter_handle *ih_ret)
+{
+ struct _pkinit_cert_iter_data *id;
+
+ if (id_cryptoctx == NULL || ih_ret == NULL)
+ return EINVAL;
+ if (id_cryptoctx->creds[0] == NULL) /* No cred info available */
+ return ENOENT;
+
+ id = calloc(1, sizeof(*id));
+ if (id == NULL)
+ return ENOMEM;
+ id->magic = ITER_MAGIC;
+ id->plgctx = plg_cryptoctx,
+ id->reqctx = req_cryptoctx,
+ id->idctx = id_cryptoctx;
+ id->index = 0;
+ *ih_ret = (pkinit_cert_iter_handle) id;
+ return 0;
+}
+
+/*
+ * End iteration over the certs loaded in crypto_load_certs()
+ */
+/* ARGSUSED */
+krb5_error_code
+crypto_cert_iteration_end(krb5_context context,
+ pkinit_cert_iter_handle ih)
+{
+ struct _pkinit_cert_iter_data *id = (struct _pkinit_cert_iter_data *)ih;
+
+ if (id == NULL || id->magic != ITER_MAGIC)
+ return EINVAL;
+ free(ih);
+ return 0;
+}
+
+/*
+ * Get next certificate handle
+ */
+/* ARGSUSED */
+krb5_error_code
+crypto_cert_iteration_next(krb5_context context,
+ pkinit_cert_iter_handle ih,
+ pkinit_cert_handle *ch_ret)
+{
+ struct _pkinit_cert_iter_data *id = (struct _pkinit_cert_iter_data *)ih;
+ struct _pkinit_cert_data *cd;
+ pkinit_identity_crypto_context id_cryptoctx;
+
+ if (id == NULL || id->magic != ITER_MAGIC)
+ return EINVAL;
+
+ if (ch_ret == NULL)
+ return EINVAL;
+
+ id_cryptoctx = id->idctx;
+ if (id_cryptoctx == NULL)
+ return EINVAL;
+
+ if (id_cryptoctx->creds[id->index] == NULL)
+ return PKINIT_ITER_NO_MORE;
+
+ cd = calloc(1, sizeof(*cd));
+ if (cd == NULL)
+ return ENOMEM;
+
+ cd->magic = CERT_MAGIC;
+ cd->plgctx = id->plgctx;
+ cd->reqctx = id->reqctx;
+ cd->idctx = id->idctx;
+ cd->index = id->index;
+ cd->cred = id_cryptoctx->creds[id->index++];
+ *ch_ret = (pkinit_cert_handle)cd;
+ return 0;
+}
+
+/*
+ * Release cert handle
+ */
+/* ARGSUSED */
+krb5_error_code
+crypto_cert_release(krb5_context context,
+ pkinit_cert_handle ch)
+{
+ struct _pkinit_cert_data *cd = (struct _pkinit_cert_data *)ch;
+ if (cd == NULL || cd->magic != CERT_MAGIC)
+ return EINVAL;
+ free(cd);
+ return 0;
+}
+
+/*
+ * Get certificate Key Usage and Extended Key Usage
+ */
+/* ARGSUSED */
+static krb5_error_code
+crypto_retieve_X509_key_usage(krb5_context context,
+ pkinit_plg_crypto_context plgcctx,
+ pkinit_req_crypto_context reqcctx,
+ X509 *x,
+ unsigned int *ret_ku_bits,
+ unsigned int *ret_eku_bits)
+{
+ /* Solaris Kerberos */
+ int i;
+ unsigned int eku_bits = 0, ku_bits = 0;
+ ASN1_BIT_STRING *usage = NULL;
+
+ if (ret_ku_bits == NULL && ret_eku_bits == NULL)
+ return EINVAL;
+
+ if (ret_eku_bits)
+ *ret_eku_bits = 0;
+ else {
+ pkiDebug("%s: EKUs not requested, not checking\n", __FUNCTION__);
+ goto check_kus;
+ }
+
+ /* Start with Extended Key usage */
+ i = X509_get_ext_by_NID(x, NID_ext_key_usage, -1);
+ if (i >= 0) {
+ EXTENDED_KEY_USAGE *eku;
+
+ eku = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL);
+ if (eku) {
+ for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
+ ASN1_OBJECT *certoid;
+ certoid = sk_ASN1_OBJECT_value(eku, i);
+ if ((OBJ_cmp(certoid, plgcctx->id_pkinit_KPClientAuth)) == 0)
+ eku_bits |= PKINIT_EKU_PKINIT;
+ else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_ms_smartcard_login))) == 0)
+ eku_bits |= PKINIT_EKU_MSSCLOGIN;
+ else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_client_auth))) == 0)
+ eku_bits |= PKINIT_EKU_CLIENTAUTH;
+ else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_email_protect))) == 0)
+ eku_bits |= PKINIT_EKU_EMAILPROTECTION;
+ }
+ EXTENDED_KEY_USAGE_free(eku);
+ }
+ }
+ pkiDebug("%s: returning eku 0x%08x\n", __FUNCTION__, eku_bits);
+ *ret_eku_bits = eku_bits;
+
+check_kus:
+ /* Now the Key Usage bits */
+ if (ret_ku_bits)
+ *ret_ku_bits = 0;
+ else {
+ pkiDebug("%s: KUs not requested, not checking\n", __FUNCTION__);
+ goto out;
+ }
+
+ /* Make sure usage exists before checking bits */
+ usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL);
+ if (usage) {
+ if (!ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE))
+ ku_bits |= PKINIT_KU_DIGITALSIGNATURE;
+ if (!ku_reject(x, X509v3_KU_KEY_ENCIPHERMENT))
+ ku_bits |= PKINIT_KU_KEYENCIPHERMENT;
+ ASN1_BIT_STRING_free(usage);
+ }
+
+ pkiDebug("%s: returning ku 0x%08x\n", __FUNCTION__, ku_bits);
+ *ret_ku_bits = ku_bits;
+
+out:
+ return 0;
+}
+
+/*
+ * Return a string format of an X509_NAME in buf where
+ * size is an in/out parameter. On input it is the size
+ * of the buffer, and on output it is the actual length
+ * of the name.
+ * If buf is NULL, returns the length req'd to hold name
+ */
+static char *
+X509_NAME_oneline_ex(X509_NAME * a,
+ char *buf,
+ unsigned int *size,
+ unsigned long flag)
+{
+ BIO *out = NULL;
+
+ out = BIO_new(BIO_s_mem ());
+ if (X509_NAME_print_ex(out, a, 0, flag) > 0) {
+ if (buf != NULL && *size > (int) BIO_number_written(out)) {
+ (void) memset(buf, 0, *size);
+ BIO_read(out, buf, (int) BIO_number_written(out));
+ }
+ else {
+ *size = BIO_number_written(out);
+ }
+ }
+ BIO_free(out);
+ return (buf);
+}
+
+/*
+ * Get certificate information
+ */
+krb5_error_code
+crypto_cert_get_matching_data(krb5_context context,
+ pkinit_cert_handle ch,
+ pkinit_cert_matching_data **ret_md)
+{
+ krb5_error_code retval;
+ pkinit_cert_matching_data *md;
+ krb5_principal *pkinit_sans =NULL, *upn_sans = NULL;
+ struct _pkinit_cert_data *cd = (struct _pkinit_cert_data *)ch;
+ int i, j;
+ char buf[DN_BUF_LEN];
+ unsigned int bufsize = sizeof(buf);
+
+ if (cd == NULL || cd->magic != CERT_MAGIC)
+ return EINVAL;
+ if (ret_md == NULL)
+ return EINVAL;
+
+ md = calloc(1, sizeof(*md));
+ if (md == NULL)
+ return ENOMEM;
+
+ md->ch = ch;
+
+ /* get the subject name (in rfc2253 format) */
+ X509_NAME_oneline_ex(X509_get_subject_name(cd->cred->cert),
+ buf, &bufsize, XN_FLAG_SEP_COMMA_PLUS);
+ md->subject_dn = strdup(buf);
+ if (md->subject_dn == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+
+ /* get the issuer name (in rfc2253 format) */
+ X509_NAME_oneline_ex(X509_get_issuer_name(cd->cred->cert),
+ buf, &bufsize, XN_FLAG_SEP_COMMA_PLUS);
+ md->issuer_dn = strdup(buf);
+ if (md->issuer_dn == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+
+ /* get the san data */
+ retval = crypto_retrieve_X509_sans(context, cd->plgctx, cd->reqctx,
+ cd->cred->cert, &pkinit_sans,
+ &upn_sans, NULL);
+ if (retval)
+ goto cleanup;
+
+ j = 0;
+ if (pkinit_sans != NULL) {
+ for (i = 0; pkinit_sans[i] != NULL; i++)
+ j++;
+ }
+ if (upn_sans != NULL) {
+ for (i = 0; upn_sans[i] != NULL; i++)
+ j++;
+ }
+ if (j != 0) {
+ md->sans = calloc((size_t)j+1, sizeof(*md->sans));
+ if (md->sans == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ j = 0;
+ if (pkinit_sans != NULL) {
+ for (i = 0; pkinit_sans[i] != NULL; i++)
+ md->sans[j++] = pkinit_sans[i];
+ free(pkinit_sans);
+ }
+ if (upn_sans != NULL) {
+ for (i = 0; upn_sans[i] != NULL; i++)
+ md->sans[j++] = upn_sans[i];
+ free(upn_sans);
+ }
+ md->sans[j] = NULL;
+ } else
+ md->sans = NULL;
+
+ /* get the KU and EKU data */
+
+ retval = crypto_retieve_X509_key_usage(context, cd->plgctx, cd->reqctx,
+ cd->cred->cert,
+ &md->ku_bits, &md->eku_bits);
+ if (retval)
+ goto cleanup;
+
+ *ret_md = md;
+ retval = 0;
+cleanup:
+ if (retval) {
+ if (md)
+ crypto_cert_free_matching_data(context, md);
+ }
+ return retval;
+}
+
+/*
+ * Free certificate information
+ */
+krb5_error_code
+crypto_cert_free_matching_data(krb5_context context,
+ pkinit_cert_matching_data *md)
+{
+ krb5_principal p;
+ int i;
+
+ if (md == NULL)
+ return EINVAL;
+ if (md->subject_dn)
+ free(md->subject_dn);
+ if (md->issuer_dn)
+ free(md->issuer_dn);
+ if (md->sans) {
+ for (i = 0, p = md->sans[i]; p != NULL; p = md->sans[++i])
+ krb5_free_principal(context, p);
+ free(md->sans);
+ }
+ free(md);
+ return 0;
+}
+
+/*
+ * Make this matching certificate "the chosen one"
+ */
+/* ARGSUSED */
+krb5_error_code
+crypto_cert_select(krb5_context context,
+ pkinit_cert_matching_data *md)
+{
+ struct _pkinit_cert_data *cd;
+ if (md == NULL)
+ return EINVAL;
+
+ cd = (struct _pkinit_cert_data *)md->ch;
+ if (cd == NULL || cd->magic != CERT_MAGIC)
+ return EINVAL;
+
+ /* copy the selected cert into our id_cryptoctx */
+ if (cd->idctx->my_certs != NULL) {
+ sk_X509_pop_free(cd->idctx->my_certs, X509_free);
+ }
+ cd->idctx->my_certs = sk_X509_new_null();
+ sk_X509_push(cd->idctx->my_certs, cd->cred->cert);
+ cd->idctx->creds[cd->index]->cert = NULL; /* Don't free it twice */
+ cd->idctx->cert_index = 0;
+
+ if (cd->idctx->pkcs11_method != 1) {
+ cd->idctx->my_key = cd->cred->key;
+ cd->idctx->creds[cd->index]->key = NULL; /* Don't free it twice */
+ }
+#ifndef WITHOUT_PKCS11
+ else {
+ cd->idctx->cert_id = cd->cred->cert_id;
+ cd->idctx->creds[cd->index]->cert_id = NULL; /* Don't free it twice */
+ cd->idctx->cert_id_len = cd->cred->cert_id_len;
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Choose the default certificate as "the chosen one"
+ */
+krb5_error_code
+crypto_cert_select_default(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx)
+{
+ krb5_error_code retval;
+ int cert_count = 0;
+
+ retval = crypto_cert_get_count(context, plg_cryptoctx, req_cryptoctx,
+ id_cryptoctx, &cert_count);
+ if (retval) {
+ pkiDebug("%s: crypto_cert_get_count error %d, %s\n",
+ __FUNCTION__, retval, error_message(retval));
+ goto errout;
+ }
+ if (cert_count != 1) {
+ /* Solaris Kerberos: Improved error messages */
+ retval = EINVAL;
+ krb5_set_error_message(context, retval,
+ gettext("failed to select default certificate: "
+ "found %d certs to choose from but there must be exactly one"),
+ cert_count);
+ pkiDebug("%s: ERROR: There are %d certs to choose from, "
+ "but there must be exactly one.\n",
+ __FUNCTION__, cert_count);
+ goto errout;
+ }
+ /* copy the selected cert into our id_cryptoctx */
+ if (id_cryptoctx->my_certs != NULL) {
+ sk_X509_pop_free(id_cryptoctx->my_certs, X509_free);
+ }
+ id_cryptoctx->my_certs = sk_X509_new_null();
+ sk_X509_push(id_cryptoctx->my_certs, id_cryptoctx->creds[0]->cert);
+ id_cryptoctx->creds[0]->cert = NULL; /* Don't free it twice */
+ id_cryptoctx->cert_index = 0;
+
+ if (id_cryptoctx->pkcs11_method != 1) {
+ id_cryptoctx->my_key = id_cryptoctx->creds[0]->key;
+ id_cryptoctx->creds[0]->key = NULL; /* Don't free it twice */
+ }
+#ifndef WITHOUT_PKCS11
+ else {
+ id_cryptoctx->cert_id = id_cryptoctx->creds[0]->cert_id;
+ id_cryptoctx->creds[0]->cert_id = NULL; /* Don't free it twice */
+ id_cryptoctx->cert_id_len = id_cryptoctx->creds[0]->cert_id_len;
+ }
+#endif
+ retval = 0;
+errout:
+ return retval;
+}
+
+
+/* ARGSUSED */
+static krb5_error_code
+load_cas_and_crls(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ int catype,
+ char *filename)
+{
+ STACK_OF(X509_INFO) *sk = NULL;
+ STACK_OF(X509) *ca_certs = NULL;
+ STACK_OF(X509_CRL) *ca_crls = NULL;
+ BIO *in = NULL;
+ /* Solaris Kerberos */
+ krb5_error_code retval = KRB5KRB_ERR_GENERIC;
+ int i = 0;
+
+ /* If there isn't already a stack in the context,
+ * create a temporary one now */
+ switch(catype) {
+ case CATYPE_ANCHORS:
+ if (id_cryptoctx->trustedCAs != NULL)
+ ca_certs = id_cryptoctx->trustedCAs;
+ else {
+ ca_certs = sk_X509_new_null();
+ if (ca_certs == NULL)
+ return ENOMEM;
+ }
+ break;
+ case CATYPE_INTERMEDIATES:
+ if (id_cryptoctx->intermediateCAs != NULL)
+ ca_certs = id_cryptoctx->intermediateCAs;
+ else {
+ ca_certs = sk_X509_new_null();
+ if (ca_certs == NULL)
+ return ENOMEM;
+ }
+ break;
+ case CATYPE_CRLS:
+ if (id_cryptoctx->revoked != NULL)
+ ca_crls = id_cryptoctx->revoked;
+ else {
+ ca_crls = sk_X509_CRL_new_null();
+ if (ca_crls == NULL)
+ return ENOMEM;
+ }
+ break;
+ default:
+ return ENOTSUP;
+ }
+
+ if (!(in = BIO_new_file(filename, "r"))) {
+ retval = errno;
+ pkiDebug("%s: error opening file '%s': %s\n", __FUNCTION__,
+ filename, error_message(errno));
+ goto cleanup;
+ }
+
+ /* This loads from a file, a stack of x509/crl/pkey sets */
+ if ((sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL) {
+ pkiDebug("%s: error reading file '%s'\n", __FUNCTION__, filename);
+ retval = EIO;
+ goto cleanup;
+ }
+
+ /* scan over the stack created from loading the file contents,
+ * weed out duplicates, and push new ones onto the return stack
+ */
+ for (i = 0; i < sk_X509_INFO_num(sk); i++) {
+ X509_INFO *xi = sk_X509_INFO_value(sk, i);
+ if (xi != NULL && xi->x509 != NULL && catype != CATYPE_CRLS) {
+ int j = 0, size = sk_X509_num(ca_certs), flag = 0;
+
+ if (!size) {
+ sk_X509_push(ca_certs, xi->x509);
+ xi->x509 = NULL;
+ continue;
+ }
+ for (j = 0; j < size; j++) {
+ X509 *x = sk_X509_value(ca_certs, j);
+ flag = X509_cmp(x, xi->x509);
+ if (flag == 0)
+ break;
+ else
+ continue;
+ }
+ if (flag != 0) {
+ sk_X509_push(ca_certs, X509_dup(xi->x509));
+ }
+ } else if (xi != NULL && xi->crl != NULL && catype == CATYPE_CRLS) {
+ int j = 0, size = sk_X509_CRL_num(ca_crls), flag = 0;
+ if (!size) {
+ sk_X509_CRL_push(ca_crls, xi->crl);
+ xi->crl = NULL;
+ continue;
+ }
+ for (j = 0; j < size; j++) {
+ X509_CRL *x = sk_X509_CRL_value(ca_crls, j);
+ flag = X509_CRL_cmp(x, xi->crl);
+ if (flag == 0)
+ break;
+ else
+ continue;
+ }
+ if (flag != 0) {
+ sk_X509_push(ca_crls, X509_CRL_dup(xi->crl));
+ }
+ }
+ }
+
+ /* If we added something and there wasn't a stack in the
+ * context before, add the temporary stack to the context.
+ */
+ switch(catype) {
+ case CATYPE_ANCHORS:
+ if (sk_X509_num(ca_certs) == 0) {
+ pkiDebug("no anchors in file, %s\n", filename);
+ if (id_cryptoctx->trustedCAs == NULL)
+ sk_X509_free(ca_certs);
+ } else {
+ if (id_cryptoctx->trustedCAs == NULL)
+ id_cryptoctx->trustedCAs = ca_certs;
+ }
+ break;
+ case CATYPE_INTERMEDIATES:
+ if (sk_X509_num(ca_certs) == 0) {
+ pkiDebug("no intermediates in file, %s\n", filename);
+ if (id_cryptoctx->intermediateCAs == NULL)
+ sk_X509_free(ca_certs);
+ } else {
+ if (id_cryptoctx->intermediateCAs == NULL)
+ id_cryptoctx->intermediateCAs = ca_certs;
+ }
+ break;
+ case CATYPE_CRLS:
+ if (sk_X509_num(ca_crls) == 0) {
+ pkiDebug("no crls in file, %s\n", filename);
+ if (id_cryptoctx->revoked == NULL)
+ sk_X509_CRL_free(ca_crls);
+ } else {
+ if (id_cryptoctx->revoked == NULL)
+ id_cryptoctx->revoked = ca_crls;
+ }
+ break;
+ default:
+ /* Should have been caught above! */
+ retval = EINVAL;
+ goto cleanup;
+ /* Solaris Kerberos: removed "break" as it's never reached */
+ }
+
+ retval = 0;
+
+ cleanup:
+ if (in != NULL)
+ BIO_free(in);
+ if (sk != NULL)
+ sk_X509_INFO_pop_free(sk, X509_INFO_free);
+
+ return retval;
+}
+
+static krb5_error_code
+load_cas_and_crls_dir(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ int catype,
+ char *dirname)
+{
+ krb5_error_code retval = EINVAL;
+ DIR *d = NULL;
+ struct dirent *dentry = NULL;
+ char filename[1024];
+
+ if (dirname == NULL)
+ return EINVAL;
+
+ d = opendir(dirname);
+ if (d == NULL)
+ return ENOENT;
+
+ while ((dentry = readdir(d))) {
+ if (strlen(dirname) + strlen(dentry->d_name) + 2 > sizeof(filename)) {
+ pkiDebug("%s: Path too long -- directory '%s' and file '%s'\n",
+ __FUNCTION__, dirname, dentry->d_name);
+ goto cleanup;
+ }
+ /* Ignore subdirectories and anything starting with a dot */
+#ifdef DT_DIR
+ if (dentry->d_type == DT_DIR)
+ continue;
+#endif
+ if (dentry->d_name[0] == '.')
+ continue;
+ (void) snprintf(filename, sizeof(filename), "%s/%s", dirname, dentry->d_name);
+
+ retval = load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx,
+ id_cryptoctx, catype, filename);
+ if (retval)
+ goto cleanup;
+ }
+
+ retval = 0;
+
+ cleanup:
+ if (d != NULL)
+ (void) closedir(d);
+
+ return retval;
+}
+
+/* ARGSUSED */
+krb5_error_code
+crypto_load_cas_and_crls(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_opts *idopts,
+ pkinit_identity_crypto_context id_cryptoctx,
+ int idtype,
+ int catype,
+ char *id)
+{
+ pkiDebug("%s: called with idtype %s and catype %s\n",
+ __FUNCTION__, idtype2string(idtype), catype2string(catype));
+ /* Solaris Kerberos: Removed "break"'s as they are never reached */
+ switch (idtype) {
+ case IDTYPE_FILE:
+ return load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx,
+ id_cryptoctx, catype, id);
+ case IDTYPE_DIR:
+ return load_cas_and_crls_dir(context, plg_cryptoctx, req_cryptoctx,
+ id_cryptoctx, catype, id);
+ default:
+ return ENOTSUP;
+ }
+}
+
+static krb5_error_code
+create_identifiers_from_stack(STACK_OF(X509) *sk,
+ krb5_external_principal_identifier *** ids)
+{
+ krb5_error_code retval = ENOMEM;
+ int i = 0, sk_size = sk_X509_num(sk);
+ krb5_external_principal_identifier **krb5_cas = NULL;
+ X509 *x = NULL;
+ X509_NAME *xn = NULL;
+ unsigned char *p = NULL;
+ int len = 0;
+ PKCS7_ISSUER_AND_SERIAL *is = NULL;
+ char buf[DN_BUF_LEN];
+
+ *ids = NULL;
+
+ krb5_cas =
+ malloc((sk_size + 1) * sizeof(krb5_external_principal_identifier *));
+ if (krb5_cas == NULL)
+ return ENOMEM;
+ krb5_cas[sk_size] = NULL;
+
+ for (i = 0; i < sk_size; i++) {
+ krb5_cas[i] = (krb5_external_principal_identifier *)malloc(sizeof(krb5_external_principal_identifier));
+
+ x = sk_X509_value(sk, i);
+
+ X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
+ pkiDebug("#%d cert= %s\n", i, buf);
+
+ /* fill-in subjectName */
+ krb5_cas[i]->subjectName.magic = 0;
+ krb5_cas[i]->subjectName.length = 0;
+ krb5_cas[i]->subjectName.data = NULL;
+
+ xn = X509_get_subject_name(x);
+ len = i2d_X509_NAME(xn, NULL);
+ if ((p = krb5_cas[i]->subjectName.data = (unsigned char *)malloc((size_t) len)) == NULL)
+ goto cleanup;
+ i2d_X509_NAME(xn, &p);
+ krb5_cas[i]->subjectName.length = len;
+
+ /* fill-in issuerAndSerialNumber */
+ krb5_cas[i]->issuerAndSerialNumber.length = 0;
+ krb5_cas[i]->issuerAndSerialNumber.magic = 0;
+ krb5_cas[i]->issuerAndSerialNumber.data = NULL;
+
+#ifdef LONGHORN_BETA_COMPAT
+if (longhorn == 0) { /* XXX Longhorn doesn't like this */
+#endif
+ is = PKCS7_ISSUER_AND_SERIAL_new();
+ X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
+ M_ASN1_INTEGER_free(is->serial);
+ is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
+ len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
+ if ((p = krb5_cas[i]->issuerAndSerialNumber.data =
+ (unsigned char *)malloc((size_t) len)) == NULL)
+ goto cleanup;
+ i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
+ krb5_cas[i]->issuerAndSerialNumber.length = len;
+#ifdef LONGHORN_BETA_COMPAT
+}
+#endif
+
+ /* fill-in subjectKeyIdentifier */
+ krb5_cas[i]->subjectKeyIdentifier.length = 0;
+ krb5_cas[i]->subjectKeyIdentifier.magic = 0;
+ krb5_cas[i]->subjectKeyIdentifier.data = NULL;
+
+
+#ifdef LONGHORN_BETA_COMPAT
+if (longhorn == 0) { /* XXX Longhorn doesn't like this */
+#endif
+ if (X509_get_ext_by_NID(x, NID_subject_key_identifier, -1) >= 0) {
+ ASN1_OCTET_STRING *ikeyid = NULL;
+
+ if ((ikeyid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL,
+ NULL))) {
+ len = i2d_ASN1_OCTET_STRING(ikeyid, NULL);
+ if ((p = krb5_cas[i]->subjectKeyIdentifier.data =
+ (unsigned char *)malloc((size_t) len)) == NULL)
+ goto cleanup;
+ i2d_ASN1_OCTET_STRING(ikeyid, &p);
+ krb5_cas[i]->subjectKeyIdentifier.length = len;
+ }
+ if (ikeyid != NULL)
+ ASN1_OCTET_STRING_free(ikeyid);
+ }
+#ifdef LONGHORN_BETA_COMPAT
+}
+#endif
+ if (is != NULL) {
+ if (is->issuer != NULL)
+ X509_NAME_free(is->issuer);
+ if (is->serial != NULL)
+ ASN1_INTEGER_free(is->serial);
+ free(is);
+ }
+ }
+
+ *ids = krb5_cas;
+
+ retval = 0;
+ cleanup:
+ if (retval)
+ free_krb5_external_principal_identifier(&krb5_cas);
+
+ return retval;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+create_krb5_invalidCertificates(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_external_principal_identifier *** ids)
+{
+
+ krb5_error_code retval = ENOMEM;
+ STACK_OF(X509) *sk = NULL;
+
+ *ids = NULL;
+ if (req_cryptoctx->received_cert == NULL)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+
+ sk = sk_X509_new_null();
+ if (sk == NULL)
+ goto cleanup;
+ sk_X509_push(sk, req_cryptoctx->received_cert);
+
+ retval = create_identifiers_from_stack(sk, ids);
+
+ sk_X509_free(sk);
+cleanup:
+
+ return retval;
+}
+
+/* ARGSUSED */
+krb5_error_code
+create_krb5_supportedCMSTypes(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_algorithm_identifier ***oids)
+{
+
+ krb5_error_code retval = ENOMEM;
+ krb5_algorithm_identifier **loids = NULL;
+ krb5_octet_data des3oid = {0, 8, (unsigned char *)"\x2A\x86\x48\x86\xF7\x0D\x03\x07" };
+
+ *oids = NULL;
+ loids = malloc(2 * sizeof(krb5_algorithm_identifier *));
+ if (loids == NULL)
+ goto cleanup;
+ loids[1] = NULL;
+ loids[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
+ if (loids[0] == NULL) {
+ free(loids);
+ goto cleanup;
+ }
+ retval = pkinit_copy_krb5_octet_data(&loids[0]->algorithm, &des3oid);
+ if (retval) {
+ free(loids[0]);
+ free(loids);
+ goto cleanup;
+ }
+ loids[0]->parameters.length = 0;
+ loids[0]->parameters.data = NULL;
+
+ *oids = loids;
+ retval = 0;
+cleanup:
+
+ return retval;
+}
+
+/* ARGSUSED */
+krb5_error_code
+create_krb5_trustedCertifiers(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_external_principal_identifier *** ids)
+{
+
+ /* Solaris Kerberos */
+ STACK_OF(X509) *sk = id_cryptoctx->trustedCAs;
+
+ *ids = NULL;
+ if (id_cryptoctx->trustedCAs == NULL)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+
+ return create_identifiers_from_stack(sk, ids);
+
+}
+
+/* ARGSUSED */
+krb5_error_code
+create_krb5_trustedCas(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ int flag,
+ krb5_trusted_ca *** ids)
+{
+ krb5_error_code retval = ENOMEM;
+ STACK_OF(X509) *sk = id_cryptoctx->trustedCAs;
+ int i = 0, len = 0, sk_size = sk_X509_num(sk);
+ krb5_trusted_ca **krb5_cas = NULL;
+ X509 *x = NULL;
+ char buf[DN_BUF_LEN];
+ X509_NAME *xn = NULL;
+ unsigned char *p = NULL;
+ PKCS7_ISSUER_AND_SERIAL *is = NULL;
+
+ *ids = NULL;
+ if (id_cryptoctx->trustedCAs == NULL)
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+
+ krb5_cas = malloc((sk_size + 1) * sizeof(krb5_trusted_ca *));
+ if (krb5_cas == NULL)
+ return ENOMEM;
+ krb5_cas[sk_size] = NULL;
+
+ for (i = 0; i < sk_size; i++) {
+ krb5_cas[i] = (krb5_trusted_ca *)malloc(sizeof(krb5_trusted_ca));
+ if (krb5_cas[i] == NULL)
+ goto cleanup;
+ x = sk_X509_value(sk, i);
+
+ X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
+ pkiDebug("#%d cert= %s\n", i, buf);
+
+ switch (flag) {
+ case choice_trusted_cas_principalName:
+ krb5_cas[i]->choice = choice_trusted_cas_principalName;
+ break;
+ case choice_trusted_cas_caName:
+ krb5_cas[i]->choice = choice_trusted_cas_caName;
+ krb5_cas[i]->u.caName.data = NULL;
+ krb5_cas[i]->u.caName.length = 0;
+ xn = X509_get_subject_name(x);
+ len = i2d_X509_NAME(xn, NULL);
+ if ((p = krb5_cas[i]->u.caName.data =
+ (unsigned char *)malloc((size_t) len)) == NULL)
+ goto cleanup;
+ i2d_X509_NAME(xn, &p);
+ krb5_cas[i]->u.caName.length = len;
+ break;
+ case choice_trusted_cas_issuerAndSerial:
+ krb5_cas[i]->choice = choice_trusted_cas_issuerAndSerial;
+ krb5_cas[i]->u.issuerAndSerial.data = NULL;
+ krb5_cas[i]->u.issuerAndSerial.length = 0;
+ is = PKCS7_ISSUER_AND_SERIAL_new();
+ X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
+ M_ASN1_INTEGER_free(is->serial);
+ is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
+ len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
+ if ((p = krb5_cas[i]->u.issuerAndSerial.data =
+ (unsigned char *)malloc((size_t) len)) == NULL)
+ goto cleanup;
+ i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
+ krb5_cas[i]->u.issuerAndSerial.length = len;
+ if (is != NULL) {
+ if (is->issuer != NULL)
+ X509_NAME_free(is->issuer);
+ if (is->serial != NULL)
+ ASN1_INTEGER_free(is->serial);
+ free(is);
+ }
+ break;
+ default: break;
+ }
+ }
+ retval = 0;
+ *ids = krb5_cas;
+cleanup:
+ if (retval)
+ free_krb5_trusted_ca(&krb5_cas);
+
+ return retval;
+}
+
+/* ARGSUSED */
+krb5_error_code
+create_issuerAndSerial(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char **out,
+ unsigned int *out_len)
+{
+ unsigned char *p = NULL;
+ PKCS7_ISSUER_AND_SERIAL *is = NULL;
+ int len = 0;
+ krb5_error_code retval = ENOMEM;
+ X509 *cert = req_cryptoctx->received_cert;
+
+ *out = NULL;
+ *out_len = 0;
+ if (req_cryptoctx->received_cert == NULL)
+ return 0;
+
+ is = PKCS7_ISSUER_AND_SERIAL_new();
+ X509_NAME_set(&is->issuer, X509_get_issuer_name(cert));
+ M_ASN1_INTEGER_free(is->serial);
+ is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
+ len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
+ if ((p = *out = (unsigned char *)malloc((size_t) len)) == NULL)
+ goto cleanup;
+ i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
+ *out_len = len;
+ retval = 0;
+
+cleanup:
+ X509_NAME_free(is->issuer);
+ ASN1_INTEGER_free(is->serial);
+ free(is);
+
+ return retval;
+}
+
+static int
+pkcs7_decrypt(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
+ PKCS7 *p7,
+ BIO *data)
+{
+ BIO *tmpmem = NULL;
+ /* Solaris Kerberos */
+ int i = 0;
+ char buf[4096];
+
+ if(p7 == NULL)
+ return 0;
+
+ if(!PKCS7_type_is_enveloped(p7)) {
+ pkiDebug("wrong pkcs7 content type\n");
+ return 0;
+ }
+
+ if(!(tmpmem = pkcs7_dataDecode(context, id_cryptoctx, p7))) {
+ pkiDebug("unable to decrypt pkcs7 object\n");
+ return 0;
+ }
+/* Solaris Kerberos: Suppress sun studio compiler warning */
+#pragma error_messages (off, E_END_OF_LOOP_CODE_NOT_REACHED)
+ for(;;) {
+ i = BIO_read(tmpmem, buf, sizeof(buf));
+ if (i <= 0) break;
+ BIO_write(data, buf, i);
+ BIO_free_all(tmpmem);
+ return 1;
+ }
+#pragma error_messages (default, E_END_OF_LOOP_CODE_NOT_REACHED)
+
+ return 0;
+}
+
+krb5_error_code
+pkinit_process_td_trusted_certifiers(
+ krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_external_principal_identifier **krb5_trusted_certifiers,
+ int td_type)
+{
+ krb5_error_code retval = ENOMEM;
+ STACK_OF(X509_NAME) *sk_xn = NULL;
+ X509_NAME *xn = NULL;
+ PKCS7_ISSUER_AND_SERIAL *is = NULL;
+ ASN1_OCTET_STRING *id = NULL;
+ const unsigned char *p = NULL;
+ char buf[DN_BUF_LEN];
+ int i = 0;
+
+ if (td_type == TD_TRUSTED_CERTIFIERS)
+ pkiDebug("received trusted certifiers\n");
+ else
+ pkiDebug("received invalid certificate\n");
+
+ sk_xn = sk_X509_NAME_new_null();
+ while(krb5_trusted_certifiers[i] != NULL) {
+ if (krb5_trusted_certifiers[i]->subjectName.data != NULL) {
+ p = krb5_trusted_certifiers[i]->subjectName.data;
+ xn = d2i_X509_NAME(NULL, &p,
+ (int)krb5_trusted_certifiers[i]->subjectName.length);
+ if (xn == NULL)
+ goto cleanup;
+ X509_NAME_oneline(xn, buf, sizeof(buf));
+ if (td_type == TD_TRUSTED_CERTIFIERS)
+ pkiDebug("#%d cert = %s is trusted by kdc\n", i, buf);
+ else
+ pkiDebug("#%d cert = %s is invalid\n", i, buf);
+ sk_X509_NAME_push(sk_xn, xn);
+ }
+
+ if (krb5_trusted_certifiers[i]->issuerAndSerialNumber.data != NULL) {
+ p = krb5_trusted_certifiers[i]->issuerAndSerialNumber.data;
+ is = d2i_PKCS7_ISSUER_AND_SERIAL(NULL, &p,
+ (int)krb5_trusted_certifiers[i]->issuerAndSerialNumber.length);
+ if (is == NULL)
+ goto cleanup;
+ X509_NAME_oneline(is->issuer, buf, sizeof(buf));
+ if (td_type == TD_TRUSTED_CERTIFIERS)
+ pkiDebug("#%d issuer = %s serial = %ld is trusted bu kdc\n", i,
+ buf, ASN1_INTEGER_get(is->serial));
+ else
+ pkiDebug("#%d issuer = %s serial = %ld is invalid\n", i, buf,
+ ASN1_INTEGER_get(is->serial));
+ PKCS7_ISSUER_AND_SERIAL_free(is);
+ }
+
+ if (krb5_trusted_certifiers[i]->subjectKeyIdentifier.data != NULL) {
+ p = krb5_trusted_certifiers[i]->subjectKeyIdentifier.data;
+ id = d2i_ASN1_OCTET_STRING(NULL, &p,
+ (int)krb5_trusted_certifiers[i]->subjectKeyIdentifier.length);
+ if (id == NULL)
+ goto cleanup;
+ /* XXX */
+ ASN1_OCTET_STRING_free(id);
+ }
+ i++;
+ }
+ /* XXX Since we not doing anything with received trusted certifiers
+ * return an error. this is the place where we can pick a different
+ * client certificate based on the information in td_trusted_certifiers
+ */
+ retval = KRB5KDC_ERR_PREAUTH_FAILED;
+cleanup:
+ if (sk_xn != NULL)
+ sk_X509_NAME_pop_free(sk_xn, X509_NAME_free);
+
+ return retval;
+}
+
+static BIO *
+pkcs7_dataDecode(krb5_context context,
+ pkinit_identity_crypto_context id_cryptoctx,
+ PKCS7 *p7)
+{
+ int i = 0;
+ unsigned int jj = 0, tmp_len = 0;
+ BIO *out=NULL,*etmp=NULL,*bio=NULL;
+ unsigned char *tmp=NULL;
+ ASN1_OCTET_STRING *data_body=NULL;
+ const EVP_CIPHER *evp_cipher=NULL;
+ EVP_CIPHER_CTX *evp_ctx=NULL;
+ X509_ALGOR *enc_alg=NULL;
+ STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
+/* Solaris Kerberos: Not used */
+#if 0
+ X509_ALGOR *xalg=NULL;
+#endif
+ PKCS7_RECIP_INFO *ri=NULL;
+ X509 *cert = sk_X509_value(id_cryptoctx->my_certs,
+ id_cryptoctx->cert_index);
+
+ p7->state=PKCS7_S_HEADER;
+
+ rsk=p7->d.enveloped->recipientinfo;
+ enc_alg=p7->d.enveloped->enc_data->algorithm;
+ data_body=p7->d.enveloped->enc_data->enc_data;
+ evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
+ if (evp_cipher == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+ goto cleanup;
+ }
+/* Solaris Kerberos: Not used */
+#if 0
+ xalg=p7->d.enveloped->enc_data->algorithm;
+#endif
+
+ if ((etmp=BIO_new(BIO_f_cipher())) == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
+ goto cleanup;
+ }
+
+ /* It was encrypted, we need to decrypt the secret key
+ * with the private key */
+
+ /* Find the recipientInfo which matches the passed certificate
+ * (if any)
+ */
+
+ if (cert) {
+ for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+ int tmp_ret = 0;
+ ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
+ tmp_ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
+ cert->cert_info->issuer);
+ if (!tmp_ret) {
+ tmp_ret = M_ASN1_INTEGER_cmp(cert->cert_info->serialNumber,
+ ri->issuer_and_serial->serial);
+ if (!tmp_ret)
+ break;
+ }
+ ri=NULL;
+ }
+ if (ri == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+ PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
+ goto cleanup;
+ }
+
+ }
+
+ /* If we haven't got a certificate try each ri in turn */
+
+ if (cert == NULL) {
+ for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+ ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
+ jj = pkinit_decode_data(context, id_cryptoctx,
+ M_ASN1_STRING_data(ri->enc_key),
+ (unsigned int) M_ASN1_STRING_length(ri->enc_key),
+ &tmp, &tmp_len);
+ if (jj) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
+ goto cleanup;
+ }
+
+ if (!jj && tmp_len > 0) {
+ jj = tmp_len;
+ break;
+ }
+
+ ERR_clear_error();
+ ri = NULL;
+ }
+
+ if (ri == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_KEY);
+ goto cleanup;
+ }
+ }
+ else {
+ jj = pkinit_decode_data(context, id_cryptoctx,
+ M_ASN1_STRING_data(ri->enc_key),
+ (unsigned int) M_ASN1_STRING_length(ri->enc_key),
+ &tmp, &tmp_len);
+ /* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */
+ if (jj || tmp_len == 0) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
+ goto cleanup;
+ }
+ jj = tmp_len;
+ }
+
+ evp_ctx=NULL;
+ BIO_get_cipher_ctx(etmp,&evp_ctx);
+ if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
+ goto cleanup;
+ if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
+ goto cleanup;
+
+ if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
+ /* Some S/MIME clients don't use the same key
+ * and effective key length. The key length is
+ * determined by the size of the decrypted RSA key.
+ */
+ if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, (int)jj)) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+ PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
+ goto cleanup;
+ }
+ }
+ if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
+ goto cleanup;
+
+ OPENSSL_cleanse(tmp,jj);
+
+ if (out == NULL)
+ out=etmp;
+ else
+ BIO_push(out,etmp);
+ etmp=NULL;
+
+ if (data_body->length > 0)
+ bio = BIO_new_mem_buf(data_body->data, data_body->length);
+ else {
+ bio=BIO_new(BIO_s_mem());
+ BIO_set_mem_eof_return(bio,0);
+ }
+ BIO_push(out,bio);
+ bio=NULL;
+
+ /* Solaris Kerberos */
+ goto out;
+
+cleanup:
+ if (out != NULL) BIO_free_all(out);
+ if (etmp != NULL) BIO_free_all(etmp);
+ if (bio != NULL) BIO_free_all(bio);
+ out=NULL;
+
+out:
+ if (tmp != NULL)
+ free(tmp);
+
+ return(out);
+}
+
+static krb5_error_code
+der_decode_data(unsigned char *data, long data_len,
+ unsigned char **out, long *out_len)
+{
+ /* Solaris Kerberos */
+ krb5_error_code retval = KRB5KRB_ERR_GENERIC;
+ ASN1_OCTET_STRING *s = NULL;
+ const unsigned char *p = data;
+
+ if ((s = d2i_ASN1_BIT_STRING(NULL, &p, data_len)) == NULL)
+ goto cleanup;
+ *out_len = s->length;
+ if ((*out = (unsigned char *) malloc((size_t) *out_len + 1)) == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ (void) memcpy(*out, s->data, (size_t) s->length);
+ (*out)[s->length] = '\0';
+
+ retval = 0;
+ cleanup:
+ if (s != NULL)
+ ASN1_OCTET_STRING_free(s);
+
+ return retval;
+}
+
+
+#ifdef DEBUG_DH
+static void
+print_dh(DH * dh, char *msg)
+{
+ BIO *bio_err = NULL;
+
+ bio_err = BIO_new(BIO_s_file());
+ BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
+
+ if (msg)
+ BIO_puts(bio_err, (const char *)msg);
+ if (dh)
+ DHparams_print(bio_err, dh);
+
+ BN_print(bio_err, dh->q);
+ BIO_puts(bio_err, (const char *)"\n");
+ BIO_free(bio_err);
+
+}
+
+static void
+print_pubkey(BIGNUM * key, char *msg)
+{
+ BIO *bio_err = NULL;
+
+ bio_err = BIO_new(BIO_s_file());
+ BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
+
+ if (msg)
+ BIO_puts(bio_err, (const char *)msg);
+ if (key)
+ BN_print(bio_err, key);
+ BIO_puts(bio_err, "\n");
+
+ BIO_free(bio_err);
+
+}
+#endif
+
+/*
+ * Solaris Kerberos:
+ * Error message generation has changed so gettext() can be used
+ */
+#if 0
+static char *
+pkinit_pkcs11_code_to_text(int err)
+{
+ int i;
+ static char uc[64];
+
+ for (i = 0; pkcs11_errstrings[i].text != NULL; i++)
+ if (pkcs11_errstrings[i].code == err)
+ break;
+ if (pkcs11_errstrings[i].text != NULL)
+ return (pkcs11_errstrings[i].text);
+ snprintf(uc, 64, gettext("unknown code 0x%x"), err);
+ return (uc);
+}
+#endif
+
+static char *
+pkinit_pkcs11_code_to_text(int err) {
+ return pkcs11_error_table(err);
+}
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h
new file mode 100644
index 0000000000..236ad91363
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h
@@ -0,0 +1,273 @@
+/*
+ * COPYRIGHT (C) 2006,2007
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#ifndef _PKINIT_CRYPTO_OPENSSL_H
+#define _PKINIT_CRYPTO_OPENSSL_H
+
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pkcs12.h>
+#include <openssl/obj_mac.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/sha.h>
+#include <openssl/asn1.h>
+#include <openssl/pem.h>
+
+#include "pkinit.h"
+
+#define DN_BUF_LEN 256
+#define MAX_CREDS_ALLOWED 20
+
+struct _pkinit_cred_info {
+ X509 *cert;
+ EVP_PKEY *key;
+#ifndef WITHOUT_PKCS11
+ CK_BYTE_PTR cert_id;
+ int cert_id_len;
+#endif
+};
+typedef struct _pkinit_cred_info * pkinit_cred_info;
+
+struct _pkinit_identity_crypto_context {
+ pkinit_cred_info creds[MAX_CREDS_ALLOWED+1];
+ STACK_OF(X509) *my_certs; /* available user certs */
+ int cert_index; /* cert to use out of available certs*/
+ EVP_PKEY *my_key; /* available user keys if in filesystem */
+ STACK_OF(X509) *trustedCAs; /* available trusted ca certs */
+ STACK_OF(X509) *intermediateCAs; /* available intermediate ca certs */
+ STACK_OF(X509_CRL) *revoked; /* available crls */
+ int pkcs11_method;
+ krb5_prompter_fct prompter;
+ void *prompter_data;
+#ifndef WITHOUT_PKCS11
+ char *p11_module_name;
+ CK_SLOT_ID slotid;
+ char *token_label;
+ char *cert_label;
+ /* These are crypto-specific */
+ void *p11_module;
+ CK_SESSION_HANDLE session;
+ CK_FUNCTION_LIST_PTR p11;
+ CK_BYTE_PTR cert_id;
+ int cert_id_len;
+ CK_MECHANISM_TYPE mech;
+ /*
+ * Solaris Kerberos:
+ * If PKCS#11 is already being used by the process then C_Finalize should
+ * not be called by pkinit as it would invalidate any PKCS#11 sessions the
+ * process was using prior to loading the pkinit plugin. "finalize_pkcs11"
+ * indicates whether or not C_Finalize should be called by pkinit.
+ */
+ krb5_boolean finalize_pkcs11;
+#endif
+};
+
+struct _pkinit_plg_crypto_context {
+ DH *dh_1024;
+ DH *dh_2048;
+ DH *dh_4096;
+ ASN1_OBJECT *id_pkinit_authData;
+ ASN1_OBJECT *id_pkinit_authData9;
+ ASN1_OBJECT *id_pkinit_DHKeyData;
+ ASN1_OBJECT *id_pkinit_rkeyData;
+ ASN1_OBJECT *id_pkinit_san;
+ ASN1_OBJECT *id_ms_san_upn;
+ ASN1_OBJECT *id_pkinit_KPClientAuth;
+ ASN1_OBJECT *id_pkinit_KPKdc;
+ ASN1_OBJECT *id_ms_kp_sc_logon;
+ ASN1_OBJECT *id_kp_serverAuth;
+};
+
+struct _pkinit_req_crypto_context {
+ X509 *received_cert;
+ DH *dh;
+};
+
+#define CERT_MAGIC 0x53534c43
+struct _pkinit_cert_data {
+ unsigned int magic;
+ pkinit_plg_crypto_context plgctx;
+ pkinit_req_crypto_context reqctx;
+ pkinit_identity_crypto_context idctx;
+ pkinit_cred_info cred;
+ unsigned int index; /* Index of this cred in the creds[] array */
+};
+
+#define ITER_MAGIC 0x53534c49
+struct _pkinit_cert_iter_data {
+ unsigned int magic;
+ pkinit_plg_crypto_context plgctx;
+ pkinit_req_crypto_context reqctx;
+ pkinit_identity_crypto_context idctx;
+ unsigned int index;
+};
+
+static void openssl_init(void);
+
+static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
+static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
+
+static krb5_error_code pkinit_init_dh_params(pkinit_plg_crypto_context );
+static void pkinit_fini_dh_params(pkinit_plg_crypto_context );
+
+static krb5_error_code pkinit_init_certs(pkinit_identity_crypto_context ctx);
+static void pkinit_fini_certs(pkinit_identity_crypto_context ctx);
+
+static krb5_error_code pkinit_init_pkcs11(pkinit_identity_crypto_context ctx);
+static void pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx);
+
+static krb5_error_code pkinit_encode_dh_params
+ (BIGNUM *, BIGNUM *, BIGNUM *, unsigned char **, unsigned int *);
+static DH *pkinit_decode_dh_params
+ (DH **, unsigned char **, unsigned int );
+static int pkinit_check_dh_params
+ (BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1);
+
+static krb5_error_code pkinit_sign_data
+ (krb5_context context, pkinit_identity_crypto_context cryptoctx,
+ unsigned char *data, unsigned int data_len,
+ unsigned char **sig, unsigned int *sig_len);
+
+static krb5_error_code create_signature
+ (unsigned char **, unsigned int *, unsigned char *, unsigned int,
+ EVP_PKEY *pkey);
+
+static krb5_error_code pkinit_decode_data
+ (krb5_context context, pkinit_identity_crypto_context cryptoctx,
+ unsigned char *data, unsigned int data_len,
+ unsigned char **decoded, unsigned int *decoded_len);
+
+static krb5_error_code decode_data
+ (unsigned char **, unsigned int *, unsigned char *, unsigned int,
+ EVP_PKEY *pkey, X509 *cert);
+
+#ifdef DEBUG_DH
+static void print_dh(DH *, char *);
+static void print_pubkey(BIGNUM *, char *);
+#endif
+
+static int prepare_enc_data
+ (unsigned char *indata, int indata_len, unsigned char **outdata,
+ int *outdata_len);
+
+static int openssl_callback (int, X509_STORE_CTX *);
+static int openssl_callback_ignore_crls (int, X509_STORE_CTX *);
+
+static int pkcs7_decrypt
+ (krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
+ PKCS7 *p7, BIO *bio);
+
+static BIO * pkcs7_dataDecode
+ (krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
+ PKCS7 *p7);
+
+static ASN1_OBJECT * pkinit_pkcs7type2oid
+ (pkinit_plg_crypto_context plg_cryptoctx, int pkcs7_type);
+
+static krb5_error_code pkinit_create_sequence_of_principal_identifiers
+ (krb5_context context, pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ int type, krb5_data **out_data);
+
+#ifndef WITHOUT_PKCS11
+static krb5_error_code pkinit_find_private_key
+ (pkinit_identity_crypto_context, CK_ATTRIBUTE_TYPE usage,
+ CK_OBJECT_HANDLE *objp);
+static krb5_error_code pkinit_login
+ (krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
+ CK_TOKEN_INFO *tip);
+static krb5_error_code pkinit_open_session
+ (krb5_context context, pkinit_identity_crypto_context id_cryptoctx);
+static void * pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p);
+static CK_RV pkinit_C_UnloadModule(void *handle);
+#ifdef SILLYDECRYPT
+CK_RV pkinit_C_Decrypt
+ (pkinit_identity_crypto_context id_cryptoctx,
+ CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
+ CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen);
+#endif
+
+static krb5_error_code pkinit_sign_data_pkcs11
+ (krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *data, unsigned int data_len,
+ unsigned char **sig, unsigned int *sig_len);
+static krb5_error_code pkinit_decode_data_pkcs11
+ (krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *data, unsigned int data_len,
+ unsigned char **decoded_data, unsigned int *decoded_data_len);
+#endif /* WITHOUT_PKCS11 */
+
+static krb5_error_code pkinit_sign_data_fs
+ (krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *data, unsigned int data_len,
+ unsigned char **sig, unsigned int *sig_len);
+static krb5_error_code pkinit_decode_data_fs
+ (krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
+ unsigned char *data, unsigned int data_len,
+ unsigned char **decoded_data, unsigned int *decoded_data_len);
+
+static krb5_error_code der_decode_data
+ (unsigned char *, long, unsigned char **, long *);
+
+static krb5_error_code
+create_krb5_invalidCertificates(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_external_principal_identifier *** ids);
+
+static krb5_error_code
+create_identifiers_from_stack(STACK_OF(X509) *sk,
+ krb5_external_principal_identifier *** ids);
+#ifdef LONGHORN_BETA_COMPAT
+static int
+wrap_signeddata(unsigned char *data, unsigned int data_len,
+ unsigned char **out, unsigned int *out_len,
+ int is_longhorn_server);
+#else
+static int
+wrap_signeddata(unsigned char *data, unsigned int data_len,
+ unsigned char **out, unsigned int *out_len);
+#endif
+
+/* This handy macro borrowed from crypto/x509v3/v3_purp.c */
+#define ku_reject(x, usage) \
+ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
+
+static char *
+pkinit_pkcs11_code_to_text(int err);
+
+#endif /* _PKINIT_CRYPTO_OPENSSL_H */
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_identity.c b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_identity.c
new file mode 100644
index 0000000000..e4a6470523
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_identity.c
@@ -0,0 +1,685 @@
+/*
+ * COPYRIGHT (C) 2007
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <libintl.h>
+
+#include "pkinit.h"
+
+static void
+free_list(char **list)
+{
+ int i;
+
+ if (list == NULL)
+ return;
+
+ for (i = 0; list[i] != NULL; i++)
+ free(list[i]);
+ free(list);
+}
+
+static krb5_error_code
+copy_list(char ***dst, char **src)
+{
+ int i;
+ char **newlist;
+
+ if (dst == NULL)
+ return EINVAL;
+ *dst = NULL;
+
+ if (src == NULL)
+ return 0;
+
+ for (i = 0; src[i] != NULL; i++);
+
+ newlist = calloc(1, (i + 1) * sizeof(*newlist));
+ if (newlist == NULL)
+ return ENOMEM;
+
+ for (i = 0; src[i] != NULL; i++) {
+ newlist[i] = strdup(src[i]);
+ if (newlist[i] == NULL)
+ goto cleanup;
+ }
+ newlist[i] = NULL;
+ *dst = newlist;
+ return 0;
+cleanup:
+ free_list(newlist);
+ return ENOMEM;
+}
+
+char *
+idtype2string(int idtype)
+{
+/* Solaris Kerberos: Removed "break"s (lint) */
+ switch(idtype) {
+ case IDTYPE_FILE: return "FILE";
+ case IDTYPE_DIR: return "DIR";
+ case IDTYPE_PKCS11: return "PKCS11";
+ case IDTYPE_PKCS12: return "PKCS12";
+ case IDTYPE_ENVVAR: return "ENV";
+ default: return "INVALID";
+ }
+}
+
+char *
+catype2string(int catype)
+{
+/* Solaris Kerberos: Removed "break"s (lint) */
+ switch(catype) {
+ case CATYPE_ANCHORS: return "ANCHORS";
+ case CATYPE_INTERMEDIATES: return "INTERMEDIATES";
+ case CATYPE_CRLS: return "CRLS";
+ default: return "INVALID";
+ }
+}
+
+krb5_error_code
+pkinit_init_identity_opts(pkinit_identity_opts **idopts)
+{
+ pkinit_identity_opts *opts = NULL;
+
+ *idopts = NULL;
+ opts = (pkinit_identity_opts *) calloc(1, sizeof(pkinit_identity_opts));
+ if (opts == NULL)
+ return ENOMEM;
+
+ opts->identity = NULL;
+ opts->anchors = NULL;
+ opts->intermediates = NULL;
+ opts->crls = NULL;
+ opts->ocsp = NULL;
+ opts->dn_mapping_file = NULL;
+
+ opts->cert_filename = NULL;
+ opts->key_filename = NULL;
+#ifndef WITHOUT_PKCS11
+ opts->p11_module_name = NULL;
+ opts->slotid = PK_NOSLOT;
+ opts->token_label = NULL;
+ opts->cert_id_string = NULL;
+ opts->cert_label = NULL;
+#endif
+
+ *idopts = opts;
+
+ return 0;
+}
+
+krb5_error_code
+pkinit_dup_identity_opts(pkinit_identity_opts *src_opts,
+ pkinit_identity_opts **dest_opts)
+{
+ pkinit_identity_opts *newopts;
+ krb5_error_code retval;
+
+ *dest_opts = NULL;
+ retval = pkinit_init_identity_opts(&newopts);
+ if (retval)
+ return retval;
+
+ retval = ENOMEM;
+
+ if (src_opts->identity != NULL) {
+ newopts->identity = strdup(src_opts->identity);
+ if (newopts->identity == NULL)
+ goto cleanup;
+ }
+
+ retval = copy_list(&newopts->anchors, src_opts->anchors);
+ if (retval)
+ goto cleanup;
+
+ retval = copy_list(&newopts->intermediates,src_opts->intermediates);
+ if (retval)
+ goto cleanup;
+
+ retval = copy_list(&newopts->crls, src_opts->crls);
+ if (retval)
+ goto cleanup;
+
+ if (src_opts->ocsp != NULL) {
+ newopts->ocsp = strdup(src_opts->ocsp);
+ if (newopts->ocsp == NULL)
+ goto cleanup;
+ }
+
+ if (src_opts->cert_filename != NULL) {
+ newopts->cert_filename = strdup(src_opts->cert_filename);
+ if (newopts->cert_filename == NULL)
+ goto cleanup;
+ }
+
+ if (src_opts->key_filename != NULL) {
+ newopts->key_filename = strdup(src_opts->key_filename);
+ if (newopts->key_filename == NULL)
+ goto cleanup;
+ }
+
+#ifndef WITHOUT_PKCS11
+ if (src_opts->p11_module_name != NULL) {
+ newopts->p11_module_name = strdup(src_opts->p11_module_name);
+ if (newopts->p11_module_name == NULL)
+ goto cleanup;
+ }
+
+ newopts->slotid = src_opts->slotid;
+
+ if (src_opts->token_label != NULL) {
+ newopts->token_label = strdup(src_opts->token_label);
+ if (newopts->token_label == NULL)
+ goto cleanup;
+ }
+
+ if (src_opts->cert_id_string != NULL) {
+ newopts->cert_id_string = strdup(src_opts->cert_id_string);
+ if (newopts->cert_id_string == NULL)
+ goto cleanup;
+ }
+
+ if (src_opts->cert_label != NULL) {
+ newopts->cert_label = strdup(src_opts->cert_label);
+ if (newopts->cert_label == NULL)
+ goto cleanup;
+ }
+#endif
+
+
+ *dest_opts = newopts;
+ return 0;
+cleanup:
+ pkinit_fini_identity_opts(newopts);
+ return retval;
+}
+
+void
+pkinit_fini_identity_opts(pkinit_identity_opts *idopts)
+{
+ if (idopts == NULL)
+ return;
+
+ if (idopts->identity != NULL)
+ free(idopts->identity);
+ free_list(idopts->anchors);
+ free_list(idopts->intermediates);
+ free_list(idopts->crls);
+ free_list(idopts->identity_alt);
+
+ if (idopts->cert_filename != NULL)
+ free(idopts->cert_filename);
+ if (idopts->key_filename != NULL)
+ free(idopts->key_filename);
+#ifndef WITHOUT_PKCS11
+ if (idopts->p11_module_name != NULL)
+ free(idopts->p11_module_name);
+ if (idopts->token_label != NULL)
+ free(idopts->token_label);
+ if (idopts->cert_id_string != NULL)
+ free(idopts->cert_id_string);
+ if (idopts->cert_label != NULL)
+ free(idopts->cert_label);
+#endif
+ free(idopts);
+}
+
+#ifndef WITHOUT_PKCS11
+/* ARGSUSED */
+static krb5_error_code
+parse_pkcs11_options(krb5_context context,
+ pkinit_identity_opts *idopts,
+ const char *residual)
+{
+ char *s, *cp, *vp;
+ krb5_error_code retval = ENOMEM;
+
+ if (residual == NULL || residual[0] == '\0')
+ return 0;
+
+ /* Split string into attr=value substrings */
+ s = strdup(residual);
+ if (s == NULL)
+ return retval;
+
+ for ((cp = strtok(s, ":")); cp; (cp = strtok(NULL, ":"))) {
+ vp = strchr(cp, '=');
+
+ /* If there is no "=", this is a pkcs11 module name */
+ if (vp == NULL) {
+ if (idopts->p11_module_name != NULL)
+ free(idopts->p11_module_name);
+ idopts->p11_module_name = strdup(cp);
+ if (idopts->p11_module_name == NULL)
+ goto cleanup;
+ continue;
+ }
+ *vp++ = '\0';
+ if (!strcmp(cp, "module_name")) {
+ if (idopts->p11_module_name != NULL)
+ free(idopts->p11_module_name);
+ idopts->p11_module_name = strdup(vp);
+ if (idopts->p11_module_name == NULL)
+ goto cleanup;
+ } else if (!strcmp(cp, "slotid")) {
+ long slotid = strtol(vp, NULL, 10);
+ if ((slotid == LONG_MIN || slotid == LONG_MAX) && errno != 0) {
+ retval = EINVAL;
+ goto cleanup;
+ }
+ if ((long) (int) slotid != slotid) {
+ retval = EINVAL;
+ goto cleanup;
+ }
+ idopts->slotid = slotid;
+ } else if (!strcmp(cp, "token")) {
+ if (idopts->token_label != NULL)
+ free(idopts->token_label);
+ idopts->token_label = strdup(vp);
+ if (idopts->token_label == NULL)
+ goto cleanup;
+ } else if (!strcmp(cp, "certid")) {
+ if (idopts->cert_id_string != NULL)
+ free(idopts->cert_id_string);
+ idopts->cert_id_string = strdup(vp);
+ if (idopts->cert_id_string == NULL)
+ goto cleanup;
+ } else if (!strcmp(cp, "certlabel")) {
+ if (idopts->cert_label != NULL)
+ free(idopts->cert_label);
+ idopts->cert_label = strdup(vp);
+ if (idopts->cert_label == NULL)
+ goto cleanup;
+ }
+ }
+ retval = 0;
+cleanup:
+ free(s);
+ return retval;
+}
+#endif
+
+/* ARGSUSED */
+static krb5_error_code
+parse_fs_options(krb5_context context,
+ pkinit_identity_opts *idopts,
+ const char *residual)
+{
+ char *certname, *keyname;
+ krb5_error_code retval = ENOMEM;
+
+ if (residual == NULL || residual[0] == '\0')
+ return 0;
+
+ certname = strdup(residual);
+ if (certname == NULL)
+ goto cleanup;
+
+ certname = strtok(certname, ",");
+ keyname = strtok(NULL, ",");
+
+ idopts->cert_filename = strdup(certname);
+ if (idopts->cert_filename == NULL)
+ goto cleanup;
+
+ idopts->key_filename = strdup(keyname ? keyname : certname);
+ if (idopts->key_filename == NULL)
+ goto cleanup;
+
+ retval = 0;
+cleanup:
+ if (certname != NULL)
+ free(certname);
+ return retval;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+parse_pkcs12_options(krb5_context context,
+ pkinit_identity_opts *idopts,
+ const char *residual)
+{
+ krb5_error_code retval = ENOMEM;
+
+ if (residual == NULL || residual[0] == '\0')
+ return 0;
+
+ idopts->cert_filename = strdup(residual);
+ if (idopts->cert_filename == NULL)
+ goto cleanup;
+
+ idopts->key_filename = strdup(residual);
+ if (idopts->key_filename == NULL)
+ goto cleanup;
+
+ pkiDebug("%s: cert_filename '%s' key_filename '%s'\n",
+ __FUNCTION__, idopts->cert_filename,
+ idopts->key_filename);
+ retval = 0;
+cleanup:
+ return retval;
+}
+
+static krb5_error_code
+process_option_identity(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_opts *idopts,
+ pkinit_identity_crypto_context id_cryptoctx,
+ const char *value)
+{
+ const char *residual;
+ int idtype;
+ krb5_error_code retval = 0;
+
+ pkiDebug("%s: processing value '%s'\n",
+ __FUNCTION__, value ? value : "NULL");
+ if (value == NULL)
+ return EINVAL;
+
+ residual = strchr(value, ':');
+ if (residual != NULL) {
+ unsigned int typelen;
+ residual++; /* skip past colon */
+ typelen = residual - value;
+ if (strncmp(value, "FILE:", typelen) == 0) {
+ idtype = IDTYPE_FILE;
+#ifndef WITHOUT_PKCS11
+ } else if (strncmp(value, "PKCS11:", typelen) == 0) {
+ idtype = IDTYPE_PKCS11;
+#endif
+ } else if (strncmp(value, "PKCS12:", typelen) == 0) {
+ idtype = IDTYPE_PKCS12;
+ } else if (strncmp(value, "DIR:", typelen) == 0) {
+ idtype = IDTYPE_DIR;
+ } else if (strncmp(value, "ENV:", typelen) == 0) {
+ idtype = IDTYPE_ENVVAR;
+ } else {
+ pkiDebug("%s: Unsupported type while processing '%s'\n",
+ __FUNCTION__, value);
+ krb5_set_error_message(context, KRB5_PREAUTH_FAILED,
+ "Unsupported type while processing '%s'\n",
+ value);
+ return KRB5_PREAUTH_FAILED;
+ }
+ } else {
+ idtype = IDTYPE_FILE;
+ residual = value;
+ }
+
+ idopts->idtype = idtype;
+ pkiDebug("%s: idtype is %s\n", __FUNCTION__, idtype2string(idopts->idtype));
+ switch (idtype) {
+ case IDTYPE_ENVVAR: {
+ /* Solaris Kerberos: Improved error messages */
+ char *envvar = getenv(residual);
+ if (envvar == NULL) {
+ krb5_set_error_message(context, EINVAL,
+ gettext("failed to find environmental variable \'%s\'"),
+ residual);
+ return EINVAL;
+ }
+ return process_option_identity(context, plg_cryptoctx,
+ req_cryptoctx, idopts, id_cryptoctx,
+ envvar);
+ /* Solaris Kerberos: not reached */
+ }
+ case IDTYPE_FILE:
+ retval = parse_fs_options(context, idopts, residual);
+ break;
+ case IDTYPE_PKCS12:
+ retval = parse_pkcs12_options(context, idopts, residual);
+ break;
+#ifndef WITHOUT_PKCS11
+ case IDTYPE_PKCS11:
+ retval = parse_pkcs11_options(context, idopts, residual);
+ break;
+#endif
+ case IDTYPE_DIR:
+ idopts->cert_filename = strdup(residual);
+ if (idopts->cert_filename == NULL)
+ retval = ENOMEM;
+ break;
+ default:
+ krb5_set_error_message(context, KRB5_PREAUTH_FAILED,
+ "Internal error parsing X509_user_identity\n");
+ retval = EINVAL;
+ break;
+ }
+ return retval;
+}
+
+static krb5_error_code
+process_option_ca_crl(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_opts *idopts,
+ pkinit_identity_crypto_context id_cryptoctx,
+ const char *value,
+ int catype)
+{
+ char *residual;
+ unsigned int typelen;
+ int idtype;
+
+ pkiDebug("%s: processing catype %s, value '%s'\n",
+ __FUNCTION__, catype2string(catype), value);
+ residual = strchr(value, ':');
+ if (residual == NULL) {
+ pkiDebug("No type given for '%s'\n", value);
+ return EINVAL;
+ }
+ residual++; /* skip past colon */
+ typelen = residual - value;
+ if (strncmp(value, "FILE:", typelen) == 0) {
+ idtype = IDTYPE_FILE;
+ } else if (strncmp(value, "DIR:", typelen) == 0) {
+ idtype = IDTYPE_DIR;
+ } else {
+ return ENOTSUP;
+ }
+ return crypto_load_cas_and_crls(context,
+ plg_cryptoctx,
+ req_cryptoctx,
+ idopts, id_cryptoctx,
+ idtype, catype, residual);
+}
+
+static krb5_error_code
+pkinit_identity_process_option(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_opts *idopts,
+ pkinit_identity_crypto_context id_cryptoctx,
+ int attr,
+ const char *value)
+{
+ krb5_error_code retval = 0;
+
+ switch (attr) {
+ case PKINIT_ID_OPT_USER_IDENTITY:
+ retval = process_option_identity(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx, value);
+ break;
+ case PKINIT_ID_OPT_ANCHOR_CAS:
+ retval = process_option_ca_crl(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx, value,
+ CATYPE_ANCHORS);
+ break;
+ case PKINIT_ID_OPT_INTERMEDIATE_CAS:
+ retval = process_option_ca_crl(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx,
+ value, CATYPE_INTERMEDIATES);
+ break;
+ case PKINIT_ID_OPT_CRLS:
+ retval = process_option_ca_crl(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx,
+ value, CATYPE_CRLS);
+ break;
+ case PKINIT_ID_OPT_OCSP:
+ retval = ENOTSUP;
+ break;
+ default:
+ retval = EINVAL;
+ break;
+ }
+ return retval;
+}
+
+krb5_error_code
+pkinit_identity_initialize(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_opts *idopts,
+ pkinit_identity_crypto_context id_cryptoctx,
+ int do_matching,
+ krb5_principal princ)
+{
+ krb5_error_code retval = EINVAL;
+ int i;
+
+ pkiDebug("%s: %p %p %p\n", __FUNCTION__, context, idopts, id_cryptoctx);
+ if (idopts == NULL || id_cryptoctx == NULL)
+ goto errout;
+
+ /*
+ * If identity was specified, use that. (For the kdc, this
+ * is specified as pkinit_identity in the kdc.conf. For users,
+ * this is specified on the command line via X509_user_identity.)
+ * If a user did not specify identity on the command line,
+ * then we will try alternatives which may have been specified
+ * in the config file.
+ */
+ if (idopts->identity != NULL) {
+ retval = pkinit_identity_process_option(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx,
+ PKINIT_ID_OPT_USER_IDENTITY,
+ idopts->identity);
+ } else if (idopts->identity_alt != NULL) {
+ for (i = 0; retval != 0 && idopts->identity_alt[i] != NULL; i++)
+ retval = pkinit_identity_process_option(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx,
+ PKINIT_ID_OPT_USER_IDENTITY,
+ idopts->identity_alt[i]);
+ } else {
+ pkiDebug("%s: no user identity options specified\n", __FUNCTION__);
+ goto errout;
+ }
+ if (retval)
+ goto errout;
+
+ retval = crypto_load_certs(context, plg_cryptoctx, req_cryptoctx,
+ idopts, id_cryptoctx, princ);
+ if (retval)
+ goto errout;
+
+ if (do_matching) {
+ retval = pkinit_cert_matching(context, plg_cryptoctx, req_cryptoctx,
+ id_cryptoctx, princ);
+ if (retval) {
+ pkiDebug("%s: No matching certificate found\n", __FUNCTION__);
+ (void) crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
+ id_cryptoctx);
+ goto errout;
+ }
+ } else {
+ /* Tell crypto code to use the "default" */
+ retval = crypto_cert_select_default(context, plg_cryptoctx,
+ req_cryptoctx, id_cryptoctx);
+ if (retval) {
+ pkiDebug("%s: Failed while selecting default certificate\n",
+ __FUNCTION__);
+ (void) crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
+ id_cryptoctx);
+ goto errout;
+ }
+ }
+
+ retval = crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
+ id_cryptoctx);
+ if (retval)
+ goto errout;
+
+ for (i = 0; idopts->anchors != NULL && idopts->anchors[i] != NULL; i++) {
+ retval = pkinit_identity_process_option(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx,
+ PKINIT_ID_OPT_ANCHOR_CAS,
+ idopts->anchors[i]);
+ if (retval)
+ goto errout;
+ }
+ for (i = 0; idopts->intermediates != NULL
+ && idopts->intermediates[i] != NULL; i++) {
+ retval = pkinit_identity_process_option(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx,
+ PKINIT_ID_OPT_INTERMEDIATE_CAS,
+ idopts->intermediates[i]);
+ if (retval)
+ goto errout;
+ }
+ for (i = 0; idopts->crls != NULL && idopts->crls[i] != NULL; i++) {
+ retval = pkinit_identity_process_option(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx,
+ PKINIT_ID_OPT_CRLS,
+ idopts->crls[i]);
+ if (retval)
+ goto errout;
+ }
+ if (idopts->ocsp != NULL) {
+ retval = pkinit_identity_process_option(context, plg_cryptoctx,
+ req_cryptoctx, idopts,
+ id_cryptoctx,
+ PKINIT_ID_OPT_OCSP,
+ idopts->ocsp);
+ if (retval)
+ goto errout;
+ }
+
+errout:
+ return retval;
+}
+
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_lib.c b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_lib.c
new file mode 100644
index 0000000000..fb6e4feada
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_lib.c
@@ -0,0 +1,479 @@
+/*
+ * COPYRIGHT (C) 2006,2007
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "pkinit.h"
+
+#define FAKECERT
+
+const krb5_octet_data
+ dh_oid = { 0, 7, (unsigned char *)"\x2A\x86\x48\xce\x3e\x02\x01" };
+
+
+krb5_error_code
+pkinit_init_req_opts(pkinit_req_opts **reqopts)
+{
+ krb5_error_code retval = ENOMEM;
+ pkinit_req_opts *opts = NULL;
+
+ *reqopts = NULL;
+ opts = (pkinit_req_opts *) calloc(1, sizeof(pkinit_req_opts));
+ if (opts == NULL)
+ return retval;
+
+ opts->require_eku = 1;
+ opts->accept_secondary_eku = 0;
+ opts->allow_upn = 0;
+ opts->dh_or_rsa = DH_PROTOCOL;
+ opts->require_crl_checking = 0;
+ opts->dh_size = PKINIT_DEFAULT_DH_MIN_BITS;
+ opts->win2k_target = 0;
+ opts->win2k_require_cksum = 0;
+
+ *reqopts = opts;
+
+ return 0;
+}
+
+void
+pkinit_fini_req_opts(pkinit_req_opts *opts)
+{
+ if (opts != NULL)
+ free(opts);
+ return;
+}
+
+krb5_error_code
+pkinit_init_plg_opts(pkinit_plg_opts **plgopts)
+{
+ krb5_error_code retval = ENOMEM;
+ pkinit_plg_opts *opts = NULL;
+
+ *plgopts = NULL;
+ opts = (pkinit_plg_opts *) calloc(1, sizeof(pkinit_plg_opts));
+ if (opts == NULL)
+ return retval;
+
+ opts->require_eku = 1;
+ opts->accept_secondary_eku = 0;
+ opts->dh_or_rsa = DH_PROTOCOL;
+ opts->allow_upn = 0;
+ opts->require_crl_checking = 0;
+
+ opts->dh_min_bits = PKINIT_DEFAULT_DH_MIN_BITS;
+
+ *plgopts = opts;
+
+ return 0;
+}
+
+void
+pkinit_fini_plg_opts(pkinit_plg_opts *opts)
+{
+ if (opts != NULL)
+ free(opts);
+ return;
+}
+
+void
+free_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in)
+{
+ if (*in == NULL) return;
+ if ((*in)->signedAuthPack.data != NULL)
+ free((*in)->signedAuthPack.data);
+ if ((*in)->trustedCertifiers != NULL)
+ free_krb5_external_principal_identifier(&(*in)->trustedCertifiers);
+ if ((*in)->kdcPkId.data != NULL)
+ free((*in)->kdcPkId.data);
+ free(*in);
+}
+
+void
+free_krb5_pa_pk_as_req_draft9(krb5_pa_pk_as_req_draft9 **in)
+{
+ if (*in == NULL) return;
+ if ((*in)->signedAuthPack.data != NULL)
+ free((*in)->signedAuthPack.data);
+ if ((*in)->kdcCert.data != NULL)
+ free((*in)->kdcCert.data);
+ if ((*in)->encryptionCert.data != NULL)
+ free((*in)->encryptionCert.data);
+ if ((*in)->trustedCertifiers != NULL)
+ free_krb5_trusted_ca(&(*in)->trustedCertifiers);
+ free(*in);
+}
+
+void
+free_krb5_reply_key_pack(krb5_reply_key_pack **in)
+{
+ if (*in == NULL) return;
+ if ((*in)->replyKey.contents != NULL)
+ free((*in)->replyKey.contents);
+ if ((*in)->asChecksum.contents != NULL)
+ free((*in)->asChecksum.contents);
+ free(*in);
+}
+
+void
+free_krb5_reply_key_pack_draft9(krb5_reply_key_pack_draft9 **in)
+{
+ if (*in == NULL) return;
+ if ((*in)->replyKey.contents != NULL)
+ free((*in)->replyKey.contents);
+ free(*in);
+}
+
+void
+free_krb5_auth_pack(krb5_auth_pack **in)
+{
+ if ((*in) == NULL) return;
+ if ((*in)->clientPublicValue != NULL) {
+ if ((*in)->clientPublicValue->algorithm.algorithm.data != NULL)
+ free((*in)->clientPublicValue->algorithm.algorithm.data);
+ if ((*in)->clientPublicValue->algorithm.parameters.data != NULL)
+ free((*in)->clientPublicValue->algorithm.parameters.data);
+ if ((*in)->clientPublicValue->subjectPublicKey.data != NULL)
+ free((*in)->clientPublicValue->subjectPublicKey.data);
+ free((*in)->clientPublicValue);
+ }
+ if ((*in)->pkAuthenticator.paChecksum.contents != NULL)
+ free((*in)->pkAuthenticator.paChecksum.contents);
+ if ((*in)->supportedCMSTypes != NULL)
+ free_krb5_algorithm_identifiers(&((*in)->supportedCMSTypes));
+ free(*in);
+}
+
+void
+free_krb5_auth_pack_draft9(krb5_context context,
+ krb5_auth_pack_draft9 **in)
+{
+ if ((*in) == NULL) return;
+ krb5_free_principal(context, (*in)->pkAuthenticator.kdcName);
+ free(*in);
+}
+
+void
+free_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in)
+{
+ if (*in == NULL) return;
+ switch ((*in)->choice) {
+ case choice_pa_pk_as_rep_dhInfo:
+ if ((*in)->u.dh_Info.dhSignedData.data != NULL)
+ free((*in)->u.dh_Info.dhSignedData.data);
+ break;
+ case choice_pa_pk_as_rep_encKeyPack:
+ if ((*in)->u.encKeyPack.data != NULL)
+ free((*in)->u.encKeyPack.data);
+ break;
+ default:
+ break;
+ }
+ free(*in);
+}
+
+void
+free_krb5_pa_pk_as_rep_draft9(krb5_pa_pk_as_rep_draft9 **in)
+{
+ if (*in == NULL) return;
+ if ((*in)->u.encKeyPack.data != NULL)
+ free((*in)->u.encKeyPack.data);
+ free(*in);
+}
+
+void
+free_krb5_external_principal_identifier(krb5_external_principal_identifier ***in)
+{
+ int i = 0;
+ if (*in == NULL) return;
+ while ((*in)[i] != NULL) {
+ if ((*in)[i]->subjectName.data != NULL)
+ free((*in)[i]->subjectName.data);
+ if ((*in)[i]->issuerAndSerialNumber.data != NULL)
+ free((*in)[i]->issuerAndSerialNumber.data);
+ if ((*in)[i]->subjectKeyIdentifier.data != NULL)
+ free((*in)[i]->subjectKeyIdentifier.data);
+ free((*in)[i]);
+ i++;
+ }
+ free(*in);
+}
+
+void
+free_krb5_trusted_ca(krb5_trusted_ca ***in)
+{
+ int i = 0;
+ if (*in == NULL) return;
+ while ((*in)[i] != NULL) {
+ switch((*in)[i]->choice) {
+ case choice_trusted_cas_principalName:
+ break;
+ case choice_trusted_cas_caName:
+ if ((*in)[i]->u.caName.data != NULL)
+ free((*in)[i]->u.caName.data);
+ break;
+ case choice_trusted_cas_issuerAndSerial:
+ if ((*in)[i]->u.issuerAndSerial.data != NULL)
+ free((*in)[i]->u.issuerAndSerial.data);
+ break;
+ case choice_trusted_cas_UNKNOWN:
+ break;
+ }
+ free((*in)[i]);
+ i++;
+ }
+ free(*in);
+}
+
+void
+free_krb5_typed_data(krb5_typed_data ***in)
+{
+ int i = 0;
+ if (*in == NULL) return;
+ while ((*in)[i] != NULL) {
+ if ((*in)[i]->data != NULL)
+ free((*in)[i]->data);
+ free((*in)[i]);
+ i++;
+ }
+ free(*in);
+}
+
+void
+free_krb5_algorithm_identifier(krb5_algorithm_identifier *in)
+{
+ if (in == NULL)
+ return;
+ if (in->algorithm.data != NULL)
+ free(in->algorithm.data);
+ if (in->parameters.data != NULL)
+ free(in->parameters.data);
+ free(in);
+}
+
+void
+free_krb5_algorithm_identifiers(krb5_algorithm_identifier ***in)
+{
+ int i;
+ if (in == NULL || *in == NULL)
+ return;
+ for (i = 0; (*in)[i] != NULL; i++) {
+ free_krb5_algorithm_identifier((*in)[i]);
+ }
+ free(*in);
+}
+
+void
+free_krb5_subject_pk_info(krb5_subject_pk_info **in)
+{
+ if ((*in) == NULL) return;
+ if ((*in)->algorithm.parameters.data != NULL)
+ free((*in)->algorithm.parameters.data);
+ if ((*in)->subjectPublicKey.data != NULL)
+ free((*in)->subjectPublicKey.data);
+ free(*in);
+}
+
+void
+free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in)
+{
+ if (*in == NULL) return;
+ if ((*in)->subjectPublicKey.data != NULL)
+ free((*in)->subjectPublicKey.data);
+ free(*in);
+}
+
+void
+init_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in)
+{
+ (*in) = malloc(sizeof(krb5_pa_pk_as_req));
+ if ((*in) == NULL) return;
+ (*in)->signedAuthPack.data = NULL;
+ (*in)->signedAuthPack.length = 0;
+ (*in)->trustedCertifiers = NULL;
+ (*in)->kdcPkId.data = NULL;
+ (*in)->kdcPkId.length = 0;
+}
+
+void
+init_krb5_pa_pk_as_req_draft9(krb5_pa_pk_as_req_draft9 **in)
+{
+ (*in) = malloc(sizeof(krb5_pa_pk_as_req_draft9));
+ if ((*in) == NULL) return;
+ (*in)->signedAuthPack.data = NULL;
+ (*in)->signedAuthPack.length = 0;
+ (*in)->trustedCertifiers = NULL;
+ (*in)->kdcCert.data = NULL;
+ (*in)->kdcCert.length = 0;
+ (*in)->encryptionCert.data = NULL;
+ (*in)->encryptionCert.length = 0;
+}
+
+void
+init_krb5_reply_key_pack(krb5_reply_key_pack **in)
+{
+ (*in) = malloc(sizeof(krb5_reply_key_pack));
+ if ((*in) == NULL) return;
+ (*in)->replyKey.contents = NULL;
+ (*in)->replyKey.length = 0;
+ (*in)->asChecksum.contents = NULL;
+ (*in)->asChecksum.length = 0;
+}
+
+void
+init_krb5_reply_key_pack_draft9(krb5_reply_key_pack_draft9 **in)
+{
+ (*in) = malloc(sizeof(krb5_reply_key_pack_draft9));
+ if ((*in) == NULL) return;
+ (*in)->replyKey.contents = NULL;
+ (*in)->replyKey.length = 0;
+}
+
+void
+init_krb5_auth_pack(krb5_auth_pack **in)
+{
+ (*in) = malloc(sizeof(krb5_auth_pack));
+ if ((*in) == NULL) return;
+ (*in)->clientPublicValue = NULL;
+ (*in)->supportedCMSTypes = NULL;
+ (*in)->clientDHNonce.length = 0;
+ (*in)->clientDHNonce.data = NULL;
+ (*in)->pkAuthenticator.paChecksum.contents = NULL;
+}
+
+void
+init_krb5_auth_pack_draft9(krb5_auth_pack_draft9 **in)
+{
+ (*in) = malloc(sizeof(krb5_auth_pack_draft9));
+ if ((*in) == NULL) return;
+ (*in)->clientPublicValue = NULL;
+}
+
+void
+init_krb5_pa_pk_as_rep(krb5_pa_pk_as_rep **in)
+{
+ (*in) = malloc(sizeof(krb5_pa_pk_as_rep));
+ if ((*in) == NULL) return;
+ (*in)->u.dh_Info.serverDHNonce.length = 0;
+ (*in)->u.dh_Info.serverDHNonce.data = NULL;
+ (*in)->u.dh_Info.dhSignedData.length = 0;
+ (*in)->u.dh_Info.dhSignedData.data = NULL;
+ (*in)->u.encKeyPack.length = 0;
+ (*in)->u.encKeyPack.data = NULL;
+}
+
+void
+init_krb5_pa_pk_as_rep_draft9(krb5_pa_pk_as_rep_draft9 **in)
+{
+ (*in) = malloc(sizeof(krb5_pa_pk_as_rep_draft9));
+ if ((*in) == NULL) return;
+ (*in)->u.dhSignedData.length = 0;
+ (*in)->u.dhSignedData.data = NULL;
+ (*in)->u.encKeyPack.length = 0;
+ (*in)->u.encKeyPack.data = NULL;
+}
+
+void
+init_krb5_typed_data(krb5_typed_data **in)
+{
+ (*in) = malloc(sizeof(krb5_typed_data));
+ if ((*in) == NULL) return;
+ (*in)->type = 0;
+ (*in)->length = 0;
+ (*in)->data = NULL;
+}
+
+void
+init_krb5_subject_pk_info(krb5_subject_pk_info **in)
+{
+ (*in) = malloc(sizeof(krb5_subject_pk_info));
+ if ((*in) == NULL) return;
+ (*in)->algorithm.parameters.data = NULL;
+ (*in)->algorithm.parameters.length = 0;
+ (*in)->subjectPublicKey.data = NULL;
+ (*in)->subjectPublicKey.length = 0;
+}
+
+krb5_error_code
+pkinit_copy_krb5_octet_data(krb5_octet_data *dst, const krb5_octet_data *src)
+{
+ if (dst == NULL || src == NULL)
+ return EINVAL;
+ if (src->data == NULL) {
+ dst->data = NULL;
+ dst->length = 0;
+ return 0;
+ }
+ dst->data = malloc(src->length);
+ if (dst->data == NULL)
+ return ENOMEM;
+ (void) memcpy(dst->data, src->data, src->length);
+ dst->length = src->length;
+ return 0;
+}
+
+/* debugging functions */
+void
+print_buffer(unsigned char *buf, unsigned int len)
+{
+ int i = 0;
+ /* Solaris Kerberos: len is unsigned (lint) */
+ if (len == 0)
+ return;
+
+ for (i = 0; i < len; i++)
+ pkiDebug("%02x ", buf[i]);
+ pkiDebug("\n");
+}
+
+void
+print_buffer_bin(unsigned char *buf, unsigned int len, char *filename)
+{
+ FILE *f = NULL;
+ int i = 0;
+
+ /* Solaris Kerberos: len is unsigned (lint) */
+ if (len == 0 || filename == NULL)
+ return;
+
+ if ((f = fopen(filename, "w")) == NULL)
+ return;
+
+ for (i = 0; i < len; i++)
+ (void) fputc(buf[i], f);
+
+ (void) fclose(f);
+}
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_matching.c b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_matching.c
new file mode 100644
index 0000000000..781e42cc34
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_matching.c
@@ -0,0 +1,843 @@
+/*
+ * COPYRIGHT (C) 2007
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <regex.h>
+#include <krb5.h>
+#include "pkinit.h"
+
+typedef struct _pkinit_cert_info pkinit_cert_info;
+
+typedef enum {
+ kw_undefined = 0,
+ kw_subject = 1,
+ kw_issuer = 2,
+ kw_san = 3,
+ kw_eku = 4,
+ kw_ku = 5
+} keyword_type;
+
+static char *
+keyword2string(unsigned int kw)
+{
+ /* Solaris Kerberos: removed "break"s (lint) */
+ switch(kw) {
+ case kw_undefined: return "NONE";
+ case kw_subject: return "SUBJECT";
+ case kw_issuer: return "ISSUER";
+ case kw_san: return "SAN";
+ case kw_eku: return "EKU";
+ case kw_ku: return "KU";
+ default: return "INVALID";
+ }
+}
+typedef enum {
+ relation_none = 0,
+ relation_and = 1,
+ relation_or = 2
+} relation_type;
+
+static char *
+relation2string(unsigned int rel)
+{
+ /* Solaris Kerberos: removed "break"s (lint) */
+ switch(rel) {
+ case relation_none: return "NONE";
+ case relation_and: return "AND";
+ case relation_or: return "OR";
+ default: return "INVALID";
+ }
+}
+
+typedef enum {
+ kwvaltype_undefined = 0,
+ kwvaltype_regexp = 1,
+ kwvaltype_list = 2
+} kw_value_type;
+
+static char *
+kwval2string(unsigned int kwval)
+{
+ /* Solaris Kerberos: removed "break"s (lint) */
+ switch(kwval) {
+ case kwvaltype_undefined: return "NONE";
+ case kwvaltype_regexp: return "REGEXP";
+ case kwvaltype_list: return "LIST";
+ default: return "INVALID";
+ }
+}
+
+struct keyword_desc {
+ const char *value;
+ size_t length;
+ keyword_type kwtype;
+ kw_value_type kwvaltype;
+} matching_keywords[] = {
+ { "<KU>", 4, kw_ku, kwvaltype_list },
+ { "<EKU>", 5, kw_eku, kwvaltype_list },
+ { "<SAN>", 5, kw_san, kwvaltype_regexp },
+ { "<ISSUER>", 8, kw_issuer, kwvaltype_regexp },
+ { "<SUBJECT>", 9, kw_subject, kwvaltype_regexp },
+ { NULL, 0, kw_undefined, kwvaltype_undefined},
+};
+
+struct ku_desc {
+ const char *value;
+ size_t length;
+ unsigned int bitval;
+};
+
+struct ku_desc ku_keywords[] = {
+ { "digitalSignature", 16, PKINIT_KU_DIGITALSIGNATURE },
+ { "keyEncipherment", 15, PKINIT_KU_KEYENCIPHERMENT },
+ { NULL, 0, 0 },
+};
+
+struct ku_desc eku_keywords[] = {
+ { "pkinit", 6, PKINIT_EKU_PKINIT },
+ { "msScLogin", 9, PKINIT_EKU_MSSCLOGIN },
+ { "clientAuth", 10, PKINIT_EKU_CLIENTAUTH },
+ { "emailProtection", 15, PKINIT_EKU_EMAILPROTECTION },
+ { NULL, 0, 0 },
+};
+
+/* Rule component */
+typedef struct _rule_component {
+ struct _rule_component *next;
+ keyword_type kw_type;
+ kw_value_type kwval_type;
+ regex_t regexp; /* Compiled regular expression */
+ char *regsrc; /* The regular expression source (for debugging) */
+ unsigned int ku_bits;
+ unsigned int eku_bits;
+} rule_component;
+
+/* Set rule components */
+typedef struct _rule_set {
+ relation_type relation;
+ int num_crs;
+ rule_component *crs;
+} rule_set;
+
+/* ARGSUSED */
+static krb5_error_code
+free_rule_component(krb5_context context,
+ rule_component *rc)
+{
+ if (rc == NULL)
+ return 0;
+
+ if (rc->kwval_type == kwvaltype_regexp) {
+ if (rc->regsrc)
+ free(rc->regsrc);
+ regfree(&rc->regexp);
+ }
+ free(rc);
+ return 0;
+}
+
+static krb5_error_code
+free_rule_set(krb5_context context,
+ rule_set *rs)
+{
+ rule_component *rc, *trc;
+
+ if (rs == NULL)
+ return 0;
+ for (rc = rs->crs; rc != NULL;) {
+ trc = rc->next;
+ /* Solaris Kerberos */
+ (void) free_rule_component(context, rc);
+ rc = trc;
+ }
+ free(rs);
+ return 0;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+parse_list_value(krb5_context context,
+ keyword_type type,
+ char *value,
+ rule_component *rc)
+{
+ krb5_error_code retval;
+ char *comma;
+ struct ku_desc *ku = NULL;
+ int found;
+ size_t len;
+ unsigned int *bitptr;
+
+
+ if (value == NULL || value[0] == '\0') {
+ pkiDebug("%s: Missing or empty value for list keyword type %d\n",
+ __FUNCTION__, type);
+ retval = EINVAL;
+ goto out;
+ }
+
+ if (type == kw_eku) {
+ bitptr = &rc->eku_bits;
+ } else if (type == kw_ku) {
+ bitptr = &rc->ku_bits;
+ } else {
+ pkiDebug("%s: Unknown list keyword type %d\n", __FUNCTION__, type);
+ retval = EINVAL;
+ goto out;
+ }
+
+ do {
+ found = 0;
+ comma = strchr(value, ',');
+ if (comma != NULL)
+ len = comma - value;
+ else
+ len = strlen(value);
+
+ if (type == kw_eku) {
+ ku = eku_keywords;
+ } else if (type == kw_ku) {
+ ku = ku_keywords;
+ }
+
+ for (; ku->value != NULL; ku++) {
+ if (strncasecmp(value, ku->value, len) == 0) {
+ *bitptr |= ku->bitval;
+ found = 1;
+ pkiDebug("%s: Found value '%s', bitfield is now 0x%x\n",
+ __FUNCTION__, ku->value, *bitptr);
+ break;
+ }
+ }
+ if (found) {
+ value += ku->length;
+ if (*value == ',')
+ value += 1;
+ } else {
+ pkiDebug("%s: Urecognized value '%s'\n", __FUNCTION__, value);
+ retval = EINVAL;
+ goto out;
+ }
+ } while (found && *value != '\0');
+
+ retval = 0;
+out:
+ pkiDebug("%s: returning %d\n", __FUNCTION__, retval);
+ return retval;
+}
+
+static krb5_error_code
+parse_rule_component(krb5_context context,
+ const char **rule,
+ int *remaining,
+ rule_component **ret_rule)
+{
+ krb5_error_code retval;
+ rule_component *rc = NULL;
+ keyword_type kw_type;
+ kw_value_type kwval_type;
+ char err_buf[128];
+ int ret;
+ struct keyword_desc *kw, *nextkw;
+ char *nk;
+ int found_next_kw = 0;
+ char *value = NULL;
+ size_t len;
+
+ for (kw = matching_keywords; kw->value != NULL; kw++) {
+ if (strncmp(*rule, kw->value, kw->length) == 0) {
+ kw_type = kw->kwtype;
+ kwval_type = kw->kwvaltype;
+ *rule += kw->length;
+ *remaining -= kw->length;
+ break;
+ }
+ }
+ if (kw->value == NULL) {
+ pkiDebug("%s: Missing or invalid keyword in rule '%s'\n",
+ __FUNCTION__, *rule);
+ retval = ENOENT;
+ goto out;
+ }
+
+ pkiDebug("%s: found keyword '%s'\n", __FUNCTION__, kw->value);
+
+ rc = calloc(1, sizeof(*rc));
+ if (rc == NULL) {
+ retval = ENOMEM;
+ goto out;
+ }
+ rc->next = NULL;
+ rc->kw_type = kw_type;
+ rc->kwval_type = kwval_type;
+
+ /*
+ * Before procesing the value for this keyword,
+ * (compiling the regular expression or processing the list)
+ * we need to find the end of it. That means parsing for the
+ * beginning of the next keyword (or the end of the rule).
+ */
+ nk = strchr(*rule, '<');
+ while (nk != NULL) {
+ /* Possibly another keyword, check it out */
+ for (nextkw = matching_keywords; nextkw->value != NULL; nextkw++) {
+ if (strncmp(nk, nextkw->value, nextkw->length) == 0) {
+ /* Found a keyword, nk points to the beginning */
+ found_next_kw = 1;
+ break; /* Need to break out of the while! */
+ }
+ }
+ if (!found_next_kw)
+ nk = strchr(nk+1, '<'); /* keep looking */
+ else
+ break;
+ }
+
+ if (nk != NULL && found_next_kw)
+ len = (nk - *rule);
+ else
+ len = (*remaining);
+
+ if (len == 0) {
+ pkiDebug("%s: Missing value for keyword '%s'\n",
+ __FUNCTION__, kw->value);
+ retval = EINVAL;
+ goto out;
+ }
+
+ value = calloc(1, len+1);
+ if (value == NULL) {
+ retval = ENOMEM;
+ goto out;
+ }
+ (void) memcpy(value, *rule, len);
+ *remaining -= len;
+ *rule += len;
+ pkiDebug("%s: found value '%s'\n", __FUNCTION__, value);
+
+ if (kw->kwvaltype == kwvaltype_regexp) {
+ ret = regcomp(&rc->regexp, value, REG_EXTENDED);
+ if (ret) {
+ (void) regerror(ret, &rc->regexp, err_buf, sizeof(err_buf));
+ pkiDebug("%s: Error compiling reg-exp '%s': %s\n",
+ __FUNCTION__, value, err_buf);
+ retval = ret;
+ goto out;
+ }
+ rc->regsrc = strdup(value);
+ if (rc->regsrc == NULL) {
+ retval = ENOMEM;
+ goto out;
+ }
+ } else if (kw->kwvaltype == kwvaltype_list) {
+ retval = parse_list_value(context, rc->kw_type, value, rc);
+ if (retval) {
+ pkiDebug("%s: Error %d, parsing list values for keyword %s\n",
+ __FUNCTION__, retval, kw->value);
+ goto out;
+ }
+ }
+
+ *ret_rule = rc;
+ retval = 0;
+out:
+ if (value != NULL)
+ free(value);
+ if (retval && rc != NULL)
+ (void) free_rule_component(context, rc);
+ pkiDebug("%s: returning %d\n", __FUNCTION__, retval);
+ return retval;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+parse_rule_set(krb5_context context,
+ const char *rule_in,
+ rule_set **out_rs)
+{
+ const char *rule;
+ /* Solaris Kerberos */
+ int remaining;
+ krb5_error_code ret, retval;
+ rule_component *rc = NULL, *trc;
+ rule_set *rs;
+
+
+ if (rule_in == NULL)
+ return EINVAL;
+ rule = rule_in;
+ /* Solaris Kerberos */
+ remaining = strlen(rule);
+
+ rs = calloc(1, sizeof(*rs));
+ if (rs == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+
+ rs->relation = relation_none;
+ if (remaining > 1) {
+ if (rule[0] == '&' && rule[1] == '&') {
+ rs->relation = relation_and;
+ rule += 2;
+ remaining -= 2;
+ } else if (rule_in[0] == '|' && rule_in[1] == '|') {
+ rs->relation = relation_or;
+ rule +=2;
+ remaining -= 2;
+ }
+ }
+ rs->num_crs = 0;
+ while (remaining > 0) {
+ if (rs->relation == relation_none && rs->num_crs > 1) {
+ pkiDebug("%s: Assuming AND relation for multiple components in rule '%s'\n",
+ __FUNCTION__, rule_in);
+ rs->relation = relation_and;
+ }
+ ret = parse_rule_component(context, &rule, &remaining, &rc);
+ if (ret) {
+ retval = ret;
+ goto cleanup;
+ }
+ pkiDebug("%s: After parse_rule_component, remaining %d, rule '%s'\n",
+ __FUNCTION__, remaining, rule);
+ rs->num_crs++;
+
+ /*
+ * Chain the new component on the end (order matters since
+ * we can short-circuit an OR or an AND relation if an
+ * earlier check passes
+ */
+ for (trc = rs->crs; trc != NULL && trc->next != NULL; trc = trc->next);
+ if (trc == NULL)
+ rs->crs = rc;
+ else {
+ trc->next = rc;
+ }
+ }
+
+ *out_rs = rs;
+
+ retval = 0;
+cleanup:
+ if (retval && rs != NULL) {
+ (void) free_rule_set(context, rs);
+ }
+ pkiDebug("%s: returning %d\n", __FUNCTION__, retval);
+ return retval;
+}
+
+/* ARGSUSED */
+static int
+regexp_match(krb5_context context, rule_component *rc, char *value)
+{
+ int code;
+
+ pkiDebug("%s: checking %s rule '%s' with value '%s'\n",
+ __FUNCTION__, keyword2string(rc->kw_type), rc->regsrc, value);
+
+ code = regexec(&rc->regexp, value, 0, NULL, 0);
+
+ pkiDebug("%s: the result is%s a match\n", __FUNCTION__,
+ code == REG_NOMATCH ? " NOT" : "");
+
+ return (code == 0 ? 1: 0);
+}
+
+static int
+component_match(krb5_context context,
+ rule_component *rc,
+ pkinit_cert_matching_data *md)
+{
+ int match = 0;
+ int i;
+ krb5_principal p;
+ char *princ_string;
+
+ switch (rc->kwval_type) {
+ case kwvaltype_regexp:
+ switch (rc->kw_type) {
+ case kw_subject:
+ match = regexp_match(context, rc, md->subject_dn);
+ break;
+ case kw_issuer:
+ match = regexp_match(context, rc, md->issuer_dn);
+ break;
+ case kw_san:
+ if (md->sans == NULL)
+ break;
+ for (i = 0, p = md->sans[i]; p != NULL; p = md->sans[++i]) {
+ krb5_unparse_name(context, p, &princ_string);
+ match = regexp_match(context, rc, princ_string);
+ krb5_free_unparsed_name(context, princ_string);
+ if (match)
+ break;
+ }
+ break;
+ default:
+ pkiDebug("%s: keyword %s, keyword value %s mismatch\n",
+ __FUNCTION__, keyword2string(rc->kw_type),
+ kwval2string(kwvaltype_regexp));
+ break;
+ }
+ break;
+ case kwvaltype_list:
+ switch(rc->kw_type) {
+ case kw_eku:
+ pkiDebug("%s: checking %s: rule 0x%08x, cert 0x%08x\n",
+ __FUNCTION__, keyword2string(rc->kw_type),
+ rc->eku_bits, md->eku_bits);
+ if ((rc->eku_bits & md->eku_bits) == rc->eku_bits)
+ match = 1;
+ break;
+ case kw_ku:
+ pkiDebug("%s: checking %s: rule 0x%08x, cert 0x%08x\n",
+ __FUNCTION__, keyword2string(rc->kw_type),
+ rc->ku_bits, md->ku_bits);
+ if ((rc->ku_bits & md->ku_bits) == rc->ku_bits)
+ match = 1;
+ break;
+ default:
+ pkiDebug("%s: keyword %s, keyword value %s mismatch\n",
+ __FUNCTION__, keyword2string(rc->kw_type),
+ kwval2string(kwvaltype_regexp));
+ break;
+ }
+ break;
+ default:
+ pkiDebug("%s: unknown keyword value type %d\n",
+ __FUNCTION__, rc->kwval_type);
+ break;
+ }
+ pkiDebug("%s: returning match = %d\n", __FUNCTION__, match);
+ return match;
+}
+/*
+ * Returns match_found == 1 only if exactly one certificate matches
+ * the given rule
+ */
+/* ARGSUSED */
+static krb5_error_code
+check_all_certs(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_principal princ,
+ rule_set *rs, /* rule to check */
+ pkinit_cert_matching_data **matchdata,
+ int *match_found,
+ pkinit_cert_matching_data **matching_cert)
+{
+ krb5_error_code retval;
+ pkinit_cert_matching_data *md;
+ int i;
+ int comp_match = 0;
+ int total_cert_matches = 0;
+ rule_component *rc;
+ int certs_checked = 0;
+ pkinit_cert_matching_data *save_match = NULL;
+
+ if (match_found == NULL || matching_cert == NULL)
+ return EINVAL;
+
+ *matching_cert = NULL;
+ *match_found = 0;
+
+ pkiDebug("%s: matching rule relation is %s with %d components\n",
+ __FUNCTION__, relation2string(rs->relation), rs->num_crs);
+
+ /*
+ * Loop through all the certs available and count
+ * how many match the rule
+ */
+ for (i = 0, md = matchdata[i]; md != NULL; md = matchdata[++i]) {
+ pkiDebug("%s: subject: '%s'\n", __FUNCTION__, md->subject_dn);
+#if 0
+ pkiDebug("%s: issuer: '%s'\n", __FUNCTION__, md->subject_dn);
+ for (j = 0, p = md->sans[j]; p != NULL; p = md->sans[++j]) {
+ char *san_string;
+ krb5_unparse_name(context, p, &san_string);
+ pkiDebug("%s: san: '%s'\n", __FUNCTION__, san_string);
+ krb5_free_unparsed_name(context, san_string);
+ }
+#endif
+ certs_checked++;
+ for (rc = rs->crs; rc != NULL; rc = rc->next) {
+ comp_match = component_match(context, rc, md);
+ if (comp_match) {
+ pkiDebug("%s: match for keyword type %s\n",
+ __FUNCTION__, keyword2string(rc->kw_type));
+ }
+ if (comp_match && rs->relation == relation_or) {
+ pkiDebug("%s: cert matches rule (OR relation)\n",
+ __FUNCTION__);
+ total_cert_matches++;
+ save_match = md;
+ goto nextcert;
+ }
+ if (!comp_match && rs->relation == relation_and) {
+ pkiDebug("%s: cert does not match rule (AND relation)\n",
+ __FUNCTION__);
+ goto nextcert;
+ }
+ }
+ if (rc == NULL && comp_match) {
+ pkiDebug("%s: cert matches rule (AND relation)\n", __FUNCTION__);
+ total_cert_matches++;
+ save_match = md;
+ }
+nextcert:
+ continue;
+ }
+ pkiDebug("%s: After checking %d certs, we found %d matches\n",
+ __FUNCTION__, certs_checked, total_cert_matches);
+ if (total_cert_matches == 1) {
+ *match_found = 1;
+ *matching_cert = save_match;
+ }
+
+ retval = 0;
+
+ pkiDebug("%s: returning %d, match_found %d\n",
+ __FUNCTION__, retval, *match_found);
+ return retval;
+}
+
+static krb5_error_code
+free_all_cert_matching_data(krb5_context context,
+ pkinit_cert_matching_data **matchdata)
+{
+ krb5_error_code retval;
+ pkinit_cert_matching_data *md;
+ int i;
+
+ if (matchdata == NULL)
+ return EINVAL;
+
+ for (i = 0, md = matchdata[i]; md != NULL; md = matchdata[++i]) {
+ pkinit_cert_handle ch = md->ch;
+ retval = crypto_cert_free_matching_data(context, md);
+ if (retval) {
+ pkiDebug("%s: crypto_cert_free_matching_data error %d, %s\n",
+ __FUNCTION__, retval, error_message(retval));
+ goto cleanup;
+ }
+ retval = crypto_cert_release(context, ch);
+ if (retval) {
+ pkiDebug("%s: crypto_cert_release error %d, %s\n",
+ __FUNCTION__, retval, error_message(retval));
+ goto cleanup;
+ }
+ }
+ free(matchdata);
+ retval = 0;
+
+cleanup:
+ return retval;
+}
+
+static krb5_error_code
+obtain_all_cert_matching_data(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ pkinit_cert_matching_data ***all_matching_data)
+{
+ krb5_error_code retval;
+ int i, cert_count;
+ pkinit_cert_iter_handle ih = NULL;
+ pkinit_cert_handle ch;
+ pkinit_cert_matching_data **matchdata = NULL;
+
+ retval = crypto_cert_get_count(context, plg_cryptoctx, req_cryptoctx,
+ id_cryptoctx, &cert_count);
+ if (retval) {
+ pkiDebug("%s: crypto_cert_get_count error %d, %s\n",
+ __FUNCTION__, retval, error_message(retval));
+ goto cleanup;
+ }
+
+ pkiDebug("%s: crypto_cert_get_count says there are %d certs\n",
+ __FUNCTION__, cert_count);
+
+ matchdata = calloc((size_t)cert_count + 1, sizeof(*matchdata));
+ if (matchdata == NULL)
+ return ENOMEM;
+
+ retval = crypto_cert_iteration_begin(context, plg_cryptoctx, req_cryptoctx,
+ id_cryptoctx, &ih);
+ if (retval) {
+ pkiDebug("%s: crypto_cert_iteration_begin returned %d, %s\n",
+ __FUNCTION__, retval, error_message(retval));
+ goto cleanup;
+ }
+
+ for (i = 0; i < cert_count; i++) {
+ retval = crypto_cert_iteration_next(context, ih, &ch);
+ if (retval) {
+ if (retval == PKINIT_ITER_NO_MORE)
+ pkiDebug("%s: We thought there were %d certs, but "
+ "crypto_cert_iteration_next stopped after %d?\n",
+ __FUNCTION__, cert_count, i);
+ else
+ pkiDebug("%s: crypto_cert_iteration_next error %d, %s\n",
+ __FUNCTION__, retval, error_message(retval));
+ goto cleanup;
+ }
+
+ retval = crypto_cert_get_matching_data(context, ch, &matchdata[i]);
+ if (retval) {
+ pkiDebug("%s: crypto_cert_get_matching_data error %d, %s\n",
+ __FUNCTION__, retval, error_message(retval));
+ goto cleanup;
+ }
+
+ }
+
+ *all_matching_data = matchdata;
+ retval = 0;
+cleanup:
+ if (ih != NULL)
+ /* Solaris Kerberos */
+ (void) crypto_cert_iteration_end(context, ih);
+ if (retval) {
+ if (matchdata != NULL)
+ (void) free_all_cert_matching_data(context, matchdata);
+ }
+ pkiDebug("%s: returning %d, certinfo %p\n",
+ __FUNCTION__, retval, *all_matching_data);
+ return retval;
+}
+
+krb5_error_code
+pkinit_cert_matching(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ krb5_principal princ)
+{
+
+ krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ int x;
+ char **rules = NULL;
+ rule_set *rs = NULL;
+ int match_found = 0;
+ pkinit_cert_matching_data **matchdata = NULL;
+ pkinit_cert_matching_data *the_matching_cert = NULL;
+
+ /* If no matching rules, select the default cert and we're done */
+ (void) pkinit_libdefault_strings(context, krb5_princ_realm(context, princ),
+ "pkinit_cert_match", &rules);
+ if (rules == NULL) {
+ pkiDebug("%s: no matching rules found in config file\n", __FUNCTION__);
+ retval = crypto_cert_select_default(context, plg_cryptoctx,
+ req_cryptoctx, id_cryptoctx);
+ goto cleanup;
+ }
+
+ /* parse each rule line one at a time and check all the certs against it */
+ for (x = 0; rules[x] != NULL; x++) {
+ pkiDebug("%s: Processing rule '%s'\n", __FUNCTION__, rules[x]);
+
+ /* Free rules from previous time through... */
+ if (rs != NULL) {
+ (void) free_rule_set(context, rs);
+ rs = NULL;
+ }
+ retval = parse_rule_set(context, rules[x], &rs);
+ if (retval) {
+ if (retval == EINVAL) {
+ pkiDebug("%s: Ignoring invalid rule pkinit_cert_match = '%s'\n",
+ __FUNCTION__, rules[x]);
+ continue;
+ }
+ goto cleanup;
+ }
+
+ /*
+ * Optimize so that we do not get cert info unless we have
+ * valid rules to check. Once obtained, keep it around
+ * until we are done.
+ */
+ if (matchdata == NULL) {
+ retval = obtain_all_cert_matching_data(context, plg_cryptoctx,
+ req_cryptoctx, id_cryptoctx,
+ &matchdata);
+ if (retval || matchdata == NULL) {
+ pkiDebug("%s: Error %d obtaining certificate information\n",
+ __FUNCTION__, retval);
+ retval = ENOENT;
+ goto cleanup;
+ }
+ }
+
+ retval = check_all_certs(context, plg_cryptoctx, req_cryptoctx,
+ id_cryptoctx, princ, rs, matchdata,
+ &match_found, &the_matching_cert);
+ if (retval) {
+ pkiDebug("%s: Error %d, checking certs against rule '%s'\n",
+ __FUNCTION__, retval, rules[x]);
+ goto cleanup;
+ }
+ if (match_found) {
+ pkiDebug("%s: We have an exact match with rule '%s'\n",
+ __FUNCTION__, rules[x]);
+ break;
+ }
+ }
+
+ if (match_found && the_matching_cert != NULL) {
+ pkiDebug("%s: Selecting the matching cert!\n", __FUNCTION__);
+ retval = crypto_cert_select(context, the_matching_cert);
+ if (retval) {
+ pkiDebug("%s: crypto_cert_select error %d, %s\n",
+ __FUNCTION__, retval, error_message(retval));
+ goto cleanup;
+ }
+ } else {
+ retval = ENOENT; /* XXX */
+ goto cleanup;
+ }
+
+ retval = 0;
+cleanup:
+ if (rules != NULL)
+ profile_free_list(rules);
+ if (rs != NULL)
+ /* Solaris Kerberos */
+ (void) free_rule_set(context, rs);
+ if (matchdata != NULL)
+ (void) free_all_cert_matching_data(context, matchdata);
+ return retval;
+}
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_profile.c b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_profile.c
new file mode 100644
index 0000000000..d11bb36f12
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_profile.c
@@ -0,0 +1,380 @@
+/*
+ * COPYRIGHT (C) 2006,2007
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include "k5-int.h"
+#include "pkinit.h"
+
+/*
+ * Routines for handling profile [config file] options
+ */
+
+/* Forward prototypes */
+static int _krb5_conf_boolean(const char *s);
+
+/*
+ * XXX
+ * The following is duplicated verbatim from src/lib/krb5/krb/get_in_tkt.c,
+ * which is duplicated from somewhere else. :-/
+ * XXX
+ */
+static const char *const conf_yes[] = {
+ "y", "yes", "true", "t", "1", "on",
+ 0,
+};
+
+static const char *const conf_no[] = {
+ "n", "no", "false", "nil", "0", "off",
+ 0,
+};
+
+static int
+_krb5_conf_boolean(const char *s)
+{
+ const char *const *p;
+
+ for(p=conf_yes; *p; p++) {
+ if (strcasecmp(*p,s) == 0)
+ return 1;
+ }
+
+ for(p=conf_no; *p; p++) {
+ if (strcasecmp(*p,s) == 0)
+ return 0;
+ }
+
+ /* Default to "no" */
+ return 0;
+}
+
+/*
+ * XXX
+ * End duplicated code from src/lib/krb5/krb/get_in_tkt.c
+ * XXX
+ */
+
+/*
+ * The following are based on krb5_libdefault_* functions in
+ * src/lib/krb5/krb/get_in_tkt.c
+ * N.B. This assumes that context->default_realm has
+ * already been established.
+ */
+krb5_error_code
+pkinit_kdcdefault_strings(krb5_context context, const char *realmname,
+ const char *option, char ***ret_value)
+{
+ profile_t profile = NULL;
+ const char *names[5];
+ char **values = NULL;
+ krb5_error_code retval;
+
+ if (context == NULL)
+ return KV5M_CONTEXT;
+
+ profile = context->profile;
+
+ if (realmname != NULL) {
+ /*
+ * Try number one:
+ *
+ * [realms]
+ * REALM = {
+ * option = <value>
+ * }
+ */
+
+ names[0] = "realms";
+ names[1] = realmname;
+ names[2] = option;
+ names[3] = 0;
+ retval = profile_get_values(profile, names, &values);
+ if (retval == 0 && values != NULL)
+ goto goodbye;
+ }
+
+ /*
+ * Try number two:
+ *
+ * [kdcdefaults]
+ * option = <value>
+ */
+
+ names[0] = "kdcdefaults";
+ names[1] = option;
+ names[2] = 0;
+ retval = profile_get_values(profile, names, &values);
+ if (retval == 0 && values != NULL)
+ goto goodbye;
+
+goodbye:
+ if (values == NULL)
+ retval = ENOENT;
+
+ *ret_value = values;
+
+ return retval;
+
+}
+
+krb5_error_code
+pkinit_kdcdefault_string(krb5_context context, const char *realmname,
+ const char *option, char **ret_value)
+{
+ krb5_error_code retval;
+ char **values = NULL;
+
+ retval = pkinit_kdcdefault_strings(context, realmname, option, &values);
+ if (retval)
+ return retval;
+
+ if (values[0] == NULL) {
+ retval = ENOENT;
+ } else {
+ *ret_value = malloc(strlen(values[0]) + 1);
+ /* Solaris Kerberos */
+ if (*ret_value == NULL) {
+ pkiDebug(error_message(ENOMEM));
+ retval = ENOMEM;
+ }
+ else /* Solaris Kerberos */
+ (void) strlcpy(*ret_value, values[0], strlen(values[0]) + 1);
+ }
+
+ profile_free_list(values);
+ return retval;
+}
+
+krb5_error_code
+pkinit_kdcdefault_boolean(krb5_context context, const char *realmname,
+ const char *option, int default_value, int *ret_value)
+{
+ char *string = NULL;
+ krb5_error_code retval;
+
+ retval = pkinit_kdcdefault_string(context, realmname, option, &string);
+
+ if (retval == 0) {
+ *ret_value = _krb5_conf_boolean(string);
+ free(string);
+ } else
+ *ret_value = default_value;
+
+ return 0;
+}
+
+krb5_error_code
+pkinit_kdcdefault_integer(krb5_context context, const char *realmname,
+ const char *option, int default_value, int *ret_value)
+{
+ char *string = NULL;
+ krb5_error_code retval;
+
+ retval = pkinit_kdcdefault_string(context, realmname, option, &string);
+
+ if (retval == 0) {
+ char *endptr;
+ long l;
+ l = strtol(string, &endptr, 0);
+ if (endptr == string)
+ *ret_value = default_value;
+ else
+ *ret_value = l;
+ free(string);
+ } else
+ *ret_value = default_value;
+
+ return 0;
+}
+
+
+/*
+ * krb5_libdefault_string() is defined as static in
+ * src/lib/krb5/krb/get_in_tkt.c. Create local versions of
+ * krb5_libdefault_* functions here. We need a libdefaults_strings()
+ * function which is not currently supported there anyway. Also,
+ * add the ability to supply a default value for the boolean and
+ * integer functions.
+ */
+
+krb5_error_code
+pkinit_libdefault_strings(krb5_context context, const krb5_data *realm,
+ const char *option, char ***ret_value)
+{
+ profile_t profile;
+ const char *names[5];
+ char **values = NULL;
+ krb5_error_code retval;
+ char realmstr[1024];
+
+ if (realm != NULL && realm->length > sizeof(realmstr)-1)
+ return EINVAL;
+
+ if (realm != NULL) {
+ /* Solaris Kerberos */
+ (void) strlcpy(realmstr, realm->data, realm->length + 1);
+ realmstr[realm->length] = '\0';
+ }
+
+ if (!context || (context->magic != KV5M_CONTEXT))
+ return KV5M_CONTEXT;
+
+ profile = context->profile;
+
+
+ if (realm != NULL) {
+ /*
+ * Try number one:
+ *
+ * [libdefaults]
+ * REALM = {
+ * option = <value>
+ * }
+ */
+
+ names[0] = "libdefaults";
+ names[1] = realmstr;
+ names[2] = option;
+ names[3] = 0;
+ retval = profile_get_values(profile, names, &values);
+ if (retval == 0 && values != NULL && values[0] != NULL)
+ goto goodbye;
+
+ /*
+ * Try number two:
+ *
+ * [realms]
+ * REALM = {
+ * option = <value>
+ * }
+ */
+
+ names[0] = "realms";
+ names[1] = realmstr;
+ names[2] = option;
+ names[3] = 0;
+ retval = profile_get_values(profile, names, &values);
+ if (retval == 0 && values != NULL && values[0] != NULL)
+ goto goodbye;
+ }
+
+ /*
+ * Try number three:
+ *
+ * [libdefaults]
+ * option = <value>
+ */
+
+ names[0] = "libdefaults";
+ names[1] = option;
+ names[2] = 0;
+ retval = profile_get_values(profile, names, &values);
+ if (retval == 0 && values != NULL && values[0] != NULL)
+ goto goodbye;
+
+goodbye:
+ if (values == NULL)
+ return ENOENT;
+
+ *ret_value = values;
+
+ return retval;
+}
+
+krb5_error_code
+pkinit_libdefault_string(krb5_context context, const krb5_data *realm,
+ const char *option, char **ret_value)
+{
+ krb5_error_code retval;
+ char **values = NULL;
+
+ retval = pkinit_libdefault_strings(context, realm, option, &values);
+ if (retval)
+ return retval;
+
+ if (values[0] == NULL) {
+ retval = ENOENT;
+ } else {
+ *ret_value = malloc(strlen(values[0]) + 1);
+ if (*ret_value == NULL)
+ retval = ENOMEM;
+ else /* Solaris Kerberos */
+ (void) strlcpy(*ret_value, values[0], strlen(values[0]) + 1);
+ }
+
+ profile_free_list(values);
+ return retval;
+}
+
+krb5_error_code
+pkinit_libdefault_boolean(krb5_context context, const krb5_data *realm,
+ const char *option, int default_value,
+ int *ret_value)
+{
+ char *string = NULL;
+ krb5_error_code retval;
+
+ retval = pkinit_libdefault_string(context, realm, option, &string);
+
+ if (retval == 0) {
+ *ret_value = _krb5_conf_boolean(string);
+ free(string);
+ } else
+ *ret_value = default_value;
+
+ return 0;
+}
+
+krb5_error_code
+pkinit_libdefault_integer(krb5_context context, const krb5_data *realm,
+ const char *option, int default_value,
+ int *ret_value)
+{
+ char *string = NULL;
+ krb5_error_code retval;
+
+ retval = pkinit_libdefault_string(context, realm, option, &string);
+
+ if (retval == 0) {
+ char *endptr;
+ long l;
+ l = strtol(string, &endptr, 0);
+ if (endptr == string)
+ *ret_value = default_value;
+ else
+ *ret_value = l;
+ free(string);
+ }
+
+ return retval;
+}
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_srv.c b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_srv.c
new file mode 100644
index 0000000000..04f45828e5
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_srv.c
@@ -0,0 +1,1426 @@
+/*
+ * COPYRIGHT (C) 2006,2007
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include "pkinit.h"
+
+static krb5_error_code
+pkinit_server_get_edata(krb5_context context,
+ krb5_kdc_req * request,
+ struct _krb5_db_entry_new * client,
+ struct _krb5_db_entry_new * server,
+ preauth_get_entry_data_proc server_get_entry_data,
+ void *pa_plugin_context,
+ krb5_pa_data * data);
+
+static krb5_error_code
+pkinit_server_verify_padata(krb5_context context,
+ struct _krb5_db_entry_new * client,
+ krb5_data *req_pkt,
+ krb5_kdc_req * request,
+ krb5_enc_tkt_part * enc_tkt_reply,
+ krb5_pa_data * data,
+ preauth_get_entry_data_proc server_get_entry_data,
+ void *pa_plugin_context,
+ void **pa_request_context,
+ krb5_data **e_data,
+ krb5_authdata ***authz_data);
+
+static krb5_error_code
+pkinit_server_return_padata(krb5_context context,
+ krb5_pa_data * padata,
+ struct _krb5_db_entry_new * client,
+ krb5_data *req_pkt,
+ krb5_kdc_req * request,
+ krb5_kdc_rep * reply,
+ struct _krb5_key_data * client_key,
+ krb5_keyblock * encrypting_key,
+ krb5_pa_data ** send_pa,
+ preauth_get_entry_data_proc server_get_entry_data,
+ void *pa_plugin_context,
+ void **pa_request_context);
+
+static int pkinit_server_get_flags
+ (krb5_context kcontext, krb5_preauthtype patype);
+
+static krb5_error_code pkinit_init_kdc_req_context
+ (krb5_context, void **blob);
+
+static void pkinit_fini_kdc_req_context
+ (krb5_context context, void *blob);
+
+static int pkinit_server_plugin_init_realm
+ (krb5_context context, const char *realmname,
+ pkinit_kdc_context *pplgctx);
+
+static void pkinit_server_plugin_fini_realm
+ (krb5_context context, pkinit_kdc_context plgctx);
+
+static int pkinit_server_plugin_init
+ (krb5_context context, void **blob, const char **realmnames);
+
+static void pkinit_server_plugin_fini
+ (krb5_context context, void *blob);
+
+static pkinit_kdc_context pkinit_find_realm_context
+ (krb5_context context, void *pa_plugin_context, krb5_principal princ);
+
+static krb5_error_code
+pkinit_create_edata(krb5_context context,
+ pkinit_plg_crypto_context plg_cryptoctx,
+ pkinit_req_crypto_context req_cryptoctx,
+ pkinit_identity_crypto_context id_cryptoctx,
+ pkinit_plg_opts *opts,
+ krb5_error_code err_code,
+ krb5_data **e_data)
+{
+ krb5_error_code retval = KRB5KRB_ERR_GENERIC;
+
+ pkiDebug("pkinit_create_edata: creating edata for error %d (%s)\n",
+ err_code, error_message(err_code));
+ switch(err_code) {
+ case KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE:
+ retval = pkinit_create_td_trusted_certifiers(context,
+ plg_cryptoctx, req_cryptoctx, id_cryptoctx, e_data);
+ break;
+ case KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED:
+ retval = pkinit_create_td_dh_parameters(context, plg_cryptoctx,
+ req_cryptoctx, id_cryptoctx, opts, e_data);
+ break;
+ case KRB5KDC_ERR_INVALID_CERTIFICATE:
+ case KRB5KDC_ERR_REVOKED_CERTIFICATE:
+ retval = pkinit_create_td_invalid_certificate(context,
+ plg_cryptoctx, req_cryptoctx, id_cryptoctx, e_data);
+ break;
+ default:
+ pkiDebug("no edata needed for error %d (%s)\n",
+ err_code, error_message(err_code));
+ retval = 0;
+ goto cleanup;
+ }
+
+cleanup:
+
+ return retval;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+pkinit_server_get_edata(krb5_context context,
+ krb5_kdc_req * request,
+ struct _krb5_db_entry_new * client,
+ struct _krb5_db_entry_new * server,
+ preauth_get_entry_data_proc server_get_entry_data,
+ void *pa_plugin_context,
+ krb5_pa_data * data)
+{
+ krb5_error_code retval = 0;
+ pkinit_kdc_context plgctx = NULL;
+
+ pkiDebug("pkinit_server_get_edata: entered!\n");
+
+ /*
+ * If we don't have a realm context for the given realm,
+ * don't tell the client that we support pkinit!
+ */
+ plgctx = pkinit_find_realm_context(context, pa_plugin_context,
+ request->server);
+ if (plgctx == NULL)
+ retval = EINVAL;
+
+ return retval;
+}
+
+static krb5_error_code
+verify_client_san(krb5_context context,
+ pkinit_kdc_context plgctx,
+ pkinit_kdc_req_context reqctx,
+ krb5_principal client,
+ int *valid_san)
+{
+ krb5_error_code retval;
+ krb5_principal *princs = NULL;
+ krb5_principal *upns = NULL;
+ int i;
+#ifdef DEBUG_SAN_INFO
+ char *client_string = NULL, *san_string;
+#endif
+
+ retval = crypto_retrieve_cert_sans(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, plgctx->idctx,
+ &princs,
+ plgctx->opts->allow_upn ? &upns : NULL,
+ NULL);
+ if (retval) {
+ pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__);
+ retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
+ goto out;
+ }
+ /* XXX Verify this is consistent with client side XXX */
+#if 0
+ retval = call_san_checking_plugins(context, plgctx, reqctx, princs,
+ upns, NULL, &plugin_decision, &ignore);
+ pkiDebug("%s: call_san_checking_plugins() returned retval %d\n",
+ __FUNCTION__);
+ if (retval) {
+ retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
+ goto cleanup;
+ }
+ pkiDebug("%s: call_san_checking_plugins() returned decision %d\n",
+ __FUNCTION__, plugin_decision);
+ if (plugin_decision != NO_DECISION) {
+ retval = plugin_decision;
+ goto out;
+ }
+#endif
+
+#ifdef DEBUG_SAN_INFO
+ krb5_unparse_name(context, client, &client_string);
+#endif
+ pkiDebug("%s: Checking pkinit sans\n", __FUNCTION__);
+ for (i = 0; princs != NULL && princs[i] != NULL; i++) {
+#ifdef DEBUG_SAN_INFO
+ krb5_unparse_name(context, princs[i], &san_string);
+ pkiDebug("%s: Comparing client '%s' to pkinit san value '%s'\n",
+ __FUNCTION__, client_string, san_string);
+ krb5_free_unparsed_name(context, san_string);
+#endif
+ if (krb5_principal_compare(context, princs[i], client)) {
+ pkiDebug("%s: pkinit san match found\n", __FUNCTION__);
+ *valid_san = 1;
+ retval = 0;
+ goto out;
+ }
+ }
+ pkiDebug("%s: no pkinit san match found\n", __FUNCTION__);
+ /*
+ * XXX if cert has names but none match, should we
+ * be returning KRB5KDC_ERR_CLIENT_NAME_MISMATCH here?
+ */
+
+ if (upns == NULL) {
+ pkiDebug("%s: no upn sans (or we wouldn't accept them anyway)\n",
+ __FUNCTION__);
+ retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
+ goto out;
+ }
+
+ pkiDebug("%s: Checking upn sans\n", __FUNCTION__);
+ for (i = 0; upns[i] != NULL; i++) {
+#ifdef DEBUG_SAN_INFO
+ krb5_unparse_name(context, upns[i], &san_string);
+ pkiDebug("%s: Comparing client '%s' to upn san value '%s'\n",
+ __FUNCTION__, client_string, san_string);
+ krb5_free_unparsed_name(context, san_string);
+#endif
+ if (krb5_principal_compare(context, upns[i], client)) {
+ pkiDebug("%s: upn san match found\n", __FUNCTION__);
+ *valid_san = 1;
+ retval = 0;
+ goto out;
+ }
+ }
+ pkiDebug("%s: no upn san match found\n", __FUNCTION__);
+
+ /* We found no match */
+ if (princs != NULL || upns != NULL) {
+ *valid_san = 0;
+ /* XXX ??? If there was one or more name in the cert, but
+ * none matched the client name, then return mismatch? */
+ retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
+ }
+ retval = 0;
+
+out:
+ if (princs != NULL) {
+ for (i = 0; princs[i] != NULL; i++)
+ krb5_free_principal(context, princs[i]);
+ free(princs);
+ }
+ if (upns != NULL) {
+ for (i = 0; upns[i] != NULL; i++)
+ krb5_free_principal(context, upns[i]);
+ free(upns);
+ }
+#ifdef DEBUG_SAN_INFO
+ if (client_string != NULL)
+ krb5_free_unparsed_name(context, client_string);
+#endif
+ pkiDebug("%s: returning retval %d, valid_san %d\n",
+ __FUNCTION__, retval, *valid_san);
+ return retval;
+}
+
+static krb5_error_code
+verify_client_eku(krb5_context context,
+ pkinit_kdc_context plgctx,
+ pkinit_kdc_req_context reqctx,
+ int *eku_accepted)
+{
+ krb5_error_code retval;
+
+ *eku_accepted = 0;
+
+ if (plgctx->opts->require_eku == 0) {
+ pkiDebug("%s: configuration requests no EKU checking\n", __FUNCTION__);
+ *eku_accepted = 1;
+ retval = 0;
+ goto out;
+ }
+
+ retval = crypto_check_cert_eku(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, plgctx->idctx,
+ 0, /* kdc cert */
+ plgctx->opts->accept_secondary_eku,
+ eku_accepted);
+ if (retval) {
+ pkiDebug("%s: Error from crypto_check_cert_eku %d (%s)\n",
+ __FUNCTION__, retval, error_message(retval));
+ goto out;
+ }
+
+out:
+ pkiDebug("%s: returning retval %d, eku_accepted %d\n",
+ __FUNCTION__, retval, *eku_accepted);
+ return retval;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+pkinit_server_verify_padata(krb5_context context,
+ struct _krb5_db_entry_new * client,
+ krb5_data *req_pkt,
+ krb5_kdc_req * request,
+ krb5_enc_tkt_part * enc_tkt_reply,
+ krb5_pa_data * data,
+ preauth_get_entry_data_proc server_get_entry_data,
+ void *pa_plugin_context,
+ void **pa_request_context,
+ krb5_data **e_data,
+ krb5_authdata ***authz_data)
+{
+ krb5_error_code retval = 0;
+ krb5_octet_data authp_data = {0, 0, NULL}, krb5_authz = {0, 0, NULL};
+ krb5_data *encoded_pkinit_authz_data = NULL;
+ krb5_pa_pk_as_req *reqp = NULL;
+ krb5_pa_pk_as_req_draft9 *reqp9 = NULL;
+ krb5_auth_pack *auth_pack = NULL;
+ krb5_auth_pack_draft9 *auth_pack9 = NULL;
+ pkinit_kdc_context plgctx = NULL;
+ pkinit_kdc_req_context reqctx;
+/* Solaris Kerberos: set but not used */
+#if 0
+ krb5_preauthtype pa_type;
+#endif
+ krb5_checksum cksum = {0, 0, 0, NULL};
+ krb5_data *der_req = NULL;
+ int valid_eku = 0, valid_san = 0;
+ krb5_authdata **my_authz_data = NULL, *pkinit_authz_data = NULL;
+ krb5_kdc_req *tmp_as_req = NULL;
+ krb5_data k5data;
+
+ pkiDebug("pkinit_verify_padata: entered!\n");
+ /* Solaris Kerberos */
+ if (data == NULL || data->length == 0 || data->contents == NULL)
+ return 0;
+
+ if (pa_plugin_context == NULL || e_data == NULL)
+ return EINVAL;
+
+ plgctx = pkinit_find_realm_context(context, pa_plugin_context,
+ request->server);
+ if (plgctx == NULL)
+ return 0;
+
+#ifdef DEBUG_ASN1
+ print_buffer_bin(data->contents, data->length, "/tmp/kdc_as_req");
+#endif
+ /* create a per-request context */
+ retval = pkinit_init_kdc_req_context(context, (void **)&reqctx);
+ if (retval)
+ goto cleanup;
+ reqctx->pa_type = data->pa_type;
+
+ PADATA_TO_KRB5DATA(data, &k5data);
+
+ switch ((int)data->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ pkiDebug("processing KRB5_PADATA_PK_AS_REQ\n");
+ retval = k5int_decode_krb5_pa_pk_as_req(&k5data, &reqp);
+ if (retval) {
+ pkiDebug("decode_krb5_pa_pk_as_req failed\n");
+ goto cleanup;
+ }
+#ifdef DEBUG_ASN1
+ print_buffer_bin(reqp->signedAuthPack.data,
+ reqp->signedAuthPack.length,
+ "/tmp/kdc_signed_data");
+#endif
+ retval = cms_signeddata_verify(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, plgctx->idctx, CMS_SIGN_CLIENT,
+ plgctx->opts->require_crl_checking,
+ reqp->signedAuthPack.data, reqp->signedAuthPack.length,
+ &authp_data.data, &authp_data.length, &krb5_authz.data,
+ &krb5_authz.length);
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ pkiDebug("processing KRB5_PADATA_PK_AS_REQ_OLD\n");
+ retval = k5int_decode_krb5_pa_pk_as_req_draft9(&k5data, &reqp9);
+ if (retval) {
+ pkiDebug("decode_krb5_pa_pk_as_req_draft9 failed\n");
+ goto cleanup;
+ }
+#ifdef DEBUG_ASN1
+ print_buffer_bin(reqp9->signedAuthPack.data,
+ reqp9->signedAuthPack.length,
+ "/tmp/kdc_signed_data_draft9");
+#endif
+
+ retval = cms_signeddata_verify(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, plgctx->idctx, CMS_SIGN_DRAFT9,
+ plgctx->opts->require_crl_checking,
+ reqp9->signedAuthPack.data, reqp9->signedAuthPack.length,
+ &authp_data.data, &authp_data.length, &krb5_authz.data,
+ &krb5_authz.length);
+ break;
+ default:
+ pkiDebug("unrecognized pa_type = %d\n", data->pa_type);
+ retval = EINVAL;
+ goto cleanup;
+ }
+ if (retval) {
+ pkiDebug("pkcs7_signeddata_verify failed\n");
+ goto cleanup;
+ }
+
+ retval = verify_client_san(context, plgctx, reqctx, request->client,
+ &valid_san);
+ if (retval)
+ goto cleanup;
+ if (!valid_san) {
+ pkiDebug("%s: did not find an acceptable SAN in user certificate\n",
+ __FUNCTION__);
+ retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
+ goto cleanup;
+ }
+ retval = verify_client_eku(context, plgctx, reqctx, &valid_eku);
+ if (retval)
+ goto cleanup;
+
+ if (!valid_eku) {
+ pkiDebug("%s: did not find an acceptable EKU in user certificate\n",
+ __FUNCTION__);
+ retval = KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE;
+ goto cleanup;
+ }
+
+#ifdef DEBUG_ASN1
+ print_buffer_bin(authp_data.data, authp_data.length, "/tmp/kdc_auth_pack");
+#endif
+
+ OCTETDATA_TO_KRB5DATA(&authp_data, &k5data);
+ switch ((int)data->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ retval = k5int_decode_krb5_auth_pack(&k5data, &auth_pack);
+ if (retval) {
+ pkiDebug("failed to decode krb5_auth_pack\n");
+ goto cleanup;
+ }
+
+ /* check dh parameters */
+ if (auth_pack->clientPublicValue != NULL) {
+ retval = server_check_dh(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, plgctx->idctx,
+ &auth_pack->clientPublicValue->algorithm.parameters,
+ plgctx->opts->dh_min_bits);
+
+ if (retval) {
+ pkiDebug("bad dh parameters\n");
+ goto cleanup;
+ }
+ }
+ /*
+ * The KDC may have modified the request after decoding it.
+ * We need to compute the checksum on the data that
+ * came from the client. Therefore, we use the original
+ * packet contents.
+ */
+ retval = k5int_decode_krb5_as_req(req_pkt, &tmp_as_req);
+ if (retval) {
+ pkiDebug("decode_krb5_as_req returned %d\n", (int)retval);
+ goto cleanup;
+ }
+
+ retval = k5int_encode_krb5_kdc_req_body(tmp_as_req, &der_req);
+ if (retval) {
+ pkiDebug("encode_krb5_kdc_req_body returned %d\n", (int) retval);
+ goto cleanup;
+ }
+ retval = krb5_c_make_checksum(context, CKSUMTYPE_NIST_SHA, NULL,
+ 0, der_req, &cksum);
+ if (retval) {
+ pkiDebug("unable to calculate AS REQ checksum\n");
+ goto cleanup;
+ }
+ if (cksum.length != auth_pack->pkAuthenticator.paChecksum.length ||
+ memcmp(cksum.contents,
+ auth_pack->pkAuthenticator.paChecksum.contents,
+ cksum.length)) {
+ pkiDebug("failed to match the checksum\n");
+#ifdef DEBUG_CKSUM
+ pkiDebug("calculating checksum on buf size (%d)\n",
+ req_pkt->length);
+ print_buffer(req_pkt->data, req_pkt->length);
+ pkiDebug("received checksum type=%d size=%d ",
+ auth_pack->pkAuthenticator.paChecksum.checksum_type,
+ auth_pack->pkAuthenticator.paChecksum.length);
+ print_buffer(auth_pack->pkAuthenticator.paChecksum.contents,
+ auth_pack->pkAuthenticator.paChecksum.length);
+ pkiDebug("expected checksum type=%d size=%d ",
+ cksum.checksum_type, cksum.length);
+ print_buffer(cksum.contents, cksum.length);
+#endif
+
+ retval = KRB5KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED;
+ goto cleanup;
+ }
+
+ /* check if kdcPkId present and match KDC's subjectIdentifier */
+ if (reqp->kdcPkId.data != NULL) {
+ int valid_kdcPkId = 0;
+ retval = pkinit_check_kdc_pkid(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, plgctx->idctx,
+ reqp->kdcPkId.data, reqp->kdcPkId.length, &valid_kdcPkId);
+ if (retval)
+ goto cleanup;
+ if (!valid_kdcPkId)
+ pkiDebug("kdcPkId in AS_REQ does not match KDC's cert"
+ "RFC says to ignore and proceed\n");
+
+ }
+ /* remember the decoded auth_pack for verify_padata routine */
+ reqctx->rcv_auth_pack = auth_pack;
+ auth_pack = NULL;
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ retval = k5int_decode_krb5_auth_pack_draft9(&k5data, &auth_pack9);
+ if (retval) {
+ pkiDebug("failed to decode krb5_auth_pack_draft9\n");
+ goto cleanup;
+ }
+ if (auth_pack9->clientPublicValue != NULL) {
+ retval = server_check_dh(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, plgctx->idctx,
+ &auth_pack9->clientPublicValue->algorithm.parameters,
+ plgctx->opts->dh_min_bits);
+
+ if (retval) {
+ pkiDebug("bad dh parameters\n");
+ goto cleanup;
+ }
+ }
+ /* remember the decoded auth_pack for verify_padata routine */
+ reqctx->rcv_auth_pack9 = auth_pack9;
+ auth_pack9 = NULL;
+ break;
+ }
+
+ /* return authorization data to be included in the ticket */
+ switch ((int)data->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ my_authz_data = malloc(2 * sizeof(*my_authz_data));
+ if (my_authz_data == NULL) {
+ retval = ENOMEM;
+ pkiDebug("Couldn't allocate krb5_authdata ptr array\n");
+ goto cleanup;
+ }
+ my_authz_data[1] = NULL;
+ my_authz_data[0] = malloc(sizeof(krb5_authdata));
+ if (my_authz_data[0] == NULL) {
+ retval = ENOMEM;
+ pkiDebug("Couldn't allocate krb5_authdata\n");
+ free(my_authz_data);
+ goto cleanup;
+ }
+ /* AD-INITIAL-VERIFIED-CAS must be wrapped in AD-IF-RELEVANT */
+ my_authz_data[0]->magic = KV5M_AUTHDATA;
+ my_authz_data[0]->ad_type = KRB5_AUTHDATA_IF_RELEVANT;
+
+ /* create an internal AD-INITIAL-VERIFIED-CAS data */
+ pkinit_authz_data = malloc(sizeof(krb5_authdata));
+ if (pkinit_authz_data == NULL) {
+ retval = ENOMEM;
+ pkiDebug("Couldn't allocate krb5_authdata\n");
+ free(my_authz_data[0]);
+ free(my_authz_data);
+ goto cleanup;
+ }
+ pkinit_authz_data->ad_type = KRB5_AUTHDATA_INITIAL_VERIFIED_CAS;
+ /* content of this ad-type contains the certification
+ path with which the client certificate was validated
+ */
+ pkinit_authz_data->contents = krb5_authz.data;
+ pkinit_authz_data->length = krb5_authz.length;
+ retval = k5int_encode_krb5_authdata_elt(pkinit_authz_data,
+ &encoded_pkinit_authz_data);
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)encoded_pkinit_authz_data->data,
+ encoded_pkinit_authz_data->length,
+ "/tmp/kdc_pkinit_authz_data");
+#endif
+ free(pkinit_authz_data);
+ if (retval) {
+ pkiDebug("k5int_encode_krb5_authdata_elt failed\n");
+ free(my_authz_data[0]);
+ free(my_authz_data);
+ goto cleanup;
+ }
+
+ my_authz_data[0]->contents =
+ (krb5_octet *) encoded_pkinit_authz_data->data;
+ my_authz_data[0]->length = encoded_pkinit_authz_data->length;
+ *authz_data = my_authz_data;
+ pkiDebug("Returning %d bytes of authorization data\n",
+ krb5_authz.length);
+ encoded_pkinit_authz_data->data = NULL; /* Don't free during cleanup*/
+ free(encoded_pkinit_authz_data);
+ break;
+ default:
+ *authz_data = NULL;
+ }
+ /* remember to set the PREAUTH flag in the reply */
+ enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH;
+ *pa_request_context = reqctx;
+ reqctx = NULL;
+
+ cleanup:
+ if (retval && data->pa_type == KRB5_PADATA_PK_AS_REQ) {
+ pkiDebug("pkinit_verify_padata failed: creating e-data\n");
+ if (pkinit_create_edata(context, plgctx->cryptoctx, reqctx->cryptoctx,
+ plgctx->idctx, plgctx->opts, retval, e_data))
+ pkiDebug("pkinit_create_edata failed\n");
+ }
+
+ switch ((int)data->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ free_krb5_pa_pk_as_req(&reqp);
+ if (cksum.contents != NULL)
+ free(cksum.contents);
+ if (der_req != NULL)
+ krb5_free_data(context, der_req);
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ free_krb5_pa_pk_as_req_draft9(&reqp9);
+ }
+ if (tmp_as_req != NULL)
+ k5int_krb5_free_kdc_req(context, tmp_as_req);
+ if (authp_data.data != NULL)
+ free(authp_data.data);
+ if (krb5_authz.data != NULL)
+ free(krb5_authz.data);
+ if (reqctx != NULL)
+ pkinit_fini_kdc_req_context(context, reqctx);
+ if (auth_pack != NULL)
+ free_krb5_auth_pack(&auth_pack);
+ if (auth_pack9 != NULL)
+ free_krb5_auth_pack_draft9(context, &auth_pack9);
+
+ return retval;
+}
+
+/* ARGSUSED */
+static krb5_error_code
+pkinit_server_return_padata(krb5_context context,
+ krb5_pa_data * padata,
+ struct _krb5_db_entry_new * client,
+ krb5_data *req_pkt,
+ krb5_kdc_req * request,
+ krb5_kdc_rep * reply,
+ struct _krb5_key_data * client_key,
+ krb5_keyblock * encrypting_key,
+ krb5_pa_data ** send_pa,
+ preauth_get_entry_data_proc server_get_entry_data,
+ void *pa_plugin_context,
+ void **pa_request_context)
+{
+ krb5_error_code retval = 0;
+ krb5_data scratch = {0, 0, NULL};
+ krb5_pa_pk_as_req *reqp = NULL;
+ krb5_pa_pk_as_req_draft9 *reqp9 = NULL;
+ int i = 0;
+
+ unsigned char *subjectPublicKey = NULL;
+ unsigned char *dh_pubkey = NULL, *server_key = NULL;
+ unsigned int subjectPublicKey_len = 0;
+ unsigned int server_key_len = 0, dh_pubkey_len = 0;
+
+ krb5_kdc_dh_key_info dhkey_info;
+ krb5_data *encoded_dhkey_info = NULL;
+ krb5_pa_pk_as_rep *rep = NULL;
+ krb5_pa_pk_as_rep_draft9 *rep9 = NULL;
+ krb5_data *out_data = NULL;
+
+ krb5_enctype enctype = -1;
+
+ krb5_reply_key_pack *key_pack = NULL;
+ krb5_reply_key_pack_draft9 *key_pack9 = NULL;
+ krb5_data *encoded_key_pack = NULL;
+ unsigned int num_types;
+ krb5_cksumtype *cksum_types = NULL;
+
+ pkinit_kdc_context plgctx;
+ pkinit_kdc_req_context reqctx;
+
+ int fixed_keypack = 0;
+
+ *send_pa = NULL;
+ /* Solaris Kerberos */
+ if (padata == NULL || padata->length == 0 || padata->contents == NULL)
+ return 0;
+
+ if (pa_request_context == NULL || *pa_request_context == NULL) {
+ pkiDebug("missing request context \n");
+ return EINVAL;
+ }
+
+ plgctx = pkinit_find_realm_context(context, pa_plugin_context,
+ request->server);
+ if (plgctx == NULL) {
+ pkiDebug("Unable to locate correct realm context\n");
+ return ENOENT;
+ }
+
+ pkiDebug("pkinit_return_padata: entered!\n");
+ reqctx = (pkinit_kdc_req_context)*pa_request_context;
+
+ if (encrypting_key->contents) {
+ free(encrypting_key->contents);
+ encrypting_key->length = 0;
+ encrypting_key->contents = NULL;
+ }
+
+ for(i = 0; i < request->nktypes; i++) {
+ enctype = request->ktype[i];
+ if (!krb5_c_valid_enctype(enctype))
+ continue;
+ else {
+ pkiDebug("KDC picked etype = %d\n", enctype);
+ break;
+ }
+ }
+
+ if (i == request->nktypes) {
+ retval = KRB5KDC_ERR_ETYPE_NOSUPP;
+ goto cleanup;
+ }
+
+ switch((int)reqctx->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ init_krb5_pa_pk_as_rep(&rep);
+ if (rep == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ /* let's assume it's RSA. we'll reset it to DH if needed */
+ rep->choice = choice_pa_pk_as_rep_encKeyPack;
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ init_krb5_pa_pk_as_rep_draft9(&rep9);
+ if (rep9 == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ rep9->choice = choice_pa_pk_as_rep_draft9_encKeyPack;
+ break;
+ default:
+ retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ goto cleanup;
+ }
+
+ if (reqctx->rcv_auth_pack != NULL &&
+ reqctx->rcv_auth_pack->clientPublicValue != NULL) {
+ subjectPublicKey =
+ reqctx->rcv_auth_pack->clientPublicValue->subjectPublicKey.data;
+ subjectPublicKey_len =
+ reqctx->rcv_auth_pack->clientPublicValue->subjectPublicKey.length;
+ rep->choice = choice_pa_pk_as_rep_dhInfo;
+ } else if (reqctx->rcv_auth_pack9 != NULL &&
+ reqctx->rcv_auth_pack9->clientPublicValue != NULL) {
+ subjectPublicKey =
+ reqctx->rcv_auth_pack9->clientPublicValue->subjectPublicKey.data;
+ subjectPublicKey_len =
+ reqctx->rcv_auth_pack9->clientPublicValue->subjectPublicKey.length;
+ rep9->choice = choice_pa_pk_as_rep_draft9_dhSignedData;
+ }
+
+ /* if this DH, then process finish computing DH key */
+ if (rep != NULL && (rep->choice == choice_pa_pk_as_rep_dhInfo ||
+ rep->choice == choice_pa_pk_as_rep_draft9_dhSignedData)) {
+ pkiDebug("received DH key delivery AS REQ\n");
+ retval = server_process_dh(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, plgctx->idctx, subjectPublicKey,
+ subjectPublicKey_len, &dh_pubkey, &dh_pubkey_len,
+ &server_key, &server_key_len);
+ if (retval) {
+ pkiDebug("failed to process/create dh paramters\n");
+ goto cleanup;
+ }
+ }
+
+ if ((rep9 != NULL &&
+ rep9->choice == choice_pa_pk_as_rep_draft9_dhSignedData) ||
+ (rep != NULL && rep->choice == choice_pa_pk_as_rep_dhInfo)) {
+ retval = pkinit_octetstring2key(context, enctype, server_key,
+ server_key_len, encrypting_key);
+ if (retval) {
+ pkiDebug("pkinit_octetstring2key failed: %s\n",
+ error_message(retval));
+ goto cleanup;
+ }
+
+ dhkey_info.subjectPublicKey.length = dh_pubkey_len;
+ dhkey_info.subjectPublicKey.data = dh_pubkey;
+ dhkey_info.nonce = request->nonce;
+ dhkey_info.dhKeyExpiration = 0;
+
+ retval = k5int_encode_krb5_kdc_dh_key_info(&dhkey_info,
+ &encoded_dhkey_info);
+ if (retval) {
+ pkiDebug("encode_krb5_kdc_dh_key_info failed\n");
+ goto cleanup;
+ }
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)encoded_dhkey_info->data,
+ encoded_dhkey_info->length,
+ "/tmp/kdc_dh_key_info");
+#endif
+
+ switch ((int)padata->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ retval = cms_signeddata_create(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, plgctx->idctx, CMS_SIGN_SERVER, 1,
+ (unsigned char *)encoded_dhkey_info->data,
+ encoded_dhkey_info->length,
+ &rep->u.dh_Info.dhSignedData.data,
+ &rep->u.dh_Info.dhSignedData.length);
+ if (retval) {
+ pkiDebug("failed to create pkcs7 signed data\n");
+ goto cleanup;
+ }
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ retval = cms_signeddata_create(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, plgctx->idctx, CMS_SIGN_DRAFT9, 1,
+ (unsigned char *)encoded_dhkey_info->data,
+ encoded_dhkey_info->length,
+ &rep9->u.dhSignedData.data,
+ &rep9->u.dhSignedData.length);
+ if (retval) {
+ pkiDebug("failed to create pkcs7 signed data\n");
+ goto cleanup;
+ }
+ break;
+ }
+ } else {
+ pkiDebug("received RSA key delivery AS REQ\n");
+
+ retval = krb5_c_make_random_key(context, enctype, encrypting_key);
+ if (retval) {
+ pkiDebug("unable to make a session key\n");
+ goto cleanup;
+ }
+
+ /* check if PA_TYPE of 132 is present which means the client is
+ * requesting that a checksum is send back instead of the nonce
+ */
+ for (i = 0; request->padata[i] != NULL; i++) {
+ pkiDebug("%s: Checking pa_type 0x%08x\n",
+ __FUNCTION__, request->padata[i]->pa_type);
+ if (request->padata[i]->pa_type == 132)
+ fixed_keypack = 1;
+ }
+ pkiDebug("%s: return checksum instead of nonce = %d\n",
+ __FUNCTION__, fixed_keypack);
+
+ /* if this is an RFC reply or draft9 client requested a checksum
+ * in the reply instead of the nonce, create an RFC-style keypack
+ */
+ if ((int)padata->pa_type == KRB5_PADATA_PK_AS_REQ || fixed_keypack) {
+ init_krb5_reply_key_pack(&key_pack);
+ if (key_pack == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ /* retrieve checksums for a given enctype of the reply key */
+ retval = krb5_c_keyed_checksum_types(context,
+ encrypting_key->enctype, &num_types, &cksum_types);
+ if (retval)
+ goto cleanup;
+
+ /* pick the first of acceptable enctypes for the checksum */
+ retval = krb5_c_make_checksum(context, cksum_types[0],
+ encrypting_key, KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM,
+ req_pkt, &key_pack->asChecksum);
+ if (retval) {
+ pkiDebug("unable to calculate AS REQ checksum\n");
+ goto cleanup;
+ }
+#ifdef DEBUG_CKSUM
+ pkiDebug("calculating checksum on buf size = %d\n", req_pkt->length);
+ print_buffer(req_pkt->data, req_pkt->length);
+ pkiDebug("checksum size = %d\n", key_pack->asChecksum.length);
+ print_buffer(key_pack->asChecksum.contents,
+ key_pack->asChecksum.length);
+ pkiDebug("encrypting key (%d)\n", encrypting_key->length);
+ print_buffer(encrypting_key->contents, encrypting_key->length);
+#endif
+
+ krb5_copy_keyblock_contents(context, encrypting_key,
+ &key_pack->replyKey);
+
+ retval = k5int_encode_krb5_reply_key_pack(key_pack,
+ &encoded_key_pack);
+ if (retval) {
+ pkiDebug("failed to encode reply_key_pack\n");
+ goto cleanup;
+ }
+ }
+
+ switch ((int)padata->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ rep->choice = choice_pa_pk_as_rep_encKeyPack;
+ retval = cms_envelopeddata_create(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, plgctx->idctx, padata->pa_type, 1,
+ (unsigned char *)encoded_key_pack->data,
+ encoded_key_pack->length,
+ &rep->u.encKeyPack.data, &rep->u.encKeyPack.length);
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ /* if the request is from the broken draft9 client that
+ * expects back a nonce, create it now
+ */
+ if (!fixed_keypack) {
+ init_krb5_reply_key_pack_draft9(&key_pack9);
+ if (key_pack9 == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ key_pack9->nonce = reqctx->rcv_auth_pack9->pkAuthenticator.nonce;
+ krb5_copy_keyblock_contents(context, encrypting_key,
+ &key_pack9->replyKey);
+
+ retval = k5int_encode_krb5_reply_key_pack_draft9(key_pack9,
+ &encoded_key_pack);
+ if (retval) {
+ pkiDebug("failed to encode reply_key_pack\n");
+ goto cleanup;
+ }
+ }
+
+ rep9->choice = choice_pa_pk_as_rep_draft9_encKeyPack;
+ retval = cms_envelopeddata_create(context, plgctx->cryptoctx,
+ reqctx->cryptoctx, plgctx->idctx, padata->pa_type, 1,
+ (unsigned char *)encoded_key_pack->data,
+ encoded_key_pack->length,
+ &rep9->u.encKeyPack.data, &rep9->u.encKeyPack.length);
+ break;
+ }
+ if (retval) {
+ pkiDebug("failed to create pkcs7 enveloped data: %s\n",
+ error_message(retval));
+ goto cleanup;
+ }
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)encoded_key_pack->data,
+ encoded_key_pack->length,
+ "/tmp/kdc_key_pack");
+ switch ((int)padata->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ print_buffer_bin(rep->u.encKeyPack.data,
+ rep->u.encKeyPack.length,
+ "/tmp/kdc_enc_key_pack");
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ print_buffer_bin(rep9->u.encKeyPack.data,
+ rep9->u.encKeyPack.length,
+ "/tmp/kdc_enc_key_pack");
+ break;
+ }
+#endif
+ }
+
+ switch ((int)padata->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ retval = k5int_encode_krb5_pa_pk_as_rep(rep, &out_data);
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ retval = k5int_encode_krb5_pa_pk_as_rep_draft9(rep9, &out_data);
+ break;
+ }
+ if (retval) {
+ pkiDebug("failed to encode AS_REP\n");
+ goto cleanup;
+ }
+#ifdef DEBUG_ASN1
+ if (out_data != NULL)
+ print_buffer_bin((unsigned char *)out_data->data, out_data->length,
+ "/tmp/kdc_as_rep");
+#endif
+
+ *send_pa = (krb5_pa_data *) malloc(sizeof(krb5_pa_data));
+ if (*send_pa == NULL) {
+ retval = ENOMEM;
+ free(out_data->data);
+ free(out_data);
+ out_data = NULL;
+ goto cleanup;
+ }
+ (*send_pa)->magic = KV5M_PA_DATA;
+ switch ((int)padata->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ (*send_pa)->pa_type = KRB5_PADATA_PK_AS_REP;
+ break;
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ (*send_pa)->pa_type = KRB5_PADATA_PK_AS_REP_OLD;
+ break;
+ }
+ (*send_pa)->length = out_data->length;
+ (*send_pa)->contents = (krb5_octet *) out_data->data;
+
+
+ cleanup:
+ pkinit_fini_kdc_req_context(context, reqctx);
+ if (scratch.data != NULL)
+ free(scratch.data);
+ if (out_data != NULL)
+ free(out_data);
+ if (encoded_dhkey_info != NULL)
+ krb5_free_data(context, encoded_dhkey_info);
+ if (encoded_key_pack != NULL)
+ krb5_free_data(context, encoded_key_pack);
+ if (dh_pubkey != NULL)
+ free(dh_pubkey);
+ if (server_key != NULL)
+ free(server_key);
+ if (cksum_types != NULL)
+ free(cksum_types);
+
+ switch ((int)padata->pa_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ free_krb5_pa_pk_as_req(&reqp);
+ free_krb5_pa_pk_as_rep(&rep);
+ free_krb5_reply_key_pack(&key_pack);
+ break;
+ case KRB5_PADATA_PK_AS_REP_OLD:
+ case KRB5_PADATA_PK_AS_REQ_OLD:
+ free_krb5_pa_pk_as_req_draft9(&reqp9);
+ free_krb5_pa_pk_as_rep_draft9(&rep9);
+ if (!fixed_keypack)
+ free_krb5_reply_key_pack_draft9(&key_pack9);
+ else
+ free_krb5_reply_key_pack(&key_pack);
+ break;
+ }
+
+ if (retval)
+ pkiDebug("pkinit_verify_padata failure");
+
+ return retval;
+}
+
+/* ARGSUSED */
+static int
+pkinit_server_get_flags(krb5_context kcontext, krb5_preauthtype patype)
+{
+ return PA_SUFFICIENT | PA_REPLACES_KEY;
+}
+
+static krb5_preauthtype supported_server_pa_types[] = {
+ KRB5_PADATA_PK_AS_REQ,
+ KRB5_PADATA_PK_AS_REQ_OLD,
+ KRB5_PADATA_PK_AS_REP_OLD,
+ 0
+};
+
+/* ARGSUSED */
+static void
+pkinit_fini_kdc_profile(krb5_context context, pkinit_kdc_context plgctx)
+{
+ /*
+ * There is nothing currently allocated by pkinit_init_kdc_profile()
+ * which needs to be freed here.
+ */
+}
+
+static krb5_error_code
+pkinit_init_kdc_profile(krb5_context context, pkinit_kdc_context plgctx)
+{
+ krb5_error_code retval;
+ char *eku_string = NULL;
+
+ pkiDebug("%s: entered for realm %s\n", __FUNCTION__, plgctx->realmname);
+ retval = pkinit_kdcdefault_string(context, plgctx->realmname,
+ "pkinit_identity",
+ &plgctx->idopts->identity);
+ if (retval != 0 || NULL == plgctx->idopts->identity) {
+ retval = EINVAL;
+ krb5_set_error_message(context, retval,
+ "No pkinit_identity supplied for realm %s",
+ plgctx->realmname);
+ goto errout;
+ }
+
+ retval = pkinit_kdcdefault_strings(context, plgctx->realmname,
+ "pkinit_anchors",
+ &plgctx->idopts->anchors);
+ if (retval != 0 || NULL == plgctx->idopts->anchors) {
+ retval = EINVAL;
+ krb5_set_error_message(context, retval,
+ "No pkinit_anchors supplied for realm %s",
+ plgctx->realmname);
+ goto errout;
+ }
+
+ /* Solaris Kerberos */
+ (void) pkinit_kdcdefault_strings(context, plgctx->realmname,
+ "pkinit_pool",
+ &plgctx->idopts->intermediates);
+
+ (void) pkinit_kdcdefault_strings(context, plgctx->realmname,
+ "pkinit_revoke",
+ &plgctx->idopts->crls);
+
+ (void) pkinit_kdcdefault_string(context, plgctx->realmname,
+ "pkinit_kdc_ocsp",
+ &plgctx->idopts->ocsp);
+
+ (void) pkinit_kdcdefault_string(context, plgctx->realmname,
+ "pkinit_mappings_file",
+ &plgctx->idopts->dn_mapping_file);
+
+ (void) pkinit_kdcdefault_integer(context, plgctx->realmname,
+ "pkinit_dh_min_bits",
+ PKINIT_DEFAULT_DH_MIN_BITS,
+ &plgctx->opts->dh_min_bits);
+ if (plgctx->opts->dh_min_bits < 1024) {
+ pkiDebug("%s: invalid value (%d) for pkinit_dh_min_bits, "
+ "using default value (%d) instead\n", __FUNCTION__,
+ plgctx->opts->dh_min_bits, PKINIT_DEFAULT_DH_MIN_BITS);
+ plgctx->opts->dh_min_bits = PKINIT_DEFAULT_DH_MIN_BITS;
+ }
+
+ (void) pkinit_kdcdefault_boolean(context, plgctx->realmname,
+ "pkinit_allow_upn",
+ 0, &plgctx->opts->allow_upn);
+
+ (void) pkinit_kdcdefault_boolean(context, plgctx->realmname,
+ "pkinit_require_crl_checking",
+ 0, &plgctx->opts->require_crl_checking);
+
+ (void) pkinit_kdcdefault_string(context, plgctx->realmname,
+ "pkinit_eku_checking",
+ &eku_string);
+ if (eku_string != NULL) {
+ if (strcasecmp(eku_string, "kpClientAuth") == 0) {
+ plgctx->opts->require_eku = 1;
+ plgctx->opts->accept_secondary_eku = 0;
+ } else if (strcasecmp(eku_string, "scLogin") == 0) {
+ plgctx->opts->require_eku = 1;
+ plgctx->opts->accept_secondary_eku = 1;
+ } else if (strcasecmp(eku_string, "none") == 0) {
+ plgctx->opts->require_eku = 0;
+ plgctx->opts->accept_secondary_eku = 0;
+ } else {
+ pkiDebug("%s: Invalid value for pkinit_eku_checking: '%s'\n",
+ __FUNCTION__, eku_string);
+ }
+ free(eku_string);
+ }
+
+
+ return 0;
+errout:
+ pkinit_fini_kdc_profile(context, plgctx);
+ return retval;
+}
+
+/* ARGSUSED */
+static pkinit_kdc_context
+pkinit_find_realm_context(krb5_context context, void *pa_plugin_context,
+ krb5_principal princ)
+{
+ int i;
+ pkinit_kdc_context *realm_contexts = pa_plugin_context;
+
+ if (pa_plugin_context == NULL)
+ return NULL;
+
+ for (i = 0; realm_contexts[i] != NULL; i++) {
+ pkinit_kdc_context p = realm_contexts[i];
+
+ if ((p->realmname_len == princ->realm.length) &&
+ (strncmp(p->realmname, princ->realm.data, p->realmname_len) == 0)) {
+ pkiDebug("%s: returning context at %p for realm '%s'\n",
+ __FUNCTION__, p, p->realmname);
+ return p;
+ }
+ }
+ pkiDebug("%s: unable to find realm context for realm '%.*s'\n",
+ __FUNCTION__, princ->realm.length, princ->realm.data);
+ return NULL;
+}
+
+static int
+pkinit_server_plugin_init_realm(krb5_context context, const char *realmname,
+ pkinit_kdc_context *pplgctx)
+{
+ krb5_error_code retval = ENOMEM;
+ pkinit_kdc_context plgctx = NULL;
+
+ *pplgctx = NULL;
+
+ plgctx = (pkinit_kdc_context) calloc(1, sizeof(*plgctx));
+ if (plgctx == NULL)
+ goto errout;
+
+ pkiDebug("%s: initializing context at %p for realm '%s'\n",
+ __FUNCTION__, plgctx, realmname);
+ (void) memset(plgctx, 0, sizeof(*plgctx));
+ plgctx->magic = PKINIT_CTX_MAGIC;
+
+ plgctx->realmname = strdup(realmname);
+ if (plgctx->realmname == NULL)
+ goto errout;
+ plgctx->realmname_len = strlen(plgctx->realmname);
+
+ retval = pkinit_init_plg_crypto(&plgctx->cryptoctx);
+ if (retval)
+ goto errout;
+
+ retval = pkinit_init_plg_opts(&plgctx->opts);
+ if (retval)
+ goto errout;
+
+ retval = pkinit_init_identity_crypto(&plgctx->idctx);
+ if (retval)
+ goto errout;
+
+ retval = pkinit_init_identity_opts(&plgctx->idopts);
+ if (retval)
+ goto errout;
+
+ retval = pkinit_init_kdc_profile(context, plgctx);
+ if (retval)
+ goto errout;
+
+ /*
+ * Solaris Kerberos:
+ * Some methods of storing key information (PKCS11, PKCS12,...) may
+ * require interactive prompting.
+ */
+ retval = pkinit_identity_set_prompter(plgctx->idctx, krb5_prompter_posix,
+ NULL);
+ if (retval)
+ goto errout;
+
+ retval = pkinit_identity_initialize(context, plgctx->cryptoctx, NULL,
+ plgctx->idopts, plgctx->idctx, 0, NULL);
+ if (retval)
+ goto errout;
+
+ pkiDebug("%s: returning context at %p for realm '%s'\n",
+ __FUNCTION__, plgctx, realmname);
+ *pplgctx = plgctx;
+ retval = 0;
+
+errout:
+ if (retval)
+ pkinit_server_plugin_fini_realm(context, plgctx);
+
+ return retval;
+}
+
+static int
+pkinit_server_plugin_init(krb5_context context, void **blob,
+ const char **realmnames)
+{
+ krb5_error_code retval = ENOMEM;
+ pkinit_kdc_context plgctx, *realm_contexts = NULL;
+ int i, j;
+ size_t numrealms;
+
+ retval = pkinit_accessor_init();
+ if (retval)
+ return retval;
+
+ /* Determine how many realms we may need to support */
+ for (i = 0; realmnames[i] != NULL; i++) {};
+ numrealms = i;
+
+ realm_contexts = (pkinit_kdc_context *)
+ calloc(numrealms+1, sizeof(pkinit_kdc_context));
+ if (realm_contexts == NULL)
+ return ENOMEM;
+
+ for (i = 0, j = 0; i < numrealms; i++) {
+ pkiDebug("%s: processing realm '%s'\n", __FUNCTION__, realmnames[i]);
+ retval = pkinit_server_plugin_init_realm(context, realmnames[i], &plgctx);
+ if (retval == 0 && plgctx != NULL)
+ realm_contexts[j++] = plgctx;
+ }
+
+ if (j == 0) {
+ /*
+ * Solaris Kerberos
+ * Improve error messages for the common case of a single realm
+ */
+ if (numrealms != 1) {
+ retval = EINVAL;
+ krb5_set_error_message(context, retval, "No realms configured "
+ "correctly for pkinit support");
+ }
+
+ goto errout;
+ }
+
+ *blob = realm_contexts;
+ retval = 0;
+ pkiDebug("%s: returning context at %p\n", __FUNCTION__, realm_contexts);
+
+errout:
+ if (retval)
+ pkinit_server_plugin_fini(context, realm_contexts);
+
+ return retval;
+}
+
+static void
+pkinit_server_plugin_fini_realm(krb5_context context, pkinit_kdc_context plgctx)
+{
+ if (plgctx == NULL)
+ return;
+
+ pkinit_fini_kdc_profile(context, plgctx);
+ pkinit_fini_identity_opts(plgctx->idopts);
+ pkinit_fini_identity_crypto(plgctx->idctx);
+ pkinit_fini_plg_crypto(plgctx->cryptoctx);
+ pkinit_fini_plg_opts(plgctx->opts);
+ free(plgctx->realmname);
+ free(plgctx);
+}
+
+static void
+pkinit_server_plugin_fini(krb5_context context, void *blob)
+{
+ pkinit_kdc_context *realm_contexts = blob;
+ int i;
+
+ if (realm_contexts == NULL)
+ return;
+
+ for (i = 0; realm_contexts[i] != NULL; i++) {
+ pkinit_server_plugin_fini_realm(context, realm_contexts[i]);
+ }
+ pkiDebug("%s: freeing context at %p\n", __FUNCTION__, realm_contexts);
+ free(realm_contexts);
+}
+
+static krb5_error_code
+pkinit_init_kdc_req_context(krb5_context context, void **ctx)
+{
+ krb5_error_code retval = ENOMEM;
+ pkinit_kdc_req_context reqctx = NULL;
+
+ reqctx = (pkinit_kdc_req_context)malloc(sizeof(*reqctx));
+ if (reqctx == NULL)
+ return retval;
+ (void) memset(reqctx, 0, sizeof(*reqctx));
+ reqctx->magic = PKINIT_CTX_MAGIC;
+
+ retval = pkinit_init_req_crypto(&reqctx->cryptoctx);
+ if (retval)
+ goto cleanup;
+ reqctx->rcv_auth_pack = NULL;
+ reqctx->rcv_auth_pack9 = NULL;
+
+ pkiDebug("%s: returning reqctx at %p\n", __FUNCTION__, reqctx);
+ *ctx = reqctx;
+ retval = 0;
+cleanup:
+ if (retval)
+ pkinit_fini_kdc_req_context(context, reqctx);
+
+ return retval;
+}
+
+static void
+pkinit_fini_kdc_req_context(krb5_context context, void *ctx)
+{
+ pkinit_kdc_req_context reqctx = (pkinit_kdc_req_context)ctx;
+
+ if (reqctx == NULL || reqctx->magic != PKINIT_CTX_MAGIC) {
+ pkiDebug("pkinit_fini_kdc_req_context: got bad reqctx (%p)!\n", reqctx);
+ return;
+ }
+ pkiDebug("%s: freeing reqctx at %p\n", __FUNCTION__, reqctx);
+
+ pkinit_fini_req_crypto(reqctx->cryptoctx);
+ if (reqctx->rcv_auth_pack != NULL)
+ free_krb5_auth_pack(&reqctx->rcv_auth_pack);
+ if (reqctx->rcv_auth_pack9 != NULL)
+ free_krb5_auth_pack_draft9(context, &reqctx->rcv_auth_pack9);
+
+ free(reqctx);
+}
+
+struct krb5plugin_preauth_server_ftable_v1 preauthentication_server_1 = {
+ "pkinit", /* name */
+ supported_server_pa_types, /* pa_type_list */
+ pkinit_server_plugin_init, /* (*init_proc) */
+ pkinit_server_plugin_fini, /* (*fini_proc) */
+ pkinit_server_get_flags, /* (*flags_proc) */
+ pkinit_server_get_edata, /* (*edata_proc) */
+ pkinit_server_verify_padata,/* (*verify_proc) */
+ pkinit_server_return_padata,/* (*return_proc) */
+ NULL, /* (*freepa_reqcontext_proc) */
+};
diff --git a/usr/src/lib/krb5/plugins/preauth/pkinit/sparc/Makefile b/usr/src/lib/krb5/plugins/preauth/pkinit/sparc/Makefile
new file mode 100644
index 0000000000..a0889a1a81
--- /dev/null
+++ b/usr/src/lib/krb5/plugins/preauth/pkinit/sparc/Makefile
@@ -0,0 +1,29 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBDIR) $(PLUGINDIR) $(PREAUTHDIR) $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/pkgdefs/SUNWkrbu/prototype_com b/usr/src/pkgdefs/SUNWkrbu/prototype_com
index daa16744e4..0390599162 100644
--- a/usr/src/pkgdefs/SUNWkrbu/prototype_com
+++ b/usr/src/pkgdefs/SUNWkrbu/prototype_com
@@ -19,10 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
#
# This required package information file contains a list of package contents.
# The 'pkgmk' command uses this file to identify the contents of a package
@@ -56,6 +55,10 @@ d none usr/lib 755 root bin
d none usr/lib/krb5 755 root bin
f none usr/lib/krb5/libss.so.1 755 root bin
s none usr/lib/krb5/libss.so=libss.so.1
+d none usr/lib/krb5/plugins 755 root bin
+d none usr/lib/krb5/plugins/preauth 755 root bin
+f none usr/lib/krb5/plugins/preauth/pkinit.so.1 755 root bin
+s none usr/lib/krb5/plugins/preauth/pkinit.so=pkinit.so.1
f none usr/lib/krb5/ktkt_warnd 555 root bin
d none usr/lib/gss 755 root bin
f none usr/lib/gss/mech_krb5.so.1 755 root bin
diff --git a/usr/src/pkgdefs/etc/exception_list_i386 b/usr/src/pkgdefs/etc/exception_list_i386
index 484e21c73d..24a5b132d8 100644
--- a/usr/src/pkgdefs/etc/exception_list_i386
+++ b/usr/src/pkgdefs/etc/exception_list_i386
@@ -584,6 +584,8 @@ usr/lib/krb5/libkdb.so i386
usr/lib/krb5/libkdb.so.1 i386
usr/lib/krb5/libkdb_ldap.so i386
usr/lib/krb5/libkdb_ldap.so.1 i386
+usr/lib/krb5/plugins/preauth/pkinit.so i386
+usr/lib/krb5/plugins/preauth/pkinit.so.1 i386
usr/lib/security/pam_krb5_first i386
usr/lib/security/pam_krb5_only i386
usr/lib/security/pam_krb5_optional i386
diff --git a/usr/src/pkgdefs/etc/exception_list_sparc b/usr/src/pkgdefs/etc/exception_list_sparc
index 125f5ea9b8..09c2bfc09a 100644
--- a/usr/src/pkgdefs/etc/exception_list_sparc
+++ b/usr/src/pkgdefs/etc/exception_list_sparc
@@ -588,6 +588,8 @@ usr/lib/krb5/libkdb.so sparc
usr/lib/krb5/libkdb.so.1 sparc
usr/lib/krb5/libkdb_ldap.so sparc
usr/lib/krb5/libkdb_ldap.so.1 sparc
+usr/lib/krb5/plugins/preauth/pkinit.so sparc
+usr/lib/krb5/plugins/preauth/pkinit.so.1 sparc
usr/lib/security/pam_krb5_first sparc
usr/lib/security/pam_krb5_only sparc
usr/lib/security/pam_krb5_optional sparc
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/block_size.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/block_size.c
index a3ccf6faa9..7093917fd8 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/block_size.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/block_size.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -25,13 +24,13 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <etypes.h>
+#include "k5-int.h"
+#include "etypes.h"
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
krb5_c_block_size(krb5_context context, krb5_enctype enctype,
- size_t *blocksize)
+ size_t *blocksize)
{
int i;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/checksum_length.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/checksum_length.c
index 2b1cc0ff96..3c7f032aa0 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/checksum_length.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/checksum_length.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -25,13 +24,13 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <cksumtypes.h>
+#include "k5-int.h"
+#include "cksumtypes.h"
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
krb5_c_checksum_length(krb5_context context, krb5_cksumtype cksumtype,
- size_t *length)
+ size_t *length)
{
int i;
@@ -44,11 +43,11 @@ krb5_c_checksum_length(krb5_context context, krb5_cksumtype cksumtype,
return(KRB5_BAD_ENCTYPE);
if (krb5_cksumtypes_list[i].keyhash)
- *length = krb5_cksumtypes_list[i].keyhash->hashsize;
- else if (krb5_cksumtypes_list[i].trunc_size)
- *length = krb5_cksumtypes_list[i].trunc_size;
+ *length = krb5_cksumtypes_list[i].keyhash->hashsize;
+ else if (krb5_cksumtypes_list[i].trunc_size)
+ *length = krb5_cksumtypes_list[i].trunc_size;
else
- *length = krb5_cksumtypes_list[i].hash->hashsize;
+ *length = krb5_cksumtypes_list[i].hash->hashsize;
return(0);
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/cksumtypes.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/cksumtypes.c
index 63f9ce6ca8..43c42bd629 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/cksumtypes.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/cksumtypes.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,15 +30,15 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <hash_provider.h>
-#include <keyhash_provider.h>
-#include <cksumtypes.h>
+#include "k5-int.h"
+#include "hash_provider.h"
+#include "keyhash_provider.h"
+#include "cksumtypes.h"
-struct krb5_cksumtypes krb5_cksumtypes_list[] = {
+const struct krb5_cksumtypes krb5_cksumtypes_list[] = {
{ CKSUMTYPE_CRC32, KRB5_CKSUMFLAG_NOT_COLL_PROOF,
"crc32", "CRC-32",
- NULL, NULL, &krb5_hash_crc32, 0,
+ NULL, NULL, &krb5int_hash_crc32, 0,
#ifdef _KERNEL
NULL,
CRYPTO_MECH_INVALID
@@ -48,7 +47,7 @@ struct krb5_cksumtypes krb5_cksumtypes_list[] = {
{ CKSUMTYPE_DESCBC, 0,
"des-cbc", "DES cbc mode",
- ENCTYPE_DES_CBC_CRC, &krb5_keyhash_descbc,
+ ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_descbc,
NULL, NULL,
#ifdef _KERNEL
NULL,
@@ -66,7 +65,7 @@ struct krb5_cksumtypes krb5_cksumtypes_list[] = {
},
{ CKSUMTYPE_RSA_MD5_DES, 0,
"md5-des", "RSA-MD5 with DES cbc mode",
- ENCTYPE_DES_CBC_CRC, &krb5_keyhash_md5des,
+ ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_md5des,
NULL, NULL,
#ifdef _KERNEL
SUN_CKM_MD5,
@@ -76,7 +75,7 @@ struct krb5_cksumtypes krb5_cksumtypes_list[] = {
{ CKSUMTYPE_NIST_SHA, 0,
"sha", "NIST-SHA",
- NULL, NULL, &krb5_hash_sha1, 0,
+ NULL, NULL, &krb5int_hash_sha1, 0,
#ifdef _KERNEL
SUN_CKM_SHA1,
CRYPTO_MECH_INVALID
@@ -85,7 +84,7 @@ struct krb5_cksumtypes krb5_cksumtypes_list[] = {
{ CKSUMTYPE_HMAC_SHA1_DES3, KRB5_CKSUMFLAG_DERIVE,
"hmac-sha1-des3", "HMAC-SHA1 DES3 key",
- NULL, NULL, &krb5_hash_sha1, 0,
+ NULL, NULL, &krb5int_hash_sha1, 0,
#ifdef _KERNEL
SUN_CKM_SHA1_HMAC,
CRYPTO_MECH_INVALID
@@ -93,31 +92,34 @@ struct krb5_cksumtypes krb5_cksumtypes_list[] = {
},
{ CKSUMTYPE_HMAC_SHA1_DES3, KRB5_CKSUMFLAG_DERIVE,
"hmac-sha1-des3-kd", "HMAC-SHA1 DES3 key", /* alias */
- NULL, NULL, &krb5_hash_sha1, 0,
+ NULL, NULL, &krb5int_hash_sha1, 0,
#ifdef _KERNEL
SUN_CKM_SHA1_HMAC,
CRYPTO_MECH_INVALID
#endif /* _KERNEL */
},
{ CKSUMTYPE_HMAC_MD5_ARCFOUR, 0,
- "hmac-md5-rc4", "Microsoft HMAC MD5 (RC4 key)",
- ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5, NULL, 0,
+ "hmac-md5-rc4", "Microsoft HMAC MD5 (RC4 key)",
+ ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5,
+ NULL, 0,
#ifdef _KERNEL
SUN_CKM_MD5,
CRYPTO_MECH_INVALID
#endif /* _KERNEL */
},
{ CKSUMTYPE_HMAC_MD5_ARCFOUR, 0,
- "hmac-md5-enc", "Microsoft HMAC MD5 (RC4 key)", /*Heimdal alias*/
- ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5, NULL, 0,
+ "hmac-md5-enc", "Microsoft HMAC MD5 (RC4 key)", /*Heimdal alias*/
+ ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5,
+ NULL, 0,
#ifdef _KERNEL
SUN_CKM_MD5,
CRYPTO_MECH_INVALID
#endif /* _KERNEL */
},
{ CKSUMTYPE_HMAC_MD5_ARCFOUR, 0,
- "hmac-md5-earcfour", "Microsoft HMAC MD5 (RC4 key)", /* alias*/
- ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5, NULL, 0,
+ "hmac-md5-earcfour", "Microsoft HMAC MD5 (RC4 key)", /* alias*/
+ ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5,
+ NULL, 0,
#ifdef _KERNEL
SUN_CKM_MD5,
CRYPTO_MECH_INVALID
@@ -125,16 +127,16 @@ struct krb5_cksumtypes krb5_cksumtypes_list[] = {
},
{ CKSUMTYPE_HMAC_SHA1_96_AES128, KRB5_CKSUMFLAG_DERIVE,
- "hmac-sha1-96-aes128", "HMAC-SHA1 AES128 key",
- NULL, NULL, &krb5_hash_sha1, 12,
+ "hmac-sha1-96-aes128", "HMAC-SHA1 AES128 key",
+ NULL, NULL, &krb5int_hash_sha1, 12,
#ifdef _KERNEL
SUN_CKM_SHA1_HMAC,
CRYPTO_MECH_INVALID
#endif /* _KERNEL */
},
{ CKSUMTYPE_HMAC_SHA1_96_AES256, KRB5_CKSUMFLAG_DERIVE,
- "hmac-sha1-96-aes256", "HMAC-SHA1 AES256 key",
- 0, NULL, &krb5_hash_sha1, 12,
+ "hmac-sha1-96-aes256", "HMAC-SHA1 AES256 key",
+ 0, NULL, &krb5int_hash_sha1, 12,
#ifdef _KERNEL
SUN_CKM_SHA1_HMAC,
CRYPTO_MECH_INVALID
@@ -146,6 +148,7 @@ struct krb5_cksumtypes krb5_cksumtypes_list[] = {
const int krb5_cksumtypes_length =
sizeof(krb5_cksumtypes_list)/sizeof(struct krb5_cksumtypes);
+/* Solaris Kerberos */
#ifdef _KERNEL
void
setup_kef_cksumtypes()
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/combine_keys.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/combine_keys.c
index 0de017fe9f..0e73756e27 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/combine_keys.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/combine_keys.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (c) 2002 Naval Research Laboratory (NRL/CCS)
@@ -53,6 +52,7 @@
#include "etypes.h"
#include "dk.h"
+/* Solaris Kerberos */
static krb5_error_code dr
(krb5_context context,
const struct krb5_enc_provider *enc, const krb5_keyblock *inkey,
@@ -151,6 +151,7 @@ krb5_error_code krb5int_c_combine_keys
input.length = key2->length;
input.data = (char *) key2->contents;
+ /* Solaris Kerberos */
if ((ret = dr(context, enc, key1, r1, &input)))
goto cleanup;
@@ -166,6 +167,7 @@ krb5_error_code krb5int_c_combine_keys
input.length = key1->length;
input.data = (char *) key1->contents;
+ /* Solaris Kerberos */
if ((ret = dr(context, enc, key2, r2, &input)))
goto cleanup;
@@ -211,6 +213,7 @@ krb5_error_code krb5int_c_combine_keys
tkey.length = keylength;
tkey.contents = output;
+ /* Solaris Kerberos */
if ((ret = (*(enc->make_key))(context, &randbits, &tkey)))
goto cleanup;
@@ -252,6 +255,7 @@ krb5_error_code krb5int_c_combine_keys
myalloc = 1;
}
+ /* Solaris Kerberos */
if ((ret = krb5_derive_key(context, enc, &tkey, outkey, &input))) {
if (myalloc) {
free(outkey->contents);
@@ -292,6 +296,7 @@ cleanup:
* Our DR function; mostly taken from derive.c
*/
+ /* Solaris Kerberos */
static krb5_error_code dr
( krb5_context context,
const struct krb5_enc_provider *enc,
@@ -336,6 +341,7 @@ static krb5_error_code dr
n = 0;
while (n < keybytes) {
+ /* Solaris Kerberos */
(*(enc->encrypt))(context, inkey, 0, &inblock, &outblock);
if ((keybytes - n) <= outblock.length) {
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/decrypt.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/decrypt.c
index 1e0bf724b4..6c51ab9254 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/decrypt.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/decrypt.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -30,14 +29,14 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <etypes.h>
+#include "k5-int.h"
+#include "etypes.h"
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
krb5_c_decrypt(krb5_context context, const krb5_keyblock *key,
- krb5_keyusage usage, const krb5_data *ivec,
- const krb5_enc_data *input, krb5_data *output)
+ krb5_keyusage usage, const krb5_data *ivec,
+ const krb5_enc_data *input, krb5_data *output)
{
int i;
krb5_error_code ret = 0;
@@ -54,6 +53,7 @@ krb5_c_decrypt(krb5_context context, const krb5_keyblock *key,
(krb5_enctypes_list[i].etype != input->enctype))
return(KRB5_BAD_ENCTYPE);
+/* Solaris Kerberos */
#ifdef _KERNEL
context->kef_cipher_mt = krb5_enctypes_list[i].kef_cipher_mt;
context->kef_hash_mt = krb5_enctypes_list[i].kef_hash_mt;
@@ -68,9 +68,8 @@ krb5_c_decrypt(krb5_context context, const krb5_keyblock *key,
#endif /* _KERNEL */
+ /* Solaris Kerberos */
return((*(krb5_enctypes_list[i].decrypt))
(context, krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash,
key, usage, ivec, &input->ciphertext, output));
}
-
-
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/default_state.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/default_state.c
index 139cea1b9e..24f2b5bf20 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/default_state.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/default_state.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 2001 by the Massachusetts Institute of Technology.
@@ -36,21 +35,23 @@
* contains that default code.
*/
-#include <k5-int.h>
+#include "k5-int.h"
/* ARGSUSED */
-krb5_error_code krb5int_des_init_state(
- krb5_context context, const krb5_keyblock *key,
+krb5_error_code krb5int_des_init_state
+(krb5_context context, const krb5_keyblock *key,
krb5_keyusage usage, krb5_data *new_state )
{
new_state->length = 8;
new_state->data = (void *) MALLOC(8);
if (new_state->data) {
+ /* Solaris Kerberos */
(void) memset (new_state->data, 0, new_state->length);
/* We need to copy in the key for des-cbc-cr--ick, but that's how it works*/
if (key->enctype == ENCTYPE_DES_CBC_CRC) {
+ /* Solaris Kerberos */
(void) memcpy (new_state->data, key->contents, new_state->length);
- }
+ }
} else {
return ENOMEM;
}
@@ -58,8 +59,8 @@ krb5_error_code krb5int_des_init_state(
}
/* ARGSUSED */
-krb5_error_code krb5int_default_free_state(
- krb5_context context, krb5_data *state)
+krb5_error_code krb5int_default_free_state
+(krb5_context context, krb5_data *state)
{
if (state->data) {
FREE (state->data, state->length);
@@ -69,3 +70,5 @@ krb5_error_code krb5int_default_free_state(
return 0;
}
+
+
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/d3_cbc.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/d3_cbc.c
index 374e913718..4f8ee963f8 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/d3_cbc.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/d3_cbc.c
@@ -1,8 +1,7 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1995 by Richard P. Basch. All Rights Reserved.
@@ -26,21 +25,16 @@
* express or implied warranty.
*/
-#include <des_int.h>
+#include "des_int.h"
/*
* Triple-DES CBC encryption mode.
*/
#ifndef _KERNEL
int
-mit_des3_cbc_encrypt(context, in, out, length, key, ivec, encrypt)
- krb5_context context;
- const mit_des_cblock *in;
- mit_des_cblock *out;
- long length;
- krb5_keyblock *key;
- mit_des_cblock ivec;
- int encrypt;
+mit_des3_cbc_encrypt(krb5_context context, const mit_des_cblock *in, mit_des_cblock *out,
+ unsigned long length, krb5_keyblock *key,
+ const mit_des_cblock ivec, int encrypt)
{
int ret = KRB5_PROG_ETYPE_NOSUPP;
/* EXPORT DELETE START */
@@ -66,7 +60,7 @@ mit_des3_cbc_encrypt(context, in, out, length, key, ivec, encrypt)
}
mechanism.mechanism = algos.enc_algo;
- mechanism.pParameter = ivec;
+ mechanism.pParameter = (void*)ivec;
if (ivec != NULL)
mechanism.ulParameterLen = sizeof(mit_des_cblock);
else
@@ -118,8 +112,8 @@ int
mit_des3_cbc_encrypt(krb5_context context,
const mit_des_cblock *in,
mit_des_cblock *out,
- long length, krb5_keyblock *key,
- mit_des_cblock ivec, int encrypt)
+ unsigned long length, krb5_keyblock *key,
+ const mit_des_cblock ivec, int encrypt)
{
int ret = KRB5_PROG_ETYPE_NOSUPP;
/* EXPORT DELETE START */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_cbc.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_cbc.c
index 40774cbb1d..10fe4f01d7 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_cbc.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_cbc.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (c) 1990 Dennis Ferguson. All rights reserved.
@@ -17,7 +16,7 @@
/*
* des_cbc_encrypt.c - an implementation of the DES cipher function in cbc mode
*/
-#include <des_int.h>
+#include "des_int.h"
/*
* des_cbc_encrypt - {en,de}crypt a stream in CBC mode
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_cksum.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_cksum.c
index 7ede8065ff..a5c46373ff 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_cksum.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_cksum.c
@@ -1,14 +1,13 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* des_cbc_cksum.c - compute an 8 byte checksum using DES in CBC mode
*/
-#include <des_int.h>
+#include "des_int.h"
/*
* This routine performs DES cipher-block-chaining checksum operation,
@@ -26,9 +25,9 @@
*/
unsigned long
mit_des_cbc_cksum(krb5_context context,
- krb5_octet *in, krb5_octet *out,
- long length, krb5_keyblock *key,
- krb5_octet *ivec)
+ const krb5_octet *in, krb5_octet *out,
+ unsigned long length, krb5_keyblock *key,
+ const krb5_octet *ivec)
{
krb5_error_code ret = 0;
/* EXPORT DELETE START */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_parity.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_parity.c
index 8240f950e3..26cf6039b4 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_parity.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/f_parity.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* These routines check and fix parity of encryption keys for the DES
* algorithm.
@@ -10,7 +9,7 @@
*/
-#include <des_int.h>
+#include "des_int.h"
/*
* des_fixup_key_parity: Forces odd parity per byte; parity is bits
@@ -22,8 +21,7 @@
#define parity_char(x) pstep(pstep(pstep((x),4),2),1)
void
-mit_des_fixup_key_parity(key)
- register mit_des_cblock key;
+mit_des_fixup_key_parity(mit_des_cblock key)
{
int i;
for (i=0; i<sizeof(mit_des_cblock); i++)
@@ -41,8 +39,7 @@ mit_des_fixup_key_parity(key)
* correct des parity.
*/
int
-mit_des_check_key_parity(key)
- register mit_des_cblock key;
+mit_des_check_key_parity(mit_des_cblock key)
{
int i;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/weak_key.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/weak_key.c
index 5297307860..005b163874 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/weak_key.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/des/weak_key.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/crypto/des/weak_key.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -30,8 +32,8 @@
* Originally written 8/85 by Steve Miller, MIT Project Athena.
*/
-#include <k5-int.h>
-#include <des_int.h>
+#include "k5-int.h"
+#include "des_int.h"
/*
* The following are the weak DES keys:
@@ -69,14 +71,13 @@ static const mit_des_cblock weak[16] = {
* Requires: key has correct odd parity.
*/
int
-mit_des_is_weak_key(key)
- mit_des_cblock key;
+mit_des_is_weak_key(mit_des_cblock key)
{
int i;
const mit_des_cblock *weak_p = weak;
for (i = 0; i < (sizeof(weak)/sizeof(mit_des_cblock)); i++) {
- if (!memcmp((char *)weak_p++,(char *)key,sizeof(mit_des_cblock)))
+ if (!memcmp(weak_p++,key,sizeof(mit_des_cblock)))
return 1;
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/checksum.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/checksum.c
index aee02c2a37..abf362998a 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/checksum.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/checksum.c
@@ -1,8 +1,7 @@
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -30,9 +29,9 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <etypes.h>
-#include <dk.h>
+#include "k5-int.h"
+#include "etypes.h"
+#include "dk.h"
#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
@@ -130,6 +129,7 @@ krb5_dk_make_checksum(context, hash, key, usage, input, output)
if (krb5_enctypes_list[i].etype == key->enctype)
break;
}
+
if (i == krb5_enctypes_length) {
KRB5_LOG(KRB5_ERR, "krb5_ck_make_checksum bad enctype: %d",
key->enctype);
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/derive.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/derive.c
index 22986e60ac..9ca6f43a70 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/derive.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/derive.c
@@ -1,8 +1,7 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -17,7 +16,7 @@
* 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
+ * notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of FundsXpress. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
@@ -30,8 +29,8 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <dk.h>
+#include "k5-int.h"
+#include "dk.h"
#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
@@ -253,6 +252,7 @@ init_derived_keydata(krb5_context context,
return (rv);
}
+
krb5_error_code
krb5_derive_key(context, enc, inkey, outkey, in_constant)
krb5_context context;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/dk_decrypt.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/dk_decrypt.c
index 2cc6f307f6..b843840b18 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/dk_decrypt.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/dk_decrypt.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,63 +30,56 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <dk.h>
+#include "k5-int.h"
+#include "dk.h"
#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
static krb5_error_code
krb5_dk_decrypt_maybe_trunc_hmac(krb5_context context,
- const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- const krb5_keyblock *key,
- krb5_keyusage usage,
- const krb5_data *ivec,
- const krb5_data *input,
- krb5_data *output,
- size_t hmacsize);
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key,
+ krb5_keyusage usage,
+ const krb5_data *ivec,
+ const krb5_data *input,
+ krb5_data *output,
+ size_t hmacsize);
krb5_error_code
krb5_dk_decrypt(
- krb5_context context,
- const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- const krb5_keyblock *key,
- krb5_keyusage usage,
- const krb5_data *ivec,
- const krb5_data *input,
- krb5_data *output)
+ krb5_context context,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
+ krb5_data *output)
{
return krb5_dk_decrypt_maybe_trunc_hmac(context, enc, hash, key, usage,
- ivec, input, output, 0);
+ ivec, input, output, 0);
}
krb5_error_code
krb5int_aes_dk_decrypt(
- krb5_context context,
- const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- const krb5_keyblock *key,
- krb5_keyusage usage,
- const krb5_data *ivec,
- const krb5_data *input,
- krb5_data *output)
+ krb5_context context,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
+ krb5_data *output)
{
return krb5_dk_decrypt_maybe_trunc_hmac(context, enc, hash, key, usage,
- ivec, input, output, 96 / 8);
+ ivec, input, output, 96 / 8);
}
static krb5_error_code
krb5_dk_decrypt_maybe_trunc_hmac(
- krb5_context context,
- krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
- krb5_const krb5_keyblock *key,
- krb5_keyusage usage,
- krb5_const krb5_data *ivec,
- krb5_const krb5_data *input,
- krb5_data *output,
- size_t hmacsize)
+ krb5_context context,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
+ krb5_data *output, size_t hmacsize)
{
krb5_error_code ret;
size_t hashsize, blocksize, enclen, plainlen;
@@ -127,11 +119,12 @@ krb5_dk_decrypt_maybe_trunc_hmac(
}
/* decrypt the ciphertext */
+
d1.length = enclen;
d1.data = input->data;
d2.length = enclen;
- d2.data = (char *)plaindata;
+ d2.data = (char *) plaindata;
if ((ret = ((*(enc->decrypt))(context, derived_encr_key,
ivec, &d1, &d2))) != 0)
@@ -144,12 +137,13 @@ krb5_dk_decrypt_maybe_trunc_hmac(
}
/* verify the hash */
+
if ((cksum = (unsigned char *) MALLOC(hashsize)) == NULL) {
ret = ENOMEM;
goto cleanup;
}
d1.length = hashsize;
- d1.data = (char *)cksum;
+ d1.data = (char *) cksum;
#ifdef _KERNEL
if ((ret = krb5_hmac(context, derived_hmac_key, &d2, &d1)) != 0)
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/dk_encrypt.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/dk_encrypt.c
index 6f80bf6610..418779eef2 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/dk_encrypt.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/dk/dk_encrypt.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,8 +30,8 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <dk.h>
+#include "k5-int.h"
+#include "dk.h"
#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
@@ -45,27 +44,23 @@
void
krb5_dk_encrypt_length(const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- size_t inputlen, size_t *length)
+ const struct krb5_hash_provider *hash,
+ size_t inputlen, size_t *length)
{
size_t blocksize, hashsize;
blocksize = enc->block_size;
hashsize = hash->hashsize;
-
*length = krb5_roundup(blocksize+inputlen, blocksize) + hashsize;
}
krb5_error_code
-krb5_dk_encrypt(
- krb5_context context,
- krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
- krb5_const krb5_keyblock *key,
- krb5_keyusage usage,
- krb5_const krb5_data *ivec,
- krb5_const krb5_data *input,
- krb5_data *output)
+krb5_dk_encrypt(krb5_context context,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
+ krb5_data *output)
{
size_t blocksize, plainlen, enclen;
krb5_error_code ret;
@@ -133,6 +128,7 @@ krb5_dk_encrypt(
cn = NULL;
/* hash the plaintext */
+
d2.length = enclen - plainlen;
d2.data = output->data+plainlen;
@@ -180,7 +176,7 @@ krb5int_aes_encrypt_length(enc, hash, inputlen, length)
hashsize = 96 / 8;
/* No roundup, since CTS requires no padding once we've hit the
- block size. */
+ block size. */
*length = blocksize+inputlen + hashsize;
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/enc_provider/des.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/enc_provider/des.c
index 815e669ddb..2e9c76fb4b 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/enc_provider/des.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/enc_provider/des.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,9 +30,9 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <des_int.h>
-#include <enc_provider.h>
+#include "k5-int.h"
+#include "des_int.h"
+#include "enc_provider.h"
static krb5_error_code
k5_des_docrypt(krb5_context context, krb5_const krb5_keyblock *key,
@@ -117,7 +116,7 @@ k5_des_make_key(krb5_context context, krb5_const krb5_data *randombits,
return (ret);
}
-const struct krb5_enc_provider krb5_enc_des = {
+const struct krb5_enc_provider krb5int_enc_des = {
8,
7, 8,
k5_des_encrypt,
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/enc_provider/des3.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/enc_provider/des3.c
index 20f73b2cd4..f47aaf5207 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/enc_provider/des3.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/enc_provider/des3.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,8 +30,8 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <des_int.h>
+#include "k5-int.h"
+#include "des_int.h"
static krb5_error_code
k5_des3_docrypt(krb5_context context,
@@ -126,7 +125,7 @@ k5_des3_make_key(krb5_context context, krb5_const krb5_data *randombits,
return(ret);
}
-const struct krb5_enc_provider krb5_enc_des3 = {
+const struct krb5_enc_provider krb5int_enc_des3 = {
8,
21, 24,
k5_des3_encrypt,
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/encrypt.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/encrypt.c
index d8dd5f3f1f..40a8558ced 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/encrypt.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/encrypt.c
@@ -1,8 +1,7 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -30,8 +29,8 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <etypes.h>
+#include "k5-int.h"
+#include "etypes.h"
#ifdef _KERNEL
@@ -174,8 +173,8 @@ init_key_uef(CK_SESSION_HANDLE hSession, krb5_keyblock *key)
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
krb5_c_encrypt(krb5_context context, const krb5_keyblock *key,
- krb5_keyusage usage, const krb5_data *ivec,
- const krb5_data *input, krb5_enc_data *output)
+ krb5_keyusage usage, const krb5_data *ivec,
+ const krb5_data *input, krb5_enc_data *output)
{
krb5_error_code ret;
int i;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/encrypt_length.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/encrypt_length.c
index 78df89bd18..40c5bf96e3 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/encrypt_length.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/encrypt_length.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -25,13 +24,13 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <etypes.h>
+#include "k5-int.h"
+#include "etypes.h"
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
krb5_c_encrypt_length(krb5_context context, krb5_enctype enctype,
- size_t inputlen, size_t *length)
+ size_t inputlen, size_t *length)
{
int i;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/etypes.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/etypes.c
index 17ab43c3ae..7566a0e036 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/etypes.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/etypes.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -35,7 +34,7 @@
/* Solaris Kerberos:
* we don't provide these functions to the kernel
*/
-#define krb5_des_string_to_key NULL
+#define krb5int_des_string_to_key NULL
#define krb5_dk_string_to_key NULL
#define krb5int_arcfour_string_to_key NULL
#endif /* _KERNEL */
@@ -59,11 +58,11 @@
struct krb5_keytypes krb5_enctypes_list[] = {
{ ENCTYPE_DES_CBC_CRC,
"des-cbc-crc", "DES cbc mode with CRC-32",
- &krb5_enc_des, &krb5_hash_crc32,
+ &krb5int_enc_des, &krb5int_hash_crc32,
krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
CKSUMTYPE_RSA_MD5,
#ifndef _KERNEL
- krb5_des_string_to_key,
+ krb5int_des_string_to_key,
#else
SUN_CKM_DES_CBC,
NULL,
@@ -73,11 +72,11 @@ struct krb5_keytypes krb5_enctypes_list[] = {
},
{ ENCTYPE_DES_CBC_MD5,
"des-cbc-md5", "DES cbc mode with RSA-MD5",
- &krb5_enc_des, &krb5int_hash_md5,
+ &krb5int_enc_des, &krb5int_hash_md5,
krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
CKSUMTYPE_RSA_MD5,
#ifndef _KERNEL
- krb5_des_string_to_key,
+ krb5int_des_string_to_key,
#else
SUN_CKM_DES_CBC,
SUN_CKM_MD5,
@@ -87,11 +86,11 @@ struct krb5_keytypes krb5_enctypes_list[] = {
},
{ ENCTYPE_DES_CBC_MD5,
"des", "DES cbc mode with RSA-MD5", /* alias */
- &krb5_enc_des, &krb5int_hash_md5,
+ &krb5int_enc_des, &krb5int_hash_md5,
krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
CKSUMTYPE_RSA_MD5,
#ifndef _KERNEL
- krb5_des_string_to_key,
+ krb5int_des_string_to_key,
#else
SUN_CKM_DES_CBC,
SUN_CKM_MD5,
@@ -101,11 +100,11 @@ struct krb5_keytypes krb5_enctypes_list[] = {
},
{ ENCTYPE_DES_CBC_RAW,
"des-cbc-raw", "DES cbc mode raw",
- &krb5_enc_des, NULL,
+ &krb5int_enc_des, NULL,
krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt,
NULL,
#ifndef _KERNEL
- krb5_des_string_to_key,
+ krb5int_des_string_to_key,
#else
SUN_CKM_DES_CBC,
NULL,
@@ -116,11 +115,11 @@ struct krb5_keytypes krb5_enctypes_list[] = {
{ ENCTYPE_DES3_CBC_RAW,
"des3-cbc-raw", "Triple DES cbc mode raw",
- &krb5_enc_des3, NULL,
+ &krb5int_enc_des3, NULL,
krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt,
NULL,
#ifndef _KERNEL
- krb5_dk_string_to_key,
+ krb5int_dk_string_to_key,
#else
SUN_CKM_DES3_CBC,
NULL,
@@ -131,11 +130,11 @@ struct krb5_keytypes krb5_enctypes_list[] = {
{ ENCTYPE_DES3_CBC_SHA1,
"des3-cbc-sha1", "Triple DES cbc mode with HMAC/sha1",
- &krb5_enc_des3, &krb5_hash_sha1,
+ &krb5int_enc_des3, &krb5int_hash_sha1,
krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
CKSUMTYPE_HMAC_SHA1_DES3,
#ifndef _KERNEL
- krb5_dk_string_to_key,
+ krb5int_dk_string_to_key,
#else
SUN_CKM_DES3_CBC,
SUN_CKM_SHA1_HMAC,
@@ -145,11 +144,11 @@ struct krb5_keytypes krb5_enctypes_list[] = {
},
{ ENCTYPE_DES3_CBC_SHA1, /* alias */
"des3-hmac-sha1", "Triple DES cbc mode with HMAC/sha1",
- &krb5_enc_des3, &krb5_hash_sha1,
+ &krb5int_enc_des3, &krb5int_hash_sha1,
krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
CKSUMTYPE_HMAC_SHA1_DES3,
#ifndef _KERNEL
- krb5_dk_string_to_key,
+ krb5int_dk_string_to_key,
#else
SUN_CKM_DES3_CBC,
SUN_CKM_SHA1_HMAC,
@@ -159,11 +158,11 @@ struct krb5_keytypes krb5_enctypes_list[] = {
},
{ ENCTYPE_DES3_CBC_SHA1, /* alias */
"des3-cbc-sha1-kd", "Triple DES cbc mode with HMAC/sha1",
- &krb5_enc_des3, &krb5_hash_sha1,
+ &krb5int_enc_des3, &krb5int_hash_sha1,
krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
CKSUMTYPE_HMAC_SHA1_DES3,
#ifndef _KERNEL
- krb5_dk_string_to_key,
+ krb5int_dk_string_to_key,
#else
SUN_CKM_DES3_CBC,
SUN_CKM_SHA1_HMAC,
@@ -176,11 +175,11 @@ struct krb5_keytypes krb5_enctypes_list[] = {
*/
{ ENCTYPE_DES3_CBC_SHA1, /* alias */
"des3-cbc-hmac-sha1-kd", "Triple DES cbc mode with HMAC/sha1",
- &krb5_enc_des3, &krb5_hash_sha1,
+ &krb5int_enc_des3, &krb5int_hash_sha1,
krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
CKSUMTYPE_HMAC_SHA1_DES3,
#ifndef _KERNEL
- krb5_dk_string_to_key,
+ krb5int_dk_string_to_key,
#else
SUN_CKM_DES3_CBC,
SUN_CKM_SHA1_HMAC,
@@ -191,11 +190,11 @@ struct krb5_keytypes krb5_enctypes_list[] = {
{ ENCTYPE_DES_HMAC_SHA1,
"des-hmac-sha1", "DES with HMAC/sha1",
- &krb5_enc_des, &krb5_hash_sha1,
+ &krb5int_enc_des, &krb5int_hash_sha1,
krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
NULL,
#ifndef _KERNEL
- krb5_dk_string_to_key,
+ krb5int_dk_string_to_key,
#else
SUN_CKM_DES_CBC,
SUN_CKM_SHA1_HMAC,
@@ -205,8 +204,9 @@ struct krb5_keytypes krb5_enctypes_list[] = {
},
{ ENCTYPE_ARCFOUR_HMAC,
"arcfour-hmac","ArcFour with HMAC/md5", &krb5int_enc_arcfour,
- &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
- krb5_arcfour_decrypt,
+ &krb5int_hash_md5,
+krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
+ krb5_arcfour_decrypt,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
#ifndef _KERNEL
krb5int_arcfour_string_to_key,
@@ -218,9 +218,10 @@ struct krb5_keytypes krb5_enctypes_list[] = {
#endif /* !_KERNEL */
},
{ ENCTYPE_ARCFOUR_HMAC, /* alias */
- "rc4-hmac", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
- &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
- krb5_arcfour_decrypt,
+ "rc4-hmac", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
+ &krb5int_hash_md5,
+ krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
+ krb5_arcfour_decrypt,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
#ifndef _KERNEL
krb5int_arcfour_string_to_key,
@@ -232,9 +233,10 @@ struct krb5_keytypes krb5_enctypes_list[] = {
#endif /* !_KERNEL */
},
{ ENCTYPE_ARCFOUR_HMAC, /* alias */
- "arcfour-hmac-md5", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
- &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
- krb5_arcfour_decrypt,
+ "arcfour-hmac-md5", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
+ &krb5int_hash_md5,
+ krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
+ krb5_arcfour_decrypt,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
#ifndef _KERNEL
krb5int_arcfour_string_to_key,
@@ -261,10 +263,11 @@ struct krb5_keytypes krb5_enctypes_list[] = {
#endif /* !_KERNEL */
},
{ ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */
- "rc4-hmac-exp", "Exportable ArcFour with HMAC/md5",
- &krb5int_enc_arcfour,
- &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
- krb5_arcfour_decrypt,
+ "rc4-hmac-exp", "Exportable ArcFour with HMAC/md5",
+ &krb5int_enc_arcfour,
+ &krb5int_hash_md5,
+ krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
+ krb5_arcfour_decrypt,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
#ifndef _KERNEL
krb5int_arcfour_string_to_key,
@@ -276,10 +279,11 @@ struct krb5_keytypes krb5_enctypes_list[] = {
#endif /* !_KERNEL */
},
{ ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */
- "arcfour-hmac-md5-exp", "Exportable ArcFour with HMAC/md5",
- &krb5int_enc_arcfour,
- &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
- krb5_arcfour_decrypt,
+ "arcfour-hmac-md5-exp", "Exportable ArcFour with HMAC/md5",
+ &krb5int_enc_arcfour,
+ &krb5int_hash_md5,
+ krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
+ krb5_arcfour_decrypt,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
#ifndef _KERNEL
krb5int_arcfour_string_to_key,
@@ -296,12 +300,12 @@ struct krb5_keytypes krb5_enctypes_list[] = {
* more info.
*/
{ ENCTYPE_AES128_CTS_HMAC_SHA1_96,
- "aes128-cts-hmac-sha1-96", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
- &krb5int_enc_aes128, &krb5_hash_sha1,
- krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
- CKSUMTYPE_HMAC_SHA1_96_AES128,
+ "aes128-cts-hmac-sha1-96", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
+ &krb5int_enc_aes128, &krb5int_hash_sha1,
+ krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
+ CKSUMTYPE_HMAC_SHA1_96_AES128,
#ifndef _KERNEL
- krb5int_aes_string_to_key,
+ krb5int_aes_string_to_key,
#else
SUN_CKM_AES_CBC,
SUN_CKM_SHA1_HMAC,
@@ -311,7 +315,7 @@ struct krb5_keytypes krb5_enctypes_list[] = {
},
{ ENCTYPE_AES128_CTS_HMAC_SHA1_96,
"aes128-cts", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
- &krb5int_enc_aes128, &krb5_hash_sha1,
+ &krb5int_enc_aes128, &krb5int_hash_sha1,
krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
CKSUMTYPE_HMAC_SHA1_96_AES128,
#ifndef _KERNEL
@@ -324,12 +328,12 @@ struct krb5_keytypes krb5_enctypes_list[] = {
#endif /* !_KERNEL */
},
{ ENCTYPE_AES256_CTS_HMAC_SHA1_96,
- "aes256-cts-hmac-sha1-96", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
- &krb5int_enc_aes256, &krb5_hash_sha1,
- krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
- CKSUMTYPE_HMAC_SHA1_96_AES256,
+ "aes256-cts-hmac-sha1-96", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
+ &krb5int_enc_aes256, &krb5int_hash_sha1,
+ krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
+ CKSUMTYPE_HMAC_SHA1_96_AES256,
#ifndef _KERNEL
- krb5int_aes_string_to_key,
+ krb5int_aes_string_to_key,
#else
SUN_CKM_AES_CBC,
SUN_CKM_SHA1_HMAC,
@@ -339,7 +343,7 @@ struct krb5_keytypes krb5_enctypes_list[] = {
},
{ ENCTYPE_AES256_CTS_HMAC_SHA1_96,
"aes256-cts", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
- &krb5int_enc_aes256, &krb5_hash_sha1,
+ &krb5int_enc_aes256, &krb5int_hash_sha1,
krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
CKSUMTYPE_HMAC_SHA1_96_AES256,
#ifndef _KERNEL
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/hash_provider/hash_crc32.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/hash_provider/hash_crc32.c
index abde11aed2..949f55b347 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/hash_provider/hash_crc32.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/hash_provider/hash_crc32.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -25,16 +24,15 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <gssapiP_krb5.h>
-#include <crc-32.h>
-#include <hash_provider.h>
+#include "k5-int.h"
+#include "crc-32.h"
+#include "hash_provider.h"
/* ARGSUSED */
static krb5_error_code
k5_crc32_hash(krb5_context context,
- unsigned int icount, krb5_const krb5_data *input,
- krb5_data *output)
+ unsigned int icount, krb5_const krb5_data *input,
+ krb5_data *output)
{
unsigned long c, cn;
int i;
@@ -56,7 +54,7 @@ k5_crc32_hash(krb5_context context,
return(0);
}
-const struct krb5_hash_provider krb5_hash_crc32 = {
+const struct krb5_hash_provider krb5int_hash_crc32 = {
CRC32_CKSUM_LENGTH,
1,
k5_crc32_hash
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/hash_provider/hash_ksha1.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/hash_provider/hash_ksha1.c
index b7046f88f6..3147b6c8a6 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/hash_provider/hash_ksha1.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/hash_provider/hash_ksha1.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -66,7 +65,7 @@ k5_sha1_hash(krb5_context context,
return(ret);
}
-const struct krb5_hash_provider krb5_hash_sha1 = {
+const struct krb5_hash_provider krb5int_hash_sha1 = {
SHS_DIGESTSIZE,
SHS_DATASIZE,
k5_sha1_hash
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/hmac.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/hmac.c
index 2ba05ab7ff..07ec50c3e3 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/hmac.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/hmac.c
@@ -1,20 +1,19 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* 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
@@ -25,14 +24,15 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
+#include "k5-int.h"
+/* Solaris Kerberos */
#ifdef _KERNEL
/*
* In kernel, use the Kernel encryption framework HMAC
@@ -101,6 +101,7 @@ krb5_hmac(krb5_context context, const krb5_keyblock *key,
* opad is the byte 0x5c repeated blocksize times
* and text is the data being protected
*/
+
krb5_error_code
krb5_hmac(krb5_context context,
krb5_const struct krb5_hash_provider *hash,
@@ -115,6 +116,7 @@ krb5_hmac(krb5_context context,
krb5_data *hashin, hashout;
krb5_error_code ret;
+ /* Solaris Kerberos */
KRB5_LOG0(KRB5_INFO, "krb5_hmac() start\n");
if (hash == NULL) {
@@ -162,11 +164,11 @@ krb5_hmac(krb5_context context,
/* create the inner padded key */
+ /* Solaris Kerberos */
(void) memset(xorkey, 0x36, blocksize);
- for (i=0; i<key->length; i++) {
+ for (i=0; i<key->length; i++)
xorkey[i] ^= key->contents[i];
- }
/* compute the inner hash */
@@ -179,11 +181,13 @@ krb5_hmac(krb5_context context,
hashout.length = hashsize;
hashout.data = (char *) ihash;
+ /* Solaris Kerberos */
if ((ret = ((*(hash->hash))(context, icount+1, hashin, &hashout))))
goto cleanup;
/* create the outer padded key */
+ /* Solaris Kerberos */
(void) memset(xorkey, 0x5c, blocksize);
for (i=0; i<key->length; i++)
@@ -197,12 +201,14 @@ krb5_hmac(krb5_context context,
output->length = hashsize;
+ /* Solaris Kerberos */
if ((ret = ((*(hash->hash))(context, 2, hashin, output))))
(void) memset(output->data, 0, output->length);
/* ret is set correctly by the prior call */
cleanup:
+ /* Solaris Kerberos */
(void) memset(xorkey, 0, blocksize);
(void) memset(ihash, 0, hashsize);
@@ -210,6 +216,7 @@ cleanup:
FREE(ihash, hashsize);
FREE(xorkey, blocksize);
+ /* Solaris Kerberos */
KRB5_LOG(KRB5_INFO, "krb5_hmac() end ret=%d\n", ret);
return(ret);
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/keyhash_provider/descbc.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/keyhash_provider/descbc.c
index d136871bbb..64660c05f8 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/keyhash_provider/descbc.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/keyhash_provider/descbc.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,9 +30,9 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <des_int.h>
-#include <keyhash_provider.h>
+#include "k5-int.h"
+#include "des_int.h"
+#include "keyhash_provider.h"
#ifdef _KERNEL
#include <sys/kmem.h>
#include <sys/crypto/api.h>
@@ -68,7 +67,7 @@ k5_descbc_hash(krb5_context context,
return(ret);
}
-const struct krb5_keyhash_provider krb5_keyhash_descbc = {
+const struct krb5_keyhash_provider krb5int_keyhash_descbc = {
MIT_DES_BLOCK_LENGTH,
k5_descbc_hash,
NULL
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/keyhash_provider/k5_kmd5des.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/keyhash_provider/k5_kmd5des.c
index c2b814f600..5d94f35085 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/keyhash_provider/k5_kmd5des.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/keyhash_provider/k5_kmd5des.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -39,8 +38,8 @@
* This means that the MD5* functions are called instead of krb5_MD5*.
*/
-#include <krb5.h>
#include <des_int.h>
+#include <krb5.h>
#include <keyhash_provider.h>
#include <sys/kmem.h>
#include <sys/crypto/api.h>
@@ -262,7 +261,7 @@ cleanup:
return(ret);
}
-const struct krb5_keyhash_provider krb5_keyhash_md5des = {
+const struct krb5_keyhash_provider krb5int_keyhash_md5des = {
CONFLENGTH+MD5_CKSUM_LENGTH,
k5_md5des_hash,
k5_md5des_verify
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/make_checksum.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/make_checksum.c
index d000988f18..7a448bab08 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/make_checksum.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/make_checksum.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,17 +30,15 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <cksumtypes.h>
-#include <etypes.h>
-
-#include <dk.h>
-
+#include "k5-int.h"
+#include "cksumtypes.h"
+#include "etypes.h"
+#include "dk.h"
krb5_error_code KRB5_CALLCONV
krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype,
- const krb5_keyblock *key, krb5_keyusage usage,
- const krb5_data *input, krb5_checksum *cksum)
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *input, krb5_checksum *cksum)
{
int i, e1, e2;
krb5_data data;
@@ -67,7 +64,7 @@ krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype,
context->kef_cksum_mt = krb5_cksumtypes_list[i].kef_cksum_mt;
#endif
cksum->length = cksumlen;
-
+
if ((cksum->contents = (krb5_octet *) MALLOC(cksum->length)) == NULL)
return(ENOMEM);
@@ -75,8 +72,8 @@ krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype,
data.data = (char *) cksum->contents;
if (krb5_cksumtypes_list[i].keyhash) {
-
/* check if key is compatible */
+
if (krb5_cksumtypes_list[i].keyed_etype) {
for (e1=0; e1<krb5_enctypes_length; e1++)
if (krb5_enctypes_list[e1].etype ==
@@ -145,8 +142,8 @@ krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype,
if (!ret) {
cksum->magic = KV5M_CHECKSUM;
cksum->checksum_type = cksumtype;
- if (krb5_cksumtypes_list[i].trunc_size) {
- krb5_octet *trunc;
+ if (krb5_cksumtypes_list[i].trunc_size) {
+ krb5_octet *trunc;
size_t old_len = cksum->length;
/*
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/mandatory_sumtype.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/mandatory_sumtype.c
index ffb5c62bbb..dd7044a593 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/mandatory_sumtype.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/mandatory_sumtype.c
@@ -1,10 +1,8 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"$
-
/*
* Copyright (C) 2003 by the Massachusetts Institute of Technology.
* All rights reserved.
@@ -29,8 +27,8 @@
* or implied warranty.
*/
-#include <k5-int.h>
-#include <etypes.h>
+#include "k5-int.h"
+#include "etypes.h"
/*ARGSUSED*/
krb5_error_code
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/nfold.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/nfold.c
index 7937e90895..a1a64531f9 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/nfold.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/nfold.c
@@ -1,15 +1,14 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* 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
@@ -31,7 +30,7 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
* Solaris Kerberos defines memory management macros in <krb5.h>,
@@ -56,11 +55,8 @@ n-fold(k-bits):
/* input length is in bits */
void
-krb5_nfold(inbits, in, outbits, out)
- int inbits;
- krb5_const unsigned char *in;
- int outbits;
- unsigned char *out;
+krb5_nfold(unsigned int inbits, const unsigned char *in, unsigned int outbits,
+ unsigned char *out)
{
int a,b,c,lcm;
int byte, i, msbit;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/old/old_decrypt.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/old/old_decrypt.c
index 14083326d2..b8e5951044 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/old/old_decrypt.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/old/old_decrypt.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,19 +30,19 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <old.h>
+#include "k5-int.h"
+#include "old.h"
/*ARGSUSED*/
krb5_error_code
krb5_old_decrypt(krb5_context context,
- krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
- krb5_const krb5_keyblock *key,
- krb5_keyusage usage,
- krb5_const krb5_data *ivec,
- krb5_const krb5_data *input,
- krb5_data *arg_output)
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key,
+ krb5_keyusage usage,
+ const krb5_data *ivec,
+ const krb5_data *input,
+ krb5_data *arg_output)
{
krb5_error_code ret;
size_t blocksize, hashsize, plainsize;
@@ -52,7 +51,6 @@ krb5_old_decrypt(krb5_context context,
int alloced;
unsigned char orig_cksum[128], new_cksum[128];
-
blocksize = enc->block_size;
hashsize = hash->hashsize;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/old/old_encrypt.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/old/old_encrypt.c
index b7d6ee9621..4c936b26e3 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/old/old_encrypt.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/old/old_encrypt.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,8 +30,8 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <old.h>
+#include "k5-int.h"
+#include "old.h"
void
krb5_old_encrypt_length(const struct krb5_enc_provider *enc,
@@ -51,13 +50,13 @@ krb5_old_encrypt_length(const struct krb5_enc_provider *enc,
/*ARGSUSED*/
krb5_error_code
krb5_old_encrypt(krb5_context context,
- krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
- krb5_const krb5_keyblock *key,
- krb5_keyusage usage,
- krb5_const krb5_data *ivec,
- krb5_const krb5_data *input,
- krb5_data *output)
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key,
+ krb5_keyusage usage,
+ const krb5_data *ivec,
+ const krb5_data *input,
+ krb5_data *output)
{
krb5_error_code ret;
size_t blocksize, hashsize, enclen;
@@ -83,7 +82,6 @@ krb5_old_encrypt(krb5_context context,
if ((ret = krb5_c_random_make_octets(context, &datain)))
return(ret);
-
(void) memcpy(output->data+blocksize+hashsize, input->data, input->length);
/* compute the checksum */
@@ -93,7 +91,7 @@ krb5_old_encrypt(krb5_context context,
if ((ret = ((*(hash->hash))(context, 1, output, &datain))))
goto cleanup;
-
+
/* encrypt it */
/* XXX this is gross, but I don't have much choice */
@@ -105,7 +103,7 @@ krb5_old_encrypt(krb5_context context,
} else
real_ivec = 1;
- if ((ret = ((*(enc->encrypt))(context, key, ivec, output, output))))
+ if ((ret = ((*(enc->encrypt))(context, key, ivec, output, output))))
goto cleanup;
/* update ivec */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/raw/raw_decrypt.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/raw/raw_decrypt.c
index c342044b5e..45eebb948d 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/raw/raw_decrypt.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/raw/raw_decrypt.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,20 +30,17 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <raw.h>
+#include "k5-int.h"
+#include "raw.h"
/*ARGSUSED*/
krb5_error_code
-krb5_raw_decrypt(context, enc, hash, key, usage, ivec, input, output)
- krb5_context context;
- krb5_const struct krb5_enc_provider *enc;
- krb5_const struct krb5_hash_provider *hash;
- krb5_const krb5_keyblock *key;
- krb5_keyusage usage;
- krb5_const krb5_data *ivec;
- krb5_const krb5_data *input;
- krb5_data *output;
+krb5_raw_decrypt(krb5_context context,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
+ krb5_data *output)
{
- return ((*(enc->decrypt))(context, key, ivec, input, output));
+ return((*(enc->decrypt))(context, key, ivec, input, output));
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/raw/raw_encrypt.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/raw/raw_encrypt.c
index 3fa8f2ae44..c1ba97a508 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/raw/raw_encrypt.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/raw/raw_encrypt.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,8 +30,8 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <raw.h>
+#include "k5-int.h"
+#include "raw.h"
/*ARGSUSED*/
void
@@ -50,13 +49,11 @@ krb5_raw_encrypt_length(const struct krb5_enc_provider *enc,
/*ARGSUSED*/
krb5_error_code
krb5_raw_encrypt(krb5_context context,
- krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
- krb5_const krb5_keyblock *key,
- krb5_keyusage usage,
- krb5_const krb5_data *ivec,
- krb5_const krb5_data *input,
- krb5_data *output)
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
+ krb5_data *output)
{
- return((*(enc->encrypt))(context, key, ivec, input, output));
+ return((*(enc->encrypt))(context, key, ivec, input, output));
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/crypto/verify_checksum.c b/usr/src/uts/common/gssapi/mechs/krb5/crypto/verify_checksum.c
index 8f1f67e5bc..9fcfeedc73 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/crypto/verify_checksum.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/crypto/verify_checksum.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,13 +30,13 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
-#include <cksumtypes.h>
+#include "k5-int.h"
+#include "cksumtypes.h"
krb5_error_code KRB5_CALLCONV
krb5_c_verify_checksum(krb5_context context, const krb5_keyblock *key,
- krb5_keyusage usage, const krb5_data *data,
- const krb5_checksum *cksum, krb5_boolean *valid)
+ krb5_keyusage usage, const krb5_data *data,
+ const krb5_checksum *cksum, krb5_boolean *valid)
{
int i;
size_t hashsize;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/aes_s2k.h b/usr/src/uts/common/gssapi/mechs/krb5/include/aes_s2k.h
new file mode 100644
index 0000000000..58a465ce8a
--- /dev/null
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/aes_s2k.h
@@ -0,0 +1,4 @@
+extern krb5_error_code
+krb5int_aes_string_to_key (krb5_context context, const struct krb5_enc_provider *,
+ const krb5_data *, const krb5_data *,
+ const krb5_data *, krb5_keyblock *key);
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/auth_con.h b/usr/src/uts/common/gssapi/mechs/krb5/include/auth_con.h
index 45c2b2e801..9543de355e 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/auth_con.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/auth_con.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
#ifndef KRB5_AUTH_CONTEXT
#define KRB5_AUTH_CONTEXT
@@ -22,8 +21,8 @@ struct _krb5_auth_context {
krb5_pointer i_vector; /* mk_priv, rd_priv only */
krb5_rcache rcache;
krb5_enctype * permitted_etypes; /* rd_req */
- krb5_mk_req_checksum_func checksum_func;
- void *checksum_func_data;
+ krb5_mk_req_checksum_func checksum_func;
+ void *checksum_func_data;
};
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/cksumtypes.h b/usr/src/uts/common/gssapi/mechs/krb5/include/cksumtypes.h
index 18cb4ba7cc..dae70c8f21 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/cksumtypes.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/cksumtypes.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -27,5 +26,5 @@
#include "k5-int.h"
-extern struct krb5_cksumtypes krb5_cksumtypes_list[];
+extern const struct krb5_cksumtypes krb5_cksumtypes_list[];
extern const int krb5_cksumtypes_length;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/crc-32.h b/usr/src/uts/common/gssapi/mechs/krb5/include/crc-32.h
index db13933a79..10facaa587 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/crc-32.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/crc-32.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* include/krb5/crc-32.h
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -25,6 +27,32 @@
* Definitions for the CRC-32 checksum
*/
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
#ifndef KRB5_CRC32__
#define KRB5_CRC32__
@@ -32,12 +60,12 @@
#define CRC32_CKSUM_LENGTH 4
void
-mit_crc32 (const krb5_pointer in, const size_t in_length, unsigned long *c);
+mit_crc32 (const krb5_pointer in, size_t in_length, unsigned long *c);
#ifdef CRC32_SHIFT4
void mit_crc32_shift4(const krb5_pointer /* in */,
- const size_t /* in_length */,
- unsigned long * /* cksum */);
+ const size_t /* in_length */,
+ unsigned long * /* cksum */);
#endif
#endif /* KRB5_CRC32__ */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/des_int.h b/usr/src/uts/common/gssapi/mechs/krb5/include/des_int.h
index 1817269cf0..8311997ff3 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/des_int.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/des_int.h
@@ -1,19 +1,19 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* lib/crypto/des/des_int.h
*
- * Copyright 1987, 1988, 1990 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
+ * Copyright 1987, 1988, 1990, 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
@@ -27,21 +27,21 @@
* 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.
- *
+ *
*
* Private include file for the Data Encryption Standard library.
*/
/*
* Copyright (C) 1998 by the FundsXpress, INC.
- *
+ *
* All rights reserved.
- *
+ *
* Export of this software from the United States of America may require
* a specific license from the United States Government. It is the
* responsibility of any person or organization contemplating export to
* obtain such a license before exporting.
- *
+ *
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
@@ -52,19 +52,18 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* only do the whole thing once */
-#ifndef DES_INTERNAL_DEFS
-#define DES_INTERNAL_DEFS
+#ifndef DES_INTERNAL_DEFS
+#define DES_INTERNAL_DEFS
-#pragma ident "%Z%%M% %I% %E% SMI"
-#include <k5-int.h>
+#include "k5-int.h"
/*
* Begin "mit-des.h"
*/
@@ -142,10 +141,9 @@ extern krb5_error_code mit_afs_string_to_key
/* f_cksum.c */
extern unsigned long mit_des_cbc_cksum
-(
- krb5_context context,
- krb5_octet *, krb5_octet *, long ,
- krb5_keyblock *, krb5_octet *);
+( krb5_context context,
+ const krb5_octet *, krb5_octet *, unsigned long ,
+ krb5_keyblock *, const krb5_octet *);
/* f_cbc.c */
extern int mit_des_cbc_encrypt
@@ -161,48 +159,47 @@ extern const mit_des_cblock mit_des_zeroblock;
/* fin_rndkey.c */
extern krb5_error_code mit_des_finish_random_key
-(const krb5_encrypt_block *,
- krb5_pointer *);
+ ( const krb5_encrypt_block *,
+ krb5_pointer *);
/* finish_key.c */
extern krb5_error_code mit_des_finish_key
-( krb5_encrypt_block *);
+ ( krb5_encrypt_block *);
/* key_parity.c */
-extern void mit_des_fixup_key_parity (mit_des_cblock);
+extern void mit_des_fixup_key_parity (mit_des_cblock );
extern int mit_des_check_key_parity (mit_des_cblock );
/* process_ky.c */
extern krb5_error_code mit_des_process_key
-( krb5_encrypt_block *, const krb5_keyblock *);
+ ( krb5_encrypt_block *, const krb5_keyblock *);
/* string2key.c */
extern krb5_error_code mit_des_string_to_key
-(const krb5_encrypt_block *,
- krb5_keyblock *,
- const krb5_data *,
- const krb5_data *);
+ ( const krb5_encrypt_block *,
+ krb5_keyblock *, const krb5_data *, const krb5_data *);
/* weak_key.c */
-extern int mit_des_is_weak_key (mit_des_cblock);
+extern int mit_des_is_weak_key (mit_des_cblock );
/* cmb_keys.c */
krb5_error_code mit_des_combine_subkeys
-(const krb5_keyblock *, const krb5_keyblock *,
- krb5_keyblock * *);
+ (const krb5_keyblock *, const krb5_keyblock *,
+ krb5_keyblock **);
/* f_pcbc.c */
int mit_des_pcbc_encrypt ();
/* f_sched.c */
-int mit_des_make_key_sched(mit_des_cblock, mit_des_key_schedule);
+int mit_des_make_key_sched(mit_des_cblock, mit_des_key_schedule);
+
/* misc.c */
-extern void swap_bits (char *) ;
-extern unsigned long long_swap_bits (unsigned long ) ;
-extern unsigned long swap_six_bits_to_ansi (unsigned long ) ;
-extern unsigned long swap_four_bits_to_ansi (unsigned long ) ;
-extern unsigned long swap_bit_pos_1 (unsigned long ) ;
+extern void swap_bits (char *);
+extern unsigned long long_swap_bits (unsigned long );
+extern unsigned long swap_six_bits_to_ansi (unsigned long );
+extern unsigned long swap_four_bits_to_ansi (unsigned long );
+extern unsigned long swap_bit_pos_1 (unsigned long );
extern unsigned long swap_bit_pos_0 (unsigned long );
extern unsigned long swap_bit_pos_0_to_ansi (unsigned long );
extern unsigned long rev_swap_bit_pos_0 (unsigned long );
@@ -215,36 +212,35 @@ extern void test_set (FILE *, const char *, int, const char *, int);
/* d3_cbc.c */
extern int mit_des3_cbc_encrypt
-(krb5_context context,
- const mit_des_cblock *in,
- mit_des_cblock *out,
- long length,
- krb5_keyblock *key,
- mit_des_cblock ivec,
- int encrypt);
+ (krb5_context context,
+ const mit_des_cblock *in,
+ mit_des_cblock *out,
+ unsigned long length,
+ krb5_keyblock *key,
+ const mit_des_cblock ivec,
+ int enc);
/* d3_procky.c */
extern krb5_error_code mit_des3_process_key
-(krb5_encrypt_block * eblock,
+ (krb5_encrypt_block * eblock,
const krb5_keyblock * keyblock);
/* d3_str2ky.c */
extern krb5_error_code mit_des3_string_to_key
-(const krb5_encrypt_block *,
- krb5_keyblock *,
- const krb5_data *,
- const krb5_data *);
-
+ (const krb5_encrypt_block * eblock,
+ krb5_keyblock * keyblock,
+ const krb5_data * data,
+ const krb5_data * salt);
/* u_nfold.c */
extern krb5_error_code mit_des_n_fold
-(const krb5_octet * input,
+ (const krb5_octet * input,
const size_t in_len,
krb5_octet * output,
const size_t out_len);
extern krb5_error_code mit_des_set_random_sequence_number
-(const krb5_data * sequence,
+ (const krb5_data * sequence,
krb5_pointer random_state);
#endif /*DES_INTERNAL_DEFS*/
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/dk.h b/usr/src/uts/common/gssapi/mechs/krb5/include/dk.h
index be73c952f8..574c7496dd 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/dk.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/dk.h
@@ -1,6 +1,3 @@
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -27,24 +24,21 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#ifndef _KRB5_DK_
-#define _KRB5_DK_
-
-#include <k5-int.h>
+#include "k5-int.h"
-extern void krb5_dk_encrypt_length
-(krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
- size_t input, size_t *length);
+void krb5_dk_encrypt_length
+(const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ size_t input, size_t *length);
-extern krb5_error_code krb5_dk_encrypt
+krb5_error_code krb5_dk_encrypt
(
- krb5_context context,
- krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
- krb5_const krb5_keyblock *key, krb5_keyusage usage,
- krb5_const krb5_data *ivec,
- krb5_const krb5_data *input, krb5_data *output);
+ krb5_context context,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec,
+ const krb5_data *input, krb5_data *output);
extern krb5_error_code krb5_dk_decrypt
(krb5_context context,
@@ -68,7 +62,7 @@ extern krb5_error_code krb5_dk_make_checksum
#ifndef _KERNEL
-extern krb5_error_code krb5_dk_string_to_key
+extern krb5_error_code krb5int_dk_string_to_key
(krb5_context context,
krb5_const struct krb5_enc_provider *enc,
krb5_const krb5_data *string,
@@ -78,7 +72,7 @@ extern krb5_error_code krb5_dk_string_to_key
#endif
void krb5int_aes_encrypt_length
-( const struct krb5_enc_provider *enc,
+(const struct krb5_enc_provider *enc,
const struct krb5_hash_provider *hash,
size_t input, size_t *length);
@@ -103,8 +97,3 @@ krb5int_aes_string_to_key (krb5_context context,
const struct krb5_enc_provider *,
const krb5_data *, const krb5_data *,
const krb5_data *, krb5_keyblock *key);
-
-
-
-#endif /* _KRB5_DK_ */
-
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/enc_provider.h b/usr/src/uts/common/gssapi/mechs/krb5/include/enc_provider.h
index 38ed5293ae..5754d1a2d5 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/enc_provider.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/enc_provider.h
@@ -1,11 +1,4 @@
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
* All rights reserved.
@@ -33,8 +26,8 @@
#include "k5-int.h"
-extern const struct krb5_enc_provider krb5_enc_des;
-extern const struct krb5_enc_provider krb5_enc_des3;
+extern const struct krb5_enc_provider krb5int_enc_des;
+extern const struct krb5_enc_provider krb5int_enc_des3;
extern const struct krb5_enc_provider krb5int_enc_arcfour;
extern const struct krb5_enc_provider krb5int_enc_aes128;
extern const struct krb5_enc_provider krb5int_enc_aes256;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h
index f218b8aba3..75d5d263b4 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1993 by OpenVision Technologies, Inc.
@@ -31,7 +30,7 @@
#define _GSSAPIP_GENERIC_H_
/*
- * $Id: gssapiP_generic.h 18131 2006-06-14 22:27:54Z tlyu $
+ * $Id: gssapiP_generic.h 18396 2006-07-25 20:29:43Z lxs $
*/
#if defined(_WIN32)
@@ -64,9 +63,9 @@ typedef UINT64_TYPE gssint_uint64;
/** helper macros **/
#if 0 /* SUNW15resync - on Solaris g_OID_equal is in gssapi_ext.h */
-#define g_OID_equal(o1, o2) \
- (((o1)->length == (o2)->length) && \
- (memcmp((o1)->elements, (o2)->elements, (o1)->length) == 0))
+#define g_OID_equal(o1, o2) \
+ (((o1)->length == (o2)->length) && \
+ (memcmp((o1)->elements,(o2)->elements,(unsigned int) (o1)->length) == 0))
#endif
/* this code knows that an int on the wire is 32 bits. The type of
@@ -98,7 +97,7 @@ typedef UINT64_TYPE gssint_uint64;
(ptr) += 2;
#define TWRITE_STR(ptr, str, len) \
- (void) memcpy((ptr), (char *) (str), (len)); \
+ (void) memcpy((ptr), (char *) (str), (len)); \
(ptr) += (len);
#define TREAD_STR(ptr, str, len) \
@@ -261,20 +260,20 @@ OM_uint32 generic_gss_create_empty_oid_set
OM_uint32 generic_gss_add_oid_set_member
(OM_uint32 *, /* minor_status */
- gss_OID_desc * const, /* member_oid */
+ const gss_OID_desc * const, /* member_oid */
gss_OID_set * /* oid_set */
);
OM_uint32 generic_gss_test_oid_set_member
(OM_uint32 *, /* minor_status */
- gss_OID_desc * const, /* member */
+ const gss_OID_desc * const, /* member */
gss_OID_set, /* set */
int * /* present */
);
OM_uint32 generic_gss_oid_to_str
(OM_uint32 *, /* minor_status */
- gss_OID_desc * const, /* oid */
+ const gss_OID_desc * const, /* oid */
gss_buffer_t /* oid_str */
);
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h
index 4ea1c17634..95002d4c6b 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 2000 by the Massachusetts Institute of Technology.
@@ -270,7 +269,7 @@ krb5_error_code kg_make_confounder (krb5_context context,
krb5_error_code kg_encrypt (krb5_context context,
krb5_keyblock *key, int usage,
krb5_pointer iv,
- krb5_pointer in,
+ krb5_const_pointer in,
krb5_pointer out,
unsigned int length);
krb5_error_code
@@ -283,7 +282,7 @@ kg_arcfour_docrypt (krb5_context,
krb5_error_code kg_decrypt (krb5_context context,
krb5_keyblock *key, int usage,
krb5_pointer iv,
- krb5_pointer in,
+ krb5_const_pointer in,
krb5_pointer out,
unsigned int length);
@@ -327,6 +326,9 @@ krb5_error_code kg_ctx_internalize (krb5_context kcontext,
OM_uint32 kg_sync_ccache_name (krb5_context context, OM_uint32 *minor_status);
+OM_uint32 kg_caller_provided_ccache_name (OM_uint32 *minor_status,
+ int *out_caller_provided_name);
+
OM_uint32 kg_get_ccache_name (OM_uint32 *minor_status,
const char **out_name);
@@ -666,7 +668,7 @@ krb5_error_code gss_krb5int_make_seal_token_v3(krb5_context,
gss_buffer_t,
int, int);
-OM_uint32 gss_krb5int_unseal_token_v3(krb5_context context,
+OM_uint32 gss_krb5int_unseal_token_v3(krb5_context *contextptr,
OM_uint32 *minor_status,
krb5_gss_ctx_id_rec *ctx,
unsigned char *ptr, int bodysize,
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_generic.h b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_generic.h
index 8e3983867a..bba249d70e 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_generic.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_generic.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,10 +28,8 @@
#ifndef _GSSAPI_GENERIC_H_
#define _GSSAPI_GENERIC_H_
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
- * $Id: gssapi_generic.h,v 1.16 2003/03/06 20:26:35 lxs Exp $
+ * $Id: gssapi_generic.h 15252 2003-03-06 20:26:39Z lxs $
*/
#include <gssapi/gssapi.h>
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/hash_provider.h b/usr/src/uts/common/gssapi/mechs/krb5/include/hash_provider.h
index 31ef24ccdc..297a2559c3 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/hash_provider.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/hash_provider.h
@@ -1,9 +1,8 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -31,8 +30,8 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
+#include "k5-int.h"
-extern const struct krb5_hash_provider krb5_hash_crc32;
+extern const struct krb5_hash_provider krb5int_hash_crc32;
extern const struct krb5_hash_provider krb5int_hash_md5;
-extern const struct krb5_hash_provider krb5_hash_sha1;
+extern const struct krb5_hash_provider krb5int_hash_sha1;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h
index a0095f0f13..449115b131 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h
@@ -1,59 +1,59 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (C) 1989,1990,1991,1992,1993,1994,1995,2000,2001, 2003,2006 by the Massachusetts Institute of Technology,
* Cambridge, MA, USA. All Rights Reserved.
- *
- * This software is being provided to you, the LICENSEE, by the
- * Massachusetts Institute of Technology (M.I.T.) under the following
- * license. By obtaining, using and/or copying this software, you agree
- * that you have read, understood, and will comply with these terms and
- * conditions:
- *
+ *
+ * This software is being provided to you, the LICENSEE, by the
+ * Massachusetts Institute of Technology (M.I.T.) under the following
+ * license. By obtaining, using and/or copying this software, you agree
+ * that you have read, understood, and will comply with these terms and
+ * conditions:
+ *
* 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 or
- * royalty is hereby granted, provided that you agree to comply with the
- * following copyright notice and statements, including the disclaimer, and
- * that the same appear on ALL copies of the software and documentation,
- * including modifications that you make for internal use or for
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify and distribute
+ * this software and its documentation for any purpose and without fee or
+ * royalty is hereby granted, provided that you agree to comply with the
+ * following copyright notice and statements, including the disclaimer, and
+ * that the same appear on ALL copies of the software and documentation,
+ * including modifications that you make for internal use or for
* distribution:
- *
- * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS
- * OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not
- * limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF
- * MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
- * THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
- * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
- *
- * The name of the Massachusetts Institute of Technology or M.I.T. may NOT
- * be used in advertising or publicity pertaining to distribution of the
- * software. Title to copyright in this software and any associated
- * documentation shall at all times remain with M.I.T., and USER agrees to
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS
+ * OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not
+ * limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF
+ * MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
+ * THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
+ * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+ *
+ * The name of the Massachusetts Institute of Technology or M.I.T. may NOT
+ * be used in advertising or publicity pertaining to distribution of the
+ * software. Title to copyright in this software and any associated
+ * documentation shall at all times remain with M.I.T., and USER agrees to
* preserve same.
*
* 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.
-
*/
+
/*
* 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
@@ -64,7 +64,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.
@@ -82,7 +82,9 @@
#ifndef _KRB5_INT_H
#define _KRB5_INT_H
-#pragma ident "%Z%%M% %I% %E% SMI"
+#ifdef KRB5_GENERAL__
+#error krb5.h included before k5-int.h
+#endif /* KRB5_GENERAL__ */
#ifndef _KERNEL
#include <osconf.h>
@@ -175,52 +177,60 @@ extern unsigned int krb5_log;
#ifndef KRB5_CONFIG__
#define KRB5_CONFIG__
-/*
- * Machine-type definitions: PC Clone 386 running Microsoft Windows
+/*
+ * Machine-type definitions: PC Clone 386 running Microloss Windows
*/
-#if defined(_MSDOS) || defined(_WIN32)
+#if defined(_MSDOS) || defined(_WIN32)
#include "win-mac.h"
/* Kerberos Windows initialization file */
-#define KERBEROS_INI "kerberos.ini"
-#define INI_FILES "Files"
-#define INI_KRB_CCACHE "krb5cc" /* Location of the ccache */
-#define INI_KRB5_CONF "krb5.ini" /* Location of krb5.conf file */
+#define KERBEROS_INI "kerberos.ini"
+#define INI_FILES "Files"
+#define INI_KRB_CCACHE "krb5cc" /* Location of the ccache */
+#define INI_KRB5_CONF "krb5.ini" /* Location of krb5.conf file */
#define ANSI_STDIO
#endif
#ifndef _KERNEL
#ifndef KRB5_AUTOCONF__
#define KRB5_AUTOCONF__
-#include <autoconf.h>
+#include "autoconf.h"
#endif
#endif /* !_KERNEL */
#ifndef KRB5_SYSTYPES__
#define KRB5_SYSTYPES__
+#ifndef _KERNEL
#ifdef HAVE_SYS_TYPES_H /* From autoconf.h */
#include <sys/types.h>
#else /* HAVE_SYS_TYPES_H */
+typedef unsigned long u_long;
+typedef unsigned int u_int;
+typedef unsigned short u_short;
+typedef unsigned char u_char;
#endif /* HAVE_SYS_TYPES_H */
#endif /* KRB5_SYSTYPES__ */
+#endif /* !_KERNEL */
+
/* #include "k5-platform.h" SUNW XXX */
/* not used in krb5.h (yet) */
typedef uint64_t krb5_ui_8;
typedef int64_t krb5_int64;
+
+
#define DEFAULT_PWD_STRING1 "Enter password:"
#define DEFAULT_PWD_STRING2 "Re-enter password for verification:"
-
#define KRB5_KDB_MAX_LIFE (60*60*24) /* one day */
#define KRB5_KDB_MAX_RLIFE (60*60*24*365) /* one year */
#define KRB5_KDB_EXPIRATION 2145830400 /* Thu Jan 1 00:00:00 2038 UTC */
#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
#define KRB5_DEFAULT_RENEW_LIFE 7*24*60*60 /* 7 Days */
-/*
+/*
* Windows requires a different api interface to each function. Here
* just define it as NULL.
*/
@@ -262,13 +272,6 @@ struct sockaddr;
/* Get mutex support; currently used only for the replay cache. */
#include "k5-thread.h"
-/*
- * Solaris Kerberos:
- * Define whether or not to do a reverse lookup when looking up a host in DNS.
- */
-#define REV_LOOKUP 1
-#define NO_REV_LOOKUP 0
-
/* krb5/krb5.h includes many other .h files in the krb5 subdirectory.
The ones that it doesn't include, we include below. */
@@ -314,6 +317,10 @@ struct sockaddr;
/* required */
#define KDC_ERR_SERVER_NOMATCH 26 /* Requested server and */
/* ticket don't match*/
+#define KDC_ERR_SVC_UNAVAILABLE 29 /* A service is not
+ * available that is
+ * required to process the
+ * request */
/* Application errors */
#define KRB_AP_ERR_BAD_INTEGRITY 31 /* Decrypt integrity check failed */
#define KRB_AP_ERR_TKT_EXPIRED 32 /* Ticket expired */
@@ -337,15 +344,32 @@ struct sockaddr;
/* in message */
#define KRB_AP_ERR_INAPP_CKSUM 50 /* Inappropriate type of */
/* checksum in message */
-#define KRB_AP_PATH_NOT_ACCEPTED 51 /* Policy rejects transited path */
-#define KRB_ERR_RESPONSE_TOO_BIG 52 /* Response too big for UDP, */
- /* retry with TCP */
+#define KRB_AP_PATH_NOT_ACCEPTED 51 /* Policy rejects transited path */
+#define KRB_ERR_RESPONSE_TOO_BIG 52 /* Response too big for UDP, */
+ /* retry with TCP */
/* other errors */
#define KRB_ERR_GENERIC 60 /* Generic error (description */
/* in e-text) */
#define KRB_ERR_FIELD_TOOLONG 61 /* Field is too long for impl. */
+/* PKINIT server-reported errors */
+#define KDC_ERR_CLIENT_NOT_TRUSTED 62 /* client cert not trusted */
+#define KDC_ERR_INVALID_SIG 64 /* client signature verify failed */
+#define KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED 65 /* invalid Diffie-Hellman parameters */
+#define KDC_ERR_CANT_VERIFY_CERTIFICATE 70 /* client cert not verifiable to */
+ /* trusted root cert */
+#define KDC_ERR_INVALID_CERTIFICATE 71 /* client cert had invalid signature */
+#define KDC_ERR_REVOKED_CERTIFICATE 72 /* client cert was revoked */
+#define KDC_ERR_REVOCATION_STATUS_UNKNOWN 73 /* client cert revoked, reason unknown */
+#define KDC_ERR_CLIENT_NAME_MISMATCH 75 /* mismatch between client cert and */
+ /* principal name */
+#define KDC_ERR_INCONSISTENT_KEY_PURPOSE 77 /* bad extended key use */
+#define KDC_ERR_DIGEST_IN_CERT_NOT_ACCEPTED 78 /* bad digest algorithm in client cert */
+#define KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED 79 /* missing paChecksum in PA-PK-AS-REQ */
+#define KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED 80 /* bad digest algorithm in SignedData */
+#define KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED 81
+
#endif /* KRB5_ERRORS__ */
/*
* End "k5-errors.h"
@@ -367,7 +391,7 @@ typedef struct _krb5_alt_method {
* A null-terminated array of this structure is returned by the KDC as
* the data part of the ETYPE_INFO preauth type. It informs the
* client which encryption types are supported.
- * The same data structure is used by both etype-info and etype-info2
+ * The same data structure is used by both etype-info and etype-info2
* but s2kparams must be null when encoding etype-info.
*/
typedef struct _krb5_etype_info_entry {
@@ -375,21 +399,21 @@ typedef struct _krb5_etype_info_entry {
krb5_enctype etype;
unsigned int length;
krb5_octet *salt;
- krb5_data s2kparams;
+ krb5_data s2kparams;
} krb5_etype_info_entry;
-/*
+/*
* This is essentially -1 without sign extension which can screw up
* comparisons on 64 bit machines. If the length is this value, then
* the salt data is not present. This is to distinguish between not
- * being set and being of 0 length.
+ * being set and being of 0 length.
*/
#define KRB5_ETYPE_NO_SALT VALID_UINT_BITS
typedef krb5_etype_info_entry ** krb5_etype_info;
/*
- * a sam_challenge is returned for alternate preauth
+ * a sam_challenge is returned for alternate preauth
*/
/*
SAMFlags ::= BIT STRING {
@@ -431,11 +455,11 @@ typedef krb5_etype_info_entry ** krb5_etype_info;
typedef struct _krb5_predicted_sam_response {
krb5_magic magic;
krb5_keyblock sam_key;
- krb5_flags sam_flags; /* Makes key munging easier */
- krb5_timestamp stime; /* time on server, for replay detection */
- krb5_int32 susec;
- krb5_principal client;
- krb5_data msd; /* mechanism specific data */
+ krb5_flags sam_flags; /* Makes key munging easier */
+ krb5_timestamp stime; /* time on server, for replay detection */
+ krb5_int32 susec;
+ krb5_principal client;
+ krb5_data msd; /* mechanism specific data */
} krb5_predicted_sam_response;
typedef struct _krb5_sam_challenge {
@@ -511,6 +535,13 @@ typedef struct _krb5_enc_sam_response_enc_2 {
} krb5_enc_sam_response_enc_2;
/*
+ * Keep the pkinit definitions in a separate file so that the plugin
+ * only has to include k5-int-pkinit.h rather than k5-int.h
+ */
+
+#include "k5-int-pkinit.h"
+
+/*
* Begin "dbm.h"
*/
#ifndef _KERNEL
@@ -607,45 +638,39 @@ extern char *strdup (const char *);
*/
#ifndef KRB5_LIBOS_PROTO__
#define KRB5_LIBOS_PROTO__
+#endif
#ifndef _KERNEL
#include <stdio.h>
struct addrlist;
+struct sendto_callback_info;
#endif
/* libos.spec */
-krb5_error_code krb5_lock_file
- (krb5_context, int, int);
+krb5_error_code krb5_lock_file (krb5_context, int, int);
+krb5_error_code krb5_unlock_file (krb5_context, int);
+krb5_error_code krb5_sendto_kdc (krb5_context, const krb5_data *,
+ const krb5_data *, krb5_data *, int *, int);
+
-krb5_error_code krb5_unlock_file
- (krb5_context, int);
+krb5_error_code krb5_get_krbhst (krb5_context, const krb5_data *, char *** );
+krb5_error_code krb5_free_krbhst (krb5_context, char * const * );
+krb5_error_code krb5_create_secure_file (krb5_context, const char * pathname);
-int krb5_net_read
- (krb5_context, int , char *, int);
+int krb5_net_read (krb5_context, int , char *, int);
int krb5_net_write
(krb5_context, int , const char *, int);
-krb5_error_code krb5_sendto_kdc
- (krb5_context, const krb5_data *, const krb5_data *,
- krb5_data *, int *, int);
-
-krb5_error_code krb5_get_krbhst
- (krb5_context, const krb5_data *, char ***);
-
-krb5_error_code krb5_free_krbhst
- (krb5_context, char * const *);
krb5_error_code krb5_gen_replay_name
(krb5_context, const krb5_address *, const char *, char **);
-krb5_error_code krb5_create_secure_file
- (krb5_context, const char * pathname);
#ifndef _KERNEL
-krb5_error_code krb5_sync_disk_file
- (krb5_context, FILE *fp);
+
+krb5_error_code krb5_sync_disk_file (krb5_context, FILE *fp);
krb5_error_code
krb5_open_pkcs11_session(CK_SESSION_HANDLE *);
@@ -656,12 +681,12 @@ krb5_error_code krb5_read_message
krb5_error_code krb5_write_message
(krb5_context, krb5_pointer, krb5_data *);
-
-krb5_error_code
-krb5int_sendto (krb5_context context, const krb5_data *message,
- const struct addrlist *addrs, krb5_data *reply,
- struct sockaddr_storage *localaddr, socklen_t *localaddrlen,
- int *addr_used);
+krb5_error_code krb5int_sendto (krb5_context context, const krb5_data *message,
+ const struct addrlist *addrs, struct sendto_callback_info* callback_info,
+ krb5_data *reply, struct sockaddr *localaddr, socklen_t *localaddrlen,
+ struct sockaddr *remoteaddr, socklen_t *remoteaddrlen, int *addr_used,
+ int (*msg_handler)(krb5_context, const krb5_data *, void *),
+ void *msg_handler_data);
krb5_error_code krb5int_get_fq_local_hostname (char *, size_t);
#endif
@@ -680,66 +705,54 @@ krb5_error_code krb5int_fqdn_get_realm(krb5_context, const char *,
krb5_error_code krb5int_init_context_kdc(krb5_context *);
-krb5_error_code krb5_os_init_context
- (krb5_context, krb5_boolean);
+krb5_error_code krb5_os_init_context (krb5_context, krb5_boolean);
void krb5_os_free_context (krb5_context);
-/* This function is needed by KfM's KerberosPreferences API
- * because it needs to be able to specify "secure" */
+/* This function is needed by KfM's KerberosPreferences API
+ * because it needs to be able to specify "secure" */
#ifndef _KERNEL
-krb5_error_code os_get_default_config_files
- (profile_filespec_t **pfiles, krb5_boolean secure);
+krb5_error_code os_get_default_config_files
+ (profile_filespec_t **pfiles, krb5_boolean secure);
#endif
-krb5_error_code krb5_find_config_files(void);
-
-krb5_error_code krb5_os_hostaddr
- (krb5_context, const char *, krb5_address ***);
+krb5_error_code krb5_os_hostaddr
+ (krb5_context, const char *, krb5_address ***);
#ifndef _KERNEL
/* N.B.: You need to include fake-addrinfo.h *before* k5-int.h if you're
- * going to use this structure. */
+ going to use this structure. */
struct addrlist {
- struct addrinfo **addrs;
- int naddrs;
- int space;
+ struct {
+#ifdef FAI_DEFINED
+ struct addrinfo *ai;
+#else
+ struct undefined_addrinfo *ai;
+#endif
+ void (*freefn)(void *);
+ void *data;
+ } *addrs;
+ int naddrs;
+ int space;
};
-
-#define ADDRLIST_INIT { 0, 0, 0 }
+#define ADDRLIST_INIT { 0, 0, 0 }
extern void krb5int_free_addrlist (struct addrlist *);
extern int krb5int_grow_addrlist (struct addrlist *, int);
extern int krb5int_add_host_to_list (struct addrlist *, const char *,
- int, int, int, int);
+ int, int, int, int);
+#include <locate_plugin.h>
krb5_error_code
-krb5int_locate_server (krb5_context,
- const krb5_data *realm,
- struct addrlist *,
- /* Only meaningful for kdc, really... */
- int want_masters,
- /* look up [realms]->$realm->$name in krb5.conf */
- const char *profilename,
- /* SRV record lookup */
- const char *dnsname,
- int is_stream_service,
- /* Port numbers, in network order! For profile
- version only, DNS code gets port numbers
- itself. Use 0 for dflport2 if there's no
- secondary port (most common, except kdc
- case). */
- int dflport1, int dflport2,
- int family);
+krb5int_locate_server (krb5_context, const krb5_data *realm,
+ struct addrlist *, enum locate_service_type svc,
+ int sockettype, int family);
#endif /* _KERNEL */
-#endif /* KRB5_LIBOS_PROTO__ */
-
/* new encryption provider api */
struct krb5_enc_provider {
-
- /* keybytes is the input size to make_key;
+ /* keybytes is the input size to make_key;
keylength is the output size */
size_t block_size, keybytes, keylength;
@@ -765,7 +778,7 @@ struct krb5_enc_provider {
};
struct krb5_hash_provider {
- size_t hashsize, blocksize;
+ size_t hashsize, blocksize;
/* this takes multiple inputs to avoid lots of copying. */
krb5_error_code (*hash) (krb5_context context,
@@ -794,9 +807,8 @@ struct krb5_keyhash_provider {
};
-typedef void (*krb5_encrypt_length_func) (
- krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
+typedef void (*krb5_encrypt_length_func) (const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
size_t inputlen, size_t *length);
typedef krb5_error_code (*krb5_crypt_func) (
@@ -815,6 +827,12 @@ typedef krb5_error_code (*krb5_str2key_func) (
krb5_keyblock *key);
#endif /* _KERNEL */
+typedef krb5_error_code (*krb5_prf_func)(
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key,
+ const krb5_data *in, krb5_data *out);
+
struct krb5_keytypes {
krb5_enctype etype;
char *in_string;
@@ -836,7 +854,6 @@ struct krb5_keytypes {
#endif /* _KERNEL */
};
-
struct krb5_cksumtypes {
krb5_cksumtype ctype;
unsigned int flags;
@@ -855,10 +872,10 @@ struct krb5_cksumtypes {
const struct krb5_keyhash_provider *keyhash;
const struct krb5_hash_provider *hash;
/* This just gets uglier and uglier. In the key derivation case,
- we produce an hmac. To make the hmac code work, we can't hack
- the output size indicated by the hash provider, but we may want
- a truncated hmac. If we want truncation, this is the number of
- bytes we truncate to; it should be 0 otherwise. */
+ we produce an hmac. To make the hmac code work, we can't hack
+ the output size indicated by the hash provider, but we may want
+ a truncated hmac. If we want truncation, this is the number of
+ bytes we truncate to; it should be 0 otherwise. */
unsigned int trunc_size;
#ifdef _KERNEL
char *mt_c_name;
@@ -869,8 +886,42 @@ struct krb5_cksumtypes {
#define KRB5_CKSUMFLAG_DERIVE 0x0001
#define KRB5_CKSUMFLAG_NOT_COLL_PROOF 0x0002
-krb5_error_code krb5int_des_init_state(
- krb5_context,
+/*
+ * in here to deal with stuff from lib/crypto
+ */
+
+void krb5_nfold
+(unsigned int inbits, const unsigned char *in,
+ unsigned int outbits, unsigned char *out);
+
+krb5_error_code krb5int_pbkdf2_hmac_sha1 (krb5_context,
+ const krb5_data *,
+ unsigned long,
+ krb5_enctype,
+ const krb5_data *,
+ const krb5_data *);
+
+/* Make this a function eventually? */
+#ifdef _WIN32
+# define krb5int_zap_data(ptr, len) SecureZeroMemory(ptr, len)
+#elif defined(__palmos__) && !defined(__GNUC__)
+/* CodeWarrior 8.3 complains about passing a pointer to volatile in to
+ memset. On the other hand, we probably want it for gcc. */
+# define krb5int_zap_data(ptr, len) memset(ptr, 0, len)
+#else
+# define krb5int_zap_data(ptr, len) memset((void *)ptr, 0, len)
+# if defined(__GNUC__) && defined(__GLIBC__)
+/* GNU libc generates multiple bogus initialization warnings if we
+ pass memset a volatile pointer. The compiler should do well enough
+ with memset even without GNU libc's attempt at optimization. */
+# undef memset
+# endif
+#endif /* WIN32 */
+#define zap(p,l) krb5int_zap_data(p,l)
+
+
+krb5_error_code krb5int_des_init_state
+( krb5_context,
const krb5_keyblock *,
krb5_keyusage, krb5_data *);
@@ -879,11 +930,13 @@ krb5_error_code krb5int_c_mandatory_cksumtype(
krb5_enctype,
krb5_cksumtype *);
-/*
+/*
* normally to free a cipher_state you can just memset the length to zero and
* free it.
*/
-krb5_error_code krb5int_default_free_state(krb5_context, krb5_data *);
+krb5_error_code krb5int_default_free_state
+(krb5_context, krb5_data *);
+
/*
* Combine two keys (normally used by the hardware preauth mechanism)
@@ -891,12 +944,7 @@ krb5_error_code krb5int_default_free_state(krb5_context, krb5_data *);
krb5_error_code krb5int_c_combine_keys
(krb5_context context, krb5_keyblock *key1, krb5_keyblock *key2,
krb5_keyblock *outkey);
-/*
- * in here to deal with stuff from lib/crypto
- */
-void krb5_nfold (int inbits, krb5_const unsigned char *in,
- int outbits, unsigned char *out);
#ifdef _KERNEL
@@ -918,27 +966,6 @@ krb5_error_code krb5_hmac
#endif /* _KERNEL */
-krb5_error_code krb5int_pbkdf2_hmac_sha1 (krb5_context,
- const krb5_data *,
- unsigned long,
- krb5_enctype,
- const krb5_data *,
- const krb5_data *);
-
-/* Make this a function eventually? */
-#ifdef WIN32
-# define krb5int_zap_data(ptr, len) SecureZeroMemory(ptr, len)
-#else
-# define krb5int_zap_data(ptr, len) memset((void *)ptr, 0, len)
-# if defined(__GNUC__) && defined(__GLIBC__)
-/* GNU libc generates multiple bogus initialization warnings if we
- pass memset a volatile pointer. The compiler should do well enough
- with memset even without GNU libc's attempt at optimization. */
-# undef memset
-# endif
-#endif /* WIN32 */
-#define zap(p,l) krb5int_zap_data(p,l)
-
/*
* These declarations are here, so both krb5 and k5crypto
@@ -952,11 +979,12 @@ extern const struct krb5_hash_provider krb5int_hash_md5;
/* #ifdef KRB5_OLD_CRYPTO XXX SUNW14resync */
krb5_error_code krb5_crypto_us_timeofday
- (krb5_int32 *, krb5_int32 *);
+ (krb5_int32 *,
+ krb5_int32 *);
#ifndef _KERNEL
/* Solaris kerberos: for convenience */
-time_t gmt_mktime (struct tm *);
+time_t krb5int_gmt_mktime (struct tm *);
#endif /* ! _KERNEL */
/* #endif KRB5_OLD_CRYPTO */
@@ -964,9 +992,9 @@ time_t gmt_mktime (struct tm *);
/* this helper fct is in libkrb5, but it makes sense declared here. */
krb5_error_code krb5_encrypt_helper
- (krb5_context context, krb5_const krb5_keyblock *key,
- krb5_keyusage usage, krb5_const krb5_data *plain,
- krb5_enc_data *cipher);
+(krb5_context context, const krb5_keyblock *key,
+ krb5_keyusage keyusage, const krb5_data *plain,
+ krb5_enc_data *cipher);
/*
* End "los-proto.h"
@@ -979,11 +1007,11 @@ krb5_error_code krb5_encrypt_helper
#define KRB5_LIBOS__
typedef struct _krb5_os_context {
- krb5_magic magic;
- krb5_int32 time_offset;
- krb5_int32 usec_offset;
- krb5_int32 os_flags;
- char * default_ccname;
+ krb5_magic magic;
+ krb5_int32 time_offset;
+ krb5_int32 usec_offset;
+ krb5_int32 os_flags;
+ char * default_ccname;
} *krb5_os_context;
/*
@@ -1018,7 +1046,6 @@ typedef struct _krb5_os_context {
* Define our view of the size of a DES key.
*/
#define KRB5_MIT_DES_KEYSIZE 8
-
/*
* Define a couple of SHA1 constants
*/
@@ -1050,14 +1077,64 @@ error(MIT_DES_KEYSIZE does not equal KRB5_MIT_DES_KEYSIZE)
* (Originally written by Glen Machin at Sandia Labs.)
*/
/*
- * Sandia National Laboratories also makes no representations about the
- * suitability of the modifications, or additions to this software for
+ * Sandia National Laboratories also makes no representations about the
+ * suitability of the modifications, or additions to this software for
* any purpose. It is provided "as is" without express or implied warranty.
- *
+ *
*/
#ifndef KRB5_PREAUTH__
#define KRB5_PREAUTH__
+#include <preauth_plugin.h>
+
+#define CLIENT_ROCK_MAGIC 0x4352434b
+/* This structure is passed into the client preauth functions and passed
+ * back to the "get_data_proc" function so that it can locate the
+ * requested information. It is opaque to the plugin code and can be
+ * expanded in the future as new types of requests are defined which
+ * may require other things to be passed through. */
+typedef struct _krb5_preauth_client_rock {
+ krb5_magic magic;
+ krb5_kdc_rep *as_reply;
+} krb5_preauth_client_rock;
+
+/* This structure lets us keep track of all of the modules which are loaded,
+ * turning the list of modules and their lists of implemented preauth types
+ * into a single list which we can walk easily. */
+typedef struct _krb5_preauth_context {
+ int n_modules;
+ struct _krb5_preauth_context_module {
+ /* Which of the possibly more than one preauth types which the
+ * module supports we're using at this point in the list. */
+ krb5_preauthtype pa_type;
+ /* Encryption types which the client claims to support -- we
+ * copy them directly into the krb5_kdc_req structure during
+ * krb5_preauth_prepare_request(). */
+ krb5_enctype *enctypes;
+ /* The plugin's per-plugin context and a function to clear it. */
+ void *plugin_context;
+ preauth_client_plugin_fini_proc client_fini;
+ /* The module's table, and some of its members, copied here for
+ * convenience when we populated the list. */
+ struct krb5plugin_preauth_client_ftable_v1 *ftable;
+ const char *name;
+ int flags, use_count;
+ preauth_client_process_proc client_process;
+ preauth_client_tryagain_proc client_tryagain;
+ preauth_client_supply_gic_opts_proc client_supply_gic_opts;
+ preauth_client_request_init_proc client_req_init;
+ preauth_client_request_fini_proc client_req_fini;
+ /* The per-request context which the client_req_init() function
+ * might allocate, which we'll need to clean up later by
+ * calling the client_req_fini() function. */
+ void *request_context;
+ /* A pointer to the request_context pointer. All modules within
+ * a plugin will point at the request_context of the first
+ * module within the plugin. */
+ void **request_context_pp;
+ } *modules;
+} krb5_preauth_context;
+
typedef struct _krb5_pa_enc_ts {
krb5_timestamp patimestamp;
krb5_int32 pausec;
@@ -1065,38 +1142,38 @@ typedef struct _krb5_pa_enc_ts {
typedef krb5_error_code (*krb5_preauth_obtain_proc)
(krb5_context,
- krb5_pa_data *,
- krb5_etype_info,
- krb5_keyblock *,
- krb5_error_code ( * )(krb5_context,
- krb5_const krb5_enctype,
- krb5_data *,
- krb5_const_pointer,
- krb5_keyblock **),
- krb5_const_pointer,
- krb5_creds *,
- krb5_kdc_req *,
- krb5_pa_data **);
+ krb5_pa_data *,
+ krb5_etype_info,
+ krb5_keyblock *,
+ krb5_error_code ( * )(krb5_context,
+ const krb5_enctype,
+ krb5_data *,
+ krb5_const_pointer,
+ krb5_keyblock **),
+ krb5_const_pointer,
+ krb5_creds *,
+ krb5_kdc_req *,
+ krb5_pa_data **);
typedef krb5_error_code (*krb5_preauth_process_proc)
(krb5_context,
- krb5_pa_data *,
- krb5_kdc_req *,
- krb5_kdc_rep *,
- krb5_error_code ( * )(krb5_context,
- krb5_const krb5_enctype,
- krb5_data *,
- krb5_const_pointer,
- krb5_keyblock **),
- krb5_const_pointer,
- krb5_error_code ( * )(krb5_context,
- krb5_const krb5_keyblock *,
- krb5_const_pointer,
- krb5_kdc_rep * ),
- krb5_keyblock **,
- krb5_creds *,
- krb5_int32 *,
- krb5_int32 *);
+ krb5_pa_data *,
+ krb5_kdc_req *,
+ krb5_kdc_rep *,
+ krb5_error_code ( * )(krb5_context,
+ const krb5_enctype,
+ krb5_data *,
+ krb5_const_pointer,
+ krb5_keyblock **),
+ krb5_const_pointer,
+ krb5_error_code ( * )(krb5_context,
+ const krb5_keyblock *,
+ krb5_const_pointer,
+ krb5_kdc_rep * ),
+ krb5_keyblock **,
+ krb5_creds *,
+ krb5_int32 *,
+ krb5_int32 *);
typedef struct _krb5_preauth_ops {
krb5_magic magic;
@@ -1106,6 +1183,37 @@ typedef struct _krb5_preauth_ops {
krb5_preauth_process_proc process;
} krb5_preauth_ops;
+
+krb5_error_code krb5_obtain_padata
+ (krb5_context,
+ krb5_pa_data **,
+ krb5_error_code ( * )(krb5_context,
+ const krb5_enctype,
+ krb5_data *,
+ krb5_const_pointer,
+ krb5_keyblock **),
+ krb5_const_pointer,
+ krb5_creds *,
+ krb5_kdc_req *);
+
+krb5_error_code krb5_process_padata
+ (krb5_context,
+ krb5_kdc_req *,
+ krb5_kdc_rep *,
+ krb5_error_code ( * )(krb5_context,
+ const krb5_enctype,
+ krb5_data *,
+ krb5_const_pointer,
+ krb5_keyblock **),
+ krb5_const_pointer,
+ krb5_error_code ( * )(krb5_context,
+ const krb5_keyblock *,
+ krb5_const_pointer,
+ krb5_kdc_rep * ),
+ krb5_keyblock **,
+ krb5_creds *,
+ krb5_int32 *);
+
void krb5_free_etype_info (krb5_context, krb5_etype_info);
/*
@@ -1119,50 +1227,148 @@ void krb5_free_etype_info (krb5_context, krb5_etype_info);
* End "preauth.h"
*/
+/*
+ * Extending the krb5_get_init_creds_opt structure. The original
+ * krb5_get_init_creds_opt structure is defined publicly. The
+ * new extended version is private. The original interface
+ * assumed a pre-allocated structure which was passed to
+ * krb5_get_init_creds_init(). The new interface assumes that
+ * the caller will call krb5_get_init_creds_alloc() and
+ * krb5_get_init_creds_free().
+ *
+ * Callers MUST NOT call krb5_get_init_creds_init() after allocating an
+ * opts structure using krb5_get_init_creds_alloc(). To do so will
+ * introduce memory leaks. Unfortunately, there is no way to enforce
+ * this behavior.
+ *
+ * Two private flags are added for backward compatibility.
+ * KRB5_GET_INIT_CREDS_OPT_EXTENDED says that the structure was allocated
+ * with the new krb5_get_init_creds_opt_alloc() function.
+ * KRB5_GET_INIT_CREDS_OPT_SHADOWED is set to indicate that the extended
+ * structure is a shadow copy of an original krb5_get_init_creds_opt
+ * structure.
+ * If KRB5_GET_INIT_CREDS_OPT_SHADOWED is set after a call to
+ * krb5int_gic_opt_to_opte(), the resulting extended structure should be
+ * freed (using krb5_get_init_creds_free). Otherwise, the original
+ * structure was already extended and there is no need to free it.
+ */
+
+#define KRB5_GET_INIT_CREDS_OPT_EXTENDED 0x80000000
+#define KRB5_GET_INIT_CREDS_OPT_SHADOWED 0x40000000
+
+#define krb5_gic_opt_is_extended(s) \
+ ((s) && ((s)->flags & KRB5_GET_INIT_CREDS_OPT_EXTENDED) ? 1 : 0)
+#define krb5_gic_opt_is_shadowed(s) \
+ ((s) && ((s)->flags & KRB5_GET_INIT_CREDS_OPT_SHADOWED) ? 1 : 0)
+
+
+typedef struct _krb5_gic_opt_private {
+ int num_preauth_data;
+ krb5_gic_opt_pa_data *preauth_data;
+} krb5_gic_opt_private;
+
+typedef struct _krb5_gic_opt_ext {
+ krb5_flags flags;
+ krb5_deltat tkt_life;
+ krb5_deltat renew_life;
+ int forwardable;
+ int proxiable;
+ krb5_enctype *etype_list;
+ int etype_list_length;
+ krb5_address **address_list;
+ krb5_preauthtype *preauth_list;
+ int preauth_list_length;
+ krb5_data *salt;
+ /*
+ * Do not change anything above this point in this structure.
+ * It is identical to the public krb5_get_init_creds_opt structure.
+ * New members must be added below.
+ */
+ krb5_gic_opt_private *opt_private;
+} krb5_gic_opt_ext;
+
+krb5_error_code
+krb5int_gic_opt_to_opte(krb5_context context,
+ krb5_get_init_creds_opt *opt,
+ krb5_gic_opt_ext **opte,
+ unsigned int force,
+ const char *where);
+
krb5_error_code
krb5int_copy_data_contents (krb5_context, const krb5_data *, krb5_data *);
#ifndef _KERNEL /* needed for lib/krb5/krb/ */
typedef krb5_error_code (*krb5_gic_get_as_key_fct)
(krb5_context,
- krb5_principal,
- krb5_enctype,
- krb5_prompter_fct,
- void *prompter_data,
- krb5_data *salt,
+ krb5_principal,
+ krb5_enctype,
+ krb5_prompter_fct,
+ void *prompter_data,
+ krb5_data *salt,
krb5_data *s2kparams,
- krb5_keyblock *as_key,
- void *gak_data);
+ krb5_keyblock *as_key,
+ void *gak_data);
krb5_error_code KRB5_CALLCONV
krb5_get_init_creds
(krb5_context context,
- krb5_creds *creds,
- krb5_principal client,
- krb5_prompter_fct prompter,
- void *prompter_data,
- krb5_deltat start_time,
- char *in_tkt_service,
- krb5_get_init_creds_opt *options,
- krb5_gic_get_as_key_fct gak,
- void *gak_data,
- int *master,
- krb5_kdc_rep **as_reply);
-
-void krb5int_populate_gic_opt (
- krb5_context, krb5_get_init_creds_opt *,
- krb5_flags options, krb5_address * const *addrs, krb5_enctype *ktypes,
- krb5_preauthtype *pre_auth_types, krb5_creds *creds);
-
-krb5_error_code krb5_do_preauth
- (krb5_context, krb5_kdc_req *,
- krb5_pa_data **, krb5_pa_data ***,
- krb5_data *, krb5_data *, krb5_enctype *,
- krb5_keyblock *,
- krb5_prompter_fct, void *,
- krb5_gic_get_as_key_fct, void *);
-#endif /* _KERNEL */
+ krb5_creds *creds,
+ krb5_principal client,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ krb5_deltat start_time,
+ char *in_tkt_service,
+ krb5_gic_opt_ext *gic_options,
+ krb5_gic_get_as_key_fct gak,
+ void *gak_data,
+ int *master,
+ krb5_kdc_rep **as_reply);
+
+krb5_error_code krb5int_populate_gic_opt (
+ krb5_context, krb5_gic_opt_ext **,
+ krb5_flags options, krb5_address * const *addrs, krb5_enctype *ktypes,
+ krb5_preauthtype *pre_auth_types, krb5_creds *creds);
+
+
+krb5_error_code KRB5_CALLCONV krb5_do_preauth
+ (krb5_context context,
+ krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data **in_padata, krb5_pa_data ***out_padata,
+ krb5_data *salt, krb5_data *s2kparams,
+ krb5_enctype *etype, krb5_keyblock *as_key,
+ krb5_prompter_fct prompter, void *prompter_data,
+ krb5_gic_get_as_key_fct gak_fct, void *gak_data,
+ krb5_preauth_client_rock *get_data_rock,
+ krb5_gic_opt_ext *opte);
+krb5_error_code KRB5_CALLCONV krb5_do_preauth_tryagain
+ (krb5_context context,
+ krb5_kdc_req *request,
+ krb5_data *encoded_request_body,
+ krb5_data *encoded_previous_request,
+ krb5_pa_data **in_padata, krb5_pa_data ***out_padata,
+ krb5_error *err_reply,
+ krb5_data *salt, krb5_data *s2kparams,
+ krb5_enctype *etype, krb5_keyblock *as_key,
+ krb5_prompter_fct prompter, void *prompter_data,
+ krb5_gic_get_as_key_fct gak_fct, void *gak_data,
+ krb5_preauth_client_rock *get_data_rock,
+ krb5_gic_opt_ext *opte);
+void KRB5_CALLCONV krb5_init_preauth_context
+ (krb5_context);
+void KRB5_CALLCONV krb5_free_preauth_context
+ (krb5_context);
+void KRB5_CALLCONV krb5_clear_preauth_context_use_counts
+ (krb5_context);
+void KRB5_CALLCONV krb5_preauth_prepare_request
+ (krb5_context, krb5_gic_opt_ext *, krb5_kdc_req *);
+void KRB5_CALLCONV krb5_preauth_request_context_init
+ (krb5_context);
+void KRB5_CALLCONV krb5_preauth_request_context_fini
+ (krb5_context);
+#endif /* _KERNEL */
void KRB5_CALLCONV krb5_free_sam_challenge
(krb5_context, krb5_sam_challenge * );
void KRB5_CALLCONV krb5_free_sam_challenge_2
@@ -1195,7 +1401,7 @@ void KRB5_CALLCONV krb5_free_enc_sam_response_enc_contents
(krb5_context, krb5_enc_sam_response_enc * );
void KRB5_CALLCONV krb5_free_enc_sam_response_enc_2_contents
(krb5_context, krb5_enc_sam_response_enc_2 * );
-
+
void KRB5_CALLCONV krb5_free_pa_enc_ts
(krb5_context, krb5_pa_enc_ts *);
@@ -1236,19 +1442,19 @@ typedef struct _arcfour_ctx {
struct _krb5_context {
krb5_magic magic;
krb5_enctype *in_tkt_ktypes;
- int in_tkt_ktype_count;
+ unsigned int in_tkt_ktype_count;
krb5_enctype *tgs_ktypes;
- int tgs_ktype_count;
- /* This used to be a void*, but since we always allocate them
- together (though in different source files), and the types
- are declared in the same header, might as well just combine
- them.
-
- The array[1] is so the existing code treating the field as
- a pointer will still work. For cleanliness, it should
- eventually get changed to a single element instead of an
- array. */
- struct _krb5_os_context os_context[1];
+ unsigned int tgs_ktype_count;
+ /* This used to be a void*, but since we always allocate them
+ together (though in different source files), and the types
+ are declared in the same header, might as well just combine
+ them.
+
+ The array[1] is so the existing code treating the field as
+ a pointer will still work. For cleanliness, it should
+ eventually get changed to a single element instead of an
+ array. */
+ struct _krb5_os_context os_context[1];
char *default_realm;
int ser_ctx_count;
krb5_boolean profile_secure;
@@ -1283,10 +1489,16 @@ struct _krb5_context {
/* Use the _configured version? */
krb5_boolean use_conf_ktypes;
+
#ifdef KRB5_DNS_LOOKUP
- krb5_boolean profile_in_memory;
+ krb5_boolean profile_in_memory;
#endif /* KRB5_DNS_LOOKUP */
+ /* locate_kdc module stuff */
+ struct plugin_dir_handle libkrb5_plugins;
+ struct krb5plugin_service_locate_ftable *vtbl;
+ void (**locate_fptrs)(void);
+
pid_t pid; /* fork safety: PID of process that did last PKCS11 init */
/* Solaris Kerberos: handles for PKCS#11 crypto */
@@ -1300,6 +1512,10 @@ struct _krb5_context {
/* arcfour_ctx: used only for rcmd stuff so no fork safety issues apply */
arcfour_ctx_rec arcfour_ctx;
+ /* preauth module stuff */
+ struct plugin_dir_handle preauth_plugins;
+ krb5_preauth_context *preauth_context;
+
/* error detail info */
struct errinfo err;
#else /* ! KERNEL */
@@ -1423,37 +1639,37 @@ derive_3des_keys(krb5_context, struct krb5_enc_provider *,
typedef struct _krb5_safe {
krb5_magic magic;
- krb5_data user_data; /* user data */
- krb5_timestamp timestamp; /* client time, optional */
- krb5_int32 usec; /* microsecond portion of time,
- optional */
- krb5_ui_4 seq_number; /* sequence #, optional */
- krb5_address *s_address; /* sender address */
- krb5_address *r_address; /* recipient address, optional */
- krb5_checksum *checksum; /* data integrity checksum */
+ krb5_data user_data; /* user data */
+ krb5_timestamp timestamp; /* client time, optional */
+ krb5_int32 usec; /* microsecond portion of time,
+ optional */
+ krb5_ui_4 seq_number; /* sequence #, optional */
+ krb5_address *s_address; /* sender address */
+ krb5_address *r_address; /* recipient address, optional */
+ krb5_checksum *checksum; /* data integrity checksum */
} krb5_safe;
typedef struct _krb5_priv {
krb5_magic magic;
- krb5_enc_data enc_part; /* encrypted part */
+ krb5_enc_data enc_part; /* encrypted part */
} krb5_priv;
typedef struct _krb5_priv_enc_part {
krb5_magic magic;
- krb5_data user_data; /* user data */
- krb5_timestamp timestamp; /* client time, optional */
- krb5_int32 usec; /* microsecond portion of time, opt. */
- krb5_ui_4 seq_number; /* sequence #, optional */
- krb5_address *s_address; /* sender address */
- krb5_address *r_address; /* recipient address, optional */
+ krb5_data user_data; /* user data */
+ krb5_timestamp timestamp; /* client time, optional */
+ krb5_int32 usec; /* microsecond portion of time, opt. */
+ krb5_ui_4 seq_number; /* sequence #, optional */
+ krb5_address *s_address; /* sender address */
+ krb5_address *r_address; /* recipient address, optional */
} krb5_priv_enc_part;
void KRB5_CALLCONV krb5_free_safe
- (krb5_context, krb5_safe * );
+ (krb5_context, krb5_safe * );
void KRB5_CALLCONV krb5_free_priv
- (krb5_context, krb5_priv * );
+ (krb5_context, krb5_priv * );
void KRB5_CALLCONV krb5_free_priv_enc_part
- (krb5_context, krb5_priv_enc_part * );
+ (krb5_context, krb5_priv_enc_part * );
/*
* Begin "asn1.h"
@@ -1463,7 +1679,7 @@ void KRB5_CALLCONV krb5_free_priv_enc_part
/* ASN.1 encoding knowledge; KEEP IN SYNC WITH ASN.1 defs! */
/* here we use some knowledge of ASN.1 encodings */
-/*
+/*
Ticket is APPLICATION 1.
Authenticator is APPLICATION 2.
AS_REQ is APPLICATION 10.
@@ -1564,11 +1780,11 @@ krb5_error_code encode_krb5_enc_tkt_part
krb5_error_code encode_krb5_enc_kdc_rep_part
(const krb5_enc_kdc_rep_part *rep, krb5_data **code);
-/* yes, the translation is identical to that used for KDC__REP */
+/* yes, the translation is identical to that used for KDC__REP */
krb5_error_code encode_krb5_as_rep
(const krb5_kdc_rep *rep, krb5_data **code);
-/* yes, the translation is identical to that used for KDC__REP */
+/* yes, the translation is identical to that used for KDC__REP */
krb5_error_code encode_krb5_tgs_rep
(const krb5_kdc_rep *rep, krb5_data **code);
@@ -1614,6 +1830,9 @@ krb5_error_code encode_krb5_error
krb5_error_code encode_krb5_authdata
(const krb5_authdata **rep, krb5_data **code);
+krb5_error_code encode_krb5_authdata_elt
+ (const krb5_authdata *rep, krb5_data **code);
+
krb5_error_code encode_krb5_pwd_sequence
(const passwd_phrase_element *rep, krb5_data **code);
@@ -1628,7 +1847,6 @@ krb5_error_code encode_krb5_alt_method
krb5_error_code encode_krb5_etype_info
(const krb5_etype_info_entry **, krb5_data **code);
-
krb5_error_code encode_krb5_etype_info2
(const krb5_etype_info_entry **, krb5_data **code);
@@ -1650,9 +1868,6 @@ krb5_error_code encode_krb5_enc_sam_response_enc
krb5_error_code encode_krb5_sam_response
(const krb5_sam_response * , krb5_data **);
-krb5_error_code encode_krb5_predicted_sam_response
- (const krb5_predicted_sam_response * , krb5_data **);
-
krb5_error_code encode_krb5_sam_challenge_2
(const krb5_sam_challenge_2 * , krb5_data **);
@@ -1665,21 +1880,56 @@ krb5_error_code encode_krb5_enc_sam_response_enc_2
krb5_error_code encode_krb5_sam_response_2
(const krb5_sam_response_2 * , krb5_data **);
+krb5_error_code encode_krb5_predicted_sam_response
+ (const krb5_predicted_sam_response * , krb5_data **);
+
krb5_error_code encode_krb5_setpw_req
- (const krb5_principal target, char *password, krb5_data **code);
+(const krb5_principal target, char *password, krb5_data **code);
/*************************************************************************
* End of prototypes for krb5_encode.c
*************************************************************************/
+krb5_error_code decode_krb5_sam_challenge
+ (const krb5_data *, krb5_sam_challenge **);
+
+krb5_error_code decode_krb5_enc_sam_key
+ (const krb5_data *, krb5_sam_key **);
+
+krb5_error_code decode_krb5_enc_sam_response_enc
+ (const krb5_data *, krb5_enc_sam_response_enc **);
+
+krb5_error_code decode_krb5_sam_response
+ (const krb5_data *, krb5_sam_response **);
+
+krb5_error_code decode_krb5_predicted_sam_response
+ (const krb5_data *, krb5_predicted_sam_response **);
+
+krb5_error_code decode_krb5_sam_challenge_2
+ (const krb5_data *, krb5_sam_challenge_2 **);
+
+krb5_error_code decode_krb5_sam_challenge_2_body
+ (const krb5_data *, krb5_sam_challenge_2_body **);
+
+krb5_error_code decode_krb5_enc_sam_response_enc_2
+ (const krb5_data *, krb5_enc_sam_response_enc_2 **);
+
+krb5_error_code decode_krb5_sam_response_2
+ (const krb5_data *, krb5_sam_response_2 **);
+
+
/*************************************************************************
* Prototypes for krb5_decode.c
*************************************************************************/
+krb5_error_code krb5_validate_times
+ (krb5_context,
+ krb5_ticket_times *);
+
/*
krb5_error_code decode_krb5_structure(const krb5_data *code,
krb5_structure **rep);
-
+
requires Expects **rep to not have been allocated;
a new *rep is allocated regardless of the old value.
effects Decodes *code into **rep.
@@ -1774,33 +2024,9 @@ krb5_error_code decode_krb5_enc_data
krb5_error_code decode_krb5_pa_enc_ts
(const krb5_data *output, krb5_pa_enc_ts **rep);
-krb5_error_code decode_krb5_sam_challenge
- (const krb5_data *, krb5_sam_challenge **);
-
krb5_error_code decode_krb5_sam_key
(const krb5_data *, krb5_sam_key **);
-krb5_error_code decode_krb5_enc_sam_response_enc
- (const krb5_data *, krb5_enc_sam_response_enc **);
-
-krb5_error_code decode_krb5_sam_response
- (const krb5_data *, krb5_sam_response **);
-
-krb5_error_code decode_krb5_predicted_sam_response
- (const krb5_data *, krb5_predicted_sam_response **);
-
-krb5_error_code decode_krb5_sam_challenge_2
- (const krb5_data *, krb5_sam_challenge_2 **);
-
-krb5_error_code decode_krb5_sam_challenge_2_body
- (const krb5_data *, krb5_sam_challenge_2_body **);
-
-krb5_error_code decode_krb5_enc_sam_response_enc_2
- (const krb5_data *, krb5_enc_sam_response_enc_2 **);
-
-krb5_error_code decode_krb5_sam_response_2
- (const krb5_data *, krb5_sam_response_2 **);
-
struct _krb5_key_data; /* kdb.h */
krb5_error_code
krb5int_ldap_encode_sequence_of_keys (struct _krb5_key_data *key_data,
@@ -1829,43 +2055,39 @@ krb5int_ldap_decode_sequence_of_keys (krb5_data *in,
*/
krb5_error_code krb5_encrypt_tkt_part
(krb5_context,
- krb5_const krb5_keyblock *,
- krb5_ticket *);
+ const krb5_keyblock *,
+ krb5_ticket * );
krb5_error_code krb5_encode_kdc_rep
(krb5_context,
- krb5_const krb5_msgtype,
- krb5_const krb5_enc_kdc_rep_part *,
- int using_subkey,
- krb5_const krb5_keyblock *,
- krb5_kdc_rep *,
- krb5_data ** );
-
-krb5_error_code krb5_validate_times
- (krb5_context, krb5_ticket_times *);
+ const krb5_msgtype,
+ const krb5_enc_kdc_rep_part *,
+ int using_subkey,
+ const krb5_keyblock *,
+ krb5_kdc_rep *,
+ krb5_data ** );
krb5_boolean krb5int_auth_con_chkseqnum
(krb5_context ctx, krb5_auth_context ac, krb5_ui_4 in_seq);
-
/*
* [De]Serialization Handle and operations.
*/
struct __krb5_serializer {
krb5_magic odtype;
krb5_error_code (*sizer) (krb5_context,
- krb5_pointer,
- size_t *);
+ krb5_pointer,
+ size_t *);
krb5_error_code (*externalizer) (krb5_context,
- krb5_pointer,
- krb5_octet **,
- size_t *);
+ krb5_pointer,
+ krb5_octet **,
+ size_t *);
krb5_error_code (*internalizer) (krb5_context,
- krb5_pointer *,
- krb5_octet **,
- size_t *);
+ krb5_pointer *,
+ krb5_octet **,
+ size_t *);
};
-typedef struct __krb5_serializer * krb5_ser_handle;
+typedef const struct __krb5_serializer * krb5_ser_handle;
typedef struct __krb5_serializer krb5_ser_entry;
krb5_ser_handle krb5_find_serializer
@@ -1885,10 +2107,10 @@ krb5_error_code KRB5_CALLCONV krb5_size_opaque
/* Serialize the structure into a buffer */
krb5_error_code KRB5_CALLCONV krb5_externalize_opaque
(krb5_context,
- krb5_magic,
- krb5_pointer,
- krb5_octet * *,
- size_t *);
+ krb5_magic,
+ krb5_pointer,
+ krb5_octet **,
+ size_t *);
/* Deserialize the structure from a buffer */
krb5_error_code KRB5_CALLCONV krb5_internalize_opaque
@@ -1939,7 +2161,7 @@ krb5_error_code KRB5_CALLCONV krb5_ser_unpack_int32
size_t *);
/* [De]serialize 8-byte integer */
krb5_error_code KRB5_CALLCONV krb5_ser_pack_int64
- (krb5_int64, krb5_octet * *, size_t *);
+ (krb5_int64, krb5_octet **, size_t *);
krb5_error_code KRB5_CALLCONV krb5_ser_unpack_int64
(krb5_int64 *, krb5_octet **, size_t *);
/* [De]serialize byte string */
@@ -1954,58 +2176,63 @@ krb5_error_code KRB5_CALLCONV krb5_ser_unpack_bytes
krb5_octet **,
size_t *);
-
krb5_error_code KRB5_CALLCONV krb5int_cc_default
(krb5_context, krb5_ccache *);
krb5_error_code KRB5_CALLCONV krb5_cc_retrieve_cred_default
- (krb5_context, krb5_ccache, krb5_flags, krb5_creds *, krb5_creds *);
+ (krb5_context, krb5_ccache, krb5_flags,
+ krb5_creds *, krb5_creds *);
+
+krb5_boolean KRB5_CALLCONV
+krb5_creds_compare (krb5_context in_context,
+ krb5_creds *in_creds,
+ krb5_creds *in_compare_creds);
void krb5int_set_prompt_types
(krb5_context, krb5_prompt_type *);
krb5_error_code
krb5int_generate_and_save_subkey (krb5_context, krb5_auth_context,
- krb5_keyblock * /* Old keyblock, not new! */);
+ krb5_keyblock * /* Old keyblock, not new! */);
/* set and change password helpers */
krb5_error_code krb5int_mk_chpw_req
- (krb5_context context, krb5_auth_context auth_context,
- krb5_data *ap_req, char *passwd, krb5_data *packet);
+ (krb5_context context, krb5_auth_context auth_context,
+ krb5_data *ap_req, char *passwd, krb5_data *packet);
krb5_error_code krb5int_rd_chpw_rep
- (krb5_context context, krb5_auth_context auth_context,
- krb5_data *packet, int *result_code,
- krb5_data *result_data);
+ (krb5_context context, krb5_auth_context auth_context,
+ krb5_data *packet, int *result_code,
+ krb5_data *result_data);
krb5_error_code KRB5_CALLCONV krb5_chpw_result_code_string
- (krb5_context context, int result_code,
- char **result_codestr);
+ (krb5_context context, int result_code,
+ char **result_codestr);
krb5_error_code krb5int_mk_setpw_req
- (krb5_context context, krb5_auth_context auth_context,
- krb5_data *ap_req, krb5_principal targetprinc, char *passwd, krb5_data *packet);
+ (krb5_context context, krb5_auth_context auth_context,
+ krb5_data *ap_req, krb5_principal targetprinc, char *passwd, krb5_data *packet);
krb5_error_code krb5int_rd_setpw_rep
- (krb5_context context, krb5_auth_context auth_context,
- krb5_data *packet, int *result_code,
- krb5_data *result_data);
-
+ (krb5_context context, krb5_auth_context auth_context,
+ krb5_data *packet, int *result_code,
+ krb5_data *result_data);
krb5_error_code krb5int_setpw_result_code_string
- (krb5_context context, int result_code,
- const char **result_codestr);
+ (krb5_context context, int result_code,
+ const char **result_codestr);
struct srv_dns_entry {
- struct srv_dns_entry *next;
- int priority;
- int weight;
- unsigned short port;
- char *host;
+ struct srv_dns_entry *next;
+ int priority;
+ int weight;
+ unsigned short port;
+ char *host;
};
-
+#ifdef KRB5_DNS_LOOKUP
krb5_error_code
krb5int_make_srv_query_realm(const krb5_data *realm,
- const char *service,
- const char *protocol,
- struct srv_dns_entry **answers);
+ const char *service,
+ const char *protocol,
+ struct srv_dns_entry **answers);
void krb5int_free_srv_dns_data(struct srv_dns_entry *);
+#endif
/*
* Convenience function for structure magic number
@@ -2030,41 +2257,38 @@ void krb5_unsetenv (const char *);
/* To keep happy libraries which are (for now) accessing internal stuff */
/* Make sure to increment by one when changing the struct */
-#define KRB5INT_ACCESS_STRUCT_VERSION 9
+#define KRB5INT_ACCESS_STRUCT_VERSION 12
#ifndef ANAME_SZ
-struct ktext; /* from krb.h, for krb524 support */
+struct ktext; /* from krb.h, for krb524 support */
#endif
typedef struct _krb5int_access {
/* crypto stuff */
const struct krb5_hash_provider *md5_hash_provider;
const struct krb5_enc_provider *arcfour_enc_provider;
- krb5_error_code (* krb5_hmac) (krb5_context,
- const struct krb5_hash_provider *hash,
- const krb5_keyblock *key,
- unsigned int icount, const krb5_data *input,
- krb5_data *output);
+ krb5_error_code (* krb5_hmac) (krb5_context, const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key,
+ unsigned int icount, const krb5_data *input,
+ krb5_data *output);
/* service location and communication */
#ifndef _KERNEL
- krb5_error_code (*locate_server) (krb5_context, const krb5_data *,
- struct addrlist *, int,
- const char *, const char *,
- int, int, int, int);
krb5_error_code (*sendto_udp) (krb5_context, const krb5_data *msg,
- const struct addrlist *, krb5_data *reply,
- struct sockaddr_storage *, socklen_t *, int *);
+ const struct addrlist *, struct sendto_callback_info*, krb5_data *reply,
+ struct sockaddr *, socklen_t *,struct sockaddr *,
+ socklen_t *, int *,
+ int (*msg_handler)(krb5_context, const krb5_data *, void *),
+ void *msg_handler_data);
krb5_error_code (*add_host_to_list)(struct addrlist *lp,
- const char *hostname,
- int port, int secport,
- int socktype, int family);
+ const char *hostname,
+ int port, int secport,
+ int socktype, int family);
void (*free_addrlist) (struct addrlist *);
#endif /* _KERNEL */
-
krb5_error_code (*make_srv_query_realm)(const krb5_data *realm,
- const char *service,
- const char *protocol,
- struct srv_dns_entry **answers);
+ const char *service,
+ const char *protocol,
+ struct srv_dns_entry **answers);
void (*free_srv_dns_data)(struct srv_dns_entry *);
int (*use_dns_kdc)(krb5_context);
@@ -2091,14 +2315,81 @@ typedef struct _krb5int_access {
struct _krb5_key_data **out,
krb5_int16 *n_key_data,
int *mkvno);
+
+ /*
+ * pkinit asn.1 encode/decode functions
+ */
+ krb5_error_code (*encode_krb5_auth_pack)
+ (const krb5_auth_pack *rep, krb5_data **code);
+ krb5_error_code (*encode_krb5_auth_pack_draft9)
+ (const krb5_auth_pack_draft9 *rep, krb5_data **code);
+ krb5_error_code (*encode_krb5_kdc_dh_key_info)
+ (const krb5_kdc_dh_key_info *rep, krb5_data **code);
+ krb5_error_code (*encode_krb5_pa_pk_as_rep)
+ (const krb5_pa_pk_as_rep *rep, krb5_data **code);
+ krb5_error_code (*encode_krb5_pa_pk_as_rep_draft9)
+ (const krb5_pa_pk_as_rep_draft9 *rep, krb5_data **code);
+ krb5_error_code (*encode_krb5_pa_pk_as_req)
+ (const krb5_pa_pk_as_req *rep, krb5_data **code);
+ krb5_error_code (*encode_krb5_pa_pk_as_req_draft9)
+ (const krb5_pa_pk_as_req_draft9 *rep, krb5_data **code);
+ krb5_error_code (*encode_krb5_reply_key_pack)
+ (const krb5_reply_key_pack *, krb5_data **code);
+ krb5_error_code (*encode_krb5_reply_key_pack_draft9)
+ (const krb5_reply_key_pack_draft9 *, krb5_data **code);
+ krb5_error_code (*encode_krb5_td_dh_parameters)
+ (const krb5_algorithm_identifier **, krb5_data **code);
+ krb5_error_code (*encode_krb5_td_trusted_certifiers)
+ (const krb5_external_principal_identifier **, krb5_data **code);
+ krb5_error_code (*encode_krb5_typed_data)
+ (const krb5_typed_data **, krb5_data **code);
+
+ krb5_error_code (*decode_krb5_auth_pack)
+ (const krb5_data *, krb5_auth_pack **);
+ krb5_error_code (*decode_krb5_auth_pack_draft9)
+ (const krb5_data *, krb5_auth_pack_draft9 **);
+ krb5_error_code (*decode_krb5_pa_pk_as_req)
+ (const krb5_data *, krb5_pa_pk_as_req **);
+ krb5_error_code (*decode_krb5_pa_pk_as_req_draft9)
+ (const krb5_data *, krb5_pa_pk_as_req_draft9 **);
+ krb5_error_code (*decode_krb5_pa_pk_as_rep)
+ (const krb5_data *, krb5_pa_pk_as_rep **);
+ krb5_error_code (*decode_krb5_pa_pk_as_rep_draft9)
+ (const krb5_data *, krb5_pa_pk_as_rep_draft9 **);
+ krb5_error_code (*decode_krb5_kdc_dh_key_info)
+ (const krb5_data *, krb5_kdc_dh_key_info **);
+ krb5_error_code (*decode_krb5_principal_name)
+ (const krb5_data *, krb5_principal_data **);
+ krb5_error_code (*decode_krb5_reply_key_pack)
+ (const krb5_data *, krb5_reply_key_pack **);
+ krb5_error_code (*decode_krb5_reply_key_pack_draft9)
+ (const krb5_data *, krb5_reply_key_pack_draft9 **);
+ krb5_error_code (*decode_krb5_td_dh_parameters)
+ (const krb5_data *, krb5_algorithm_identifier ***);
+ krb5_error_code (*decode_krb5_td_trusted_certifiers)
+ (const krb5_data *, krb5_external_principal_identifier ***);
+ krb5_error_code (*decode_krb5_typed_data)
+ (const krb5_data *, krb5_typed_data ***);
+
+ krb5_error_code (*decode_krb5_as_req)
+ (const krb5_data *output, krb5_kdc_req **rep);
+ krb5_error_code (*encode_krb5_kdc_req_body)
+ (const krb5_kdc_req *rep, krb5_data **code);
+ void (KRB5_CALLCONV *krb5_free_kdc_req)
+ (krb5_context, krb5_kdc_req * );
+ void (*krb5int_set_prompt_types)
+ (krb5_context, krb5_prompt_type *);
+ krb5_error_code (*encode_krb5_authdata_elt)
+ (const krb5_authdata *rep, krb5_data **code);
+
} krb5int_access;
#define KRB5INT_ACCESS_VERSION \
(((krb5_int32)((sizeof(krb5int_access) & 0xFFFF) | \
- (KRB5INT_ACCESS_STRUCT_VERSION << 16))) & 0xFFFFFFFF)
+ (KRB5INT_ACCESS_STRUCT_VERSION << 16))) & 0xFFFFFFFF)
krb5_error_code KRB5_CALLCONV krb5int_accessor
- (krb5int_access*, krb5_int32);
+ (krb5int_access*, krb5_int32);
/* Ick -- some krb524 and krb4 support placed in the krb5 library,
because AFS (and potentially other applications?) use the krb4
@@ -2115,13 +2406,13 @@ extern int krb5int_krb_time_to_life(krb5_int32, krb5_int32);
/* conv_creds.c */
int krb5int_encode_v4tkt
- (struct ktext *v4tkt, char *buf, unsigned int *encoded_len);
+ (struct ktext *v4tkt, char *buf, unsigned int *encoded_len);
/* send524.c */
int krb5int_524_sendto_kdc
(krb5_context context, const krb5_data * message,
- const krb5_data * realm, krb5_data * reply,
- struct sockaddr *, socklen_t *);
+ const krb5_data * realm, krb5_data * reply,
+ struct sockaddr *, socklen_t *);
/* temporary -- this should be under lib/krb5/ccache somewhere */
@@ -2131,134 +2422,181 @@ struct _krb5_ccache {
krb5_pointer data;
};
+/*
+ * Per-type ccache cursor.
+ */
+struct krb5_cc_ptcursor {
+ const struct _krb5_cc_ops *ops;
+ krb5_pointer data;
+};
+typedef struct krb5_cc_ptcursor *krb5_cc_ptcursor;
+
struct _krb5_cc_ops {
krb5_magic magic;
char *prefix;
const char * (KRB5_CALLCONV *get_name) (krb5_context, krb5_ccache);
krb5_error_code (KRB5_CALLCONV *resolve) (krb5_context, krb5_ccache *,
- const char *);
+ const char *);
krb5_error_code (KRB5_CALLCONV *gen_new) (krb5_context, krb5_ccache *);
krb5_error_code (KRB5_CALLCONV *init) (krb5_context, krb5_ccache,
- krb5_principal);
+ krb5_principal);
krb5_error_code (KRB5_CALLCONV *destroy) (krb5_context, krb5_ccache);
krb5_error_code (KRB5_CALLCONV *close) (krb5_context, krb5_ccache);
krb5_error_code (KRB5_CALLCONV *store) (krb5_context, krb5_ccache,
- krb5_creds *);
+ krb5_creds *);
krb5_error_code (KRB5_CALLCONV *retrieve) (krb5_context, krb5_ccache,
- krb5_flags, krb5_creds *,
- krb5_creds *);
+ krb5_flags, krb5_creds *,
+ krb5_creds *);
krb5_error_code (KRB5_CALLCONV *get_princ) (krb5_context, krb5_ccache,
- krb5_principal *);
+ krb5_principal *);
krb5_error_code (KRB5_CALLCONV *get_first) (krb5_context, krb5_ccache,
- krb5_cc_cursor *);
+ krb5_cc_cursor *);
krb5_error_code (KRB5_CALLCONV *get_next) (krb5_context, krb5_ccache,
- krb5_cc_cursor *, krb5_creds *);
+ krb5_cc_cursor *, krb5_creds *);
krb5_error_code (KRB5_CALLCONV *end_get) (krb5_context, krb5_ccache,
- krb5_cc_cursor *);
+ krb5_cc_cursor *);
krb5_error_code (KRB5_CALLCONV *remove_cred) (krb5_context, krb5_ccache,
- krb5_flags, krb5_creds *);
+ krb5_flags, krb5_creds *);
krb5_error_code (KRB5_CALLCONV *set_flags) (krb5_context, krb5_ccache,
- krb5_flags);
+ krb5_flags);
+ krb5_error_code (KRB5_CALLCONV *get_flags) (krb5_context, krb5_ccache,
+ krb5_flags *);
+ krb5_error_code (KRB5_CALLCONV *ptcursor_new)(krb5_context,
+ krb5_cc_ptcursor *);
+ krb5_error_code (KRB5_CALLCONV *ptcursor_next)(krb5_context,
+ krb5_cc_ptcursor,
+ krb5_ccache *);
+ krb5_error_code (KRB5_CALLCONV *ptcursor_free)(krb5_context,
+ krb5_cc_ptcursor *);
+ krb5_error_code (KRB5_CALLCONV *move)(krb5_context, krb5_ccache);
+ krb5_error_code (KRB5_CALLCONV *lastchange)(krb5_context,
+ krb5_ccache, krb5_timestamp *);
+ krb5_error_code (KRB5_CALLCONV *wasdefault)(krb5_context, krb5_ccache,
+ krb5_timestamp *);
};
extern const krb5_cc_ops *krb5_cc_dfl_ops;
+krb5_error_code
+krb5int_cc_os_default_name(krb5_context context, char **name);
+
+/*
+ * Cursor for iterating over ccache types
+ */
+struct krb5_cc_typecursor;
+typedef struct krb5_cc_typecursor *krb5_cc_typecursor;
+
+krb5_error_code
+krb5int_cc_typecursor_new(krb5_context context, krb5_cc_typecursor *cursor);
+
+krb5_error_code
+krb5int_cc_typecursor_next(
+ krb5_context context,
+ krb5_cc_typecursor cursor,
+ const struct _krb5_cc_ops **ops);
+
+krb5_error_code
+krb5int_cc_typecursor_free(
+ krb5_context context,
+ krb5_cc_typecursor *cursor);
+
typedef struct _krb5_donot_replay {
krb5_magic magic;
krb5_ui_4 hash;
- char *server; /* null-terminated */
- char *client; /* null-terminated */
+ char *server; /* null-terminated */
+ char *client; /* null-terminated */
krb5_int32 cusec;
krb5_timestamp ctime;
} krb5_donot_replay;
krb5_error_code krb5_rc_default
- (krb5_context,
- krb5_rcache *);
+ (krb5_context,
+ krb5_rcache *);
krb5_error_code krb5_rc_resolve_type
- (krb5_context,
- krb5_rcache *,char *);
+ (krb5_context,
+ krb5_rcache *,char *);
krb5_error_code krb5_rc_resolve_full
- (krb5_context,
- krb5_rcache *,char *);
+ (krb5_context,
+ krb5_rcache *,char *);
char * krb5_rc_get_type
- (krb5_context,
- krb5_rcache);
+ (krb5_context,
+ krb5_rcache);
char * krb5_rc_default_type
- (krb5_context);
+ (krb5_context);
char * krb5_rc_default_name
- (krb5_context);
+ (krb5_context);
krb5_error_code krb5_auth_to_rep
- (krb5_context,
- krb5_tkt_authent *,
- krb5_donot_replay *);
+ (krb5_context,
+ krb5_tkt_authent *,
+ krb5_donot_replay *);
+
krb5_error_code KRB5_CALLCONV krb5_rc_initialize
- (krb5_context, krb5_rcache,krb5_deltat);
+ (krb5_context, krb5_rcache,krb5_deltat);
krb5_error_code KRB5_CALLCONV krb5_rc_recover_or_initialize
- (krb5_context, krb5_rcache,krb5_deltat);
+ (krb5_context, krb5_rcache,krb5_deltat);
krb5_error_code KRB5_CALLCONV krb5_rc_recover
- (krb5_context, krb5_rcache);
+ (krb5_context, krb5_rcache);
krb5_error_code KRB5_CALLCONV krb5_rc_destroy
- (krb5_context, krb5_rcache);
+ (krb5_context, krb5_rcache);
krb5_error_code KRB5_CALLCONV krb5_rc_close
- (krb5_context, krb5_rcache);
+ (krb5_context, krb5_rcache);
krb5_error_code KRB5_CALLCONV krb5_rc_store
- (krb5_context, krb5_rcache,krb5_donot_replay *);
+ (krb5_context, krb5_rcache,krb5_donot_replay *);
krb5_error_code KRB5_CALLCONV krb5_rc_expunge
- (krb5_context, krb5_rcache);
+ (krb5_context, krb5_rcache);
krb5_error_code KRB5_CALLCONV krb5_rc_get_lifespan
- (krb5_context, krb5_rcache,krb5_deltat *);
+ (krb5_context, krb5_rcache,krb5_deltat *);
char *KRB5_CALLCONV krb5_rc_get_name
- (krb5_context, krb5_rcache);
+ (krb5_context, krb5_rcache);
krb5_error_code KRB5_CALLCONV krb5_rc_resolve
- (krb5_context, krb5_rcache, char *);
+ (krb5_context, krb5_rcache, char *);
typedef struct _krb5_kt_ops {
krb5_magic magic;
char *prefix;
/* routines always present */
krb5_error_code (KRB5_CALLCONV *resolve)
- (krb5_context,
- const char *,
- krb5_keytab *);
+ (krb5_context,
+ const char *,
+ krb5_keytab *);
krb5_error_code (KRB5_CALLCONV *get_name)
- (krb5_context,
- krb5_keytab,
- char *,
- unsigned int);
+ (krb5_context,
+ krb5_keytab,
+ char *,
+ unsigned int);
krb5_error_code (KRB5_CALLCONV *close)
- (krb5_context,
- krb5_keytab);
+ (krb5_context,
+ krb5_keytab);
krb5_error_code (KRB5_CALLCONV *get)
- (krb5_context,
- krb5_keytab,
- krb5_const_principal,
- krb5_kvno,
- krb5_enctype,
- krb5_keytab_entry *);
+ (krb5_context,
+ krb5_keytab,
+ krb5_const_principal,
+ krb5_kvno,
+ krb5_enctype,
+ krb5_keytab_entry *);
krb5_error_code (KRB5_CALLCONV *start_seq_get)
- (krb5_context,
- krb5_keytab,
- krb5_kt_cursor *);
+ (krb5_context,
+ krb5_keytab,
+ krb5_kt_cursor *);
krb5_error_code (KRB5_CALLCONV *get_next)
- (krb5_context,
- krb5_keytab,
- krb5_keytab_entry *,
- krb5_kt_cursor *);
+ (krb5_context,
+ krb5_keytab,
+ krb5_keytab_entry *,
+ krb5_kt_cursor *);
krb5_error_code (KRB5_CALLCONV *end_get)
- (krb5_context,
- krb5_keytab,
- krb5_kt_cursor *);
+ (krb5_context,
+ krb5_keytab,
+ krb5_kt_cursor *);
/* routines to be included on extended version (write routines) */
krb5_error_code (KRB5_CALLCONV *add)
- (krb5_context,
- krb5_keytab,
- krb5_keytab_entry *);
+ (krb5_context,
+ krb5_keytab,
+ krb5_keytab_entry *);
krb5_error_code (KRB5_CALLCONV *remove)
- (krb5_context,
- krb5_keytab,
- krb5_keytab_entry *);
+ (krb5_context,
+ krb5_keytab,
+ krb5_keytab_entry *);
/* Handle for serializer */
const krb5_ser_entry *serializer;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-load_16.h b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-load_16.h
new file mode 100644
index 0000000000..42f27e4b73
--- /dev/null
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-load_16.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+/*
+ * k5-platform.h
+ *
+ * Copyright 2003, 2004, 2005 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.
+ *
+ *
+ * Some platform-dependent definitions to sync up the C support level.
+ * Some to a C99-ish level, some related utility code.
+ *
+ * Currently:
+ * + make "static inline" work
+ * + 64-bit types and load/store code
+ * + SIZE_MAX
+ * + shared library init/fini hooks
+ * + consistent getpwnam/getpwuid interfaces
+ */
+
+static unsigned short
+load_16_be (unsigned char *p)
+{
+ return (p[1] | (p[0] << 8));
+}
+
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-load_32.h b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-load_32.h
new file mode 100644
index 0000000000..7199c56837
--- /dev/null
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-load_32.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+/*
+ * k5-platform.h
+ *
+ * Copyright 2003, 2004, 2005 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.
+ *
+ *
+ * Some platform-dependent definitions to sync up the C support level.
+ * Some to a C99-ish level, some related utility code.
+ *
+ * Currently:
+ * + make "static inline" work
+ * + 64-bit types and load/store code
+ * + SIZE_MAX
+ * + shared library init/fini hooks
+ * + consistent getpwnam/getpwuid interfaces
+ */
+
+static unsigned int
+load_32_be (unsigned char *p)
+{
+ return (p[3] | (p[2] << 8) | (p[1] << 16) | (p[0] << 24));
+}
+
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-load_64.h b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-load_64.h
new file mode 100644
index 0000000000..78a46fb125
--- /dev/null
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-load_64.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+/*
+ * k5-platform.h
+ *
+ * Copyright 2003, 2004, 2005 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.
+ *
+ *
+ * Some platform-dependent definitions to sync up the C support level.
+ * Some to a C99-ish level, some related utility code.
+ *
+ * Currently:
+ * + make "static inline" work
+ * + 64-bit types and load/store code
+ * + SIZE_MAX
+ * + shared library init/fini hooks
+ * + consistent getpwnam/getpwuid interfaces
+ */
+
+#include <k5-platform-load_32.h>
+
+static UINT64_TYPE
+load_64_be (unsigned char *p)
+{
+ return ((UINT64_TYPE)load_32_be(p) << 32) | load_32_be(p+4);
+}
+
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-store_16.h b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-store_16.h
new file mode 100644
index 0000000000..7265e41dc1
--- /dev/null
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-store_16.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+/*
+ * k5-platform.h
+ *
+ * Copyright 2003, 2004, 2005 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.
+ *
+ *
+ * Some platform-dependent definitions to sync up the C support level.
+ * Some to a C99-ish level, some related utility code.
+ *
+ * Currently:
+ * + make "static inline" work
+ * + 64-bit types and load/store code
+ * + SIZE_MAX
+ * + shared library init/fini hooks
+ * + consistent getpwnam/getpwuid interfaces
+ */
+
+static void
+store_16_be (unsigned int val, unsigned char *p)
+{
+ p[0] = (val >> 8) & 0xff;
+ p[1] = (val ) & 0xff;
+}
+
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-store_32.h b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-store_32.h
new file mode 100644
index 0000000000..d7f7aa14af
--- /dev/null
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-store_32.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+/*
+ * k5-platform.h
+ *
+ * Copyright 2003, 2004, 2005 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.
+ *
+ *
+ * Some platform-dependent definitions to sync up the C support level.
+ * Some to a C99-ish level, some related utility code.
+ *
+ * Currently:
+ * + make "static inline" work
+ * + 64-bit types and load/store code
+ * + SIZE_MAX
+ * + shared library init/fini hooks
+ * + consistent getpwnam/getpwuid interfaces
+ */
+
+static void
+store_32_be (unsigned int val, unsigned char *p)
+{
+ p[0] = (val >> 24) & 0xff;
+ p[1] = (val >> 16) & 0xff;
+ p[2] = (val >> 8) & 0xff;
+ p[3] = (val ) & 0xff;
+}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-store_64.h b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-store_64.h
new file mode 100644
index 0000000000..58e545df31
--- /dev/null
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform-store_64.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+/*
+ * k5-platform.h
+ *
+ * Copyright 2003, 2004, 2005 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.
+ *
+ *
+ * Some platform-dependent definitions to sync up the C support level.
+ * Some to a C99-ish level, some related utility code.
+ *
+ * Currently:
+ * + make "static inline" work
+ * + 64-bit types and load/store code
+ * + SIZE_MAX
+ * + shared library init/fini hooks
+ * + consistent getpwnam/getpwuid interfaces
+ */
+
+static void
+store_64_be (UINT64_TYPE val, unsigned char *p)
+{
+ p[0] = (unsigned char)((val >> 56) & 0xff);
+ p[1] = (unsigned char)((val >> 48) & 0xff);
+ p[2] = (unsigned char)((val >> 40) & 0xff);
+ p[3] = (unsigned char)((val >> 32) & 0xff);
+ p[4] = (unsigned char)((val >> 24) & 0xff);
+ p[5] = (unsigned char)((val >> 16) & 0xff);
+ p[6] = (unsigned char)((val >> 8) & 0xff);
+ p[7] = (unsigned char)((val ) & 0xff);
+}
+
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h
index 8b6824c3aa..8fe696a6ad 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h
@@ -1,14 +1,13 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* k5-platform.h
*
- * Copyright 2003, 2004 Massachusetts Institute of Technology.
+ * Copyright 2003, 2004, 2005 Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -39,12 +38,16 @@
* + 64-bit types and load/store code
* + SIZE_MAX
* + shared library init/fini hooks
+ * + consistent getpwnam/getpwuid interfaces
*/
#ifndef K5_PLATFORM_H
#define K5_PLATFORM_H
+/* Solaris Kerberos */
#ifndef _KERNEL
+#include <sys/types.h>
+
#include "autoconf.h"
/* Initialization and finalization function support for libraries.
@@ -52,14 +55,23 @@
At top level, before the functions are defined or even declared:
MAKE_INIT_FUNCTION(init_fn);
MAKE_FINI_FUNCTION(fini_fn);
+ Then:
int init_fn(void) { ... }
void fini_fn(void) { if (INITIALIZER_RAN(init_fn)) ... }
-
In code, in the same file:
err = CALL_INIT_FUNCTION(init_fn);
To trigger or verify the initializer invocation from another file,
- an additional function must be created.
+ a helper function must be created.
+
+ This model handles both the load-time execution (Windows) and
+ delayed execution (pthread_once) approaches, and should be able to
+ guarantee in both cases that the init function is run once, in one
+ thread, before other stuff in the library is done; furthermore, the
+ finalization code should only run if the initialization code did.
+ (Maybe I could've made the "if INITIALIZER_RAN" test implicit, via
+ another function hidden in macros, but this is hairy enough
+ already.)
The init_fn and fini_fn names should be chosen such that any
exported names staring with those names, and optionally followed by
@@ -67,6 +79,21 @@
the library in question.
+ There's also PROGRAM_EXITING() currently always defined as zero.
+ If there's some trivial way to find out if the fini function is
+ being called because the program that the library is linked into is
+ exiting, we can just skip all the work because the resources are
+ about to be freed up anyways. Generally this is likely to be the
+ same as distinguishing whether the library was loaded dynamically
+ while the program was running, or loaded as part of program
+ startup. On most platforms, I don't think we can distinguish these
+ cases easily, and it's probably not worth expending any significant
+ effort. (Note in particular that atexit() won't do, because if the
+ library is explicitly loaded and unloaded, it would have to be able
+ to deregister the atexit callback function. Also, the system limit
+ on atexit callbacks may be small.)
+
+
Implementation outline:
Windows: MAKE_FINI_FUNCTION creates a symbol with a magic name that
@@ -86,6 +113,11 @@
just check the flag) and returns the stored error code (or the
pthread_once error).
+ (That's the basic idea. With some debugging assert() calls and
+ such, it's a bit more complicated. And we also need to handle
+ doing the pthread test at run time on systems where that works, so
+ we use the k5_once_t stuff instead.)
+
UNIX, with compiler support: MAKE_FINI_FUNCTION declares the
function as a destructor, and the run time linker support or
whatever will cause it to be invoked when the library is unloaded,
@@ -99,12 +131,20 @@
UNIX, no library finalization support: The finalization function
never runs, and we leak memory. Tough.
+ DELAY_INITIALIZER will be defined by the configure script if we
+ want to use k5_once instead of load-time initialization. That'll
+ be the preferred method on most systems except Windows, where we
+ have to initialize some mutexes.
+
+
For maximum flexibility in defining the macros, the function name
parameter should be a simple name, not even a macro defined as
another name. The function should have a unique name, and should
conform to whatever namespace is used by the library in question.
+ (We do have export lists, but (1) they're not used for all
+ platforms, and (2) they're not used for static libraries.)
If the macro expansion needs the function to have been declared, it
must include a declaration. If it is not necessary for the symbol
@@ -118,7 +158,8 @@
This is going to be compiler- and environment-specific, and may
require some support at library build time, and/or "asm"
- statements.
+ statements. But through macro expansion and auxiliary functions,
+ we should be able to handle most things except #pragma.
It's okay for this code to require that the library be built
with the same compiler and compiler options throughout, but
@@ -137,7 +178,12 @@
work, we'll only have memory leaks in a load/use/unload cycle. If
anyone (like, say, the OS vendor) complains about this, they can
tell us how to get a shared library finalization function invoked
- automatically. */
+ automatically.
+
+ Currently there's --disable-delayed-initialization for preventing
+ the initialization from being delayed on UNIX, but that's mainly
+ just for testing the linker options for initialization, and will
+ probably be removed at some point. */
/* Helper macros. */
@@ -160,6 +206,30 @@ typedef struct { k5_once_t once; int error, did_run; void (*fn)(void); } k5_init
# else
# define MAYBE_DUMMY_INIT(NAME)
# endif
+# ifdef __GNUC__
+/* Do it in macro form so we get the file/line of the invocation if
+ the assertion fails. */
+# define k5_call_init_function(I) \
+ (__extension__ ({ \
+ k5_init_t *k5int_i = (I); \
+ int k5int_err = k5_once(&k5int_i->once, k5int_i->fn); \
+ (k5int_err \
+ ? k5int_err \
+ : (assert(k5int_i->did_run != 0), k5int_i->error)); \
+ }))
+# define MAYBE_DEFINE_CALLINIT_FUNCTION
+# else
+# define MAYBE_DEFINE_CALLINIT_FUNCTION \
+ static int k5_call_init_function(k5_init_t *i) \
+ { \
+ int err; \
+ err = k5_once(&i->once, i->fn); \
+ if (err) \
+ return err; \
+ assert (i->did_run != 0); \
+ return i->error; \
+ }
+# endif
# define MAKE_INIT_FUNCTION(NAME) \
static int NAME(void); \
MAYBE_DUMMY_INIT(NAME) \
@@ -167,6 +237,7 @@ typedef struct { k5_once_t once; int error, did_run; void (*fn)(void); } k5_init
static void JOIN__2(NAME, aux) (void); \
static k5_init_t JOIN__2(NAME, once) = \
{ K5_ONCE_INIT, 0, 0, JOIN__2(NAME, aux) }; \
+ MAYBE_DEFINE_CALLINIT_FUNCTION \
static void JOIN__2(NAME, aux) (void) \
{ \
JOIN__2(NAME, once).did_run = 1; \
@@ -176,34 +247,15 @@ typedef struct { k5_once_t once; int error, did_run; void (*fn)(void); } k5_init
static int NAME(void)
# define CALL_INIT_FUNCTION(NAME) \
k5_call_init_function(& JOIN__2(NAME, once))
-# ifdef __GNUC__
-/* Do it in macro form so we get the file/line of the invocation if
- the assertion fails. */
-# define k5_call_init_function(I) \
- (__extension__ ({ \
- k5_init_t *k5int_i = (I); \
- int k5int_err = k5_once(&k5int_i->once, k5int_i->fn); \
- (k5int_err \
- ? k5int_err \
- : (assert(k5int_i->did_run != 0), k5int_i->error)); \
- }))
-# else /* __GNUC__ */
-static int k5_call_init_function(k5_init_t *i)
-{
- int err;
- err = k5_once(&i->once, i->fn);
- if (err)
- return err;
- assert (i->did_run != 0);
- return i->error;
-}
-# endif /* __GNUC__ */
/* This should be called in finalization only, so we shouldn't have
multiple active threads mucking around in our library at this
point. So ignore the once_t object and just look at the flag.
- XXX Could we have problems with memory coherence between
- processors if we don't invoke mutex/once routines? */
+ XXX Could we have problems with memory coherence between processors
+ if we don't invoke mutex/once routines? Probably not, the
+ application code should already be coordinating things such that
+ the library code is not in use by this point, and memory
+ synchronization will be needed there. */
# define INITIALIZER_RAN(NAME) \
(JOIN__2(NAME, once).did_run && JOIN__2(NAME, once).error == 0)
@@ -214,6 +266,7 @@ static int k5_call_init_function(k5_init_t *i)
/* Run initializer at load time, via GCC/C++ hook magic. */
# ifdef USE_LINKER_INIT_OPTION
+ /* Both gcc and linker option?? Favor gcc. */
# define MAYBE_DUMMY_INIT(NAME) \
void JOIN__2(NAME, auxinit) () { }
# else
@@ -240,6 +293,8 @@ typedef struct { int error; unsigned char did_run; } k5_init_t;
: (abort(),0))
# define INITIALIZER_RAN(NAME) (JOIN__2(NAME,ran).did_run == 3 && JOIN__2(NAME, ran).error == 0)
+# define PROGRAM_EXITING() (0)
+
#elif defined(USE_LINKER_INIT_OPTION) || defined(_WIN32)
/* Run initializer at load time, via linker magic, or in the
@@ -279,9 +334,35 @@ typedef struct { int error; unsigned char did_run; } k5_init_t;
matter what compiler we're using. Do it the same way
regardless. */
-# define MAKE_FINI_FUNCTION(NAME) \
+# ifdef __hpux
+
+ /* On HP-UX, we need this auxiliary function. At dynamic load or
+ unload time (but *not* program startup and termination for
+ link-time specified libraries), the linker-indicated function
+ is called with a handle on the library and a flag indicating
+ whether it's being loaded or unloaded.
+
+ The "real" fini function doesn't need to be exported, so
+ declare it static.
+
+ As usual, the final declaration is just for syntactic
+ convenience, so the top-level invocation of this macro can be
+ followed by a semicolon. */
+
+# include <dl.h>
+# define MAKE_FINI_FUNCTION(NAME) \
+ static void NAME(void); \
+ void JOIN__2(NAME, auxfini)(shl_t, int); /* silence gcc warnings */ \
+ void JOIN__2(NAME, auxfini)(shl_t h, int l) { if (!l) NAME(); } \
+ static void NAME(void)
+
+# else /* not hpux */
+
+# define MAKE_FINI_FUNCTION(NAME) \
void NAME(void)
+# endif
+
#elif defined(__GNUC__) && defined(DESTRUCTOR_ATTR_WORKS)
/* If we're using gcc, if the C++ support works, the compiler should
build executables and shared libraries that support the use of
@@ -302,11 +383,11 @@ typedef struct { int error; unsigned char did_run; } k5_init_t;
# define MAKE_FINI_FUNCTION(NAME) \
static void NAME(void)
-#else /* DELAY_INITIALIZER */
+#else
# error "Don't know how to do unload-time finalization for this configuration."
-#endif /* DELAY_INITIALIZER */
+#endif
#endif /* !_KERNEL */
@@ -347,19 +428,22 @@ typedef struct { int error; unsigned char did_run; } k5_init_t;
unaligned word stores and gcc/asm instructions for byte swaps,
etc.) */
-static void
+/* Solaris Kerberos: To avoid problems with lint the following
+ functions can be found in separate header files. */
+#if 0
+static void
store_16_be (unsigned int val, unsigned char *p)
{
p[0] = (val >> 8) & 0xff;
p[1] = (val ) & 0xff;
}
-static void
+static void
store_16_le (unsigned int val, unsigned char *p)
{
p[1] = (val >> 8) & 0xff;
p[0] = (val ) & 0xff;
}
-static void
+static void
store_32_be (unsigned int val, unsigned char *p)
{
p[0] = (val >> 24) & 0xff;
@@ -367,7 +451,7 @@ store_32_be (unsigned int val, unsigned char *p)
p[2] = (val >> 8) & 0xff;
p[3] = (val ) & 0xff;
}
-static void
+static void
store_32_le (unsigned int val, unsigned char *p)
{
p[3] = (val >> 24) & 0xff;
@@ -375,7 +459,7 @@ store_32_le (unsigned int val, unsigned char *p)
p[1] = (val >> 8) & 0xff;
p[0] = (val ) & 0xff;
}
-static void
+static void
store_64_be (UINT64_TYPE val, unsigned char *p)
{
p[0] = (unsigned char)((val >> 56) & 0xff);
@@ -387,7 +471,7 @@ store_64_be (UINT64_TYPE val, unsigned char *p)
p[6] = (unsigned char)((val >> 8) & 0xff);
p[7] = (unsigned char)((val ) & 0xff);
}
-static void
+static void
store_64_le (UINT64_TYPE val, unsigned char *p)
{
p[7] = (unsigned char)((val >> 56) & 0xff);
@@ -399,12 +483,12 @@ store_64_le (UINT64_TYPE val, unsigned char *p)
p[1] = (unsigned char)((val >> 8) & 0xff);
p[0] = (unsigned char)((val ) & 0xff);
}
-static unsigned short
+static unsigned short
load_16_be (unsigned char *p)
{
return (p[1] | (p[0] << 8));
}
-static unsigned short
+static unsigned short
load_16_le (unsigned char *p)
{
return (p[0] | (p[1] << 8));
@@ -419,17 +503,17 @@ load_32_le (unsigned char *p)
{
return (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24));
}
-static UINT64_TYPE
+static UINT64_TYPE
load_64_be (unsigned char *p)
{
return ((UINT64_TYPE)load_32_be(p) << 32) | load_32_be(p+4);
}
-static UINT64_TYPE
+static UINT64_TYPE
load_64_le (unsigned char *p)
{
return ((UINT64_TYPE)load_32_le(p+4) << 32) | load_32_le(p);
}
-
+#endif
/* Make the interfaces to getpwnam and getpwuid consistent.
Model the wrappers on the POSIX thread-safe versions, but
@@ -445,3 +529,4 @@ load_64_le (unsigned char *p)
#endif /* K5_PLATFORM_H */
+
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-thread.h b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-thread.h
index 73f31d03ef..315bcc3f31 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-thread.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-thread.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,8 +35,6 @@
#ifndef K5_THREAD_H
#define K5_THREAD_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef _KERNEL
#include <sys/ksynch.h>
@@ -66,7 +64,6 @@ k5_mutex_unlock(k5_mutex_t *m)
#else /* _KERNEL */
#include "autoconf.h"
-
#ifndef KRB5_CALLCONV
# define KRB5_CALLCONV
#endif
@@ -200,7 +197,7 @@ typedef struct {
#if __GNUC__ >= 2
#define K5_DEBUG_LOC (__extension__ (k5_debug_loc)K5_DEBUG_LOC_INIT)
#else
-static inline k5_debug_loc k5_debug_make_loc(const char *file, short line)
+static inline k5_debug_loc k5_debug_make_loc(const char *file, int line)
{
k5_debug_loc l;
l.filename = file;
@@ -250,6 +247,12 @@ timediff(k5_debug_time_t t2, k5_debug_time_t t1)
{
return (t2.tv_sec - t1.tv_sec) * 1000000 + (t2.tv_usec - t1.tv_usec);
}
+static inline k5_debug_time_t get_current_time(void)
+{
+ struct timeval tv;
+ if (gettimeofday(&tv,0) < 0) { tv.tv_sec = tv.tv_usec = 0; }
+ return tv;
+}
struct k5_timediff_stats {
k5_debug_timediff_t valmin, valmax, valsum, valsqsum;
};
@@ -258,10 +261,20 @@ typedef struct {
k5_debug_time_t time_acquired, time_created;
struct k5_timediff_stats lockwait, lockheld;
} k5_debug_mutex_stats;
-#define k5_mutex_init_stats(S) \
- (memset((S), 0, sizeof(struct k5_debug_mutex_stats)), 0)
+#define k5_mutex_init_stats(S) \
+ (memset((S), 0, sizeof(k5_debug_mutex_stats)), \
+ (S)->time_created = get_current_time(), \
+ 0)
#define k5_mutex_finish_init_stats(S) (0)
#define K5_MUTEX_STATS_INIT { 0, {0}, {0}, {0}, {0} }
+typedef k5_debug_time_t k5_mutex_stats_tmp;
+#define k5_mutex_stats_start() get_current_time()
+void KRB5_CALLCONV krb5int_mutex_lock_update_stats(k5_debug_mutex_stats *m,
+ k5_mutex_stats_tmp start);
+void KRB5_CALLCONV krb5int_mutex_unlock_update_stats(k5_debug_mutex_stats *m);
+#define k5_mutex_lock_update_stats krb5int_mutex_lock_update_stats
+#define k5_mutex_unlock_update_stats krb5int_mutex_unlock_update_stats
+void KRB5_CALLCONV krb5int_mutex_report_stats(/* k5_mutex_t *m */);
#else
@@ -269,6 +282,26 @@ typedef char k5_debug_mutex_stats;
#define k5_mutex_init_stats(S) (*(S) = 's', 0)
#define k5_mutex_finish_init_stats(S) (0)
#define K5_MUTEX_STATS_INIT 's'
+typedef int k5_mutex_stats_tmp;
+#define k5_mutex_stats_start() (0)
+#ifdef __GNUC__
+static void
+k5_mutex_lock_update_stats(k5_debug_mutex_stats *m, k5_mutex_stats_tmp t)
+{
+}
+#else
+# define k5_mutex_lock_update_stats(M,S) (S)
+#endif
+#define k5_mutex_unlock_update_stats(M) (*(M) = 's')
+
+/* If statistics tracking isn't enabled, these functions don't actually
+ do anything. Declare anyways so we can do type checking etc. */
+void KRB5_CALLCONV krb5int_mutex_lock_update_stats(k5_debug_mutex_stats *m,
+ k5_mutex_stats_tmp start);
+void KRB5_CALLCONV krb5int_mutex_unlock_update_stats(k5_debug_mutex_stats *m);
+void KRB5_CALLCONV krb5int_mutex_report_stats(/* k5_mutex_t *m */);
+
+#define krb5int_mutex_report_stats(M) ((M)->stats = 'd')
#endif
@@ -328,7 +361,6 @@ typedef struct {
ASSERT((M)->locked == K5_MUTEX_DEBUG_UNLOCKED))
#else /* threads disabled and not debugging */
-
typedef char k5_os_nothread_mutex;
# define K5_OS_NOTHREAD_MUTEX_PARTIAL_INITIALIZER 0
/* Empty inline functions avoid the "statement with no effect"
@@ -379,7 +411,6 @@ typedef unsigned char k5_os_nothread_once_t;
#ifndef ENABLE_THREADS
-
typedef k5_os_nothread_mutex k5_os_mutex;
# define K5_OS_MUTEX_PARTIAL_INITIALIZER \
K5_OS_NOTHREAD_MUTEX_PARTIAL_INITIALIZER
@@ -403,9 +434,13 @@ typedef k5_os_nothread_mutex k5_os_mutex;
Linux: Stub mutex routines exist, but pthread_once does not.
- Solaris: In libc there's a pthread_once that doesn't seem
- to do anything. Bleah. But pthread_mutexattr_setrobust_np
- is defined only in libpthread.
+ Solaris: In libc there's a pthread_once that doesn't seem to do
+ anything. Bleah. But pthread_mutexattr_setrobust_np is defined
+ only in libpthread. However, some version of GNU libc (Red Hat's
+ Fedora Core 5, reportedly) seems to have that function, but no
+ declaration, so we'd have to declare it in order to test for its
+ address. We now have tests to see if pthread_once actually works,
+ so stick with that for now.
IRIX 6.5 stub pthread support in libc is really annoying. The
pthread_mutex_lock function returns ENOSYS for a program not linked
@@ -503,7 +538,7 @@ typedef struct {
_r2; \
})
# else
-static inline int
+static int
k5_pthread_mutex_lock(k5_os_mutex *m)
{
int r = pthread_mutex_lock(&m->p);
@@ -593,7 +628,7 @@ static int return_after_yield(int r)
# define K5_OS_MUTEX_PARTIAL_INITIALIZER \
{ PTHREAD_MUTEX_INITIALIZER, K5_OS_NOTHREAD_MUTEX_PARTIAL_INITIALIZER }
# endif
-
+asdfsdf
# define k5_os_mutex_finish_init(M) \
k5_os_nothread_mutex_finish_init(&(M)->n)
# define k5_os_mutex_init(M) \
@@ -671,7 +706,7 @@ typedef struct {
# define k5_os_mutex_destroy(M) \
(CloseHandle((M)->h) ? ((M)->h = 0, 0) : GetLastError())
-static inline int k5_os_mutex_lock(k5_os_mutex *m)
+static int k5_os_mutex_lock(k5_os_mutex *m)
{
DWORD res;
res = WaitForSingleObject(m->h, INFINITE);
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/keyhash_provider.h b/usr/src/uts/common/gssapi/mechs/krb5/include/keyhash_provider.h
index a3a599872e..ccd3b76300 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/keyhash_provider.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/keyhash_provider.h
@@ -1,20 +1,19 @@
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* 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
@@ -25,14 +24,14 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
+#include "k5-int.h"
-extern const struct krb5_keyhash_provider krb5_keyhash_descbc;
-extern const struct krb5_keyhash_provider krb5_keyhash_md5des;
+extern const struct krb5_keyhash_provider krb5int_keyhash_descbc;
+extern const struct krb5_keyhash_provider krb5int_keyhash_md5des;
extern const struct krb5_keyhash_provider krb5int_keyhash_hmac_md5;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h b/usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h
index c153c8f90f..3147259a7c 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h
@@ -8,7 +8,6 @@
#ifndef _KRB5_H
#define _KRB5_H
-#pragma ident "%Z%%M% %I% %E% SMI"
#define SIZEOF_INT 4
@@ -46,21 +45,21 @@
* 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.
- *
+ *
*
* General definitions for Kerberos version 5.
*/
/*
* Copyright (C) 1998 by the FundsXpress, INC.
- *
+ *
* All rights reserved.
- *
+ *
* Export of this software from the United States of America may require
* a specific license from the United States Government. It is the
* responsibility of any person or organization contemplating export to
* obtain such a license before exporting.
- *
+ *
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
@@ -71,7 +70,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.
@@ -125,14 +124,14 @@
#define KRB5_PRIVATE 1
#endif
-#if defined(__MACH__) && defined(__APPLE__)
-# include <TargetConditionals.h>
-# if TARGET_RT_MAC_CFM
-# error "Use KfM 4.0 SDK headers for CFM compilation."
-# endif
+#if defined(__MACH__) && defined(__APPLE__)
+# include <TargetConditionals.h>
+# if TARGET_RT_MAC_CFM
+# error "Use KfM 4.0 SDK headers for CFM compilation."
+# endif
#endif
-#if (defined(_MSDOS) || defined(_WIN32))
+#if defined(_MSDOS) || defined(_WIN32)
#include <win-mac.h>
#endif
@@ -163,15 +162,15 @@
#define KRB5_OLD_CRYPTO
-#ifndef KRB5INT_BEGIN_DECLS
-#if defined(__cplusplus)
-#define KRB5INT_BEGIN_DECLS extern "C" {
-#define KRB5INT_END_DECLS }
-#else
-#define KRB5INT_BEGIN_DECLS
-#define KRB5INT_END_DECLS
-#endif
-#endif /* KRB5INT_BEGIN_DECLS */
+#ifndef KRB5INT_BEGIN_DECLS
+#if defined(__cplusplus)
+#define KRB5INT_BEGIN_DECLS extern "C" {
+#define KRB5INT_END_DECLS }
+#else
+#define KRB5INT_BEGIN_DECLS
+#define KRB5INT_END_DECLS
+#endif
+#endif
#if TARGET_OS_MAC
# pragma options align=mac68k
@@ -181,7 +180,6 @@
struct _profile_t;
/* typedef struct _profile_t *profile_t; */
-
/*
* begin wordsize.h
*/
@@ -203,7 +201,7 @@ typedef unsigned short krb5_ui_2;
#endif
#if INT_MAX == 0x7fffffffL
-typedef int krb5_int32;
+typedef int krb5_int32;
typedef unsigned int krb5_ui_4;
#elif LONG_MAX == 0x7fffffffL
typedef long krb5_int32;
@@ -215,8 +213,8 @@ typedef unsigned short krb5_ui_4;
#error: undefined 32 bit type
#endif
-#define VALID_INT_BITS INT_MAX
-#define VALID_UINT_BITS UINT_MAX
+#define VALID_INT_BITS INT_MAX
+#define VALID_UINT_BITS UINT_MAX
#define KRB5_INT32_MAX 2147483647
/* this strange form is necessary since - is a unary operator, not a sign
@@ -251,11 +249,11 @@ typedef unsigned int krb5_boolean;
typedef unsigned int krb5_msgtype;
typedef unsigned int krb5_kvno;
-typedef krb5_int32 krb5_addrtype;
-typedef krb5_int32 krb5_enctype;
-typedef krb5_int32 krb5_cksumtype;
-typedef krb5_int32 krb5_authdatatype;
-typedef krb5_int32 krb5_keyusage;
+typedef krb5_int32 krb5_addrtype;
+typedef krb5_int32 krb5_enctype;
+typedef krb5_int32 krb5_cksumtype;
+typedef krb5_int32 krb5_authdatatype;
+typedef krb5_int32 krb5_keyusage;
typedef krb5_int32 krb5_preauthtype; /* This may change, later on */
typedef krb5_int32 krb5_flags;
@@ -266,22 +264,28 @@ typedef krb5_int32 krb5_deltat;
typedef krb5_error_code krb5_magic;
typedef struct _krb5_data {
- krb5_magic magic;
- unsigned int length;
- char *data;
+ krb5_magic magic;
+ unsigned int length;
+ char *data;
} krb5_data;
+typedef struct _krb5_octet_data {
+ krb5_magic magic;
+ unsigned int length;
+ krb5_octet *data;
+} krb5_octet_data;
+
/*
- * Hack length for crypto library to use the afs_string_to_key It is
- * equivalent to -1 without possible sign extension
- * We also overload for an unset salt type length - which is also -1, but
- * hey, why not....
-*/
-#define SALT_TYPE_AFS_LENGTH UINT_MAX
-#define SALT_TYPE_NO_LENGTH UINT_MAX
+ * Hack length for crypto library to use the afs_string_to_key It is
+ * equivalent to -1 without possible sign extension
+ * We also overload for an unset salt type length - which is also -1, but
+ * hey, why not....
+*/
+#define SALT_TYPE_AFS_LENGTH UINT_MAX
+#define SALT_TYPE_NO_LENGTH UINT_MAX
-typedef void * krb5_pointer;
-typedef void const * krb5_const_pointer;
+typedef void * krb5_pointer;
+typedef void const * krb5_const_pointer;
typedef struct krb5_principal_data {
krb5_magic magic;
@@ -320,10 +324,10 @@ typedef const krb5_principal_data *krb5_const_principal;
#define krb5_princ_size(context, princ) (princ)->length
#define krb5_princ_type(context, princ) (princ)->type
#define krb5_princ_name(context, princ) (princ)->data
-#define krb5_princ_component(context, princ,i) \
- (((i) < krb5_princ_size(context, princ)) \
- ? (princ)->data + (i) \
- : NULL)
+#define krb5_princ_component(context, princ,i) \
+ (((i) < krb5_princ_size(context, princ)) \
+ ? (princ)->data + (i) \
+ : NULL)
/*
* Constants for realm referrals.
@@ -356,11 +360,11 @@ typedef struct _krb5_address {
#define ADDRTYPE_CHAOS 0x0005
#define ADDRTYPE_XNS 0x0006
#define ADDRTYPE_ISO 0x0007
-#define ADDRTYPE_DDP 0x0010
-#define ADDRTYPE_INET6 0x0018
+#define ADDRTYPE_DDP 0x0010
+#define ADDRTYPE_INET6 0x0018
/* not yet in the spec... */
-#define ADDRTYPE_ADDRPORT 0x0100
-#define ADDRTYPE_IPPORT 0x0101
+#define ADDRTYPE_ADDRPORT 0x0100
+#define ADDRTYPE_IPPORT 0x0101
/* macros to determine if a type is a local type */
#define ADDRTYPE_IS_LOCAL(addrtype) (addrtype & 0x8000)
@@ -395,6 +399,7 @@ typedef struct _dk_node {
/*
* begin "encryption.h"
*/
+
typedef struct _krb5_keyblock {
krb5_magic magic;
krb5_enctype enctype;
@@ -438,17 +443,17 @@ typedef struct _krb5_enc_data {
#define ENCTYPE_DES_CBC_CRC 0x0001 /* DES cbc mode with CRC-32 */
#define ENCTYPE_DES_CBC_MD4 0x0002 /* DES cbc mode with RSA-MD4 */
#define ENCTYPE_DES_CBC_MD5 0x0003 /* DES cbc mode with RSA-MD5 */
-#define ENCTYPE_DES_CBC_RAW 0x0004 /* DES cbc mode raw */
+#define ENCTYPE_DES_CBC_RAW 0x0004 /* DES cbc mode raw */
/* XXX deprecated? */
#define ENCTYPE_DES3_CBC_SHA 0x0005 /* DES-3 cbc mode with NIST-SHA */
#define ENCTYPE_DES3_CBC_RAW 0x0006 /* DES-3 cbc mode raw */
-#define ENCTYPE_DES_HMAC_SHA1 0x0008
-#define ENCTYPE_DES3_CBC_SHA1 0x0010
-#define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011
-#define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012
+#define ENCTYPE_DES_HMAC_SHA1 0x0008
+#define ENCTYPE_DES3_CBC_SHA1 0x0010
+#define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011
+#define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012
#define ENCTYPE_ARCFOUR_HMAC 0x0017
#define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018
-#define ENCTYPE_UNKNOWN 0x01ff
+#define ENCTYPE_UNKNOWN 0x01ff
#define CKSUMTYPE_CRC32 0x0001
#define CKSUMTYPE_RSA_MD4 0x0002
@@ -458,8 +463,8 @@ typedef struct _krb5_enc_data {
/* rsa-md4-des-k */
#define CKSUMTYPE_RSA_MD5 0x0007
#define CKSUMTYPE_RSA_MD5_DES 0x0008
-#define CKSUMTYPE_NIST_SHA 0x0009
-#define CKSUMTYPE_HMAC_SHA1_DES3 0x000c
+#define CKSUMTYPE_NIST_SHA 0x0009
+#define CKSUMTYPE_HMAC_SHA1_DES3 0x000c
#define CKSUMTYPE_HMAC_SHA1_96_AES128 0x000f
#define CKSUMTYPE_HMAC_SHA1_96_AES256 0x0010
#define CKSUMTYPE_HMAC_MD5_ARCFOUR -138 /*Microsoft md5 hmac cksumtype*/
@@ -502,16 +507,14 @@ enum {
krb5_error_code KRB5_CALLCONV
krb5_c_encrypt
- (krb5_context context,
- const krb5_keyblock *key,
- krb5_keyusage usage, const krb5_data *ivec,
+ (krb5_context context, const krb5_keyblock *key,
+ krb5_keyusage usage, const krb5_data *cipher_state,
const krb5_data *input, krb5_enc_data *output);
krb5_error_code KRB5_CALLCONV
krb5_c_decrypt
- (krb5_context context,
- const krb5_keyblock *key,
- krb5_keyusage usage, const krb5_data *ivec,
+ (krb5_context context, const krb5_keyblock *key,
+ krb5_keyusage usage, const krb5_data *cipher_state,
const krb5_enc_data *input, krb5_data *output);
krb5_error_code KRB5_CALLCONV
@@ -525,6 +528,11 @@ krb5_error_code KRB5_CALLCONV
size_t *blocksize);
krb5_error_code KRB5_CALLCONV
+ krb5_c_keylengths
+ (krb5_context context, krb5_enctype enctype,
+ size_t *keybytes, size_t *keylength);
+
+krb5_error_code KRB5_CALLCONV
krb5_c_init_state(krb5_context,
const krb5_keyblock *, krb5_keyusage,
krb5_data *);
@@ -538,6 +546,11 @@ krb5_error_code KRB5_CALLCONV
(krb5_context context, krb5_enctype enctype,
krb5_keyblock *random_key);
+krb5_error_code KRB5_CALLCONV
+ krb5_c_random_to_key
+ (krb5_context context, krb5_enctype enctype,
+ krb5_data *random_data, krb5_keyblock *k5_random_key);
+
/* Register a new entropy sample with the PRNG. may cause
* the PRNG to be reseeded, although this is not guaranteed. See previous randsource definitions
* for information on how each source should be used.
@@ -550,19 +563,19 @@ krb5_error_code KRB5_CALLCONV
krb5_c_random_make_octets
(krb5_context context, krb5_data *data);
-/*
-* Collect entropy from the OS if possible. strong requests that as strong
-* of a source of entropy as available be used. Setting strong may
-* increase the probability of blocking and should not be used for normal
-* applications. Good uses include seeding the PRNG for kadmind
-* and realm setup.
-* If successful is non-null, then successful is set to 1 if the OS provided
-* entropy else zero.
-*/
+/*
+* Collect entropy from the OS if possible. strong requests that as strong
+* of a source of entropy as available be used. Setting strong may
+* increase the probability of blocking and should not be used for normal
+* applications. Good uses include seeding the PRNG for kadmind
+* and realm setup.
+* If successful is non-null, then successful is set to 1 if the OS provided
+* entropy else zero.
+*/
#if 0 /* SUNW14resync - not used in Solaris */
-krb5_error_code KRB5_CALLCONV
-krb5_c_random_os_entropy
-(krb5_context context, int strong, int *success);
+krb5_error_code KRB5_CALLCONV
+krb5_c_random_os_entropy
+(krb5_context context, int strong, int *success);
#endif
/*deprecated*/ krb5_error_code KRB5_CALLCONV
@@ -574,14 +587,13 @@ krb5_error_code KRB5_CALLCONV
(krb5_context context, krb5_enctype enctype,
const krb5_data *string, const krb5_data *salt,
krb5_keyblock *key);
-
-krb5_error_code KRB5_CALLCONV
+krb5_error_code KRB5_CALLCONV
krb5_c_string_to_key_with_params(krb5_context context,
- krb5_enctype enctype,
- const krb5_data *string,
- const krb5_data *salt,
- const krb5_data *params,
- krb5_keyblock *key);
+ krb5_enctype enctype,
+ const krb5_data *string,
+ const krb5_data *salt,
+ const krb5_data *params,
+ krb5_keyblock *key);
krb5_error_code KRB5_CALLCONV
krb5_c_enctype_compare
@@ -593,15 +605,15 @@ krb5_error_code KRB5_CALLCONV
(krb5_context context, krb5_cksumtype cksumtype,
const krb5_keyblock *key, krb5_keyusage usage,
const krb5_data *input, krb5_checksum *cksum);
-
+
krb5_error_code KRB5_CALLCONV
krb5_c_verify_checksum
- (krb5_context context,
+ (krb5_context context,
const krb5_keyblock *key, krb5_keyusage usage,
const krb5_data *data,
const krb5_checksum *cksum,
krb5_boolean *valid);
-
+
krb5_error_code KRB5_CALLCONV
krb5_c_checksum_length
(krb5_context context, krb5_cksumtype cksumtype,
@@ -609,7 +621,7 @@ krb5_error_code KRB5_CALLCONV
krb5_error_code KRB5_CALLCONV
krb5_c_keyed_checksum_types
- (krb5_context context, krb5_enctype enctype,
+ (krb5_context context, krb5_enctype enctype,
unsigned int *count, krb5_cksumtype **cksumtypes);
#define KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS 1
@@ -650,48 +662,113 @@ krb5_error_code KRB5_CALLCONV
#define KRB5_KEYUSAGE_PA_REFERRAL 26 /* XXX note conflict with above */
krb5_boolean KRB5_CALLCONV krb5_c_valid_enctype
- (krb5_enctype ktype);
+ (krb5_enctype ktype);
krb5_boolean KRB5_CALLCONV krb5_c_valid_cksumtype
- (krb5_cksumtype ctype);
+ (krb5_cksumtype ctype);
krb5_boolean KRB5_CALLCONV krb5_c_is_coll_proof_cksum
- (krb5_cksumtype ctype);
+ (krb5_cksumtype ctype);
krb5_boolean KRB5_CALLCONV krb5_c_is_keyed_cksum
- (krb5_cksumtype ctype);
-
+ (krb5_cksumtype ctype);
#if KRB5_PRIVATE
/* Use the above four instead. */
krb5_boolean KRB5_CALLCONV valid_enctype
- (krb5_enctype ktype);
+ (krb5_enctype ktype);
krb5_boolean KRB5_CALLCONV valid_cksumtype
- (krb5_cksumtype ctype);
+ (krb5_cksumtype ctype);
krb5_boolean KRB5_CALLCONV is_coll_proof_cksum
- (krb5_cksumtype ctype);
+ (krb5_cksumtype ctype);
krb5_boolean KRB5_CALLCONV is_keyed_cksum
- (krb5_cksumtype ctype);
+ (krb5_cksumtype ctype);
#endif
-
#ifdef KRB5_OLD_CRYPTO
/*
* old cryptosystem routine prototypes. These are now layered
* on top of the functions above.
*/
-krb5_error_code KRB5_CALLCONV krb5_use_enctype
- (krb5_context context,
- krb5_encrypt_block * eblock,
- krb5_enctype enctype);
-
+krb5_error_code KRB5_CALLCONV krb5_encrypt
+ (krb5_context context,
+ krb5_const_pointer inptr,
+ krb5_pointer outptr,
+ size_t size,
+ krb5_encrypt_block * eblock,
+ krb5_pointer ivec);
+krb5_error_code KRB5_CALLCONV krb5_decrypt
+ (krb5_context context,
+ krb5_const_pointer inptr,
+ krb5_pointer outptr,
+ size_t size,
+ krb5_encrypt_block * eblock,
+ krb5_pointer ivec);
+krb5_error_code KRB5_CALLCONV krb5_process_key
+ (krb5_context context,
+ krb5_encrypt_block * eblock,
+ const krb5_keyblock * key);
+krb5_error_code KRB5_CALLCONV krb5_finish_key
+ (krb5_context context,
+ krb5_encrypt_block * eblock);
krb5_error_code KRB5_CALLCONV krb5_string_to_key
- (krb5_context context,
- const krb5_encrypt_block * eblock,
- krb5_keyblock * keyblock,
- const krb5_data * data,
- const krb5_data * salt);
-
+ (krb5_context context,
+ const krb5_encrypt_block * eblock,
+ krb5_keyblock * keyblock,
+ const krb5_data * data,
+ const krb5_data * salt);
+krb5_error_code KRB5_CALLCONV krb5_init_random_key
+ (krb5_context context,
+ const krb5_encrypt_block * eblock,
+ const krb5_keyblock * keyblock,
+ krb5_pointer * ptr);
+krb5_error_code KRB5_CALLCONV krb5_finish_random_key
+ (krb5_context context,
+ const krb5_encrypt_block * eblock,
+ krb5_pointer * ptr);
+krb5_error_code KRB5_CALLCONV krb5_random_key
+ (krb5_context context,
+ const krb5_encrypt_block * eblock,
+ krb5_pointer ptr,
+ krb5_keyblock ** keyblock);
+krb5_enctype KRB5_CALLCONV krb5_eblock_enctype
+ (krb5_context context,
+ const krb5_encrypt_block * eblock);
+krb5_error_code KRB5_CALLCONV krb5_use_enctype
+ (krb5_context context,
+ krb5_encrypt_block * eblock,
+ krb5_enctype enctype);
+size_t KRB5_CALLCONV krb5_encrypt_size
+ (size_t length,
+ krb5_enctype crypto);
size_t KRB5_CALLCONV krb5_checksum_size
(krb5_context context,
krb5_cksumtype ctype);
+krb5_error_code KRB5_CALLCONV krb5_calculate_checksum
+ (krb5_context context,
+ krb5_cksumtype ctype,
+ krb5_const_pointer in, size_t in_length,
+ krb5_const_pointer seed, size_t seed_length,
+ krb5_checksum * outcksum);
+krb5_error_code KRB5_CALLCONV krb5_verify_checksum
+ (krb5_context context,
+ krb5_cksumtype ctype,
+ const krb5_checksum * cksum,
+ krb5_const_pointer in, size_t in_length,
+ krb5_const_pointer seed, size_t seed_length);
+
+#if KRB5_PRIVATE
+krb5_error_code KRB5_CALLCONV krb5_random_confounder
+ (size_t, krb5_pointer);
+
+krb5_error_code krb5_encrypt_data
+ (krb5_context context, krb5_keyblock *key,
+ krb5_pointer ivec, krb5_data *data,
+ krb5_enc_data *enc_data);
+
+krb5_error_code krb5_decrypt_data
+ (krb5_context context, krb5_keyblock *key,
+ krb5_pointer ivec, krb5_enc_data *data,
+ krb5_data *enc_data);
+#endif
+
#endif /* KRB5_OLD_CRYPTO */
/*
@@ -731,7 +808,7 @@ size_t KRB5_CALLCONV krb5_checksum_size
/* #define KDC_OPT_RESERVED 0x00000100 */
/* #define KDC_OPT_RESERVED 0x00000080 */
/* #define KDC_OPT_RESERVED 0x00000040 */
-#define KDC_OPT_DISABLE_TRANSITED_CHECK 0x00000020
+#define KDC_OPT_DISABLE_TRANSITED_CHECK 0x00000020
#define KDC_OPT_RENEWABLE_OK 0x00000010
#define KDC_OPT_ENC_TKT_IN_SKEY 0x00000008
/* #define KDC_OPT_UNUSED 0x00000004 */
@@ -741,9 +818,9 @@ size_t KRB5_CALLCONV krb5_checksum_size
/*
* Mask of ticket flags in the TGT which should be converted into KDC
* options when using the TGT to get derivitive tickets.
- *
+ *
* New mask = KDC_OPT_FORWARDABLE | KDC_OPT_PROXIABLE |
- * KDC_OPT_ALLOW_POSTDATE | KDC_OPT_RENEWABLE
+ * KDC_OPT_ALLOW_POSTDATE | KDC_OPT_RENEWABLE
*/
#define KDC_TKT_COMMON_MASK 0x54800000
@@ -781,7 +858,7 @@ size_t KRB5_CALLCONV krb5_checksum_size
/* #define AP_OPTS_RESERVED 0x00000008 */
/* #define AP_OPTS_RESERVED 0x00000004 */
/* #define AP_OPTS_RESERVED 0x00000002 */
-#define AP_OPTS_USE_SUBKEY 0x00000001
+#define AP_OPTS_USE_SUBKEY 0x00000001
#define AP_OPTS_WIRE_MASK 0xfffffff0
@@ -869,32 +946,31 @@ size_t KRB5_CALLCONV krb5_checksum_size
#define KRB5_ERROR ((krb5_msgtype)30) /* Error response */
/* LastReq types */
-#define KRB5_LRQ_NONE 0
-#define KRB5_LRQ_ALL_LAST_TGT 1
-#define KRB5_LRQ_ONE_LAST_TGT (-1)
-#define KRB5_LRQ_ALL_LAST_INITIAL 2
-#define KRB5_LRQ_ONE_LAST_INITIAL (-2)
-#define KRB5_LRQ_ALL_LAST_TGT_ISSUED 3
-#define KRB5_LRQ_ONE_LAST_TGT_ISSUED (-3)
-#define KRB5_LRQ_ALL_LAST_RENEWAL 4
-#define KRB5_LRQ_ONE_LAST_RENEWAL (-4)
-#define KRB5_LRQ_ALL_LAST_REQ 5
-#define KRB5_LRQ_ONE_LAST_REQ (-5)
-#define KRB5_LRQ_ALL_PW_EXPTIME 6
-#define KRB5_LRQ_ONE_PW_EXPTIME (-6)
-
+#define KRB5_LRQ_NONE 0
+#define KRB5_LRQ_ALL_LAST_TGT 1
+#define KRB5_LRQ_ONE_LAST_TGT (-1)
+#define KRB5_LRQ_ALL_LAST_INITIAL 2
+#define KRB5_LRQ_ONE_LAST_INITIAL (-2)
+#define KRB5_LRQ_ALL_LAST_TGT_ISSUED 3
+#define KRB5_LRQ_ONE_LAST_TGT_ISSUED (-3)
+#define KRB5_LRQ_ALL_LAST_RENEWAL 4
+#define KRB5_LRQ_ONE_LAST_RENEWAL (-4)
+#define KRB5_LRQ_ALL_LAST_REQ 5
+#define KRB5_LRQ_ONE_LAST_REQ (-5)
+#define KRB5_LRQ_ALL_PW_EXPTIME 6
+#define KRB5_LRQ_ONE_PW_EXPTIME (-6)
/* PADATA types */
-#define KRB5_PADATA_NONE 0
+#define KRB5_PADATA_NONE 0
#define KRB5_PADATA_AP_REQ 1
#define KRB5_PADATA_TGS_REQ KRB5_PADATA_AP_REQ
#define KRB5_PADATA_ENC_TIMESTAMP 2
#define KRB5_PADATA_PW_SALT 3
#if 0 /* Not used */
-#define KRB5_PADATA_ENC_ENCKEY 4 /* Key encrypted within itself */
+#define KRB5_PADATA_ENC_ENCKEY 4 /* Key encrypted within itself */
#endif
-#define KRB5_PADATA_ENC_UNIX_TIME 5 /* timestamp encrypted in key */
-#define KRB5_PADATA_ENC_SANDIA_SECURID 6 /* SecurId passcode */
+#define KRB5_PADATA_ENC_UNIX_TIME 5 /* timestamp encrypted in key */
+#define KRB5_PADATA_ENC_SANDIA_SECURID 6 /* SecurId passcode */
#define KRB5_PADATA_SESAME 7 /* Sesame project */
#define KRB5_PADATA_OSF_DCE 8 /* OSF DCE */
#define KRB5_CYBERSAFE_SECUREID 9 /* Cybersafe */
@@ -902,13 +978,15 @@ size_t KRB5_CALLCONV krb5_checksum_size
#define KRB5_PADATA_ETYPE_INFO 11 /* Etype info for preauth */
#define KRB5_PADATA_SAM_CHALLENGE 12 /* draft challenge system */
#define KRB5_PADATA_SAM_RESPONSE 13 /* draft challenge system response */
-#define KRB5_PADATA_PK_AS_REQ 14 /* PKINIT */
-#define KRB5_PADATA_PK_AS_REP 15 /* PKINIT */
+#define KRB5_PADATA_PK_AS_REQ_OLD 14 /* PKINIT */
+#define KRB5_PADATA_PK_AS_REP_OLD 15 /* PKINIT */
+#define KRB5_PADATA_PK_AS_REQ 16 /* PKINIT */
+#define KRB5_PADATA_PK_AS_REP 17 /* PKINIT */
#define KRB5_PADATA_ETYPE_INFO2 19
#define KRB5_PADATA_REFERRAL 25 /* draft referral system */
#define KRB5_PADATA_SAM_CHALLENGE_2 30 /* draft challenge system, updated */
#define KRB5_PADATA_SAM_RESPONSE_2 31 /* draft challenge system, updated */
-
+
#define KRB5_SAM_USE_SAD_AS_KEY 0x80000000
#define KRB5_SAM_SEND_ENCRYPTED_SAD 0x40000000
#define KRB5_SAM_MUST_PK_ENCRYPT_SAD 0x20000000 /* currently must be zero */
@@ -923,6 +1001,11 @@ size_t KRB5_CALLCONV krb5_checksum_size
#define KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE 64
/* authorization data types */
+#define KRB5_AUTHDATA_IF_RELEVANT 1
+#define KRB5_AUTHDATA_KDC_ISSUED 4
+#define KRB5_AUTHDATA_AND_OR 5
+#define KRB5_AUTHDATA_MANDATORY_FOR_KDC 8
+#define KRB5_AUTHDATA_INITIAL_VERIFIED_CAS 9
#define KRB5_AUTHDATA_OSF_DCE 64
#define KRB5_AUTHDATA_SESAME 65
@@ -935,9 +1018,9 @@ size_t KRB5_CALLCONV krb5_checksum_size
#define KRB5_KPASSWD_SOFTERROR 4
/* These are Microsoft's extensions in RFC 3244, and it looks like
they'll become standardized, possibly with other additions. */
-#define KRB5_KPASSWD_ACCESSDENIED 5 /* unused */
-#define KRB5_KPASSWD_BAD_VERSION 6
-#define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7 /* unused */
+#define KRB5_KPASSWD_ACCESSDENIED 5 /* unused */
+#define KRB5_KPASSWD_BAD_VERSION 6
+#define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7 /* unused */
/*
* end "proto.h"
@@ -946,7 +1029,7 @@ size_t KRB5_CALLCONV krb5_checksum_size
/* Time set */
typedef struct _krb5_ticket_times {
krb5_timestamp authtime; /* XXX ? should ktime in KDC_REP == authtime
- in ticket? otherwise client can't get this */
+ in ticket? otherwise client can't get this */
krb5_timestamp starttime; /* optional in ticket, if not present,
use authtime */
krb5_timestamp endtime;
@@ -976,8 +1059,8 @@ typedef struct _krb5_enc_tkt_part {
krb5_principal client; /* client name/realm */
krb5_transited transited; /* list of transited realms */
krb5_ticket_times times; /* auth, start, end, renew_till */
- krb5_address * *caddrs; /* array of ptrs to addresses */
- krb5_authdata * *authorization_data; /* auth data */
+ krb5_address **caddrs; /* array of ptrs to addresses */
+ krb5_authdata **authorization_data; /* auth data */
} krb5_enc_tkt_part;
typedef struct _krb5_ticket {
@@ -999,7 +1082,7 @@ typedef struct _krb5_authenticator {
krb5_timestamp ctime; /* client sec portion */
krb5_keyblock *subkey; /* true session key, optional */
krb5_ui_4 seq_number; /* sequence #, optional */
- krb5_authdata * *authorization_data; /* New add by Ari, auth data */
+ krb5_authdata **authorization_data; /* New add by Ari, auth data */
} krb5_authenticator;
typedef struct _krb5_tkt_authent {
@@ -1009,7 +1092,7 @@ typedef struct _krb5_tkt_authent {
krb5_flags ap_options;
} krb5_tkt_authent;
-/* credentials: Ticket, session key, etc. */
+/* credentials: Ticket, session key, etc. */
typedef struct _krb5_creds {
krb5_magic magic;
krb5_principal client; /* client's principal identifier */
@@ -1024,7 +1107,7 @@ typedef struct _krb5_creds {
krb5_data second_ticket; /* second ticket, if related to
ticket (via DUPLICATE-SKEY or
ENC-TKT-IN-SKEY) */
- krb5_authdata * *authdata; /* authorization data */
+ krb5_authdata **authdata; /* authorization data */
} krb5_creds;
/* Last request fields */
@@ -1045,7 +1128,7 @@ typedef struct _krb5_pa_data {
typedef struct _krb5_kdc_req {
krb5_magic magic;
krb5_msgtype msg_type; /* AS_REQ or TGS_REQ? */
- krb5_pa_data * *padata; /* e.g. encoded AP_REQ */
+ krb5_pa_data **padata; /* e.g. encoded AP_REQ */
/* real body */
krb5_flags kdc_options; /* requested options */
krb5_principal client; /* includes realm; optional */
@@ -1057,11 +1140,11 @@ typedef struct _krb5_kdc_req {
krb5_int32 nonce; /* nonce to match request/response */
int nktypes; /* # of ktypes, must be positive */
krb5_enctype *ktype; /* requested enctype(s) */
- krb5_address * *addresses; /* requested addresses, optional */
+ krb5_address **addresses; /* requested addresses, optional */
krb5_enc_data authorization_data; /* encrypted auth data; OPTIONAL */
- krb5_authdata * *unenc_authdata; /* unencrypted auth data,
+ krb5_authdata **unenc_authdata; /* unencrypted auth data,
if available */
- krb5_ticket * *second_ticket;/* second ticket array; OPTIONAL */
+ krb5_ticket **second_ticket;/* second ticket array; OPTIONAL */
} krb5_kdc_req;
typedef struct _krb5_enc_kdc_rep_part {
@@ -1069,13 +1152,13 @@ typedef struct _krb5_enc_kdc_rep_part {
/* encrypted part: */
krb5_msgtype msg_type; /* krb5 message type */
krb5_keyblock *session; /* session key */
- krb5_last_req_entry * *last_req; /* array of ptrs to entries */
+ krb5_last_req_entry **last_req; /* array of ptrs to entries */
krb5_int32 nonce; /* nonce from request */
krb5_timestamp key_exp; /* expiration date */
krb5_flags flags; /* ticket flags */
krb5_ticket_times times; /* lifetime info */
krb5_principal server; /* server's principal identifier */
- krb5_address * *caddrs; /* array of ptrs to addresses,
+ krb5_address **caddrs; /* array of ptrs to addresses,
optional */
} krb5_enc_kdc_rep_part;
@@ -1083,7 +1166,7 @@ typedef struct _krb5_kdc_rep {
krb5_magic magic;
/* cleartext part: */
krb5_msgtype msg_type; /* AS_REP or KDC_REP? */
- krb5_pa_data * *padata; /* preauthentication data from KDC */
+ krb5_pa_data **padata; /* preauthentication data from KDC */
krb5_principal client; /* client's principal identifier */
krb5_ticket *ticket; /* ticket */
krb5_enc_data enc_part; /* encryption type, kvno, encrypted
@@ -1137,31 +1220,31 @@ typedef struct _krb5_response {
typedef struct _krb5_cred_info {
krb5_magic magic;
- krb5_keyblock *session; /* session key used to encrypt */
+ krb5_keyblock *session; /* session key used to encrypt */
/* ticket */
- krb5_principal client; /* client name/realm, optional */
- krb5_principal server; /* server name/realm, optional */
+ krb5_principal client; /* client name/realm, optional */
+ krb5_principal server; /* server name/realm, optional */
krb5_flags flags; /* ticket flags, optional */
krb5_ticket_times times; /* auth, start, end, renew_till, */
- /* optional */
- krb5_address * *caddrs; /* array of ptrs to addresses */
+ /* optional */
+ krb5_address **caddrs; /* array of ptrs to addresses */
} krb5_cred_info;
typedef struct _krb5_cred_enc_part {
krb5_magic magic;
- krb5_int32 nonce; /* nonce, optional */
- krb5_timestamp timestamp; /* client time */
- krb5_int32 usec; /* microsecond portion of time */
- krb5_address *s_address; /* sender address, optional */
- krb5_address *r_address; /* recipient address, optional */
- krb5_cred_info * *ticket_info;
-} krb5_cred_enc_part;
+ krb5_int32 nonce; /* nonce, optional */
+ krb5_timestamp timestamp; /* client time */
+ krb5_int32 usec; /* microsecond portion of time */
+ krb5_address *s_address; /* sender address, optional */
+ krb5_address *r_address; /* recipient address, optional */
+ krb5_cred_info **ticket_info;
+} krb5_cred_enc_part;
typedef struct _krb5_cred {
krb5_magic magic;
- krb5_ticket * *tickets; /* tickets */
+ krb5_ticket **tickets; /* tickets */
krb5_enc_data enc_part; /* encrypted part */
- krb5_cred_enc_part *enc_part2; /* unencrypted version, if available*/
+ krb5_cred_enc_part *enc_part2; /* unencrypted version, if available*/
} krb5_cred;
/* Sandia password generation structures */
@@ -1174,7 +1257,7 @@ typedef struct _passwd_phrase_element {
typedef struct _krb5_pwd_data {
krb5_magic magic;
int sequence_count;
- passwd_phrase_element * *element;
+ passwd_phrase_element **element;
} krb5_pwd_data;
/* these need to be here so the typedefs are available for the prototypes */
@@ -1183,35 +1266,31 @@ typedef struct _krb5_pwd_data {
* begin "safepriv.h"
*/
-#define KRB5_AUTH_CONTEXT_DO_TIME 0x00000001
-#define KRB5_AUTH_CONTEXT_RET_TIME 0x00000002
-#define KRB5_AUTH_CONTEXT_DO_SEQUENCE 0x00000004
-#define KRB5_AUTH_CONTEXT_RET_SEQUENCE 0x00000008
+#define KRB5_AUTH_CONTEXT_DO_TIME 0x00000001
+#define KRB5_AUTH_CONTEXT_RET_TIME 0x00000002
+#define KRB5_AUTH_CONTEXT_DO_SEQUENCE 0x00000004
+#define KRB5_AUTH_CONTEXT_RET_SEQUENCE 0x00000008
#define KRB5_AUTH_CONTEXT_PERMIT_ALL 0x00000010
-#define KRB5_AUTH_CONTEXT_USE_SUBKEY 0x00000020
-
-typedef struct krb5_replay_data {
- krb5_timestamp timestamp;
- krb5_int32 usec;
- krb5_int32 seq;
+#define KRB5_AUTH_CONTEXT_USE_SUBKEY 0x00000020
+
+typedef struct krb5_replay_data {
+ krb5_timestamp timestamp;
+ krb5_int32 usec;
+ krb5_int32 seq;
} krb5_replay_data;
/* flags for krb5_auth_con_genaddrs() */
-#define KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR 0x00000001
-#define KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR 0x00000002
-#define KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR 0x00000004
-#define KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR 0x00000008
+#define KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR 0x00000001
+#define KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR 0x00000002
+#define KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR 0x00000004
+#define KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR 0x00000008
/* type of function used as a callback to generate checksum data for
* mk_req */
-typedef krb5_error_code
-(KRB5_CALLCONV * krb5_mk_req_checksum_func) (
- krb5_context,
- krb5_auth_context,
- void *,
- krb5_data **);
-
+typedef krb5_error_code
+(KRB5_CALLCONV * krb5_mk_req_checksum_func) (krb5_context, krb5_auth_context , void *,
+ krb5_data **);
/*
* end "safepriv.h"
@@ -1246,51 +1325,54 @@ typedef struct _krb5_cc_ops krb5_cc_ops;
#define KRB5_TC_NOTICKET 0x00000002
+krb5_error_code KRB5_CALLCONV
+krb5_cc_gen_new (krb5_context context, krb5_ccache *cache);
-krb5_error_code KRB5_CALLCONV
-krb5_cc_gen_new (krb5_context context, krb5_ccache *cache);
-
-krb5_error_code KRB5_CALLCONV
-krb5_cc_initialize(krb5_context context, krb5_ccache cache,
- krb5_principal principal);
+krb5_error_code KRB5_CALLCONV
+krb5_cc_initialize(krb5_context context, krb5_ccache cache,
+ krb5_principal principal);
-krb5_error_code KRB5_CALLCONV
-krb5_cc_destroy (krb5_context context, krb5_ccache cache);
+krb5_error_code KRB5_CALLCONV
+krb5_cc_destroy (krb5_context context, krb5_ccache cache);
-krb5_error_code KRB5_CALLCONV
-krb5_cc_close (krb5_context context, krb5_ccache cache);
+krb5_error_code KRB5_CALLCONV
+krb5_cc_close (krb5_context context, krb5_ccache cache);
-krb5_error_code KRB5_CALLCONV
-krb5_cc_store_cred (krb5_context context, krb5_ccache cache,
+krb5_error_code KRB5_CALLCONV
+krb5_cc_store_cred (krb5_context context, krb5_ccache cache,
krb5_creds *creds);
-krb5_error_code KRB5_CALLCONV
-krb5_cc_retrieve_cred (krb5_context context, krb5_ccache cache,
- krb5_flags flags, krb5_creds *mcreds,
- krb5_creds *creds);
+krb5_error_code KRB5_CALLCONV
+krb5_cc_retrieve_cred (krb5_context context, krb5_ccache cache,
+ krb5_flags flags, krb5_creds *mcreds,
+ krb5_creds *creds);
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_get_principal (krb5_context context, krb5_ccache cache,
+ krb5_principal *principal);
-krb5_error_code KRB5_CALLCONV
-krb5_cc_get_principal (krb5_context context, krb5_ccache cache,
- krb5_principal *principal);
krb5_error_code KRB5_CALLCONV
krb5_cc_start_seq_get (krb5_context context, krb5_ccache cache,
- krb5_cc_cursor *cursor);
+ krb5_cc_cursor *cursor);
-krb5_error_code KRB5_CALLCONV
-krb5_cc_next_cred (krb5_context context, krb5_ccache cache,
- krb5_cc_cursor *cursor, krb5_creds *creds);
+krb5_error_code KRB5_CALLCONV
+krb5_cc_next_cred (krb5_context context, krb5_ccache cache,
+ krb5_cc_cursor *cursor, krb5_creds *creds);
-krb5_error_code KRB5_CALLCONV
-krb5_cc_end_seq_get (krb5_context context, krb5_ccache cache,
- krb5_cc_cursor *cursor);
+krb5_error_code KRB5_CALLCONV
+krb5_cc_end_seq_get (krb5_context context, krb5_ccache cache,
+ krb5_cc_cursor *cursor);
krb5_error_code KRB5_CALLCONV
krb5_cc_remove_cred (krb5_context context, krb5_ccache cache, krb5_flags flags,
- krb5_creds *creds);
+ krb5_creds *creds);
krb5_error_code KRB5_CALLCONV
krb5_cc_set_flags (krb5_context context, krb5_ccache cache, krb5_flags flags);
+krb5_error_code KRB5_CALLCONV
+krb5_cc_get_flags (krb5_context context, krb5_ccache cache, krb5_flags *flags);
+
const char * KRB5_CALLCONV
krb5_cc_get_type (krb5_context context, krb5_ccache cache);
@@ -1298,6 +1380,13 @@ krb5_cc_get_type (krb5_context context, krb5_ccache cache);
const char * KRB5_CALLCONV
krb5_cc_get_name (krb5_context context, krb5_ccache cache);
+krb5_error_code KRB5_CALLCONV
+krb5_cc_new_unique(
+ krb5_context context,
+ const char *type,
+ const char *hint,
+ krb5_ccache *id);
+
/*
* end "ccache.h"
*/
@@ -1326,43 +1415,43 @@ typedef krb5_pointer krb5_kt_cursor; /* XXX */
typedef struct krb5_keytab_entry_st {
krb5_magic magic;
krb5_principal principal; /* principal of this key */
- krb5_timestamp timestamp; /* time entry written to keytable */
+ krb5_timestamp timestamp; /* time entry written to keytable */
krb5_kvno vno; /* key version number */
krb5_keyblock key; /* the secret key */
} krb5_keytab_entry;
#if KRB5_PRIVATE
-struct _krb5_kt_ops;
-typedef struct _krb5_kt { /* should move into k5-int.h */
+struct _krb5_kt_ops;
+typedef struct _krb5_kt { /* should move into k5-int.h */
krb5_magic magic;
- const struct _krb5_kt_ops *ops;
+ const struct _krb5_kt_ops *ops;
krb5_pointer data;
-} *krb5_keytab;
+} *krb5_keytab;
#else
-struct _krb5_kt;
-typedef struct _krb5_kt *krb5_keytab;
+struct _krb5_kt;
+typedef struct _krb5_kt *krb5_keytab;
#endif
char * KRB5_CALLCONV
krb5_kt_get_type (krb5_context, krb5_keytab keytab);
krb5_error_code KRB5_CALLCONV
krb5_kt_get_name(krb5_context context, krb5_keytab keytab, char *name,
- unsigned int namelen);
+ unsigned int namelen);
krb5_error_code KRB5_CALLCONV
krb5_kt_close(krb5_context context, krb5_keytab 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);
+ krb5_const_principal principal, krb5_kvno vno,
+ krb5_enctype enctype, krb5_keytab_entry *entry);
krb5_error_code KRB5_CALLCONV
krb5_kt_start_seq_get(krb5_context context, krb5_keytab keytab,
- krb5_kt_cursor *cursor);
+ krb5_kt_cursor *cursor);
krb5_error_code KRB5_CALLCONV
krb5_kt_next_entry(krb5_context context, krb5_keytab keytab,
- krb5_keytab_entry *entry, krb5_kt_cursor *cursor);
+ krb5_keytab_entry *entry, krb5_kt_cursor *cursor);
krb5_error_code KRB5_CALLCONV
krb5_kt_end_seq_get(krb5_context context, krb5_keytab keytab,
- krb5_kt_cursor *cursor);
+ krb5_kt_cursor *cursor);
/*
* end "keytab.h"
@@ -2311,7 +2400,6 @@ krb5_error_code KRB5_CALLCONV krb5_auth_con_getauthenticator
* begin stuff from libos.h
*/
-
#if KRB5_PRIVATE
krb5_error_code krb5_read_message (krb5_context, krb5_pointer, krb5_data *);
krb5_error_code krb5_write_message (krb5_context, krb5_pointer, krb5_data *);
@@ -2443,7 +2531,6 @@ krb5_error_code KRB5_CALLCONV krb5_deltat_to_string
/* flags for recvauth */
#define KRB5_RECVAUTH_SKIP_VERSION 0x0001
#define KRB5_RECVAUTH_BADAUTHVERS 0x0002
-
/* initial ticket api functions */
typedef struct _krb5_prompt {
@@ -2461,8 +2548,7 @@ typedef krb5_error_code (KRB5_CALLCONV *krb5_prompter_fct)(krb5_context context,
krb5_error_code KRB5_CALLCONV
-krb5_prompter_posix
- (krb5_context context,
+krb5_prompter_posix (krb5_context context,
void *data,
const char *name,
const char *banner,
@@ -2491,6 +2577,17 @@ typedef struct _krb5_get_init_creds_opt {
#define KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST 0x0020
#define KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST 0x0040
#define KRB5_GET_INIT_CREDS_OPT_SALT 0x0080
+#define KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT 0x0100
+
+krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_opt_alloc
+(krb5_context context,
+ krb5_get_init_creds_opt **opt);
+
+void KRB5_CALLCONV
+krb5_get_init_creds_opt_free
+(krb5_context context,
+ krb5_get_init_creds_opt *opt);
void KRB5_CALLCONV
krb5_get_init_creds_opt_init
@@ -2538,7 +2635,31 @@ krb5_get_init_creds_opt_set_salt
(krb5_get_init_creds_opt *opt,
krb5_data *salt);
+void KRB5_CALLCONV
+krb5_get_init_creds_opt_set_change_password_prompt
+(krb5_get_init_creds_opt *opt,
+ int prompt);
+/* Generic preauth option attribute/value pairs */
+typedef struct _krb5_gic_opt_pa_data {
+ char *attr;
+ char *value;
+} krb5_gic_opt_pa_data;
+
+/*
+ * This function allows the caller to supply options to preauth
+ * plugins. Preauth plugin modules are given a chance to look
+ * at each option at the time this function is called in ordre
+ * to check the validity of the option.
+ * The 'opt' pointer supplied to this function must have been
+ * obtained using krb5_get_init_creds_opt_alloc()
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_opt_set_pa
+ (krb5_context context,
+ krb5_get_init_creds_opt *opt,
+ const char *attr,
+ const char *value);
krb5_error_code KRB5_CALLCONV
krb5_get_init_creds_password
@@ -2663,10 +2784,10 @@ void KRB5_CALLCONV krb5_free_realm_string
* Prompter enhancements
*/
-#define KRB5_PROMPT_TYPE_PASSWORD 0x1
-#define KRB5_PROMPT_TYPE_NEW_PASSWORD 0x2
-#define KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN 0x3
-#define KRB5_PROMPT_TYPE_PREAUTH 0x4
+#define KRB5_PROMPT_TYPE_PASSWORD 0x1
+#define KRB5_PROMPT_TYPE_NEW_PASSWORD 0x2
+#define KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN 0x3
+#define KRB5_PROMPT_TYPE_PREAUTH 0x4
typedef krb5_int32 krb5_prompt_type;
@@ -2697,9 +2818,12 @@ krb5_free_error_message (krb5_context, const char *);
void KRB5_CALLCONV
krb5_clear_error_message (krb5_context);
-#if TARGET_OS_MAC
-# pragma options align=reset
-#endif /* KRB5INT_END_DECLS */
+
+#if TARGET_OS_MAC
+# pragma pack(pop)
+#endif
+
+KRB5INT_END_DECLS
/* Don't use this! We're going to phase it out. It's just here to keep
applications from breaking right away. */
@@ -2742,7 +2866,7 @@ krb5_clear_error_message (krb5_context);
#define KRB5KDC_ERR_SERVER_NOMATCH (-1765328358L)
#define KRB5PLACEHOLD_27 (-1765328357L)
#define KRB5PLACEHOLD_28 (-1765328356L)
-#define KRB5PLACEHOLD_29 (-1765328355L)
+#define KRB5KDC_ERR_SVC_UNAVAILABLE (-1765328355L)
#define KRB5PLACEHOLD_30 (-1765328354L)
#define KRB5KRB_AP_ERR_BAD_INTEGRITY (-1765328353L)
#define KRB5KRB_AP_ERR_TKT_EXPIRED (-1765328352L)
@@ -2764,8 +2888,8 @@ krb5_clear_error_message (krb5_context);
#define KRB5KRB_AP_ERR_METHOD (-1765328336L)
#define KRB5KRB_AP_ERR_BADSEQ (-1765328335L)
#define KRB5KRB_AP_ERR_INAPP_CKSUM (-1765328334L)
-#define KRB5PLACEHOLD_51 (-1765328333L)
-#define KRB5PLACEHOLD_52 (-1765328332L)
+#define KRB5KRB_AP_PATH_NOT_ACCEPTED (-1765328333L)
+#define KRB5KRB_ERR_RESPONSE_TOO_BIG (-1765328332L)
#define KRB5PLACEHOLD_53 (-1765328331L)
#define KRB5PLACEHOLD_54 (-1765328330L)
#define KRB5PLACEHOLD_55 (-1765328329L)
@@ -2775,26 +2899,26 @@ krb5_clear_error_message (krb5_context);
#define KRB5PLACEHOLD_59 (-1765328325L)
#define KRB5KRB_ERR_GENERIC (-1765328324L)
#define KRB5KRB_ERR_FIELD_TOOLONG (-1765328323L)
-#define KRB5PLACEHOLD_62 (-1765328322L)
-#define KRB5PLACEHOLD_63 (-1765328321L)
-#define KRB5PLACEHOLD_64 (-1765328320L)
-#define KRB5PLACEHOLD_65 (-1765328319L)
-#define KRB5PLACEHOLD_66 (-1765328318L)
+#define KRB5KDC_ERR_CLIENT_NOT_TRUSTED (-1765328322L)
+#define KRB5KDC_ERR_KDC_NOT_TRUSTED (-1765328321L)
+#define KRB5KDC_ERR_INVALID_SIG (-1765328320L)
+#define KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED (-1765328319L)
+#define KRB5KDC_ERR_CERTIFICATE_MISMATCH (-1765328318L)
#define KRB5PLACEHOLD_67 (-1765328317L)
#define KRB5PLACEHOLD_68 (-1765328316L)
#define KRB5PLACEHOLD_69 (-1765328315L)
-#define KRB5PLACEHOLD_70 (-1765328314L)
-#define KRB5PLACEHOLD_71 (-1765328313L)
-#define KRB5PLACEHOLD_72 (-1765328312L)
-#define KRB5PLACEHOLD_73 (-1765328311L)
-#define KRB5PLACEHOLD_74 (-1765328310L)
-#define KRB5PLACEHOLD_75 (-1765328309L)
-#define KRB5PLACEHOLD_76 (-1765328308L)
-#define KRB5PLACEHOLD_77 (-1765328307L)
-#define KRB5PLACEHOLD_78 (-1765328306L)
-#define KRB5PLACEHOLD_79 (-1765328305L)
-#define KRB5PLACEHOLD_80 (-1765328304L)
-#define KRB5PLACEHOLD_81 (-1765328303L)
+#define KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE (-1765328314L)
+#define KRB5KDC_ERR_INVALID_CERTIFICATE (-1765328313L)
+#define KRB5KDC_ERR_REVOKED_CERTIFICATE (-1765328312L)
+#define KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN (-1765328311L)
+#define KRB5KDC_ERR_REVOCATION_STATUS_UNAVAILABLE (-1765328310L)
+#define KRB5KDC_ERR_CLIENT_NAME_MISMATCH (-1765328309L)
+#define KRB5KDC_ERR_KDC_NAME_MISMATCH (-1765328308L)
+#define KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE (-1765328307L)
+#define KRB5KDC_ERR_DIGEST_IN_CERT_NOT_ACCEPTED (-1765328306L)
+#define KRB5KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED (-1765328305L)
+#define KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED (-1765328304L)
+#define KRB5KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED (-1765328303L)
#define KRB5PLACEHOLD_82 (-1765328302L)
#define KRB5PLACEHOLD_83 (-1765328301L)
#define KRB5PLACEHOLD_84 (-1765328300L)
@@ -2939,28 +3063,28 @@ krb5_clear_error_message (krb5_context);
#define KRB5_GET_IN_TKT_LOOP (-1765328161L)
#define KRB5_CONFIG_NODEFREALM (-1765328160L)
#define KRB5_SAM_UNSUPPORTED (-1765328159L)
-#define KRB5_SAM_INVALID_ETYPE (-1765328158L)
-#define KRB5_SAM_NO_CHECKSUM (-1765328157L)
-#define KRB5_SAM_BAD_CHECKSUM (-1765328156L)
-#define KRB5_KT_NAME_TOOLONG (-1765328155L)
-#define KRB5_KT_KVNONOTFOUND (-1765328154L)
-#define KRB5_APPL_EXPIRED (-1765328153L)
-#define KRB5_LIB_EXPIRED (-1765328152L)
-#define KRB5_CHPW_PWDNULL (-1765328151L)
-#define KRB5_CHPW_FAIL (-1765328150L)
-#define KRB5_KT_FORMAT (-1765328149L)
-#define KRB5_NOPERM_ETYPE (-1765328148L)
-#define KRB5_CONFIG_ETYPE_NOSUPP (-1765328147L)
-#define KRB5_OBSOLETE_FN (-1765328146L)
-#define KRB5_EAI_FAIL (-1765328145L)
-#define KRB5_EAI_NODATA (-1765328144L)
-#define KRB5_EAI_NONAME (-1765328143L)
-#define KRB5_EAI_SERVICE (-1765328142L)
-#define KRB5_ERR_NUMERIC_REALM (-1765328141L)
-#define KRB5_ERR_BAD_S2K_PARAMS (-1765328140L)
-#define KRB5_ERR_NO_SERVICE (-1765328139L)
-#define KRB5_CC_READONLY (-1765328138L)
-#define KRB5_CC_NOSUPP (-1765328137L)
+#define KRB5_SAM_INVALID_ETYPE (-1765328158L)
+#define KRB5_SAM_NO_CHECKSUM (-1765328157L)
+#define KRB5_SAM_BAD_CHECKSUM (-1765328156L)
+#define KRB5_KT_NAME_TOOLONG (-1765328155L)
+#define KRB5_KT_KVNONOTFOUND (-1765328154L)
+#define KRB5_APPL_EXPIRED (-1765328153L)
+#define KRB5_LIB_EXPIRED (-1765328152L)
+#define KRB5_CHPW_PWDNULL (-1765328151L)
+#define KRB5_CHPW_FAIL (-1765328150L)
+#define KRB5_KT_FORMAT (-1765328149L)
+#define KRB5_NOPERM_ETYPE (-1765328148L)
+#define KRB5_CONFIG_ETYPE_NOSUPP (-1765328147L)
+#define KRB5_OBSOLETE_FN (-1765328146L)
+#define KRB5_EAI_FAIL (-1765328145L)
+#define KRB5_EAI_NODATA (-1765328144L)
+#define KRB5_EAI_NONAME (-1765328143L)
+#define KRB5_EAI_SERVICE (-1765328142L)
+#define KRB5_ERR_NUMERIC_REALM (-1765328141L)
+#define KRB5_ERR_BAD_S2K_PARAMS (-1765328140L)
+#define KRB5_ERR_NO_SERVICE (-1765328139L)
+#define KRB5_CC_READONLY (-1765328138L)
+#define KRB5_CC_NOSUPP (-1765328137L)
/* NOTE! error values should not collide */
/* XXX Note KRB5_RC_BADNAME and KRB5_CONF_NOT_CONFIGURED are Solaris specific */
@@ -3085,13 +3209,13 @@ krb5_clear_error_message (krb5_context);
#define KV5M_SAM_CHALLENGE (-1760647378L)
#define KV5M_SAM_KEY (-1760647377L)
#define KV5M_ENC_SAM_RESPONSE_ENC (-1760647376L)
-#define KV5M_ENC_SAM_RESPONSE_ENC_2 (-1760647374L)
-#define KV5M_SAM_RESPONSE (-1760647373L)
-#define KV5M_SAM_RESPONSE_2 (-1760647372L)
-#define KV5M_PREDICTED_SAM_RESPONSE (-1760647371L)
-#define KV5M_PASSWD_PHRASE_ELEMENT (-1760647370L)
-#define KV5M_GSS_OID (-1760647369L)
-#define KV5M_GSS_QUEUE (-1760647368L)
+#define KV5M_ENC_SAM_RESPONSE_ENC_2 (-1760647374L)
+#define KV5M_SAM_RESPONSE (-1760647373L)
+#define KV5M_SAM_RESPONSE_2 (-1760647372L)
+#define KV5M_PREDICTED_SAM_RESPONSE (-1760647371L)
+#define KV5M_PASSWD_PHRASE_ELEMENT (-1760647370L)
+#define KV5M_GSS_OID (-1760647369L)
+#define KV5M_GSS_QUEUE (-1760647368L)
#define ERROR_TABLE_BASE_kv5m (-1760647424L)
/* for compatibility with older versions... */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/old.h b/usr/src/uts/common/gssapi/mechs/krb5/include/old.h
index 33b3e4d590..ffbce89cfb 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/old.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/old.h
@@ -1,8 +1,7 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
@@ -30,35 +29,34 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
+#include "k5-int.h"
void krb5_old_encrypt_length
(const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
+ const struct krb5_hash_provider *hash,
size_t input, size_t *length);
krb5_error_code krb5_old_encrypt
(krb5_context context,
- krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
- krb5_const krb5_keyblock *key, krb5_keyusage usage,
- krb5_const krb5_data *ivec, krb5_const krb5_data *input,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
krb5_data *output);
krb5_error_code krb5_old_decrypt
(krb5_context context,
- krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
- krb5_const krb5_keyblock *key, krb5_keyusage usage,
- krb5_const krb5_data *ivec, krb5_const krb5_data *input,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
krb5_data *arg_output);
#ifndef _KERNEL
-krb5_error_code krb5_des_string_to_key
+krb5_error_code krb5int_des_string_to_key
(krb5_context context,
- krb5_const struct krb5_enc_provider *enc,
- krb5_const krb5_data *string,
- krb5_const krb5_data *salt,
- krb5_const krb5_data *params,
+ const struct krb5_enc_provider *enc,
+ const krb5_data *string, const krb5_data *salt,
+ const krb5_data *params,
krb5_keyblock *key);
#endif /* _KERNEL */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/raw.h b/usr/src/uts/common/gssapi/mechs/krb5/include/raw.h
index 9ddf242d53..e4c0e3c94d 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/raw.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/raw.h
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
@@ -28,22 +27,22 @@
#include "k5-int.h"
void krb5_raw_encrypt_length
-(krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
+(const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
size_t input, size_t *length);
krb5_error_code krb5_raw_encrypt
(krb5_context context,
- krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
- krb5_const krb5_keyblock *key, krb5_keyusage usage,
- krb5_const krb5_data *ivec, krb5_const krb5_data *input,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
krb5_data *output);
krb5_error_code krb5_raw_decrypt
(krb5_context context,
- krb5_const struct krb5_enc_provider *enc,
- krb5_const struct krb5_hash_provider *hash,
- krb5_const krb5_keyblock *key, krb5_keyusage usage,
- krb5_const krb5_data *ivec, krb5_const krb5_data *input,
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
krb5_data *arg_output);
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_auth.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_auth.c
index 68ae89f5b5..1225f53386 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_auth.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_auth.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/copy_auth.c
*
@@ -33,7 +32,7 @@
* krb5_copy_authdata()
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*ARGSUSED*/
static krb5_error_code
@@ -43,17 +42,12 @@ krb5_copy_authdatum(krb5_context context, const krb5_authdata *inad, krb5_authda
if (!(tmpad = (krb5_authdata *)MALLOC(sizeof(*tmpad))))
return ENOMEM;
-#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
*tmpad = *inad;
-#else
- (void) memcpy(tmpad, inad, sizeof(krb5_authdata));
-#endif
if (!(tmpad->contents = (krb5_octet *)MALLOC(inad->length))) {
krb5_xfree_wrap(tmpad, inad->length);
return ENOMEM;
}
- (void) memcpy((char *)tmpad->contents, (char *)inad->contents,
- inad->length);
+ (void) memcpy((char *)tmpad->contents, (char *)inad->contents, inad->length);
*outad = tmpad;
return 0;
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_cksum.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_cksum.c
index 1a06d1cd40..5dfef028d7 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_cksum.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_cksum.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/copy_cksum.c
*
@@ -33,7 +32,7 @@
* krb5_copy_checksum()
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*ARGSUSED*/
krb5_error_code KRB5_CALLCONV
@@ -43,14 +42,11 @@ krb5_copy_checksum(krb5_context context, const krb5_checksum *ckfrom, krb5_check
if (!(tempto = (krb5_checksum *)MALLOC(sizeof(*tempto))))
return ENOMEM;
-#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
*tempto = *ckfrom;
-#else
- (void) memcpy(tempto, ckfrom, sizeof(krb5_checksum));
-#endif
if (!(tempto->contents =
(krb5_octet *)MALLOC(tempto->length))) {
+ krb5_xfree(tempto);
return ENOMEM;
}
(void) memcpy((char *) tempto->contents, (char *) ckfrom->contents,
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_key.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_key.c
index 82a00def34..fc86b13245 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_key.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_key.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/copy_key.c
*
@@ -33,7 +32,7 @@
* krb5_copy_keyblock()
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
* krb5_copy_keyblock_data
@@ -112,4 +111,3 @@ krb5_copy_keyblock(context, from, to)
*to = new_key;
return (ret);
}
-
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_princ.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_princ.c
index c71dea8cbc..4feece541c 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_princ.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_princ.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/copy_princ.c
*
@@ -33,7 +32,8 @@
* krb5_copy_principal()
*/
-#include <k5-int.h>
+#include "k5-int.h"
+
/*
* Copy a principal structure, with fresh allocation.
*/
@@ -49,11 +49,7 @@ krb5_copy_principal(krb5_context context, krb5_const_principal inprinc, krb5_pri
if (tempprinc == 0)
return ENOMEM;
-#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
- *tempprinc = *inprinc; /* Copy all of the non-allocated pieces */
-#else
- (void) memcpy(tempprinc, inprinc, sizeof(krb5_principal_data));
-#endif
+ *tempprinc = *inprinc;
nelems = (int) krb5_princ_size(context, inprinc);
tempprinc->data = MALLOC(nelems * sizeof(krb5_data));
@@ -97,15 +93,15 @@ krb5_copy_principal(krb5_context context, krb5_const_principal inprinc, krb5_pri
*/
tempprinc->realm.data = MALLOC(tempprinc->realm.length + 1);
if (!tempprinc->realm.data) {
- for (i = 0; i < nelems; i++)
- FREE(krb5_princ_component(context, tempprinc, i)->data,
- krb5_princ_component(context, inprinc, i)->length + 1);
+ for (i = 0; i < nelems; i++)
+ FREE(krb5_princ_component(context, tempprinc, i)->data,
+ krb5_princ_component(context, inprinc, i)->length + 1);
FREE(tempprinc->data, nelems * sizeof(krb5_data));
FREE(tempprinc, sizeof(krb5_principal_data));
- return ENOMEM;
- }
+ return ENOMEM;
+ }
memcpy(tempprinc->realm.data, inprinc->realm.data,
- inprinc->realm.length);
+ inprinc->realm.length);
tempprinc->realm.data[tempprinc->realm.length] = 0;
*outprinc = tempprinc;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/init_ctx.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/init_ctx.c
index baf7e5169a..59764e0b00 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/init_ctx.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/init_ctx.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/init_ctx.c
@@ -59,7 +58,7 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
* Solaris Kerberos: the code related to EF/pkcs11 and fork safety are mods Sun
@@ -96,7 +95,7 @@ pid_t __krb5_current_pid; /* fork safety: contains the current process ID */
* delete , sign/verify, wrap/unwrap routines are ported to the kernel.
*/
-#if (defined(_MSDOS) || defined(_WIN32))
+#if (defined(_WIN32))
extern krb5_error_code krb5_vercheck();
extern void krb5_win_ccdll_load(krb5_context context);
#endif
@@ -104,16 +103,20 @@ extern void krb5_win_ccdll_load(krb5_context context);
static krb5_error_code init_common (krb5_context *, krb5_boolean, krb5_boolean);
krb5_error_code KRB5_CALLCONV
-krb5_init_context(context)
- krb5_context *context;
+krb5_init_context(krb5_context *context)
{
+
return init_common (context, FALSE, FALSE);
}
krb5_error_code KRB5_CALLCONV
-krb5_init_secure_context(context)
- krb5_context *context;
+krb5_init_secure_context(krb5_context *context)
{
+
+#if 0 /* Solaris Kerberos */
+ /* This is to make gcc -Wall happy */
+ if(0) krb5_brand[0] = krb5_brand[0];
+#endif
return init_common (context, TRUE, FALSE);
}
@@ -125,6 +128,7 @@ krb5int_init_context_kdc(krb5_context *context)
return init_common (context, FALSE, TRUE);
}
+/* Solaris Kerberos */
krb5_error_code
krb5_open_pkcs11_session(CK_SESSION_HANDLE *hSession)
{
@@ -358,6 +362,27 @@ init_common (krb5_context *context, krb5_boolean secure, krb5_boolean kdc)
} seed_data;
krb5_data seed;
int tmp;
+/* Solaris Kerberos */
+#if 0
+ /* Verify some assumptions. If the assumptions hold and the
+ compiler is optimizing, this should result in no code being
+ executed. If we're guessing "unsigned long long" instead
+ of using uint64_t, the possibility does exist that we're
+ wrong. */
+ {
+ krb5_ui_8 i64;
+ assert(sizeof(i64) == 8);
+ i64 = 0, i64--, i64 >>= 62;
+ assert(i64 == 3);
+ i64 = 1, i64 <<= 31, i64 <<= 31, i64 <<= 1;
+ assert(i64 != 0);
+ i64 <<= 1;
+ assert(i64 == 0);
+ }
+#endif
+ retval = krb5int_initialize_library();
+ if (retval)
+ return retval;
#endif
#if (defined(_WIN32))
@@ -375,12 +400,6 @@ init_common (krb5_context *context, krb5_boolean secure, krb5_boolean kdc)
retval = krb5_vercheck();
if (retval)
return retval;
-#else /* assume UNIX for now */
-#ifndef _KERNEL
- retval = krb5int_initialize_library ();
- if (retval)
- return retval;
-#endif /* !_KERNEL */
#endif
*context = 0;
@@ -488,11 +507,7 @@ init_common (krb5_context *context, krb5_boolean secure, krb5_boolean kdc)
* Note: DCE 1.0.3a only supports a cache type of 1
* DCE 1.1 supports a cache type of 2.
*/
-#ifdef macintosh
#define DEFAULT_CCACHE_TYPE 4
-#else
-#define DEFAULT_CCACHE_TYPE 3
-#endif
profile_get_integer(ctx->profile, "libdefaults", "ccache_type",
0, DEFAULT_CCACHE_TYPE, &tmp);
ctx->fcc_default_format = tmp + 0x0500;
@@ -526,6 +541,8 @@ krb5_free_context(krb5_context ctx)
ctx->conf_tgs_ktypes_count = 0;
}
+ krb5_clear_error_message(ctx);
+
#endif
krb5_os_free_context(ctx);
@@ -550,9 +567,9 @@ krb5_free_context(krb5_context ctx)
ctx->ser_ctx_count = 0;
}
+
ctx->magic = 0;
FREE(ctx, sizeof(struct _krb5_context));
-
}
#ifndef _KERNEL
@@ -591,7 +608,7 @@ krb5_set_default_in_tkt_ktypes(krb5_context context, const krb5_enctype *ktypes)
static krb5_error_code
get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profstr,
- int ctx_count, krb5_enctype *ctx_list)
+ unsigned int ctx_count, krb5_enctype *ctx_list)
{
krb5_enctype *old_ktypes = NULL;
@@ -672,7 +689,7 @@ get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profst
/* skip to next token */
while (*sp) sp++;
- while (!*sp) sp++;
+ while (! *sp) sp++;
}
old_ktypes[j] = (krb5_enctype) 0;
@@ -685,8 +702,6 @@ get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profst
return KRB5_CONFIG_ETYPE_NOSUPP;
}
-
-
*ktypes = old_ktypes;
return 0;
}
@@ -699,7 +714,7 @@ krb5_get_default_in_tkt_ktypes(krb5_context context, krb5_enctype **ktypes)
context->in_tkt_ktypes));
}
-krb5_error_code
+krb5_error_code KRB5_CALLCONV
krb5_set_default_tgs_enctypes (krb5_context context, const krb5_enctype *ktypes)
{
krb5_enctype * new_ktypes;
@@ -707,7 +722,7 @@ krb5_set_default_tgs_enctypes (krb5_context context, const krb5_enctype *ktypes)
if (ktypes) {
for (i = 0; ktypes[i]; i++) {
- if (!valid_enctype(ktypes[i]))
+ if (!krb5_c_valid_enctype(ktypes[i]))
return KRB5_PROG_ETYPE_NOSUPP;
}
@@ -736,8 +751,6 @@ krb5_error_code krb5_set_default_tgs_ktypes
}
-
-
/*ARGSUSED*/
void
KRB5_CALLCONV
@@ -791,4 +804,96 @@ krb5_is_permitted_enctype(krb5_context context, krb5_enctype etype)
return(ret);
}
+
+static krb5_error_code
+copy_ktypes(krb5_context ctx,
+ unsigned int nktypes,
+ krb5_enctype *oldktypes,
+ krb5_enctype **newktypes)
+{
+ unsigned int i;
+
+ *newktypes = NULL;
+ if (!nktypes)
+ return 0;
+
+ *newktypes = MALLOC(nktypes * sizeof(krb5_enctype));
+ if (*newktypes == NULL)
+ return ENOMEM;
+ for (i = 0; i < nktypes; i++)
+ (*newktypes)[i] = oldktypes[i];
+ return 0;
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_copy_context(krb5_context ctx, krb5_context *nctx_out)
+{
+ krb5_error_code ret;
+ krb5_context nctx;
+
+ *nctx_out = NULL;
+ if (ctx == NULL)
+ return EINVAL; /* XXX */
+
+ nctx = MALLOC(sizeof(*nctx));
+ if (nctx == NULL)
+ return ENOMEM;
+
+ *nctx = *ctx;
+
+ nctx->in_tkt_ktypes = NULL;
+ nctx->in_tkt_ktype_count = 0;
+ nctx->tgs_ktypes = NULL;
+ nctx->tgs_ktype_count = 0;
+ nctx->default_realm = NULL;
+ nctx->profile = NULL;
+ nctx->db_context = NULL;
+ nctx->ser_ctx_count = 0;
+ nctx->ser_ctx = NULL;
+ nctx->prompt_types = NULL;
+ nctx->os_context->default_ccname = NULL;
+
+ memset(&nctx->preauth_plugins, 0, sizeof(nctx->preauth_plugins));
+ nctx->preauth_context = NULL;
+
+ memset(&nctx->libkrb5_plugins, 0, sizeof(nctx->libkrb5_plugins));
+ nctx->vtbl = NULL;
+ nctx->locate_fptrs = NULL;
+
+ memset(&nctx->err, 0, sizeof(nctx->err));
+
+ ret = copy_ktypes(nctx, ctx->in_tkt_ktype_count,
+ ctx->in_tkt_ktypes, &nctx->in_tkt_ktypes);
+ if (ret)
+ goto errout;
+ nctx->in_tkt_ktype_count = ctx->in_tkt_ktype_count;
+
+ ret = copy_ktypes(nctx, ctx->tgs_ktype_count,
+ ctx->tgs_ktypes, &nctx->in_tkt_ktypes);
+ if (ret)
+ goto errout;
+ nctx->tgs_ktype_count = ctx->tgs_ktype_count;
+
+ if (ctx->os_context->default_ccname != NULL) {
+ nctx->os_context->default_ccname =
+ strdup(ctx->os_context->default_ccname);
+ if (nctx->os_context->default_ccname == NULL) {
+ ret = ENOMEM;
+ goto errout;
+ }
+ }
+ ret = krb5_get_profile(ctx, &nctx->profile);
+ if (ret)
+ goto errout;
+
+errout:
+ if (ret) {
+ krb5_free_context(nctx);
+ } else {
+ *nctx_out = nctx;
+ }
+ return ret;
+}
#endif /* !KERNEL */
+
+
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/kfree.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/kfree.c
index c1b04a59b2..9fc66d26c1 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/kfree.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/kfree.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1990-1998 by the Massachusetts Institute of Technology.
@@ -26,9 +25,12 @@
* 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_free_address()
*/
-#include <k5-int.h>
+#include "k5-int.h"
static void cleanup_dk_list(krb5_context, krb5_keyblock *);
@@ -204,7 +206,7 @@ krb5_free_cred_contents(krb5_context context, krb5_creds *val)
}
}
-void KRB5_CALLCONV
+void KRB5_CALLCONV
krb5_free_cred_enc_part(krb5_context context, register krb5_cred_enc_part *val)
{
register krb5_cred_info **temp;
@@ -701,7 +703,7 @@ krb5_free_sam_challenge_contents(krb5_context ctx, krb5_sam_challenge *sc)
void KRB5_CALLCONV
krb5_free_sam_challenge_2_contents(krb5_context ctx,
- krb5_sam_challenge_2 *sc2)
+ krb5_sam_challenge_2 *sc2)
{
krb5_checksum **cksump;
@@ -715,14 +717,14 @@ krb5_free_sam_challenge_2_contents(krb5_context ctx,
krb5_free_checksum(ctx, *cksump);
cksump++;
}
- krb5_xfree(sc2->sam_cksum);
+ krb5_xfree(sc2->sam_cksum);
sc2->sam_cksum = 0;
}
}
void KRB5_CALLCONV
krb5_free_sam_challenge_2_body(krb5_context ctx,
- krb5_sam_challenge_2_body *sc2)
+ krb5_sam_challenge_2_body *sc2)
{
if (!sc2)
return;
@@ -732,11 +734,11 @@ krb5_free_sam_challenge_2_body(krb5_context ctx,
void KRB5_CALLCONV
krb5_free_sam_challenge_2_body_contents(krb5_context ctx,
- krb5_sam_challenge_2_body *sc2)
+ krb5_sam_challenge_2_body *sc2)
{
if (!sc2)
return;
- if (sc2->sam_type_name.data)
+ if (sc2->sam_type_name.data)
krb5_free_data_contents(ctx, &sc2->sam_type_name);
if (sc2->sam_track_id.data)
krb5_free_data_contents(ctx, &sc2->sam_track_id);
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/parse.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/parse.c
index ff7e3c72df..1fc4c570ce 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/parse.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/parse.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/parse.c
*
@@ -14,7 +13,7 @@
* 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
@@ -28,7 +27,7 @@
* 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_parse_name() routine.
*
@@ -36,6 +35,7 @@
* characters in the principal name.
*/
+
#include "k5-int.h"
#ifndef _KERNEL
@@ -48,27 +48,27 @@
* converts a single-string representation of the name to the
* multi-part principal format used in the protocols.
*
- * principal will point to allocated storage which should be freed by
+ * principal will point to allocated storage which should be freed by
* the caller (using krb5_free_principal) after use.
- *
+ *
* Conventions: / is used to separate components. If @ is present in the
* string, then the rest of the string after it represents the realm name.
* Otherwise the local realm name is used.
- *
+ *
* error return:
* KRB5_PARSE_MALFORMED badly formatted string
*
* also returns system errors:
- * ENOMEM MALLOC failed/out of memory
+ * ENOMEM malloc failed/out of memory
*
* get_default_realm() is called; it may return other errors.
*/
-#define REALM_SEP '@'
+#define REALM_SEP '@'
#define COMPONENT_SEP '/'
-#define QUOTECHAR '\\'
+#define QUOTECHAR '\\'
-#define FCOMPNUM 10
+#define FCOMPNUM 10
/*
@@ -79,9 +79,9 @@
krb5_error_code KRB5_CALLCONV
krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincipal)
{
- const char *cp;
- char *q;
- int i, c, size;
+ register const char *cp;
+ register char *q;
+ register int i,c,size;
int components = 0;
const char *parsed_realm = NULL;
int fcompsize[FCOMPNUM];
@@ -109,7 +109,7 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
* QUOTECHAR can't be at the last
* character of the name!
*/
- return (KRB5_PARSE_MALFORMED);
+ return(KRB5_PARSE_MALFORMED);
size++;
continue;
} else if (c == COMPONENT_SEP) {
@@ -118,7 +118,7 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
* Shouldn't see a component separator
* after we've parsed out the realm name!
*/
- return (KRB5_PARSE_MALFORMED);
+ return(KRB5_PARSE_MALFORMED);
if (i < FCOMPNUM) {
fcompsize[i] = size;
}
@@ -130,8 +130,8 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
* Multiple realm separaters
* not allowed; zero-length realms are.
*/
- return (KRB5_PARSE_MALFORMED);
- parsed_realm = cp + 1;
+ return(KRB5_PARSE_MALFORMED);
+ parsed_realm = cp+1;
if (i < FCOMPNUM) {
fcompsize[i] = size;
}
@@ -141,25 +141,25 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
}
if (parsed_realm)
realmsize = size;
- else if (i < FCOMPNUM)
+ else if (i < FCOMPNUM)
fcompsize[i] = size;
components = i + 1;
/*
* Now, we allocate the principal structure and all of its
* component pieces
*/
- principal = (krb5_principal)MALLOC(sizeof (krb5_principal_data));
+ principal = (krb5_principal)MALLOC(sizeof(krb5_principal_data));
if (!principal) {
- return (ENOMEM);
+ return(ENOMEM);
}
- principal->data = (krb5_data *)MALLOC(sizeof (krb5_data) * components);
+ principal->data = (krb5_data *)MALLOC(sizeof(krb5_data) * components);
if (!principal->data) {
- krb5_xfree_wrap((char *)principal, sizeof (krb5_principal_data));
- return (ENOMEM);
+ krb5_xfree_wrap((char *)principal, sizeof(krb5_principal_data));
+ return ENOMEM;
}
principal->length = components;
/*
- * If a realm was not found, then use the default realm....
+ * If a realm was not found, then use the defualt realm....
*/
/*
* In the kernel we import the ctx and it always contains the
@@ -175,7 +175,7 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
sizeof (krb5_data) * components);
krb5_xfree_wrap((char *)principal,
sizeof (krb5_principal_data));
- return (retval);
+ return(retval);
}
default_realm_size = strlen(default_realm);
}
@@ -192,7 +192,7 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
size = 0;
parsed_realm = NULL;
/*LINTED*/
- for (i = 0, cp = name; (c = *cp); cp++) {
+ for (i=0,cp = name; (c = *cp); cp++) {
if (c == QUOTECHAR) {
cp++;
size++;
@@ -213,12 +213,13 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
krb5_princ_realm(context, principal)->length = size;
else
if (krb5_princ_size(context, principal) > i)
- krb5_princ_component(context, principal,
- i)->length = size;
+ krb5_princ_component(context, principal, i)->length = size;
if (i + 1 != components) {
#ifndef _KERNEL
- fprintf(stderr,
- "Programming error in krb5_parse_name!");
+#if !defined(_WIN32)
+ fprintf(stderr,
+ "Programming error in krb5_parse_name!");
+#endif
ASSERT(i + 1 == components);
abort();
#else
@@ -231,9 +232,8 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
* usual case), then just copy the sizes to the
* principal structure
*/
- for (i = 0; i < components; i++)
- krb5_princ_component(context,
- principal, i)->length = fcompsize[i];
+ for (i=0; i < components; i++)
+ krb5_princ_component(context, principal, i)->length = fcompsize[i];
}
/*
* Now, we need to allocate the space for the strings themselves.....
@@ -252,9 +252,9 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
}
krb5_princ_set_realm_length(context, principal, realmsize);
krb5_princ_set_realm_data(context, principal, tmpdata);
- for (i = 0; i < components; i++) {
- char *tmpdata2 = MALLOC(krb5_princ_component(context,
- principal, i)->length + 1);
+ for (i=0; i < components; i++) {
+ char *tmpdata2 =
+ MALLOC(krb5_princ_component(context, principal, i)->length + 1);
if (!tmpdata2) {
/*
* Release the principle and realm strings remembering
@@ -291,7 +291,7 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
*/
q = krb5_princ_component(context, principal, 0)->data;
/*LINTED*/
- for (i = 0, cp = name; (c = *cp); cp++) {
+ for (i=0,cp = name; (c = *cp); cp++) {
if (c == QUOTECHAR) {
cp++;
switch (c = *cp) {
@@ -314,15 +314,13 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
i++;
*q++ = '\0';
if (c == COMPONENT_SEP)
- q = krb5_princ_component(context,
- principal, i)->data;
+ q = krb5_princ_component(context, principal, i)->data;
else
q = krb5_princ_realm(context, principal)->data;
} else
*q++ = (char) c;
}
*q++ = '\0';
-
if (!parsed_realm)
#ifndef _KERNEL
(void) strcpy(krb5_princ_realm(context, principal)->data,
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_actx.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_actx.c
index d66959f042..211621720a 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_actx.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_actx.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/ser_actx.c
*
@@ -34,9 +33,9 @@
/*
* ser_actx.c - Serialize krb5_auth_context structure.
*/
-#include <k5-int.h>
-#include <int-proto.h>
-#include <auth_con.h>
+#include "k5-int.h"
+#include "int-proto.h"
+#include "auth_con.h"
#define TOKEN_RADDR 950916
#define TOKEN_RPORT 950917
@@ -94,6 +93,7 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
* krb5_int32 for KV5M_AUTH_CONTEXT
*/
kret = EINVAL;
+ /* Solaris Kerberos */
auth_context = (krb5_auth_context) arg;
if (auth_context) {
kret = 0;
@@ -202,14 +202,14 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe
size_t required;
krb5_octet *bp;
size_t remain;
- size_t obuf;
+ size_t obuf;
krb5_int32 obuf32;
-
required = 0;
bp = *buffer;
remain = *lenremain;
kret = EINVAL;
+ /* Solaris Kerberos */
auth_context = (krb5_auth_context) arg;
if (auth_context) {
kret = ENOMEM;
@@ -555,7 +555,7 @@ krb5_auth_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_oc
* Register the auth_context serializer.
*/
krb5_error_code KRB5_CALLCONV
-krb5_ser_auth_context_init(krb5_context kcontext)
+krb5_ser_auth_context_init(krb5_context kcontext)
{
krb5_error_code kret;
kret = krb5_register_serializer(kcontext, &krb5_auth_context_ser_entry);
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_adata.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_adata.c
index 307d473f34..32047a9ce8 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_adata.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_adata.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/ser_adata.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -26,8 +28,8 @@
/*
* ser_adata.c - Serialize a krb5_authdata structure.
*/
-#include <k5-int.h>
-#include <int-proto.h>
+#include "k5-int.h"
+#include "int-proto.h"
/*
* Routines to deal with externalizing the krb5_authdata:
@@ -40,7 +42,7 @@ static krb5_error_code krb5_authdata_size
static krb5_error_code krb5_authdata_externalize
(krb5_context, krb5_pointer, krb5_octet **, size_t *);
static krb5_error_code krb5_authdata_internalize
- (krb5_context, krb5_pointer *, krb5_octet **, size_t *);
+ (krb5_context,krb5_pointer *, krb5_octet **, size_t *);
/* Local data */
static const krb5_ser_entry krb5_authdata_ser_entry = {
@@ -70,6 +72,7 @@ krb5_authdata_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
* krb5_int32 for KV5M_AUTHDATA
*/
kret = EINVAL;
+ /* Solaris Kerberos */
authdata = (krb5_authdata *) arg;
if (authdata) {
*sizep += (sizeof(krb5_int32) +
@@ -98,6 +101,7 @@ krb5_authdata_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **
bp = *buffer;
remain = *lenremain;
kret = EINVAL;
+ /* Solaris Kerberos */
authdata = (krb5_authdata *) arg;
if (authdata) {
kret = ENOMEM;
@@ -165,6 +169,7 @@ krb5_authdata_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet
authdata->length = (int) ibuf;
/* Get the string */
+ /* Solaris Kerberos */
authdata->contents = (krb5_octet *)
MALLOC((size_t) (ibuf));
if ((authdata->contents) &&
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_addr.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_addr.c
index dba92cf002..140a2d6547 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_addr.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_addr.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/ser_addr.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -26,8 +28,8 @@
/*
* ser_addr.c - Serialize a krb5_address structure.
*/
-#include <k5-int.h>
-#include <int-proto.h>
+#include "k5-int.h"
+#include "int-proto.h"
/*
* Routines to deal with externalizing the krb5_address:
@@ -70,6 +72,7 @@ krb5_address_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
* krb5_int32 for KV5M_ADDRESS
*/
kret = EINVAL;
+ /* Solaris Kerberos */
address = (krb5_address *) arg;
if (address) {
*sizep += (sizeof(krb5_int32) +
@@ -98,6 +101,7 @@ krb5_address_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **b
bp = *buffer;
remain = *lenremain;
kret = EINVAL;
+ /* Solaris Kerberos */
address = (krb5_address *) arg;
if (address) {
kret = ENOMEM;
@@ -169,6 +173,7 @@ krb5_address_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet *
address->length = (int) ibuf;
/* Get the string */
+ /* Solaris Kerberos */
address->contents = (krb5_octet *) MALLOC((size_t) (ibuf));
if ((address->contents) &&
!(kret = krb5_ser_unpack_bytes(address->contents,
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_auth.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_auth.c
index 7b7d7cd954..8043021f7b 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_auth.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_auth.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/ser_auth.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -26,8 +28,8 @@
/*
* ser_auth.c - Serialize krb5_authenticator structure.
*/
-#include <k5-int.h>
-#include <int-proto.h>
+#include "k5-int.h"
+#include "int-proto.h"
/*
* Routines to deal with externalizing the krb5_authenticator:
@@ -71,6 +73,7 @@ krb5_authenticator_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
* krb5_int32 for KV5M_AUTHENTICATOR
*/
kret = EINVAL;
+ /* Solaris Kerberos */
authenticator = (krb5_authenticator *) arg;
if (authenticator) {
required = sizeof(krb5_int32)*6;
@@ -133,6 +136,7 @@ krb5_authenticator_externalize(krb5_context kcontext, krb5_pointer arg, krb5_oct
bp = *buffer;
remain = *lenremain;
kret = EINVAL;
+ /* Solaris Kerberos */
authenticator = (krb5_authenticator *) arg;
if (authenticator) {
kret = ENOMEM;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_cksum.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_cksum.c
index 72e9c42f7b..d1a9caf3f3 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_cksum.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_cksum.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/ser_cksum.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -26,8 +28,8 @@
/*
* ser_cksum.c - Serialize a krb5_checksum structure.
*/
-#include <k5-int.h>
-#include <int-proto.h>
+#include "k5-int.h"
+#include "int-proto.h"
/*
* Routines to deal with externalizing the krb5_checksum:
@@ -70,6 +72,7 @@ krb5_checksum_esize(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
* checksum->length for contents
*/
kret = EINVAL;
+ /* Solaris Kerberos */
checksum = (krb5_checksum *) arg;
if (checksum) {
*sizep += (sizeof(krb5_int32) +
@@ -98,6 +101,7 @@ krb5_checksum_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **
bp = *buffer;
remain = *lenremain;
kret = EINVAL;
+ /* Solaris Kerberos */
checksum = (krb5_checksum *) arg;
if (checksum) {
kret = ENOMEM;
@@ -166,6 +170,7 @@ krb5_checksum_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet
checksum->length = (int) ibuf;
/* Get the string */
+ /* Solaris Kerberos */
if (ibuf)
checksum->contents = (krb5_octet *)
MALLOC((size_t) (ibuf));
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_ctx.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_ctx.c
index 9b76bc6395..fa837f7ee2 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_ctx.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_ctx.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/ser_ctx.c
*
@@ -30,7 +29,7 @@
* ser_ctx.c - Routines to deal with serializing the krb5_context and
* krb5_os_context structures.
*/
-#include <k5-int.h>
+#include "k5-int.h"
/*
* Routines to deal with externalizing the krb5_context:
@@ -128,8 +127,7 @@ krb5_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
* krb5_int32 for trailer.
*/
kret = EINVAL;
- context = (krb5_context) arg;
- if (context) {
+ if ((context = (krb5_context) arg)) {
/* Calculate base length */
required = (14 * sizeof(krb5_int32) +
(context->in_tkt_ktype_count * sizeof(krb5_int32)) +
@@ -489,7 +487,7 @@ krb5_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet *
&bp, &remain);
if (kret && (kret != EINVAL) && (kret != ENOENT))
goto cleanup;
-
+
#ifndef _KERNEL
/* Attempt to read in the profile */
kret = krb5_internalize_opaque(kcontext, PROF_MAGIC_PROFILE,
@@ -554,8 +552,7 @@ krb5_oscontext_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet *
bp = *buffer;
remain = *lenremain;
kret = EINVAL;
- os_ctx = (krb5_os_context) arg;
- if (os_ctx) {
+ if ((os_ctx = (krb5_os_context) arg)) {
kret = ENOMEM;
if (!krb5_oscontext_size(kcontext, arg, &required) &&
(required <= remain)) {
@@ -600,9 +597,8 @@ krb5_oscontext_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet
kret = ENOMEM;
/* Get memory for the context */
- os_ctx = (krb5_os_context)
- MALLOC(sizeof(struct _krb5_os_context));
- if ((os_ctx) &&
+ if ((os_ctx = (krb5_os_context)
+ MALLOC(sizeof(struct _krb5_os_context))) &&
(remain >= 4*sizeof(krb5_int32))) {
(void) memset(os_ctx, 0, sizeof(struct _krb5_os_context));
os_ctx->magic = KV5M_OS_CONTEXT;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_key.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_key.c
index d5afb4e1cf..d307248f12 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_key.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_key.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/ser_key.c
*
@@ -26,8 +25,8 @@
/*
* ser_key.c - Serialize a krb5_keyblock structure.
*/
-#include <k5-int.h>
-#include <int-proto.h>
+#include "k5-int.h"
+#include "int-proto.h"
/*
* Routines to deal with externalizing the krb5_keyblock:
@@ -70,6 +69,7 @@ krb5_keyblock_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
* krb5_int32 for KV5M_KEYBLOCK
*/
kret = EINVAL;
+ /* Solaris Kerberos */
keyblock = (krb5_keyblock *) arg;
if (keyblock) {
*sizep += (sizeof(krb5_int32) +
@@ -99,6 +99,7 @@ krb5_keyblock_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **
bp = *buffer;
remain = *lenremain;
kret = EINVAL;
+ /* Solaris Kerberos */
keyblock = (krb5_keyblock *) arg;
if (keyblock) {
kret = ENOMEM;
@@ -168,6 +169,7 @@ krb5_keyblock_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet
keyblock->length = (int) ibuf;
/* Get the string */
+ /* Solaris Kerberos */
keyblock->contents = (krb5_octet *) MALLOC((size_t) (ibuf));
if ((keyblock->contents)&&
!(kret = krb5_ser_unpack_bytes(keyblock->contents,
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_princ.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_princ.c
index 9f3ff325f5..9c5d69e4c8 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_princ.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_princ.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/ser_princ.c
@@ -23,7 +22,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -32,8 +34,8 @@
/*
* ser_princ.c - Serialize a krb5_principal structure.
*/
-#include <k5-int.h>
-#include <int-proto.h>
+#include "k5-int.h"
+#include "int-proto.h"
/*
* Routines to deal with externalizing the krb5_principal:
@@ -75,10 +77,12 @@ krb5_principal_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
* krb5_int32 for KV5M_PRINCIPAL
*/
kret = EINVAL;
+ /* Solaris Kerberos */
principal = (krb5_principal) arg;
if ((principal) &&
!(kret = krb5_unparse_name(kcontext, principal, &fname))) {
*sizep += (3*sizeof(krb5_int32)) + strlen(fname);
+ /* Solaris Kerberos */
krb5_xfree_wrap(fname, strlen(fname) + 1);
}
return(kret);
@@ -101,6 +105,7 @@ krb5_principal_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet *
bp = *buffer;
remain = *lenremain;
kret = EINVAL;
+ /* Solaris Kerberos */
principal = (krb5_principal) arg;
if (principal) {
kret = ENOMEM;
@@ -117,6 +122,7 @@ krb5_principal_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet *
*buffer = bp;
*lenremain = remain;
+ /* Solaris Kerberos */
krb5_xfree_wrap(fname, strlen(fname) + 1);
}
}
@@ -136,6 +142,7 @@ krb5_principal_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet
krb5_octet *bp;
size_t remain;
char *tmpname;
+ /* Solaris Kerberos */
int tmpsize;
bp = *buffer;
remain = *lenremain;
@@ -149,6 +156,7 @@ krb5_principal_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet
/* See if we have enough data for the length */
if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) {
/* Get the string */
+ /* Solaris Kerberos */
tmpsize = ibuf+1;
tmpname = (char *) MALLOC(tmpsize);
if ((tmpname) &&
@@ -172,6 +180,7 @@ krb5_principal_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet
}
if (kret && principal)
krb5_free_principal(kcontext, principal);
+ /* Solaris Kerberos */
FREE(tmpname,tmpsize);
}
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/serialize.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/serialize.c
index d605d88397..ace4214f85 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/serialize.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/serialize.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/serialize.c
*
@@ -34,9 +33,13 @@
/*
* Base routines to deal with serialization of Kerberos metadata.
*/
-#include <k5-int.h>
+#include "k5-int.h"
+/* Solaris Kerberos */
#include <k5-platform.h>
+#include <k5-platform-store_64.h>
+#include <k5-platform-load_64.h>
+
/*
* krb5_find_serializer() - See if a particular type is registered.
*/
@@ -57,7 +60,7 @@ krb5_find_serializer(krb5_context kcontext, krb5_magic odtype)
}
return(res);
}
-
+
/*
* krb5_register_serializer() - Register a particular serializer.
*/
@@ -77,10 +80,10 @@ krb5_register_serializer(krb5_context kcontext, const krb5_ser_entry *entry)
(kcontext->ser_ctx_count+1)))) {
/* Copy in old table */
if (kcontext->ser_ctx_count)
- (void) memcpy(stable, kcontext->ser_ctx,
- sizeof(krb5_ser_entry) * kcontext->ser_ctx_count);
+ (void) memcpy((void*)stable, kcontext->ser_ctx,
+ sizeof(krb5_ser_entry) * kcontext->ser_ctx_count);
/* Copy in new entry */
- (void) memcpy(&stable[kcontext->ser_ctx_count], entry,
+ (void) memcpy((void*)&stable[kcontext->ser_ctx_count], entry,
sizeof(krb5_ser_entry));
if (kcontext->ser_ctx)
krb5_xfree_wrap(kcontext->ser_ctx,
@@ -92,10 +95,10 @@ krb5_register_serializer(krb5_context kcontext, const krb5_ser_entry *entry)
kret = ENOMEM;
}
else
- (void) memcpy(stable, entry, sizeof(krb5_ser_entry));
+ (void) memcpy((void*)stable, entry, sizeof(krb5_ser_entry));
return(kret);
}
-
+
/*
* krb5_size_opaque() - Determine the size necessary to serialize a given
* piece of opaque data.
@@ -112,7 +115,7 @@ krb5_size_opaque(krb5_context kcontext, krb5_magic odtype, krb5_pointer arg, siz
kret = (shandle->sizer) ? (*shandle->sizer)(kcontext, arg, sizep) : 0;
return(kret);
}
-
+
/*
* krb5_externalize_opaque() - Externalize a piece of opaque data.
*/
@@ -129,7 +132,7 @@ krb5_externalize_opaque(krb5_context kcontext, krb5_magic odtype, krb5_pointer a
(*shandle->externalizer)(kcontext, arg, bufpp, sizep) : 0;
return(kret);
}
-
+
/*
* Externalize a piece of arbitrary data.
*/
@@ -163,7 +166,7 @@ krb5_externalize_data(krb5_context kcontext, krb5_pointer arg, krb5_octet **bufp
}
return(kret);
}
-
+
/*
* krb5_internalize_opaque() - Convert external representation into a data
* structure.
@@ -181,9 +184,9 @@ krb5_internalize_opaque(krb5_context kcontext, krb5_magic odtype, krb5_pointer *
(*shandle->internalizer)(kcontext, argp, bufpp, sizep) : 0;
return(kret);
}
-
+
/*
- * krb5_ser_pack_int32() - Pack a 4-byte integer if space is availble.
+ * krb5_ser_pack_int32() - Pack a 4-byte integer if space is available.
* Update buffer pointer and remaining space.
*/
krb5_error_code KRB5_CALLCONV
@@ -201,7 +204,7 @@ krb5_ser_pack_int32(krb5_int32 iarg, krb5_octet **bufp, size_t *remainp)
else
return(ENOMEM);
}
-
+
/*
* krb5_ser_pack_int64() - Pack an 8-byte integer if space is available.
* Update buffer pointer and remaining space.
@@ -216,9 +219,9 @@ krb5_ser_pack_int64(krb5_int64 iarg, krb5_octet **bufp, size_t *remainp)
return(0);
}
else
- return(ENOMEM);
+ return(ENOMEM);
}
-
+
/*
* krb5_ser_pack_bytes() - Pack a string of bytes.
*/
@@ -234,7 +237,7 @@ krb5_ser_pack_bytes(krb5_octet *ostring, size_t osize, krb5_octet **bufp, size_t
else
return(ENOMEM);
}
-
+
/*
* krb5_ser_unpack_int32() - Unpack a 4-byte integer if it's there.
*/
@@ -253,7 +256,7 @@ krb5_ser_unpack_int32(krb5_int32 *intp, krb5_octet **bufp, size_t *remainp)
else
return(ENOMEM);
}
-
+
/*
* krb5_ser_unpack_int64() - Unpack an 8-byte integer if it's there.
*/
@@ -267,9 +270,9 @@ krb5_ser_unpack_int64(krb5_int64 *intp, krb5_octet **bufp, size_t *remainp)
return(0);
}
else
- return(ENOMEM);
+ return(ENOMEM);
}
-
+
/*
* krb5_ser_unpack_bytes() - Unpack a byte string if it's there.
*/
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/unparse.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/unparse.c
index 2fd0a91b7f..84d2a67ca1 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/unparse.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/unparse.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/krb/unparse.c
*
@@ -35,7 +34,7 @@
*/
-#include <k5-int.h>
+#include "k5-int.h"
#ifndef _KERNEL
#include <stdio.h>
#endif
@@ -97,7 +96,7 @@ krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, regi
totalsize++;
totalsize++; /* This is for the separator */
}
- if (nelem == 0 )
+ if (nelem == 0)
totalsize++;
/*
@@ -163,7 +162,7 @@ krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, regi
}
if (i > 0)
- q--; /* Back up last component separator */
+ q--; /* Back up last component separator */
*q++ = REALM_SEP;
cp = krb5_princ_realm(context, principal)->data;
@@ -204,8 +203,8 @@ krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, regi
krb5_error_code KRB5_CALLCONV
krb5_unparse_name(krb5_context context, krb5_const_principal principal, register char **name)
{
- if (name) /* name == NULL will return error from _ext */
- *name = NULL;
+ if (name) /* name == NULL will return error from _ext */
+ *name = NULL;
return(krb5_unparse_name_ext(context, principal, name, NULL));
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/c_ustime.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/c_ustime.c
index dffde1f40d..97aa56a2d4 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/c_ustime.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/c_ustime.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/crypto/os/c_ustime.c
@@ -33,13 +32,10 @@
*
* krb5_mstimeofday for BSD 4.3
*/
-
-
-#define NEED_SOCKETS
+
#include "k5-int.h"
#include "k5-thread.h"
-
k5_mutex_t krb5int_us_time_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
struct time_now { krb5_int32 sec, usec; };
@@ -65,7 +61,6 @@ get_time_now(struct time_now *n)
#else
-
/* Everybody else is UNIX, right? POSIX 1996 doesn't give us
gettimeofday, but what real OS doesn't? */
@@ -88,6 +83,7 @@ get_time_now(struct time_now *n)
n->usec = tv.tv_usec;
return 0;
}
+
#endif
static struct time_now last_time;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/init_os_ctx.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/init_os_ctx.c
index d412ff85a9..dae8427104 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/init_os_ctx.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/init_os_ctx.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/init_ctx.c
@@ -34,21 +33,22 @@
*/
#define NEED_WINDOWS
-#include <k5-int.h>
+
+#include "k5-int.h"
#ifndef _KERNEL
#include "os-proto.h"
+#if 0 /* Solaris Kerberos */
+#include "prof_int.h" /* XXX for profile_copy, not public yet */
#endif
-
-/* SUNW14resync: Solaris kerb does not need this feature in this file */
-#ifdef USE_LOGIN_LIBRARY
-#undef USE_LOGIN_LIBRARY
+errcode_t KRB5_CALLCONV profile_copy (profile_t, profile_t *);
#endif
#ifdef USE_LOGIN_LIBRARY
#include "KerberosLoginPrivate.h"
-#endif
+#endif
#if defined(_WIN32)
+#include <winsock.h>
static krb5_error_code
get_from_windows_dir(
@@ -183,7 +183,7 @@ get_from_registry(
#ifndef _KERNEL
static void
-free_filespecs(profile_filespec_t *files)
+free_filespecs(profile_filespec_t *files)
{
char **cp;
@@ -195,7 +195,7 @@ free_filespecs(profile_filespec_t *files)
free(files);
}
-/* This function is needed by KfM's KerberosPreferences API
+/* This function is needed by KfM's KerberosPreferences API
* because it needs to be able to specify "secure" */
krb5_error_code
os_get_default_config_files(profile_filespec_t **pfiles, krb5_boolean secure)
@@ -252,17 +252,17 @@ os_get_default_config_files(profile_filespec_t **pfiles, krb5_boolean secure)
unsigned int ent_len;
const char *s, *t;
-#ifdef USE_LOGIN_LIBRARY
- /* If __KLAllowHomeDirectoryAccess() == FALSE, we are probably
- trying to authenticate to a fileserver for the user's homedir. */
- if (secure || !__KLAllowHomeDirectoryAccess ()) {
-#else
- if (secure) {
-#endif
- filepath = DEFAULT_SECURE_PROFILE_PATH;
- } else {
- filepath = getenv("KRB5_CONFIG");
- if (!filepath) filepath = DEFAULT_PROFILE_PATH;
+#ifdef USE_LOGIN_LIBRARY
+ /* If __KLAllowHomeDirectoryAccess() == FALSE, we are probably
+ trying to authenticate to a fileserver for the user's homedir. */
+ if (!__KLAllowHomeDirectoryAccess ())
+ secure = 1;
+#endif
+ if (secure) {
+ filepath = DEFAULT_SECURE_PROFILE_PATH;
+ } else {
+ filepath = getenv("KRB5_CONFIG");
+ if (!filepath) filepath = DEFAULT_PROFILE_PATH;
}
/* count the distinct filename components */
@@ -331,9 +331,11 @@ add_kdc_config_file(profile_filespec_t **pfiles)
return 0;
}
-/* Set the profile paths in the context. If secure is set to TRUE then
- do not include user paths (from environment variables, etc.)
-*/
+
+/* Set the profile paths in the context. If secure is set to TRUE
+ then do not include user paths (from environment variables, etc).
+ If kdc is TRUE, include kdc.conf from whereever we expect to find
+ it. */
static krb5_error_code
os_init_paths(krb5_context ctx, krb5_boolean kdc)
{
@@ -347,7 +349,7 @@ os_init_paths(krb5_context ctx, krb5_boolean kdc)
retval = os_get_default_config_files(&files, secure);
- if (retval == 0 && kdc == TRUE)
+ if (retval == 0 && kdc)
retval = add_kdc_config_file(&files);
if (!retval) {
@@ -390,25 +392,43 @@ krb5_os_init_context(krb5_context ctx, krb5_boolean kdc)
{
krb5_os_context os_ctx;
krb5_error_code retval = 0;
+#ifdef _WIN32
+ WORD wVersionRequested;
+ WSADATA wsaData;
+#endif /* _WIN32 */
os_ctx = ctx->os_context;
os_ctx->magic = KV5M_OS_CONTEXT;
-
os_ctx->time_offset = 0;
os_ctx->usec_offset = 0;
os_ctx->os_flags = 0;
os_ctx->default_ccname = 0;
#ifndef _KERNEL
- krb5_cc_set_default_name(ctx, NULL);
+ ctx->vtbl = 0;
+ PLUGIN_DIR_INIT(&ctx->libkrb5_plugins);
+ PLUGIN_DIR_INIT(&ctx->preauth_plugins);
+ ctx->preauth_context = NULL;
retval = os_init_paths(ctx, kdc);
-#endif
/*
* If there's an error in the profile, return an error. Just
* ignoring the error is a Bad Thing (tm).
*/
+
+ if (!retval) {
+ krb5_cc_set_default_name(ctx, NULL);
+
+#ifdef _WIN32
+ /* We initialize winsock to version 1.1 but
+ * we do not care if we succeed or fail.
+ */
+ wVersionRequested = 0x0101;
+ WSAStartup (wVersionRequested, &wsaData);
+#endif /* _WIN32 */
+ }
+#endif
return retval;
}
@@ -417,30 +437,7 @@ krb5_os_init_context(krb5_context ctx, krb5_boolean kdc)
krb5_error_code KRB5_CALLCONV
krb5_get_profile (krb5_context ctx, profile_t *profile)
{
- krb5_error_code retval = 0;
- profile_filespec_t *files = 0;
-
- retval = os_get_default_config_files(&files, ctx->profile_secure);
-
- if (!retval) {
- retval = profile_init((const_profile_filespec_t *) files,
- profile);
- }
-
- if (files)
- free_filespecs(files);
-
- if (retval == ENOENT)
- return KRB5_CONFIG_CANTOPEN;
-
- if ((retval == PROF_SECTION_NOTOP) ||
- (retval == PROF_SECTION_SYNTAX) ||
- (retval == PROF_RELATION_SYNTAX) ||
- (retval == PROF_EXTRA_CBRACE) ||
- (retval == PROF_MISSING_OBRACE))
- return KRB5_CONFIG_BADFORMAT;
-
- return retval;
+ return profile_copy (ctx->profile, profile);
}
#endif
@@ -513,7 +510,7 @@ krb5_os_free_context(krb5_context ctx)
os_ctx = ctx->os_context;
- if (os_ctx->default_ccname) {
+ if (os_ctx->default_ccname) {
FREE(os_ctx->default_ccname,
strlen(os_ctx->default_ccname) + 1);
os_ctx->default_ccname = 0;
@@ -523,8 +520,19 @@ krb5_os_free_context(krb5_context ctx)
#ifndef _KERNEL
if (ctx->profile) {
- profile_release(ctx->profile);
+ profile_release(ctx->profile);
ctx->profile = 0;
}
+
+ if (ctx->preauth_context) {
+ krb5_free_preauth_context(ctx);
+ ctx->preauth_context = NULL;
+ }
+ krb5int_close_plugin_dirs (&ctx->preauth_plugins);
+ krb5int_close_plugin_dirs (&ctx->libkrb5_plugins);
+
#endif
}
+#ifdef _WIN32
+ WSACleanup();
+#endif /* _WIN32 */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/timeofday.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/timeofday.c
index 3608dc4d4c..9e37adc2d8 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/timeofday.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/timeofday.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/timeofday.c
*
@@ -22,7 +21,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -31,7 +33,7 @@
*/
-#include <k5-int.h>
+#include "k5-int.h"
#ifdef _KERNEL
#include <sys/time.h>
@@ -40,20 +42,11 @@
#include <errno.h>
#endif
-#ifdef POSIX_TYPES
-#define timetype time_t
-#else
-#define timetype long
-#endif
-
-#ifndef HAVE_ERRNO
-extern int errno;
-#endif
-
-krb5_error_code KRB5_CALLCONV
-krb5_timeofday(krb5_context context, register krb5_int32 *timeret)
+krb5_error_code KRB5_CALLCONV
+krb5_timeofday(krb5_context context, register krb5_timestamp *timeret)
{
krb5_os_context os_ctx = context->os_context;
+ /* Solaris Kerberos */
krb5_int32 tval;
if (os_ctx->os_flags & KRB5_OS_TOFFSET_TIME) {
@@ -68,7 +61,8 @@ krb5_timeofday(krb5_context context, register krb5_int32 *timeret)
&usecs))
return kret;
}
- if (tval == (timetype) -1)
+ /* Solaris Kerberos */
+ if (tval == (krb5_int32) -1)
#ifdef _KERNEL
return 1;
#else
@@ -77,6 +71,5 @@ krb5_timeofday(krb5_context context, register krb5_int32 *timeret)
if (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID)
tval += os_ctx->time_offset;
*timeret = tval;
-
return 0;
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/toffset.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/toffset.c
index 980f7e5e2a..967b9d62be 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/toffset.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/os/toffset.c
@@ -1,4 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/krb5/os/toffset.c
*
@@ -17,7 +16,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * 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.
*
@@ -33,10 +35,8 @@
* between the system time and the "real time" as passed to this
* routine
*/
-krb5_error_code
-krb5_set_real_time(context, seconds, microseconds)
- krb5_context context;
- krb5_int32 seconds, microseconds;
+krb5_error_code KRB5_CALLCONV
+krb5_set_real_time(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds)
{
krb5_os_context os_ctx = context->os_context;
krb5_int32 sec, usec;
@@ -58,9 +58,7 @@ krb5_set_real_time(context, seconds, microseconds)
* is useful for running the krb5 routines through test suites
*/
krb5_error_code
-krb5_set_debugging_time(context, seconds, microseconds)
- krb5_context context;
- krb5_int32 seconds, microseconds;
+krb5_set_debugging_time(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds)
{
krb5_os_context os_ctx = context->os_context;
@@ -76,8 +74,7 @@ krb5_set_debugging_time(context, seconds, microseconds)
* routines return the "natural" time.
*/
krb5_error_code
-krb5_use_natural_time(context)
- krb5_context context;
+krb5_use_natural_time(krb5_context context)
{
krb5_os_context os_ctx = context->os_context;
@@ -89,10 +86,8 @@ krb5_use_natural_time(context)
/*
* This routine returns the current time offsets in use.
*/
-krb5_error_code
-krb5_get_time_offsets(context, seconds, microseconds)
- krb5_context context;
- krb5_int32 *seconds, *microseconds;
+krb5_error_code KRB5_CALLCONV
+krb5_get_time_offsets(krb5_context context, krb5_timestamp *seconds, krb5_int32 *microseconds)
{
krb5_os_context os_ctx = context->os_context;
@@ -108,9 +103,7 @@ krb5_get_time_offsets(context, seconds, microseconds)
* This routine sets the time offsets directly.
*/
krb5_error_code
-krb5_set_time_offsets(context, seconds, microseconds)
- krb5_context context;
- krb5_int32 seconds, microseconds;
+krb5_set_time_offsets(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds)
{
krb5_os_context os_ctx = context->os_context;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c
index 8b41e6cd61..736fd44a71 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1993 by OpenVision Technologies, Inc.
@@ -31,7 +30,7 @@
#include "mglueP.h" /* SUNW15resync - for KGSS_ macros */
/*
- * $Id: delete_sec_context.c 16465 2004-06-16 02:37:23Z tlyu $
+ * $Id: delete_sec_context.c 18396 2006-07-25 20:29:43Z lxs $
*/
@@ -196,7 +195,7 @@ krb5_gss_delete_sec_context(minor_status,
if (ctx->mech_used)
(void) KGSS_RELEASE_OID(minor_status, &ctx->mech_used);
-
+
if (ctx->k5_context)
krb5_free_context(ctx->k5_context);
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c
index 3b32075239..d28386c35c 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1993 by OpenVision Technologies, Inc.
@@ -54,7 +53,7 @@
*/
/*
- * $Id: gssapi_krb5.c 18131 2006-06-14 22:27:54Z tlyu $
+ * $Id: gssapi_krb5.c 18343 2006-07-19 18:14:01Z lxs $
*/
@@ -204,6 +203,22 @@ kg_sync_ccache_name (krb5_context context, OM_uint32 *minor_status)
return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
}
+/* This function returns whether or not the caller set a cccache name. Used by
+ * gss_acquire_cred to figure out if the caller wants to only look at this
+ * ccache or search the cache collection for the desired name */
+OM_uint32
+kg_caller_provided_ccache_name (OM_uint32 *minor_status,
+int *out_caller_provided_name)
+{
+ if (out_caller_provided_name) {
+ *out_caller_provided_name =
+ (k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME) != NULL);
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
OM_uint32
kg_get_ccache_name (OM_uint32 *minor_status, const char **out_name)
{
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/import_sec_context.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/import_sec_context.c
index 4353a2576d..dafc7bcb39 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/import_sec_context.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/import_sec_context.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/gssapi/krb5/import_sec_context.c
@@ -148,7 +147,6 @@ krb5_gss_import_sec_context(minor_status, interprocess_token, context_handle)
*minor_status = (OM_uint32) G_VALIDATE_FAILED;
return(GSS_S_FAILURE);
}
-
ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
*context_handle = (gss_ctx_id_t) ctx;
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/k5seal.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/k5seal.c
index a38b494934..9373deede7 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/k5seal.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/k5seal.c
@@ -1,13 +1,12 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* 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
@@ -17,7 +16,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
@@ -53,43 +52,24 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
#include <k5-int.h>
static krb5_error_code
make_seal_token_v1 (krb5_context context,
- krb5_keyblock *enc,
- krb5_keyblock *seq,
- gssint_uint64 *seqnum,
- int direction,
- gss_buffer_t text,
- gss_buffer_t token,
- int signalg,
- int cksum_size,
- int sealalg,
- int encrypt,
- int toktype,
- int bigend,
- gss_OID oid);
-
-static krb5_error_code
-make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
- signalg, cksum_size, sealalg, encrypt, toktype,
- bigend, oid)
- krb5_context context;
- krb5_keyblock *enc;
- krb5_keyblock *seq;
- gssint_uint64 *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_keyblock *enc,
+ krb5_keyblock *seq,
+ gssint_uint64 *seqnum,
+ int direction,
+ gss_buffer_t text,
+ gss_buffer_t token,
+ int signalg,
+ size_t cksum_size,
+ int sealalg,
+ int encrypt,
+ int toktype,
+ int bigend,
+ gss_OID oid)
{
krb5_error_code code;
size_t sumlen;
@@ -97,15 +77,13 @@ make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
krb5_data plaind;
krb5_checksum md5cksum;
krb5_checksum cksum;
- /*
- * msglen contains the message length
- * we are signing/encrypting. tmsglen
- * contains the length of the message
- * we plan to write out to the token.
- * tlen is the length of the token
- * including header.
- */
- int conflen=0, tmsglen, tlen, msglen;
+ /* msglen contains the message length
+ * we are signing/encrypting. tmsglen
+ * contains the length of the message
+ * we plan to write out to the token.
+ * tlen is the length of the token
+ * including header. */
+ unsigned conflen=0, tmsglen, tlen, msglen;
unsigned char *t, *ptr;
unsigned char *plain;
unsigned char pad;
@@ -134,57 +112,51 @@ make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
/* create the token buffer */
/* Do we need confounder? */
if (encrypt || (!bigend && (toktype == KG_TOK_SEAL_MSG)))
- conflen = kg_confounder_size(context, enc);
- else
- conflen = 0;
+ conflen = kg_confounder_size(context, enc);
+ else conflen = 0;
if (toktype == KG_TOK_SEAL_MSG) {
- switch (sealalg) {
- case SEAL_ALG_MICROSOFT_RC4:
- msglen = conflen + text->length+1;
- pad = 1;
- break;
- default:
- /* XXX knows that des block size is 8 */
- msglen = (conflen+text->length+8)&(~7);
- pad = 8-(text->length%8);
- }
- tmsglen = msglen;
+ switch (sealalg) {
+ case SEAL_ALG_MICROSOFT_RC4:
+ msglen = conflen + text->length+1;
+ pad = 1;
+ break;
+ default:
+ /* XXX knows that des block size is 8 */
+ msglen = (conflen+text->length+8)&(~7);
+ pad = 8-(text->length%8);
+ }
+ tmsglen = msglen;
} else {
- tmsglen = 0;
- msglen = text->length;
- pad = 0;
+ tmsglen = 0;
+ msglen = text->length;
+ pad = 0;
}
-
tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen);
if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
- return(ENOMEM);
+ 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] = (unsigned char) (signalg & 0xff);
ptr[1] = (unsigned char) ((signalg >> 8) & 0xff);
/* 2..3 SEAL_ALG or Filler */
-
if ((toktype == KG_TOK_SEAL_MSG) && encrypt) {
ptr[2] = (unsigned char) (sealalg & 0xff);
ptr[3] = (unsigned char) ((sealalg >> 8) & 0xff);
} else {
- /* No seal */
- ptr[2] = 0xff;
- ptr[3] = 0xff;
+ /* No seal */
+ ptr[2] = 0xff;
+ ptr[3] = 0xff;
}
/* 4..5 Filler */
-
ptr[4] = 0xff;
ptr[5] = 0xff;
@@ -194,21 +166,21 @@ make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
switch (signalg) {
case SGN_ALG_DES_MAC_MD5:
case SGN_ALG_MD2_5:
- md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
- break;
+ md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
case SGN_ALG_HMAC_SHA1_DES3_KD:
- md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3;
- break;
+ md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3;
+ break;
case SGN_ALG_HMAC_MD5:
- md5cksum.checksum_type = CKSUMTYPE_HMAC_MD5_ARCFOUR;
- if (toktype != KG_TOK_SEAL_MSG)
- sign_usage = 15;
- break;
+ md5cksum.checksum_type = CKSUMTYPE_HMAC_MD5_ARCFOUR;
+ if (toktype != KG_TOK_SEAL_MSG)
+ sign_usage = 15;
+ break;
default:
KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, error2 signalg=%d\n",
signalg);
#ifndef _KERNEL
- abort ();
+ abort ();
#else
return (GSS_S_DEFECTIVE_TOKEN);
#endif /* _KERNEL */
@@ -218,28 +190,28 @@ make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
if (code) {
KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, krb5_c_checksum_length() "
"error code=%d\n", code);
- return(code);
+ return(code);
}
- md5cksum.length = (size_t)sumlen;
+ md5cksum.length = sumlen;
+
if ((plain = (unsigned char *) xmalloc(msglen ? msglen : 1)) == NULL) {
- xfree_wrap(t, tlen);
- return(ENOMEM);
+ xfree_wrap(t, tlen);
+ return(ENOMEM);
}
if (conflen) {
- if ((code = kg_make_confounder(context, enc, plain))) {
- xfree_wrap(plain, msglen ? msglen : 1);
- xfree_wrap(t, tlen);
- KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, "
- "kg_make_confounder() error code=%d\n", code);
- return(code);
- }
+ if ((code = kg_make_confounder(context, enc, plain))) {
+ xfree_wrap(plain, msglen ? msglen : 1);
+ xfree_wrap(t, tlen);
+ KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, "
+ "kg_make_confounder() error code=%d\n", code);
+ return(code);
+ }
}
(void) memcpy(plain+conflen, text->value, text->length);
- if (pad)
- (void) memset(plain+conflen+text->length, pad, pad);
+ if (pad) (void) memset(plain+conflen+text->length, pad, pad);
/* compute the checksum */
@@ -252,70 +224,67 @@ make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
}
(void) memcpy(data_ptr, ptr-2, 8);
if (bigend)
- (void) memcpy(data_ptr+8, text->value, text->length);
+ (void) memcpy(data_ptr+8, text->value, text->length);
else
- (void) memcpy(data_ptr+8, plain, msglen);
-
+ (void) memcpy(data_ptr+8, plain, msglen);
plaind.length = 8 + (bigend ? text->length : msglen);
plaind.data = data_ptr;
-
code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq,
- sign_usage, &plaind, &md5cksum);
-
+ sign_usage, &plaind, &md5cksum);
xfree_wrap(data_ptr,8 + (bigend ? text->length : msglen));
if (code) {
- KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, "
- "krb5_c_make_checksum() error code=%d\n", code);
- xfree_wrap(plain, msglen ? msglen : 1);
- xfree_wrap(t, tlen);
- return(code);
+ KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, "
+ "krb5_c_make_checksum() error code=%d\n", code);
+ xfree_wrap(plain, msglen ? msglen : 1);
+ xfree_wrap(t, tlen);
+ return(code);
}
-
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_wrap(md5cksum.contents, md5cksum.length);
- xfree_wrap(t, tlen);
-
- KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, kg_encrypt() "
- "error code=%d\n", code);
- return code;
- }
+ 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_wrap(md5cksum.contents, md5cksum.length);
+ xfree_wrap(t, tlen);
+
+ KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, kg_encrypt() "
+ "error code=%d\n", code);
+ return code;
+ }
- cksum.length = cksum_size;
- cksum.contents = md5cksum.contents + 16 - cksum.length;
+ cksum.length = cksum_size;
+ cksum.contents = md5cksum.contents + 16 - cksum.length;
- (void) memcpy(ptr+14, cksum.contents, cksum.length);
- break;
+ (void) 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)
+ /*
+ * Using key derivation, the call to krb5_c_make_checksum
+ * already dealt with encrypting.
+ */
+ if (md5cksum.length != cksum_size)
{
KRB5_LOG1(KRB5_ERR, "make_seal_token_v1() end, error "
- "md5cksum.length %d != "
- "cksum_size %d\n",
- md5cksum.length, cksum_size);
+ "md5cksum.length %u != "
+ "cksum_size %u\n",
+ (unsigned int)md5cksum.length,
+ (unsigned int) cksum_size);
#ifndef _KERNEL
- abort ();
+ abort ();
#else
- return (GSS_S_DEFECTIVE_TOKEN);
+ return (GSS_S_DEFECTIVE_TOKEN);
#endif
}
- (void) memcpy(ptr+14, md5cksum.contents, md5cksum.length);
- break;
+ (void) memcpy(ptr+14, md5cksum.contents, md5cksum.length);
+ break;
case SGN_ALG_HMAC_MD5:
- KRB5_LOG(KRB5_INFO, "make_seal_token_v1() cksum_size = %d",
- cksum_size);
+ KRB5_LOG(KRB5_INFO, "make_seal_token_v1() cksum_size = %u",
+ (unsigned int)cksum_size);
(void) memcpy(ptr+14, md5cksum.contents, cksum_size);
break;
}
@@ -332,49 +301,49 @@ make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
"error code=%d\n", code);
return(code);
}
+
if (encrypt) {
- switch(sealalg) {
- case SEAL_ALG_MICROSOFT_RC4:
+ switch(sealalg) {
+ case SEAL_ALG_MICROSOFT_RC4:
{
- unsigned char bigend_seqnum[4];
- krb5_keyblock *enc_key;
- int i;
- bigend_seqnum[0] = (*seqnum>>24) & 0xff;
- bigend_seqnum[1] = (*seqnum>>16) & 0xff;
- bigend_seqnum[2] = (*seqnum>>8) & 0xff;
- bigend_seqnum[3] = *seqnum & 0xff;
- code = krb5_copy_keyblock (context, enc, &enc_key);
- if (code)
- {
- xfree_wrap(plain, msglen ? msglen : 1);
- xfree_wrap(t, tlen);
- return(code);
- }
- for (i = 0; i <= 15; i++)
- ((char *) enc_key->contents)[i] ^=0xf0;
- code = kg_arcfour_docrypt (context,
- enc_key, 0,
- bigend_seqnum, 4,
- plain, tmsglen,
- ptr+14+cksum_size);
- krb5_free_keyblock (context, enc_key);
- if (code)
- {
- xfree_wrap(plain, msglen ? msglen : 1);
- xfree_wrap(t, tlen);
- return(code);
- }
+ unsigned char bigend_seqnum[4];
+ krb5_keyblock *enc_key;
+ int i;
+ bigend_seqnum[0] = (*seqnum>>24) & 0xff;
+ bigend_seqnum[1] = (*seqnum>>16) & 0xff;
+ bigend_seqnum[2] = (*seqnum>>8) & 0xff;
+ bigend_seqnum[3] = *seqnum & 0xff;
+ code = krb5_copy_keyblock (context, enc, &enc_key);
+ if (code)
+ {
+ xfree_wrap(plain, msglen ? msglen : 1);
+ xfree_wrap(t, tlen);
+ return(code);
+ }
+ for (i = 0; i <= 15; i++)
+ ((char *) enc_key->contents)[i] ^=0xf0;
+ code = kg_arcfour_docrypt (context, enc_key, 0,
+ bigend_seqnum, 4,
+ plain, tmsglen,
+ ptr+14+cksum_size);
+ krb5_free_keyblock (context, enc_key);
+ if (code)
+ {
+ xfree_wrap(plain, msglen ? msglen : 1);
+ xfree_wrap(t, tlen);
+ return(code);
+ }
}
- break;
- default:
+ break;
+ default:
if ((code = kg_encrypt(context, enc, KG_USAGE_SEAL, NULL,
- (krb5_pointer) plain,
- (krb5_pointer) (ptr+cksum_size+14),
- tmsglen))) {
- xfree_wrap(plain, msglen ? msglen : 1);
- xfree_wrap(t, tlen);
- return(code);
- }
+ (krb5_pointer) plain,
+ (krb5_pointer) (ptr+cksum_size+14),
+ tmsglen))) {
+ xfree_wrap(plain, msglen ? msglen : 1);
+ xfree_wrap(t, tlen);
+ return(code);
+ }
}
}else {
if (tmsglen)
@@ -382,6 +351,7 @@ make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
}
xfree_wrap(plain, msglen ? msglen : 1);
+
/* that's it. return the token */
(*seqnum)++;
@@ -421,10 +391,10 @@ kg_seal(minor_status, context_handle, conf_req_flag, qop_req,
/* Only default qop or matching established cryptosystem is allowed.
- There are NO EXTENSIONS to this set for AES and friends! The
- new spec says "just use 0". The old spec plus extensions would
- actually allow for certain non-zero values. Fix this to handle
- them later. */
+ There are NO EXTENSIONS to this set for AES and friends! The
+ new spec says "just use 0". The old spec plus extensions would
+ actually allow for certain non-zero values. Fix this to handle
+ them later. */
if (qop_req != 0) {
*minor_status = (OM_uint32) G_UNKNOWN_QOP;
KRB5_LOG0(KRB5_ERR, "kg_seal() end, error G_UNKNOWN_QOP\n");
@@ -457,20 +427,20 @@ kg_seal(minor_status, context_handle, conf_req_flag, qop_req,
{
case 0:
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);
+ &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);
break;
case 1:
code = gss_krb5int_make_seal_token_v3(context, ctx,
- input_message_buffer,
- output_message_buffer,
- conf_req_flag, toktype);
+ input_message_buffer,
+ output_message_buffer,
+ conf_req_flag, toktype);
break;
default:
- code = G_UNKNOWN_QOP;
+ code = G_UNKNOWN_QOP; /* XXX */
break;
}
@@ -484,7 +454,7 @@ kg_seal(minor_status, context_handle, conf_req_flag, qop_req,
if (conf_state)
*conf_state = conf_req_flag;
- *minor_status = 0;
+ *minor_status = 0;
if (ctx->endtime < now) {
(void) gss_release_buffer(minor_status, output_message_buffer);
KRB5_LOG(KRB5_ERR, "kg_seal() end, error GSS_S_CONTEXT_EXPIRED "
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/k5sealv3.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/k5sealv3.c
index 14aad1237a..0c4e508825 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/k5sealv3.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/k5sealv3.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/gssapi/krb5/k5sealv3.c
@@ -15,7 +14,7 @@
* 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
@@ -23,13 +22,13 @@
* 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
+ * 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.
- *
+ *
*
*/
/* draft-ietf-krb-wg-gssapi-cfx-05 */
@@ -41,10 +40,18 @@
#define ASSERT assert
#endif
-#include <k5-int.h>
-#include <gssapiP_krb5.h>
+/* Solaris Kerberos */
+#include "k5-int.h" /* for zap() */
+#include "k5-platform.h"
+
+/* Solaris Kerberos */
+#include "k5-platform-store_16.h"
+#include "k5-platform-store_64.h"
+#include "k5-platform-load_16.h"
+#include "k5-platform-load_64.h"
+
+#include "gssapiP_krb5.h"
#include <sys/int_limits.h>
-#include <k5-platform.h>
static int
rotate_left (void *ptr, size_t bufsiz, size_t rc)
@@ -278,7 +285,6 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
err = krb5_c_make_checksum(context, ctx->cksumtype, key,
key_usage, &plain, &sum);
-
bzero(plain.data, plain.length);
FREE(plain.data, plain.length);
plain.data = 0;
@@ -342,13 +348,14 @@ error:
conf_state is only valid if SEAL. */
OM_uint32
-gss_krb5int_unseal_token_v3(krb5_context context,
+gss_krb5int_unseal_token_v3(krb5_context *contextptr,
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)
{
+ krb5_context context = *contextptr;
krb5_data plain;
gssint_uint64 seqnum;
size_t ec, rrc;
@@ -403,7 +410,7 @@ gss_krb5int_unseal_token_v3(krb5_context context,
namely, a copy of the AP-REQ subkey, if it was provided. So
the initiator may think we wanted a subkey, and set the flag,
even though we weren't trying to set the subkey. The "other"
- key, the one not ASSERTed by the acceptor, will have the same
+ key, the one not asserted by the acceptor, will have the same
value in that case, though, so we can just ignore the flag. */
if (ctx->have_acceptor_subkey && (ptr[2] & FLAG_ACCEPTOR_SUBKEY)) {
key = ctx->acceptor_subkey;
@@ -429,7 +436,7 @@ gss_krb5int_unseal_token_v3(krb5_context context,
rrc = load_16_be(ptr+6);
seqnum = load_64_be(ptr+8);
if (!rotate_left(ptr+16, bodysize-16, rrc)) {
- no_mem:
+ no_mem:
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
@@ -491,7 +498,7 @@ gss_krb5int_unseal_token_v3(krb5_context context,
Rotate the first two. */
store_16_be(0, ptr+4);
store_16_be(0, ptr+6);
- plain.length = bodysize - ec;
+ plain.length = bodysize-ec;
plain.data = (char *)ptr;
if (!rotate_left(ptr, bodysize-ec, 16))
goto no_mem;
@@ -556,7 +563,7 @@ gss_krb5int_unseal_token_v3(krb5_context context,
err = krb5_c_verify_checksum(context, key, key_usage,
&plain, &sum, &valid);
if (err) {
-error:
+ error:
FREE(plain.data, plain.length);
*minor_status = err;
return GSS_S_BAD_SIG; /* XXX */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/k5unseal.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/k5unseal.c
index 61a47cb3d6..cb6e16eadf 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/k5unseal.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/k5unseal.c
@@ -3,11 +3,11 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
+ * Copyright 2001 by the Massachusetts Institute of Technology.
* 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
@@ -17,7 +17,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
@@ -53,18 +53,13 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <gssapiP_krb5.h>
-#include <k5-int.h>
-
-/*
- * $Id: k5unseal.c,v 1.19.6.2 2000/05/31 17:17:38 raeburn Exp $
- */
+#include "gssapiP_krb5.h"
+#include "k5-int.h"
/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
- conf_state is only valid if SEAL.
- */
+ conf_state is only valid if SEAL. */
-OM_uint32
+static OM_uint32
kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
conf_state, qop_state, toktype)
krb5_context context;
@@ -88,8 +83,8 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
char *data_ptr;
krb5_timestamp now;
unsigned char *plain;
- int cksum_len = 0;
- int plainlen;
+ unsigned int cksum_len = 0;
+ size_t plainlen;
int direction;
krb5_ui_4 seqnum;
OM_uint32 retval;
@@ -142,11 +137,11 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
but few enough that we can try them all. */
if ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) ||
- (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
+ (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
(ctx->sealalg == SEAL_ALG_DES3KD &&
- signalg != SGN_ALG_HMAC_SHA1_DES3_KD) ||
+ signalg != SGN_ALG_HMAC_SHA1_DES3_KD)||
(ctx->sealalg == SEAL_ALG_MICROSOFT_RC4 &&
- signalg != SGN_ALG_HMAC_MD5)) {
+ signalg != SGN_ALG_HMAC_MD5)) {
*minor_status = 0;
KRB5_LOG0(KRB5_ERR, "kg_unseal_v1() end, error4 GSS_S_DEFECTIVE_TOKEN\n");
return GSS_S_DEFECTIVE_TOKEN;
@@ -161,7 +156,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
cksum_len = 8;
if (toktype != KG_TOK_SEAL_MSG)
sign_usage = 15;
- break;
+ break;
case SGN_ALG_3:
cksum_len = 16;
break;
@@ -198,8 +193,9 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
#endif /* _KERNEL */
/* get the token parameters */
+
if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction,
- &seqnum))) {
+ &seqnum))) {
*minor_status = code;
return(GSS_S_BAD_SIG);
}
@@ -218,25 +214,24 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
KRB5_LOG0(KRB5_ERR, "kg_unseal_v1() end, error ENOMEM\n");
return(GSS_S_FAILURE);
}
- if (ctx->enc->enctype == ENCTYPE_ARCFOUR_HMAC) {
- unsigned char bigend_seqnum[4];
- krb5_keyblock *enc_key;
- int i;
-
- bigend_seqnum[0] = (seqnum>>24) & 0xff;
- bigend_seqnum[1] = (seqnum>>16) & 0xff;
- bigend_seqnum[2] = (seqnum>>8) & 0xff;
- bigend_seqnum[3] = seqnum & 0xff;
- code = krb5_copy_keyblock (context, ctx->enc, &enc_key);
- if (code)
+ if (ctx->enc->enctype == ENCTYPE_ARCFOUR_HMAC) {
+ unsigned char bigend_seqnum[4];
+ krb5_keyblock *enc_key;
+ int i;
+ bigend_seqnum[0] = (seqnum>>24) & 0xff;
+ bigend_seqnum[1] = (seqnum>>16) & 0xff;
+ bigend_seqnum[2] = (seqnum>>8) & 0xff;
+ bigend_seqnum[3] = seqnum & 0xff;
+ code = krb5_copy_keyblock (context, ctx->enc, &enc_key);
+ if (code)
{
- xfree_wrap(plain, tmsglen);
+ xfree_wrap(plain, tmsglen);
*minor_status = code;
return(GSS_S_FAILURE);
}
- for (i = 0; i <= 15; i++)
- ((char *) enc_key->contents)[i] ^=0xf0;
+ for (i = 0; i <= 15; i++)
+ ((char *) enc_key->contents)[i] ^=0xf0;
#ifndef _KERNEL
/*
@@ -266,7 +261,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
xfree_wrap(plain, tmsglen);
*minor_status = code;
return(GSS_S_FAILURE);
- }
+ }
} else {
plain = ptr+14+cksum_len;
}
@@ -332,12 +327,12 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
case SGN_ALG_3:
md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
break;
+ case SGN_ALG_HMAC_MD5:
+ md5cksum.checksum_type = CKSUMTYPE_HMAC_MD5_ARCFOUR;
+ break;
case SGN_ALG_HMAC_SHA1_DES3_KD:
md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3;
break;
- case SGN_ALG_HMAC_MD5:
- md5cksum.checksum_type = CKSUMTYPE_HMAC_MD5_ARCFOUR;
- break;
default:
KRB5_LOG(KRB5_ERR, "kg_unseal_v1() end, error2 signalg=%d\n", signalg);
#ifndef _KERNEL
@@ -348,8 +343,8 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
#endif /* _KERNEL */
}
- if (code = krb5_c_checksum_length(context, md5cksum.checksum_type,
- &sumlen))
+ code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen);
+ if (code)
{
KRB5_LOG(KRB5_ERR, "kg_unseal_v1() end, krb5_c_checksum_length() error "
"code=%d\n", code);
@@ -698,20 +693,20 @@ kg_unseal(minor_status, context_handle, input_token_buffer,
if (ctx->proto)
switch (toktype) {
case KG_TOK_SIGN_MSG:
- toktype2 = 0x0404;
- break;
+ toktype2 = 0x0404;
+ break;
case KG_TOK_SEAL_MSG:
- toktype2 = 0x0504;
- break;
+ toktype2 = 0x0504;
+ break;
case KG_TOK_DEL_CTX:
- toktype2 = 0x0405;
- break;
+ toktype2 = 0x0405;
+ break;
default:
- toktype2 = toktype;
- break;
+ toktype2 = toktype;
+ break;
}
else
- toktype2 = toktype;
+ toktype2 = toktype;
err = g_verify_token_header(ctx->mech_used,
(uint32_t *)&bodysize, &ptr, toktype2,
input_token_buffer->length,
@@ -721,15 +716,13 @@ kg_unseal(minor_status, context_handle, input_token_buffer,
return GSS_S_DEFECTIVE_TOKEN;
}
-
-
if (ctx->proto == 0) {
err = kg_unseal_v1(ctx->k5_context, minor_status, ctx, ptr, bodysize,
message_buffer, conf_state, qop_state,
toktype);
} else {
- err = gss_krb5int_unseal_token_v3(ctx->k5_context, minor_status, ctx,
+ err = gss_krb5int_unseal_token_v3(&ctx->k5_context, minor_status, ctx,
ptr, bodysize, message_buffer,
conf_state, qop_state, toktype);
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/ser_sctx.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/ser_sctx.c
index 0181913db9..a3d6df322e 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/ser_sctx.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/ser_sctx.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* lib/gssapi/krb5/ser_sctx.c
@@ -654,13 +653,13 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
if (kret == EINVAL)
kret = 0;
}
-
+
#ifndef PROVIDE_KERNEL_IMPORT
if (!kret)
kret = krb5_internalize_opaque(kcontext,
KV5M_CONTEXT,
- (krb5_pointer *) &ctx->k5_context,
- &bp, &remain);
+ (krb5_pointer *) &ctx->k5_context,
+ &bp, &remain);
if (!kret)
kret = krb5_internalize_opaque(kcontext,
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/sign.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/sign.c
index 2cd38505cd..ee00b28b16 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/sign.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/sign.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1993 by OpenVision Technologies, Inc.
@@ -51,7 +50,7 @@ krb5_gss_sign(minor_status, context_handle,
OM_uint32 gssd_ctx_verifier;
#endif
{
- return(kg_seal(minor_status, context_handle, 0,
+ return(kg_seal(minor_status, context_handle, 0,
qop_req, message_buffer, NULL,
message_token, KG_TOK_SIGN_MSG));
}
@@ -66,7 +65,7 @@ krb5_gss_get_mic(minor_status, context_handle, qop_req,
gss_buffer_t message_buffer;
gss_buffer_t message_token;
{
- return(kg_seal(minor_status, context_handle, 0,
+ return(kg_seal(minor_status, context_handle, 0,
(int) qop_req, message_buffer, NULL,
message_token, KG_TOK_MIC_MSG));
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/unseal.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/unseal.c
index 22a6c3beea..7636d01dba 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/unseal.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/unseal.c
@@ -1,11 +1,10 @@
/* EXPORT DELETE START */
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1993 by OpenVision Technologies, Inc.
@@ -54,7 +53,7 @@ krb5_gss_unseal(minor_status, context_handle,
OM_uint32 gssd_ctx_verifier;
#endif
{
- return(kg_unseal(minor_status, context_handle,
+ return(kg_unseal(minor_status, context_handle,
input_message_buffer, output_message_buffer,
conf_state, qop_state, KG_TOK_SEAL_MSG));
}
@@ -78,8 +77,8 @@ krb5_gss_unwrap(minor_status, context_handle,
int qstate;
rstat = kg_unseal(minor_status, context_handle,
- input_message_buffer, output_message_buffer,
- conf_state, &qstate, KG_TOK_WRAP_MSG);
+ input_message_buffer, output_message_buffer,
+ conf_state, &qstate, KG_TOK_WRAP_MSG);
if (!rstat && qop_state)
*qop_state = (gss_qop_t) qstate;
return(rstat);
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_crypt.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_crypt.c
index 47eaafae7f..b7a4444cb1 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_crypt.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_crypt.c
@@ -1,11 +1,11 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
+ * Copyright2001 by the Massachusetts Institute of Technology.
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -71,11 +71,13 @@ kg_confounder_size(context, key)
krb5_context context;
krb5_keyblock *key;
{
+ krb5_error_code code;
size_t blocksize;
/* We special case rc4*/
if (key->enctype == ENCTYPE_ARCFOUR_HMAC)
- return 8;
- if (krb5_c_block_size(context, key->enctype, &blocksize) != 0)
+ return 8;
+ code = krb5_c_block_size(context, key->enctype, &blocksize);
+ if (code)
return(-1); /* XXX */
return(blocksize);
@@ -89,15 +91,16 @@ kg_make_confounder(context, key, buf)
{
krb5_error_code code;
size_t blocksize;
- krb5_data random;
+ krb5_data lrandom;
- if (code = krb5_c_block_size(context, key->enctype, &blocksize))
+ code = krb5_c_block_size(context, key->enctype, &blocksize);
+ if (code)
return(code);
- random.length = blocksize;
- random.data = (char *) buf;
+ lrandom.length = blocksize;
+ lrandom.data = (char *) buf;
- return(krb5_c_random_make_octets(context, &random));
+ return(krb5_c_random_make_octets(context, &lrandom));
}
int
@@ -120,7 +123,7 @@ kg_encrypt(context, key, usage, iv, in, out, length)
krb5_keyblock *key;
int usage;
krb5_pointer iv;
- krb5_pointer in;
+ krb5_const_pointer in;
krb5_pointer out;
unsigned int length;
{
@@ -132,7 +135,8 @@ kg_encrypt(context, key, usage, iv, in, out, length)
KRB5_LOG0(KRB5_INFO, "kg_encrypt() start.");
if (iv) {
- if (code = krb5_c_block_size(context, key->enctype, &blocksize))
+ code = krb5_c_block_size(context, key->enctype, &blocksize);
+ if (code)
return(code);
ivd.length = blocksize;
@@ -146,7 +150,7 @@ kg_encrypt(context, key, usage, iv, in, out, length)
}
inputd.length = length;
- inputd.data = in;
+ inputd.data = (char *)in; /* Solaris Kerberos */
outputd.ciphertext.length = length;
outputd.ciphertext.data = out;
@@ -167,7 +171,7 @@ kg_decrypt(context, key, usage, iv, in, out, length)
krb5_keyblock *key;
int usage;
krb5_pointer iv;
- krb5_pointer in;
+ krb5_const_pointer in;
krb5_pointer out;
unsigned int length;
{
@@ -178,7 +182,8 @@ kg_decrypt(context, key, usage, iv, in, out, length)
KRB5_LOG0(KRB5_INFO, "kg_decrypt() start.");
if (iv) {
- if (code = krb5_c_block_size(context, key->enctype, &blocksize))
+ code = krb5_c_block_size(context, key->enctype, &blocksize);
+ if (code)
return(code);
ivd.length = blocksize;
@@ -193,7 +198,7 @@ kg_decrypt(context, key, usage, iv, in, out, length)
inputd.enctype = ENCTYPE_UNKNOWN;
inputd.ciphertext.length = length;
- inputd.ciphertext.data = in;
+ inputd.ciphertext.data = (char *)in; /* Solaris Kerberos */
outputd.length = length;
outputd.data = out;
@@ -267,7 +272,7 @@ kg_arcfour_docrypt (krb5_context context,
#endif /* _KERNEL */
if (code)
goto cleanup_arcfour;
-
+
input.data = ( void *) kd_data;
input.length = kd_data_len;
output.data = (void *) seq_enc_key.contents;
@@ -280,11 +285,9 @@ kg_arcfour_docrypt (krb5_context context,
if (code)
goto cleanup_arcfour;
-
input.data = ( void * ) input_buf;
input.length = input_len;
-
- output.data = (char *)output_buf;
+ output.data = (void * ) output_buf;
output.length = input_len;
/*
@@ -304,3 +307,4 @@ kg_arcfour_docrypt (krb5_context context,
KRB5_LOG(KRB5_INFO, "kg_arcfour_docrypt() end code = %d", code);
return (code);
}
+
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_ordering.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_ordering.c
index c6796dadf0..546536b0f2 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_ordering.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_ordering.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1993 by OpenVision Technologies, Inc.
@@ -28,7 +27,7 @@
*/
/*
- * $Id: util_ordering.c,v 1.4 1996/10/21 20:17:11 tytso Exp $
+ * $Id: util_ordering.c 19310 2007-03-29 21:36:38Z tlyu $
*/
/*
@@ -41,8 +40,8 @@
* functions to check sequence numbers for replay and sequencing
*/
-#include <mechglueP.h>
-#include <gssapiP_generic.h>
+#include "mechglueP.h"
+#include "gssapiP_generic.h"
#define QUEUE_LENGTH 20
@@ -156,7 +155,7 @@ queue_insert(queue *q, int after, gssint_uint64 seqnum)
q->length++;
}
}
-
+
gss_int32
g_order_init(void **vqueue, gssint_uint64 seqnum,
int do_replay, int do_sequence, int wide_nums)
@@ -164,7 +163,7 @@ g_order_init(void **vqueue, gssint_uint64 seqnum,
queue *q;
if ((q = (queue *) MALLOC(sizeof(queue))) == NULL)
- return (ENOMEM);
+ return(ENOMEM);
q->do_replay = do_replay;
q->do_sequence = do_sequence;
@@ -176,7 +175,7 @@ g_order_init(void **vqueue, gssint_uint64 seqnum,
q->elem[q->start] = ((gssint_uint64)0 - 1) & q->mask;
*vqueue = (void *) q;
- return (0);
+ return(0);
}
gss_int32
@@ -185,11 +184,11 @@ g_order_check(void **vqueue, gssint_uint64 seqnum)
queue *q;
int i;
gssint_uint64 expected;
-
+
q = (queue *) (*vqueue);
if (!q->do_replay && !q->do_sequence)
- return (GSS_S_COMPLETE);
+ return(GSS_S_COMPLETE);
/* All checks are done relative to the initial sequence number, to
avoid (or at least put off) the pain of wrapping. */
@@ -203,34 +202,35 @@ g_order_check(void **vqueue, gssint_uint64 seqnum)
seqnum &= q->mask;
/* rule 1: expected sequence number */
+
expected = (QELEM(q,q->start+q->length-1)+1) & q->mask;
- if (seqnum == expected) {
+ if (seqnum == expected) {
queue_insert(q, q->start+q->length-1, seqnum);
- return (GSS_S_COMPLETE);
+ return(GSS_S_COMPLETE);
}
/* rule 2: > expected sequence number */
if (after(seqnum, expected, q->mask)) {
queue_insert(q, q->start+q->length-1, seqnum);
if (q->do_replay && !q->do_sequence)
- return (GSS_S_COMPLETE);
+ return(GSS_S_COMPLETE);
else
- return (GSS_S_GAP_TOKEN);
+ return(GSS_S_GAP_TOKEN);
}
/* rule 3: seqnum < seqnum(first) */
if (after(QELEM(q,q->start), seqnum, q->mask)) {
if (q->do_replay && !q->do_sequence)
- return (GSS_S_OLD_TOKEN);
+ return(GSS_S_OLD_TOKEN);
else
- return (GSS_S_UNSEQ_TOKEN);
+ return(GSS_S_UNSEQ_TOKEN);
}
/* rule 4+5: seqnum in [seqnum(first),seqnum(last)] */
else {
if (seqnum == QELEM(q,q->start+q->length-1))
- return (GSS_S_DUPLICATE_TOKEN);
+ return(GSS_S_DUPLICATE_TOKEN);
for (i=q->start; i<q->start+q->length-1; i++) {
if (seqnum == QELEM(q,i))
@@ -247,7 +247,7 @@ g_order_check(void **vqueue, gssint_uint64 seqnum)
}
/* this should never happen */
- return (GSS_S_FAILURE);
+ return(GSS_S_FAILURE);
}
void
@@ -271,7 +271,7 @@ gss_uint32
g_queue_size(void *vqueue, size_t *sizep)
{
*sizep += sizeof(queue);
- return (0);
+ return 0;
}
gss_uint32
@@ -281,7 +281,7 @@ g_queue_externalize(void *vqueue, unsigned char **buf, size_t *lenremain)
*buf += sizeof(queue);
*lenremain -= sizeof(queue);
- return (0);
+ return 0;
}
gss_uint32
@@ -295,5 +295,5 @@ g_queue_internalize(void **vqueue, unsigned char **buf, size_t *lenremain)
*buf += sizeof(queue);
*lenremain -= sizeof(queue);
*vqueue = q;
- return (0);
+ return 0;
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_seed.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_seed.c
index da03f37e8a..9d39e49370 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_seed.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_seed.c
@@ -1,5 +1,3 @@
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
@@ -27,7 +25,7 @@
#include <memory.h>
#endif
-static unsigned char zeros[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
+static const unsigned char zeros[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
krb5_error_code
kg_make_seed(context, key, seed)
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_validate.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_validate.c
index a934036880..5138e78288 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_validate.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_validate.c
@@ -1,9 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1993 by OpenVision Technologies, Inc.
@@ -28,7 +27,7 @@
*/
/*
- * $Id: util_validate.c 16475 2004-06-17 02:23:21Z raeburn $
+ * $Id: util_validate.c 18721 2006-10-16 16:18:29Z epeisach $
*/
/*
@@ -51,12 +50,10 @@
#include <limits.h>
#endif
-
#ifdef HAVE_BSD_DB
#include <sys/file.h>
#include <db.h>
-
static const int one = 1;
static const DBT dbtone = { (void *) &one, sizeof(one) };
@@ -133,7 +130,6 @@ static int g_save(db, type, ptr)
/* SUNW15resync */
ret = (g_set_entry_add(gs, ptr, (void *)(intptr_t)type) == 0);
-
(void) k5_mutex_unlock(&db->mutex);
return ret;
#endif
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/verify.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/verify.c
index 8fe69387e6..4994e6d6c5 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/verify.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/verify.c
@@ -1,10 +1,8 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
@@ -70,10 +68,9 @@ krb5_gss_verify_mic(minor_status, context_handle,
OM_uint32 rstat;
int qstate;
-
rstat = kg_unseal(minor_status, context_handle,
- token_buffer, message_buffer,
- NULL, &qstate, KG_TOK_MIC_MSG);
+ token_buffer, message_buffer,
+ NULL, &qstate, KG_TOK_MIC_MSG);
if (!rstat && qop_state)
*qop_state = (gss_qop_t) qstate;
return(rstat);