summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/lib/gssapi
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/lib/gssapi')
-rw-r--r--crypto/heimdal/lib/gssapi/ChangeLog2970
-rw-r--r--crypto/heimdal/lib/gssapi/Makefile.am358
-rw-r--r--crypto/heimdal/lib/gssapi/Makefile.in2544
-rw-r--r--crypto/heimdal/lib/gssapi/gss-commands.in59
-rw-r--r--crypto/heimdal/lib/gssapi/gss_acquire_cred.3688
-rw-r--r--crypto/heimdal/lib/gssapi/gssapi.3172
-rw-r--r--crypto/heimdal/lib/gssapi/gssapi.h41
-rw-r--r--crypto/heimdal/lib/gssapi/gssapi/gssapi.h1120
-rw-r--r--crypto/heimdal/lib/gssapi/gssapi/gssapi_krb5.h225
-rw-r--r--crypto/heimdal/lib/gssapi/gssapi/gssapi_ntlm.h41
-rw-r--r--crypto/heimdal/lib/gssapi/gssapi/gssapi_oid.h245
-rw-r--r--crypto/heimdal/lib/gssapi/gssapi/gssapi_spnego.h55
-rw-r--r--crypto/heimdal/lib/gssapi/gssapi_mech.h594
-rw-r--r--crypto/heimdal/lib/gssapi/gsstool.c255
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/8003.c245
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/accept_sec_context.c935
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/acquire_cred.c450
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/add_cred.c239
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/address_to_krb5addr.c77
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/aeap.c102
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/arcfour.c762
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/authorize_localname.c66
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/canonicalize_name.c58
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/ccache_name.c77
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/cfx.c1769
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/cfx.h65
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/compare_name.c53
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/compat.c125
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/context_time.c93
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/copy_ccache.c193
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/creds.c255
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/decapsulate.c207
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/delete_sec_context.c84
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/display_name.c72
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/display_status.c199
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/duplicate_name.c58
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/encapsulate.c153
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/export_name.c92
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/export_sec_context.c238
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/external.c355
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/get_mic.c329
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/gkrb5_err.et31
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/gsskrb5-private.h796
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/gsskrb5_locl.h140
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/import_name.c255
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/import_sec_context.c229
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/indicate_mechs.c55
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/init.c81
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/init_sec_context.c1015
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/inquire_context.c110
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/inquire_cred.c180
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c74
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c81
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c55
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c77
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c605
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/pname_to_uid.c85
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/prf.c148
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/process_context_token.c66
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/release_buffer.c46
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/release_cred.c76
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/release_name.c53
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/sequence.c292
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/set_cred_option.c248
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/set_sec_context_option.c260
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/store_cred.c116
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/test_cfx.c173
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/ticket_flags.c58
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/unwrap.c448
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/verify_mic.c354
-rw-r--r--crypto/heimdal/lib/gssapi/krb5/wrap.c590
-rw-r--r--crypto/heimdal/lib/gssapi/mech/compat.h94
-rw-r--r--crypto/heimdal/lib/gssapi/mech/context.c163
-rw-r--r--crypto/heimdal/lib/gssapi/mech/context.h41
-rw-r--r--crypto/heimdal/lib/gssapi/mech/cred.h57
-rw-r--r--crypto/heimdal/lib/gssapi/mech/doxygen.c132
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_accept_sec_context.c308
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_acquire_cred.c168
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_acquire_cred_ext.c193
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_acquire_cred_with_password.c118
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_add_cred.c186
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_add_cred_with_password.c150
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c84
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_aeap.c216
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_authorize_localname.c187
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_buffer_set.c124
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_canonicalize_name.c111
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_compare_name.c76
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_context_time.c40
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c51
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_cred.c224
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_decapsulate_token.c72
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_delete_name_attribute.c65
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_delete_sec_context.c57
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_display_name.c82
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_display_name_ext.c68
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_display_status.c211
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_duplicate_name.c95
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_duplicate_oid.c68
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_encapsulate_token.c66
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_export_name.c54
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_export_name_composite.c66
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_export_sec_context.c77
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_get_mic.c51
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_get_name_attribute.c81
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_import_name.c291
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_import_sec_context.c82
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_indicate_mechs.c64
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_init_sec_context.c212
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_inquire_context.c105
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_inquire_cred.c195
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c92
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c86
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c76
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_inquire_name.c79
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c73
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c70
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_krb5.c941
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_mech_switch.c438
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_mo.c635
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_names.c110
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_oid.c266
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_oid_equal.c58
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_oid_to_str.c98
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_pname_to_uid.c167
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_process_context_token.c41
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_pseudo_random.c70
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_release_buffer.c42
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_release_cred.c73
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_release_name.c74
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_release_oid.c58
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_release_oid_set.c44
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_seal.c45
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_set_cred_option.c118
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_set_name_attribute.c69
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c70
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_sign.c41
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_store_cred.c94
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c46
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_unseal.c43
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_unwrap.c45
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_utils.c78
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_verify.c42
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_verify_mic.c52
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_wrap.c71
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c52
-rw-r--r--crypto/heimdal/lib/gssapi/mech/gssapi.asn112
-rw-r--r--crypto/heimdal/lib/gssapi/mech/mech.594
-rw-r--r--crypto/heimdal/lib/gssapi/mech/mech.cat561
-rw-r--r--crypto/heimdal/lib/gssapi/mech/mech_locl.h81
-rw-r--r--crypto/heimdal/lib/gssapi/mech/mech_switch.h43
-rw-r--r--crypto/heimdal/lib/gssapi/mech/mechqueue.h97
-rw-r--r--crypto/heimdal/lib/gssapi/mech/name.h48
-rw-r--r--crypto/heimdal/lib/gssapi/mech/utils.h33
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/accept_sec_context.c267
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/acquire_cred.c89
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/add_cred.c60
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/canonicalize_name.c45
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/compare_name.c45
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/context_time.c45
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/creds.c160
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/crypto.c590
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/delete_sec_context.c63
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/display_name.c71
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/display_status.c54
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/duplicate_name.c48
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/export_name.c50
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/export_sec_context.c50
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/external.c137
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/import_name.c112
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/import_sec_context.c48
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/indicate_mechs.c46
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/init_sec_context.c501
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/inquire_context.c68
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/inquire_cred_by_mech.c58
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/inquire_mechs_for_name.c48
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/inquire_names_for_mech.c51
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/inquire_sec_context_by_oid.c90
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/iter_cred.c99
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/kdc.c438
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/ntlm-private.h282
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/ntlm.h145
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/process_context_token.c44
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/release_cred.c63
-rw-r--r--crypto/heimdal/lib/gssapi/ntlm/release_name.c52
-rw-r--r--crypto/heimdal/lib/gssapi/spnego/accept_sec_context.c917
-rw-r--r--crypto/heimdal/lib/gssapi/spnego/compat.c317
-rw-r--r--crypto/heimdal/lib/gssapi/spnego/context_stubs.c815
-rw-r--r--crypto/heimdal/lib/gssapi/spnego/cred_stubs.c273
-rw-r--r--crypto/heimdal/lib/gssapi/spnego/external.c161
-rw-r--r--crypto/heimdal/lib/gssapi/spnego/init_sec_context.c660
-rw-r--r--crypto/heimdal/lib/gssapi/spnego/spnego-private.h323
-rw-r--r--crypto/heimdal/lib/gssapi/spnego/spnego.asn163
-rw-r--r--crypto/heimdal/lib/gssapi/spnego/spnego.opt1
-rw-r--r--crypto/heimdal/lib/gssapi/spnego/spnego_locl.h111
-rw-r--r--crypto/heimdal/lib/gssapi/test_acquire_cred.c329
-rw-r--r--crypto/heimdal/lib/gssapi/test_common.c73
-rw-r--r--crypto/heimdal/lib/gssapi/test_common.h36
-rw-r--r--crypto/heimdal/lib/gssapi/test_context.c970
-rw-r--r--crypto/heimdal/lib/gssapi/test_cred.c230
-rw-r--r--crypto/heimdal/lib/gssapi/test_kcred.c186
-rw-r--r--crypto/heimdal/lib/gssapi/test_names.c238
-rw-r--r--crypto/heimdal/lib/gssapi/test_ntlm.c337
-rw-r--r--crypto/heimdal/lib/gssapi/test_oid.c71
-rw-r--r--crypto/heimdal/lib/gssapi/version-script.map196
205 files changed, 43452 insertions, 0 deletions
diff --git a/crypto/heimdal/lib/gssapi/ChangeLog b/crypto/heimdal/lib/gssapi/ChangeLog
new file mode 100644
index 0000000..5c25d69
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ChangeLog
@@ -0,0 +1,2970 @@
+2008-08-14 Love Hornquist Astrand <lha@10a140laptop.local>
+
+ * krb5/accept_sec_context.c: If there is a initiator subkey, copy
+ that to acceptor subkey to match windows behavior. From Metze.
+
+2008-08-02 Love Hörnquist Åstrand <lha@h5l.org>
+
+ * ntlm/init_sec_context.c: Catch error
+
+ * krb5/inquire_sec_context_by_oid.c: Catch store failure.
+
+ * mech/gss_canonicalize_name.c: Not init m, return never
+ used (overwritten later).
+
+2008-07-25 Love Hörnquist Åstrand <lha@kth.se>
+
+ * ntlm/init_sec_context.c: Use krb5_cc_get_config.
+
+2008-07-25 Love Hörnquist Åstrand <lha@kth.se>
+
+ * krb5/init_sec_context.c: Match the orignal patch I got from
+ metze, seems that DCE-STYLE is even more weirer then what I though
+ when I merged the patch.
+
+2008-06-02 Love Hörnquist Åstrand <lha@kth.se>
+
+ * krb5/init_sec_context.c: Don't add asn1 wrapping to token when
+ using DCE_STYLE. Patch from Stefan Metzmacher.
+
+2008-05-27 Love Hörnquist Åstrand <lha@kth.se>
+
+ * ntlm/init_sec_context.c: use krb5_get_error_message
+
+2008-05-05 Love Hörnquist Åstrand <lha@kth.se>
+
+ * spnego/spnego_locl.h: Add back "mech/utils.h", its needed for
+ oid/buffer functions.
+
+2008-05-02 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * spnego: Changes from doug barton to make spnego indepedant of
+ the heimdal version of the plugin system.
+
+2008-04-27 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5: use DES_set_key_unchecked()
+
+2008-04-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * add __declspec() for windows.
+
+2008-04-15 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/import_sec_context.c: Use tmp to read ac->flags value to
+ avoid warning.
+
+2008-04-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_mech_switch.c: Use unsigned where appropriate.
+
+2008-03-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_context.c: Add test for gsskrb5_register_acceptor_identity.
+
+2008-03-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/init_sec_context.c (init_auth): use right variable to
+ detect if we want to free or not.
+
+2008-02-26 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: add missing \
+
+ * Makefile.am: reshuffle depenencies
+
+ * Add flag to krb5 to not add GSS-API INT|CONF to the negotiation
+
+2008-02-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * make the SPNEGO mech store the error itself instead, works for
+ everything except other stackable mechs
+
+2008-02-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * spnego/init_sec_context.c (spnego_reply): if the reply token was
+ of length 0, make it the same as no token. Pointed out by Zeqing
+ Xia.
+
+ * krb5/acquire_cred.c (acquire_initiator_cred): handle the
+ credential cache better, use destroy/close when appriate and for
+ all cases. Thanks to Michael Allen for point out the memory-leak
+ that I also fixed.
+
+2008-02-03 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * spnego/accept_sec_context.c: Make error reporting somewhat more
+ correct for SPNEGO.
+
+2008-01-27 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_common.c: Improve the error message.
+
+2008-01-24 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/accept_sec_context.c: Avoid free-ing type1 message before
+ its allocated.
+
+2008-01-13 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_ntlm.c: Test source name (and make the acceptor in ntlm gss
+ mech useful).
+
+2007-12-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/init_sec_context.c: Don't confuse target name and source
+ name, make regressiont tests pass again.
+
+2007-12-29 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm: clean up name handling
+
+2007-12-04 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/init_sec_context.c: Use credential if it was passed in.
+
+ * ntlm/acquire_cred.c: Check if there is initial creds with
+ _gss_ntlm_get_user_cred().
+
+ * ntlm/init_sec_context.c: Add _gss_ntlm_get_user_info() that
+ return the user info so it can be used by external modules.
+
+ * ntlm/inquire_cred.c: use the right error code.
+
+ * ntlm/inquire_cred.c: Return GSS_C_NO_CREDENTIAL if there is no
+ credential, ntlm have (not yet) a default credential.
+
+ * mech/gss_release_oid_set.c: Avoid trying to deref NULL, from
+ Phil Fisher.
+
+2007-12-03 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_acquire_cred.c: Always try to fetch cred (even with
+ GSS_C_NO_NAME).
+
+2007-08-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_krb5.c: Readd gss_krb5_get_tkt_flags.
+
+2007-08-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * spnego/compat.c (_gss_spnego_internal_delete_sec_context):
+ release ctx->target_name too From Rafal Malinowski.
+
+2007-07-26 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_mech_switch.c: Don't try to do dlopen if system doesn't
+ have dlopen. From Rune of Chalmers.
+
+2007-07-10 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_duplicate_name.c: New signature of _gss_find_mn.
+
+ * mech/gss_init_sec_context.c: New signature of _gss_find_mn.
+
+ * mech/gss_acquire_cred.c: New signature of _gss_find_mn.
+
+ * mech/name.h: New signature of _gss_find_mn.
+
+ * mech/gss_canonicalize_name.c: New signature of _gss_find_mn.
+
+ * mech/gss_compare_name.c: New signature of _gss_find_mn.
+
+ * mech/gss_add_cred.c: New signature of _gss_find_mn.
+
+ * mech/gss_names.c (_gss_find_mn): Return an error code for
+ caller.
+
+ * spnego/accept_sec_context.c: remove checks that are done by the
+ previous function.
+
+ * Makefile.am: New library version.
+
+2007-07-04 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_oid_to_str.c: Refuse to print GSS_C_NULL_OID, from
+ Rafal Malinowski.
+
+ * spnego/spnego.asn1: Indent and make NegTokenInit and
+ NegTokenResp extendable.
+
+2007-06-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/inquire_cred.c: Implement _gss_ntlm_inquire_cred.
+
+ * mech/gss_display_status.c: Provide message for GSS_S_COMPLETE.
+
+ * mech/context.c: If the canned string is "", its no use to the
+ user, make it fall back to the default error string.
+
+2007-06-20 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_display_name.c (gss_display_name): no name ->
+ fail. From Rafal Malinswski.
+
+ * spnego/accept_sec_context.c: Wrap name in a spnego_name instead
+ of just a copy of the underlaying object. From Rafal Malinswski.
+
+ * spnego/accept_sec_context.c: Handle underlaying mech not
+ returning mn.
+
+ * mech/gss_accept_sec_context.c: Handle underlaying mech not
+ returning mn.
+
+ * spnego/accept_sec_context.c: Make sure src_name is always set to
+ GSS_C_NO_NAME when returning.
+
+ * krb5/acquire_cred.c (acquire_acceptor_cred): don't claim
+ everything is well on failure. From Phil Fisher.
+
+ * mech/gss_duplicate_name.c: catch error (and ignore it)
+
+ * ntlm/init_sec_context.c: Use heim_ntlm_calculate_ntlm2_sess.
+
+ * mech/gss_accept_sec_context.c: Only wrap the delegated cred if
+ we got a delegated mech cred. From Rafal Malinowski.
+
+ * spnego/accept_sec_context.c: Only wrap the delegated cred if we
+ are going to return it to the consumer. From Rafal Malinowski.
+
+ * spnego/accept_sec_context.c: Fixed memory leak pointed out by
+ Rafal Malinowski, also while here moved to use NegotiationToken
+ for decoding.
+
+2007-06-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/prf.c (_gsskrb5_pseudo_random): add missing break.
+
+ * krb5/release_name.c: Set *minor_status unconditionallty, its
+ done later anyway.
+
+ * spnego/accept_sec_context.c: Init get_mic to 0.
+
+ * mech/gss_set_cred_option.c: Free memory in failure case, found
+ by beam.
+
+ * mech/gss_inquire_context.c: Handle mech_type being NULL.
+
+ * mech/gss_inquire_cred_by_mech.c: Handle cred_name being NULL.
+
+ * mech/gss_krb5.c: Free memory in error case, found by beam.
+
+2007-06-12 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/inquire_context.c: Use ctx->gssflags for flags.
+
+ * krb5/display_name.c: Use KRB5_PRINCIPAL_UNPARSE_DISPLAY, this is
+ not ment for machine consumption.
+
+2007-06-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/digest.c (kdc_alloc): free memory on failure, pointed out
+ by Rafal Malinowski.
+
+ * ntlm/digest.c (kdc_destroy): free context when done, pointed out
+ by Rafal Malinowski.
+
+ * spnego/context_stubs.c (_gss_spnego_display_name): if input_name
+ is null, fail. From Rafal Malinowski.
+
+2007-06-04 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/digest.c: Free memory when done.
+
+2007-06-02 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_ntlm.c: Test both with and without keyex.
+
+ * ntlm/digest.c: If we didn't set session key, don't expect one
+ back.
+
+ * test_ntlm.c: Set keyex flag and calculate session key.
+
+2007-05-31 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * spnego/accept_sec_context.c: Use the return value before is
+ overwritten by later calls. From Rafal Malinowski
+
+ * krb5/release_cred.c: Give an minor_status argument to
+ gss_release_oid_set. From Rafal Malinowski
+
+2007-05-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/accept_sec_context.c: Catch errors and return the up the
+ stack.
+
+ * test_kcred.c: more testing of lifetimes
+
+2007-05-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: Drop the gss oid_set function for the krb5 mech,
+ use the mech glue versions instead. Pointed out by Rafal
+ Malinowski.
+
+ * krb5: Use gss oid_set functions from mechglue
+
+2007-05-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/accept_sec_context.c: Set session key only if we are
+ returned a session key. Found by David Love.
+
+2007-05-13 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/prf.c: switched MIN to min to make compile on solaris,
+ pointed out by David Love.
+
+2007-05-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/inquire_cred_by_mech.c: Fill in all of the variables if
+ they are passed in. Pointed out by Phil Fisher.
+
+2007-05-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/inquire_cred.c: Fix copy and paste error, bug spotted by
+ from Phil Fisher.
+
+ * mech: dont keep track of gc_usage, just figure it out at
+ gss_inquire_cred() time
+
+ * mech/gss_mech_switch.c (add_builtin): ok for
+ __gss_mech_initialize() to return NULL
+
+ * test_kcred.c: more correct tests
+
+ * spnego/cred_stubs.c (gss_inquire_cred*): wrap the name with a
+ spnego_name.
+
+ * ntlm/inquire_cred.c: make ntlm gss_inquire_cred fail for now,
+ need to find default cred and friends.
+
+ * krb5/inquire_cred_by_mech.c: reimplement
+
+2007-05-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/acquire_cred.c: drop unused variable.
+
+ * ntlm/acquire_cred.c: Reimplement.
+
+ * Makefile.am: add ntlm/digest.c
+
+ * ntlm: split out backend ntlm server processing
+
+2007-04-24 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/delete_sec_context.c (_gss_ntlm_delete_sec_context): free
+ credcache when done
+
+2007-04-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/init_sec_context.c: ntlm-key credential entry is prefix with @
+
+ * ntlm/init_sec_context.c (get_user_ccache): pick up the ntlm
+ creds from the krb5 credential cache.
+
+2007-04-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/delete_sec_context.c: free the key stored in the context
+
+ * ntlm/ntlm.h: switch password for a key
+
+ * test_oid.c: Switch oid to one that is exported.
+
+2007-04-20 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/init_sec_context.c: move where hash is calculated to make
+ it easier to add ccache support.
+
+ * Makefile.am: Add version-script.map to EXTRA_DIST.
+
+2007-04-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: Unconfuse newer versions of automake that doesn't
+ know the diffrence between depenences and setting variables. foo:
+ vs foo=.
+
+ * test_ntlm.c: delete sec context when done.
+
+ * version-script.map: export more symbols.
+
+ * Makefile.am: add version script if ld supports it
+
+ * version-script.map: add version script if ld supports it
+
+2007-04-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: test_acquire_cred need test_common.[ch]
+
+ * test_acquire_cred.c: add more test options.
+
+ * krb5/external.c: add GSS_KRB5_CCACHE_NAME_X
+
+ * gssapi/gssapi_krb5.h: add GSS_KRB5_CCACHE_NAME_X
+
+ * krb5/set_sec_context_option.c: refactor code, implement
+ GSS_KRB5_CCACHE_NAME_X
+
+ * mech/gss_krb5.c: reimplement gss_krb5_ccache_name
+
+2007-04-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * spnego/cred_stubs.c: Need to import spnego name before we can
+ use it as a gss_name_t.
+
+ * test_acquire_cred.c: use this test as part of the regression
+ suite.
+
+ * mech/gss_acquire_cred.c (gss_acquire_cred): dont init
+ cred->gc_mc every time in the loop.
+
+2007-04-15 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: add test_common.h
+
+2007-02-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: Add link for
+ gsskrb5_register_acceptor_identity.
+
+2007-02-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/copy_ccache.c: Try to leak less memory in the failure case.
+
+2007-01-31 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_display_status.c: Use right printf formater.
+
+ * test_*.[ch]: split out the error printing function and try to
+ return better errors
+
+2007-01-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/init_sec_context.c: revert 1.75: (init_auth): only turn on
+ GSS_C_CONF_FLAG and GSS_C_INT_FLAG if the caller requseted it.
+
+ This is because Kerberos always support INT|CONF, matches behavior
+ with MS and MIT. The creates problems for the GSS-SPNEGO mech.
+
+2007-01-24 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/prf.c: constrain desired_output_len
+
+ * krb5/external.c (krb5_mech): add _gsskrb5_pseudo_random
+
+ * mech/gss_pseudo_random.c: Catch error from underlaying mech on
+ failure.
+
+ * Makefile.am: Add krb5/prf.c
+
+ * krb5/prf.c: gss_pseudo_random for krb5
+
+ * test_context.c: Checks for gss_pseudo_random.
+
+ * krb5/gkrb5_err.et: add KG_INPUT_TOO_LONG
+
+ * Makefile.am: Add mech/gss_pseudo_random.c
+
+ * gssapi/gssapi.h: try to load pseudo_random
+
+ * mech/gss_mech_switch.c: try to load pseudo_random
+
+ * mech/gss_pseudo_random.c: Add gss_pseudo_random.
+
+ * gssapi_mech.h: Add hook for gm_pseudo_random.
+
+2007-01-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_context.c: Don't assume bufer from gss_display_status is
+ ok.
+
+ * mech/gss_wrap_size_limit.c: Reset out variables.
+
+ * mech/gss_wrap.c: Reset out variables.
+
+ * mech/gss_verify_mic.c: Reset out variables.
+
+ * mech/gss_utils.c: Reset out variables.
+
+ * mech/gss_release_oid_set.c: Reset out variables.
+
+ * mech/gss_release_cred.c: Reset out variables.
+
+ * mech/gss_release_buffer.c: Reset variables.
+
+ * mech/gss_oid_to_str.c: Reset out variables.
+
+ * mech/gss_inquire_sec_context_by_oid.c: Fix reset out variables.
+
+ * mech/gss_mech_switch.c: Reset out variables.
+
+ * mech/gss_inquire_sec_context_by_oid.c: Reset out variables.
+
+ * mech/gss_inquire_names_for_mech.c: Reset out variables.
+
+ * mech/gss_inquire_cred_by_oid.c: Reset out variables.
+
+ * mech/gss_inquire_cred_by_oid.c: Reset out variables.
+
+ * mech/gss_inquire_cred_by_mech.c: Reset out variables.
+
+ * mech/gss_inquire_cred.c: Reset out variables, fix memory leak.
+
+ * mech/gss_inquire_context.c: Reset out variables.
+
+ * mech/gss_init_sec_context.c: Zero out outbuffer on failure.
+
+ * mech/gss_import_name.c: Reset out variables.
+
+ * mech/gss_import_name.c: Reset out variables.
+
+ * mech/gss_get_mic.c: Reset out variables.
+
+ * mech/gss_export_name.c: Reset out variables.
+
+ * mech/gss_encapsulate_token.c: Reset out variables.
+
+ * mech/gss_duplicate_oid.c: Reset out variables.
+
+ * mech/gss_duplicate_oid.c: Reset out variables.
+
+ * mech/gss_duplicate_name.c: Reset out variables.
+
+ * mech/gss_display_status.c: Reset out variables.
+
+ * mech/gss_display_name.c: Reset out variables.
+
+ * mech/gss_delete_sec_context.c: Reset out variables using propper
+ macros.
+
+ * mech/gss_decapsulate_token.c: Reset out variables using propper
+ macros.
+
+ * mech/gss_add_cred.c: Reset out variables.
+
+ * mech/gss_acquire_cred.c: Reset out variables.
+
+ * mech/gss_accept_sec_context.c: Reset out variables using propper
+ macros.
+
+ * mech/gss_init_sec_context.c: Reset out variables.
+
+ * mech/mech_locl.h (_mg_buffer_zero): new macro that zaps a
+ gss_buffer_t
+
+2007-01-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech: sprinkel _gss_mg_error
+
+ * mech/gss_display_status.c (gss_display_status): use
+ _gss_mg_get_error to fetch the error from underlaying mech, if it
+ failes, let do the regular dance for GSS-CODE version and a
+ generic print-the-error code for MECH-CODE.
+
+ * mech/gss_oid_to_str.c: Don't include the NUL in the length of
+ the string.
+
+ * mech/context.h: Protoypes for _gss_mg_.
+
+ * mech/context.c: Glue to catch the error from the lower gss-api
+ layer and save that for later so gss_display_status() can show the
+ error.
+
+ * gss.c: Detect NTLM.
+
+2007-01-11 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_accept_sec_context.c: spelling
+
+2007-01-04 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: Include build (private) prototypes header files.
+
+ * Makefile.am (ntlmsrc): add ntlm/ntlm-private.h
+
+2006-12-28 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/accept_sec_context.c: Pass signseal argument to
+ _gss_ntlm_set_key.
+
+ * ntlm/init_sec_context.c: Pass signseal argument to
+ _gss_ntlm_set_key.
+
+ * ntlm/crypto.c (_gss_ntlm_set_key): add signseal argument
+
+ * test_ntlm.c: add ntlmv2 test
+
+ * ntlm/ntlm.h: break out struct ntlmv2_key;
+
+ * ntlm/crypto.c (_gss_ntlm_set_key): set ntlm v2 keys.
+
+ * ntlm/accept_sec_context.c: Set dummy ntlmv2 keys and Check TI.
+
+ * ntlm/ntlm.h: NTLMv2 keys.
+
+ * ntlm/crypto.c: NTLMv2 sign and verify.
+
+2006-12-20 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/accept_sec_context.c: Don't send targetinfo now.
+
+ * ntlm/init_sec_context.c: Build ntlmv2 answer buffer.
+
+ * ntlm/init_sec_context.c: Leak less memory.
+
+ * ntlm/init_sec_context.c: Announce that we support key exchange.
+
+ * ntlm/init_sec_context.c: Add NTLM_NEG_NTLM2_SESSION, NTLMv2
+ session security (disable because missing sign and seal).
+
+2006-12-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/accept_sec_context.c: split RC4 send and recv keystreams
+
+ * ntlm/init_sec_context.c: split RC4 send and recv keystreams
+
+ * ntlm/ntlm.h: split RC4 send and recv keystreams
+
+ * ntlm/crypto.c: Implement SEAL.
+
+ * ntlm/crypto.c: move gss_wrap/gss_unwrap here
+
+ * test_context.c: request INT and CONF from the gss layer, test
+ get and verify MIC.
+
+ * ntlm/ntlm.h: add crypto bits.
+
+ * ntlm/accept_sec_context.c: Save session master key.
+
+ * Makefile.am: Move get and verify mic to the same file (crypto.c)
+ since they share code.
+
+ * ntlm/crypto.c: Move get and verify mic to the same file since
+ they share code, implement NTLM v1 and dummy signatures.
+
+ * ntlm/init_sec_context.c: pass on GSS_C_CONF_FLAG and
+ GSS_C_INTEG_FLAG, save the session master key
+
+ * spnego/accept_sec_context.c: try using gss_accept_sec_context()
+ on the opportunistic token instead of guessing the acceptor name
+ and do gss_acquire_cred, this make SPNEGO work like before.
+
+2006-12-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/init_sec_context.c: Calculate the NTLM version 1 "master"
+ key.
+
+ * spnego/accept_sec_context.c: Resurect negHints for the acceptor
+ sends first packet.
+
+ * Makefile.am: Add "windows" versions of the NegTokenInitWin and
+ friends.
+
+ * test_context.c: add --wrapunwrap flag
+
+ * spnego/compat.c: move _gss_spnego_indicate_mechtypelist() to
+ compat.c, use the sequence types of MechTypeList, make
+ add_mech_type() static.
+
+ * spnego/accept_sec_context.c: move
+ _gss_spnego_indicate_mechtypelist() to compat.c
+
+ * Makefile.am: Generate sequence code for MechTypeList
+
+ * spnego: check that the generated acceptor mechlist is acceptable too
+
+ * spnego/init_sec_context.c: Abstract out the initiator filter
+ function, it will be needed for the acceptor too.
+
+ * spnego/accept_sec_context.c: Abstract out the initiator filter
+ function, it will be needed for the acceptor too. Remove negHints.
+
+ * test_context.c: allow asserting return mech
+
+ * ntlm/accept_sec_context.c: add _gss_ntlm_allocate_ctx
+
+ * ntlm/acquire_cred.c: Check that the KDC seem to there and
+ answering us, we can't do better then that wen checking if we will
+ accept the credential.
+
+ * ntlm/get_mic.c: return GSS_S_UNAVAILABLE
+
+ * mech/utils.h: add _gss_free_oid, reverse of _gss_copy_oid
+
+ * mech/gss_utils.c: add _gss_free_oid, reverse of _gss_copy_oid
+
+ * spnego/spnego.asn1: Its very sad, but NegHints its are not part
+ of the NegTokenInit, this makes SPNEGO acceptor life a lot harder.
+
+ * spnego: try harder to handle names better. handle missing
+ acceptor and initator creds better (ie dont propose/accept mech
+ that there are no credentials for) split NegTokenInit and
+ NegTokenResp in acceptor
+
+2006-12-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/import_name.c: Allocate the buffer from the right length.
+
+2006-12-15 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ntlm/init_sec_context.c (init_sec_context): Tell the other side
+ what domain we think we are talking to.
+
+ * ntlm/delete_sec_context.c: free username and password
+
+ * ntlm/release_name.c (_gss_ntlm_release_name): free name.
+
+ * ntlm/import_name.c (_gss_ntlm_import_name): add support for
+ GSS_C_NT_HOSTBASED_SERVICE names
+
+ * ntlm/ntlm.h: Add ntlm_name.
+
+ * test_context.c: allow testing of ntlm.
+
+ * gssapi_mech.h: add __gss_ntlm_initialize
+
+ * ntlm/accept_sec_context.c (handle_type3): verify that the kdc
+ approved of the ntlm exchange too
+
+ * mech/gss_mech_switch.c: Add the builtin ntlm mech
+
+ * test_ntlm.c: NTLM test app.
+
+ * mech/gss_accept_sec_context.c: Add detection of NTLMSSP.
+
+ * gssapi/gssapi.h: add ntlm mech oid
+
+ * ntlm/external.c: Switch OID to the ms ntlmssp oid
+
+ * Makefile.am: Add ntlm gss-api module.
+
+ * ntlm/accept_sec_context.c: Catch more error errors.
+
+ * ntlm/accept_sec_context.c: Check after a credential to use.
+
+2006-12-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/set_sec_context_option.c (GSS_KRB5_SET_DEFAULT_REALM_X):
+ don't fail on success. Bug report from Stefan Metzmacher.
+
+2006-12-13 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/init_sec_context.c (init_auth): only turn on
+ GSS_C_CONF_FLAG and GSS_C_INT_FLAG if the caller requseted it.
+ From Stefan Metzmacher.
+
+2006-12-11 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am (libgssapi_la_OBJECTS): depends on gssapi_asn1.h
+ spnego_asn1.h.
+
+2006-11-20 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/acquire_cred.c: Make krb5_get_init_creds_opt_free take a
+ context argument.
+
+2006-11-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_context.c: Test that token keys are the same, return
+ actual_mech.
+
+2006-11-15 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * spnego/spnego_locl.h: Make bitfields unsigned, add maybe_open.
+
+ * spnego/accept_sec_context.c: Use ASN.1 encoder functions to
+ encode CHOICE structure now that we can handle it.
+
+ * spnego/init_sec_context.c: Use ASN.1 encoder functions to encode
+ CHOICE structure now that we can handle it.
+
+ * spnego/accept_sec_context.c (_gss_spnego_accept_sec_context):
+ send back ad accept_completed when the security context is ->open,
+ w/o this the client doesn't know that the server have completed
+ the transaction.
+
+ * test_context.c: Add delegate flag and check that the delegated
+ cred works.
+
+ * spnego/init_sec_context.c: Keep track of the opportunistic token
+ in the inital message, it might be a complete gss-api context, in
+ that case we'll get back accept_completed without any token. With
+ this change, krb5 w/o mutual authentication works.
+
+ * spnego/accept_sec_context.c: Use ASN.1 encoder functions to
+ encode CHOICE structure now that we can handle it.
+
+ * spnego/accept_sec_context.c: Filter out SPNEGO from the out
+ supported mechs list and make sure we don't select that for the
+ preferred mechamism.
+
+2006-11-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_init_sec_context.c (_gss_mech_cred_find): break out the
+ cred finding to its own function
+
+ * krb5/wrap.c: Better error strings, from Andrew Bartlet.
+
+2006-11-13 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_context.c: Create our own krb5_context.
+
+ * krb5: Switch from using a specific error message context in the
+ TLS to have a whole krb5_context in TLS. This have some
+ interestion side-effekts for the configruration setting options
+ since they operate on per-thread basis now.
+
+ * mech/gss_set_cred_option.c: When calling ->gm_set_cred_option
+ and checking for success, use GSS_S_COMPLETE. From Andrew Bartlet.
+
+2006-11-12 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: Help solaris make even more.
+
+ * Makefile.am: Help solaris make.
+
+2006-11-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: remove include $(srcdir)/Makefile-digest.am for now
+
+ * mech/gss_accept_sec_context.c: Try better guessing what is mech
+ we are going to select by looking harder at the input_token, idea
+ from Luke Howard's mechglue branch.
+
+ * Makefile.am: libgssapi_la_OBJECTS: add depency on gkrb5_err.h
+
+ * gssapi/gssapi_krb5.h: add GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X
+
+ * mech/gss_krb5.c: implement gss_krb5_set_allowable_enctypes
+
+ * gssapi/gssapi.h: GSS_KRB5_S_
+
+ * krb5/gsskrb5_locl.h: Include <gkrb5_err.h>.
+
+ * gssapi/gssapi_krb5.h: Add gss_krb5_set_allowable_enctypes.
+
+ * Makefile.am: Build and install gkrb5_err.h
+
+ * krb5/gkrb5_err.et: Move the GSS_KRB5_S error here.
+
+2006-11-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_krb5.c: Add gsskrb5_set_default_realm.
+
+ * krb5/set_sec_context_option.c: Support
+ GSS_KRB5_SET_DEFAULT_REALM_X.
+
+ * gssapi/gssapi_krb5.h: add GSS_KRB5_SET_DEFAULT_REALM_X
+
+ * krb5/external.c: add GSS_KRB5_SET_DEFAULT_REALM_X
+
+2006-11-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_context.c: rename krb5_[gs]et_time_wrap to
+ krb5_[gs]et_max_time_skew
+
+ * krb5/copy_ccache.c: _gsskrb5_extract_authz_data_from_sec_context
+ no longer used, bye bye
+
+ * mech/gss_krb5.c: No depenency of the krb5 gssapi mech.
+
+ * mech/gss_krb5.c (gsskrb5_extract_authtime_from_sec_context): use
+ _gsskrb5_decode_om_uint32. From Andrew Bartlet.
+
+ * mech/gss_krb5.c: Add dummy gss_krb5_set_allowable_enctypes for
+ now.
+
+ * spnego/spnego_locl.h: Include <roken.h> for compatiblity.
+
+ * krb5/arcfour.c: Use IS_DCE_STYLE flag. There is no padding in
+ DCE-STYLE, don't try to use to. From Andrew Bartlett.
+
+ * test_context.c: test wrap/unwrap, add flag for dce-style and
+ mutual auth, also support multi-roundtrip sessions
+
+ * krb5/gsskrb5_locl.h: Add IS_DCE_STYLE macro.
+
+ * krb5/accept_sec_context.c (gsskrb5_acceptor_start): use
+ krb5_rd_req_ctx
+
+ * mech/gss_krb5.c (gsskrb5_get_subkey): return the per message
+ token subkey
+
+ * krb5/inquire_sec_context_by_oid.c: check if there is any key at
+ all
+
+2006-11-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/inquire_sec_context_by_oid.c: Set more error strings, use
+ right enum for acceptor subkey. From Andrew Bartlett.
+
+2006-11-04 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_context.c: Test gsskrb5_extract_service_keyblock, needed in
+ PAC valication. From Andrew Bartlett
+
+ * mech/gss_krb5.c: Add gsskrb5_extract_authz_data_from_sec_context
+ and keyblock extraction functions.
+
+ * gssapi/gssapi_krb5.h: Add extraction of keyblock function, from
+ Andrew Bartlett.
+
+ * krb5/external.c: Add GSS_KRB5_GET_SERVICE_KEYBLOCK_X
+
+2006-11-03 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_context.c: Rename various routines and constants from
+ canonize to canonicalize. From Andrew Bartlett
+
+ * mech/gss_krb5.c: Rename various routines and constants from
+ canonize to canonicalize. From Andrew Bartlett
+
+ * krb5/set_sec_context_option.c: Rename various routines and
+ constants from canonize to canonicalize. From Andrew Bartlett
+
+ * krb5/external.c: Rename various routines and constants from
+ canonize to canonicalize. From Andrew Bartlett
+
+ * gssapi/gssapi_krb5.h: Rename various routines and constants from
+ canonize to canonicalize. From Andrew Bartlett
+
+2006-10-25 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/accept_sec_context.c (gsskrb5_accept_delegated_token): need
+ to free ccache
+
+2006-10-24 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_context.c (loop): free target_name
+
+ * mech/gss_accept_sec_context.c: SLIST_INIT the ->gc_mc'
+
+ * mech/gss_acquire_cred.c : SLIST_INIT the ->gc_mc'
+
+ * krb5/init_sec_context.c: Avoid leaking memory.
+
+ * mech/gss_buffer_set.c (gss_release_buffer_set): don't leak the
+ ->elements memory.
+
+ * test_context.c: make compile
+
+ * krb5/cfx.c (_gssapi_verify_mic_cfx): always free crypto context.
+
+ * krb5/set_cred_option.c (import_cred): free sp
+
+2006-10-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_add_oid_set_member.c: Use old implementation of
+ gss_add_oid_set_member, it leaks less memory.
+
+ * krb5/test_cfx.c: free krb5_crypto.
+
+ * krb5/test_cfx.c: free krb5_context
+
+ * mech/gss_release_name.c (gss_release_name): free input_name
+ it-self.
+
+2006-10-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_context.c: Call setprogname.
+
+ * mech/gss_krb5.c: Add gsskrb5_extract_authtime_from_sec_context.
+
+ * gssapi/gssapi_krb5.h: add
+ gsskrb5_extract_authtime_from_sec_context
+
+2006-10-20 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/inquire_sec_context_by_oid.c: Add get_authtime.
+
+ * krb5/external.c: add GSS_KRB5_GET_AUTHTIME_X
+
+ * gssapi/gssapi_krb5.h: add GSS_KRB5_GET_AUTHTIME_X
+
+ * krb5/set_sec_context_option.c: Implement GSS_KRB5_SEND_TO_KDC_X.
+
+ * mech/gss_krb5.c: Add gsskrb5_set_send_to_kdc
+
+ * gssapi/gssapi_krb5.h: Add GSS_KRB5_SEND_TO_KDC_X and
+ gsskrb5_set_send_to_kdc
+
+ * krb5/external.c: add GSS_KRB5_SEND_TO_KDC_X
+
+ * Makefile.am: more files
+
+2006-10-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: remove spnego/gssapi_spnego.h, its now in gssapi/
+
+ * test_context.c: Allow specifing mech.
+
+ * krb5/external.c: add GSS_SASL_DIGEST_MD5_MECHANISM (for now)
+
+ * gssapi/gssapi.h: Rename GSS_DIGEST_MECHANISM to
+ GSS_SASL_DIGEST_MD5_MECHANISM
+
+2006-10-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gssapi.asn1: Make it into a heim_any_set, its doesn't
+ except a tag.
+
+ * mech/gssapi.asn1: GSSAPIContextToken is IMPLICIT SEQUENCE
+
+ * gssapi/gssapi_krb5.h: add GSS_KRB5_GET_ACCEPTOR_SUBKEY_X
+
+ * krb5/external.c: Add GSS_KRB5_GET_ACCEPTOR_SUBKEY_X.
+
+ * gssapi/gssapi_krb5.h: add GSS_KRB5_GET_INITIATOR_SUBKEY_X and
+ GSS_KRB5_GET_SUBKEY_X
+
+ * krb5/external.c: add GSS_KRB5_GET_INITIATOR_SUBKEY_X,
+ GSS_KRB5_GET_SUBKEY_X
+
+2006-10-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_context.c: Support switching on name type oid's
+
+ * test_context.c: add test for dns canon flag
+
+ * mech/gss_krb5.c: Add gsskrb5_set_dns_canonlize.
+
+ * gssapi/gssapi_krb5.h: remove gss_krb5_compat_des3_mic
+
+ * gssapi/gssapi_krb5.h: Add gsskrb5_set_dns_canonlize.
+
+ * krb5/set_sec_context_option.c: implement
+ GSS_KRB5_SET_DNS_CANONIZE_X
+
+ * gssapi/gssapi_krb5.h: add GSS_KRB5_SET_DNS_CANONIZE_X
+
+ * krb5/external.c: add GSS_KRB5_SET_DNS_CANONIZE_X
+
+ * mech/gss_krb5.c: add bits to make lucid context work
+
+2006-10-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_oid_to_str.c: Prefix der primitives with der_.
+
+ * krb5/inquire_sec_context_by_oid.c: Prefix der primitives with
+ der_.
+
+ * krb5/encapsulate.c: Prefix der primitives with der_.
+
+ * mech/gss_oid_to_str.c: New der_print_heim_oid signature.
+
+2006-10-12 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: add test_context
+
+ * krb5/inquire_sec_context_by_oid.c: Make it work.
+
+ * test_oid.c: Test lucid oid.
+
+ * gssapi/gssapi.h: Add OM_uint64_t.
+
+ * krb5/inquire_sec_context_by_oid.c: Add lucid interface.
+
+ * krb5/external.c: Add lucid interface, renumber oids to my
+ delegated space.
+
+ * mech/gss_krb5.c: Add lucid interface.
+
+ * gssapi/gssapi_krb5.h: Add lucid interface.
+
+ * spnego/spnego_locl.h: Maybe include <netdb.h>.
+
+2006-10-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_mech_switch.c: define RTLD_LOCAL to 0 if not defined.
+
+2006-10-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: install gssapi_krb5.H and gssapi_spnego.h
+
+ * gssapi/gssapi_krb5.h: Move krb5 stuff to <gssapi/gssapi_krb5.h>.
+
+ * gssapi/gssapi.h: Move krb5 stuff to <gssapi/gssapi_krb5.h>.
+
+ * Makefile.am: Drop some -I no longer needed.
+
+ * gssapi/gssapi_spnego.h: Move gssapi_spengo.h over here.
+
+ * krb5: reference all include files using 'krb5/'
+
+2006-10-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi.h: Add file inclusion protection.
+
+ * gssapi/gssapi.h: Correct header file inclusion protection.
+
+ * gssapi/gssapi.h: Move the gssapi.h from lib/gssapi/ to
+ lib/gssapi/gssapi/ to please automake.
+
+ * spnego/spnego_locl.h: Maybe include <sys/types.h>.
+
+ * mech/mech_locl.h: Include <roken.h>.
+
+ * Makefile.am: split build files into dist_ and noinst_ SOURCES
+
+2006-10-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss.c: #if 0 out unused code.
+
+ * mech/gss_mech_switch.c: Cast argument to ctype(3) functions
+ to (unsigned char).
+
+2006-10-05 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/name.h: remove <sys/queue.h>
+
+ * mech/mech_switch.h: remove <sys/queue.h>
+
+ * mech/cred.h: remove <sys/queue.h>
+
+2006-10-02 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/arcfour.c: Thinker more with header lengths.
+
+ * krb5/arcfour.c: Improve the calcucation of header
+ lengths. DCE-STYLE data is also padded so remove if (1 || ...)
+ code.
+
+ * krb5/wrap.c (_gsskrb5_wrap_size_limit): use
+ _gssapi_wrap_size_arcfour for arcfour
+
+ * krb5/arcfour.c: Move _gssapi_wrap_size_arcfour here.
+
+ * Makefile.am: Split all mech to diffrent mechsrc variables.
+
+ * spnego/context_stubs.c: Make internal function static (and
+ rename).
+
+2006-10-01 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/inquire_cred.c: Fix "if (x) lock(y)" bug. From Harald
+ Barth.
+
+ * spnego/spnego_locl.h: Include <sys/param.h> for MAXHOSTNAMELEN.
+
+2006-09-25 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/arcfour.c: Add wrap support, interrop with itself but not
+ w2k3s-sp1
+
+ * krb5/gsskrb5_locl.h: move the arcfour specific stuff to the
+ arcfour header.
+
+ * krb5/arcfour.c: Support DCE-style unwrap, tested with
+ w2k3server-sp1.
+
+ * mech/gss_accept_sec_context.c (gss_accept_sec_context): if the
+ token doesn't start with [APPLICATION 0] SEQUENCE, lets assume its
+ a DCE-style kerberos 5 connection. XXX this needs to be made
+ better in cause we get another GSS-API protocol violating
+ protocol. It should be possible to detach the Kerberos DCE-style
+ since it starts with a AP-REQ PDU, but that have to wait for now.
+
+2006-09-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi.h: Add GSS_C flags from
+ draft-brezak-win2k-krb-rc4-hmac-04.txt.
+
+ * krb5/delete_sec_context.c: Free service_keyblock and fwd_data,
+ indent.
+
+ * krb5/accept_sec_context.c: Merge of the acceptor part from the
+ samba patch by Stefan Metzmacher and Andrew Bartlet.
+
+ * krb5/init_sec_context.c: Add GSS_C_DCE_STYLE.
+
+ * krb5/{init_sec_context.c,gsskrb5_locl.h}: merge most of the
+ initiator part from the samba patch by Stefan Metzmacher and
+ Andrew Bartlet (still missing DCE/RPC support)
+
+2006-08-28 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss.c (help): use sl_slc_help().
+
+2006-07-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss-commands.in: rename command to supported-mechanisms
+
+ * Makefile.am: Make gss objects depend on the slc built
+ gss-commands.h
+
+2006-07-20 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss-commands.in: add slc commands for gss
+
+ * krb5/gsskrb5_locl.h: Remove dup prototype of _gsskrb5_init()
+
+ * Makefile.am: Add test_cfx
+
+ * krb5/external.c: add GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X
+
+ * krb5/set_sec_context_option.c: catch
+ GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X
+
+ * krb5/accept_sec_context.c: reimplement
+ gsskrb5_register_acceptor_identity
+
+ * mech/gss_krb5.c: implement gsskrb5_register_acceptor_identity
+
+ * mech/gss_inquire_mechs_for_name.c: call _gss_load_mech
+
+ * mech/gss_inquire_cred.c (gss_inquire_cred): call _gss_load_mech
+
+ * mech/gss_mech_switch.c: Make _gss_load_mech() atomic and run
+ only once, this have the side effect that _gss_mechs and
+ _gss_mech_oids is only initialized once, so if just the users of
+ these two global variables calls _gss_load_mech() first, it will
+ act as a barrier and make sure the variables are never changed and
+ we don't need to lock them.
+
+ * mech/utils.h: no need to mark functions extern.
+
+ * mech/name.h: no need to mark _gss_find_mn extern.
+
+2006-07-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/cfx.c: Redo the wrap length calculations.
+
+ * krb5/test_cfx.c: test max_wrap_size in cfx.c
+
+ * mech/gss_display_status.c: Handle more error codes.
+
+2006-07-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/mech_locl.h: Include <krb5-types.h> and "mechqueue.h"
+
+ * mech/mechqueue.h: Add SLIST macros.
+
+ * krb5/inquire_context.c: Don't free return values on success.
+
+ * krb5/inquire_cred.c (_gsskrb5_inquire_cred): When cred provided
+ is the default cred, acquire the acceptor cred and initator cred
+ in two diffrent steps and then query them for the information,
+ this way, the code wont fail if there are no keytab, but there is
+ a credential cache.
+
+ * mech/gss_inquire_cred.c: move the check if we found any cred
+ where it matter for both cases
+ (default cred and provided cred)
+
+ * mech/gss_init_sec_context.c: If the desired mechanism can't
+ convert the name to a MN, fail with GSS_S_BAD_NAME rather then a
+ NULL de-reference.
+
+2006-07-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * spnego/external.c: readd gss_spnego_inquire_names_for_mech
+
+ * spnego/spnego_locl.h: reimplement
+ gss_spnego_inquire_names_for_mech add support function
+ _gss_spnego_supported_mechs
+
+ * spnego/context_stubs.h: reimplement
+ gss_spnego_inquire_names_for_mech add support function
+ _gss_spnego_supported_mechs
+
+ * spnego/context_stubs.c: drop gss_spnego_indicate_mechs
+
+ * mech/gss_indicate_mechs.c: if the underlaying mech doesn't
+ support gss_indicate_mechs, use the oid in the mechswitch
+ structure
+
+ * spnego/external.c: let the mech glue layer implement
+ gss_indicate_mechs
+
+ * spnego/cred_stubs.c (gss_spnego_acquire_cred): don't care about
+ desired_mechs, get our own list with indicate_mechs and remove
+ ourself.
+
+2006-07-05 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * spnego/external.c: remove gss_spnego_inquire_names_for_mech, let
+ the mechglue layer implement it
+
+ * spnego/context_stubs.c: remove gss_spnego_inquire_names_for_mech, let
+ the mechglue layer implement it
+
+ * spnego/spnego_locl.c: remove gss_spnego_inquire_names_for_mech, let
+ the mechglue layer implement it
+
+2006-07-01 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_set_cred_option.c: fix argument to gss_release_cred
+
+2006-06-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/init_sec_context.c: Make work on compilers that are
+ somewhat more picky then gcc4 (like gcc2.95)
+
+ * krb5/init_sec_context.c (do_delegation): use KDCOptions2int to
+ convert fwd_flags to an integer, since otherwise int2KDCOptions in
+ krb5_get_forwarded_creds wont do the right thing.
+
+ * mech/gss_set_cred_option.c (gss_set_cred_option): free memory on
+ failure
+
+ * krb5/set_sec_context_option.c (_gsskrb5_set_sec_context_option):
+ init global kerberos context
+
+ * krb5/set_cred_option.c (_gsskrb5_set_cred_option): init global
+ kerberos context
+
+ * mech/gss_accept_sec_context.c: Insert the delegated sub cred on
+ the delegated cred handle, not cred handle
+
+ * mech/gss_accept_sec_context.c (gss_accept_sec_context): handle
+ the case where ret_flags == NULL
+
+ * mech/gss_mech_switch.c (add_builtin): set
+ _gss_mech_switch->gm_mech_oid
+
+ * mech/gss_set_cred_option.c (gss_set_cred_option): laod mechs
+
+ * test_cred.c (gss_print_errors): don't try to print error when
+ gss_display_status failed
+
+ * Makefile.am: Add mech/gss_release_oid.c
+
+ * mech/gss_release_oid.c: Add gss_release_oid, reverse of
+ gss_duplicate_oid
+
+ * spnego/compat.c: preferred_mech_type was allocated with
+ gss_duplicate_oid in one place and assigned static varianbles a
+ the second place. change that static assignement to
+ gss_duplicate_oid and bring back gss_release_oid.
+
+ * spnego/compat.c (_gss_spnego_delete_sec_context): don't release
+ preferred_mech_type and negotiated_mech_type, they where never
+ allocated from the begining.
+
+2006-06-29 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * mech/gss_import_name.c (gss_import_name): avoid
+ type-punned/strict aliasing rules
+
+ * mech/gss_add_cred.c: avoid type-punned/strict aliasing rules
+
+ * gssapi.h: Make gss_name_t an opaque type.
+
+ * krb5: make gss_name_t an opaque type
+
+ * krb5/set_cred_option.c: Add
+
+ * mech/gss_set_cred_option.c (gss_set_cred_option): support the
+ case where *cred_handle == NULL
+
+ * mech/gss_krb5.c (gss_krb5_import_cred): make sure cred is
+ GSS_C_NO_CREDENTIAL on failure.
+
+ * mech/gss_acquire_cred.c (gss_acquire_cred): if desired_mechs is
+ NO_OID_SET, there is a need to load the mechs, so always do that.
+
+2006-06-28 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * krb5/inquire_cred_by_oid.c: Reimplement GSS_KRB5_COPY_CCACHE_X
+ to instead pass a fullname to the credential, then resolve and
+ copy out the content, and then close the cred.
+
+ * mech/gss_krb5.c: Reimplement GSS_KRB5_COPY_CCACHE_X to instead
+ pass a fullname to the credential, then resolve and copy out the
+ content, and then close the cred.
+
+ * krb5/inquire_cred_by_oid.c: make "work", GSS_KRB5_COPY_CCACHE_X
+ interface needs to be re-done, currently its utterly broken.
+
+ * mech/gss_set_cred_option.c: Make work.
+
+ * krb5/external.c: Add _gsskrb5_set_{sec_context,cred}_option
+
+ * mech/gss_krb5.c (gss_krb5_import_cred): implement
+
+ * Makefile.am: Add gss_set_{sec_context,cred}_option and sort
+
+ * mech/gss_set_{sec_context,cred}_option.c: add
+
+ * gssapi.h: Add GSS_KRB5_IMPORT_CRED_X
+
+ * test_*.c: make compile again
+
+ * Makefile.am: Add lib dependencies and test programs
+
+ * spnego: remove dependency on libkrb5
+
+ * mech: Bug fixes, cleanup, compiler warnings, restructure code.
+
+ * spnego: Rename gss_context_id_t and gss_cred_id_t to local names
+
+ * krb5: repro copy the krb5 files here
+
+ * mech: import Doug Rabson mechglue from freebsd
+
+ * spnego: Import Luke Howard's SPNEGO from the mechglue branch
+
+2006-06-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi.h: Add oid_to_str.
+
+ * Makefile.am: add oid_to_str and test_oid
+
+ * oid_to_str.c: Add gss_oid_to_str
+
+ * test_oid.c: Add test for gss_oid_to_str()
+
+2006-05-13 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * verify_mic.c: Less pointer signedness warnings.
+
+ * unwrap.c: Less pointer signedness warnings.
+
+ * arcfour.c: Less pointer signedness warnings.
+
+ * gssapi_locl.h: Use const void * to instead of unsigned char * to
+ avoid pointer signedness warnings.
+
+ * encapsulate.c: Use const void * to instead of unsigned char * to
+ avoid pointer signedness warnings.
+
+ * decapsulate.c: Use const void * to instead of unsigned char * to
+ avoid pointer signedness warnings.
+
+ * decapsulate.c: Less pointer signedness warnings.
+
+ * cfx.c: Less pointer signedness warnings.
+
+ * init_sec_context.c: Less pointer signedness warnings (partly by
+ using the new asn.1 CHOICE decoder)
+
+ * import_sec_context.c: Less pointer signedness warnings.
+
+2006-05-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * accept_sec_context.c (gsskrb5_is_cfx): always set is_cfx. From
+ Andrew Abartlet.
+
+2006-05-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * get_mic.c (mic_des3): make sure message_buffer doesn't point to
+ free()ed memory on failure. Pointed out by IBM checker.
+
+2006-05-05 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Rename u_intXX_t to uintXX_t
+
+2006-05-04 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.c: Less pointer signedness warnings.
+
+ * arcfour.c: Avoid pointer signedness warnings.
+
+ * gssapi_locl.h (gssapi_decode_*): make data argument const void *
+
+ * 8003.c (gssapi_decode_*): make data argument const void *
+
+2006-04-12 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * export_sec_context.c: Export sequence order element. From Wynn
+ Wilkes <wynn.wilkes@quest.com>.
+
+ * import_sec_context.c: Import sequence order element. From Wynn
+ Wilkes <wynn.wilkes@quest.com>.
+
+ * sequence.c (_gssapi_msg_order_import,_gssapi_msg_order_export):
+ New functions, used by {import,export}_sec_context. From Wynn
+ Wilkes <wynn.wilkes@quest.com>.
+
+ * test_sequence.c: Add test for import/export sequence.
+
+2006-04-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * add_cred.c: Check that cred != GSS_C_NO_CREDENTIAL, this is a
+ standard conformance failure, but much better then a crash.
+
+2006-04-02 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * get_mic.c (get_mic*)_: make sure message_token is cleaned on
+ error, found by IBM checker.
+
+ * wrap.c (wrap*): Reset output_buffer on error, found by IBM
+ checker.
+
+2006-02-15 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * import_name.c: Accept both GSS_C_NT_HOSTBASED_SERVICE and
+ GSS_C_NT_HOSTBASED_SERVICE_X as nametype for hostbased names.
+
+2006-01-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * delete_sec_context.c (gss_delete_sec_context): if the context
+ handle is GSS_C_NO_CONTEXT, don't fall over.
+
+2005-12-12 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: Replace gss_krb5_import_ccache with
+ gss_krb5_import_cred and add more references
+
+2005-12-05 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi.h: Change gss_krb5_import_ccache to gss_krb5_import_cred,
+ it can handle keytabs too.
+
+ * add_cred.c (gss_add_cred): avoid deadlock
+
+ * context_time.c (gssapi_lifetime_left): define the 0 lifetime as
+ GSS_C_INDEFINITE.
+
+2005-12-01 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * acquire_cred.c (acquire_acceptor_cred): only check if principal
+ exists if we got called with principal as an argument.
+
+ * acquire_cred.c (acquire_acceptor_cred): check that the acceptor
+ exists in the keytab before returning ok.
+
+2005-11-29 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * copy_ccache.c (gss_krb5_import_cred): fix buglet, from Andrew
+ Bartlett.
+
+2005-11-25 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_kcred.c: Rename gss_krb5_import_ccache to
+ gss_krb5_import_cred.
+
+ * copy_ccache.c: Rename gss_krb5_import_ccache to
+ gss_krb5_import_cred and let it grow code to handle keytabs too.
+
+2005-11-02 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * init_sec_context.c: Change sematics of ok-as-delegate to match
+ windows if
+ [gssapi]realm/ok-as-delegate=true is set, otherwise keep old
+ sematics.
+
+ * release_cred.c (gss_release_cred): use
+ GSS_CF_DESTROY_CRED_ON_RELEASE to decide if the cache should be
+ krb5_cc_destroy-ed
+
+ * acquire_cred.c (acquire_initiator_cred):
+ GSS_CF_DESTROY_CRED_ON_RELEASE on created credentials.
+
+ * accept_sec_context.c (gsskrb5_accept_delegated_token): rewrite
+ to use gss_krb5_import_ccache
+
+2005-11-01 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * arcfour.c: Remove signedness warnings.
+
+2005-10-31 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: Document that gss_krb5_import_ccache is copy
+ by reference.
+
+ * copy_ccache.c (gss_krb5_import_ccache): Instead of making a copy
+ of the ccache, make a reference by getting the name and resolving
+ the name. This way the cache is shared, this flipp side is of
+ course that if someone calls krb5_cc_destroy the cache is lost for
+ everyone.
+
+ * test_kcred.c: Remove memory leaks.
+
+2005-10-26 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: build test_kcred
+
+ * gss_acquire_cred.3: Document gss_krb5_import_ccache
+
+ * gssapi.3: Sort and add gss_krb5_import_ccache.
+
+ * acquire_cred.c (_gssapi_krb5_ccache_lifetime): break out code
+ used to extract lifetime from a credential cache
+
+ * gssapi_locl.h: Add _gssapi_krb5_ccache_lifetime, used to extract
+ lifetime from a credential cache.
+
+ * gssapi.h: add gss_krb5_import_ccache, reverse of
+ gss_krb5_copy_ccache
+
+ * copy_ccache.c: add gss_krb5_import_ccache, reverse of
+ gss_krb5_copy_ccache
+
+ * test_kcred.c: test gss_krb5_import_ccache
+
+2005-10-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * acquire_cred.c (acquire_initiator_cred): use krb5_cc_cache_match
+ to find a matching creditial cache, if that failes, fallback to
+ the default cache.
+
+2005-10-12 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi_locl.h: Add gssapi_krb5_set_status and
+ gssapi_krb5_clear_status
+
+ * init_sec_context.c (spnego_reply): Don't pass back raw Kerberos
+ errors, use GSS-API errors instead. From Michael B Allen.
+
+ * display_status.c: Add gssapi_krb5_clear_status,
+ gssapi_krb5_set_status for handling error messages.
+
+2005-08-23 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * external.c: Use rk_UNCONST to avoid const warning.
+
+ * display_status.c: Constify strings to avoid warnings.
+
+2005-08-11 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * init_sec_context.c: avoid warnings, update (c)
+
+2005-07-13 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * init_sec_context.c (spnego_initial): use NegotiationToken
+ encoder now that we have one with the new asn1. compiler.
+
+ * Makefile.am: the new asn.1 compiler includes the modules name in
+ the depend file
+
+2005-06-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * decapsulate.c: use rk_UNCONST
+
+ * ccache_name.c: rename to avoid shadowing
+
+ * gssapi_locl.h: give kret in GSSAPI_KRB5_INIT a more unique name
+
+ * process_context_token.c: use rk_UNCONST to unconstify
+
+ * test_cred.c: rename optind to optidx
+
+2005-05-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * init_sec_context.c (init_auth): honor ok-as-delegate if local
+ configuration approves
+
+ * gssapi_locl.h: prototype for _gss_check_compat
+
+ * compat.c: export check_compat as _gss_check_compat
+
+2005-05-29 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * init_sec_context.c: Prefix Der_class with ASN1_C_ to avoid
+ problems with system headerfiles that pollute the name space.
+
+ * accept_sec_context.c: Prefix Der_class with ASN1_C_ to avoid
+ problems with system headerfiles that pollute the name space.
+
+2005-05-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * init_sec_context.c (init_auth): set
+ KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED (for java compatibility),
+ also while here, use krb5_auth_con_addflags
+
+2005-05-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * arcfour.c (_gssapi_wrap_arcfour): fix calculating the encap
+ length. From: Tom Maher <tmaher@eecs.berkeley.edu>
+
+2005-05-02 Dave Love <fx@gnu.org>
+
+ * test_cred.c (main): Call setprogname.
+
+2005-04-27 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * prefix all sequence symbols with _, they are not part of the
+ GSS-API api. By comment from Wynn Wilkes <wynnw@vintela.com>
+
+2005-04-10 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * accept_sec_context.c: break out the processing of the delegated
+ credential to a separate function to make error handling easier,
+ move the credential handling to after other setup is done
+
+ * test_sequence.c: make less verbose in case of success
+
+ * Makefile.am: add test_sequence to TESTS
+
+2005-04-01 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * 8003.c (gssapi_krb5_verify_8003_checksum): check that cksum
+ isn't NULL From: Nicolas Pouvesle <npouvesle@tenablesecurity.com>
+
+2005-03-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: use $(LIB_roken)
+
+2005-03-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * display_status.c (gssapi_krb5_set_error_string): pass in the
+ krb5_context to krb5_free_error_string
+
+2005-03-15 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * display_status.c (gssapi_krb5_set_error_string): don't misuse
+ the krb5_get_error_string api
+
+2005-03-01 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * compat.c (_gss_DES3_get_mic_compat): don't unlock mutex
+ here. Bug reported by Stefan Metzmacher <metze@samba.org>
+
+2005-02-21 Luke Howard <lukeh@padl.com>
+
+ * init_sec_context.c: don't call krb5_get_credentials() with
+ KRB5_TC_MATCH_KEYTYPE, it can lead to the credentials cache
+ growing indefinitely as no key is found with KEYTYPE_NULL
+
+ * compat.c: remove GSS_C_EXPECTING_MECH_LIST_MIC_FLAG, it is
+ no longer used (however the mechListMIC behaviour is broken,
+ rfc2478bis support requires the code in the mechglue branch)
+
+ * init_sec_context.c: remove GSS_C_EXPECTING_MECH_LIST_MIC_FLAG
+
+ * gssapi.h: remove GSS_C_EXPECTING_MECH_LIST_MIC_FLAG
+
+2005-01-05 Luke Howard <lukeh@padl.com>
+
+ * 8003.c: use symbolic name for checksum type
+
+ * accept_sec_context.c: allow client to indicate
+ that subkey should be used
+
+ * acquire_cred.c: plug leak
+
+ * get_mic.c: use gss_krb5_get_subkey() instead
+ of gss_krb5_get_{local,remote}key(), support
+ KEYTYPE_ARCFOUR_56
+
+ * gssapi_local.c: use gss_krb5_get_subkey(),
+ support KEYTYPE_ARCFOUR_56
+
+ * import_sec_context.c: plug leak
+
+ * unwrap.c: use gss_krb5_get_subkey(),
+ support KEYTYPE_ARCFOUR_56
+
+ * verify_mic.c: use gss_krb5_get_subkey(),
+ support KEYTYPE_ARCFOUR_56
+
+ * wrap.c: use gss_krb5_get_subkey(),
+ support KEYTYPE_ARCFOUR_56
+
+2004-11-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * inquire_cred.c: Reverse order of HEIMDAL_MUTEX_unlock and
+ gss_release_cred to avoid deadlock, from Luke Howard
+ <lukeh@padl.com>.
+
+2004-09-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: gss_krb5_extract_authz_data_from_sec_context
+ was renamed to gsskrb5_extract_authz_data_from_sec_context
+
+2004-08-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * unwrap.c: mutex buglet, From: Luke Howard <lukeh@PADL.COM>
+
+ * arcfour.c: mutex buglet, From: Luke Howard <lukeh@PADL.COM>
+
+2004-05-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi.3: spelling from Josef El-Rayes <josef@FreeBSD.org> while
+ here, write some text about the SPNEGO situation
+
+2004-04-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.c: s/CTXAcceptorSubkey/CFXAcceptorSubkey/
+
+2004-04-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi.h: add GSS_C_EXPECTING_MECH_LIST_MIC_FLAG From: Luke
+ Howard <lukeh@padl.com>
+
+ * init_sec_context.c (spnego_reply): use
+ _gss_spnego_require_mechlist_mic to figure out if we need to check
+ MechListMIC; From: Luke Howard <lukeh@padl.com>
+
+ * accept_sec_context.c (send_accept): use
+ _gss_spnego_require_mechlist_mic to figure out if we need to send
+ MechListMIC; From: Luke Howard <lukeh@padl.com>
+
+ * gssapi_locl.h: add _gss_spnego_require_mechlist_mic
+ From: Luke Howard <lukeh@padl.com>
+
+ * compat.c: add _gss_spnego_require_mechlist_mic for compatibility
+ with MS SPNEGO, From: Luke Howard <lukeh@padl.com>
+
+2004-04-05 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * accept_sec_context.c (gsskrb5_is_cfx): krb5_keyblock->keytype is
+ an enctype, not keytype
+
+ * accept_sec_context.c: use ASN1_MALLOC_ENCODE
+
+ * init_sec_context.c: avoid the malloc loop and just allocate the
+ propper amount of data
+
+ * init_sec_context.c (spnego_initial): handle mech_token better
+
+2004-03-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi.h: add gss_krb5_get_tkt_flags
+
+ * Makefile.am: add ticket_flags.c
+
+ * ticket_flags.c: Get ticket-flags from acceptor ticket From: Luke
+ Howard <lukeh@PADL.COM>
+
+ * gss_acquire_cred.3: document gss_krb5_get_tkt_flags
+
+2004-03-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * acquire_cred.c (gss_acquire_cred): check usage before even
+ bothering to process it, add both keytab and initial tgt if
+ requested
+
+ * wrap.c: support cfx, try to handle acceptor asserted subkey
+
+ * unwrap.c: support cfx, try to handle acceptor asserted subkey
+
+ * verify_mic.c: support cfx
+
+ * get_mic.c: support cfx
+
+ * test_sequence.c: handle changed signature of
+ gssapi_msg_order_create
+
+ * import_sec_context.c: handle acceptor asserted subkey
+
+ * init_sec_context.c: handle acceptor asserted subkey
+
+ * accept_sec_context.c: handle acceptor asserted subkey
+
+ * sequence.c: add dummy use_64 argument to gssapi_msg_order_create
+
+ * gssapi_locl.h: add partial support for CFX
+
+ * Makefile.am (noinst_PROGRAMS) += test_cred
+
+ * test_cred.c: gssapi credential testing
+
+ * test_acquire_cred.c: fix comment
+
+2004-03-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * arcfour.h: drop structures for message formats, no longer used
+
+ * arcfour.c: comment describing message formats
+
+ * accept_sec_context.c (spnego_accept_sec_context): make sure the
+ length of the choice element doesn't overrun us
+
+ * init_sec_context.c (spnego_reply): make sure the length of the
+ choice element doesn't overrun us
+
+ * spnego.asn1: move NegotiationToken to avoid warning
+
+ * spnego.asn1: uncomment NegotiationToken
+
+ * Makefile.am: spnego_files += asn1_NegotiationToken.x
+
+2004-01-25 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi.h: add gss_krb5_ccache_name
+
+ * Makefile.am (libgssapi_la_SOURCES): += ccache_name.c
+
+ * ccache_name.c (gss_krb5_ccache_name): help function enable to
+ set krb5 name, using out_name argument makes function no longer
+ thread-safe
+
+ * gssapi.3: add missing gss_krb5_ references
+
+ * gss_acquire_cred.3: document gss_krb5_ccache_name
+
+2003-12-12 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.c: make rrc a modulus operation if its longer then the
+ length of the message, noticed by Sam Hartman
+
+2003-12-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * accept_sec_context.c: use krb5_auth_con_addflags
+
+2003-12-05 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.c: Wrap token id was in wrong order, found by Sam Hartman
+
+2003-12-04 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.c: add AcceptorSubkey (but no code understand it yet) ignore
+ unknown token flags
+
+2003-11-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * accept_sec_context.c: Don't require timestamp to be set on
+ delegated token, its already protected by the outer token (and
+ windows doesn't alway send it) Pointed out by Zi-Bin Yang
+ <zbyang@decru.com> on heimdal-discuss
+
+2003-11-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.c: fix {} error, pointed out by Liqiang Zhu
+
+2003-11-10 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.c: Sequence number should be stored in bigendian order From:
+ Luke Howard <lukeh@padl.com>
+
+2003-11-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * delete_sec_context.c (gss_delete_sec_context): don't free
+ ticket, krb5_free_ticket does that now
+
+2003-11-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.c: checksum the header last in MIC token, update to -03
+ From: Luke Howard <lukeh@padl.com>
+
+2003-10-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * add_cred.c: If its a MEMORY cc, make a copy. We need to do this
+ since now gss_release_cred will destroy the cred. This should be
+ really be solved a better way.
+
+ * acquire_cred.c (gss_release_cred): if its a mcc, destroy it
+ rather the just release it Found by: "Zi-Bin Yang"
+ <zbyang@decru.com>
+
+ * acquire_cred.c (acquire_initiator_cred): use kret instead of ret
+ where appropriate
+
+2003-09-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: spelling
+ From: jmc <jmc@prioris.mini.pw.edu.pl>
+
+2003-09-23 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.c: - EC and RRC are big-endian, not little-endian - The
+ default is now to rotate regardless of GSS_C_DCE_STYLE. There are
+ no longer any references to GSS_C_DCE_STYLE. - rrc_rotate()
+ avoids allocating memory on the heap if rrc <= 256
+ From: Luke Howard <lukeh@padl.com>
+
+2003-09-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.[ch]: rrc_rotate() was untested and broken, fix it.
+ Set and verify wrap Token->Filler.
+ Correct token ID for wrap tokens,
+ were accidentally swapped with delete tokens.
+ From: Luke Howard <lukeh@PADL.COM>
+
+2003-09-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.[ch]: no ASN.1-ish header on per-message tokens
+ From: Luke Howard <lukeh@PADL.COM>
+
+2003-09-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * arcfour.h: remove depenency on gss_arcfour_mic_token and
+ gss_arcfour_warp_token
+
+ * arcfour.c: remove depenency on gss_arcfour_mic_token and
+ gss_arcfour_warp_token
+
+2003-09-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * 8003.c: remove #if 0'ed code
+
+2003-09-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * accept_sec_context.c (gsskrb5_accept_sec_context): set sequence
+ number when not requesting mutual auth From: Luke Howard
+ <lukeh@PADL.COM>
+
+ * init_sec_context.c (init_auth): set sequence number when not
+ requesting mutual auth From: Luke Howard <lukeh@PADL.COM>
+
+2003-09-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * arcfour.c (*): set minor_status
+ (gss_wrap): set conf_state to conf_req_flags on success
+ From: Luke Howard <lukeh@PADL.COM>
+
+ * wrap.c (gss_wrap_size_limit): use existing function From: Luke
+ Howard <lukeh@PADL.COM>
+
+2003-09-12 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * indicate_mechs.c (gss_indicate_mechs): in case of error, free
+ mech_set
+
+ * indicate_mechs.c (gss_indicate_mechs): add SPNEGO
+
+2003-09-10 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * init_sec_context.c (spnego_initial): catch errors and return
+ them
+
+ * init_sec_context.c (spnego_initial): add #if 0 out version of
+ the CHOICE branch encoding, also where here, free no longer used
+ memory
+
+2003-09-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: support GSS_SPNEGO_MECHANISM
+
+ * accept_sec_context.c: SPNEGO doesn't include gss wrapping on
+ SubsequentContextToken like the Kerberos 5 mech does.
+
+ * init_sec_context.c (spnego_reply): SPNEGO doesn't include gss
+ wrapping on SubsequentContextToken like the Kerberos 5 mech
+ does. Lets check for it anyway.
+
+ * accept_sec_context.c: Add support for SPNEGO on the initator
+ side. Implementation initially from Assar Westerlund, passes
+ though quite a lot of hands before I commited it.
+
+ * init_sec_context.c: Add support for SPNEGO on the initator side.
+ Tested with ldap server on a Windows 2000 DC. Implementation
+ initially from Assar Westerlund, passes though quite a lot of
+ hands before I commited it.
+
+ * gssapi.h: export GSS_SPNEGO_MECHANISM
+
+ * gssapi_locl.h: include spnego_as.h add prototype for
+ gssapi_krb5_get_mech
+
+ * decapsulate.c (gssapi_krb5_get_mech): make non static
+
+ * Makefile.am: build SPNEGO file
+
+2003-09-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * external.c: SPENGO and IAKERB oids
+
+ * spnego.asn1: SPENGO ASN1
+
+2003-09-05 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.c: RRC also need to be zero before wraping them
+ From: Luke Howard <lukeh@PADL.COM>
+
+2003-09-04 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * encapsulate.c (gssapi_krb5_encap_length): don't return void
+
+2003-09-03 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * verify_mic.c: switch from the des_ to the DES_ api
+
+ * get_mic.c: switch from the des_ to the DES_ api
+
+ * unwrap.c: switch from the des_ to the DES_ api
+
+ * wrap.c: switch from the des_ to the DES_ api
+
+ * cfx.c: EC is not included in the checksum since the length might
+ change depending on the data. From: Luke Howard <lukeh@PADL.COM>
+
+ * acquire_cred.c: use
+ krb5_get_init_creds_opt_alloc/krb5_get_init_creds_opt_free
+
+2003-09-01 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * copy_ccache.c: rename
+ gss_krb5_extract_authz_data_from_sec_context to
+ gsskrb5_extract_authz_data_from_sec_context
+
+ * gssapi.h: rename gss_krb5_extract_authz_data_from_sec_context to
+ gsskrb5_extract_authz_data_from_sec_context
+
+2003-08-31 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * copy_ccache.c (gss_krb5_extract_authz_data_from_sec_context):
+ check that we have a ticket before we start to use it
+
+ * gss_acquire_cred.3: document
+ gss_krb5_extract_authz_data_from_sec_context
+
+ * gssapi.h (gss_krb5_extract_authz_data_from_sec_context):
+ return the kerberos authorizationdata, from idea of Luke Howard
+
+ * copy_ccache.c (gss_krb5_extract_authz_data_from_sec_context):
+ return the kerberos authorizationdata, from idea of Luke Howard
+
+ * verify_mic.c (gss_verify_mic_internal): switch type and key
+ argument
+
+2003-08-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * cfx.[ch]: draft-ietf-krb-wg-gssapi-cfx-01.txt implemetation
+ From: Luke Howard <lukeh@PADL.COM>
+
+2003-08-28 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * arcfour.c (arcfour_mic_cksum): use free_Checksum to free the
+ checksum
+
+ * arcfour.h: swap two last arguments to verify_mic for consistency
+ with des3
+
+ * wrap.c,unwrap.c,get_mic.c,verify_mic.c,cfx.c,cfx.h:
+ prefix cfx symbols with _gssapi_
+
+ * arcfour.c: release the right buffer
+
+ * arcfour.c: rename token structure in consistency with rest of
+ GSS-API From: Luke Howard <lukeh@PADL.COM>
+
+ * unwrap.c (unwrap_des3): use _gssapi_verify_pad
+ (unwrap_des): use _gssapi_verify_pad
+
+ * arcfour.c (_gssapi_wrap_arcfour): set the correct padding
+ (_gssapi_unwrap_arcfour): verify and strip padding
+
+ * gssapi_locl.h: added _gssapi_verify_pad
+
+ * decapsulate.c (_gssapi_verify_pad): verify padding of a gss
+ wrapped message and return its length
+
+ * arcfour.c: support KEYTYPE_ARCFOUR_56 keys, from Luke Howard
+ <lukeh@PADL.COM>
+
+ * arcfour.c: use right seal alg, inherit keytype from parent key
+
+ * arcfour.c: include the confounder in the checksum use the right
+ key usage number for warped/unwraped tokens
+
+ * gssapi.h: add gss_krb5_nt_general_name as an mit compat glue
+ (same as GSS_KRB5_NT_PRINCIPAL_NAME)
+
+ * unwrap.c: hook in arcfour unwrap
+
+ * wrap.c: hook in arcfour wrap
+
+ * verify_mic.c: hook in arcfour verify_mic
+
+ * get_mic.c: hook in arcfour get_mic
+
+ * arcfour.c: implement wrap/unwarp
+
+ * gssapi_locl.h: add gssapi_{en,de}code_be_om_uint32
+
+ * 8003.c: add gssapi_{en,de}code_be_om_uint32
+
+2003-08-27 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * arcfour.c (_gssapi_verify_mic_arcfour): Do the checksum on right
+ area. Swap filler check, it was reversed.
+
+ * Makefile.am (libgssapi_la_SOURCES): += arcfour.c
+
+ * gssapi_locl.h: include "arcfour.h"
+
+ * arcfour.c: arcfour gss-api mech, get_mic/verify_mic working
+
+ * arcfour.h: arcfour gss-api mech, get_mic/verify_mic working
+
+2003-08-26 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi_locl.h: always include cfx.h add prototype for
+ _gssapi_decapsulate
+
+ * cfx.[ch]: Implementation of draft-ietf-krb-wg-gssapi-cfx-00.txt
+ from Luke Howard <lukeh@PADL.COM>
+
+ * decapsulate.c: add _gssapi_decapsulate, from Luke Howard
+ <lukeh@PADL.COM>
+
+2003-08-25 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * unwrap.c: encap/decap now takes a oid if the enctype/keytype is
+ arcfour, return error add hook for cfx
+
+ * verify_mic.c: encap/decap now takes a oid if the enctype/keytype
+ is arcfour, return error add hook for cfx
+
+ * get_mic.c: encap/decap now takes a oid if the enctype/keytype is
+ arcfour, return error add hook for cfx
+
+ * accept_sec_context.c: encap/decap now takes a oid
+
+ * init_sec_context.c: encap/decap now takes a oid
+
+ * gssapi_locl.h: include cfx.h if we need it lifetime is a
+ OM_uint32, depend on gssapi interface add all new encap/decap
+ functions
+
+ * decapsulate.c: add decap functions that doesn't take the token
+ type also make all decap function take the oid mech that they
+ should use
+
+ * encapsulate.c: add encap functions that doesn't take the token
+ type also make all encap function take the oid mech that they
+ should use
+
+ * sequence.c (elem_insert): fix a off by one index counter
+
+ * inquire_cred.c (gss_inquire_cred): handle cred_handle being
+ GSS_C_NO_CREDENTIAL and use the default cred then.
+
+2003-08-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: break out extensions and document
+ gsskrb5_register_acceptor_identity
+
+2003-08-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_acquire_cred.c (print_time): time is returned in seconds
+ from now, not unix time
+
+2003-08-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * compat.c (check_compat): avoid leaking principal when finding a
+ match
+
+ * address_to_krb5addr.c: sa_size argument to krb5_addr2sockaddr is
+ a krb5_socklen_t
+
+ * acquire_cred.c (gss_acquire_cred): 4th argument to
+ gss_test_oid_set_member is a int
+
+2003-07-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * init_sec_context.c (repl_mutual): don't set kerberos error where
+ there was no kerberos error
+
+ * gssapi_locl.h: Add destruction/creation prototypes and structure
+ for the thread specific storage.
+
+ * display_status.c: use thread specific storage to set/get the
+ kerberos error message
+
+ * init.c: Provide locking around the creation of the global
+ krb5_context. Add destruction/creation functions for the thread
+ specific storage that the error string handling is using.
+
+2003-07-20 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: add missing prototype and missing .Ft
+ arguments
+
+2003-06-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * verify_mic.c: reorder code so sequence numbers can can be used
+
+ * unwrap.c: reorder code so sequence numbers can can be used
+
+ * sequence.c: remove unused function, indent, add
+ gssapi_msg_order_f that filter gss flags to gss_msg_order flags
+
+ * gssapi_locl.h: prototypes for
+ gssapi_{encode_om_uint32,decode_om_uint32} add sequence number
+ verifier prototypes
+
+ * delete_sec_context.c: destroy sequence number verifier
+
+ * init_sec_context.c: remember to free data use sequence number
+ verifier
+
+ * accept_sec_context.c: don't clear output_token twice remember to
+ free data use sequence number verifier
+
+ * 8003.c: export and rename encode_om_uint32/decode_om_uint32 and
+ start to use them
+
+2003-06-09 Johan Danielsson <joda@pdc.kth.se>
+
+ * Makefile.am: can't have sequence.c in two different places
+
+2003-06-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_sequence.c: check rollover, print summery
+
+ * wrap.c (sub_wrap_size): gss_wrap_size_limit() has
+ req_output_size and max_input_size around the wrong way -- it
+ returns the output token size for a given input size, rather than
+ the maximum input size for a given output token size.
+
+ From: Luke Howard <lukeh@PADL.COM>
+
+2003-06-05 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi_locl.h: add prototypes for sequence.c
+
+ * Makefile.am (libgssapi_la_SOURCES): add sequence.c
+ (test_sequence): build
+
+ * sequence.c: sequence number checks, order and replay
+ * test_sequence.c: sequence number checks, order and replay
+
+2003-06-03 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * accept_sec_context.c (gss_accept_sec_context): make sure time is
+ returned in seconds from now, not in kerberos time
+
+ * acquire_cred.c (gss_aquire_cred): make sure time is returned in
+ seconds from now, not in kerberos time
+
+ * init_sec_context.c (init_auth): if the cred is expired before we
+ tries to create a token, fail so the peer doesn't need reject us
+ (*): make sure time is returned in seconds from now,
+ not in kerberos time
+ (repl_mutual): remember to unlock the context mutex
+
+ * context_time.c (gss_context_time): remove unused variable
+
+ * verify_mic.c: make sure minor_status is always set, pointed out
+ by Luke Howard <lukeh@PADL.COM>
+
+2003-05-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * *.[ch]: do some basic locking (no reference counting so contexts
+ can be removed while still used)
+ - don't export gss_ctx_id_t_desc_struct and gss_cred_id_t_desc_struct
+ - make sure all lifetime are returned in seconds left until expired,
+ not in unix epoch
+
+ * gss_acquire_cred.3: document argument lifetime_rec to function
+ gss_inquire_context
+
+2003-05-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_acquire_cred.c: test gss_add_cred more then once
+
+2003-05-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi.h: if __cplusplus, wrap the extern variable (just to be
+ safe) and functions in extern "C" { }
+
+2003-04-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi.3: more about the des3 mic mess
+
+ * verify_mic.c (verify_mic_des3): always check if the mic is the
+ correct mic or the mic that old heimdal would have generated
+
+2003-04-28 Jacques Vidrine <nectar@kth.se>
+
+ * verify_mic.c (verify_mic_des3): If MIC verification fails,
+ retry using the `old' MIC computation (with zero IV).
+
+2003-04-26 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: more about difference between comparing IN
+ and MN
+
+ * gss_acquire_cred.3: more about name type and access control
+
+2003-04-25 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: document gss_context_time
+
+ * context_time.c: if lifetime of context have expired, set
+ time_rec to 0 and return GSS_S_CONTEXT_EXPIRED
+
+ * gssapi.3: document [gssapi]correct_des3_mic
+ [gssapi]broken_des3_mic
+
+ * gss_acquire_cred.3: document gss_krb5_compat_des3_mic
+
+ * compat.c (gss_krb5_compat_des3_mic): enable turning on/off des3
+ mic compat
+ (_gss_DES3_get_mic_compat): handle [gssapi]correct_des3_mic too
+
+ * gssapi.h (gss_krb5_compat_des3_mic): new function, turn on/off
+ des3 mic compat
+ (GSS_C_KRB5_COMPAT_DES3_MIC): cpp symbol that exists if
+ gss_krb5_compat_des3_mic exists
+
+2003-04-24 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: (libgssapi_la_LDFLAGS): update major
+ version of gssapi for incompatiblity in 3des getmic support
+
+2003-04-23 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: test_acquire_cred_LDADD: use libgssapi.la not
+ ./libgssapi.la (make make -jN work)
+
+2003-04-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi.3: spelling
+
+ * gss_acquire_cred.3: Change .Fd #include <header.h> to .In
+ header.h, from Thomas Klausner <wiz@netbsd.org>
+
+
+2003-04-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: spelling
+
+ * Makefile.am: remove stuff that sneaked in with last commit
+
+ * acquire_cred.c (acquire_initiator_cred): if the requested name
+ isn't in the ccache, also check keytab. Extact the krbtgt for the
+ default realm to check how long the credentials will last.
+
+ * add_cred.c (gss_add_cred): don't create a new ccache, just open
+ the old one; better check if output handle is compatible with new
+ (copied) handle
+
+ * test_acquire_cred.c: test gss_add_cred too
+
+2003-04-03 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: build test_acquire_cred
+
+ * test_acquire_cred.c: simple gss_acquire_cred test
+
+2003-04-02 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: s/gssapi/GSS-API/
+
+2003-03-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: document v1 interface (and that they are
+ obsolete)
+
+2003-03-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: list supported mechanism and nametypes
+
+2003-03-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_acquire_cred.3: text about gss_display_name
+
+ * Makefile.am (libgssapi_la_LDFLAGS): bump to 3:6:2
+ (libgssapi_la_SOURCES): add all new functions
+
+ * gssapi.3: now that we have a functions, uncomment the missing
+ ones
+
+ * gss_acquire_cred.3: now that we have a functions, uncomment the
+ missing ones
+
+ * process_context_token.c: implement gss_process_context_token
+
+ * inquire_names_for_mech.c: implement gss_inquire_names_for_mech
+
+ * inquire_mechs_for_name.c: implement gss_inquire_mechs_for_name
+
+ * inquire_cred_by_mech.c: implement gss_inquire_cred_by_mech
+
+ * add_cred.c: implement gss_add_cred
+
+ * acquire_cred.c (gss_acquire_cred): more testing of input
+ argument, make sure output arguments are ok, since we don't know
+ the time_rec (for now), set it to time_req
+
+ * export_sec_context.c: send lifetime, also set minor_status
+
+ * get_mic.c: set minor_status
+
+ * import_sec_context.c (gss_import_sec_context): add error
+ checking, pick up lifetime (if there is no lifetime, use
+ GSS_C_INDEFINITE)
+
+ * init_sec_context.c: take care to set export value to something
+ sane before we start so caller will have harmless values in them
+ if then function fails
+
+ * release_buffer.c (gss_release_buffer): set minor_status
+
+ * wrap.c: make sure minor_status get set
+
+ * verify_mic.c (gss_verify_mic_internal): rename verify_mic to
+ gss_verify_mic_internal and let it take the type as an argument,
+ (gss_verify_mic): call gss_verify_mic_internal
+ set minor_status
+
+ * unwrap.c: set minor_status
+
+ * test_oid_set_member.c (gss_test_oid_set_member): use
+ gss_oid_equal
+
+ * release_oid_set.c (gss_release_oid_set): set minor_status
+
+ * release_name.c (gss_release_name): set minor_status
+
+ * release_cred.c (gss_release_cred): set minor_status
+
+ * add_oid_set_member.c (gss_add_oid_set_member): set minor_status
+
+ * compare_name.c (gss_compare_name): set minor_status
+
+ * compat.c (check_compat): make sure ret have a defined value
+
+ * context_time.c (gss_context_time): set minor_status
+
+ * copy_ccache.c (gss_krb5_copy_ccache): set minor_status
+
+ * create_emtpy_oid_set.c (gss_create_empty_oid_set): set
+ minor_status
+
+ * delete_sec_context.c (gss_delete_sec_context): set minor_status
+
+ * display_name.c (gss_display_name): set minor_status
+
+ * display_status.c (gss_display_status): use gss_oid_equal, handle
+ supplementary errors
+
+ * duplicate_name.c (gss_duplicate_name): set minor_status
+
+ * inquire_context.c (gss_inquire_context): set lifetime_rec now
+ when we know it, set minor_status
+
+ * inquire_cred.c (gss_inquire_cred): take care to set export value
+ to something sane before we start so caller will have harmless
+ values in them if the function fails
+
+ * accept_sec_context.c (gss_accept_sec_context): take care to set
+ export value to something sane before we start so caller will have
+ harmless values in them if then function fails, set lifetime from
+ ticket expiration date
+
+ * indicate_mechs.c (gss_indicate_mechs): use
+ gss_create_empty_oid_set and gss_add_oid_set_member
+
+ * gssapi.h (gss_ctx_id_t_desc): store the lifetime in the cred,
+ since there is no ticket transfered in the exported context
+
+ * export_name.c (gss_export_name): export name with
+ GSS_C_NT_EXPORT_NAME wrapping, not just the principal
+
+ * import_name.c (import_export_name): new function, parses a
+ GSS_C_NT_EXPORT_NAME
+ (import_krb5_name): factor out common code of parsing krb5 name
+ (gss_oid_equal): rename from oid_equal
+
+ * gssapi_locl.h: add prototypes for gss_oid_equal and
+ gss_verify_mic_internal
+
+ * gssapi.h: comment out the argument names
+
+2003-03-15 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gssapi.3: add LIST OF FUNCTIONS and copyright/license
+
+ * Makefile.am: s/gss_aquire_cred.3/gss_acquire_cred.3/
+
+ * Makefile.am: man_MANS += gss_aquire_cred.3
+
+2003-03-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss_aquire_cred.3: the gssapi api manpage
+
+2003-03-03 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * inquire_context.c: (gss_inquire_context): rename argument open
+ to open_context
+
+ * gssapi.h (gss_inquire_context): rename argument open to open_context
+
+2003-02-27 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * init_sec_context.c (do_delegation): remove unused variable
+ subkey
+
+ * gssapi.3: all 0.5.x version had broken token delegation
+
+2003-02-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * (init_auth): only generate one subkey
+
+2003-01-27 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * verify_mic.c (verify_mic_des3): fix 3des verify_mic to conform
+ to rfc (and mit kerberos), provide backward compat hook
+
+ * get_mic.c (mic_des3): fix 3des get_mic to conform to rfc (and
+ mit kerberos), provide backward compat hook
+
+ * init_sec_context.c (init_auth): check if we need compat for
+ older get_mic/verify_mic
+
+ * gssapi_locl.h: add prototype for _gss_DES3_get_mic_compat
+
+ * gssapi.h (more_flags): add COMPAT_OLD_DES3
+
+ * Makefile.am: add gssapi.3 and compat.c
+
+ * gssapi.3: add gssapi COMPATIBILITY documentation
+
+ * accept_sec_context.c (gss_accept_sec_context): check if we need
+ compat for older get_mic/verify_mic
+
+ * compat.c: check for compatiblity with other heimdal's 3des
+ get_mic/verify_mic
+
+2002-10-31 Johan Danielsson <joda@pdc.kth.se>
+
+ * check return value from gssapi_krb5_init
+
+ * 8003.c (gssapi_krb5_verify_8003_checksum): check size of input
+
+2002-09-03 Johan Danielsson <joda@pdc.kth.se>
+
+ * wrap.c (wrap_des3): use ETYPE_DES3_CBC_NONE
+
+ * unwrap.c (unwrap_des3): use ETYPE_DES3_CBC_NONE
+
+2002-09-02 Johan Danielsson <joda@pdc.kth.se>
+
+ * init_sec_context.c: we need to generate a local subkey here
+
+2002-08-20 Jacques Vidrine <n@nectar.com>
+
+ * acquire_cred.c, inquire_cred.c, release_cred.c: Use default
+ credential resolution if gss_acquire_cred is called with
+ GSS_C_NO_NAME.
+
+2002-06-20 Jacques Vidrine <n@nectar.com>
+
+ * import_name.c: Compare name types by value if pointers do
+ not match. Reported by: "Douglas E. Engert" <deengert@anl.gov>
+
+2002-05-20 Jacques Vidrine <n@nectar.com>
+
+ * verify_mic.c (gss_verify_mic), unwrap.c (gss_unwrap): initialize
+ the qop_state parameter. from Doug Rabson <dfr@nlsystems.com>
+
+2002-05-09 Jacques Vidrine <n@nectar.com>
+
+ * acquire_cred.c: handle GSS_C_INITIATE/GSS_C_ACCEPT/GSS_C_BOTH
+
+2002-05-08 Jacques Vidrine <n@nectar.com>
+
+ * acquire_cred.c: initialize gssapi; handle null desired_name
+
+2002-03-22 Johan Danielsson <joda@pdc.kth.se>
+
+ * Makefile.am: remove non-functional stuff accidentally committed
+
+2002-03-11 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libgssapi_la_LDFLAGS): bump version to 3:5:2
+ * 8003.c (gssapi_krb5_verify_8003_checksum): handle zero channel
+ bindings
+
+2001-10-31 Jacques Vidrine <n@nectar.com>
+
+ * get_mic.c (mic_des3): MIC computation using DES3/SHA1
+ was bogusly appending the message buffer to the result,
+ overwriting a heap buffer in the process.
+
+2001-08-29 Assar Westerlund <assar@sics.se>
+
+ * 8003.c (gssapi_krb5_verify_8003_checksum,
+ gssapi_krb5_create_8003_checksum): make more consistent by always
+ returning an gssapi error and setting minor status. update
+ callers
+
+2001-08-28 Jacques Vidrine <n@nectar.com>
+
+ * accept_sec_context.c: Create a cache for delegated credentials
+ when needed.
+
+2001-08-28 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libgssapi_la_LDFLAGS): set version to 3:4:2
+
+2001-08-23 Assar Westerlund <assar@sics.se>
+
+ * *.c: handle minor_status more consistently
+
+ * display_status.c (gss_display_status): handle krb5_get_err_text
+ failing
+
+2001-08-15 Johan Danielsson <joda@pdc.kth.se>
+
+ * gssapi_locl.h: fix prototype for gssapi_krb5_init
+
+2001-08-13 Johan Danielsson <joda@pdc.kth.se>
+
+ * accept_sec_context.c (gsskrb5_register_acceptor_identity): init
+ context and check return value from kt_resolve
+
+ * init.c: return error code
+
+2001-07-19 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libgssapi_la_LDFLAGS): update to 3:3:2
+
+2001-07-12 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libgssapi_la_LIBADD): add required library
+ dependencies
+
+2001-07-06 Assar Westerlund <assar@sics.se>
+
+ * accept_sec_context.c (gsskrb5_register_acceptor_identity): set
+ the keytab to be used for gss_acquire_cred too'
+
+2001-07-03 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libgssapi_la_LDFLAGS): set version to 3:2:2
+
+2001-06-18 Assar Westerlund <assar@sics.se>
+
+ * wrap.c: replace gss_krb5_getsomekey with gss_krb5_get_localkey
+ and gss_krb5_get_remotekey
+ * verify_mic.c: update krb5_auth_con function names use
+ gss_krb5_get_remotekey
+ * unwrap.c: replace gss_krb5_getsomekey with gss_krb5_get_localkey
+ and gss_krb5_get_remotekey
+ * gssapi_locl.h (gss_krb5_get_remotekey, gss_krb5_get_localkey):
+ add prototypes
+ * get_mic.c: update krb5_auth_con function names. use
+ gss_krb5_get_localkey
+ * accept_sec_context.c: update krb5_auth_con function names
+
+2001-05-17 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump version to 3:1:2
+
+2001-05-14 Assar Westerlund <assar@sics.se>
+
+ * address_to_krb5addr.c: adapt to new address functions
+
+2001-05-11 Assar Westerlund <assar@sics.se>
+
+ * try to return the error string from libkrb5 where applicable
+
+2001-05-08 Assar Westerlund <assar@sics.se>
+
+ * delete_sec_context.c (gss_delete_sec_context): remember to free
+ the memory used by the ticket itself. from <tmartin@mirapoint.com>
+
+2001-05-04 Assar Westerlund <assar@sics.se>
+
+ * gssapi_locl.h: add config.h for completeness
+ * gssapi.h: remove config.h, this is an installed header file
+ sys/types.h is not needed either
+
+2001-03-12 Assar Westerlund <assar@sics.se>
+
+ * acquire_cred.c (gss_acquire_cred): remove memory leaks. from
+ Jason R Thorpe <thorpej@zembu.com>
+
+2001-02-18 Assar Westerlund <assar@sics.se>
+
+ * accept_sec_context.c (gss_accept_sec_context): either return
+ gss_name NULL-ed or set
+
+ * import_name.c: set minor_status in some cases where it was not
+ done
+
+2001-02-15 Assar Westerlund <assar@sics.se>
+
+ * wrap.c: use krb5_generate_random_block for the confounders
+
+2001-01-30 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libgssapi_la_LDFLAGS): bump version to 3:0:2
+ * acquire_cred.c, init_sec_context.c, release_cred.c: add support
+ for getting creds from a keytab, from fvdl@netbsd.org
+
+ * copy_ccache.c: add gss_krb5_copy_ccache
+
+2001-01-27 Assar Westerlund <assar@sics.se>
+
+ * get_mic.c: cast parameters to des function to non-const pointers
+ to handle the case where these functions actually take non-const
+ des_cblock *
+
+2001-01-09 Assar Westerlund <assar@sics.se>
+
+ * accept_sec_context.c (gss_accept_sec_context): use krb5_rd_cred2
+ instead of krb5_rd_cred
+
+2000-12-11 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libgssapi_la_LDFLAGS): bump to 2:3:1
+
+2000-12-08 Assar Westerlund <assar@sics.se>
+
+ * wrap.c (wrap_des3): use the checksum as ivec when encrypting the
+ sequence number
+ * unwrap.c (unwrap_des3): use the checksum as ivec when encrypting
+ the sequence number
+ * init_sec_context.c (init_auth): always zero fwd_data
+
+2000-12-06 Johan Danielsson <joda@pdc.kth.se>
+
+ * accept_sec_context.c: de-pointerise auth_context parameter to
+ krb5_mk_rep
+
+2000-11-15 Assar Westerlund <assar@sics.se>
+
+ * init_sec_context.c (init_auth): update to new
+ krb5_build_authenticator
+
+2000-09-19 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libgssapi_la_LDFLAGS): bump to 2:2:1
+
+2000-08-27 Assar Westerlund <assar@sics.se>
+
+ * init_sec_context.c: actually pay attention to `time_req'
+ * init_sec_context.c: re-organize. leak less memory.
+ * gssapi_locl.h (gssapi_krb5_encapsulate, gss_krb5_getsomekey):
+ update prototypes add assert.h
+ * gssapi.h (GSS_KRB5_CONF_C_QOP_DES, GSS_KRB5_CONF_C_QOP_DES3_KD):
+ add
+ * verify_mic.c: re-organize and add 3DES code
+ * wrap.c: re-organize and add 3DES code
+ * unwrap.c: re-organize and add 3DES code
+ * get_mic.c: re-organize and add 3DES code
+ * encapsulate.c (gssapi_krb5_encapsulate): do not free `in_data',
+ let the caller do that. fix the callers.
+
+2000-08-16 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump version to 2:1:1
+
+2000-07-29 Assar Westerlund <assar@sics.se>
+
+ * decapsulate.c (gssapi_krb5_verify_header): sanity-check length
+
+2000-07-25 Johan Danielsson <joda@pdc.kth.se>
+
+ * Makefile.am: bump version to 2:0:1
+
+2000-07-22 Assar Westerlund <assar@sics.se>
+
+ * gssapi.h: update OID for GSS_C_NT_HOSTBASED_SERVICE and other
+ details from rfc2744
+
+2000-06-29 Assar Westerlund <assar@sics.se>
+
+ * address_to_krb5addr.c (gss_address_to_krb5addr): actually use
+ `int' instead of `sa_family_t' for the address family.
+
+2000-06-21 Assar Westerlund <assar@sics.se>
+
+ * add support for token delegation. From Daniel Kouril
+ <kouril@ics.muni.cz> and Miroslav Ruda <ruda@ics.muni.cz>
+
+2000-05-15 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libgssapi_la_LDFLAGS): set version to 1:1:1
+
+2000-04-12 Assar Westerlund <assar@sics.se>
+
+ * release_oid_set.c (gss_release_oid_set): clear set for
+ robustness. From GOMBAS Gabor <gombasg@inf.elte.hu>
+ * release_name.c (gss_release_name): reset input_name for
+ robustness. From GOMBAS Gabor <gombasg@inf.elte.hu>
+ * release_buffer.c (gss_release_buffer): set value to NULL to be
+ more robust. From GOMBAS Gabor <gombasg@inf.elte.hu>
+ * add_oid_set_member.c (gss_add_oid_set_member): actually check if
+ the oid is a member first. leave the oid_set unchanged if realloc
+ fails.
+
+2000-02-13 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 1:0:1
+
+2000-02-12 Assar Westerlund <assar@sics.se>
+
+ * gssapi_locl.h: add flags for import/export
+ * import_sec_context.c (import_sec_context: add flags for what
+ fields are included. do not include the authenticator for now.
+ * export_sec_context.c (export_sec_context: add flags for what
+ fields are included. do not include the authenticator for now.
+ * accept_sec_context.c (gss_accept_sec_context): set target in
+ context_handle
+
+2000-02-11 Assar Westerlund <assar@sics.se>
+
+ * delete_sec_context.c (gss_delete_sec_context): set context to
+ GSS_C_NO_CONTEXT
+
+ * Makefile.am: add {export,import}_sec_context.c
+ * export_sec_context.c: new file
+ * import_sec_context.c: new file
+ * accept_sec_context.c (gss_accept_sec_context): set trans flag
+
+2000-02-07 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 0:5:0
+
+2000-01-26 Assar Westerlund <assar@sics.se>
+
+ * delete_sec_context.c (gss_delete_sec_context): handle a NULL
+ output_token
+
+ * wrap.c: update to pseudo-standard APIs for md4,md5,sha. some
+ changes to libdes calls to make them more portable.
+ * verify_mic.c: update to pseudo-standard APIs for md4,md5,sha.
+ some changes to libdes calls to make them more portable.
+ * unwrap.c: update to pseudo-standard APIs for md4,md5,sha. some
+ changes to libdes calls to make them more portable.
+ * get_mic.c: update to pseudo-standard APIs for md4,md5,sha. some
+ changes to libdes calls to make them more portable.
+ * 8003.c: update to pseudo-standard APIs for md4,md5,sha.
+
+2000-01-06 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 0:4:0
+
+1999-12-26 Assar Westerlund <assar@sics.se>
+
+ * accept_sec_context.c (gss_accept_sec_context): always set
+ `output_token'
+ * init_sec_context.c (init_auth): always initialize `output_token'
+ * delete_sec_context.c (gss_delete_sec_context): always set
+ `output_token'
+
+1999-12-06 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump version to 0:3:0
+
+1999-10-20 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 0:2:0
+
+1999-09-21 Assar Westerlund <assar@sics.se>
+
+ * init_sec_context.c (gss_init_sec_context): initialize `ticket'
+
+ * gssapi.h (gss_ctx_id_t_desc): add ticket in here. ick.
+
+ * delete_sec_context.c (gss_delete_sec_context): free ticket
+
+ * accept_sec_context.c (gss_accept_sec_context): stove away
+ `krb5_ticket' in context so that ugly programs such as
+ gss_nt_server can get at it. uck.
+
+1999-09-20 Johan Danielsson <joda@pdc.kth.se>
+
+ * accept_sec_context.c: set minor_status
+
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * display_status.c (calling_error, routine_error): right shift the
+ code to make it possible to index into the arrays
+
+1999-07-28 Assar Westerlund <assar@sics.se>
+
+ * gssapi.h (GSS_C_AF_INET6): add
+
+ * import_name.c (import_hostbased_name): set minor_status
+
+1999-07-26 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 0:1:0
+
+Wed Apr 7 14:05:15 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * display_status.c: set minor_status
+
+ * init_sec_context.c: set minor_status
+
+ * lib/gssapi/init.c: remove donep (check gssapi_krb5_context
+ directly)
+
diff --git a/crypto/heimdal/lib/gssapi/Makefile.am b/crypto/heimdal/lib/gssapi/Makefile.am
new file mode 100644
index 0000000..919799f
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/Makefile.am
@@ -0,0 +1,358 @@
+# $Id$
+
+include $(top_srcdir)/Makefile.am.common
+
+AUTOMAKE_OPTIONS = subdir-objects
+
+AM_CPPFLAGS += \
+ -I$(srcdir)/../krb5 \
+ -I$(srcdir) \
+ -I$(srcdir)/gssapi \
+ -I$(srcdir)/mech \
+ -I$(srcdir)/ntlm \
+ -I$(srcdir)/krb5 \
+ -I$(srcdir)/spnego \
+ $(INCLUDE_libintl) \
+ $(INCLUDE_hcrypto) \
+ $(INCLUDE_krb4)
+
+lib_LTLIBRARIES = libgssapi.la
+
+krb5src = \
+ krb5/8003.c \
+ krb5/accept_sec_context.c \
+ krb5/acquire_cred.c \
+ krb5/add_cred.c \
+ krb5/address_to_krb5addr.c \
+ krb5/aeap.c \
+ krb5/arcfour.c \
+ krb5/canonicalize_name.c \
+ krb5/creds.c \
+ krb5/ccache_name.c \
+ krb5/cfx.c \
+ krb5/cfx.h \
+ krb5/compare_name.c \
+ krb5/compat.c \
+ krb5/context_time.c \
+ krb5/copy_ccache.c \
+ krb5/decapsulate.c \
+ krb5/delete_sec_context.c \
+ krb5/display_name.c \
+ krb5/display_status.c \
+ krb5/duplicate_name.c \
+ krb5/encapsulate.c \
+ krb5/export_name.c \
+ krb5/export_sec_context.c \
+ krb5/external.c \
+ krb5/get_mic.c \
+ krb5/gsskrb5_locl.h \
+ krb5/gsskrb5-private.h \
+ krb5/import_name.c \
+ krb5/import_sec_context.c \
+ krb5/indicate_mechs.c \
+ krb5/init.c \
+ krb5/init_sec_context.c \
+ krb5/inquire_context.c \
+ krb5/inquire_cred.c \
+ krb5/inquire_cred_by_mech.c \
+ krb5/inquire_cred_by_oid.c \
+ krb5/inquire_mechs_for_name.c \
+ krb5/inquire_names_for_mech.c \
+ krb5/inquire_sec_context_by_oid.c \
+ krb5/pname_to_uid.c \
+ krb5/process_context_token.c \
+ krb5/prf.c \
+ krb5/release_buffer.c \
+ krb5/release_cred.c \
+ krb5/release_name.c \
+ krb5/sequence.c \
+ krb5/store_cred.c \
+ krb5/set_cred_option.c \
+ krb5/set_sec_context_option.c \
+ krb5/ticket_flags.c \
+ krb5/unwrap.c \
+ krb5/authorize_localname.c \
+ krb5/verify_mic.c \
+ krb5/wrap.c
+
+mechsrc = \
+ mech/context.h \
+ mech/context.c \
+ mech/cred.h \
+ mech/compat.h \
+ mech/doxygen.c \
+ mech/gss_accept_sec_context.c \
+ mech/gss_acquire_cred.c \
+ mech/gss_acquire_cred_ext.c \
+ mech/gss_acquire_cred_with_password.c \
+ mech/gss_add_cred.c \
+ mech/gss_add_cred_with_password.c \
+ mech/gss_add_oid_set_member.c \
+ mech/gss_aeap.c \
+ mech/gss_buffer_set.c \
+ mech/gss_canonicalize_name.c \
+ mech/gss_compare_name.c \
+ mech/gss_context_time.c \
+ mech/gss_create_empty_oid_set.c \
+ mech/gss_cred.c \
+ mech/gss_decapsulate_token.c \
+ mech/gss_delete_name_attribute.c \
+ mech/gss_delete_sec_context.c \
+ mech/gss_display_name.c \
+ mech/gss_display_name_ext.c \
+ mech/gss_display_status.c \
+ mech/gss_duplicate_name.c \
+ mech/gss_duplicate_oid.c \
+ mech/gss_encapsulate_token.c \
+ mech/gss_export_name.c \
+ mech/gss_export_name_composite.c \
+ mech/gss_export_sec_context.c \
+ mech/gss_get_mic.c \
+ mech/gss_get_name_attribute.c \
+ mech/gss_import_name.c \
+ mech/gss_import_sec_context.c \
+ mech/gss_indicate_mechs.c \
+ mech/gss_init_sec_context.c \
+ mech/gss_inquire_context.c \
+ mech/gss_inquire_cred.c \
+ mech/gss_inquire_cred_by_mech.c \
+ mech/gss_inquire_cred_by_oid.c \
+ mech/gss_inquire_mechs_for_name.c \
+ mech/gss_inquire_name.c \
+ mech/gss_inquire_names_for_mech.c \
+ mech/gss_krb5.c \
+ mech/gss_mech_switch.c \
+ mech/gss_mo.c \
+ mech/gss_names.c \
+ mech/gss_oid.c \
+ mech/gss_oid_equal.c \
+ mech/gss_oid_to_str.c \
+ mech/gss_pname_to_uid.c \
+ mech/gss_process_context_token.c \
+ mech/gss_pseudo_random.c \
+ mech/gss_release_buffer.c \
+ mech/gss_release_cred.c \
+ mech/gss_release_name.c \
+ mech/gss_release_oid.c \
+ mech/gss_release_oid_set.c \
+ mech/gss_seal.c \
+ mech/gss_set_cred_option.c \
+ mech/gss_set_name_attribute.c \
+ mech/gss_set_sec_context_option.c \
+ mech/gss_sign.c \
+ mech/gss_store_cred.c \
+ mech/gss_test_oid_set_member.c \
+ mech/gss_unseal.c \
+ mech/gss_unwrap.c \
+ mech/gss_authorize_localname.c \
+ mech/gss_utils.c \
+ mech/gss_verify.c \
+ mech/gss_verify_mic.c \
+ mech/gss_wrap.c \
+ mech/gss_wrap_size_limit.c \
+ mech/gss_inquire_sec_context_by_oid.c \
+ mech/mech_switch.h \
+ mech/mechqueue.h \
+ mech/mech_locl.h \
+ mech/name.h \
+ mech/utils.h
+
+spnegosrc = \
+ spnego/accept_sec_context.c \
+ spnego/compat.c \
+ spnego/context_stubs.c \
+ spnego/cred_stubs.c \
+ spnego/external.c \
+ spnego/init_sec_context.c \
+ spnego/spnego_locl.h \
+ spnego/spnego-private.h
+
+ntlmsrc = \
+ ntlm/accept_sec_context.c \
+ ntlm/acquire_cred.c \
+ ntlm/add_cred.c \
+ ntlm/canonicalize_name.c \
+ ntlm/compare_name.c \
+ ntlm/context_time.c \
+ ntlm/creds.c \
+ ntlm/crypto.c \
+ ntlm/delete_sec_context.c \
+ ntlm/display_name.c \
+ ntlm/display_status.c \
+ ntlm/duplicate_name.c \
+ ntlm/export_name.c \
+ ntlm/export_sec_context.c \
+ ntlm/external.c \
+ ntlm/ntlm.h \
+ ntlm/ntlm-private.h \
+ ntlm/import_name.c \
+ ntlm/import_sec_context.c \
+ ntlm/indicate_mechs.c \
+ ntlm/init_sec_context.c \
+ ntlm/inquire_context.c \
+ ntlm/inquire_cred_by_mech.c \
+ ntlm/inquire_mechs_for_name.c \
+ ntlm/inquire_names_for_mech.c \
+ ntlm/inquire_sec_context_by_oid.c \
+ ntlm/iter_cred.c \
+ ntlm/process_context_token.c \
+ ntlm/release_cred.c \
+ ntlm/release_name.c \
+ ntlm/kdc.c
+
+$(srcdir)/ntlm/ntlm-private.h:
+ cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -p ntlm/ntlm-private.h $(ntlmsrc) || rm -f ntlm/ntlm-private.h
+
+dist_libgssapi_la_SOURCES = \
+ $(krb5src) \
+ $(mechsrc) \
+ $(ntlmsrc) \
+ $(spnegosrc)
+
+nodist_libgssapi_la_SOURCES = \
+ gkrb5_err.c \
+ gkrb5_err.h \
+ $(BUILT_SOURCES)
+
+libgssapi_la_DEPENDENCIES = version-script.map
+
+libgssapi_la_LDFLAGS = -version-info 3:0:0
+
+if versionscript
+libgssapi_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map
+endif
+
+libgssapi_la_LIBADD = \
+ $(top_builddir)/lib/ntlm/libheimntlm.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_com_err) \
+ $(LIB_hcrypto) \
+ $(LIBADD_roken)
+
+man_MANS = gssapi.3 gss_acquire_cred.3 mech/mech.5
+
+include_HEADERS = gssapi.h
+noinst_HEADERS = \
+ gssapi_mech.h \
+ ntlm/ntlm-private.h \
+ spnego/spnego-private.h \
+ krb5/gsskrb5-private.h
+
+nobase_include_HEADERS = \
+ gssapi/gssapi.h \
+ gssapi/gssapi_krb5.h \
+ gssapi/gssapi_ntlm.h \
+ gssapi/gssapi_oid.h \
+ gssapi/gssapi_spnego.h
+
+gssapidir = $(includedir)/gssapi
+nodist_gssapi_HEADERS = gkrb5_err.h
+
+gssapi_files = asn1_GSSAPIContextToken.x
+
+spnego_files = \
+ asn1_ContextFlags.x \
+ asn1_MechType.x \
+ asn1_MechTypeList.x \
+ asn1_NegotiationToken.x \
+ asn1_NegotiationTokenWin.x \
+ asn1_NegHints.x \
+ asn1_NegTokenInit.x \
+ asn1_NegTokenInitWin.x \
+ asn1_NegTokenResp.x
+
+BUILTHEADERS = \
+ $(srcdir)/krb5/gsskrb5-private.h \
+ $(srcdir)/spnego/spnego-private.h \
+ $(srcdir)/ntlm/ntlm-private.h
+
+$(libgssapi_la_OBJECTS): $(BUILTHEADERS)
+$(test_context_OBJECTS): $(BUILTHEADERS)
+
+$(libgssapi_la_OBJECTS): $(srcdir)/version-script.map
+
+BUILT_SOURCES = $(spnego_files:.x=.c) $(gssapi_files:.x=.c)
+
+CLEANFILES = $(BUILT_SOURCES) \
+ gkrb5_err.h gkrb5_err.c \
+ $(spnego_files) spnego_asn1*.h* spnego_asn1_files spnego_asn1-template.c \
+ $(gssapi_files) gssapi_asn1*.h* gssapi_asn1_files gssapi_asn1-template.c \
+ gss-commands.h gss-commands.c
+
+$(spnego_files) spnego_asn1.hx spnego_asn1-priv.hx: spnego_asn1_files
+$(gssapi_files) gssapi_asn1.hx gssapi_asn1-priv.hx: gssapi_asn1_files
+
+spnego_asn1_files: $(ASN1_COMPILE_DEP) $(srcdir)/spnego/spnego.asn1 $(srcdir)/spnego/spnego.opt
+ $(ASN1_COMPILE) --option-file=$(srcdir)/spnego/spnego.opt $(srcdir)/spnego/spnego.asn1 spnego_asn1
+
+gssapi_asn1_files: $(ASN1_COMPILE_DEP) $(srcdir)/mech/gssapi.asn1
+ $(ASN1_COMPILE) $(srcdir)/mech/gssapi.asn1 gssapi_asn1
+
+$(srcdir)/krb5/gsskrb5-private.h:
+ cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -p krb5/gsskrb5-private.h $(krb5src) || rm -f krb5/gsskrb5-private.h
+
+$(srcdir)/spnego/spnego-private.h:
+ cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -p spnego/spnego-private.h $(spnegosrc) || rm -f spnego/spnego-private.h
+
+
+TESTS = test_oid test_names test_cfx
+# test_sequence
+
+test_cfx_SOURCES = krb5/test_cfx.c
+
+check_PROGRAMS = test_acquire_cred $(TESTS)
+
+bin_PROGRAMS = gsstool
+noinst_PROGRAMS = test_cred test_kcred test_context test_ntlm
+
+test_context_SOURCES = test_context.c test_common.c test_common.h
+test_ntlm_SOURCES = test_ntlm.c test_common.c test_common.h
+test_acquire_cred_SOURCES = test_acquire_cred.c test_common.c test_common.h
+
+test_ntlm_LDADD = \
+ $(top_builddir)/lib/ntlm/libheimntlm.la \
+ $(LDADD)
+
+LDADD = libgssapi.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(LIB_roken)
+
+# gss
+
+dist_gsstool_SOURCES = gsstool.c
+nodist_gsstool_SOURCES = gss-commands.c gss-commands.h
+
+gsstool_LDADD = libgssapi.la \
+ $(top_builddir)/lib/sl/libsl.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(LIB_readline) \
+ $(LIB_roken)
+
+gss-commands.c gss-commands.h: gss-commands.in
+ $(SLC) $(srcdir)/gss-commands.in
+
+$(gsstool_OBJECTS): gss-commands.h
+
+EXTRA_DIST = \
+ NTMakefile \
+ libgssapi-version.rc \
+ libgssapi-exports.def \
+ $(man_MANS) \
+ krb5/gkrb5_err.et \
+ mech/gssapi.asn1 \
+ spnego/spnego.asn1 \
+ spnego/spnego.opt \
+ version-script.map \
+ gss-commands.in
+
+$(libgssapi_la_OBJECTS): gkrb5_err.h gssapi_asn1.h gssapi_asn1-priv.h
+$(libgssapi_la_OBJECTS): spnego_asn1.h spnego_asn1-priv.h
+$(libgssapi_la_OBJECTS): $(srcdir)/gssapi/gssapi_oid.h
+
+gkrb5_err.h gkrb5_err.c: $(srcdir)/krb5/gkrb5_err.et
+ $(COMPILE_ET) $(srcdir)/krb5/gkrb5_err.et
+
+$(srcdir)/gssapi/gssapi_oid.h $(srcdir)/mech/gss_oid.c:
+ perl $(srcdir)/gen-oid.pl -b base -h $(srcdir)/oid.txt > $(srcdir)/gssapi/gssapi_oid.h
+ perl $(srcdir)/gen-oid.pl -b base $(srcdir)/oid.txt > $(srcdir)/mech/gss_oid.c
diff --git a/crypto/heimdal/lib/gssapi/Makefile.in b/crypto/heimdal/lib/gssapi/Makefile.in
new file mode 100644
index 0000000..4649903
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/Makefile.in
@@ -0,0 +1,2544 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# $Id$
+
+# $Id$
+
+# $Id$
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+DIST_COMMON = $(include_HEADERS) $(nobase_include_HEADERS) \
+ $(noinst_HEADERS) $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/Makefile.am.common \
+ $(top_srcdir)/cf/Makefile.am.common ChangeLog
+@versionscript_TRUE@am__append_1 = $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map
+TESTS = test_oid$(EXEEXT) test_names$(EXEEXT) test_cfx$(EXEEXT)
+check_PROGRAMS = test_acquire_cred$(EXEEXT) $(am__EXEEXT_1)
+bin_PROGRAMS = gsstool$(EXEEXT)
+noinst_PROGRAMS = test_cred$(EXEEXT) test_kcred$(EXEEXT) \
+ test_context$(EXEEXT) test_ntlm$(EXEEXT)
+subdir = lib/gssapi
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \
+ $(top_srcdir)/cf/auth-modules.m4 \
+ $(top_srcdir)/cf/broken-getaddrinfo.m4 \
+ $(top_srcdir)/cf/broken-glob.m4 \
+ $(top_srcdir)/cf/broken-realloc.m4 \
+ $(top_srcdir)/cf/broken-snprintf.m4 $(top_srcdir)/cf/broken.m4 \
+ $(top_srcdir)/cf/broken2.m4 $(top_srcdir)/cf/c-attribute.m4 \
+ $(top_srcdir)/cf/capabilities.m4 \
+ $(top_srcdir)/cf/check-compile-et.m4 \
+ $(top_srcdir)/cf/check-getpwnam_r-posix.m4 \
+ $(top_srcdir)/cf/check-man.m4 \
+ $(top_srcdir)/cf/check-netinet-ip-and-tcp.m4 \
+ $(top_srcdir)/cf/check-type-extra.m4 \
+ $(top_srcdir)/cf/check-var.m4 $(top_srcdir)/cf/check-x.m4 \
+ $(top_srcdir)/cf/check-xau.m4 $(top_srcdir)/cf/crypto.m4 \
+ $(top_srcdir)/cf/db.m4 $(top_srcdir)/cf/destdirs.m4 \
+ $(top_srcdir)/cf/dispatch.m4 $(top_srcdir)/cf/dlopen.m4 \
+ $(top_srcdir)/cf/find-func-no-libs.m4 \
+ $(top_srcdir)/cf/find-func-no-libs2.m4 \
+ $(top_srcdir)/cf/find-func.m4 \
+ $(top_srcdir)/cf/find-if-not-broken.m4 \
+ $(top_srcdir)/cf/framework-security.m4 \
+ $(top_srcdir)/cf/have-struct-field.m4 \
+ $(top_srcdir)/cf/have-type.m4 $(top_srcdir)/cf/irix.m4 \
+ $(top_srcdir)/cf/krb-bigendian.m4 \
+ $(top_srcdir)/cf/krb-func-getlogin.m4 \
+ $(top_srcdir)/cf/krb-ipv6.m4 $(top_srcdir)/cf/krb-prog-ln-s.m4 \
+ $(top_srcdir)/cf/krb-readline.m4 \
+ $(top_srcdir)/cf/krb-struct-spwd.m4 \
+ $(top_srcdir)/cf/krb-struct-winsize.m4 \
+ $(top_srcdir)/cf/largefile.m4 $(top_srcdir)/cf/libtool.m4 \
+ $(top_srcdir)/cf/ltoptions.m4 $(top_srcdir)/cf/ltsugar.m4 \
+ $(top_srcdir)/cf/ltversion.m4 $(top_srcdir)/cf/lt~obsolete.m4 \
+ $(top_srcdir)/cf/mips-abi.m4 $(top_srcdir)/cf/misc.m4 \
+ $(top_srcdir)/cf/need-proto.m4 $(top_srcdir)/cf/osfc2.m4 \
+ $(top_srcdir)/cf/otp.m4 $(top_srcdir)/cf/pkg.m4 \
+ $(top_srcdir)/cf/proto-compat.m4 $(top_srcdir)/cf/pthreads.m4 \
+ $(top_srcdir)/cf/resolv.m4 $(top_srcdir)/cf/retsigtype.m4 \
+ $(top_srcdir)/cf/roken-frag.m4 \
+ $(top_srcdir)/cf/socket-wrapper.m4 $(top_srcdir)/cf/sunos.m4 \
+ $(top_srcdir)/cf/telnet.m4 $(top_srcdir)/cf/test-package.m4 \
+ $(top_srcdir)/cf/version-script.m4 $(top_srcdir)/cf/wflags.m4 \
+ $(top_srcdir)/cf/win32.m4 $(top_srcdir)/cf/with-all.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)" \
+ "$(DESTDIR)$(gssapidir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+am__dirstamp = $(am__leading_dot)dirstamp
+am__objects_1 = krb5/8003.lo krb5/accept_sec_context.lo \
+ krb5/acquire_cred.lo krb5/add_cred.lo \
+ krb5/address_to_krb5addr.lo krb5/aeap.lo krb5/arcfour.lo \
+ krb5/canonicalize_name.lo krb5/creds.lo krb5/ccache_name.lo \
+ krb5/cfx.lo krb5/compare_name.lo krb5/compat.lo \
+ krb5/context_time.lo krb5/copy_ccache.lo krb5/decapsulate.lo \
+ krb5/delete_sec_context.lo krb5/display_name.lo \
+ krb5/display_status.lo krb5/duplicate_name.lo \
+ krb5/encapsulate.lo krb5/export_name.lo \
+ krb5/export_sec_context.lo krb5/external.lo krb5/get_mic.lo \
+ krb5/import_name.lo krb5/import_sec_context.lo \
+ krb5/indicate_mechs.lo krb5/init.lo krb5/init_sec_context.lo \
+ krb5/inquire_context.lo krb5/inquire_cred.lo \
+ krb5/inquire_cred_by_mech.lo krb5/inquire_cred_by_oid.lo \
+ krb5/inquire_mechs_for_name.lo krb5/inquire_names_for_mech.lo \
+ krb5/inquire_sec_context_by_oid.lo krb5/pname_to_uid.lo \
+ krb5/process_context_token.lo krb5/prf.lo \
+ krb5/release_buffer.lo krb5/release_cred.lo \
+ krb5/release_name.lo krb5/sequence.lo krb5/store_cred.lo \
+ krb5/set_cred_option.lo krb5/set_sec_context_option.lo \
+ krb5/ticket_flags.lo krb5/unwrap.lo \
+ krb5/authorize_localname.lo krb5/verify_mic.lo krb5/wrap.lo
+am__objects_2 = mech/context.lo mech/doxygen.lo \
+ mech/gss_accept_sec_context.lo mech/gss_acquire_cred.lo \
+ mech/gss_acquire_cred_ext.lo \
+ mech/gss_acquire_cred_with_password.lo mech/gss_add_cred.lo \
+ mech/gss_add_cred_with_password.lo \
+ mech/gss_add_oid_set_member.lo mech/gss_aeap.lo \
+ mech/gss_buffer_set.lo mech/gss_canonicalize_name.lo \
+ mech/gss_compare_name.lo mech/gss_context_time.lo \
+ mech/gss_create_empty_oid_set.lo mech/gss_cred.lo \
+ mech/gss_decapsulate_token.lo \
+ mech/gss_delete_name_attribute.lo \
+ mech/gss_delete_sec_context.lo mech/gss_display_name.lo \
+ mech/gss_display_name_ext.lo mech/gss_display_status.lo \
+ mech/gss_duplicate_name.lo mech/gss_duplicate_oid.lo \
+ mech/gss_encapsulate_token.lo mech/gss_export_name.lo \
+ mech/gss_export_name_composite.lo \
+ mech/gss_export_sec_context.lo mech/gss_get_mic.lo \
+ mech/gss_get_name_attribute.lo mech/gss_import_name.lo \
+ mech/gss_import_sec_context.lo mech/gss_indicate_mechs.lo \
+ mech/gss_init_sec_context.lo mech/gss_inquire_context.lo \
+ mech/gss_inquire_cred.lo mech/gss_inquire_cred_by_mech.lo \
+ mech/gss_inquire_cred_by_oid.lo \
+ mech/gss_inquire_mechs_for_name.lo mech/gss_inquire_name.lo \
+ mech/gss_inquire_names_for_mech.lo mech/gss_krb5.lo \
+ mech/gss_mech_switch.lo mech/gss_mo.lo mech/gss_names.lo \
+ mech/gss_oid.lo mech/gss_oid_equal.lo mech/gss_oid_to_str.lo \
+ mech/gss_pname_to_uid.lo mech/gss_process_context_token.lo \
+ mech/gss_pseudo_random.lo mech/gss_release_buffer.lo \
+ mech/gss_release_cred.lo mech/gss_release_name.lo \
+ mech/gss_release_oid.lo mech/gss_release_oid_set.lo \
+ mech/gss_seal.lo mech/gss_set_cred_option.lo \
+ mech/gss_set_name_attribute.lo \
+ mech/gss_set_sec_context_option.lo mech/gss_sign.lo \
+ mech/gss_store_cred.lo mech/gss_test_oid_set_member.lo \
+ mech/gss_unseal.lo mech/gss_unwrap.lo \
+ mech/gss_authorize_localname.lo mech/gss_utils.lo \
+ mech/gss_verify.lo mech/gss_verify_mic.lo mech/gss_wrap.lo \
+ mech/gss_wrap_size_limit.lo \
+ mech/gss_inquire_sec_context_by_oid.lo
+am__objects_3 = ntlm/accept_sec_context.lo ntlm/acquire_cred.lo \
+ ntlm/add_cred.lo ntlm/canonicalize_name.lo \
+ ntlm/compare_name.lo ntlm/context_time.lo ntlm/creds.lo \
+ ntlm/crypto.lo ntlm/delete_sec_context.lo ntlm/display_name.lo \
+ ntlm/display_status.lo ntlm/duplicate_name.lo \
+ ntlm/export_name.lo ntlm/export_sec_context.lo \
+ ntlm/external.lo ntlm/import_name.lo \
+ ntlm/import_sec_context.lo ntlm/indicate_mechs.lo \
+ ntlm/init_sec_context.lo ntlm/inquire_context.lo \
+ ntlm/inquire_cred_by_mech.lo ntlm/inquire_mechs_for_name.lo \
+ ntlm/inquire_names_for_mech.lo \
+ ntlm/inquire_sec_context_by_oid.lo ntlm/iter_cred.lo \
+ ntlm/process_context_token.lo ntlm/release_cred.lo \
+ ntlm/release_name.lo ntlm/kdc.lo
+am__objects_4 = spnego/accept_sec_context.lo spnego/compat.lo \
+ spnego/context_stubs.lo spnego/cred_stubs.lo \
+ spnego/external.lo spnego/init_sec_context.lo
+dist_libgssapi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
+ $(am__objects_3) $(am__objects_4)
+am__objects_5 = asn1_ContextFlags.lo asn1_MechType.lo \
+ asn1_MechTypeList.lo asn1_NegotiationToken.lo \
+ asn1_NegotiationTokenWin.lo asn1_NegHints.lo \
+ asn1_NegTokenInit.lo asn1_NegTokenInitWin.lo \
+ asn1_NegTokenResp.lo
+am__objects_6 = asn1_GSSAPIContextToken.lo
+am__objects_7 = $(am__objects_5) $(am__objects_6)
+nodist_libgssapi_la_OBJECTS = gkrb5_err.lo $(am__objects_7)
+libgssapi_la_OBJECTS = $(dist_libgssapi_la_OBJECTS) \
+ $(nodist_libgssapi_la_OBJECTS)
+libgssapi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libgssapi_la_LDFLAGS) $(LDFLAGS) -o $@
+am__EXEEXT_1 = test_oid$(EXEEXT) test_names$(EXEEXT) test_cfx$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+dist_gsstool_OBJECTS = gsstool.$(OBJEXT)
+nodist_gsstool_OBJECTS = gss-commands.$(OBJEXT)
+gsstool_OBJECTS = $(dist_gsstool_OBJECTS) $(nodist_gsstool_OBJECTS)
+gsstool_DEPENDENCIES = libgssapi.la $(top_builddir)/lib/sl/libsl.la \
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_test_acquire_cred_OBJECTS = test_acquire_cred.$(OBJEXT) \
+ test_common.$(OBJEXT)
+test_acquire_cred_OBJECTS = $(am_test_acquire_cred_OBJECTS)
+test_acquire_cred_LDADD = $(LDADD)
+test_acquire_cred_DEPENDENCIES = libgssapi.la \
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1)
+am_test_cfx_OBJECTS = krb5/test_cfx.$(OBJEXT)
+test_cfx_OBJECTS = $(am_test_cfx_OBJECTS)
+test_cfx_LDADD = $(LDADD)
+test_cfx_DEPENDENCIES = libgssapi.la \
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1)
+am_test_context_OBJECTS = test_context.$(OBJEXT) test_common.$(OBJEXT)
+test_context_OBJECTS = $(am_test_context_OBJECTS)
+test_context_LDADD = $(LDADD)
+test_context_DEPENDENCIES = libgssapi.la \
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1)
+test_cred_SOURCES = test_cred.c
+test_cred_OBJECTS = test_cred.$(OBJEXT)
+test_cred_LDADD = $(LDADD)
+test_cred_DEPENDENCIES = libgssapi.la \
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1)
+test_kcred_SOURCES = test_kcred.c
+test_kcred_OBJECTS = test_kcred.$(OBJEXT)
+test_kcred_LDADD = $(LDADD)
+test_kcred_DEPENDENCIES = libgssapi.la \
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1)
+test_names_SOURCES = test_names.c
+test_names_OBJECTS = test_names.$(OBJEXT)
+test_names_LDADD = $(LDADD)
+test_names_DEPENDENCIES = libgssapi.la \
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1)
+am_test_ntlm_OBJECTS = test_ntlm.$(OBJEXT) test_common.$(OBJEXT)
+test_ntlm_OBJECTS = $(am_test_ntlm_OBJECTS)
+am__DEPENDENCIES_2 = libgssapi.la $(top_builddir)/lib/krb5/libkrb5.la \
+ $(am__DEPENDENCIES_1)
+test_ntlm_DEPENDENCIES = $(top_builddir)/lib/ntlm/libheimntlm.la \
+ $(am__DEPENDENCIES_2)
+test_oid_SOURCES = test_oid.c
+test_oid_OBJECTS = test_oid.$(OBJEXT)
+test_oid_LDADD = $(LDADD)
+test_oid_DEPENDENCIES = libgssapi.la \
+ $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(dist_libgssapi_la_SOURCES) $(nodist_libgssapi_la_SOURCES) \
+ $(dist_gsstool_SOURCES) $(nodist_gsstool_SOURCES) \
+ $(test_acquire_cred_SOURCES) $(test_cfx_SOURCES) \
+ $(test_context_SOURCES) test_cred.c test_kcred.c test_names.c \
+ $(test_ntlm_SOURCES) test_oid.c
+DIST_SOURCES = $(dist_libgssapi_la_SOURCES) $(dist_gsstool_SOURCES) \
+ $(test_acquire_cred_SOURCES) $(test_cfx_SOURCES) \
+ $(test_context_SOURCES) test_cred.c test_kcred.c test_names.c \
+ $(test_ntlm_SOURCES) test_oid.c
+man3dir = $(mandir)/man3
+man5dir = $(mandir)/man5
+MANS = $(man_MANS)
+HEADERS = $(include_HEADERS) $(nobase_include_HEADERS) \
+ $(nodist_gssapi_HEADERS) $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AMTAR = @AMTAR@
+AR = @AR@
+ASN1_COMPILE = @ASN1_COMPILE@
+ASN1_COMPILE_DEP = @ASN1_COMPILE_DEP@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CAPNG_CFLAGS = @CAPNG_CFLAGS@
+CAPNG_LIBS = @CAPNG_LIBS@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMPILE_ET = @COMPILE_ET@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBHEADER = @DBHEADER@
+DBLIB = @DBLIB@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIR_com_err = @DIR_com_err@
+DIR_hcrypto = @DIR_hcrypto@
+DIR_hdbdir = @DIR_hdbdir@
+DIR_roken = @DIR_roken@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INCLUDES_roken = @INCLUDES_roken@
+INCLUDE_hcrypto = @INCLUDE_hcrypto@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+INCLUDE_krb4 = @INCLUDE_krb4@
+INCLUDE_libedit = @INCLUDE_libedit@
+INCLUDE_libintl = @INCLUDE_libintl@
+INCLUDE_openldap = @INCLUDE_openldap@
+INCLUDE_readline = @INCLUDE_readline@
+INCLUDE_sqlite3 = @INCLUDE_sqlite3@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_VERSION_SCRIPT = @LDFLAGS_VERSION_SCRIPT@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBADD_roken = @LIBADD_roken@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_NDBM = @LIB_NDBM@
+LIB_XauFileName = @LIB_XauFileName@
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_XauWriteAuth = @LIB_XauWriteAuth@
+LIB_bswap16 = @LIB_bswap16@
+LIB_bswap32 = @LIB_bswap32@
+LIB_com_err = @LIB_com_err@
+LIB_com_err_a = @LIB_com_err_a@
+LIB_com_err_so = @LIB_com_err_so@
+LIB_crypt = @LIB_crypt@
+LIB_db_create = @LIB_db_create@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dispatch_async_f = @LIB_dispatch_async_f@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_dns_search = @LIB_dns_search@
+LIB_door_create = @LIB_door_create@
+LIB_freeaddrinfo = @LIB_freeaddrinfo@
+LIB_gai_strerror = @LIB_gai_strerror@
+LIB_getaddrinfo = @LIB_getaddrinfo@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_gethostbyname2 = @LIB_gethostbyname2@
+LIB_getnameinfo = @LIB_getnameinfo@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_hcrypto = @LIB_hcrypto@
+LIB_hcrypto_a = @LIB_hcrypto_a@
+LIB_hcrypto_appl = @LIB_hcrypto_appl@
+LIB_hcrypto_so = @LIB_hcrypto_so@
+LIB_hesiod = @LIB_hesiod@
+LIB_hstrerror = @LIB_hstrerror@
+LIB_kdb = @LIB_kdb@
+LIB_krb4 = @LIB_krb4@
+LIB_libedit = @LIB_libedit@
+LIB_libintl = @LIB_libintl@
+LIB_loadquery = @LIB_loadquery@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_openldap = @LIB_openldap@
+LIB_openpty = @LIB_openpty@
+LIB_otp = @LIB_otp@
+LIB_pidfile = @LIB_pidfile@
+LIB_readline = @LIB_readline@
+LIB_res_ndestroy = @LIB_res_ndestroy@
+LIB_res_nsearch = @LIB_res_nsearch@
+LIB_res_search = @LIB_res_search@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_sqlite3 = @LIB_sqlite3@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_AFS = @NO_AFS@
+NROFF = @NROFF@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDADD = @PTHREAD_LDADD@
+PTHREAD_LIBADD = @PTHREAD_LIBADD@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SLC = @SLC@
+SLC_DEP = @SLC_DEP@
+STRIP = @STRIP@
+VERSION = @VERSION@
+VERSIONING = @VERSIONING@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dpagaix_cflags = @dpagaix_cflags@
+dpagaix_ldadd = @dpagaix_ldadd@
+dpagaix_ldflags = @dpagaix_ldflags@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUFFIXES = .et .h .x .z .hx .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include
+AM_CPPFLAGS = $(INCLUDES_roken) -I$(srcdir)/../krb5 -I$(srcdir) \
+ -I$(srcdir)/gssapi -I$(srcdir)/mech -I$(srcdir)/ntlm \
+ -I$(srcdir)/krb5 -I$(srcdir)/spnego $(INCLUDE_libintl) \
+ $(INCLUDE_hcrypto) $(INCLUDE_krb4)
+@do_roken_rename_TRUE@ROKEN_RENAME = -DROKEN_RENAME
+AM_CFLAGS = $(WFLAGS)
+CP = cp
+buildinclude = $(top_builddir)/include
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_setpcred = @LIB_setpcred@
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+libexec_heimdaldir = $(libexecdir)/heimdal
+NROFF_MAN = groff -mandoc -Tascii
+LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la \
+@KRB5_TRUE@ $(top_builddir)/lib/asn1/libasn1.la
+
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+LIB_heimbase = $(top_builddir)/base/libheimbase.la
+@DCE_TRUE@LIB_kdfs = $(top_builddir)/lib/kdfs/libkdfs.la
+AUTOMAKE_OPTIONS = subdir-objects
+lib_LTLIBRARIES = libgssapi.la
+krb5src = \
+ krb5/8003.c \
+ krb5/accept_sec_context.c \
+ krb5/acquire_cred.c \
+ krb5/add_cred.c \
+ krb5/address_to_krb5addr.c \
+ krb5/aeap.c \
+ krb5/arcfour.c \
+ krb5/canonicalize_name.c \
+ krb5/creds.c \
+ krb5/ccache_name.c \
+ krb5/cfx.c \
+ krb5/cfx.h \
+ krb5/compare_name.c \
+ krb5/compat.c \
+ krb5/context_time.c \
+ krb5/copy_ccache.c \
+ krb5/decapsulate.c \
+ krb5/delete_sec_context.c \
+ krb5/display_name.c \
+ krb5/display_status.c \
+ krb5/duplicate_name.c \
+ krb5/encapsulate.c \
+ krb5/export_name.c \
+ krb5/export_sec_context.c \
+ krb5/external.c \
+ krb5/get_mic.c \
+ krb5/gsskrb5_locl.h \
+ krb5/gsskrb5-private.h \
+ krb5/import_name.c \
+ krb5/import_sec_context.c \
+ krb5/indicate_mechs.c \
+ krb5/init.c \
+ krb5/init_sec_context.c \
+ krb5/inquire_context.c \
+ krb5/inquire_cred.c \
+ krb5/inquire_cred_by_mech.c \
+ krb5/inquire_cred_by_oid.c \
+ krb5/inquire_mechs_for_name.c \
+ krb5/inquire_names_for_mech.c \
+ krb5/inquire_sec_context_by_oid.c \
+ krb5/pname_to_uid.c \
+ krb5/process_context_token.c \
+ krb5/prf.c \
+ krb5/release_buffer.c \
+ krb5/release_cred.c \
+ krb5/release_name.c \
+ krb5/sequence.c \
+ krb5/store_cred.c \
+ krb5/set_cred_option.c \
+ krb5/set_sec_context_option.c \
+ krb5/ticket_flags.c \
+ krb5/unwrap.c \
+ krb5/authorize_localname.c \
+ krb5/verify_mic.c \
+ krb5/wrap.c
+
+mechsrc = \
+ mech/context.h \
+ mech/context.c \
+ mech/cred.h \
+ mech/compat.h \
+ mech/doxygen.c \
+ mech/gss_accept_sec_context.c \
+ mech/gss_acquire_cred.c \
+ mech/gss_acquire_cred_ext.c \
+ mech/gss_acquire_cred_with_password.c \
+ mech/gss_add_cred.c \
+ mech/gss_add_cred_with_password.c \
+ mech/gss_add_oid_set_member.c \
+ mech/gss_aeap.c \
+ mech/gss_buffer_set.c \
+ mech/gss_canonicalize_name.c \
+ mech/gss_compare_name.c \
+ mech/gss_context_time.c \
+ mech/gss_create_empty_oid_set.c \
+ mech/gss_cred.c \
+ mech/gss_decapsulate_token.c \
+ mech/gss_delete_name_attribute.c \
+ mech/gss_delete_sec_context.c \
+ mech/gss_display_name.c \
+ mech/gss_display_name_ext.c \
+ mech/gss_display_status.c \
+ mech/gss_duplicate_name.c \
+ mech/gss_duplicate_oid.c \
+ mech/gss_encapsulate_token.c \
+ mech/gss_export_name.c \
+ mech/gss_export_name_composite.c \
+ mech/gss_export_sec_context.c \
+ mech/gss_get_mic.c \
+ mech/gss_get_name_attribute.c \
+ mech/gss_import_name.c \
+ mech/gss_import_sec_context.c \
+ mech/gss_indicate_mechs.c \
+ mech/gss_init_sec_context.c \
+ mech/gss_inquire_context.c \
+ mech/gss_inquire_cred.c \
+ mech/gss_inquire_cred_by_mech.c \
+ mech/gss_inquire_cred_by_oid.c \
+ mech/gss_inquire_mechs_for_name.c \
+ mech/gss_inquire_name.c \
+ mech/gss_inquire_names_for_mech.c \
+ mech/gss_krb5.c \
+ mech/gss_mech_switch.c \
+ mech/gss_mo.c \
+ mech/gss_names.c \
+ mech/gss_oid.c \
+ mech/gss_oid_equal.c \
+ mech/gss_oid_to_str.c \
+ mech/gss_pname_to_uid.c \
+ mech/gss_process_context_token.c \
+ mech/gss_pseudo_random.c \
+ mech/gss_release_buffer.c \
+ mech/gss_release_cred.c \
+ mech/gss_release_name.c \
+ mech/gss_release_oid.c \
+ mech/gss_release_oid_set.c \
+ mech/gss_seal.c \
+ mech/gss_set_cred_option.c \
+ mech/gss_set_name_attribute.c \
+ mech/gss_set_sec_context_option.c \
+ mech/gss_sign.c \
+ mech/gss_store_cred.c \
+ mech/gss_test_oid_set_member.c \
+ mech/gss_unseal.c \
+ mech/gss_unwrap.c \
+ mech/gss_authorize_localname.c \
+ mech/gss_utils.c \
+ mech/gss_verify.c \
+ mech/gss_verify_mic.c \
+ mech/gss_wrap.c \
+ mech/gss_wrap_size_limit.c \
+ mech/gss_inquire_sec_context_by_oid.c \
+ mech/mech_switch.h \
+ mech/mechqueue.h \
+ mech/mech_locl.h \
+ mech/name.h \
+ mech/utils.h
+
+spnegosrc = \
+ spnego/accept_sec_context.c \
+ spnego/compat.c \
+ spnego/context_stubs.c \
+ spnego/cred_stubs.c \
+ spnego/external.c \
+ spnego/init_sec_context.c \
+ spnego/spnego_locl.h \
+ spnego/spnego-private.h
+
+ntlmsrc = \
+ ntlm/accept_sec_context.c \
+ ntlm/acquire_cred.c \
+ ntlm/add_cred.c \
+ ntlm/canonicalize_name.c \
+ ntlm/compare_name.c \
+ ntlm/context_time.c \
+ ntlm/creds.c \
+ ntlm/crypto.c \
+ ntlm/delete_sec_context.c \
+ ntlm/display_name.c \
+ ntlm/display_status.c \
+ ntlm/duplicate_name.c \
+ ntlm/export_name.c \
+ ntlm/export_sec_context.c \
+ ntlm/external.c \
+ ntlm/ntlm.h \
+ ntlm/ntlm-private.h \
+ ntlm/import_name.c \
+ ntlm/import_sec_context.c \
+ ntlm/indicate_mechs.c \
+ ntlm/init_sec_context.c \
+ ntlm/inquire_context.c \
+ ntlm/inquire_cred_by_mech.c \
+ ntlm/inquire_mechs_for_name.c \
+ ntlm/inquire_names_for_mech.c \
+ ntlm/inquire_sec_context_by_oid.c \
+ ntlm/iter_cred.c \
+ ntlm/process_context_token.c \
+ ntlm/release_cred.c \
+ ntlm/release_name.c \
+ ntlm/kdc.c
+
+dist_libgssapi_la_SOURCES = \
+ $(krb5src) \
+ $(mechsrc) \
+ $(ntlmsrc) \
+ $(spnegosrc)
+
+nodist_libgssapi_la_SOURCES = \
+ gkrb5_err.c \
+ gkrb5_err.h \
+ $(BUILT_SOURCES)
+
+libgssapi_la_DEPENDENCIES = version-script.map
+libgssapi_la_LDFLAGS = -version-info 3:0:0 $(am__append_1)
+libgssapi_la_LIBADD = \
+ $(top_builddir)/lib/ntlm/libheimntlm.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_com_err) \
+ $(LIB_hcrypto) \
+ $(LIBADD_roken)
+
+man_MANS = gssapi.3 gss_acquire_cred.3 mech/mech.5
+include_HEADERS = gssapi.h
+noinst_HEADERS = \
+ gssapi_mech.h \
+ ntlm/ntlm-private.h \
+ spnego/spnego-private.h \
+ krb5/gsskrb5-private.h
+
+nobase_include_HEADERS = \
+ gssapi/gssapi.h \
+ gssapi/gssapi_krb5.h \
+ gssapi/gssapi_ntlm.h \
+ gssapi/gssapi_oid.h \
+ gssapi/gssapi_spnego.h
+
+gssapidir = $(includedir)/gssapi
+nodist_gssapi_HEADERS = gkrb5_err.h
+gssapi_files = asn1_GSSAPIContextToken.x
+spnego_files = \
+ asn1_ContextFlags.x \
+ asn1_MechType.x \
+ asn1_MechTypeList.x \
+ asn1_NegotiationToken.x \
+ asn1_NegotiationTokenWin.x \
+ asn1_NegHints.x \
+ asn1_NegTokenInit.x \
+ asn1_NegTokenInitWin.x \
+ asn1_NegTokenResp.x
+
+BUILTHEADERS = \
+ $(srcdir)/krb5/gsskrb5-private.h \
+ $(srcdir)/spnego/spnego-private.h \
+ $(srcdir)/ntlm/ntlm-private.h
+
+BUILT_SOURCES = $(spnego_files:.x=.c) $(gssapi_files:.x=.c)
+CLEANFILES = $(BUILT_SOURCES) \
+ gkrb5_err.h gkrb5_err.c \
+ $(spnego_files) spnego_asn1*.h* spnego_asn1_files spnego_asn1-template.c \
+ $(gssapi_files) gssapi_asn1*.h* gssapi_asn1_files gssapi_asn1-template.c \
+ gss-commands.h gss-commands.c
+
+# test_sequence
+test_cfx_SOURCES = krb5/test_cfx.c
+test_context_SOURCES = test_context.c test_common.c test_common.h
+test_ntlm_SOURCES = test_ntlm.c test_common.c test_common.h
+test_acquire_cred_SOURCES = test_acquire_cred.c test_common.c test_common.h
+test_ntlm_LDADD = \
+ $(top_builddir)/lib/ntlm/libheimntlm.la \
+ $(LDADD)
+
+LDADD = libgssapi.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(LIB_roken)
+
+
+# gss
+dist_gsstool_SOURCES = gsstool.c
+nodist_gsstool_SOURCES = gss-commands.c gss-commands.h
+gsstool_LDADD = libgssapi.la \
+ $(top_builddir)/lib/sl/libsl.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(LIB_readline) \
+ $(LIB_roken)
+
+EXTRA_DIST = \
+ NTMakefile \
+ libgssapi-version.rc \
+ libgssapi-exports.def \
+ $(man_MANS) \
+ krb5/gkrb5_err.et \
+ mech/gssapi.asn1 \
+ spnego/spnego.asn1 \
+ spnego/spnego.opt \
+ version-script.map \
+ gss-commands.in
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .et .h .x .z .hx .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/gssapi/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign lib/gssapi/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+krb5/$(am__dirstamp):
+ @$(MKDIR_P) krb5
+ @: > krb5/$(am__dirstamp)
+krb5/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) krb5/$(DEPDIR)
+ @: > krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/8003.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/accept_sec_context.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/acquire_cred.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/add_cred.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/address_to_krb5addr.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/aeap.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/arcfour.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/canonicalize_name.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/creds.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/ccache_name.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/cfx.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/compare_name.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/compat.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/context_time.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/copy_ccache.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/decapsulate.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/delete_sec_context.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/display_name.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/display_status.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/duplicate_name.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/encapsulate.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/export_name.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/export_sec_context.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/external.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/get_mic.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/import_name.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/import_sec_context.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/indicate_mechs.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/init.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/init_sec_context.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/inquire_context.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/inquire_cred.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/inquire_cred_by_mech.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/inquire_cred_by_oid.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/inquire_mechs_for_name.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/inquire_names_for_mech.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/inquire_sec_context_by_oid.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/pname_to_uid.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/process_context_token.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/prf.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/release_buffer.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/release_cred.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/release_name.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/sequence.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/store_cred.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/set_cred_option.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/set_sec_context_option.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/ticket_flags.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/unwrap.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/authorize_localname.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/verify_mic.lo: krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+krb5/wrap.lo: krb5/$(am__dirstamp) krb5/$(DEPDIR)/$(am__dirstamp)
+mech/$(am__dirstamp):
+ @$(MKDIR_P) mech
+ @: > mech/$(am__dirstamp)
+mech/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) mech/$(DEPDIR)
+ @: > mech/$(DEPDIR)/$(am__dirstamp)
+mech/context.lo: mech/$(am__dirstamp) mech/$(DEPDIR)/$(am__dirstamp)
+mech/doxygen.lo: mech/$(am__dirstamp) mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_accept_sec_context.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_acquire_cred.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_acquire_cred_ext.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_acquire_cred_with_password.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_add_cred.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_add_cred_with_password.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_add_oid_set_member.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_aeap.lo: mech/$(am__dirstamp) mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_buffer_set.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_canonicalize_name.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_compare_name.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_context_time.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_create_empty_oid_set.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_cred.lo: mech/$(am__dirstamp) mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_decapsulate_token.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_delete_name_attribute.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_delete_sec_context.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_display_name.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_display_name_ext.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_display_status.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_duplicate_name.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_duplicate_oid.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_encapsulate_token.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_export_name.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_export_name_composite.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_export_sec_context.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_get_mic.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_get_name_attribute.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_import_name.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_import_sec_context.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_indicate_mechs.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_init_sec_context.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_inquire_context.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_inquire_cred.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_inquire_cred_by_mech.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_inquire_cred_by_oid.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_inquire_mechs_for_name.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_inquire_name.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_inquire_names_for_mech.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_krb5.lo: mech/$(am__dirstamp) mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_mech_switch.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_mo.lo: mech/$(am__dirstamp) mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_names.lo: mech/$(am__dirstamp) mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_oid.lo: mech/$(am__dirstamp) mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_oid_equal.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_oid_to_str.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_pname_to_uid.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_process_context_token.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_pseudo_random.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_release_buffer.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_release_cred.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_release_name.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_release_oid.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_release_oid_set.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_seal.lo: mech/$(am__dirstamp) mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_set_cred_option.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_set_name_attribute.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_set_sec_context_option.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_sign.lo: mech/$(am__dirstamp) mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_store_cred.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_test_oid_set_member.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_unseal.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_unwrap.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_authorize_localname.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_utils.lo: mech/$(am__dirstamp) mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_verify.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_verify_mic.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_wrap.lo: mech/$(am__dirstamp) mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_wrap_size_limit.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+mech/gss_inquire_sec_context_by_oid.lo: mech/$(am__dirstamp) \
+ mech/$(DEPDIR)/$(am__dirstamp)
+ntlm/$(am__dirstamp):
+ @$(MKDIR_P) ntlm
+ @: > ntlm/$(am__dirstamp)
+ntlm/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) ntlm/$(DEPDIR)
+ @: > ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/accept_sec_context.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/acquire_cred.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/add_cred.lo: ntlm/$(am__dirstamp) ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/canonicalize_name.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/compare_name.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/context_time.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/creds.lo: ntlm/$(am__dirstamp) ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/crypto.lo: ntlm/$(am__dirstamp) ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/delete_sec_context.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/display_name.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/display_status.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/duplicate_name.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/export_name.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/export_sec_context.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/external.lo: ntlm/$(am__dirstamp) ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/import_name.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/import_sec_context.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/indicate_mechs.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/init_sec_context.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/inquire_context.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/inquire_cred_by_mech.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/inquire_mechs_for_name.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/inquire_names_for_mech.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/inquire_sec_context_by_oid.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/iter_cred.lo: ntlm/$(am__dirstamp) ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/process_context_token.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/release_cred.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/release_name.lo: ntlm/$(am__dirstamp) \
+ ntlm/$(DEPDIR)/$(am__dirstamp)
+ntlm/kdc.lo: ntlm/$(am__dirstamp) ntlm/$(DEPDIR)/$(am__dirstamp)
+spnego/$(am__dirstamp):
+ @$(MKDIR_P) spnego
+ @: > spnego/$(am__dirstamp)
+spnego/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) spnego/$(DEPDIR)
+ @: > spnego/$(DEPDIR)/$(am__dirstamp)
+spnego/accept_sec_context.lo: spnego/$(am__dirstamp) \
+ spnego/$(DEPDIR)/$(am__dirstamp)
+spnego/compat.lo: spnego/$(am__dirstamp) \
+ spnego/$(DEPDIR)/$(am__dirstamp)
+spnego/context_stubs.lo: spnego/$(am__dirstamp) \
+ spnego/$(DEPDIR)/$(am__dirstamp)
+spnego/cred_stubs.lo: spnego/$(am__dirstamp) \
+ spnego/$(DEPDIR)/$(am__dirstamp)
+spnego/external.lo: spnego/$(am__dirstamp) \
+ spnego/$(DEPDIR)/$(am__dirstamp)
+spnego/init_sec_context.lo: spnego/$(am__dirstamp) \
+ spnego/$(DEPDIR)/$(am__dirstamp)
+libgssapi.la: $(libgssapi_la_OBJECTS) $(libgssapi_la_DEPENDENCIES)
+ $(libgssapi_la_LINK) -rpath $(libdir) $(libgssapi_la_OBJECTS) $(libgssapi_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+gsstool$(EXEEXT): $(gsstool_OBJECTS) $(gsstool_DEPENDENCIES)
+ @rm -f gsstool$(EXEEXT)
+ $(LINK) $(gsstool_OBJECTS) $(gsstool_LDADD) $(LIBS)
+test_acquire_cred$(EXEEXT): $(test_acquire_cred_OBJECTS) $(test_acquire_cred_DEPENDENCIES)
+ @rm -f test_acquire_cred$(EXEEXT)
+ $(LINK) $(test_acquire_cred_OBJECTS) $(test_acquire_cred_LDADD) $(LIBS)
+krb5/test_cfx.$(OBJEXT): krb5/$(am__dirstamp) \
+ krb5/$(DEPDIR)/$(am__dirstamp)
+test_cfx$(EXEEXT): $(test_cfx_OBJECTS) $(test_cfx_DEPENDENCIES)
+ @rm -f test_cfx$(EXEEXT)
+ $(LINK) $(test_cfx_OBJECTS) $(test_cfx_LDADD) $(LIBS)
+test_context$(EXEEXT): $(test_context_OBJECTS) $(test_context_DEPENDENCIES)
+ @rm -f test_context$(EXEEXT)
+ $(LINK) $(test_context_OBJECTS) $(test_context_LDADD) $(LIBS)
+test_cred$(EXEEXT): $(test_cred_OBJECTS) $(test_cred_DEPENDENCIES)
+ @rm -f test_cred$(EXEEXT)
+ $(LINK) $(test_cred_OBJECTS) $(test_cred_LDADD) $(LIBS)
+test_kcred$(EXEEXT): $(test_kcred_OBJECTS) $(test_kcred_DEPENDENCIES)
+ @rm -f test_kcred$(EXEEXT)
+ $(LINK) $(test_kcred_OBJECTS) $(test_kcred_LDADD) $(LIBS)
+test_names$(EXEEXT): $(test_names_OBJECTS) $(test_names_DEPENDENCIES)
+ @rm -f test_names$(EXEEXT)
+ $(LINK) $(test_names_OBJECTS) $(test_names_LDADD) $(LIBS)
+test_ntlm$(EXEEXT): $(test_ntlm_OBJECTS) $(test_ntlm_DEPENDENCIES)
+ @rm -f test_ntlm$(EXEEXT)
+ $(LINK) $(test_ntlm_OBJECTS) $(test_ntlm_LDADD) $(LIBS)
+test_oid$(EXEEXT): $(test_oid_OBJECTS) $(test_oid_DEPENDENCIES)
+ @rm -f test_oid$(EXEEXT)
+ $(LINK) $(test_oid_OBJECTS) $(test_oid_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+ -rm -f krb5/8003.$(OBJEXT)
+ -rm -f krb5/8003.lo
+ -rm -f krb5/accept_sec_context.$(OBJEXT)
+ -rm -f krb5/accept_sec_context.lo
+ -rm -f krb5/acquire_cred.$(OBJEXT)
+ -rm -f krb5/acquire_cred.lo
+ -rm -f krb5/add_cred.$(OBJEXT)
+ -rm -f krb5/add_cred.lo
+ -rm -f krb5/address_to_krb5addr.$(OBJEXT)
+ -rm -f krb5/address_to_krb5addr.lo
+ -rm -f krb5/aeap.$(OBJEXT)
+ -rm -f krb5/aeap.lo
+ -rm -f krb5/arcfour.$(OBJEXT)
+ -rm -f krb5/arcfour.lo
+ -rm -f krb5/authorize_localname.$(OBJEXT)
+ -rm -f krb5/authorize_localname.lo
+ -rm -f krb5/canonicalize_name.$(OBJEXT)
+ -rm -f krb5/canonicalize_name.lo
+ -rm -f krb5/ccache_name.$(OBJEXT)
+ -rm -f krb5/ccache_name.lo
+ -rm -f krb5/cfx.$(OBJEXT)
+ -rm -f krb5/cfx.lo
+ -rm -f krb5/compare_name.$(OBJEXT)
+ -rm -f krb5/compare_name.lo
+ -rm -f krb5/compat.$(OBJEXT)
+ -rm -f krb5/compat.lo
+ -rm -f krb5/context_time.$(OBJEXT)
+ -rm -f krb5/context_time.lo
+ -rm -f krb5/copy_ccache.$(OBJEXT)
+ -rm -f krb5/copy_ccache.lo
+ -rm -f krb5/creds.$(OBJEXT)
+ -rm -f krb5/creds.lo
+ -rm -f krb5/decapsulate.$(OBJEXT)
+ -rm -f krb5/decapsulate.lo
+ -rm -f krb5/delete_sec_context.$(OBJEXT)
+ -rm -f krb5/delete_sec_context.lo
+ -rm -f krb5/display_name.$(OBJEXT)
+ -rm -f krb5/display_name.lo
+ -rm -f krb5/display_status.$(OBJEXT)
+ -rm -f krb5/display_status.lo
+ -rm -f krb5/duplicate_name.$(OBJEXT)
+ -rm -f krb5/duplicate_name.lo
+ -rm -f krb5/encapsulate.$(OBJEXT)
+ -rm -f krb5/encapsulate.lo
+ -rm -f krb5/export_name.$(OBJEXT)
+ -rm -f krb5/export_name.lo
+ -rm -f krb5/export_sec_context.$(OBJEXT)
+ -rm -f krb5/export_sec_context.lo
+ -rm -f krb5/external.$(OBJEXT)
+ -rm -f krb5/external.lo
+ -rm -f krb5/get_mic.$(OBJEXT)
+ -rm -f krb5/get_mic.lo
+ -rm -f krb5/import_name.$(OBJEXT)
+ -rm -f krb5/import_name.lo
+ -rm -f krb5/import_sec_context.$(OBJEXT)
+ -rm -f krb5/import_sec_context.lo
+ -rm -f krb5/indicate_mechs.$(OBJEXT)
+ -rm -f krb5/indicate_mechs.lo
+ -rm -f krb5/init.$(OBJEXT)
+ -rm -f krb5/init.lo
+ -rm -f krb5/init_sec_context.$(OBJEXT)
+ -rm -f krb5/init_sec_context.lo
+ -rm -f krb5/inquire_context.$(OBJEXT)
+ -rm -f krb5/inquire_context.lo
+ -rm -f krb5/inquire_cred.$(OBJEXT)
+ -rm -f krb5/inquire_cred.lo
+ -rm -f krb5/inquire_cred_by_mech.$(OBJEXT)
+ -rm -f krb5/inquire_cred_by_mech.lo
+ -rm -f krb5/inquire_cred_by_oid.$(OBJEXT)
+ -rm -f krb5/inquire_cred_by_oid.lo
+ -rm -f krb5/inquire_mechs_for_name.$(OBJEXT)
+ -rm -f krb5/inquire_mechs_for_name.lo
+ -rm -f krb5/inquire_names_for_mech.$(OBJEXT)
+ -rm -f krb5/inquire_names_for_mech.lo
+ -rm -f krb5/inquire_sec_context_by_oid.$(OBJEXT)
+ -rm -f krb5/inquire_sec_context_by_oid.lo
+ -rm -f krb5/pname_to_uid.$(OBJEXT)
+ -rm -f krb5/pname_to_uid.lo
+ -rm -f krb5/prf.$(OBJEXT)
+ -rm -f krb5/prf.lo
+ -rm -f krb5/process_context_token.$(OBJEXT)
+ -rm -f krb5/process_context_token.lo
+ -rm -f krb5/release_buffer.$(OBJEXT)
+ -rm -f krb5/release_buffer.lo
+ -rm -f krb5/release_cred.$(OBJEXT)
+ -rm -f krb5/release_cred.lo
+ -rm -f krb5/release_name.$(OBJEXT)
+ -rm -f krb5/release_name.lo
+ -rm -f krb5/sequence.$(OBJEXT)
+ -rm -f krb5/sequence.lo
+ -rm -f krb5/set_cred_option.$(OBJEXT)
+ -rm -f krb5/set_cred_option.lo
+ -rm -f krb5/set_sec_context_option.$(OBJEXT)
+ -rm -f krb5/set_sec_context_option.lo
+ -rm -f krb5/store_cred.$(OBJEXT)
+ -rm -f krb5/store_cred.lo
+ -rm -f krb5/test_cfx.$(OBJEXT)
+ -rm -f krb5/ticket_flags.$(OBJEXT)
+ -rm -f krb5/ticket_flags.lo
+ -rm -f krb5/unwrap.$(OBJEXT)
+ -rm -f krb5/unwrap.lo
+ -rm -f krb5/verify_mic.$(OBJEXT)
+ -rm -f krb5/verify_mic.lo
+ -rm -f krb5/wrap.$(OBJEXT)
+ -rm -f krb5/wrap.lo
+ -rm -f mech/context.$(OBJEXT)
+ -rm -f mech/context.lo
+ -rm -f mech/doxygen.$(OBJEXT)
+ -rm -f mech/doxygen.lo
+ -rm -f mech/gss_accept_sec_context.$(OBJEXT)
+ -rm -f mech/gss_accept_sec_context.lo
+ -rm -f mech/gss_acquire_cred.$(OBJEXT)
+ -rm -f mech/gss_acquire_cred.lo
+ -rm -f mech/gss_acquire_cred_ext.$(OBJEXT)
+ -rm -f mech/gss_acquire_cred_ext.lo
+ -rm -f mech/gss_acquire_cred_with_password.$(OBJEXT)
+ -rm -f mech/gss_acquire_cred_with_password.lo
+ -rm -f mech/gss_add_cred.$(OBJEXT)
+ -rm -f mech/gss_add_cred.lo
+ -rm -f mech/gss_add_cred_with_password.$(OBJEXT)
+ -rm -f mech/gss_add_cred_with_password.lo
+ -rm -f mech/gss_add_oid_set_member.$(OBJEXT)
+ -rm -f mech/gss_add_oid_set_member.lo
+ -rm -f mech/gss_aeap.$(OBJEXT)
+ -rm -f mech/gss_aeap.lo
+ -rm -f mech/gss_authorize_localname.$(OBJEXT)
+ -rm -f mech/gss_authorize_localname.lo
+ -rm -f mech/gss_buffer_set.$(OBJEXT)
+ -rm -f mech/gss_buffer_set.lo
+ -rm -f mech/gss_canonicalize_name.$(OBJEXT)
+ -rm -f mech/gss_canonicalize_name.lo
+ -rm -f mech/gss_compare_name.$(OBJEXT)
+ -rm -f mech/gss_compare_name.lo
+ -rm -f mech/gss_context_time.$(OBJEXT)
+ -rm -f mech/gss_context_time.lo
+ -rm -f mech/gss_create_empty_oid_set.$(OBJEXT)
+ -rm -f mech/gss_create_empty_oid_set.lo
+ -rm -f mech/gss_cred.$(OBJEXT)
+ -rm -f mech/gss_cred.lo
+ -rm -f mech/gss_decapsulate_token.$(OBJEXT)
+ -rm -f mech/gss_decapsulate_token.lo
+ -rm -f mech/gss_delete_name_attribute.$(OBJEXT)
+ -rm -f mech/gss_delete_name_attribute.lo
+ -rm -f mech/gss_delete_sec_context.$(OBJEXT)
+ -rm -f mech/gss_delete_sec_context.lo
+ -rm -f mech/gss_display_name.$(OBJEXT)
+ -rm -f mech/gss_display_name.lo
+ -rm -f mech/gss_display_name_ext.$(OBJEXT)
+ -rm -f mech/gss_display_name_ext.lo
+ -rm -f mech/gss_display_status.$(OBJEXT)
+ -rm -f mech/gss_display_status.lo
+ -rm -f mech/gss_duplicate_name.$(OBJEXT)
+ -rm -f mech/gss_duplicate_name.lo
+ -rm -f mech/gss_duplicate_oid.$(OBJEXT)
+ -rm -f mech/gss_duplicate_oid.lo
+ -rm -f mech/gss_encapsulate_token.$(OBJEXT)
+ -rm -f mech/gss_encapsulate_token.lo
+ -rm -f mech/gss_export_name.$(OBJEXT)
+ -rm -f mech/gss_export_name.lo
+ -rm -f mech/gss_export_name_composite.$(OBJEXT)
+ -rm -f mech/gss_export_name_composite.lo
+ -rm -f mech/gss_export_sec_context.$(OBJEXT)
+ -rm -f mech/gss_export_sec_context.lo
+ -rm -f mech/gss_get_mic.$(OBJEXT)
+ -rm -f mech/gss_get_mic.lo
+ -rm -f mech/gss_get_name_attribute.$(OBJEXT)
+ -rm -f mech/gss_get_name_attribute.lo
+ -rm -f mech/gss_import_name.$(OBJEXT)
+ -rm -f mech/gss_import_name.lo
+ -rm -f mech/gss_import_sec_context.$(OBJEXT)
+ -rm -f mech/gss_import_sec_context.lo
+ -rm -f mech/gss_indicate_mechs.$(OBJEXT)
+ -rm -f mech/gss_indicate_mechs.lo
+ -rm -f mech/gss_init_sec_context.$(OBJEXT)
+ -rm -f mech/gss_init_sec_context.lo
+ -rm -f mech/gss_inquire_context.$(OBJEXT)
+ -rm -f mech/gss_inquire_context.lo
+ -rm -f mech/gss_inquire_cred.$(OBJEXT)
+ -rm -f mech/gss_inquire_cred.lo
+ -rm -f mech/gss_inquire_cred_by_mech.$(OBJEXT)
+ -rm -f mech/gss_inquire_cred_by_mech.lo
+ -rm -f mech/gss_inquire_cred_by_oid.$(OBJEXT)
+ -rm -f mech/gss_inquire_cred_by_oid.lo
+ -rm -f mech/gss_inquire_mechs_for_name.$(OBJEXT)
+ -rm -f mech/gss_inquire_mechs_for_name.lo
+ -rm -f mech/gss_inquire_name.$(OBJEXT)
+ -rm -f mech/gss_inquire_name.lo
+ -rm -f mech/gss_inquire_names_for_mech.$(OBJEXT)
+ -rm -f mech/gss_inquire_names_for_mech.lo
+ -rm -f mech/gss_inquire_sec_context_by_oid.$(OBJEXT)
+ -rm -f mech/gss_inquire_sec_context_by_oid.lo
+ -rm -f mech/gss_krb5.$(OBJEXT)
+ -rm -f mech/gss_krb5.lo
+ -rm -f mech/gss_mech_switch.$(OBJEXT)
+ -rm -f mech/gss_mech_switch.lo
+ -rm -f mech/gss_mo.$(OBJEXT)
+ -rm -f mech/gss_mo.lo
+ -rm -f mech/gss_names.$(OBJEXT)
+ -rm -f mech/gss_names.lo
+ -rm -f mech/gss_oid.$(OBJEXT)
+ -rm -f mech/gss_oid.lo
+ -rm -f mech/gss_oid_equal.$(OBJEXT)
+ -rm -f mech/gss_oid_equal.lo
+ -rm -f mech/gss_oid_to_str.$(OBJEXT)
+ -rm -f mech/gss_oid_to_str.lo
+ -rm -f mech/gss_pname_to_uid.$(OBJEXT)
+ -rm -f mech/gss_pname_to_uid.lo
+ -rm -f mech/gss_process_context_token.$(OBJEXT)
+ -rm -f mech/gss_process_context_token.lo
+ -rm -f mech/gss_pseudo_random.$(OBJEXT)
+ -rm -f mech/gss_pseudo_random.lo
+ -rm -f mech/gss_release_buffer.$(OBJEXT)
+ -rm -f mech/gss_release_buffer.lo
+ -rm -f mech/gss_release_cred.$(OBJEXT)
+ -rm -f mech/gss_release_cred.lo
+ -rm -f mech/gss_release_name.$(OBJEXT)
+ -rm -f mech/gss_release_name.lo
+ -rm -f mech/gss_release_oid.$(OBJEXT)
+ -rm -f mech/gss_release_oid.lo
+ -rm -f mech/gss_release_oid_set.$(OBJEXT)
+ -rm -f mech/gss_release_oid_set.lo
+ -rm -f mech/gss_seal.$(OBJEXT)
+ -rm -f mech/gss_seal.lo
+ -rm -f mech/gss_set_cred_option.$(OBJEXT)
+ -rm -f mech/gss_set_cred_option.lo
+ -rm -f mech/gss_set_name_attribute.$(OBJEXT)
+ -rm -f mech/gss_set_name_attribute.lo
+ -rm -f mech/gss_set_sec_context_option.$(OBJEXT)
+ -rm -f mech/gss_set_sec_context_option.lo
+ -rm -f mech/gss_sign.$(OBJEXT)
+ -rm -f mech/gss_sign.lo
+ -rm -f mech/gss_store_cred.$(OBJEXT)
+ -rm -f mech/gss_store_cred.lo
+ -rm -f mech/gss_test_oid_set_member.$(OBJEXT)
+ -rm -f mech/gss_test_oid_set_member.lo
+ -rm -f mech/gss_unseal.$(OBJEXT)
+ -rm -f mech/gss_unseal.lo
+ -rm -f mech/gss_unwrap.$(OBJEXT)
+ -rm -f mech/gss_unwrap.lo
+ -rm -f mech/gss_utils.$(OBJEXT)
+ -rm -f mech/gss_utils.lo
+ -rm -f mech/gss_verify.$(OBJEXT)
+ -rm -f mech/gss_verify.lo
+ -rm -f mech/gss_verify_mic.$(OBJEXT)
+ -rm -f mech/gss_verify_mic.lo
+ -rm -f mech/gss_wrap.$(OBJEXT)
+ -rm -f mech/gss_wrap.lo
+ -rm -f mech/gss_wrap_size_limit.$(OBJEXT)
+ -rm -f mech/gss_wrap_size_limit.lo
+ -rm -f ntlm/accept_sec_context.$(OBJEXT)
+ -rm -f ntlm/accept_sec_context.lo
+ -rm -f ntlm/acquire_cred.$(OBJEXT)
+ -rm -f ntlm/acquire_cred.lo
+ -rm -f ntlm/add_cred.$(OBJEXT)
+ -rm -f ntlm/add_cred.lo
+ -rm -f ntlm/canonicalize_name.$(OBJEXT)
+ -rm -f ntlm/canonicalize_name.lo
+ -rm -f ntlm/compare_name.$(OBJEXT)
+ -rm -f ntlm/compare_name.lo
+ -rm -f ntlm/context_time.$(OBJEXT)
+ -rm -f ntlm/context_time.lo
+ -rm -f ntlm/creds.$(OBJEXT)
+ -rm -f ntlm/creds.lo
+ -rm -f ntlm/crypto.$(OBJEXT)
+ -rm -f ntlm/crypto.lo
+ -rm -f ntlm/delete_sec_context.$(OBJEXT)
+ -rm -f ntlm/delete_sec_context.lo
+ -rm -f ntlm/display_name.$(OBJEXT)
+ -rm -f ntlm/display_name.lo
+ -rm -f ntlm/display_status.$(OBJEXT)
+ -rm -f ntlm/display_status.lo
+ -rm -f ntlm/duplicate_name.$(OBJEXT)
+ -rm -f ntlm/duplicate_name.lo
+ -rm -f ntlm/export_name.$(OBJEXT)
+ -rm -f ntlm/export_name.lo
+ -rm -f ntlm/export_sec_context.$(OBJEXT)
+ -rm -f ntlm/export_sec_context.lo
+ -rm -f ntlm/external.$(OBJEXT)
+ -rm -f ntlm/external.lo
+ -rm -f ntlm/import_name.$(OBJEXT)
+ -rm -f ntlm/import_name.lo
+ -rm -f ntlm/import_sec_context.$(OBJEXT)
+ -rm -f ntlm/import_sec_context.lo
+ -rm -f ntlm/indicate_mechs.$(OBJEXT)
+ -rm -f ntlm/indicate_mechs.lo
+ -rm -f ntlm/init_sec_context.$(OBJEXT)
+ -rm -f ntlm/init_sec_context.lo
+ -rm -f ntlm/inquire_context.$(OBJEXT)
+ -rm -f ntlm/inquire_context.lo
+ -rm -f ntlm/inquire_cred_by_mech.$(OBJEXT)
+ -rm -f ntlm/inquire_cred_by_mech.lo
+ -rm -f ntlm/inquire_mechs_for_name.$(OBJEXT)
+ -rm -f ntlm/inquire_mechs_for_name.lo
+ -rm -f ntlm/inquire_names_for_mech.$(OBJEXT)
+ -rm -f ntlm/inquire_names_for_mech.lo
+ -rm -f ntlm/inquire_sec_context_by_oid.$(OBJEXT)
+ -rm -f ntlm/inquire_sec_context_by_oid.lo
+ -rm -f ntlm/iter_cred.$(OBJEXT)
+ -rm -f ntlm/iter_cred.lo
+ -rm -f ntlm/kdc.$(OBJEXT)
+ -rm -f ntlm/kdc.lo
+ -rm -f ntlm/process_context_token.$(OBJEXT)
+ -rm -f ntlm/process_context_token.lo
+ -rm -f ntlm/release_cred.$(OBJEXT)
+ -rm -f ntlm/release_cred.lo
+ -rm -f ntlm/release_name.$(OBJEXT)
+ -rm -f ntlm/release_name.lo
+ -rm -f spnego/accept_sec_context.$(OBJEXT)
+ -rm -f spnego/accept_sec_context.lo
+ -rm -f spnego/compat.$(OBJEXT)
+ -rm -f spnego/compat.lo
+ -rm -f spnego/context_stubs.$(OBJEXT)
+ -rm -f spnego/context_stubs.lo
+ -rm -f spnego/cred_stubs.$(OBJEXT)
+ -rm -f spnego/cred_stubs.lo
+ -rm -f spnego/external.$(OBJEXT)
+ -rm -f spnego/external.lo
+ -rm -f spnego/init_sec_context.$(OBJEXT)
+ -rm -f spnego/init_sec_context.lo
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_ContextFlags.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_GSSAPIContextToken.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_MechType.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_MechTypeList.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_NegHints.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_NegTokenInit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_NegTokenInitWin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_NegTokenResp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_NegotiationToken.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_NegotiationTokenWin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gkrb5_err.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gss-commands.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsstool.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_acquire_cred.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_context.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cred.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_kcred.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_names.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ntlm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_oid.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/8003.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/accept_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/acquire_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/add_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/address_to_krb5addr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/aeap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/arcfour.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/authorize_localname.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/canonicalize_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/ccache_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/cfx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/compare_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/compat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/context_time.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/copy_ccache.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/creds.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/decapsulate.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/delete_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/display_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/display_status.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/duplicate_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/encapsulate.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/export_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/export_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/external.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/get_mic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/import_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/import_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/indicate_mechs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/init_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/inquire_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/inquire_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/inquire_cred_by_mech.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/inquire_cred_by_oid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/inquire_mechs_for_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/inquire_names_for_mech.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/inquire_sec_context_by_oid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/pname_to_uid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/prf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/process_context_token.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/release_buffer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/release_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/release_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/sequence.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/set_cred_option.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/set_sec_context_option.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/store_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/test_cfx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/ticket_flags.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/unwrap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/verify_mic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@krb5/$(DEPDIR)/wrap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/doxygen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_accept_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_acquire_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_acquire_cred_ext.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_acquire_cred_with_password.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_add_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_add_cred_with_password.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_add_oid_set_member.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_aeap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_authorize_localname.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_buffer_set.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_canonicalize_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_compare_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_context_time.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_create_empty_oid_set.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_decapsulate_token.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_delete_name_attribute.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_delete_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_display_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_display_name_ext.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_display_status.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_duplicate_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_duplicate_oid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_encapsulate_token.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_export_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_export_name_composite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_export_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_get_mic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_get_name_attribute.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_import_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_import_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_indicate_mechs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_init_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_inquire_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_inquire_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_inquire_cred_by_mech.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_inquire_cred_by_oid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_inquire_mechs_for_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_inquire_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_inquire_names_for_mech.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_inquire_sec_context_by_oid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_krb5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_mech_switch.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_mo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_names.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_oid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_oid_equal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_oid_to_str.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_pname_to_uid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_process_context_token.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_pseudo_random.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_release_buffer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_release_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_release_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_release_oid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_release_oid_set.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_seal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_set_cred_option.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_set_name_attribute.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_set_sec_context_option.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_sign.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_store_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_test_oid_set_member.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_unseal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_unwrap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_utils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_verify.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_verify_mic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_wrap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@mech/$(DEPDIR)/gss_wrap_size_limit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/accept_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/acquire_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/add_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/canonicalize_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/compare_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/context_time.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/creds.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/crypto.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/delete_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/display_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/display_status.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/duplicate_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/export_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/export_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/external.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/import_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/import_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/indicate_mechs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/init_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/inquire_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/inquire_cred_by_mech.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/inquire_mechs_for_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/inquire_names_for_mech.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/inquire_sec_context_by_oid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/iter_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/kdc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/process_context_token.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/release_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntlm/$(DEPDIR)/release_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@spnego/$(DEPDIR)/accept_sec_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@spnego/$(DEPDIR)/compat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@spnego/$(DEPDIR)/context_stubs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@spnego/$(DEPDIR)/cred_stubs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@spnego/$(DEPDIR)/external.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@spnego/$(DEPDIR)/init_sec_context.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+ -rm -rf krb5/.libs krb5/_libs
+ -rm -rf mech/.libs mech/_libs
+ -rm -rf ntlm/.libs ntlm/_libs
+ -rm -rf spnego/.libs spnego/_libs
+install-man3: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
+ @list=''; test -n "$(man3dir)" || exit 0; \
+ { for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.3[a-z]*$$/p'; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man3:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man3dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.3[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ test -z "$$files" || { \
+ echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(man3dir)" && rm -f $$files; }
+install-man5: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)"
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ { for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ test -z "$$files" || { \
+ echo " ( cd '$(DESTDIR)$(man5dir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(man5dir)" && rm -f $$files; }
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(includedir)" && rm -f $$files
+install-nobase_includeHEADERS: $(nobase_include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
+ @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
+ $(am__nobase_list) | while read dir files; do \
+ xfiles=; for file in $$files; do \
+ if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+ test -z "$$xfiles" || { \
+ test "x$$dir" = x. || { \
+ echo "$(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \
+ echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \
+ $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \
+ done
+
+uninstall-nobase_includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
+ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(includedir)" && rm -f $$files
+install-nodist_gssapiHEADERS: $(nodist_gssapi_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(gssapidir)" || $(MKDIR_P) "$(DESTDIR)$(gssapidir)"
+ @list='$(nodist_gssapi_HEADERS)'; test -n "$(gssapidir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(gssapidir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(gssapidir)" || exit $$?; \
+ done
+
+uninstall-nodist_gssapiHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nodist_gssapi_HEADERS)'; test -n "$(gssapidir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(gssapidir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(gssapidir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ echo "$$grn$$dashes"; \
+ else \
+ echo "$$red$$dashes"; \
+ fi; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes$$std"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @list='$(MANS)'; if test -n "$$list"; then \
+ list=`for p in $$list; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
+ if test -n "$$list" && \
+ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
+ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
+ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
+ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
+ echo " typically \`make maintainer-clean' will remove them" >&2; \
+ exit 1; \
+ else :; fi; \
+ else :; fi
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(HEADERS) \
+ all-local
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(gssapidir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f krb5/$(DEPDIR)/$(am__dirstamp)
+ -rm -f krb5/$(am__dirstamp)
+ -rm -f mech/$(DEPDIR)/$(am__dirstamp)
+ -rm -f mech/$(am__dirstamp)
+ -rm -f ntlm/$(DEPDIR)/$(am__dirstamp)
+ -rm -f ntlm/$(am__dirstamp)
+ -rm -f spnego/$(DEPDIR)/$(am__dirstamp)
+ -rm -f spnego/$(am__dirstamp)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
+ clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR) krb5/$(DEPDIR) mech/$(DEPDIR) ntlm/$(DEPDIR) spnego/$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-includeHEADERS install-man \
+ install-nobase_includeHEADERS install-nodist_gssapiHEADERS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man3 install-man5
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR) krb5/$(DEPDIR) mech/$(DEPDIR) ntlm/$(DEPDIR) spnego/$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \
+ uninstall-libLTLIBRARIES uninstall-man \
+ uninstall-nobase_includeHEADERS uninstall-nodist_gssapiHEADERS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
+uninstall-man: uninstall-man3 uninstall-man5
+
+.MAKE: all check check-am install install-am install-data-am \
+ install-exec-am install-strip uninstall-am
+
+.PHONY: CTAGS GTAGS all all-am all-local check check-TESTS check-am \
+ check-local clean clean-binPROGRAMS clean-checkPROGRAMS \
+ clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-noinstPROGRAMS ctags dist-hook distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-binPROGRAMS install-data \
+ install-data-am install-data-hook install-dvi install-dvi-am \
+ install-exec install-exec-am install-exec-hook install-html \
+ install-html-am install-includeHEADERS install-info \
+ install-info-am install-libLTLIBRARIES install-man \
+ install-man3 install-man5 install-nobase_includeHEADERS \
+ install-nodist_gssapiHEADERS install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-hook uninstall-includeHEADERS \
+ uninstall-libLTLIBRARIES uninstall-man uninstall-man3 \
+ uninstall-man5 uninstall-nobase_includeHEADERS \
+ uninstall-nodist_gssapiHEADERS
+
+
+install-suid-programs:
+ @foo='$(bin_SUIDS)'; \
+ for file in $$foo; do \
+ x=$(DESTDIR)$(bindir)/$$file; \
+ if chown 0:0 $$x && chmod u+s $$x; then :; else \
+ echo "*"; \
+ echo "* Failed to install $$x setuid root"; \
+ echo "*"; \
+ fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ) $(nobase_include_HEADERS)
+ @foo='$(include_HEADERS) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " $(CP) $$file $(buildinclude)/$$f"; \
+ $(CP) $$file $(buildinclude)/$$f; \
+ fi ; \
+ done ; \
+ foo='$(nobase_include_HEADERS)'; \
+ for f in $$foo; do \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ $(mkdir_p) $(buildinclude)/`dirname $$f` ; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " $(CP) $$file $(buildinclude)/$$f"; \
+ $(CP) $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+
+check-local::
+ @if test '$(CHECK_LOCAL)' = "no-check-local"; then \
+ foo=''; elif test '$(CHECK_LOCAL)'; then \
+ foo='$(CHECK_LOCAL)'; else \
+ foo='$(PROGRAMS)'; fi; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if (./$$i --version && ./$$i --help) > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0 || exit 1; \
+ fi
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+.hx.h:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(NROFF_MAN) $< > $@
+.8.cat8:
+ $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+ @foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat3-mans:
+ @foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat5-mans:
+ @foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-cat8-mans:
+ @foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done ;\
+ for i in $$foo; do \
+ x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+ echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+ $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+ done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat-mans:
+ $(SHELL) $(top_srcdir)/cf/install-catman.sh install "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS)
+
+uninstall-cat-mans:
+ $(SHELL) $(top_srcdir)/cf/install-catman.sh uninstall "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS)
+
+install-data-hook: install-cat-mans
+uninstall-hook: uninstall-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+#
+# Useful target for debugging
+#
+
+check-valgrind:
+ tobjdir=`cd $(top_builddir) && pwd` ; \
+ tsrcdir=`cd $(top_srcdir) && pwd` ; \
+ env TESTS_ENVIRONMENT="$${tsrcdir}/cf/maybe-valgrind.sh -s $${tsrcdir} -o $${tobjdir}" make check
+
+#
+# Target to please samba build farm, builds distfiles in-tree.
+# Will break when automake changes...
+#
+
+distdir-in-tree: $(DISTFILES) $(INFO_DEPS)
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" != .; then \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) distdir-in-tree) ; \
+ fi ; \
+ done
+
+$(srcdir)/ntlm/ntlm-private.h:
+ cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -p ntlm/ntlm-private.h $(ntlmsrc) || rm -f ntlm/ntlm-private.h
+
+$(libgssapi_la_OBJECTS): $(BUILTHEADERS)
+$(test_context_OBJECTS): $(BUILTHEADERS)
+
+$(libgssapi_la_OBJECTS): $(srcdir)/version-script.map
+
+$(spnego_files) spnego_asn1.hx spnego_asn1-priv.hx: spnego_asn1_files
+$(gssapi_files) gssapi_asn1.hx gssapi_asn1-priv.hx: gssapi_asn1_files
+
+spnego_asn1_files: $(ASN1_COMPILE_DEP) $(srcdir)/spnego/spnego.asn1 $(srcdir)/spnego/spnego.opt
+ $(ASN1_COMPILE) --option-file=$(srcdir)/spnego/spnego.opt $(srcdir)/spnego/spnego.asn1 spnego_asn1
+
+gssapi_asn1_files: $(ASN1_COMPILE_DEP) $(srcdir)/mech/gssapi.asn1
+ $(ASN1_COMPILE) $(srcdir)/mech/gssapi.asn1 gssapi_asn1
+
+$(srcdir)/krb5/gsskrb5-private.h:
+ cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -p krb5/gsskrb5-private.h $(krb5src) || rm -f krb5/gsskrb5-private.h
+
+$(srcdir)/spnego/spnego-private.h:
+ cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -p spnego/spnego-private.h $(spnegosrc) || rm -f spnego/spnego-private.h
+
+gss-commands.c gss-commands.h: gss-commands.in
+ $(SLC) $(srcdir)/gss-commands.in
+
+$(gsstool_OBJECTS): gss-commands.h
+
+$(libgssapi_la_OBJECTS): gkrb5_err.h gssapi_asn1.h gssapi_asn1-priv.h
+$(libgssapi_la_OBJECTS): spnego_asn1.h spnego_asn1-priv.h
+$(libgssapi_la_OBJECTS): $(srcdir)/gssapi/gssapi_oid.h
+
+gkrb5_err.h gkrb5_err.c: $(srcdir)/krb5/gkrb5_err.et
+ $(COMPILE_ET) $(srcdir)/krb5/gkrb5_err.et
+
+$(srcdir)/gssapi/gssapi_oid.h $(srcdir)/mech/gss_oid.c:
+ perl $(srcdir)/gen-oid.pl -b base -h $(srcdir)/oid.txt > $(srcdir)/gssapi/gssapi_oid.h
+ perl $(srcdir)/gen-oid.pl -b base $(srcdir)/oid.txt > $(srcdir)/mech/gss_oid.c
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/crypto/heimdal/lib/gssapi/gss-commands.in b/crypto/heimdal/lib/gssapi/gss-commands.in
new file mode 100644
index 0000000..a2fc228
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gss-commands.in
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+/* $Id$ */
+
+command = {
+ name = "supported-mechanisms"
+ help = "Print the supported mechanisms"
+}
+command = {
+ name = "attrs-for-mech"
+ help = "Print the attributes for mechs"
+ option = {
+ long = "all"
+ type = "flag"
+ }
+ option = {
+ long = "mech"
+ type = "string"
+ argument = "mechanism"
+ }
+}
+command = {
+ name = "help"
+ name = "?"
+ argument = "[command]"
+ min_args = "0"
+ max_args = "1"
+ help = "Help! I need somebody."
+}
diff --git a/crypto/heimdal/lib/gssapi/gss_acquire_cred.3 b/crypto/heimdal/lib/gssapi/gss_acquire_cred.3
new file mode 100644
index 0000000..25d7b4d
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gss_acquire_cred.3
@@ -0,0 +1,688 @@
+.\" Copyright (c) 2003 - 2007 Kungliga Tekniska Högskolan
+.\" (Royal Institute of Technology, Stockholm, Sweden).
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\"
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+.\"
+.\" $Id$
+.\"
+.Dd October 26, 2005
+.Dt GSS_ACQUIRE_CRED 3
+.Os HEIMDAL
+.Sh NAME
+.Nm gss_accept_sec_context ,
+.Nm gss_acquire_cred ,
+.Nm gss_add_cred ,
+.Nm gss_add_oid_set_member ,
+.Nm gss_canonicalize_name ,
+.Nm gss_compare_name ,
+.Nm gss_context_time ,
+.Nm gss_create_empty_oid_set ,
+.Nm gss_delete_sec_context ,
+.Nm gss_display_name ,
+.Nm gss_display_status ,
+.Nm gss_duplicate_name ,
+.Nm gss_export_name ,
+.Nm gss_export_sec_context ,
+.Nm gss_get_mic ,
+.Nm gss_import_name ,
+.Nm gss_import_sec_context ,
+.Nm gss_indicate_mechs ,
+.Nm gss_init_sec_context ,
+.Nm gss_inquire_context ,
+.Nm gss_inquire_cred ,
+.Nm gss_inquire_cred_by_mech ,
+.Nm gss_inquire_mechs_for_name ,
+.Nm gss_inquire_names_for_mech ,
+.Nm gss_krb5_ccache_name ,
+.Nm gss_krb5_compat_des3_mic ,
+.Nm gss_krb5_copy_ccache ,
+.Nm gss_krb5_import_cred
+.Nm gsskrb5_extract_authz_data_from_sec_context ,
+.Nm gsskrb5_register_acceptor_identity ,
+.Nm gss_krb5_import_ccache ,
+.Nm gss_krb5_get_tkt_flags ,
+.Nm gss_process_context_token ,
+.Nm gss_release_buffer ,
+.Nm gss_release_cred ,
+.Nm gss_release_name ,
+.Nm gss_release_oid_set ,
+.Nm gss_seal ,
+.Nm gss_sign ,
+.Nm gss_test_oid_set_member ,
+.Nm gss_unseal ,
+.Nm gss_unwrap ,
+.Nm gss_verify ,
+.Nm gss_verify_mic ,
+.Nm gss_wrap ,
+.Nm gss_wrap_size_limit
+.Nd Generic Security Service Application Program Interface library
+.Sh LIBRARY
+GSS-API library (libgssapi, -lgssapi)
+.Sh SYNOPSIS
+.In gssapi.h
+.Pp
+.Ft OM_uint32
+.Fo gss_accept_sec_context
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_ctx_id_t * context_handle"
+.Fa "const gss_cred_id_t acceptor_cred_handle"
+.Fa "const gss_buffer_t input_token_buffer"
+.Fa "const gss_channel_bindings_t input_chan_bindings"
+.Fa "gss_name_t * src_name"
+.Fa "gss_OID * mech_type"
+.Fa "gss_buffer_t output_token"
+.Fa "OM_uint32 * ret_flags"
+.Fa "OM_uint32 * time_rec"
+.Fa "gss_cred_id_t * delegated_cred_handle"
+.Fc
+.Pp
+.Ft OM_uint32
+.Fo gss_acquire_cred
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_name_t desired_name"
+.Fa "OM_uint32 time_req"
+.Fa "const gss_OID_set desired_mechs"
+.Fa "gss_cred_usage_t cred_usage"
+.Fa "gss_cred_id_t * output_cred_handle"
+.Fa "gss_OID_set * actual_mechs"
+.Fa "OM_uint32 * time_rec"
+.Fc
+.Ft OM_uint32
+.Fo gss_add_cred
+.Fa "OM_uint32 *minor_status"
+.Fa "const gss_cred_id_t input_cred_handle"
+.Fa "const gss_name_t desired_name"
+.Fa "const gss_OID desired_mech"
+.Fa "gss_cred_usage_t cred_usage"
+.Fa "OM_uint32 initiator_time_req"
+.Fa "OM_uint32 acceptor_time_req"
+.Fa "gss_cred_id_t *output_cred_handle"
+.Fa "gss_OID_set *actual_mechs"
+.Fa "OM_uint32 *initiator_time_rec"
+.Fa "OM_uint32 *acceptor_time_rec"
+.Fc
+.Ft OM_uint32
+.Fo gss_add_oid_set_member
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_OID member_oid"
+.Fa "gss_OID_set * oid_set"
+.Fc
+.Ft OM_uint32
+.Fo gss_canonicalize_name
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_name_t input_name"
+.Fa "const gss_OID mech_type"
+.Fa "gss_name_t * output_name"
+.Fc
+.Ft OM_uint32
+.Fo gss_compare_name
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_name_t name1"
+.Fa "const gss_name_t name2"
+.Fa "int * name_equal"
+.Fc
+.Ft OM_uint32
+.Fo gss_context_time
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_ctx_id_t context_handle"
+.Fa "OM_uint32 * time_rec"
+.Fc
+.Ft OM_uint32
+.Fo gss_create_empty_oid_set
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_OID_set * oid_set"
+.Fc
+.Ft OM_uint32
+.Fo gss_delete_sec_context
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_ctx_id_t * context_handle"
+.Fa "gss_buffer_t output_token"
+.Fc
+.Ft OM_uint32
+.Fo gss_display_name
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_name_t input_name"
+.Fa "gss_buffer_t output_name_buffer"
+.Fa "gss_OID * output_name_type"
+.Fc
+.Ft OM_uint32
+.Fo gss_display_status
+.Fa "OM_uint32 *minor_status"
+.Fa "OM_uint32 status_value"
+.Fa "int status_type"
+.Fa "const gss_OID mech_type"
+.Fa "OM_uint32 *message_context"
+.Fa "gss_buffer_t status_string"
+.Fc
+.Ft OM_uint32
+.Fo gss_duplicate_name
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_name_t src_name"
+.Fa "gss_name_t * dest_name"
+.Fc
+.Ft OM_uint32
+.Fo gss_export_name
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_name_t input_name"
+.Fa "gss_buffer_t exported_name"
+.Fc
+.Ft OM_uint32
+.Fo gss_export_sec_context
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_ctx_id_t * context_handle"
+.Fa "gss_buffer_t interprocess_token"
+.Fc
+.Ft OM_uint32
+.Fo gss_get_mic
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_ctx_id_t context_handle"
+.Fa "gss_qop_t qop_req"
+.Fa "const gss_buffer_t message_buffer"
+.Fa "gss_buffer_t message_token"
+.Fc
+.Ft OM_uint32
+.Fo gss_import_name
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_buffer_t input_name_buffer"
+.Fa "const gss_OID input_name_type"
+.Fa "gss_name_t * output_name"
+.Fc
+.Ft OM_uint32
+.Fo gss_import_sec_context
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_buffer_t interprocess_token"
+.Fa "gss_ctx_id_t * context_handle"
+.Fc
+.Ft OM_uint32
+.Fo gss_indicate_mechs
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_OID_set * mech_set"
+.Fc
+.Ft OM_uint32
+.Fo gss_init_sec_context
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_cred_id_t initiator_cred_handle"
+.Fa "gss_ctx_id_t * context_handle"
+.Fa "const gss_name_t target_name"
+.Fa "const gss_OID mech_type"
+.Fa "OM_uint32 req_flags"
+.Fa "OM_uint32 time_req"
+.Fa "const gss_channel_bindings_t input_chan_bindings"
+.Fa "const gss_buffer_t input_token"
+.Fa "gss_OID * actual_mech_type"
+.Fa "gss_buffer_t output_token"
+.Fa "OM_uint32 * ret_flags"
+.Fa "OM_uint32 * time_rec"
+.Fc
+.Ft OM_uint32
+.Fo gss_inquire_context
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_ctx_id_t context_handle"
+.Fa "gss_name_t * src_name"
+.Fa "gss_name_t * targ_name"
+.Fa "OM_uint32 * lifetime_rec"
+.Fa "gss_OID * mech_type"
+.Fa "OM_uint32 * ctx_flags"
+.Fa "int * locally_initiated"
+.Fa "int * open_context"
+.Fc
+.Ft OM_uint32
+.Fo gss_inquire_cred
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_cred_id_t cred_handle"
+.Fa "gss_name_t * name"
+.Fa "OM_uint32 * lifetime"
+.Fa "gss_cred_usage_t * cred_usage"
+.Fa "gss_OID_set * mechanisms"
+.Fc
+.Ft OM_uint32
+.Fo gss_inquire_cred_by_mech
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_cred_id_t cred_handle"
+.Fa "const gss_OID mech_type"
+.Fa "gss_name_t * name"
+.Fa "OM_uint32 * initiator_lifetime"
+.Fa "OM_uint32 * acceptor_lifetime"
+.Fa "gss_cred_usage_t * cred_usage"
+.Fc
+.Ft OM_uint32
+.Fo gss_inquire_mechs_for_name
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_name_t input_name"
+.Fa "gss_OID_set * mech_types"
+.Fc
+.Ft OM_uint32
+.Fo gss_inquire_names_for_mech
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_OID mechanism"
+.Fa "gss_OID_set * name_types"
+.Fc
+.Ft OM_uint32
+.Fo gss_krb5_ccache_name
+.Fa "OM_uint32 *minor"
+.Fa "const char *name"
+.Fa "const char **old_name"
+.Fc
+.Ft OM_uint32
+.Fo gss_krb5_copy_ccache
+.Fa "OM_uint32 *minor"
+.Fa "gss_cred_id_t cred"
+.Fa "krb5_ccache out"
+.Fc
+.Ft OM_uint32
+.Fo gss_krb5_import_cred
+.Fa "OM_uint32 *minor_status"
+.Fa "krb5_ccache id"
+.Fa "krb5_principal keytab_principal"
+.Fa "krb5_keytab keytab"
+.Fa "gss_cred_id_t *cred"
+.Fc
+.Ft OM_uint32
+.Fo gss_krb5_compat_des3_mic
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_ctx_id_t context_handle"
+.Fa "int onoff"
+.Fc
+.Ft OM_uint32
+.Fo gsskrb5_extract_authz_data_from_sec_context
+.Fa "OM_uint32 *minor_status"
+.Fa "gss_ctx_id_t context_handle"
+.Fa "int ad_type"
+.Fa "gss_buffer_t ad_data"
+.Fc
+.Ft OM_uint32
+.Fo gsskrb5_register_acceptor_identity
+.Fa "const char *identity"
+.Fc
+.Ft OM_uint32
+.Fo gss_krb5_import_cache
+.Fa "OM_uint32 *minor"
+.Fa "krb5_ccache id"
+.Fa "krb5_keytab keytab"
+.Fa "gss_cred_id_t *cred"
+.Fc
+.Ft OM_uint32
+.Fo gss_krb5_get_tkt_flags
+.Fa "OM_uint32 *minor_status"
+.Fa "gss_ctx_id_t context_handle"
+.Fa "OM_uint32 *tkt_flags"
+.Fc
+.Ft OM_uint32
+.Fo gss_process_context_token
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_ctx_id_t context_handle"
+.Fa "const gss_buffer_t token_buffer"
+.Fc
+.Ft OM_uint32
+.Fo gss_release_buffer
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_buffer_t buffer"
+.Fc
+.Ft OM_uint32
+.Fo gss_release_cred
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_cred_id_t * cred_handle"
+.Fc
+.Ft OM_uint32
+.Fo gss_release_name
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_name_t * input_name"
+.Fc
+.Ft OM_uint32
+.Fo gss_release_oid_set
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_OID_set * set"
+.Fc
+.Ft OM_uint32
+.Fo gss_seal
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_ctx_id_t context_handle"
+.Fa "int conf_req_flag"
+.Fa "int qop_req"
+.Fa "gss_buffer_t input_message_buffer"
+.Fa "int * conf_state"
+.Fa "gss_buffer_t output_message_buffer"
+.Fc
+.Ft OM_uint32
+.Fo gss_sign
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_ctx_id_t context_handle"
+.Fa "int qop_req"
+.Fa "gss_buffer_t message_buffer"
+.Fa "gss_buffer_t message_token"
+.Fc
+.Ft OM_uint32
+.Fo gss_test_oid_set_member
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_OID member"
+.Fa "const gss_OID_set set"
+.Fa "int * present"
+.Fc
+.Ft OM_uint32
+.Fo gss_unseal
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_ctx_id_t context_handle"
+.Fa "gss_buffer_t input_message_buffer"
+.Fa "gss_buffer_t output_message_buffer"
+.Fa "int * conf_state"
+.Fa "int * qop_state"
+.Fc
+.Ft OM_uint32
+.Fo gss_unwrap
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_ctx_id_t context_handle"
+.Fa "const gss_buffer_t input_message_buffer"
+.Fa "gss_buffer_t output_message_buffer"
+.Fa "int * conf_state"
+.Fa "gss_qop_t * qop_state"
+.Fc
+.Ft OM_uint32
+.Fo gss_verify
+.Fa "OM_uint32 * minor_status"
+.Fa "gss_ctx_id_t context_handle"
+.Fa "gss_buffer_t message_buffer"
+.Fa "gss_buffer_t token_buffer"
+.Fa "int * qop_state"
+.Fc
+.Ft OM_uint32
+.Fo gss_verify_mic
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_ctx_id_t context_handle"
+.Fa "const gss_buffer_t message_buffer"
+.Fa "const gss_buffer_t token_buffer"
+.Fa "gss_qop_t * qop_state"
+.Fc
+.Ft OM_uint32
+.Fo gss_wrap
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_ctx_id_t context_handle"
+.Fa "int conf_req_flag"
+.Fa "gss_qop_t qop_req"
+.Fa "const gss_buffer_t input_message_buffer"
+.Fa "int * conf_state"
+.Fa "gss_buffer_t output_message_buffer"
+.Fc
+.Ft OM_uint32
+.Fo gss_wrap_size_limit
+.Fa "OM_uint32 * minor_status"
+.Fa "const gss_ctx_id_t context_handle"
+.Fa "int conf_req_flag"
+.Fa "gss_qop_t qop_req"
+.Fa "OM_uint32 req_output_size"
+.Fa "OM_uint32 * max_input_size"
+.Fc
+.Sh DESCRIPTION
+Generic Security Service API (GSS-API) version 2, and its C binding,
+is described in
+.Li RFC2743
+and
+.Li RFC2744 .
+Version 1 (deprecated) of the C binding is described in
+.Li RFC1509 .
+.Pp
+Heimdals GSS-API implementation supports the following mechanisms
+.Bl -bullet
+.It
+.Li GSS_KRB5_MECHANISM
+.It
+.Li GSS_SPNEGO_MECHANISM
+.El
+.Pp
+GSS-API have generic name types that all mechanism are supposed to
+implement (if possible):
+.Bl -bullet
+.It
+.Li GSS_C_NT_USER_NAME
+.It
+.Li GSS_C_NT_MACHINE_UID_NAME
+.It
+.Li GSS_C_NT_STRING_UID_NAME
+.It
+.Li GSS_C_NT_HOSTBASED_SERVICE
+.It
+.Li GSS_C_NT_ANONYMOUS
+.It
+.Li GSS_C_NT_EXPORT_NAME
+.El
+.Pp
+GSS-API implementations that supports Kerberos 5 have some additional
+name types:
+.Bl -bullet
+.It
+.Li GSS_KRB5_NT_PRINCIPAL_NAME
+.It
+.Li GSS_KRB5_NT_USER_NAME
+.It
+.Li GSS_KRB5_NT_MACHINE_UID_NAME
+.It
+.Li GSS_KRB5_NT_STRING_UID_NAME
+.El
+.Pp
+In GSS-API, names have two forms, internal names and contiguous string
+names.
+.Bl -bullet
+.It
+.Li Internal name and mechanism name
+.Pp
+Internal names are implementation specific representation of
+a GSS-API name.
+.Li Mechanism names
+special form of internal names corresponds to one and only one mechanism.
+.Pp
+In GSS-API an internal name is stored in a
+.Dv gss_name_t .
+.It
+.Li Contiguous string name and exported name
+.Pp
+Contiguous string names are gssapi names stored in a
+.Dv OCTET STRING
+that together with a name type identifier (OID) uniquely specifies a
+gss-name.
+A special form of the contiguous string name is the exported name that
+have a OID embedded in the string to make it unique.
+Exported name have the nametype
+.Dv GSS_C_NT_EXPORT_NAME .
+.Pp
+In GSS-API an contiguous string name is stored in a
+.Dv gss_buffer_t .
+.Pp
+Exported names also have the property that they are specified by the
+mechanism itself and compatible between different GSS-API
+implementations.
+.El
+.Sh ACCESS CONTROL
+There are two ways of comparing GSS-API names, either comparing two
+internal names with each other or two contiguous string names with
+either other.
+.Pp
+To compare two internal names with each other, import (if needed) the
+names with
+.Fn gss_import_name
+into the GSS-API implementation and the compare the imported name with
+.Fn gss_compare_name .
+.Pp
+Importing names can be slow, so when its possible to store exported
+names in the access control list, comparing contiguous string name
+might be better.
+.Pp
+when comparing contiguous string name, first export them into a
+.Dv GSS_C_NT_EXPORT_NAME
+name with
+.Fn gss_export_name
+and then compare with
+.Xr memcmp 3 .
+.Pp
+Note that there are might be a difference between the two methods of
+comparing names.
+The first (using
+.Fn gss_compare_name )
+will compare to (unauthenticated) names are the same.
+The second will compare if a mechanism will authenticate them as the
+same principal.
+.Pp
+For example, if
+.Fn gss_import_name
+name was used with
+.Dv GSS_C_NO_OID
+the default syntax is used for all mechanism the GSS-API
+implementation supports.
+When compare the imported name of
+.Dv GSS_C_NO_OID
+it may match serveral mechanism names (MN).
+.Pp
+The resulting name from
+.Fn gss_display_name
+must not be used for acccess control.
+.Sh FUNCTIONS
+.Fn gss_display_name
+takes the gss name in
+.Fa input_name
+and puts a printable form in
+.Fa output_name_buffer .
+.Fa output_name_buffer
+should be freed when done using
+.Fn gss_release_buffer .
+.Fa output_name_type
+can either be
+.Dv NULL
+or a pointer to a
+.Li gss_OID
+and will in the latter case contain the OID type of the name.
+The name must only be used for printing.
+If access control is needed, see section
+.Sx ACCESS CONTROL .
+.Pp
+.Fn gss_inquire_context
+returns information about the context.
+Information is available even after the context have expired.
+.Fa lifetime_rec
+argument is set to
+.Dv GSS_C_INDEFINITE
+(dont expire) or the number of seconds that the context is still valid.
+A value of 0 means that the context is expired.
+.Fa mech_type
+argument should be considered readonly and must not be released.
+.Fa src_name
+and
+.Fn dest_name
+are both mechanims names and must be released with
+.Fn gss_release_name
+when no longer used.
+.Pp
+.Nm gss_context_time
+will return the amount of time (in seconds) of the context is still
+valid.
+If its expired
+.Fa time_rec
+will be set to 0 and
+.Dv GSS_S_CONTEXT_EXPIRED
+returned.
+.Pp
+.Fn gss_sign ,
+.Fn gss_verify ,
+.Fn gss_seal ,
+and
+.Fn gss_unseal
+are part of the GSS-API V1 interface and are obsolete.
+The functions should not be used for new applications.
+They are provided so that version 1 applications can link against the
+library.
+.Sh EXTENSIONS
+.Fn gss_krb5_ccache_name
+sets the internal kerberos 5 credential cache name to
+.Fa name .
+The old name is returned in
+.Fa old_name ,
+and must not be freed.
+The data allocated for
+.Fa old_name
+is free upon next call to
+.Fn gss_krb5_ccache_name .
+This function is not threadsafe if
+.Fa old_name
+argument is used.
+.Pp
+.Fn gss_krb5_copy_ccache
+will extract the krb5 credentials that are transferred from the
+initiator to the acceptor when using token delegation in the Kerberos
+mechanism.
+The acceptor receives the delegated token in the last argument to
+.Fn gss_accept_sec_context .
+.Pp
+.Fn gss_krb5_import_cred
+will import the krb5 credentials (both keytab and/or credential cache)
+into gss credential so it can be used withing GSS-API.
+The
+.Fa ccache
+is copied by reference and thus shared, so if the credential is destroyed
+with
+.Fa krb5_cc_destroy ,
+all users of thep
+.Fa gss_cred_id_t
+returned by
+.Fn gss_krb5_import_ccache
+will fail.
+.Pp
+.Fn gsskrb5_register_acceptor_identity
+sets the Kerberos 5 filebased keytab that the acceptor will use. The
+.Fa identifier
+is the file name.
+.Pp
+.Fn gsskrb5_extract_authz_data_from_sec_context
+extracts the Kerberos authorizationdata that may be stored within the
+context.
+Tha caller must free the returned buffer
+.Fa ad_data
+with
+.Fn gss_release_buffer
+upon success.
+.Pp
+.Fn gss_krb5_get_tkt_flags
+return the ticket flags for the kerberos ticket receive when
+authenticating the initiator.
+Only valid on the acceptor context.
+.Pp
+.Fn gss_krb5_compat_des3_mic
+turns on or off the compatibility with older version of Heimdal using
+des3 get and verify mic, this is way to programmatically set the
+[gssapi]broken_des3_mic and [gssapi]correct_des3_mic flags (see
+COMPATIBILITY section in
+.Xr gssapi 3 ) .
+If the CPP symbol
+.Dv GSS_C_KRB5_COMPAT_DES3_MIC
+is present,
+.Fn gss_krb5_compat_des3_mic
+exists.
+.Fn gss_krb5_compat_des3_mic
+will be removed in a later version of the GSS-API library.
+.Sh SEE ALSO
+.Xr gssapi 3 ,
+.Xr krb5 3 ,
+.Xr krb5_ccache 3 ,
+.Xr kerberos 8
diff --git a/crypto/heimdal/lib/gssapi/gssapi.3 b/crypto/heimdal/lib/gssapi/gssapi.3
new file mode 100644
index 0000000..089f751
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gssapi.3
@@ -0,0 +1,172 @@
+.\" Copyright (c) 2003 - 2005 Kungliga Tekniska Högskolan
+.\" (Royal Institute of Technology, Stockholm, Sweden).
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\"
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+.\"
+.\" $Id$
+.\"
+.Dd April 20, 2005
+.Dt GSSAPI 3
+.Os
+.Sh NAME
+.Nm gssapi
+.Nd Generic Security Service Application Program Interface library
+.Sh LIBRARY
+GSS-API Library (libgssapi, -lgssapi)
+.Sh DESCRIPTION
+The Generic Security Service Application Program Interface (GSS-API)
+provides security services to callers in a generic fashion,
+supportable with a range of underlying mechanisms and technologies and
+hence allowing source-level portability of applications to different
+environments.
+.Pp
+The GSS-API implementation in Heimdal implements the Kerberos 5 and
+the SPNEGO GSS-API security mechanisms.
+.Sh LIST OF FUNCTIONS
+These functions constitute the gssapi library,
+.Em libgssapi .
+Declarations for these functions may be obtained from the include file
+.Pa gssapi.h .
+.Bl -column -compact
+.It Sy Name/Page
+.It Xr gss_accept_sec_context 3
+.It Xr gss_acquire_cred 3
+.It Xr gss_add_cred 3
+.It Xr gss_add_oid_set_member 3
+.It Xr gss_canonicalize_name 3
+.It Xr gss_compare_name 3
+.It Xr gss_context_time 3
+.It Xr gss_create_empty_oid_set 3
+.It Xr gss_delete_sec_context 3
+.It Xr gss_display_name 3
+.It Xr gss_display_status 3
+.It Xr gss_duplicate_name 3
+.It Xr gss_export_name 3
+.It Xr gss_export_sec_context 3
+.It Xr gss_get_mic 3
+.It Xr gss_import_name 3
+.It Xr gss_import_sec_context 3
+.It Xr gss_indicate_mechs 3
+.It Xr gss_init_sec_context 3
+.It Xr gss_inquire_context 3
+.It Xr gss_inquire_cred 3
+.It Xr gss_inquire_cred_by_mech 3
+.It Xr gss_inquire_mechs_for_name 3
+.It Xr gss_inquire_names_for_mech 3
+.It Xr gss_krb5_ccache_name 3
+.It Xr gss_krb5_compat_des3_mic 3
+.It Xr gss_krb5_copy_ccache 3
+.It Xr gss_krb5_extract_authz_data_from_sec_context 3
+.It Xr gss_krb5_import_ccache 3
+.It Xr gss_process_context_token 3
+.It Xr gss_release_buffer 3
+.It Xr gss_release_cred 3
+.It Xr gss_release_name 3
+.It Xr gss_release_oid_set 3
+.It Xr gss_seal 3
+.It Xr gss_sign 3
+.It Xr gss_test_oid_set_member 3
+.It Xr gss_unseal 3
+.It Xr gss_unwrap 3
+.It Xr gss_verify 3
+.It Xr gss_verify_mic 3
+.It Xr gss_wrap 3
+.It Xr gss_wrap_size_limit 3
+.El
+.Sh COMPATIBILITY
+The
+.Nm Heimdal
+GSS-API implementation had a bug in releases before 0.6 that made it
+fail to inter-operate when using DES3 with other GSS-API
+implementations when using
+.Fn gss_get_mic
+/
+.Fn gss_verify_mic .
+It is possible to modify the behavior of the generator of the MIC with
+the
+.Pa krb5.conf
+configuration file so that old clients/servers will still
+work.
+.Pp
+New clients/servers will try both the old and new MIC in Heimdal 0.6.
+In 0.7 it will check only if configured - the compatibility code will
+be removed in 0.8.
+.Pp
+Heimdal 0.6 still generates by default the broken GSS-API DES3 mic,
+this will change in 0.7 to generate correct des3 mic.
+.Pp
+To turn on compatibility with older clients and servers, change the
+.Nm [gssapi]
+.Ar broken_des3_mic
+in
+.Pa krb5.conf
+that contains a list of globbing expressions that will be matched
+against the server name.
+To turn off generation of the old (incompatible) mic of the MIC use
+.Nm [gssapi]
+.Ar correct_des3_mic .
+.Pp
+If a match for a entry is in both
+.Nm [gssapi]
+.Ar correct_des3_mic
+and
+.Nm [gssapi]
+.Ar broken_des3_mic ,
+the later will override.
+.Pp
+This config option modifies behaviour for both clients and servers.
+.Pp
+Microsoft implemented SPNEGO to Windows2000, however, they managed to
+get it wrong, their implementation didn't fill in the MechListMIC in
+the reply token with the right content.
+There is a work around for this problem, but not all implementation
+support it.
+.Pp
+Heimdal defaults to correct SPNEGO when the the kerberos
+implementation uses CFX, or when it is configured by the user.
+To turn on compatibility with peers, use option
+.Nm [gssapi]
+.Ar require_mechlist_mic .
+.Sh EXAMPLES
+.Bd -literal -offset indent
+[gssapi]
+ broken_des3_mic = cvs/*@SU.SE
+ broken_des3_mic = host/*@E.KTH.SE
+ correct_des3_mic = host/*@SU.SE
+ require_mechlist_mic = host/*@SU.SE
+.Ed
+.Sh BUGS
+All of 0.5.x versions of
+.Nm heimdal
+had broken token delegations in the client side, the server side was
+correct.
+.Sh SEE ALSO
+.Xr krb5 3 ,
+.Xr krb5.conf 5 ,
+.Xr kerberos 8
diff --git a/crypto/heimdal/lib/gssapi/gssapi.h b/crypto/heimdal/lib/gssapi/gssapi.h
new file mode 100644
index 0000000..d2f039a
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gssapi.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+#ifndef GSSAPI_H_
+#define GSSAPI_H_
+
+#include <gssapi/gssapi.h>
+
+#endif
diff --git a/crypto/heimdal/lib/gssapi/gssapi/gssapi.h b/crypto/heimdal/lib/gssapi/gssapi/gssapi.h
new file mode 100644
index 0000000..bbb2fd5
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gssapi/gssapi.h
@@ -0,0 +1,1120 @@
+/*
+ * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef GSSAPI_GSSAPI_H_
+#define GSSAPI_GSSAPI_H_
+
+/*
+ * First, include stddef.h to get size_t defined.
+ */
+#include <stddef.h>
+
+#include <krb5-types.h>
+
+#ifndef BUILD_GSSAPI_LIB
+#if defined(_WIN32)
+#define GSSAPI_LIB_FUNCTION __declspec(dllimport)
+#define GSSAPI_LIB_CALL __stdcall
+#define GSSAPI_LIB_VARIABLE __declspec(dllimport)
+#else
+#define GSSAPI_LIB_FUNCTION
+#define GSSAPI_LIB_CALL
+#define GSSAPI_LIB_VARIABLE
+#endif
+#endif
+
+#ifndef GSSAPI_DEPRECATED_FUNCTION
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
+#define GSSAPI_DEPRECATED_FUNCTION(X) __attribute__((deprecated))
+#else
+#define GSSAPI_DEPRECATED_FUNCTION(X)
+#endif
+#endif
+
+/* Compatiblity with MIT Kerberos on the Mac */
+#if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__) || defined(__i386__) || defined(__x86_64__))
+#pragma pack(push,2)
+#endif
+
+#ifdef __cplusplus
+#define GSSAPI_CPP_START extern "C" {
+#define GSSAPI_CPP_END }
+#else
+#define GSSAPI_CPP_START
+#define GSSAPI_CPP_END
+#endif
+
+#ifdef _WIN32
+#define GSSAPI_CALLCONV __stdcall
+#else
+#define GSSAPI_CALLCONV
+#endif
+
+/*
+ * Now define the three implementation-dependent types.
+ */
+
+typedef uint32_t OM_uint32;
+typedef uint64_t OM_uint64;
+
+typedef uint32_t gss_uint32;
+
+struct gss_name_t_desc_struct;
+typedef struct gss_name_t_desc_struct *gss_name_t;
+typedef const struct gss_name_t_desc_struct *gss_const_name_t;
+
+struct gss_ctx_id_t_desc_struct;
+typedef struct gss_ctx_id_t_desc_struct *gss_ctx_id_t;
+typedef const struct gss_ctx_id_t_desc_struct gss_const_ctx_id_t;
+
+typedef struct gss_OID_desc_struct {
+ OM_uint32 length;
+ void *elements;
+} gss_OID_desc, *gss_OID;
+typedef const gss_OID_desc * gss_const_OID;
+
+typedef struct gss_OID_set_desc_struct {
+ size_t count;
+ gss_OID elements;
+} gss_OID_set_desc, *gss_OID_set;
+typedef const gss_OID_set_desc * gss_const_OID_set;
+
+typedef int gss_cred_usage_t;
+
+struct gss_cred_id_t_desc_struct;
+typedef struct gss_cred_id_t_desc_struct *gss_cred_id_t;
+typedef const struct gss_cred_id_t_desc_struct *gss_const_cred_id_t;
+
+typedef struct gss_buffer_desc_struct {
+ size_t length;
+ void *value;
+} gss_buffer_desc, *gss_buffer_t;
+typedef const gss_buffer_desc * gss_const_buffer_t;
+
+typedef struct gss_channel_bindings_struct {
+ OM_uint32 initiator_addrtype;
+ gss_buffer_desc initiator_address;
+ OM_uint32 acceptor_addrtype;
+ gss_buffer_desc acceptor_address;
+ gss_buffer_desc application_data;
+} *gss_channel_bindings_t;
+typedef const struct gss_channel_bindings_struct *gss_const_channel_bindings_t;
+
+/* GGF extension data types */
+typedef struct gss_buffer_set_desc_struct {
+ size_t count;
+ gss_buffer_desc *elements;
+} gss_buffer_set_desc, *gss_buffer_set_t;
+
+typedef struct gss_iov_buffer_desc_struct {
+ OM_uint32 type;
+ gss_buffer_desc buffer;
+} gss_iov_buffer_desc, *gss_iov_buffer_t;
+
+/*
+ * For now, define a QOP-type as an OM_uint32
+ */
+typedef OM_uint32 gss_qop_t;
+
+
+
+/*
+ * Flag bits for context-level services.
+ */
+#define GSS_C_DELEG_FLAG 1
+#define GSS_C_MUTUAL_FLAG 2
+#define GSS_C_REPLAY_FLAG 4
+#define GSS_C_SEQUENCE_FLAG 8
+#define GSS_C_CONF_FLAG 16
+#define GSS_C_INTEG_FLAG 32
+#define GSS_C_ANON_FLAG 64
+#define GSS_C_PROT_READY_FLAG 128
+#define GSS_C_TRANS_FLAG 256
+
+#define GSS_C_DCE_STYLE 4096
+#define GSS_C_IDENTIFY_FLAG 8192
+#define GSS_C_EXTENDED_ERROR_FLAG 16384
+#define GSS_C_DELEG_POLICY_FLAG 32768
+
+/*
+ * Credential usage options
+ */
+#define GSS_C_BOTH 0
+#define GSS_C_INITIATE 1
+#define GSS_C_ACCEPT 2
+
+/*
+ * Status code types for gss_display_status
+ */
+#define GSS_C_GSS_CODE 1
+#define GSS_C_MECH_CODE 2
+
+/*
+ * The constant definitions for channel-bindings address families
+ */
+#define GSS_C_AF_UNSPEC 0
+#define GSS_C_AF_LOCAL 1
+#define GSS_C_AF_INET 2
+#define GSS_C_AF_IMPLINK 3
+#define GSS_C_AF_PUP 4
+#define GSS_C_AF_CHAOS 5
+#define GSS_C_AF_NS 6
+#define GSS_C_AF_NBS 7
+#define GSS_C_AF_ECMA 8
+#define GSS_C_AF_DATAKIT 9
+#define GSS_C_AF_CCITT 10
+#define GSS_C_AF_SNA 11
+#define GSS_C_AF_DECnet 12
+#define GSS_C_AF_DLI 13
+#define GSS_C_AF_LAT 14
+#define GSS_C_AF_HYLINK 15
+#define GSS_C_AF_APPLETALK 16
+#define GSS_C_AF_BSC 17
+#define GSS_C_AF_DSS 18
+#define GSS_C_AF_OSI 19
+#define GSS_C_AF_X25 21
+#define GSS_C_AF_INET6 24
+
+#define GSS_C_AF_NULLADDR 255
+
+/*
+ * Various Null values
+ */
+#define GSS_C_NO_NAME ((gss_name_t) 0)
+#define GSS_C_NO_BUFFER ((gss_buffer_t) 0)
+#define GSS_C_NO_BUFFER_SET ((gss_buffer_set_t) 0)
+#define GSS_C_NO_OID ((gss_OID) 0)
+#define GSS_C_NO_OID_SET ((gss_OID_set) 0)
+#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0)
+#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0)
+#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0)
+#define GSS_C_EMPTY_BUFFER {0, NULL}
+#define GSS_C_NO_IOV_BUFFER ((gss_iov_buffer_t)0)
+
+/*
+ * Some alternate names for a couple of the above
+ * values. These are defined for V1 compatibility.
+ */
+#define GSS_C_NULL_OID GSS_C_NO_OID
+#define GSS_C_NULL_OID_SET GSS_C_NO_OID_SET
+
+/*
+ * Define the default Quality of Protection for per-message
+ * services. Note that an implementation that offers multiple
+ * levels of QOP may define GSS_C_QOP_DEFAULT to be either zero
+ * (as done here) to mean "default protection", or to a specific
+ * explicit QOP value. However, a value of 0 should always be
+ * interpreted by a GSSAPI implementation as a request for the
+ * default protection level.
+ */
+#define GSS_C_QOP_DEFAULT 0
+
+#define GSS_KRB5_CONF_C_QOP_DES 0x0100
+#define GSS_KRB5_CONF_C_QOP_DES3_KD 0x0200
+
+/*
+ * Expiration time of 2^32-1 seconds means infinite lifetime for a
+ * credential or security context
+ */
+#define GSS_C_INDEFINITE 0xfffffffful
+
+/*
+ * Type of gss_wrap_iov()/gss_unwrap_iov().
+ */
+
+#define GSS_IOV_BUFFER_TYPE_EMPTY 0
+#define GSS_IOV_BUFFER_TYPE_DATA 1
+#define GSS_IOV_BUFFER_TYPE_HEADER 2
+#define GSS_IOV_BUFFER_TYPE_MECH_PARAMS 3
+
+#define GSS_IOV_BUFFER_TYPE_TRAILER 7
+#define GSS_IOV_BUFFER_TYPE_PADDING 9
+#define GSS_IOV_BUFFER_TYPE_STREAM 10
+#define GSS_IOV_BUFFER_TYPE_SIGN_ONLY 11
+
+#define GSS_IOV_BUFFER_TYPE_FLAG_MASK 0xffff0000
+#define GSS_IOV_BUFFER_FLAG_ALLOCATE 0x00010000
+#define GSS_IOV_BUFFER_FLAG_ALLOCATED 0x00020000
+
+#define GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE 0x00010000 /* old name */
+#define GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED 0x00020000 /* old name */
+
+#define GSS_IOV_BUFFER_TYPE(_t) ((_t) & ~GSS_IOV_BUFFER_TYPE_FLAG_MASK)
+#define GSS_IOV_BUFFER_FLAGS(_t) ((_t) & GSS_IOV_BUFFER_TYPE_FLAG_MASK)
+
+GSSAPI_CPP_START
+
+#include <gssapi/gssapi_oid.h>
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x01"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_user_name_oid_desc;
+#define GSS_C_NT_USER_NAME (&__gss_c_nt_user_name_oid_desc)
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_machine_uid_name_oid_desc;
+#define GSS_C_NT_MACHINE_UID_NAME (&__gss_c_nt_machine_uid_name_oid_desc)
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x03"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_string_uid_name_oid_desc;
+#define GSS_C_NT_STRING_UID_NAME (&__gss_c_nt_string_uid_name_oid_desc)
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) org(3) dod(6) internet(1) security(5)
+ * nametypes(6) gss-host-based-services(2)). The constant
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
+ * to that gss_OID_desc. This is a deprecated OID value, and
+ * implementations wishing to support hostbased-service names
+ * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
+ * defined below, to identify such names;
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
+ * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
+ * parameter, but should not be emitted by GSS-API
+ * implementations
+ */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_hostbased_service_x_oid_desc;
+#define GSS_C_NT_HOSTBASED_SERVICE_X (&__gss_c_nt_hostbased_service_x_oid_desc)
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x04"}, corresponding to an
+ * object-identifier value of {iso(1) member-body(2)
+ * Unites States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) service_name(4)}. The constant
+ * GSS_C_NT_HOSTBASED_SERVICE should be initialized
+ * to point to that gss_OID_desc.
+ */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_hostbased_service_oid_desc;
+#define GSS_C_NT_HOSTBASED_SERVICE (&__gss_c_nt_hostbased_service_oid_desc)
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ * corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_anonymous_oid_desc;
+#define GSS_C_NT_ANONYMOUS (&__gss_c_nt_anonymous_oid_desc)
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_export_name_oid_desc;
+#define GSS_C_NT_EXPORT_NAME (&__gss_c_nt_export_name_oid_desc)
+
+/* Major status codes */
+
+#define GSS_S_COMPLETE 0
+
+/*
+ * Some "helper" definitions to make the status code macros obvious.
+ */
+#define GSS_C_CALLING_ERROR_OFFSET 24
+#define GSS_C_ROUTINE_ERROR_OFFSET 16
+#define GSS_C_SUPPLEMENTARY_OFFSET 0
+#define GSS_C_CALLING_ERROR_MASK 0377ul
+#define GSS_C_ROUTINE_ERROR_MASK 0377ul
+#define GSS_C_SUPPLEMENTARY_MASK 0177777ul
+
+/*
+ * The macros that test status codes for error conditions.
+ * Note that the GSS_ERROR() macro has changed slightly from
+ * the V1 GSSAPI so that it now evaluates its argument
+ * only once.
+ */
+#define GSS_CALLING_ERROR(x) \
+ (x & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
+#define GSS_ROUTINE_ERROR(x) \
+ (x & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
+#define GSS_SUPPLEMENTARY_INFO(x) \
+ (x & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
+#define GSS_ERROR(x) \
+ (x & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
+ (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
+
+/*
+ * Now the actual status code definitions
+ */
+
+/*
+ * Calling errors:
+ */
+#define GSS_S_CALL_INACCESSIBLE_READ \
+ (1ul << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_INACCESSIBLE_WRITE \
+ (2ul << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_BAD_STRUCTURE \
+ (3ul << GSS_C_CALLING_ERROR_OFFSET)
+
+/*
+ * Routine errors:
+ */
+#define GSS_S_BAD_MECH (1ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAME (2ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAMETYPE (3ul << GSS_C_ROUTINE_ERROR_OFFSET)
+
+#define GSS_S_BAD_BINDINGS (4ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_STATUS (5ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_SIG (6ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_MIC GSS_S_BAD_SIG
+#define GSS_S_NO_CRED (7ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CONTEXT (8ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_TOKEN (9ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_CREDENTIAL (10ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CREDENTIALS_EXPIRED (11ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CONTEXT_EXPIRED (12ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_FAILURE (13ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_QOP (14ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAUTHORIZED (15ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAVAILABLE (16ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DUPLICATE_ELEMENT (17ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NAME_NOT_MN (18ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_MECH_ATTR (19ul << GSS_C_ROUTINE_ERROR_OFFSET)
+
+/*
+ * Apparently awating spec fix.
+ */
+#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
+
+/*
+ * Supplementary info bits:
+ */
+#define GSS_S_CONTINUE_NEEDED (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
+#define GSS_S_DUPLICATE_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
+#define GSS_S_OLD_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
+#define GSS_S_UNSEQ_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
+#define GSS_S_GAP_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
+
+/*
+ * Finally, function prototypes for the GSS-API routines.
+ */
+
+#define GSS_C_OPTION_MASK 0xffff
+#define GSS_C_CRED_NO_UI 0x10000
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_acquire_cred
+ (OM_uint32 * /*minor_status*/,
+ const gss_name_t /*desired_name*/,
+ OM_uint32 /*time_req*/,
+ const gss_OID_set /*desired_mechs*/,
+ gss_cred_usage_t /*cred_usage*/,
+ gss_cred_id_t * /*output_cred_handle*/,
+ gss_OID_set * /*actual_mechs*/,
+ OM_uint32 * /*time_rec*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_release_cred
+ (OM_uint32 * /*minor_status*/,
+ gss_cred_id_t * /*cred_handle*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_init_sec_context
+ (OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*initiator_cred_handle*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_name_t /*target_name*/,
+ const gss_OID /*mech_type*/,
+ OM_uint32 /*req_flags*/,
+ OM_uint32 /*time_req*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ const gss_buffer_t /*input_token*/,
+ gss_OID * /*actual_mech_type*/,
+ gss_buffer_t /*output_token*/,
+ OM_uint32 * /*ret_flags*/,
+ OM_uint32 * /*time_rec*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_accept_sec_context
+ (OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_cred_id_t /*acceptor_cred_handle*/,
+ const gss_buffer_t /*input_token_buffer*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ gss_name_t * /*src_name*/,
+ gss_OID * /*mech_type*/,
+ gss_buffer_t /*output_token*/,
+ OM_uint32 * /*ret_flags*/,
+ OM_uint32 * /*time_rec*/,
+ gss_cred_id_t * /*delegated_cred_handle*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_process_context_token
+ (OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*token_buffer*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_delete_sec_context
+ (OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ gss_buffer_t /*output_token*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_context_time
+ (OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ OM_uint32 * /*time_rec*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_get_mic
+ (OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*message_buffer*/,
+ gss_buffer_t /*message_token*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_verify_mic
+ (OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t * /*qop_state*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_wrap
+ (OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ int * /*conf_state*/,
+ gss_buffer_t /*output_message_buffer*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_unwrap
+ (OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ gss_buffer_t /*output_message_buffer*/,
+ int * /*conf_state*/,
+ gss_qop_t * /*qop_state*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_display_status
+ (OM_uint32 * /*minor_status*/,
+ OM_uint32 /*status_value*/,
+ int /*status_type*/,
+ const gss_OID /*mech_type*/,
+ OM_uint32 * /*message_context*/,
+ gss_buffer_t /*status_string*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_indicate_mechs
+ (OM_uint32 * /*minor_status*/,
+ gss_OID_set * /*mech_set*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_compare_name
+ (OM_uint32 * /*minor_status*/,
+ const gss_name_t /*name1*/,
+ const gss_name_t /*name2*/,
+ int * /*name_equal*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_display_name
+ (OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t /*output_name_buffer*/,
+ gss_OID * /*output_name_type*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_import_name
+ (OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*input_name_buffer*/,
+ const gss_OID /*input_name_type*/,
+ gss_name_t * /*output_name*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_export_name
+ (OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t /*exported_name*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_release_name
+ (OM_uint32 * /*minor_status*/,
+ gss_name_t * /*input_name*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_release_buffer
+ (OM_uint32 * /*minor_status*/,
+ gss_buffer_t /*buffer*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_release_oid_set
+ (OM_uint32 * /*minor_status*/,
+ gss_OID_set * /*set*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_cred
+ (OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ gss_name_t * /*name*/,
+ OM_uint32 * /*lifetime*/,
+ gss_cred_usage_t * /*cred_usage*/,
+ gss_OID_set * /*mechanisms*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ gss_name_t * /*src_name*/,
+ gss_name_t * /*targ_name*/,
+ OM_uint32 * /*lifetime_rec*/,
+ gss_OID * /*mech_type*/,
+ OM_uint32 * /*ctx_flags*/,
+ int * /*locally_initiated*/,
+ int * /*open_context*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_wrap_size_limit (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ OM_uint32 /*req_output_size*/,
+ OM_uint32 * /*max_input_size*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_add_cred (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*input_cred_handle*/,
+ const gss_name_t /*desired_name*/,
+ const gss_OID /*desired_mech*/,
+ gss_cred_usage_t /*cred_usage*/,
+ OM_uint32 /*initiator_time_req*/,
+ OM_uint32 /*acceptor_time_req*/,
+ gss_cred_id_t * /*output_cred_handle*/,
+ gss_OID_set * /*actual_mechs*/,
+ OM_uint32 * /*initiator_time_rec*/,
+ OM_uint32 * /*acceptor_time_rec*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_cred_by_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * /*name*/,
+ OM_uint32 * /*initiator_lifetime*/,
+ OM_uint32 * /*acceptor_lifetime*/,
+ gss_cred_usage_t * /*cred_usage*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_export_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ gss_buffer_t /*interprocess_token*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_import_sec_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*interprocess_token*/,
+ gss_ctx_id_t * /*context_handle*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_create_empty_oid_set (
+ OM_uint32 * /*minor_status*/,
+ gss_OID_set * /*oid_set*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_add_oid_set_member (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*member_oid*/,
+ gss_OID_set * /*oid_set*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_test_oid_set_member (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*member*/,
+ const gss_OID_set /*set*/,
+ int * /*present*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_names_for_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*mechanism*/,
+ gss_OID_set * /*name_types*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_mechs_for_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_OID_set * /*mech_types*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_canonicalize_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * /*output_name*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_duplicate_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*src_name*/,
+ gss_name_t * /*dest_name*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_duplicate_oid (
+ OM_uint32 * /* minor_status */,
+ gss_OID /* src_oid */,
+ gss_OID * /* dest_oid */
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_release_oid
+ (OM_uint32 * /*minor_status*/,
+ gss_OID * /* oid */
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_oid_to_str(
+ OM_uint32 * /*minor_status*/,
+ gss_OID /* oid */,
+ gss_buffer_t /* str */
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_sec_context_by_oid(
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_set_sec_context_option (OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_set_cred_option (OM_uint32 *minor_status,
+ gss_cred_id_t *cred_handle,
+ const gss_OID object,
+ const gss_buffer_t value);
+
+GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL
+gss_oid_equal(gss_const_OID a, gss_const_OID b);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_create_empty_buffer_set
+ (OM_uint32 * minor_status,
+ gss_buffer_set_t *buffer_set);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_add_buffer_set_member
+ (OM_uint32 * minor_status,
+ const gss_buffer_t member_buffer,
+ gss_buffer_set_t *buffer_set);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_release_buffer_set
+ (OM_uint32 * minor_status,
+ gss_buffer_set_t *buffer_set);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_cred_by_oid(OM_uint32 *minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set);
+
+/*
+ * RFC 4401
+ */
+
+#define GSS_C_PRF_KEY_FULL 0
+#define GSS_C_PRF_KEY_PARTIAL 1
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_pseudo_random
+ (OM_uint32 *minor_status,
+ gss_ctx_id_t context,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_store_cred(OM_uint32 * /* minor_status */,
+ gss_cred_id_t /* input_cred_handle */,
+ gss_cred_usage_t /* cred_usage */,
+ const gss_OID /* desired_mech */,
+ OM_uint32 /* overwrite_cred */,
+ OM_uint32 /* default_cred */,
+ gss_OID_set * /* elements_stored */,
+ gss_cred_usage_t * /* cred_usage_stored */);
+
+
+/*
+ * Query functions
+ */
+
+typedef struct {
+ size_t header; /**< size of header */
+ size_t trailer; /**< size of trailer */
+ size_t max_msg_size; /**< maximum message size */
+ size_t buffers; /**< extra GSS_IOV_BUFFER_TYPE_EMPTY buffer to pass */
+ size_t blocksize; /**< Specificed optimal size of messages, also
+ is the maximum padding size
+ (GSS_IOV_BUFFER_TYPE_PADDING) */
+} gss_context_stream_sizes;
+
+extern gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_attr_stream_sizes_oid_desc;
+#define GSS_C_ATTR_STREAM_SIZES (&__gss_c_attr_stream_sizes_oid_desc)
+
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_context_query_attributes(OM_uint32 * /* minor_status */,
+ const gss_ctx_id_t /* context_handle */,
+ const gss_OID /* attribute */,
+ void * /*data*/,
+ size_t /* len */);
+/*
+ * The following routines are obsolete variants of gss_get_mic,
+ * gss_verify_mic, gss_wrap and gss_unwrap. They should be
+ * provided by GSSAPI V2 implementations for backwards
+ * compatibility with V1 applications. Distinct entrypoints
+ * (as opposed to #defines) should be provided, both to allow
+ * GSSAPI V1 applications to link against GSSAPI V2 implementations,
+ * and to retain the slight parameter type differences between the
+ * obsolete versions of these routines and their current forms.
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_sign
+ (OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int /*qop_req*/,
+ gss_buffer_t /*message_buffer*/,
+ gss_buffer_t /*message_token*/
+ ) GSSAPI_DEPRECATED_FUNCTION("Use gss_get_mic");
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_verify
+ (OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ gss_buffer_t /*message_buffer*/,
+ gss_buffer_t /*token_buffer*/,
+ int * /*qop_state*/
+ ) GSSAPI_DEPRECATED_FUNCTION("Use gss_verify_mic");
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_seal
+ (OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ int /*qop_req*/,
+ gss_buffer_t /*input_message_buffer*/,
+ int * /*conf_state*/,
+ gss_buffer_t /*output_message_buffer*/
+ ) GSSAPI_DEPRECATED_FUNCTION("Use gss_wrap");
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_unseal
+ (OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ gss_buffer_t /*input_message_buffer*/,
+ gss_buffer_t /*output_message_buffer*/,
+ int * /*conf_state*/,
+ int * /*qop_state*/
+ ) GSSAPI_DEPRECATED_FUNCTION("Use gss_unwrap");
+
+/**
+ *
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_encapsulate_token(gss_const_buffer_t /* input_token */,
+ gss_const_OID /* oid */,
+ gss_buffer_t /* output_token */);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_decapsulate_token(gss_const_buffer_t /* input_token */,
+ gss_const_OID /* oid */,
+ gss_buffer_t /* output_token */);
+
+
+
+/*
+ * AEAD support
+ */
+
+/*
+ * GSS_IOV
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_wrap_iov(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *,
+ gss_iov_buffer_desc *, int);
+
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_unwrap_iov(OM_uint32 *, gss_ctx_id_t, int *, gss_qop_t *,
+ gss_iov_buffer_desc *, int);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_wrap_iov_length(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *,
+ gss_iov_buffer_desc *, int);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_release_iov_buffer(OM_uint32 *, gss_iov_buffer_desc *, int);
+
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_export_cred(OM_uint32 * /* minor_status */,
+ gss_cred_id_t /* cred_handle */,
+ gss_buffer_t /* cred_token */);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_import_cred(OM_uint32 * /* minor_status */,
+ gss_buffer_t /* cred_token */,
+ gss_cred_id_t * /* cred_handle */);
+
+/*
+ * mech option
+ */
+
+GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL
+gss_mo_set(gss_const_OID mech, gss_const_OID option,
+ int enable, gss_buffer_t value);
+
+GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL
+gss_mo_get(gss_const_OID mech, gss_const_OID option, gss_buffer_t value);
+
+GSSAPI_LIB_FUNCTION void GSSAPI_LIB_CALL
+gss_mo_list(gss_const_OID mech, gss_OID_set *options);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_mo_name(gss_const_OID mech, gss_const_OID options, gss_buffer_t name);
+
+/*
+ * SASL glue functions and mech inquire
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_saslname_for_mech(OM_uint32 *minor_status,
+ const gss_OID desired_mech,
+ gss_buffer_t sasl_mech_name,
+ gss_buffer_t mech_name,
+ gss_buffer_t mech_description);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_mech_for_saslname(OM_uint32 *minor_status,
+ const gss_buffer_t sasl_mech_name,
+ gss_OID *mech_type);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_indicate_mechs_by_attrs(OM_uint32 * minor_status,
+ gss_const_OID_set desired_mech_attrs,
+ gss_const_OID_set except_mech_attrs,
+ gss_const_OID_set critical_mech_attrs,
+ gss_OID_set *mechs);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_attrs_for_mech(OM_uint32 * minor_status,
+ gss_const_OID mech,
+ gss_OID_set *mech_attr,
+ gss_OID_set *known_mech_attrs);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_display_mech_attr(OM_uint32 * minor_status,
+ gss_const_OID mech_attr,
+ gss_buffer_t name,
+ gss_buffer_t short_desc,
+ gss_buffer_t long_desc);
+
+/*
+ * Solaris compat
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_acquire_cred_with_password
+ (OM_uint32 * /*minor_status*/,
+ const gss_name_t /*desired_name*/,
+ const gss_buffer_t /*password*/,
+ OM_uint32 /*time_req*/,
+ const gss_OID_set /*desired_mechs*/,
+ gss_cred_usage_t /*cred_usage*/,
+ gss_cred_id_t * /*output_cred_handle*/,
+ gss_OID_set * /*actual_mechs*/,
+ OM_uint32 * /*time_rec*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_add_cred_with_password (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*input_cred_handle*/,
+ const gss_name_t /*desired_name*/,
+ const gss_OID /*desired_mech*/,
+ const gss_buffer_t /*password*/,
+ gss_cred_usage_t /*cred_usage*/,
+ OM_uint32 /*initiator_time_req*/,
+ OM_uint32 /*acceptor_time_req*/,
+ gss_cred_id_t * /*output_cred_handle*/,
+ gss_OID_set * /*actual_mechs*/,
+ OM_uint32 * /*initiator_time_rec*/,
+ OM_uint32 * /*acceptor_time_rec*/
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_pname_to_uid(
+ OM_uint32 *minor,
+ const gss_name_t name,
+ const gss_OID mech_type,
+ uid_t *uidOut);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_authorize_localname(
+ OM_uint32 *minor,
+ const gss_name_t name,
+ const gss_name_t user);
+
+GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL
+gss_userok(const gss_name_t name,
+ const char *user);
+
+extern GSSAPI_LIB_VARIABLE gss_buffer_desc __gss_c_attr_local_login_user;
+#define GSS_C_ATTR_LOCAL_LOGIN_USER (&__gss_c_attr_local_login_user)
+
+/*
+ * Naming extensions
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_display_name_ext (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_OID, /* display_as_name_type */
+ gss_buffer_t /* display_name */
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_name (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ int *, /* name_is_MN */
+ gss_OID *, /* MN_mech */
+ gss_buffer_set_t * /* attrs */
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_get_name_attribute (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t, /* attr */
+ int *, /* authenticated */
+ int *, /* complete */
+ gss_buffer_t, /* value */
+ gss_buffer_t, /* display_value */
+ int * /* more */
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_set_name_attribute (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ int, /* complete */
+ gss_buffer_t, /* attr */
+ gss_buffer_t /* value */
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_delete_name_attribute (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t /* attr */
+ );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_export_name_composite (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t /* exp_composite_name */
+ );
+
+/*
+ *
+ */
+
+GSSAPI_LIB_FUNCTION const char * GSSAPI_LIB_CALL
+gss_oid_to_name(gss_const_OID oid);
+
+GSSAPI_LIB_FUNCTION gss_OID GSSAPI_LIB_CALL
+gss_name_to_oid(const char *name);
+
+GSSAPI_CPP_END
+
+#if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__) || defined(__i386__) || defined(__x86_64__))
+#pragma pack(pop)
+#endif
+
+#undef GSSAPI_DEPRECATED_FUNCTION
+
+#endif /* GSSAPI_GSSAPI_H_ */
diff --git a/crypto/heimdal/lib/gssapi/gssapi/gssapi_krb5.h b/crypto/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
new file mode 100644
index 0000000..2f605f5
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+#ifndef GSSAPI_KRB5_H_
+#define GSSAPI_KRB5_H_
+
+#include <gssapi.h>
+
+GSSAPI_CPP_START
+
+#if !defined(__GNUC__) && !defined(__attribute__)
+#define __attribute__(x)
+#endif
+
+#ifndef GSSKRB5_FUNCTION_DEPRECATED
+#define GSSKRB5_FUNCTION_DEPRECATED __attribute__((deprecated))
+#endif
+
+
+/*
+ * This is for kerberos5 names.
+ */
+
+extern gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_nt_principal_name_oid_desc;
+#define GSS_KRB5_NT_PRINCIPAL_NAME (&__gss_krb5_nt_principal_name_oid_desc)
+
+#define GSS_KRB5_NT_USER_NAME (&__gss_c_nt_user_name_oid_desc)
+#define GSS_KRB5_NT_MACHINE_UID_NAME (&__gss_c_nt_machine_uid_name_oid_desc)
+#define GSS_KRB5_NT_STRING_UID_NAME (&__gss_c_nt_string_uid_name_oid_desc)
+
+extern gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_mechanism_oid_desc;
+#define GSS_KRB5_MECHANISM (&__gss_krb5_mechanism_oid_desc)
+
+/* for compatibility with MIT api */
+
+#define gss_mech_krb5 GSS_KRB5_MECHANISM
+#define gss_krb5_nt_general_name GSS_KRB5_NT_PRINCIPAL_NAME
+
+/*
+ * kerberos mechanism specific functions
+ */
+
+struct krb5_keytab_data;
+struct krb5_ccache_data;
+struct Principal;
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_krb5_ccache_name(OM_uint32 * /*minor_status*/,
+ const char * /*name */,
+ const char ** /*out_name */);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gsskrb5_register_acceptor_identity
+ (const char * /*identity*/);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL krb5_gss_register_acceptor_identity
+ (const char * /*identity*/);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_krb5_copy_ccache
+ (OM_uint32 * /*minor*/,
+ gss_cred_id_t /*cred*/,
+ struct krb5_ccache_data * /*out*/);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_krb5_import_cred(OM_uint32 * /*minor*/,
+ struct krb5_ccache_data * /*in*/,
+ struct Principal * /*keytab_principal*/,
+ struct krb5_keytab_data * /*keytab*/,
+ gss_cred_id_t * /*out*/);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_krb5_get_tkt_flags
+ (OM_uint32 * /*minor*/,
+ gss_ctx_id_t /*context_handle*/,
+ OM_uint32 * /*tkt_flags*/);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_extract_authz_data_from_sec_context
+ (OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int /*ad_type*/,
+ gss_buffer_t /*ad_data*/);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_set_dns_canonicalize(int);
+
+struct gsskrb5_send_to_kdc {
+ void *func;
+ void *ptr;
+};
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *)
+ GSSKRB5_FUNCTION_DEPRECATED;
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_set_default_realm(const char *);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_extract_authtime_from_sec_context(OM_uint32 *, gss_ctx_id_t, time_t *);
+
+struct EncryptionKey;
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_extract_service_keyblock(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ struct EncryptionKey **out);
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_get_initiator_subkey(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ struct EncryptionKey **out);
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_get_subkey(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ struct EncryptionKey **out);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_set_time_offset(int);
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_get_time_offset(int *);
+
+struct gsskrb5_krb5_plugin {
+ int type;
+ char *name;
+ void *symbol;
+};
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_plugin_register(struct gsskrb5_krb5_plugin *);
+
+
+/*
+ * Lucid - NFSv4 interface to GSS-API KRB5 to expose key material to
+ * do GSS content token handling in-kernel.
+ */
+
+typedef struct gss_krb5_lucid_key {
+ OM_uint32 type;
+ OM_uint32 length;
+ void * data;
+} gss_krb5_lucid_key_t;
+
+typedef struct gss_krb5_rfc1964_keydata {
+ OM_uint32 sign_alg;
+ OM_uint32 seal_alg;
+ gss_krb5_lucid_key_t ctx_key;
+} gss_krb5_rfc1964_keydata_t;
+
+typedef struct gss_krb5_cfx_keydata {
+ OM_uint32 have_acceptor_subkey;
+ gss_krb5_lucid_key_t ctx_key;
+ gss_krb5_lucid_key_t acceptor_subkey;
+} gss_krb5_cfx_keydata_t;
+
+typedef struct gss_krb5_lucid_context_v1 {
+ OM_uint32 version;
+ OM_uint32 initiate;
+ OM_uint32 endtime;
+ OM_uint64 send_seq;
+ OM_uint64 recv_seq;
+ OM_uint32 protocol;
+ gss_krb5_rfc1964_keydata_t rfc1964_kd;
+ gss_krb5_cfx_keydata_t cfx_kd;
+} gss_krb5_lucid_context_v1_t;
+
+typedef struct gss_krb5_lucid_context_version {
+ OM_uint32 version; /* Structure version number */
+} gss_krb5_lucid_context_version_t;
+
+/*
+ * Function declarations
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ OM_uint32 version,
+ void **kctx);
+
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status,
+ void *kctx);
+
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status,
+ gss_cred_id_t cred,
+ OM_uint32 num_enctypes,
+ int32_t *enctypes);
+
+GSSAPI_CPP_END
+
+#endif /* GSSAPI_SPNEGO_H_ */
diff --git a/crypto/heimdal/lib/gssapi/gssapi/gssapi_ntlm.h b/crypto/heimdal/lib/gssapi/gssapi/gssapi_ntlm.h
new file mode 100644
index 0000000..e37c003
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gssapi/gssapi_ntlm.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2006 - 2009 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+#ifndef GSSAPI_NTLM_H_
+#define GSSAPI_NTLM_H_
+
+#include <gssapi.h>
+
+#endif /* GSSAPI_NTLM_H_ */
diff --git a/crypto/heimdal/lib/gssapi/gssapi/gssapi_oid.h b/crypto/heimdal/lib/gssapi/gssapi/gssapi_oid.h
new file mode 100644
index 0000000..9465efc
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gssapi/gssapi_oid.h
@@ -0,0 +1,245 @@
+/* Generated file */
+#ifndef GSSAPI_GSSAPI_OID
+#define GSSAPI_GSSAPI_OID 1
+
+ /* contact Love Hörnquist Åstrand <lha@h5l.org> for new oid arcs */
+ /*
+ * 1.2.752.43.13 Heimdal GSS-API Extentions
+ */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_copy_ccache_x_oid_desc;
+#define GSS_KRB5_COPY_CCACHE_X (&__gss_krb5_copy_ccache_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_tkt_flags_x_oid_desc;
+#define GSS_KRB5_GET_TKT_FLAGS_X (&__gss_krb5_get_tkt_flags_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_extract_authz_data_from_sec_context_x_oid_desc;
+#define GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X (&__gss_krb5_extract_authz_data_from_sec_context_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_compat_des3_mic_x_oid_desc;
+#define GSS_KRB5_COMPAT_DES3_MIC_X (&__gss_krb5_compat_des3_mic_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_register_acceptor_identity_x_oid_desc;
+#define GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X (&__gss_krb5_register_acceptor_identity_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_export_lucid_context_x_oid_desc;
+#define GSS_KRB5_EXPORT_LUCID_CONTEXT_X (&__gss_krb5_export_lucid_context_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_export_lucid_context_v1_x_oid_desc;
+#define GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X (&__gss_krb5_export_lucid_context_v1_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_set_dns_canonicalize_x_oid_desc;
+#define GSS_KRB5_SET_DNS_CANONICALIZE_X (&__gss_krb5_set_dns_canonicalize_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_subkey_x_oid_desc;
+#define GSS_KRB5_GET_SUBKEY_X (&__gss_krb5_get_subkey_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_initiator_subkey_x_oid_desc;
+#define GSS_KRB5_GET_INITIATOR_SUBKEY_X (&__gss_krb5_get_initiator_subkey_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_acceptor_subkey_x_oid_desc;
+#define GSS_KRB5_GET_ACCEPTOR_SUBKEY_X (&__gss_krb5_get_acceptor_subkey_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_send_to_kdc_x_oid_desc;
+#define GSS_KRB5_SEND_TO_KDC_X (&__gss_krb5_send_to_kdc_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_authtime_x_oid_desc;
+#define GSS_KRB5_GET_AUTHTIME_X (&__gss_krb5_get_authtime_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_service_keyblock_x_oid_desc;
+#define GSS_KRB5_GET_SERVICE_KEYBLOCK_X (&__gss_krb5_get_service_keyblock_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_set_allowable_enctypes_x_oid_desc;
+#define GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X (&__gss_krb5_set_allowable_enctypes_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_set_default_realm_x_oid_desc;
+#define GSS_KRB5_SET_DEFAULT_REALM_X (&__gss_krb5_set_default_realm_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_ccache_name_x_oid_desc;
+#define GSS_KRB5_CCACHE_NAME_X (&__gss_krb5_ccache_name_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_set_time_offset_x_oid_desc;
+#define GSS_KRB5_SET_TIME_OFFSET_X (&__gss_krb5_set_time_offset_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_time_offset_x_oid_desc;
+#define GSS_KRB5_GET_TIME_OFFSET_X (&__gss_krb5_get_time_offset_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_plugin_register_x_oid_desc;
+#define GSS_KRB5_PLUGIN_REGISTER_X (&__gss_krb5_plugin_register_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_ntlm_get_session_key_x_oid_desc;
+#define GSS_NTLM_GET_SESSION_KEY_X (&__gss_ntlm_get_session_key_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_ntlm_oid_desc;
+#define GSS_C_NT_NTLM (&__gss_c_nt_ntlm_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_dn_oid_desc;
+#define GSS_C_NT_DN (&__gss_c_nt_dn_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_nt_principal_name_referral_oid_desc;
+#define GSS_KRB5_NT_PRINCIPAL_NAME_REFERRAL (&__gss_krb5_nt_principal_name_referral_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ntlm_avguest_oid_desc;
+#define GSS_C_NTLM_AVGUEST (&__gss_c_ntlm_avguest_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ntlm_v1_oid_desc;
+#define GSS_C_NTLM_V1 (&__gss_c_ntlm_v1_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ntlm_v2_oid_desc;
+#define GSS_C_NTLM_V2 (&__gss_c_ntlm_v2_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ntlm_session_key_oid_desc;
+#define GSS_C_NTLM_SESSION_KEY (&__gss_c_ntlm_session_key_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ntlm_force_v1_oid_desc;
+#define GSS_C_NTLM_FORCE_V1 (&__gss_c_ntlm_force_v1_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_cred_no_ci_flags_x_oid_desc;
+#define GSS_KRB5_CRED_NO_CI_FLAGS_X (&__gss_krb5_cred_no_ci_flags_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_import_cred_x_oid_desc;
+#define GSS_KRB5_IMPORT_CRED_X (&__gss_krb5_import_cred_x_oid_desc)
+
+ /* glue for gss_inquire_saslname_for_mech */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_sasl_mech_name_oid_desc;
+#define GSS_C_MA_SASL_MECH_NAME (&__gss_c_ma_sasl_mech_name_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_mech_name_oid_desc;
+#define GSS_C_MA_MECH_NAME (&__gss_c_ma_mech_name_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_mech_description_oid_desc;
+#define GSS_C_MA_MECH_DESCRIPTION (&__gss_c_ma_mech_description_oid_desc)
+
+ /* credential types */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_cred_password_oid_desc;
+#define GSS_C_CRED_PASSWORD (&__gss_c_cred_password_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_cred_certificate_oid_desc;
+#define GSS_C_CRED_CERTIFICATE (&__gss_c_cred_certificate_oid_desc)
+
+/* Heimdal mechanisms - 1.2.752.43.14 */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_sasl_digest_md5_mechanism_oid_desc;
+#define GSS_SASL_DIGEST_MD5_MECHANISM (&__gss_sasl_digest_md5_mechanism_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_netlogon_mechanism_oid_desc;
+#define GSS_NETLOGON_MECHANISM (&__gss_netlogon_mechanism_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_netlogon_set_session_key_x_oid_desc;
+#define GSS_NETLOGON_SET_SESSION_KEY_X (&__gss_netlogon_set_session_key_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_netlogon_set_sign_algorithm_x_oid_desc;
+#define GSS_NETLOGON_SET_SIGN_ALGORITHM_X (&__gss_netlogon_set_sign_algorithm_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_netlogon_nt_netbios_dns_name_oid_desc;
+#define GSS_NETLOGON_NT_NETBIOS_DNS_NAME (&__gss_netlogon_nt_netbios_dns_name_oid_desc)
+
+/* GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X.128 */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_inq_win2k_pac_x_oid_desc;
+#define GSS_C_INQ_WIN2K_PAC_X (&__gss_c_inq_win2k_pac_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_inq_sspi_session_key_oid_desc;
+#define GSS_C_INQ_SSPI_SESSION_KEY (&__gss_c_inq_sspi_session_key_oid_desc)
+
+/*
+ * "Standard" mechs
+ */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_mechanism_oid_desc;
+#define GSS_KRB5_MECHANISM (&__gss_krb5_mechanism_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_ntlm_mechanism_oid_desc;
+#define GSS_NTLM_MECHANISM (&__gss_ntlm_mechanism_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_spnego_mechanism_oid_desc;
+#define GSS_SPNEGO_MECHANISM (&__gss_spnego_mechanism_oid_desc)
+
+ /* From Luke Howard */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_peer_has_updated_spnego_oid_desc;
+#define GSS_C_PEER_HAS_UPDATED_SPNEGO (&__gss_c_peer_has_updated_spnego_oid_desc)
+
+/*
+ * OID mappings with name and short description and and slightly longer description
+ */
+/*
+ * RFC5587
+ */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_mech_concrete_oid_desc;
+#define GSS_C_MA_MECH_CONCRETE (&__gss_c_ma_mech_concrete_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_mech_pseudo_oid_desc;
+#define GSS_C_MA_MECH_PSEUDO (&__gss_c_ma_mech_pseudo_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_mech_composite_oid_desc;
+#define GSS_C_MA_MECH_COMPOSITE (&__gss_c_ma_mech_composite_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_mech_nego_oid_desc;
+#define GSS_C_MA_MECH_NEGO (&__gss_c_ma_mech_nego_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_mech_glue_oid_desc;
+#define GSS_C_MA_MECH_GLUE (&__gss_c_ma_mech_glue_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_not_mech_oid_desc;
+#define GSS_C_MA_NOT_MECH (&__gss_c_ma_not_mech_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_deprecated_oid_desc;
+#define GSS_C_MA_DEPRECATED (&__gss_c_ma_deprecated_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_not_dflt_mech_oid_desc;
+#define GSS_C_MA_NOT_DFLT_MECH (&__gss_c_ma_not_dflt_mech_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_itok_framed_oid_desc;
+#define GSS_C_MA_ITOK_FRAMED (&__gss_c_ma_itok_framed_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_auth_init_oid_desc;
+#define GSS_C_MA_AUTH_INIT (&__gss_c_ma_auth_init_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_auth_targ_oid_desc;
+#define GSS_C_MA_AUTH_TARG (&__gss_c_ma_auth_targ_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_auth_init_init_oid_desc;
+#define GSS_C_MA_AUTH_INIT_INIT (&__gss_c_ma_auth_init_init_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_auth_targ_init_oid_desc;
+#define GSS_C_MA_AUTH_TARG_INIT (&__gss_c_ma_auth_targ_init_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_auth_init_anon_oid_desc;
+#define GSS_C_MA_AUTH_INIT_ANON (&__gss_c_ma_auth_init_anon_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_auth_targ_anon_oid_desc;
+#define GSS_C_MA_AUTH_TARG_ANON (&__gss_c_ma_auth_targ_anon_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_deleg_cred_oid_desc;
+#define GSS_C_MA_DELEG_CRED (&__gss_c_ma_deleg_cred_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_integ_prot_oid_desc;
+#define GSS_C_MA_INTEG_PROT (&__gss_c_ma_integ_prot_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_conf_prot_oid_desc;
+#define GSS_C_MA_CONF_PROT (&__gss_c_ma_conf_prot_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_mic_oid_desc;
+#define GSS_C_MA_MIC (&__gss_c_ma_mic_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_wrap_oid_desc;
+#define GSS_C_MA_WRAP (&__gss_c_ma_wrap_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_prot_ready_oid_desc;
+#define GSS_C_MA_PROT_READY (&__gss_c_ma_prot_ready_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_replay_det_oid_desc;
+#define GSS_C_MA_REPLAY_DET (&__gss_c_ma_replay_det_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_oos_det_oid_desc;
+#define GSS_C_MA_OOS_DET (&__gss_c_ma_oos_det_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_cbindings_oid_desc;
+#define GSS_C_MA_CBINDINGS (&__gss_c_ma_cbindings_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_pfs_oid_desc;
+#define GSS_C_MA_PFS (&__gss_c_ma_pfs_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_compress_oid_desc;
+#define GSS_C_MA_COMPRESS (&__gss_c_ma_compress_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_ctx_trans_oid_desc;
+#define GSS_C_MA_CTX_TRANS (&__gss_c_ma_ctx_trans_oid_desc)
+
+#endif /* GSSAPI_GSSAPI_OID */
diff --git a/crypto/heimdal/lib/gssapi/gssapi/gssapi_spnego.h b/crypto/heimdal/lib/gssapi/gssapi/gssapi_spnego.h
new file mode 100644
index 0000000..dd3b2a5
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gssapi/gssapi_spnego.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+#ifndef GSSAPI_SPNEGO_H_
+#define GSSAPI_SPNEGO_H_
+
+#include <gssapi.h>
+
+GSSAPI_CPP_START
+
+/*
+ * RFC2478, SPNEGO:
+ * The security mechanism of the initial
+ * negotiation token is identified by the Object Identifier
+ * iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2).
+ */
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_spnego_mechanism_oid_desc;
+#define GSS_SPNEGO_MECHANISM (&__gss_spnego_mechanism_oid_desc)
+#define gss_mech_spnego GSS_SPNEGO_MECHANISM
+
+GSSAPI_CPP_END
+
+#endif /* GSSAPI_SPNEGO_H_ */
diff --git a/crypto/heimdal/lib/gssapi/gssapi_mech.h b/crypto/heimdal/lib/gssapi/gssapi_mech.h
new file mode 100644
index 0000000..d8f3a18
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gssapi_mech.h
@@ -0,0 +1,594 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef GSSAPI_MECH_H
+#define GSSAPI_MECH_H 1
+
+#include <gssapi.h>
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_acquire_cred_t
+ (OM_uint32 *, /* minor_status */
+ const gss_name_t, /* desired_name */
+ OM_uint32, /* time_req */
+ const gss_OID_set, /* desired_mechs */
+ gss_cred_usage_t, /* cred_usage */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 * /* time_rec */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_release_cred_t
+ (OM_uint32 *, /* minor_status */
+ gss_cred_id_t * /* cred_handle */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_init_sec_context_t
+ (OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* initiator_cred_handle */
+ gss_ctx_id_t *, /* context_handle */
+ const gss_name_t, /* target_name */
+ const gss_OID, /* mech_type */
+ OM_uint32, /* req_flags */
+ OM_uint32, /* time_req */
+ const gss_channel_bindings_t,
+ /* input_chan_bindings */
+ const gss_buffer_t, /* input_token */
+ gss_OID *, /* actual_mech_type */
+ gss_buffer_t, /* output_token */
+ OM_uint32 *, /* ret_flags */
+ OM_uint32 * /* time_rec */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_accept_sec_context_t
+ (OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ const gss_cred_id_t, /* acceptor_cred_handle */
+ const gss_buffer_t, /* input_token_buffer */
+ const gss_channel_bindings_t,
+ /* input_chan_bindings */
+ gss_name_t *, /* src_name */
+ gss_OID *, /* mech_type */
+ gss_buffer_t, /* output_token */
+ OM_uint32 *, /* ret_flags */
+ OM_uint32 *, /* time_rec */
+ gss_cred_id_t * /* delegated_cred_handle */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_process_context_token_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_buffer_t /* token_buffer */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_delete_sec_context_t
+ (OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ gss_buffer_t /* output_token */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_context_time_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ OM_uint32 * /* time_rec */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_get_mic_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ gss_qop_t, /* qop_req */
+ const gss_buffer_t, /* message_buffer */
+ gss_buffer_t /* message_token */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_verify_mic_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_buffer_t, /* message_buffer */
+ const gss_buffer_t, /* token_buffer */
+ gss_qop_t * /* qop_state */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_wrap_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ const gss_buffer_t, /* input_message_buffer */
+ int *, /* conf_state */
+ gss_buffer_t /* output_message_buffer */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_unwrap_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_buffer_t, /* input_message_buffer */
+ gss_buffer_t, /* output_message_buffer */
+ int *, /* conf_state */
+ gss_qop_t * /* qop_state */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_display_status_t
+ (OM_uint32 *, /* minor_status */
+ OM_uint32, /* status_value */
+ int, /* status_type */
+ const gss_OID, /* mech_type */
+ OM_uint32 *, /* message_context */
+ gss_buffer_t /* status_string */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_indicate_mechs_t
+ (OM_uint32 *, /* minor_status */
+ gss_OID_set * /* mech_set */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_compare_name_t
+ (OM_uint32 *, /* minor_status */
+ const gss_name_t, /* name1 */
+ const gss_name_t, /* name2 */
+ int * /* name_equal */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_display_name_t
+ (OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_buffer_t, /* output_name_buffer */
+ gss_OID * /* output_name_type */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_import_name_t
+ (OM_uint32 *, /* minor_status */
+ const gss_buffer_t, /* input_name_buffer */
+ const gss_OID, /* input_name_type */
+ gss_name_t * /* output_name */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_export_name_t
+ (OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_buffer_t /* exported_name */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_release_name_t
+ (OM_uint32 *, /* minor_status */
+ gss_name_t * /* input_name */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_cred_t
+ (OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* cred_handle */
+ gss_name_t *, /* name */
+ OM_uint32 *, /* lifetime */
+ gss_cred_usage_t *, /* cred_usage */
+ gss_OID_set * /* mechanisms */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_context_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ gss_name_t *, /* src_name */
+ gss_name_t *, /* targ_name */
+ OM_uint32 *, /* lifetime_rec */
+ gss_OID *, /* mech_type */
+ OM_uint32 *, /* ctx_flags */
+ int *, /* locally_initiated */
+ int * /* open */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_wrap_size_limit_t
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ OM_uint32, /* req_output_size */
+ OM_uint32 * /* max_input_size */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_add_cred_t (
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* input_cred_handle */
+ const gss_name_t, /* desired_name */
+ const gss_OID, /* desired_mech */
+ gss_cred_usage_t, /* cred_usage */
+ OM_uint32, /* initiator_time_req */
+ OM_uint32, /* acceptor_time_req */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *, /* initiator_time_rec */
+ OM_uint32 * /* acceptor_time_rec */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_cred_by_mech_t (
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* cred_handle */
+ const gss_OID, /* mech_type */
+ gss_name_t *, /* name */
+ OM_uint32 *, /* initiator_lifetime */
+ OM_uint32 *, /* acceptor_lifetime */
+ gss_cred_usage_t * /* cred_usage */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_export_sec_context_t (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ gss_buffer_t /* interprocess_token */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_import_sec_context_t (
+ OM_uint32 *, /* minor_status */
+ const gss_buffer_t, /* interprocess_token */
+ gss_ctx_id_t * /* context_handle */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_names_for_mech_t (
+ OM_uint32 *, /* minor_status */
+ const gss_OID, /* mechanism */
+ gss_OID_set * /* name_types */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_mechs_for_name_t (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_OID_set * /* mech_types */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_canonicalize_name_t (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ const gss_OID, /* mech_type */
+ gss_name_t * /* output_name */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_duplicate_name_t (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* src_name */
+ gss_name_t * /* dest_name */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_sec_context_by_oid (
+ OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_cred_by_oid (
+ OM_uint32 *minor_status,
+ const gss_cred_id_t cred,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_set_sec_context_option (
+ OM_uint32 *minor_status,
+ gss_ctx_id_t *cred_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_set_cred_option (
+ OM_uint32 *minor_status,
+ gss_cred_id_t *cred_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value
+ );
+
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_pseudo_random(
+ OM_uint32 *minor_status,
+ gss_ctx_id_t context,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_wrap_iov_t(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int * conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count);
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_unwrap_iov_t(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int *conf_state,
+ gss_qop_t *qop_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count);
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_wrap_iov_length_t(OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count);
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_store_cred_t(OM_uint32 *minor_status,
+ gss_cred_id_t input_cred_handle,
+ gss_cred_usage_t cred_usage,
+ const gss_OID desired_mech,
+ OM_uint32 overwrite_cred,
+ OM_uint32 default_cred,
+ gss_OID_set *elements_stored,
+ gss_cred_usage_t *cred_usage_stored);
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_export_cred_t(OM_uint32 *minor_status,
+ gss_cred_id_t cred_handle,
+ gss_buffer_t cred_token);
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_import_cred_t(OM_uint32 * minor_status,
+ gss_buffer_t cred_token,
+ gss_cred_id_t * cred_handle);
+
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_acquire_cred_ext_t(OM_uint32 * /*minor_status */,
+ const gss_name_t /* desired_name */,
+ gss_const_OID /* credential_type */,
+ const void * /* credential_data */,
+ OM_uint32 /* time_req */,
+ gss_const_OID /* desired_mech */,
+ gss_cred_usage_t /* cred_usage */,
+ gss_cred_id_t * /* output_cred_handle */);
+
+typedef void GSSAPI_CALLCONV
+_gss_iter_creds_t(OM_uint32 /* flags */,
+ void * /* userctx */,
+ void (* /*cred_iter */ )(void *, gss_OID, gss_cred_id_t));
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_destroy_cred_t(OM_uint32 * /* minor_status */,
+ gss_cred_id_t * /* cred */);
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_cred_hold_t(OM_uint32 * /* minor_status */,
+ gss_cred_id_t /* cred */);
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_cred_unhold_t(OM_uint32 * /* minor_status */,
+ gss_cred_id_t /* cred */);
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_cred_label_set_t(OM_uint32 * /* minor_status */,
+ gss_cred_id_t /* cred */,
+ const char * /* label */,
+ gss_buffer_t /* value */);
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_cred_label_get_t(OM_uint32 * /* minor_status */,
+ gss_cred_id_t /* cred */,
+ const char * /* label */,
+ gss_buffer_t /* value */);
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_display_name_ext_t (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_OID, /* display_as_name_type */
+ gss_buffer_t /* display_name */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_name_t (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ int *, /* name_is_MN */
+ gss_OID *, /* MN_mech */
+ gss_buffer_set_t * /* attrs */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_get_name_attribute_t (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t, /* attr */
+ int *, /* authenticated */
+ int *, /* complete */
+ gss_buffer_t, /* value */
+ gss_buffer_t, /* display_value */
+ int * /* more */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_set_name_attribute_t (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ int, /* complete */
+ gss_buffer_t, /* attr */
+ gss_buffer_t /* value */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_delete_name_attribute_t (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t /* attr */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_export_name_composite_t (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t /* exp_composite_name */
+ );
+
+/*
+ *
+ */
+
+typedef struct gss_mo_desc_struct gss_mo_desc;
+
+typedef OM_uint32 GSSAPI_CALLCONV
+_gss_mo_init (OM_uint32 *, gss_OID, gss_mo_desc **, size_t *);
+
+
+struct gss_mo_desc_struct {
+ gss_OID option;
+ OM_uint32 flags;
+#define GSS_MO_MA 1
+#define GSS_MO_MA_CRITICAL 2
+ const char *name;
+ void *ctx;
+ int (*get)(gss_const_OID, gss_mo_desc *, gss_buffer_t);
+ int (*set)(gss_const_OID, gss_mo_desc *, int, gss_buffer_t);
+};
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_pname_to_uid_t (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* name */
+ const gss_OID, /* mech_type */
+ uid_t * /* uidOut */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_authorize_localname_t (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* name */
+ gss_const_buffer_t, /* user */
+ gss_const_OID /* user_name_type */
+ );
+
+/* mechglue internal */
+struct gss_mech_compat_desc_struct;
+
+#define GMI_VERSION 5
+
+/* gm_flags */
+#define GM_USE_MG_CRED 1 /* uses mech glue credentials */
+
+typedef struct gssapi_mech_interface_desc {
+ unsigned gm_version;
+ const char *gm_name;
+ gss_OID_desc gm_mech_oid;
+ unsigned gm_flags;
+ _gss_acquire_cred_t *gm_acquire_cred;
+ _gss_release_cred_t *gm_release_cred;
+ _gss_init_sec_context_t *gm_init_sec_context;
+ _gss_accept_sec_context_t *gm_accept_sec_context;
+ _gss_process_context_token_t *gm_process_context_token;
+ _gss_delete_sec_context_t *gm_delete_sec_context;
+ _gss_context_time_t *gm_context_time;
+ _gss_get_mic_t *gm_get_mic;
+ _gss_verify_mic_t *gm_verify_mic;
+ _gss_wrap_t *gm_wrap;
+ _gss_unwrap_t *gm_unwrap;
+ _gss_display_status_t *gm_display_status;
+ _gss_indicate_mechs_t *gm_indicate_mechs;
+ _gss_compare_name_t *gm_compare_name;
+ _gss_display_name_t *gm_display_name;
+ _gss_import_name_t *gm_import_name;
+ _gss_export_name_t *gm_export_name;
+ _gss_release_name_t *gm_release_name;
+ _gss_inquire_cred_t *gm_inquire_cred;
+ _gss_inquire_context_t *gm_inquire_context;
+ _gss_wrap_size_limit_t *gm_wrap_size_limit;
+ _gss_add_cred_t *gm_add_cred;
+ _gss_inquire_cred_by_mech_t *gm_inquire_cred_by_mech;
+ _gss_export_sec_context_t *gm_export_sec_context;
+ _gss_import_sec_context_t *gm_import_sec_context;
+ _gss_inquire_names_for_mech_t *gm_inquire_names_for_mech;
+ _gss_inquire_mechs_for_name_t *gm_inquire_mechs_for_name;
+ _gss_canonicalize_name_t *gm_canonicalize_name;
+ _gss_duplicate_name_t *gm_duplicate_name;
+ _gss_inquire_sec_context_by_oid *gm_inquire_sec_context_by_oid;
+ _gss_inquire_cred_by_oid *gm_inquire_cred_by_oid;
+ _gss_set_sec_context_option *gm_set_sec_context_option;
+ _gss_set_cred_option *gm_set_cred_option;
+ _gss_pseudo_random *gm_pseudo_random;
+ _gss_wrap_iov_t *gm_wrap_iov;
+ _gss_unwrap_iov_t *gm_unwrap_iov;
+ _gss_wrap_iov_length_t *gm_wrap_iov_length;
+ _gss_store_cred_t *gm_store_cred;
+ _gss_export_cred_t *gm_export_cred;
+ _gss_import_cred_t *gm_import_cred;
+ _gss_acquire_cred_ext_t *gm_acquire_cred_ext;
+ _gss_iter_creds_t *gm_iter_creds;
+ _gss_destroy_cred_t *gm_destroy_cred;
+ _gss_cred_hold_t *gm_cred_hold;
+ _gss_cred_unhold_t *gm_cred_unhold;
+ _gss_cred_label_get_t *gm_cred_label_get;
+ _gss_cred_label_set_t *gm_cred_label_set;
+ gss_mo_desc *gm_mo;
+ size_t gm_mo_num;
+ _gss_pname_to_uid_t *gm_pname_to_uid;
+ _gss_authorize_localname_t *gm_authorize_localname;
+ _gss_display_name_ext_t *gm_display_name_ext;
+ _gss_inquire_name_t *gm_inquire_name;
+ _gss_get_name_attribute_t *gm_get_name_attribute;
+ _gss_set_name_attribute_t *gm_set_name_attribute;
+ _gss_delete_name_attribute_t *gm_delete_name_attribute;
+ _gss_export_name_composite_t *gm_export_name_composite;
+ struct gss_mech_compat_desc_struct *gm_compat;
+} gssapi_mech_interface_desc, *gssapi_mech_interface;
+
+gssapi_mech_interface
+__gss_get_mechanism(gss_const_OID /* oid */);
+
+gssapi_mech_interface __gss_spnego_initialize(void);
+gssapi_mech_interface __gss_krb5_initialize(void);
+gssapi_mech_interface __gss_ntlm_initialize(void);
+
+void gss_mg_collect_error(gss_OID, OM_uint32, OM_uint32);
+
+int _gss_mo_get_option_1(gss_const_OID, gss_mo_desc *, gss_buffer_t);
+int _gss_mo_get_option_0(gss_const_OID, gss_mo_desc *, gss_buffer_t);
+int _gss_mo_get_ctx_as_string(gss_const_OID, gss_mo_desc *, gss_buffer_t);
+
+struct _gss_oid_name_table {
+ gss_OID oid;
+ const char *name;
+ const char *short_desc;
+ const char *long_desc;
+};
+
+extern struct _gss_oid_name_table _gss_ont_mech[];
+extern struct _gss_oid_name_table _gss_ont_ma[];
+
+/*
+ * Extended credentials acqusition API, not to be exported until
+ * it or something equivalent has been standardised.
+ */
+extern gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_cred_password_oid_desc;
+#define GSS_C_CRED_PASSWORD (&__gss_c_cred_password_oid_desc)
+
+extern gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_cred_certificate_oid_desc;
+#define GSS_C_CRED_CERTIFICATE (&__gss_c_cred_certificate_oid_desc)
+
+OM_uint32 _gss_acquire_cred_ext
+ (OM_uint32 * /*minor_status*/,
+ const gss_name_t /*desired_name*/,
+ gss_const_OID /*credential_type*/,
+ const void * /*credential_data*/,
+ OM_uint32 /*time_req*/,
+ gss_const_OID /*desired_mech*/,
+ gss_cred_usage_t /*cred_usage*/,
+ gss_cred_id_t * /*output_cred_handle*/
+ );
+
+#endif /* GSSAPI_MECH_H */
diff --git a/crypto/heimdal/lib/gssapi/gsstool.c b/crypto/heimdal/lib/gssapi/gsstool.c
new file mode 100644
index 0000000..5ce3cb0
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/gsstool.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2009 - 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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.
+ */
+
+#include <config.h>
+#include <roken.h>
+
+#include <stdio.h>
+#include <gssapi.h>
+#include <gssapi_krb5.h>
+#include <gssapi_spnego.h>
+#include <gssapi_ntlm.h>
+#include <err.h>
+#include <getarg.h>
+#include <rtbl.h>
+#include <gss-commands.h>
+
+
+static int version_flag = 0;
+static int help_flag = 0;
+
+static struct getargs args[] = {
+ {"version", 0, arg_flag, &version_flag, "print version", NULL },
+ {"help", 0, arg_flag, &help_flag, NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args, sizeof(args)/sizeof(*args),
+ NULL, "service@host");
+ exit (ret);
+}
+
+#define COL_OID "OID"
+#define COL_NAME "Name"
+#define COL_DESC "Description"
+#define COL_VALUE "Value"
+#define COL_MECH "Mech"
+#define COL_EXPIRE "Expire"
+#define COL_SASL "SASL"
+
+int
+supported_mechanisms(void *argptr, int argc, char **argv)
+{
+ OM_uint32 maj_stat, min_stat;
+ gss_OID_set mechs;
+ rtbl_t ct;
+ size_t i;
+
+ maj_stat = gss_indicate_mechs(&min_stat, &mechs);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_indicate_mechs failed");
+
+ printf("Supported mechanisms:\n");
+
+ ct = rtbl_create();
+ if (ct == NULL)
+ errx(1, "rtbl_create");
+
+ rtbl_set_separator(ct, " ");
+ rtbl_add_column(ct, COL_OID, 0);
+ rtbl_add_column(ct, COL_NAME, 0);
+ rtbl_add_column(ct, COL_DESC, 0);
+ rtbl_add_column(ct, COL_SASL, 0);
+
+ for (i = 0; i < mechs->count; i++) {
+ gss_buffer_desc str, sasl_name, mech_name, mech_desc;
+
+ maj_stat = gss_oid_to_str(&min_stat, &mechs->elements[i], &str);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_oid_to_str failed");
+
+ rtbl_add_column_entryv(ct, COL_OID, "%.*s",
+ (int)str.length, (char *)str.value);
+ gss_release_buffer(&min_stat, &str);
+
+ (void)gss_inquire_saslname_for_mech(&min_stat,
+ &mechs->elements[i],
+ &sasl_name,
+ &mech_name,
+ &mech_desc);
+
+ rtbl_add_column_entryv(ct, COL_NAME, "%.*s",
+ (int)mech_name.length, (char *)mech_name.value);
+ rtbl_add_column_entryv(ct, COL_DESC, "%.*s",
+ (int)mech_desc.length, (char *)mech_desc.value);
+ rtbl_add_column_entryv(ct, COL_SASL, "%.*s",
+ (int)sasl_name.length, (char *)sasl_name.value);
+
+ gss_release_buffer(&min_stat, &mech_name);
+ gss_release_buffer(&min_stat, &mech_desc);
+ gss_release_buffer(&min_stat, &sasl_name);
+
+ }
+ gss_release_oid_set(&min_stat, &mechs);
+
+ rtbl_format(ct, stdout);
+ rtbl_destroy(ct);
+
+ return 0;
+}
+
+static void
+print_mech_attr(const char *mechname, gss_const_OID mech, gss_OID_set set)
+{
+ gss_buffer_desc name, desc;
+ OM_uint32 major, minor;
+ rtbl_t ct;
+ size_t n;
+
+ ct = rtbl_create();
+ if (ct == NULL)
+ errx(1, "rtbl_create");
+
+ rtbl_set_separator(ct, " ");
+ rtbl_add_column(ct, COL_OID, 0);
+ rtbl_add_column(ct, COL_DESC, 0);
+ if (mech)
+ rtbl_add_column(ct, COL_VALUE, 0);
+
+ for (n = 0; n < set->count; n++) {
+ major = gss_display_mech_attr(&minor, &set->elements[n], &name, &desc, NULL);
+ if (major)
+ continue;
+
+ rtbl_add_column_entryv(ct, COL_OID, "%.*s",
+ (int)name.length, (char *)name.value);
+ rtbl_add_column_entryv(ct, COL_DESC, "%.*s",
+ (int)desc.length, (char *)desc.value);
+ if (mech) {
+ gss_buffer_desc value;
+
+ if (gss_mo_get(mech, &set->elements[n], &value) != 0)
+ value.length = 0;
+
+ if (value.length)
+ rtbl_add_column_entryv(ct, COL_VALUE, "%.*s",
+ (int)value.length, (char *)value.value);
+ else
+ rtbl_add_column_entryv(ct, COL_VALUE, "<>");
+ gss_release_buffer(&minor, &value);
+ }
+
+ gss_release_buffer(&minor, &name);
+ gss_release_buffer(&minor, &desc);
+ }
+
+ printf("attributes for: %s\n", mechname);
+ rtbl_format(ct, stdout);
+ rtbl_destroy(ct);
+}
+
+
+int
+attrs_for_mech(struct attrs_for_mech_options *opt, int argc, char **argv)
+{
+ gss_OID_set mech_attr = NULL, known_mech_attrs = NULL;
+ gss_OID mech = GSS_C_NO_OID;
+ OM_uint32 major, minor;
+
+ if (opt->mech_string) {
+ mech = gss_name_to_oid(opt->mech_string);
+ if (mech == NULL)
+ errx(1, "mech %s is unknown", opt->mech_string);
+ }
+
+ major = gss_inquire_attrs_for_mech(&minor, mech, &mech_attr, &known_mech_attrs);
+ if (major)
+ errx(1, "gss_inquire_attrs_for_mech");
+
+ if (mech) {
+ print_mech_attr(opt->mech_string, mech, mech_attr);
+ }
+
+ if (opt->all_flag) {
+ print_mech_attr("all mechs", NULL, known_mech_attrs);
+ }
+
+ gss_release_oid_set(&minor, &mech_attr);
+ gss_release_oid_set(&minor, &known_mech_attrs);
+
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+int
+help(void *opt, int argc, char **argv)
+{
+ sl_slc_help(commands, argc, argv);
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int optidx = 0;
+
+ setprogname(argv[0]);
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ if (argc == 0) {
+ help(NULL, argc, argv);
+ return 1;
+ }
+
+ return sl_command (commands, argc, argv);
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/8003.c b/crypto/heimdal/lib/gssapi/krb5/8003.c
new file mode 100644
index 0000000..d4555c5
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/8003.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+krb5_error_code
+_gsskrb5_encode_om_uint32(OM_uint32 n, u_char *p)
+{
+ p[0] = (n >> 0) & 0xFF;
+ p[1] = (n >> 8) & 0xFF;
+ p[2] = (n >> 16) & 0xFF;
+ p[3] = (n >> 24) & 0xFF;
+ return 0;
+}
+
+krb5_error_code
+_gsskrb5_encode_be_om_uint32(OM_uint32 n, u_char *p)
+{
+ p[0] = (n >> 24) & 0xFF;
+ p[1] = (n >> 16) & 0xFF;
+ p[2] = (n >> 8) & 0xFF;
+ p[3] = (n >> 0) & 0xFF;
+ return 0;
+}
+
+krb5_error_code
+_gsskrb5_decode_om_uint32(const void *ptr, OM_uint32 *n)
+{
+ const u_char *p = ptr;
+ *n = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+ return 0;
+}
+
+krb5_error_code
+_gsskrb5_decode_be_om_uint32(const void *ptr, OM_uint32 *n)
+{
+ const u_char *p = ptr;
+ *n = (p[0] <<24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
+ return 0;
+}
+
+static krb5_error_code
+hash_input_chan_bindings (const gss_channel_bindings_t b,
+ u_char *p)
+{
+ u_char num[4];
+ EVP_MD_CTX *ctx;
+
+ ctx = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+
+ _gsskrb5_encode_om_uint32 (b->initiator_addrtype, num);
+ EVP_DigestUpdate(ctx, num, sizeof(num));
+ _gsskrb5_encode_om_uint32 (b->initiator_address.length, num);
+ EVP_DigestUpdate(ctx, num, sizeof(num));
+ if (b->initiator_address.length)
+ EVP_DigestUpdate(ctx,
+ b->initiator_address.value,
+ b->initiator_address.length);
+ _gsskrb5_encode_om_uint32 (b->acceptor_addrtype, num);
+ EVP_DigestUpdate(ctx, num, sizeof(num));
+ _gsskrb5_encode_om_uint32 (b->acceptor_address.length, num);
+ EVP_DigestUpdate(ctx, num, sizeof(num));
+ if (b->acceptor_address.length)
+ EVP_DigestUpdate(ctx,
+ b->acceptor_address.value,
+ b->acceptor_address.length);
+ _gsskrb5_encode_om_uint32 (b->application_data.length, num);
+ EVP_DigestUpdate(ctx, num, sizeof(num));
+ if (b->application_data.length)
+ EVP_DigestUpdate(ctx,
+ b->application_data.value,
+ b->application_data.length);
+ EVP_DigestFinal_ex(ctx, p, NULL);
+ EVP_MD_CTX_destroy(ctx);
+
+ return 0;
+}
+
+/*
+ * create a checksum over the chanel bindings in
+ * `input_chan_bindings', `flags' and `fwd_data' and return it in
+ * `result'
+ */
+
+OM_uint32
+_gsskrb5_create_8003_checksum (
+ OM_uint32 *minor_status,
+ const gss_channel_bindings_t input_chan_bindings,
+ OM_uint32 flags,
+ const krb5_data *fwd_data,
+ Checksum *result)
+{
+ u_char *p;
+
+ /*
+ * see rfc1964 (section 1.1.1 (Initial Token), and the checksum value
+ * field's format) */
+ result->cksumtype = CKSUMTYPE_GSSAPI;
+ if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG))
+ result->checksum.length = 24 + 4 + fwd_data->length;
+ else
+ result->checksum.length = 24;
+ result->checksum.data = malloc (result->checksum.length);
+ if (result->checksum.data == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ p = result->checksum.data;
+ _gsskrb5_encode_om_uint32 (16, p);
+ p += 4;
+ if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS) {
+ memset (p, 0, 16);
+ } else {
+ hash_input_chan_bindings (input_chan_bindings, p);
+ }
+ p += 16;
+ _gsskrb5_encode_om_uint32 (flags, p);
+ p += 4;
+
+ if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG)) {
+
+ *p++ = (1 >> 0) & 0xFF; /* DlgOpt */ /* == 1 */
+ *p++ = (1 >> 8) & 0xFF; /* DlgOpt */ /* == 0 */
+ *p++ = (fwd_data->length >> 0) & 0xFF; /* Dlgth */
+ *p++ = (fwd_data->length >> 8) & 0xFF; /* Dlgth */
+ memcpy(p, (unsigned char *) fwd_data->data, fwd_data->length);
+
+ p += fwd_data->length;
+ }
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * verify the checksum in `cksum' over `input_chan_bindings'
+ * returning `flags' and `fwd_data'
+ */
+
+OM_uint32
+_gsskrb5_verify_8003_checksum(
+ OM_uint32 *minor_status,
+ const gss_channel_bindings_t input_chan_bindings,
+ const Checksum *cksum,
+ OM_uint32 *flags,
+ krb5_data *fwd_data)
+{
+ unsigned char hash[16];
+ unsigned char *p;
+ OM_uint32 length;
+ int DlgOpt;
+ static unsigned char zeros[16];
+
+ /* XXX should handle checksums > 24 bytes */
+ if(cksum->cksumtype != CKSUMTYPE_GSSAPI || cksum->checksum.length < 24) {
+ *minor_status = 0;
+ return GSS_S_BAD_BINDINGS;
+ }
+
+ p = cksum->checksum.data;
+ _gsskrb5_decode_om_uint32(p, &length);
+ if(length != sizeof(hash)) {
+ *minor_status = 0;
+ return GSS_S_BAD_BINDINGS;
+ }
+
+ p += 4;
+
+ if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS
+ && memcmp(p, zeros, sizeof(zeros)) != 0) {
+ if(hash_input_chan_bindings(input_chan_bindings, hash) != 0) {
+ *minor_status = 0;
+ return GSS_S_BAD_BINDINGS;
+ }
+ if(ct_memcmp(hash, p, sizeof(hash)) != 0) {
+ *minor_status = 0;
+ return GSS_S_BAD_BINDINGS;
+ }
+ }
+
+ p += sizeof(hash);
+
+ _gsskrb5_decode_om_uint32(p, flags);
+ p += 4;
+
+ if (cksum->checksum.length > 24 && (*flags & GSS_C_DELEG_FLAG)) {
+ if(cksum->checksum.length < 28) {
+ *minor_status = 0;
+ return GSS_S_BAD_BINDINGS;
+ }
+
+ DlgOpt = (p[0] << 0) | (p[1] << 8);
+ p += 2;
+ if (DlgOpt != 1) {
+ *minor_status = 0;
+ return GSS_S_BAD_BINDINGS;
+ }
+
+ fwd_data->length = (p[0] << 0) | (p[1] << 8);
+ p += 2;
+ if(cksum->checksum.length < 28 + fwd_data->length) {
+ *minor_status = 0;
+ return GSS_S_BAD_BINDINGS;
+ }
+ fwd_data->data = malloc(fwd_data->length);
+ if (fwd_data->data == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy(fwd_data->data, p, fwd_data->length);
+ }
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/accept_sec_context.c b/crypto/heimdal/lib/gssapi/krb5/accept_sec_context.c
new file mode 100644
index 0000000..5a00e12
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/accept_sec_context.c
@@ -0,0 +1,935 @@
+/*
+ * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
+krb5_keytab _gsskrb5_keytab;
+
+static krb5_error_code
+validate_keytab(krb5_context context, const char *name, krb5_keytab *id)
+{
+ krb5_error_code ret;
+
+ ret = krb5_kt_resolve(context, name, id);
+ if (ret)
+ return ret;
+
+ ret = krb5_kt_have_content(context, *id);
+ if (ret) {
+ krb5_kt_close(context, *id);
+ *id = NULL;
+ }
+
+ return ret;
+}
+
+OM_uint32
+_gsskrb5_register_acceptor_identity(OM_uint32 *min_stat, const char *identity)
+{
+ krb5_context context;
+ krb5_error_code ret;
+
+ *min_stat = 0;
+
+ ret = _gsskrb5_init(&context);
+ if(ret)
+ return GSS_S_FAILURE;
+
+ HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
+
+ if(_gsskrb5_keytab != NULL) {
+ krb5_kt_close(context, _gsskrb5_keytab);
+ _gsskrb5_keytab = NULL;
+ }
+ if (identity == NULL) {
+ ret = krb5_kt_default(context, &_gsskrb5_keytab);
+ } else {
+ /*
+ * First check if we can the keytab as is and if it has content...
+ */
+ ret = validate_keytab(context, identity, &_gsskrb5_keytab);
+ /*
+ * if it doesn't, lets prepend FILE: and try again
+ */
+ if (ret) {
+ char *p = NULL;
+ ret = asprintf(&p, "FILE:%s", identity);
+ if(ret < 0 || p == NULL) {
+ HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
+ return GSS_S_FAILURE;
+ }
+ ret = validate_keytab(context, p, &_gsskrb5_keytab);
+ free(p);
+ }
+ }
+ HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
+ if(ret) {
+ *min_stat = ret;
+ return GSS_S_FAILURE;
+ }
+ return GSS_S_COMPLETE;
+}
+
+void
+_gsskrb5i_is_cfx(krb5_context context, gsskrb5_ctx ctx, int acceptor)
+{
+ krb5_error_code ret;
+ krb5_keyblock *key;
+
+ if (acceptor) {
+ if (ctx->auth_context->local_subkey)
+ key = ctx->auth_context->local_subkey;
+ else
+ key = ctx->auth_context->remote_subkey;
+ } else {
+ if (ctx->auth_context->remote_subkey)
+ key = ctx->auth_context->remote_subkey;
+ else
+ key = ctx->auth_context->local_subkey;
+ }
+ if (key == NULL)
+ key = ctx->auth_context->keyblock;
+
+ if (key == NULL)
+ return;
+
+ switch (key->keytype) {
+ case ETYPE_DES_CBC_CRC:
+ case ETYPE_DES_CBC_MD4:
+ case ETYPE_DES_CBC_MD5:
+ case ETYPE_DES3_CBC_MD5:
+ case ETYPE_OLD_DES3_CBC_SHA1:
+ case ETYPE_DES3_CBC_SHA1:
+ case ETYPE_ARCFOUR_HMAC_MD5:
+ case ETYPE_ARCFOUR_HMAC_MD5_56:
+ break;
+ default :
+ ctx->more_flags |= IS_CFX;
+
+ if ((acceptor && ctx->auth_context->local_subkey) ||
+ (!acceptor && ctx->auth_context->remote_subkey))
+ ctx->more_flags |= ACCEPTOR_SUBKEY;
+ break;
+ }
+ if (ctx->crypto)
+ krb5_crypto_destroy(context, ctx->crypto);
+ ret = krb5_crypto_init(context, key, 0, &ctx->crypto);
+}
+
+
+static OM_uint32
+gsskrb5_accept_delegated_token
+(OM_uint32 * minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ gss_cred_id_t * delegated_cred_handle
+ )
+{
+ krb5_ccache ccache = NULL;
+ krb5_error_code kret;
+ int32_t ac_flags, ret = GSS_S_COMPLETE;
+
+ *minor_status = 0;
+
+ /* XXX Create a new delegated_cred_handle? */
+ if (delegated_cred_handle == NULL) {
+ kret = krb5_cc_default (context, &ccache);
+ } else {
+ *delegated_cred_handle = NULL;
+ kret = krb5_cc_new_unique (context, krb5_cc_type_memory,
+ NULL, &ccache);
+ }
+ if (kret) {
+ ctx->flags &= ~GSS_C_DELEG_FLAG;
+ goto out;
+ }
+
+ kret = krb5_cc_initialize(context, ccache, ctx->source);
+ if (kret) {
+ ctx->flags &= ~GSS_C_DELEG_FLAG;
+ goto out;
+ }
+
+ krb5_auth_con_removeflags(context,
+ ctx->auth_context,
+ KRB5_AUTH_CONTEXT_DO_TIME,
+ &ac_flags);
+ kret = krb5_rd_cred2(context,
+ ctx->auth_context,
+ ccache,
+ &ctx->fwd_data);
+ krb5_auth_con_setflags(context,
+ ctx->auth_context,
+ ac_flags);
+ if (kret) {
+ ctx->flags &= ~GSS_C_DELEG_FLAG;
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ goto out;
+ }
+
+ if (delegated_cred_handle) {
+ gsskrb5_cred handle;
+
+ ret = _gsskrb5_krb5_import_cred(minor_status,
+ ccache,
+ NULL,
+ NULL,
+ delegated_cred_handle);
+ if (ret != GSS_S_COMPLETE)
+ goto out;
+
+ handle = (gsskrb5_cred) *delegated_cred_handle;
+
+ handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
+ krb5_cc_close(context, ccache);
+ ccache = NULL;
+ }
+
+out:
+ if (ccache) {
+ /* Don't destroy the default cred cache */
+ if (delegated_cred_handle == NULL)
+ krb5_cc_close(context, ccache);
+ else
+ krb5_cc_destroy(context, ccache);
+ }
+ return ret;
+}
+
+static OM_uint32
+gsskrb5_acceptor_ready(OM_uint32 * minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ gss_cred_id_t *delegated_cred_handle)
+{
+ OM_uint32 ret;
+ int32_t seq_number;
+ int is_cfx = 0;
+
+ krb5_auth_con_getremoteseqnumber (context,
+ ctx->auth_context,
+ &seq_number);
+
+ _gsskrb5i_is_cfx(context, ctx, 1);
+ is_cfx = (ctx->more_flags & IS_CFX);
+
+ ret = _gssapi_msg_order_create(minor_status,
+ &ctx->order,
+ _gssapi_msg_order_f(ctx->flags),
+ seq_number, 0, is_cfx);
+ if (ret)
+ return ret;
+
+ /*
+ * If requested, set local sequence num to remote sequence if this
+ * isn't a mutual authentication context
+ */
+ if (!(ctx->flags & GSS_C_MUTUAL_FLAG) && _gssapi_msg_order_f(ctx->flags)) {
+ krb5_auth_con_setlocalseqnumber(context,
+ ctx->auth_context,
+ seq_number);
+ }
+
+ /*
+ * We should handle the delegation ticket, in case it's there
+ */
+ if (ctx->fwd_data.length > 0 && (ctx->flags & GSS_C_DELEG_FLAG)) {
+ ret = gsskrb5_accept_delegated_token(minor_status,
+ ctx,
+ context,
+ delegated_cred_handle);
+ if (ret)
+ return ret;
+ } else {
+ /* Well, looks like it wasn't there after all */
+ ctx->flags &= ~GSS_C_DELEG_FLAG;
+ }
+
+ ctx->state = ACCEPTOR_READY;
+ ctx->more_flags |= OPEN;
+
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+send_error_token(OM_uint32 *minor_status,
+ krb5_context context,
+ krb5_error_code kret,
+ krb5_principal server,
+ krb5_data *indata,
+ gss_buffer_t output_token)
+{
+ krb5_principal ap_req_server = NULL;
+ krb5_error_code ret;
+ krb5_data outbuf;
+ /* this e_data value encodes KERB_AP_ERR_TYPE_SKEW_RECOVERY which
+ tells windows to try again with the corrected timestamp. See
+ [MS-KILE] 2.2.1 KERB-ERROR-DATA */
+ krb5_data e_data = { 7, rk_UNCONST("\x30\x05\xa1\x03\x02\x01\x02") };
+
+ /* build server from request if the acceptor had not selected one */
+ if (server == NULL) {
+ AP_REQ ap_req;
+
+ ret = krb5_decode_ap_req(context, indata, &ap_req);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ ret = _krb5_principalname2krb5_principal(context,
+ &ap_req_server,
+ ap_req.ticket.sname,
+ ap_req.ticket.realm);
+ free_AP_REQ(&ap_req);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ server = ap_req_server;
+ }
+
+ ret = krb5_mk_error(context, kret, NULL, &e_data, NULL,
+ server, NULL, NULL, &outbuf);
+ if (ap_req_server)
+ krb5_free_principal(context, ap_req_server);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = _gsskrb5_encapsulate(minor_status,
+ &outbuf,
+ output_token,
+ "\x03\x00",
+ GSS_KRB5_MECHANISM);
+ krb5_data_free (&outbuf);
+ if (ret)
+ return ret;
+
+ *minor_status = 0;
+ return GSS_S_CONTINUE_NEEDED;
+}
+
+
+static OM_uint32
+gsskrb5_acceptor_start(OM_uint32 * minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ const gss_channel_bindings_t input_chan_bindings,
+ gss_name_t * src_name,
+ gss_OID * mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec,
+ gss_cred_id_t * delegated_cred_handle)
+{
+ krb5_error_code kret;
+ OM_uint32 ret = GSS_S_COMPLETE;
+ krb5_data indata;
+ krb5_flags ap_options;
+ krb5_keytab keytab = NULL;
+ int is_cfx = 0;
+ const gsskrb5_cred acceptor_cred = (gsskrb5_cred)acceptor_cred_handle;
+
+ /*
+ * We may, or may not, have an escapsulation.
+ */
+ ret = _gsskrb5_decapsulate (minor_status,
+ input_token_buffer,
+ &indata,
+ "\x01\x00",
+ GSS_KRB5_MECHANISM);
+
+ if (ret) {
+ /* Assume that there is no OID wrapping. */
+ indata.length = input_token_buffer->length;
+ indata.data = input_token_buffer->value;
+ }
+
+ /*
+ * We need to get our keytab
+ */
+ if (acceptor_cred == NULL) {
+ if (_gsskrb5_keytab != NULL)
+ keytab = _gsskrb5_keytab;
+ } else if (acceptor_cred->keytab != NULL) {
+ keytab = acceptor_cred->keytab;
+ }
+
+ /*
+ * We need to check the ticket and create the AP-REP packet
+ */
+
+ {
+ krb5_rd_req_in_ctx in = NULL;
+ krb5_rd_req_out_ctx out = NULL;
+ krb5_principal server = NULL;
+
+ if (acceptor_cred)
+ server = acceptor_cred->principal;
+
+ kret = krb5_rd_req_in_ctx_alloc(context, &in);
+ if (kret == 0)
+ kret = krb5_rd_req_in_set_keytab(context, in, keytab);
+ if (kret) {
+ if (in)
+ krb5_rd_req_in_ctx_free(context, in);
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_rd_req_ctx(context,
+ &ctx->auth_context,
+ &indata,
+ server,
+ in, &out);
+ krb5_rd_req_in_ctx_free(context, in);
+ if (kret == KRB5KRB_AP_ERR_SKEW || kret == KRB5KRB_AP_ERR_TKT_NYV) {
+ /*
+ * No reply in non-MUTUAL mode, but we don't know that its
+ * non-MUTUAL mode yet, thats inside the 8003 checksum, so
+ * lets only send the error token on clock skew, that
+ * limit when send error token for non-MUTUAL.
+ */
+ return send_error_token(minor_status, context, kret,
+ server, &indata, output_token);
+ } else if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ /*
+ * we need to remember some data on the context_handle.
+ */
+ kret = krb5_rd_req_out_get_ap_req_options(context, out,
+ &ap_options);
+ if (kret == 0)
+ kret = krb5_rd_req_out_get_ticket(context, out,
+ &ctx->ticket);
+ if (kret == 0)
+ kret = krb5_rd_req_out_get_keyblock(context, out,
+ &ctx->service_keyblock);
+ ctx->lifetime = ctx->ticket->ticket.endtime;
+
+ krb5_rd_req_out_ctx_free(context, out);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ return ret;
+ }
+ }
+
+
+ /*
+ * We need to copy the principal names to the context and the
+ * calling layer.
+ */
+ kret = krb5_copy_principal(context,
+ ctx->ticket->client,
+ &ctx->source);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ }
+
+ kret = krb5_copy_principal(context,
+ ctx->ticket->server,
+ &ctx->target);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ return ret;
+ }
+
+ /*
+ * We need to setup some compat stuff, this assumes that
+ * context_handle->target is already set.
+ */
+ ret = _gss_DES3_get_mic_compat(minor_status, ctx, context);
+ if (ret)
+ return ret;
+
+ if (src_name != NULL) {
+ kret = krb5_copy_principal (context,
+ ctx->ticket->client,
+ (gsskrb5_name*)src_name);
+ if (kret) {
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ return ret;
+ }
+ }
+
+ /*
+ * We need to get the flags out of the 8003 checksum.
+ */
+
+ {
+ krb5_authenticator authenticator;
+
+ kret = krb5_auth_con_getauthenticator(context,
+ ctx->auth_context,
+ &authenticator);
+ if(kret) {
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ return ret;
+ }
+
+ if (authenticator->cksum == NULL) {
+ krb5_free_authenticator(context, &authenticator);
+ *minor_status = 0;
+ return GSS_S_BAD_BINDINGS;
+ }
+
+ if (authenticator->cksum->cksumtype == CKSUMTYPE_GSSAPI) {
+ ret = _gsskrb5_verify_8003_checksum(minor_status,
+ input_chan_bindings,
+ authenticator->cksum,
+ &ctx->flags,
+ &ctx->fwd_data);
+
+ krb5_free_authenticator(context, &authenticator);
+ if (ret) {
+ return ret;
+ }
+ } else {
+ krb5_crypto crypto;
+
+ kret = krb5_crypto_init(context,
+ ctx->auth_context->keyblock,
+ 0, &crypto);
+ if(kret) {
+ krb5_free_authenticator(context, &authenticator);
+
+ ret = GSS_S_FAILURE;
+ *minor_status = kret;
+ return ret;
+ }
+
+ /*
+ * Windows accepts Samba3's use of a kerberos, rather than
+ * GSSAPI checksum here
+ */
+
+ kret = krb5_verify_checksum(context,
+ crypto, KRB5_KU_AP_REQ_AUTH_CKSUM, NULL, 0,
+ authenticator->cksum);
+ krb5_free_authenticator(context, &authenticator);
+ krb5_crypto_destroy(context, crypto);
+
+ if(kret) {
+ ret = GSS_S_BAD_SIG;
+ *minor_status = kret;
+ return ret;
+ }
+
+ /*
+ * Samba style get some flags (but not DCE-STYLE), use
+ * ap_options to guess the mutual flag.
+ */
+ ctx->flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
+ if (ap_options & AP_OPTS_MUTUAL_REQUIRED)
+ ctx->flags |= GSS_C_MUTUAL_FLAG;
+ }
+ }
+
+ if(ctx->flags & GSS_C_MUTUAL_FLAG) {
+ krb5_data outbuf;
+ int use_subkey = 0;
+
+ _gsskrb5i_is_cfx(context, ctx, 1);
+ is_cfx = (ctx->more_flags & IS_CFX);
+
+ if (is_cfx || (ap_options & AP_OPTS_USE_SUBKEY)) {
+ use_subkey = 1;
+ } else {
+ krb5_keyblock *rkey;
+
+ /*
+ * If there is a initiator subkey, copy that to acceptor
+ * subkey to match Windows behavior
+ */
+ kret = krb5_auth_con_getremotesubkey(context,
+ ctx->auth_context,
+ &rkey);
+ if (kret == 0) {
+ kret = krb5_auth_con_setlocalsubkey(context,
+ ctx->auth_context,
+ rkey);
+ if (kret == 0)
+ use_subkey = 1;
+ krb5_free_keyblock(context, rkey);
+ }
+ }
+ if (use_subkey) {
+ ctx->more_flags |= ACCEPTOR_SUBKEY;
+ krb5_auth_con_addflags(context, ctx->auth_context,
+ KRB5_AUTH_CONTEXT_USE_SUBKEY,
+ NULL);
+ }
+
+ kret = krb5_mk_rep(context,
+ ctx->auth_context,
+ &outbuf);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ if (IS_DCE_STYLE(ctx)) {
+ output_token->length = outbuf.length;
+ output_token->value = outbuf.data;
+ } else {
+ ret = _gsskrb5_encapsulate(minor_status,
+ &outbuf,
+ output_token,
+ "\x02\x00",
+ GSS_KRB5_MECHANISM);
+ krb5_data_free (&outbuf);
+ if (ret)
+ return ret;
+ }
+ }
+
+ ctx->flags |= GSS_C_TRANS_FLAG;
+
+ /* Remember the flags */
+
+ ctx->lifetime = ctx->ticket->ticket.endtime;
+ ctx->more_flags |= OPEN;
+
+ if (mech_type)
+ *mech_type = GSS_KRB5_MECHANISM;
+
+ if (time_rec) {
+ ret = _gsskrb5_lifetime_left(minor_status,
+ context,
+ ctx->lifetime,
+ time_rec);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ /*
+ * When GSS_C_DCE_STYLE is in use, we need ask for a AP-REP from
+ * the client.
+ */
+ if (IS_DCE_STYLE(ctx)) {
+ /*
+ * Return flags to caller, but we haven't processed
+ * delgations yet
+ */
+ if (ret_flags)
+ *ret_flags = (ctx->flags & ~GSS_C_DELEG_FLAG);
+
+ ctx->state = ACCEPTOR_WAIT_FOR_DCESTYLE;
+ return GSS_S_CONTINUE_NEEDED;
+ }
+
+ ret = gsskrb5_acceptor_ready(minor_status, ctx, context,
+ delegated_cred_handle);
+
+ if (ret_flags)
+ *ret_flags = ctx->flags;
+
+ return ret;
+}
+
+static OM_uint32
+acceptor_wait_for_dcestyle(OM_uint32 * minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ const gss_channel_bindings_t input_chan_bindings,
+ gss_name_t * src_name,
+ gss_OID * mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec,
+ gss_cred_id_t * delegated_cred_handle)
+{
+ OM_uint32 ret;
+ krb5_error_code kret;
+ krb5_data inbuf;
+ int32_t r_seq_number, l_seq_number;
+
+ /*
+ * We know it's GSS_C_DCE_STYLE so we don't need to decapsulate the AP_REP
+ */
+
+ inbuf.length = input_token_buffer->length;
+ inbuf.data = input_token_buffer->value;
+
+ /*
+ * We need to remeber the old remote seq_number, then check if the
+ * client has replied with our local seq_number, and then reset
+ * the remote seq_number to the old value
+ */
+ {
+ kret = krb5_auth_con_getlocalseqnumber(context,
+ ctx->auth_context,
+ &l_seq_number);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_auth_con_getremoteseqnumber(context,
+ ctx->auth_context,
+ &r_seq_number);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_auth_con_setremoteseqnumber(context,
+ ctx->auth_context,
+ l_seq_number);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ /*
+ * We need to verify the AP_REP, but we need to flag that this is
+ * DCE_STYLE, so don't check the timestamps this time, but put the
+ * flag DO_TIME back afterward.
+ */
+ {
+ krb5_ap_rep_enc_part *repl;
+ int32_t auth_flags;
+
+ krb5_auth_con_removeflags(context,
+ ctx->auth_context,
+ KRB5_AUTH_CONTEXT_DO_TIME,
+ &auth_flags);
+
+ kret = krb5_rd_rep(context, ctx->auth_context, &inbuf, &repl);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ krb5_free_ap_rep_enc_part(context, repl);
+ krb5_auth_con_setflags(context, ctx->auth_context, auth_flags);
+ }
+
+ /* We need to check the liftime */
+ {
+ OM_uint32 lifetime_rec;
+
+ ret = _gsskrb5_lifetime_left(minor_status,
+ context,
+ ctx->lifetime,
+ &lifetime_rec);
+ if (ret) {
+ return ret;
+ }
+ if (lifetime_rec == 0) {
+ return GSS_S_CONTEXT_EXPIRED;
+ }
+
+ if (time_rec) *time_rec = lifetime_rec;
+ }
+
+ /* We need to give the caller the flags which are in use */
+ if (ret_flags) *ret_flags = ctx->flags;
+
+ if (src_name) {
+ kret = krb5_copy_principal(context,
+ ctx->source,
+ (gsskrb5_name*)src_name);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ /*
+ * After the krb5_rd_rep() the remote and local seq_number should
+ * be the same, because the client just replies the seq_number
+ * from our AP-REP in its AP-REP, but then the client uses the
+ * seq_number from its AP-REQ for GSS_wrap()
+ */
+ {
+ int32_t tmp_r_seq_number, tmp_l_seq_number;
+
+ kret = krb5_auth_con_getremoteseqnumber(context,
+ ctx->auth_context,
+ &tmp_r_seq_number);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_auth_con_getlocalseqnumber(context,
+ ctx->auth_context,
+ &tmp_l_seq_number);
+ if (kret) {
+
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ /*
+ * Here we check if the client has responsed with our local seq_number,
+ */
+ if (tmp_r_seq_number != tmp_l_seq_number) {
+ return GSS_S_UNSEQ_TOKEN;
+ }
+ }
+
+ /*
+ * We need to reset the remote seq_number, because the client will use,
+ * the old one for the GSS_wrap() calls
+ */
+ {
+ kret = krb5_auth_con_setremoteseqnumber(context,
+ ctx->auth_context,
+ r_seq_number);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ return gsskrb5_acceptor_ready(minor_status, ctx, context,
+ delegated_cred_handle);
+}
+
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_accept_sec_context(OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ const gss_channel_bindings_t input_chan_bindings,
+ gss_name_t * src_name,
+ gss_OID * mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec,
+ gss_cred_id_t * delegated_cred_handle)
+{
+ krb5_context context;
+ OM_uint32 ret;
+ gsskrb5_ctx ctx;
+
+ GSSAPI_KRB5_INIT(&context);
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ if (src_name != NULL)
+ *src_name = NULL;
+ if (mech_type)
+ *mech_type = GSS_KRB5_MECHANISM;
+
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ ret = _gsskrb5_create_ctx(minor_status,
+ context_handle,
+ context,
+ input_chan_bindings,
+ ACCEPTOR_START);
+ if (ret)
+ return ret;
+ }
+
+ ctx = (gsskrb5_ctx)*context_handle;
+
+
+ /*
+ * TODO: check the channel_bindings
+ * (above just sets them to krb5 layer)
+ */
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ switch (ctx->state) {
+ case ACCEPTOR_START:
+ ret = gsskrb5_acceptor_start(minor_status,
+ ctx,
+ context,
+ acceptor_cred_handle,
+ input_token_buffer,
+ input_chan_bindings,
+ src_name,
+ mech_type,
+ output_token,
+ ret_flags,
+ time_rec,
+ delegated_cred_handle);
+ break;
+ case ACCEPTOR_WAIT_FOR_DCESTYLE:
+ ret = acceptor_wait_for_dcestyle(minor_status,
+ ctx,
+ context,
+ acceptor_cred_handle,
+ input_token_buffer,
+ input_chan_bindings,
+ src_name,
+ mech_type,
+ output_token,
+ ret_flags,
+ time_rec,
+ delegated_cred_handle);
+ break;
+ case ACCEPTOR_READY:
+ /*
+ * If we get there, the caller have called
+ * gss_accept_sec_context() one time too many.
+ */
+ ret = GSS_S_BAD_STATUS;
+ break;
+ default:
+ /* TODO: is this correct here? --metze */
+ ret = GSS_S_BAD_STATUS;
+ break;
+ }
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ if (GSS_ERROR(ret)) {
+ OM_uint32 min2;
+ _gsskrb5_delete_sec_context(&min2, context_handle, GSS_C_NO_BUFFER);
+ }
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/acquire_cred.c b/crypto/heimdal/lib/gssapi/krb5/acquire_cred.c
new file mode 100644
index 0000000..0f1f5f8
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/acquire_cred.c
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32
+__gsskrb5_ccache_lifetime(OM_uint32 *minor_status,
+ krb5_context context,
+ krb5_ccache id,
+ krb5_principal principal,
+ OM_uint32 *lifetime)
+{
+ krb5_creds in_cred, out_cred;
+ krb5_const_realm realm;
+ krb5_error_code kret;
+
+ memset(&in_cred, 0, sizeof(in_cred));
+ in_cred.client = principal;
+
+ realm = krb5_principal_get_realm(context, principal);
+ if (realm == NULL) {
+ _gsskrb5_clear_status ();
+ *minor_status = KRB5_PRINC_NOMATCH; /* XXX */
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_make_principal(context, &in_cred.server,
+ realm, KRB5_TGS_NAME, realm, NULL);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_cc_retrieve_cred(context, id, 0, &in_cred, &out_cred);
+ krb5_free_principal(context, in_cred.server);
+ if (kret) {
+ *minor_status = 0;
+ *lifetime = 0;
+ return GSS_S_COMPLETE;
+ }
+
+ *lifetime = out_cred.times.endtime;
+ krb5_free_cred_contents(context, &out_cred);
+
+ return GSS_S_COMPLETE;
+}
+
+
+
+
+static krb5_error_code
+get_keytab(krb5_context context, krb5_keytab *keytab)
+{
+ krb5_error_code kret;
+
+ HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
+
+ if (_gsskrb5_keytab != NULL) {
+ char *name = NULL;
+
+ kret = krb5_kt_get_full_name(context, _gsskrb5_keytab, &name);
+ if (kret == 0) {
+ kret = krb5_kt_resolve(context, name, keytab);
+ krb5_xfree(name);
+ }
+ } else
+ kret = krb5_kt_default(context, keytab);
+
+ HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
+
+ return (kret);
+}
+
+static OM_uint32 acquire_initiator_cred
+ (OM_uint32 * minor_status,
+ krb5_context context,
+ gss_const_OID credential_type,
+ const void *credential_data,
+ const gss_name_t desired_name,
+ OM_uint32 time_req,
+ gss_const_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ gsskrb5_cred handle
+ )
+{
+ OM_uint32 ret;
+ krb5_creds cred;
+ krb5_principal def_princ;
+ krb5_get_init_creds_opt *opt;
+ krb5_ccache ccache;
+ krb5_keytab keytab;
+ krb5_error_code kret;
+
+ keytab = NULL;
+ ccache = NULL;
+ def_princ = NULL;
+ ret = GSS_S_FAILURE;
+ memset(&cred, 0, sizeof(cred));
+
+ /*
+ * If we have a preferred principal, lets try to find it in all
+ * caches, otherwise, fall back to default cache, ignore all
+ * errors while searching.
+ */
+
+ if (credential_type != GSS_C_NO_OID &&
+ !gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD)) {
+ kret = KRB5_NOCREDS_SUPPLIED; /* XXX */
+ goto end;
+ }
+
+ if (handle->principal) {
+ kret = krb5_cc_cache_match (context,
+ handle->principal,
+ &ccache);
+ if (kret == 0) {
+ ret = GSS_S_COMPLETE;
+ goto found;
+ }
+ }
+
+ if (ccache == NULL) {
+ kret = krb5_cc_default(context, &ccache);
+ if (kret)
+ goto end;
+ }
+ kret = krb5_cc_get_principal(context, ccache, &def_princ);
+ if (kret != 0) {
+ /* we'll try to use a keytab below */
+ krb5_cc_close(context, ccache);
+ def_princ = NULL;
+ kret = 0;
+ } else if (handle->principal == NULL) {
+ kret = krb5_copy_principal(context, def_princ, &handle->principal);
+ if (kret)
+ goto end;
+ } else if (handle->principal != NULL &&
+ krb5_principal_compare(context, handle->principal,
+ def_princ) == FALSE) {
+ krb5_free_principal(context, def_princ);
+ def_princ = NULL;
+ krb5_cc_close(context, ccache);
+ ccache = NULL;
+ }
+ if (def_princ == NULL) {
+ /* We have no existing credentials cache,
+ * so attempt to get a TGT using a keytab.
+ */
+ if (handle->principal == NULL) {
+ kret = krb5_get_default_principal(context, &handle->principal);
+ if (kret)
+ goto end;
+ }
+ kret = krb5_get_init_creds_opt_alloc(context, &opt);
+ if (kret)
+ goto end;
+ if (credential_type != GSS_C_NO_OID &&
+ gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD)) {
+ gss_buffer_t password = (gss_buffer_t)credential_data;
+
+ /* XXX are we requiring password to be NUL terminated? */
+
+ kret = krb5_get_init_creds_password(context, &cred,
+ handle->principal,
+ password->value,
+ NULL, NULL, 0, NULL, opt);
+ } else {
+ kret = get_keytab(context, &keytab);
+ if (kret) {
+ krb5_get_init_creds_opt_free(context, opt);
+ goto end;
+ }
+ kret = krb5_get_init_creds_keytab(context, &cred,
+ handle->principal, keytab,
+ 0, NULL, opt);
+ }
+ krb5_get_init_creds_opt_free(context, opt);
+ if (kret)
+ goto end;
+ kret = krb5_cc_new_unique(context, krb5_cc_type_memory,
+ NULL, &ccache);
+ if (kret)
+ goto end;
+ kret = krb5_cc_initialize(context, ccache, cred.client);
+ if (kret) {
+ krb5_cc_destroy(context, ccache);
+ goto end;
+ }
+ kret = krb5_cc_store_cred(context, ccache, &cred);
+ if (kret) {
+ krb5_cc_destroy(context, ccache);
+ goto end;
+ }
+ handle->lifetime = cred.times.endtime;
+ handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
+ } else {
+
+ ret = __gsskrb5_ccache_lifetime(minor_status,
+ context,
+ ccache,
+ handle->principal,
+ &handle->lifetime);
+ if (ret != GSS_S_COMPLETE) {
+ krb5_cc_close(context, ccache);
+ goto end;
+ }
+ kret = 0;
+ }
+ found:
+ handle->ccache = ccache;
+ ret = GSS_S_COMPLETE;
+
+end:
+ if (cred.client != NULL)
+ krb5_free_cred_contents(context, &cred);
+ if (def_princ != NULL)
+ krb5_free_principal(context, def_princ);
+ if (keytab != NULL)
+ krb5_kt_close(context, keytab);
+ if (ret != GSS_S_COMPLETE && kret != 0)
+ *minor_status = kret;
+ return (ret);
+}
+
+static OM_uint32 acquire_acceptor_cred
+ (OM_uint32 * minor_status,
+ krb5_context context,
+ gss_const_OID credential_type,
+ const void *credential_data,
+ const gss_name_t desired_name,
+ OM_uint32 time_req,
+ gss_const_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ gsskrb5_cred handle
+ )
+{
+ OM_uint32 ret;
+ krb5_error_code kret;
+
+ ret = GSS_S_FAILURE;
+
+ if (credential_type != GSS_C_NO_OID) {
+ kret = EINVAL;
+ goto end;
+ }
+
+ kret = get_keytab(context, &handle->keytab);
+ if (kret)
+ goto end;
+
+ /* check that the requested principal exists in the keytab */
+ if (handle->principal) {
+ krb5_keytab_entry entry;
+
+ kret = krb5_kt_get_entry(context, handle->keytab,
+ handle->principal, 0, 0, &entry);
+ if (kret)
+ goto end;
+ krb5_kt_free_entry(context, &entry);
+ ret = GSS_S_COMPLETE;
+ } else {
+ /*
+ * Check if there is at least one entry in the keytab before
+ * declaring it as an useful keytab.
+ */
+ krb5_keytab_entry tmp;
+ krb5_kt_cursor c;
+
+ kret = krb5_kt_start_seq_get (context, handle->keytab, &c);
+ if (kret)
+ goto end;
+ if (krb5_kt_next_entry(context, handle->keytab, &tmp, &c) == 0) {
+ krb5_kt_free_entry(context, &tmp);
+ ret = GSS_S_COMPLETE; /* ok found one entry */
+ }
+ krb5_kt_end_seq_get (context, handle->keytab, &c);
+ }
+end:
+ if (ret != GSS_S_COMPLETE) {
+ if (handle->keytab != NULL)
+ krb5_kt_close(context, handle->keytab);
+ if (kret != 0) {
+ *minor_status = kret;
+ }
+ }
+ return (ret);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred
+(OM_uint32 * minor_status,
+ const gss_name_t desired_name,
+ OM_uint32 time_req,
+ const gss_OID_set desired_mechs,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t * output_cred_handle,
+ gss_OID_set * actual_mechs,
+ OM_uint32 * time_rec
+ )
+{
+ OM_uint32 ret;
+
+ if (desired_mechs) {
+ int present = 0;
+
+ ret = gss_test_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ desired_mechs, &present);
+ if (ret)
+ return ret;
+ if (!present) {
+ *minor_status = 0;
+ return GSS_S_BAD_MECH;
+ }
+ }
+
+ ret = _gsskrb5_acquire_cred_ext(minor_status,
+ desired_name,
+ GSS_C_NO_OID,
+ NULL,
+ time_req,
+ GSS_KRB5_MECHANISM,
+ cred_usage,
+ output_cred_handle);
+ if (ret)
+ return ret;
+
+
+ ret = _gsskrb5_inquire_cred(minor_status, *output_cred_handle,
+ NULL, time_rec, NULL, actual_mechs);
+ if (ret) {
+ OM_uint32 tmp;
+ _gsskrb5_release_cred(&tmp, output_cred_handle);
+ }
+
+ return ret;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred_ext
+(OM_uint32 * minor_status,
+ const gss_name_t desired_name,
+ gss_const_OID credential_type,
+ const void *credential_data,
+ OM_uint32 time_req,
+ gss_const_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t * output_cred_handle
+ )
+{
+ krb5_context context;
+ gsskrb5_cred handle;
+ OM_uint32 ret;
+
+ cred_usage &= GSS_C_OPTION_MASK;
+
+ if (cred_usage != GSS_C_ACCEPT && cred_usage != GSS_C_INITIATE && cred_usage != GSS_C_BOTH) {
+ *minor_status = GSS_KRB5_S_G_BAD_USAGE;
+ return GSS_S_FAILURE;
+ }
+
+ GSSAPI_KRB5_INIT(&context);
+
+ *output_cred_handle = NULL;
+
+ handle = calloc(1, sizeof(*handle));
+ if (handle == NULL) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+
+ HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
+
+ if (desired_name != GSS_C_NO_NAME) {
+ ret = _gsskrb5_canon_name(minor_status, context, 1, NULL,
+ desired_name, &handle->principal);
+ if (ret) {
+ HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ free(handle);
+ return ret;
+ }
+ }
+ if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) {
+ ret = acquire_initiator_cred(minor_status, context,
+ credential_type, credential_data,
+ desired_name, time_req,
+ desired_mech, cred_usage, handle);
+ if (ret != GSS_S_COMPLETE) {
+ HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ krb5_free_principal(context, handle->principal);
+ free(handle);
+ return (ret);
+ }
+ }
+ if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) {
+ ret = acquire_acceptor_cred(minor_status, context,
+ credential_type, credential_data,
+ desired_name, time_req,
+ desired_mech, cred_usage, handle);
+ if (ret != GSS_S_COMPLETE) {
+ HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ krb5_free_principal(context, handle->principal);
+ free(handle);
+ return (ret);
+ }
+ }
+ ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
+ if (ret == GSS_S_COMPLETE)
+ ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &handle->mechanisms);
+ if (ret != GSS_S_COMPLETE) {
+ if (handle->mechanisms != NULL)
+ gss_release_oid_set(NULL, &handle->mechanisms);
+ HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ krb5_free_principal(context, handle->principal);
+ free(handle);
+ return (ret);
+ }
+ handle->usage = cred_usage;
+ *minor_status = 0;
+ *output_cred_handle = (gss_cred_id_t)handle;
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/add_cred.c b/crypto/heimdal/lib/gssapi/krb5/add_cred.c
new file mode 100644
index 0000000..00cf55f
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/add_cred.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred (
+ OM_uint32 *minor_status,
+ const gss_cred_id_t input_cred_handle,
+ const gss_name_t desired_name,
+ const gss_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ OM_uint32 initiator_time_req,
+ OM_uint32 acceptor_time_req,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *initiator_time_rec,
+ OM_uint32 *acceptor_time_rec)
+{
+ krb5_context context;
+ OM_uint32 ret, lifetime;
+ gsskrb5_cred cred, handle;
+ krb5_const_principal dname;
+
+ handle = NULL;
+ cred = (gsskrb5_cred)input_cred_handle;
+ dname = (krb5_const_principal)desired_name;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0) {
+ *minor_status = 0;
+ return GSS_S_BAD_MECH;
+ }
+
+ if (cred == NULL && output_cred_handle == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ if (cred == NULL) { /* XXX standard conformance failure */
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ /* check if requested output usage is compatible with output usage */
+ if (output_cred_handle != NULL) {
+ HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
+ if (cred->usage != cred_usage && cred->usage != GSS_C_BOTH) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = GSS_KRB5_S_G_BAD_USAGE;
+ return(GSS_S_FAILURE);
+ }
+ }
+
+ /* check that we have the same name */
+ if (dname != NULL &&
+ krb5_principal_compare(context, dname,
+ cred->principal) != FALSE) {
+ if (output_cred_handle)
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = 0;
+ return GSS_S_BAD_NAME;
+ }
+
+ /* make a copy */
+ if (output_cred_handle) {
+ krb5_error_code kret;
+
+ handle = calloc(1, sizeof(*handle));
+ if (handle == NULL) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+
+ handle->usage = cred_usage;
+ handle->lifetime = cred->lifetime;
+ handle->principal = NULL;
+ handle->keytab = NULL;
+ handle->ccache = NULL;
+ handle->mechanisms = NULL;
+ HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
+
+ ret = GSS_S_FAILURE;
+
+ kret = krb5_copy_principal(context, cred->principal,
+ &handle->principal);
+ if (kret) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ free(handle);
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ if (cred->keytab) {
+ char *name = NULL;
+
+ ret = GSS_S_FAILURE;
+
+ kret = krb5_kt_get_full_name(context, cred->keytab, &name);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ kret = krb5_kt_resolve(context, name,
+ &handle->keytab);
+ krb5_xfree(name);
+ if (kret){
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+
+ if (cred->ccache) {
+ const char *type, *name;
+ char *type_name = NULL;
+
+ ret = GSS_S_FAILURE;
+
+ type = krb5_cc_get_type(context, cred->ccache);
+ if (type == NULL){
+ *minor_status = ENOMEM;
+ goto failure;
+ }
+
+ if (strcmp(type, "MEMORY") == 0) {
+ ret = krb5_cc_new_unique(context, type,
+ NULL, &handle->ccache);
+ if (ret) {
+ *minor_status = ret;
+ goto failure;
+ }
+
+ ret = krb5_cc_copy_cache(context, cred->ccache,
+ handle->ccache);
+ if (ret) {
+ *minor_status = ret;
+ goto failure;
+ }
+
+ } else {
+ name = krb5_cc_get_name(context, cred->ccache);
+ if (name == NULL) {
+ *minor_status = ENOMEM;
+ goto failure;
+ }
+
+ kret = asprintf(&type_name, "%s:%s", type, name);
+ if (kret < 0 || type_name == NULL) {
+ *minor_status = ENOMEM;
+ goto failure;
+ }
+
+ kret = krb5_cc_resolve(context, type_name,
+ &handle->ccache);
+ free(type_name);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+ }
+ ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
+ if (ret)
+ goto failure;
+
+ ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &handle->mechanisms);
+ if (ret)
+ goto failure;
+ }
+
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+
+ ret = _gsskrb5_inquire_cred(minor_status, (gss_cred_id_t)cred,
+ NULL, &lifetime, NULL, actual_mechs);
+ if (ret)
+ goto failure;
+
+ if (initiator_time_rec)
+ *initiator_time_rec = lifetime;
+ if (acceptor_time_rec)
+ *acceptor_time_rec = lifetime;
+
+ if (output_cred_handle) {
+ *output_cred_handle = (gss_cred_id_t)handle;
+ }
+
+ *minor_status = 0;
+ return ret;
+
+ failure:
+
+ if (handle) {
+ if (handle->principal)
+ krb5_free_principal(context, handle->principal);
+ if (handle->keytab)
+ krb5_kt_close(context, handle->keytab);
+ if (handle->ccache)
+ krb5_cc_destroy(context, handle->ccache);
+ if (handle->mechanisms)
+ gss_release_oid_set(NULL, &handle->mechanisms);
+ free(handle);
+ }
+ if (output_cred_handle)
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/address_to_krb5addr.c b/crypto/heimdal/lib/gssapi/krb5/address_to_krb5addr.c
new file mode 100644
index 0000000..fa115d9
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/address_to_krb5addr.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+#include <roken.h>
+
+krb5_error_code
+_gsskrb5i_address_to_krb5addr(krb5_context context,
+ OM_uint32 gss_addr_type,
+ gss_buffer_desc *gss_addr,
+ int16_t port,
+ krb5_address *address)
+{
+ int addr_type;
+ struct sockaddr sa;
+ krb5_socklen_t sa_size = sizeof(sa);
+ krb5_error_code problem;
+
+ if (gss_addr == NULL)
+ return GSS_S_FAILURE;
+
+ switch (gss_addr_type) {
+#ifdef HAVE_IPV6
+ case GSS_C_AF_INET6: addr_type = AF_INET6;
+ break;
+#endif /* HAVE_IPV6 */
+
+ case GSS_C_AF_INET: addr_type = AF_INET;
+ break;
+ default:
+ return GSS_S_FAILURE;
+ }
+
+ problem = krb5_h_addr2sockaddr (context,
+ addr_type,
+ gss_addr->value,
+ &sa,
+ &sa_size,
+ port);
+ if (problem)
+ return GSS_S_FAILURE;
+
+ problem = krb5_sockaddr2address (context, &sa, address);
+
+ return problem;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/aeap.c b/crypto/heimdal/lib/gssapi/krb5/aeap.c
new file mode 100644
index 0000000..e2f1b37
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/aeap.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+#include <roken.h>
+
+#if 0
+OM_uint32 GSSAPI_CALLCONV
+_gk_wrap_iov(OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int * conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+ krb5_context context;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_wrap_cfx_iov(minor_status, ctx, context,
+ conf_req_flag, conf_state,
+ iov, iov_count);
+
+ return GSS_S_FAILURE;
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gk_unwrap_iov(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int *conf_state,
+ gss_qop_t *qop_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+ krb5_context context;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_unwrap_cfx_iov(minor_status, ctx, context,
+ conf_state, qop_state, iov, iov_count);
+
+ return GSS_S_FAILURE;
+}
+#endif
+
+OM_uint32 GSSAPI_CALLCONV
+_gk_wrap_iov_length(OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+ krb5_context context;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_wrap_iov_length_cfx(minor_status, ctx, context,
+ conf_req_flag, qop_req, conf_state,
+ iov, iov_count);
+
+ return GSS_S_FAILURE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/arcfour.c b/crypto/heimdal/lib/gssapi/krb5/arcfour.c
new file mode 100644
index 0000000..15b1b34
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/arcfour.c
@@ -0,0 +1,762 @@
+/*
+ * Copyright (c) 2003 - 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+/*
+ * Implements draft-brezak-win2k-krb-rc4-hmac-04.txt
+ *
+ * The arcfour message have the following formats:
+ *
+ * MIC token
+ * TOK_ID[2] = 01 01
+ * SGN_ALG[2] = 11 00
+ * Filler[4]
+ * SND_SEQ[8]
+ * SGN_CKSUM[8]
+ *
+ * WRAP token
+ * TOK_ID[2] = 02 01
+ * SGN_ALG[2];
+ * SEAL_ALG[2]
+ * Filler[2]
+ * SND_SEQ[2]
+ * SGN_CKSUM[8]
+ * Confounder[8]
+ */
+
+/*
+ * WRAP in DCE-style have a fixed size header, the oid and length over
+ * the WRAP header is a total of
+ * GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE +
+ * GSS_ARCFOUR_WRAP_TOKEN_SIZE byte (ie total of 45 bytes overhead,
+ * remember the 2 bytes from APPL [0] SEQ).
+ */
+
+#define GSS_ARCFOUR_WRAP_TOKEN_SIZE 32
+#define GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE 13
+
+
+static krb5_error_code
+arcfour_mic_key(krb5_context context, krb5_keyblock *key,
+ void *cksum_data, size_t cksum_size,
+ void *key6_data, size_t key6_size)
+{
+ krb5_error_code ret;
+
+ Checksum cksum_k5;
+ krb5_keyblock key5;
+ char k5_data[16];
+
+ Checksum cksum_k6;
+
+ char T[4];
+
+ memset(T, 0, 4);
+ cksum_k5.checksum.data = k5_data;
+ cksum_k5.checksum.length = sizeof(k5_data);
+
+ if (key->keytype == ENCTYPE_ARCFOUR_HMAC_MD5_56) {
+ char L40[14] = "fortybits";
+
+ memcpy(L40 + 10, T, sizeof(T));
+ ret = krb5_hmac(context, CKSUMTYPE_RSA_MD5,
+ L40, 14, 0, key, &cksum_k5);
+ memset(&k5_data[7], 0xAB, 9);
+ } else {
+ ret = krb5_hmac(context, CKSUMTYPE_RSA_MD5,
+ T, 4, 0, key, &cksum_k5);
+ }
+ if (ret)
+ return ret;
+
+ key5.keytype = ENCTYPE_ARCFOUR_HMAC_MD5;
+ key5.keyvalue = cksum_k5.checksum;
+
+ cksum_k6.checksum.data = key6_data;
+ cksum_k6.checksum.length = key6_size;
+
+ return krb5_hmac(context, CKSUMTYPE_RSA_MD5,
+ cksum_data, cksum_size, 0, &key5, &cksum_k6);
+}
+
+
+static krb5_error_code
+arcfour_mic_cksum(krb5_context context,
+ krb5_keyblock *key, unsigned usage,
+ u_char *sgn_cksum, size_t sgn_cksum_sz,
+ const u_char *v1, size_t l1,
+ const void *v2, size_t l2,
+ const void *v3, size_t l3)
+{
+ Checksum CKSUM;
+ u_char *ptr;
+ size_t len;
+ krb5_crypto crypto;
+ krb5_error_code ret;
+
+ assert(sgn_cksum_sz == 8);
+
+ len = l1 + l2 + l3;
+
+ ptr = malloc(len);
+ if (ptr == NULL)
+ return ENOMEM;
+
+ memcpy(ptr, v1, l1);
+ memcpy(ptr + l1, v2, l2);
+ memcpy(ptr + l1 + l2, v3, l3);
+
+ ret = krb5_crypto_init(context, key, 0, &crypto);
+ if (ret) {
+ free(ptr);
+ return ret;
+ }
+
+ ret = krb5_create_checksum(context,
+ crypto,
+ usage,
+ 0,
+ ptr, len,
+ &CKSUM);
+ free(ptr);
+ if (ret == 0) {
+ memcpy(sgn_cksum, CKSUM.checksum.data, sgn_cksum_sz);
+ free_Checksum(&CKSUM);
+ }
+ krb5_crypto_destroy(context, crypto);
+
+ return ret;
+}
+
+
+OM_uint32
+_gssapi_get_mic_arcfour(OM_uint32 * minor_status,
+ const gsskrb5_ctx context_handle,
+ krb5_context context,
+ gss_qop_t qop_req,
+ const gss_buffer_t message_buffer,
+ gss_buffer_t message_token,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ int32_t seq_number;
+ size_t len, total_len;
+ u_char k6_data[16], *p0, *p;
+ EVP_CIPHER_CTX rc4_key;
+
+ _gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
+
+ message_token->length = total_len;
+ message_token->value = malloc (total_len);
+ if (message_token->value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ p0 = _gssapi_make_mech_header(message_token->value,
+ len,
+ GSS_KRB5_MECHANISM);
+ p = p0;
+
+ *p++ = 0x01; /* TOK_ID */
+ *p++ = 0x01;
+ *p++ = 0x11; /* SGN_ALG */
+ *p++ = 0x00;
+ *p++ = 0xff; /* Filler */
+ *p++ = 0xff;
+ *p++ = 0xff;
+ *p++ = 0xff;
+
+ p = NULL;
+
+ ret = arcfour_mic_cksum(context,
+ key, KRB5_KU_USAGE_SIGN,
+ p0 + 16, 8, /* SGN_CKSUM */
+ p0, 8, /* TOK_ID, SGN_ALG, Filer */
+ message_buffer->value, message_buffer->length,
+ NULL, 0);
+ if (ret) {
+ _gsskrb5_release_buffer(minor_status, message_token);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = arcfour_mic_key(context, key,
+ p0 + 16, 8, /* SGN_CKSUM */
+ k6_data, sizeof(k6_data));
+ if (ret) {
+ _gsskrb5_release_buffer(minor_status, message_token);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ krb5_auth_con_getlocalseqnumber (context,
+ context_handle->auth_context,
+ &seq_number);
+ p = p0 + 8; /* SND_SEQ */
+ _gsskrb5_encode_be_om_uint32(seq_number, p);
+
+ krb5_auth_con_setlocalseqnumber (context,
+ context_handle->auth_context,
+ ++seq_number);
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+
+ memset (p + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4);
+
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+ EVP_Cipher(&rc4_key, p, p, 8);
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
+
+ memset(k6_data, 0, sizeof(k6_data));
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+
+OM_uint32
+_gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
+ const gsskrb5_ctx context_handle,
+ krb5_context context,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t * qop_state,
+ krb5_keyblock *key,
+ const char *type)
+{
+ krb5_error_code ret;
+ uint32_t seq_number;
+ OM_uint32 omret;
+ u_char SND_SEQ[8], cksum_data[8], *p;
+ char k6_data[16];
+ int cmp;
+
+ if (qop_state)
+ *qop_state = 0;
+
+ p = token_buffer->value;
+ omret = _gsskrb5_verify_header (&p,
+ token_buffer->length,
+ type,
+ GSS_KRB5_MECHANISM);
+ if (omret)
+ return omret;
+
+ if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */
+ return GSS_S_BAD_SIG;
+ p += 2;
+ if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
+ return GSS_S_BAD_MIC;
+ p += 4;
+
+ ret = arcfour_mic_cksum(context,
+ key, KRB5_KU_USAGE_SIGN,
+ cksum_data, sizeof(cksum_data),
+ p - 8, 8,
+ message_buffer->value, message_buffer->length,
+ NULL, 0);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = arcfour_mic_key(context, key,
+ cksum_data, sizeof(cksum_data),
+ k6_data, sizeof(k6_data));
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ cmp = ct_memcmp(cksum_data, p + 8, 8);
+ if (cmp) {
+ *minor_status = 0;
+ return GSS_S_BAD_MIC;
+ }
+
+ {
+ EVP_CIPHER_CTX rc4_key;
+
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 0);
+ EVP_Cipher(&rc4_key, SND_SEQ, p, 8);
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
+
+ memset(k6_data, 0, sizeof(k6_data));
+ }
+
+ _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number);
+
+ if (context_handle->more_flags & LOCAL)
+ cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
+ else
+ cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);
+
+ memset(SND_SEQ, 0, sizeof(SND_SEQ));
+ if (cmp != 0) {
+ *minor_status = 0;
+ return GSS_S_BAD_MIC;
+ }
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ omret = _gssapi_msg_order_check(context_handle->order, seq_number);
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ if (omret)
+ return omret;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+_gssapi_wrap_arcfour(OM_uint32 * minor_status,
+ const gsskrb5_ctx context_handle,
+ krb5_context context,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ const gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_message_buffer,
+ krb5_keyblock *key)
+{
+ u_char Klocaldata[16], k6_data[16], *p, *p0;
+ size_t len, total_len, datalen;
+ krb5_keyblock Klocal;
+ krb5_error_code ret;
+ int32_t seq_number;
+
+ if (conf_state)
+ *conf_state = 0;
+
+ datalen = input_message_buffer->length;
+
+ if (IS_DCE_STYLE(context_handle)) {
+ len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+ total_len += datalen;
+ } else {
+ datalen += 1; /* padding */
+ len = datalen + GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+ }
+
+ output_message_buffer->length = total_len;
+ output_message_buffer->value = malloc (total_len);
+ if (output_message_buffer->value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ p0 = _gssapi_make_mech_header(output_message_buffer->value,
+ len,
+ GSS_KRB5_MECHANISM);
+ p = p0;
+
+ *p++ = 0x02; /* TOK_ID */
+ *p++ = 0x01;
+ *p++ = 0x11; /* SGN_ALG */
+ *p++ = 0x00;
+ if (conf_req_flag) {
+ *p++ = 0x10; /* SEAL_ALG */
+ *p++ = 0x00;
+ } else {
+ *p++ = 0xff; /* SEAL_ALG */
+ *p++ = 0xff;
+ }
+ *p++ = 0xff; /* Filler */
+ *p++ = 0xff;
+
+ p = NULL;
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ krb5_auth_con_getlocalseqnumber (context,
+ context_handle->auth_context,
+ &seq_number);
+
+ _gsskrb5_encode_be_om_uint32(seq_number, p0 + 8);
+
+ krb5_auth_con_setlocalseqnumber (context,
+ context_handle->auth_context,
+ ++seq_number);
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+
+ memset (p0 + 8 + 4,
+ (context_handle->more_flags & LOCAL) ? 0 : 0xff,
+ 4);
+
+ krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */
+
+ /* p points to data */
+ p = p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ memcpy(p, input_message_buffer->value, input_message_buffer->length);
+
+ if (!IS_DCE_STYLE(context_handle))
+ p[input_message_buffer->length] = 1; /* padding */
+
+ ret = arcfour_mic_cksum(context,
+ key, KRB5_KU_USAGE_SEAL,
+ p0 + 16, 8, /* SGN_CKSUM */
+ p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */
+ p0 + 24, 8, /* Confounder */
+ p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,
+ datalen);
+ if (ret) {
+ *minor_status = ret;
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ return GSS_S_FAILURE;
+ }
+
+ {
+ int i;
+
+ Klocal.keytype = key->keytype;
+ Klocal.keyvalue.data = Klocaldata;
+ Klocal.keyvalue.length = sizeof(Klocaldata);
+
+ for (i = 0; i < 16; i++)
+ Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;
+ }
+ ret = arcfour_mic_key(context, &Klocal,
+ p0 + 8, 4, /* SND_SEQ */
+ k6_data, sizeof(k6_data));
+ memset(Klocaldata, 0, sizeof(Klocaldata));
+ if (ret) {
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+
+ if(conf_req_flag) {
+ EVP_CIPHER_CTX rc4_key;
+
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+ EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8 + datalen);
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
+ }
+ memset(k6_data, 0, sizeof(k6_data));
+
+ ret = arcfour_mic_key(context, key,
+ p0 + 16, 8, /* SGN_CKSUM */
+ k6_data, sizeof(k6_data));
+ if (ret) {
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ {
+ EVP_CIPHER_CTX rc4_key;
+
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+ EVP_Cipher(&rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8);
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
+ memset(k6_data, 0, sizeof(k6_data));
+ }
+
+ if (conf_state)
+ *conf_state = conf_req_flag;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
+ const gsskrb5_ctx context_handle,
+ krb5_context context,
+ const gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int *conf_state,
+ gss_qop_t *qop_state,
+ krb5_keyblock *key)
+{
+ u_char Klocaldata[16];
+ krb5_keyblock Klocal;
+ krb5_error_code ret;
+ uint32_t seq_number;
+ size_t datalen;
+ OM_uint32 omret;
+ u_char k6_data[16], SND_SEQ[8], Confounder[8];
+ u_char cksum_data[8];
+ u_char *p, *p0;
+ int cmp;
+ int conf_flag;
+ size_t padlen = 0, len;
+
+ if (conf_state)
+ *conf_state = 0;
+ if (qop_state)
+ *qop_state = 0;
+
+ p0 = input_message_buffer->value;
+
+ if (IS_DCE_STYLE(context_handle)) {
+ len = GSS_ARCFOUR_WRAP_TOKEN_SIZE +
+ GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE;
+ if (input_message_buffer->length < len)
+ return GSS_S_BAD_MECH;
+ } else {
+ len = input_message_buffer->length;
+ }
+
+ omret = _gssapi_verify_mech_header(&p0,
+ len,
+ GSS_KRB5_MECHANISM);
+ if (omret)
+ return omret;
+
+ /* length of mech header */
+ len = (p0 - (u_char *)input_message_buffer->value) +
+ GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+
+ if (len > input_message_buffer->length)
+ return GSS_S_BAD_MECH;
+
+ /* length of data */
+ datalen = input_message_buffer->length - len;
+
+ p = p0;
+
+ if (memcmp(p, "\x02\x01", 2) != 0)
+ return GSS_S_BAD_SIG;
+ p += 2;
+ if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */
+ return GSS_S_BAD_SIG;
+ p += 2;
+
+ if (memcmp (p, "\x10\x00", 2) == 0)
+ conf_flag = 1;
+ else if (memcmp (p, "\xff\xff", 2) == 0)
+ conf_flag = 0;
+ else
+ return GSS_S_BAD_SIG;
+
+ p += 2;
+ if (memcmp (p, "\xff\xff", 2) != 0)
+ return GSS_S_BAD_MIC;
+ p = NULL;
+
+ ret = arcfour_mic_key(context, key,
+ p0 + 16, 8, /* SGN_CKSUM */
+ k6_data, sizeof(k6_data));
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ {
+ EVP_CIPHER_CTX rc4_key;
+
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+ EVP_Cipher(&rc4_key, SND_SEQ, p0 + 8, 8);
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
+ memset(k6_data, 0, sizeof(k6_data));
+ }
+
+ _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number);
+
+ if (context_handle->more_flags & LOCAL)
+ cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
+ else
+ cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);
+
+ if (cmp != 0) {
+ *minor_status = 0;
+ return GSS_S_BAD_MIC;
+ }
+
+ {
+ int i;
+
+ Klocal.keytype = key->keytype;
+ Klocal.keyvalue.data = Klocaldata;
+ Klocal.keyvalue.length = sizeof(Klocaldata);
+
+ for (i = 0; i < 16; i++)
+ Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;
+ }
+ ret = arcfour_mic_key(context, &Klocal,
+ SND_SEQ, 4,
+ k6_data, sizeof(k6_data));
+ memset(Klocaldata, 0, sizeof(Klocaldata));
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ output_message_buffer->value = malloc(datalen);
+ if (output_message_buffer->value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ output_message_buffer->length = datalen;
+
+ if(conf_flag) {
+ EVP_CIPHER_CTX rc4_key;
+
+ EVP_CIPHER_CTX_init(&rc4_key);
+ EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
+ EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8);
+ EVP_Cipher(&rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen);
+ EVP_CIPHER_CTX_cleanup(&rc4_key);
+ } else {
+ memcpy(Confounder, p0 + 24, 8); /* Confounder */
+ memcpy(output_message_buffer->value,
+ p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,
+ datalen);
+ }
+ memset(k6_data, 0, sizeof(k6_data));
+
+ if (!IS_DCE_STYLE(context_handle)) {
+ ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen);
+ if (ret) {
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ *minor_status = 0;
+ return ret;
+ }
+ output_message_buffer->length -= padlen;
+ }
+
+ ret = arcfour_mic_cksum(context,
+ key, KRB5_KU_USAGE_SEAL,
+ cksum_data, sizeof(cksum_data),
+ p0, 8,
+ Confounder, sizeof(Confounder),
+ output_message_buffer->value,
+ output_message_buffer->length + padlen);
+ if (ret) {
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ cmp = ct_memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */
+ if (cmp) {
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ *minor_status = 0;
+ return GSS_S_BAD_MIC;
+ }
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ omret = _gssapi_msg_order_check(context_handle->order, seq_number);
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ if (omret)
+ return omret;
+
+ if (conf_state)
+ *conf_state = conf_flag;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+max_wrap_length_arcfour(const gsskrb5_ctx ctx,
+ krb5_crypto crypto,
+ size_t input_length,
+ OM_uint32 *max_input_size)
+{
+ /*
+ * if GSS_C_DCE_STYLE is in use:
+ * - we only need to encapsulate the WRAP token
+ * However, since this is a fixed since, we just
+ */
+ if (IS_DCE_STYLE(ctx)) {
+ size_t len, total_len;
+
+ len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+
+ if (input_length < len)
+ *max_input_size = 0;
+ else
+ *max_input_size = input_length - len;
+
+ } else {
+ size_t extrasize = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
+ size_t blocksize = 8;
+ size_t len, total_len;
+
+ len = 8 + input_length + blocksize + extrasize;
+
+ _gsskrb5_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+
+ total_len -= input_length; /* token length */
+ if (total_len < input_length) {
+ *max_input_size = (input_length - total_len);
+ (*max_input_size) &= (~(OM_uint32)(blocksize - 1));
+ } else {
+ *max_input_size = 0;
+ }
+ }
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+_gssapi_wrap_size_arcfour(OM_uint32 *minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 *max_input_size,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ krb5_crypto crypto;
+
+ ret = krb5_crypto_init(context, key, 0, &crypto);
+ if (ret != 0) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = max_wrap_length_arcfour(ctx, crypto,
+ req_output_size, max_input_size);
+ if (ret != 0) {
+ *minor_status = ret;
+ krb5_crypto_destroy(context, crypto);
+ return GSS_S_FAILURE;
+ }
+
+ krb5_crypto_destroy(context, crypto);
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/authorize_localname.c b/crypto/heimdal/lib/gssapi/krb5/authorize_localname.c
new file mode 100644
index 0000000..4bab062
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/authorize_localname.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_authorize_localname(OM_uint32 *minor_status,
+ const gss_name_t input_name,
+ gss_const_buffer_t user_name,
+ gss_const_OID user_name_type)
+{
+ krb5_context context;
+ krb5_principal princ = (krb5_principal)input_name;
+ char *user;
+ int user_ok;
+
+ if (!gss_oid_equal(user_name_type, GSS_C_NT_USER_NAME))
+ return GSS_S_BAD_NAMETYPE;
+
+ GSSAPI_KRB5_INIT(&context);
+
+ user = malloc(user_name->length + 1);
+ if (user == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ memcpy(user, user_name->value, user_name->length);
+ user[user_name->length] = '\0';
+
+ *minor_status = 0;
+ user_ok = krb5_kuserok(context, princ, user);
+
+ free(user);
+
+ return user_ok ? GSS_S_COMPLETE : GSS_S_UNAUTHORIZED;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/canonicalize_name.c b/crypto/heimdal/lib/gssapi/krb5/canonicalize_name.c
new file mode 100644
index 0000000..7fc921b
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/canonicalize_name.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_canonicalize_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ const gss_OID mech_type,
+ gss_name_t * output_name
+ )
+{
+ krb5_context context;
+ krb5_principal name;
+ OM_uint32 ret;
+
+ *output_name = NULL;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ ret = _gsskrb5_canon_name(minor_status, context, 1, NULL, input_name, &name);
+ if (ret)
+ return ret;
+
+ *output_name = (gss_name_t)name;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/ccache_name.c b/crypto/heimdal/lib/gssapi/krb5/ccache_name.c
new file mode 100644
index 0000000..1577fb2
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/ccache_name.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+char *last_out_name;
+
+OM_uint32
+_gsskrb5_krb5_ccache_name(OM_uint32 *minor_status,
+ const char *name,
+ const char **out_name)
+{
+ krb5_context context;
+ krb5_error_code kret;
+
+ *minor_status = 0;
+
+ GSSAPI_KRB5_INIT(&context);
+
+ if (out_name) {
+ const char *n;
+
+ if (last_out_name) {
+ free(last_out_name);
+ last_out_name = NULL;
+ }
+
+ n = krb5_cc_default_name(context);
+ if (n == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ last_out_name = strdup(n);
+ if (last_out_name == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ *out_name = last_out_name;
+ }
+
+ kret = krb5_cc_set_default_name(context, name);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/cfx.c b/crypto/heimdal/lib/gssapi/krb5/cfx.c
new file mode 100644
index 0000000..28cf47b
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/cfx.c
@@ -0,0 +1,1769 @@
+/*
+ * Copyright (c) 2003, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+/*
+ * Implementation of RFC 4121
+ */
+
+#define CFXSentByAcceptor (1 << 0)
+#define CFXSealed (1 << 1)
+#define CFXAcceptorSubkey (1 << 2)
+
+krb5_error_code
+_gsskrb5cfx_wrap_length_cfx(krb5_context context,
+ krb5_crypto crypto,
+ int conf_req_flag,
+ int dce_style,
+ size_t input_length,
+ size_t *output_length,
+ size_t *cksumsize,
+ uint16_t *padlength)
+{
+ krb5_error_code ret;
+ krb5_cksumtype type;
+
+ /* 16-byte header is always first */
+ *output_length = sizeof(gss_cfx_wrap_token_desc);
+ *padlength = 0;
+
+ ret = krb5_crypto_get_checksum_type(context, crypto, &type);
+ if (ret)
+ return ret;
+
+ ret = krb5_checksumsize(context, type, cksumsize);
+ if (ret)
+ return ret;
+
+ if (conf_req_flag) {
+ size_t padsize;
+
+ /* Header is concatenated with data before encryption */
+ input_length += sizeof(gss_cfx_wrap_token_desc);
+
+ if (dce_style) {
+ ret = krb5_crypto_getblocksize(context, crypto, &padsize);
+ } else {
+ ret = krb5_crypto_getpadsize(context, crypto, &padsize);
+ }
+ if (ret) {
+ return ret;
+ }
+ if (padsize > 1) {
+ /* XXX check this */
+ *padlength = padsize - (input_length % padsize);
+
+ /* We add the pad ourselves (noted here for completeness only) */
+ input_length += *padlength;
+ }
+
+ *output_length += krb5_get_wrapped_length(context,
+ crypto, input_length);
+ } else {
+ /* Checksum is concatenated with data */
+ *output_length += input_length + *cksumsize;
+ }
+
+ assert(*output_length > input_length);
+
+ return 0;
+}
+
+OM_uint32
+_gssapi_wrap_size_cfx(OM_uint32 *minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 *max_input_size)
+{
+ krb5_error_code ret;
+
+ *max_input_size = 0;
+
+ /* 16-byte header is always first */
+ if (req_output_size < 16)
+ return 0;
+ req_output_size -= 16;
+
+ if (conf_req_flag) {
+ size_t wrapped_size, sz;
+
+ wrapped_size = req_output_size + 1;
+ do {
+ wrapped_size--;
+ sz = krb5_get_wrapped_length(context,
+ ctx->crypto, wrapped_size);
+ } while (wrapped_size && sz > req_output_size);
+ if (wrapped_size == 0)
+ return 0;
+
+ /* inner header */
+ if (wrapped_size < 16)
+ return 0;
+
+ wrapped_size -= 16;
+
+ *max_input_size = wrapped_size;
+ } else {
+ krb5_cksumtype type;
+ size_t cksumsize;
+
+ ret = krb5_crypto_get_checksum_type(context, ctx->crypto, &type);
+ if (ret)
+ return ret;
+
+ ret = krb5_checksumsize(context, type, &cksumsize);
+ if (ret)
+ return ret;
+
+ if (req_output_size < cksumsize)
+ return 0;
+
+ /* Checksum is concatenated with data */
+ *max_input_size = req_output_size - cksumsize;
+ }
+
+ return 0;
+}
+
+/*
+ * Rotate "rrc" bytes to the front or back
+ */
+
+static krb5_error_code
+rrc_rotate(void *data, size_t len, uint16_t rrc, krb5_boolean unrotate)
+{
+ u_char *tmp, buf[256];
+ size_t left;
+
+ if (len == 0)
+ return 0;
+
+ rrc %= len;
+
+ if (rrc == 0)
+ return 0;
+
+ left = len - rrc;
+
+ if (rrc <= sizeof(buf)) {
+ tmp = buf;
+ } else {
+ tmp = malloc(rrc);
+ if (tmp == NULL)
+ return ENOMEM;
+ }
+
+ if (unrotate) {
+ memcpy(tmp, data, rrc);
+ memmove(data, (u_char *)data + rrc, left);
+ memcpy((u_char *)data + left, tmp, rrc);
+ } else {
+ memcpy(tmp, (u_char *)data + left, rrc);
+ memmove((u_char *)data + rrc, data, left);
+ memcpy(data, tmp, rrc);
+ }
+
+ if (rrc > sizeof(buf))
+ free(tmp);
+
+ return 0;
+}
+
+gss_iov_buffer_desc *
+_gk_find_buffer(gss_iov_buffer_desc *iov, int iov_count, OM_uint32 type)
+{
+ int i;
+
+ for (i = 0; i < iov_count; i++)
+ if (type == GSS_IOV_BUFFER_TYPE(iov[i].type))
+ return &iov[i];
+ return NULL;
+}
+
+OM_uint32
+_gk_allocate_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *buffer, size_t size)
+{
+ if (buffer->type & GSS_IOV_BUFFER_FLAG_ALLOCATED) {
+ if (buffer->buffer.length == size)
+ return GSS_S_COMPLETE;
+ free(buffer->buffer.value);
+ }
+
+ buffer->buffer.value = malloc(size);
+ buffer->buffer.length = size;
+ if (buffer->buffer.value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ buffer->type |= GSS_IOV_BUFFER_FLAG_ALLOCATED;
+
+ return GSS_S_COMPLETE;
+}
+
+
+OM_uint32
+_gk_verify_buffers(OM_uint32 *minor_status,
+ const gsskrb5_ctx ctx,
+ const gss_iov_buffer_desc *header,
+ const gss_iov_buffer_desc *padding,
+ const gss_iov_buffer_desc *trailer)
+{
+ if (header == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (IS_DCE_STYLE(ctx)) {
+ /*
+ * In DCE style mode we reject having a padding or trailer buffer
+ */
+ if (padding) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ if (trailer) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ } else {
+ /*
+ * In non-DCE style mode we require having a padding buffer
+ */
+ if (padding == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+#if 0
+OM_uint32
+_gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ OM_uint32 major_status, junk;
+ gss_iov_buffer_desc *header, *trailer, *padding;
+ size_t gsshsize, k5hsize;
+ size_t gsstsize, k5tsize;
+ size_t rrc = 0, ec = 0;
+ int i;
+ gss_cfx_wrap_token token;
+ krb5_error_code ret;
+ int32_t seq_number;
+ unsigned usage;
+ krb5_crypto_iov *data = NULL;
+
+ header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
+ if (header == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
+ if (padding != NULL) {
+ padding->buffer.length = 0;
+ }
+
+ trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
+
+ major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
+ if (major_status != GSS_S_COMPLETE) {
+ return major_status;
+ }
+
+ if (conf_req_flag) {
+ size_t k5psize = 0;
+ size_t k5pbase = 0;
+ size_t k5bsize = 0;
+ size_t size = 0;
+
+ for (i = 0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ size += iov[i].buffer.length;
+ break;
+ default:
+ break;
+ }
+ }
+
+ size += sizeof(gss_cfx_wrap_token_desc);
+
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_HEADER,
+ &k5hsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_TRAILER,
+ &k5tsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_PADDING,
+ &k5pbase);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ if (k5pbase > 1) {
+ k5psize = k5pbase - (size % k5pbase);
+ } else {
+ k5psize = 0;
+ }
+
+ if (k5psize == 0 && IS_DCE_STYLE(ctx)) {
+ *minor_status = krb5_crypto_getblocksize(context, ctx->crypto,
+ &k5bsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+ ec = k5bsize;
+ } else {
+ ec = k5psize;
+ }
+
+ gsshsize = sizeof(gss_cfx_wrap_token_desc) + k5hsize;
+ gsstsize = sizeof(gss_cfx_wrap_token_desc) + ec + k5tsize;
+ } else {
+ if (IS_DCE_STYLE(ctx)) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ k5hsize = 0;
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_CHECKSUM,
+ &k5tsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ gsshsize = sizeof(gss_cfx_wrap_token_desc);
+ gsstsize = k5tsize;
+ }
+
+ /*
+ *
+ */
+
+ if (trailer == NULL) {
+ rrc = gsstsize;
+ if (IS_DCE_STYLE(ctx))
+ rrc -= ec;
+ gsshsize += gsstsize;
+ gsstsize = 0;
+ } else if (GSS_IOV_BUFFER_FLAGS(trailer->type) & GSS_IOV_BUFFER_FLAG_ALLOCATE) {
+ major_status = _gk_allocate_buffer(minor_status, trailer, gsstsize);
+ if (major_status)
+ goto failure;
+ } else if (trailer->buffer.length < gsstsize) {
+ *minor_status = KRB5_BAD_MSIZE;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ } else
+ trailer->buffer.length = gsstsize;
+
+ /*
+ *
+ */
+
+ if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_FLAG_ALLOCATE) {
+ major_status = _gk_allocate_buffer(minor_status, header, gsshsize);
+ if (major_status != GSS_S_COMPLETE)
+ goto failure;
+ } else if (header->buffer.length < gsshsize) {
+ *minor_status = KRB5_BAD_MSIZE;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ } else
+ header->buffer.length = gsshsize;
+
+ token = (gss_cfx_wrap_token)header->buffer.value;
+
+ token->TOK_ID[0] = 0x05;
+ token->TOK_ID[1] = 0x04;
+ token->Flags = 0;
+ token->Filler = 0xFF;
+
+ if ((ctx->more_flags & LOCAL) == 0)
+ token->Flags |= CFXSentByAcceptor;
+
+ if (ctx->more_flags & ACCEPTOR_SUBKEY)
+ token->Flags |= CFXAcceptorSubkey;
+
+ if (ctx->more_flags & LOCAL)
+ usage = KRB5_KU_USAGE_INITIATOR_SEAL;
+ else
+ usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
+
+ if (conf_req_flag) {
+ /*
+ * In Wrap tokens with confidentiality, the EC field is
+ * used to encode the size (in bytes) of the random filler.
+ */
+ token->Flags |= CFXSealed;
+ token->EC[0] = (ec >> 8) & 0xFF;
+ token->EC[1] = (ec >> 0) & 0xFF;
+
+ } else {
+ /*
+ * In Wrap tokens without confidentiality, the EC field is
+ * used to encode the size (in bytes) of the trailing
+ * checksum.
+ *
+ * This is not used in the checksum calcuation itself,
+ * because the checksum length could potentially vary
+ * depending on the data length.
+ */
+ token->EC[0] = 0;
+ token->EC[1] = 0;
+ }
+
+ /*
+ * In Wrap tokens that provide for confidentiality, the RRC
+ * field in the header contains the hex value 00 00 before
+ * encryption.
+ *
+ * In Wrap tokens that do not provide for confidentiality,
+ * both the EC and RRC fields in the appended checksum
+ * contain the hex value 00 00 for the purpose of calculating
+ * the checksum.
+ */
+ token->RRC[0] = 0;
+ token->RRC[1] = 0;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ krb5_auth_con_getlocalseqnumber(context,
+ ctx->auth_context,
+ &seq_number);
+ _gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
+ _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
+ krb5_auth_con_setlocalseqnumber(context,
+ ctx->auth_context,
+ ++seq_number);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ data = calloc(iov_count + 3, sizeof(data[0]));
+ if (data == NULL) {
+ *minor_status = ENOMEM;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (conf_req_flag) {
+ /*
+ plain packet:
+
+ {"header" | encrypt(plaintext-data | ec-padding | E"header")}
+
+ Expanded, this is with with RRC = 0:
+
+ {"header" | krb5-header | plaintext-data | ec-padding | E"header" | krb5-trailer }
+
+ In DCE-RPC mode == no trailer: RRC = gss "trailer" == length(ec-padding | E"header" | krb5-trailer)
+
+ {"header" | ec-padding | E"header" | krb5-trailer | krb5-header | plaintext-data }
+ */
+
+ i = 0;
+ data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
+ data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize;
+ data[i].data.length = k5hsize;
+
+ for (i = 1; i < iov_count + 1; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i - 1].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ break;
+ default:
+ data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+ break;
+ }
+ data[i].data.length = iov[i - 1].buffer.length;
+ data[i].data.data = iov[i - 1].buffer.value;
+ }
+
+ /*
+ * Any necessary padding is added here to ensure that the
+ * encrypted token header is always at the end of the
+ * ciphertext.
+ */
+
+ /* encrypted CFX header in trailer (or after the header if in
+ DCE mode). Copy in header into E"header"
+ */
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ if (trailer)
+ data[i].data.data = trailer->buffer.value;
+ else
+ data[i].data.data = ((uint8_t *)header->buffer.value) + sizeof(*token);
+
+ data[i].data.length = ec + sizeof(*token);
+ memset(data[i].data.data, 0xFF, ec);
+ memcpy(((uint8_t *)data[i].data.data) + ec, token, sizeof(*token));
+ i++;
+
+ /* Kerberos trailer comes after the gss trailer */
+ data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
+ data[i].data.data = ((uint8_t *)data[i-1].data.data) + ec + sizeof(*token);
+ data[i].data.length = k5tsize;
+ i++;
+
+ ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage, data, i, NULL);
+ if (ret != 0) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (rrc) {
+ token->RRC[0] = (rrc >> 8) & 0xFF;
+ token->RRC[1] = (rrc >> 0) & 0xFF;
+ }
+
+ } else {
+ /*
+ plain packet:
+
+ {data | "header" | gss-trailer (krb5 checksum)
+
+ don't do RRC != 0
+
+ */
+
+ for (i = 0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ break;
+ default:
+ data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+ break;
+ }
+ data[i].data.length = iov[i].buffer.length;
+ data[i].data.data = iov[i].buffer.value;
+ }
+
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ data[i].data.data = header->buffer.value;
+ data[i].data.length = sizeof(gss_cfx_wrap_token_desc);
+ i++;
+
+ data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
+ if (trailer) {
+ data[i].data.data = trailer->buffer.value;
+ } else {
+ data[i].data.data = (uint8_t *)header->buffer.value +
+ sizeof(gss_cfx_wrap_token_desc);
+ }
+ data[i].data.length = k5tsize;
+ i++;
+
+ ret = krb5_create_checksum_iov(context, ctx->crypto, usage, data, i, NULL);
+ if (ret) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (rrc) {
+ token->RRC[0] = (rrc >> 8) & 0xFF;
+ token->RRC[1] = (rrc >> 0) & 0xFF;
+ }
+
+ token->EC[0] = (k5tsize >> 8) & 0xFF;
+ token->EC[1] = (k5tsize >> 0) & 0xFF;
+ }
+
+ if (conf_state != NULL)
+ *conf_state = conf_req_flag;
+
+ free(data);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+
+ failure:
+ if (data)
+ free(data);
+
+ gss_release_iov_buffer(&junk, iov, iov_count);
+
+ return major_status;
+}
+#endif
+
+/* This is slowpath */
+static OM_uint32
+unrotate_iov(OM_uint32 *minor_status, size_t rrc, gss_iov_buffer_desc *iov, int iov_count)
+{
+ uint8_t *p, *q;
+ size_t len = 0, skip;
+ int i;
+
+ for (i = 0; i < iov_count; i++)
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+ len += iov[i].buffer.length;
+
+ p = malloc(len);
+ if (p == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ q = p;
+
+ /* copy up */
+
+ for (i = 0; i < iov_count; i++) {
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+ {
+ memcpy(q, iov[i].buffer.value, iov[i].buffer.length);
+ q += iov[i].buffer.length;
+ }
+ }
+ assert((size_t)(q - p) == len);
+
+ /* unrotate first part */
+ q = p + rrc;
+ skip = rrc;
+ for (i = 0; i < iov_count; i++) {
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+ {
+ if (iov[i].buffer.length <= skip) {
+ skip -= iov[i].buffer.length;
+ } else {
+ memcpy(((uint8_t *)iov[i].buffer.value) + skip, q, iov[i].buffer.length - skip);
+ q += iov[i].buffer.length - skip;
+ skip = 0;
+ }
+ }
+ }
+ /* copy trailer */
+ q = p;
+ skip = rrc;
+ for (i = 0; i < iov_count; i++) {
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+ {
+ memcpy(q, iov[i].buffer.value, min(iov[i].buffer.length, skip));
+ if (iov[i].buffer.length > skip)
+ break;
+ skip -= iov[i].buffer.length;
+ q += iov[i].buffer.length;
+ }
+ }
+ return GSS_S_COMPLETE;
+}
+
+#if 0
+
+OM_uint32
+_gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ int *conf_state,
+ gss_qop_t *qop_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ OM_uint32 seq_number_lo, seq_number_hi, major_status, junk;
+ gss_iov_buffer_desc *header, *trailer, *padding;
+ gss_cfx_wrap_token token, ttoken;
+ u_char token_flags;
+ krb5_error_code ret;
+ unsigned usage;
+ uint16_t ec, rrc;
+ krb5_crypto_iov *data = NULL;
+ int i, j;
+
+ *minor_status = 0;
+
+ header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
+ if (header == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (header->buffer.length < sizeof(*token)) /* we check exact below */
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
+ if (padding != NULL && padding->buffer.length != 0) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
+
+ major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
+ if (major_status != GSS_S_COMPLETE) {
+ return major_status;
+ }
+
+ token = (gss_cfx_wrap_token)header->buffer.value;
+
+ if (token->TOK_ID[0] != 0x05 || token->TOK_ID[1] != 0x04)
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ /* Ignore unknown flags */
+ token_flags = token->Flags &
+ (CFXSentByAcceptor | CFXSealed | CFXAcceptorSubkey);
+
+ if (token_flags & CFXSentByAcceptor) {
+ if ((ctx->more_flags & LOCAL) == 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (ctx->more_flags & ACCEPTOR_SUBKEY) {
+ if ((token_flags & CFXAcceptorSubkey) == 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ } else {
+ if (token_flags & CFXAcceptorSubkey)
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (token->Filler != 0xFF)
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ if (conf_state != NULL)
+ *conf_state = (token_flags & CFXSealed) ? 1 : 0;
+
+ ec = (token->EC[0] << 8) | token->EC[1];
+ rrc = (token->RRC[0] << 8) | token->RRC[1];
+
+ /*
+ * Check sequence number
+ */
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo);
+ if (seq_number_hi) {
+ /* no support for 64-bit sequence numbers */
+ *minor_status = ERANGE;
+ return GSS_S_UNSEQ_TOKEN;
+ }
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
+ if (ret != 0) {
+ *minor_status = 0;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+ }
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ /*
+ * Decrypt and/or verify checksum
+ */
+
+ if (ctx->more_flags & LOCAL) {
+ usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
+ } else {
+ usage = KRB5_KU_USAGE_INITIATOR_SEAL;
+ }
+
+ data = calloc(iov_count + 3, sizeof(data[0]));
+ if (data == NULL) {
+ *minor_status = ENOMEM;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (token_flags & CFXSealed) {
+ size_t k5tsize, k5hsize;
+
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize);
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize);
+
+ /* Rotate by RRC; bogus to do this in-place XXX */
+ /* Check RRC */
+
+ if (trailer == NULL) {
+ size_t gsstsize = k5tsize + sizeof(*token);
+ size_t gsshsize = k5hsize + sizeof(*token);
+
+ if (rrc != gsstsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ }
+
+ if (IS_DCE_STYLE(ctx))
+ gsstsize += ec;
+
+ gsshsize += gsstsize;
+
+ if (header->buffer.length != gsshsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ }
+ } else if (trailer->buffer.length != sizeof(*token) + k5tsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ } else if (header->buffer.length != sizeof(*token) + k5hsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ } else if (rrc != 0) {
+ /* go though slowpath */
+ major_status = unrotate_iov(minor_status, rrc, iov, iov_count);
+ if (major_status)
+ goto failure;
+ }
+
+ i = 0;
+ data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
+ data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize;
+ data[i].data.length = k5hsize;
+ i++;
+
+ for (j = 0; j < iov_count; i++, j++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[j].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ break;
+ default:
+ data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+ break;
+ }
+ data[i].data.length = iov[j].buffer.length;
+ data[i].data.data = iov[j].buffer.value;
+ }
+
+ /* encrypted CFX header in trailer (or after the header if in
+ DCE mode). Copy in header into E"header"
+ */
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ if (trailer) {
+ data[i].data.data = trailer->buffer.value;
+ } else {
+ data[i].data.data = ((uint8_t *)header->buffer.value) +
+ header->buffer.length - k5hsize - k5tsize - ec- sizeof(*token);
+ }
+
+ data[i].data.length = ec + sizeof(*token);
+ ttoken = (gss_cfx_wrap_token)(((uint8_t *)data[i].data.data) + ec);
+ i++;
+
+ /* Kerberos trailer comes after the gss trailer */
+ data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
+ data[i].data.data = ((uint8_t *)data[i-1].data.data) + ec + sizeof(*token);
+ data[i].data.length = k5tsize;
+ i++;
+
+ ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage, data, i, NULL);
+ if (ret != 0) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ ttoken->RRC[0] = token->RRC[0];
+ ttoken->RRC[1] = token->RRC[1];
+
+ /* Check the integrity of the header */
+ if (ct_memcmp(ttoken, token, sizeof(*token)) != 0) {
+ major_status = GSS_S_BAD_MIC;
+ goto failure;
+ }
+ } else {
+ size_t gsstsize = ec;
+ size_t gsshsize = sizeof(*token);
+
+ if (trailer == NULL) {
+ /* Check RRC */
+ if (rrc != gsstsize) {
+ *minor_status = EINVAL;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ gsshsize += gsstsize;
+ gsstsize = 0;
+ } else if (trailer->buffer.length != gsstsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ } else if (rrc != 0) {
+ /* Check RRC */
+ *minor_status = EINVAL;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (header->buffer.length != gsshsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ }
+
+ for (i = 0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ break;
+ default:
+ data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+ break;
+ }
+ data[i].data.length = iov[i].buffer.length;
+ data[i].data.data = iov[i].buffer.value;
+ }
+
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ data[i].data.data = header->buffer.value;
+ data[i].data.length = sizeof(*token);
+ i++;
+
+ data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
+ if (trailer) {
+ data[i].data.data = trailer->buffer.value;
+ } else {
+ data[i].data.data = (uint8_t *)header->buffer.value +
+ sizeof(*token);
+ }
+ data[i].data.length = ec;
+ i++;
+
+ token = (gss_cfx_wrap_token)header->buffer.value;
+ token->EC[0] = 0;
+ token->EC[1] = 0;
+ token->RRC[0] = 0;
+ token->RRC[1] = 0;
+
+ ret = krb5_verify_checksum_iov(context, ctx->crypto, usage, data, i, NULL);
+ if (ret) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+ }
+
+ if (qop_state != NULL) {
+ *qop_state = GSS_C_QOP_DEFAULT;
+ }
+
+ free(data);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+
+ failure:
+ if (data)
+ free(data);
+
+ gss_release_iov_buffer(&junk, iov, iov_count);
+
+ return major_status;
+}
+#endif
+
+OM_uint32
+_gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ OM_uint32 major_status;
+ size_t size;
+ int i;
+ gss_iov_buffer_desc *header = NULL;
+ gss_iov_buffer_desc *padding = NULL;
+ gss_iov_buffer_desc *trailer = NULL;
+ size_t gsshsize = 0;
+ size_t gsstsize = 0;
+ size_t k5hsize = 0;
+ size_t k5tsize = 0;
+
+ GSSAPI_KRB5_INIT (&context);
+ *minor_status = 0;
+
+ for (size = 0, i = 0; i < iov_count; i++) {
+ switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_EMPTY:
+ break;
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ size += iov[i].buffer.length;
+ break;
+ case GSS_IOV_BUFFER_TYPE_HEADER:
+ if (header != NULL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+ header = &iov[i];
+ break;
+ case GSS_IOV_BUFFER_TYPE_TRAILER:
+ if (trailer != NULL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+ trailer = &iov[i];
+ break;
+ case GSS_IOV_BUFFER_TYPE_PADDING:
+ if (padding != NULL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+ padding = &iov[i];
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ break;
+ default:
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
+ if (major_status != GSS_S_COMPLETE) {
+ return major_status;
+ }
+
+ if (conf_req_flag) {
+ size_t k5psize = 0;
+ size_t k5pbase = 0;
+ size_t k5bsize = 0;
+ size_t ec = 0;
+
+ size += sizeof(gss_cfx_wrap_token_desc);
+
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_HEADER,
+ &k5hsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_TRAILER,
+ &k5tsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_PADDING,
+ &k5pbase);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ if (k5pbase > 1) {
+ k5psize = k5pbase - (size % k5pbase);
+ } else {
+ k5psize = 0;
+ }
+
+ if (k5psize == 0 && IS_DCE_STYLE(ctx)) {
+ *minor_status = krb5_crypto_getblocksize(context, ctx->crypto,
+ &k5bsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ ec = k5bsize;
+ } else {
+ ec = k5psize;
+ }
+
+ gsshsize = sizeof(gss_cfx_wrap_token_desc) + k5hsize;
+ gsstsize = sizeof(gss_cfx_wrap_token_desc) + ec + k5tsize;
+ } else {
+ *minor_status = krb5_crypto_length(context, ctx->crypto,
+ KRB5_CRYPTO_TYPE_CHECKSUM,
+ &k5tsize);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ gsshsize = sizeof(gss_cfx_wrap_token_desc);
+ gsstsize = k5tsize;
+ }
+
+ if (trailer != NULL) {
+ trailer->buffer.length = gsstsize;
+ } else {
+ gsshsize += gsstsize;
+ }
+
+ header->buffer.length = gsshsize;
+
+ if (padding) {
+ /* padding is done via EC and is contained in the header or trailer */
+ padding->buffer.length = 0;
+ }
+
+ if (conf_state) {
+ *conf_state = conf_req_flag;
+ }
+
+ return GSS_S_COMPLETE;
+}
+
+
+
+
+OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ const gss_buffer_t input_message_buffer,
+ int *conf_state,
+ gss_buffer_t output_message_buffer)
+{
+ gss_cfx_wrap_token token;
+ krb5_error_code ret;
+ unsigned usage;
+ krb5_data cipher;
+ size_t wrapped_len, cksumsize;
+ uint16_t padlength, rrc = 0;
+ int32_t seq_number;
+ u_char *p;
+
+ ret = _gsskrb5cfx_wrap_length_cfx(context,
+ ctx->crypto, conf_req_flag,
+ IS_DCE_STYLE(ctx),
+ input_message_buffer->length,
+ &wrapped_len, &cksumsize, &padlength);
+ if (ret != 0) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ /* Always rotate encrypted token (if any) and checksum to header */
+ rrc = (conf_req_flag ? sizeof(*token) : 0) + (uint16_t)cksumsize;
+
+ output_message_buffer->length = wrapped_len;
+ output_message_buffer->value = malloc(output_message_buffer->length);
+ if (output_message_buffer->value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ p = output_message_buffer->value;
+ token = (gss_cfx_wrap_token)p;
+ token->TOK_ID[0] = 0x05;
+ token->TOK_ID[1] = 0x04;
+ token->Flags = 0;
+ token->Filler = 0xFF;
+ if ((ctx->more_flags & LOCAL) == 0)
+ token->Flags |= CFXSentByAcceptor;
+ if (ctx->more_flags & ACCEPTOR_SUBKEY)
+ token->Flags |= CFXAcceptorSubkey;
+ if (conf_req_flag) {
+ /*
+ * In Wrap tokens with confidentiality, the EC field is
+ * used to encode the size (in bytes) of the random filler.
+ */
+ token->Flags |= CFXSealed;
+ token->EC[0] = (padlength >> 8) & 0xFF;
+ token->EC[1] = (padlength >> 0) & 0xFF;
+ } else {
+ /*
+ * In Wrap tokens without confidentiality, the EC field is
+ * used to encode the size (in bytes) of the trailing
+ * checksum.
+ *
+ * This is not used in the checksum calcuation itself,
+ * because the checksum length could potentially vary
+ * depending on the data length.
+ */
+ token->EC[0] = 0;
+ token->EC[1] = 0;
+ }
+
+ /*
+ * In Wrap tokens that provide for confidentiality, the RRC
+ * field in the header contains the hex value 00 00 before
+ * encryption.
+ *
+ * In Wrap tokens that do not provide for confidentiality,
+ * both the EC and RRC fields in the appended checksum
+ * contain the hex value 00 00 for the purpose of calculating
+ * the checksum.
+ */
+ token->RRC[0] = 0;
+ token->RRC[1] = 0;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ krb5_auth_con_getlocalseqnumber(context,
+ ctx->auth_context,
+ &seq_number);
+ _gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
+ _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
+ krb5_auth_con_setlocalseqnumber(context,
+ ctx->auth_context,
+ ++seq_number);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ /*
+ * If confidentiality is requested, the token header is
+ * appended to the plaintext before encryption; the resulting
+ * token is {"header" | encrypt(plaintext | pad | "header")}.
+ *
+ * If no confidentiality is requested, the checksum is
+ * calculated over the plaintext concatenated with the
+ * token header.
+ */
+ if (ctx->more_flags & LOCAL) {
+ usage = KRB5_KU_USAGE_INITIATOR_SEAL;
+ } else {
+ usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
+ }
+
+ if (conf_req_flag) {
+ /*
+ * Any necessary padding is added here to ensure that the
+ * encrypted token header is always at the end of the
+ * ciphertext.
+ *
+ * The specification does not require that the padding
+ * bytes are initialized.
+ */
+ p += sizeof(*token);
+ memcpy(p, input_message_buffer->value, input_message_buffer->length);
+ memset(p + input_message_buffer->length, 0xFF, padlength);
+ memcpy(p + input_message_buffer->length + padlength,
+ token, sizeof(*token));
+
+ ret = krb5_encrypt(context, ctx->crypto,
+ usage, p,
+ input_message_buffer->length + padlength +
+ sizeof(*token),
+ &cipher);
+ if (ret != 0) {
+ *minor_status = ret;
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ return GSS_S_FAILURE;
+ }
+ assert(sizeof(*token) + cipher.length == wrapped_len);
+ token->RRC[0] = (rrc >> 8) & 0xFF;
+ token->RRC[1] = (rrc >> 0) & 0xFF;
+
+ /*
+ * this is really ugly, but needed against windows
+ * for DCERPC, as windows rotates by EC+RRC.
+ */
+ if (IS_DCE_STYLE(ctx)) {
+ ret = rrc_rotate(cipher.data, cipher.length, rrc+padlength, FALSE);
+ } else {
+ ret = rrc_rotate(cipher.data, cipher.length, rrc, FALSE);
+ }
+ if (ret != 0) {
+ *minor_status = ret;
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ return GSS_S_FAILURE;
+ }
+ memcpy(p, cipher.data, cipher.length);
+ krb5_data_free(&cipher);
+ } else {
+ char *buf;
+ Checksum cksum;
+
+ buf = malloc(input_message_buffer->length + sizeof(*token));
+ if (buf == NULL) {
+ *minor_status = ENOMEM;
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ return GSS_S_FAILURE;
+ }
+ memcpy(buf, input_message_buffer->value, input_message_buffer->length);
+ memcpy(buf + input_message_buffer->length, token, sizeof(*token));
+
+ ret = krb5_create_checksum(context, ctx->crypto,
+ usage, 0, buf,
+ input_message_buffer->length +
+ sizeof(*token),
+ &cksum);
+ if (ret != 0) {
+ *minor_status = ret;
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ free(buf);
+ return GSS_S_FAILURE;
+ }
+
+ free(buf);
+
+ assert(cksum.checksum.length == cksumsize);
+ token->EC[0] = (cksum.checksum.length >> 8) & 0xFF;
+ token->EC[1] = (cksum.checksum.length >> 0) & 0xFF;
+ token->RRC[0] = (rrc >> 8) & 0xFF;
+ token->RRC[1] = (rrc >> 0) & 0xFF;
+
+ p += sizeof(*token);
+ memcpy(p, input_message_buffer->value, input_message_buffer->length);
+ memcpy(p + input_message_buffer->length,
+ cksum.checksum.data, cksum.checksum.length);
+
+ ret = rrc_rotate(p,
+ input_message_buffer->length + cksum.checksum.length, rrc, FALSE);
+ if (ret != 0) {
+ *minor_status = ret;
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ free_Checksum(&cksum);
+ return GSS_S_FAILURE;
+ }
+ free_Checksum(&cksum);
+ }
+
+ if (conf_state != NULL) {
+ *conf_state = conf_req_flag;
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ const gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int *conf_state,
+ gss_qop_t *qop_state)
+{
+ gss_cfx_wrap_token token;
+ u_char token_flags;
+ krb5_error_code ret;
+ unsigned usage;
+ krb5_data data;
+ uint16_t ec, rrc;
+ OM_uint32 seq_number_lo, seq_number_hi;
+ size_t len;
+ u_char *p;
+
+ *minor_status = 0;
+
+ if (input_message_buffer->length < sizeof(*token)) {
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ p = input_message_buffer->value;
+
+ token = (gss_cfx_wrap_token)p;
+
+ if (token->TOK_ID[0] != 0x05 || token->TOK_ID[1] != 0x04) {
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ /* Ignore unknown flags */
+ token_flags = token->Flags &
+ (CFXSentByAcceptor | CFXSealed | CFXAcceptorSubkey);
+
+ if (token_flags & CFXSentByAcceptor) {
+ if ((ctx->more_flags & LOCAL) == 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (ctx->more_flags & ACCEPTOR_SUBKEY) {
+ if ((token_flags & CFXAcceptorSubkey) == 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ } else {
+ if (token_flags & CFXAcceptorSubkey)
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (token->Filler != 0xFF) {
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (conf_state != NULL) {
+ *conf_state = (token_flags & CFXSealed) ? 1 : 0;
+ }
+
+ ec = (token->EC[0] << 8) | token->EC[1];
+ rrc = (token->RRC[0] << 8) | token->RRC[1];
+
+ /*
+ * Check sequence number
+ */
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo);
+ if (seq_number_hi) {
+ /* no support for 64-bit sequence numbers */
+ *minor_status = ERANGE;
+ return GSS_S_UNSEQ_TOKEN;
+ }
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
+ if (ret != 0) {
+ *minor_status = 0;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ return ret;
+ }
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ /*
+ * Decrypt and/or verify checksum
+ */
+
+ if (ctx->more_flags & LOCAL) {
+ usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
+ } else {
+ usage = KRB5_KU_USAGE_INITIATOR_SEAL;
+ }
+
+ p += sizeof(*token);
+ len = input_message_buffer->length;
+ len -= (p - (u_char *)input_message_buffer->value);
+
+ if (token_flags & CFXSealed) {
+ /*
+ * this is really ugly, but needed against windows
+ * for DCERPC, as windows rotates by EC+RRC.
+ */
+ if (IS_DCE_STYLE(ctx)) {
+ *minor_status = rrc_rotate(p, len, rrc+ec, TRUE);
+ } else {
+ *minor_status = rrc_rotate(p, len, rrc, TRUE);
+ }
+ if (*minor_status != 0) {
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_decrypt(context, ctx->crypto, usage,
+ p, len, &data);
+ if (ret != 0) {
+ *minor_status = ret;
+ return GSS_S_BAD_MIC;
+ }
+
+ /* Check that there is room for the pad and token header */
+ if (data.length < ec + sizeof(*token)) {
+ krb5_data_free(&data);
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+ p = data.data;
+ p += data.length - sizeof(*token);
+
+ /* RRC is unprotected; don't modify input buffer */
+ ((gss_cfx_wrap_token)p)->RRC[0] = token->RRC[0];
+ ((gss_cfx_wrap_token)p)->RRC[1] = token->RRC[1];
+
+ /* Check the integrity of the header */
+ if (ct_memcmp(p, token, sizeof(*token)) != 0) {
+ krb5_data_free(&data);
+ return GSS_S_BAD_MIC;
+ }
+
+ output_message_buffer->value = data.data;
+ output_message_buffer->length = data.length - ec - sizeof(*token);
+ } else {
+ Checksum cksum;
+
+ /* Rotate by RRC; bogus to do this in-place XXX */
+ *minor_status = rrc_rotate(p, len, rrc, TRUE);
+ if (*minor_status != 0) {
+ return GSS_S_FAILURE;
+ }
+
+ /* Determine checksum type */
+ ret = krb5_crypto_get_checksum_type(context,
+ ctx->crypto,
+ &cksum.cksumtype);
+ if (ret != 0) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ cksum.checksum.length = ec;
+
+ /* Check we have at least as much data as the checksum */
+ if (len < cksum.checksum.length) {
+ *minor_status = ERANGE;
+ return GSS_S_BAD_MIC;
+ }
+
+ /* Length now is of the plaintext only, no checksum */
+ len -= cksum.checksum.length;
+ cksum.checksum.data = p + len;
+
+ output_message_buffer->length = len; /* for later */
+ output_message_buffer->value = malloc(len + sizeof(*token));
+ if (output_message_buffer->value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ /* Checksum is over (plaintext-data | "header") */
+ memcpy(output_message_buffer->value, p, len);
+ memcpy((u_char *)output_message_buffer->value + len,
+ token, sizeof(*token));
+
+ /* EC is not included in checksum calculation */
+ token = (gss_cfx_wrap_token)((u_char *)output_message_buffer->value +
+ len);
+ token->EC[0] = 0;
+ token->EC[1] = 0;
+ token->RRC[0] = 0;
+ token->RRC[1] = 0;
+
+ ret = krb5_verify_checksum(context, ctx->crypto,
+ usage,
+ output_message_buffer->value,
+ len + sizeof(*token),
+ &cksum);
+ if (ret != 0) {
+ *minor_status = ret;
+ _gsskrb5_release_buffer(minor_status, output_message_buffer);
+ return GSS_S_BAD_MIC;
+ }
+ }
+
+ if (qop_state != NULL) {
+ *qop_state = GSS_C_QOP_DEFAULT;
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ gss_qop_t qop_req,
+ const gss_buffer_t message_buffer,
+ gss_buffer_t message_token)
+{
+ gss_cfx_mic_token token;
+ krb5_error_code ret;
+ unsigned usage;
+ Checksum cksum;
+ u_char *buf;
+ size_t len;
+ int32_t seq_number;
+
+ len = message_buffer->length + sizeof(*token);
+ buf = malloc(len);
+ if (buf == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ memcpy(buf, message_buffer->value, message_buffer->length);
+
+ token = (gss_cfx_mic_token)(buf + message_buffer->length);
+ token->TOK_ID[0] = 0x04;
+ token->TOK_ID[1] = 0x04;
+ token->Flags = 0;
+ if ((ctx->more_flags & LOCAL) == 0)
+ token->Flags |= CFXSentByAcceptor;
+ if (ctx->more_flags & ACCEPTOR_SUBKEY)
+ token->Flags |= CFXAcceptorSubkey;
+ memset(token->Filler, 0xFF, 5);
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ krb5_auth_con_getlocalseqnumber(context,
+ ctx->auth_context,
+ &seq_number);
+ _gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
+ _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
+ krb5_auth_con_setlocalseqnumber(context,
+ ctx->auth_context,
+ ++seq_number);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ if (ctx->more_flags & LOCAL) {
+ usage = KRB5_KU_USAGE_INITIATOR_SIGN;
+ } else {
+ usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
+ }
+
+ ret = krb5_create_checksum(context, ctx->crypto,
+ usage, 0, buf, len, &cksum);
+ if (ret != 0) {
+ *minor_status = ret;
+ free(buf);
+ return GSS_S_FAILURE;
+ }
+
+ /* Determine MIC length */
+ message_token->length = sizeof(*token) + cksum.checksum.length;
+ message_token->value = malloc(message_token->length);
+ if (message_token->value == NULL) {
+ *minor_status = ENOMEM;
+ free_Checksum(&cksum);
+ free(buf);
+ return GSS_S_FAILURE;
+ }
+
+ /* Token is { "header" | get_mic("header" | plaintext-data) } */
+ memcpy(message_token->value, token, sizeof(*token));
+ memcpy((u_char *)message_token->value + sizeof(*token),
+ cksum.checksum.data, cksum.checksum.length);
+
+ free_Checksum(&cksum);
+ free(buf);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t *qop_state)
+{
+ gss_cfx_mic_token token;
+ u_char token_flags;
+ krb5_error_code ret;
+ unsigned usage;
+ OM_uint32 seq_number_lo, seq_number_hi;
+ u_char *buf, *p;
+ Checksum cksum;
+
+ *minor_status = 0;
+
+ if (token_buffer->length < sizeof(*token)) {
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ p = token_buffer->value;
+
+ token = (gss_cfx_mic_token)p;
+
+ if (token->TOK_ID[0] != 0x04 || token->TOK_ID[1] != 0x04) {
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ /* Ignore unknown flags */
+ token_flags = token->Flags & (CFXSentByAcceptor | CFXAcceptorSubkey);
+
+ if (token_flags & CFXSentByAcceptor) {
+ if ((ctx->more_flags & LOCAL) == 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+ if (ctx->more_flags & ACCEPTOR_SUBKEY) {
+ if ((token_flags & CFXAcceptorSubkey) == 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ } else {
+ if (token_flags & CFXAcceptorSubkey)
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (ct_memcmp(token->Filler, "\xff\xff\xff\xff\xff", 5) != 0) {
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ /*
+ * Check sequence number
+ */
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo);
+ if (seq_number_hi) {
+ *minor_status = ERANGE;
+ return GSS_S_UNSEQ_TOKEN;
+ }
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
+ if (ret != 0) {
+ *minor_status = 0;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+ }
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ /*
+ * Verify checksum
+ */
+ ret = krb5_crypto_get_checksum_type(context, ctx->crypto,
+ &cksum.cksumtype);
+ if (ret != 0) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ cksum.checksum.data = p + sizeof(*token);
+ cksum.checksum.length = token_buffer->length - sizeof(*token);
+
+ if (ctx->more_flags & LOCAL) {
+ usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
+ } else {
+ usage = KRB5_KU_USAGE_INITIATOR_SIGN;
+ }
+
+ buf = malloc(message_buffer->length + sizeof(*token));
+ if (buf == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy(buf, message_buffer->value, message_buffer->length);
+ memcpy(buf + message_buffer->length, token, sizeof(*token));
+
+ ret = krb5_verify_checksum(context, ctx->crypto,
+ usage,
+ buf,
+ sizeof(*token) + message_buffer->length,
+ &cksum);
+ if (ret != 0) {
+ *minor_status = ret;
+ free(buf);
+ return GSS_S_BAD_MIC;
+ }
+
+ free(buf);
+
+ if (qop_state != NULL) {
+ *qop_state = GSS_C_QOP_DEFAULT;
+ }
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/cfx.h b/crypto/heimdal/lib/gssapi/krb5/cfx.h
new file mode 100644
index 0000000..c30ed07
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/cfx.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2003, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+/* $Id$ */
+
+#ifndef GSSAPI_CFX_H_
+#define GSSAPI_CFX_H_ 1
+
+/*
+ * Implementation of draft-ietf-krb-wg-gssapi-cfx-01.txt
+ */
+
+typedef struct gss_cfx_mic_token_desc_struct {
+ u_char TOK_ID[2]; /* 04 04 */
+ u_char Flags;
+ u_char Filler[5];
+ u_char SND_SEQ[8];
+} gss_cfx_mic_token_desc, *gss_cfx_mic_token;
+
+typedef struct gss_cfx_wrap_token_desc_struct {
+ u_char TOK_ID[2]; /* 04 05 */
+ u_char Flags;
+ u_char Filler;
+ u_char EC[2];
+ u_char RRC[2];
+ u_char SND_SEQ[8];
+} gss_cfx_wrap_token_desc, *gss_cfx_wrap_token;
+
+typedef struct gss_cfx_delete_token_desc_struct {
+ u_char TOK_ID[2]; /* 05 04 */
+ u_char Flags;
+ u_char Filler[5];
+ u_char SND_SEQ[8];
+} gss_cfx_delete_token_desc, *gss_cfx_delete_token;
+
+#endif /* GSSAPI_CFX_H_ */
diff --git a/crypto/heimdal/lib/gssapi/krb5/compare_name.c b/crypto/heimdal/lib/gssapi/krb5/compare_name.c
new file mode 100644
index 0000000..7409d45
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/compare_name.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_compare_name
+ (OM_uint32 * minor_status,
+ const gss_name_t name1,
+ const gss_name_t name2,
+ int * name_equal
+ )
+{
+ krb5_const_principal princ1 = (krb5_const_principal)name1;
+ krb5_const_principal princ2 = (krb5_const_principal)name2;
+ krb5_context context;
+
+ GSSAPI_KRB5_INIT(&context);
+
+ *name_equal = krb5_principal_compare (context,
+ princ1, princ2);
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/compat.c b/crypto/heimdal/lib/gssapi/krb5/compat.c
new file mode 100644
index 0000000..3381dff
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/compat.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2003 - 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+static krb5_error_code
+check_compat(OM_uint32 *minor_status,
+ krb5_context context, krb5_const_principal name,
+ const char *option, krb5_boolean *compat,
+ krb5_boolean match_val)
+{
+ krb5_error_code ret = 0;
+ char **p, **q;
+ krb5_principal match;
+
+
+ p = krb5_config_get_strings(context, NULL, "gssapi",
+ option, NULL);
+ if(p == NULL)
+ return 0;
+
+ match = NULL;
+ for(q = p; *q; q++) {
+ ret = krb5_parse_name(context, *q, &match);
+ if (ret)
+ break;
+
+ if (krb5_principal_match(context, name, match)) {
+ *compat = match_val;
+ break;
+ }
+
+ krb5_free_principal(context, match);
+ match = NULL;
+ }
+ if (match)
+ krb5_free_principal(context, match);
+ krb5_config_free_strings(p);
+
+ if (ret) {
+ if (minor_status)
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ return 0;
+}
+
+/*
+ * ctx->ctx_id_mutex is assumed to be locked
+ */
+
+OM_uint32
+_gss_DES3_get_mic_compat(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context)
+{
+ krb5_boolean use_compat = FALSE;
+ OM_uint32 ret;
+
+ if ((ctx->more_flags & COMPAT_OLD_DES3_SELECTED) == 0) {
+ ret = check_compat(minor_status, context, ctx->target,
+ "broken_des3_mic", &use_compat, TRUE);
+ if (ret)
+ return ret;
+ ret = check_compat(minor_status, context, ctx->target,
+ "correct_des3_mic", &use_compat, FALSE);
+ if (ret)
+ return ret;
+
+ if (use_compat)
+ ctx->more_flags |= COMPAT_OLD_DES3;
+ ctx->more_flags |= COMPAT_OLD_DES3_SELECTED;
+ }
+ return 0;
+}
+
+#if 0
+OM_uint32
+gss_krb5_compat_des3_mic(OM_uint32 *minor_status, gss_ctx_id_t ctx, int on)
+{
+ *minor_status = 0;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ if (on) {
+ ctx->more_flags |= COMPAT_OLD_DES3;
+ } else {
+ ctx->more_flags &= ~COMPAT_OLD_DES3;
+ }
+ ctx->more_flags |= COMPAT_OLD_DES3_SELECTED;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ return 0;
+}
+#endif
diff --git a/crypto/heimdal/lib/gssapi/krb5/context_time.c b/crypto/heimdal/lib/gssapi/krb5/context_time.c
new file mode 100644
index 0000000..cb15500
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/context_time.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32
+_gsskrb5_lifetime_left(OM_uint32 *minor_status,
+ krb5_context context,
+ OM_uint32 lifetime,
+ OM_uint32 *lifetime_rec)
+{
+ krb5_timestamp timeret;
+ krb5_error_code kret;
+
+ if (lifetime == 0) {
+ *lifetime_rec = GSS_C_INDEFINITE;
+ return GSS_S_COMPLETE;
+ }
+
+ kret = krb5_timeofday(context, &timeret);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ if (lifetime < timeret)
+ *lifetime_rec = 0;
+ else
+ *lifetime_rec = lifetime - timeret;
+
+ return GSS_S_COMPLETE;
+}
+
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_context_time
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ OM_uint32 * time_rec
+ )
+{
+ krb5_context context;
+ OM_uint32 lifetime;
+ OM_uint32 major_status;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ lifetime = ctx->lifetime;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ major_status = _gsskrb5_lifetime_left(minor_status, context,
+ lifetime, time_rec);
+ if (major_status != GSS_S_COMPLETE)
+ return major_status;
+
+ *minor_status = 0;
+
+ if (*time_rec == 0)
+ return GSS_S_CONTEXT_EXPIRED;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/copy_ccache.c b/crypto/heimdal/lib/gssapi/krb5/copy_ccache.c
new file mode 100644
index 0000000..e332d29
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/copy_ccache.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2000 - 2001, 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+#if 0
+OM_uint32
+gss_krb5_copy_ccache(OM_uint32 *minor_status,
+ krb5_context context,
+ gss_cred_id_t cred,
+ krb5_ccache out)
+{
+ krb5_error_code kret;
+
+ HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
+
+ if (cred->ccache == NULL) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_cc_copy_cache(context, cred->ccache, out);
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+#endif
+
+
+OM_uint32
+_gsskrb5_krb5_import_cred(OM_uint32 *minor_status,
+ krb5_ccache id,
+ krb5_principal keytab_principal,
+ krb5_keytab keytab,
+ gss_cred_id_t *cred)
+{
+ krb5_context context;
+ krb5_error_code kret;
+ gsskrb5_cred handle;
+ OM_uint32 ret;
+
+ *cred = NULL;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ handle = calloc(1, sizeof(*handle));
+ if (handle == NULL) {
+ _gsskrb5_clear_status ();
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
+
+ handle->usage = 0;
+
+ if (id) {
+ char *str;
+
+ handle->usage |= GSS_C_INITIATE;
+
+ kret = krb5_cc_get_principal(context, id,
+ &handle->principal);
+ if (kret) {
+ free(handle);
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ if (keytab_principal) {
+ krb5_boolean match;
+
+ match = krb5_principal_compare(context,
+ handle->principal,
+ keytab_principal);
+ if (match == FALSE) {
+ krb5_free_principal(context, handle->principal);
+ free(handle);
+ _gsskrb5_clear_status ();
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ ret = __gsskrb5_ccache_lifetime(minor_status,
+ context,
+ id,
+ handle->principal,
+ &handle->lifetime);
+ if (ret != GSS_S_COMPLETE) {
+ krb5_free_principal(context, handle->principal);
+ free(handle);
+ return ret;
+ }
+
+
+ kret = krb5_cc_get_full_name(context, id, &str);
+ if (kret)
+ goto out;
+
+ kret = krb5_cc_resolve(context, str, &handle->ccache);
+ free(str);
+ if (kret)
+ goto out;
+ }
+
+
+ if (keytab) {
+ char *str;
+
+ handle->usage |= GSS_C_ACCEPT;
+
+ if (keytab_principal && handle->principal == NULL) {
+ kret = krb5_copy_principal(context,
+ keytab_principal,
+ &handle->principal);
+ if (kret)
+ goto out;
+ }
+
+ kret = krb5_kt_get_full_name(context, keytab, &str);
+ if (kret)
+ goto out;
+
+ kret = krb5_kt_resolve(context, str, &handle->keytab);
+ free(str);
+ if (kret)
+ goto out;
+ }
+
+
+ if (id || keytab) {
+ ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
+ if (ret == GSS_S_COMPLETE)
+ ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &handle->mechanisms);
+ if (ret != GSS_S_COMPLETE) {
+ kret = *minor_status;
+ goto out;
+ }
+ }
+
+ *minor_status = 0;
+ *cred = (gss_cred_id_t)handle;
+ return GSS_S_COMPLETE;
+
+out:
+ gss_release_oid_set(minor_status, &handle->mechanisms);
+ if (handle->ccache)
+ krb5_cc_close(context, handle->ccache);
+ if (handle->keytab)
+ krb5_kt_close(context, handle->keytab);
+ if (handle->principal)
+ krb5_free_principal(context, handle->principal);
+ HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
+ free(handle);
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/creds.c b/crypto/heimdal/lib/gssapi/krb5/creds.c
new file mode 100644
index 0000000..fa45d19
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/creds.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2009 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_export_cred(OM_uint32 *minor_status,
+ gss_cred_id_t cred_handle,
+ gss_buffer_t cred_token)
+{
+ gsskrb5_cred handle = (gsskrb5_cred)cred_handle;
+ krb5_context context;
+ krb5_error_code ret;
+ krb5_storage *sp;
+ krb5_data data, mech;
+ const char *type;
+ char *str;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (handle->usage != GSS_C_INITIATE && handle->usage != GSS_C_BOTH) {
+ *minor_status = GSS_KRB5_S_G_BAD_USAGE;
+ return GSS_S_FAILURE;
+ }
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ type = krb5_cc_get_type(context, handle->ccache);
+ if (strcmp(type, "MEMORY") == 0) {
+ krb5_creds *creds;
+ ret = krb5_store_uint32(sp, 0);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = _krb5_get_krbtgt(context, handle->ccache,
+ handle->principal->realm,
+ &creds);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_store_creds(sp, creds);
+ krb5_free_creds(context, creds);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ } else {
+ ret = krb5_store_uint32(sp, 1);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_get_full_name(context, handle->ccache, &str);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_store_string(sp, str);
+ free(str);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ }
+ ret = krb5_storage_to_data(sp, &data);
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ krb5_data_free(&data);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ mech.data = GSS_KRB5_MECHANISM->elements;
+ mech.length = GSS_KRB5_MECHANISM->length;
+
+ ret = krb5_store_data(sp, mech);
+ if (ret) {
+ krb5_data_free(&data);
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_store_data(sp, data);
+ krb5_data_free(&data);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_storage_to_data(sp, &data);
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ cred_token->value = data.data;
+ cred_token->length = data.length;
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_import_cred(OM_uint32 * minor_status,
+ gss_buffer_t cred_token,
+ gss_cred_id_t * cred_handle)
+{
+ krb5_context context;
+ krb5_error_code ret;
+ gsskrb5_cred handle;
+ krb5_ccache id;
+ krb5_storage *sp;
+ char *str;
+ uint32_t type;
+ int flags = 0;
+
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ sp = krb5_storage_from_mem(cred_token->value, cred_token->length);
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_ret_uint32(sp, &type);
+ if (ret) {
+ krb5_storage_free(sp);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ switch (type) {
+ case 0: {
+ krb5_creds creds;
+
+ ret = krb5_ret_creds(sp, &creds);
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_new_unique(context, "MEMORY", NULL, &id);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_initialize(context, id, creds.client);
+ if (ret) {
+ krb5_cc_destroy(context, id);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_store_cred(context, id, &creds);
+ krb5_free_cred_contents(context, &creds);
+
+ flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
+
+ break;
+ }
+ case 1:
+ ret = krb5_ret_string(sp, &str);
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_resolve(context, str, &id);
+ krb5_xfree(str);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ break;
+
+ default:
+ krb5_storage_free(sp);
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ handle = calloc(1, sizeof(*handle));
+ if (handle == NULL) {
+ krb5_cc_close(context, id);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ handle->usage = GSS_C_INITIATE;
+ krb5_cc_get_principal(context, id, &handle->principal);
+ handle->ccache = id;
+ handle->cred_flags = flags;
+
+ *cred_handle = (gss_cred_id_t)handle;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/decapsulate.c b/crypto/heimdal/lib/gssapi/krb5/decapsulate.c
new file mode 100644
index 0000000..640c064
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/decapsulate.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+/*
+ * return the length of the mechanism in token or -1
+ * (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN
+ */
+
+ssize_t
+_gsskrb5_get_mech (const u_char *ptr,
+ size_t total_len,
+ const u_char **mech_ret)
+{
+ size_t len, len_len, mech_len, foo;
+ const u_char *p = ptr;
+ int e;
+
+ if (total_len < 1)
+ return -1;
+ if (*p++ != 0x60)
+ return -1;
+ e = der_get_length (p, total_len - 1, &len, &len_len);
+ if (e || 1 + len_len + len != total_len)
+ return -1;
+ p += len_len;
+ if (*p++ != 0x06)
+ return -1;
+ e = der_get_length (p, total_len - 1 - len_len - 1,
+ &mech_len, &foo);
+ if (e)
+ return -1;
+ p += foo;
+ *mech_ret = p;
+ return mech_len;
+}
+
+OM_uint32
+_gssapi_verify_mech_header(u_char **str,
+ size_t total_len,
+ gss_OID mech)
+{
+ const u_char *p;
+ ssize_t mech_len;
+
+ mech_len = _gsskrb5_get_mech (*str, total_len, &p);
+ if (mech_len < 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ if (mech_len != mech->length)
+ return GSS_S_BAD_MECH;
+ if (ct_memcmp(p,
+ mech->elements,
+ mech->length) != 0)
+ return GSS_S_BAD_MECH;
+ p += mech_len;
+ *str = rk_UNCONST(p);
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+_gsskrb5_verify_header(u_char **str,
+ size_t total_len,
+ const void *type,
+ gss_OID oid)
+{
+ OM_uint32 ret;
+ size_t len;
+ u_char *p = *str;
+
+ ret = _gssapi_verify_mech_header(str, total_len, oid);
+ if (ret)
+ return ret;
+
+ len = total_len - (*str - p);
+
+ if (len < 2)
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ if (ct_memcmp (*str, type, 2) != 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ *str += 2;
+
+ return 0;
+}
+
+/*
+ * Remove the GSS-API wrapping from `in_token' giving `out_data.
+ * Does not copy data, so just free `in_token'.
+ */
+
+OM_uint32
+_gssapi_decapsulate(
+ OM_uint32 *minor_status,
+ gss_buffer_t input_token_buffer,
+ krb5_data *out_data,
+ const gss_OID mech
+)
+{
+ u_char *p;
+ OM_uint32 ret;
+
+ p = input_token_buffer->value;
+ ret = _gssapi_verify_mech_header(&p,
+ input_token_buffer->length,
+ mech);
+ if (ret) {
+ *minor_status = 0;
+ return ret;
+ }
+
+ out_data->length = input_token_buffer->length -
+ (p - (u_char *)input_token_buffer->value);
+ out_data->data = p;
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * Remove the GSS-API wrapping from `in_token' giving `out_data.
+ * Does not copy data, so just free `in_token'.
+ */
+
+OM_uint32
+_gsskrb5_decapsulate(OM_uint32 *minor_status,
+ gss_buffer_t input_token_buffer,
+ krb5_data *out_data,
+ const void *type,
+ gss_OID oid)
+{
+ u_char *p;
+ OM_uint32 ret;
+
+ p = input_token_buffer->value;
+ ret = _gsskrb5_verify_header(&p,
+ input_token_buffer->length,
+ type,
+ oid);
+ if (ret) {
+ *minor_status = 0;
+ return ret;
+ }
+
+ out_data->length = input_token_buffer->length -
+ (p - (u_char *)input_token_buffer->value);
+ out_data->data = p;
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * Verify padding of a gss wrapped message and return its length.
+ */
+
+OM_uint32
+_gssapi_verify_pad(gss_buffer_t wrapped_token,
+ size_t datalen,
+ size_t *padlen)
+{
+ u_char *pad;
+ size_t padlength;
+ int i;
+
+ pad = (u_char *)wrapped_token->value + wrapped_token->length - 1;
+ padlength = *pad;
+
+ if (padlength > datalen)
+ return GSS_S_BAD_MECH;
+
+ for (i = padlength; i > 0 && *pad == padlength; i--, pad--)
+ ;
+ if (i != 0)
+ return GSS_S_BAD_MIC;
+
+ *padlen = padlength;
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/delete_sec_context.c b/crypto/heimdal/lib/gssapi/krb5/delete_sec_context.c
new file mode 100644
index 0000000..83a66cc
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/delete_sec_context.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_delete_sec_context(OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t output_token)
+{
+ krb5_context context;
+ gsskrb5_ctx ctx;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ *minor_status = 0;
+
+ if (output_token) {
+ output_token->length = 0;
+ output_token->value = NULL;
+ }
+
+ if (*context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_COMPLETE;
+
+ ctx = (gsskrb5_ctx) *context_handle;
+ *context_handle = GSS_C_NO_CONTEXT;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ krb5_auth_con_free (context, ctx->auth_context);
+ krb5_auth_con_free (context, ctx->deleg_auth_context);
+ if (ctx->kcred)
+ krb5_free_creds(context, ctx->kcred);
+ if(ctx->source)
+ krb5_free_principal (context, ctx->source);
+ if(ctx->target)
+ krb5_free_principal (context, ctx->target);
+ if (ctx->ticket)
+ krb5_free_ticket (context, ctx->ticket);
+ if(ctx->order)
+ _gssapi_msg_order_destroy(&ctx->order);
+ if (ctx->service_keyblock)
+ krb5_free_keyblock (context, ctx->service_keyblock);
+ krb5_data_free(&ctx->fwd_data);
+ if (ctx->crypto)
+ krb5_crypto_destroy(context, ctx->crypto);
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+ memset(ctx, 0, sizeof(*ctx));
+ free (ctx);
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/display_name.c b/crypto/heimdal/lib/gssapi/krb5/display_name.c
new file mode 100644
index 0000000..a296399
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/display_name.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_display_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t output_name_buffer,
+ gss_OID * output_name_type
+ )
+{
+ krb5_context context;
+ krb5_const_principal name = (krb5_const_principal)input_name;
+ krb5_error_code kret;
+ char *buf;
+ size_t len;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ kret = krb5_unparse_name_flags (context, name,
+ KRB5_PRINCIPAL_UNPARSE_DISPLAY, &buf);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ len = strlen (buf);
+ output_name_buffer->length = len;
+ output_name_buffer->value = malloc(len + 1);
+ if (output_name_buffer->value == NULL) {
+ free (buf);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy (output_name_buffer->value, buf, len);
+ ((char *)output_name_buffer->value)[len] = '\0';
+ free (buf);
+ if (output_name_type)
+ *output_name_type = GSS_KRB5_NT_PRINCIPAL_NAME;
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/display_status.c b/crypto/heimdal/lib/gssapi/krb5/display_status.c
new file mode 100644
index 0000000..c502006
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/display_status.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 1998 - 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+static const char *
+calling_error(OM_uint32 v)
+{
+ static const char *msgs[] = {
+ NULL, /* 0 */
+ "A required input parameter could not be read.", /* */
+ "A required output parameter could not be written.", /* */
+ "A parameter was malformed"
+ };
+
+ v >>= GSS_C_CALLING_ERROR_OFFSET;
+
+ if (v == 0)
+ return "";
+ else if (v >= sizeof(msgs)/sizeof(*msgs))
+ return "unknown calling error";
+ else
+ return msgs[v];
+}
+
+static const char *
+routine_error(OM_uint32 v)
+{
+ static const char *msgs[] = {
+ NULL, /* 0 */
+ "An unsupported mechanism was requested",
+ "An invalid name was supplied",
+ "A supplied name was of an unsupported type",
+ "Incorrect channel bindings were supplied",
+ "An invalid status code was supplied",
+ "A token had an invalid MIC",
+ "No credentials were supplied, "
+ "or the credentials were unavailable or inaccessible.",
+ "No context has been established",
+ "A token was invalid",
+ "A credential was invalid",
+ "The referenced credentials have expired",
+ "The context has expired",
+ "Miscellaneous failure (see text)",
+ "The quality-of-protection requested could not be provide",
+ "The operation is forbidden by local security policy",
+ "The operation or option is not available",
+ "The requested credential element already exists",
+ "The provided name was not a mechanism name.",
+ };
+
+ v >>= GSS_C_ROUTINE_ERROR_OFFSET;
+
+ if (v == 0)
+ return "";
+ else if (v >= sizeof(msgs)/sizeof(*msgs))
+ return "unknown routine error";
+ else
+ return msgs[v];
+}
+
+static const char *
+supplementary_error(OM_uint32 v)
+{
+ static const char *msgs[] = {
+ "normal completion",
+ "continuation call to routine required",
+ "duplicate per-message token detected",
+ "timed-out per-message token detected",
+ "reordered (early) per-message token detected",
+ "skipped predecessor token(s) detected"
+ };
+
+ v >>= GSS_C_SUPPLEMENTARY_OFFSET;
+
+ if (v >= sizeof(msgs)/sizeof(*msgs))
+ return "unknown routine error";
+ else
+ return msgs[v];
+}
+
+void
+_gsskrb5_clear_status (void)
+{
+ krb5_context context;
+
+ if (_gsskrb5_init (&context) != 0)
+ return;
+ krb5_clear_error_message(context);
+}
+
+void
+_gsskrb5_set_status (int ret, const char *fmt, ...)
+{
+ krb5_context context;
+ va_list args;
+ char *str;
+ int e;
+
+ if (_gsskrb5_init (&context) != 0)
+ return;
+
+ va_start(args, fmt);
+ e = vasprintf(&str, fmt, args);
+ va_end(args);
+ if (e >= 0 && str) {
+ krb5_set_error_message(context, ret, "%s", str);
+ free(str);
+ }
+}
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_display_status
+(OM_uint32 *minor_status,
+ OM_uint32 status_value,
+ int status_type,
+ const gss_OID mech_type,
+ OM_uint32 *message_context,
+ gss_buffer_t status_string)
+{
+ krb5_context context;
+ char *buf = NULL;
+ int e = 0;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ status_string->length = 0;
+ status_string->value = NULL;
+
+ if (gss_oid_equal(mech_type, GSS_C_NO_OID) == 0 &&
+ gss_oid_equal(mech_type, GSS_KRB5_MECHANISM) == 0) {
+ *minor_status = 0;
+ return GSS_C_GSS_CODE;
+ }
+
+ if (status_type == GSS_C_GSS_CODE) {
+ if (GSS_SUPPLEMENTARY_INFO(status_value))
+ e = asprintf(&buf, "%s",
+ supplementary_error(GSS_SUPPLEMENTARY_INFO(status_value)));
+ else
+ e = asprintf (&buf, "%s %s",
+ calling_error(GSS_CALLING_ERROR(status_value)),
+ routine_error(GSS_ROUTINE_ERROR(status_value)));
+ } else if (status_type == GSS_C_MECH_CODE) {
+ const char *buf2 = krb5_get_error_message(context, status_value);
+ if (buf2) {
+ buf = strdup(buf2);
+ krb5_free_error_message(context, buf2);
+ } else {
+ e = asprintf(&buf, "unknown mech error-code %u",
+ (unsigned)status_value);
+ }
+ } else {
+ *minor_status = EINVAL;
+ return GSS_S_BAD_STATUS;
+ }
+
+ if (e < 0 || buf == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ *message_context = 0;
+ *minor_status = 0;
+
+ status_string->length = strlen(buf);
+ status_string->value = buf;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/duplicate_name.c b/crypto/heimdal/lib/gssapi/krb5/duplicate_name.c
new file mode 100644
index 0000000..0bc57e8
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/duplicate_name.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_duplicate_name (
+ OM_uint32 * minor_status,
+ const gss_name_t src_name,
+ gss_name_t * dest_name
+ )
+{
+ krb5_const_principal src = (krb5_const_principal)src_name;
+ krb5_context context;
+ krb5_principal dest;
+ krb5_error_code kret;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ kret = krb5_copy_principal (context, src, &dest);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ } else {
+ *dest_name = (gss_name_t)dest;
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ }
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/encapsulate.c b/crypto/heimdal/lib/gssapi/krb5/encapsulate.c
new file mode 100644
index 0000000..fe5dac7
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/encapsulate.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+void
+_gssapi_encap_length (size_t data_len,
+ size_t *len,
+ size_t *total_len,
+ const gss_OID mech)
+{
+ size_t len_len;
+
+ *len = 1 + 1 + mech->length + data_len;
+
+ len_len = der_length_len(*len);
+
+ *total_len = 1 + len_len + *len;
+}
+
+void
+_gsskrb5_encap_length (size_t data_len,
+ size_t *len,
+ size_t *total_len,
+ const gss_OID mech)
+{
+ _gssapi_encap_length(data_len + 2, len, total_len, mech);
+}
+
+void *
+_gsskrb5_make_header (void *ptr,
+ size_t len,
+ const void *type,
+ const gss_OID mech)
+{
+ u_char *p = ptr;
+ p = _gssapi_make_mech_header(p, len, mech);
+ memcpy (p, type, 2);
+ p += 2;
+ return p;
+}
+
+void *
+_gssapi_make_mech_header(void *ptr,
+ size_t len,
+ const gss_OID mech)
+{
+ u_char *p = ptr;
+ int e;
+ size_t len_len, foo;
+
+ *p++ = 0x60;
+ len_len = der_length_len(len);
+ e = der_put_length (p + len_len - 1, len_len, len, &foo);
+ if(e || foo != len_len)
+ abort ();
+ p += len_len;
+ *p++ = 0x06;
+ *p++ = mech->length;
+ memcpy (p, mech->elements, mech->length);
+ p += mech->length;
+ return p;
+}
+
+/*
+ * Give it a krb5_data and it will encapsulate with extra GSS-API wrappings.
+ */
+
+OM_uint32
+_gssapi_encapsulate(
+ OM_uint32 *minor_status,
+ const krb5_data *in_data,
+ gss_buffer_t output_token,
+ const gss_OID mech
+)
+{
+ size_t len, outer_len;
+ void *p;
+
+ _gssapi_encap_length (in_data->length, &len, &outer_len, mech);
+
+ output_token->length = outer_len;
+ output_token->value = malloc (outer_len);
+ if (output_token->value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ p = _gssapi_make_mech_header (output_token->value, len, mech);
+ memcpy (p, in_data->data, in_data->length);
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * Give it a krb5_data and it will encapsulate with extra GSS-API krb5
+ * wrappings.
+ */
+
+OM_uint32
+_gsskrb5_encapsulate(
+ OM_uint32 *minor_status,
+ const krb5_data *in_data,
+ gss_buffer_t output_token,
+ const void *type,
+ const gss_OID mech
+)
+{
+ size_t len, outer_len;
+ u_char *p;
+
+ _gsskrb5_encap_length (in_data->length, &len, &outer_len, mech);
+
+ output_token->length = outer_len;
+ output_token->value = malloc (outer_len);
+ if (output_token->value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ p = _gsskrb5_make_header (output_token->value, len, type, mech);
+ memcpy (p, in_data->data, in_data->length);
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/export_name.c b/crypto/heimdal/lib/gssapi/krb5/export_name.c
new file mode 100644
index 0000000..32368d3
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/export_name.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1997, 1999, 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_export_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t exported_name
+ )
+{
+ krb5_context context;
+ krb5_const_principal princ = (krb5_const_principal)input_name;
+ krb5_error_code kret;
+ char *buf, *name;
+ size_t len;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ kret = krb5_unparse_name (context, princ, &name);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ len = strlen (name);
+
+ exported_name->length = 10 + len + GSS_KRB5_MECHANISM->length;
+ exported_name->value = malloc(exported_name->length);
+ if (exported_name->value == NULL) {
+ free (name);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ /* TOK, MECH_OID_LEN, DER(MECH_OID), NAME_LEN, NAME */
+
+ buf = exported_name->value;
+ memcpy(buf, "\x04\x01", 2);
+ buf += 2;
+ buf[0] = ((GSS_KRB5_MECHANISM->length + 2) >> 8) & 0xff;
+ buf[1] = (GSS_KRB5_MECHANISM->length + 2) & 0xff;
+ buf+= 2;
+ buf[0] = 0x06;
+ buf[1] = (GSS_KRB5_MECHANISM->length) & 0xFF;
+ buf+= 2;
+
+ memcpy(buf, GSS_KRB5_MECHANISM->elements, GSS_KRB5_MECHANISM->length);
+ buf += GSS_KRB5_MECHANISM->length;
+
+ buf[0] = (len >> 24) & 0xff;
+ buf[1] = (len >> 16) & 0xff;
+ buf[2] = (len >> 8) & 0xff;
+ buf[3] = (len) & 0xff;
+ buf += 4;
+
+ memcpy (buf, name, len);
+
+ free (name);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/export_sec_context.c b/crypto/heimdal/lib/gssapi/krb5/export_sec_context.c
new file mode 100644
index 0000000..eeb2743
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/export_sec_context.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 1999 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_export_sec_context (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t interprocess_token
+ )
+{
+ krb5_context context;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) *context_handle;
+ krb5_storage *sp;
+ krb5_auth_context ac;
+ OM_uint32 ret = GSS_S_COMPLETE;
+ krb5_data data;
+ gss_buffer_desc buffer;
+ int flags;
+ OM_uint32 minor;
+ krb5_error_code kret;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ if (!(ctx->flags & GSS_C_TRANS_FLAG)) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ *minor_status = 0;
+ return GSS_S_UNAVAILABLE;
+ }
+
+ sp = krb5_storage_emem ();
+ if (sp == NULL) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ ac = ctx->auth_context;
+
+ /* flagging included fields */
+
+ flags = 0;
+ if (ac->local_address)
+ flags |= SC_LOCAL_ADDRESS;
+ if (ac->remote_address)
+ flags |= SC_REMOTE_ADDRESS;
+ if (ac->keyblock)
+ flags |= SC_KEYBLOCK;
+ if (ac->local_subkey)
+ flags |= SC_LOCAL_SUBKEY;
+ if (ac->remote_subkey)
+ flags |= SC_REMOTE_SUBKEY;
+
+ kret = krb5_store_int32 (sp, flags);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ /* marshall auth context */
+
+ kret = krb5_store_int32 (sp, ac->flags);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ if (ac->local_address) {
+ kret = krb5_store_address (sp, *ac->local_address);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+ if (ac->remote_address) {
+ kret = krb5_store_address (sp, *ac->remote_address);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+ kret = krb5_store_int16 (sp, ac->local_port);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ kret = krb5_store_int16 (sp, ac->remote_port);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ if (ac->keyblock) {
+ kret = krb5_store_keyblock (sp, *ac->keyblock);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+ if (ac->local_subkey) {
+ kret = krb5_store_keyblock (sp, *ac->local_subkey);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+ if (ac->remote_subkey) {
+ kret = krb5_store_keyblock (sp, *ac->remote_subkey);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ }
+ kret = krb5_store_int32 (sp, ac->local_seqnumber);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ kret = krb5_store_int32 (sp, ac->remote_seqnumber);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ kret = krb5_store_int32 (sp, ac->keytype);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ kret = krb5_store_int32 (sp, ac->cksumtype);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ /* names */
+
+ ret = _gsskrb5_export_name (minor_status,
+ (gss_name_t)ctx->source, &buffer);
+ if (ret)
+ goto failure;
+ data.data = buffer.value;
+ data.length = buffer.length;
+ kret = krb5_store_data (sp, data);
+ _gsskrb5_release_buffer (&minor, &buffer);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ ret = _gsskrb5_export_name (minor_status,
+ (gss_name_t)ctx->target, &buffer);
+ if (ret)
+ goto failure;
+ data.data = buffer.value;
+ data.length = buffer.length;
+
+ ret = GSS_S_FAILURE;
+
+ kret = krb5_store_data (sp, data);
+ _gsskrb5_release_buffer (&minor, &buffer);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ kret = krb5_store_int32 (sp, ctx->flags);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ kret = krb5_store_int32 (sp, ctx->more_flags);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ kret = krb5_store_int32 (sp, ctx->lifetime);
+ if (kret) {
+ *minor_status = kret;
+ goto failure;
+ }
+ kret = _gssapi_msg_order_export(sp, ctx->order);
+ if (kret ) {
+ *minor_status = kret;
+ goto failure;
+ }
+
+ kret = krb5_storage_to_data (sp, &data);
+ krb5_storage_free (sp);
+ if (kret) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ interprocess_token->length = data.length;
+ interprocess_token->value = data.data;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5_delete_sec_context (minor_status, context_handle,
+ GSS_C_NO_BUFFER);
+ if (ret != GSS_S_COMPLETE)
+ _gsskrb5_release_buffer (NULL, interprocess_token);
+ *minor_status = 0;
+ return ret;
+ failure:
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ krb5_storage_free (sp);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/external.c b/crypto/heimdal/lib/gssapi/krb5/external.c
new file mode 100644
index 0000000..60a9f75
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/external.c
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+#include <gssapi_mech.h>
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x01"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_user_name_oid_desc =
+ {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x01")};
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_machine_uid_name_oid_desc =
+ {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x02")};
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x03"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_string_uid_name_oid_desc =
+ {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x03")};
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) org(3) dod(6) internet(1) security(5)
+ * nametypes(6) gss-host-based-services(2)). The constant
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
+ * to that gss_OID_desc. This is a deprecated OID value, and
+ * implementations wishing to support hostbased-service names
+ * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
+ * defined below, to identify such names;
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
+ * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
+ * parameter, but should not be emitted by GSS-API
+ * implementations
+ */
+
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_hostbased_service_x_oid_desc =
+ {6, rk_UNCONST("\x2b\x06\x01\x05\x06\x02")};
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x04"}, corresponding to an
+ * object-identifier value of {iso(1) member-body(2)
+ * Unites States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) service_name(4)}. The constant
+ * GSS_C_NT_HOSTBASED_SERVICE should be initialized
+ * to point to that gss_OID_desc.
+ */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_hostbased_service_oid_desc =
+ {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x04")};
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ * corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_anonymous_oid_desc =
+ {6, rk_UNCONST("\x2b\x06\01\x05\x06\x03")};
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_export_name_oid_desc =
+ {6, rk_UNCONST("\x2b\x06\x01\x05\x06\x04") };
+
+/*
+ * This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * krb5(2) krb5_name(1)}. The recommended symbolic name for this type
+ * is "GSS_KRB5_NT_PRINCIPAL_NAME".
+ */
+
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_nt_principal_name_oid_desc =
+ {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01") };
+
+/*
+ * draft-ietf-cat-iakerb-09, IAKERB:
+ * The mechanism ID for IAKERB proxy GSS-API Kerberos, in accordance
+ * with the mechanism proposed by SPNEGO [7] for negotiating protocol
+ * variations, is: {iso(1) org(3) dod(6) internet(1) security(5)
+ * mechanisms(5) iakerb(10) iakerbProxyProtocol(1)}. The proposed
+ * mechanism ID for IAKERB minimum messages GSS-API Kerberos, in
+ * accordance with the mechanism proposed by SPNEGO for negotiating
+ * protocol variations, is: {iso(1) org(3) dod(6) internet(1)
+ * security(5) mechanisms(5) iakerb(10)
+ * iakerbMinimumMessagesProtocol(2)}.
+ */
+
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_iakerb_proxy_mechanism_oid_desc =
+ {7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x01")};
+
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_iakerb_min_msg_mechanism_oid_desc =
+ {7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x02") };
+
+/*
+ * Context for krb5 calls.
+ */
+
+#if 0
+static gss_mo_desc krb5_mo[] = {
+ {
+ GSS_C_MA_SASL_MECH_NAME,
+ GSS_MO_MA,
+ "SASL mech name",
+ rk_UNCONST("GS2-KRB5"),
+ _gss_mo_get_ctx_as_string,
+ NULL
+ },
+ {
+ GSS_C_MA_MECH_NAME,
+ GSS_MO_MA,
+ "Mechanism name",
+ rk_UNCONST("KRB5"),
+ _gss_mo_get_ctx_as_string,
+ NULL
+ },
+ {
+ GSS_C_MA_MECH_DESCRIPTION,
+ GSS_MO_MA,
+ "Mechanism description",
+ rk_UNCONST("Heimdal Kerberos 5 mech"),
+ _gss_mo_get_ctx_as_string,
+ NULL
+ },
+ {
+ GSS_C_MA_MECH_CONCRETE,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_ITOK_FRAMED,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_AUTH_INIT,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_AUTH_TARG,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_AUTH_INIT_ANON,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_DELEG_CRED,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_INTEG_PROT,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_CONF_PROT,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_MIC,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_WRAP,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_PROT_READY,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_REPLAY_DET,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_OOS_DET,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_CBINDINGS,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_PFS,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_CTX_TRANS,
+ GSS_MO_MA
+ }
+};
+#endif
+
+/*
+ *
+ */
+
+static gssapi_mech_interface_desc krb5_mech = {
+ GMI_VERSION,
+ "kerberos 5",
+ {9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") },
+ 0,
+ _gsskrb5_acquire_cred,
+ _gsskrb5_release_cred,
+ _gsskrb5_init_sec_context,
+ _gsskrb5_accept_sec_context,
+ _gsskrb5_process_context_token,
+ _gsskrb5_delete_sec_context,
+ _gsskrb5_context_time,
+ _gsskrb5_get_mic,
+ _gsskrb5_verify_mic,
+ _gsskrb5_wrap,
+ _gsskrb5_unwrap,
+ _gsskrb5_display_status,
+ _gsskrb5_indicate_mechs,
+ _gsskrb5_compare_name,
+ _gsskrb5_display_name,
+ _gsskrb5_import_name,
+ _gsskrb5_export_name,
+ _gsskrb5_release_name,
+ _gsskrb5_inquire_cred,
+ _gsskrb5_inquire_context,
+ _gsskrb5_wrap_size_limit,
+ _gsskrb5_add_cred,
+ _gsskrb5_inquire_cred_by_mech,
+ _gsskrb5_export_sec_context,
+ _gsskrb5_import_sec_context,
+ _gsskrb5_inquire_names_for_mech,
+ _gsskrb5_inquire_mechs_for_name,
+ _gsskrb5_canonicalize_name,
+ _gsskrb5_duplicate_name,
+ _gsskrb5_inquire_sec_context_by_oid,
+ _gsskrb5_inquire_cred_by_oid,
+ _gsskrb5_set_sec_context_option,
+ _gsskrb5_set_cred_option,
+ _gsskrb5_pseudo_random,
+#if 0
+ _gk_wrap_iov,
+ _gk_unwrap_iov,
+ _gk_wrap_iov_length,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+ _gsskrb5_store_cred,
+ _gsskrb5_export_cred,
+ _gsskrb5_import_cred,
+ _gsskrb5_acquire_cred_ext,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#if 0
+ krb5_mo,
+ sizeof(krb5_mo) / sizeof(krb5_mo[0]),
+#else
+ NULL,
+ 0,
+#endif
+ _gsskrb5_pname_to_uid,
+ _gsskrb5_authorize_localname,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+gssapi_mech_interface
+__gss_krb5_initialize(void)
+{
+ return &krb5_mech;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/get_mic.c b/crypto/heimdal/lib/gssapi/krb5/get_mic.c
new file mode 100644
index 0000000..0109ca7
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/get_mic.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+#ifdef HEIM_WEAK_CRYPTO
+
+static OM_uint32
+mic_des
+ (OM_uint32 * minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ gss_qop_t qop_req,
+ const gss_buffer_t message_buffer,
+ gss_buffer_t message_token,
+ krb5_keyblock *key
+ )
+{
+ u_char *p;
+ EVP_MD_CTX *md5;
+ u_char hash[16];
+ DES_key_schedule schedule;
+ EVP_CIPHER_CTX des_ctx;
+ DES_cblock deskey;
+ DES_cblock zero;
+ int32_t seq_number;
+ size_t len, total_len;
+
+ _gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
+
+ message_token->length = total_len;
+ message_token->value = malloc (total_len);
+ if (message_token->value == NULL) {
+ message_token->length = 0;
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ p = _gsskrb5_make_header(message_token->value,
+ len,
+ "\x01\x01", /* TOK_ID */
+ GSS_KRB5_MECHANISM);
+
+ memcpy (p, "\x00\x00", 2); /* SGN_ALG = DES MAC MD5 */
+ p += 2;
+
+ memcpy (p, "\xff\xff\xff\xff", 4); /* Filler */
+ p += 4;
+
+ /* Fill in later (SND-SEQ) */
+ memset (p, 0, 16);
+ p += 16;
+
+ /* checksum */
+ md5 = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(md5, EVP_md5(), NULL);
+ EVP_DigestUpdate(md5, p - 24, 8);
+ EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length);
+ EVP_DigestFinal_ex(md5, hash, NULL);
+ EVP_MD_CTX_destroy(md5);
+
+ memset (&zero, 0, sizeof(zero));
+ memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
+ DES_set_key_unchecked (&deskey, &schedule);
+ DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
+ &schedule, &zero);
+ memcpy (p - 8, hash, 8); /* SGN_CKSUM */
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ /* sequence number */
+ krb5_auth_con_getlocalseqnumber (context,
+ ctx->auth_context,
+ &seq_number);
+
+ p -= 16; /* SND_SEQ */
+ p[0] = (seq_number >> 0) & 0xFF;
+ p[1] = (seq_number >> 8) & 0xFF;
+ p[2] = (seq_number >> 16) & 0xFF;
+ p[3] = (seq_number >> 24) & 0xFF;
+ memset (p + 4,
+ (ctx->more_flags & LOCAL) ? 0 : 0xFF,
+ 4);
+
+ EVP_CIPHER_CTX_init(&des_ctx);
+ EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
+ EVP_Cipher(&des_ctx, p, p, 8);
+ EVP_CIPHER_CTX_cleanup(&des_ctx);
+
+ krb5_auth_con_setlocalseqnumber (context,
+ ctx->auth_context,
+ ++seq_number);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ memset (deskey, 0, sizeof(deskey));
+ memset (&schedule, 0, sizeof(schedule));
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+#endif
+
+static OM_uint32
+mic_des3
+ (OM_uint32 * minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ gss_qop_t qop_req,
+ const gss_buffer_t message_buffer,
+ gss_buffer_t message_token,
+ krb5_keyblock *key
+ )
+{
+ u_char *p;
+ Checksum cksum;
+ u_char seq[8];
+
+ int32_t seq_number;
+ size_t len, total_len;
+
+ krb5_crypto crypto;
+ krb5_error_code kret;
+ krb5_data encdata;
+ char *tmp;
+ char ivec[8];
+
+ _gsskrb5_encap_length (36, &len, &total_len, GSS_KRB5_MECHANISM);
+
+ message_token->length = total_len;
+ message_token->value = malloc (total_len);
+ if (message_token->value == NULL) {
+ message_token->length = 0;
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ p = _gsskrb5_make_header(message_token->value,
+ len,
+ "\x01\x01", /* TOK-ID */
+ GSS_KRB5_MECHANISM);
+
+ memcpy (p, "\x04\x00", 2); /* SGN_ALG = HMAC SHA1 DES3-KD */
+ p += 2;
+
+ memcpy (p, "\xff\xff\xff\xff", 4); /* filler */
+ p += 4;
+
+ /* this should be done in parts */
+
+ tmp = malloc (message_buffer->length + 8);
+ if (tmp == NULL) {
+ free (message_token->value);
+ message_token->value = NULL;
+ message_token->length = 0;
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy (tmp, p - 8, 8);
+ memcpy (tmp + 8, message_buffer->value, message_buffer->length);
+
+ kret = krb5_crypto_init(context, key, 0, &crypto);
+ if (kret) {
+ free (message_token->value);
+ message_token->value = NULL;
+ message_token->length = 0;
+ free (tmp);
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_create_checksum (context,
+ crypto,
+ KRB5_KU_USAGE_SIGN,
+ 0,
+ tmp,
+ message_buffer->length + 8,
+ &cksum);
+ free (tmp);
+ krb5_crypto_destroy (context, crypto);
+ if (kret) {
+ free (message_token->value);
+ message_token->value = NULL;
+ message_token->length = 0;
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ memcpy (p + 8, cksum.checksum.data, cksum.checksum.length);
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ /* sequence number */
+ krb5_auth_con_getlocalseqnumber (context,
+ ctx->auth_context,
+ &seq_number);
+
+ seq[0] = (seq_number >> 0) & 0xFF;
+ seq[1] = (seq_number >> 8) & 0xFF;
+ seq[2] = (seq_number >> 16) & 0xFF;
+ seq[3] = (seq_number >> 24) & 0xFF;
+ memset (seq + 4,
+ (ctx->more_flags & LOCAL) ? 0 : 0xFF,
+ 4);
+
+ kret = krb5_crypto_init(context, key,
+ ETYPE_DES3_CBC_NONE, &crypto);
+ if (kret) {
+ free (message_token->value);
+ message_token->value = NULL;
+ message_token->length = 0;
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ if (ctx->more_flags & COMPAT_OLD_DES3)
+ memset(ivec, 0, 8);
+ else
+ memcpy(ivec, p + 8, 8);
+
+ kret = krb5_encrypt_ivec (context,
+ crypto,
+ KRB5_KU_USAGE_SEQ,
+ seq, 8, &encdata, ivec);
+ krb5_crypto_destroy (context, crypto);
+ if (kret) {
+ free (message_token->value);
+ message_token->value = NULL;
+ message_token->length = 0;
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ assert (encdata.length == 8);
+
+ memcpy (p, encdata.data, encdata.length);
+ krb5_data_free (&encdata);
+
+ krb5_auth_con_setlocalseqnumber (context,
+ ctx->auth_context,
+ ++seq_number);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ free_Checksum (&cksum);
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_qop_t qop_req,
+ const gss_buffer_t message_buffer,
+ gss_buffer_t message_token
+ )
+{
+ krb5_context context;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+ krb5_keyblock *key;
+ OM_uint32 ret;
+ krb5_keytype keytype;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_mic_cfx (minor_status, ctx, context, qop_req,
+ message_buffer, message_token);
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(ctx, context, &key);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ krb5_enctype_to_keytype (context, key->keytype, &keytype);
+
+ switch (keytype) {
+ case KEYTYPE_DES :
+#ifdef HEIM_WEAK_CRYPTO
+ ret = mic_des (minor_status, ctx, context, qop_req,
+ message_buffer, message_token, key);
+#else
+ ret = GSS_S_FAILURE;
+#endif
+ break;
+ case KEYTYPE_DES3 :
+ ret = mic_des3 (minor_status, ctx, context, qop_req,
+ message_buffer, message_token, key);
+ break;
+ case KEYTYPE_ARCFOUR:
+ case KEYTYPE_ARCFOUR_56:
+ ret = _gssapi_get_mic_arcfour (minor_status, ctx, context, qop_req,
+ message_buffer, message_token, key);
+ break;
+ default :
+ abort();
+ break;
+ }
+ krb5_free_keyblock (context, key);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/gkrb5_err.et b/crypto/heimdal/lib/gssapi/krb5/gkrb5_err.et
new file mode 100644
index 0000000..3c23412
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/gkrb5_err.et
@@ -0,0 +1,31 @@
+#
+# extended gss krb5 error messages
+#
+
+id "$Id$"
+
+error_table gk5
+
+prefix GSS_KRB5_S
+
+error_code G_BAD_SERVICE_NAME, "No @ in SERVICE-NAME name string"
+error_code G_BAD_STRING_UID, "STRING-UID-NAME contains nondigits"
+error_code G_NOUSER, "UID does not resolve to username"
+error_code G_VALIDATE_FAILED, "Validation error"
+error_code G_BUFFER_ALLOC, "Couldn't allocate gss_buffer_t data"
+error_code G_BAD_MSG_CTX, "Message context invalid"
+error_code G_WRONG_SIZE, "Buffer is the wrong size"
+error_code G_BAD_USAGE, "Credential usage type is unknown"
+error_code G_UNKNOWN_QOP, "Unknown quality of protection specified"
+
+index 128
+
+error_code KG_CCACHE_NOMATCH, "Principal in credential cache does not match desired name"
+error_code KG_KEYTAB_NOMATCH, "No principal in keytab matches desired name"
+error_code KG_TGT_MISSING, "Credential cache has no TGT"
+error_code KG_NO_SUBKEY, "Authenticator has no subkey"
+error_code KG_CONTEXT_ESTABLISHED, "Context is already fully established"
+error_code KG_BAD_SIGN_TYPE, "Unknown signature type in token"
+error_code KG_BAD_LENGTH, "Invalid field length in token"
+error_code KG_CTX_INCOMPLETE, "Attempt to use incomplete security context"
+error_code KG_INPUT_TOO_LONG, "Input too long"
diff --git a/crypto/heimdal/lib/gssapi/krb5/gsskrb5-private.h b/crypto/heimdal/lib/gssapi/krb5/gsskrb5-private.h
new file mode 100644
index 0000000..2a669d86
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/gsskrb5-private.h
@@ -0,0 +1,796 @@
+/* This is a generated file */
+#ifndef __gsskrb5_private_h__
+#define __gsskrb5_private_h__
+
+#include <stdarg.h>
+
+gssapi_mech_interface
+__gss_krb5_initialize (void);
+
+OM_uint32
+__gsskrb5_ccache_lifetime (
+ OM_uint32 */*minor_status*/,
+ krb5_context /*context*/,
+ krb5_ccache /*id*/,
+ krb5_principal /*principal*/,
+ OM_uint32 */*lifetime*/);
+
+OM_uint32
+_gk_allocate_buffer (
+ OM_uint32 */*minor_status*/,
+ gss_iov_buffer_desc */*buffer*/,
+ size_t /*size*/);
+
+gss_iov_buffer_desc *
+_gk_find_buffer (
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/,
+ OM_uint32 /*type*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gk_unwrap_iov (
+ OM_uint32 */*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int */*conf_state*/,
+ gss_qop_t */*qop_state*/,
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/);
+
+OM_uint32
+_gk_verify_buffers (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*ctx*/,
+ const gss_iov_buffer_desc */*header*/,
+ const gss_iov_buffer_desc */*padding*/,
+ const gss_iov_buffer_desc */*trailer*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gk_wrap_iov (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ int * /*conf_state*/,
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gk_wrap_iov_length (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ int */*conf_state*/,
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/);
+
+OM_uint32
+_gss_DES3_get_mic_compat (
+ OM_uint32 */*minor_status*/,
+ gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/);
+
+OM_uint32
+_gssapi_decapsulate (
+ OM_uint32 */*minor_status*/,
+ gss_buffer_t /*input_token_buffer*/,
+ krb5_data */*out_data*/,
+ const gss_OID mech );
+
+void
+_gssapi_encap_length (
+ size_t /*data_len*/,
+ size_t */*len*/,
+ size_t */*total_len*/,
+ const gss_OID /*mech*/);
+
+OM_uint32
+_gssapi_encapsulate (
+ OM_uint32 */*minor_status*/,
+ const krb5_data */*in_data*/,
+ gss_buffer_t /*output_token*/,
+ const gss_OID mech );
+
+OM_uint32
+_gssapi_get_mic_arcfour (
+ OM_uint32 * /*minor_status*/,
+ const gsskrb5_ctx /*context_handle*/,
+ krb5_context /*context*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*message_buffer*/,
+ gss_buffer_t /*message_token*/,
+ krb5_keyblock */*key*/);
+
+void *
+_gssapi_make_mech_header (
+ void */*ptr*/,
+ size_t /*len*/,
+ const gss_OID /*mech*/);
+
+OM_uint32
+_gssapi_mic_cfx (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*message_buffer*/,
+ gss_buffer_t /*message_token*/);
+
+OM_uint32
+_gssapi_msg_order_check (
+ struct gss_msg_order */*o*/,
+ OM_uint32 /*seq_num*/);
+
+OM_uint32
+_gssapi_msg_order_create (
+ OM_uint32 */*minor_status*/,
+ struct gss_msg_order **/*o*/,
+ OM_uint32 /*flags*/,
+ OM_uint32 /*seq_num*/,
+ OM_uint32 /*jitter_window*/,
+ int /*use_64*/);
+
+OM_uint32
+_gssapi_msg_order_destroy (struct gss_msg_order **/*m*/);
+
+krb5_error_code
+_gssapi_msg_order_export (
+ krb5_storage */*sp*/,
+ struct gss_msg_order */*o*/);
+
+OM_uint32
+_gssapi_msg_order_f (OM_uint32 /*flags*/);
+
+OM_uint32
+_gssapi_msg_order_import (
+ OM_uint32 */*minor_status*/,
+ krb5_storage */*sp*/,
+ struct gss_msg_order **/*o*/);
+
+OM_uint32
+_gssapi_unwrap_arcfour (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*context_handle*/,
+ krb5_context /*context*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ gss_buffer_t /*output_message_buffer*/,
+ int */*conf_state*/,
+ gss_qop_t */*qop_state*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
+_gssapi_unwrap_cfx (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ gss_buffer_t /*output_message_buffer*/,
+ int */*conf_state*/,
+ gss_qop_t */*qop_state*/);
+
+OM_uint32
+_gssapi_unwrap_cfx_iov (
+ OM_uint32 */*minor_status*/,
+ gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ int */*conf_state*/,
+ gss_qop_t */*qop_state*/,
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/);
+
+OM_uint32
+_gssapi_verify_mech_header (
+ u_char **/*str*/,
+ size_t /*total_len*/,
+ gss_OID /*mech*/);
+
+OM_uint32
+_gssapi_verify_mic_arcfour (
+ OM_uint32 * /*minor_status*/,
+ const gsskrb5_ctx /*context_handle*/,
+ krb5_context /*context*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t * /*qop_state*/,
+ krb5_keyblock */*key*/,
+ const char */*type*/);
+
+OM_uint32
+_gssapi_verify_mic_cfx (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t */*qop_state*/);
+
+OM_uint32
+_gssapi_verify_pad (
+ gss_buffer_t /*wrapped_token*/,
+ size_t /*datalen*/,
+ size_t */*padlen*/);
+
+OM_uint32
+_gssapi_wrap_arcfour (
+ OM_uint32 * /*minor_status*/,
+ const gsskrb5_ctx /*context_handle*/,
+ krb5_context /*context*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ int * /*conf_state*/,
+ gss_buffer_t /*output_message_buffer*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
+_gssapi_wrap_cfx (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ int /*conf_req_flag*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ int */*conf_state*/,
+ gss_buffer_t /*output_message_buffer*/);
+
+OM_uint32
+_gssapi_wrap_cfx_iov (
+ OM_uint32 */*minor_status*/,
+ gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ int /*conf_req_flag*/,
+ int */*conf_state*/,
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/);
+
+OM_uint32
+_gssapi_wrap_iov_length_cfx (
+ OM_uint32 */*minor_status*/,
+ gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ int */*conf_state*/,
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/);
+
+OM_uint32
+_gssapi_wrap_size_arcfour (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ OM_uint32 /*req_output_size*/,
+ OM_uint32 */*max_input_size*/,
+ krb5_keyblock */*key*/);
+
+OM_uint32
+_gssapi_wrap_size_cfx (
+ OM_uint32 */*minor_status*/,
+ const gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ OM_uint32 /*req_output_size*/,
+ OM_uint32 */*max_input_size*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_accept_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_cred_id_t /*acceptor_cred_handle*/,
+ const gss_buffer_t /*input_token_buffer*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ gss_name_t * /*src_name*/,
+ gss_OID * /*mech_type*/,
+ gss_buffer_t /*output_token*/,
+ OM_uint32 * /*ret_flags*/,
+ OM_uint32 * /*time_rec*/,
+ gss_cred_id_t * /*delegated_cred_handle*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_acquire_cred (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*desired_name*/,
+ OM_uint32 /*time_req*/,
+ const gss_OID_set /*desired_mechs*/,
+ gss_cred_usage_t /*cred_usage*/,
+ gss_cred_id_t * /*output_cred_handle*/,
+ gss_OID_set * /*actual_mechs*/,
+ OM_uint32 * time_rec );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_acquire_cred_ext (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*desired_name*/,
+ gss_const_OID /*credential_type*/,
+ const void */*credential_data*/,
+ OM_uint32 /*time_req*/,
+ gss_const_OID /*desired_mech*/,
+ gss_cred_usage_t /*cred_usage*/,
+ gss_cred_id_t * output_cred_handle );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_add_cred (
+ OM_uint32 */*minor_status*/,
+ const gss_cred_id_t /*input_cred_handle*/,
+ const gss_name_t /*desired_name*/,
+ const gss_OID /*desired_mech*/,
+ gss_cred_usage_t /*cred_usage*/,
+ OM_uint32 /*initiator_time_req*/,
+ OM_uint32 /*acceptor_time_req*/,
+ gss_cred_id_t */*output_cred_handle*/,
+ gss_OID_set */*actual_mechs*/,
+ OM_uint32 */*initiator_time_rec*/,
+ OM_uint32 */*acceptor_time_rec*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_authorize_localname (
+ OM_uint32 */*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_const_buffer_t /*user_name*/,
+ gss_const_OID /*user_name_type*/);
+
+OM_uint32
+_gsskrb5_canon_name (
+ OM_uint32 */*minor_status*/,
+ krb5_context /*context*/,
+ int /*use_dns*/,
+ krb5_const_principal /*sourcename*/,
+ gss_name_t /*targetname*/,
+ krb5_principal */*out*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_canonicalize_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * output_name );
+
+void
+_gsskrb5_clear_status (void);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_compare_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*name1*/,
+ const gss_name_t /*name2*/,
+ int * name_equal );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_context_time (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ OM_uint32 * time_rec );
+
+OM_uint32
+_gsskrb5_create_8003_checksum (
+ OM_uint32 */*minor_status*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ OM_uint32 /*flags*/,
+ const krb5_data */*fwd_data*/,
+ Checksum */*result*/);
+
+OM_uint32
+_gsskrb5_create_ctx (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ krb5_context /*context*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ enum gss_ctx_id_t_state /*state*/);
+
+OM_uint32
+_gsskrb5_decapsulate (
+ OM_uint32 */*minor_status*/,
+ gss_buffer_t /*input_token_buffer*/,
+ krb5_data */*out_data*/,
+ const void */*type*/,
+ gss_OID /*oid*/);
+
+krb5_error_code
+_gsskrb5_decode_be_om_uint32 (
+ const void */*ptr*/,
+ OM_uint32 */*n*/);
+
+krb5_error_code
+_gsskrb5_decode_om_uint32 (
+ const void */*ptr*/,
+ OM_uint32 */*n*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_delete_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ gss_buffer_t /*output_token*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_display_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t /*output_name_buffer*/,
+ gss_OID * output_name_type );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_display_status (
+ OM_uint32 */*minor_status*/,
+ OM_uint32 /*status_value*/,
+ int /*status_type*/,
+ const gss_OID /*mech_type*/,
+ OM_uint32 */*message_context*/,
+ gss_buffer_t /*status_string*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_duplicate_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*src_name*/,
+ gss_name_t * dest_name );
+
+void
+_gsskrb5_encap_length (
+ size_t /*data_len*/,
+ size_t */*len*/,
+ size_t */*total_len*/,
+ const gss_OID /*mech*/);
+
+OM_uint32
+_gsskrb5_encapsulate (
+ OM_uint32 */*minor_status*/,
+ const krb5_data */*in_data*/,
+ gss_buffer_t /*output_token*/,
+ const void */*type*/,
+ const gss_OID mech );
+
+krb5_error_code
+_gsskrb5_encode_be_om_uint32 (
+ OM_uint32 /*n*/,
+ u_char */*p*/);
+
+krb5_error_code
+_gsskrb5_encode_om_uint32 (
+ OM_uint32 /*n*/,
+ u_char */*p*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_export_cred (
+ OM_uint32 */*minor_status*/,
+ gss_cred_id_t /*cred_handle*/,
+ gss_buffer_t /*cred_token*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_export_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t exported_name );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_export_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ gss_buffer_t interprocess_token );
+
+ssize_t
+_gsskrb5_get_mech (
+ const u_char */*ptr*/,
+ size_t /*total_len*/,
+ const u_char **/*mech_ret*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_get_mic (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*message_buffer*/,
+ gss_buffer_t message_token );
+
+OM_uint32
+_gsskrb5_get_tkt_flags (
+ OM_uint32 */*minor_status*/,
+ gsskrb5_ctx /*ctx*/,
+ OM_uint32 */*tkt_flags*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_import_cred (
+ OM_uint32 * /*minor_status*/,
+ gss_buffer_t /*cred_token*/,
+ gss_cred_id_t * /*cred_handle*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_import_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*input_name_buffer*/,
+ const gss_OID /*input_name_type*/,
+ gss_name_t * output_name );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_import_sec_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*interprocess_token*/,
+ gss_ctx_id_t * context_handle );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_indicate_mechs (
+ OM_uint32 * /*minor_status*/,
+ gss_OID_set * mech_set );
+
+krb5_error_code
+_gsskrb5_init (krb5_context */*context*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_init_sec_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_name_t /*target_name*/,
+ const gss_OID /*mech_type*/,
+ OM_uint32 /*req_flags*/,
+ OM_uint32 /*time_req*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ const gss_buffer_t /*input_token*/,
+ gss_OID * /*actual_mech_type*/,
+ gss_buffer_t /*output_token*/,
+ OM_uint32 * /*ret_flags*/,
+ OM_uint32 * time_rec );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_inquire_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ gss_name_t * /*src_name*/,
+ gss_name_t * /*targ_name*/,
+ OM_uint32 * /*lifetime_rec*/,
+ gss_OID * /*mech_type*/,
+ OM_uint32 * /*ctx_flags*/,
+ int * /*locally_initiated*/,
+ int * open_context );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_inquire_cred (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ gss_name_t * /*output_name*/,
+ OM_uint32 * /*lifetime*/,
+ gss_cred_usage_t * /*cred_usage*/,
+ gss_OID_set * mechanisms );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_inquire_cred_by_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * /*name*/,
+ OM_uint32 * /*initiator_lifetime*/,
+ OM_uint32 * /*acceptor_lifetime*/,
+ gss_cred_usage_t * cred_usage );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_inquire_cred_by_oid (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ const gss_OID /*desired_object*/,
+ gss_buffer_set_t */*data_set*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_inquire_mechs_for_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_OID_set * mech_types );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_inquire_names_for_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*mechanism*/,
+ gss_OID_set * name_types );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_inquire_sec_context_by_oid (
+ OM_uint32 */*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_OID /*desired_object*/,
+ gss_buffer_set_t */*data_set*/);
+
+OM_uint32
+_gsskrb5_krb5_ccache_name (
+ OM_uint32 */*minor_status*/,
+ const char */*name*/,
+ const char **/*out_name*/);
+
+OM_uint32
+_gsskrb5_krb5_import_cred (
+ OM_uint32 */*minor_status*/,
+ krb5_ccache /*id*/,
+ krb5_principal /*keytab_principal*/,
+ krb5_keytab /*keytab*/,
+ gss_cred_id_t */*cred*/);
+
+OM_uint32
+_gsskrb5_lifetime_left (
+ OM_uint32 */*minor_status*/,
+ krb5_context /*context*/,
+ OM_uint32 /*lifetime*/,
+ OM_uint32 */*lifetime_rec*/);
+
+void *
+_gsskrb5_make_header (
+ void */*ptr*/,
+ size_t /*len*/,
+ const void */*type*/,
+ const gss_OID /*mech*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_pname_to_uid (
+ OM_uint32 */*minor_status*/,
+ const gss_name_t /*pname*/,
+ const gss_OID /*mech_type*/,
+ uid_t */*uidp*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_process_context_token (
+ OM_uint32 */*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t token_buffer );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_pseudo_random (
+ OM_uint32 */*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int /*prf_key*/,
+ const gss_buffer_t /*prf_in*/,
+ ssize_t /*desired_output_len*/,
+ gss_buffer_t /*prf_out*/);
+
+OM_uint32
+_gsskrb5_register_acceptor_identity (
+ OM_uint32 */*min_stat*/,
+ const char */*identity*/);
+
+OM_uint32
+_gsskrb5_release_buffer (
+ OM_uint32 * /*minor_status*/,
+ gss_buffer_t buffer );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_release_cred (
+ OM_uint32 * /*minor_status*/,
+ gss_cred_id_t * cred_handle );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_release_name (
+ OM_uint32 * /*minor_status*/,
+ gss_name_t * input_name );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_set_cred_option (
+ OM_uint32 */*minor_status*/,
+ gss_cred_id_t */*cred_handle*/,
+ const gss_OID /*desired_object*/,
+ const gss_buffer_t /*value*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_set_sec_context_option (
+ OM_uint32 */*minor_status*/,
+ gss_ctx_id_t */*context_handle*/,
+ const gss_OID /*desired_object*/,
+ const gss_buffer_t /*value*/);
+
+void
+_gsskrb5_set_status (
+ int /*ret*/,
+ const char */*fmt*/,
+ ...);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_store_cred (
+ OM_uint32 */*minor_status*/,
+ gss_cred_id_t /*input_cred_handle*/,
+ gss_cred_usage_t /*cred_usage*/,
+ const gss_OID /*desired_mech*/,
+ OM_uint32 /*overwrite_cred*/,
+ OM_uint32 /*default_cred*/,
+ gss_OID_set */*elements_stored*/,
+ gss_cred_usage_t */*cred_usage_stored*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_unwrap (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ gss_buffer_t /*output_message_buffer*/,
+ int * /*conf_state*/,
+ gss_qop_t * qop_state );
+
+OM_uint32
+_gsskrb5_verify_8003_checksum (
+ OM_uint32 */*minor_status*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ const Checksum */*cksum*/,
+ OM_uint32 */*flags*/,
+ krb5_data */*fwd_data*/);
+
+OM_uint32
+_gsskrb5_verify_header (
+ u_char **/*str*/,
+ size_t /*total_len*/,
+ const void */*type*/,
+ gss_OID /*oid*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_verify_mic (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t * qop_state );
+
+OM_uint32
+_gsskrb5_verify_mic_internal (
+ OM_uint32 * /*minor_status*/,
+ const gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t * /*qop_state*/,
+ const char * type );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_wrap (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ int * /*conf_state*/,
+ gss_buffer_t output_message_buffer );
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_wrap_size_limit (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ OM_uint32 /*req_output_size*/,
+ OM_uint32 * max_input_size );
+
+krb5_error_code
+_gsskrb5cfx_wrap_length_cfx (
+ krb5_context /*context*/,
+ krb5_crypto /*crypto*/,
+ int /*conf_req_flag*/,
+ int /*dce_style*/,
+ size_t /*input_length*/,
+ size_t */*output_length*/,
+ size_t */*cksumsize*/,
+ uint16_t */*padlength*/);
+
+krb5_error_code
+_gsskrb5i_address_to_krb5addr (
+ krb5_context /*context*/,
+ OM_uint32 /*gss_addr_type*/,
+ gss_buffer_desc */*gss_addr*/,
+ int16_t /*port*/,
+ krb5_address */*address*/);
+
+krb5_error_code
+_gsskrb5i_get_acceptor_subkey (
+ const gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ krb5_keyblock **/*key*/);
+
+krb5_error_code
+_gsskrb5i_get_initiator_subkey (
+ const gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ krb5_keyblock **/*key*/);
+
+OM_uint32
+_gsskrb5i_get_token_key (
+ const gsskrb5_ctx /*ctx*/,
+ krb5_context /*context*/,
+ krb5_keyblock **/*key*/);
+
+void
+_gsskrb5i_is_cfx (
+ krb5_context /*context*/,
+ gsskrb5_ctx /*ctx*/,
+ int /*acceptor*/);
+
+#endif /* __gsskrb5_private_h__ */
diff --git a/crypto/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/crypto/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
new file mode 100644
index 0000000..6b9b03f
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+#ifndef GSSKRB5_LOCL_H
+#define GSSKRB5_LOCL_H
+
+#include <config.h>
+
+#include <krb5_locl.h>
+#include <gkrb5_err.h>
+#include <gssapi.h>
+#include <gssapi_mech.h>
+#include <gssapi_krb5.h>
+#include <assert.h>
+
+#include "cfx.h"
+
+/*
+ *
+ */
+
+struct gss_msg_order;
+
+typedef struct gsskrb5_ctx {
+ struct krb5_auth_context_data *auth_context;
+ struct krb5_auth_context_data *deleg_auth_context;
+ krb5_principal source, target;
+#define IS_DCE_STYLE(ctx) (((ctx)->flags & GSS_C_DCE_STYLE) != 0)
+ OM_uint32 flags;
+ enum { LOCAL = 1, OPEN = 2,
+ COMPAT_OLD_DES3 = 4,
+ COMPAT_OLD_DES3_SELECTED = 8,
+ ACCEPTOR_SUBKEY = 16,
+ RETRIED = 32,
+ CLOSE_CCACHE = 64,
+ IS_CFX = 128
+ } more_flags;
+ enum gss_ctx_id_t_state {
+ /* initiator states */
+ INITIATOR_START,
+ INITIATOR_RESTART,
+ INITIATOR_WAIT_FOR_MUTAL,
+ INITIATOR_READY,
+ /* acceptor states */
+ ACCEPTOR_START,
+ ACCEPTOR_WAIT_FOR_DCESTYLE,
+ ACCEPTOR_READY
+ } state;
+ krb5_creds *kcred;
+ krb5_ccache ccache;
+ struct krb5_ticket *ticket;
+ OM_uint32 lifetime;
+ HEIMDAL_MUTEX ctx_id_mutex;
+ struct gss_msg_order *order;
+ krb5_keyblock *service_keyblock;
+ krb5_data fwd_data;
+ krb5_crypto crypto;
+} *gsskrb5_ctx;
+
+typedef struct {
+ krb5_principal principal;
+ int cred_flags;
+#define GSS_CF_DESTROY_CRED_ON_RELEASE 1
+#define GSS_CF_NO_CI_FLAGS 2
+ struct krb5_keytab_data *keytab;
+ OM_uint32 lifetime;
+ gss_cred_usage_t usage;
+ gss_OID_set mechanisms;
+ struct krb5_ccache_data *ccache;
+ HEIMDAL_MUTEX cred_id_mutex;
+ krb5_enctype *enctypes;
+} *gsskrb5_cred;
+
+typedef struct Principal *gsskrb5_name;
+
+/*
+ *
+ */
+
+extern krb5_keytab _gsskrb5_keytab;
+extern HEIMDAL_MUTEX gssapi_keytab_mutex;
+
+/*
+ * Prototypes
+ */
+
+#include <gsskrb5-private.h>
+
+#define GSSAPI_KRB5_INIT(ctx) do { \
+ krb5_error_code kret_gss_init; \
+ if((kret_gss_init = _gsskrb5_init (ctx)) != 0) { \
+ *minor_status = kret_gss_init; \
+ return GSS_S_FAILURE; \
+ } \
+} while (0)
+
+/* sec_context flags */
+
+#define SC_LOCAL_ADDRESS 0x01
+#define SC_REMOTE_ADDRESS 0x02
+#define SC_KEYBLOCK 0x04
+#define SC_LOCAL_SUBKEY 0x08
+#define SC_REMOTE_SUBKEY 0x10
+
+/* type to signal that that dns canon maybe should be done */
+#define MAGIC_HOSTBASED_NAME_TYPE 4711
+
+#endif
diff --git a/crypto/heimdal/lib/gssapi/krb5/import_name.c b/crypto/heimdal/lib/gssapi/krb5/import_name.c
new file mode 100644
index 0000000..5fe5126
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/import_name.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+static OM_uint32
+parse_krb5_name (OM_uint32 *minor_status,
+ krb5_context context,
+ const char *name,
+ gss_name_t *output_name)
+{
+ krb5_principal princ;
+ krb5_error_code kerr;
+
+ kerr = krb5_parse_name (context, name, &princ);
+
+ if (kerr == 0) {
+ *output_name = (gss_name_t)princ;
+ return GSS_S_COMPLETE;
+ }
+ *minor_status = kerr;
+
+ if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
+ return GSS_S_BAD_NAME;
+
+ return GSS_S_FAILURE;
+}
+
+static OM_uint32
+import_krb5_name (OM_uint32 *minor_status,
+ krb5_context context,
+ const gss_buffer_t input_name_buffer,
+ gss_name_t *output_name)
+{
+ OM_uint32 ret;
+ char *tmp;
+
+ tmp = malloc (input_name_buffer->length + 1);
+ if (tmp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy (tmp,
+ input_name_buffer->value,
+ input_name_buffer->length);
+ tmp[input_name_buffer->length] = '\0';
+
+ ret = parse_krb5_name(minor_status, context, tmp, output_name);
+ free(tmp);
+
+ return ret;
+}
+
+OM_uint32
+_gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context,
+ int use_dns, krb5_const_principal sourcename, gss_name_t targetname,
+ krb5_principal *out)
+{
+ krb5_principal p = (krb5_principal)targetname;
+ krb5_error_code ret;
+ char *hostname = NULL, *service;
+
+ *minor_status = 0;
+
+ /* If its not a hostname */
+ if (krb5_principal_get_type(context, p) != MAGIC_HOSTBASED_NAME_TYPE) {
+ ret = krb5_copy_principal(context, p, out);
+ } else if (!use_dns) {
+ ret = krb5_copy_principal(context, p, out);
+ if (ret)
+ goto out;
+ krb5_principal_set_type(context, *out, KRB5_NT_SRV_HST);
+ if (sourcename)
+ ret = krb5_principal_set_realm(context, *out, sourcename->realm);
+ } else {
+ if (p->name.name_string.len == 0)
+ return GSS_S_BAD_NAME;
+ else if (p->name.name_string.len > 1)
+ hostname = p->name.name_string.val[1];
+
+ service = p->name.name_string.val[0];
+
+ ret = krb5_sname_to_principal(context,
+ hostname,
+ service,
+ KRB5_NT_SRV_HST,
+ out);
+ }
+
+ out:
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ return 0;
+}
+
+
+static OM_uint32
+import_hostbased_name (OM_uint32 *minor_status,
+ krb5_context context,
+ const gss_buffer_t input_name_buffer,
+ gss_name_t *output_name)
+{
+ krb5_principal princ = NULL;
+ krb5_error_code kerr;
+ char *tmp, *p, *host = NULL;
+
+ tmp = malloc (input_name_buffer->length + 1);
+ if (tmp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy (tmp,
+ input_name_buffer->value,
+ input_name_buffer->length);
+ tmp[input_name_buffer->length] = '\0';
+
+ p = strchr (tmp, '@');
+ if (p != NULL) {
+ *p = '\0';
+ host = p + 1;
+ }
+
+ kerr = krb5_make_principal(context, &princ, NULL, tmp, host, NULL);
+ free (tmp);
+ *minor_status = kerr;
+ if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
+ return GSS_S_BAD_NAME;
+ else if (kerr)
+ return GSS_S_FAILURE;
+
+ krb5_principal_set_type(context, princ, MAGIC_HOSTBASED_NAME_TYPE);
+ *output_name = (gss_name_t)princ;
+
+ return 0;
+}
+
+static OM_uint32
+import_export_name (OM_uint32 *minor_status,
+ krb5_context context,
+ const gss_buffer_t input_name_buffer,
+ gss_name_t *output_name)
+{
+ unsigned char *p;
+ uint32_t length;
+ OM_uint32 ret;
+ char *name;
+
+ if (input_name_buffer->length < 10 + GSS_KRB5_MECHANISM->length)
+ return GSS_S_BAD_NAME;
+
+ /* TOK, MECH_OID_LEN, DER(MECH_OID), NAME_LEN, NAME */
+
+ p = input_name_buffer->value;
+
+ if (memcmp(&p[0], "\x04\x01\x00", 3) != 0 ||
+ p[3] != GSS_KRB5_MECHANISM->length + 2 ||
+ p[4] != 0x06 ||
+ p[5] != GSS_KRB5_MECHANISM->length ||
+ memcmp(&p[6], GSS_KRB5_MECHANISM->elements,
+ GSS_KRB5_MECHANISM->length) != 0)
+ return GSS_S_BAD_NAME;
+
+ p += 6 + GSS_KRB5_MECHANISM->length;
+
+ length = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
+ p += 4;
+
+ if (length > input_name_buffer->length - 10 - GSS_KRB5_MECHANISM->length)
+ return GSS_S_BAD_NAME;
+
+ name = malloc(length + 1);
+ if (name == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy(name, p, length);
+ name[length] = '\0';
+
+ ret = parse_krb5_name(minor_status, context, name, output_name);
+ free(name);
+
+ return ret;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_import_name
+ (OM_uint32 * minor_status,
+ const gss_buffer_t input_name_buffer,
+ const gss_OID input_name_type,
+ gss_name_t * output_name
+ )
+{
+ krb5_context context;
+
+ *minor_status = 0;
+ *output_name = GSS_C_NO_NAME;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE) ||
+ gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE_X))
+ return import_hostbased_name (minor_status,
+ context,
+ input_name_buffer,
+ output_name);
+ else if (input_name_type == GSS_C_NO_OID
+ || gss_oid_equal(input_name_type, GSS_C_NT_USER_NAME)
+ || gss_oid_equal(input_name_type, GSS_KRB5_NT_PRINCIPAL_NAME))
+ /* default printable syntax */
+ return import_krb5_name (minor_status,
+ context,
+ input_name_buffer,
+ output_name);
+ else if (gss_oid_equal(input_name_type, GSS_C_NT_EXPORT_NAME)) {
+ return import_export_name(minor_status,
+ context,
+ input_name_buffer,
+ output_name);
+ } else {
+ *minor_status = 0;
+ return GSS_S_BAD_NAMETYPE;
+ }
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/import_sec_context.c b/crypto/heimdal/lib/gssapi/krb5/import_sec_context.c
new file mode 100644
index 0000000..3bab180
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/import_sec_context.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 1999 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_import_sec_context (
+ OM_uint32 * minor_status,
+ const gss_buffer_t interprocess_token,
+ gss_ctx_id_t * context_handle
+ )
+{
+ OM_uint32 ret = GSS_S_FAILURE;
+ krb5_context context;
+ krb5_error_code kret;
+ krb5_storage *sp;
+ krb5_auth_context ac;
+ krb5_address local, remote;
+ krb5_address *localp, *remotep;
+ krb5_data data;
+ gss_buffer_desc buffer;
+ krb5_keyblock keyblock;
+ int32_t flags, tmp;
+ gsskrb5_ctx ctx;
+ gss_name_t name;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ *context_handle = GSS_C_NO_CONTEXT;
+
+ localp = remotep = NULL;
+
+ sp = krb5_storage_from_mem (interprocess_token->value,
+ interprocess_token->length);
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL) {
+ *minor_status = ENOMEM;
+ krb5_storage_free (sp);
+ return GSS_S_FAILURE;
+ }
+ HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
+
+ kret = krb5_auth_con_init (context,
+ &ctx->auth_context);
+ if (kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ /* flags */
+
+ *minor_status = 0;
+
+ if (krb5_ret_int32 (sp, &flags) != 0)
+ goto failure;
+
+ /* retrieve the auth context */
+
+ ac = ctx->auth_context;
+ if (krb5_ret_int32 (sp, &tmp) != 0)
+ goto failure;
+ ac->flags = tmp;
+ if (flags & SC_LOCAL_ADDRESS) {
+ if (krb5_ret_address (sp, localp = &local) != 0)
+ goto failure;
+ }
+
+ if (flags & SC_REMOTE_ADDRESS) {
+ if (krb5_ret_address (sp, remotep = &remote) != 0)
+ goto failure;
+ }
+
+ krb5_auth_con_setaddrs (context, ac, localp, remotep);
+ if (localp)
+ krb5_free_address (context, localp);
+ if (remotep)
+ krb5_free_address (context, remotep);
+ localp = remotep = NULL;
+
+ if (krb5_ret_int16 (sp, &ac->local_port) != 0)
+ goto failure;
+
+ if (krb5_ret_int16 (sp, &ac->remote_port) != 0)
+ goto failure;
+ if (flags & SC_KEYBLOCK) {
+ if (krb5_ret_keyblock (sp, &keyblock) != 0)
+ goto failure;
+ krb5_auth_con_setkey (context, ac, &keyblock);
+ krb5_free_keyblock_contents (context, &keyblock);
+ }
+ if (flags & SC_LOCAL_SUBKEY) {
+ if (krb5_ret_keyblock (sp, &keyblock) != 0)
+ goto failure;
+ krb5_auth_con_setlocalsubkey (context, ac, &keyblock);
+ krb5_free_keyblock_contents (context, &keyblock);
+ }
+ if (flags & SC_REMOTE_SUBKEY) {
+ if (krb5_ret_keyblock (sp, &keyblock) != 0)
+ goto failure;
+ krb5_auth_con_setremotesubkey (context, ac, &keyblock);
+ krb5_free_keyblock_contents (context, &keyblock);
+ }
+ if (krb5_ret_uint32 (sp, &ac->local_seqnumber))
+ goto failure;
+ if (krb5_ret_uint32 (sp, &ac->remote_seqnumber))
+ goto failure;
+
+ if (krb5_ret_int32 (sp, &tmp) != 0)
+ goto failure;
+ ac->keytype = tmp;
+ if (krb5_ret_int32 (sp, &tmp) != 0)
+ goto failure;
+ ac->cksumtype = tmp;
+
+ /* names */
+
+ if (krb5_ret_data (sp, &data))
+ goto failure;
+ buffer.value = data.data;
+ buffer.length = data.length;
+
+ ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
+ &name);
+ if (ret) {
+ ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
+ &name);
+ if (ret) {
+ krb5_data_free (&data);
+ goto failure;
+ }
+ }
+ ctx->source = (krb5_principal)name;
+ krb5_data_free (&data);
+
+ if (krb5_ret_data (sp, &data) != 0)
+ goto failure;
+ buffer.value = data.data;
+ buffer.length = data.length;
+
+ ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
+ &name);
+ if (ret) {
+ ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
+ &name);
+ if (ret) {
+ krb5_data_free (&data);
+ goto failure;
+ }
+ }
+ ctx->target = (krb5_principal)name;
+ krb5_data_free (&data);
+
+ if (krb5_ret_int32 (sp, &tmp))
+ goto failure;
+ ctx->flags = tmp;
+ if (krb5_ret_int32 (sp, &tmp))
+ goto failure;
+ ctx->more_flags = tmp;
+ if (krb5_ret_int32 (sp, &tmp))
+ goto failure;
+ ctx->lifetime = tmp;
+
+ ret = _gssapi_msg_order_import(minor_status, sp, &ctx->order);
+ if (ret)
+ goto failure;
+
+ krb5_storage_free (sp);
+
+ _gsskrb5i_is_cfx(context, ctx, (ctx->more_flags & LOCAL) == 0);
+
+ *context_handle = (gss_ctx_id_t)ctx;
+
+ return GSS_S_COMPLETE;
+
+failure:
+ krb5_auth_con_free (context,
+ ctx->auth_context);
+ if (ctx->source != NULL)
+ krb5_free_principal(context, ctx->source);
+ if (ctx->target != NULL)
+ krb5_free_principal(context, ctx->target);
+ if (localp)
+ krb5_free_address (context, localp);
+ if (remotep)
+ krb5_free_address (context, remotep);
+ if(ctx->order)
+ _gssapi_msg_order_destroy(&ctx->order);
+ HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+ krb5_storage_free (sp);
+ free (ctx);
+ *context_handle = GSS_C_NO_CONTEXT;
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/indicate_mechs.c b/crypto/heimdal/lib/gssapi/krb5/indicate_mechs.c
new file mode 100644
index 0000000..6201378
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/indicate_mechs.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_indicate_mechs
+ (OM_uint32 * minor_status,
+ gss_OID_set * mech_set
+ )
+{
+ OM_uint32 ret, junk;
+
+ ret = gss_create_empty_oid_set(minor_status, mech_set);
+ if (ret)
+ return ret;
+
+ ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, mech_set);
+ if (ret) {
+ gss_release_oid_set(&junk, mech_set);
+ return ret;
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/init.c b/crypto/heimdal/lib/gssapi/krb5/init.c
new file mode 100644
index 0000000..3a22c33
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/init.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1997 - 2001, 2003, 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER;
+static int created_key;
+static HEIMDAL_thread_key context_key;
+
+static void
+destroy_context(void *ptr)
+{
+ krb5_context context = ptr;
+
+ if (context == NULL)
+ return;
+ krb5_free_context(context);
+}
+
+krb5_error_code
+_gsskrb5_init (krb5_context *context)
+{
+ krb5_error_code ret = 0;
+
+ HEIMDAL_MUTEX_lock(&context_mutex);
+
+ if (!created_key) {
+ HEIMDAL_key_create(&context_key, destroy_context, ret);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&context_mutex);
+ return ret;
+ }
+ created_key = 1;
+ }
+ HEIMDAL_MUTEX_unlock(&context_mutex);
+
+ *context = HEIMDAL_getspecific(context_key);
+ if (*context == NULL) {
+
+ ret = krb5_init_context(context);
+ if (ret == 0) {
+ HEIMDAL_setspecific(context_key, *context, ret);
+ if (ret) {
+ krb5_free_context(*context);
+ *context = NULL;
+ }
+ }
+ }
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/init_sec_context.c b/crypto/heimdal/lib/gssapi/krb5/init_sec_context.c
new file mode 100644
index 0000000..5f8b01b
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/init_sec_context.c
@@ -0,0 +1,1015 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+/*
+ * copy the addresses from `input_chan_bindings' (if any) to
+ * the auth context `ac'
+ */
+
+static OM_uint32
+set_addresses (krb5_context context,
+ krb5_auth_context ac,
+ const gss_channel_bindings_t input_chan_bindings)
+{
+ /* Port numbers are expected to be in application_data.value,
+ * initator's port first */
+
+ krb5_address initiator_addr, acceptor_addr;
+ krb5_error_code kret;
+
+ if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS
+ || input_chan_bindings->application_data.length !=
+ 2 * sizeof(ac->local_port))
+ return 0;
+
+ memset(&initiator_addr, 0, sizeof(initiator_addr));
+ memset(&acceptor_addr, 0, sizeof(acceptor_addr));
+
+ ac->local_port =
+ *(int16_t *) input_chan_bindings->application_data.value;
+
+ ac->remote_port =
+ *((int16_t *) input_chan_bindings->application_data.value + 1);
+
+ kret = _gsskrb5i_address_to_krb5addr(context,
+ input_chan_bindings->acceptor_addrtype,
+ &input_chan_bindings->acceptor_address,
+ ac->remote_port,
+ &acceptor_addr);
+ if (kret)
+ return kret;
+
+ kret = _gsskrb5i_address_to_krb5addr(context,
+ input_chan_bindings->initiator_addrtype,
+ &input_chan_bindings->initiator_address,
+ ac->local_port,
+ &initiator_addr);
+ if (kret) {
+ krb5_free_address (context, &acceptor_addr);
+ return kret;
+ }
+
+ kret = krb5_auth_con_setaddrs(context,
+ ac,
+ &initiator_addr, /* local address */
+ &acceptor_addr); /* remote address */
+
+ krb5_free_address (context, &initiator_addr);
+ krb5_free_address (context, &acceptor_addr);
+
+#if 0
+ free(input_chan_bindings->application_data.value);
+ input_chan_bindings->application_data.value = NULL;
+ input_chan_bindings->application_data.length = 0;
+#endif
+
+ return kret;
+}
+
+OM_uint32
+_gsskrb5_create_ctx(
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ krb5_context context,
+ const gss_channel_bindings_t input_chan_bindings,
+ enum gss_ctx_id_t_state state)
+{
+ krb5_error_code kret;
+ gsskrb5_ctx ctx;
+
+ *context_handle = NULL;
+
+ ctx = malloc(sizeof(*ctx));
+ if (ctx == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ ctx->auth_context = NULL;
+ ctx->deleg_auth_context = NULL;
+ ctx->source = NULL;
+ ctx->target = NULL;
+ ctx->kcred = NULL;
+ ctx->ccache = NULL;
+ ctx->state = state;
+ ctx->flags = 0;
+ ctx->more_flags = 0;
+ ctx->service_keyblock = NULL;
+ ctx->ticket = NULL;
+ krb5_data_zero(&ctx->fwd_data);
+ ctx->lifetime = GSS_C_INDEFINITE;
+ ctx->order = NULL;
+ ctx->crypto = NULL;
+ HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
+
+ kret = krb5_auth_con_init (context, &ctx->auth_context);
+ if (kret) {
+ *minor_status = kret;
+ HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_auth_con_init (context, &ctx->deleg_auth_context);
+ if (kret) {
+ *minor_status = kret;
+ krb5_auth_con_free(context, ctx->auth_context);
+ HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+ return GSS_S_FAILURE;
+ }
+
+ kret = set_addresses(context, ctx->auth_context, input_chan_bindings);
+ if (kret) {
+ *minor_status = kret;
+
+ krb5_auth_con_free(context, ctx->auth_context);
+ krb5_auth_con_free(context, ctx->deleg_auth_context);
+
+ HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+
+ return GSS_S_BAD_BINDINGS;
+ }
+
+ kret = set_addresses(context, ctx->deleg_auth_context, input_chan_bindings);
+ if (kret) {
+ *minor_status = kret;
+
+ krb5_auth_con_free(context, ctx->auth_context);
+ krb5_auth_con_free(context, ctx->deleg_auth_context);
+
+ HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+
+ return GSS_S_BAD_BINDINGS;
+ }
+
+ /*
+ * We need a sequence number
+ */
+
+ krb5_auth_con_addflags(context,
+ ctx->auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE |
+ KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED,
+ NULL);
+
+ /*
+ * We need a sequence number
+ */
+
+ krb5_auth_con_addflags(context,
+ ctx->deleg_auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE |
+ KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED,
+ NULL);
+
+ *context_handle = (gss_ctx_id_t)ctx;
+
+ return GSS_S_COMPLETE;
+}
+
+
+static OM_uint32
+gsskrb5_get_creds(
+ OM_uint32 * minor_status,
+ krb5_context context,
+ krb5_ccache ccache,
+ gsskrb5_ctx ctx,
+ const gss_name_t target_name,
+ int use_dns,
+ OM_uint32 time_req,
+ OM_uint32 * time_rec)
+{
+ OM_uint32 ret;
+ krb5_error_code kret;
+ krb5_creds this_cred;
+ OM_uint32 lifetime_rec;
+
+ if (ctx->target) {
+ krb5_free_principal(context, ctx->target);
+ ctx->target = NULL;
+ }
+ if (ctx->kcred) {
+ krb5_free_creds(context, ctx->kcred);
+ ctx->kcred = NULL;
+ }
+
+ ret = _gsskrb5_canon_name(minor_status, context, use_dns,
+ ctx->source, target_name, &ctx->target);
+ if (ret)
+ return ret;
+
+ memset(&this_cred, 0, sizeof(this_cred));
+ this_cred.client = ctx->source;
+ this_cred.server = ctx->target;
+
+ if (time_req && time_req != GSS_C_INDEFINITE) {
+ krb5_timestamp ts;
+
+ krb5_timeofday (context, &ts);
+ this_cred.times.endtime = ts + time_req;
+ } else {
+ this_cred.times.endtime = 0;
+ }
+
+ this_cred.session.keytype = KEYTYPE_NULL;
+
+ kret = krb5_get_credentials(context,
+ 0,
+ ccache,
+ &this_cred,
+ &ctx->kcred);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ ctx->lifetime = ctx->kcred->times.endtime;
+
+ ret = _gsskrb5_lifetime_left(minor_status, context,
+ ctx->lifetime, &lifetime_rec);
+ if (ret) return ret;
+
+ if (lifetime_rec == 0) {
+ *minor_status = 0;
+ return GSS_S_CONTEXT_EXPIRED;
+ }
+
+ if (time_rec) *time_rec = lifetime_rec;
+
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+gsskrb5_initiator_ready(
+ OM_uint32 * minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context)
+{
+ OM_uint32 ret;
+ int32_t seq_number;
+ int is_cfx = 0;
+ OM_uint32 flags = ctx->flags;
+
+ krb5_free_creds(context, ctx->kcred);
+ ctx->kcred = NULL;
+
+ if (ctx->more_flags & CLOSE_CCACHE)
+ krb5_cc_close(context, ctx->ccache);
+ ctx->ccache = NULL;
+
+ krb5_auth_con_getremoteseqnumber (context, ctx->auth_context, &seq_number);
+
+ _gsskrb5i_is_cfx(context, ctx, 0);
+ is_cfx = (ctx->more_flags & IS_CFX);
+
+ ret = _gssapi_msg_order_create(minor_status,
+ &ctx->order,
+ _gssapi_msg_order_f(flags),
+ seq_number, 0, is_cfx);
+ if (ret) return ret;
+
+ ctx->state = INITIATOR_READY;
+ ctx->more_flags |= OPEN;
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * handle delegated creds in init-sec-context
+ */
+
+static void
+do_delegation (krb5_context context,
+ krb5_auth_context ac,
+ krb5_ccache ccache,
+ krb5_creds *cred,
+ krb5_const_principal name,
+ krb5_data *fwd_data,
+ uint32_t flagmask,
+ uint32_t *flags)
+{
+ krb5_creds creds;
+ KDCOptions fwd_flags;
+ krb5_error_code kret;
+
+ memset (&creds, 0, sizeof(creds));
+ krb5_data_zero (fwd_data);
+
+ kret = krb5_cc_get_principal(context, ccache, &creds.client);
+ if (kret)
+ goto out;
+
+ kret = krb5_make_principal(context,
+ &creds.server,
+ creds.client->realm,
+ KRB5_TGS_NAME,
+ creds.client->realm,
+ NULL);
+ if (kret)
+ goto out;
+
+ creds.times.endtime = 0;
+
+ memset(&fwd_flags, 0, sizeof(fwd_flags));
+ fwd_flags.forwarded = 1;
+ fwd_flags.forwardable = 1;
+
+ if ( /*target_name->name.name_type != KRB5_NT_SRV_HST ||*/
+ name->name.name_string.len < 2)
+ goto out;
+
+ kret = krb5_get_forwarded_creds(context,
+ ac,
+ ccache,
+ KDCOptions2int(fwd_flags),
+ name->name.name_string.val[1],
+ &creds,
+ fwd_data);
+
+ out:
+ if (kret)
+ *flags &= ~flagmask;
+ else
+ *flags |= flagmask;
+
+ if (creds.client)
+ krb5_free_principal(context, creds.client);
+ if (creds.server)
+ krb5_free_principal(context, creds.server);
+}
+
+/*
+ * first stage of init-sec-context
+ */
+
+static OM_uint32
+init_auth
+(OM_uint32 * minor_status,
+ gsskrb5_cred cred,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ gss_name_t name,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+ )
+{
+ OM_uint32 ret = GSS_S_FAILURE;
+ krb5_error_code kret;
+ krb5_data outbuf;
+ krb5_data fwd_data;
+ OM_uint32 lifetime_rec;
+ int allow_dns = 1;
+
+ krb5_data_zero(&outbuf);
+ krb5_data_zero(&fwd_data);
+
+ *minor_status = 0;
+
+ if (actual_mech_type)
+ *actual_mech_type = GSS_KRB5_MECHANISM;
+
+ if (cred == NULL) {
+ kret = krb5_cc_default (context, &ctx->ccache);
+ if (kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+ ctx->more_flags |= CLOSE_CCACHE;
+ } else
+ ctx->ccache = cred->ccache;
+
+ kret = krb5_cc_get_principal (context, ctx->ccache, &ctx->source);
+ if (kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ /*
+ * This is hideous glue for (NFS) clients that wants to limit the
+ * available enctypes to what it can support (encryption in
+ * kernel). If there is no enctypes selected for this credential,
+ * reset it to the default set of enctypes.
+ */
+ {
+ krb5_enctype *enctypes = NULL;
+
+ if (cred && cred->enctypes)
+ enctypes = cred->enctypes;
+ krb5_set_default_in_tkt_etypes(context, enctypes);
+ }
+
+ /* canon name if needed for client + target realm */
+ kret = krb5_cc_get_config(context, ctx->ccache, NULL,
+ "realm-config", &outbuf);
+ if (kret == 0) {
+ /* XXX 2 is no server canon */
+ if (outbuf.length < 1 || ((((unsigned char *)outbuf.data)[0]) & 2))
+ allow_dns = 0;
+ krb5_data_free(&outbuf);
+ }
+
+ /*
+ * First we try w/o dns, hope that the KDC have register alias
+ * (and referrals if cross realm) for this principal. If that
+ * fails and if we are allowed to using this realm try again with
+ * DNS canonicalizion.
+ */
+ ret = gsskrb5_get_creds(minor_status, context, ctx->ccache,
+ ctx, name, 0, time_req,
+ time_rec);
+ if (ret && allow_dns)
+ ret = gsskrb5_get_creds(minor_status, context, ctx->ccache,
+ ctx, name, 1, time_req,
+ time_rec);
+ if (ret)
+ goto failure;
+
+ ctx->lifetime = ctx->kcred->times.endtime;
+
+ ret = _gss_DES3_get_mic_compat(minor_status, ctx, context);
+ if (ret)
+ goto failure;
+
+ ret = _gsskrb5_lifetime_left(minor_status,
+ context,
+ ctx->lifetime,
+ &lifetime_rec);
+ if (ret)
+ goto failure;
+
+ if (lifetime_rec == 0) {
+ *minor_status = 0;
+ ret = GSS_S_CONTEXT_EXPIRED;
+ goto failure;
+ }
+
+ krb5_auth_con_setkey(context,
+ ctx->auth_context,
+ &ctx->kcred->session);
+
+ kret = krb5_auth_con_generatelocalsubkey(context,
+ ctx->auth_context,
+ &ctx->kcred->session);
+ if(kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ return GSS_S_COMPLETE;
+
+failure:
+ if (ctx->ccache && (ctx->more_flags & CLOSE_CCACHE))
+ krb5_cc_close(context, ctx->ccache);
+ ctx->ccache = NULL;
+
+ return ret;
+
+}
+
+static OM_uint32
+init_auth_restart
+(OM_uint32 * minor_status,
+ gsskrb5_cred cred,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ OM_uint32 req_flags,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+ )
+{
+ OM_uint32 ret = GSS_S_FAILURE;
+ krb5_error_code kret;
+ krb5_flags ap_options;
+ krb5_data outbuf;
+ uint32_t flags;
+ krb5_data authenticator;
+ Checksum cksum;
+ krb5_enctype enctype;
+ krb5_data fwd_data, timedata;
+ int32_t offset = 0, oldoffset = 0;
+ uint32_t flagmask;
+
+ krb5_data_zero(&outbuf);
+ krb5_data_zero(&fwd_data);
+
+ *minor_status = 0;
+
+ /*
+ * If the credential doesn't have ok-as-delegate, check if there
+ * is a realm setting and use that.
+ */
+ if (!ctx->kcred->flags.b.ok_as_delegate) {
+ krb5_data data;
+
+ ret = krb5_cc_get_config(context, ctx->ccache, NULL,
+ "realm-config", &data);
+ if (ret == 0) {
+ /* XXX 1 is use ok-as-delegate */
+ if (data.length < 1 || ((((unsigned char *)data.data)[0]) & 1) == 0)
+ req_flags &= ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG);
+ krb5_data_free(&data);
+ }
+ }
+
+ flagmask = 0;
+
+ /* if we used GSS_C_DELEG_POLICY_FLAG, trust KDC */
+ if ((req_flags & GSS_C_DELEG_POLICY_FLAG)
+ && ctx->kcred->flags.b.ok_as_delegate)
+ flagmask |= GSS_C_DELEG_FLAG | GSS_C_DELEG_POLICY_FLAG;
+ /* if there still is a GSS_C_DELEG_FLAG, use that */
+ if (req_flags & GSS_C_DELEG_FLAG)
+ flagmask |= GSS_C_DELEG_FLAG;
+
+
+ flags = 0;
+ ap_options = 0;
+ if (flagmask & GSS_C_DELEG_FLAG) {
+ do_delegation (context,
+ ctx->deleg_auth_context,
+ ctx->ccache, ctx->kcred, ctx->target,
+ &fwd_data, flagmask, &flags);
+ }
+
+ if (req_flags & GSS_C_MUTUAL_FLAG) {
+ flags |= GSS_C_MUTUAL_FLAG;
+ ap_options |= AP_OPTS_MUTUAL_REQUIRED;
+ }
+
+ if (req_flags & GSS_C_REPLAY_FLAG)
+ flags |= GSS_C_REPLAY_FLAG;
+ if (req_flags & GSS_C_SEQUENCE_FLAG)
+ flags |= GSS_C_SEQUENCE_FLAG;
+#if 0
+ if (req_flags & GSS_C_ANON_FLAG)
+ ; /* XXX */
+#endif
+ if (req_flags & GSS_C_DCE_STYLE) {
+ /* GSS_C_DCE_STYLE implies GSS_C_MUTUAL_FLAG */
+ flags |= GSS_C_DCE_STYLE | GSS_C_MUTUAL_FLAG;
+ ap_options |= AP_OPTS_MUTUAL_REQUIRED;
+ }
+ if (req_flags & GSS_C_IDENTIFY_FLAG)
+ flags |= GSS_C_IDENTIFY_FLAG;
+ if (req_flags & GSS_C_EXTENDED_ERROR_FLAG)
+ flags |= GSS_C_EXTENDED_ERROR_FLAG;
+
+ if (req_flags & GSS_C_CONF_FLAG) {
+ flags |= GSS_C_CONF_FLAG;
+ }
+ if (req_flags & GSS_C_INTEG_FLAG) {
+ flags |= GSS_C_INTEG_FLAG;
+ }
+ if (cred == NULL || !(cred->cred_flags & GSS_CF_NO_CI_FLAGS)) {
+ flags |= GSS_C_CONF_FLAG;
+ flags |= GSS_C_INTEG_FLAG;
+ }
+ flags |= GSS_C_TRANS_FLAG;
+
+ if (ret_flags)
+ *ret_flags = flags;
+ ctx->flags = flags;
+ ctx->more_flags |= LOCAL;
+
+ ret = _gsskrb5_create_8003_checksum (minor_status,
+ input_chan_bindings,
+ flags,
+ &fwd_data,
+ &cksum);
+ krb5_data_free (&fwd_data);
+ if (ret)
+ goto failure;
+
+ enctype = ctx->auth_context->keyblock->keytype;
+
+ ret = krb5_cc_get_config(context, ctx->ccache, ctx->target,
+ "time-offset", &timedata);
+ if (ret == 0) {
+ if (timedata.length == 4) {
+ const u_char *p = timedata.data;
+ offset = (p[0] <<24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
+ }
+ krb5_data_free(&timedata);
+ }
+
+ if (offset) {
+ krb5_get_kdc_sec_offset (context, &oldoffset, NULL);
+ krb5_set_kdc_sec_offset (context, offset, -1);
+ }
+
+ kret = _krb5_build_authenticator(context,
+ ctx->auth_context,
+ enctype,
+ ctx->kcred,
+ &cksum,
+ &authenticator,
+ KRB5_KU_AP_REQ_AUTH);
+
+ if (kret) {
+ if (offset)
+ krb5_set_kdc_sec_offset (context, oldoffset, -1);
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ kret = krb5_build_ap_req (context,
+ enctype,
+ ctx->kcred,
+ ap_options,
+ authenticator,
+ &outbuf);
+ if (offset)
+ krb5_set_kdc_sec_offset (context, oldoffset, -1);
+ if (kret) {
+ *minor_status = kret;
+ ret = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (flags & GSS_C_DCE_STYLE) {
+ output_token->value = outbuf.data;
+ output_token->length = outbuf.length;
+ } else {
+ ret = _gsskrb5_encapsulate (minor_status, &outbuf, output_token,
+ (u_char *)(intptr_t)"\x01\x00",
+ GSS_KRB5_MECHANISM);
+ krb5_data_free (&outbuf);
+ if (ret)
+ goto failure;
+ }
+
+ free_Checksum(&cksum);
+
+ if (flags & GSS_C_MUTUAL_FLAG) {
+ ctx->state = INITIATOR_WAIT_FOR_MUTAL;
+ return GSS_S_CONTINUE_NEEDED;
+ }
+
+ return gsskrb5_initiator_ready(minor_status, ctx, context);
+failure:
+ if (ctx->ccache && (ctx->more_flags & CLOSE_CCACHE))
+ krb5_cc_close(context, ctx->ccache);
+ ctx->ccache = NULL;
+
+ return ret;
+}
+
+static krb5_error_code
+handle_error_packet(krb5_context context,
+ gsskrb5_ctx ctx,
+ krb5_data indata)
+{
+ krb5_error_code kret;
+ KRB_ERROR error;
+
+ kret = krb5_rd_error(context, &indata, &error);
+ if (kret == 0) {
+ kret = krb5_error_from_rd_error(context, &error, NULL);
+
+ /* save the time skrew for this host */
+ if (kret == KRB5KRB_AP_ERR_SKEW) {
+ krb5_data timedata;
+ unsigned char p[4];
+ int32_t t = error.stime - time(NULL);
+
+ p[0] = (t >> 24) & 0xFF;
+ p[1] = (t >> 16) & 0xFF;
+ p[2] = (t >> 8) & 0xFF;
+ p[3] = (t >> 0) & 0xFF;
+
+ timedata.data = p;
+ timedata.length = sizeof(p);
+
+ krb5_cc_set_config(context, ctx->ccache, ctx->target,
+ "time-offset", &timedata);
+
+ if ((ctx->more_flags & RETRIED) == 0)
+ ctx->state = INITIATOR_RESTART;
+ ctx->more_flags |= RETRIED;
+ }
+ free_KRB_ERROR (&error);
+ }
+ return kret;
+}
+
+
+static OM_uint32
+repl_mutual
+(OM_uint32 * minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+ )
+{
+ OM_uint32 ret;
+ krb5_error_code kret;
+ krb5_data indata;
+ krb5_ap_rep_enc_part *repl;
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ if (actual_mech_type)
+ *actual_mech_type = GSS_KRB5_MECHANISM;
+
+ if (IS_DCE_STYLE(ctx)) {
+ /* There is no OID wrapping. */
+ indata.length = input_token->length;
+ indata.data = input_token->value;
+ kret = krb5_rd_rep(context,
+ ctx->auth_context,
+ &indata,
+ &repl);
+ if (kret) {
+ ret = _gsskrb5_decapsulate(minor_status,
+ input_token,
+ &indata,
+ "\x03\x00",
+ GSS_KRB5_MECHANISM);
+ if (ret == GSS_S_COMPLETE) {
+ *minor_status = handle_error_packet(context, ctx, indata);
+ } else {
+ *minor_status = kret;
+ }
+ return GSS_S_FAILURE;
+ }
+ } else {
+ ret = _gsskrb5_decapsulate (minor_status,
+ input_token,
+ &indata,
+ "\x02\x00",
+ GSS_KRB5_MECHANISM);
+ if (ret == GSS_S_DEFECTIVE_TOKEN) {
+ /* check if there is an error token sent instead */
+ ret = _gsskrb5_decapsulate (minor_status,
+ input_token,
+ &indata,
+ "\x03\x00",
+ GSS_KRB5_MECHANISM);
+ if (ret == GSS_S_COMPLETE) {
+ *minor_status = handle_error_packet(context, ctx, indata);
+ return GSS_S_FAILURE;
+ }
+ }
+ kret = krb5_rd_rep (context,
+ ctx->auth_context,
+ &indata,
+ &repl);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ krb5_free_ap_rep_enc_part (context,
+ repl);
+
+ *minor_status = 0;
+ if (time_rec) {
+ ret = _gsskrb5_lifetime_left(minor_status,
+ context,
+ ctx->lifetime,
+ time_rec);
+ } else {
+ ret = GSS_S_COMPLETE;
+ }
+ if (ret_flags)
+ *ret_flags = ctx->flags;
+
+ if (req_flags & GSS_C_DCE_STYLE) {
+ int32_t local_seq, remote_seq;
+ krb5_data outbuf;
+
+ /*
+ * So DCE_STYLE is strange. The client echos the seq number
+ * that the server used in the server's mk_rep in its own
+ * mk_rep(). After when done, it resets to it's own seq number
+ * for the gss_wrap calls.
+ */
+
+ krb5_auth_con_getremoteseqnumber(context, ctx->auth_context, &remote_seq);
+ krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &local_seq);
+ krb5_auth_con_setlocalseqnumber(context, ctx->auth_context, remote_seq);
+
+ kret = krb5_mk_rep(context, ctx->auth_context, &outbuf);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ /* reset local seq number */
+ krb5_auth_con_setlocalseqnumber(context, ctx->auth_context, local_seq);
+
+ output_token->length = outbuf.length;
+ output_token->value = outbuf.data;
+ }
+
+ return gsskrb5_initiator_ready(minor_status, ctx, context);
+}
+
+/*
+ * gss_init_sec_context
+ */
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_init_sec_context
+(OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+ )
+{
+ krb5_context context;
+ gsskrb5_cred cred = (gsskrb5_cred)cred_handle;
+ gsskrb5_ctx ctx;
+ OM_uint32 ret;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ if (context_handle == NULL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
+ }
+
+ if (ret_flags)
+ *ret_flags = 0;
+ if (time_rec)
+ *time_rec = 0;
+
+ if (target_name == GSS_C_NO_NAME) {
+ if (actual_mech_type)
+ *actual_mech_type = GSS_C_NO_OID;
+ *minor_status = 0;
+ return GSS_S_BAD_NAME;
+ }
+
+ if (mech_type != GSS_C_NO_OID &&
+ !gss_oid_equal(mech_type, GSS_KRB5_MECHANISM))
+ return GSS_S_BAD_MECH;
+
+ if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) {
+ OM_uint32 ret1;
+
+ if (*context_handle != GSS_C_NO_CONTEXT) {
+ *minor_status = 0;
+ return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
+ }
+
+ ret1 = _gsskrb5_create_ctx(minor_status,
+ context_handle,
+ context,
+ input_chan_bindings,
+ INITIATOR_START);
+ if (ret1)
+ return ret1;
+ }
+
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ *minor_status = 0;
+ return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
+ }
+
+ ctx = (gsskrb5_ctx) *context_handle;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ again:
+ switch (ctx->state) {
+ case INITIATOR_START:
+ ret = init_auth(minor_status,
+ cred,
+ ctx,
+ context,
+ target_name,
+ mech_type,
+ req_flags,
+ time_req,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+ if (ret != GSS_S_COMPLETE)
+ break;
+ /* FALL THOUGH */
+ case INITIATOR_RESTART:
+ ret = init_auth_restart(minor_status,
+ cred,
+ ctx,
+ context,
+ req_flags,
+ input_chan_bindings,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+ break;
+ case INITIATOR_WAIT_FOR_MUTAL:
+ ret = repl_mutual(minor_status,
+ ctx,
+ context,
+ mech_type,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+ if (ctx->state == INITIATOR_RESTART)
+ goto again;
+ break;
+ case INITIATOR_READY:
+ /*
+ * If we get there, the caller have called
+ * gss_init_sec_context() one time too many.
+ */
+ _gsskrb5_set_status(EINVAL, "init_sec_context "
+ "called one time too many");
+ *minor_status = EINVAL;
+ ret = GSS_S_BAD_STATUS;
+ break;
+ default:
+ _gsskrb5_set_status(EINVAL, "init_sec_context "
+ "invalid state %d for client",
+ (int)ctx->state);
+ *minor_status = EINVAL;
+ ret = GSS_S_BAD_STATUS;
+ break;
+ }
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ /* destroy context in case of error */
+ if (GSS_ERROR(ret)) {
+ OM_uint32 min2;
+ _gsskrb5_delete_sec_context(&min2, context_handle, GSS_C_NO_BUFFER);
+ }
+
+ return ret;
+
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/inquire_context.c b/crypto/heimdal/lib/gssapi/krb5/inquire_context.c
new file mode 100644
index 0000000..ade8ec4
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/inquire_context.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1997, 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_context (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_name_t * src_name,
+ gss_name_t * targ_name,
+ OM_uint32 * lifetime_rec,
+ gss_OID * mech_type,
+ OM_uint32 * ctx_flags,
+ int * locally_initiated,
+ int * open_context
+ )
+{
+ krb5_context context;
+ OM_uint32 ret;
+ gsskrb5_ctx ctx = (gsskrb5_ctx)context_handle;
+ gss_name_t name;
+
+ if (src_name)
+ *src_name = GSS_C_NO_NAME;
+ if (targ_name)
+ *targ_name = GSS_C_NO_NAME;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ if (src_name) {
+ name = (gss_name_t)ctx->source;
+ ret = _gsskrb5_duplicate_name (minor_status, name, src_name);
+ if (ret)
+ goto failed;
+ }
+
+ if (targ_name) {
+ name = (gss_name_t)ctx->target;
+ ret = _gsskrb5_duplicate_name (minor_status, name, targ_name);
+ if (ret)
+ goto failed;
+ }
+
+ if (lifetime_rec) {
+ ret = _gsskrb5_lifetime_left(minor_status,
+ context,
+ ctx->lifetime,
+ lifetime_rec);
+ if (ret)
+ goto failed;
+ }
+
+ if (mech_type)
+ *mech_type = GSS_KRB5_MECHANISM;
+
+ if (ctx_flags)
+ *ctx_flags = ctx->flags;
+
+ if (locally_initiated)
+ *locally_initiated = ctx->more_flags & LOCAL;
+
+ if (open_context)
+ *open_context = ctx->more_flags & OPEN;
+
+ *minor_status = 0;
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return GSS_S_COMPLETE;
+
+failed:
+ if (src_name)
+ _gsskrb5_release_name(NULL, src_name);
+ if (targ_name)
+ _gsskrb5_release_name(NULL, targ_name);
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/inquire_cred.c b/crypto/heimdal/lib/gssapi/krb5/inquire_cred.c
new file mode 100644
index 0000000..f881996
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/inquire_cred.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 1997, 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred
+(OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ gss_name_t * output_name,
+ OM_uint32 * lifetime,
+ gss_cred_usage_t * cred_usage,
+ gss_OID_set * mechanisms
+ )
+{
+ krb5_context context;
+ gss_cred_id_t aqcred_init = GSS_C_NO_CREDENTIAL;
+ gss_cred_id_t aqcred_accept = GSS_C_NO_CREDENTIAL;
+ gsskrb5_cred acred = NULL, icred = NULL;
+ OM_uint32 ret;
+
+ *minor_status = 0;
+
+ if (output_name)
+ *output_name = NULL;
+ if (mechanisms)
+ *mechanisms = GSS_C_NO_OID_SET;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL) {
+ ret = _gsskrb5_acquire_cred(minor_status,
+ GSS_C_NO_NAME,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ GSS_C_ACCEPT,
+ &aqcred_accept,
+ NULL,
+ NULL);
+ if (ret == GSS_S_COMPLETE)
+ acred = (gsskrb5_cred)aqcred_accept;
+
+ ret = _gsskrb5_acquire_cred(minor_status,
+ GSS_C_NO_NAME,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ GSS_C_INITIATE,
+ &aqcred_init,
+ NULL,
+ NULL);
+ if (ret == GSS_S_COMPLETE)
+ icred = (gsskrb5_cred)aqcred_init;
+
+ if (icred == NULL && acred == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+ } else
+ acred = (gsskrb5_cred)cred_handle;
+
+ if (acred)
+ HEIMDAL_MUTEX_lock(&acred->cred_id_mutex);
+ if (icred)
+ HEIMDAL_MUTEX_lock(&icred->cred_id_mutex);
+
+ if (output_name != NULL) {
+ if (icred && icred->principal != NULL) {
+ gss_name_t name;
+
+ if (acred && acred->principal)
+ name = (gss_name_t)acred->principal;
+ else
+ name = (gss_name_t)icred->principal;
+
+ ret = _gsskrb5_duplicate_name(minor_status, name, output_name);
+ if (ret)
+ goto out;
+ } else if (acred && acred->usage == GSS_C_ACCEPT) {
+ krb5_principal princ;
+ *minor_status = krb5_sname_to_principal(context, NULL,
+ NULL, KRB5_NT_SRV_HST,
+ &princ);
+ if (*minor_status) {
+ ret = GSS_S_FAILURE;
+ goto out;
+ }
+ *output_name = (gss_name_t)princ;
+ } else {
+ krb5_principal princ;
+ *minor_status = krb5_get_default_principal(context,
+ &princ);
+ if (*minor_status) {
+ ret = GSS_S_FAILURE;
+ goto out;
+ }
+ *output_name = (gss_name_t)princ;
+ }
+ }
+ if (lifetime != NULL) {
+ OM_uint32 alife = GSS_C_INDEFINITE, ilife = GSS_C_INDEFINITE;
+
+ if (acred) alife = acred->lifetime;
+ if (icred) ilife = icred->lifetime;
+
+ ret = _gsskrb5_lifetime_left(minor_status,
+ context,
+ min(alife,ilife),
+ lifetime);
+ if (ret)
+ goto out;
+ }
+ if (cred_usage != NULL) {
+ if (acred && icred)
+ *cred_usage = GSS_C_BOTH;
+ else if (acred)
+ *cred_usage = GSS_C_ACCEPT;
+ else if (icred)
+ *cred_usage = GSS_C_INITIATE;
+ else
+ abort();
+ }
+
+ if (mechanisms != NULL) {
+ ret = gss_create_empty_oid_set(minor_status, mechanisms);
+ if (ret)
+ goto out;
+ if (acred)
+ ret = gss_add_oid_set_member(minor_status,
+ &acred->mechanisms->elements[0],
+ mechanisms);
+ if (ret == GSS_S_COMPLETE && icred)
+ ret = gss_add_oid_set_member(minor_status,
+ &icred->mechanisms->elements[0],
+ mechanisms);
+ if (ret)
+ goto out;
+ }
+ ret = GSS_S_COMPLETE;
+out:
+ if (acred)
+ HEIMDAL_MUTEX_unlock(&acred->cred_id_mutex);
+ if (icred)
+ HEIMDAL_MUTEX_unlock(&icred->cred_id_mutex);
+
+ if (aqcred_init != GSS_C_NO_CREDENTIAL)
+ ret = _gsskrb5_release_cred(minor_status, &aqcred_init);
+ if (aqcred_accept != GSS_C_NO_CREDENTIAL)
+ ret = _gsskrb5_release_cred(minor_status, &aqcred_accept);
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c b/crypto/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
new file mode 100644
index 0000000..7bd9c11
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2003, 2006, 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred_by_mech (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID mech_type,
+ gss_name_t * name,
+ OM_uint32 * initiator_lifetime,
+ OM_uint32 * acceptor_lifetime,
+ gss_cred_usage_t * cred_usage
+ )
+{
+ gss_cred_usage_t usage;
+ OM_uint32 maj_stat;
+ OM_uint32 lifetime;
+
+ maj_stat =
+ _gsskrb5_inquire_cred (minor_status, cred_handle,
+ name, &lifetime, &usage, NULL);
+ if (maj_stat)
+ return maj_stat;
+
+ if (initiator_lifetime) {
+ if (usage == GSS_C_INITIATE || usage == GSS_C_BOTH)
+ *initiator_lifetime = lifetime;
+ else
+ *initiator_lifetime = 0;
+ }
+
+ if (acceptor_lifetime) {
+ if (usage == GSS_C_ACCEPT || usage == GSS_C_BOTH)
+ *acceptor_lifetime = lifetime;
+ else
+ *acceptor_lifetime = 0;
+ }
+
+ if (cred_usage)
+ *cred_usage = usage;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c b/crypto/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c
new file mode 100644
index 0000000..d560ed4
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred_by_oid
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ krb5_context context;
+ gsskrb5_cred cred = (gsskrb5_cred)cred_handle;
+ krb5_error_code ret;
+ gss_buffer_desc buffer;
+ char *str;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (gss_oid_equal(desired_object, GSS_KRB5_COPY_CCACHE_X) == 0) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
+
+ if (cred->ccache == NULL) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_cc_get_full_name(context, cred->ccache, &str);
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ buffer.value = str;
+ buffer.length = strlen(str);
+
+ ret = gss_add_buffer_set_member(minor_status, &buffer, data_set);
+ if (ret != GSS_S_COMPLETE)
+ _gsskrb5_clear_status ();
+
+ free(str);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
diff --git a/crypto/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c b/crypto/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c
new file mode 100644
index 0000000..6197a81
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_mechs_for_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_OID_set * mech_types
+ )
+{
+ OM_uint32 ret;
+
+ ret = gss_create_empty_oid_set(minor_status, mech_types);
+ if (ret)
+ return ret;
+
+ ret = gss_add_oid_set_member(minor_status,
+ GSS_KRB5_MECHANISM,
+ mech_types);
+ if (ret)
+ gss_release_oid_set(NULL, mech_types);
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c b/crypto/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c
new file mode 100644
index 0000000..65bd49c
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+static gss_OID name_list[] = {
+ GSS_C_NT_HOSTBASED_SERVICE,
+ GSS_C_NT_USER_NAME,
+ GSS_KRB5_NT_PRINCIPAL_NAME,
+ GSS_C_NT_EXPORT_NAME,
+ NULL
+};
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_names_for_mech (
+ OM_uint32 * minor_status,
+ const gss_OID mechanism,
+ gss_OID_set * name_types
+ )
+{
+ OM_uint32 ret;
+ int i;
+
+ *minor_status = 0;
+
+ if (gss_oid_equal(mechanism, GSS_KRB5_MECHANISM) == 0 &&
+ gss_oid_equal(mechanism, GSS_C_NULL_OID) == 0) {
+ *name_types = GSS_C_NO_OID_SET;
+ return GSS_S_BAD_MECH;
+ }
+
+ ret = gss_create_empty_oid_set(minor_status, name_types);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ for (i = 0; name_list[i] != NULL; i++) {
+ ret = gss_add_oid_set_member(minor_status,
+ name_list[i],
+ name_types);
+ if (ret != GSS_S_COMPLETE)
+ break;
+ }
+
+ if (ret != GSS_S_COMPLETE)
+ gss_release_oid_set(NULL, name_types);
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c b/crypto/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c
new file mode 100644
index 0000000..b57217a
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c
@@ -0,0 +1,605 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+static int
+oid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix)
+{
+ int ret;
+ heim_oid oid;
+ heim_oid prefix;
+
+ *suffix = 0;
+
+ ret = der_get_oid(oid_enc->elements, oid_enc->length,
+ &oid, NULL);
+ if (ret) {
+ return 0;
+ }
+
+ ret = der_get_oid(prefix_enc->elements, prefix_enc->length,
+ &prefix, NULL);
+ if (ret) {
+ der_free_oid(&oid);
+ return 0;
+ }
+
+ ret = 0;
+
+ if (oid.length - 1 == prefix.length) {
+ *suffix = oid.components[oid.length - 1];
+ oid.length--;
+ ret = (der_heim_oid_cmp(&oid, &prefix) == 0);
+ oid.length++;
+ }
+
+ der_free_oid(&oid);
+ der_free_oid(&prefix);
+
+ return ret;
+}
+
+static OM_uint32 inquire_sec_context_tkt_flags
+ (OM_uint32 *minor_status,
+ const gsskrb5_ctx context_handle,
+ gss_buffer_set_t *data_set)
+{
+ OM_uint32 tkt_flags;
+ unsigned char buf[4];
+ gss_buffer_desc value;
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+
+ if (context_handle->ticket == NULL) {
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ _gsskrb5_set_status(EINVAL, "No ticket from which to obtain flags");
+ *minor_status = EINVAL;
+ return GSS_S_BAD_MECH;
+ }
+
+ tkt_flags = TicketFlags2int(context_handle->ticket->ticket.flags);
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+
+ _gsskrb5_encode_om_uint32(tkt_flags, buf);
+ value.length = sizeof(buf);
+ value.value = buf;
+
+ return gss_add_buffer_set_member(minor_status,
+ &value,
+ data_set);
+}
+
+enum keytype { ACCEPTOR_KEY, INITIATOR_KEY, TOKEN_KEY };
+
+static OM_uint32 inquire_sec_context_get_subkey
+ (OM_uint32 *minor_status,
+ const gsskrb5_ctx context_handle,
+ krb5_context context,
+ enum keytype keytype,
+ gss_buffer_set_t *data_set)
+{
+ krb5_keyblock *key = NULL;
+ krb5_storage *sp = NULL;
+ krb5_data data;
+ OM_uint32 maj_stat = GSS_S_COMPLETE;
+ krb5_error_code ret;
+
+ krb5_data_zero(&data);
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ _gsskrb5_clear_status();
+ ret = ENOMEM;
+ goto out;
+ }
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ switch(keytype) {
+ case ACCEPTOR_KEY:
+ ret = _gsskrb5i_get_acceptor_subkey(context_handle, context, &key);
+ break;
+ case INITIATOR_KEY:
+ ret = _gsskrb5i_get_initiator_subkey(context_handle, context, &key);
+ break;
+ case TOKEN_KEY:
+ ret = _gsskrb5i_get_token_key(context_handle, context, &key);
+ break;
+ default:
+ _gsskrb5_set_status(EINVAL, "%d is not a valid subkey type", keytype);
+ ret = EINVAL;
+ break;
+ }
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ if (ret)
+ goto out;
+ if (key == NULL) {
+ _gsskrb5_set_status(EINVAL, "have no subkey of type %d", keytype);
+ ret = EINVAL;
+ goto out;
+ }
+
+ ret = krb5_store_keyblock(sp, *key);
+ krb5_free_keyblock (context, key);
+ if (ret)
+ goto out;
+
+ ret = krb5_storage_to_data(sp, &data);
+ if (ret)
+ goto out;
+
+ {
+ gss_buffer_desc value;
+
+ value.length = data.length;
+ value.value = data.data;
+
+ maj_stat = gss_add_buffer_set_member(minor_status,
+ &value,
+ data_set);
+ }
+
+out:
+ krb5_data_free(&data);
+ if (sp)
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ maj_stat = GSS_S_FAILURE;
+ }
+ return maj_stat;
+}
+
+static OM_uint32 inquire_sec_context_get_sspi_session_key
+ (OM_uint32 *minor_status,
+ const gsskrb5_ctx context_handle,
+ krb5_context context,
+ gss_buffer_set_t *data_set)
+{
+ krb5_keyblock *key;
+ OM_uint32 maj_stat = GSS_S_COMPLETE;
+ krb5_error_code ret;
+ gss_buffer_desc value;
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(context_handle, context, &key);
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+
+ if (ret)
+ goto out;
+ if (key == NULL) {
+ ret = EINVAL;
+ goto out;
+ }
+
+ value.length = key->keyvalue.length;
+ value.value = key->keyvalue.data;
+
+ maj_stat = gss_add_buffer_set_member(minor_status,
+ &value,
+ data_set);
+ krb5_free_keyblock(context, key);
+
+ /* MIT also returns the enctype encoded as an OID in data_set[1] */
+
+out:
+ if (ret) {
+ *minor_status = ret;
+ maj_stat = GSS_S_FAILURE;
+ }
+ return maj_stat;
+}
+
+static OM_uint32 inquire_sec_context_authz_data
+ (OM_uint32 *minor_status,
+ const gsskrb5_ctx context_handle,
+ krb5_context context,
+ unsigned ad_type,
+ gss_buffer_set_t *data_set)
+{
+ krb5_data data;
+ gss_buffer_desc ad_data;
+ OM_uint32 ret;
+
+ *minor_status = 0;
+ *data_set = GSS_C_NO_BUFFER_SET;
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ if (context_handle->ticket == NULL) {
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ *minor_status = EINVAL;
+ _gsskrb5_set_status(EINVAL, "No ticket to obtain authz data from");
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ret = krb5_ticket_get_authorization_data_type(context,
+ context_handle->ticket,
+ ad_type,
+ &data);
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ad_data.value = data.data;
+ ad_data.length = data.length;
+
+ ret = gss_add_buffer_set_member(minor_status,
+ &ad_data,
+ data_set);
+
+ krb5_data_free(&data);
+
+ return ret;
+}
+
+static OM_uint32 inquire_sec_context_has_updated_spnego
+ (OM_uint32 *minor_status,
+ const gsskrb5_ctx context_handle,
+ gss_buffer_set_t *data_set)
+{
+ int is_updated = 0;
+
+ *minor_status = 0;
+ *data_set = GSS_C_NO_BUFFER_SET;
+
+ /*
+ * For Windows SPNEGO implementations, both the initiator and the
+ * acceptor are assumed to have been updated if a "newer" [CLAR] or
+ * different enctype is negotiated for use by the Kerberos GSS-API
+ * mechanism.
+ */
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ is_updated = (context_handle->more_flags & IS_CFX);
+ if (is_updated == 0) {
+ krb5_keyblock *acceptor_subkey;
+
+ if (context_handle->more_flags & LOCAL)
+ acceptor_subkey = context_handle->auth_context->remote_subkey;
+ else
+ acceptor_subkey = context_handle->auth_context->local_subkey;
+
+ if (acceptor_subkey != NULL)
+ is_updated = (acceptor_subkey->keytype !=
+ context_handle->auth_context->keyblock->keytype);
+ }
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+
+ return is_updated ? GSS_S_COMPLETE : GSS_S_FAILURE;
+}
+
+/*
+ *
+ */
+
+static OM_uint32
+export_lucid_sec_context_v1(OM_uint32 *minor_status,
+ gsskrb5_ctx context_handle,
+ krb5_context context,
+ gss_buffer_set_t *data_set)
+{
+ krb5_storage *sp = NULL;
+ OM_uint32 major_status = GSS_S_COMPLETE;
+ krb5_error_code ret;
+ krb5_keyblock *key = NULL;
+ int32_t number;
+ int is_cfx;
+ krb5_data data;
+
+ *minor_status = 0;
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+
+ is_cfx = (context_handle->more_flags & IS_CFX);
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ _gsskrb5_clear_status();
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ret = krb5_store_int32(sp, 1);
+ if (ret) goto out;
+ ret = krb5_store_int32(sp, (context_handle->more_flags & LOCAL) ? 1 : 0);
+ if (ret) goto out;
+ ret = krb5_store_int32(sp, context_handle->lifetime);
+ if (ret) goto out;
+ krb5_auth_con_getlocalseqnumber (context,
+ context_handle->auth_context,
+ &number);
+ ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */
+ if (ret) goto out;
+ ret = krb5_store_uint32(sp, (uint32_t)number);
+ if (ret) goto out;
+ krb5_auth_con_getremoteseqnumber (context,
+ context_handle->auth_context,
+ &number);
+ ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */
+ if (ret) goto out;
+ ret = krb5_store_uint32(sp, (uint32_t)number);
+ if (ret) goto out;
+ ret = krb5_store_int32(sp, (is_cfx) ? 1 : 0);
+ if (ret) goto out;
+
+ ret = _gsskrb5i_get_token_key(context_handle, context, &key);
+ if (ret) goto out;
+
+ if (is_cfx == 0) {
+ int sign_alg, seal_alg;
+
+ switch (key->keytype) {
+ case ETYPE_DES_CBC_CRC:
+ case ETYPE_DES_CBC_MD4:
+ case ETYPE_DES_CBC_MD5:
+ sign_alg = 0;
+ seal_alg = 0;
+ break;
+ case ETYPE_DES3_CBC_MD5:
+ case ETYPE_DES3_CBC_SHA1:
+ sign_alg = 4;
+ seal_alg = 2;
+ break;
+ case ETYPE_ARCFOUR_HMAC_MD5:
+ case ETYPE_ARCFOUR_HMAC_MD5_56:
+ sign_alg = 17;
+ seal_alg = 16;
+ break;
+ default:
+ sign_alg = -1;
+ seal_alg = -1;
+ break;
+ }
+ ret = krb5_store_int32(sp, sign_alg);
+ if (ret) goto out;
+ ret = krb5_store_int32(sp, seal_alg);
+ if (ret) goto out;
+ /* ctx_key */
+ ret = krb5_store_keyblock(sp, *key);
+ if (ret) goto out;
+ } else {
+ int subkey_p = (context_handle->more_flags & ACCEPTOR_SUBKEY) ? 1 : 0;
+
+ /* have_acceptor_subkey */
+ ret = krb5_store_int32(sp, subkey_p);
+ if (ret) goto out;
+ /* ctx_key */
+ ret = krb5_store_keyblock(sp, *key);
+ if (ret) goto out;
+ /* acceptor_subkey */
+ if (subkey_p) {
+ ret = krb5_store_keyblock(sp, *key);
+ if (ret) goto out;
+ }
+ }
+ ret = krb5_storage_to_data(sp, &data);
+ if (ret) goto out;
+
+ {
+ gss_buffer_desc ad_data;
+
+ ad_data.value = data.data;
+ ad_data.length = data.length;
+
+ ret = gss_add_buffer_set_member(minor_status, &ad_data, data_set);
+ krb5_data_free(&data);
+ if (ret)
+ goto out;
+ }
+
+out:
+ if (key)
+ krb5_free_keyblock (context, key);
+ if (sp)
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ }
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return major_status;
+}
+
+static OM_uint32
+get_authtime(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ gss_buffer_set_t *data_set)
+
+{
+ gss_buffer_desc value;
+ unsigned char buf[4];
+ OM_uint32 authtime;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ if (ctx->ticket == NULL) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ _gsskrb5_set_status(EINVAL, "No ticket to obtain auth time from");
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ authtime = ctx->ticket->ticket.authtime;
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ _gsskrb5_encode_om_uint32(authtime, buf);
+ value.length = sizeof(buf);
+ value.value = buf;
+
+ return gss_add_buffer_set_member(minor_status,
+ &value,
+ data_set);
+}
+
+
+static OM_uint32
+get_service_keyblock
+ (OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ gss_buffer_set_t *data_set)
+{
+ krb5_storage *sp = NULL;
+ krb5_data data;
+ OM_uint32 maj_stat = GSS_S_COMPLETE;
+ krb5_error_code ret = EINVAL;
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ _gsskrb5_clear_status();
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ if (ctx->service_keyblock == NULL) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ krb5_storage_free(sp);
+ _gsskrb5_set_status(EINVAL, "No service keyblock on gssapi context");
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ krb5_data_zero(&data);
+
+ ret = krb5_store_keyblock(sp, *ctx->service_keyblock);
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ if (ret)
+ goto out;
+
+ ret = krb5_storage_to_data(sp, &data);
+ if (ret)
+ goto out;
+
+ {
+ gss_buffer_desc value;
+
+ value.length = data.length;
+ value.value = data.data;
+
+ maj_stat = gss_add_buffer_set_member(minor_status,
+ &value,
+ data_set);
+ }
+
+out:
+ krb5_data_free(&data);
+ if (sp)
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ maj_stat = GSS_S_FAILURE;
+ }
+ return maj_stat;
+}
+/*
+ *
+ */
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_sec_context_by_oid
+ (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ krb5_context context;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+ unsigned suffix;
+
+ if (ctx == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (gss_oid_equal(desired_object, GSS_KRB5_GET_TKT_FLAGS_X)) {
+ return inquire_sec_context_tkt_flags(minor_status,
+ ctx,
+ data_set);
+ } else if (gss_oid_equal(desired_object, GSS_C_PEER_HAS_UPDATED_SPNEGO)) {
+ return inquire_sec_context_has_updated_spnego(minor_status,
+ ctx,
+ data_set);
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SUBKEY_X)) {
+ return inquire_sec_context_get_subkey(minor_status,
+ ctx,
+ context,
+ TOKEN_KEY,
+ data_set);
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_INITIATOR_SUBKEY_X)) {
+ return inquire_sec_context_get_subkey(minor_status,
+ ctx,
+ context,
+ INITIATOR_KEY,
+ data_set);
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_ACCEPTOR_SUBKEY_X)) {
+ return inquire_sec_context_get_subkey(minor_status,
+ ctx,
+ context,
+ ACCEPTOR_KEY,
+ data_set);
+ } else if (gss_oid_equal(desired_object, GSS_C_INQ_SSPI_SESSION_KEY)) {
+ return inquire_sec_context_get_sspi_session_key(minor_status,
+ ctx,
+ context,
+ data_set);
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_AUTHTIME_X)) {
+ return get_authtime(minor_status, ctx, data_set);
+ } else if (oid_prefix_equal(desired_object,
+ GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X,
+ &suffix)) {
+ return inquire_sec_context_authz_data(minor_status,
+ ctx,
+ context,
+ suffix,
+ data_set);
+ } else if (oid_prefix_equal(desired_object,
+ GSS_KRB5_EXPORT_LUCID_CONTEXT_X,
+ &suffix)) {
+ if (suffix == 1)
+ return export_lucid_sec_context_v1(minor_status,
+ ctx,
+ context,
+ data_set);
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SERVICE_KEYBLOCK_X)) {
+ return get_service_keyblock(minor_status, ctx, data_set);
+ } else {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+}
+
diff --git a/crypto/heimdal/lib/gssapi/krb5/pname_to_uid.c b/crypto/heimdal/lib/gssapi/krb5/pname_to_uid.c
new file mode 100644
index 0000000..ff754e7
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/pname_to_uid.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2011, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_pname_to_uid(OM_uint32 *minor_status,
+ const gss_name_t pname,
+ const gss_OID mech_type,
+ uid_t *uidp)
+{
+#ifdef NO_LOCALNAME
+ *minor_status = KRB5_NO_LOCALNAME;
+ return GSS_S_FAILURE;
+#else
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_const_principal princ = (krb5_const_principal)pname;
+ char localname[256];
+#ifdef POSIX_GETPWNAM_R
+ char pwbuf[2048];
+ struct passwd pw, *pwd;
+#else
+ struct passwd *pwd;
+#endif
+
+ GSSAPI_KRB5_INIT(&context);
+
+ *minor_status = 0;
+
+ ret = krb5_aname_to_localname(context, princ,
+ sizeof(localname), localname);
+ if (ret != 0) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+#ifdef POSIX_GETPWNAM_R
+ if (getpwnam_r(localname, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0) {
+ *minor_status = KRB5_NO_LOCALNAME;
+ return GSS_S_FAILURE;
+ }
+#else
+ pwd = getpwnam(localname);
+#endif
+
+ if (pwd == NULL) {
+ *minor_status = KRB5_NO_LOCALNAME;
+ return GSS_S_FAILURE;
+ }
+
+ *uidp = pwd->pw_uid;
+
+ return GSS_S_COMPLETE;
+#endif /* NO_LOCALNAME */
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/prf.c b/crypto/heimdal/lib/gssapi/krb5/prf.c
new file mode 100644
index 0000000..162a309
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/prf.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_pseudo_random(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out)
+{
+ gsskrb5_ctx ctx = (gsskrb5_ctx)context_handle;
+ krb5_context context;
+ krb5_error_code ret;
+ krb5_crypto crypto;
+ krb5_data input, output;
+ uint32_t num;
+ OM_uint32 junk;
+ unsigned char *p;
+ krb5_keyblock *key = NULL;
+ size_t dol;
+
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ if (desired_output_len <= 0 || prf_in->length + 4 < prf_in->length) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+ dol = desired_output_len;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ switch(prf_key) {
+ case GSS_C_PRF_KEY_FULL:
+ _gsskrb5i_get_acceptor_subkey(ctx, context, &key);
+ break;
+ case GSS_C_PRF_KEY_PARTIAL:
+ _gsskrb5i_get_initiator_subkey(ctx, context, &key);
+ break;
+ default:
+ _gsskrb5_set_status(EINVAL, "unknown kerberos prf_key");
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (key == NULL) {
+ _gsskrb5_set_status(EINVAL, "no prf_key found");
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_crypto_init(context, key, 0, &crypto);
+ krb5_free_keyblock (context, key);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ prf_out->value = malloc(dol);
+ if (prf_out->value == NULL) {
+ _gsskrb5_set_status(GSS_KRB5_S_KG_INPUT_TOO_LONG, "Out of memory");
+ *minor_status = GSS_KRB5_S_KG_INPUT_TOO_LONG;
+ krb5_crypto_destroy(context, crypto);
+ return GSS_S_FAILURE;
+ }
+ prf_out->length = dol;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ input.length = prf_in->length + 4;
+ input.data = malloc(prf_in->length + 4);
+ if (input.data == NULL) {
+ _gsskrb5_set_status(GSS_KRB5_S_KG_INPUT_TOO_LONG, "Out of memory");
+ *minor_status = GSS_KRB5_S_KG_INPUT_TOO_LONG;
+ gss_release_buffer(&junk, prf_out);
+ krb5_crypto_destroy(context, crypto);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return GSS_S_FAILURE;
+ }
+ memcpy(((uint8_t *)input.data) + 4, prf_in->value, prf_in->length);
+
+ num = 0;
+ p = prf_out->value;
+ while(dol > 0) {
+ size_t tsize;
+
+ _gsskrb5_encode_om_uint32(num, input.data);
+
+ ret = krb5_crypto_prf(context, crypto, &input, &output);
+ if (ret) {
+ *minor_status = ret;
+ free(input.data);
+ gss_release_buffer(&junk, prf_out);
+ krb5_crypto_destroy(context, crypto);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return GSS_S_FAILURE;
+ }
+
+ tsize = min(dol, output.length);
+ memcpy(p, output.data, tsize);
+ p += output.length;
+ dol -= tsize;
+ krb5_data_free(&output);
+ num++;
+ }
+ free(input.data);
+
+ krb5_crypto_destroy(context, crypto);
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/process_context_token.c b/crypto/heimdal/lib/gssapi/krb5/process_context_token.c
new file mode 100644
index 0000000..0cc1c07
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/process_context_token.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_process_context_token (
+ OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t token_buffer
+ )
+{
+ krb5_context context;
+ OM_uint32 ret = GSS_S_FAILURE;
+ gss_buffer_desc empty_buffer;
+
+ empty_buffer.length = 0;
+ empty_buffer.value = NULL;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ ret = _gsskrb5_verify_mic_internal(minor_status,
+ (gsskrb5_ctx)context_handle,
+ context,
+ token_buffer, &empty_buffer,
+ GSS_C_QOP_DEFAULT,
+ "\x01\x02");
+
+ if (ret == GSS_S_COMPLETE)
+ ret = _gsskrb5_delete_sec_context(minor_status,
+ rk_UNCONST(&context_handle),
+ GSS_C_NO_BUFFER);
+ if (ret == GSS_S_COMPLETE)
+ *minor_status = 0;
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/release_buffer.c b/crypto/heimdal/lib/gssapi/krb5/release_buffer.c
new file mode 100644
index 0000000..b704e00
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/release_buffer.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1997 - 2000, 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 _gsskrb5_release_buffer
+ (OM_uint32 * minor_status,
+ gss_buffer_t buffer
+ )
+{
+ *minor_status = 0;
+ free (buffer->value);
+ buffer->value = NULL;
+ buffer->length = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/release_cred.c b/crypto/heimdal/lib/gssapi/krb5/release_cred.c
new file mode 100644
index 0000000..105a7a6
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/release_cred.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_release_cred
+ (OM_uint32 * minor_status,
+ gss_cred_id_t * cred_handle
+ )
+{
+ krb5_context context;
+ gsskrb5_cred cred;
+ OM_uint32 junk;
+
+ *minor_status = 0;
+
+ if (*cred_handle == NULL)
+ return GSS_S_COMPLETE;
+
+ cred = (gsskrb5_cred)*cred_handle;
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
+
+ if (cred->principal != NULL)
+ krb5_free_principal(context, cred->principal);
+ if (cred->keytab != NULL)
+ krb5_kt_close(context, cred->keytab);
+ if (cred->ccache != NULL) {
+ if (cred->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE)
+ krb5_cc_destroy(context, cred->ccache);
+ else
+ krb5_cc_close(context, cred->ccache);
+ }
+ gss_release_oid_set(&junk, &cred->mechanisms);
+ if (cred->enctypes)
+ free(cred->enctypes);
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ HEIMDAL_MUTEX_destroy(&cred->cred_id_mutex);
+ memset(cred, 0, sizeof(*cred));
+ free(cred);
+ return GSS_S_COMPLETE;
+}
+
diff --git a/crypto/heimdal/lib/gssapi/krb5/release_name.c b/crypto/heimdal/lib/gssapi/krb5/release_name.c
new file mode 100644
index 0000000..57fc8a4
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/release_name.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_release_name
+ (OM_uint32 * minor_status,
+ gss_name_t * input_name
+ )
+{
+ krb5_context context;
+ krb5_principal name = (krb5_principal)*input_name;
+
+ *minor_status = 0;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ *input_name = GSS_C_NO_NAME;
+
+ krb5_free_principal(context, name);
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/sequence.c b/crypto/heimdal/lib/gssapi/krb5/sequence.c
new file mode 100644
index 0000000..2e0e7b2
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/sequence.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2003 - 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+#define DEFAULT_JITTER_WINDOW 20
+
+struct gss_msg_order {
+ OM_uint32 flags;
+ OM_uint32 start;
+ OM_uint32 length;
+ OM_uint32 jitter_window;
+ OM_uint32 first_seq;
+ OM_uint32 elem[1];
+};
+
+
+/*
+ *
+ */
+
+static OM_uint32
+msg_order_alloc(OM_uint32 *minor_status,
+ struct gss_msg_order **o,
+ OM_uint32 jitter_window)
+{
+ size_t len;
+
+ len = jitter_window * sizeof((*o)->elem[0]);
+ len += sizeof(**o);
+ len -= sizeof((*o)->elem[0]);
+
+ *o = calloc(1, len);
+ if (*o == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+/*
+ *
+ */
+
+OM_uint32
+_gssapi_msg_order_create(OM_uint32 *minor_status,
+ struct gss_msg_order **o,
+ OM_uint32 flags,
+ OM_uint32 seq_num,
+ OM_uint32 jitter_window,
+ int use_64)
+{
+ OM_uint32 ret;
+
+ if (jitter_window == 0)
+ jitter_window = DEFAULT_JITTER_WINDOW;
+
+ ret = msg_order_alloc(minor_status, o, jitter_window);
+ if(ret != GSS_S_COMPLETE)
+ return ret;
+
+ (*o)->flags = flags;
+ (*o)->length = 0;
+ (*o)->first_seq = seq_num;
+ (*o)->jitter_window = jitter_window;
+ (*o)->elem[0] = seq_num - 1;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+_gssapi_msg_order_destroy(struct gss_msg_order **m)
+{
+ free(*m);
+ *m = NULL;
+ return GSS_S_COMPLETE;
+}
+
+static void
+elem_set(struct gss_msg_order *o, unsigned int slot, OM_uint32 val)
+{
+ o->elem[slot % o->jitter_window] = val;
+}
+
+static void
+elem_insert(struct gss_msg_order *o,
+ unsigned int after_slot,
+ OM_uint32 seq_num)
+{
+ assert(o->jitter_window > after_slot);
+
+ if (o->length > after_slot)
+ memmove(&o->elem[after_slot + 1], &o->elem[after_slot],
+ (o->length - after_slot - 1) * sizeof(o->elem[0]));
+
+ elem_set(o, after_slot, seq_num);
+
+ if (o->length < o->jitter_window)
+ o->length++;
+}
+
+/* rule 1: expected sequence number */
+/* rule 2: > expected sequence number */
+/* rule 3: seqnum < seqnum(first) */
+/* rule 4+5: seqnum in [seqnum(first),seqnum(last)] */
+
+OM_uint32
+_gssapi_msg_order_check(struct gss_msg_order *o, OM_uint32 seq_num)
+{
+ OM_uint32 r;
+ size_t i;
+
+ if (o == NULL)
+ return GSS_S_COMPLETE;
+
+ if ((o->flags & (GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG)) == 0)
+ return GSS_S_COMPLETE;
+
+ /* check if the packet is the next in order */
+ if (o->elem[0] == seq_num - 1) {
+ elem_insert(o, 0, seq_num);
+ return GSS_S_COMPLETE;
+ }
+
+ r = (o->flags & (GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG))==GSS_C_REPLAY_FLAG;
+
+ /* sequence number larger then largest sequence number
+ * or smaller then the first sequence number */
+ if (seq_num > o->elem[0]
+ || seq_num < o->first_seq
+ || o->length == 0)
+ {
+ elem_insert(o, 0, seq_num);
+ if (r) {
+ return GSS_S_COMPLETE;
+ } else {
+ return GSS_S_GAP_TOKEN;
+ }
+ }
+
+ assert(o->length > 0);
+
+ /* sequence number smaller the first sequence number */
+ if (seq_num < o->elem[o->length - 1]) {
+ if (r)
+ return(GSS_S_OLD_TOKEN);
+ else
+ return(GSS_S_UNSEQ_TOKEN);
+ }
+
+ if (seq_num == o->elem[o->length - 1]) {
+ return GSS_S_DUPLICATE_TOKEN;
+ }
+
+ for (i = 0; i < o->length - 1; i++) {
+ if (o->elem[i] == seq_num)
+ return GSS_S_DUPLICATE_TOKEN;
+ if (o->elem[i + 1] < seq_num && o->elem[i] < seq_num) {
+ elem_insert(o, i, seq_num);
+ if (r)
+ return GSS_S_COMPLETE;
+ else
+ return GSS_S_UNSEQ_TOKEN;
+ }
+ }
+
+ return GSS_S_FAILURE;
+}
+
+OM_uint32
+_gssapi_msg_order_f(OM_uint32 flags)
+{
+ return flags & (GSS_C_SEQUENCE_FLAG|GSS_C_REPLAY_FLAG);
+}
+
+/*
+ * Translate `o` into inter-process format and export in to `sp'.
+ */
+
+krb5_error_code
+_gssapi_msg_order_export(krb5_storage *sp, struct gss_msg_order *o)
+{
+ krb5_error_code kret;
+ OM_uint32 i;
+
+ kret = krb5_store_int32(sp, o->flags);
+ if (kret)
+ return kret;
+ kret = krb5_store_int32(sp, o->start);
+ if (kret)
+ return kret;
+ kret = krb5_store_int32(sp, o->length);
+ if (kret)
+ return kret;
+ kret = krb5_store_int32(sp, o->jitter_window);
+ if (kret)
+ return kret;
+ kret = krb5_store_int32(sp, o->first_seq);
+ if (kret)
+ return kret;
+
+ for (i = 0; i < o->jitter_window; i++) {
+ kret = krb5_store_int32(sp, o->elem[i]);
+ if (kret)
+ return kret;
+ }
+
+ return 0;
+}
+
+OM_uint32
+_gssapi_msg_order_import(OM_uint32 *minor_status,
+ krb5_storage *sp,
+ struct gss_msg_order **o)
+{
+ OM_uint32 ret;
+ krb5_error_code kret;
+ int32_t i, flags, start, length, jitter_window, first_seq;
+
+ kret = krb5_ret_int32(sp, &flags);
+ if (kret)
+ goto failed;
+ kret = krb5_ret_int32(sp, &start);
+ if (kret)
+ goto failed;
+ kret = krb5_ret_int32(sp, &length);
+ if (kret)
+ goto failed;
+ kret = krb5_ret_int32(sp, &jitter_window);
+ if (kret)
+ goto failed;
+ kret = krb5_ret_int32(sp, &first_seq);
+ if (kret)
+ goto failed;
+
+ ret = msg_order_alloc(minor_status, o, jitter_window);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ (*o)->flags = flags;
+ (*o)->start = start;
+ (*o)->length = length;
+ (*o)->jitter_window = jitter_window;
+ (*o)->first_seq = first_seq;
+
+ for( i = 0; i < jitter_window; i++ ) {
+ kret = krb5_ret_int32(sp, (int32_t*)&((*o)->elem[i]));
+ if (kret)
+ goto failed;
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+
+failed:
+ _gssapi_msg_order_destroy(o);
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/set_cred_option.c b/crypto/heimdal/lib/gssapi/krb5/set_cred_option.c
new file mode 100644
index 0000000..bd38716
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/set_cred_option.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+static OM_uint32
+import_cred(OM_uint32 *minor_status,
+ krb5_context context,
+ gss_cred_id_t *cred_handle,
+ const gss_buffer_t value)
+{
+ OM_uint32 major_stat;
+ krb5_error_code ret;
+ krb5_principal keytab_principal = NULL;
+ krb5_keytab keytab = NULL;
+ krb5_storage *sp = NULL;
+ krb5_ccache id = NULL;
+ char *str;
+
+ if (cred_handle == NULL || *cred_handle != GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+
+ sp = krb5_storage_from_mem(value->value, value->length);
+ if (sp == NULL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+
+ /* credential cache name */
+ ret = krb5_ret_string(sp, &str);
+ if (ret) {
+ *minor_status = ret;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+ if (str[0]) {
+ ret = krb5_cc_resolve(context, str, &id);
+ if (ret) {
+ *minor_status = ret;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+ }
+ free(str);
+ str = NULL;
+
+ /* keytab principal name */
+ ret = krb5_ret_string(sp, &str);
+ if (ret == 0 && str[0])
+ ret = krb5_parse_name(context, str, &keytab_principal);
+ if (ret) {
+ *minor_status = ret;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+ free(str);
+ str = NULL;
+
+ /* keytab principal */
+ ret = krb5_ret_string(sp, &str);
+ if (ret) {
+ *minor_status = ret;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+ if (str[0]) {
+ ret = krb5_kt_resolve(context, str, &keytab);
+ if (ret) {
+ *minor_status = ret;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+ }
+ free(str);
+ str = NULL;
+
+ major_stat = _gsskrb5_krb5_import_cred(minor_status, id, keytab_principal,
+ keytab, cred_handle);
+out:
+ if (id)
+ krb5_cc_close(context, id);
+ if (keytab_principal)
+ krb5_free_principal(context, keytab_principal);
+ if (keytab)
+ krb5_kt_close(context, keytab);
+ if (str)
+ free(str);
+ if (sp)
+ krb5_storage_free(sp);
+
+ return major_stat;
+}
+
+
+static OM_uint32
+allowed_enctypes(OM_uint32 *minor_status,
+ krb5_context context,
+ gss_cred_id_t *cred_handle,
+ const gss_buffer_t value)
+{
+ OM_uint32 major_stat;
+ krb5_error_code ret;
+ size_t len, i;
+ krb5_enctype *enctypes = NULL;
+ krb5_storage *sp = NULL;
+ gsskrb5_cred cred;
+
+ if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+
+ cred = (gsskrb5_cred)*cred_handle;
+
+ if ((value->length % 4) != 0) {
+ *minor_status = 0;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+
+ len = value->length / 4;
+ enctypes = malloc((len + 1) * 4);
+ if (enctypes == NULL) {
+ *minor_status = ENOMEM;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+
+ sp = krb5_storage_from_mem(value->value, value->length);
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+
+ for (i = 0; i < len; i++) {
+ uint32_t e;
+
+ ret = krb5_ret_uint32(sp, &e);
+ if (ret) {
+ *minor_status = ret;
+ major_stat = GSS_S_FAILURE;
+ goto out;
+ }
+ enctypes[i] = e;
+ }
+ enctypes[i] = 0;
+
+ if (cred->enctypes)
+ free(cred->enctypes);
+ cred->enctypes = enctypes;
+
+ krb5_storage_free(sp);
+
+ return GSS_S_COMPLETE;
+
+out:
+ if (sp)
+ krb5_storage_free(sp);
+ if (enctypes)
+ free(enctypes);
+
+ return major_stat;
+}
+
+static OM_uint32
+no_ci_flags(OM_uint32 *minor_status,
+ krb5_context context,
+ gss_cred_id_t *cred_handle,
+ const gss_buffer_t value)
+{
+ gsskrb5_cred cred;
+
+ if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+
+ cred = (gsskrb5_cred)*cred_handle;
+ cred->cred_flags |= GSS_CF_NO_CI_FLAGS;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+
+}
+
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_set_cred_option
+ (OM_uint32 *minor_status,
+ gss_cred_id_t *cred_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value)
+{
+ krb5_context context;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (value == GSS_C_NO_BUFFER) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X))
+ return import_cred(minor_status, context, cred_handle, value);
+
+ if (gss_oid_equal(desired_object, GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X))
+ return allowed_enctypes(minor_status, context, cred_handle, value);
+
+ if (gss_oid_equal(desired_object, GSS_KRB5_CRED_NO_CI_FLAGS_X)) {
+ return no_ci_flags(minor_status, context, cred_handle, value);
+ }
+
+
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/set_sec_context_option.c b/crypto/heimdal/lib/gssapi/krb5/set_sec_context_option.c
new file mode 100644
index 0000000..141ff72
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/set_sec_context_option.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+/*
+ * glue routine for _gsskrb5_inquire_sec_context_by_oid
+ */
+
+#include "gsskrb5_locl.h"
+
+static OM_uint32
+get_bool(OM_uint32 *minor_status,
+ const gss_buffer_t value,
+ int *flag)
+{
+ if (value->value == NULL || value->length != 1) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ *flag = *((const char *)value->value) != 0;
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+get_string(OM_uint32 *minor_status,
+ const gss_buffer_t value,
+ char **str)
+{
+ if (value == NULL || value->length == 0) {
+ *str = NULL;
+ } else {
+ *str = malloc(value->length + 1);
+ if (*str == NULL) {
+ *minor_status = 0;
+ return GSS_S_UNAVAILABLE;
+ }
+ memcpy(*str, value->value, value->length);
+ (*str)[value->length] = '\0';
+ }
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+get_int32(OM_uint32 *minor_status,
+ const gss_buffer_t value,
+ OM_uint32 *ret)
+{
+ *minor_status = 0;
+ if (value == NULL || value->length == 0)
+ *ret = 0;
+ else if (value->length == sizeof(*ret))
+ memcpy(ret, value->value, sizeof(*ret));
+ else
+ return GSS_S_UNAVAILABLE;
+
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+set_int32(OM_uint32 *minor_status,
+ const gss_buffer_t value,
+ OM_uint32 set)
+{
+ *minor_status = 0;
+ if (value->length == sizeof(set))
+ memcpy(value->value, &set, sizeof(set));
+ else
+ return GSS_S_UNAVAILABLE;
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_set_sec_context_option
+ (OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value)
+{
+ krb5_context context;
+ OM_uint32 maj_stat;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (value == GSS_C_NO_BUFFER) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (gss_oid_equal(desired_object, GSS_KRB5_COMPAT_DES3_MIC_X)) {
+ gsskrb5_ctx ctx;
+ int flag;
+
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ *minor_status = EINVAL;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ maj_stat = get_bool(minor_status, value, &flag);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+
+ ctx = (gsskrb5_ctx)*context_handle;
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ if (flag)
+ ctx->more_flags |= COMPAT_OLD_DES3;
+ else
+ ctx->more_flags &= ~COMPAT_OLD_DES3;
+ ctx->more_flags |= COMPAT_OLD_DES3_SELECTED;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return GSS_S_COMPLETE;
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DNS_CANONICALIZE_X)) {
+ int flag;
+
+ maj_stat = get_bool(minor_status, value, &flag);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+
+ krb5_set_dns_canonicalize_hostname(context, flag);
+ return GSS_S_COMPLETE;
+
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) {
+ char *str;
+
+ maj_stat = get_string(minor_status, value, &str);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+
+ maj_stat = _gsskrb5_register_acceptor_identity(minor_status, str);
+ free(str);
+
+ return maj_stat;
+
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DEFAULT_REALM_X)) {
+ char *str;
+
+ maj_stat = get_string(minor_status, value, &str);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+ if (str == NULL) {
+ *minor_status = 0;
+ return GSS_S_CALL_INACCESSIBLE_READ;
+ }
+
+ krb5_set_default_realm(context, str);
+ free(str);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_SEND_TO_KDC_X)) {
+
+ if (value == NULL || value->length == 0) {
+ krb5_set_send_to_kdc_func(context, NULL, NULL);
+ } else {
+ struct gsskrb5_send_to_kdc c;
+
+ if (value->length != sizeof(c)) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ memcpy(&c, value->value, sizeof(c));
+ krb5_set_send_to_kdc_func(context,
+ (krb5_send_to_kdc_func)c.func,
+ c.ptr);
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_CCACHE_NAME_X)) {
+ char *str;
+
+ maj_stat = get_string(minor_status, value, &str);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+ if (str == NULL) {
+ *minor_status = 0;
+ return GSS_S_CALL_INACCESSIBLE_READ;
+ }
+
+ *minor_status = krb5_cc_set_default_name(context, str);
+ free(str);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+
+ return GSS_S_COMPLETE;
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_TIME_OFFSET_X)) {
+ OM_uint32 offset;
+ time_t t;
+
+ maj_stat = get_int32(minor_status, value, &offset);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+
+ t = time(NULL) + offset;
+
+ krb5_set_real_time(context, t, 0);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_TIME_OFFSET_X)) {
+ krb5_timestamp sec;
+ int32_t usec;
+ time_t t;
+
+ t = time(NULL);
+
+ krb5_us_timeofday (context, &sec, &usec);
+
+ maj_stat = set_int32(minor_status, value, sec - t);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_PLUGIN_REGISTER_X)) {
+ struct gsskrb5_krb5_plugin c;
+
+ if (value->length != sizeof(c)) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ memcpy(&c, value->value, sizeof(c));
+ krb5_plugin_register(context, c.type, c.name, c.symbol);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ }
+
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/store_cred.c b/crypto/heimdal/lib/gssapi/krb5/store_cred.c
new file mode 100644
index 0000000..a3aa2fb
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/store_cred.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_store_cred(OM_uint32 *minor_status,
+ gss_cred_id_t input_cred_handle,
+ gss_cred_usage_t cred_usage,
+ const gss_OID desired_mech,
+ OM_uint32 overwrite_cred,
+ OM_uint32 default_cred,
+ gss_OID_set *elements_stored,
+ gss_cred_usage_t *cred_usage_stored)
+{
+ krb5_context context;
+ krb5_error_code ret;
+ gsskrb5_cred cred;
+ krb5_ccache id;
+ int destroy = 0;
+
+ *minor_status = 0;
+
+ if (cred_usage != GSS_C_INITIATE) {
+ *minor_status = GSS_KRB5_S_G_BAD_USAGE;
+ return GSS_S_FAILURE;
+ }
+
+ if (gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0)
+ return GSS_S_BAD_MECH;
+
+ cred = (gsskrb5_cred)input_cred_handle;
+ if (cred == NULL)
+ return GSS_S_NO_CRED;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);
+ if (cred->usage != cred_usage && cred->usage != GSS_C_BOTH) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = GSS_KRB5_S_G_BAD_USAGE;
+ return(GSS_S_FAILURE);
+ }
+
+ if (cred->principal == NULL) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = GSS_KRB5_S_KG_TGT_MISSING;
+ return(GSS_S_FAILURE);
+ }
+
+ /* write out cred to credential cache */
+
+ ret = krb5_cc_cache_match(context, cred->principal, &id);
+ if (ret) {
+ ret = krb5_cc_new_unique(context, NULL, NULL, &id);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = ret;
+ return(GSS_S_FAILURE);
+ }
+ destroy = 1;
+ }
+
+ ret = krb5_cc_initialize(context, id, cred->principal);
+ if (ret == 0)
+ ret = krb5_cc_copy_match_f(context, cred->ccache, id, NULL, NULL, NULL);
+ if (ret) {
+ if (destroy)
+ krb5_cc_destroy(context, id);
+ else
+ krb5_cc_close(context, id);
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+ *minor_status = ret;
+ return(GSS_S_FAILURE);
+ }
+
+ if (default_cred)
+ krb5_cc_switch(context, id);
+
+ krb5_cc_close(context, id);
+
+ HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/test_cfx.c b/crypto/heimdal/lib/gssapi/krb5/test_cfx.c
new file mode 100644
index 0000000..0b196fc
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/test_cfx.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+struct range {
+ size_t lower;
+ size_t upper;
+};
+
+struct range tests[] = {
+ { 0, 1040 },
+ { 2040, 2080 },
+ { 4080, 5000 },
+ { 8180, 8292 },
+ { 9980, 10010 }
+};
+
+static void
+test_range(const struct range *r, int integ,
+ krb5_context context, krb5_crypto crypto)
+{
+ krb5_error_code ret;
+ size_t size, rsize;
+ struct gsskrb5_ctx ctx;
+
+ for (size = r->lower; size < r->upper; size++) {
+ size_t cksumsize;
+ uint16_t padsize;
+ OM_uint32 minor;
+ OM_uint32 max_wrap_size;
+
+ ctx.crypto = crypto;
+
+ ret = _gssapi_wrap_size_cfx(&minor,
+ &ctx,
+ context,
+ integ,
+ 0,
+ size,
+ &max_wrap_size);
+ if (ret)
+ krb5_errx(context, 1, "_gsskrb5cfx_max_wrap_length_cfx: %d", ret);
+ if (max_wrap_size == 0)
+ continue;
+
+ ret = _gsskrb5cfx_wrap_length_cfx(context,
+ crypto,
+ integ,
+ 0,
+ max_wrap_size,
+ &rsize, &cksumsize, &padsize);
+ if (ret)
+ krb5_errx(context, 1, "_gsskrb5cfx_wrap_length_cfx: %d", ret);
+
+ if (size < rsize)
+ krb5_errx(context, 1,
+ "size (%d) < rsize (%d) for max_wrap_size %d",
+ (int)size, (int)rsize, (int)max_wrap_size);
+ }
+}
+
+static void
+test_special(krb5_context context, krb5_crypto crypto,
+ int integ, size_t testsize)
+{
+ krb5_error_code ret;
+ size_t rsize;
+ OM_uint32 max_wrap_size;
+ size_t cksumsize;
+ uint16_t padsize;
+ struct gsskrb5_ctx ctx;
+ OM_uint32 minor;
+
+ ctx.crypto = crypto;
+
+ ret = _gssapi_wrap_size_cfx(&minor,
+ &ctx,
+ context,
+ integ,
+ 0,
+ testsize,
+ &max_wrap_size);
+ if (ret)
+ krb5_errx(context, 1, "_gsskrb5cfx_max_wrap_length_cfx: %d", ret);
+ if (ret)
+ krb5_errx(context, 1, "_gsskrb5cfx_max_wrap_length_cfx: %d", ret);
+
+ ret = _gsskrb5cfx_wrap_length_cfx(context,
+ crypto,
+ integ,
+ 0,
+ max_wrap_size,
+ &rsize, &cksumsize, &padsize);
+ if (ret)
+ krb5_errx(context, 1, "_gsskrb5cfx_wrap_length_cfx: %d", ret);
+
+ if (testsize < rsize)
+ krb5_errx(context, 1,
+ "testsize (%d) < rsize (%d) for max_wrap_size %d",
+ (int)testsize, (int)rsize, (int)max_wrap_size);
+}
+
+
+
+
+int
+main(int argc, char **argv)
+{
+ krb5_keyblock keyblock;
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_crypto crypto;
+ int i;
+
+ ret = krb5_init_context(&context);
+ if (ret)
+ errx(1, "krb5_context_init: %d", ret);
+
+ ret = krb5_generate_random_keyblock(context,
+ ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+ &keyblock);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
+
+ ret = krb5_crypto_init(context, &keyblock, 0, &crypto);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_crypto_init");
+
+ test_special(context, crypto, 1, 60);
+ test_special(context, crypto, 0, 60);
+
+ for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
+ test_range(&tests[i], 1, context, crypto);
+ test_range(&tests[i], 0, context, crypto);
+ }
+
+ krb5_free_keyblock_contents(context, &keyblock);
+ krb5_crypto_destroy(context, crypto);
+ krb5_free_context(context);
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/ticket_flags.c b/crypto/heimdal/lib/gssapi/krb5/ticket_flags.c
new file mode 100644
index 0000000..df5f11d
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/ticket_flags.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+OM_uint32
+_gsskrb5_get_tkt_flags(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ OM_uint32 *tkt_flags)
+{
+ if (ctx == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_NO_CONTEXT;
+ }
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ if (ctx->ticket == NULL) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ *minor_status = EINVAL;
+ return GSS_S_BAD_MECH;
+ }
+
+ *tkt_flags = TicketFlags2int(ctx->ticket->ticket.flags);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/unwrap.c b/crypto/heimdal/lib/gssapi/krb5/unwrap.c
new file mode 100644
index 0000000..d6bc204
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/unwrap.c
@@ -0,0 +1,448 @@
+/*
+ * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+#ifdef HEIM_WEAK_CRYPTO
+
+static OM_uint32
+unwrap_des
+ (OM_uint32 * minor_status,
+ const gsskrb5_ctx context_handle,
+ const gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int * conf_state,
+ gss_qop_t * qop_state,
+ krb5_keyblock *key
+ )
+{
+ u_char *p, *seq;
+ size_t len;
+ EVP_MD_CTX *md5;
+ u_char hash[16];
+ EVP_CIPHER_CTX des_ctx;
+ DES_key_schedule schedule;
+ DES_cblock deskey;
+ DES_cblock zero;
+ size_t i;
+ uint32_t seq_number;
+ size_t padlength;
+ OM_uint32 ret;
+ int cstate;
+ int cmp;
+ int token_len;
+
+ if (IS_DCE_STYLE(context_handle)) {
+ token_len = 22 + 8 + 15; /* 45 */
+ } else {
+ token_len = input_message_buffer->length;
+ }
+
+ p = input_message_buffer->value;
+ ret = _gsskrb5_verify_header (&p,
+ token_len,
+ "\x02\x01",
+ GSS_KRB5_MECHANISM);
+ if (ret)
+ return ret;
+
+ if (memcmp (p, "\x00\x00", 2) != 0)
+ return GSS_S_BAD_SIG;
+ p += 2;
+ if (memcmp (p, "\x00\x00", 2) == 0) {
+ cstate = 1;
+ } else if (memcmp (p, "\xFF\xFF", 2) == 0) {
+ cstate = 0;
+ } else
+ return GSS_S_BAD_MIC;
+ p += 2;
+ if(conf_state != NULL)
+ *conf_state = cstate;
+ if (memcmp (p, "\xff\xff", 2) != 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ p += 2;
+ p += 16;
+
+ len = p - (u_char *)input_message_buffer->value;
+
+ if(cstate) {
+ /* decrypt data */
+ memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
+ memset (&zero, 0, sizeof(zero));
+
+ for (i = 0; i < sizeof(deskey); ++i)
+ deskey[i] ^= 0xf0;
+
+
+ EVP_CIPHER_CTX_init(&des_ctx);
+ EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, deskey, zero, 0);
+ EVP_Cipher(&des_ctx, p, p, input_message_buffer->length - len);
+ EVP_CIPHER_CTX_cleanup(&des_ctx);
+
+ memset (&schedule, 0, sizeof(schedule));
+ }
+
+ if (IS_DCE_STYLE(context_handle)) {
+ padlength = 0;
+ } else {
+ /* check pad */
+ ret = _gssapi_verify_pad(input_message_buffer,
+ input_message_buffer->length - len,
+ &padlength);
+ if (ret)
+ return ret;
+ }
+
+ md5 = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(md5, EVP_md5(), NULL);
+ EVP_DigestUpdate(md5, p - 24, 8);
+ EVP_DigestUpdate(md5, p, input_message_buffer->length - len);
+ EVP_DigestFinal_ex(md5, hash, NULL);
+ EVP_MD_CTX_destroy(md5);
+
+ memset (&zero, 0, sizeof(zero));
+ memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
+ DES_set_key_unchecked (&deskey, &schedule);
+ DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
+ &schedule, &zero);
+ if (ct_memcmp (p - 8, hash, 8) != 0)
+ return GSS_S_BAD_MIC;
+
+ /* verify sequence number */
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+
+ p -= 16;
+
+ EVP_CIPHER_CTX_init(&des_ctx);
+ EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
+ EVP_Cipher(&des_ctx, p, p, 8);
+ EVP_CIPHER_CTX_cleanup(&des_ctx);
+
+ memset (deskey, 0, sizeof(deskey));
+ memset (&schedule, 0, sizeof(schedule));
+
+ seq = p;
+ _gsskrb5_decode_om_uint32(seq, &seq_number);
+
+ if (context_handle->more_flags & LOCAL)
+ cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
+ else
+ cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
+
+ if (cmp != 0) {
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return GSS_S_BAD_MIC;
+ }
+
+ ret = _gssapi_msg_order_check(context_handle->order, seq_number);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return ret;
+ }
+
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+
+ /* copy out data */
+
+ output_message_buffer->length = input_message_buffer->length
+ - len - padlength - 8;
+ output_message_buffer->value = malloc(output_message_buffer->length);
+ if(output_message_buffer->length != 0 && output_message_buffer->value == NULL)
+ return GSS_S_FAILURE;
+ memcpy (output_message_buffer->value,
+ p + 24,
+ output_message_buffer->length);
+ return GSS_S_COMPLETE;
+}
+#endif
+
+static OM_uint32
+unwrap_des3
+ (OM_uint32 * minor_status,
+ const gsskrb5_ctx context_handle,
+ krb5_context context,
+ const gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int * conf_state,
+ gss_qop_t * qop_state,
+ krb5_keyblock *key
+ )
+{
+ u_char *p;
+ size_t len;
+ u_char *seq;
+ krb5_data seq_data;
+ u_char cksum[20];
+ uint32_t seq_number;
+ size_t padlength;
+ OM_uint32 ret;
+ int cstate;
+ krb5_crypto crypto;
+ Checksum csum;
+ int cmp;
+ int token_len;
+
+ if (IS_DCE_STYLE(context_handle)) {
+ token_len = 34 + 8 + 15; /* 57 */
+ } else {
+ token_len = input_message_buffer->length;
+ }
+
+ p = input_message_buffer->value;
+ ret = _gsskrb5_verify_header (&p,
+ token_len,
+ "\x02\x01",
+ GSS_KRB5_MECHANISM);
+ if (ret)
+ return ret;
+
+ if (memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */
+ return GSS_S_BAD_SIG;
+ p += 2;
+ if (ct_memcmp (p, "\x02\x00", 2) == 0) {
+ cstate = 1;
+ } else if (ct_memcmp (p, "\xff\xff", 2) == 0) {
+ cstate = 0;
+ } else
+ return GSS_S_BAD_MIC;
+ p += 2;
+ if(conf_state != NULL)
+ *conf_state = cstate;
+ if (ct_memcmp (p, "\xff\xff", 2) != 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ p += 2;
+ p += 28;
+
+ len = p - (u_char *)input_message_buffer->value;
+
+ if(cstate) {
+ /* decrypt data */
+ krb5_data tmp;
+
+ ret = krb5_crypto_init(context, key,
+ ETYPE_DES3_CBC_NONE, &crypto);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ ret = krb5_decrypt(context, crypto, KRB5_KU_USAGE_SEAL,
+ p, input_message_buffer->length - len, &tmp);
+ krb5_crypto_destroy(context, crypto);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ assert (tmp.length == input_message_buffer->length - len);
+
+ memcpy (p, tmp.data, tmp.length);
+ krb5_data_free(&tmp);
+ }
+
+ if (IS_DCE_STYLE(context_handle)) {
+ padlength = 0;
+ } else {
+ /* check pad */
+ ret = _gssapi_verify_pad(input_message_buffer,
+ input_message_buffer->length - len,
+ &padlength);
+ if (ret)
+ return ret;
+ }
+
+ /* verify sequence number */
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+
+ p -= 28;
+
+ ret = krb5_crypto_init(context, key,
+ ETYPE_DES3_CBC_NONE, &crypto);
+ if (ret) {
+ *minor_status = ret;
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return GSS_S_FAILURE;
+ }
+ {
+ DES_cblock ivec;
+
+ memcpy(&ivec, p + 8, 8);
+ ret = krb5_decrypt_ivec (context,
+ crypto,
+ KRB5_KU_USAGE_SEQ,
+ p, 8, &seq_data,
+ &ivec);
+ }
+ krb5_crypto_destroy (context, crypto);
+ if (ret) {
+ *minor_status = ret;
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return GSS_S_FAILURE;
+ }
+ if (seq_data.length != 8) {
+ krb5_data_free (&seq_data);
+ *minor_status = 0;
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return GSS_S_BAD_MIC;
+ }
+
+ seq = seq_data.data;
+ _gsskrb5_decode_om_uint32(seq, &seq_number);
+
+ if (context_handle->more_flags & LOCAL)
+ cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
+ else
+ cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
+
+ krb5_data_free (&seq_data);
+ if (cmp != 0) {
+ *minor_status = 0;
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return GSS_S_BAD_MIC;
+ }
+
+ ret = _gssapi_msg_order_check(context_handle->order, seq_number);
+ if (ret) {
+ *minor_status = 0;
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return ret;
+ }
+
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+
+ /* verify checksum */
+
+ memcpy (cksum, p + 8, 20);
+
+ memcpy (p + 20, p - 8, 8);
+
+ csum.cksumtype = CKSUMTYPE_HMAC_SHA1_DES3;
+ csum.checksum.length = 20;
+ csum.checksum.data = cksum;
+
+ ret = krb5_crypto_init(context, key, 0, &crypto);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_verify_checksum (context, crypto,
+ KRB5_KU_USAGE_SIGN,
+ p + 20,
+ input_message_buffer->length - len + 8,
+ &csum);
+ krb5_crypto_destroy (context, crypto);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ /* copy out data */
+
+ output_message_buffer->length = input_message_buffer->length
+ - len - padlength - 8;
+ output_message_buffer->value = malloc(output_message_buffer->length);
+ if(output_message_buffer->length != 0 && output_message_buffer->value == NULL)
+ return GSS_S_FAILURE;
+ memcpy (output_message_buffer->value,
+ p + 36,
+ output_message_buffer->length);
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int * conf_state,
+ gss_qop_t * qop_state
+ )
+{
+ krb5_keyblock *key;
+ krb5_context context;
+ OM_uint32 ret;
+ krb5_keytype keytype;
+ gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
+
+ output_message_buffer->value = NULL;
+ output_message_buffer->length = 0;
+ if (qop_state != NULL)
+ *qop_state = GSS_C_QOP_DEFAULT;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_unwrap_cfx (minor_status, ctx, context,
+ input_message_buffer, output_message_buffer,
+ conf_state, qop_state);
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(ctx, context, &key);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ krb5_enctype_to_keytype (context, key->keytype, &keytype);
+
+ *minor_status = 0;
+
+ switch (keytype) {
+ case KEYTYPE_DES :
+#ifdef HEIM_WEAK_CRYPTO
+ ret = unwrap_des (minor_status, ctx,
+ input_message_buffer, output_message_buffer,
+ conf_state, qop_state, key);
+#else
+ ret = GSS_S_FAILURE;
+#endif
+ break;
+ case KEYTYPE_DES3 :
+ ret = unwrap_des3 (minor_status, ctx, context,
+ input_message_buffer, output_message_buffer,
+ conf_state, qop_state, key);
+ break;
+ case KEYTYPE_ARCFOUR:
+ case KEYTYPE_ARCFOUR_56:
+ ret = _gssapi_unwrap_arcfour (minor_status, ctx, context,
+ input_message_buffer, output_message_buffer,
+ conf_state, qop_state, key);
+ break;
+ default :
+ abort();
+ break;
+ }
+ krb5_free_keyblock (context, key);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/verify_mic.c b/crypto/heimdal/lib/gssapi/krb5/verify_mic.c
new file mode 100644
index 0000000..3123787
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/verify_mic.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+#ifdef HEIM_WEAK_CRYPTO
+
+static OM_uint32
+verify_mic_des
+ (OM_uint32 * minor_status,
+ const gsskrb5_ctx context_handle,
+ krb5_context context,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t * qop_state,
+ krb5_keyblock *key,
+ const char *type
+ )
+{
+ u_char *p;
+ EVP_MD_CTX *md5;
+ u_char hash[16], *seq;
+ DES_key_schedule schedule;
+ EVP_CIPHER_CTX des_ctx;
+ DES_cblock zero;
+ DES_cblock deskey;
+ uint32_t seq_number;
+ OM_uint32 ret;
+ int cmp;
+
+ p = token_buffer->value;
+ ret = _gsskrb5_verify_header (&p,
+ token_buffer->length,
+ type,
+ GSS_KRB5_MECHANISM);
+ if (ret)
+ return ret;
+
+ if (memcmp(p, "\x00\x00", 2) != 0)
+ return GSS_S_BAD_SIG;
+ p += 2;
+ if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
+ return GSS_S_BAD_MIC;
+ p += 4;
+ p += 16;
+
+ /* verify checksum */
+ md5 = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(md5, EVP_md5(), NULL);
+ EVP_DigestUpdate(md5, p - 24, 8);
+ EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length);
+ EVP_DigestFinal_ex(md5, hash, NULL);
+ EVP_MD_CTX_destroy(md5);
+
+ memset (&zero, 0, sizeof(zero));
+ memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
+
+ DES_set_key_unchecked (&deskey, &schedule);
+ DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
+ &schedule, &zero);
+ if (ct_memcmp (p - 8, hash, 8) != 0) {
+ memset (deskey, 0, sizeof(deskey));
+ memset (&schedule, 0, sizeof(schedule));
+ return GSS_S_BAD_MIC;
+ }
+
+ /* verify sequence number */
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+
+ p -= 16;
+
+ EVP_CIPHER_CTX_init(&des_ctx);
+ EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
+ EVP_Cipher(&des_ctx, p, p, 8);
+ EVP_CIPHER_CTX_cleanup(&des_ctx);
+
+ memset (deskey, 0, sizeof(deskey));
+ memset (&schedule, 0, sizeof(schedule));
+
+ seq = p;
+ _gsskrb5_decode_om_uint32(seq, &seq_number);
+
+ if (context_handle->more_flags & LOCAL)
+ cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
+ else
+ cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
+
+ if (cmp != 0) {
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return GSS_S_BAD_MIC;
+ }
+
+ ret = _gssapi_msg_order_check(context_handle->order, seq_number);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return ret;
+ }
+
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+
+ return GSS_S_COMPLETE;
+}
+#endif
+
+static OM_uint32
+verify_mic_des3
+ (OM_uint32 * minor_status,
+ const gsskrb5_ctx context_handle,
+ krb5_context context,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t * qop_state,
+ krb5_keyblock *key,
+ const char *type
+ )
+{
+ u_char *p;
+ u_char *seq;
+ uint32_t seq_number;
+ OM_uint32 ret;
+ krb5_crypto crypto;
+ krb5_data seq_data;
+ int cmp, docompat;
+ Checksum csum;
+ char *tmp;
+ char ivec[8];
+
+ p = token_buffer->value;
+ ret = _gsskrb5_verify_header (&p,
+ token_buffer->length,
+ type,
+ GSS_KRB5_MECHANISM);
+ if (ret)
+ return ret;
+
+ if (memcmp(p, "\x04\x00", 2) != 0) /* SGN_ALG = HMAC SHA1 DES3-KD */
+ return GSS_S_BAD_SIG;
+ p += 2;
+ if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
+ return GSS_S_BAD_MIC;
+ p += 4;
+
+ ret = krb5_crypto_init(context, key,
+ ETYPE_DES3_CBC_NONE, &crypto);
+ if (ret){
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ /* verify sequence number */
+ docompat = 0;
+retry:
+ if (docompat)
+ memset(ivec, 0, 8);
+ else
+ memcpy(ivec, p + 8, 8);
+
+ ret = krb5_decrypt_ivec (context,
+ crypto,
+ KRB5_KU_USAGE_SEQ,
+ p, 8, &seq_data, ivec);
+ if (ret) {
+ if (docompat++) {
+ krb5_crypto_destroy (context, crypto);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ } else
+ goto retry;
+ }
+
+ if (seq_data.length != 8) {
+ krb5_data_free (&seq_data);
+ if (docompat++) {
+ krb5_crypto_destroy (context, crypto);
+ return GSS_S_BAD_MIC;
+ } else
+ goto retry;
+ }
+
+ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+
+ seq = seq_data.data;
+ _gsskrb5_decode_om_uint32(seq, &seq_number);
+
+ if (context_handle->more_flags & LOCAL)
+ cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
+ else
+ cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
+
+ krb5_data_free (&seq_data);
+ if (cmp != 0) {
+ krb5_crypto_destroy (context, crypto);
+ *minor_status = 0;
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return GSS_S_BAD_MIC;
+ }
+
+ ret = _gssapi_msg_order_check(context_handle->order, seq_number);
+ if (ret) {
+ krb5_crypto_destroy (context, crypto);
+ *minor_status = 0;
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return ret;
+ }
+
+ /* verify checksum */
+
+ tmp = malloc (message_buffer->length + 8);
+ if (tmp == NULL) {
+ krb5_crypto_destroy (context, crypto);
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ memcpy (tmp, p - 8, 8);
+ memcpy (tmp + 8, message_buffer->value, message_buffer->length);
+
+ csum.cksumtype = CKSUMTYPE_HMAC_SHA1_DES3;
+ csum.checksum.length = 20;
+ csum.checksum.data = p + 8;
+
+ ret = krb5_verify_checksum (context, crypto,
+ KRB5_KU_USAGE_SIGN,
+ tmp, message_buffer->length + 8,
+ &csum);
+ free (tmp);
+ if (ret) {
+ krb5_crypto_destroy (context, crypto);
+ *minor_status = ret;
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ return GSS_S_BAD_MIC;
+ }
+ HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+
+ krb5_crypto_destroy (context, crypto);
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32
+_gsskrb5_verify_mic_internal
+ (OM_uint32 * minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t * qop_state,
+ const char * type
+ )
+{
+ krb5_keyblock *key;
+ OM_uint32 ret;
+ krb5_keytype keytype;
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_verify_mic_cfx (minor_status, ctx,
+ context, message_buffer, token_buffer,
+ qop_state);
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(ctx, context, &key);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ *minor_status = 0;
+ krb5_enctype_to_keytype (context, key->keytype, &keytype);
+ switch (keytype) {
+ case KEYTYPE_DES :
+#ifdef HEIM_WEAK_CRYPTO
+ ret = verify_mic_des (minor_status, ctx, context,
+ message_buffer, token_buffer, qop_state, key,
+ type);
+#else
+ ret = GSS_S_FAILURE;
+#endif
+ break;
+ case KEYTYPE_DES3 :
+ ret = verify_mic_des3 (minor_status, ctx, context,
+ message_buffer, token_buffer, qop_state, key,
+ type);
+ break;
+ case KEYTYPE_ARCFOUR :
+ case KEYTYPE_ARCFOUR_56 :
+ ret = _gssapi_verify_mic_arcfour (minor_status, ctx,
+ context,
+ message_buffer, token_buffer,
+ qop_state, key, type);
+ break;
+ default :
+ abort();
+ }
+ krb5_free_keyblock (context, key);
+
+ return ret;
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_verify_mic
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t * qop_state
+ )
+{
+ krb5_context context;
+ OM_uint32 ret;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (qop_state != NULL)
+ *qop_state = GSS_C_QOP_DEFAULT;
+
+ ret = _gsskrb5_verify_mic_internal(minor_status,
+ (gsskrb5_ctx)context_handle,
+ context,
+ message_buffer, token_buffer,
+ qop_state, (void *)(intptr_t)"\x01\x01");
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/krb5/wrap.c b/crypto/heimdal/lib/gssapi/krb5/wrap.c
new file mode 100644
index 0000000..1026e41
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/krb5/wrap.c
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "gsskrb5_locl.h"
+
+/*
+ * Return initiator subkey, or if that doesn't exists, the subkey.
+ */
+
+krb5_error_code
+_gsskrb5i_get_initiator_subkey(const gsskrb5_ctx ctx,
+ krb5_context context,
+ krb5_keyblock **key)
+{
+ krb5_error_code ret;
+ *key = NULL;
+
+ if (ctx->more_flags & LOCAL) {
+ ret = krb5_auth_con_getlocalsubkey(context,
+ ctx->auth_context,
+ key);
+ } else {
+ ret = krb5_auth_con_getremotesubkey(context,
+ ctx->auth_context,
+ key);
+ }
+ if (ret == 0 && *key == NULL)
+ ret = krb5_auth_con_getkey(context,
+ ctx->auth_context,
+ key);
+ if (ret == 0 && *key == NULL) {
+ krb5_set_error_message(context, 0, "No initiator subkey available");
+ return GSS_KRB5_S_KG_NO_SUBKEY;
+ }
+ return ret;
+}
+
+krb5_error_code
+_gsskrb5i_get_acceptor_subkey(const gsskrb5_ctx ctx,
+ krb5_context context,
+ krb5_keyblock **key)
+{
+ krb5_error_code ret;
+ *key = NULL;
+
+ if (ctx->more_flags & LOCAL) {
+ ret = krb5_auth_con_getremotesubkey(context,
+ ctx->auth_context,
+ key);
+ } else {
+ ret = krb5_auth_con_getlocalsubkey(context,
+ ctx->auth_context,
+ key);
+ }
+ if (ret == 0 && *key == NULL) {
+ krb5_set_error_message(context, 0, "No acceptor subkey available");
+ return GSS_KRB5_S_KG_NO_SUBKEY;
+ }
+ return ret;
+}
+
+OM_uint32
+_gsskrb5i_get_token_key(const gsskrb5_ctx ctx,
+ krb5_context context,
+ krb5_keyblock **key)
+{
+ _gsskrb5i_get_acceptor_subkey(ctx, context, key);
+ if(*key == NULL) {
+ /*
+ * Only use the initiator subkey or ticket session key if an
+ * acceptor subkey was not required.
+ */
+ if ((ctx->more_flags & ACCEPTOR_SUBKEY) == 0)
+ _gsskrb5i_get_initiator_subkey(ctx, context, key);
+ }
+ if (*key == NULL) {
+ krb5_set_error_message(context, 0, "No token key available");
+ return GSS_KRB5_S_KG_NO_SUBKEY;
+ }
+ return 0;
+}
+
+static OM_uint32
+sub_wrap_size (
+ OM_uint32 req_output_size,
+ OM_uint32 * max_input_size,
+ int blocksize,
+ int extrasize
+ )
+{
+ size_t len, total_len;
+
+ len = 8 + req_output_size + blocksize + extrasize;
+
+ _gsskrb5_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+
+ total_len -= req_output_size; /* token length */
+ if (total_len < req_output_size) {
+ *max_input_size = (req_output_size - total_len);
+ (*max_input_size) &= (~(OM_uint32)(blocksize - 1));
+ } else {
+ *max_input_size = 0;
+ }
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_wrap_size_limit (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 * max_input_size
+ )
+{
+ krb5_context context;
+ krb5_keyblock *key;
+ OM_uint32 ret;
+ krb5_keytype keytype;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_wrap_size_cfx(minor_status, ctx, context,
+ conf_req_flag, qop_req,
+ req_output_size, max_input_size);
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(ctx, context, &key);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ krb5_enctype_to_keytype (context, key->keytype, &keytype);
+
+ switch (keytype) {
+ case KEYTYPE_DES :
+#ifdef HEIM_WEAK_CRYPTO
+ ret = sub_wrap_size(req_output_size, max_input_size, 8, 22);
+#else
+ ret = GSS_S_FAILURE;
+#endif
+ break;
+ case ENCTYPE_ARCFOUR_HMAC_MD5:
+ case ENCTYPE_ARCFOUR_HMAC_MD5_56:
+ ret = _gssapi_wrap_size_arcfour(minor_status, ctx, context,
+ conf_req_flag, qop_req,
+ req_output_size, max_input_size, key);
+ break;
+ case KEYTYPE_DES3 :
+ ret = sub_wrap_size(req_output_size, max_input_size, 8, 34);
+ break;
+ default :
+ abort();
+ break;
+ }
+ krb5_free_keyblock (context, key);
+ *minor_status = 0;
+ return ret;
+}
+
+#ifdef HEIM_WEAK_CRYPTO
+
+static OM_uint32
+wrap_des
+ (OM_uint32 * minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ const gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_message_buffer,
+ krb5_keyblock *key
+ )
+{
+ u_char *p;
+ EVP_MD_CTX *md5;
+ u_char hash[16];
+ DES_key_schedule schedule;
+ EVP_CIPHER_CTX des_ctx;
+ DES_cblock deskey;
+ DES_cblock zero;
+ size_t i;
+ int32_t seq_number;
+ size_t len, total_len, padlength, datalen;
+
+ if (IS_DCE_STYLE(ctx)) {
+ padlength = 0;
+ datalen = input_message_buffer->length;
+ len = 22 + 8;
+ _gsskrb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
+ total_len += datalen;
+ datalen += 8;
+ } else {
+ padlength = 8 - (input_message_buffer->length % 8);
+ datalen = input_message_buffer->length + padlength + 8;
+ len = datalen + 22;
+ _gsskrb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
+ }
+
+ output_message_buffer->length = total_len;
+ output_message_buffer->value = malloc (total_len);
+ if (output_message_buffer->value == NULL) {
+ output_message_buffer->length = 0;
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ p = _gsskrb5_make_header(output_message_buffer->value,
+ len,
+ "\x02\x01", /* TOK_ID */
+ GSS_KRB5_MECHANISM);
+
+ /* SGN_ALG */
+ memcpy (p, "\x00\x00", 2);
+ p += 2;
+ /* SEAL_ALG */
+ if(conf_req_flag)
+ memcpy (p, "\x00\x00", 2);
+ else
+ memcpy (p, "\xff\xff", 2);
+ p += 2;
+ /* Filler */
+ memcpy (p, "\xff\xff", 2);
+ p += 2;
+
+ /* fill in later */
+ memset (p, 0, 16);
+ p += 16;
+
+ /* confounder + data + pad */
+ krb5_generate_random_block(p, 8);
+ memcpy (p + 8, input_message_buffer->value,
+ input_message_buffer->length);
+ memset (p + 8 + input_message_buffer->length, padlength, padlength);
+
+ /* checksum */
+ md5 = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(md5, EVP_md5(), NULL);
+ EVP_DigestUpdate(md5, p - 24, 8);
+ EVP_DigestUpdate(md5, p, datalen);
+ EVP_DigestFinal_ex(md5, hash, NULL);
+ EVP_MD_CTX_destroy(md5);
+
+ memset (&zero, 0, sizeof(zero));
+ memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
+ DES_set_key_unchecked (&deskey, &schedule);
+ DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
+ &schedule, &zero);
+ memcpy (p - 8, hash, 8);
+
+ /* sequence number */
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ krb5_auth_con_getlocalseqnumber (context,
+ ctx->auth_context,
+ &seq_number);
+
+ p -= 16;
+ p[0] = (seq_number >> 0) & 0xFF;
+ p[1] = (seq_number >> 8) & 0xFF;
+ p[2] = (seq_number >> 16) & 0xFF;
+ p[3] = (seq_number >> 24) & 0xFF;
+ memset (p + 4,
+ (ctx->more_flags & LOCAL) ? 0 : 0xFF,
+ 4);
+
+ EVP_CIPHER_CTX_init(&des_ctx);
+ EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
+ EVP_Cipher(&des_ctx, p, p, 8);
+ EVP_CIPHER_CTX_cleanup(&des_ctx);
+
+ krb5_auth_con_setlocalseqnumber (context,
+ ctx->auth_context,
+ ++seq_number);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ /* encrypt the data */
+ p += 16;
+
+ if(conf_req_flag) {
+ memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
+
+ for (i = 0; i < sizeof(deskey); ++i)
+ deskey[i] ^= 0xf0;
+
+ EVP_CIPHER_CTX_init(&des_ctx);
+ EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, deskey, zero, 1);
+ EVP_Cipher(&des_ctx, p, p, datalen);
+ EVP_CIPHER_CTX_cleanup(&des_ctx);
+ }
+ memset (deskey, 0, sizeof(deskey));
+ memset (&schedule, 0, sizeof(schedule));
+
+ if(conf_state != NULL)
+ *conf_state = conf_req_flag;
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+#endif
+
+static OM_uint32
+wrap_des3
+ (OM_uint32 * minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ const gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_message_buffer,
+ krb5_keyblock *key
+ )
+{
+ u_char *p;
+ u_char seq[8];
+ int32_t seq_number;
+ size_t len, total_len, padlength, datalen;
+ uint32_t ret;
+ krb5_crypto crypto;
+ Checksum cksum;
+ krb5_data encdata;
+
+ if (IS_DCE_STYLE(ctx)) {
+ padlength = 0;
+ datalen = input_message_buffer->length;
+ len = 34 + 8;
+ _gsskrb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
+ total_len += datalen;
+ datalen += 8;
+ } else {
+ padlength = 8 - (input_message_buffer->length % 8);
+ datalen = input_message_buffer->length + padlength + 8;
+ len = datalen + 34;
+ _gsskrb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
+ }
+
+ output_message_buffer->length = total_len;
+ output_message_buffer->value = malloc (total_len);
+ if (output_message_buffer->value == NULL) {
+ output_message_buffer->length = 0;
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ p = _gsskrb5_make_header(output_message_buffer->value,
+ len,
+ "\x02\x01", /* TOK_ID */
+ GSS_KRB5_MECHANISM);
+
+ /* SGN_ALG */
+ memcpy (p, "\x04\x00", 2); /* HMAC SHA1 DES3-KD */
+ p += 2;
+ /* SEAL_ALG */
+ if(conf_req_flag)
+ memcpy (p, "\x02\x00", 2); /* DES3-KD */
+ else
+ memcpy (p, "\xff\xff", 2);
+ p += 2;
+ /* Filler */
+ memcpy (p, "\xff\xff", 2);
+ p += 2;
+
+ /* calculate checksum (the above + confounder + data + pad) */
+
+ memcpy (p + 20, p - 8, 8);
+ krb5_generate_random_block(p + 28, 8);
+ memcpy (p + 28 + 8, input_message_buffer->value,
+ input_message_buffer->length);
+ memset (p + 28 + 8 + input_message_buffer->length, padlength, padlength);
+
+ ret = krb5_crypto_init(context, key, 0, &crypto);
+ if (ret) {
+ free (output_message_buffer->value);
+ output_message_buffer->length = 0;
+ output_message_buffer->value = NULL;
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_create_checksum (context,
+ crypto,
+ KRB5_KU_USAGE_SIGN,
+ 0,
+ p + 20,
+ datalen + 8,
+ &cksum);
+ krb5_crypto_destroy (context, crypto);
+ if (ret) {
+ free (output_message_buffer->value);
+ output_message_buffer->length = 0;
+ output_message_buffer->value = NULL;
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ /* zero out SND_SEQ + SGN_CKSUM in case */
+ memset (p, 0, 28);
+
+ memcpy (p + 8, cksum.checksum.data, cksum.checksum.length);
+ free_Checksum (&cksum);
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ /* sequence number */
+ krb5_auth_con_getlocalseqnumber (context,
+ ctx->auth_context,
+ &seq_number);
+
+ seq[0] = (seq_number >> 0) & 0xFF;
+ seq[1] = (seq_number >> 8) & 0xFF;
+ seq[2] = (seq_number >> 16) & 0xFF;
+ seq[3] = (seq_number >> 24) & 0xFF;
+ memset (seq + 4,
+ (ctx->more_flags & LOCAL) ? 0 : 0xFF,
+ 4);
+
+
+ ret = krb5_crypto_init(context, key, ETYPE_DES3_CBC_NONE,
+ &crypto);
+ if (ret) {
+ free (output_message_buffer->value);
+ output_message_buffer->length = 0;
+ output_message_buffer->value = NULL;
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ {
+ DES_cblock ivec;
+
+ memcpy (&ivec, p + 8, 8);
+ ret = krb5_encrypt_ivec (context,
+ crypto,
+ KRB5_KU_USAGE_SEQ,
+ seq, 8, &encdata,
+ &ivec);
+ }
+ krb5_crypto_destroy (context, crypto);
+ if (ret) {
+ free (output_message_buffer->value);
+ output_message_buffer->length = 0;
+ output_message_buffer->value = NULL;
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ assert (encdata.length == 8);
+
+ memcpy (p, encdata.data, encdata.length);
+ krb5_data_free (&encdata);
+
+ krb5_auth_con_setlocalseqnumber (context,
+ ctx->auth_context,
+ ++seq_number);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ /* encrypt the data */
+ p += 28;
+
+ if(conf_req_flag) {
+ krb5_data tmp;
+
+ ret = krb5_crypto_init(context, key,
+ ETYPE_DES3_CBC_NONE, &crypto);
+ if (ret) {
+ free (output_message_buffer->value);
+ output_message_buffer->length = 0;
+ output_message_buffer->value = NULL;
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ ret = krb5_encrypt(context, crypto, KRB5_KU_USAGE_SEAL,
+ p, datalen, &tmp);
+ krb5_crypto_destroy(context, crypto);
+ if (ret) {
+ free (output_message_buffer->value);
+ output_message_buffer->length = 0;
+ output_message_buffer->value = NULL;
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ assert (tmp.length == datalen);
+
+ memcpy (p, tmp.data, datalen);
+ krb5_data_free(&tmp);
+ }
+ if(conf_state != NULL)
+ *conf_state = conf_req_flag;
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_wrap
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ const gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_message_buffer
+ )
+{
+ krb5_context context;
+ krb5_keyblock *key;
+ OM_uint32 ret;
+ krb5_keytype keytype;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+
+ output_message_buffer->value = NULL;
+ output_message_buffer->length = 0;
+
+ GSSAPI_KRB5_INIT (&context);
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_wrap_cfx (minor_status, ctx, context, conf_req_flag,
+ input_message_buffer, conf_state,
+ output_message_buffer);
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gsskrb5i_get_token_key(ctx, context, &key);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ krb5_enctype_to_keytype (context, key->keytype, &keytype);
+
+ switch (keytype) {
+ case KEYTYPE_DES :
+#ifdef HEIM_WEAK_CRYPTO
+ ret = wrap_des (minor_status, ctx, context, conf_req_flag,
+ qop_req, input_message_buffer, conf_state,
+ output_message_buffer, key);
+#else
+ ret = GSS_S_FAILURE;
+#endif
+ break;
+ case KEYTYPE_DES3 :
+ ret = wrap_des3 (minor_status, ctx, context, conf_req_flag,
+ qop_req, input_message_buffer, conf_state,
+ output_message_buffer, key);
+ break;
+ case KEYTYPE_ARCFOUR:
+ case KEYTYPE_ARCFOUR_56:
+ ret = _gssapi_wrap_arcfour (minor_status, ctx, context, conf_req_flag,
+ qop_req, input_message_buffer, conf_state,
+ output_message_buffer, key);
+ break;
+ default :
+ abort();
+ break;
+ }
+ krb5_free_keyblock (context, key);
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/compat.h b/crypto/heimdal/lib/gssapi/mech/compat.h
new file mode 100644
index 0000000..e63f1e5
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/compat.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2010, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_saslname_for_mech_t (
+ OM_uint32 *, /* minor_status */
+ const gss_OID, /* desired_mech */
+ gss_buffer_t, /* sasl_mech_name */
+ gss_buffer_t, /* mech_name */
+ gss_buffer_t /* mech_description */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_mech_for_saslname_t (
+ OM_uint32 *, /* minor_status */
+ const gss_buffer_t, /* sasl_mech_name */
+ gss_OID * /* mech_type */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_attrs_for_mech_t (
+ OM_uint32 *, /* minor_status */
+ gss_const_OID, /* mech */
+ gss_OID_set *, /* mech_attrs */
+ gss_OID_set * /* known_mech_attrs */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_acquire_cred_with_password_t
+ (OM_uint32 *, /* minor_status */
+ const gss_name_t, /* desired_name */
+ const gss_buffer_t, /* password */
+ OM_uint32, /* time_req */
+ const gss_OID_set, /* desired_mechs */
+ gss_cred_usage_t, /* cred_usage */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 * /* time_rec */
+ );
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_add_cred_with_password_t (
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* input_cred_handle */
+ const gss_name_t, /* desired_name */
+ const gss_OID, /* desired_mech */
+ const gss_buffer_t, /* password */
+ gss_cred_usage_t, /* cred_usage */
+ OM_uint32, /* initiator_time_req */
+ OM_uint32, /* acceptor_time_req */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *, /* initiator_time_rec */
+ OM_uint32 * /* acceptor_time_rec */
+ );
+
+/*
+ * API-as-SPI compatibility for compatibility with MIT mechanisms;
+ * native Heimdal mechanisms should not use these.
+ */
+struct gss_mech_compat_desc_struct {
+ _gss_inquire_saslname_for_mech_t *gmc_inquire_saslname_for_mech;
+ _gss_inquire_mech_for_saslname_t *gmc_inquire_mech_for_saslname;
+ _gss_inquire_attrs_for_mech_t *gmc_inquire_attrs_for_mech;
+ _gss_acquire_cred_with_password_t *gmc_acquire_cred_with_password;
+#if 0
+ _gss_add_cred_with_password_t *gmc_add_cred_with_password;
+#endif
+};
+
diff --git a/crypto/heimdal/lib/gssapi/mech/context.c b/crypto/heimdal/lib/gssapi/mech/context.c
new file mode 100644
index 0000000..5ea0ac4
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/context.c
@@ -0,0 +1,163 @@
+#include "mech_locl.h"
+#include "heim_threads.h"
+
+struct mg_thread_ctx {
+ gss_OID mech;
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+ gss_buffer_desc maj_error;
+ gss_buffer_desc min_error;
+};
+
+static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER;
+static int created_key;
+static HEIMDAL_thread_key context_key;
+
+
+static void
+destroy_context(void *ptr)
+{
+ struct mg_thread_ctx *mg = ptr;
+ OM_uint32 junk;
+
+ if (mg == NULL)
+ return;
+
+ gss_release_buffer(&junk, &mg->maj_error);
+ gss_release_buffer(&junk, &mg->min_error);
+ free(mg);
+}
+
+
+static struct mg_thread_ctx *
+_gss_mechglue_thread(void)
+{
+ struct mg_thread_ctx *ctx;
+ int ret = 0;
+
+ HEIMDAL_MUTEX_lock(&context_mutex);
+
+ if (!created_key) {
+ HEIMDAL_key_create(&context_key, destroy_context, ret);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&context_mutex);
+ return NULL;
+ }
+ created_key = 1;
+ }
+ HEIMDAL_MUTEX_unlock(&context_mutex);
+
+ ctx = HEIMDAL_getspecific(context_key);
+ if (ctx == NULL) {
+
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL)
+ return NULL;
+ HEIMDAL_setspecific(context_key, ctx, ret);
+ if (ret) {
+ free(ctx);
+ return NULL;
+ }
+ }
+ return ctx;
+}
+
+OM_uint32
+_gss_mg_get_error(const gss_OID mech, OM_uint32 type,
+ OM_uint32 value, gss_buffer_t string)
+{
+ struct mg_thread_ctx *mg;
+
+ mg = _gss_mechglue_thread();
+ if (mg == NULL)
+ return GSS_S_BAD_STATUS;
+
+#if 0
+ /*
+ * We cant check the mech here since a pseudo-mech might have
+ * called an lower layer and then the mech info is all broken
+ */
+ if (mech != NULL && gss_oid_equal(mg->mech, mech) == 0)
+ return GSS_S_BAD_STATUS;
+#endif
+
+ switch (type) {
+ case GSS_C_GSS_CODE: {
+ if (value != mg->maj_stat || mg->maj_error.length == 0)
+ break;
+ string->value = malloc(mg->maj_error.length + 1);
+ string->length = mg->maj_error.length;
+ memcpy(string->value, mg->maj_error.value, mg->maj_error.length);
+ ((char *) string->value)[string->length] = '\0';
+ return GSS_S_COMPLETE;
+ }
+ case GSS_C_MECH_CODE: {
+ if (value != mg->min_stat || mg->min_error.length == 0)
+ break;
+ string->value = malloc(mg->min_error.length + 1);
+ string->length = mg->min_error.length;
+ memcpy(string->value, mg->min_error.value, mg->min_error.length);
+ ((char *) string->value)[string->length] = '\0';
+ return GSS_S_COMPLETE;
+ }
+ }
+ string->value = NULL;
+ string->length = 0;
+ return GSS_S_BAD_STATUS;
+}
+
+void
+_gss_mg_error(gssapi_mech_interface m, OM_uint32 maj, OM_uint32 min)
+{
+ OM_uint32 major_status, minor_status;
+ OM_uint32 message_content;
+ struct mg_thread_ctx *mg;
+
+ /*
+ * Mechs without gss_display_status() does
+ * gss_mg_collect_error() by themself.
+ */
+ if (m->gm_display_status == NULL)
+ return ;
+
+ mg = _gss_mechglue_thread();
+ if (mg == NULL)
+ return;
+
+ gss_release_buffer(&minor_status, &mg->maj_error);
+ gss_release_buffer(&minor_status, &mg->min_error);
+
+ mg->mech = &m->gm_mech_oid;
+ mg->maj_stat = maj;
+ mg->min_stat = min;
+
+ major_status = m->gm_display_status(&minor_status,
+ maj,
+ GSS_C_GSS_CODE,
+ &m->gm_mech_oid,
+ &message_content,
+ &mg->maj_error);
+ if (GSS_ERROR(major_status)) {
+ mg->maj_error.value = NULL;
+ mg->maj_error.length = 0;
+ }
+ major_status = m->gm_display_status(&minor_status,
+ min,
+ GSS_C_MECH_CODE,
+ &m->gm_mech_oid,
+ &message_content,
+ &mg->min_error);
+ if (GSS_ERROR(major_status)) {
+ mg->min_error.value = NULL;
+ mg->min_error.length = 0;
+ }
+}
+
+void
+gss_mg_collect_error(gss_OID mech, OM_uint32 maj, OM_uint32 min)
+{
+ gssapi_mech_interface m = __gss_get_mechanism(mech);
+ if (m == NULL)
+ return;
+ _gss_mg_error(m, maj, min);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/context.h b/crypto/heimdal/lib/gssapi/mech/context.h
new file mode 100644
index 0000000..f2a7009
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/context.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/context.h,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ * $Id$
+ */
+
+#include <gssapi_mech.h>
+
+struct _gss_context {
+ gssapi_mech_interface gc_mech;
+ gss_ctx_id_t gc_ctx;
+};
+
+void
+_gss_mg_error(gssapi_mech_interface, OM_uint32, OM_uint32);
+
+OM_uint32
+_gss_mg_get_error(const gss_OID, OM_uint32, OM_uint32, gss_buffer_t);
diff --git a/crypto/heimdal/lib/gssapi/mech/cred.h b/crypto/heimdal/lib/gssapi/mech/cred.h
new file mode 100644
index 0000000..5661b53
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/cred.h
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/cred.h,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ * $Id$
+ */
+
+struct _gss_mechanism_cred {
+ HEIM_SLIST_ENTRY(_gss_mechanism_cred) gmc_link;
+ gssapi_mech_interface gmc_mech; /* mechanism ops for MC */
+ gss_OID gmc_mech_oid; /* mechanism oid for MC */
+ gss_cred_id_t gmc_cred; /* underlying MC */
+};
+HEIM_SLIST_HEAD(_gss_mechanism_cred_list, _gss_mechanism_cred);
+
+struct _gss_cred {
+ struct _gss_mechanism_cred_list gc_mc;
+};
+
+struct _gss_mechanism_cred *
+_gss_copy_cred(struct _gss_mechanism_cred *mc);
+
+struct _gss_mechanism_name;
+
+OM_uint32
+_gss_acquire_mech_cred(OM_uint32 *minor_status,
+ gssapi_mech_interface m,
+ const struct _gss_mechanism_name *mn,
+ gss_const_OID credential_type,
+ const void *credential_data,
+ OM_uint32 time_req,
+ gss_const_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ struct _gss_mechanism_cred **output_cred_handle);
+
diff --git a/crypto/heimdal/lib/gssapi/mech/doxygen.c b/crypto/heimdal/lib/gssapi/mech/doxygen.c
new file mode 100644
index 0000000..a341cba
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/doxygen.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2009 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/*! @mainpage Heimdal GSS-API Library
+ *
+ * Heimdal implements the following mechanisms:
+ *
+ * - Kerberos 5
+ * - SPNEGO
+ * - NTLM
+ *
+ * See @ref gssapi_mechs for more describtion about these mechanisms.
+ *
+ * The project web page: http://www.h5l.org/
+ *
+ * - @ref gssapi_services_intro
+ * - @ref gssapi_mechs
+ * - @ref gssapi_api_INvsMN
+ */
+
+/**
+ * @page gssapi_services_intro Introduction to GSS-API services
+ * @section gssapi_services GSS-API services
+ *
+ * @subsection gssapi_services_context Context creation
+ *
+ * - delegation
+ * - mutual authentication
+ * - anonymous
+ * - use per message before context creation has completed
+ *
+ * return status:
+ * - support conf
+ * - support int
+ *
+ * @subsection gssapi_context_flags Context creation flags
+ *
+ * - GSS_C_DELEG_FLAG
+ * - GSS_C_MUTUAL_FLAG
+ * - GSS_C_REPLAY_FLAG
+ * - GSS_C_SEQUENCE_FLAG
+ * - GSS_C_CONF_FLAG
+ * - GSS_C_INTEG_FLAG
+ * - GSS_C_ANON_FLAG
+ * - GSS_C_PROT_READY_FLAG
+ * - GSS_C_TRANS_FLAG
+ * - GSS_C_DCE_STYLE
+ * - GSS_C_IDENTIFY_FLAG
+ * - GSS_C_EXTENDED_ERROR_FLAG
+ * - GSS_C_DELEG_POLICY_FLAG
+ *
+ *
+ * @subsection gssapi_services_permessage Per-message services
+ *
+ * - conf
+ * - int
+ * - message integrity
+ * - replay detection
+ * - out of sequence
+ *
+ */
+
+/**
+ * @page gssapi_mechs_intro GSS-API mechanisms
+ * @section gssapi_mechs GSS-API mechanisms
+ *
+ * - Kerberos 5 - GSS_KRB5_MECHANISM
+ * - SPNEGO - GSS_SPNEGO_MECHANISM
+ * - NTLM - GSS_NTLM_MECHANISM
+
+ */
+
+
+/**
+ * @page internalVSmechname Internal names and mechanism names
+ * @section gssapi_api_INvsMN Name forms
+ *
+ * There are two forms of name in GSS-API, Internal form and
+ * Contiguous string ("flat") form. gss_export_name() and
+ * gss_import_name() can be used to convert between the two forms.
+ *
+ * - The contiguous string form is described by an oid specificing the
+ * type and an octet string. A special form of the contiguous
+ * string form is the exported name object. The exported name
+ * defined for each mechanism, is something that can be stored and
+ * complared later. The exported name is what should be used for
+ * ACLs comparisons.
+ *
+ * - The Internal form
+ *
+ * There is also special form of the Internal Name (IN), and that is
+ * the Mechanism Name (MN). In the mechanism name all the generic
+ * information is stripped of and only contain the information for
+ * one mechanism. In GSS-API some function return MN and some
+ * require MN as input. Each of these function is marked up as such.
+ *
+ *
+ * Describe relationship between import_name, canonicalize_name,
+ * export_name and friends.
+ */
+
+/** @defgroup gssapi Heimdal GSS-API functions */
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/crypto/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
new file mode 100644
index 0000000..bf7ea03
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
@@ -0,0 +1,308 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_accept_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+static OM_uint32
+parse_header(const gss_buffer_t input_token, gss_OID mech_oid)
+{
+ unsigned char *p = input_token->value;
+ size_t len = input_token->length;
+ size_t a, b;
+
+ /*
+ * Token must start with [APPLICATION 0] SEQUENCE.
+ * But if it doesn't assume it is DCE-STYLE Kerberos!
+ */
+ if (len == 0)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ p++;
+ len--;
+
+ /*
+ * Decode the length and make sure it agrees with the
+ * token length.
+ */
+ if (len == 0)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ if ((*p & 0x80) == 0) {
+ a = *p;
+ p++;
+ len--;
+ } else {
+ b = *p & 0x7f;
+ p++;
+ len--;
+ if (len < b)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ a = 0;
+ while (b) {
+ a = (a << 8) | *p;
+ p++;
+ len--;
+ b--;
+ }
+ }
+ if (a != len)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ /*
+ * Decode the OID for the mechanism. Simplify life by
+ * assuming that the OID length is less than 128 bytes.
+ */
+ if (len < 2 || *p != 0x06)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ if ((p[1] & 0x80) || p[1] > (len - 2))
+ return (GSS_S_DEFECTIVE_TOKEN);
+ mech_oid->length = p[1];
+ p += 2;
+ len -= 2;
+ mech_oid->elements = p;
+
+ return GSS_S_COMPLETE;
+}
+
+static gss_OID_desc krb5_mechanism =
+ {9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")};
+static gss_OID_desc ntlm_mechanism =
+ {10, rk_UNCONST("\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a")};
+static gss_OID_desc spnego_mechanism =
+ {6, rk_UNCONST("\x2b\x06\x01\x05\x05\x02")};
+
+static OM_uint32
+choose_mech(const gss_buffer_t input, gss_OID mech_oid)
+{
+ OM_uint32 status;
+
+ /*
+ * First try to parse the gssapi token header and see if it's a
+ * correct header, use that in the first hand.
+ */
+
+ status = parse_header(input, mech_oid);
+ if (status == GSS_S_COMPLETE)
+ return GSS_S_COMPLETE;
+
+ /*
+ * Lets guess what mech is really is, callback function to mech ??
+ */
+
+ if (input->length > 8 &&
+ memcmp((const char *)input->value, "NTLMSSP\x00", 8) == 0)
+ {
+ *mech_oid = ntlm_mechanism;
+ return GSS_S_COMPLETE;
+ } else if (input->length != 0 &&
+ ((const char *)input->value)[0] == 0x6E)
+ {
+ /* Could be a raw AP-REQ (check for APPLICATION tag) */
+ *mech_oid = krb5_mechanism;
+ return GSS_S_COMPLETE;
+ } else if (input->length == 0) {
+ /*
+ * There is the a wierd mode of SPNEGO (in CIFS and
+ * SASL GSS-SPENGO where the first token is zero
+ * length and the acceptor returns a mech_list, lets
+ * hope that is what is happening now.
+ *
+ * http://msdn.microsoft.com/en-us/library/cc213114.aspx
+ * "NegTokenInit2 Variation for Server-Initiation"
+ */
+ *mech_oid = spnego_mechanism;
+ return GSS_S_COMPLETE;
+ }
+ return status;
+}
+
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_accept_sec_context(OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token,
+ const gss_channel_bindings_t input_chan_bindings,
+ gss_name_t *src_name,
+ gss_OID *mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 *ret_flags,
+ OM_uint32 *time_rec,
+ gss_cred_id_t *delegated_cred_handle)
+{
+ OM_uint32 major_status, mech_ret_flags, junk;
+ gssapi_mech_interface m;
+ struct _gss_context *ctx = (struct _gss_context *) *context_handle;
+ struct _gss_cred *cred = (struct _gss_cred *) acceptor_cred_handle;
+ struct _gss_mechanism_cred *mc;
+ gss_cred_id_t acceptor_mc, delegated_mc;
+ gss_name_t src_mn;
+ gss_OID mech_ret_type = NULL;
+
+ *minor_status = 0;
+ if (src_name)
+ *src_name = GSS_C_NO_NAME;
+ if (mech_type)
+ *mech_type = GSS_C_NO_OID;
+ if (ret_flags)
+ *ret_flags = 0;
+ if (time_rec)
+ *time_rec = 0;
+ if (delegated_cred_handle)
+ *delegated_cred_handle = GSS_C_NO_CREDENTIAL;
+ _mg_buffer_zero(output_token);
+
+
+ /*
+ * If this is the first call (*context_handle is NULL), we must
+ * parse the input token to figure out the mechanism to use.
+ */
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ gss_OID_desc mech_oid;
+
+ major_status = choose_mech(input_token, &mech_oid);
+ if (major_status != GSS_S_COMPLETE)
+ return major_status;
+
+ /*
+ * Now that we have a mechanism, we can find the
+ * implementation.
+ */
+ ctx = malloc(sizeof(struct _gss_context));
+ if (!ctx) {
+ *minor_status = ENOMEM;
+ return (GSS_S_DEFECTIVE_TOKEN);
+ }
+ memset(ctx, 0, sizeof(struct _gss_context));
+ m = ctx->gc_mech = __gss_get_mechanism(&mech_oid);
+ if (!m) {
+ free(ctx);
+ return (GSS_S_BAD_MECH);
+ }
+ *context_handle = (gss_ctx_id_t) ctx;
+ } else {
+ m = ctx->gc_mech;
+ }
+
+ if (cred) {
+ HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link)
+ if (mc->gmc_mech == m)
+ break;
+ if (!mc) {
+ gss_delete_sec_context(&junk, context_handle, NULL);
+ return (GSS_S_BAD_MECH);
+ }
+ acceptor_mc = mc->gmc_cred;
+ } else {
+ acceptor_mc = GSS_C_NO_CREDENTIAL;
+ }
+ delegated_mc = GSS_C_NO_CREDENTIAL;
+
+ mech_ret_flags = 0;
+ major_status = m->gm_accept_sec_context(minor_status,
+ &ctx->gc_ctx,
+ acceptor_mc,
+ input_token,
+ input_chan_bindings,
+ &src_mn,
+ &mech_ret_type,
+ output_token,
+ &mech_ret_flags,
+ time_rec,
+ &delegated_mc);
+ if (major_status != GSS_S_COMPLETE &&
+ major_status != GSS_S_CONTINUE_NEEDED)
+ {
+ _gss_mg_error(m, major_status, *minor_status);
+ gss_delete_sec_context(&junk, context_handle, NULL);
+ return (major_status);
+ }
+
+ if (mech_type)
+ *mech_type = mech_ret_type;
+
+ if (src_name && src_mn) {
+ /*
+ * Make a new name and mark it as an MN.
+ */
+ struct _gss_name *name = _gss_make_name(m, src_mn);
+
+ if (!name) {
+ m->gm_release_name(minor_status, &src_mn);
+ gss_delete_sec_context(&junk, context_handle, NULL);
+ return (GSS_S_FAILURE);
+ }
+ *src_name = (gss_name_t) name;
+ } else if (src_mn) {
+ m->gm_release_name(minor_status, &src_mn);
+ }
+
+ if (mech_ret_flags & GSS_C_DELEG_FLAG) {
+ if (!delegated_cred_handle) {
+ m->gm_release_cred(minor_status, &delegated_mc);
+ mech_ret_flags &=
+ ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG);
+ } else if (gss_oid_equal(mech_ret_type, &m->gm_mech_oid) == 0) {
+ /*
+ * If the returned mech_type is not the same
+ * as the mech, assume its pseudo mech type
+ * and the returned type is already a
+ * mech-glue object
+ */
+ *delegated_cred_handle = delegated_mc;
+
+ } else if (delegated_mc) {
+ struct _gss_cred *dcred;
+ struct _gss_mechanism_cred *dmc;
+
+ dcred = malloc(sizeof(struct _gss_cred));
+ if (!dcred) {
+ *minor_status = ENOMEM;
+ gss_delete_sec_context(&junk, context_handle, NULL);
+ return (GSS_S_FAILURE);
+ }
+ HEIM_SLIST_INIT(&dcred->gc_mc);
+ dmc = malloc(sizeof(struct _gss_mechanism_cred));
+ if (!dmc) {
+ free(dcred);
+ *minor_status = ENOMEM;
+ gss_delete_sec_context(&junk, context_handle, NULL);
+ return (GSS_S_FAILURE);
+ }
+ dmc->gmc_mech = m;
+ dmc->gmc_mech_oid = &m->gm_mech_oid;
+ dmc->gmc_cred = delegated_mc;
+ HEIM_SLIST_INSERT_HEAD(&dcred->gc_mc, dmc, gmc_link);
+
+ *delegated_cred_handle = (gss_cred_id_t) dcred;
+ }
+ }
+
+ if (ret_flags)
+ *ret_flags = mech_ret_flags;
+ return (major_status);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_acquire_cred.c b/crypto/heimdal/lib/gssapi/mech/gss_acquire_cred.c
new file mode 100644
index 0000000..ade65df
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_acquire_cred.c
@@ -0,0 +1,168 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_acquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_acquire_cred(OM_uint32 *minor_status,
+ const gss_name_t desired_name,
+ OM_uint32 time_req,
+ const gss_OID_set desired_mechs,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *time_rec)
+{
+ OM_uint32 major_status;
+ gss_OID_set mechs = desired_mechs;
+ gss_OID_set_desc set;
+ struct _gss_name *name = (struct _gss_name *) desired_name;
+ gssapi_mech_interface m;
+ struct _gss_cred *cred;
+ struct _gss_mechanism_cred *mc;
+ OM_uint32 min_time, cred_time;
+ size_t i;
+
+ *minor_status = 0;
+ if (output_cred_handle == NULL)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+ if (actual_mechs)
+ *actual_mechs = GSS_C_NO_OID_SET;
+ if (time_rec)
+ *time_rec = 0;
+
+ _gss_load_mech();
+
+ /*
+ * First make sure that at least one of the requested
+ * mechanisms is one that we support.
+ */
+ if (mechs) {
+ for (i = 0; i < mechs->count; i++) {
+ int t;
+ gss_test_oid_set_member(minor_status,
+ &mechs->elements[i], _gss_mech_oids, &t);
+ if (t)
+ break;
+ }
+ if (i == mechs->count) {
+ *minor_status = 0;
+ return (GSS_S_BAD_MECH);
+ }
+ }
+
+ if (actual_mechs) {
+ major_status = gss_create_empty_oid_set(minor_status,
+ actual_mechs);
+ if (major_status)
+ return (major_status);
+ }
+
+ cred = malloc(sizeof(struct _gss_cred));
+ if (!cred) {
+ if (actual_mechs)
+ gss_release_oid_set(minor_status, actual_mechs);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ HEIM_SLIST_INIT(&cred->gc_mc);
+
+ if (mechs == GSS_C_NO_OID_SET)
+ mechs = _gss_mech_oids;
+
+ set.count = 1;
+ min_time = GSS_C_INDEFINITE;
+ for (i = 0; i < mechs->count; i++) {
+ struct _gss_mechanism_name *mn = NULL;
+
+ m = __gss_get_mechanism(&mechs->elements[i]);
+ if (!m)
+ continue;
+
+ if (desired_name != GSS_C_NO_NAME) {
+ major_status = _gss_find_mn(minor_status, name,
+ &mechs->elements[i], &mn);
+ if (major_status != GSS_S_COMPLETE)
+ continue;
+ }
+
+ mc = malloc(sizeof(struct _gss_mechanism_cred));
+ if (!mc) {
+ continue;
+ }
+ mc->gmc_mech = m;
+ mc->gmc_mech_oid = &m->gm_mech_oid;
+
+ /*
+ * XXX Probably need to do something with actual_mechs.
+ */
+ set.elements = &mechs->elements[i];
+ major_status = m->gm_acquire_cred(minor_status,
+ (desired_name != GSS_C_NO_NAME
+ ? mn->gmn_name : GSS_C_NO_NAME),
+ time_req, &set, cred_usage,
+ &mc->gmc_cred, NULL, &cred_time);
+ if (major_status) {
+ free(mc);
+ continue;
+ }
+ if (cred_time < min_time)
+ min_time = cred_time;
+
+ if (actual_mechs) {
+ major_status = gss_add_oid_set_member(minor_status,
+ mc->gmc_mech_oid, actual_mechs);
+ if (major_status) {
+ m->gm_release_cred(minor_status,
+ &mc->gmc_cred);
+ free(mc);
+ continue;
+ }
+ }
+
+ HEIM_SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);
+ }
+
+ /*
+ * If we didn't manage to create a single credential, return
+ * an error.
+ */
+ if (!HEIM_SLIST_FIRST(&cred->gc_mc)) {
+ free(cred);
+ if (actual_mechs)
+ gss_release_oid_set(minor_status, actual_mechs);
+ *minor_status = 0;
+ return (GSS_S_NO_CRED);
+ }
+
+ if (time_rec)
+ *time_rec = min_time;
+ *output_cred_handle = (gss_cred_id_t) cred;
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_acquire_cred_ext.c b/crypto/heimdal/lib/gssapi/mech/gss_acquire_cred_ext.c
new file mode 100644
index 0000000..1cbb29f
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_acquire_cred_ext.c
@@ -0,0 +1,193 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2011 PADL Software Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_acquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+OM_uint32
+_gss_acquire_mech_cred(OM_uint32 *minor_status,
+ gssapi_mech_interface m,
+ const struct _gss_mechanism_name *mn,
+ gss_const_OID credential_type,
+ const void *credential_data,
+ OM_uint32 time_req,
+ gss_const_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ struct _gss_mechanism_cred **output_cred_handle)
+{
+ OM_uint32 major_status;
+ struct _gss_mechanism_cred *mc;
+ gss_OID_set_desc set2;
+
+ *output_cred_handle = NULL;
+
+ mc = calloc(1, sizeof(struct _gss_mechanism_cred));
+ if (mc == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ mc->gmc_mech = m;
+ mc->gmc_mech_oid = &m->gm_mech_oid;
+
+ set2.count = 1;
+ set2.elements = mc->gmc_mech_oid;
+
+ if (m->gm_acquire_cred_ext) {
+ major_status = m->gm_acquire_cred_ext(minor_status,
+ mn->gmn_name,
+ credential_type,
+ credential_data,
+ time_req,
+ mc->gmc_mech_oid,
+ cred_usage,
+ &mc->gmc_cred);
+ } else if (gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD) &&
+ m->gm_compat &&
+ m->gm_compat->gmc_acquire_cred_with_password) {
+ /*
+ * Shim for mechanisms that adhere to API-as-SPI and do not
+ * implement gss_acquire_cred_ext().
+ */
+
+ major_status = m->gm_compat->gmc_acquire_cred_with_password(minor_status,
+ mn->gmn_name,
+ (const gss_buffer_t)credential_data,
+ time_req,
+ &set2,
+ cred_usage,
+ &mc->gmc_cred,
+ NULL,
+ NULL);
+ } else if (credential_type == GSS_C_NO_OID) {
+ major_status = m->gm_acquire_cred(minor_status,
+ mn->gmn_name,
+ time_req,
+ &set2,
+ cred_usage,
+ &mc->gmc_cred,
+ NULL,
+ NULL);
+ } else {
+ major_status = GSS_S_UNAVAILABLE;
+ free(mc);
+ mc= NULL;
+ }
+
+ *output_cred_handle = mc;
+ return major_status;
+}
+
+OM_uint32
+_gss_acquire_cred_ext(OM_uint32 *minor_status,
+ const gss_name_t desired_name,
+ gss_const_OID credential_type,
+ const void *credential_data,
+ OM_uint32 time_req,
+ gss_const_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t *output_cred_handle)
+{
+ OM_uint32 major_status;
+ struct _gss_name *name = (struct _gss_name *) desired_name;
+ gssapi_mech_interface m;
+ struct _gss_cred *cred;
+ gss_OID_set_desc set, *mechs;
+ size_t i;
+
+ *minor_status = 0;
+ if (output_cred_handle == NULL)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ _gss_load_mech();
+
+ if (desired_mech != GSS_C_NO_OID) {
+ int match = 0;
+
+ gss_test_oid_set_member(minor_status, (gss_OID)desired_mech,
+ _gss_mech_oids, &match);
+ if (!match)
+ return GSS_S_BAD_MECH;
+
+ set.count = 1;
+ set.elements = (gss_OID)desired_mech;
+ mechs = &set;
+ } else
+ mechs = _gss_mech_oids;
+
+ cred = calloc(1, sizeof(*cred));
+ if (cred == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ HEIM_SLIST_INIT(&cred->gc_mc);
+
+ for (i = 0; i < mechs->count; i++) {
+ struct _gss_mechanism_name *mn = NULL;
+ struct _gss_mechanism_cred *mc = NULL;
+ gss_name_t desired_mech_name = GSS_C_NO_NAME;
+
+ m = __gss_get_mechanism(&mechs->elements[i]);
+ if (!m)
+ continue;
+
+ if (desired_name != GSS_C_NO_NAME) {
+ major_status = _gss_find_mn(minor_status, name,
+ &mechs->elements[i], &mn);
+ if (major_status != GSS_S_COMPLETE)
+ continue;
+
+ desired_mech_name = mn->gmn_name;
+ }
+
+ major_status = _gss_acquire_mech_cred(minor_status, m, mn,
+ credential_type, credential_data,
+ time_req, desired_mech, cred_usage,
+ &mc);
+ if (GSS_ERROR(major_status))
+ continue;
+
+ HEIM_SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);
+ }
+
+ /*
+ * If we didn't manage to create a single credential, return
+ * an error.
+ */
+ if (!HEIM_SLIST_FIRST(&cred->gc_mc)) {
+ free(cred);
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ *output_cred_handle = (gss_cred_id_t) cred;
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_acquire_cred_with_password.c b/crypto/heimdal/lib/gssapi/mech/gss_acquire_cred_with_password.c
new file mode 100644
index 0000000..8c2a648
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_acquire_cred_with_password.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2011, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_acquire_cred_with_password(OM_uint32 *minor_status,
+ const gss_name_t desired_name,
+ const gss_buffer_t password,
+ OM_uint32 time_req,
+ const gss_OID_set desired_mechs,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *time_rec)
+{
+ OM_uint32 major_status, tmp_minor;
+
+ if (desired_mechs == GSS_C_NO_OID_SET) {
+ major_status = _gss_acquire_cred_ext(minor_status,
+ desired_name,
+ GSS_C_CRED_PASSWORD,
+ password,
+ time_req,
+ GSS_C_NO_OID,
+ cred_usage,
+ output_cred_handle);
+ if (GSS_ERROR(major_status))
+ return major_status;
+ } else {
+ size_t i;
+ struct _gss_cred *new_cred;
+
+ new_cred = calloc(1, sizeof(*new_cred));
+ if (new_cred == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ HEIM_SLIST_INIT(&new_cred->gc_mc);
+
+ for (i = 0; i < desired_mechs->count; i++) {
+ struct _gss_cred *tmp_cred = NULL;
+ struct _gss_mechanism_cred *mc;
+
+ major_status = _gss_acquire_cred_ext(minor_status,
+ desired_name,
+ GSS_C_CRED_PASSWORD,
+ password,
+ time_req,
+ &desired_mechs->elements[i],
+ cred_usage,
+ (gss_cred_id_t *)&tmp_cred);
+ if (GSS_ERROR(major_status))
+ continue;
+
+ mc = HEIM_SLIST_FIRST(&tmp_cred->gc_mc);
+ if (mc) {
+ HEIM_SLIST_REMOVE_HEAD(&tmp_cred->gc_mc, gmc_link);
+ HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, mc, gmc_link);
+ }
+
+ gss_release_cred(&tmp_minor, (gss_cred_id_t *)&tmp_cred);
+ }
+
+ if (!HEIM_SLIST_FIRST(&new_cred->gc_mc)) {
+ free(new_cred);
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ *output_cred_handle = (gss_cred_id_t)new_cred;
+ }
+
+ if (actual_mechs != NULL || time_rec != NULL) {
+ major_status = gss_inquire_cred(minor_status,
+ *output_cred_handle,
+ NULL,
+ time_rec,
+ NULL,
+ actual_mechs);
+ if (GSS_ERROR(major_status)) {
+ gss_release_cred(&tmp_minor, output_cred_handle);
+ return major_status;
+ }
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_add_cred.c b/crypto/heimdal/lib/gssapi/mech/gss_add_cred.c
new file mode 100644
index 0000000..a998bc6
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_add_cred.c
@@ -0,0 +1,186 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+struct _gss_mechanism_cred *
+_gss_copy_cred(struct _gss_mechanism_cred *mc)
+{
+ struct _gss_mechanism_cred *new_mc;
+ gssapi_mech_interface m = mc->gmc_mech;
+ OM_uint32 major_status, minor_status;
+ gss_name_t name;
+ gss_cred_id_t cred;
+ OM_uint32 initiator_lifetime, acceptor_lifetime;
+ gss_cred_usage_t cred_usage;
+
+ major_status = m->gm_inquire_cred_by_mech(&minor_status,
+ mc->gmc_cred, mc->gmc_mech_oid,
+ &name, &initiator_lifetime, &acceptor_lifetime, &cred_usage);
+ if (major_status) {
+ _gss_mg_error(m, major_status, minor_status);
+ return (0);
+ }
+
+ major_status = m->gm_add_cred(&minor_status,
+ GSS_C_NO_CREDENTIAL, name, mc->gmc_mech_oid,
+ cred_usage, initiator_lifetime, acceptor_lifetime,
+ &cred, 0, 0, 0);
+ m->gm_release_name(&minor_status, &name);
+
+ if (major_status) {
+ _gss_mg_error(m, major_status, minor_status);
+ return (0);
+ }
+
+ new_mc = malloc(sizeof(struct _gss_mechanism_cred));
+ if (!new_mc) {
+ m->gm_release_cred(&minor_status, &cred);
+ return (0);
+ }
+ new_mc->gmc_mech = m;
+ new_mc->gmc_mech_oid = &m->gm_mech_oid;
+ new_mc->gmc_cred = cred;
+
+ return (new_mc);
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_add_cred(OM_uint32 *minor_status,
+ const gss_cred_id_t input_cred_handle,
+ const gss_name_t desired_name,
+ const gss_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ OM_uint32 initiator_time_req,
+ OM_uint32 acceptor_time_req,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *initiator_time_rec,
+ OM_uint32 *acceptor_time_rec)
+{
+ OM_uint32 major_status;
+ gssapi_mech_interface m;
+ struct _gss_cred *cred = (struct _gss_cred *) input_cred_handle;
+ struct _gss_cred *new_cred;
+ gss_cred_id_t release_cred;
+ struct _gss_mechanism_cred *mc, *target_mc, *copy_mc;
+ struct _gss_mechanism_name *mn;
+ OM_uint32 junk;
+
+ *minor_status = 0;
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+ if (initiator_time_rec)
+ *initiator_time_rec = 0;
+ if (acceptor_time_rec)
+ *acceptor_time_rec = 0;
+ if (actual_mechs)
+ *actual_mechs = GSS_C_NO_OID_SET;
+
+ new_cred = malloc(sizeof(struct _gss_cred));
+ if (!new_cred) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ HEIM_SLIST_INIT(&new_cred->gc_mc);
+
+ /*
+ * We go through all the mc attached to the input_cred_handle
+ * and check the mechanism. If it matches, we call
+ * gss_add_cred for that mechanism, otherwise we copy the mc
+ * to new_cred.
+ */
+ target_mc = 0;
+ if (cred) {
+ HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) {
+ target_mc = mc;
+ }
+ copy_mc = _gss_copy_cred(mc);
+ if (!copy_mc) {
+ release_cred = (gss_cred_id_t)new_cred;
+ gss_release_cred(&junk, &release_cred);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, copy_mc, gmc_link);
+ }
+ }
+
+ /*
+ * Figure out a suitable mn, if any.
+ */
+ if (desired_name) {
+ major_status = _gss_find_mn(minor_status,
+ (struct _gss_name *) desired_name,
+ desired_mech,
+ &mn);
+ if (major_status != GSS_S_COMPLETE) {
+ free(new_cred);
+ return major_status;
+ }
+ } else {
+ mn = 0;
+ }
+
+ m = __gss_get_mechanism(desired_mech);
+
+ mc = malloc(sizeof(struct _gss_mechanism_cred));
+ if (!mc) {
+ release_cred = (gss_cred_id_t)new_cred;
+ gss_release_cred(&junk, &release_cred);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ mc->gmc_mech = m;
+ mc->gmc_mech_oid = &m->gm_mech_oid;
+
+ major_status = m->gm_add_cred(minor_status,
+ target_mc ? target_mc->gmc_cred : GSS_C_NO_CREDENTIAL,
+ desired_name ? mn->gmn_name : GSS_C_NO_NAME,
+ desired_mech,
+ cred_usage,
+ initiator_time_req,
+ acceptor_time_req,
+ &mc->gmc_cred,
+ actual_mechs,
+ initiator_time_rec,
+ acceptor_time_rec);
+
+ if (major_status) {
+ _gss_mg_error(m, major_status, *minor_status);
+ release_cred = (gss_cred_id_t)new_cred;
+ gss_release_cred(&junk, &release_cred);
+ free(mc);
+ return (major_status);
+ }
+ HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, mc, gmc_link);
+ *output_cred_handle = (gss_cred_id_t) new_cred;
+
+ return (GSS_S_COMPLETE);
+}
+
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_add_cred_with_password.c b/crypto/heimdal/lib/gssapi/mech/gss_add_cred_with_password.c
new file mode 100644
index 0000000..f966305
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_add_cred_with_password.c
@@ -0,0 +1,150 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_add_cred_with_password(OM_uint32 *minor_status,
+ const gss_cred_id_t input_cred_handle,
+ const gss_name_t desired_name,
+ const gss_OID desired_mech,
+ const gss_buffer_t password,
+ gss_cred_usage_t cred_usage,
+ OM_uint32 initiator_time_req,
+ OM_uint32 acceptor_time_req,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *initiator_time_rec,
+ OM_uint32 *acceptor_time_rec)
+{
+ OM_uint32 major_status;
+ gssapi_mech_interface m;
+ struct _gss_cred *cred = (struct _gss_cred *) input_cred_handle;
+ struct _gss_cred *new_cred;
+ struct _gss_mechanism_cred *mc;
+ struct _gss_mechanism_name *mn = NULL;
+ OM_uint32 junk, time_req;
+
+ *minor_status = 0;
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+ if (initiator_time_rec)
+ *initiator_time_rec = 0;
+ if (acceptor_time_rec)
+ *acceptor_time_rec = 0;
+ if (actual_mechs)
+ *actual_mechs = GSS_C_NO_OID_SET;
+
+ m = __gss_get_mechanism(desired_mech);
+ if (m == NULL) {
+ *minor_status = 0;
+ return (GSS_S_BAD_MECH);
+ }
+
+ new_cred = calloc(1, sizeof(struct _gss_cred));
+ if (new_cred == NULL) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ HEIM_SLIST_INIT(&new_cred->gc_mc);
+
+ /*
+ * Copy credentials from un-desired mechanisms to the new credential.
+ */
+ if (cred) {
+ HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ struct _gss_mechanism_cred *copy_mc;
+
+ if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) {
+ continue;
+ }
+ copy_mc = _gss_copy_cred(mc);
+ if (copy_mc == NULL) {
+ gss_release_cred(&junk, (gss_cred_id_t *)&new_cred);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, copy_mc, gmc_link);
+ }
+ }
+
+ /*
+ * Figure out a suitable mn, if any.
+ */
+ if (desired_name != GSS_C_NO_NAME) {
+ major_status = _gss_find_mn(minor_status,
+ (struct _gss_name *) desired_name,
+ desired_mech,
+ &mn);
+ if (major_status != GSS_S_COMPLETE) {
+ gss_release_cred(&junk, (gss_cred_id_t *)&new_cred);
+ return (major_status);
+ }
+ }
+
+ if (cred_usage == GSS_C_BOTH)
+ time_req = initiator_time_req > acceptor_time_req ? acceptor_time_req : initiator_time_req;
+ else if (cred_usage == GSS_C_INITIATE)
+ time_req = initiator_time_req;
+ else
+ time_req = acceptor_time_req;
+
+ major_status = _gss_acquire_mech_cred(minor_status, m, mn,
+ GSS_C_CRED_PASSWORD, password,
+ time_req, desired_mech,
+ cred_usage, &mc);
+ if (major_status != GSS_S_COMPLETE) {
+ gss_release_cred(&junk, (gss_cred_id_t *)&new_cred);
+ return (major_status);
+ }
+
+ HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, mc, gmc_link);
+
+ if (actual_mechs || initiator_time_rec || acceptor_time_rec) {
+ OM_uint32 time_rec;
+
+ major_status = gss_inquire_cred(minor_status,
+ (gss_cred_id_t)new_cred,
+ NULL,
+ &time_rec,
+ NULL,
+ actual_mechs);
+ if (GSS_ERROR(major_status)) {
+ gss_release_cred(&junk, (gss_cred_id_t *)&new_cred);
+ return (major_status);
+ }
+ if (initiator_time_rec &&
+ (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH))
+ *initiator_time_rec = time_rec;
+ if (acceptor_time_rec &&
+ (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH))
+ *acceptor_time_rec = time_rec;
+ }
+
+ *output_cred_handle = (gss_cred_id_t) new_cred;
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c b/crypto/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c
new file mode 100644
index 0000000..a232705
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "mech_locl.h"
+
+/**
+ * Add a oid to the oid set, function does not make a copy of the oid,
+ * so the pointer to member_oid needs to be stable for the whole time
+ * oid_set is used.
+ *
+ * If there is a duplicate member of the oid, the new member is not
+ * added to to the set.
+ *
+ * @param minor_status minor status code.
+ * @param member_oid member to add to the oid set
+ * @param oid_set oid set to add the member too
+ *
+ * @returns a gss_error code, see gss_display_status() about printing
+ * the error code.
+ *
+ * @ingroup gssapi
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_add_oid_set_member (OM_uint32 * minor_status,
+ const gss_OID member_oid,
+ gss_OID_set * oid_set)
+{
+ gss_OID tmp;
+ size_t n;
+ OM_uint32 res;
+ int present;
+
+ res = gss_test_oid_set_member(minor_status, member_oid, *oid_set, &present);
+ if (res != GSS_S_COMPLETE)
+ return res;
+
+ if (present) {
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ }
+
+ n = (*oid_set)->count + 1;
+ tmp = realloc ((*oid_set)->elements, n * sizeof(gss_OID_desc));
+ if (tmp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ (*oid_set)->elements = tmp;
+ (*oid_set)->count = n;
+ (*oid_set)->elements[n-1] = *member_oid;
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_aeap.c b/crypto/heimdal/lib/gssapi/mech/gss_aeap.c
new file mode 100644
index 0000000..3008c0d
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_aeap.c
@@ -0,0 +1,216 @@
+/*
+ * AEAD support
+ */
+
+#include "mech_locl.h"
+
+/**
+ * Encrypts or sign the data.
+ *
+ * This is a more complicated version of gss_wrap(), it allows the
+ * caller to use AEAD data (signed header/trailer) and allow greater
+ * controll over where the encrypted data is placed.
+ *
+ * The maximum packet size is gss_context_stream_sizes.max_msg_size.
+ *
+ * The caller needs provide the folloing buffers when using in conf_req_flag=1 mode:
+ *
+ * - HEADER (of size gss_context_stream_sizes.header)
+ * { DATA or SIGN_ONLY } (optional, zero or more)
+ * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted)
+ * TRAILER (of size gss_context_stream_sizes.trailer)
+ *
+ * - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the
+ * DATA elements is padded to a block bountry and header is of at
+ * least size gss_context_stream_sizes.header + gss_context_stream_sizes.trailer.
+ *
+ * HEADER, PADDING, TRAILER will be shrunken to the size required to transmit any of them too large.
+ *
+ * To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER
+ *
+ * When used in conf_req_flag=0,
+ *
+ * - HEADER (of size gss_context_stream_sizes.header)
+ * { DATA or SIGN_ONLY } (optional, zero or more)
+ * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted)
+ * TRAILER (of size gss_context_stream_sizes.trailer)
+ *
+ *
+ * The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or
+ * gss_context_query_attributes().
+ *
+ * @ingroup gssapi
+ */
+
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_wrap_iov(OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int * conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ gssapi_mech_interface m;
+
+ if (minor_status)
+ *minor_status = 0;
+ if (conf_state)
+ *conf_state = 0;
+ if (ctx == NULL)
+ return GSS_S_NO_CONTEXT;
+ if (iov == NULL && iov_count != 0)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ m = ctx->gc_mech;
+
+ if (m->gm_wrap_iov == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ return (m->gm_wrap_iov)(minor_status, ctx->gc_ctx,
+ conf_req_flag, qop_req, conf_state,
+ iov, iov_count);
+}
+
+/**
+ * Decrypt or verifies the signature on the data.
+ *
+ *
+ * @ingroup gssapi
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_unwrap_iov(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int *conf_state,
+ gss_qop_t *qop_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ gssapi_mech_interface m;
+
+ if (minor_status)
+ *minor_status = 0;
+ if (conf_state)
+ *conf_state = 0;
+ if (qop_state)
+ *qop_state = 0;
+ if (ctx == NULL)
+ return GSS_S_NO_CONTEXT;
+ if (iov == NULL && iov_count != 0)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ m = ctx->gc_mech;
+
+ if (m->gm_unwrap_iov == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ return (m->gm_unwrap_iov)(minor_status, ctx->gc_ctx,
+ conf_state, qop_state,
+ iov, iov_count);
+}
+
+/**
+ * Update the length fields in iov buffer for the types:
+ * - GSS_IOV_BUFFER_TYPE_HEADER
+ * - GSS_IOV_BUFFER_TYPE_PADDING
+ * - GSS_IOV_BUFFER_TYPE_TRAILER
+ *
+ * Consider using gss_context_query_attributes() to fetch the data instead.
+ *
+ * @ingroup gssapi
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_wrap_iov_length(OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ gssapi_mech_interface m;
+
+ if (minor_status)
+ *minor_status = 0;
+ if (conf_state)
+ *conf_state = 0;
+ if (ctx == NULL)
+ return GSS_S_NO_CONTEXT;
+ if (iov == NULL && iov_count != 0)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ m = ctx->gc_mech;
+
+ if (m->gm_wrap_iov_length == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ return (m->gm_wrap_iov_length)(minor_status, ctx->gc_ctx,
+ conf_req_flag, qop_req, conf_state,
+ iov, iov_count);
+}
+
+/**
+ * Free all buffer allocated by gss_wrap_iov() or gss_unwrap_iov() by
+ * looking at the GSS_IOV_BUFFER_FLAG_ALLOCATED flag.
+ *
+ * @ingroup gssapi
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_release_iov_buffer(OM_uint32 *minor_status,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ OM_uint32 junk;
+ int i;
+
+ if (minor_status)
+ *minor_status = 0;
+ if (iov == NULL && iov_count != 0)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ for (i = 0; i < iov_count; i++) {
+ if ((iov[i].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) == 0)
+ continue;
+ gss_release_buffer(&junk, &iov[i].buffer);
+ iov[i].type &= ~GSS_IOV_BUFFER_FLAG_ALLOCATED;
+ }
+ return GSS_S_COMPLETE;
+}
+
+/**
+ * Query the context for parameters.
+ *
+ * SSPI equivalent if this function is QueryContextAttributes.
+ *
+ * - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes.
+ *
+ * @ingroup gssapi
+ */
+
+gss_OID_desc GSSAPI_LIB_FUNCTION __gss_c_attr_stream_sizes_oid_desc =
+ {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03")};
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_context_query_attributes(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID attribute,
+ void *data,
+ size_t len)
+{
+ if (minor_status)
+ *minor_status = 0;
+
+ if (gss_oid_equal(GSS_C_ATTR_STREAM_SIZES, attribute)) {
+ memset(data, 0, len);
+ return GSS_S_COMPLETE;
+ }
+
+ return GSS_S_FAILURE;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_authorize_localname.c b/crypto/heimdal/lib/gssapi/mech/gss_authorize_localname.c
new file mode 100644
index 0000000..a0ad065
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_authorize_localname.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2011, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+gss_buffer_desc GSSAPI_LIB_VARIABLE __gss_c_attr_local_login_user = {
+ sizeof("local-login-user") - 1,
+ "local-login-user"
+};
+
+static OM_uint32
+mech_authorize_localname(OM_uint32 *minor_status,
+ const struct _gss_name *name,
+ const struct _gss_name *user)
+{
+ OM_uint32 major_status = GSS_S_NAME_NOT_MN;
+ struct _gss_mechanism_name *mn;
+
+ HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ gssapi_mech_interface m = mn->gmn_mech;
+
+ if (m->gm_authorize_localname == NULL) {
+ major_status = GSS_S_UNAVAILABLE;
+ continue;
+ }
+
+ major_status = m->gm_authorize_localname(minor_status,
+ mn->gmn_name,
+ &user->gn_value,
+ &user->gn_type);
+ if (major_status != GSS_S_UNAUTHORIZED)
+ break;
+ }
+
+ return major_status;
+}
+
+/*
+ * Naming extensions based local login authorization.
+ */
+static OM_uint32
+attr_authorize_localname(OM_uint32 *minor_status,
+ const struct _gss_name *name,
+ const struct _gss_name *user)
+{
+ OM_uint32 major_status = GSS_S_UNAVAILABLE;
+ int more = -1;
+
+ if (!gss_oid_equal(&user->gn_type, GSS_C_NT_USER_NAME))
+ return GSS_S_BAD_NAMETYPE;
+
+ while (more != 0 && major_status != GSS_S_COMPLETE) {
+ OM_uint32 tmpMajor, tmpMinor;
+ gss_buffer_desc value;
+ gss_buffer_desc display_value;
+ int authenticated = 0, complete = 0;
+
+ tmpMajor = gss_get_name_attribute(minor_status,
+ (gss_name_t)name,
+ GSS_C_ATTR_LOCAL_LOGIN_USER,
+ &authenticated,
+ &complete,
+ &value,
+ &display_value,
+ &more);
+ if (GSS_ERROR(tmpMajor)) {
+ major_status = tmpMajor;
+ break;
+ }
+
+ /* If attribute is present, return an authoritative error code. */
+ if (authenticated &&
+ value.length == user->gn_value.length &&
+ memcmp(value.value, user->gn_value.value, user->gn_value.length) == 0)
+ major_status = GSS_S_COMPLETE;
+ else
+ major_status = GSS_S_UNAUTHORIZED;
+
+ gss_release_buffer(&tmpMinor, &value);
+ gss_release_buffer(&tmpMinor, &display_value);
+ }
+
+ return major_status;
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_authorize_localname(OM_uint32 *minor_status,
+ const gss_name_t gss_name,
+ const gss_name_t gss_user)
+
+{
+ OM_uint32 major_status;
+ const struct _gss_name *name = (const struct _gss_name *) gss_name;
+ const struct _gss_name *user = (const struct _gss_name *) gss_user;
+ int mechAvailable = 0;
+
+ *minor_status = 0;
+
+ if (gss_name == GSS_C_NO_NAME || gss_user == GSS_C_NO_NAME)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ /*
+ * We should check that the user name is not a mechanism name, but
+ * as Heimdal always calls the mechanism's gss_import_name(), it's
+ * not possible to make this check.
+ */
+#if 0
+ if (HEIM_SLIST_FIRST(&user->gn_mn) != NULL)
+ return GSS_S_BAD_NAME;
+#endif
+
+ /* If mech returns yes, we return yes */
+ major_status = mech_authorize_localname(minor_status, name, user);
+ if (major_status == GSS_S_COMPLETE)
+ return GSS_S_COMPLETE;
+ else if (major_status != GSS_S_UNAVAILABLE)
+ mechAvailable = 1;
+
+ /* If attribute exists, it is authoritative */
+ major_status = attr_authorize_localname(minor_status, name, user);
+ if (major_status == GSS_S_COMPLETE || major_status == GSS_S_UNAUTHORIZED)
+ return major_status;
+
+ /* If mechanism did not implement SPI, compare the local name */
+ if (mechAvailable == 0) {
+ int match = 0;
+
+ major_status = gss_compare_name(minor_status, gss_name,
+ gss_user, &match);
+ if (major_status == GSS_S_COMPLETE && match == 0)
+ major_status = GSS_S_UNAUTHORIZED;
+ }
+
+ return major_status;
+}
+
+GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL
+gss_userok(const gss_name_t name,
+ const char *user)
+{
+ OM_uint32 major_status, minor_status;
+ gss_buffer_desc userBuf;
+ gss_name_t userName;
+
+ userBuf.value = (void *)user;
+ userBuf.length = strlen(user);
+
+ major_status = gss_import_name(&minor_status, &userBuf,
+ GSS_C_NT_USER_NAME, &userName);
+ if (GSS_ERROR(major_status))
+ return 0;
+
+ major_status = gss_authorize_localname(&minor_status, name, userName);
+
+ gss_release_name(&minor_status, &userName);
+
+ return (major_status == GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_buffer_set.c b/crypto/heimdal/lib/gssapi/mech/gss_buffer_set.c
new file mode 100644
index 0000000..48fb720
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_buffer_set.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_create_empty_buffer_set
+ (OM_uint32 * minor_status,
+ gss_buffer_set_t *buffer_set)
+{
+ gss_buffer_set_t set;
+
+ set = (gss_buffer_set_desc *) malloc(sizeof(*set));
+ if (set == GSS_C_NO_BUFFER_SET) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ set->count = 0;
+ set->elements = NULL;
+
+ *buffer_set = set;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_add_buffer_set_member
+ (OM_uint32 * minor_status,
+ const gss_buffer_t member_buffer,
+ gss_buffer_set_t *buffer_set)
+{
+ gss_buffer_set_t set;
+ gss_buffer_t p;
+ OM_uint32 ret;
+
+ if (*buffer_set == GSS_C_NO_BUFFER_SET) {
+ ret = gss_create_empty_buffer_set(minor_status,
+ buffer_set);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ set = *buffer_set;
+ set->elements = realloc(set->elements,
+ (set->count + 1) * sizeof(set->elements[0]));
+ if (set->elements == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ p = &set->elements[set->count];
+
+ p->value = malloc(member_buffer->length);
+ if (p->value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy(p->value, member_buffer->value, member_buffer->length);
+ p->length = member_buffer->length;
+
+ set->count++;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_release_buffer_set(OM_uint32 * minor_status,
+ gss_buffer_set_t *buffer_set)
+{
+ size_t i;
+ OM_uint32 minor;
+
+ *minor_status = 0;
+
+ if (*buffer_set == GSS_C_NO_BUFFER_SET)
+ return GSS_S_COMPLETE;
+
+ for (i = 0; i < (*buffer_set)->count; i++)
+ gss_release_buffer(&minor, &((*buffer_set)->elements[i]));
+
+ free((*buffer_set)->elements);
+
+ (*buffer_set)->elements = NULL;
+ (*buffer_set)->count = 0;
+
+ free(*buffer_set);
+ *buffer_set = GSS_C_NO_BUFFER_SET;
+
+ return GSS_S_COMPLETE;
+}
+
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_canonicalize_name.c b/crypto/heimdal/lib/gssapi/mech/gss_canonicalize_name.c
new file mode 100644
index 0000000..bd8ff52
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_canonicalize_name.c
@@ -0,0 +1,111 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_canonicalize_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+/**
+ * gss_canonicalize_name takes a Internal Name (IN) and converts in into a
+ * mechanism specific Mechanism Name (MN).
+ *
+ * The input name may multiple name, or generic name types.
+ *
+ * If the input_name if of the GSS_C_NT_USER_NAME, and the Kerberos
+ * mechanism is specified, the resulting MN type is a
+ * GSS_KRB5_NT_PRINCIPAL_NAME.
+ *
+ * For more information about @ref internalVSmechname.
+ *
+ * @param minor_status minor status code.
+ * @param input_name name to covert, unchanged by gss_canonicalize_name().
+ * @param mech_type the type to convert Name too.
+ * @param output_name the resulting type, release with
+ * gss_release_name(), independent of input_name.
+ *
+ * @returns a gss_error code, see gss_display_status() about printing
+ * the error code.
+ *
+ * @ingroup gssapi
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_canonicalize_name(OM_uint32 *minor_status,
+ const gss_name_t input_name,
+ const gss_OID mech_type,
+ gss_name_t *output_name)
+{
+ OM_uint32 major_status;
+ struct _gss_name *name = (struct _gss_name *) input_name;
+ struct _gss_mechanism_name *mn;
+ gssapi_mech_interface m;
+ gss_name_t new_canonical_name;
+
+ *minor_status = 0;
+ *output_name = 0;
+
+ major_status = _gss_find_mn(minor_status, name, mech_type, &mn);
+ if (major_status)
+ return major_status;
+
+ m = mn->gmn_mech;
+ major_status = m->gm_canonicalize_name(minor_status,
+ mn->gmn_name, mech_type, &new_canonical_name);
+ if (major_status) {
+ _gss_mg_error(m, major_status, *minor_status);
+ return (major_status);
+ }
+
+ /*
+ * Now we make a new name and mark it as an MN.
+ */
+ *minor_status = 0;
+ name = malloc(sizeof(struct _gss_name));
+ if (!name) {
+ m->gm_release_name(minor_status, &new_canonical_name);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ memset(name, 0, sizeof(struct _gss_name));
+
+ mn = malloc(sizeof(struct _gss_mechanism_name));
+ if (!mn) {
+ m->gm_release_name(minor_status, &new_canonical_name);
+ free(name);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+
+ HEIM_SLIST_INIT(&name->gn_mn);
+ mn->gmn_mech = m;
+ mn->gmn_mech_oid = &m->gm_mech_oid;
+ mn->gmn_name = new_canonical_name;
+ HEIM_SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
+
+ *output_name = (gss_name_t) name;
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_compare_name.c b/crypto/heimdal/lib/gssapi/mech/gss_compare_name.c
new file mode 100644
index 0000000..70b4b1c
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_compare_name.c
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_compare_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_compare_name(OM_uint32 *minor_status,
+ const gss_name_t name1_arg,
+ const gss_name_t name2_arg,
+ int *name_equal)
+{
+ struct _gss_name *name1 = (struct _gss_name *) name1_arg;
+ struct _gss_name *name2 = (struct _gss_name *) name2_arg;
+
+ /*
+ * First check the implementation-independant name if both
+ * names have one. Otherwise, try to find common mechanism
+ * names and compare them.
+ */
+ if (name1->gn_value.value && name2->gn_value.value) {
+ *name_equal = 1;
+ if (!gss_oid_equal(&name1->gn_type, &name2->gn_type)) {
+ *name_equal = 0;
+ } else if (name1->gn_value.length != name2->gn_value.length ||
+ memcmp(name1->gn_value.value, name1->gn_value.value,
+ name1->gn_value.length)) {
+ *name_equal = 0;
+ }
+ } else {
+ struct _gss_mechanism_name *mn1;
+ struct _gss_mechanism_name *mn2;
+
+ HEIM_SLIST_FOREACH(mn1, &name1->gn_mn, gmn_link) {
+ OM_uint32 major_status;
+
+ major_status = _gss_find_mn(minor_status, name2,
+ mn1->gmn_mech_oid, &mn2);
+ if (major_status == GSS_S_COMPLETE) {
+ return (mn1->gmn_mech->gm_compare_name(
+ minor_status,
+ mn1->gmn_name,
+ mn2->gmn_name,
+ name_equal));
+ }
+ }
+ *name_equal = 0;
+ }
+
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_context_time.c b/crypto/heimdal/lib/gssapi/mech/gss_context_time.c
new file mode 100644
index 0000000..69434ee
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_context_time.c
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_context_time.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_context_time(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ OM_uint32 *time_rec)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ gssapi_mech_interface m = ctx->gc_mech;
+
+ return (m->gm_context_time(minor_status, ctx->gc_ctx, time_rec));
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c b/crypto/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c
new file mode 100644
index 0000000..8d880f5
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_create_empty_oid_set.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_create_empty_oid_set(OM_uint32 *minor_status,
+ gss_OID_set *oid_set)
+{
+ gss_OID_set set;
+
+ *minor_status = 0;
+ *oid_set = GSS_C_NO_OID_SET;
+
+ set = malloc(sizeof(gss_OID_set_desc));
+ if (!set) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+
+ set->count = 0;
+ set->elements = 0;
+ *oid_set = set;
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_cred.c b/crypto/heimdal/lib/gssapi/mech/gss_cred.c
new file mode 100644
index 0000000..99de687
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_cred.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2009 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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.
+ */
+
+#include "mech_locl.h"
+#include <krb5.h>
+
+/*
+ * format: any number of:
+ * mech-len: int32
+ * mech-data: char * (not alligned)
+ * cred-len: int32
+ * cred-data char * (not alligned)
+*/
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_export_cred(OM_uint32 * minor_status,
+ gss_cred_id_t cred_handle,
+ gss_buffer_t token)
+{
+ struct _gss_cred *cred = (struct _gss_cred *)cred_handle;
+ struct _gss_mechanism_cred *mc;
+ gss_buffer_desc buffer;
+ krb5_error_code ret;
+ krb5_storage *sp;
+ OM_uint32 major;
+ krb5_data data;
+
+ _mg_buffer_zero(token);
+
+ if (cred == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ if (mc->gmc_mech->gm_export_cred == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+ }
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+
+ major = mc->gmc_mech->gm_export_cred(minor_status,
+ mc->gmc_cred, &buffer);
+ if (major) {
+ krb5_storage_free(sp);
+ return major;
+ }
+
+ ret = krb5_storage_write(sp, buffer.value, buffer.length);
+ if (ret < 0 || (size_t)ret != buffer.length) {
+ gss_release_buffer(minor_status, &buffer);
+ krb5_storage_free(sp);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ gss_release_buffer(minor_status, &buffer);
+ }
+
+ ret = krb5_storage_to_data(sp, &data);
+ krb5_storage_free(sp);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ token->value = data.data;
+ token->length = data.length;
+
+ return GSS_S_COMPLETE;
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_import_cred(OM_uint32 * minor_status,
+ gss_buffer_t token,
+ gss_cred_id_t * cred_handle)
+{
+ gssapi_mech_interface m;
+ krb5_error_code ret;
+ struct _gss_cred *cred;
+ krb5_storage *sp = NULL;
+ OM_uint32 major, junk;
+ krb5_data data;
+
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+
+ if (token->length == 0) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ sp = krb5_storage_from_readonly_mem(token->value, token->length);
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ cred = calloc(1, sizeof(struct _gss_cred));
+ if (cred == NULL) {
+ krb5_storage_free(sp);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ HEIM_SLIST_INIT(&cred->gc_mc);
+
+ *cred_handle = (gss_cred_id_t)cred;
+
+ while(1) {
+ struct _gss_mechanism_cred *mc;
+ gss_buffer_desc buffer;
+ gss_cred_id_t mcred;
+ gss_OID_desc oid;
+
+ ret = krb5_ret_data(sp, &data);
+ if (ret == HEIM_ERR_EOF) {
+ break;
+ } else if (ret) {
+ *minor_status = ret;
+ major = GSS_S_FAILURE;
+ goto out;
+ }
+ oid.elements = data.data;
+ oid.length = data.length;
+
+ m = __gss_get_mechanism(&oid);
+ krb5_data_free(&data);
+ if (!m) {
+ *minor_status = 0;
+ major = GSS_S_BAD_MECH;
+ goto out;
+ }
+
+ if (m->gm_import_cred == NULL) {
+ *minor_status = 0;
+ major = GSS_S_BAD_MECH;
+ goto out;
+ }
+
+ ret = krb5_ret_data(sp, &data);
+ if (ret) {
+ *minor_status = ret;
+ major = GSS_S_FAILURE;
+ goto out;
+ }
+
+ buffer.value = data.data;
+ buffer.length = data.length;
+
+ major = m->gm_import_cred(minor_status,
+ &buffer, &mcred);
+ krb5_data_free(&data);
+ if (major) {
+ goto out;
+ }
+
+ mc = malloc(sizeof(struct _gss_mechanism_cred));
+ if (mc == NULL) {
+ *minor_status = EINVAL;
+ major = GSS_S_FAILURE;
+ goto out;
+ }
+
+ mc->gmc_mech = m;
+ mc->gmc_mech_oid = &m->gm_mech_oid;
+ mc->gmc_cred = mcred;
+
+ HEIM_SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);
+ }
+ krb5_storage_free(sp);
+ sp = NULL;
+
+ if (HEIM_SLIST_EMPTY(&cred->gc_mc)) {
+ major = GSS_S_NO_CRED;
+ goto out;
+ }
+
+ return GSS_S_COMPLETE;
+
+ out:
+ if (sp)
+ krb5_storage_free(sp);
+
+ gss_release_cred(&junk, cred_handle);
+
+ return major;
+
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_decapsulate_token.c b/crypto/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
new file mode 100644
index 0000000..3f2974e
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_decapsulate_token(gss_const_buffer_t input_token,
+ gss_const_OID oid,
+ gss_buffer_t output_token)
+{
+ GSSAPIContextToken ct;
+ heim_oid o;
+ OM_uint32 status;
+ int ret;
+ size_t size;
+
+ _mg_buffer_zero(output_token);
+
+ ret = der_get_oid (oid->elements, oid->length, &o, &size);
+ if (ret)
+ return GSS_S_FAILURE;
+
+ ret = decode_GSSAPIContextToken(input_token->value, input_token->length,
+ &ct, NULL);
+ if (ret) {
+ der_free_oid(&o);
+ return GSS_S_FAILURE;
+ }
+
+ if (der_heim_oid_cmp(&ct.thisMech, &o) == 0) {
+ status = GSS_S_COMPLETE;
+ output_token->value = ct.innerContextToken.data;
+ output_token->length = ct.innerContextToken.length;
+ der_free_oid(&ct.thisMech);
+ } else {
+ free_GSSAPIContextToken(&ct);
+ status = GSS_S_FAILURE;
+ }
+ der_free_oid(&o);
+
+ return status;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_delete_name_attribute.c b/crypto/heimdal/lib/gssapi/mech/gss_delete_name_attribute.c
new file mode 100644
index 0000000..cb35dd0
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_delete_name_attribute.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_delete_name_attribute(OM_uint32 *minor_status,
+ gss_name_t input_name,
+ gss_buffer_t attr)
+{
+ OM_uint32 major_status = GSS_S_UNAVAILABLE;
+ struct _gss_name *name = (struct _gss_name *) input_name;
+ struct _gss_mechanism_name *mn;
+
+ *minor_status = 0;
+
+ if (input_name == GSS_C_NO_NAME)
+ return GSS_S_BAD_NAME;
+
+ HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ gssapi_mech_interface m = mn->gmn_mech;
+
+ if (!m->gm_delete_name_attribute)
+ continue;
+
+ major_status = m->gm_delete_name_attribute(minor_status,
+ mn->gmn_name,
+ attr);
+ if (GSS_ERROR(major_status))
+ _gss_mg_error(m, major_status, *minor_status);
+ else
+ break;
+ }
+
+ return major_status;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_delete_sec_context.c b/crypto/heimdal/lib/gssapi/mech/gss_delete_sec_context.c
new file mode 100644
index 0000000..ce57a76
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_delete_sec_context.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_delete_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_delete_sec_context(OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ gss_buffer_t output_token)
+{
+ OM_uint32 major_status;
+ struct _gss_context *ctx = (struct _gss_context *) *context_handle;
+
+ if (output_token)
+ _mg_buffer_zero(output_token);
+
+ *minor_status = 0;
+ if (ctx) {
+ /*
+ * If we have an implementation ctx, delete it,
+ * otherwise fake an empty token.
+ */
+ if (ctx->gc_ctx) {
+ major_status = ctx->gc_mech->gm_delete_sec_context(
+ minor_status, &ctx->gc_ctx, output_token);
+ }
+ free(ctx);
+ *context_handle = GSS_C_NO_CONTEXT;
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_display_name.c b/crypto/heimdal/lib/gssapi/mech/gss_display_name.c
new file mode 100644
index 0000000..524a586
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_display_name.c
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_display_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_display_name(OM_uint32 *minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t output_name_buffer,
+ gss_OID *output_name_type)
+{
+ OM_uint32 major_status;
+ struct _gss_name *name = (struct _gss_name *) input_name;
+ struct _gss_mechanism_name *mn;
+
+ _mg_buffer_zero(output_name_buffer);
+ if (output_name_type)
+ *output_name_type = GSS_C_NO_OID;
+
+ if (name == NULL) {
+ *minor_status = 0;
+ return (GSS_S_BAD_NAME);
+ }
+
+ /*
+ * If we know it, copy the buffer used to import the name in
+ * the first place. Otherwise, ask all the MNs in turn if
+ * they can display the thing.
+ */
+ if (name->gn_value.value) {
+ output_name_buffer->value = malloc(name->gn_value.length);
+ if (!output_name_buffer->value) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ output_name_buffer->length = name->gn_value.length;
+ memcpy(output_name_buffer->value, name->gn_value.value,
+ output_name_buffer->length);
+ if (output_name_type)
+ *output_name_type = &name->gn_type;
+
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+ } else {
+ HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ major_status = mn->gmn_mech->gm_display_name(
+ minor_status, mn->gmn_name,
+ output_name_buffer,
+ output_name_type);
+ if (major_status == GSS_S_COMPLETE)
+ return (GSS_S_COMPLETE);
+ }
+ }
+
+ *minor_status = 0;
+ return (GSS_S_FAILURE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_display_name_ext.c b/crypto/heimdal/lib/gssapi/mech/gss_display_name_ext.c
new file mode 100644
index 0000000..6c0e5f3
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_display_name_ext.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2010, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_display_name_ext(OM_uint32 *minor_status,
+ gss_name_t input_name,
+ gss_OID display_as_name_type,
+ gss_buffer_t display_name)
+{
+ OM_uint32 major_status = GSS_S_UNAVAILABLE;
+ struct _gss_name *name = (struct _gss_name *) input_name;
+ struct _gss_mechanism_name *mn;
+
+ *minor_status = 0;
+ _mg_buffer_zero(display_name);
+
+ if (input_name == GSS_C_NO_NAME)
+ return GSS_S_BAD_NAME;
+
+ HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ gssapi_mech_interface m = mn->gmn_mech;
+
+ if (!m->gm_display_name_ext)
+ continue;
+
+ major_status = m->gm_display_name_ext(minor_status,
+ mn->gmn_name,
+ display_as_name_type,
+ display_name);
+ if (GSS_ERROR(major_status))
+ _gss_mg_error(m, major_status, *minor_status);
+ else
+ break;
+ }
+
+ return major_status;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_display_status.c b/crypto/heimdal/lib/gssapi/mech/gss_display_status.c
new file mode 100644
index 0000000..1e508ca
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_display_status.c
@@ -0,0 +1,211 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_display_status.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+/*
+ * Copyright (c) 1998 - 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "mech_locl.h"
+
+static const char *
+calling_error(OM_uint32 v)
+{
+ static const char *msgs[] = {
+ NULL, /* 0 */
+ "A required input parameter could not be read.", /* */
+ "A required output parameter could not be written.", /* */
+ "A parameter was malformed"
+ };
+
+ v >>= GSS_C_CALLING_ERROR_OFFSET;
+
+ if (v == 0)
+ return "";
+ else if (v >= sizeof(msgs)/sizeof(*msgs))
+ return "unknown calling error";
+ else
+ return msgs[v];
+}
+
+static const char *
+routine_error(OM_uint32 v)
+{
+ static const char *msgs[] = {
+ "Function completed successfully", /* 0 */
+ "An unsupported mechanism was requested",
+ "An invalid name was supplied",
+ "A supplied name was of an unsupported type",
+ "Incorrect channel bindings were supplied",
+ "An invalid status code was supplied",
+ "A token had an invalid MIC",
+ "No credentials were supplied, "
+ "or the credentials were unavailable or inaccessible.",
+ "No context has been established",
+ "A token was invalid",
+ "A credential was invalid",
+ "The referenced credentials have expired",
+ "The context has expired",
+ "Miscellaneous failure (see text)",
+ "The quality-of-protection requested could not be provide",
+ "The operation is forbidden by local security policy",
+ "The operation or option is not available",
+ "The requested credential element already exists",
+ "The provided name was not a mechanism name.",
+ };
+
+ v >>= GSS_C_ROUTINE_ERROR_OFFSET;
+
+ if (v >= sizeof(msgs)/sizeof(*msgs))
+ return "unknown routine error";
+ else
+ return msgs[v];
+}
+
+static const char *
+supplementary_error(OM_uint32 v)
+{
+ static const char *msgs[] = {
+ "normal completion",
+ "continuation call to routine required",
+ "duplicate per-message token detected",
+ "timed-out per-message token detected",
+ "reordered (early) per-message token detected",
+ "skipped predecessor token(s) detected"
+ };
+
+ v >>= GSS_C_SUPPLEMENTARY_OFFSET;
+
+ if (v >= sizeof(msgs)/sizeof(*msgs))
+ return "unknown routine error";
+ else
+ return msgs[v];
+}
+
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_display_status(OM_uint32 *minor_status,
+ OM_uint32 status_value,
+ int status_type,
+ const gss_OID mech_type,
+ OM_uint32 *message_content,
+ gss_buffer_t status_string)
+{
+ OM_uint32 major_status;
+
+ _mg_buffer_zero(status_string);
+ *message_content = 0;
+
+ major_status = _gss_mg_get_error(mech_type, status_type,
+ status_value, status_string);
+ if (major_status == GSS_S_COMPLETE) {
+
+ *message_content = 0;
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ }
+
+ *minor_status = 0;
+ switch (status_type) {
+ case GSS_C_GSS_CODE: {
+ char *buf = NULL;
+ int e;
+
+ if (GSS_SUPPLEMENTARY_INFO(status_value))
+ e = asprintf(&buf, "%s", supplementary_error(
+ GSS_SUPPLEMENTARY_INFO(status_value)));
+ else
+ e = asprintf (&buf, "%s %s",
+ calling_error(GSS_CALLING_ERROR(status_value)),
+ routine_error(GSS_ROUTINE_ERROR(status_value)));
+
+ if (e < 0 || buf == NULL)
+ break;
+
+ status_string->length = strlen(buf);
+ status_string->value = buf;
+
+ return GSS_S_COMPLETE;
+ }
+ case GSS_C_MECH_CODE: {
+ OM_uint32 maj_junk, min_junk;
+ gss_buffer_desc oid;
+ char *buf = NULL;
+ int e;
+
+ maj_junk = gss_oid_to_str(&min_junk, mech_type, &oid);
+ if (maj_junk != GSS_S_COMPLETE) {
+ oid.value = rk_UNCONST("unknown");
+ oid.length = 7;
+ }
+
+ e = asprintf (&buf, "unknown mech-code %lu for mech %.*s",
+ (unsigned long)status_value,
+ (int)oid.length, (char *)oid.value);
+ if (maj_junk == GSS_S_COMPLETE)
+ gss_release_buffer(&min_junk, &oid);
+
+ if (e < 0 || buf == NULL)
+ break;
+
+ status_string->length = strlen(buf);
+ status_string->value = buf;
+
+ return GSS_S_COMPLETE;
+ }
+ }
+ _mg_buffer_zero(status_string);
+ return (GSS_S_BAD_STATUS);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_duplicate_name.c b/crypto/heimdal/lib/gssapi/mech/gss_duplicate_name.c
new file mode 100644
index 0000000..a76c87c
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_duplicate_name.c
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_duplicate_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_duplicate_name(OM_uint32 *minor_status,
+ const gss_name_t src_name,
+ gss_name_t *dest_name)
+{
+ OM_uint32 major_status;
+ struct _gss_name *name = (struct _gss_name *) src_name;
+ struct _gss_name *new_name;
+ struct _gss_mechanism_name *mn;
+
+ *minor_status = 0;
+ *dest_name = GSS_C_NO_NAME;
+
+ /*
+ * If this name has a value (i.e. it didn't come from
+ * gss_canonicalize_name(), we re-import the thing. Otherwise,
+ * we make copy of each mech names.
+ */
+ if (name->gn_value.value) {
+ major_status = gss_import_name(minor_status,
+ &name->gn_value, &name->gn_type, dest_name);
+ if (major_status != GSS_S_COMPLETE)
+ return (major_status);
+ new_name = (struct _gss_name *) *dest_name;
+
+ HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ struct _gss_mechanism_name *mn2;
+ _gss_find_mn(minor_status, new_name,
+ mn->gmn_mech_oid, &mn2);
+ }
+ } else {
+ new_name = malloc(sizeof(struct _gss_name));
+ if (!new_name) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ memset(new_name, 0, sizeof(struct _gss_name));
+ HEIM_SLIST_INIT(&new_name->gn_mn);
+ *dest_name = (gss_name_t) new_name;
+
+ HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ struct _gss_mechanism_name *new_mn;
+
+ new_mn = malloc(sizeof(*new_mn));
+ if (!new_mn) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ new_mn->gmn_mech = mn->gmn_mech;
+ new_mn->gmn_mech_oid = mn->gmn_mech_oid;
+
+ major_status =
+ mn->gmn_mech->gm_duplicate_name(minor_status,
+ mn->gmn_name, &new_mn->gmn_name);
+ if (major_status != GSS_S_COMPLETE) {
+ free(new_mn);
+ continue;
+ }
+ HEIM_SLIST_INSERT_HEAD(&new_name->gn_mn, new_mn, gmn_link);
+ }
+
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_duplicate_oid.c b/crypto/heimdal/lib/gssapi/mech/gss_duplicate_oid.c
new file mode 100644
index 0000000..10a2000
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_duplicate_oid.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_duplicate_oid (
+ OM_uint32 *minor_status,
+ gss_OID src_oid,
+ gss_OID *dest_oid
+ )
+{
+ *minor_status = 0;
+
+ if (src_oid == GSS_C_NO_OID) {
+ *dest_oid = GSS_C_NO_OID;
+ return GSS_S_COMPLETE;
+ }
+
+ *dest_oid = malloc(sizeof(**dest_oid));
+ if (*dest_oid == GSS_C_NO_OID) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ (*dest_oid)->elements = malloc(src_oid->length);
+ if ((*dest_oid)->elements == NULL) {
+ free(*dest_oid);
+ *dest_oid = GSS_C_NO_OID;
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy((*dest_oid)->elements, src_oid->elements, src_oid->length);
+ (*dest_oid)->length = src_oid->length;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_encapsulate_token.c b/crypto/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
new file mode 100644
index 0000000..1b1f973
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_encapsulate_token(gss_const_buffer_t input_token,
+ gss_const_OID oid,
+ gss_buffer_t output_token)
+{
+ GSSAPIContextToken ct;
+ int ret;
+ size_t size;
+
+ ret = der_get_oid (oid->elements, oid->length, &ct.thisMech, &size);
+ if (ret) {
+ _mg_buffer_zero(output_token);
+ return GSS_S_FAILURE;
+ }
+
+ ct.innerContextToken.data = input_token->value;
+ ct.innerContextToken.length = input_token->length;
+
+ ASN1_MALLOC_ENCODE(GSSAPIContextToken,
+ output_token->value, output_token->length,
+ &ct, &size, ret);
+ der_free_oid(&ct.thisMech);
+ if (ret) {
+ _mg_buffer_zero(output_token);
+ return GSS_S_FAILURE;
+ }
+ if (output_token->length != size)
+ abort();
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_export_name.c b/crypto/heimdal/lib/gssapi/mech/gss_export_name.c
new file mode 100644
index 0000000..3e6e626
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_export_name.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_export_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_export_name(OM_uint32 *minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t exported_name)
+{
+ struct _gss_name *name = (struct _gss_name *) input_name;
+ struct _gss_mechanism_name *mn;
+
+ _mg_buffer_zero(exported_name);
+
+ /*
+ * If this name already has any attached MNs, export the first
+ * one, otherwise export based on the first mechanism in our
+ * list.
+ */
+ mn = HEIM_SLIST_FIRST(&name->gn_mn);
+ if (!mn) {
+ *minor_status = 0;
+ return (GSS_S_NAME_NOT_MN);
+ }
+
+ return mn->gmn_mech->gm_export_name(minor_status,
+ mn->gmn_name, exported_name);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_export_name_composite.c b/crypto/heimdal/lib/gssapi/mech/gss_export_name_composite.c
new file mode 100644
index 0000000..530a905
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_export_name_composite.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_export_name_composite(OM_uint32 *minor_status,
+ gss_name_t input_name,
+ gss_buffer_t exp_composite_name)
+{
+ OM_uint32 major_status = GSS_S_UNAVAILABLE;
+ struct _gss_name *name = (struct _gss_name *) input_name;
+ struct _gss_mechanism_name *mn;
+
+ *minor_status = 0;
+ _mg_buffer_zero(exp_composite_name);
+
+ if (input_name == GSS_C_NO_NAME)
+ return GSS_S_BAD_NAME;
+
+ HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ gssapi_mech_interface m = mn->gmn_mech;
+
+ if (!m->gm_export_name_composite)
+ continue;
+
+ major_status = m->gm_export_name_composite(minor_status,
+ mn->gmn_name,
+ exp_composite_name);
+ if (GSS_ERROR(major_status))
+ _gss_mg_error(m, major_status, *minor_status);
+ else
+ break;
+ }
+
+ return major_status;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_export_sec_context.c b/crypto/heimdal/lib/gssapi/mech/gss_export_sec_context.c
new file mode 100644
index 0000000..369f3a2
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_export_sec_context.c
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_export_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_export_sec_context(OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ gss_buffer_t interprocess_token)
+{
+ OM_uint32 major_status;
+ struct _gss_context *ctx = (struct _gss_context *) *context_handle;
+ gssapi_mech_interface m = ctx->gc_mech;
+ gss_buffer_desc buf;
+
+ _mg_buffer_zero(interprocess_token);
+
+ major_status = m->gm_export_sec_context(minor_status,
+ &ctx->gc_ctx, &buf);
+
+ if (major_status == GSS_S_COMPLETE) {
+ unsigned char *p;
+
+ free(ctx);
+ *context_handle = GSS_C_NO_CONTEXT;
+ interprocess_token->length = buf.length
+ + 2 + m->gm_mech_oid.length;
+ interprocess_token->value = malloc(interprocess_token->length);
+ if (!interprocess_token->value) {
+ /*
+ * We are in trouble here - the context is
+ * already gone. This is allowed as long as we
+ * set the caller's context_handle to
+ * GSS_C_NO_CONTEXT, which we did above.
+ * Return GSS_S_FAILURE.
+ */
+ _mg_buffer_zero(interprocess_token);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ p = interprocess_token->value;
+ p[0] = m->gm_mech_oid.length >> 8;
+ p[1] = m->gm_mech_oid.length;
+ memcpy(p + 2, m->gm_mech_oid.elements, m->gm_mech_oid.length);
+ memcpy(p + 2 + m->gm_mech_oid.length, buf.value, buf.length);
+ gss_release_buffer(minor_status, &buf);
+ } else {
+ _gss_mg_error(m, major_status, *minor_status);
+ }
+
+ return (major_status);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_get_mic.c b/crypto/heimdal/lib/gssapi/mech/gss_get_mic.c
new file mode 100644
index 0000000..6eebfe0
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_get_mic.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_get_mic.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_get_mic(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_qop_t qop_req,
+ const gss_buffer_t message_buffer,
+ gss_buffer_t message_token)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ gssapi_mech_interface m;
+
+ _mg_buffer_zero(message_token);
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ m = ctx->gc_mech;
+
+ return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req,
+ message_buffer, message_token));
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_get_name_attribute.c b/crypto/heimdal/lib/gssapi/mech/gss_get_name_attribute.c
new file mode 100644
index 0000000..450bbac
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_get_name_attribute.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_get_name_attribute(OM_uint32 *minor_status,
+ gss_name_t input_name,
+ gss_buffer_t attr,
+ int *authenticated,
+ int *complete,
+ gss_buffer_t value,
+ gss_buffer_t display_value,
+ int *more)
+{
+ OM_uint32 major_status = GSS_S_UNAVAILABLE;
+ struct _gss_name *name = (struct _gss_name *) input_name;
+ struct _gss_mechanism_name *mn;
+
+ *minor_status = 0;
+ if (authenticated != NULL)
+ *authenticated = 0;
+ if (complete != NULL)
+ *complete = 0;
+ _mg_buffer_zero(value);
+ _mg_buffer_zero(display_value);
+
+ if (input_name == GSS_C_NO_NAME)
+ return GSS_S_BAD_NAME;
+
+ HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ gssapi_mech_interface m = mn->gmn_mech;
+
+ if (!m->gm_get_name_attribute)
+ continue;
+
+ major_status = m->gm_get_name_attribute(minor_status,
+ mn->gmn_name,
+ attr,
+ authenticated,
+ complete,
+ value,
+ display_value,
+ more);
+ if (GSS_ERROR(major_status))
+ _gss_mg_error(m, major_status, *minor_status);
+ else
+ break;
+ }
+
+ return major_status;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_import_name.c b/crypto/heimdal/lib/gssapi/mech/gss_import_name.c
new file mode 100644
index 0000000..d1b3dc9
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_import_name.c
@@ -0,0 +1,291 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_import_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+static OM_uint32
+_gss_import_export_name(OM_uint32 *minor_status,
+ const gss_buffer_t input_name_buffer,
+ gss_name_t *output_name)
+{
+ OM_uint32 major_status;
+ unsigned char *p = input_name_buffer->value;
+ size_t len = input_name_buffer->length;
+ size_t t;
+ gss_OID_desc mech_oid;
+ gssapi_mech_interface m;
+ struct _gss_name *name;
+ gss_name_t new_canonical_name;
+ int composite = 0;
+
+ *minor_status = 0;
+ *output_name = 0;
+
+ /*
+ * Make sure that TOK_ID is {4, 1}.
+ */
+ if (len < 2)
+ return (GSS_S_BAD_NAME);
+ if (p[0] != 4)
+ return (GSS_S_BAD_NAME);
+ switch (p[1]) {
+ case 1: /* non-composite name */
+ break;
+ case 2: /* composite name */
+ composite = 1;
+ break;
+ default:
+ return (GSS_S_BAD_NAME);
+ }
+ p += 2;
+ len -= 2;
+
+ /*
+ * Get the mech length and the name length and sanity
+ * check the size of of the buffer.
+ */
+ if (len < 2)
+ return (GSS_S_BAD_NAME);
+ t = (p[0] << 8) + p[1];
+ p += 2;
+ len -= 2;
+
+ /*
+ * Check the DER encoded OID to make sure it agrees with the
+ * length we just decoded.
+ */
+ if (p[0] != 6) /* 6=OID */
+ return (GSS_S_BAD_NAME);
+ p++;
+ len--;
+ t--;
+ if (p[0] & 0x80) {
+ int digits = p[0];
+ p++;
+ len--;
+ t--;
+ mech_oid.length = 0;
+ while (digits--) {
+ mech_oid.length = (mech_oid.length << 8) | p[0];
+ p++;
+ len--;
+ t--;
+ }
+ } else {
+ mech_oid.length = p[0];
+ p++;
+ len--;
+ t--;
+ }
+ if (mech_oid.length != t)
+ return (GSS_S_BAD_NAME);
+
+ mech_oid.elements = p;
+
+ if (len < t + 4)
+ return (GSS_S_BAD_NAME);
+ p += t;
+ len -= t;
+
+ t = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ p += 4;
+ len -= 4;
+
+ if (!composite && len != t)
+ return (GSS_S_BAD_NAME);
+
+ m = __gss_get_mechanism(&mech_oid);
+ if (!m)
+ return (GSS_S_BAD_MECH);
+
+ /*
+ * Ask the mechanism to import the name.
+ */
+ major_status = m->gm_import_name(minor_status,
+ input_name_buffer, GSS_C_NT_EXPORT_NAME, &new_canonical_name);
+ if (major_status != GSS_S_COMPLETE) {
+ _gss_mg_error(m, major_status, *minor_status);
+ return major_status;
+ }
+
+ /*
+ * Now we make a new name and mark it as an MN.
+ */
+ name = _gss_make_name(m, new_canonical_name);
+ if (!name) {
+ m->gm_release_name(minor_status, &new_canonical_name);
+ return (GSS_S_FAILURE);
+ }
+
+ *output_name = (gss_name_t) name;
+
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+}
+
+/**
+ * Import a name internal or mechanism name
+ *
+ * Type of name and their format:
+ * - GSS_C_NO_OID
+ * - GSS_C_NT_USER_NAME
+ * - GSS_C_NT_HOSTBASED_SERVICE
+ * - GSS_C_NT_EXPORT_NAME
+ * - GSS_C_NT_ANONYMOUS
+ * - GSS_KRB5_NT_PRINCIPAL_NAME
+ *
+ * For more information about @ref internalVSmechname.
+ *
+ * @param minor_status minor status code
+ * @param input_name_buffer import name buffer
+ * @param input_name_type type of the import name buffer
+ * @param output_name the resulting type, release with
+ * gss_release_name(), independent of input_name
+ *
+ * @returns a gss_error code, see gss_display_status() about printing
+ * the error code.
+ *
+ * @ingroup gssapi
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_import_name(OM_uint32 *minor_status,
+ const gss_buffer_t input_name_buffer,
+ const gss_OID input_name_type,
+ gss_name_t *output_name)
+{
+ struct _gss_mechanism_name *mn;
+ gss_OID name_type = input_name_type;
+ OM_uint32 major_status, ms;
+ struct _gss_name *name;
+ struct _gss_mech_switch *m;
+ gss_name_t rname;
+
+ *output_name = GSS_C_NO_NAME;
+
+ if (input_name_buffer->length == 0) {
+ *minor_status = 0;
+ return (GSS_S_BAD_NAME);
+ }
+
+ _gss_load_mech();
+
+ /*
+ * Use GSS_NT_USER_NAME as default name type.
+ */
+ if (name_type == GSS_C_NO_OID)
+ name_type = GSS_C_NT_USER_NAME;
+
+ /*
+ * If this is an exported name, we need to parse it to find
+ * the mechanism and then import it as an MN. See RFC 2743
+ * section 3.2 for a description of the format.
+ */
+ if (gss_oid_equal(name_type, GSS_C_NT_EXPORT_NAME)) {
+ return _gss_import_export_name(minor_status,
+ input_name_buffer, output_name);
+ }
+
+
+ *minor_status = 0;
+ name = calloc(1, sizeof(struct _gss_name));
+ if (!name) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+
+ HEIM_SLIST_INIT(&name->gn_mn);
+
+ major_status = _gss_copy_oid(minor_status,
+ name_type, &name->gn_type);
+ if (major_status) {
+ free(name);
+ return (GSS_S_FAILURE);
+ }
+
+ major_status = _gss_copy_buffer(minor_status,
+ input_name_buffer, &name->gn_value);
+ if (major_status)
+ goto out;
+
+ /*
+ * Walk over the mechs and import the name into a mech name
+ * for those supported this nametype.
+ */
+
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ int present = 0;
+
+ major_status = gss_test_oid_set_member(minor_status,
+ name_type, m->gm_name_types, &present);
+
+ if (major_status || present == 0)
+ continue;
+
+ mn = malloc(sizeof(struct _gss_mechanism_name));
+ if (!mn) {
+ *minor_status = ENOMEM;
+ major_status = GSS_S_FAILURE;
+ goto out;
+ }
+
+ major_status = (*m->gm_mech.gm_import_name)(minor_status,
+ &name->gn_value,
+ (name->gn_type.elements
+ ? &name->gn_type : GSS_C_NO_OID),
+ &mn->gmn_name);
+ if (major_status != GSS_S_COMPLETE) {
+ _gss_mg_error(&m->gm_mech, major_status, *minor_status);
+ free(mn);
+ goto out;
+ }
+
+ mn->gmn_mech = &m->gm_mech;
+ mn->gmn_mech_oid = &m->gm_mech_oid;
+ HEIM_SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
+ }
+
+ /*
+ * If we can't find a mn for the name, bail out already here.
+ */
+
+ mn = HEIM_SLIST_FIRST(&name->gn_mn);
+ if (!mn) {
+ *minor_status = 0;
+ major_status = GSS_S_NAME_NOT_MN;
+ goto out;
+ }
+
+ *output_name = (gss_name_t) name;
+ return (GSS_S_COMPLETE);
+
+ out:
+ rname = (gss_name_t)name;
+ gss_release_name(&ms, &rname);
+ return major_status;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_import_sec_context.c b/crypto/heimdal/lib/gssapi/mech/gss_import_sec_context.c
new file mode 100644
index 0000000..9865db7
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_import_sec_context.c
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_import_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_import_sec_context(OM_uint32 *minor_status,
+ const gss_buffer_t interprocess_token,
+ gss_ctx_id_t *context_handle)
+{
+ OM_uint32 major_status;
+ gssapi_mech_interface m;
+ struct _gss_context *ctx;
+ gss_OID_desc mech_oid;
+ gss_buffer_desc buf;
+ unsigned char *p;
+ size_t len;
+
+ *minor_status = 0;
+ *context_handle = GSS_C_NO_CONTEXT;
+
+ /*
+ * We added an oid to the front of the token in
+ * gss_export_sec_context.
+ */
+ p = interprocess_token->value;
+ len = interprocess_token->length;
+ if (len < 2)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ mech_oid.length = (p[0] << 8) | p[1];
+ if (len < mech_oid.length + 2)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ mech_oid.elements = p + 2;
+ buf.length = len - 2 - mech_oid.length;
+ buf.value = p + 2 + mech_oid.length;
+
+ m = __gss_get_mechanism(&mech_oid);
+ if (!m)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ ctx = malloc(sizeof(struct _gss_context));
+ if (!ctx) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ ctx->gc_mech = m;
+ major_status = m->gm_import_sec_context(minor_status,
+ &buf, &ctx->gc_ctx);
+ if (major_status != GSS_S_COMPLETE) {
+ _gss_mg_error(m, major_status, *minor_status);
+ free(ctx);
+ } else {
+ *context_handle = (gss_ctx_id_t) ctx;
+ }
+
+ return (major_status);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_indicate_mechs.c b/crypto/heimdal/lib/gssapi/mech/gss_indicate_mechs.c
new file mode 100644
index 0000000..8fd53d9
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_indicate_mechs.c
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_indicate_mechs.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_indicate_mechs(OM_uint32 *minor_status,
+ gss_OID_set *mech_set)
+{
+ struct _gss_mech_switch *m;
+ OM_uint32 major_status;
+ gss_OID_set set;
+ size_t i;
+
+ _gss_load_mech();
+
+ major_status = gss_create_empty_oid_set(minor_status, mech_set);
+ if (major_status)
+ return (major_status);
+
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ if (m->gm_mech.gm_indicate_mechs) {
+ major_status = m->gm_mech.gm_indicate_mechs(
+ minor_status, &set);
+ if (major_status)
+ continue;
+ for (i = 0; i < set->count; i++)
+ major_status = gss_add_oid_set_member(
+ minor_status, &set->elements[i], mech_set);
+ gss_release_oid_set(minor_status, &set);
+ } else {
+ major_status = gss_add_oid_set_member(
+ minor_status, &m->gm_mech_oid, mech_set);
+ }
+ }
+
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_init_sec_context.c b/crypto/heimdal/lib/gssapi/mech/gss_init_sec_context.c
new file mode 100644
index 0000000..af0170a
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_init_sec_context.c
@@ -0,0 +1,212 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_init_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+static gss_cred_id_t
+_gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type)
+{
+ struct _gss_cred *cred = (struct _gss_cred *)cred_handle;
+ struct _gss_mechanism_cred *mc;
+
+ if (cred == NULL)
+ return GSS_C_NO_CREDENTIAL;
+
+ HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ if (gss_oid_equal(mech_type, mc->gmc_mech_oid))
+ return mc->gmc_cred;
+ }
+ return GSS_C_NO_CREDENTIAL;
+}
+
+/**
+ * As the initiator build a context with an acceptor.
+ *
+ * Returns in the major
+ * - GSS_S_COMPLETE - if the context if build
+ * - GSS_S_CONTINUE_NEEDED - if the caller needs to continue another
+ * round of gss_i nit_sec_context
+ * - error code - any other error code
+ *
+ * @param minor_status minor status code.
+ *
+ * @param initiator_cred_handle the credential to use when building
+ * the context, if GSS_C_NO_CREDENTIAL is passed, the default
+ * credential for the mechanism will be used.
+ *
+ * @param context_handle a pointer to a context handle, will be
+ * returned as long as there is not an error.
+ *
+ * @param target_name the target name of acceptor, created using
+ * gss_import_name(). The name is can be of any name types the
+ * mechanism supports, check supported name types with
+ * gss_inquire_names_for_mech().
+ *
+ * @param input_mech_type mechanism type to use, if GSS_C_NO_OID is
+ * used, Kerberos (GSS_KRB5_MECHANISM) will be tried. Other
+ * available mechanism are listed in the @ref gssapi_mechs_intro
+ * section.
+ *
+ * @param req_flags flags using when building the context, see @ref
+ * gssapi_context_flags
+ *
+ * @param time_req time requested this context should be valid in
+ * seconds, common used value is GSS_C_INDEFINITE
+ *
+ * @param input_chan_bindings Channel bindings used, if not exepected
+ * otherwise, used GSS_C_NO_CHANNEL_BINDINGS
+ *
+ * @param input_token input token sent from the acceptor, for the
+ * initial packet the buffer of { NULL, 0 } should be used.
+ *
+ * @param actual_mech_type the actual mech used, MUST NOT be freed
+ * since it pointing to static memory.
+ *
+ * @param output_token if there is an output token, regardless of
+ * complete, continue_needed, or error it should be sent to the
+ * acceptor
+ *
+ * @param ret_flags return what flags was negotitated, caller should
+ * check if they are accetable. For example, if
+ * GSS_C_MUTUAL_FLAG was negotiated with the acceptor or not.
+ *
+ * @param time_rec amount of time this context is valid for
+ *
+ * @returns a gss_error code, see gss_display_status() about printing
+ * the error code.
+ *
+ * @ingroup gssapi
+ */
+
+
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_init_sec_context(OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID input_mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec)
+{
+ OM_uint32 major_status;
+ gssapi_mech_interface m;
+ struct _gss_name *name = (struct _gss_name *) target_name;
+ struct _gss_mechanism_name *mn;
+ struct _gss_context *ctx = (struct _gss_context *) *context_handle;
+ gss_cred_id_t cred_handle;
+ int allocated_ctx;
+ gss_OID mech_type = input_mech_type;
+
+ *minor_status = 0;
+
+ _mg_buffer_zero(output_token);
+ if (actual_mech_type)
+ *actual_mech_type = GSS_C_NO_OID;
+ if (ret_flags)
+ *ret_flags = 0;
+ if (time_rec)
+ *time_rec = 0;
+
+ /*
+ * If we haven't allocated a context yet, do so now and lookup
+ * the mechanism switch table. If we have one already, make
+ * sure we use the same mechanism switch as before.
+ */
+ if (!ctx) {
+ if (mech_type == NULL)
+ mech_type = GSS_KRB5_MECHANISM;
+
+ ctx = malloc(sizeof(struct _gss_context));
+ if (!ctx) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ memset(ctx, 0, sizeof(struct _gss_context));
+ m = ctx->gc_mech = __gss_get_mechanism(mech_type);
+ if (!m) {
+ free(ctx);
+ return (GSS_S_BAD_MECH);
+ }
+ allocated_ctx = 1;
+ } else {
+ m = ctx->gc_mech;
+ mech_type = &ctx->gc_mech->gm_mech_oid;
+ allocated_ctx = 0;
+ }
+
+ /*
+ * Find the MN for this mechanism.
+ */
+ major_status = _gss_find_mn(minor_status, name, mech_type, &mn);
+ if (major_status != GSS_S_COMPLETE) {
+ if (allocated_ctx)
+ free(ctx);
+ return major_status;
+ }
+
+ /*
+ * If we have a cred, find the cred for this mechanism.
+ */
+ if (m->gm_flags & GM_USE_MG_CRED)
+ cred_handle = initiator_cred_handle;
+ else
+ cred_handle = _gss_mech_cred_find(initiator_cred_handle, mech_type);
+
+ major_status = m->gm_init_sec_context(minor_status,
+ cred_handle,
+ &ctx->gc_ctx,
+ mn->gmn_name,
+ mech_type,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+
+ if (major_status != GSS_S_COMPLETE
+ && major_status != GSS_S_CONTINUE_NEEDED) {
+ if (allocated_ctx)
+ free(ctx);
+ _mg_buffer_zero(output_token);
+ _gss_mg_error(m, major_status, *minor_status);
+ } else {
+ *context_handle = (gss_ctx_id_t) ctx;
+ }
+
+ return (major_status);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_inquire_context.c b/crypto/heimdal/lib/gssapi/mech/gss_inquire_context.c
new file mode 100644
index 0000000..2568075
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_inquire_context.c
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_inquire_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_context(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_name_t *src_name,
+ gss_name_t *targ_name,
+ OM_uint32 *lifetime_rec,
+ gss_OID *mech_type,
+ OM_uint32 *ctx_flags,
+ int *locally_initiated,
+ int *xopen)
+{
+ OM_uint32 major_status;
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ gssapi_mech_interface m = ctx->gc_mech;
+ struct _gss_name *name;
+ gss_name_t src_mn, targ_mn;
+
+ if (locally_initiated)
+ *locally_initiated = 0;
+ if (xopen)
+ *xopen = 0;
+ if (lifetime_rec)
+ *lifetime_rec = 0;
+
+ if (src_name)
+ *src_name = GSS_C_NO_NAME;
+ if (targ_name)
+ *targ_name = GSS_C_NO_NAME;
+ if (mech_type)
+ *mech_type = GSS_C_NO_OID;
+ src_mn = targ_mn = GSS_C_NO_NAME;
+
+ major_status = m->gm_inquire_context(minor_status,
+ ctx->gc_ctx,
+ src_name ? &src_mn : NULL,
+ targ_name ? &targ_mn : NULL,
+ lifetime_rec,
+ mech_type,
+ ctx_flags,
+ locally_initiated,
+ xopen);
+
+ if (major_status != GSS_S_COMPLETE) {
+ _gss_mg_error(m, major_status, *minor_status);
+ return (major_status);
+ }
+
+ if (src_name) {
+ name = _gss_make_name(m, src_mn);
+ if (!name) {
+ if (mech_type)
+ *mech_type = GSS_C_NO_OID;
+ m->gm_release_name(minor_status, &src_mn);
+ *minor_status = 0;
+ return (GSS_S_FAILURE);
+ }
+ *src_name = (gss_name_t) name;
+ }
+
+ if (targ_name) {
+ name = _gss_make_name(m, targ_mn);
+ if (!name) {
+ if (mech_type)
+ *mech_type = GSS_C_NO_OID;
+ if (src_name)
+ gss_release_name(minor_status, src_name);
+ m->gm_release_name(minor_status, &targ_mn);
+ *minor_status = 0;
+ return (GSS_S_FAILURE);
+ }
+ *targ_name = (gss_name_t) name;
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_inquire_cred.c b/crypto/heimdal/lib/gssapi/mech/gss_inquire_cred.c
new file mode 100644
index 0000000..1db0f23
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_inquire_cred.c
@@ -0,0 +1,195 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_inquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+#define AUSAGE 1
+#define IUSAGE 2
+
+static void
+updateusage(gss_cred_usage_t usage, int *usagemask)
+{
+ if (usage == GSS_C_BOTH)
+ *usagemask |= AUSAGE | IUSAGE;
+ else if (usage == GSS_C_ACCEPT)
+ *usagemask |= AUSAGE;
+ else if (usage == GSS_C_INITIATE)
+ *usagemask |= IUSAGE;
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_cred(OM_uint32 *minor_status,
+ const gss_cred_id_t cred_handle,
+ gss_name_t *name_ret,
+ OM_uint32 *lifetime,
+ gss_cred_usage_t *cred_usage,
+ gss_OID_set *mechanisms)
+{
+ OM_uint32 major_status;
+ struct _gss_mech_switch *m;
+ struct _gss_cred *cred = (struct _gss_cred *) cred_handle;
+ struct _gss_name *name;
+ struct _gss_mechanism_name *mn;
+ OM_uint32 min_lifetime;
+ int found = 0;
+ int usagemask = 0;
+ gss_cred_usage_t usage;
+
+ _gss_load_mech();
+
+ *minor_status = 0;
+ if (name_ret)
+ *name_ret = GSS_C_NO_NAME;
+ if (lifetime)
+ *lifetime = 0;
+ if (cred_usage)
+ *cred_usage = 0;
+ if (mechanisms)
+ *mechanisms = GSS_C_NO_OID_SET;
+
+ if (name_ret) {
+ name = calloc(1, sizeof(*name));
+ if (name == NULL) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ HEIM_SLIST_INIT(&name->gn_mn);
+ } else {
+ name = NULL;
+ }
+
+ if (mechanisms) {
+ major_status = gss_create_empty_oid_set(minor_status,
+ mechanisms);
+ if (major_status) {
+ if (name) free(name);
+ return (major_status);
+ }
+ }
+
+ min_lifetime = GSS_C_INDEFINITE;
+ if (cred) {
+ struct _gss_mechanism_cred *mc;
+
+ HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ gss_name_t mc_name;
+ OM_uint32 mc_lifetime;
+
+ major_status = mc->gmc_mech->gm_inquire_cred(minor_status,
+ mc->gmc_cred, &mc_name, &mc_lifetime, &usage, NULL);
+ if (major_status)
+ continue;
+
+ updateusage(usage, &usagemask);
+ if (name) {
+ mn = malloc(sizeof(struct _gss_mechanism_name));
+ if (!mn) {
+ mc->gmc_mech->gm_release_name(minor_status,
+ &mc_name);
+ continue;
+ }
+ mn->gmn_mech = mc->gmc_mech;
+ mn->gmn_mech_oid = mc->gmc_mech_oid;
+ mn->gmn_name = mc_name;
+ HEIM_SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
+ } else {
+ mc->gmc_mech->gm_release_name(minor_status,
+ &mc_name);
+ }
+
+ if (mc_lifetime < min_lifetime)
+ min_lifetime = mc_lifetime;
+
+ if (mechanisms)
+ gss_add_oid_set_member(minor_status,
+ mc->gmc_mech_oid, mechanisms);
+ found++;
+ }
+ } else {
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ gss_name_t mc_name;
+ OM_uint32 mc_lifetime;
+
+ major_status = m->gm_mech.gm_inquire_cred(minor_status,
+ GSS_C_NO_CREDENTIAL, &mc_name, &mc_lifetime,
+ &usage, NULL);
+ if (major_status)
+ continue;
+
+ updateusage(usage, &usagemask);
+ if (name && mc_name) {
+ mn = malloc(
+ sizeof(struct _gss_mechanism_name));
+ if (!mn) {
+ m->gm_mech.gm_release_name(
+ minor_status, &mc_name);
+ continue;
+ }
+ mn->gmn_mech = &m->gm_mech;
+ mn->gmn_mech_oid = &m->gm_mech_oid;
+ mn->gmn_name = mc_name;
+ HEIM_SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
+ } else if (mc_name) {
+ m->gm_mech.gm_release_name(minor_status,
+ &mc_name);
+ }
+
+ if (mc_lifetime < min_lifetime)
+ min_lifetime = mc_lifetime;
+
+ if (mechanisms)
+ gss_add_oid_set_member(minor_status,
+ &m->gm_mech_oid, mechanisms);
+ found++;
+ }
+ }
+
+ if (found == 0) {
+ gss_name_t n = (gss_name_t)name;
+ if (n)
+ gss_release_name(minor_status, &n);
+ gss_release_oid_set(minor_status, mechanisms);
+ *minor_status = 0;
+ return (GSS_S_NO_CRED);
+ }
+
+ *minor_status = 0;
+ if (name_ret)
+ *name_ret = (gss_name_t) name;
+ if (lifetime)
+ *lifetime = min_lifetime;
+ if (cred_usage) {
+ if ((usagemask & (AUSAGE|IUSAGE)) == (AUSAGE|IUSAGE))
+ *cred_usage = GSS_C_BOTH;
+ else if (usagemask & IUSAGE)
+ *cred_usage = GSS_C_INITIATE;
+ else if (usagemask & AUSAGE)
+ *cred_usage = GSS_C_ACCEPT;
+ }
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c b/crypto/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c
new file mode 100644
index 0000000..e7746e4
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_inquire_cred_by_mech.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_cred_by_mech(OM_uint32 *minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID mech_type,
+ gss_name_t *cred_name,
+ OM_uint32 *initiator_lifetime,
+ OM_uint32 *acceptor_lifetime,
+ gss_cred_usage_t *cred_usage)
+{
+ OM_uint32 major_status;
+ gssapi_mech_interface m;
+ struct _gss_mechanism_cred *mcp;
+ gss_cred_id_t mc;
+ gss_name_t mn;
+ struct _gss_name *name;
+
+ *minor_status = 0;
+ if (cred_name)
+ *cred_name = GSS_C_NO_NAME;
+ if (initiator_lifetime)
+ *initiator_lifetime = 0;
+ if (acceptor_lifetime)
+ *acceptor_lifetime = 0;
+ if (cred_usage)
+ *cred_usage = 0;
+
+ m = __gss_get_mechanism(mech_type);
+ if (!m)
+ return (GSS_S_NO_CRED);
+
+ if (cred_handle != GSS_C_NO_CREDENTIAL) {
+ struct _gss_cred *cred = (struct _gss_cred *) cred_handle;
+ HEIM_SLIST_FOREACH(mcp, &cred->gc_mc, gmc_link)
+ if (mcp->gmc_mech == m)
+ break;
+ if (!mcp)
+ return (GSS_S_NO_CRED);
+ mc = mcp->gmc_cred;
+ } else {
+ mc = GSS_C_NO_CREDENTIAL;
+ }
+
+ major_status = m->gm_inquire_cred_by_mech(minor_status, mc, mech_type,
+ &mn, initiator_lifetime, acceptor_lifetime, cred_usage);
+ if (major_status != GSS_S_COMPLETE) {
+ _gss_mg_error(m, major_status, *minor_status);
+ return (major_status);
+ }
+
+ if (cred_name) {
+ name = _gss_make_name(m, mn);
+ if (!name) {
+ m->gm_release_name(minor_status, &mn);
+ return (GSS_S_NO_CRED);
+ }
+ *cred_name = (gss_name_t) name;
+ } else
+ m->gm_release_name(minor_status, &mn);
+
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c b/crypto/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c
new file mode 100644
index 0000000..e674dd4
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_cred_by_oid (OM_uint32 *minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ struct _gss_cred *cred = (struct _gss_cred *) cred_handle;
+ OM_uint32 status = GSS_S_COMPLETE;
+ struct _gss_mechanism_cred *mc;
+ gssapi_mech_interface m;
+ gss_buffer_set_t set = GSS_C_NO_BUFFER_SET;
+
+ *minor_status = 0;
+ *data_set = GSS_C_NO_BUFFER_SET;
+
+ if (cred == NULL)
+ return GSS_S_NO_CRED;
+
+ HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ gss_buffer_set_t rset = GSS_C_NO_BUFFER_SET;
+ size_t i;
+
+ m = mc->gmc_mech;
+ if (m == NULL) {
+ gss_release_buffer_set(minor_status, &set);
+ *minor_status = 0;
+ return GSS_S_BAD_MECH;
+ }
+
+ if (m->gm_inquire_cred_by_oid == NULL)
+ continue;
+
+ status = m->gm_inquire_cred_by_oid(minor_status,
+ mc->gmc_cred, desired_object, &rset);
+ if (status != GSS_S_COMPLETE)
+ continue;
+
+ for (i = 0; i < rset->count; i++) {
+ status = gss_add_buffer_set_member(minor_status,
+ &rset->elements[i], &set);
+ if (status != GSS_S_COMPLETE)
+ break;
+ }
+ gss_release_buffer_set(minor_status, &rset);
+ }
+ if (set == GSS_C_NO_BUFFER_SET)
+ status = GSS_S_FAILURE;
+ *data_set = set;
+ *minor_status = 0;
+ return status;
+}
+
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c b/crypto/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c
new file mode 100644
index 0000000..f8eab82
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_inquire_mechs_for_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_mechs_for_name(OM_uint32 *minor_status,
+ const gss_name_t input_name,
+ gss_OID_set *mech_types)
+{
+ OM_uint32 major_status;
+ struct _gss_name *name = (struct _gss_name *) input_name;
+ struct _gss_mech_switch *m;
+ gss_OID_set name_types;
+ int present;
+
+ *minor_status = 0;
+
+ _gss_load_mech();
+
+ major_status = gss_create_empty_oid_set(minor_status, mech_types);
+ if (major_status)
+ return (major_status);
+
+ /*
+ * We go through all the loaded mechanisms and see if this
+ * name's type is supported by the mechanism. If it is, add
+ * the mechanism to the set.
+ */
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ major_status = gss_inquire_names_for_mech(minor_status,
+ &m->gm_mech_oid, &name_types);
+ if (major_status) {
+ gss_release_oid_set(minor_status, mech_types);
+ return (major_status);
+ }
+ gss_test_oid_set_member(minor_status,
+ &name->gn_type, name_types, &present);
+ gss_release_oid_set(minor_status, &name_types);
+ if (present) {
+ major_status = gss_add_oid_set_member(minor_status,
+ &m->gm_mech_oid, mech_types);
+ if (major_status) {
+ gss_release_oid_set(minor_status, mech_types);
+ return (major_status);
+ }
+ }
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_inquire_name.c b/crypto/heimdal/lib/gssapi/mech/gss_inquire_name.c
new file mode 100644
index 0000000..10acaaa
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_inquire_name.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_name(OM_uint32 *minor_status,
+ gss_name_t input_name,
+ int *name_is_MN,
+ gss_OID *MN_mech,
+ gss_buffer_set_t *attrs)
+{
+ OM_uint32 major_status = GSS_S_UNAVAILABLE;
+ struct _gss_name *name = (struct _gss_name *) input_name;
+ struct _gss_mechanism_name *mn;
+
+ *minor_status = 0;
+ if (name_is_MN != NULL)
+ *name_is_MN = 0;
+ if (MN_mech != NULL)
+ *MN_mech = GSS_C_NO_OID;
+ if (attrs != NULL)
+ *attrs = GSS_C_NO_BUFFER_SET;
+
+ if (input_name == GSS_C_NO_NAME)
+ return GSS_S_BAD_NAME;
+
+ HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ gssapi_mech_interface m = mn->gmn_mech;
+
+ if (!m->gm_inquire_name)
+ continue;
+
+ major_status = m->gm_inquire_name(minor_status,
+ mn->gmn_name,
+ NULL,
+ MN_mech,
+ attrs);
+ if (major_status == GSS_S_COMPLETE) {
+ if (name_is_MN != NULL)
+ *name_is_MN = 1;
+ if (MN_mech != NULL && *MN_mech == GSS_C_NO_OID)
+ *MN_mech = &m->gm_mech_oid;
+ break;
+ }
+ _gss_mg_error(m, major_status, *minor_status);
+ }
+
+ return major_status;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c b/crypto/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c
new file mode 100644
index 0000000..595ab73
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_inquire_names_for_mech.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_names_for_mech(OM_uint32 *minor_status,
+ const gss_OID mechanism,
+ gss_OID_set *name_types)
+{
+ OM_uint32 major_status;
+ gssapi_mech_interface m = __gss_get_mechanism(mechanism);
+
+ *minor_status = 0;
+ *name_types = GSS_C_NO_OID_SET;
+ if (!m)
+ return (GSS_S_BAD_MECH);
+
+ /*
+ * If the implementation can do it, ask it for a list of
+ * names, otherwise fake it.
+ */
+ if (m->gm_inquire_names_for_mech) {
+ return (m->gm_inquire_names_for_mech(minor_status,
+ mechanism, name_types));
+ } else {
+ major_status = gss_create_empty_oid_set(minor_status,
+ name_types);
+ if (major_status)
+ return (major_status);
+ major_status = gss_add_oid_set_member(minor_status,
+ GSS_C_NT_HOSTBASED_SERVICE, name_types);
+ if (major_status) {
+ OM_uint32 junk;
+ gss_release_oid_set(&junk, name_types);
+ return (major_status);
+ }
+ major_status = gss_add_oid_set_member(minor_status,
+ GSS_C_NT_USER_NAME, name_types);
+ if (major_status) {
+ OM_uint32 junk;
+ gss_release_oid_set(&junk, name_types);
+ return (major_status);
+ }
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c b/crypto/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c
new file mode 100644
index 0000000..cc6e5c9
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ OM_uint32 major_status;
+ gssapi_mech_interface m;
+
+ *minor_status = 0;
+ *data_set = GSS_C_NO_BUFFER_SET;
+ if (ctx == NULL)
+ return GSS_S_NO_CONTEXT;
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ m = ctx->gc_mech;
+
+ if (m == NULL)
+ return GSS_S_BAD_MECH;
+
+ if (m->gm_inquire_sec_context_by_oid != NULL) {
+ major_status = m->gm_inquire_sec_context_by_oid(minor_status,
+ ctx->gc_ctx, desired_object, data_set);
+ if (major_status != GSS_S_COMPLETE)
+ _gss_mg_error(m, major_status, *minor_status);
+ } else
+ major_status = GSS_S_BAD_MECH;
+
+ return major_status;
+}
+
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_krb5.c b/crypto/heimdal/lib/gssapi/mech/gss_krb5.c
new file mode 100644
index 0000000..fe88a38
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_krb5.c
@@ -0,0 +1,941 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_krb5.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+#include <krb5.h>
+#include <roken.h>
+
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_krb5_copy_ccache(OM_uint32 *minor_status,
+ gss_cred_id_t cred,
+ krb5_ccache out)
+{
+ gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
+ krb5_context context;
+ krb5_error_code kret;
+ krb5_ccache id;
+ OM_uint32 ret;
+ char *str = NULL;
+
+ ret = gss_inquire_cred_by_oid(minor_status,
+ cred,
+ GSS_KRB5_COPY_CCACHE_X,
+ &data_set);
+ if (ret)
+ return ret;
+
+ if (data_set == GSS_C_NO_BUFFER_SET || data_set->count < 1) {
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_init_context(&context);
+ if (kret) {
+ *minor_status = kret;
+ gss_release_buffer_set(minor_status, &data_set);
+ return GSS_S_FAILURE;
+ }
+
+ kret = asprintf(&str, "%.*s", (int)data_set->elements[0].length,
+ (char *)data_set->elements[0].value);
+ gss_release_buffer_set(minor_status, &data_set);
+ if (kret < 0 || str == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_cc_resolve(context, str, &id);
+ free(str);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ kret = krb5_cc_copy_cache(context, id, out);
+ krb5_cc_close(context, id);
+ krb5_free_context(context);
+ if (kret) {
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ return ret;
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_krb5_import_cred(OM_uint32 *minor_status,
+ krb5_ccache id,
+ krb5_principal keytab_principal,
+ krb5_keytab keytab,
+ gss_cred_id_t *cred)
+{
+ gss_buffer_desc buffer;
+ OM_uint32 major_status;
+ krb5_context context;
+ krb5_error_code ret;
+ krb5_storage *sp;
+ krb5_data data;
+ char *str;
+
+ *cred = GSS_C_NO_CREDENTIAL;
+
+ ret = krb5_init_context(&context);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ major_status = GSS_S_FAILURE;
+ goto out;
+ }
+
+ if (id) {
+ ret = krb5_cc_get_full_name(context, id, &str);
+ if (ret == 0) {
+ ret = krb5_store_string(sp, str);
+ free(str);
+ }
+ } else
+ ret = krb5_store_string(sp, "");
+ if (ret) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto out;
+ }
+
+ if (keytab_principal) {
+ ret = krb5_unparse_name(context, keytab_principal, &str);
+ if (ret == 0) {
+ ret = krb5_store_string(sp, str);
+ free(str);
+ }
+ } else
+ krb5_store_string(sp, "");
+ if (ret) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto out;
+ }
+
+
+ if (keytab) {
+ ret = krb5_kt_get_full_name(context, keytab, &str);
+ if (ret == 0) {
+ ret = krb5_store_string(sp, str);
+ free(str);
+ }
+ } else
+ krb5_store_string(sp, "");
+ if (ret) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto out;
+ }
+
+ ret = krb5_storage_to_data(sp, &data);
+ if (ret) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto out;
+ }
+
+ buffer.value = data.data;
+ buffer.length = data.length;
+
+ major_status = gss_set_cred_option(minor_status,
+ cred,
+ GSS_KRB5_IMPORT_CRED_X,
+ &buffer);
+ krb5_data_free(&data);
+out:
+ if (sp)
+ krb5_storage_free(sp);
+ krb5_free_context(context);
+ return major_status;
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_register_acceptor_identity(const char *identity)
+{
+ gssapi_mech_interface m;
+ gss_buffer_desc buffer;
+ OM_uint32 junk;
+
+ _gss_load_mech();
+
+ buffer.value = rk_UNCONST(identity);
+ buffer.length = strlen(identity);
+
+ m = __gss_get_mechanism(GSS_KRB5_MECHANISM);
+ if (m == NULL || m->gm_set_sec_context_option == NULL)
+ return GSS_S_FAILURE;
+
+ return m->gm_set_sec_context_option(&junk, NULL,
+ GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X, &buffer);
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+krb5_gss_register_acceptor_identity(const char *identity)
+{
+ return gsskrb5_register_acceptor_identity(identity);
+}
+
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_set_dns_canonicalize(int flag)
+{
+ struct _gss_mech_switch *m;
+ gss_buffer_desc buffer;
+ OM_uint32 junk;
+ char b = (flag != 0);
+
+ _gss_load_mech();
+
+ buffer.value = &b;
+ buffer.length = sizeof(b);
+
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ if (m->gm_mech.gm_set_sec_context_option == NULL)
+ continue;
+ m->gm_mech.gm_set_sec_context_option(&junk, NULL,
+ GSS_KRB5_SET_DNS_CANONICALIZE_X, &buffer);
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+
+
+static krb5_error_code
+set_key(krb5_keyblock *keyblock, gss_krb5_lucid_key_t *key)
+{
+ key->type = keyblock->keytype;
+ key->length = keyblock->keyvalue.length;
+ key->data = malloc(key->length);
+ if (key->data == NULL && key->length != 0)
+ return ENOMEM;
+ memcpy(key->data, keyblock->keyvalue.data, key->length);
+ return 0;
+}
+
+static void
+free_key(gss_krb5_lucid_key_t *key)
+{
+ memset(key->data, 0, key->length);
+ free(key->data);
+ memset(key, 0, sizeof(*key));
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ OM_uint32 version,
+ void **rctx)
+{
+ krb5_context context = NULL;
+ krb5_error_code ret;
+ gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
+ OM_uint32 major_status;
+ gss_krb5_lucid_context_v1_t *ctx = NULL;
+ krb5_storage *sp = NULL;
+ uint32_t num;
+
+ if (context_handle == NULL
+ || *context_handle == GSS_C_NO_CONTEXT
+ || version != 1)
+ {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ major_status =
+ gss_inquire_sec_context_by_oid (minor_status,
+ *context_handle,
+ GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X,
+ &data_set);
+ if (major_status)
+ return major_status;
+
+ if (data_set == GSS_C_NO_BUFFER_SET || data_set->count != 1) {
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_init_context(&context);
+ if (ret)
+ goto out;
+
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ sp = krb5_storage_from_mem(data_set->elements[0].value,
+ data_set->elements[0].length);
+ if (sp == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ret = krb5_ret_uint32(sp, &num);
+ if (ret) goto out;
+ if (num != 1) {
+ ret = EINVAL;
+ goto out;
+ }
+ ctx->version = 1;
+ /* initiator */
+ ret = krb5_ret_uint32(sp, &ctx->initiate);
+ if (ret) goto out;
+ /* endtime */
+ ret = krb5_ret_uint32(sp, &ctx->endtime);
+ if (ret) goto out;
+ /* send_seq */
+ ret = krb5_ret_uint32(sp, &num);
+ if (ret) goto out;
+ ctx->send_seq = ((uint64_t)num) << 32;
+ ret = krb5_ret_uint32(sp, &num);
+ if (ret) goto out;
+ ctx->send_seq |= num;
+ /* recv_seq */
+ ret = krb5_ret_uint32(sp, &num);
+ if (ret) goto out;
+ ctx->recv_seq = ((uint64_t)num) << 32;
+ ret = krb5_ret_uint32(sp, &num);
+ if (ret) goto out;
+ ctx->recv_seq |= num;
+ /* protocol */
+ ret = krb5_ret_uint32(sp, &ctx->protocol);
+ if (ret) goto out;
+ if (ctx->protocol == 0) {
+ krb5_keyblock key;
+
+ /* sign_alg */
+ ret = krb5_ret_uint32(sp, &ctx->rfc1964_kd.sign_alg);
+ if (ret) goto out;
+ /* seal_alg */
+ ret = krb5_ret_uint32(sp, &ctx->rfc1964_kd.seal_alg);
+ if (ret) goto out;
+ /* ctx_key */
+ ret = krb5_ret_keyblock(sp, &key);
+ if (ret) goto out;
+ ret = set_key(&key, &ctx->rfc1964_kd.ctx_key);
+ krb5_free_keyblock_contents(context, &key);
+ if (ret) goto out;
+ } else if (ctx->protocol == 1) {
+ krb5_keyblock key;
+
+ /* acceptor_subkey */
+ ret = krb5_ret_uint32(sp, &ctx->cfx_kd.have_acceptor_subkey);
+ if (ret) goto out;
+ /* ctx_key */
+ ret = krb5_ret_keyblock(sp, &key);
+ if (ret) goto out;
+ ret = set_key(&key, &ctx->cfx_kd.ctx_key);
+ krb5_free_keyblock_contents(context, &key);
+ if (ret) goto out;
+ /* acceptor_subkey */
+ if (ctx->cfx_kd.have_acceptor_subkey) {
+ ret = krb5_ret_keyblock(sp, &key);
+ if (ret) goto out;
+ ret = set_key(&key, &ctx->cfx_kd.acceptor_subkey);
+ krb5_free_keyblock_contents(context, &key);
+ if (ret) goto out;
+ }
+ } else {
+ ret = EINVAL;
+ goto out;
+ }
+
+ *rctx = ctx;
+
+out:
+ gss_release_buffer_set(minor_status, &data_set);
+ if (sp)
+ krb5_storage_free(sp);
+ if (context)
+ krb5_free_context(context);
+
+ if (ret) {
+ if (ctx)
+ gss_krb5_free_lucid_sec_context(NULL, ctx);
+
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *c)
+{
+ gss_krb5_lucid_context_v1_t *ctx = c;
+
+ if (ctx->version != 1) {
+ if (minor_status)
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+
+ if (ctx->protocol == 0) {
+ free_key(&ctx->rfc1964_kd.ctx_key);
+ } else if (ctx->protocol == 1) {
+ free_key(&ctx->cfx_kd.ctx_key);
+ if (ctx->cfx_kd.have_acceptor_subkey)
+ free_key(&ctx->cfx_kd.acceptor_subkey);
+ }
+ free(ctx);
+ if (minor_status)
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+/*
+ *
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status,
+ gss_cred_id_t cred,
+ OM_uint32 num_enctypes,
+ int32_t *enctypes)
+{
+ krb5_error_code ret;
+ OM_uint32 maj_status;
+ gss_buffer_desc buffer;
+ krb5_storage *sp;
+ krb5_data data;
+ size_t i;
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ *minor_status = ENOMEM;
+ maj_status = GSS_S_FAILURE;
+ goto out;
+ }
+
+ for (i = 0; i < num_enctypes; i++) {
+ ret = krb5_store_int32(sp, enctypes[i]);
+ if (ret) {
+ *minor_status = ret;
+ maj_status = GSS_S_FAILURE;
+ goto out;
+ }
+ }
+
+ ret = krb5_storage_to_data(sp, &data);
+ if (ret) {
+ *minor_status = ret;
+ maj_status = GSS_S_FAILURE;
+ goto out;
+ }
+
+ buffer.value = data.data;
+ buffer.length = data.length;
+
+ maj_status = gss_set_cred_option(minor_status,
+ &cred,
+ GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X,
+ &buffer);
+ krb5_data_free(&data);
+out:
+ if (sp)
+ krb5_storage_free(sp);
+ return maj_status;
+}
+
+/*
+ *
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *c)
+{
+ struct _gss_mech_switch *m;
+ gss_buffer_desc buffer;
+ OM_uint32 junk;
+
+ _gss_load_mech();
+
+ if (c) {
+ buffer.value = c;
+ buffer.length = sizeof(*c);
+ } else {
+ buffer.value = NULL;
+ buffer.length = 0;
+ }
+
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ if (m->gm_mech.gm_set_sec_context_option == NULL)
+ continue;
+ m->gm_mech.gm_set_sec_context_option(&junk, NULL,
+ GSS_KRB5_SEND_TO_KDC_X, &buffer);
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+/*
+ *
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_krb5_ccache_name(OM_uint32 *minor_status,
+ const char *name,
+ const char **out_name)
+{
+ struct _gss_mech_switch *m;
+ gss_buffer_desc buffer;
+ OM_uint32 junk;
+
+ _gss_load_mech();
+
+ if (out_name)
+ *out_name = NULL;
+
+ buffer.value = rk_UNCONST(name);
+ buffer.length = strlen(name);
+
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ if (m->gm_mech.gm_set_sec_context_option == NULL)
+ continue;
+ m->gm_mech.gm_set_sec_context_option(&junk, NULL,
+ GSS_KRB5_CCACHE_NAME_X, &buffer);
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+
+/*
+ *
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ time_t *authtime)
+{
+ gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
+ OM_uint32 maj_stat;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ maj_stat =
+ gss_inquire_sec_context_by_oid (minor_status,
+ context_handle,
+ GSS_KRB5_GET_AUTHTIME_X,
+ &data_set);
+ if (maj_stat)
+ return maj_stat;
+
+ if (data_set == GSS_C_NO_BUFFER_SET) {
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (data_set->count != 1) {
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (data_set->elements[0].length != 4) {
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ {
+ unsigned char *buf = data_set->elements[0].value;
+ *authtime = (buf[3] <<24) | (buf[2] << 16) |
+ (buf[1] << 8) | (buf[0] << 0);
+ }
+
+ gss_release_buffer_set(minor_status, &data_set);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+/*
+ *
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int ad_type,
+ gss_buffer_t ad_data)
+{
+ gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
+ OM_uint32 maj_stat;
+ gss_OID_desc oid_flat;
+ heim_oid baseoid, oid;
+ size_t size;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ /* All this to append an integer to an oid... */
+
+ if (der_get_oid(GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X->elements,
+ GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X->length,
+ &baseoid, NULL) != 0) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ oid.length = baseoid.length + 1;
+ oid.components = calloc(oid.length, sizeof(*oid.components));
+ if (oid.components == NULL) {
+ der_free_oid(&baseoid);
+
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ memcpy(oid.components, baseoid.components,
+ baseoid.length * sizeof(*baseoid.components));
+
+ der_free_oid(&baseoid);
+
+ oid.components[oid.length - 1] = ad_type;
+
+ oid_flat.length = der_length_oid(&oid);
+ oid_flat.elements = malloc(oid_flat.length);
+ if (oid_flat.elements == NULL) {
+ free(oid.components);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ if (der_put_oid((unsigned char *)oid_flat.elements + oid_flat.length - 1,
+ oid_flat.length, &oid, &size) != 0) {
+ free(oid.components);
+ free(oid_flat.elements);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ if (oid_flat.length != size)
+ abort();
+
+ free(oid.components);
+
+ /* FINALLY, we have the OID */
+
+ maj_stat = gss_inquire_sec_context_by_oid (minor_status,
+ context_handle,
+ &oid_flat,
+ &data_set);
+
+ free(oid_flat.elements);
+
+ if (maj_stat)
+ return maj_stat;
+
+ if (data_set == GSS_C_NO_BUFFER_SET || data_set->count != 1) {
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ ad_data->value = malloc(data_set->elements[0].length);
+ if (ad_data->value == NULL) {
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ ad_data->length = data_set->elements[0].length;
+ memcpy(ad_data->value, data_set->elements[0].value, ad_data->length);
+ gss_release_buffer_set(minor_status, &data_set);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+/*
+ *
+ */
+
+static OM_uint32
+gsskrb5_extract_key(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ const gss_OID oid,
+ krb5_keyblock **keyblock)
+{
+ krb5_error_code ret;
+ gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
+ OM_uint32 major_status;
+ krb5_context context = NULL;
+ krb5_storage *sp = NULL;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_init_context(&context);
+ if(ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ major_status =
+ gss_inquire_sec_context_by_oid (minor_status,
+ context_handle,
+ oid,
+ &data_set);
+ if (major_status)
+ return major_status;
+
+ if (data_set == GSS_C_NO_BUFFER_SET || data_set->count != 1) {
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ sp = krb5_storage_from_mem(data_set->elements[0].value,
+ data_set->elements[0].length);
+ if (sp == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ *keyblock = calloc(1, sizeof(**keyblock));
+ if (keyblock == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ret = krb5_ret_keyblock(sp, *keyblock);
+
+out:
+ gss_release_buffer_set(minor_status, &data_set);
+ if (sp)
+ krb5_storage_free(sp);
+ if (ret && keyblock) {
+ krb5_free_keyblock(context, *keyblock);
+ *keyblock = NULL;
+ }
+ if (context)
+ krb5_free_context(context);
+
+ *minor_status = ret;
+ if (ret)
+ return GSS_S_FAILURE;
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ *
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_extract_service_keyblock(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ krb5_keyblock **keyblock)
+{
+ return gsskrb5_extract_key(minor_status,
+ context_handle,
+ GSS_KRB5_GET_SERVICE_KEYBLOCK_X,
+ keyblock);
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_get_initiator_subkey(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ krb5_keyblock **keyblock)
+{
+ return gsskrb5_extract_key(minor_status,
+ context_handle,
+ GSS_KRB5_GET_INITIATOR_SUBKEY_X,
+ keyblock);
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_get_subkey(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ krb5_keyblock **keyblock)
+{
+ return gsskrb5_extract_key(minor_status,
+ context_handle,
+ GSS_KRB5_GET_SUBKEY_X,
+ keyblock);
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_set_default_realm(const char *realm)
+{
+ struct _gss_mech_switch *m;
+ gss_buffer_desc buffer;
+ OM_uint32 junk;
+
+ _gss_load_mech();
+
+ buffer.value = rk_UNCONST(realm);
+ buffer.length = strlen(realm);
+
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ if (m->gm_mech.gm_set_sec_context_option == NULL)
+ continue;
+ m->gm_mech.gm_set_sec_context_option(&junk, NULL,
+ GSS_KRB5_SET_DEFAULT_REALM_X, &buffer);
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_krb5_get_tkt_flags(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ OM_uint32 *tkt_flags)
+{
+
+ OM_uint32 major_status;
+ gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ major_status =
+ gss_inquire_sec_context_by_oid (minor_status,
+ context_handle,
+ GSS_KRB5_GET_TKT_FLAGS_X,
+ &data_set);
+ if (major_status)
+ return major_status;
+
+ if (data_set == GSS_C_NO_BUFFER_SET ||
+ data_set->count != 1 ||
+ data_set->elements[0].length < 4) {
+ gss_release_buffer_set(minor_status, &data_set);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ {
+ const u_char *p = data_set->elements[0].value;
+ *tkt_flags = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+ }
+
+ gss_release_buffer_set(minor_status, &data_set);
+ return GSS_S_COMPLETE;
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_set_time_offset(int offset)
+{
+ struct _gss_mech_switch *m;
+ gss_buffer_desc buffer;
+ OM_uint32 junk;
+ int32_t o = offset;
+
+ _gss_load_mech();
+
+ buffer.value = &o;
+ buffer.length = sizeof(o);
+
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ if (m->gm_mech.gm_set_sec_context_option == NULL)
+ continue;
+ m->gm_mech.gm_set_sec_context_option(&junk, NULL,
+ GSS_KRB5_SET_TIME_OFFSET_X, &buffer);
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_get_time_offset(int *offset)
+{
+ struct _gss_mech_switch *m;
+ gss_buffer_desc buffer;
+ OM_uint32 maj_stat, junk;
+ int32_t o;
+
+ _gss_load_mech();
+
+ buffer.value = &o;
+ buffer.length = sizeof(o);
+
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ if (m->gm_mech.gm_set_sec_context_option == NULL)
+ continue;
+ maj_stat = m->gm_mech.gm_set_sec_context_option(&junk, NULL,
+ GSS_KRB5_GET_TIME_OFFSET_X, &buffer);
+
+ if (maj_stat == GSS_S_COMPLETE) {
+ *offset = o;
+ return maj_stat;
+ }
+ }
+
+ return (GSS_S_UNAVAILABLE);
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gsskrb5_plugin_register(struct gsskrb5_krb5_plugin *c)
+{
+ struct _gss_mech_switch *m;
+ gss_buffer_desc buffer;
+ OM_uint32 junk;
+
+ _gss_load_mech();
+
+ buffer.value = c;
+ buffer.length = sizeof(*c);
+
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ if (m->gm_mech.gm_set_sec_context_option == NULL)
+ continue;
+ m->gm_mech.gm_set_sec_context_option(&junk, NULL,
+ GSS_KRB5_PLUGIN_REGISTER_X, &buffer);
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_mech_switch.c b/crypto/heimdal/lib/gssapi/mech/gss_mech_switch.c
new file mode 100644
index 0000000..55e0109
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_mech_switch.c
@@ -0,0 +1,438 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_mech_switch.c,v 1.2 2006/02/04 09:40:21 dfr Exp $
+ */
+
+#include "mech_locl.h"
+#include <heim_threads.h>
+
+#ifndef _PATH_GSS_MECH
+#define _PATH_GSS_MECH "/etc/gss/mech"
+#endif
+
+struct _gss_mech_switch_list _gss_mechs = { NULL } ;
+gss_OID_set _gss_mech_oids;
+static HEIMDAL_MUTEX _gss_mech_mutex = HEIMDAL_MUTEX_INITIALIZER;
+
+/*
+ * Convert a string containing an OID in 'dot' form
+ * (e.g. 1.2.840.113554.1.2.2) to a gss_OID.
+ */
+static int
+_gss_string_to_oid(const char* s, gss_OID oid)
+{
+ int number_count, i, j;
+ size_t byte_count;
+ const char *p, *q;
+ char *res;
+
+ oid->length = 0;
+ oid->elements = NULL;
+
+ /*
+ * First figure out how many numbers in the oid, then
+ * calculate the compiled oid size.
+ */
+ number_count = 0;
+ for (p = s; p; p = q) {
+ q = strchr(p, '.');
+ if (q) q = q + 1;
+ number_count++;
+ }
+
+ /*
+ * The first two numbers are in the first byte and each
+ * subsequent number is encoded in a variable byte sequence.
+ */
+ if (number_count < 2)
+ return (EINVAL);
+
+ /*
+ * We do this in two passes. The first pass, we just figure
+ * out the size. Second time around, we actually encode the
+ * number.
+ */
+ res = 0;
+ for (i = 0; i < 2; i++) {
+ byte_count = 0;
+ for (p = s, j = 0; p; p = q, j++) {
+ unsigned int number = 0;
+
+ /*
+ * Find the end of this number.
+ */
+ q = strchr(p, '.');
+ if (q) q = q + 1;
+
+ /*
+ * Read the number of of the string. Don't
+ * bother with anything except base ten.
+ */
+ while (*p && *p != '.') {
+ number = 10 * number + (*p - '0');
+ p++;
+ }
+
+ /*
+ * Encode the number. The first two numbers
+ * are packed into the first byte. Subsequent
+ * numbers are encoded in bytes seven bits at
+ * a time with the last byte having the high
+ * bit set.
+ */
+ if (j == 0) {
+ if (res)
+ *res = number * 40;
+ } else if (j == 1) {
+ if (res) {
+ *res += number;
+ res++;
+ }
+ byte_count++;
+ } else if (j >= 2) {
+ /*
+ * The number is encoded in seven bit chunks.
+ */
+ unsigned int t;
+ unsigned int bytes;
+
+ bytes = 0;
+ for (t = number; t; t >>= 7)
+ bytes++;
+ if (bytes == 0) bytes = 1;
+ while (bytes) {
+ if (res) {
+ int bit = 7*(bytes-1);
+
+ *res = (number >> bit) & 0x7f;
+ if (bytes != 1)
+ *res |= 0x80;
+ res++;
+ }
+ byte_count++;
+ bytes--;
+ }
+ }
+ }
+ if (!res) {
+ res = malloc(byte_count);
+ if (!res)
+ return (ENOMEM);
+ oid->length = byte_count;
+ oid->elements = res;
+ }
+ }
+
+ return (0);
+}
+
+#define SYM(name) \
+do { \
+ m->gm_mech.gm_ ## name = dlsym(so, "gss_" #name); \
+ if (!m->gm_mech.gm_ ## name || \
+ m->gm_mech.gm_ ##name == gss_ ## name) { \
+ fprintf(stderr, "can't find symbol gss_" #name "\n"); \
+ goto bad; \
+ } \
+} while (0)
+
+#define OPTSYM(name) \
+do { \
+ m->gm_mech.gm_ ## name = dlsym(so, "gss_" #name); \
+ if (m->gm_mech.gm_ ## name == gss_ ## name) \
+ m->gm_mech.gm_ ## name = NULL; \
+} while (0)
+
+#define OPTSPISYM(name) \
+do { \
+ m->gm_mech.gm_ ## name = dlsym(so, "gssspi_" #name); \
+} while (0)
+
+#define COMPATSYM(name) \
+do { \
+ m->gm_mech.gm_compat->gmc_ ## name = dlsym(so, "gss_" #name); \
+ if (m->gm_mech.gm_compat->gmc_ ## name == gss_ ## name) \
+ m->gm_mech.gm_compat->gmc_ ## name = NULL; \
+} while (0)
+
+#define COMPATSPISYM(name) \
+do { \
+ m->gm_mech.gm_compat->gmc_ ## name = dlsym(so, "gssspi_" #name);\
+ if (m->gm_mech.gm_compat->gmc_ ## name == gss_ ## name) \
+ m->gm_mech.gm_compat->gmc_ ## name = NULL; \
+} while (0)
+
+/*
+ *
+ */
+static int
+add_builtin(gssapi_mech_interface mech)
+{
+ struct _gss_mech_switch *m;
+ OM_uint32 minor_status;
+
+ /* not registering any mech is ok */
+ if (mech == NULL)
+ return 0;
+
+ m = calloc(1, sizeof(*m));
+ if (m == NULL)
+ return ENOMEM;
+ m->gm_so = NULL;
+ m->gm_mech = *mech;
+ m->gm_mech_oid = mech->gm_mech_oid; /* XXX */
+ gss_add_oid_set_member(&minor_status,
+ &m->gm_mech.gm_mech_oid, &_gss_mech_oids);
+
+ /* pick up the oid sets of names */
+
+ if (m->gm_mech.gm_inquire_names_for_mech)
+ (*m->gm_mech.gm_inquire_names_for_mech)(&minor_status,
+ &m->gm_mech.gm_mech_oid, &m->gm_name_types);
+
+ if (m->gm_name_types == NULL)
+ gss_create_empty_oid_set(&minor_status, &m->gm_name_types);
+
+ HEIM_SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link);
+ return 0;
+}
+
+/*
+ * Load the mechanisms file (/etc/gss/mech).
+ */
+void
+_gss_load_mech(void)
+{
+ OM_uint32 major_status, minor_status;
+ FILE *fp;
+ char buf[256];
+ char *p;
+ char *name, *oid, *lib, *kobj;
+ struct _gss_mech_switch *m;
+ void *so;
+ gss_OID_desc mech_oid;
+ int found;
+
+
+ HEIMDAL_MUTEX_lock(&_gss_mech_mutex);
+
+ if (HEIM_SLIST_FIRST(&_gss_mechs)) {
+ HEIMDAL_MUTEX_unlock(&_gss_mech_mutex);
+ return;
+ }
+
+ major_status = gss_create_empty_oid_set(&minor_status,
+ &_gss_mech_oids);
+ if (major_status) {
+ HEIMDAL_MUTEX_unlock(&_gss_mech_mutex);
+ return;
+ }
+
+ add_builtin(__gss_krb5_initialize());
+ add_builtin(__gss_spnego_initialize());
+ add_builtin(__gss_ntlm_initialize());
+
+#ifdef HAVE_DLOPEN
+ fp = fopen(_PATH_GSS_MECH, "r");
+ if (!fp) {
+ HEIMDAL_MUTEX_unlock(&_gss_mech_mutex);
+ return;
+ }
+ rk_cloexec_file(fp);
+
+ while (fgets(buf, sizeof(buf), fp)) {
+ _gss_mo_init *mi;
+
+ if (*buf == '#')
+ continue;
+ p = buf;
+ name = strsep(&p, "\t\n ");
+ if (p) while (isspace((unsigned char)*p)) p++;
+ oid = strsep(&p, "\t\n ");
+ if (p) while (isspace((unsigned char)*p)) p++;
+ lib = strsep(&p, "\t\n ");
+ if (p) while (isspace((unsigned char)*p)) p++;
+ kobj = strsep(&p, "\t\n ");
+ if (!name || !oid || !lib || !kobj)
+ continue;
+
+ if (_gss_string_to_oid(oid, &mech_oid))
+ continue;
+
+ /*
+ * Check for duplicates, already loaded mechs.
+ */
+ found = 0;
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ if (gss_oid_equal(&m->gm_mech.gm_mech_oid, &mech_oid)) {
+ found = 1;
+ free(mech_oid.elements);
+ break;
+ }
+ }
+ if (found)
+ continue;
+
+#ifndef RTLD_LOCAL
+#define RTLD_LOCAL 0
+#endif
+
+#ifndef RTLD_GROUP
+#define RTLD_GROUP 0
+#endif
+
+ so = dlopen(lib, RTLD_LAZY | RTLD_LOCAL | RTLD_GROUP);
+ if (so == NULL) {
+/* fprintf(stderr, "dlopen: %s\n", dlerror()); */
+ goto bad;
+ }
+
+ m = calloc(1, sizeof(*m));
+ if (m == NULL)
+ goto bad;
+
+ m->gm_so = so;
+ m->gm_mech.gm_mech_oid = mech_oid;
+ m->gm_mech.gm_flags = 0;
+ m->gm_mech.gm_compat = calloc(1, sizeof(struct gss_mech_compat_desc_struct));
+ if (m->gm_mech.gm_compat == NULL)
+ goto bad;
+
+ major_status = gss_add_oid_set_member(&minor_status,
+ &m->gm_mech.gm_mech_oid, &_gss_mech_oids);
+ if (GSS_ERROR(major_status))
+ goto bad;
+
+ SYM(acquire_cred);
+ SYM(release_cred);
+ SYM(init_sec_context);
+ SYM(accept_sec_context);
+ SYM(process_context_token);
+ SYM(delete_sec_context);
+ SYM(context_time);
+ SYM(get_mic);
+ SYM(verify_mic);
+ SYM(wrap);
+ SYM(unwrap);
+ SYM(display_status);
+ SYM(indicate_mechs);
+ SYM(compare_name);
+ SYM(display_name);
+ SYM(import_name);
+ SYM(export_name);
+ SYM(release_name);
+ SYM(inquire_cred);
+ SYM(inquire_context);
+ SYM(wrap_size_limit);
+ SYM(add_cred);
+ SYM(inquire_cred_by_mech);
+ SYM(export_sec_context);
+ SYM(import_sec_context);
+ SYM(inquire_names_for_mech);
+ SYM(inquire_mechs_for_name);
+ SYM(canonicalize_name);
+ SYM(duplicate_name);
+ OPTSYM(inquire_cred_by_oid);
+ OPTSYM(inquire_sec_context_by_oid);
+ OPTSYM(set_sec_context_option);
+ OPTSPISYM(set_cred_option);
+ OPTSYM(pseudo_random);
+ OPTSYM(wrap_iov);
+ OPTSYM(unwrap_iov);
+ OPTSYM(wrap_iov_length);
+ OPTSYM(store_cred);
+ OPTSYM(export_cred);
+ OPTSYM(import_cred);
+#if 0
+ OPTSYM(acquire_cred_ext);
+ OPTSYM(iter_creds);
+ OPTSYM(destroy_cred);
+ OPTSYM(cred_hold);
+ OPTSYM(cred_unhold);
+ OPTSYM(cred_label_get);
+ OPTSYM(cred_label_set);
+#endif
+ OPTSYM(display_name_ext);
+ OPTSYM(inquire_name);
+ OPTSYM(get_name_attribute);
+ OPTSYM(set_name_attribute);
+ OPTSYM(delete_name_attribute);
+ OPTSYM(export_name_composite);
+ OPTSYM(pname_to_uid);
+ OPTSPISYM(authorize_localname);
+
+ mi = dlsym(so, "gss_mo_init");
+ if (mi != NULL) {
+ major_status = mi(&minor_status, &mech_oid,
+ &m->gm_mech.gm_mo, &m->gm_mech.gm_mo_num);
+ if (GSS_ERROR(major_status))
+ goto bad;
+ } else {
+ /* API-as-SPI compatibility */
+ COMPATSYM(inquire_saslname_for_mech);
+ COMPATSYM(inquire_mech_for_saslname);
+ COMPATSYM(inquire_attrs_for_mech);
+ COMPATSPISYM(acquire_cred_with_password);
+ }
+
+ /* pick up the oid sets of names */
+
+ if (m->gm_mech.gm_inquire_names_for_mech)
+ (*m->gm_mech.gm_inquire_names_for_mech)(&minor_status,
+ &m->gm_mech.gm_mech_oid, &m->gm_name_types);
+
+ if (m->gm_name_types == NULL)
+ gss_create_empty_oid_set(&minor_status, &m->gm_name_types);
+
+ HEIM_SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link);
+ continue;
+
+ bad:
+ if (m != NULL) {
+ free(m->gm_mech.gm_compat);
+ free(m->gm_mech.gm_mech_oid.elements);
+ free(m);
+ }
+ dlclose(so);
+ continue;
+ }
+ fclose(fp);
+#endif
+ HEIMDAL_MUTEX_unlock(&_gss_mech_mutex);
+}
+
+gssapi_mech_interface
+__gss_get_mechanism(gss_const_OID mech)
+{
+ struct _gss_mech_switch *m;
+
+ _gss_load_mech();
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech))
+ return &m->gm_mech;
+ }
+ return NULL;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_mo.c b/crypto/heimdal/lib/gssapi/mech/gss_mo.c
new file mode 100644
index 0000000..ad74d92
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_mo.c
@@ -0,0 +1,635 @@
+/*
+ * Copyright (c) 2010 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
+ * Portions Copyright (c) 2010 PADL Software Pty Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "mech_locl.h"
+
+#include <crypto-headers.h>
+
+static int
+get_option_def(int def, gss_const_OID mech, gss_mo_desc *mo, gss_buffer_t value)
+{
+ return def;
+}
+
+int
+_gss_mo_get_option_1(gss_const_OID mech, gss_mo_desc *mo, gss_buffer_t value)
+{
+ return get_option_def(1, mech, mo, value);
+}
+
+int
+_gss_mo_get_option_0(gss_const_OID mech, gss_mo_desc *mo, gss_buffer_t value)
+{
+ return get_option_def(0, mech, mo, value);
+}
+
+int
+_gss_mo_get_ctx_as_string(gss_const_OID mech, gss_mo_desc *mo, gss_buffer_t value)
+{
+ if (value) {
+ value->value = strdup((char *)mo->ctx);
+ if (value->value == NULL)
+ return GSS_S_FAILURE;
+ value->length = strlen((char *)mo->ctx);
+ }
+ return GSS_S_COMPLETE;
+}
+
+GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL
+gss_mo_set(gss_const_OID mech, gss_const_OID option,
+ int enable, gss_buffer_t value)
+{
+ gssapi_mech_interface m;
+ size_t n;
+
+ if ((m = __gss_get_mechanism(mech)) == NULL)
+ return GSS_S_BAD_MECH;
+
+ for (n = 0; n < m->gm_mo_num; n++)
+ if (gss_oid_equal(option, m->gm_mo[n].option) && m->gm_mo[n].set)
+ return m->gm_mo[n].set(mech, &m->gm_mo[n], enable, value);
+
+ return GSS_S_UNAVAILABLE;
+}
+
+GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL
+gss_mo_get(gss_const_OID mech, gss_const_OID option, gss_buffer_t value)
+{
+ gssapi_mech_interface m;
+ size_t n;
+
+ _mg_buffer_zero(value);
+
+ if ((m = __gss_get_mechanism(mech)) == NULL)
+ return GSS_S_BAD_MECH;
+
+ for (n = 0; n < m->gm_mo_num; n++)
+ if (gss_oid_equal(option, m->gm_mo[n].option) && m->gm_mo[n].get)
+ return m->gm_mo[n].get(mech, &m->gm_mo[n], value);
+
+ return GSS_S_UNAVAILABLE;
+}
+
+static void
+add_all_mo(gssapi_mech_interface m, gss_OID_set *options, OM_uint32 mask)
+{
+ OM_uint32 minor;
+ size_t n;
+
+ for (n = 0; n < m->gm_mo_num; n++)
+ if ((m->gm_mo[n].flags & mask) == mask)
+ gss_add_oid_set_member(&minor, m->gm_mo[n].option, options);
+}
+
+GSSAPI_LIB_FUNCTION void GSSAPI_LIB_CALL
+gss_mo_list(gss_const_OID mech, gss_OID_set *options)
+{
+ gssapi_mech_interface m;
+ OM_uint32 major, minor;
+
+ if (options == NULL)
+ return;
+
+ *options = GSS_C_NO_OID_SET;
+
+ if ((m = __gss_get_mechanism(mech)) == NULL)
+ return;
+
+ major = gss_create_empty_oid_set(&minor, options);
+ if (major != GSS_S_COMPLETE)
+ return;
+
+ add_all_mo(m, options, 0);
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_mo_name(gss_const_OID mech, gss_const_OID option, gss_buffer_t name)
+{
+ gssapi_mech_interface m;
+ size_t n;
+
+ if (name == NULL)
+ return GSS_S_BAD_NAME;
+
+ if ((m = __gss_get_mechanism(mech)) == NULL)
+ return GSS_S_BAD_MECH;
+
+ for (n = 0; n < m->gm_mo_num; n++) {
+ if (gss_oid_equal(option, m->gm_mo[n].option)) {
+ /*
+ * If there is no name, its because its a GSS_C_MA and
+ * there is already a table for that.
+ */
+ if (m->gm_mo[n].name) {
+ name->value = strdup(m->gm_mo[n].name);
+ if (name->value == NULL)
+ return GSS_S_BAD_NAME;
+ name->length = strlen(m->gm_mo[n].name);
+ return GSS_S_COMPLETE;
+ } else {
+ OM_uint32 junk;
+ return gss_display_mech_attr(&junk, option,
+ NULL, name, NULL);
+ }
+ }
+ }
+ return GSS_S_BAD_NAME;
+}
+
+/*
+ * Helper function to allow NULL name
+ */
+
+static OM_uint32
+mo_value(const gss_const_OID mech, gss_const_OID option, gss_buffer_t name)
+{
+ if (name == NULL)
+ return GSS_S_COMPLETE;
+
+ return gss_mo_get(mech, option, name);
+}
+
+/* code derived from draft-ietf-cat-sasl-gssapi-01 */
+static char basis_32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
+
+static OM_uint32
+make_sasl_name(OM_uint32 *minor, const gss_OID mech, char sasl_name[16])
+{
+ EVP_MD_CTX *ctx;
+ char *p = sasl_name;
+ u_char hdr[2], hash[20], *h = hash;
+
+ if (mech->length > 127)
+ return GSS_S_BAD_MECH;
+
+ hdr[0] = 0x06;
+ hdr[1] = mech->length;
+
+ ctx = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
+ EVP_DigestUpdate(ctx, hdr, 2);
+ EVP_DigestUpdate(ctx, mech->elements, mech->length);
+ EVP_DigestFinal_ex(ctx, hash, NULL);
+
+ memcpy(p, "GS2-", 4);
+ p += 4;
+
+ *p++ = basis_32[(h[0] >> 3)];
+ *p++ = basis_32[((h[0] & 7) << 2) | (h[1] >> 6)];
+ *p++ = basis_32[(h[1] & 0x3f) >> 1];
+ *p++ = basis_32[((h[1] & 1) << 4) | (h[2] >> 4)];
+ *p++ = basis_32[((h[2] & 0xf) << 1) | (h[3] >> 7)];
+ *p++ = basis_32[(h[3] & 0x7f) >> 2];
+ *p++ = basis_32[((h[3] & 3) << 3) | (h[4] >> 5)];
+ *p++ = basis_32[(h[4] & 0x1f)];
+ *p++ = basis_32[(h[5] >> 3)];
+ *p++ = basis_32[((h[5] & 7) << 2) | (h[6] >> 6)];
+ *p++ = basis_32[(h[6] & 0x3f) >> 1];
+
+ *p = '\0';
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * gss_inquire_saslname_for_mech() wrapper that uses MIT SPI
+ */
+static OM_uint32
+inquire_saslname_for_mech_compat(OM_uint32 *minor,
+ const gss_OID desired_mech,
+ gss_buffer_t sasl_mech_name,
+ gss_buffer_t mech_name,
+ gss_buffer_t mech_description)
+{
+ struct gss_mech_compat_desc_struct *gmc;
+ gssapi_mech_interface m;
+ OM_uint32 major;
+
+ m = __gss_get_mechanism(desired_mech);
+ if (m == NULL)
+ return GSS_S_BAD_MECH;
+
+ gmc = m->gm_compat;
+
+ if (gmc != NULL && gmc->gmc_inquire_saslname_for_mech != NULL) {
+ major = gmc->gmc_inquire_saslname_for_mech(minor,
+ desired_mech,
+ sasl_mech_name,
+ mech_name,
+ mech_description);
+ } else {
+ major = GSS_S_UNAVAILABLE;
+ }
+
+ return major;
+}
+
+/**
+ * Returns different protocol names and description of the mechanism.
+ *
+ * @param minor_status minor status code
+ * @param desired_mech mech list query
+ * @param sasl_mech_name SASL GS2 protocol name
+ * @param mech_name gssapi protocol name
+ * @param mech_description description of gssapi mech
+ *
+ * @return returns GSS_S_COMPLETE or a error code.
+ *
+ * @ingroup gssapi
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_saslname_for_mech(OM_uint32 *minor_status,
+ const gss_OID desired_mech,
+ gss_buffer_t sasl_mech_name,
+ gss_buffer_t mech_name,
+ gss_buffer_t mech_description)
+{
+ OM_uint32 major;
+
+ _mg_buffer_zero(sasl_mech_name);
+ _mg_buffer_zero(mech_name);
+ _mg_buffer_zero(mech_description);
+
+ if (minor_status)
+ *minor_status = 0;
+
+ if (desired_mech == NULL)
+ return GSS_S_BAD_MECH;
+
+ major = mo_value(desired_mech, GSS_C_MA_SASL_MECH_NAME, sasl_mech_name);
+ if (major == GSS_S_COMPLETE) {
+ /* Native SPI */
+ major = mo_value(desired_mech, GSS_C_MA_MECH_NAME, mech_name);
+ if (GSS_ERROR(major))
+ return major;
+
+ major = mo_value(desired_mech, GSS_C_MA_MECH_DESCRIPTION, mech_description);
+ if (GSS_ERROR(major))
+ return major;
+ }
+
+ if (GSS_ERROR(major)) {
+ /* API-as-SPI compatibility */
+ major = inquire_saslname_for_mech_compat(minor_status,
+ desired_mech,
+ sasl_mech_name,
+ mech_name,
+ mech_description);
+ }
+
+ if (GSS_ERROR(major)) {
+ /* Algorithmically dervied SASL mechanism name */
+ char buf[16];
+ gss_buffer_desc tmp = { sizeof(buf) - 1, buf };
+
+ major = make_sasl_name(minor_status, desired_mech, buf);
+ if (GSS_ERROR(major))
+ return major;
+
+ major = _gss_copy_buffer(minor_status, &tmp, sasl_mech_name);
+ if (GSS_ERROR(major))
+ return major;
+ }
+
+ return major;
+}
+
+/**
+ * Find a mech for a sasl name
+ *
+ * @param minor_status minor status code
+ * @param sasl_mech_name
+ * @param mech_type
+ *
+ * @return returns GSS_S_COMPLETE or an error code.
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_mech_for_saslname(OM_uint32 *minor_status,
+ const gss_buffer_t sasl_mech_name,
+ gss_OID *mech_type)
+{
+ struct _gss_mech_switch *m;
+ gss_buffer_desc name;
+ OM_uint32 major, junk;
+ char buf[16];
+
+ _gss_load_mech();
+
+ *mech_type = NULL;
+
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ struct gss_mech_compat_desc_struct *gmc;
+
+ /* Native SPI */
+ major = mo_value(&m->gm_mech_oid, GSS_C_MA_SASL_MECH_NAME, &name);
+ if (major == GSS_S_COMPLETE &&
+ name.length == sasl_mech_name->length &&
+ memcmp(name.value, sasl_mech_name->value, name.length) == 0) {
+ gss_release_buffer(&junk, &name);
+ *mech_type = &m->gm_mech_oid;
+ return GSS_S_COMPLETE;
+ }
+ gss_release_buffer(&junk, &name);
+
+ if (GSS_ERROR(major)) {
+ /* API-as-SPI compatibility */
+ gmc = m->gm_mech.gm_compat;
+ if (gmc && gmc->gmc_inquire_mech_for_saslname) {
+ major = gmc->gmc_inquire_mech_for_saslname(minor_status,
+ sasl_mech_name,
+ mech_type);
+ if (major == GSS_S_COMPLETE)
+ return GSS_S_COMPLETE;
+ }
+ }
+
+ if (GSS_ERROR(major)) {
+ /* Algorithmically dervied SASL mechanism name */
+ if (sasl_mech_name->length == 16 &&
+ make_sasl_name(minor_status, &m->gm_mech_oid, buf) == GSS_S_COMPLETE &&
+ memcmp(buf, sasl_mech_name->value, 16) == 0) {
+ *mech_type = &m->gm_mech_oid;
+ return GSS_S_COMPLETE;
+ }
+ }
+ }
+
+ return GSS_S_BAD_MECH;
+}
+
+/*
+ * Test mechanism against indicated attributes using both Heimdal and
+ * MIT SPIs.
+ */
+static int
+test_mech_attrs(gssapi_mech_interface mi,
+ gss_const_OID_set mech_attrs,
+ gss_const_OID_set against_attrs,
+ int except)
+{
+ size_t n, m;
+ int eq = 0;
+
+ if (against_attrs == GSS_C_NO_OID_SET)
+ return 1;
+
+ for (n = 0; n < against_attrs->count; n++) {
+ for (m = 0; m < mi->gm_mo_num; m++) {
+ eq = gss_oid_equal(mi->gm_mo[m].option,
+ &against_attrs->elements[n]);
+ if (eq)
+ break;
+ }
+ if (mech_attrs != GSS_C_NO_OID_SET) {
+ for (m = 0; m < mech_attrs->count; m++) {
+ eq = gss_oid_equal(&mech_attrs->elements[m],
+ &against_attrs->elements[n]);
+ if (eq)
+ break;
+ }
+ }
+ if (!eq ^ except)
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * Return set of mechanism that fullfill the criteria
+ *
+ * @param minor_status minor status code
+ * @param desired_mech_attrs
+ * @param except_mech_attrs
+ * @param critical_mech_attrs
+ * @param mechs returned mechs, free with gss_release_oid_set().
+ *
+ * @return returns GSS_S_COMPLETE or an error code.
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_indicate_mechs_by_attrs(OM_uint32 * minor_status,
+ gss_const_OID_set desired_mech_attrs,
+ gss_const_OID_set except_mech_attrs,
+ gss_const_OID_set critical_mech_attrs,
+ gss_OID_set *mechs)
+{
+ struct _gss_mech_switch *ms;
+ gss_OID_set mech_attrs = GSS_C_NO_OID_SET;
+ gss_OID_set known_mech_attrs = GSS_C_NO_OID_SET;
+ OM_uint32 major;
+
+ major = gss_create_empty_oid_set(minor_status, mechs);
+ if (GSS_ERROR(major))
+ return major;
+
+ _gss_load_mech();
+
+ HEIM_SLIST_FOREACH(ms, &_gss_mechs, gm_link) {
+ gssapi_mech_interface mi = &ms->gm_mech;
+ struct gss_mech_compat_desc_struct *gmc = mi->gm_compat;
+ OM_uint32 tmp;
+
+ if (gmc && gmc->gmc_inquire_attrs_for_mech) {
+ major = gmc->gmc_inquire_attrs_for_mech(minor_status,
+ &mi->gm_mech_oid,
+ &mech_attrs,
+ &known_mech_attrs);
+ if (GSS_ERROR(major))
+ continue;
+ }
+
+ /*
+ * Test mechanism supports all of desired_mech_attrs;
+ * none of except_mech_attrs;
+ * and knows of all critical_mech_attrs.
+ */
+ if (test_mech_attrs(mi, mech_attrs, desired_mech_attrs, 0) &&
+ test_mech_attrs(mi, mech_attrs, except_mech_attrs, 1) &&
+ test_mech_attrs(mi, known_mech_attrs, critical_mech_attrs, 0)) {
+ major = gss_add_oid_set_member(minor_status, &mi->gm_mech_oid, mechs);
+ }
+
+ gss_release_oid_set(&tmp, &mech_attrs);
+ gss_release_oid_set(&tmp, &known_mech_attrs);
+
+ if (GSS_ERROR(major))
+ break;
+ }
+
+ return major;
+}
+
+/**
+ * List support attributes for a mech and/or all mechanisms.
+ *
+ * @param minor_status minor status code
+ * @param mech given together with mech_attr will return the list of
+ * attributes for mechanism, can optionally be GSS_C_NO_OID.
+ * @param mech_attr see mech parameter, can optionally be NULL,
+ * release with gss_release_oid_set().
+ * @param known_mech_attrs all attributes for mechanisms supported,
+ * release with gss_release_oid_set().
+ *
+ * @ingroup gssapi
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_inquire_attrs_for_mech(OM_uint32 * minor_status,
+ gss_const_OID mech,
+ gss_OID_set *mech_attr,
+ gss_OID_set *known_mech_attrs)
+{
+ OM_uint32 major, junk;
+
+ if (known_mech_attrs)
+ *known_mech_attrs = GSS_C_NO_OID_SET;
+
+ if (mech_attr && mech) {
+ gssapi_mech_interface m;
+ struct gss_mech_compat_desc_struct *gmc;
+
+ if ((m = __gss_get_mechanism(mech)) == NULL) {
+ *minor_status = 0;
+ return GSS_S_BAD_MECH;
+ }
+
+ gmc = m->gm_compat;
+
+ if (gmc && gmc->gmc_inquire_attrs_for_mech) {
+ major = gmc->gmc_inquire_attrs_for_mech(minor_status,
+ mech,
+ mech_attr,
+ known_mech_attrs);
+ } else {
+ major = gss_create_empty_oid_set(minor_status, mech_attr);
+ if (major == GSS_S_COMPLETE)
+ add_all_mo(m, mech_attr, GSS_MO_MA);
+ }
+ if (GSS_ERROR(major))
+ return major;
+ }
+
+ if (known_mech_attrs) {
+ struct _gss_mech_switch *m;
+
+ if (*known_mech_attrs == GSS_C_NO_OID_SET) {
+ major = gss_create_empty_oid_set(minor_status, known_mech_attrs);
+ if (GSS_ERROR(major)) {
+ if (mech_attr)
+ gss_release_oid_set(&junk, mech_attr);
+ return major;
+ }
+ }
+
+ _gss_load_mech();
+
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link)
+ add_all_mo(&m->gm_mech, known_mech_attrs, GSS_MO_MA);
+ }
+
+
+ return GSS_S_COMPLETE;
+}
+
+/**
+ * Return names and descriptions of mech attributes
+ *
+ * @param minor_status minor status code
+ * @param mech_attr
+ * @param name
+ * @param short_desc
+ * @param long_desc
+ *
+ * @return returns GSS_S_COMPLETE or an error code.
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_display_mech_attr(OM_uint32 * minor_status,
+ gss_const_OID mech_attr,
+ gss_buffer_t name,
+ gss_buffer_t short_desc,
+ gss_buffer_t long_desc)
+{
+ struct _gss_oid_name_table *ma = NULL;
+ OM_uint32 major;
+ size_t n;
+
+ _mg_buffer_zero(name);
+ _mg_buffer_zero(short_desc);
+ _mg_buffer_zero(long_desc);
+
+ if (minor_status)
+ *minor_status = 0;
+
+ for (n = 0; ma == NULL && _gss_ont_ma[n].oid; n++)
+ if (gss_oid_equal(mech_attr, _gss_ont_ma[n].oid))
+ ma = &_gss_ont_ma[n];
+
+ if (ma == NULL)
+ return GSS_S_BAD_MECH_ATTR;
+
+ if (name) {
+ gss_buffer_desc bd;
+ bd.value = rk_UNCONST(ma->name);
+ bd.length = strlen(ma->name);
+ major = _gss_copy_buffer(minor_status, &bd, name);
+ if (major != GSS_S_COMPLETE)
+ return major;
+ }
+
+ if (short_desc) {
+ gss_buffer_desc bd;
+ bd.value = rk_UNCONST(ma->short_desc);
+ bd.length = strlen(ma->short_desc);
+ major = _gss_copy_buffer(minor_status, &bd, short_desc);
+ if (major != GSS_S_COMPLETE)
+ return major;
+ }
+
+ if (long_desc) {
+ gss_buffer_desc bd;
+ bd.value = rk_UNCONST(ma->long_desc);
+ bd.length = strlen(ma->long_desc);
+ major = _gss_copy_buffer(minor_status, &bd, long_desc);
+ if (major != GSS_S_COMPLETE)
+ return major;
+ }
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_names.c b/crypto/heimdal/lib/gssapi/mech/gss_names.c
new file mode 100644
index 0000000..43e0e2a
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_names.c
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_names.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+OM_uint32
+_gss_find_mn(OM_uint32 *minor_status, struct _gss_name *name, gss_OID mech,
+ struct _gss_mechanism_name **output_mn)
+{
+ OM_uint32 major_status;
+ gssapi_mech_interface m;
+ struct _gss_mechanism_name *mn;
+
+ *output_mn = NULL;
+
+ HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ if (gss_oid_equal(mech, mn->gmn_mech_oid))
+ break;
+ }
+
+ if (!mn) {
+ /*
+ * If this name is canonical (i.e. there is only an
+ * MN but it is from a different mech), give up now.
+ */
+ if (!name->gn_value.value)
+ return GSS_S_BAD_NAME;
+
+ m = __gss_get_mechanism(mech);
+ if (!m)
+ return (GSS_S_BAD_MECH);
+
+ mn = malloc(sizeof(struct _gss_mechanism_name));
+ if (!mn)
+ return GSS_S_FAILURE;
+
+ major_status = m->gm_import_name(minor_status,
+ &name->gn_value,
+ (name->gn_type.elements
+ ? &name->gn_type : GSS_C_NO_OID),
+ &mn->gmn_name);
+ if (major_status != GSS_S_COMPLETE) {
+ _gss_mg_error(m, major_status, *minor_status);
+ free(mn);
+ return major_status;
+ }
+
+ mn->gmn_mech = m;
+ mn->gmn_mech_oid = &m->gm_mech_oid;
+ HEIM_SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
+ }
+ *output_mn = mn;
+ return 0;
+}
+
+
+/*
+ * Make a name from an MN.
+ */
+struct _gss_name *
+_gss_make_name(gssapi_mech_interface m, gss_name_t new_mn)
+{
+ struct _gss_name *name;
+ struct _gss_mechanism_name *mn;
+
+ name = malloc(sizeof(struct _gss_name));
+ if (!name)
+ return (0);
+ memset(name, 0, sizeof(struct _gss_name));
+
+ mn = malloc(sizeof(struct _gss_mechanism_name));
+ if (!mn) {
+ free(name);
+ return (0);
+ }
+
+ HEIM_SLIST_INIT(&name->gn_mn);
+ mn->gmn_mech = m;
+ mn->gmn_mech_oid = &m->gm_mech_oid;
+ mn->gmn_name = new_mn;
+ HEIM_SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
+
+ return (name);
+}
+
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_oid.c b/crypto/heimdal/lib/gssapi/mech/gss_oid.c
new file mode 100644
index 0000000..916d1e4
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_oid.c
@@ -0,0 +1,266 @@
+/* Generated file */
+#include "mech_locl.h"
+
+/* GSS_KRB5_COPY_CCACHE_X - 1.2.752.43.13.1 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_copy_ccache_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x01") };
+
+/* GSS_KRB5_GET_TKT_FLAGS_X - 1.2.752.43.13.2 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_tkt_flags_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x02") };
+
+/* GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X - 1.2.752.43.13.3 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_extract_authz_data_from_sec_context_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x03") };
+
+/* GSS_KRB5_COMPAT_DES3_MIC_X - 1.2.752.43.13.4 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_compat_des3_mic_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x04") };
+
+/* GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X - 1.2.752.43.13.5 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_register_acceptor_identity_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x05") };
+
+/* GSS_KRB5_EXPORT_LUCID_CONTEXT_X - 1.2.752.43.13.6 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_export_lucid_context_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06") };
+
+/* GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X - 1.2.752.43.13.6.1 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_export_lucid_context_v1_x_oid_desc = { 7, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06\x01") };
+
+/* GSS_KRB5_SET_DNS_CANONICALIZE_X - 1.2.752.43.13.7 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_set_dns_canonicalize_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x07") };
+
+/* GSS_KRB5_GET_SUBKEY_X - 1.2.752.43.13.8 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_subkey_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x08") };
+
+/* GSS_KRB5_GET_INITIATOR_SUBKEY_X - 1.2.752.43.13.9 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_initiator_subkey_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x09") };
+
+/* GSS_KRB5_GET_ACCEPTOR_SUBKEY_X - 1.2.752.43.13.10 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_acceptor_subkey_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0a") };
+
+/* GSS_KRB5_SEND_TO_KDC_X - 1.2.752.43.13.11 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_send_to_kdc_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0b") };
+
+/* GSS_KRB5_GET_AUTHTIME_X - 1.2.752.43.13.12 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_authtime_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0c") };
+
+/* GSS_KRB5_GET_SERVICE_KEYBLOCK_X - 1.2.752.43.13.13 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_service_keyblock_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0d") };
+
+/* GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X - 1.2.752.43.13.14 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_set_allowable_enctypes_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0e") };
+
+/* GSS_KRB5_SET_DEFAULT_REALM_X - 1.2.752.43.13.15 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_set_default_realm_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0f") };
+
+/* GSS_KRB5_CCACHE_NAME_X - 1.2.752.43.13.16 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_ccache_name_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x10") };
+
+/* GSS_KRB5_SET_TIME_OFFSET_X - 1.2.752.43.13.17 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_set_time_offset_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11") };
+
+/* GSS_KRB5_GET_TIME_OFFSET_X - 1.2.752.43.13.18 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_time_offset_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x12") };
+
+/* GSS_KRB5_PLUGIN_REGISTER_X - 1.2.752.43.13.19 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_plugin_register_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x13") };
+
+/* GSS_NTLM_GET_SESSION_KEY_X - 1.2.752.43.13.20 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_ntlm_get_session_key_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x14") };
+
+/* GSS_C_NT_NTLM - 1.2.752.43.13.21 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_ntlm_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x15") };
+
+/* GSS_C_NT_DN - 1.2.752.43.13.22 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_dn_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x16") };
+
+/* GSS_KRB5_NT_PRINCIPAL_NAME_REFERRAL - 1.2.752.43.13.23 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_nt_principal_name_referral_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x17") };
+
+/* GSS_C_NTLM_AVGUEST - 1.2.752.43.13.24 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_avguest_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x18") };
+
+/* GSS_C_NTLM_V1 - 1.2.752.43.13.25 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_v1_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x19") };
+
+/* GSS_C_NTLM_V2 - 1.2.752.43.13.26 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_v2_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1a") };
+
+/* GSS_C_NTLM_SESSION_KEY - 1.2.752.43.13.27 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_session_key_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1b") };
+
+/* GSS_C_NTLM_FORCE_V1 - 1.2.752.43.13.28 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_force_v1_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1c") };
+
+/* GSS_KRB5_CRED_NO_CI_FLAGS_X - 1.2.752.43.13.29 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_cred_no_ci_flags_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1d") };
+
+/* GSS_KRB5_IMPORT_CRED_X - 1.2.752.43.13.30 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_import_cred_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1e") };
+
+/* GSS_C_MA_SASL_MECH_NAME - 1.2.752.43.13.100 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_sasl_mech_name_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x64") };
+
+/* GSS_C_MA_MECH_NAME - 1.2.752.43.13.101 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_name_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x65") };
+
+/* GSS_C_MA_MECH_DESCRIPTION - 1.2.752.43.13.102 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_description_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x66") };
+
+/* GSS_C_CRED_PASSWORD - 1.2.752.43.13.200 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_cred_password_oid_desc = { 7, "\x2a\x85\x70\x2b\x0d\x81\x48" };
+
+/* GSS_C_CRED_CERTIFICATE - 1.2.752.43.13.201 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_cred_certificate_oid_desc = { 7, "\x2a\x85\x70\x2b\x0d\x81\x49" };
+
+/* GSS_SASL_DIGEST_MD5_MECHANISM - 1.2.752.43.14.1 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_sasl_digest_md5_mechanism_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x01") };
+
+/* GSS_NETLOGON_MECHANISM - 1.2.752.43.14.2 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_netlogon_mechanism_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x02") };
+
+/* GSS_NETLOGON_SET_SESSION_KEY_X - 1.2.752.43.14.3 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_netlogon_set_session_key_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x03") };
+
+/* GSS_NETLOGON_SET_SIGN_ALGORITHM_X - 1.2.752.43.14.4 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_netlogon_set_sign_algorithm_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x04") };
+
+/* GSS_NETLOGON_NT_NETBIOS_DNS_NAME - 1.2.752.43.14.5 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_netlogon_nt_netbios_dns_name_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x05") };
+
+/* GSS_C_INQ_WIN2K_PAC_X - 1.2.752.43.13.3.128 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_win2k_pac_x_oid_desc = { 8, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x03\x81\x00") };
+
+/* GSS_C_INQ_SSPI_SESSION_KEY - 1.2.840.113554.1.2.2.5.5 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_sspi_session_key_oid_desc = { 11, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05") };
+
+/* GSS_KRB5_MECHANISM - 1.2.840.113554.1.2.2 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_mechanism_oid_desc = { 9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") };
+
+/* GSS_NTLM_MECHANISM - 1.3.6.1.4.1.311.2.2.10 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_ntlm_mechanism_oid_desc = { 10, rk_UNCONST("\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a") };
+
+/* GSS_SPNEGO_MECHANISM - 1.3.6.1.5.5.2 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_spnego_mechanism_oid_desc = { 6, rk_UNCONST("\x2b\x06\x01\x05\x05\x02") };
+
+/* GSS_C_PEER_HAS_UPDATED_SPNEGO - 1.3.6.1.4.1.9513.19.5 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_peer_has_updated_spnego_oid_desc = { 9, rk_UNCONST("\x2b\x06\x01\x04\x01\xca\x29\x13\x05") };
+
+/* GSS_C_MA_MECH_CONCRETE - 1.3.6.1.5.5.13.1 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_concrete_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x01") };
+
+/* GSS_C_MA_MECH_PSEUDO - 1.3.6.1.5.5.13.2 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_pseudo_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x02") };
+
+/* GSS_C_MA_MECH_COMPOSITE - 1.3.6.1.5.5.13.3 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_composite_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x03") };
+
+/* GSS_C_MA_MECH_NEGO - 1.3.6.1.5.5.13.4 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_nego_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x04") };
+
+/* GSS_C_MA_MECH_GLUE - 1.3.6.1.5.5.13.5 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_glue_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x05") };
+
+/* GSS_C_MA_NOT_MECH - 1.3.6.1.5.5.13.6 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_not_mech_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x06") };
+
+/* GSS_C_MA_DEPRECATED - 1.3.6.1.5.5.13.7 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_deprecated_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x07") };
+
+/* GSS_C_MA_NOT_DFLT_MECH - 1.3.6.1.5.5.13.8 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_not_dflt_mech_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x08") };
+
+/* GSS_C_MA_ITOK_FRAMED - 1.3.6.1.5.5.13.9 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_itok_framed_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x09") };
+
+/* GSS_C_MA_AUTH_INIT - 1.3.6.1.5.5.13.10 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_auth_init_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x0a") };
+
+/* GSS_C_MA_AUTH_TARG - 1.3.6.1.5.5.13.11 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_auth_targ_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x0b") };
+
+/* GSS_C_MA_AUTH_INIT_INIT - 1.3.6.1.5.5.13.12 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_auth_init_init_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x0c") };
+
+/* GSS_C_MA_AUTH_TARG_INIT - 1.3.6.1.5.5.13.13 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_auth_targ_init_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x0d") };
+
+/* GSS_C_MA_AUTH_INIT_ANON - 1.3.6.1.5.5.13.14 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_auth_init_anon_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x0e") };
+
+/* GSS_C_MA_AUTH_TARG_ANON - 1.3.6.1.5.5.13.15 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_auth_targ_anon_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x0f") };
+
+/* GSS_C_MA_DELEG_CRED - 1.3.6.1.5.5.13.16 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_deleg_cred_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x10") };
+
+/* GSS_C_MA_INTEG_PROT - 1.3.6.1.5.5.13.17 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_integ_prot_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x11") };
+
+/* GSS_C_MA_CONF_PROT - 1.3.6.1.5.5.13.18 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_conf_prot_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x12") };
+
+/* GSS_C_MA_MIC - 1.3.6.1.5.5.13.19 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mic_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x13") };
+
+/* GSS_C_MA_WRAP - 1.3.6.1.5.5.13.20 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_wrap_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x14") };
+
+/* GSS_C_MA_PROT_READY - 1.3.6.1.5.5.13.21 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_prot_ready_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x15") };
+
+/* GSS_C_MA_REPLAY_DET - 1.3.6.1.5.5.13.22 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_replay_det_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x16") };
+
+/* GSS_C_MA_OOS_DET - 1.3.6.1.5.5.13.23 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_oos_det_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x17") };
+
+/* GSS_C_MA_CBINDINGS - 1.3.6.1.5.5.13.24 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_cbindings_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x18") };
+
+/* GSS_C_MA_PFS - 1.3.6.1.5.5.13.25 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_pfs_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x19") };
+
+/* GSS_C_MA_COMPRESS - 1.3.6.1.5.5.13.26 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_compress_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x1a") };
+
+/* GSS_C_MA_CTX_TRANS - 1.3.6.1.5.5.13.27 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_ctx_trans_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x1b") };
+
+struct _gss_oid_name_table _gss_ont_ma[] = {
+ { GSS_C_MA_COMPRESS, "GSS_C_MA_COMPRESS", "compress", "" },
+ { GSS_C_MA_AUTH_TARG_INIT, "GSS_C_MA_AUTH_TARG_INIT", "auth-targ-princ-initial", "" },
+ { GSS_C_MA_CBINDINGS, "GSS_C_MA_CBINDINGS", "channel-bindings", "" },
+ { GSS_C_MA_WRAP, "GSS_C_MA_WRAP", "wrap", "" },
+ { GSS_C_MA_ITOK_FRAMED, "GSS_C_MA_ITOK_FRAMED", "initial-is-framed", "" },
+ { GSS_C_MA_MECH_NEGO, "GSS_C_MA_MECH_NEGO", "mech-negotiation-mech", "" },
+ { GSS_C_MA_MECH_COMPOSITE, "GSS_C_MA_MECH_COMPOSITE", "composite-mech", "" },
+ { GSS_C_MA_REPLAY_DET, "GSS_C_MA_REPLAY_DET", "replay-detection", "" },
+ { GSS_C_MA_AUTH_INIT_ANON, "GSS_C_MA_AUTH_INIT_ANON", "auth-init-princ-anon", "" },
+ { GSS_C_MA_PROT_READY, "GSS_C_MA_PROT_READY", "prot-ready", "" },
+ { GSS_C_MA_AUTH_INIT, "GSS_C_MA_AUTH_INIT", "auth-init-princ", "" },
+ { GSS_C_MA_PFS, "GSS_C_MA_PFS", "pfs", "" },
+ { GSS_C_MA_CONF_PROT, "GSS_C_MA_CONF_PROT", "conf-prot", "" },
+ { GSS_C_MA_MECH_PSEUDO, "GSS_C_MA_MECH_PSEUDO", "pseudo-mech", "" },
+ { GSS_C_MA_AUTH_TARG, "GSS_C_MA_AUTH_TARG", "auth-targ-princ", "" },
+ { GSS_C_MA_MECH_NAME, "GSS_C_MA_MECH_NAME", "GSS mech name", "The name of the GSS-API mechanism" },
+ { GSS_C_MA_NOT_MECH, "GSS_C_MA_NOT_MECH", "not-mech", "" },
+ { GSS_C_MA_MIC, "GSS_C_MA_MIC", "mic", "" },
+ { GSS_C_MA_DEPRECATED, "GSS_C_MA_DEPRECATED", "mech-deprecated", "" },
+ { GSS_C_MA_MECH_GLUE, "GSS_C_MA_MECH_GLUE", "mech-glue", "" },
+ { GSS_C_MA_DELEG_CRED, "GSS_C_MA_DELEG_CRED", "deleg-cred", "" },
+ { GSS_C_MA_NOT_DFLT_MECH, "GSS_C_MA_NOT_DFLT_MECH", "mech-not-default", "" },
+ { GSS_C_MA_AUTH_TARG_ANON, "GSS_C_MA_AUTH_TARG_ANON", "auth-targ-princ-anon", "" },
+ { GSS_C_MA_INTEG_PROT, "GSS_C_MA_INTEG_PROT", "integ-prot", "" },
+ { GSS_C_MA_CTX_TRANS, "GSS_C_MA_CTX_TRANS", "context-transfer", "" },
+ { GSS_C_MA_MECH_DESCRIPTION, "GSS_C_MA_MECH_DESCRIPTION", "Mech description", "The long description of the mechanism" },
+ { GSS_C_MA_OOS_DET, "GSS_C_MA_OOS_DET", "oos-detection", "" },
+ { GSS_C_MA_AUTH_INIT_INIT, "GSS_C_MA_AUTH_INIT_INIT", "auth-init-princ-initial", "" },
+ { GSS_C_MA_MECH_CONCRETE, "GSS_C_MA_MECH_CONCRETE", "concrete-mech", "Indicates that a mech is neither a pseudo-mechanism nor a composite mechanism" },
+ { GSS_C_MA_SASL_MECH_NAME, "GSS_C_MA_SASL_MECH_NAME", "SASL mechanism name", "The name of the SASL mechanism" },
+ { NULL }
+};
+
+struct _gss_oid_name_table _gss_ont_mech[] = {
+ { GSS_KRB5_MECHANISM, "GSS_KRB5_MECHANISM", "Kerberos 5", "Heimdal Kerberos 5 mechanism" },
+ { GSS_SPNEGO_MECHANISM, "GSS_SPNEGO_MECHANISM", "SPNEGO", "Heimdal SPNEGO mechanism" },
+ { GSS_NTLM_MECHANISM, "GSS_NTLM_MECHANISM", "NTLM", "Heimdal NTLM mechanism" },
+ { NULL }
+};
+
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_oid_equal.c b/crypto/heimdal/lib/gssapi/mech/gss_oid_equal.c
new file mode 100644
index 0000000..b125ede
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_oid_equal.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "mech_locl.h"
+
+/**
+ * Compare two GSS-API OIDs with each other.
+ *
+ * GSS_C_NO_OID matches nothing, not even it-self.
+ *
+ * @param a first oid to compare
+ * @param b second oid to compare
+ *
+ * @return non-zero when both oid are the same OID, zero when they are
+ * not the same.
+ *
+ * @ingroup gssapi
+ */
+
+GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL
+gss_oid_equal(gss_const_OID a, gss_const_OID b)
+{
+ if (a == b && a != GSS_C_NO_OID)
+ return 1;
+ if (a == GSS_C_NO_OID || b == GSS_C_NO_OID || a->length != b->length)
+ return 0;
+ return memcmp(a->elements, b->elements, a->length) == 0;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_oid_to_str.c b/crypto/heimdal/lib/gssapi/mech/gss_oid_to_str.c
new file mode 100644
index 0000000..a1d7768
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_oid_to_str.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_oid_to_str(OM_uint32 *minor_status, gss_OID oid, gss_buffer_t oid_str)
+{
+ int ret;
+ size_t size;
+ heim_oid o;
+ char *p;
+
+ _mg_buffer_zero(oid_str);
+
+ if (oid == GSS_C_NULL_OID)
+ return GSS_S_FAILURE;
+
+ ret = der_get_oid (oid->elements, oid->length, &o, &size);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = der_print_heim_oid(&o, ' ', &p);
+ der_free_oid(&o);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ oid_str->value = p;
+ oid_str->length = strlen(p);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
+
+GSSAPI_LIB_FUNCTION const char * GSSAPI_LIB_CALL
+gss_oid_to_name(gss_const_OID oid)
+{
+ size_t i;
+
+ for (i = 0; _gss_ont_mech[i].oid; i++) {
+ if (gss_oid_equal(oid, _gss_ont_mech[i].oid))
+ return _gss_ont_mech[i].name;
+ }
+ return NULL;
+}
+
+GSSAPI_LIB_FUNCTION gss_OID GSSAPI_LIB_CALL
+gss_name_to_oid(const char *name)
+{
+ size_t i, partial = (size_t)-1;
+
+ for (i = 0; _gss_ont_mech[i].oid; i++) {
+ if (strcasecmp(name, _gss_ont_mech[i].short_desc) == 0)
+ return _gss_ont_mech[i].oid;
+ if (strncasecmp(name, _gss_ont_mech[i].short_desc, strlen(name)) == 0) {
+ if (partial != (size_t)-1)
+ return NULL;
+ partial = i;
+ }
+ }
+ if (partial != (size_t)-1)
+ return _gss_ont_mech[partial].oid;
+ return NULL;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_pname_to_uid.c b/crypto/heimdal/lib/gssapi/mech/gss_pname_to_uid.c
new file mode 100644
index 0000000..c5f2694
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_pname_to_uid.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2011, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+static OM_uint32
+mech_pname_to_uid(OM_uint32 *minor_status,
+ struct _gss_mechanism_name *mn,
+ uid_t *uidp)
+{
+ OM_uint32 major_status = GSS_S_UNAVAILABLE;
+
+ *minor_status = 0;
+
+ if (mn->gmn_mech->gm_pname_to_uid == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ major_status = mn->gmn_mech->gm_pname_to_uid(minor_status,
+ mn->gmn_name,
+ mn->gmn_mech_oid,
+ uidp);
+ if (GSS_ERROR(major_status))
+ _gss_mg_error(mn->gmn_mech, major_status, *minor_status);
+
+ return major_status;
+}
+
+static OM_uint32
+attr_pname_to_uid(OM_uint32 *minor_status,
+ struct _gss_mechanism_name *mn,
+ uid_t *uidp)
+{
+#ifdef NO_LOCALNAME
+ return GSS_S_UNAVAILABLE;
+#else
+ OM_uint32 major_status = GSS_S_UNAVAILABLE;
+ OM_uint32 tmpMinor;
+ int more = -1;
+
+ *minor_status = 0;
+
+ if (mn->gmn_mech->gm_get_name_attribute == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ while (more != 0) {
+ gss_buffer_desc value;
+ gss_buffer_desc display_value;
+ int authenticated = 0, complete = 0;
+#ifdef POSIX_GETPWNAM_R
+ char pwbuf[2048];
+ struct passwd pw, *pwd;
+#else
+ struct passwd *pwd;
+#endif
+ char *localname;
+
+ major_status = mn->gmn_mech->gm_get_name_attribute(minor_status,
+ mn->gmn_name,
+ GSS_C_ATTR_LOCAL_LOGIN_USER,
+ &authenticated,
+ &complete,
+ &value,
+ &display_value,
+ &more);
+ if (GSS_ERROR(major_status)) {
+ _gss_mg_error(mn->gmn_mech, major_status, *minor_status);
+ break;
+ }
+
+ localname = malloc(value.length + 1);
+ if (localname == NULL) {
+ major_status = GSS_S_FAILURE;
+ *minor_status = ENOMEM;
+ break;
+ }
+
+ memcpy(localname, value.value, value.length);
+ localname[value.length] = '\0';
+
+#ifdef POSIX_GETPWNAM_R
+ if (getpwnam_r(localname, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0)
+ pwd = NULL;
+#else
+ pwd = getpwnam(localname);
+#endif
+
+ free(localname);
+ gss_release_buffer(&tmpMinor, &value);
+ gss_release_buffer(&tmpMinor, &display_value);
+
+ if (pwd != NULL) {
+ *uidp = pwd->pw_uid;
+ major_status = GSS_S_COMPLETE;
+ *minor_status = 0;
+ break;
+ } else
+ major_status = GSS_S_UNAVAILABLE;
+ }
+
+ return major_status;
+#endif /* NO_LOCALNAME */
+}
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_pname_to_uid(OM_uint32 *minor_status,
+ const gss_name_t pname,
+ const gss_OID mech_type,
+ uid_t *uidp)
+{
+ OM_uint32 major_status = GSS_S_UNAVAILABLE;
+ struct _gss_name *name = (struct _gss_name *) pname;
+ struct _gss_mechanism_name *mn = NULL;
+
+ *minor_status = 0;
+
+ if (mech_type != GSS_C_NO_OID) {
+ major_status = _gss_find_mn(minor_status, name, mech_type, &mn);
+ if (GSS_ERROR(major_status))
+ return major_status;
+
+ major_status = mech_pname_to_uid(minor_status, mn, uidp);
+ if (major_status != GSS_S_COMPLETE)
+ major_status = attr_pname_to_uid(minor_status, mn, uidp);
+ } else {
+ HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ major_status = mech_pname_to_uid(minor_status, mn, uidp);
+ if (major_status != GSS_S_COMPLETE)
+ major_status = attr_pname_to_uid(minor_status, mn, uidp);
+ if (major_status != GSS_S_UNAVAILABLE)
+ break;
+ }
+ }
+
+ if (major_status != GSS_S_COMPLETE && mn != NULL)
+ _gss_mg_error(mn->gmn_mech, major_status, *minor_status);
+
+ return major_status;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_process_context_token.c b/crypto/heimdal/lib/gssapi/mech/gss_process_context_token.c
new file mode 100644
index 0000000..e8e9b56
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_process_context_token.c
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_process_context_token.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_process_context_token(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t token_buffer)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ gssapi_mech_interface m = ctx->gc_mech;
+
+ return (m->gm_process_context_token(minor_status, ctx->gc_ctx,
+ token_buffer));
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_pseudo_random.c b/crypto/heimdal/lib/gssapi/mech/gss_pseudo_random.c
new file mode 100644
index 0000000..ce4f9a4
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_pseudo_random.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_pseudo_random(OM_uint32 *minor_status,
+ gss_ctx_id_t context,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context;
+ gssapi_mech_interface m;
+ OM_uint32 major_status;
+
+ _mg_buffer_zero(prf_out);
+ *minor_status = 0;
+
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ m = ctx->gc_mech;
+
+ if (m->gm_pseudo_random == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ major_status = (*m->gm_pseudo_random)(minor_status, ctx->gc_ctx,
+ prf_key, prf_in, desired_output_len,
+ prf_out);
+ if (major_status != GSS_S_COMPLETE)
+ _gss_mg_error(m, major_status, *minor_status);
+
+ return major_status;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_release_buffer.c b/crypto/heimdal/lib/gssapi/mech/gss_release_buffer.c
new file mode 100644
index 0000000..c3dd457
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_release_buffer.c
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_release_buffer.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_release_buffer(OM_uint32 *minor_status,
+ gss_buffer_t buffer)
+{
+
+ *minor_status = 0;
+ if (buffer->value)
+ free(buffer->value);
+ _mg_buffer_zero(buffer);
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_release_cred.c b/crypto/heimdal/lib/gssapi/mech/gss_release_cred.c
new file mode 100644
index 0000000..341f9f6
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_release_cred.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_release_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+/**
+ * Release a credentials
+ *
+ * Its ok to release the GSS_C_NO_CREDENTIAL/NULL credential, it will
+ * return a GSS_S_COMPLETE error code. On return cred_handle is set ot
+ * GSS_C_NO_CREDENTIAL.
+ *
+ * Example:
+ *
+ * @code
+ * gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
+ * major = gss_release_cred(&minor, &cred);
+ * @endcode
+ *
+ * @param minor_status minor status return code, mech specific
+ * @param cred_handle a pointer to the credential too release
+ *
+ * @return an gssapi error code
+ *
+ * @ingroup gssapi
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
+{
+ struct _gss_cred *cred = (struct _gss_cred *) *cred_handle;
+ struct _gss_mechanism_cred *mc;
+
+ if (*cred_handle == GSS_C_NO_CREDENTIAL)
+ return (GSS_S_COMPLETE);
+
+ while (HEIM_SLIST_FIRST(&cred->gc_mc)) {
+ mc = HEIM_SLIST_FIRST(&cred->gc_mc);
+ HEIM_SLIST_REMOVE_HEAD(&cred->gc_mc, gmc_link);
+ mc->gmc_mech->gm_release_cred(minor_status, &mc->gmc_cred);
+ free(mc);
+ }
+ free(cred);
+
+ *minor_status = 0;
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_release_name.c b/crypto/heimdal/lib/gssapi/mech/gss_release_name.c
new file mode 100644
index 0000000..fd0b5df3
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_release_name.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_release_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+/**
+ * Free a name
+ *
+ * import_name can point to NULL or be NULL, or a pointer to a
+ * gss_name_t structure. If it was a pointer to gss_name_t, the
+ * pointer will be set to NULL on success and failure.
+ *
+ * @param minor_status minor status code
+ * @param input_name name to free
+ *
+ * @returns a gss_error code, see gss_display_status() about printing
+ * the error code.
+ *
+ * @ingroup gssapi
+ */
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_release_name(OM_uint32 *minor_status,
+ gss_name_t *input_name)
+{
+ struct _gss_name *name;
+
+ *minor_status = 0;
+
+ if (input_name == NULL || *input_name == NULL)
+ return GSS_S_COMPLETE;
+
+ name = (struct _gss_name *) *input_name;
+
+ if (name->gn_type.elements)
+ free(name->gn_type.elements);
+ while (HEIM_SLIST_FIRST(&name->gn_mn)) {
+ struct _gss_mechanism_name *mn;
+ mn = HEIM_SLIST_FIRST(&name->gn_mn);
+ HEIM_SLIST_REMOVE_HEAD(&name->gn_mn, gmn_link);
+ mn->gmn_mech->gm_release_name(minor_status,
+ &mn->gmn_name);
+ free(mn);
+ }
+ gss_release_buffer(minor_status, &name->gn_value);
+ free(name);
+ *input_name = GSS_C_NO_NAME;
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_release_oid.c b/crypto/heimdal/lib/gssapi/mech/gss_release_oid.c
new file mode 100644
index 0000000..610daf2
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_release_oid.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "mech_locl.h"
+
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_release_oid(OM_uint32 *minor_status, gss_OID *oid)
+{
+ gss_OID o = *oid;
+
+ *oid = GSS_C_NO_OID;
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (o == GSS_C_NO_OID)
+ return GSS_S_COMPLETE;
+
+ if (o->elements != NULL) {
+ free(o->elements);
+ o->elements = NULL;
+ }
+ o->length = 0;
+ free(o);
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_release_oid_set.c b/crypto/heimdal/lib/gssapi/mech/gss_release_oid_set.c
new file mode 100644
index 0000000..183ddf8
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_release_oid_set.c
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_release_oid_set.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_release_oid_set(OM_uint32 *minor_status,
+ gss_OID_set *set)
+{
+
+ *minor_status = 0;
+ if (set && *set) {
+ if ((*set)->elements)
+ free((*set)->elements);
+ free(*set);
+ *set = GSS_C_NO_OID_SET;
+ }
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_seal.c b/crypto/heimdal/lib/gssapi/mech/gss_seal.c
new file mode 100644
index 0000000..26c65da
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_seal.c
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_seal.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_seal(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ int qop_req,
+ gss_buffer_t input_message_buffer,
+ int *conf_state,
+ gss_buffer_t output_message_buffer)
+{
+
+ return (gss_wrap(minor_status,
+ context_handle, conf_req_flag, qop_req,
+ input_message_buffer, conf_state,
+ output_message_buffer));
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_set_cred_option.c b/crypto/heimdal/lib/gssapi/mech/gss_set_cred_option.c
new file mode 100644
index 0000000..d33453d
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_set_cred_option.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_set_cred_option (OM_uint32 *minor_status,
+ gss_cred_id_t *cred_handle,
+ const gss_OID object,
+ const gss_buffer_t value)
+{
+ struct _gss_cred *cred = (struct _gss_cred *) *cred_handle;
+ OM_uint32 major_status = GSS_S_COMPLETE;
+ struct _gss_mechanism_cred *mc;
+ int one_ok = 0;
+
+ *minor_status = 0;
+
+ _gss_load_mech();
+
+ if (cred == NULL) {
+ struct _gss_mech_switch *m;
+
+ cred = malloc(sizeof(*cred));
+ if (cred == NULL)
+ return GSS_S_FAILURE;
+
+ HEIM_SLIST_INIT(&cred->gc_mc);
+
+ HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+
+ if (m->gm_mech.gm_set_cred_option == NULL)
+ continue;
+
+ mc = malloc(sizeof(*mc));
+ if (mc == NULL) {
+ *cred_handle = (gss_cred_id_t)cred;
+ gss_release_cred(minor_status, cred_handle);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ mc->gmc_mech = &m->gm_mech;
+ mc->gmc_mech_oid = &m->gm_mech_oid;
+ mc->gmc_cred = GSS_C_NO_CREDENTIAL;
+
+ major_status = m->gm_mech.gm_set_cred_option(
+ minor_status, &mc->gmc_cred, object, value);
+
+ if (major_status) {
+ free(mc);
+ continue;
+ }
+ one_ok = 1;
+ HEIM_SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);
+ }
+ *cred_handle = (gss_cred_id_t)cred;
+ if (!one_ok) {
+ OM_uint32 junk;
+ gss_release_cred(&junk, cred_handle);
+ }
+ } else {
+ gssapi_mech_interface m;
+
+ HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ m = mc->gmc_mech;
+
+ if (m == NULL)
+ return GSS_S_BAD_MECH;
+
+ if (m->gm_set_cred_option == NULL)
+ continue;
+
+ major_status = m->gm_set_cred_option(minor_status,
+ &mc->gmc_cred, object, value);
+ if (major_status == GSS_S_COMPLETE)
+ one_ok = 1;
+ else
+ _gss_mg_error(m, major_status, *minor_status);
+
+ }
+ }
+ if (one_ok) {
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ }
+ return major_status;
+}
+
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_set_name_attribute.c b/crypto/heimdal/lib/gssapi/mech/gss_set_name_attribute.c
new file mode 100644
index 0000000..ada7a06
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_set_name_attribute.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2010, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_set_name_attribute(OM_uint32 *minor_status,
+ gss_name_t input_name,
+ int complete,
+ gss_buffer_t attr,
+ gss_buffer_t value)
+{
+ OM_uint32 major_status = GSS_S_UNAVAILABLE;
+ struct _gss_name *name = (struct _gss_name *) input_name;
+ struct _gss_mechanism_name *mn;
+
+ *minor_status = 0;
+
+ if (input_name == GSS_C_NO_NAME)
+ return GSS_S_BAD_NAME;
+
+ HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ gssapi_mech_interface m = mn->gmn_mech;
+
+ if (!m->gm_set_name_attribute)
+ continue;
+
+ major_status = m->gm_set_name_attribute(minor_status,
+ mn->gmn_name,
+ complete,
+ attr,
+ value);
+ if (GSS_ERROR(major_status))
+ _gss_mg_error(m, major_status, *minor_status);
+ else
+ break;
+ }
+
+ return major_status;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c b/crypto/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c
new file mode 100644
index 0000000..6efe1a0
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_set_sec_context_option (OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ const gss_OID object,
+ const gss_buffer_t value)
+{
+ struct _gss_context *ctx;
+ OM_uint32 major_status;
+ gssapi_mech_interface m;
+
+ *minor_status = 0;
+
+ if (context_handle == NULL)
+ return GSS_S_NO_CONTEXT;
+
+ ctx = (struct _gss_context *) *context_handle;
+
+ if (ctx == NULL)
+ return GSS_S_NO_CONTEXT;
+
+ m = ctx->gc_mech;
+
+ if (m == NULL)
+ return GSS_S_BAD_MECH;
+
+ if (m->gm_set_sec_context_option != NULL) {
+ major_status = m->gm_set_sec_context_option(minor_status,
+ &ctx->gc_ctx, object, value);
+ if (major_status != GSS_S_COMPLETE)
+ _gss_mg_error(m, major_status, *minor_status);
+ } else
+ major_status = GSS_S_BAD_MECH;
+
+ return major_status;
+}
+
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_sign.c b/crypto/heimdal/lib/gssapi/mech/gss_sign.c
new file mode 100644
index 0000000..4ef99c1
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_sign.c
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_sign.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_sign(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int qop_req,
+ gss_buffer_t message_buffer,
+ gss_buffer_t message_token)
+{
+
+ return gss_get_mic(minor_status,
+ context_handle, qop_req, message_buffer, message_token);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_store_cred.c b/crypto/heimdal/lib/gssapi/mech/gss_store_cred.c
new file mode 100644
index 0000000..4d2bfde
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_store_cred.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2009 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_store_cred(OM_uint32 *minor_status,
+ gss_cred_id_t input_cred_handle,
+ gss_cred_usage_t cred_usage,
+ const gss_OID desired_mech,
+ OM_uint32 overwrite_cred,
+ OM_uint32 default_cred,
+ gss_OID_set *elements_stored,
+ gss_cred_usage_t *cred_usage_stored)
+{
+ struct _gss_cred *cred = (struct _gss_cred *) input_cred_handle;
+ struct _gss_mechanism_cred *mc;
+ OM_uint32 maj, junk;
+
+ if (minor_status == NULL)
+ return GSS_S_FAILURE;
+ if (elements_stored)
+ *elements_stored = NULL;
+ if (cred_usage_stored)
+ *cred_usage_stored = 0;
+
+ if (cred == NULL)
+ return GSS_S_NO_CONTEXT;
+
+ if (elements_stored) {
+ maj = gss_create_empty_oid_set(minor_status, elements_stored);
+ if (maj != GSS_S_COMPLETE)
+ return maj;
+ }
+
+ HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ gssapi_mech_interface m = mc->gmc_mech;
+
+ if (m == NULL || m->gm_store_cred == NULL)
+ continue;
+
+ if (desired_mech) {
+ maj = gss_oid_equal(&m->gm_mech_oid, desired_mech);
+ if (maj != 0)
+ continue;
+ }
+
+ maj = (m->gm_store_cred)(minor_status, mc->gmc_cred,
+ cred_usage, desired_mech, overwrite_cred,
+ default_cred, NULL, cred_usage_stored);
+ if (maj != GSS_S_COMPLETE) {
+ gss_release_oid_set(&junk, elements_stored);
+ return maj;
+ }
+
+ if (elements_stored) {
+ gss_add_oid_set_member(&junk,
+ &m->gm_mech_oid,
+ elements_stored);
+ }
+
+ }
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c b/crypto/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c
new file mode 100644
index 0000000..715d34b
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_test_oid_set_member.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_test_oid_set_member(OM_uint32 *minor_status,
+ const gss_OID member,
+ const gss_OID_set set,
+ int *present)
+{
+ size_t i;
+
+ *present = 0;
+ for (i = 0; i < set->count; i++)
+ if (gss_oid_equal(member, &set->elements[i]))
+ *present = 1;
+
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_unseal.c b/crypto/heimdal/lib/gssapi/mech/gss_unseal.c
new file mode 100644
index 0000000..0add03d
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_unseal.c
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_unseal.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_unseal(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int *conf_state,
+ int *qop_state)
+{
+
+ return (gss_unwrap(minor_status,
+ context_handle, input_message_buffer,
+ output_message_buffer, conf_state, (gss_qop_t *)qop_state));
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_unwrap.c b/crypto/heimdal/lib/gssapi/mech/gss_unwrap.c
new file mode 100644
index 0000000..d0d18ac
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_unwrap.c
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_unwrap.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_unwrap(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int *conf_state,
+ gss_qop_t *qop_state)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ gssapi_mech_interface m = ctx->gc_mech;
+
+ return (m->gm_unwrap(minor_status, ctx->gc_ctx,
+ input_message_buffer, output_message_buffer,
+ conf_state, qop_state));
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_utils.c b/crypto/heimdal/lib/gssapi/mech/gss_utils.c
new file mode 100644
index 0000000..2071621b
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_utils.c
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_utils.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+OM_uint32
+_gss_copy_oid(OM_uint32 *minor_status,
+ const gss_OID from_oid, gss_OID to_oid)
+{
+ size_t len = from_oid->length;
+
+ *minor_status = 0;
+ to_oid->elements = malloc(len);
+ if (!to_oid->elements) {
+ to_oid->length = 0;
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ to_oid->length = len;
+ memcpy(to_oid->elements, from_oid->elements, len);
+ return (GSS_S_COMPLETE);
+}
+
+OM_uint32
+_gss_free_oid(OM_uint32 *minor_status, gss_OID oid)
+{
+ *minor_status = 0;
+ if (oid->elements) {
+ free(oid->elements);
+ oid->elements = NULL;
+ oid->length = 0;
+ }
+ return (GSS_S_COMPLETE);
+}
+
+OM_uint32
+_gss_copy_buffer(OM_uint32 *minor_status,
+ const gss_buffer_t from_buf, gss_buffer_t to_buf)
+{
+ size_t len = from_buf->length;
+
+ *minor_status = 0;
+ to_buf->value = malloc(len);
+ if (!to_buf->value) {
+ *minor_status = ENOMEM;
+ to_buf->length = 0;
+ return GSS_S_FAILURE;
+ }
+ to_buf->length = len;
+ memcpy(to_buf->value, from_buf->value, len);
+ return (GSS_S_COMPLETE);
+}
+
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_verify.c b/crypto/heimdal/lib/gssapi/mech/gss_verify.c
new file mode 100644
index 0000000..dd53ddb
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_verify.c
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_verify.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_verify(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ gss_buffer_t message_buffer,
+ gss_buffer_t token_buffer,
+ int *qop_state)
+{
+
+ return (gss_verify_mic(minor_status,
+ context_handle, message_buffer, token_buffer,
+ (gss_qop_t *)qop_state));
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_verify_mic.c b/crypto/heimdal/lib/gssapi/mech/gss_verify_mic.c
new file mode 100644
index 0000000..a791dc7
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_verify_mic.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_verify_mic.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_verify_mic(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t *qop_state)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ gssapi_mech_interface m;
+
+ if (qop_state)
+ *qop_state = 0;
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ m = ctx->gc_mech;
+
+ return (m->gm_verify_mic(minor_status, ctx->gc_ctx,
+ message_buffer, token_buffer, qop_state));
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_wrap.c b/crypto/heimdal/lib/gssapi/mech/gss_wrap.c
new file mode 100644
index 0000000..d9864b3
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_wrap.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_wrap.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+/**
+ * Wrap a message using either confidentiality (encryption +
+ * signature) or sealing (signature).
+ *
+ * @param minor_status minor status code.
+ * @param context_handle context handle.
+ * @param conf_req_flag if non zero, confidentiality is requestd.
+ * @param qop_req type of protection needed, in most cases it GSS_C_QOP_DEFAULT should be passed in.
+ * @param input_message_buffer messages to wrap
+ * @param conf_state returns non zero if confidentiality was honoured.
+ * @param output_message_buffer the resulting buffer, release with gss_release_buffer().
+ *
+ * @ingroup gssapi
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_wrap(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ const gss_buffer_t input_message_buffer,
+ int *conf_state,
+ gss_buffer_t output_message_buffer)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ gssapi_mech_interface m;
+
+ if (conf_state)
+ *conf_state = 0;
+ _mg_buffer_zero(output_message_buffer);
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ m = ctx->gc_mech;
+
+ return (m->gm_wrap(minor_status, ctx->gc_ctx,
+ conf_req_flag, qop_req, input_message_buffer,
+ conf_state, output_message_buffer));
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c b/crypto/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c
new file mode 100644
index 0000000..9bebcf6
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/gss_wrap_size_limit.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_wrap_size_limit(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 *max_input_size)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ gssapi_mech_interface m;
+
+ *max_input_size = 0;
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ m = ctx->gc_mech;
+
+ return (m->gm_wrap_size_limit(minor_status, ctx->gc_ctx,
+ conf_req_flag, qop_req, req_output_size, max_input_size));
+}
diff --git a/crypto/heimdal/lib/gssapi/mech/gssapi.asn1 b/crypto/heimdal/lib/gssapi/mech/gssapi.asn1
new file mode 100644
index 0000000..1ba7b40
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/gssapi.asn1
@@ -0,0 +1,12 @@
+-- $Id$
+
+GSS-API DEFINITIONS ::= BEGIN
+
+IMPORTS heim_any_set FROM heim;
+
+GSSAPIContextToken ::= [APPLICATION 0] IMPLICIT SEQUENCE {
+ thisMech OBJECT IDENTIFIER,
+ innerContextToken heim_any_set
+}
+
+END \ No newline at end of file
diff --git a/crypto/heimdal/lib/gssapi/mech/mech.5 b/crypto/heimdal/lib/gssapi/mech/mech.5
new file mode 100644
index 0000000..e7b083d
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/mech.5
@@ -0,0 +1,94 @@
+.\" Copyright (c) 2005 Doug Rabson
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+.\"
+.\" $FreeBSD: src/lib/libgssapi/mech.5,v 1.1 2005/12/29 14:40:20 dfr Exp $
+.Dd November 14, 2005
+.Dt MECH 5
+.Os
+.Sh NAME
+.Nm mech ,
+.Nm qop
+.Nd "GSS-API Mechanism and QOP files"
+.Sh SYNOPSIS
+.Pa "/etc/gss/mech"
+.Pa "/etc/gss/qop"
+.Sh DESCRIPTION
+The
+.Pa "/etc/gss/mech"
+file contains a list of installed GSS-API security mechanisms.
+Each line of the file either contains a comment if the first character
+is '#' or it contains five fields with the following meanings:
+.Bl -tag
+.It Name
+The name of this GSS-API mechanism.
+.It Object identifier
+The OID for this mechanism.
+.It Library
+A shared library containing the implementation of this mechanism.
+.It Kernel module (optional)
+A kernel module containing the implementation of this mechanism (not
+yet supported in FreeBSD).
+.It Library options (optional)
+Optionsal parameters interpreted by the mechanism. Library options
+must be enclosed in brackets ([ ]) to differentiate them from the
+optional kernel module entry.
+.El
+.Pp
+The
+.Pa "/etc/gss/qop"
+file contains a list of Quality of Protection values for use with
+GSS-API.
+Each line of the file either contains a comment if the first character
+is '#' or it contains three fields with the following meanings:
+.Bl -tag
+.It QOP string
+The name of this Quality of Protection algorithm.
+.It QOP value
+The numeric value used to select this algorithm for use with GSS-API
+functions such as
+.Xr gss_get_mic 3 .
+.It Mechanism name
+The GSS-API mechanism name that corresponds to this algorithm.
+.El
+.Sh EXAMPLES
+This is a typical entry from
+.Pa "/etc/gss/mech" :
+.Bd -literal
+kerberosv5 1.2.840.113554.1.2.2 /usr/lib/libgssapi_krb5.so.8 -
+.Ed
+.Pp
+This is a typical entry from
+.Pa "/etc/gss/qop" :
+.Bd -literal
+GSS_KRB5_CONF_C_QOP_DES 0x0100 kerberosv5
+.Ed
+.Sh HISTORY
+The
+.Nm
+manual page example first appeared in
+.Fx 7.0 .
+.Sh AUTHORS
+This
+manual page was written by
+.An Doug Rabson Aq dfr@FreeBSD.org .
diff --git a/crypto/heimdal/lib/gssapi/mech/mech.cat5 b/crypto/heimdal/lib/gssapi/mech/mech.cat5
new file mode 100644
index 0000000..821a193
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/mech.cat5
@@ -0,0 +1,61 @@
+
+MECH(5) BSD File Formats Manual MECH(5)
+
+NNAAMMEE
+ mmeecchh, qqoopp -- GSS-API Mechanism and QOP files
+
+SSYYNNOOPPSSIISS
+ _/_e_t_c_/_g_s_s_/_m_e_c_h _/_e_t_c_/_g_s_s_/_q_o_p
+
+DDEESSCCRRIIPPTTIIOONN
+ The _/_e_t_c_/_g_s_s_/_m_e_c_h file contains a list of installed GSS-API security
+ mechanisms. Each line of the file either contains a comment if the first
+ character is '#' or it contains five fields with the following meanings:
+
+ Name The name of this GSS-API mechanism.
+
+ Object identifier
+ The OID for this mechanism.
+
+ Library A shared library containing the implementation of this
+ mechanism.
+
+ Kernel module (optional)
+ A kernel module containing the implementation of this mech-
+ anism (not yet supported in FreeBSD).
+
+ Library options (optional)
+ Optionsal parameters interpreted by the mechanism. Library
+ options must be enclosed in brackets ([ ]) to differentiate
+ them from the optional kernel module entry.
+
+ The _/_e_t_c_/_g_s_s_/_q_o_p file contains a list of Quality of Protection values for
+ use with GSS-API. Each line of the file either contains a comment if the
+ first character is '#' or it contains three fields with the following
+ meanings:
+
+ QOP string The name of this Quality of Protection algorithm.
+
+ QOP value The numeric value used to select this algorithm for use
+ with GSS-API functions such as gss_get_mic(3).
+
+ Mechanism name
+ The GSS-API mechanism name that corresponds to this algo-
+ rithm.
+
+EEXXAAMMPPLLEESS
+ This is a typical entry from _/_e_t_c_/_g_s_s_/_m_e_c_h:
+
+ kerberosv5 1.2.840.113554.1.2.2 /usr/lib/libgssapi_krb5.so.8 -
+
+ This is a typical entry from _/_e_t_c_/_g_s_s_/_q_o_p:
+
+ GSS_KRB5_CONF_C_QOP_DES 0x0100 kerberosv5
+
+HHIISSTTOORRYY
+ The mmeecchh manual page example first appeared in FreeBSD 7.0.
+
+AAUUTTHHOORRSS
+ This manual page was written by Doug Rabson <dfr@FreeBSD.org>.
+
+BSD November 14, 2005 BSD
diff --git a/crypto/heimdal/lib/gssapi/mech/mech_locl.h b/crypto/heimdal/lib/gssapi/mech/mech_locl.h
new file mode 100644
index 0000000..6c23ac5
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/mech_locl.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+#include <config.h>
+
+#include <krb5-types.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <dlfcn.h>
+#include <errno.h>
+
+#include <gssapi_asn1.h>
+#include <der.h>
+
+#include <roken.h>
+
+#include <gssapi.h>
+#include <gssapi_mech.h>
+#include <gssapi_krb5.h>
+
+#include "mechqueue.h"
+
+#include "context.h"
+#include "cred.h"
+#include "mech_switch.h"
+#include "name.h"
+#include "utils.h"
+#include "compat.h"
+
+#define _mg_buffer_zero(buffer) \
+ do { \
+ if (buffer) { \
+ (buffer)->value = NULL; \
+ (buffer)->length = 0; \
+ } \
+ } while(0)
+
+#define _mg_oid_set_zero(oid_set) \
+ do { \
+ if (oid_set) { \
+ (oid_set)->elements = NULL; \
+ (oid_set)->count = 0; \
+ } \
+ } while(0)
diff --git a/crypto/heimdal/lib/gssapi/mech/mech_switch.h b/crypto/heimdal/lib/gssapi/mech/mech_switch.h
new file mode 100644
index 0000000..7ed3d4d
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/mech_switch.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/mech_switch.h,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ * $Id$
+ */
+
+#include <gssapi_mech.h>
+
+struct _gss_mech_switch {
+ HEIM_SLIST_ENTRY(_gss_mech_switch) gm_link;
+ gss_OID_desc gm_mech_oid;
+ gss_OID_set gm_name_types;
+ void *gm_so;
+ gssapi_mech_interface_desc gm_mech;
+};
+HEIM_SLIST_HEAD(_gss_mech_switch_list, _gss_mech_switch);
+extern struct _gss_mech_switch_list _gss_mechs;
+extern gss_OID_set _gss_mech_oids;
+
+void _gss_load_mech(void);
diff --git a/crypto/heimdal/lib/gssapi/mech/mechqueue.h b/crypto/heimdal/lib/gssapi/mech/mechqueue.h
new file mode 100644
index 0000000..95941ba
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/mechqueue.h
@@ -0,0 +1,97 @@
+/* $NetBSD: queue.h,v 1.39 2004/04/18 14:25:34 lukem Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef _MECHQUEUE_H_
+#define _MECHQUEUE_H_
+
+/*
+ * Singly-linked List definitions.
+ */
+#define HEIM_SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#define HEIM_SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define HEIM_SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define HEIM_SLIST_INIT(head) do { \
+ (head)->slh_first = NULL; \
+} while (/*CONSTCOND*/0)
+
+#define HEIM_SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ (elm)->field.sle_next = (slistelm)->field.sle_next; \
+ (slistelm)->field.sle_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define HEIM_SLIST_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.sle_next = (head)->slh_first; \
+ (head)->slh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define HEIM_SLIST_REMOVE_HEAD(head, field) do { \
+ (head)->slh_first = (head)->slh_first->field.sle_next; \
+} while (/*CONSTCOND*/0)
+
+#define HEIM_SLIST_REMOVE(head, elm, type, field) do { \
+ if ((head)->slh_first == (elm)) { \
+ HEIM_SLIST_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ struct type *curelm = (head)->slh_first; \
+ while(curelm->field.sle_next != (elm)) \
+ curelm = curelm->field.sle_next; \
+ curelm->field.sle_next = \
+ curelm->field.sle_next->field.sle_next; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define HEIM_SLIST_FOREACH(var, head, field) \
+ for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
+
+/*
+ * Singly-linked List access methods.
+ */
+#define HEIM_SLIST_EMPTY(head) ((head)->slh_first == NULL)
+#define HEIM_SLIST_FIRST(head) ((head)->slh_first)
+#define HEIM_SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+#endif /* !_MECHQUEUE_H_ */
diff --git a/crypto/heimdal/lib/gssapi/mech/name.h b/crypto/heimdal/lib/gssapi/mech/name.h
new file mode 100644
index 0000000..4baeebf
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/name.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/name.h,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ * $Id$
+ */
+
+struct _gss_mechanism_name {
+ HEIM_SLIST_ENTRY(_gss_mechanism_name) gmn_link;
+ gssapi_mech_interface gmn_mech; /* mechanism ops for MN */
+ gss_OID gmn_mech_oid; /* mechanism oid for MN */
+ gss_name_t gmn_name; /* underlying MN */
+};
+HEIM_SLIST_HEAD(_gss_mechanism_name_list, _gss_mechanism_name);
+
+struct _gss_name {
+ gss_OID_desc gn_type; /* type of name */
+ gss_buffer_desc gn_value; /* value (as imported) */
+ struct _gss_mechanism_name_list gn_mn; /* list of MNs */
+};
+
+OM_uint32
+ _gss_find_mn(OM_uint32 *, struct _gss_name *, gss_OID,
+ struct _gss_mechanism_name **);
+struct _gss_name *
+ _gss_make_name(gssapi_mech_interface m, gss_name_t new_mn);
diff --git a/crypto/heimdal/lib/gssapi/mech/utils.h b/crypto/heimdal/lib/gssapi/mech/utils.h
new file mode 100644
index 0000000..7b27d38
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/mech/utils.h
@@ -0,0 +1,33 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libgssapi/utils.h,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ * $Id$
+ */
+
+OM_uint32 _gss_free_oid(OM_uint32 *, gss_OID);
+OM_uint32 _gss_copy_oid(OM_uint32 *, const gss_OID, gss_OID);
+OM_uint32 _gss_copy_buffer(OM_uint32 *minor_status,
+ const gss_buffer_t from_buf, gss_buffer_t to_buf);
diff --git a/crypto/heimdal/lib/gssapi/ntlm/accept_sec_context.c b/crypto/heimdal/lib/gssapi/ntlm/accept_sec_context.c
new file mode 100644
index 0000000..533fc15
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/accept_sec_context.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+/*
+ *
+ */
+
+OM_uint32
+_gss_ntlm_allocate_ctx(OM_uint32 *minor_status, ntlm_ctx *ctx)
+{
+ OM_uint32 maj_stat;
+ struct ntlm_server_interface *ns_interface = NULL;
+
+#ifdef DIGEST
+ ns_interface = &ntlmsspi_kdc_digest;
+#endif
+ if (ns_interface == NULL)
+ return GSS_S_FAILURE;
+
+ *ctx = calloc(1, sizeof(**ctx));
+
+ (*ctx)->server = ns_interface;
+
+ maj_stat = (*(*ctx)->server->nsi_init)(minor_status, &(*ctx)->ictx);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ *
+ */
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_accept_sec_context
+(OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ const gss_channel_bindings_t input_chan_bindings,
+ gss_name_t * src_name,
+ gss_OID * mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec,
+ gss_cred_id_t * delegated_cred_handle
+ )
+{
+ krb5_error_code ret;
+ struct ntlm_buf data;
+ OM_uint32 junk;
+ ntlm_ctx ctx;
+
+ output_token->value = NULL;
+ output_token->length = 0;
+
+ *minor_status = 0;
+
+ if (context_handle == NULL)
+ return GSS_S_FAILURE;
+
+ if (input_token_buffer == GSS_C_NO_BUFFER)
+ return GSS_S_FAILURE;
+
+ if (src_name)
+ *src_name = GSS_C_NO_NAME;
+ if (mech_type)
+ *mech_type = GSS_C_NO_OID;
+ if (ret_flags)
+ *ret_flags = 0;
+ if (time_rec)
+ *time_rec = 0;
+ if (delegated_cred_handle)
+ *delegated_cred_handle = GSS_C_NO_CREDENTIAL;
+
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ struct ntlm_type1 type1;
+ OM_uint32 major_status;
+ OM_uint32 retflags;
+ struct ntlm_buf out;
+
+ major_status = _gss_ntlm_allocate_ctx(minor_status, &ctx);
+ if (major_status)
+ return major_status;
+ *context_handle = (gss_ctx_id_t)ctx;
+
+ /* check if the mechs is allowed by remote service */
+ major_status = (*ctx->server->nsi_probe)(minor_status, ctx->ictx, NULL);
+ if (major_status) {
+ _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
+ return major_status;
+ }
+
+ data.data = input_token_buffer->value;
+ data.length = input_token_buffer->length;
+
+ ret = heim_ntlm_decode_type1(&data, &type1);
+ if (ret) {
+ _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ if ((type1.flags & NTLM_NEG_UNICODE) == 0) {
+ heim_ntlm_free_type1(&type1);
+ _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (type1.flags & NTLM_NEG_SIGN)
+ ctx->gssflags |= GSS_C_CONF_FLAG;
+ if (type1.flags & NTLM_NEG_SIGN)
+ ctx->gssflags |= GSS_C_INTEG_FLAG;
+
+ major_status = (*ctx->server->nsi_type2)(minor_status,
+ ctx->ictx,
+ type1.flags,
+ type1.hostname,
+ type1.domain,
+ &retflags,
+ &out);
+ heim_ntlm_free_type1(&type1);
+ if (major_status != GSS_S_COMPLETE) {
+ OM_uint32 gunk;
+ _gss_ntlm_delete_sec_context(&gunk, context_handle, NULL);
+ return major_status;
+ }
+
+ output_token->value = malloc(out.length);
+ if (output_token->value == NULL && out.length != 0) {
+ OM_uint32 gunk;
+ _gss_ntlm_delete_sec_context(&gunk, context_handle, NULL);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy(output_token->value, out.data, out.length);
+ output_token->length = out.length;
+
+ ctx->flags = retflags;
+
+ return GSS_S_CONTINUE_NEEDED;
+ } else {
+ OM_uint32 maj_stat;
+ struct ntlm_type3 type3;
+ struct ntlm_buf session;
+
+ ctx = (ntlm_ctx)*context_handle;
+
+ data.data = input_token_buffer->value;
+ data.length = input_token_buffer->length;
+
+ ret = heim_ntlm_decode_type3(&data, 1, &type3);
+ if (ret) {
+ _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ maj_stat = (*ctx->server->nsi_type3)(minor_status,
+ ctx->ictx,
+ &type3,
+ &session);
+ if (maj_stat) {
+ heim_ntlm_free_type3(&type3);
+ _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
+ return maj_stat;
+ }
+
+ if (src_name) {
+ ntlm_name n = calloc(1, sizeof(*n));
+ if (n) {
+ n->user = strdup(type3.username);
+ n->domain = strdup(type3.targetname);
+ }
+ if (n == NULL || n->user == NULL || n->domain == NULL) {
+ gss_name_t tempn = (gss_name_t)n;
+ _gss_ntlm_release_name(&junk, &tempn);
+ heim_ntlm_free_type3(&type3);
+ _gss_ntlm_delete_sec_context(minor_status,
+ context_handle, NULL);
+ return maj_stat;
+ }
+ *src_name = (gss_name_t)n;
+ }
+
+ heim_ntlm_free_type3(&type3);
+
+ ret = krb5_data_copy(&ctx->sessionkey,
+ session.data, session.length);
+ if (ret) {
+ if (src_name)
+ _gss_ntlm_release_name(&junk, src_name);
+ _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ if (session.length != 0) {
+
+ ctx->status |= STATUS_SESSIONKEY;
+
+ if (ctx->flags & NTLM_NEG_NTLM2_SESSION) {
+ _gss_ntlm_set_key(&ctx->u.v2.send, 1,
+ (ctx->flags & NTLM_NEG_KEYEX),
+ ctx->sessionkey.data,
+ ctx->sessionkey.length);
+ _gss_ntlm_set_key(&ctx->u.v2.recv, 0,
+ (ctx->flags & NTLM_NEG_KEYEX),
+ ctx->sessionkey.data,
+ ctx->sessionkey.length);
+ } else {
+ RC4_set_key(&ctx->u.v1.crypto_send.key,
+ ctx->sessionkey.length,
+ ctx->sessionkey.data);
+ RC4_set_key(&ctx->u.v1.crypto_recv.key,
+ ctx->sessionkey.length,
+ ctx->sessionkey.data);
+ }
+ }
+
+ if (mech_type)
+ *mech_type = GSS_NTLM_MECHANISM;
+ if (time_rec)
+ *time_rec = GSS_C_INDEFINITE;
+
+ ctx->status |= STATUS_OPEN;
+
+ if (ret_flags)
+ *ret_flags = ctx->gssflags;
+
+ return GSS_S_COMPLETE;
+ }
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/acquire_cred.c b/crypto/heimdal/lib/gssapi/ntlm/acquire_cred.c
new file mode 100644
index 0000000..b186271
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/acquire_cred.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV _gss_ntlm_acquire_cred
+ (OM_uint32 * min_stat,
+ const gss_name_t desired_name,
+ OM_uint32 time_req,
+ const gss_OID_set desired_mechs,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t * output_cred_handle,
+ gss_OID_set * actual_mechs,
+ OM_uint32 * time_rec
+ )
+{
+ ntlm_name name = (ntlm_name) desired_name;
+ OM_uint32 maj_stat;
+ ntlm_ctx ctx;
+
+ *min_stat = 0;
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+ if (actual_mechs)
+ *actual_mechs = GSS_C_NO_OID_SET;
+ if (time_rec)
+ *time_rec = GSS_C_INDEFINITE;
+
+ if (desired_name == NULL)
+ return GSS_S_NO_CRED;
+
+ if (cred_usage == GSS_C_BOTH || cred_usage == GSS_C_ACCEPT) {
+
+ maj_stat = _gss_ntlm_allocate_ctx(min_stat, &ctx);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+
+ maj_stat = (*ctx->server->nsi_probe)(min_stat, ctx->ictx,
+ name->domain);
+ {
+ gss_ctx_id_t context = (gss_ctx_id_t)ctx;
+ OM_uint32 junk;
+ _gss_ntlm_delete_sec_context(&junk, &context, NULL);
+ }
+ if (maj_stat)
+ return maj_stat;
+ }
+ if (cred_usage == GSS_C_BOTH || cred_usage == GSS_C_INITIATE) {
+ ntlm_cred cred;
+
+ *min_stat = _gss_ntlm_get_user_cred(name, &cred);
+ if (*min_stat)
+ return GSS_S_FAILURE;
+ cred->usage = cred_usage;
+
+ *output_cred_handle = (gss_cred_id_t)cred;
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/add_cred.c b/crypto/heimdal/lib/gssapi/ntlm/add_cred.c
new file mode 100644
index 0000000..7c6b5ba
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/add_cred.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV _gss_ntlm_add_cred (
+ OM_uint32 *minor_status,
+ const gss_cred_id_t input_cred_handle,
+ const gss_name_t desired_name,
+ const gss_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ OM_uint32 initiator_time_req,
+ OM_uint32 acceptor_time_req,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *initiator_time_rec,
+ OM_uint32 *acceptor_time_rec)
+{
+ if (minor_status)
+ *minor_status = 0;
+ if (output_cred_handle)
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+ if (actual_mechs)
+ *actual_mechs = GSS_C_NO_OID_SET;
+ if (initiator_time_rec)
+ *initiator_time_rec = 0;
+ if (acceptor_time_rec)
+ *acceptor_time_rec = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/canonicalize_name.c b/crypto/heimdal/lib/gssapi/ntlm/canonicalize_name.c
new file mode 100644
index 0000000..0ea6429
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/canonicalize_name.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_canonicalize_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ const gss_OID mech_type,
+ gss_name_t * output_name
+ )
+{
+ return gss_duplicate_name (minor_status, input_name, output_name);
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/compare_name.c b/crypto/heimdal/lib/gssapi/ntlm/compare_name.c
new file mode 100644
index 0000000..6e095bd
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/compare_name.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV _gss_ntlm_compare_name
+ (OM_uint32 * minor_status,
+ const gss_name_t name1,
+ const gss_name_t name2,
+ int * name_equal
+ )
+{
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/context_time.c b/crypto/heimdal/lib/gssapi/ntlm/context_time.c
new file mode 100644
index 0000000..73debda
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/context_time.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV _gss_ntlm_context_time
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ OM_uint32 * time_rec
+ )
+{
+ if (time_rec)
+ *time_rec = GSS_C_INDEFINITE;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/creds.c b/crypto/heimdal/lib/gssapi/ntlm/creds.c
new file mode 100644
index 0000000..ffbf355
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/creds.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_inquire_cred
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ gss_name_t * name,
+ OM_uint32 * lifetime,
+ gss_cred_usage_t * cred_usage,
+ gss_OID_set * mechanisms
+ )
+{
+ OM_uint32 ret, junk;
+
+ *minor_status = 0;
+
+ if (cred_handle == NULL)
+ return GSS_S_NO_CRED;
+
+ if (name) {
+ ntlm_name n = calloc(1, sizeof(*n));
+ ntlm_cred c = (ntlm_cred)cred_handle;
+ if (n) {
+ n->user = strdup(c->username);
+ n->domain = strdup(c->domain);
+ }
+ if (n == NULL || n->user == NULL || n->domain == NULL) {
+ if (n)
+ free(n->user);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ *name = (gss_name_t)n;
+ }
+ if (lifetime)
+ *lifetime = GSS_C_INDEFINITE;
+ if (cred_usage)
+ *cred_usage = 0;
+ if (mechanisms)
+ *mechanisms = GSS_C_NO_OID_SET;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL)
+ return GSS_S_NO_CRED;
+
+ if (mechanisms) {
+ ret = gss_create_empty_oid_set(minor_status, mechanisms);
+ if (ret)
+ goto out;
+ ret = gss_add_oid_set_member(minor_status,
+ GSS_NTLM_MECHANISM,
+ mechanisms);
+ if (ret)
+ goto out;
+ }
+
+ return GSS_S_COMPLETE;
+out:
+ gss_release_oid_set(&junk, mechanisms);
+ return ret;
+}
+
+#ifdef HAVE_KCM
+static OM_uint32
+_gss_ntlm_destroy_kcm_cred(gss_cred_id_t *cred_handle)
+{
+ krb5_storage *request, *response;
+ krb5_data response_data;
+ krb5_context context;
+ krb5_error_code ret;
+ ntlm_cred cred;
+
+ cred = (ntlm_cred)*cred_handle;
+
+ ret = krb5_init_context(&context);
+ if (ret)
+ return ret;
+
+ ret = krb5_kcm_storage_request(context, KCM_OP_DEL_NTLM_CRED, &request);
+ if (ret)
+ goto out;
+
+ ret = krb5_store_stringz(request, cred->username);
+ if (ret)
+ goto out;
+
+ ret = krb5_store_stringz(request, cred->domain);
+ if (ret)
+ goto out;
+
+ ret = krb5_kcm_call(context, request, &response, &response_data);
+ if (ret)
+ goto out;
+
+ krb5_storage_free(request);
+ krb5_storage_free(response);
+ krb5_data_free(&response_data);
+
+ out:
+ krb5_free_context(context);
+
+ return ret;
+}
+#endif /* HAVE_KCM */
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_destroy_cred(OM_uint32 *minor_status,
+ gss_cred_id_t *cred_handle)
+{
+#ifdef HAVE_KCM
+ krb5_error_code ret;
+#endif
+
+ if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL)
+ return GSS_S_COMPLETE;
+
+#ifdef HAVE_KCM
+ ret = _gss_ntlm_destroy_kcm_cred(cred_handle);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+#endif
+
+ return _gss_ntlm_release_cred(minor_status, cred_handle);
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/crypto.c b/crypto/heimdal/lib/gssapi/ntlm/crypto.c
new file mode 100644
index 0000000..85dc638
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/crypto.c
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+uint32_t
+_krb5_crc_update (const char *p, size_t len, uint32_t res);
+void
+_krb5_crc_init_table(void);
+
+/*
+ *
+ */
+
+static void
+encode_le_uint32(uint32_t n, unsigned char *p)
+{
+ p[0] = (n >> 0) & 0xFF;
+ p[1] = (n >> 8) & 0xFF;
+ p[2] = (n >> 16) & 0xFF;
+ p[3] = (n >> 24) & 0xFF;
+}
+
+
+static void
+decode_le_uint32(const void *ptr, uint32_t *n)
+{
+ const unsigned char *p = ptr;
+ *n = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+/*
+ *
+ */
+
+const char a2i_signmagic[] =
+ "session key to server-to-client signing key magic constant";
+const char a2i_sealmagic[] =
+ "session key to server-to-client sealing key magic constant";
+const char i2a_signmagic[] =
+ "session key to client-to-server signing key magic constant";
+const char i2a_sealmagic[] =
+ "session key to client-to-server sealing key magic constant";
+
+
+void
+_gss_ntlm_set_key(struct ntlmv2_key *key, int acceptor, int sealsign,
+ unsigned char *data, size_t len)
+{
+ unsigned char out[16];
+ EVP_MD_CTX *ctx;
+ const char *signmagic;
+ const char *sealmagic;
+
+ if (acceptor) {
+ signmagic = a2i_signmagic;
+ sealmagic = a2i_sealmagic;
+ } else {
+ signmagic = i2a_signmagic;
+ sealmagic = i2a_sealmagic;
+ }
+
+ key->seq = 0;
+
+ ctx = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+ EVP_DigestUpdate(ctx, data, len);
+ EVP_DigestUpdate(ctx, signmagic, strlen(signmagic) + 1);
+ EVP_DigestFinal_ex(ctx, key->signkey, NULL);
+
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+ EVP_DigestUpdate(ctx, data, len);
+ EVP_DigestUpdate(ctx, sealmagic, strlen(sealmagic) + 1);
+ EVP_DigestFinal_ex(ctx, out, NULL);
+ EVP_MD_CTX_destroy(ctx);
+
+ RC4_set_key(&key->sealkey, 16, out);
+ if (sealsign)
+ key->signsealkey = &key->sealkey;
+}
+
+/*
+ *
+ */
+
+static OM_uint32
+v1_sign_message(gss_buffer_t in,
+ RC4_KEY *signkey,
+ uint32_t seq,
+ unsigned char out[16])
+{
+ unsigned char sigature[12];
+ uint32_t crc;
+
+ _krb5_crc_init_table();
+ crc = _krb5_crc_update(in->value, in->length, 0);
+
+ encode_le_uint32(0, &sigature[0]);
+ encode_le_uint32(crc, &sigature[4]);
+ encode_le_uint32(seq, &sigature[8]);
+
+ encode_le_uint32(1, out); /* version */
+ RC4(signkey, sizeof(sigature), sigature, out + 4);
+
+ if (RAND_bytes(out + 4, 4) != 1)
+ return GSS_S_UNAVAILABLE;
+
+ return 0;
+}
+
+
+static OM_uint32
+v2_sign_message(gss_buffer_t in,
+ unsigned char signkey[16],
+ RC4_KEY *sealkey,
+ uint32_t seq,
+ unsigned char out[16])
+{
+ unsigned char hmac[16];
+ unsigned int hmaclen;
+ HMAC_CTX c;
+
+ HMAC_CTX_init(&c);
+ HMAC_Init_ex(&c, signkey, 16, EVP_md5(), NULL);
+
+ encode_le_uint32(seq, hmac);
+ HMAC_Update(&c, hmac, 4);
+ HMAC_Update(&c, in->value, in->length);
+ HMAC_Final(&c, hmac, &hmaclen);
+ HMAC_CTX_cleanup(&c);
+
+ encode_le_uint32(1, &out[0]);
+ if (sealkey)
+ RC4(sealkey, 8, hmac, &out[4]);
+ else
+ memcpy(&out[4], hmac, 8);
+
+ memset(&out[12], 0, 4);
+
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+v2_verify_message(gss_buffer_t in,
+ unsigned char signkey[16],
+ RC4_KEY *sealkey,
+ uint32_t seq,
+ const unsigned char checksum[16])
+{
+ OM_uint32 ret;
+ unsigned char out[16];
+
+ ret = v2_sign_message(in, signkey, sealkey, seq, out);
+ if (ret)
+ return ret;
+
+ if (memcmp(checksum, out, 16) != 0)
+ return GSS_S_BAD_MIC;
+
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+v2_seal_message(const gss_buffer_t in,
+ unsigned char signkey[16],
+ uint32_t seq,
+ RC4_KEY *sealkey,
+ gss_buffer_t out)
+{
+ unsigned char *p;
+ OM_uint32 ret;
+
+ if (in->length + 16 < in->length)
+ return EINVAL;
+
+ p = malloc(in->length + 16);
+ if (p == NULL)
+ return ENOMEM;
+
+ RC4(sealkey, in->length, in->value, p);
+
+ ret = v2_sign_message(in, signkey, sealkey, seq, &p[in->length]);
+ if (ret) {
+ free(p);
+ return ret;
+ }
+
+ out->value = p;
+ out->length = in->length + 16;
+
+ return 0;
+}
+
+static OM_uint32
+v2_unseal_message(gss_buffer_t in,
+ unsigned char signkey[16],
+ uint32_t seq,
+ RC4_KEY *sealkey,
+ gss_buffer_t out)
+{
+ OM_uint32 ret;
+
+ if (in->length < 16)
+ return GSS_S_BAD_MIC;
+
+ out->length = in->length - 16;
+ out->value = malloc(out->length);
+ if (out->value == NULL)
+ return GSS_S_BAD_MIC;
+
+ RC4(sealkey, out->length, in->value, out->value);
+
+ ret = v2_verify_message(out, signkey, sealkey, seq,
+ ((const unsigned char *)in->value) + out->length);
+ if (ret) {
+ OM_uint32 junk;
+ gss_release_buffer(&junk, out);
+ }
+ return ret;
+}
+
+/*
+ *
+ */
+
+#define CTX_FLAGS_ISSET(_ctx,_flags) \
+ (((_ctx)->flags & (_flags)) == (_flags))
+
+/*
+ *
+ */
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_get_mic
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_qop_t qop_req,
+ const gss_buffer_t message_buffer,
+ gss_buffer_t message_token
+ )
+{
+ ntlm_ctx ctx = (ntlm_ctx)context_handle;
+ OM_uint32 junk;
+
+ *minor_status = 0;
+
+ message_token->value = malloc(16);
+ message_token->length = 16;
+ if (message_token->value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SIGN|NTLM_NEG_NTLM2_SESSION)) {
+ OM_uint32 ret;
+
+ if ((ctx->status & STATUS_SESSIONKEY) == 0) {
+ gss_release_buffer(&junk, message_token);
+ return GSS_S_UNAVAILABLE;
+ }
+
+ ret = v2_sign_message(message_buffer,
+ ctx->u.v2.send.signkey,
+ ctx->u.v2.send.signsealkey,
+ ctx->u.v2.send.seq++,
+ message_token->value);
+ if (ret)
+ gss_release_buffer(&junk, message_token);
+ return ret;
+
+ } else if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SIGN)) {
+ OM_uint32 ret;
+
+ if ((ctx->status & STATUS_SESSIONKEY) == 0) {
+ gss_release_buffer(&junk, message_token);
+ return GSS_S_UNAVAILABLE;
+ }
+
+ ret = v1_sign_message(message_buffer,
+ &ctx->u.v1.crypto_send.key,
+ ctx->u.v1.crypto_send.seq++,
+ message_token->value);
+ if (ret)
+ gss_release_buffer(&junk, message_token);
+ return ret;
+
+ } else if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_ALWAYS_SIGN)) {
+ unsigned char *sigature;
+
+ sigature = message_token->value;
+
+ encode_le_uint32(1, &sigature[0]); /* version */
+ encode_le_uint32(0, &sigature[4]);
+ encode_le_uint32(0, &sigature[8]);
+ encode_le_uint32(0, &sigature[12]);
+
+ return GSS_S_COMPLETE;
+ }
+ gss_release_buffer(&junk, message_token);
+
+ return GSS_S_UNAVAILABLE;
+}
+
+/*
+ *
+ */
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_verify_mic
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t * qop_state
+ )
+{
+ ntlm_ctx ctx = (ntlm_ctx)context_handle;
+
+ if (qop_state != NULL)
+ *qop_state = GSS_C_QOP_DEFAULT;
+ *minor_status = 0;
+
+ if (token_buffer->length != 16)
+ return GSS_S_BAD_MIC;
+
+ if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SIGN|NTLM_NEG_NTLM2_SESSION)) {
+ OM_uint32 ret;
+
+ if ((ctx->status & STATUS_SESSIONKEY) == 0)
+ return GSS_S_UNAVAILABLE;
+
+ ret = v2_verify_message(message_buffer,
+ ctx->u.v2.recv.signkey,
+ ctx->u.v2.recv.signsealkey,
+ ctx->u.v2.recv.seq++,
+ token_buffer->value);
+ if (ret)
+ return ret;
+
+ return GSS_S_COMPLETE;
+ } else if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SIGN)) {
+
+ unsigned char sigature[12];
+ uint32_t crc, num;
+
+ if ((ctx->status & STATUS_SESSIONKEY) == 0)
+ return GSS_S_UNAVAILABLE;
+
+ decode_le_uint32(token_buffer->value, &num);
+ if (num != 1)
+ return GSS_S_BAD_MIC;
+
+ RC4(&ctx->u.v1.crypto_recv.key, sizeof(sigature),
+ ((unsigned char *)token_buffer->value) + 4, sigature);
+
+ _krb5_crc_init_table();
+ crc = _krb5_crc_update(message_buffer->value,
+ message_buffer->length, 0);
+ /* skip first 4 bytes in the encrypted checksum */
+ decode_le_uint32(&sigature[4], &num);
+ if (num != crc)
+ return GSS_S_BAD_MIC;
+ decode_le_uint32(&sigature[8], &num);
+ if (ctx->u.v1.crypto_recv.seq != num)
+ return GSS_S_BAD_MIC;
+ ctx->u.v1.crypto_recv.seq++;
+
+ return GSS_S_COMPLETE;
+ } else if (ctx->flags & NTLM_NEG_ALWAYS_SIGN) {
+ uint32_t num;
+ unsigned char *p;
+
+ p = (unsigned char*)(token_buffer->value);
+
+ decode_le_uint32(&p[0], &num); /* version */
+ if (num != 1) return GSS_S_BAD_MIC;
+ decode_le_uint32(&p[4], &num);
+ if (num != 0) return GSS_S_BAD_MIC;
+ decode_le_uint32(&p[8], &num);
+ if (num != 0) return GSS_S_BAD_MIC;
+ decode_le_uint32(&p[12], &num);
+ if (num != 0) return GSS_S_BAD_MIC;
+
+ return GSS_S_COMPLETE;
+ }
+
+ return GSS_S_UNAVAILABLE;
+}
+
+/*
+ *
+ */
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_wrap_size_limit (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 * max_input_size
+ )
+{
+ ntlm_ctx ctx = (ntlm_ctx)context_handle;
+
+ *minor_status = 0;
+
+ if(ctx->flags & NTLM_NEG_SEAL) {
+
+ if (req_output_size < 16)
+ *max_input_size = 0;
+ else
+ *max_input_size = req_output_size - 16;
+
+ return GSS_S_COMPLETE;
+ }
+
+ return GSS_S_UNAVAILABLE;
+}
+
+/*
+ *
+ */
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_wrap
+(OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ const gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_message_buffer
+ )
+{
+ ntlm_ctx ctx = (ntlm_ctx)context_handle;
+ OM_uint32 ret;
+
+ *minor_status = 0;
+ if (conf_state)
+ *conf_state = 0;
+ if (output_message_buffer == GSS_C_NO_BUFFER)
+ return GSS_S_FAILURE;
+
+
+ if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SEAL|NTLM_NEG_NTLM2_SESSION)) {
+
+ return v2_seal_message(input_message_buffer,
+ ctx->u.v2.send.signkey,
+ ctx->u.v2.send.seq++,
+ &ctx->u.v2.send.sealkey,
+ output_message_buffer);
+
+ } else if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SEAL)) {
+ gss_buffer_desc trailer;
+ OM_uint32 junk;
+
+ output_message_buffer->length = input_message_buffer->length + 16;
+ output_message_buffer->value = malloc(output_message_buffer->length);
+ if (output_message_buffer->value == NULL) {
+ output_message_buffer->length = 0;
+ return GSS_S_FAILURE;
+ }
+
+
+ RC4(&ctx->u.v1.crypto_send.key, input_message_buffer->length,
+ input_message_buffer->value, output_message_buffer->value);
+
+ ret = _gss_ntlm_get_mic(minor_status, context_handle,
+ 0, input_message_buffer,
+ &trailer);
+ if (ret) {
+ gss_release_buffer(&junk, output_message_buffer);
+ return ret;
+ }
+ if (trailer.length != 16) {
+ gss_release_buffer(&junk, output_message_buffer);
+ gss_release_buffer(&junk, &trailer);
+ return GSS_S_FAILURE;
+ }
+ memcpy(((unsigned char *)output_message_buffer->value) +
+ input_message_buffer->length,
+ trailer.value, trailer.length);
+ gss_release_buffer(&junk, &trailer);
+
+ return GSS_S_COMPLETE;
+ }
+
+ return GSS_S_UNAVAILABLE;
+}
+
+/*
+ *
+ */
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_unwrap
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int * conf_state,
+ gss_qop_t * qop_state
+ )
+{
+ ntlm_ctx ctx = (ntlm_ctx)context_handle;
+ OM_uint32 ret;
+
+ *minor_status = 0;
+ output_message_buffer->value = NULL;
+ output_message_buffer->length = 0;
+
+ if (conf_state)
+ *conf_state = 0;
+ if (qop_state)
+ *qop_state = 0;
+
+ if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SEAL|NTLM_NEG_NTLM2_SESSION)) {
+
+ return v2_unseal_message(input_message_buffer,
+ ctx->u.v2.recv.signkey,
+ ctx->u.v2.recv.seq++,
+ &ctx->u.v2.recv.sealkey,
+ output_message_buffer);
+
+ } else if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SEAL)) {
+
+ gss_buffer_desc trailer;
+ OM_uint32 junk;
+
+ if (input_message_buffer->length < 16)
+ return GSS_S_BAD_MIC;
+
+ output_message_buffer->length = input_message_buffer->length - 16;
+ output_message_buffer->value = malloc(output_message_buffer->length);
+ if (output_message_buffer->value == NULL) {
+ output_message_buffer->length = 0;
+ return GSS_S_FAILURE;
+ }
+
+ RC4(&ctx->u.v1.crypto_recv.key, output_message_buffer->length,
+ input_message_buffer->value, output_message_buffer->value);
+
+ trailer.value = ((unsigned char *)input_message_buffer->value) +
+ output_message_buffer->length;
+ trailer.length = 16;
+
+ ret = _gss_ntlm_verify_mic(minor_status, context_handle,
+ output_message_buffer,
+ &trailer, NULL);
+ if (ret) {
+ gss_release_buffer(&junk, output_message_buffer);
+ return ret;
+ }
+
+ return GSS_S_COMPLETE;
+ }
+
+ return GSS_S_UNAVAILABLE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/delete_sec_context.c b/crypto/heimdal/lib/gssapi/ntlm/delete_sec_context.c
new file mode 100644
index 0000000..41c30b7
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/delete_sec_context.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV _gss_ntlm_delete_sec_context
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t output_token
+ )
+{
+ if (context_handle) {
+ ntlm_ctx ctx = (ntlm_ctx)*context_handle;
+ gss_cred_id_t cred = (gss_cred_id_t)ctx->client;
+
+ *context_handle = GSS_C_NO_CONTEXT;
+
+ if (ctx->server)
+ (*ctx->server->nsi_destroy)(minor_status, ctx->ictx);
+
+ _gss_ntlm_release_cred(NULL, &cred);
+
+ memset(ctx, 0, sizeof(*ctx));
+ free(ctx);
+ }
+ if (output_token) {
+ output_token->length = 0;
+ output_token->value = NULL;
+ }
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/display_name.c b/crypto/heimdal/lib/gssapi/ntlm/display_name.c
new file mode 100644
index 0000000..4f8e3e6
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/display_name.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_display_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t output_name_buffer,
+ gss_OID * output_name_type
+ )
+{
+ *minor_status = 0;
+
+ if (output_name_type)
+ *output_name_type = GSS_NTLM_MECHANISM;
+
+ if (output_name_buffer) {
+ ntlm_name n = (ntlm_name)input_name;
+ char *str = NULL;
+ int len;
+
+ output_name_buffer->length = 0;
+ output_name_buffer->value = NULL;
+
+ if (n == NULL) {
+ *minor_status = 0;
+ return GSS_S_BAD_NAME;
+ }
+
+ len = asprintf(&str, "%s@%s", n->user, n->domain);
+ if (len < 0 || str == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ output_name_buffer->length = len;
+ output_name_buffer->value = str;
+ }
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/display_status.c b/crypto/heimdal/lib/gssapi/ntlm/display_status.c
new file mode 100644
index 0000000..c9e1792
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/display_status.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1998 - 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_display_status
+ (OM_uint32 *minor_status,
+ OM_uint32 status_value,
+ int status_type,
+ const gss_OID mech_type,
+ OM_uint32 *message_context,
+ gss_buffer_t status_string)
+{
+ if (minor_status)
+ *minor_status = 0;
+ if (status_string) {
+ status_string->length = 0;
+ status_string->value = NULL;
+ }
+ if (message_context)
+ *message_context = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/duplicate_name.c b/crypto/heimdal/lib/gssapi/ntlm/duplicate_name.c
new file mode 100644
index 0000000..4ef574f
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/duplicate_name.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_duplicate_name (
+ OM_uint32 * minor_status,
+ const gss_name_t src_name,
+ gss_name_t * dest_name
+ )
+{
+ if (minor_status)
+ *minor_status = 0;
+ if (dest_name)
+ *dest_name = NULL;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/export_name.c b/crypto/heimdal/lib/gssapi/ntlm/export_name.c
new file mode 100644
index 0000000..8fe69aa
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/export_name.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1997, 1999, 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_export_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t exported_name
+ )
+{
+ if (minor_status)
+ *minor_status = 0;
+ if (exported_name) {
+ exported_name->length = 0;
+ exported_name->value = NULL;
+ }
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/export_sec_context.c b/crypto/heimdal/lib/gssapi/ntlm/export_sec_context.c
new file mode 100644
index 0000000..027a921
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/export_sec_context.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1999 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_export_sec_context (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t interprocess_token
+ )
+{
+ if (minor_status)
+ *minor_status = 0;
+ if (interprocess_token) {
+ interprocess_token->length = 0;
+ interprocess_token->value = NULL;
+ }
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/external.c b/crypto/heimdal/lib/gssapi/ntlm/external.c
new file mode 100644
index 0000000..ee15c3e
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/external.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+#if 0
+static gss_mo_desc ntlm_mo[] = {
+ {
+ GSS_C_MA_SASL_MECH_NAME,
+ GSS_MO_MA,
+ "SASL mech name",
+ rk_UNCONST("NTLM"),
+ _gss_mo_get_ctx_as_string,
+ NULL
+ },
+ {
+ GSS_C_MA_MECH_NAME,
+ GSS_MO_MA,
+ "Mechanism name",
+ rk_UNCONST("NTLMSPP"),
+ _gss_mo_get_ctx_as_string,
+ NULL
+ },
+ {
+ GSS_C_MA_MECH_DESCRIPTION,
+ GSS_MO_MA,
+ "Mechanism description",
+ rk_UNCONST("Heimdal NTLMSSP Mechanism"),
+ _gss_mo_get_ctx_as_string,
+ NULL
+ }
+};
+
+#endif
+
+static gssapi_mech_interface_desc ntlm_mech = {
+ GMI_VERSION,
+ "ntlm",
+ {10, rk_UNCONST("\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a") },
+ 0,
+ _gss_ntlm_acquire_cred,
+ _gss_ntlm_release_cred,
+ _gss_ntlm_init_sec_context,
+ _gss_ntlm_accept_sec_context,
+ _gss_ntlm_process_context_token,
+ _gss_ntlm_delete_sec_context,
+ _gss_ntlm_context_time,
+ _gss_ntlm_get_mic,
+ _gss_ntlm_verify_mic,
+ _gss_ntlm_wrap,
+ _gss_ntlm_unwrap,
+ _gss_ntlm_display_status,
+ NULL,
+ _gss_ntlm_compare_name,
+ _gss_ntlm_display_name,
+ _gss_ntlm_import_name,
+ _gss_ntlm_export_name,
+ _gss_ntlm_release_name,
+ _gss_ntlm_inquire_cred,
+ _gss_ntlm_inquire_context,
+ _gss_ntlm_wrap_size_limit,
+ _gss_ntlm_add_cred,
+ _gss_ntlm_inquire_cred_by_mech,
+ _gss_ntlm_export_sec_context,
+ _gss_ntlm_import_sec_context,
+ _gss_ntlm_inquire_names_for_mech,
+ _gss_ntlm_inquire_mechs_for_name,
+ _gss_ntlm_canonicalize_name,
+ _gss_ntlm_duplicate_name,
+ _gss_ntlm_inquire_sec_context_by_oid,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _gss_ntlm_iter_creds_f,
+ _gss_ntlm_destroy_cred,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#if 0
+ ntlm_mo,
+ sizeof(ntlm_mo) / sizeof(ntlm_mo[0]),
+#else
+ NULL,
+ 0,
+#endif
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+gssapi_mech_interface
+__gss_ntlm_initialize(void)
+{
+ return &ntlm_mech;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/import_name.c b/crypto/heimdal/lib/gssapi/ntlm/import_name.c
new file mode 100644
index 0000000..e75388d
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/import_name.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_import_name
+ (OM_uint32 * minor_status,
+ const gss_buffer_t input_name_buffer,
+ const gss_OID input_name_type,
+ gss_name_t * output_name
+ )
+{
+ char *name, *p, *p2;
+ int is_hostnamed;
+ int is_username;
+ ntlm_name n;
+
+ *minor_status = 0;
+
+ if (output_name == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *output_name = GSS_C_NO_NAME;
+
+ is_hostnamed = gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE);
+ is_username = gss_oid_equal(input_name_type, GSS_C_NT_USER_NAME);
+
+ if (!is_hostnamed && !is_username)
+ return GSS_S_BAD_NAMETYPE;
+
+ name = malloc(input_name_buffer->length + 1);
+ if (name == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ memcpy(name, input_name_buffer->value, input_name_buffer->length);
+ name[input_name_buffer->length] = '\0';
+
+ /* find "domain" part of the name and uppercase it */
+ p = strchr(name, '@');
+ if (p == NULL) {
+ free(name);
+ return GSS_S_BAD_NAME;
+ }
+ p[0] = '\0';
+ p++;
+ p2 = strchr(p, '.');
+ if (p2 && p2[1] != '\0') {
+ if (is_hostnamed) {
+ p = p2 + 1;
+ p2 = strchr(p, '.');
+ }
+ if (p2)
+ *p2 = '\0';
+ }
+ strupr(p);
+
+ n = calloc(1, sizeof(*n));
+ if (n == NULL) {
+ free(name);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ n->user = strdup(name);
+ n->domain = strdup(p);
+
+ free(name);
+
+ if (n->user == NULL || n->domain == NULL) {
+ free(n->user);
+ free(n->domain);
+ free(n);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ *output_name = (gss_name_t)n;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/import_sec_context.c b/crypto/heimdal/lib/gssapi/ntlm/import_sec_context.c
new file mode 100644
index 0000000..fe637c0
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/import_sec_context.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1999 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_import_sec_context (
+ OM_uint32 * minor_status,
+ const gss_buffer_t interprocess_token,
+ gss_ctx_id_t * context_handle
+ )
+{
+ if (minor_status)
+ *minor_status = 0;
+ if (context_handle)
+ *context_handle = GSS_C_NO_CONTEXT;
+ return GSS_S_FAILURE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/indicate_mechs.c b/crypto/heimdal/lib/gssapi/ntlm/indicate_mechs.c
new file mode 100644
index 0000000..7cda475
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/indicate_mechs.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 _gss_ntlm_indicate_mechs
+(OM_uint32 * minor_status,
+ gss_OID_set * mech_set
+ )
+{
+ if (minor_status)
+ *minor_status = 0;
+ if (mech_set)
+ *mech_set = GSS_C_NO_OID_SET;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/init_sec_context.c b/crypto/heimdal/lib/gssapi/ntlm/init_sec_context.c
new file mode 100644
index 0000000..bae04e1
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/init_sec_context.c
@@ -0,0 +1,501 @@
+/*
+ * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+static int
+from_file(const char *fn, const char *target_domain,
+ char **username, struct ntlm_buf *key)
+{
+ char *str, buf[1024];
+ FILE *f;
+
+ f = fopen(fn, "r");
+ if (f == NULL)
+ return ENOENT;
+ rk_cloexec_file(f);
+
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ char *d, *u, *p;
+ buf[strcspn(buf, "\r\n")] = '\0';
+ if (buf[0] == '#')
+ continue;
+ str = NULL;
+ d = strtok_r(buf, ":", &str);
+ if (d && strcasecmp(target_domain, d) != 0)
+ continue;
+ u = strtok_r(NULL, ":", &str);
+ p = strtok_r(NULL, ":", &str);
+ if (u == NULL || p == NULL)
+ continue;
+
+ *username = strdup(u);
+
+ heim_ntlm_nt_key(p, key);
+
+ memset(buf, 0, sizeof(buf));
+ fclose(f);
+ return 0;
+ }
+ memset(buf, 0, sizeof(buf));
+ fclose(f);
+ return ENOENT;
+}
+
+static int
+get_user_file(const ntlm_name target_name,
+ char **username, struct ntlm_buf *key)
+{
+ const char *fn;
+
+ if (issuid())
+ return ENOENT;
+
+ fn = getenv("NTLM_USER_FILE");
+ if (fn == NULL)
+ return ENOENT;
+ if (from_file(fn, target_name->domain, username, key) == 0)
+ return 0;
+
+ return ENOENT;
+}
+
+/*
+ * Pick up the ntlm cred from the default krb5 credential cache.
+ */
+
+static int
+get_user_ccache(const ntlm_name name, char **username, struct ntlm_buf *key)
+{
+ krb5_context context = NULL;
+ krb5_principal client;
+ krb5_ccache id = NULL;
+ krb5_error_code ret;
+ char *confname;
+ krb5_data data;
+
+ *username = NULL;
+ krb5_data_zero(&data);
+ key->length = 0;
+ key->data = NULL;
+
+ ret = krb5_init_context(&context);
+ if (ret)
+ return ret;
+
+ ret = krb5_cc_default(context, &id);
+ if (ret)
+ goto out;
+
+ ret = krb5_cc_get_principal(context, id, &client);
+ if (ret)
+ goto out;
+
+ ret = krb5_unparse_name_flags(context, client,
+ KRB5_PRINCIPAL_UNPARSE_NO_REALM,
+ username);
+ krb5_free_principal(context, client);
+ if (ret)
+ goto out;
+
+ asprintf(&confname, "ntlm-key-%s", name->domain);
+ if (confname == NULL) {
+ krb5_clear_error_message(context);
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ret = krb5_cc_get_config(context, id, NULL,
+ confname, &data);
+ if (ret)
+ goto out;
+
+ key->data = malloc(data.length);
+ if (key->data == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ key->length = data.length;
+ memcpy(key->data, data.data, data.length);
+
+ out:
+ krb5_data_free(&data);
+ if (id)
+ krb5_cc_close(context, id);
+
+ krb5_free_context(context);
+
+ return ret;
+}
+
+int
+_gss_ntlm_get_user_cred(const ntlm_name target_name,
+ ntlm_cred *rcred)
+{
+ ntlm_cred cred;
+ int ret;
+
+ cred = calloc(1, sizeof(*cred));
+ if (cred == NULL)
+ return ENOMEM;
+
+ ret = get_user_file(target_name, &cred->username, &cred->key);
+ if (ret)
+ ret = get_user_ccache(target_name, &cred->username, &cred->key);
+ if (ret) {
+ free(cred);
+ return ret;
+ }
+
+ cred->domain = strdup(target_name->domain);
+ *rcred = cred;
+
+ return ret;
+}
+
+static int
+_gss_copy_cred(ntlm_cred from, ntlm_cred *to)
+{
+ *to = calloc(1, sizeof(**to));
+ if (*to == NULL)
+ return ENOMEM;
+ (*to)->username = strdup(from->username);
+ if ((*to)->username == NULL) {
+ free(*to);
+ return ENOMEM;
+ }
+ (*to)->domain = strdup(from->domain);
+ if ((*to)->domain == NULL) {
+ free((*to)->username);
+ free(*to);
+ return ENOMEM;
+ }
+ (*to)->key.data = malloc(from->key.length);
+ if ((*to)->key.data == NULL) {
+ free((*to)->domain);
+ free((*to)->username);
+ free(*to);
+ return ENOMEM;
+ }
+ memcpy((*to)->key.data, from->key.data, from->key.length);
+ (*to)->key.length = from->key.length;
+
+ return 0;
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_init_sec_context
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+ )
+{
+ ntlm_ctx ctx;
+ ntlm_name name = (ntlm_name)target_name;
+
+ *minor_status = 0;
+
+ if (ret_flags)
+ *ret_flags = 0;
+ if (time_rec)
+ *time_rec = 0;
+ if (actual_mech_type)
+ *actual_mech_type = GSS_C_NO_OID;
+
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ struct ntlm_type1 type1;
+ struct ntlm_buf data;
+ uint32_t flags = 0;
+ int ret;
+
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ *context_handle = (gss_ctx_id_t)ctx;
+
+ if (initiator_cred_handle != GSS_C_NO_CREDENTIAL) {
+ ntlm_cred cred = (ntlm_cred)initiator_cred_handle;
+ ret = _gss_copy_cred(cred, &ctx->client);
+ } else
+ ret = _gss_ntlm_get_user_cred(name, &ctx->client);
+
+ if (ret) {
+ _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ if (req_flags & GSS_C_CONF_FLAG)
+ flags |= NTLM_NEG_SEAL;
+ if (req_flags & GSS_C_INTEG_FLAG)
+ flags |= NTLM_NEG_SIGN;
+ else
+ flags |= NTLM_NEG_ALWAYS_SIGN;
+
+ flags |= NTLM_NEG_UNICODE;
+ flags |= NTLM_NEG_NTLM;
+ flags |= NTLM_NEG_NTLM2_SESSION;
+ flags |= NTLM_NEG_KEYEX;
+
+ memset(&type1, 0, sizeof(type1));
+
+ type1.flags = flags;
+ type1.domain = name->domain;
+ type1.hostname = NULL;
+ type1.os[0] = 0;
+ type1.os[1] = 0;
+
+ ret = heim_ntlm_encode_type1(&type1, &data);
+ if (ret) {
+ _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ output_token->value = data.data;
+ output_token->length = data.length;
+
+ return GSS_S_CONTINUE_NEEDED;
+ } else {
+ krb5_error_code ret;
+ struct ntlm_type2 type2;
+ struct ntlm_type3 type3;
+ struct ntlm_buf data;
+
+ ctx = (ntlm_ctx)*context_handle;
+
+ data.data = input_token->value;
+ data.length = input_token->length;
+
+ ret = heim_ntlm_decode_type2(&data, &type2);
+ if (ret) {
+ _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ctx->flags = type2.flags;
+
+ /* XXX check that type2.targetinfo matches `target_name´ */
+ /* XXX check verify targetinfo buffer */
+
+ memset(&type3, 0, sizeof(type3));
+
+ type3.username = ctx->client->username;
+ type3.flags = type2.flags;
+ type3.targetname = type2.targetname;
+ type3.ws = rk_UNCONST("workstation");
+
+ /*
+ * NTLM Version 1 if no targetinfo buffer.
+ */
+
+ if (1 || type2.targetinfo.length == 0) {
+ struct ntlm_buf sessionkey;
+
+ if (type2.flags & NTLM_NEG_NTLM2_SESSION) {
+ unsigned char nonce[8];
+
+ if (RAND_bytes(nonce, sizeof(nonce)) != 1) {
+ _gss_ntlm_delete_sec_context(minor_status,
+ context_handle, NULL);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ ret = heim_ntlm_calculate_ntlm2_sess(nonce,
+ type2.challenge,
+ ctx->client->key.data,
+ &type3.lm,
+ &type3.ntlm);
+ } else {
+ ret = heim_ntlm_calculate_ntlm1(ctx->client->key.data,
+ ctx->client->key.length,
+ type2.challenge,
+ &type3.ntlm);
+
+ }
+ if (ret) {
+ _gss_ntlm_delete_sec_context(minor_status,context_handle,NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = heim_ntlm_build_ntlm1_master(ctx->client->key.data,
+ ctx->client->key.length,
+ &sessionkey,
+ &type3.sessionkey);
+ if (ret) {
+ if (type3.lm.data)
+ free(type3.lm.data);
+ if (type3.ntlm.data)
+ free(type3.ntlm.data);
+ _gss_ntlm_delete_sec_context(minor_status,context_handle,NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_data_copy(&ctx->sessionkey,
+ sessionkey.data, sessionkey.length);
+ free(sessionkey.data);
+ if (ret) {
+ if (type3.lm.data)
+ free(type3.lm.data);
+ if (type3.ntlm.data)
+ free(type3.ntlm.data);
+ _gss_ntlm_delete_sec_context(minor_status,context_handle,NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ ctx->status |= STATUS_SESSIONKEY;
+
+ } else {
+ struct ntlm_buf sessionkey;
+ unsigned char ntlmv2[16];
+ struct ntlm_targetinfo ti;
+
+ /* verify infotarget */
+
+ ret = heim_ntlm_decode_targetinfo(&type2.targetinfo, 1, &ti);
+ if(ret) {
+ _gss_ntlm_delete_sec_context(minor_status,
+ context_handle, NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ if (ti.domainname && strcmp(ti.domainname, name->domain) != 0) {
+ _gss_ntlm_delete_sec_context(minor_status,
+ context_handle, NULL);
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ ret = heim_ntlm_calculate_ntlm2(ctx->client->key.data,
+ ctx->client->key.length,
+ ctx->client->username,
+ name->domain,
+ type2.challenge,
+ &type2.targetinfo,
+ ntlmv2,
+ &type3.ntlm);
+ if (ret) {
+ _gss_ntlm_delete_sec_context(minor_status,
+ context_handle, NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = heim_ntlm_build_ntlm1_master(ntlmv2, sizeof(ntlmv2),
+ &sessionkey,
+ &type3.sessionkey);
+ memset(ntlmv2, 0, sizeof(ntlmv2));
+ if (ret) {
+ _gss_ntlm_delete_sec_context(minor_status,
+ context_handle, NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ctx->flags |= NTLM_NEG_NTLM2_SESSION;
+
+ ret = krb5_data_copy(&ctx->sessionkey,
+ sessionkey.data, sessionkey.length);
+ free(sessionkey.data);
+ if (ret) {
+ _gss_ntlm_delete_sec_context(minor_status,
+ context_handle, NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ if (ctx->flags & NTLM_NEG_NTLM2_SESSION) {
+ ctx->status |= STATUS_SESSIONKEY;
+ _gss_ntlm_set_key(&ctx->u.v2.send, 0, (ctx->flags & NTLM_NEG_KEYEX),
+ ctx->sessionkey.data,
+ ctx->sessionkey.length);
+ _gss_ntlm_set_key(&ctx->u.v2.recv, 1, (ctx->flags & NTLM_NEG_KEYEX),
+ ctx->sessionkey.data,
+ ctx->sessionkey.length);
+ } else {
+ ctx->status |= STATUS_SESSIONKEY;
+ RC4_set_key(&ctx->u.v1.crypto_recv.key,
+ ctx->sessionkey.length,
+ ctx->sessionkey.data);
+ RC4_set_key(&ctx->u.v1.crypto_send.key,
+ ctx->sessionkey.length,
+ ctx->sessionkey.data);
+ }
+
+
+
+ ret = heim_ntlm_encode_type3(&type3, &data);
+ free(type3.sessionkey.data);
+ if (type3.lm.data)
+ free(type3.lm.data);
+ if (type3.ntlm.data)
+ free(type3.ntlm.data);
+ if (ret) {
+ _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ output_token->length = data.length;
+ output_token->value = data.data;
+
+ if (actual_mech_type)
+ *actual_mech_type = GSS_NTLM_MECHANISM;
+ if (ret_flags)
+ *ret_flags = 0;
+ if (time_rec)
+ *time_rec = GSS_C_INDEFINITE;
+
+ ctx->status |= STATUS_OPEN;
+
+ return GSS_S_COMPLETE;
+ }
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/inquire_context.c b/crypto/heimdal/lib/gssapi/ntlm/inquire_context.c
new file mode 100644
index 0000000..fd0cb87
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/inquire_context.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_inquire_context (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_name_t * src_name,
+ gss_name_t * targ_name,
+ OM_uint32 * lifetime_rec,
+ gss_OID * mech_type,
+ OM_uint32 * ctx_flags,
+ int * locally_initiated,
+ int * open_context
+ )
+{
+ ntlm_ctx ctx = (ntlm_ctx)context_handle;
+
+ *minor_status = 0;
+ if (src_name)
+ *src_name = GSS_C_NO_NAME;
+ if (targ_name)
+ *targ_name = GSS_C_NO_NAME;
+ if (lifetime_rec)
+ *lifetime_rec = GSS_C_INDEFINITE;
+ if (mech_type)
+ *mech_type = GSS_NTLM_MECHANISM;
+ if (ctx_flags)
+ *ctx_flags = ctx->gssflags;
+ if (locally_initiated)
+ *locally_initiated = (ctx->status & STATUS_CLIENT) ? 1 : 0;
+ if (open_context)
+ *open_context = (ctx->status & STATUS_OPEN) ? 1 : 0;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/inquire_cred_by_mech.c b/crypto/heimdal/lib/gssapi/ntlm/inquire_cred_by_mech.c
new file mode 100644
index 0000000..b5976b9
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/inquire_cred_by_mech.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_inquire_cred_by_mech (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID mech_type,
+ gss_name_t * name,
+ OM_uint32 * initiator_lifetime,
+ OM_uint32 * acceptor_lifetime,
+ gss_cred_usage_t * cred_usage
+ )
+{
+ if (minor_status)
+ *minor_status = 0;
+ if (name)
+ *name = GSS_C_NO_NAME;
+ if (initiator_lifetime)
+ *initiator_lifetime = 0;
+ if (acceptor_lifetime)
+ *acceptor_lifetime = 0;
+ if (cred_usage)
+ *cred_usage = 0;
+ return GSS_S_UNAVAILABLE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/inquire_mechs_for_name.c b/crypto/heimdal/lib/gssapi/ntlm/inquire_mechs_for_name.c
new file mode 100644
index 0000000..4fd5380
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/inquire_mechs_for_name.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_inquire_mechs_for_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_OID_set * mech_types
+ )
+{
+ if (minor_status)
+ *minor_status = 0;
+ if (mech_types)
+ *mech_types = GSS_C_NO_OID_SET;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/inquire_names_for_mech.c b/crypto/heimdal/lib/gssapi/ntlm/inquire_names_for_mech.c
new file mode 100644
index 0000000..7f49b33
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/inquire_names_for_mech.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_inquire_names_for_mech (
+ OM_uint32 * minor_status,
+ const gss_OID mechanism,
+ gss_OID_set * name_types
+ )
+{
+ OM_uint32 ret;
+
+ ret = gss_create_empty_oid_set(minor_status, name_types);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/inquire_sec_context_by_oid.c b/crypto/heimdal/lib/gssapi/ntlm/inquire_sec_context_by_oid.c
new file mode 100644
index 0000000..ee791b1
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/inquire_sec_context_by_oid.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_inquire_sec_context_by_oid(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ ntlm_ctx ctx = (ntlm_ctx)context_handle;
+
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ if (gss_oid_equal(desired_object, GSS_NTLM_GET_SESSION_KEY_X) ||
+ gss_oid_equal(desired_object, GSS_C_INQ_SSPI_SESSION_KEY)) {
+ gss_buffer_desc value;
+
+ value.length = ctx->sessionkey.length;
+ value.value = ctx->sessionkey.data;
+
+ return gss_add_buffer_set_member(minor_status,
+ &value,
+ data_set);
+ } else if (gss_oid_equal(desired_object, GSS_C_INQ_WIN2K_PAC_X)) {
+ if (ctx->pac.length == 0) {
+ *minor_status = ENOENT;
+ return GSS_S_FAILURE;
+ }
+
+ return gss_add_buffer_set_member(minor_status,
+ &ctx->pac,
+ data_set);
+
+ } else if (gss_oid_equal(desired_object, GSS_C_NTLM_AVGUEST)) {
+ gss_buffer_desc value;
+ uint32_t num;
+
+ if (ctx->kcmflags & KCM_NTLM_FLAG_AV_GUEST)
+ num = 1;
+ else
+ num = 0;
+
+ value.length = sizeof(num);
+ value.value = &num;
+
+ return gss_add_buffer_set_member(minor_status,
+ &value,
+ data_set);
+ } else {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/iter_cred.c b/crypto/heimdal/lib/gssapi/ntlm/iter_cred.c
new file mode 100644
index 0000000..34456db
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/iter_cred.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+void GSSAPI_CALLCONV
+_gss_ntlm_iter_creds_f(OM_uint32 flags,
+ void *userctx ,
+ void (*cred_iter)(void *, gss_OID, gss_cred_id_t))
+{
+#ifdef HAVE_KCM
+ krb5_error_code ret;
+ krb5_context context = NULL;
+ krb5_storage *request, *response;
+ krb5_data response_data;
+
+ ret = krb5_init_context(&context);
+ if (ret)
+ goto done;
+
+ ret = krb5_kcm_storage_request(context, KCM_OP_GET_NTLM_USER_LIST, &request);
+ if (ret)
+ goto done;
+
+ ret = krb5_kcm_call(context, request, &response, &response_data);
+ krb5_storage_free(request);
+ if (ret)
+ goto done;
+
+ while (1) {
+ uint32_t morep;
+ char *user = NULL, *domain = NULL;
+ ntlm_cred dn;
+
+ ret = krb5_ret_uint32(response, &morep);
+ if (ret) goto out;
+
+ if (!morep) goto out;
+
+ ret = krb5_ret_stringz(response, &user);
+ if (ret) goto out;
+ ret = krb5_ret_stringz(response, &domain);
+ if (ret) {
+ free(user);
+ goto out;
+ }
+
+ dn = calloc(1, sizeof(*dn));
+ if (dn == NULL) {
+ free(user);
+ free(domain);
+ goto out;
+ }
+ dn->username = user;
+ dn->domain = domain;
+
+ cred_iter(userctx, GSS_NTLM_MECHANISM, (gss_cred_id_t)dn);
+ }
+ out:
+ krb5_storage_free(response);
+ krb5_data_free(&response_data);
+ done:
+ if (context)
+ krb5_free_context(context);
+#endif /* HAVE_KCM */
+ (*cred_iter)(userctx, NULL, NULL);
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/kdc.c b/crypto/heimdal/lib/gssapi/ntlm/kdc.c
new file mode 100644
index 0000000..7d56c75
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/kdc.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+#ifdef DIGEST
+
+/*
+ *
+ */
+
+struct ntlmkrb5 {
+ krb5_context context;
+ krb5_ntlm ntlm;
+ krb5_realm kerberos_realm;
+ krb5_ccache id;
+ krb5_data opaque;
+ int destroy;
+ OM_uint32 flags;
+ struct ntlm_buf key;
+ krb5_data sessionkey;
+};
+
+static OM_uint32 kdc_destroy(OM_uint32 *, void *);
+
+/*
+ * Get credential cache that the ntlm code can use to talk to the KDC
+ * using the digest API.
+ */
+
+static krb5_error_code
+get_ccache(krb5_context context, int *destroy, krb5_ccache *id)
+{
+ krb5_principal principal = NULL;
+ krb5_error_code ret;
+ krb5_keytab kt = NULL;
+
+ *id = NULL;
+
+ if (!issuid()) {
+ const char *cache;
+
+ cache = getenv("NTLM_ACCEPTOR_CCACHE");
+ if (cache) {
+ ret = krb5_cc_resolve(context, cache, id);
+ if (ret)
+ goto out;
+ return 0;
+ }
+ }
+
+ ret = krb5_sname_to_principal(context, NULL, "host",
+ KRB5_NT_SRV_HST, &principal);
+ if (ret)
+ goto out;
+
+ ret = krb5_cc_cache_match(context, principal, id);
+ if (ret == 0)
+ return 0;
+
+ /* did not find in default credcache, lets try default keytab */
+ ret = krb5_kt_default(context, &kt);
+ if (ret)
+ goto out;
+
+ /* XXX check in keytab */
+ {
+ krb5_get_init_creds_opt *opt;
+ krb5_creds cred;
+
+ memset(&cred, 0, sizeof(cred));
+
+ ret = krb5_cc_new_unique(context, "MEMORY", NULL, id);
+ if (ret)
+ goto out;
+ *destroy = 1;
+ ret = krb5_get_init_creds_opt_alloc(context, &opt);
+ if (ret)
+ goto out;
+ ret = krb5_get_init_creds_keytab (context,
+ &cred,
+ principal,
+ kt,
+ 0,
+ NULL,
+ opt);
+ krb5_get_init_creds_opt_free(context, opt);
+ if (ret)
+ goto out;
+ ret = krb5_cc_initialize (context, *id, cred.client);
+ if (ret) {
+ krb5_free_cred_contents (context, &cred);
+ goto out;
+ }
+ ret = krb5_cc_store_cred (context, *id, &cred);
+ krb5_free_cred_contents (context, &cred);
+ if (ret)
+ goto out;
+ }
+
+ krb5_kt_close(context, kt);
+
+ return 0;
+
+out:
+ if (*id) {
+ if (*destroy)
+ krb5_cc_destroy(context, *id);
+ else
+ krb5_cc_close(context, *id);
+ *id = NULL;
+ }
+
+ if (kt)
+ krb5_kt_close(context, kt);
+
+ if (principal)
+ krb5_free_principal(context, principal);
+ return ret;
+}
+
+/*
+ *
+ */
+
+static OM_uint32
+kdc_alloc(OM_uint32 *minor, void **ctx)
+{
+ krb5_error_code ret;
+ struct ntlmkrb5 *c;
+ OM_uint32 junk;
+
+ c = calloc(1, sizeof(*c));
+ if (c == NULL) {
+ *minor = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_init_context(&c->context);
+ if (ret) {
+ kdc_destroy(&junk, c);
+ *minor = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = get_ccache(c->context, &c->destroy, &c->id);
+ if (ret) {
+ kdc_destroy(&junk, c);
+ *minor = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_ntlm_alloc(c->context, &c->ntlm);
+ if (ret) {
+ kdc_destroy(&junk, c);
+ *minor = ret;
+ return GSS_S_FAILURE;
+ }
+
+ *ctx = c;
+
+ return GSS_S_COMPLETE;
+}
+
+static int
+kdc_probe(OM_uint32 *minor, void *ctx, const char *realm)
+{
+ struct ntlmkrb5 *c = ctx;
+ krb5_error_code ret;
+ unsigned flags;
+
+ ret = krb5_digest_probe(c->context, rk_UNCONST(realm), c->id, &flags);
+ if (ret)
+ return ret;
+
+ if ((flags & (1|2|4)) == 0)
+ return EINVAL;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static OM_uint32
+kdc_destroy(OM_uint32 *minor, void *ctx)
+{
+ struct ntlmkrb5 *c = ctx;
+ krb5_data_free(&c->opaque);
+ krb5_data_free(&c->sessionkey);
+ if (c->ntlm)
+ krb5_ntlm_free(c->context, c->ntlm);
+ if (c->id) {
+ if (c->destroy)
+ krb5_cc_destroy(c->context, c->id);
+ else
+ krb5_cc_close(c->context, c->id);
+ }
+ if (c->context)
+ krb5_free_context(c->context);
+ memset(c, 0, sizeof(*c));
+ free(c);
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ *
+ */
+
+static OM_uint32
+kdc_type2(OM_uint32 *minor_status,
+ void *ctx,
+ uint32_t flags,
+ const char *hostname,
+ const char *domain,
+ uint32_t *ret_flags,
+ struct ntlm_buf *out)
+{
+ struct ntlmkrb5 *c = ctx;
+ krb5_error_code ret;
+ struct ntlm_type2 type2;
+ krb5_data challange;
+ struct ntlm_buf data;
+ krb5_data ti;
+
+ memset(&type2, 0, sizeof(type2));
+
+ /*
+ * Request data for type 2 packet from the KDC.
+ */
+ ret = krb5_ntlm_init_request(c->context,
+ c->ntlm,
+ NULL,
+ c->id,
+ flags,
+ hostname,
+ domain);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ /*
+ *
+ */
+
+ ret = krb5_ntlm_init_get_opaque(c->context, c->ntlm, &c->opaque);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ /*
+ *
+ */
+
+ ret = krb5_ntlm_init_get_flags(c->context, c->ntlm, &type2.flags);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ *ret_flags = type2.flags;
+
+ ret = krb5_ntlm_init_get_challange(c->context, c->ntlm, &challange);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ if (challange.length != sizeof(type2.challenge)) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ memcpy(type2.challenge, challange.data, sizeof(type2.challenge));
+ krb5_data_free(&challange);
+
+ ret = krb5_ntlm_init_get_targetname(c->context, c->ntlm,
+ &type2.targetname);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ ret = krb5_ntlm_init_get_targetinfo(c->context, c->ntlm, &ti);
+ if (ret) {
+ free(type2.targetname);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ type2.targetinfo.data = ti.data;
+ type2.targetinfo.length = ti.length;
+
+ ret = heim_ntlm_encode_type2(&type2, &data);
+ free(type2.targetname);
+ krb5_data_free(&ti);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ out->data = data.data;
+ out->length = data.length;
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ *
+ */
+
+static OM_uint32
+kdc_type3(OM_uint32 *minor_status,
+ void *ctx,
+ const struct ntlm_type3 *type3,
+ struct ntlm_buf *sessionkey)
+{
+ struct ntlmkrb5 *c = ctx;
+ krb5_error_code ret;
+
+ sessionkey->data = NULL;
+ sessionkey->length = 0;
+
+ ret = krb5_ntlm_req_set_flags(c->context, c->ntlm, type3->flags);
+ if (ret) goto out;
+ ret = krb5_ntlm_req_set_username(c->context, c->ntlm, type3->username);
+ if (ret) goto out;
+ ret = krb5_ntlm_req_set_targetname(c->context, c->ntlm,
+ type3->targetname);
+ if (ret) goto out;
+ ret = krb5_ntlm_req_set_lm(c->context, c->ntlm,
+ type3->lm.data, type3->lm.length);
+ if (ret) goto out;
+ ret = krb5_ntlm_req_set_ntlm(c->context, c->ntlm,
+ type3->ntlm.data, type3->ntlm.length);
+ if (ret) goto out;
+ ret = krb5_ntlm_req_set_opaque(c->context, c->ntlm, &c->opaque);
+ if (ret) goto out;
+
+ if (type3->sessionkey.length) {
+ ret = krb5_ntlm_req_set_session(c->context, c->ntlm,
+ type3->sessionkey.data,
+ type3->sessionkey.length);
+ if (ret) goto out;
+ }
+
+ /*
+ * Verify with the KDC the type3 packet is ok
+ */
+ ret = krb5_ntlm_request(c->context,
+ c->ntlm,
+ NULL,
+ c->id);
+ if (ret)
+ goto out;
+
+ if (krb5_ntlm_rep_get_status(c->context, c->ntlm) != TRUE) {
+ ret = EINVAL;
+ goto out;
+ }
+
+ if (type3->sessionkey.length) {
+ ret = krb5_ntlm_rep_get_sessionkey(c->context,
+ c->ntlm,
+ &c->sessionkey);
+ if (ret)
+ goto out;
+
+ sessionkey->data = c->sessionkey.data;
+ sessionkey->length = c->sessionkey.length;
+ }
+
+ return 0;
+
+ out:
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+}
+
+/*
+ *
+ */
+
+static void
+kdc_free_buffer(struct ntlm_buf *sessionkey)
+{
+ if (sessionkey->data)
+ free(sessionkey->data);
+ sessionkey->data = NULL;
+ sessionkey->length = 0;
+}
+
+/*
+ *
+ */
+
+struct ntlm_server_interface ntlmsspi_kdc_digest = {
+ kdc_alloc,
+ kdc_destroy,
+ kdc_probe,
+ kdc_type2,
+ kdc_type3,
+ kdc_free_buffer
+};
+
+#endif /* DIGEST */
diff --git a/crypto/heimdal/lib/gssapi/ntlm/ntlm-private.h b/crypto/heimdal/lib/gssapi/ntlm/ntlm-private.h
new file mode 100644
index 0000000..0c62b35
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/ntlm-private.h
@@ -0,0 +1,282 @@
+/* This is a generated file */
+#ifndef __ntlm_private_h__
+#define __ntlm_private_h__
+
+#include <stdarg.h>
+
+gssapi_mech_interface
+__gss_ntlm_initialize (void);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_accept_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_cred_id_t /*acceptor_cred_handle*/,
+ const gss_buffer_t /*input_token_buffer*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ gss_name_t * /*src_name*/,
+ gss_OID * /*mech_type*/,
+ gss_buffer_t /*output_token*/,
+ OM_uint32 * /*ret_flags*/,
+ OM_uint32 * /*time_rec*/,
+ gss_cred_id_t * delegated_cred_handle );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_acquire_cred (
+ OM_uint32 * /*min_stat*/,
+ const gss_name_t /*desired_name*/,
+ OM_uint32 /*time_req*/,
+ const gss_OID_set /*desired_mechs*/,
+ gss_cred_usage_t /*cred_usage*/,
+ gss_cred_id_t * /*output_cred_handle*/,
+ gss_OID_set * /*actual_mechs*/,
+ OM_uint32 * time_rec );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_add_cred (
+ OM_uint32 */*minor_status*/,
+ const gss_cred_id_t /*input_cred_handle*/,
+ const gss_name_t /*desired_name*/,
+ const gss_OID /*desired_mech*/,
+ gss_cred_usage_t /*cred_usage*/,
+ OM_uint32 /*initiator_time_req*/,
+ OM_uint32 /*acceptor_time_req*/,
+ gss_cred_id_t */*output_cred_handle*/,
+ gss_OID_set */*actual_mechs*/,
+ OM_uint32 */*initiator_time_rec*/,
+ OM_uint32 */*acceptor_time_rec*/);
+
+OM_uint32
+_gss_ntlm_allocate_ctx (
+ OM_uint32 */*minor_status*/,
+ ntlm_ctx */*ctx*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_canonicalize_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * output_name );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_compare_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*name1*/,
+ const gss_name_t /*name2*/,
+ int * name_equal );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_context_time (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ OM_uint32 * time_rec );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_delete_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ gss_buffer_t output_token );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_destroy_cred (
+ OM_uint32 */*minor_status*/,
+ gss_cred_id_t */*cred_handle*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_display_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t /*output_name_buffer*/,
+ gss_OID * output_name_type );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_display_status (
+ OM_uint32 */*minor_status*/,
+ OM_uint32 /*status_value*/,
+ int /*status_type*/,
+ const gss_OID /*mech_type*/,
+ OM_uint32 */*message_context*/,
+ gss_buffer_t /*status_string*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_duplicate_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*src_name*/,
+ gss_name_t * dest_name );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_export_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t exported_name );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_export_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ gss_buffer_t interprocess_token );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_get_mic (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*message_buffer*/,
+ gss_buffer_t message_token );
+
+int
+_gss_ntlm_get_user_cred (
+ const ntlm_name /*target_name*/,
+ ntlm_cred */*rcred*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_import_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*input_name_buffer*/,
+ const gss_OID /*input_name_type*/,
+ gss_name_t * output_name );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_import_sec_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*interprocess_token*/,
+ gss_ctx_id_t * context_handle );
+
+OM_uint32
+_gss_ntlm_indicate_mechs (
+ OM_uint32 * /*minor_status*/,
+ gss_OID_set * mech_set );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_init_sec_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*initiator_cred_handle*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_name_t /*target_name*/,
+ const gss_OID /*mech_type*/,
+ OM_uint32 /*req_flags*/,
+ OM_uint32 /*time_req*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ const gss_buffer_t /*input_token*/,
+ gss_OID * /*actual_mech_type*/,
+ gss_buffer_t /*output_token*/,
+ OM_uint32 * /*ret_flags*/,
+ OM_uint32 * time_rec );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_inquire_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ gss_name_t * /*src_name*/,
+ gss_name_t * /*targ_name*/,
+ OM_uint32 * /*lifetime_rec*/,
+ gss_OID * /*mech_type*/,
+ OM_uint32 * /*ctx_flags*/,
+ int * /*locally_initiated*/,
+ int * open_context );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_inquire_cred (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ gss_name_t * /*name*/,
+ OM_uint32 * /*lifetime*/,
+ gss_cred_usage_t * /*cred_usage*/,
+ gss_OID_set * mechanisms );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_inquire_cred_by_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * /*name*/,
+ OM_uint32 * /*initiator_lifetime*/,
+ OM_uint32 * /*acceptor_lifetime*/,
+ gss_cred_usage_t * cred_usage );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_inquire_mechs_for_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_OID_set * mech_types );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_inquire_names_for_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*mechanism*/,
+ gss_OID_set * name_types );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_inquire_sec_context_by_oid (
+ OM_uint32 */*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_OID /*desired_object*/,
+ gss_buffer_set_t */*data_set*/);
+
+void GSSAPI_CALLCONV
+_gss_ntlm_iter_creds_f (
+ OM_uint32 /*flags*/,
+ void *userctx ,
+ void (*/*cred_iter*/)(void *, gss_OID, gss_cred_id_t));
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_process_context_token (
+ OM_uint32 */*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t token_buffer );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_release_cred (
+ OM_uint32 * /*minor_status*/,
+ gss_cred_id_t * cred_handle );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_release_name (
+ OM_uint32 * /*minor_status*/,
+ gss_name_t * input_name );
+
+void
+_gss_ntlm_set_key (
+ struct ntlmv2_key */*key*/,
+ int /*acceptor*/,
+ int /*sealsign*/,
+ unsigned char */*data*/,
+ size_t /*len*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_unwrap (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ gss_buffer_t /*output_message_buffer*/,
+ int * /*conf_state*/,
+ gss_qop_t * qop_state );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_verify_mic (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t * qop_state );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_wrap (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ int * /*conf_state*/,
+ gss_buffer_t output_message_buffer );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_wrap_size_limit (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ OM_uint32 /*req_output_size*/,
+ OM_uint32 * max_input_size );
+
+#endif /* __ntlm_private_h__ */
diff --git a/crypto/heimdal/lib/gssapi/ntlm/ntlm.h b/crypto/heimdal/lib/gssapi/ntlm/ntlm.h
new file mode 100644
index 0000000..1ed12d5
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/ntlm.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+#ifndef NTLM_NTLM_H
+#define NTLM_NTLM_H
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+
+#include <roken.h>
+
+#include <gssapi.h>
+#include <gssapi_ntlm.h>
+#include <gssapi_mech.h>
+#include <gssapi_oid.h>
+
+#include <krb5.h>
+#include <kcm.h>
+#include <heim_threads.h>
+
+#include <heimntlm.h>
+
+#define HC_DEPRECATED_CRYPTO
+#include "crypto-headers.h"
+
+typedef OM_uint32
+(*ntlm_interface_init)(OM_uint32 *, void **);
+
+typedef OM_uint32
+(*ntlm_interface_destroy)(OM_uint32 *, void *);
+
+typedef int
+(*ntlm_interface_probe)(OM_uint32 *, void *, const char *);
+
+typedef OM_uint32
+(*ntlm_interface_type2)(OM_uint32 *, void *, uint32_t, const char *,
+ const char *, uint32_t *, struct ntlm_buf *);
+
+typedef OM_uint32
+(*ntlm_interface_type3)(OM_uint32 *, void *, const struct ntlm_type3 *,
+ struct ntlm_buf *);
+
+typedef void
+(*ntlm_interface_free_buffer)(struct ntlm_buf *);
+
+struct ntlm_server_interface {
+ ntlm_interface_init nsi_init;
+ ntlm_interface_destroy nsi_destroy;
+ ntlm_interface_probe nsi_probe;
+ ntlm_interface_type2 nsi_type2;
+ ntlm_interface_type3 nsi_type3;
+ ntlm_interface_free_buffer nsi_free_buffer;
+};
+
+
+struct ntlmv2_key {
+ uint32_t seq;
+ RC4_KEY sealkey;
+ RC4_KEY *signsealkey;
+ unsigned char signkey[16];
+};
+
+extern struct ntlm_server_interface ntlmsspi_kdc_digest;
+
+typedef struct ntlm_cred {
+ gss_cred_usage_t usage;
+ char *username;
+ char *domain;
+ struct ntlm_buf key;
+} *ntlm_cred;
+
+typedef struct {
+ struct ntlm_server_interface *server;
+ void *ictx;
+ ntlm_cred client;
+ OM_uint32 gssflags;
+ uint32_t kcmflags;
+ uint32_t flags;
+ uint32_t status;
+#define STATUS_OPEN 1
+#define STATUS_CLIENT 2
+#define STATUS_SESSIONKEY 4
+ krb5_data sessionkey;
+
+ gss_buffer_desc pac;
+
+ union {
+ struct {
+ struct {
+ uint32_t seq;
+ RC4_KEY key;
+ } crypto_send, crypto_recv;
+ } v1;
+ struct {
+ struct ntlmv2_key send, recv;
+ } v2;
+ } u;
+} *ntlm_ctx;
+
+typedef struct {
+ char *user;
+ char *domain;
+} *ntlm_name;
+
+#include <ntlm-private.h>
+
+
+#endif /* NTLM_NTLM_H */
diff --git a/crypto/heimdal/lib/gssapi/ntlm/process_context_token.c b/crypto/heimdal/lib/gssapi/ntlm/process_context_token.c
new file mode 100644
index 0000000..16efcd1
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/process_context_token.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV _gss_ntlm_process_context_token (
+ OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t token_buffer
+ )
+{
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/ntlm/release_cred.c b/crypto/heimdal/lib/gssapi/ntlm/release_cred.c
new file mode 100644
index 0000000..49d88a2
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/release_cred.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV _gss_ntlm_release_cred
+ (OM_uint32 * minor_status,
+ gss_cred_id_t * cred_handle
+ )
+{
+ ntlm_cred cred;
+
+ if (minor_status)
+ *minor_status = 0;
+
+ if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL)
+ return GSS_S_COMPLETE;
+
+ cred = (ntlm_cred)*cred_handle;
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+
+ if (cred->username)
+ free(cred->username);
+ if (cred->domain)
+ free(cred->domain);
+ if (cred->key.data) {
+ memset(cred->key.data, 0, cred->key.length);
+ free(cred->key.data);
+ }
+
+ return GSS_S_COMPLETE;
+}
+
diff --git a/crypto/heimdal/lib/gssapi/ntlm/release_name.c b/crypto/heimdal/lib/gssapi/ntlm/release_name.c
new file mode 100644
index 0000000..86c1da3
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/ntlm/release_name.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "ntlm.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_ntlm_release_name
+ (OM_uint32 * minor_status,
+ gss_name_t * input_name
+ )
+{
+ if (minor_status)
+ *minor_status = 0;
+ if (input_name) {
+ ntlm_name n = (ntlm_name)*input_name;
+ *input_name = GSS_C_NO_NAME;
+ free(n->user);
+ free(n->domain);
+ free(n);
+ }
+ return GSS_S_COMPLETE;
+}
diff --git a/crypto/heimdal/lib/gssapi/spnego/accept_sec_context.c b/crypto/heimdal/lib/gssapi/spnego/accept_sec_context.c
new file mode 100644
index 0000000..3a51dd3
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/spnego/accept_sec_context.c
@@ -0,0 +1,917 @@
+/*
+ * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * Portions Copyright (c) 2004 PADL Software Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "spnego_locl.h"
+
+static OM_uint32
+send_reject (OM_uint32 *minor_status,
+ gss_buffer_t output_token)
+{
+ NegotiationToken nt;
+ size_t size;
+
+ nt.element = choice_NegotiationToken_negTokenResp;
+
+ ALLOC(nt.u.negTokenResp.negResult, 1);
+ if (nt.u.negTokenResp.negResult == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ *(nt.u.negTokenResp.negResult) = reject;
+ nt.u.negTokenResp.supportedMech = NULL;
+ nt.u.negTokenResp.responseToken = NULL;
+ nt.u.negTokenResp.mechListMIC = NULL;
+
+ ASN1_MALLOC_ENCODE(NegotiationToken,
+ output_token->value, output_token->length, &nt,
+ &size, *minor_status);
+ free_NegotiationToken(&nt);
+ if (*minor_status != 0)
+ return GSS_S_FAILURE;
+
+ return GSS_S_BAD_MECH;
+}
+
+static OM_uint32
+acceptor_approved(gss_name_t target_name, gss_OID mech)
+{
+ gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
+ gss_OID_set oidset;
+ OM_uint32 junk, ret;
+
+ if (target_name == GSS_C_NO_NAME)
+ return GSS_S_COMPLETE;
+
+ gss_create_empty_oid_set(&junk, &oidset);
+ gss_add_oid_set_member(&junk, mech, &oidset);
+
+ ret = gss_acquire_cred(&junk, target_name, GSS_C_INDEFINITE, oidset,
+ GSS_C_ACCEPT, &cred, NULL, NULL);
+ gss_release_oid_set(&junk, &oidset);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+ gss_release_cred(&junk, &cred);
+
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+send_supported_mechs (OM_uint32 *minor_status,
+ gss_buffer_t output_token)
+{
+ NegotiationTokenWin nt;
+ size_t buf_len = 0;
+ gss_buffer_desc data;
+ OM_uint32 ret;
+
+ memset(&nt, 0, sizeof(nt));
+
+ nt.element = choice_NegotiationTokenWin_negTokenInit;
+ nt.u.negTokenInit.reqFlags = NULL;
+ nt.u.negTokenInit.mechToken = NULL;
+ nt.u.negTokenInit.negHints = NULL;
+
+ ret = _gss_spnego_indicate_mechtypelist(minor_status, GSS_C_NO_NAME,
+ acceptor_approved, 1, NULL,
+ &nt.u.negTokenInit.mechTypes, NULL);
+ if (ret != GSS_S_COMPLETE) {
+ return ret;
+ }
+
+ ALLOC(nt.u.negTokenInit.negHints, 1);
+ if (nt.u.negTokenInit.negHints == NULL) {
+ *minor_status = ENOMEM;
+ free_NegotiationTokenWin(&nt);
+ return GSS_S_FAILURE;
+ }
+
+ ALLOC(nt.u.negTokenInit.negHints->hintName, 1);
+ if (nt.u.negTokenInit.negHints->hintName == NULL) {
+ *minor_status = ENOMEM;
+ free_NegotiationTokenWin(&nt);
+ return GSS_S_FAILURE;
+ }
+
+ *nt.u.negTokenInit.negHints->hintName = strdup("not_defined_in_RFC4178@please_ignore");
+ nt.u.negTokenInit.negHints->hintAddress = NULL;
+
+ ASN1_MALLOC_ENCODE(NegotiationTokenWin,
+ data.value, data.length, &nt, &buf_len, ret);
+ free_NegotiationTokenWin(&nt);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ if (data.length != buf_len) {
+ abort();
+ UNREACHABLE(return GSS_S_FAILURE);
+ }
+
+ ret = gss_encapsulate_token(&data, GSS_SPNEGO_MECHANISM, output_token);
+
+ free (data.value);
+
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ *minor_status = 0;
+
+ return GSS_S_CONTINUE_NEEDED;
+}
+
+static OM_uint32
+send_accept (OM_uint32 *minor_status,
+ gssspnego_ctx context_handle,
+ gss_buffer_t mech_token,
+ int initial_response,
+ gss_buffer_t mech_buf,
+ gss_buffer_t output_token)
+{
+ NegotiationToken nt;
+ OM_uint32 ret;
+ gss_buffer_desc mech_mic_buf;
+ size_t size;
+
+ memset(&nt, 0, sizeof(nt));
+
+ nt.element = choice_NegotiationToken_negTokenResp;
+
+ ALLOC(nt.u.negTokenResp.negResult, 1);
+ if (nt.u.negTokenResp.negResult == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ if (context_handle->open) {
+ if (mech_token != GSS_C_NO_BUFFER
+ && mech_token->length != 0
+ && mech_buf != GSS_C_NO_BUFFER)
+ *(nt.u.negTokenResp.negResult) = accept_incomplete;
+ else
+ *(nt.u.negTokenResp.negResult) = accept_completed;
+ } else {
+ if (initial_response && context_handle->require_mic)
+ *(nt.u.negTokenResp.negResult) = request_mic;
+ else
+ *(nt.u.negTokenResp.negResult) = accept_incomplete;
+ }
+
+ if (initial_response) {
+ ALLOC(nt.u.negTokenResp.supportedMech, 1);
+ if (nt.u.negTokenResp.supportedMech == NULL) {
+ free_NegotiationToken(&nt);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ ret = der_get_oid(context_handle->preferred_mech_type->elements,
+ context_handle->preferred_mech_type->length,
+ nt.u.negTokenResp.supportedMech,
+ NULL);
+ if (ret) {
+ free_NegotiationToken(&nt);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ } else {
+ nt.u.negTokenResp.supportedMech = NULL;
+ }
+
+ if (mech_token != GSS_C_NO_BUFFER && mech_token->length != 0) {
+ ALLOC(nt.u.negTokenResp.responseToken, 1);
+ if (nt.u.negTokenResp.responseToken == NULL) {
+ free_NegotiationToken(&nt);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ nt.u.negTokenResp.responseToken->length = mech_token->length;
+ nt.u.negTokenResp.responseToken->data = mech_token->value;
+ mech_token->length = 0;
+ mech_token->value = NULL;
+ } else {
+ nt.u.negTokenResp.responseToken = NULL;
+ }
+
+ if (mech_buf != GSS_C_NO_BUFFER) {
+ ret = gss_get_mic(minor_status,
+ context_handle->negotiated_ctx_id,
+ 0,
+ mech_buf,
+ &mech_mic_buf);
+ if (ret == GSS_S_COMPLETE) {
+ ALLOC(nt.u.negTokenResp.mechListMIC, 1);
+ if (nt.u.negTokenResp.mechListMIC == NULL) {
+ gss_release_buffer(minor_status, &mech_mic_buf);
+ free_NegotiationToken(&nt);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ nt.u.negTokenResp.mechListMIC->length = mech_mic_buf.length;
+ nt.u.negTokenResp.mechListMIC->data = mech_mic_buf.value;
+ } else if (ret == GSS_S_UNAVAILABLE) {
+ nt.u.negTokenResp.mechListMIC = NULL;
+ } else {
+ free_NegotiationToken(&nt);
+ return ret;
+ }
+
+ } else
+ nt.u.negTokenResp.mechListMIC = NULL;
+
+ ASN1_MALLOC_ENCODE(NegotiationToken,
+ output_token->value, output_token->length,
+ &nt, &size, ret);
+ if (ret) {
+ free_NegotiationToken(&nt);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ /*
+ * The response should not be encapsulated, because
+ * it is a SubsequentContextToken (note though RFC 1964
+ * specifies encapsulation for all _Kerberos_ tokens).
+ */
+
+ if (*(nt.u.negTokenResp.negResult) == accept_completed)
+ ret = GSS_S_COMPLETE;
+ else
+ ret = GSS_S_CONTINUE_NEEDED;
+ free_NegotiationToken(&nt);
+ return ret;
+}
+
+
+static OM_uint32
+verify_mechlist_mic
+ (OM_uint32 *minor_status,
+ gssspnego_ctx context_handle,
+ gss_buffer_t mech_buf,
+ heim_octet_string *mechListMIC
+ )
+{
+ OM_uint32 ret;
+ gss_buffer_desc mic_buf;
+
+ if (context_handle->verified_mic) {
+ /* This doesn't make sense, we've already verified it? */
+ *minor_status = 0;
+ return GSS_S_DUPLICATE_TOKEN;
+ }
+
+ if (mechListMIC == NULL) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ mic_buf.length = mechListMIC->length;
+ mic_buf.value = mechListMIC->data;
+
+ ret = gss_verify_mic(minor_status,
+ context_handle->negotiated_ctx_id,
+ mech_buf,
+ &mic_buf,
+ NULL);
+
+ if (ret != GSS_S_COMPLETE)
+ ret = GSS_S_DEFECTIVE_TOKEN;
+
+ return ret;
+}
+
+static OM_uint32
+select_mech(OM_uint32 *minor_status, MechType *mechType, int verify_p,
+ gss_OID *mech_p)
+{
+ char mechbuf[64];
+ size_t mech_len;
+ gss_OID_desc oid;
+ gss_OID oidp;
+ gss_OID_set mechs;
+ size_t i;
+ OM_uint32 ret, junk;
+
+ ret = der_put_oid ((unsigned char *)mechbuf + sizeof(mechbuf) - 1,
+ sizeof(mechbuf),
+ mechType,
+ &mech_len);
+ if (ret) {
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ oid.length = mech_len;
+ oid.elements = mechbuf + sizeof(mechbuf) - mech_len;
+
+ if (gss_oid_equal(&oid, GSS_SPNEGO_MECHANISM)) {
+ return GSS_S_BAD_MECH;
+ }
+
+ *minor_status = 0;
+
+ /* Translate broken MS Kebreros OID */
+ if (gss_oid_equal(&oid, &_gss_spnego_mskrb_mechanism_oid_desc))
+ oidp = &_gss_spnego_krb5_mechanism_oid_desc;
+ else
+ oidp = &oid;
+
+
+ ret = gss_indicate_mechs(&junk, &mechs);
+ if (ret)
+ return (ret);
+
+ for (i = 0; i < mechs->count; i++)
+ if (gss_oid_equal(&mechs->elements[i], oidp))
+ break;
+
+ if (i == mechs->count) {
+ gss_release_oid_set(&junk, &mechs);
+ return GSS_S_BAD_MECH;
+ }
+ gss_release_oid_set(&junk, &mechs);
+
+ ret = gss_duplicate_oid(minor_status,
+ &oid, /* possibly this should be oidp */
+ mech_p);
+
+ if (verify_p) {
+ gss_name_t name = GSS_C_NO_NAME;
+ gss_buffer_desc namebuf;
+ char *str = NULL, *host, hostname[MAXHOSTNAMELEN];
+
+ host = getenv("GSSAPI_SPNEGO_NAME");
+ if (host == NULL || issuid()) {
+ int rv;
+ if (gethostname(hostname, sizeof(hostname)) != 0) {
+ *minor_status = errno;
+ return GSS_S_FAILURE;
+ }
+ rv = asprintf(&str, "host@%s", hostname);
+ if (rv < 0 || str == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ host = str;
+ }
+
+ namebuf.length = strlen(host);
+ namebuf.value = host;
+
+ ret = gss_import_name(minor_status, &namebuf,
+ GSS_C_NT_HOSTBASED_SERVICE, &name);
+ if (str)
+ free(str);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ ret = acceptor_approved(name, *mech_p);
+ gss_release_name(&junk, &name);
+ }
+
+ return ret;
+}
+
+
+static OM_uint32
+acceptor_complete(OM_uint32 * minor_status,
+ gssspnego_ctx ctx,
+ int *get_mic,
+ gss_buffer_t mech_buf,
+ gss_buffer_t mech_input_token,
+ gss_buffer_t mech_output_token,
+ heim_octet_string *mic,
+ gss_buffer_t output_token)
+{
+ OM_uint32 ret;
+ int require_mic, verify_mic;
+
+ ret = _gss_spnego_require_mechlist_mic(minor_status, ctx, &require_mic);
+ if (ret)
+ return ret;
+
+ ctx->require_mic = require_mic;
+
+ if (mic != NULL)
+ require_mic = 1;
+
+ if (ctx->open && require_mic) {
+ if (mech_input_token == GSS_C_NO_BUFFER) { /* Even/One */
+ verify_mic = 1;
+ *get_mic = 0;
+ } else if (mech_output_token != GSS_C_NO_BUFFER &&
+ mech_output_token->length == 0) { /* Odd */
+ *get_mic = verify_mic = 1;
+ } else { /* Even/One */
+ verify_mic = 0;
+ *get_mic = 1;
+ }
+
+ if (verify_mic || *get_mic) {
+ int eret;
+ size_t buf_len = 0;
+
+ ASN1_MALLOC_ENCODE(MechTypeList,
+ mech_buf->value, mech_buf->length,
+ &ctx->initiator_mech_types, &buf_len, eret);
+ if (eret) {
+ *minor_status = eret;
+ return GSS_S_FAILURE;
+ }
+ heim_assert(mech_buf->length == buf_len, "Internal ASN.1 error");
+ UNREACHABLE(return GSS_S_FAILURE);
+ }
+
+ if (verify_mic) {
+ ret = verify_mechlist_mic(minor_status, ctx, mech_buf, mic);
+ if (ret) {
+ if (*get_mic)
+ send_reject (minor_status, output_token);
+ return ret;
+ }
+ ctx->verified_mic = 1;
+ }
+ } else
+ *get_mic = 0;
+
+ return GSS_S_COMPLETE;
+}
+
+
+static OM_uint32 GSSAPI_CALLCONV
+acceptor_start
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ const gss_channel_bindings_t input_chan_bindings,
+ gss_name_t * src_name,
+ gss_OID * mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec,
+ gss_cred_id_t *delegated_cred_handle
+ )
+{
+ OM_uint32 ret, junk;
+ NegotiationToken nt;
+ size_t nt_len;
+ NegTokenInit *ni;
+ gss_buffer_desc data;
+ gss_buffer_t mech_input_token = GSS_C_NO_BUFFER;
+ gss_buffer_desc mech_output_token;
+ gss_buffer_desc mech_buf;
+ gss_OID preferred_mech_type = GSS_C_NO_OID;
+ gssspnego_ctx ctx;
+ int get_mic = 0;
+ int first_ok = 0;
+
+ mech_output_token.value = NULL;
+ mech_output_token.length = 0;
+ mech_buf.value = NULL;
+
+ if (input_token_buffer->length == 0)
+ return send_supported_mechs (minor_status, output_token);
+
+ ret = _gss_spnego_alloc_sec_context(minor_status, context_handle);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ ctx = (gssspnego_ctx)*context_handle;
+
+ /*
+ * The GSS-API encapsulation is only present on the initial
+ * context token (negTokenInit).
+ */
+ ret = gss_decapsulate_token (input_token_buffer,
+ GSS_SPNEGO_MECHANISM,
+ &data);
+ if (ret)
+ return ret;
+
+ ret = decode_NegotiationToken(data.value, data.length, &nt, &nt_len);
+ gss_release_buffer(minor_status, &data);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+ if (nt.element != choice_NegotiationToken_negTokenInit) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+ ni = &nt.u.negTokenInit;
+
+ if (ni->mechTypes.len < 1) {
+ free_NegotiationToken(&nt);
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ ret = copy_MechTypeList(&ni->mechTypes, &ctx->initiator_mech_types);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ free_NegotiationToken(&nt);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ /*
+ * First we try the opportunistic token if we have support for it,
+ * don't try to verify we have credential for the token,
+ * gss_accept_sec_context() will (hopefully) tell us that.
+ * If that failes,
+ */
+
+ ret = select_mech(minor_status,
+ &ni->mechTypes.val[0],
+ 0,
+ &preferred_mech_type);
+
+ if (ret == 0 && ni->mechToken != NULL) {
+ gss_buffer_desc ibuf;
+
+ ibuf.length = ni->mechToken->length;
+ ibuf.value = ni->mechToken->data;
+ mech_input_token = &ibuf;
+
+ if (ctx->mech_src_name != GSS_C_NO_NAME)
+ gss_release_name(&junk, &ctx->mech_src_name);
+
+ ret = gss_accept_sec_context(minor_status,
+ &ctx->negotiated_ctx_id,
+ acceptor_cred_handle,
+ mech_input_token,
+ input_chan_bindings,
+ &ctx->mech_src_name,
+ &ctx->negotiated_mech_type,
+ &mech_output_token,
+ &ctx->mech_flags,
+ &ctx->mech_time_rec,
+ delegated_cred_handle);
+
+ if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
+ ctx->preferred_mech_type = preferred_mech_type;
+ if (ret == GSS_S_COMPLETE)
+ ctx->open = 1;
+
+ ret = acceptor_complete(minor_status,
+ ctx,
+ &get_mic,
+ &mech_buf,
+ mech_input_token,
+ &mech_output_token,
+ ni->mechListMIC,
+ output_token);
+ if (ret != GSS_S_COMPLETE)
+ goto out;
+
+ first_ok = 1;
+ } else {
+ gss_mg_collect_error(preferred_mech_type, ret, *minor_status);
+ }
+ }
+
+ /*
+ * If opportunistic token failed, lets try the other mechs.
+ */
+
+ if (!first_ok && ni->mechToken != NULL) {
+ size_t j;
+
+ preferred_mech_type = GSS_C_NO_OID;
+
+ /* Call glue layer to find first mech we support */
+ for (j = 1; j < ni->mechTypes.len; ++j) {
+ ret = select_mech(minor_status,
+ &ni->mechTypes.val[j],
+ 1,
+ &preferred_mech_type);
+ if (ret == 0)
+ break;
+ }
+ if (preferred_mech_type == GSS_C_NO_OID) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ free_NegotiationToken(&nt);
+ return ret;
+ }
+
+ ctx->preferred_mech_type = preferred_mech_type;
+ }
+
+ /*
+ * The initial token always have a response
+ */
+
+ ret = send_accept (minor_status,
+ ctx,
+ &mech_output_token,
+ 1,
+ get_mic ? &mech_buf : NULL,
+ output_token);
+ if (ret)
+ goto out;
+
+out:
+ if (mech_output_token.value != NULL)
+ gss_release_buffer(&junk, &mech_output_token);
+ if (mech_buf.value != NULL) {
+ free(mech_buf.value);
+ mech_buf.value = NULL;
+ }
+ free_NegotiationToken(&nt);
+
+
+ if (ret == GSS_S_COMPLETE) {
+ if (src_name != NULL && ctx->mech_src_name != NULL) {
+ spnego_name name;
+
+ name = calloc(1, sizeof(*name));
+ if (name) {
+ name->mech = ctx->mech_src_name;
+ ctx->mech_src_name = NULL;
+ *src_name = (gss_name_t)name;
+ }
+ }
+ }
+
+ if (mech_type != NULL)
+ *mech_type = ctx->negotiated_mech_type;
+ if (ret_flags != NULL)
+ *ret_flags = ctx->mech_flags;
+ if (time_rec != NULL)
+ *time_rec = ctx->mech_time_rec;
+
+ if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+ }
+
+ _gss_spnego_internal_delete_sec_context(&junk, context_handle,
+ GSS_C_NO_BUFFER);
+
+ return ret;
+}
+
+
+static OM_uint32 GSSAPI_CALLCONV
+acceptor_continue
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ const gss_channel_bindings_t input_chan_bindings,
+ gss_name_t * src_name,
+ gss_OID * mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec,
+ gss_cred_id_t *delegated_cred_handle
+ )
+{
+ OM_uint32 ret, ret2, minor;
+ NegotiationToken nt;
+ size_t nt_len;
+ NegTokenResp *na;
+ unsigned int negResult = accept_incomplete;
+ gss_buffer_t mech_input_token = GSS_C_NO_BUFFER;
+ gss_buffer_t mech_output_token = GSS_C_NO_BUFFER;
+ gss_buffer_desc mech_buf;
+ gssspnego_ctx ctx;
+
+ mech_buf.value = NULL;
+
+ ctx = (gssspnego_ctx)*context_handle;
+
+ /*
+ * The GSS-API encapsulation is only present on the initial
+ * context token (negTokenInit).
+ */
+
+ ret = decode_NegotiationToken(input_token_buffer->value,
+ input_token_buffer->length,
+ &nt, &nt_len);
+ if (ret) {
+ *minor_status = ret;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+ if (nt.element != choice_NegotiationToken_negTokenResp) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+ na = &nt.u.negTokenResp;
+
+ if (na->negResult != NULL) {
+ negResult = *(na->negResult);
+ }
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ {
+ gss_buffer_desc ibuf, obuf;
+ int require_mic, get_mic = 0;
+ int require_response;
+ heim_octet_string *mic;
+
+ if (na->responseToken != NULL) {
+ ibuf.length = na->responseToken->length;
+ ibuf.value = na->responseToken->data;
+ mech_input_token = &ibuf;
+ } else {
+ ibuf.value = NULL;
+ ibuf.length = 0;
+ }
+
+ if (mech_input_token != GSS_C_NO_BUFFER) {
+
+ if (ctx->mech_src_name != GSS_C_NO_NAME)
+ gss_release_name(&minor, &ctx->mech_src_name);
+
+ ret = gss_accept_sec_context(&minor,
+ &ctx->negotiated_ctx_id,
+ acceptor_cred_handle,
+ mech_input_token,
+ input_chan_bindings,
+ &ctx->mech_src_name,
+ &ctx->negotiated_mech_type,
+ &obuf,
+ &ctx->mech_flags,
+ &ctx->mech_time_rec,
+ delegated_cred_handle);
+
+ if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
+ mech_output_token = &obuf;
+ }
+ if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) {
+ free_NegotiationToken(&nt);
+ gss_mg_collect_error(ctx->negotiated_mech_type, ret, minor);
+ send_reject (minor_status, output_token);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+ }
+ if (ret == GSS_S_COMPLETE)
+ ctx->open = 1;
+ } else
+ ret = GSS_S_COMPLETE;
+
+ ret2 = _gss_spnego_require_mechlist_mic(minor_status,
+ ctx,
+ &require_mic);
+ if (ret2)
+ goto out;
+
+ ctx->require_mic = require_mic;
+
+ mic = na->mechListMIC;
+ if (mic != NULL)
+ require_mic = 1;
+
+ if (ret == GSS_S_COMPLETE)
+ ret = acceptor_complete(minor_status,
+ ctx,
+ &get_mic,
+ &mech_buf,
+ mech_input_token,
+ mech_output_token,
+ na->mechListMIC,
+ output_token);
+
+ if (ctx->mech_flags & GSS_C_DCE_STYLE)
+ require_response = (negResult != accept_completed);
+ else
+ require_response = 0;
+
+ /*
+ * Check whether we need to send a result: there should be only
+ * one accept_completed response sent in the entire negotiation
+ */
+ if ((mech_output_token != GSS_C_NO_BUFFER &&
+ mech_output_token->length != 0)
+ || (ctx->open && negResult == accept_incomplete)
+ || require_response
+ || get_mic) {
+ ret2 = send_accept (minor_status,
+ ctx,
+ mech_output_token,
+ 0,
+ get_mic ? &mech_buf : NULL,
+ output_token);
+ if (ret2)
+ goto out;
+ }
+
+ out:
+ if (ret2 != GSS_S_COMPLETE)
+ ret = ret2;
+ if (mech_output_token != NULL)
+ gss_release_buffer(&minor, mech_output_token);
+ if (mech_buf.value != NULL)
+ free(mech_buf.value);
+ free_NegotiationToken(&nt);
+ }
+
+ if (ret == GSS_S_COMPLETE) {
+ if (src_name != NULL && ctx->mech_src_name != NULL) {
+ spnego_name name;
+
+ name = calloc(1, sizeof(*name));
+ if (name) {
+ name->mech = ctx->mech_src_name;
+ ctx->mech_src_name = NULL;
+ *src_name = (gss_name_t)name;
+ }
+ }
+ }
+
+ if (mech_type != NULL)
+ *mech_type = ctx->negotiated_mech_type;
+ if (ret_flags != NULL)
+ *ret_flags = ctx->mech_flags;
+ if (time_rec != NULL)
+ *time_rec = ctx->mech_time_rec;
+
+ if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+ }
+
+ _gss_spnego_internal_delete_sec_context(&minor, context_handle,
+ GSS_C_NO_BUFFER);
+
+ return ret;
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_accept_sec_context
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token_buffer,
+ const gss_channel_bindings_t input_chan_bindings,
+ gss_name_t * src_name,
+ gss_OID * mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec,
+ gss_cred_id_t *delegated_cred_handle
+ )
+{
+ _gss_accept_sec_context_t *func;
+
+ *minor_status = 0;
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ if (src_name != NULL)
+ *src_name = GSS_C_NO_NAME;
+ if (mech_type != NULL)
+ *mech_type = GSS_C_NO_OID;
+ if (ret_flags != NULL)
+ *ret_flags = 0;
+ if (time_rec != NULL)
+ *time_rec = 0;
+ if (delegated_cred_handle != NULL)
+ *delegated_cred_handle = GSS_C_NO_CREDENTIAL;
+
+
+ if (*context_handle == GSS_C_NO_CONTEXT)
+ func = acceptor_start;
+ else
+ func = acceptor_continue;
+
+
+ return (*func)(minor_status, context_handle, acceptor_cred_handle,
+ input_token_buffer, input_chan_bindings,
+ src_name, mech_type, output_token, ret_flags,
+ time_rec, delegated_cred_handle);
+}
diff --git a/crypto/heimdal/lib/gssapi/spnego/compat.c b/crypto/heimdal/lib/gssapi/spnego/compat.c
new file mode 100644
index 0000000..cf5ee30
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/spnego/compat.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "spnego_locl.h"
+
+/*
+ * Apparently Microsoft got the OID wrong, and used
+ * 1.2.840.48018.1.2.2 instead. We need both this and
+ * the correct Kerberos OID here in order to deal with
+ * this. Because this is manifest in SPNEGO only I'd
+ * prefer to deal with this here rather than inside the
+ * Kerberos mechanism.
+ */
+gss_OID_desc _gss_spnego_mskrb_mechanism_oid_desc =
+ {9, rk_UNCONST("\x2a\x86\x48\x82\xf7\x12\x01\x02\x02")};
+
+gss_OID_desc _gss_spnego_krb5_mechanism_oid_desc =
+ {9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")};
+
+/*
+ * Allocate a SPNEGO context handle
+ */
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_alloc_sec_context (OM_uint32 * minor_status,
+ gss_ctx_id_t *context_handle)
+{
+ gssspnego_ctx ctx;
+
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ ctx->initiator_mech_types.len = 0;
+ ctx->initiator_mech_types.val = NULL;
+ ctx->preferred_mech_type = GSS_C_NO_OID;
+ ctx->negotiated_mech_type = GSS_C_NO_OID;
+ ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
+
+ /*
+ * Cache these so we can return them before returning
+ * GSS_S_COMPLETE, even if the mechanism has itself
+ * completed earlier
+ */
+ ctx->mech_flags = 0;
+ ctx->mech_time_rec = 0;
+ ctx->mech_src_name = GSS_C_NO_NAME;
+
+ ctx->open = 0;
+ ctx->local = 0;
+ ctx->require_mic = 0;
+ ctx->verified_mic = 0;
+
+ HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
+
+ *context_handle = (gss_ctx_id_t)ctx;
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * Free a SPNEGO context handle. The caller must have acquired
+ * the lock before this is called.
+ */
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_internal_delete_sec_context
+ (OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ gss_buffer_t output_token
+ )
+{
+ gssspnego_ctx ctx;
+ OM_uint32 ret, minor;
+
+ *minor_status = 0;
+
+ if (context_handle == NULL) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ if (output_token != GSS_C_NO_BUFFER) {
+ output_token->length = 0;
+ output_token->value = NULL;
+ }
+
+ ctx = (gssspnego_ctx)*context_handle;
+ *context_handle = GSS_C_NO_CONTEXT;
+
+ if (ctx == NULL) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ if (ctx->initiator_mech_types.val != NULL)
+ free_MechTypeList(&ctx->initiator_mech_types);
+
+ gss_release_oid(&minor, &ctx->preferred_mech_type);
+ ctx->negotiated_mech_type = GSS_C_NO_OID;
+
+ gss_release_name(&minor, &ctx->target_name);
+ gss_release_name(&minor, &ctx->mech_src_name);
+
+ if (ctx->negotiated_ctx_id != GSS_C_NO_CONTEXT) {
+ ret = gss_delete_sec_context(minor_status,
+ &ctx->negotiated_ctx_id,
+ output_token);
+ ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
+ } else {
+ ret = GSS_S_COMPLETE;
+ }
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
+
+ free(ctx);
+
+ return ret;
+}
+
+/*
+ * For compatability with the Windows SPNEGO implementation, the
+ * default is to ignore the mechListMIC unless CFX is used and
+ * a non-preferred mechanism was negotiated
+ */
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_require_mechlist_mic(OM_uint32 *minor_status,
+ gssspnego_ctx ctx,
+ int *require_mic)
+{
+ gss_buffer_set_t buffer_set = GSS_C_NO_BUFFER_SET;
+ OM_uint32 minor;
+
+ *minor_status = 0;
+ *require_mic = 0;
+
+ if (ctx == NULL) {
+ return GSS_S_COMPLETE;
+ }
+
+ if (ctx->require_mic) {
+ /* Acceptor requested it: mandatory to honour */
+ *require_mic = 1;
+ return GSS_S_COMPLETE;
+ }
+
+ /*
+ * Check whether peer indicated implicit support for updated SPNEGO
+ * (eg. in the Kerberos case by using CFX)
+ */
+ if (gss_inquire_sec_context_by_oid(&minor, ctx->negotiated_ctx_id,
+ GSS_C_PEER_HAS_UPDATED_SPNEGO,
+ &buffer_set) == GSS_S_COMPLETE) {
+ *require_mic = 1;
+ gss_release_buffer_set(&minor, &buffer_set);
+ }
+
+ /* Safe-to-omit MIC rules follow */
+ if (*require_mic) {
+ if (gss_oid_equal(ctx->negotiated_mech_type, ctx->preferred_mech_type)) {
+ *require_mic = 0;
+ } else if (gss_oid_equal(ctx->negotiated_mech_type, &_gss_spnego_krb5_mechanism_oid_desc) &&
+ gss_oid_equal(ctx->preferred_mech_type, &_gss_spnego_mskrb_mechanism_oid_desc)) {
+ *require_mic = 0;
+ }
+ }
+
+ return GSS_S_COMPLETE;
+}
+
+static int
+add_mech_type(gss_OID mech_type,
+ int includeMSCompatOID,
+ MechTypeList *mechtypelist)
+{
+ MechType mech;
+ int ret;
+
+ if (gss_oid_equal(mech_type, GSS_SPNEGO_MECHANISM))
+ return 0;
+
+ if (includeMSCompatOID &&
+ gss_oid_equal(mech_type, &_gss_spnego_krb5_mechanism_oid_desc)) {
+ ret = der_get_oid(_gss_spnego_mskrb_mechanism_oid_desc.elements,
+ _gss_spnego_mskrb_mechanism_oid_desc.length,
+ &mech,
+ NULL);
+ if (ret)
+ return ret;
+ ret = add_MechTypeList(mechtypelist, &mech);
+ free_MechType(&mech);
+ if (ret)
+ return ret;
+ }
+ ret = der_get_oid(mech_type->elements, mech_type->length, &mech, NULL);
+ if (ret)
+ return ret;
+ ret = add_MechTypeList(mechtypelist, &mech);
+ free_MechType(&mech);
+ return ret;
+}
+
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_indicate_mechtypelist (OM_uint32 *minor_status,
+ gss_name_t target_name,
+ OM_uint32 (*func)(gss_name_t, gss_OID),
+ int includeMSCompatOID,
+ const gss_cred_id_t cred_handle,
+ MechTypeList *mechtypelist,
+ gss_OID *preferred_mech)
+{
+ gss_OID_set supported_mechs = GSS_C_NO_OID_SET;
+ gss_OID first_mech = GSS_C_NO_OID;
+ OM_uint32 ret;
+ size_t i;
+
+ mechtypelist->len = 0;
+ mechtypelist->val = NULL;
+
+ if (cred_handle) {
+ ret = gss_inquire_cred(minor_status,
+ cred_handle,
+ NULL,
+ NULL,
+ NULL,
+ &supported_mechs);
+ } else {
+ ret = gss_indicate_mechs(minor_status, &supported_mechs);
+ }
+
+ if (ret != GSS_S_COMPLETE) {
+ return ret;
+ }
+
+ if (supported_mechs->count == 0) {
+ *minor_status = ENOENT;
+ gss_release_oid_set(minor_status, &supported_mechs);
+ return GSS_S_FAILURE;
+ }
+
+ ret = (*func)(target_name, GSS_KRB5_MECHANISM);
+ if (ret == GSS_S_COMPLETE) {
+ ret = add_mech_type(GSS_KRB5_MECHANISM,
+ includeMSCompatOID,
+ mechtypelist);
+ if (!GSS_ERROR(ret))
+ first_mech = GSS_KRB5_MECHANISM;
+ }
+ ret = GSS_S_COMPLETE;
+
+ for (i = 0; i < supported_mechs->count; i++) {
+ OM_uint32 subret;
+ if (gss_oid_equal(&supported_mechs->elements[i], GSS_SPNEGO_MECHANISM))
+ continue;
+ if (gss_oid_equal(&supported_mechs->elements[i], GSS_KRB5_MECHANISM))
+ continue;
+
+ subret = (*func)(target_name, &supported_mechs->elements[i]);
+ if (subret != GSS_S_COMPLETE)
+ continue;
+
+ ret = add_mech_type(&supported_mechs->elements[i],
+ includeMSCompatOID,
+ mechtypelist);
+ if (ret != 0) {
+ *minor_status = ret;
+ ret = GSS_S_FAILURE;
+ break;
+ }
+ if (first_mech == GSS_C_NO_OID)
+ first_mech = &supported_mechs->elements[i];
+ }
+
+ if (mechtypelist->len == 0) {
+ gss_release_oid_set(minor_status, &supported_mechs);
+ *minor_status = 0;
+ return GSS_S_BAD_MECH;
+ }
+
+ if (preferred_mech != NULL) {
+ ret = gss_duplicate_oid(minor_status, first_mech, preferred_mech);
+ if (ret != GSS_S_COMPLETE)
+ free_MechTypeList(mechtypelist);
+ }
+ gss_release_oid_set(minor_status, &supported_mechs);
+
+ return ret;
+}
diff --git a/crypto/heimdal/lib/gssapi/spnego/context_stubs.c b/crypto/heimdal/lib/gssapi/spnego/context_stubs.c
new file mode 100644
index 0000000..70ca728
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/spnego/context_stubs.c
@@ -0,0 +1,815 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "spnego_locl.h"
+
+static OM_uint32
+spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs)
+{
+ OM_uint32 ret, junk;
+ gss_OID_set m;
+ size_t i;
+
+ ret = gss_indicate_mechs(minor_status, &m);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ ret = gss_create_empty_oid_set(minor_status, mechs);
+ if (ret != GSS_S_COMPLETE) {
+ gss_release_oid_set(&junk, &m);
+ return ret;
+ }
+
+ for (i = 0; i < m->count; i++) {
+ if (gss_oid_equal(&m->elements[i], GSS_SPNEGO_MECHANISM))
+ continue;
+
+ ret = gss_add_oid_set_member(minor_status, &m->elements[i], mechs);
+ if (ret) {
+ gss_release_oid_set(&junk, &m);
+ gss_release_oid_set(&junk, mechs);
+ return ret;
+ }
+ }
+ gss_release_oid_set(&junk, &m);
+ return ret;
+}
+
+
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_process_context_token
+ (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t token_buffer
+ )
+{
+ gss_ctx_id_t context ;
+ gssspnego_ctx ctx;
+ OM_uint32 ret;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
+
+ context = context_handle;
+ ctx = (gssspnego_ctx)context_handle;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ ret = gss_process_context_token(minor_status,
+ ctx->negotiated_ctx_id,
+ token_buffer);
+ if (ret != GSS_S_COMPLETE) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+ }
+
+ ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
+
+ return _gss_spnego_internal_delete_sec_context(minor_status,
+ &context,
+ GSS_C_NO_BUFFER);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_delete_sec_context
+ (OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ gss_buffer_t output_token
+ )
+{
+ gssspnego_ctx ctx;
+
+ if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
+
+ ctx = (gssspnego_ctx)*context_handle;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ return _gss_spnego_internal_delete_sec_context(minor_status,
+ context_handle,
+ output_token);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_context_time
+ (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ OM_uint32 *time_rec
+ )
+{
+ gssspnego_ctx ctx;
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_context_time(minor_status,
+ ctx->negotiated_ctx_id,
+ time_rec);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_get_mic
+ (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_qop_t qop_req,
+ const gss_buffer_t message_buffer,
+ gss_buffer_t message_token
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_get_mic(minor_status, ctx->negotiated_ctx_id,
+ qop_req, message_buffer, message_token);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_verify_mic
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t message_buffer,
+ const gss_buffer_t token_buffer,
+ gss_qop_t * qop_state
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_verify_mic(minor_status,
+ ctx->negotiated_ctx_id,
+ message_buffer,
+ token_buffer,
+ qop_state);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_wrap
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ const gss_buffer_t input_message_buffer,
+ int * conf_state,
+ gss_buffer_t output_message_buffer
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_wrap(minor_status,
+ ctx->negotiated_ctx_id,
+ conf_req_flag,
+ qop_req,
+ input_message_buffer,
+ conf_state,
+ output_message_buffer);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_unwrap
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_buffer_t input_message_buffer,
+ gss_buffer_t output_message_buffer,
+ int * conf_state,
+ gss_qop_t * qop_state
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_unwrap(minor_status,
+ ctx->negotiated_ctx_id,
+ input_message_buffer,
+ output_message_buffer,
+ conf_state,
+ qop_state);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_compare_name
+ (OM_uint32 *minor_status,
+ const gss_name_t name1,
+ const gss_name_t name2,
+ int * name_equal
+ )
+{
+ spnego_name n1 = (spnego_name)name1;
+ spnego_name n2 = (spnego_name)name2;
+
+ *name_equal = 0;
+
+ if (!gss_oid_equal(&n1->type, &n2->type))
+ return GSS_S_COMPLETE;
+ if (n1->value.length != n2->value.length)
+ return GSS_S_COMPLETE;
+ if (memcmp(n1->value.value, n2->value.value, n2->value.length) != 0)
+ return GSS_S_COMPLETE;
+
+ *name_equal = 1;
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_display_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t output_name_buffer,
+ gss_OID * output_name_type
+ )
+{
+ spnego_name name = (spnego_name)input_name;
+
+ *minor_status = 0;
+
+ if (name == NULL || name->mech == GSS_C_NO_NAME)
+ return GSS_S_FAILURE;
+
+ return gss_display_name(minor_status, name->mech,
+ output_name_buffer, output_name_type);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_import_name
+ (OM_uint32 * minor_status,
+ const gss_buffer_t name_buffer,
+ const gss_OID name_type,
+ gss_name_t * output_name
+ )
+{
+ spnego_name name;
+ OM_uint32 maj_stat;
+
+ *minor_status = 0;
+
+ name = calloc(1, sizeof(*name));
+ if (name == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ maj_stat = _gss_copy_oid(minor_status, name_type, &name->type);
+ if (maj_stat) {
+ free(name);
+ return GSS_S_FAILURE;
+ }
+
+ maj_stat = _gss_copy_buffer(minor_status, name_buffer, &name->value);
+ if (maj_stat) {
+ gss_name_t rname = (gss_name_t)name;
+ _gss_spnego_release_name(minor_status, &rname);
+ return GSS_S_FAILURE;
+ }
+ name->mech = GSS_C_NO_NAME;
+ *output_name = (gss_name_t)name;
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_name
+ (OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_buffer_t exported_name
+ )
+{
+ spnego_name name;
+ *minor_status = 0;
+
+ if (input_name == GSS_C_NO_NAME)
+ return GSS_S_BAD_NAME;
+
+ name = (spnego_name)input_name;
+ if (name->mech == GSS_C_NO_NAME)
+ return GSS_S_BAD_NAME;
+
+ return gss_export_name(minor_status, name->mech, exported_name);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_release_name
+ (OM_uint32 * minor_status,
+ gss_name_t * input_name
+ )
+{
+ *minor_status = 0;
+
+ if (*input_name != GSS_C_NO_NAME) {
+ OM_uint32 junk;
+ spnego_name name = (spnego_name)*input_name;
+ _gss_free_oid(&junk, &name->type);
+ gss_release_buffer(&junk, &name->value);
+ if (name->mech != GSS_C_NO_NAME)
+ gss_release_name(&junk, &name->mech);
+ free(name);
+
+ *input_name = GSS_C_NO_NAME;
+ }
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_context (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_name_t * src_name,
+ gss_name_t * targ_name,
+ OM_uint32 * lifetime_rec,
+ gss_OID * mech_type,
+ OM_uint32 * ctx_flags,
+ int * locally_initiated,
+ int * open_context
+ )
+{
+ gssspnego_ctx ctx;
+ OM_uint32 maj_stat, junk;
+ gss_name_t src_mn, targ_mn;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
+
+ maj_stat = gss_inquire_context(minor_status,
+ ctx->negotiated_ctx_id,
+ &src_mn,
+ &targ_mn,
+ lifetime_rec,
+ mech_type,
+ ctx_flags,
+ locally_initiated,
+ open_context);
+ if (maj_stat != GSS_S_COMPLETE)
+ return maj_stat;
+
+ if (src_name) {
+ spnego_name name = calloc(1, sizeof(*name));
+ if (name == NULL)
+ goto enomem;
+ name->mech = src_mn;
+ *src_name = (gss_name_t)name;
+ } else
+ gss_release_name(&junk, &src_mn);
+
+ if (targ_name) {
+ spnego_name name = calloc(1, sizeof(*name));
+ if (name == NULL) {
+ gss_release_name(minor_status, src_name);
+ goto enomem;
+ }
+ name->mech = targ_mn;
+ *targ_name = (gss_name_t)name;
+ } else
+ gss_release_name(&junk, &targ_mn);
+
+ return GSS_S_COMPLETE;
+
+enomem:
+ gss_release_name(&junk, &targ_mn);
+ gss_release_name(&junk, &src_mn);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_wrap_size_limit (
+ OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 * max_input_size
+ )
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_wrap_size_limit(minor_status,
+ ctx->negotiated_ctx_id,
+ conf_req_flag,
+ qop_req,
+ req_output_size,
+ max_input_size);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_sec_context (
+ OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t interprocess_token
+ )
+{
+ gssspnego_ctx ctx;
+ OM_uint32 ret;
+
+ *minor_status = 0;
+
+ if (context_handle == NULL) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)*context_handle;
+
+ if (ctx == NULL)
+ return GSS_S_NO_CONTEXT;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ret = gss_export_sec_context(minor_status,
+ &ctx->negotiated_ctx_id,
+ interprocess_token);
+ if (ret == GSS_S_COMPLETE) {
+ ret = _gss_spnego_internal_delete_sec_context(minor_status,
+ context_handle,
+ GSS_C_NO_BUFFER);
+ if (ret == GSS_S_COMPLETE)
+ return GSS_S_COMPLETE;
+ }
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ return ret;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_import_sec_context (
+ OM_uint32 * minor_status,
+ const gss_buffer_t interprocess_token,
+ gss_ctx_id_t *context_handle
+ )
+{
+ OM_uint32 ret, minor;
+ gss_ctx_id_t context;
+ gssspnego_ctx ctx;
+
+ ret = _gss_spnego_alloc_sec_context(minor_status, &context);
+ if (ret != GSS_S_COMPLETE) {
+ return ret;
+ }
+ ctx = (gssspnego_ctx)context;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ ret = gss_import_sec_context(minor_status,
+ interprocess_token,
+ &ctx->negotiated_ctx_id);
+ if (ret != GSS_S_COMPLETE) {
+ _gss_spnego_internal_delete_sec_context(&minor, context_handle, GSS_C_NO_BUFFER);
+ return ret;
+ }
+
+ ctx->open = 1;
+ /* don't bother filling in the rest of the fields */
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ *context_handle = (gss_ctx_id_t)ctx;
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_names_for_mech (
+ OM_uint32 * minor_status,
+ const gss_OID mechanism,
+ gss_OID_set * name_types
+ )
+{
+ gss_OID_set mechs, names, n;
+ OM_uint32 ret, junk;
+ size_t i, j;
+
+ *name_types = NULL;
+
+ ret = spnego_supported_mechs(minor_status, &mechs);
+ if (ret != GSS_S_COMPLETE)
+ return ret;
+
+ ret = gss_create_empty_oid_set(minor_status, &names);
+ if (ret != GSS_S_COMPLETE)
+ goto out;
+
+ for (i = 0; i < mechs->count; i++) {
+ ret = gss_inquire_names_for_mech(minor_status,
+ &mechs->elements[i],
+ &n);
+ if (ret)
+ continue;
+
+ for (j = 0; j < n->count; j++)
+ gss_add_oid_set_member(minor_status,
+ &n->elements[j],
+ &names);
+ gss_release_oid_set(&junk, &n);
+ }
+
+ ret = GSS_S_COMPLETE;
+ *name_types = names;
+out:
+
+ gss_release_oid_set(&junk, &mechs);
+
+ return ret;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_mechs_for_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ gss_OID_set * mech_types
+ )
+{
+ OM_uint32 ret, junk;
+
+ ret = gss_create_empty_oid_set(minor_status, mech_types);
+ if (ret)
+ return ret;
+
+ ret = gss_add_oid_set_member(minor_status,
+ GSS_SPNEGO_MECHANISM,
+ mech_types);
+ if (ret)
+ gss_release_oid_set(&junk, mech_types);
+
+ return ret;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_canonicalize_name (
+ OM_uint32 * minor_status,
+ const gss_name_t input_name,
+ const gss_OID mech_type,
+ gss_name_t * output_name
+ )
+{
+ /* XXX */
+ return gss_duplicate_name(minor_status, input_name, output_name);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_duplicate_name (
+ OM_uint32 * minor_status,
+ const gss_name_t src_name,
+ gss_name_t * dest_name
+ )
+{
+ return gss_duplicate_name(minor_status, src_name, dest_name);
+}
+
+#if 0
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_wrap_iov(OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int * conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ gssspnego_ctx ctx = (gssspnego_ctx)context_handle;
+
+ *minor_status = 0;
+
+ if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
+
+ return gss_wrap_iov(minor_status, ctx->negotiated_ctx_id,
+ conf_req_flag, qop_req, conf_state,
+ iov, iov_count);
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_unwrap_iov(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int *conf_state,
+ gss_qop_t *qop_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ gssspnego_ctx ctx = (gssspnego_ctx)context_handle;
+
+ *minor_status = 0;
+
+ if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
+
+ return gss_unwrap_iov(minor_status,
+ ctx->negotiated_ctx_id,
+ conf_state, qop_state,
+ iov, iov_count);
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_wrap_iov_length(OM_uint32 * minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ gssspnego_ctx ctx = (gssspnego_ctx)context_handle;
+
+ *minor_status = 0;
+
+ if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
+
+ return gss_wrap_iov_length(minor_status, ctx->negotiated_ctx_id,
+ conf_req_flag, qop_req, conf_state,
+ iov, iov_count);
+}
+
+#endif
+
+#if 0
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_complete_auth_token
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_buffer_t input_message_buffer)
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_complete_auth_token(minor_status,
+ ctx->negotiated_ctx_id,
+ input_message_buffer);
+}
+#endif
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_sec_context_by_oid
+ (OM_uint32 * minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_inquire_sec_context_by_oid(minor_status,
+ ctx->negotiated_ctx_id,
+ desired_object,
+ data_set);
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_set_sec_context_option
+ (OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value)
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (gssspnego_ctx)*context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ return gss_set_sec_context_option(minor_status,
+ &ctx->negotiated_ctx_id,
+ desired_object,
+ value);
+}
+
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_pseudo_random(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out)
+{
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
+
+ ctx = (gssspnego_ctx)context_handle;
+
+ if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
+ return GSS_S_NO_CONTEXT;
+
+ return gss_pseudo_random(minor_status,
+ ctx->negotiated_ctx_id,
+ prf_key,
+ prf_in,
+ desired_output_len,
+ prf_out);
+}
diff --git a/crypto/heimdal/lib/gssapi/spnego/cred_stubs.c b/crypto/heimdal/lib/gssapi/spnego/cred_stubs.c
new file mode 100644
index 0000000..353c312
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/spnego/cred_stubs.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "spnego_locl.h"
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
+{
+ OM_uint32 ret;
+
+ *minor_status = 0;
+
+ if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL)
+ return GSS_S_COMPLETE;
+
+ ret = gss_release_cred(minor_status, cred_handle);
+
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+
+ return ret;
+}
+
+/*
+ * For now, just a simple wrapper that avoids recursion. When
+ * we support gss_{get,set}_neg_mechs() we will need to expose
+ * more functionality.
+ */
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_acquire_cred
+(OM_uint32 *minor_status,
+ const gss_name_t desired_name,
+ OM_uint32 time_req,
+ const gss_OID_set desired_mechs,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t * output_cred_handle,
+ gss_OID_set * actual_mechs,
+ OM_uint32 * time_rec
+ )
+{
+ const spnego_name dname = (const spnego_name)desired_name;
+ gss_name_t name = GSS_C_NO_NAME;
+ OM_uint32 ret, tmp;
+ gss_OID_set_desc actual_desired_mechs;
+ gss_OID_set mechs;
+ size_t i, j;
+
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+
+ if (dname) {
+ ret = gss_import_name(minor_status, &dname->value, &dname->type, &name);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ ret = gss_indicate_mechs(minor_status, &mechs);
+ if (ret != GSS_S_COMPLETE) {
+ gss_release_name(minor_status, &name);
+ return ret;
+ }
+
+ /* Remove ourselves from this list */
+ actual_desired_mechs.count = mechs->count;
+ actual_desired_mechs.elements = malloc(actual_desired_mechs.count *
+ sizeof(gss_OID_desc));
+ if (actual_desired_mechs.elements == NULL) {
+ *minor_status = ENOMEM;
+ ret = GSS_S_FAILURE;
+ goto out;
+ }
+
+ for (i = 0, j = 0; i < mechs->count; i++) {
+ if (gss_oid_equal(&mechs->elements[i], GSS_SPNEGO_MECHANISM))
+ continue;
+
+ actual_desired_mechs.elements[j] = mechs->elements[i];
+ j++;
+ }
+ actual_desired_mechs.count = j;
+
+ ret = gss_acquire_cred(minor_status, name,
+ time_req, &actual_desired_mechs,
+ cred_usage,
+ output_cred_handle,
+ actual_mechs, time_rec);
+ if (ret != GSS_S_COMPLETE)
+ goto out;
+
+out:
+ gss_release_name(minor_status, &name);
+ gss_release_oid_set(&tmp, &mechs);
+ if (actual_desired_mechs.elements != NULL) {
+ free(actual_desired_mechs.elements);
+ }
+ if (ret != GSS_S_COMPLETE) {
+ _gss_spnego_release_cred(&tmp, output_cred_handle);
+ }
+
+ return ret;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_cred
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ gss_name_t * name,
+ OM_uint32 * lifetime,
+ gss_cred_usage_t * cred_usage,
+ gss_OID_set * mechanisms
+ )
+{
+ spnego_name sname = NULL;
+ OM_uint32 ret;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ if (name) {
+ sname = calloc(1, sizeof(*sname));
+ if (sname == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ ret = gss_inquire_cred(minor_status,
+ cred_handle,
+ sname ? &sname->mech : NULL,
+ lifetime,
+ cred_usage,
+ mechanisms);
+ if (ret) {
+ if (sname)
+ free(sname);
+ return ret;
+ }
+ if (name)
+ *name = (gss_name_t)sname;
+
+ return ret;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_cred_by_mech (
+ OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID mech_type,
+ gss_name_t * name,
+ OM_uint32 * initiator_lifetime,
+ OM_uint32 * acceptor_lifetime,
+ gss_cred_usage_t * cred_usage
+ )
+{
+ spnego_name sname = NULL;
+ OM_uint32 ret;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ if (name) {
+ sname = calloc(1, sizeof(*sname));
+ if (sname == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ ret = gss_inquire_cred_by_mech(minor_status,
+ cred_handle,
+ mech_type,
+ sname ? &sname->mech : NULL,
+ initiator_lifetime,
+ acceptor_lifetime,
+ cred_usage);
+
+ if (ret) {
+ if (sname)
+ free(sname);
+ return ret;
+ }
+ if (name)
+ *name = (gss_name_t)sname;
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_cred_by_oid
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ OM_uint32 ret;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ ret = gss_inquire_cred_by_oid(minor_status,
+ cred_handle,
+ desired_object,
+ data_set);
+
+ return ret;
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_set_cred_option (OM_uint32 *minor_status,
+ gss_cred_id_t *cred_handle,
+ const gss_OID object,
+ const gss_buffer_t value)
+{
+ if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
+ *minor_status = 0;
+ return GSS_S_NO_CRED;
+ }
+
+ return gss_set_cred_option(minor_status,
+ cred_handle,
+ object,
+ value);
+}
+
+#if 0
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_export_cred (OM_uint32 *minor_status,
+ gss_cred_id_t cred_handle,
+ gss_buffer_t value)
+{
+ return gss_export_cred(minor_status, cred_handle, value);
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_import_cred (OM_uint32 *minor_status,
+ gss_buffer_t value,
+ gss_cred_id_t *cred_handle)
+{
+ return gss_import_cred(minor_status, value, cred_handle);
+}
+
+#endif
diff --git a/crypto/heimdal/lib/gssapi/spnego/external.c b/crypto/heimdal/lib/gssapi/spnego/external.c
new file mode 100644
index 0000000..e1d74e5
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/spnego/external.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+#include "spnego_locl.h"
+#include <gssapi_mech.h>
+
+/*
+ * RFC2478, SPNEGO:
+ * The security mechanism of the initial
+ * negotiation token is identified by the Object Identifier
+ * iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2).
+ */
+#if 0
+static gss_mo_desc spnego_mo[] = {
+ {
+ GSS_C_MA_SASL_MECH_NAME,
+ GSS_MO_MA,
+ "SASL mech name",
+ rk_UNCONST("SPNEGO"),
+ _gss_mo_get_ctx_as_string,
+ NULL
+ },
+ {
+ GSS_C_MA_MECH_NAME,
+ GSS_MO_MA,
+ "Mechanism name",
+ rk_UNCONST("SPNEGO"),
+ _gss_mo_get_ctx_as_string,
+ NULL
+ },
+ {
+ GSS_C_MA_MECH_DESCRIPTION,
+ GSS_MO_MA,
+ "Mechanism description",
+ rk_UNCONST("Heimdal SPNEGO Mechanism"),
+ _gss_mo_get_ctx_as_string,
+ NULL
+ },
+ {
+ GSS_C_MA_MECH_NEGO,
+ GSS_MO_MA
+ },
+ {
+ GSS_C_MA_MECH_PSEUDO,
+ GSS_MO_MA
+ }
+};
+#endif
+
+static gssapi_mech_interface_desc spnego_mech = {
+ GMI_VERSION,
+ "spnego",
+ {6, rk_UNCONST("\x2b\x06\x01\x05\x05\x02") },
+ 0,
+ _gss_spnego_acquire_cred,
+ _gss_spnego_release_cred,
+ _gss_spnego_init_sec_context,
+ _gss_spnego_accept_sec_context,
+ _gss_spnego_process_context_token,
+ _gss_spnego_internal_delete_sec_context,
+ _gss_spnego_context_time,
+ _gss_spnego_get_mic,
+ _gss_spnego_verify_mic,
+ _gss_spnego_wrap,
+ _gss_spnego_unwrap,
+ NULL, /* gm_display_status */
+ NULL, /* gm_indicate_mechs */
+ _gss_spnego_compare_name,
+ _gss_spnego_display_name,
+ _gss_spnego_import_name,
+ _gss_spnego_export_name,
+ _gss_spnego_release_name,
+ _gss_spnego_inquire_cred,
+ _gss_spnego_inquire_context,
+ _gss_spnego_wrap_size_limit,
+ gss_add_cred,
+ _gss_spnego_inquire_cred_by_mech,
+ _gss_spnego_export_sec_context,
+ _gss_spnego_import_sec_context,
+ NULL /* _gss_spnego_inquire_names_for_mech */,
+ _gss_spnego_inquire_mechs_for_name,
+ _gss_spnego_canonicalize_name,
+ _gss_spnego_duplicate_name,
+ _gss_spnego_inquire_sec_context_by_oid,
+ _gss_spnego_inquire_cred_by_oid,
+ _gss_spnego_set_sec_context_option,
+ _gss_spnego_set_cred_option,
+ _gss_spnego_pseudo_random,
+#if 0
+ _gss_spnego_wrap_iov,
+ _gss_spnego_unwrap_iov,
+ _gss_spnego_wrap_iov_length,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+ NULL,
+#if 0
+ _gss_spnego_export_cred,
+ _gss_spnego_import_cred,
+#else
+ NULL,
+ NULL,
+#endif
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#if 0
+ spnego_mo,
+ sizeof(spnego_mo) / sizeof(spnego_mo[0]),
+#else
+ NULL,
+ 0,
+#endif
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+gssapi_mech_interface
+__gss_spnego_initialize(void)
+{
+ return &spnego_mech;
+}
diff --git a/crypto/heimdal/lib/gssapi/spnego/init_sec_context.c b/crypto/heimdal/lib/gssapi/spnego/init_sec_context.c
new file mode 100644
index 0000000..b4b1bce
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/spnego/init_sec_context.c
@@ -0,0 +1,660 @@
+/*
+ * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * Portions Copyright (c) 2004 PADL Software Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "spnego_locl.h"
+
+/*
+ * Is target_name an sane target for `mech´.
+ */
+
+static OM_uint32
+initiator_approved(gss_name_t target_name, gss_OID mech)
+{
+ OM_uint32 min_stat, maj_stat;
+ gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
+ gss_buffer_desc out;
+
+ maj_stat = gss_init_sec_context(&min_stat,
+ GSS_C_NO_CREDENTIAL,
+ &ctx,
+ target_name,
+ mech,
+ 0,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ GSS_C_NO_BUFFER,
+ NULL,
+ &out,
+ NULL,
+ NULL);
+ if (GSS_ERROR(maj_stat)) {
+ gss_mg_collect_error(mech, maj_stat, min_stat);
+ return GSS_S_BAD_MECH;
+ }
+ gss_release_buffer(&min_stat, &out);
+ gss_delete_sec_context(&min_stat, &ctx, NULL);
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * Send a reply. Note that we only need to send a reply if we
+ * need to send a MIC or a mechanism token. Otherwise, we can
+ * return an empty buffer.
+ *
+ * The return value of this will be returned to the API, so it
+ * must return GSS_S_CONTINUE_NEEDED if a token was generated.
+ */
+static OM_uint32
+spnego_reply_internal(OM_uint32 *minor_status,
+ gssspnego_ctx context_handle,
+ const gss_buffer_t mech_buf,
+ gss_buffer_t mech_token,
+ gss_buffer_t output_token)
+{
+ NegotiationToken nt;
+ gss_buffer_desc mic_buf;
+ OM_uint32 ret;
+ size_t size;
+
+ if (mech_buf == GSS_C_NO_BUFFER && mech_token->length == 0) {
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ return context_handle->open ? GSS_S_COMPLETE : GSS_S_FAILURE;
+ }
+
+ memset(&nt, 0, sizeof(nt));
+
+ nt.element = choice_NegotiationToken_negTokenResp;
+
+ ALLOC(nt.u.negTokenResp.negResult, 1);
+ if (nt.u.negTokenResp.negResult == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ nt.u.negTokenResp.supportedMech = NULL;
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ if (mech_token->length == 0) {
+ nt.u.negTokenResp.responseToken = NULL;
+ *(nt.u.negTokenResp.negResult) = accept_completed;
+ } else {
+ ALLOC(nt.u.negTokenResp.responseToken, 1);
+ if (nt.u.negTokenResp.responseToken == NULL) {
+ free_NegotiationToken(&nt);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ nt.u.negTokenResp.responseToken->length = mech_token->length;
+ nt.u.negTokenResp.responseToken->data = mech_token->value;
+ mech_token->length = 0;
+ mech_token->value = NULL;
+
+ *(nt.u.negTokenResp.negResult) = accept_incomplete;
+ }
+
+ if (mech_buf != GSS_C_NO_BUFFER) {
+
+ ret = gss_get_mic(minor_status,
+ context_handle->negotiated_ctx_id,
+ 0,
+ mech_buf,
+ &mic_buf);
+ if (ret == GSS_S_COMPLETE) {
+ ALLOC(nt.u.negTokenResp.mechListMIC, 1);
+ if (nt.u.negTokenResp.mechListMIC == NULL) {
+ gss_release_buffer(minor_status, &mic_buf);
+ free_NegotiationToken(&nt);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ nt.u.negTokenResp.mechListMIC->length = mic_buf.length;
+ nt.u.negTokenResp.mechListMIC->data = mic_buf.value;
+ } else if (ret == GSS_S_UNAVAILABLE) {
+ nt.u.negTokenResp.mechListMIC = NULL;
+ } if (ret) {
+ free_NegotiationToken(&nt);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ } else {
+ nt.u.negTokenResp.mechListMIC = NULL;
+ }
+
+ ASN1_MALLOC_ENCODE(NegotiationToken,
+ output_token->value, output_token->length,
+ &nt, &size, ret);
+ if (ret) {
+ free_NegotiationToken(&nt);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+
+ if (*(nt.u.negTokenResp.negResult) == accept_completed)
+ ret = GSS_S_COMPLETE;
+ else
+ ret = GSS_S_CONTINUE_NEEDED;
+
+ free_NegotiationToken(&nt);
+ return ret;
+}
+
+static OM_uint32
+spnego_initial
+ (OM_uint32 * minor_status,
+ gss_cred_id_t cred,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+ )
+{
+ NegTokenInit ni;
+ int ret;
+ OM_uint32 sub, minor;
+ gss_buffer_desc mech_token;
+ u_char *buf;
+ size_t buf_size, buf_len;
+ gss_buffer_desc data;
+ size_t ni_len;
+ gss_ctx_id_t context;
+ gssspnego_ctx ctx;
+ spnego_name name = (spnego_name)target_name;
+
+ *minor_status = 0;
+
+ memset (&ni, 0, sizeof(ni));
+
+ *context_handle = GSS_C_NO_CONTEXT;
+
+ if (target_name == GSS_C_NO_NAME)
+ return GSS_S_BAD_NAME;
+
+ sub = _gss_spnego_alloc_sec_context(&minor, &context);
+ if (GSS_ERROR(sub)) {
+ *minor_status = minor;
+ return sub;
+ }
+ ctx = (gssspnego_ctx)context;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ ctx->local = 1;
+
+ sub = gss_import_name(&minor, &name->value, &name->type, &ctx->target_name);
+ if (GSS_ERROR(sub)) {
+ *minor_status = minor;
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return sub;
+ }
+
+ sub = _gss_spnego_indicate_mechtypelist(&minor,
+ ctx->target_name,
+ initiator_approved,
+ 0,
+ cred,
+ &ni.mechTypes,
+ &ctx->preferred_mech_type);
+ if (GSS_ERROR(sub)) {
+ *minor_status = minor;
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return sub;
+ }
+
+ ni.reqFlags = NULL;
+
+ /*
+ * If we have a credential handle, use it to select the mechanism
+ * that we will use
+ */
+
+ /* generate optimistic token */
+ sub = gss_init_sec_context(&minor,
+ cred,
+ &ctx->negotiated_ctx_id,
+ ctx->target_name,
+ ctx->preferred_mech_type,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ &ctx->negotiated_mech_type,
+ &mech_token,
+ &ctx->mech_flags,
+ &ctx->mech_time_rec);
+ if (GSS_ERROR(sub)) {
+ free_NegTokenInit(&ni);
+ *minor_status = minor;
+ gss_mg_collect_error(ctx->preferred_mech_type, sub, minor);
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return sub;
+ }
+ if (sub == GSS_S_COMPLETE)
+ ctx->maybe_open = 1;
+
+ if (mech_token.length != 0) {
+ ALLOC(ni.mechToken, 1);
+ if (ni.mechToken == NULL) {
+ free_NegTokenInit(&ni);
+ gss_release_buffer(&minor, &mech_token);
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ ni.mechToken->length = mech_token.length;
+ ni.mechToken->data = malloc(mech_token.length);
+ if (ni.mechToken->data == NULL && mech_token.length != 0) {
+ free_NegTokenInit(&ni);
+ gss_release_buffer(&minor, &mech_token);
+ *minor_status = ENOMEM;
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return GSS_S_FAILURE;
+ }
+ memcpy(ni.mechToken->data, mech_token.value, mech_token.length);
+ gss_release_buffer(&minor, &mech_token);
+ } else
+ ni.mechToken = NULL;
+
+ ni.mechListMIC = NULL;
+
+ ni_len = length_NegTokenInit(&ni);
+ buf_size = 1 + der_length_len(ni_len) + ni_len;
+
+ buf = malloc(buf_size);
+ if (buf == NULL) {
+ free_NegTokenInit(&ni);
+ *minor_status = ENOMEM;
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return GSS_S_FAILURE;
+ }
+
+ ret = encode_NegTokenInit(buf + buf_size - 1,
+ ni_len,
+ &ni, &buf_len);
+ if (ret == 0 && ni_len != buf_len)
+ abort();
+
+ if (ret == 0) {
+ size_t tmp;
+
+ ret = der_put_length_and_tag(buf + buf_size - buf_len - 1,
+ buf_size - buf_len,
+ buf_len,
+ ASN1_C_CONTEXT,
+ CONS,
+ 0,
+ &tmp);
+ if (ret == 0 && tmp + buf_len != buf_size)
+ abort();
+ }
+ if (ret) {
+ *minor_status = ret;
+ free(buf);
+ free_NegTokenInit(&ni);
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return GSS_S_FAILURE;
+ }
+
+ data.value = buf;
+ data.length = buf_size;
+
+ ctx->initiator_mech_types.len = ni.mechTypes.len;
+ ctx->initiator_mech_types.val = ni.mechTypes.val;
+ ni.mechTypes.len = 0;
+ ni.mechTypes.val = NULL;
+
+ free_NegTokenInit(&ni);
+
+ sub = gss_encapsulate_token(&data,
+ GSS_SPNEGO_MECHANISM,
+ output_token);
+ free (buf);
+
+ if (sub) {
+ _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
+ return sub;
+ }
+
+ if (actual_mech_type)
+ *actual_mech_type = ctx->negotiated_mech_type;
+ if (ret_flags)
+ *ret_flags = ctx->mech_flags;
+ if (time_rec)
+ *time_rec = ctx->mech_time_rec;
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ *context_handle = context;
+
+ return GSS_S_CONTINUE_NEEDED;
+}
+
+static OM_uint32
+spnego_reply
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t cred,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+ )
+{
+ OM_uint32 ret, minor;
+ NegotiationToken resp;
+ gss_OID_desc mech;
+ int require_mic;
+ size_t buf_len = 0;
+ gss_buffer_desc mic_buf, mech_buf;
+ gss_buffer_desc mech_output_token;
+ gssspnego_ctx ctx;
+
+ *minor_status = 0;
+
+ ctx = (gssspnego_ctx)*context_handle;
+
+ output_token->length = 0;
+ output_token->value = NULL;
+
+ mech_output_token.length = 0;
+ mech_output_token.value = NULL;
+
+ mech_buf.value = NULL;
+ mech_buf.length = 0;
+
+ ret = decode_NegotiationToken(input_token->value, input_token->length,
+ &resp, NULL);
+ if (ret)
+ return ret;
+
+ if (resp.element != choice_NegotiationToken_negTokenResp) {
+ free_NegotiationToken(&resp);
+ *minor_status = 0;
+ return GSS_S_BAD_MECH;
+ }
+
+ if (resp.u.negTokenResp.negResult == NULL
+ || *(resp.u.negTokenResp.negResult) == reject
+ /* || resp.u.negTokenResp.supportedMech == NULL */
+ )
+ {
+ free_NegotiationToken(&resp);
+ return GSS_S_BAD_MECH;
+ }
+
+ /*
+ * Pick up the mechanism that the acceptor selected, only allow it
+ * to be sent in packet.
+ */
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+
+ if (resp.u.negTokenResp.supportedMech) {
+
+ if (ctx->oidlen) {
+ free_NegotiationToken(&resp);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return GSS_S_BAD_MECH;
+ }
+ ret = der_put_oid(ctx->oidbuf + sizeof(ctx->oidbuf) - 1,
+ sizeof(ctx->oidbuf),
+ resp.u.negTokenResp.supportedMech,
+ &ctx->oidlen);
+ /* Avoid recursively embedded SPNEGO */
+ if (ret || (ctx->oidlen == GSS_SPNEGO_MECHANISM->length &&
+ memcmp(ctx->oidbuf + sizeof(ctx->oidbuf) - ctx->oidlen,
+ GSS_SPNEGO_MECHANISM->elements,
+ ctx->oidlen) == 0))
+ {
+ free_NegotiationToken(&resp);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return GSS_S_BAD_MECH;
+ }
+
+ /* check if the acceptor took our optimistic token */
+ if (ctx->oidlen != ctx->preferred_mech_type->length ||
+ memcmp(ctx->oidbuf + sizeof(ctx->oidbuf) - ctx->oidlen,
+ ctx->preferred_mech_type->elements,
+ ctx->oidlen) != 0)
+ {
+ gss_delete_sec_context(&minor, &ctx->negotiated_ctx_id,
+ GSS_C_NO_BUFFER);
+ ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
+ }
+ } else if (ctx->oidlen == 0) {
+ free_NegotiationToken(&resp);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return GSS_S_BAD_MECH;
+ }
+
+ /* if a token (of non zero length), or no context, pass to underlaying mech */
+ if ((resp.u.negTokenResp.responseToken != NULL && resp.u.negTokenResp.responseToken->length) ||
+ ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+ gss_buffer_desc mech_input_token;
+
+ if (resp.u.negTokenResp.responseToken) {
+ mech_input_token.length = resp.u.negTokenResp.responseToken->length;
+ mech_input_token.value = resp.u.negTokenResp.responseToken->data;
+ } else {
+ mech_input_token.length = 0;
+ mech_input_token.value = NULL;
+ }
+
+
+ mech.length = ctx->oidlen;
+ mech.elements = ctx->oidbuf + sizeof(ctx->oidbuf) - ctx->oidlen;
+
+ /* Fall through as if the negotiated mechanism
+ was requested explicitly */
+ ret = gss_init_sec_context(&minor,
+ cred,
+ &ctx->negotiated_ctx_id,
+ ctx->target_name,
+ &mech,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ &mech_input_token,
+ &ctx->negotiated_mech_type,
+ &mech_output_token,
+ &ctx->mech_flags,
+ &ctx->mech_time_rec);
+ if (GSS_ERROR(ret)) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ free_NegotiationToken(&resp);
+ gss_mg_collect_error(&mech, ret, minor);
+ *minor_status = minor;
+ return ret;
+ }
+ if (ret == GSS_S_COMPLETE) {
+ ctx->open = 1;
+ }
+ } else if (*(resp.u.negTokenResp.negResult) == accept_completed) {
+ if (ctx->maybe_open)
+ ctx->open = 1;
+ }
+
+ if (*(resp.u.negTokenResp.negResult) == request_mic) {
+ ctx->require_mic = 1;
+ }
+
+ if (ctx->open) {
+ /*
+ * Verify the mechListMIC if one was provided or CFX was
+ * used and a non-preferred mechanism was selected
+ */
+ if (resp.u.negTokenResp.mechListMIC != NULL) {
+ require_mic = 1;
+ } else {
+ ret = _gss_spnego_require_mechlist_mic(minor_status, ctx,
+ &require_mic);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ free_NegotiationToken(&resp);
+ gss_release_buffer(&minor, &mech_output_token);
+ return ret;
+ }
+ }
+ } else {
+ require_mic = 0;
+ }
+
+ if (require_mic) {
+ ASN1_MALLOC_ENCODE(MechTypeList, mech_buf.value, mech_buf.length,
+ &ctx->initiator_mech_types, &buf_len, ret);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ free_NegotiationToken(&resp);
+ gss_release_buffer(&minor, &mech_output_token);
+ *minor_status = ret;
+ return GSS_S_FAILURE;
+ }
+ if (mech_buf.length != buf_len) {
+ abort();
+ UNREACHABLE(return GSS_S_FAILURE);
+ }
+
+ if (resp.u.negTokenResp.mechListMIC == NULL) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ free(mech_buf.value);
+ free_NegotiationToken(&resp);
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+ mic_buf.length = resp.u.negTokenResp.mechListMIC->length;
+ mic_buf.value = resp.u.negTokenResp.mechListMIC->data;
+
+ if (mech_output_token.length == 0) {
+ ret = gss_verify_mic(minor_status,
+ ctx->negotiated_ctx_id,
+ &mech_buf,
+ &mic_buf,
+ NULL);
+ if (ret) {
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ free(mech_buf.value);
+ gss_release_buffer(&minor, &mech_output_token);
+ free_NegotiationToken(&resp);
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+ ctx->verified_mic = 1;
+ }
+ }
+
+ ret = spnego_reply_internal(minor_status, ctx,
+ require_mic ? &mech_buf : NULL,
+ &mech_output_token,
+ output_token);
+
+ if (mech_buf.value != NULL)
+ free(mech_buf.value);
+
+ free_NegotiationToken(&resp);
+ gss_release_buffer(&minor, &mech_output_token);
+
+ if (actual_mech_type)
+ *actual_mech_type = ctx->negotiated_mech_type;
+ if (ret_flags)
+ *ret_flags = ctx->mech_flags;
+ if (time_rec)
+ *time_rec = ctx->mech_time_rec;
+
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+}
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_init_sec_context
+ (OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+ )
+{
+ if (*context_handle == GSS_C_NO_CONTEXT)
+ return spnego_initial (minor_status,
+ initiator_cred_handle,
+ context_handle,
+ target_name,
+ mech_type,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+ else
+ return spnego_reply (minor_status,
+ initiator_cred_handle,
+ context_handle,
+ target_name,
+ mech_type,
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+}
+
diff --git a/crypto/heimdal/lib/gssapi/spnego/spnego-private.h b/crypto/heimdal/lib/gssapi/spnego/spnego-private.h
new file mode 100644
index 0000000..f50574d
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/spnego/spnego-private.h
@@ -0,0 +1,323 @@
+/* This is a generated file */
+#ifndef __spnego_private_h__
+#define __spnego_private_h__
+
+#include <stdarg.h>
+
+gssapi_mech_interface
+__gss_spnego_initialize (void);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_accept_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_cred_id_t /*acceptor_cred_handle*/,
+ const gss_buffer_t /*input_token_buffer*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ gss_name_t * /*src_name*/,
+ gss_OID * /*mech_type*/,
+ gss_buffer_t /*output_token*/,
+ OM_uint32 * /*ret_flags*/,
+ OM_uint32 * /*time_rec*/,
+ gss_cred_id_t *delegated_cred_handle );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_acquire_cred (
+ OM_uint32 */*minor_status*/,
+ const gss_name_t /*desired_name*/,
+ OM_uint32 /*time_req*/,
+ const gss_OID_set /*desired_mechs*/,
+ gss_cred_usage_t /*cred_usage*/,
+ gss_cred_id_t * /*output_cred_handle*/,
+ gss_OID_set * /*actual_mechs*/,
+ OM_uint32 * time_rec );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_alloc_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t */*context_handle*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_canonicalize_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * output_name );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_compare_name (
+ OM_uint32 */*minor_status*/,
+ const gss_name_t /*name1*/,
+ const gss_name_t /*name2*/,
+ int * name_equal );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_context_time (
+ OM_uint32 */*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ OM_uint32 *time_rec );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_delete_sec_context (
+ OM_uint32 */*minor_status*/,
+ gss_ctx_id_t */*context_handle*/,
+ gss_buffer_t output_token );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_display_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t /*output_name_buffer*/,
+ gss_OID * output_name_type );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_duplicate_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*src_name*/,
+ gss_name_t * dest_name );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_export_cred (
+ OM_uint32 */*minor_status*/,
+ gss_cred_id_t /*cred_handle*/,
+ gss_buffer_t /*value*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_export_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_buffer_t exported_name );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_export_sec_context (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ gss_buffer_t interprocess_token );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_get_mic (
+ OM_uint32 */*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*message_buffer*/,
+ gss_buffer_t message_token );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_import_cred (
+ OM_uint32 */*minor_status*/,
+ gss_buffer_t /*value*/,
+ gss_cred_id_t */*cred_handle*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_import_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*name_buffer*/,
+ const gss_OID /*name_type*/,
+ gss_name_t * output_name );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_import_sec_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*interprocess_token*/,
+ gss_ctx_id_t *context_handle );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_indicate_mechtypelist (
+ OM_uint32 */*minor_status*/,
+ gss_name_t /*target_name*/,
+ OM_uint32 (*/*func*/)(gss_name_t, gss_OID),
+ int /*includeMSCompatOID*/,
+ const gss_cred_id_t /*cred_handle*/,
+ MechTypeList */*mechtypelist*/,
+ gss_OID */*preferred_mech*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_init_sec_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*initiator_cred_handle*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_name_t /*target_name*/,
+ const gss_OID /*mech_type*/,
+ OM_uint32 /*req_flags*/,
+ OM_uint32 /*time_req*/,
+ const gss_channel_bindings_t /*input_chan_bindings*/,
+ const gss_buffer_t /*input_token*/,
+ gss_OID * /*actual_mech_type*/,
+ gss_buffer_t /*output_token*/,
+ OM_uint32 * /*ret_flags*/,
+ OM_uint32 * time_rec );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_inquire_context (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ gss_name_t * /*src_name*/,
+ gss_name_t * /*targ_name*/,
+ OM_uint32 * /*lifetime_rec*/,
+ gss_OID * /*mech_type*/,
+ OM_uint32 * /*ctx_flags*/,
+ int * /*locally_initiated*/,
+ int * open_context );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_inquire_cred (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ gss_name_t * /*name*/,
+ OM_uint32 * /*lifetime*/,
+ gss_cred_usage_t * /*cred_usage*/,
+ gss_OID_set * mechanisms );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_inquire_cred_by_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ const gss_OID /*mech_type*/,
+ gss_name_t * /*name*/,
+ OM_uint32 * /*initiator_lifetime*/,
+ OM_uint32 * /*acceptor_lifetime*/,
+ gss_cred_usage_t * cred_usage );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_inquire_cred_by_oid (
+ OM_uint32 * /*minor_status*/,
+ const gss_cred_id_t /*cred_handle*/,
+ const gss_OID /*desired_object*/,
+ gss_buffer_set_t */*data_set*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_inquire_mechs_for_name (
+ OM_uint32 * /*minor_status*/,
+ const gss_name_t /*input_name*/,
+ gss_OID_set * mech_types );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_inquire_names_for_mech (
+ OM_uint32 * /*minor_status*/,
+ const gss_OID /*mechanism*/,
+ gss_OID_set * name_types );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_inquire_sec_context_by_oid (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_OID /*desired_object*/,
+ gss_buffer_set_t */*data_set*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_internal_delete_sec_context (
+ OM_uint32 */*minor_status*/,
+ gss_ctx_id_t */*context_handle*/,
+ gss_buffer_t output_token );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_process_context_token (
+ OM_uint32 */*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t token_buffer );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_pseudo_random (
+ OM_uint32 */*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int /*prf_key*/,
+ const gss_buffer_t /*prf_in*/,
+ ssize_t /*desired_output_len*/,
+ gss_buffer_t /*prf_out*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_release_cred (
+ OM_uint32 */*minor_status*/,
+ gss_cred_id_t */*cred_handle*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_release_name (
+ OM_uint32 * /*minor_status*/,
+ gss_name_t * input_name );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_require_mechlist_mic (
+ OM_uint32 */*minor_status*/,
+ gssspnego_ctx /*ctx*/,
+ int */*require_mic*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_set_cred_option (
+ OM_uint32 */*minor_status*/,
+ gss_cred_id_t */*cred_handle*/,
+ const gss_OID /*object*/,
+ const gss_buffer_t /*value*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_set_sec_context_option (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t * /*context_handle*/,
+ const gss_OID /*desired_object*/,
+ const gss_buffer_t /*value*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_unwrap (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ gss_buffer_t /*output_message_buffer*/,
+ int * /*conf_state*/,
+ gss_qop_t * qop_state );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_unwrap_iov (
+ OM_uint32 */*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int */*conf_state*/,
+ gss_qop_t */*qop_state*/,
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_verify_mic (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ const gss_buffer_t /*message_buffer*/,
+ const gss_buffer_t /*token_buffer*/,
+ gss_qop_t * qop_state );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_wrap (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ const gss_buffer_t /*input_message_buffer*/,
+ int * /*conf_state*/,
+ gss_buffer_t output_message_buffer );
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_wrap_iov (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ int * /*conf_state*/,
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_wrap_iov_length (
+ OM_uint32 * /*minor_status*/,
+ gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ int */*conf_state*/,
+ gss_iov_buffer_desc */*iov*/,
+ int /*iov_count*/);
+
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_wrap_size_limit (
+ OM_uint32 * /*minor_status*/,
+ const gss_ctx_id_t /*context_handle*/,
+ int /*conf_req_flag*/,
+ gss_qop_t /*qop_req*/,
+ OM_uint32 /*req_output_size*/,
+ OM_uint32 * max_input_size );
+
+#endif /* __spnego_private_h__ */
diff --git a/crypto/heimdal/lib/gssapi/spnego/spnego.asn1 b/crypto/heimdal/lib/gssapi/spnego/spnego.asn1
new file mode 100644
index 0000000..048e86b
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/spnego/spnego.asn1
@@ -0,0 +1,63 @@
+-- $Id$
+
+SPNEGO DEFINITIONS ::=
+BEGIN
+
+MechType::= OBJECT IDENTIFIER
+
+MechTypeList ::= SEQUENCE OF MechType
+
+ContextFlags ::= BIT STRING {
+ delegFlag (0),
+ mutualFlag (1),
+ replayFlag (2),
+ sequenceFlag (3),
+ anonFlag (4),
+ confFlag (5),
+ integFlag (6)
+}
+
+NegHints ::= SEQUENCE {
+ hintName [0] GeneralString OPTIONAL,
+ hintAddress [1] OCTET STRING OPTIONAL
+}
+
+NegTokenInitWin ::= SEQUENCE {
+ mechTypes [0] MechTypeList,
+ reqFlags [1] ContextFlags OPTIONAL,
+ mechToken [2] OCTET STRING OPTIONAL,
+ negHints [3] NegHints OPTIONAL
+}
+
+NegTokenInit ::= SEQUENCE {
+ mechTypes [0] MechTypeList,
+ reqFlags [1] ContextFlags OPTIONAL,
+ mechToken [2] OCTET STRING OPTIONAL,
+ mechListMIC [3] OCTET STRING OPTIONAL,
+ ...
+}
+
+-- NB: negResult is not OPTIONAL in the new SPNEGO spec but
+-- Windows clients do not always send it
+NegTokenResp ::= SEQUENCE {
+ negResult [0] ENUMERATED {
+ accept_completed (0),
+ accept_incomplete (1),
+ reject (2),
+ request-mic (3) } OPTIONAL,
+ supportedMech [1] MechType OPTIONAL,
+ responseToken [2] OCTET STRING OPTIONAL,
+ mechListMIC [3] OCTET STRING OPTIONAL,
+ ...
+}
+
+NegotiationToken ::= CHOICE {
+ negTokenInit[0] NegTokenInit,
+ negTokenResp[1] NegTokenResp
+}
+
+NegotiationTokenWin ::= CHOICE {
+ negTokenInit[0] NegTokenInitWin
+}
+
+END
diff --git a/crypto/heimdal/lib/gssapi/spnego/spnego.opt b/crypto/heimdal/lib/gssapi/spnego/spnego.opt
new file mode 100644
index 0000000..cbf2f23
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/spnego/spnego.opt
@@ -0,0 +1 @@
+--sequence=MechTypeList
diff --git a/crypto/heimdal/lib/gssapi/spnego/spnego_locl.h b/crypto/heimdal/lib/gssapi/spnego/spnego_locl.h
new file mode 100644
index 0000000..3e151c7
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/spnego/spnego_locl.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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.
+ */
+
+/* $Id$ */
+
+#ifndef SPNEGO_LOCL_H
+#define SPNEGO_LOCL_H
+
+#include <config.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include <roken.h>
+
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+#include <gssapi.h>
+#include <gssapi_krb5.h>
+#include <gssapi_spnego.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include <heim_threads.h>
+#include <asn1_err.h>
+
+#include <gssapi_mech.h>
+
+#include "spnego_asn1.h"
+#include "utils.h"
+#include <der.h>
+
+#include <heimbase.h>
+
+#define ALLOC(X, N) (X) = calloc((N), sizeof(*(X)))
+
+typedef struct {
+ MechTypeList initiator_mech_types;
+ gss_OID preferred_mech_type;
+ gss_OID negotiated_mech_type;
+ gss_ctx_id_t negotiated_ctx_id;
+ OM_uint32 mech_flags;
+ OM_uint32 mech_time_rec;
+ gss_name_t mech_src_name;
+ unsigned int open : 1;
+ unsigned int local : 1;
+ unsigned int require_mic : 1;
+ unsigned int verified_mic : 1;
+ unsigned int maybe_open : 1;
+ HEIMDAL_MUTEX ctx_id_mutex;
+
+ gss_name_t target_name;
+
+ u_char oidbuf[17];
+ size_t oidlen;
+
+} *gssspnego_ctx;
+
+typedef struct {
+ gss_OID_desc type;
+ gss_buffer_desc value;
+ gss_name_t mech;
+} *spnego_name;
+
+extern gss_OID_desc _gss_spnego_mskrb_mechanism_oid_desc;
+extern gss_OID_desc _gss_spnego_krb5_mechanism_oid_desc;
+
+#include <spnego-private.h>
+
+#endif /* SPNEGO_LOCL_H */
diff --git a/crypto/heimdal/lib/gssapi/test_acquire_cred.c b/crypto/heimdal/lib/gssapi/test_acquire_cred.c
new file mode 100644
index 0000000..e1a929b
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/test_acquire_cred.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2003-2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <roken.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <gssapi.h>
+#include <gssapi_krb5.h>
+#include <gssapi_spnego.h>
+#include <err.h>
+#include <getarg.h>
+
+#include "test_common.h"
+
+static void
+print_time(OM_uint32 time_rec)
+{
+ if (time_rec == GSS_C_INDEFINITE) {
+ printf("cred never expire\n");
+ } else {
+ time_t t = time_rec + time(NULL);
+ printf("expiration time: %s", ctime(&t));
+ }
+}
+
+#if 0
+
+static void
+test_add(gss_cred_id_t cred_handle)
+{
+ OM_uint32 major_status, minor_status;
+ gss_cred_id_t copy_cred;
+ OM_uint32 time_rec;
+
+ major_status = gss_add_cred (&minor_status,
+ cred_handle,
+ GSS_C_NO_NAME,
+ GSS_KRB5_MECHANISM,
+ GSS_C_INITIATE,
+ 0,
+ 0,
+ &copy_cred,
+ NULL,
+ &time_rec,
+ NULL);
+
+ if (GSS_ERROR(major_status))
+ errx(1, "add_cred failed");
+
+ print_time(time_rec);
+
+ major_status = gss_release_cred(&minor_status,
+ &copy_cred);
+ if (GSS_ERROR(major_status))
+ errx(1, "release_cred failed");
+}
+
+static void
+copy_cred(void)
+{
+ OM_uint32 major_status, minor_status;
+ gss_cred_id_t cred_handle;
+ OM_uint32 time_rec;
+
+ major_status = gss_acquire_cred(&minor_status,
+ GSS_C_NO_NAME,
+ 0,
+ NULL,
+ GSS_C_INITIATE,
+ &cred_handle,
+ NULL,
+ &time_rec);
+ if (GSS_ERROR(major_status))
+ errx(1, "acquire_cred failed");
+
+ print_time(time_rec);
+
+ test_add(cred_handle);
+ test_add(cred_handle);
+ test_add(cred_handle);
+
+ major_status = gss_release_cred(&minor_status,
+ &cred_handle);
+ if (GSS_ERROR(major_status))
+ errx(1, "release_cred failed");
+}
+#endif
+
+static gss_cred_id_t
+acquire_cred_service(const char *service,
+ gss_OID nametype,
+ gss_OID_set oidset,
+ int flags)
+{
+ OM_uint32 major_status, minor_status;
+ gss_cred_id_t cred_handle;
+ OM_uint32 time_rec;
+ gss_buffer_desc name_buffer;
+ gss_name_t name = GSS_C_NO_NAME;
+
+ if (service) {
+ name_buffer.value = rk_UNCONST(service);
+ name_buffer.length = strlen(service);
+
+ major_status = gss_import_name(&minor_status,
+ &name_buffer,
+ nametype,
+ &name);
+ if (GSS_ERROR(major_status))
+ errx(1, "import_name failed");
+ }
+
+ major_status = gss_acquire_cred(&minor_status,
+ name,
+ 0,
+ oidset,
+ flags,
+ &cred_handle,
+ NULL,
+ &time_rec);
+ if (GSS_ERROR(major_status)) {
+ warnx("acquire_cred failed: %s",
+ gssapi_err(major_status, minor_status, GSS_C_NO_OID));
+ } else {
+ print_time(time_rec);
+ gss_release_cred(&minor_status, &cred_handle);
+ }
+
+ if (name != GSS_C_NO_NAME)
+ gss_release_name(&minor_status, &name);
+
+ if (GSS_ERROR(major_status))
+ exit(1);
+
+ return cred_handle;
+}
+
+static int version_flag = 0;
+static int help_flag = 0;
+static int kerberos_flag = 0;
+static int enctype = 0;
+static char *acquire_name;
+static char *acquire_type;
+static char *target_name;
+static char *name_type;
+static char *ccache;
+static int num_loops = 1;
+
+static struct getargs args[] = {
+ {"acquire-name", 0, arg_string, &acquire_name, "name", NULL },
+ {"acquire-type", 0, arg_string, &acquire_type, "type", NULL },
+ {"enctype", 0, arg_integer, &enctype, "enctype-num", NULL },
+ {"loops", 0, arg_integer, &num_loops, "enctype-num", NULL },
+ {"kerberos", 0, arg_flag, &kerberos_flag, "enctype-num", NULL },
+ {"target-name", 0, arg_string, &target_name, "name", NULL },
+ {"ccache", 0, arg_string, &ccache, "name", NULL },
+ {"name-type", 0, arg_string, &name_type, "type", NULL },
+ {"version", 0, arg_flag, &version_flag, "print version", NULL },
+ {"help", 0, arg_flag, &help_flag, NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ gss_OID_set oidset = GSS_C_NULL_OID_SET;
+ gss_OID mechoid = GSS_C_NO_OID;
+ OM_uint32 maj_stat, min_stat;
+ gss_cred_id_t cred;
+ gss_name_t target = GSS_C_NO_NAME;
+ int i, optidx = 0;
+ OM_uint32 flag;
+ gss_OID type;
+
+ setprogname(argv[0]);
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ if (argc != 0)
+ usage(1);
+
+ if (acquire_type) {
+ if (strcasecmp(acquire_type, "both") == 0)
+ flag = GSS_C_BOTH;
+ else if (strcasecmp(acquire_type, "accept") == 0)
+ flag = GSS_C_ACCEPT;
+ else if (strcasecmp(acquire_type, "initiate") == 0)
+ flag = GSS_C_INITIATE;
+ else
+ errx(1, "unknown type %s", acquire_type);
+ } else
+ flag = GSS_C_ACCEPT;
+
+ if (name_type) {
+ if (strcasecmp("hostbased-service", name_type) == 0)
+ type = GSS_C_NT_HOSTBASED_SERVICE;
+ else if (strcasecmp("user-name", name_type) == 0)
+ type = GSS_C_NT_USER_NAME;
+ else
+ errx(1, "unknown name type %s", name_type);
+ } else
+ type = GSS_C_NT_HOSTBASED_SERVICE;
+
+ if (ccache) {
+ maj_stat = gss_krb5_ccache_name(&min_stat, ccache, NULL);
+ if (GSS_ERROR(maj_stat))
+ errx(1, "gss_krb5_ccache_name %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+ }
+
+ if (kerberos_flag) {
+ mechoid = GSS_KRB5_MECHANISM;
+
+ maj_stat = gss_create_empty_oid_set(&min_stat, &oidset);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_create_empty_oid_set: %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+
+ maj_stat = gss_add_oid_set_member(&min_stat, GSS_KRB5_MECHANISM, &oidset);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_add_oid_set_member: %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+ }
+
+ if (target_name) {
+ gss_buffer_desc name;
+
+ name.value = target_name;
+ name.length = strlen(target_name);
+ maj_stat = gss_import_name(&min_stat, &name,
+ GSS_C_NT_HOSTBASED_SERVICE, &target);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_import_name: %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+ }
+
+ for (i = 0; i < num_loops; i++) {
+
+ cred = acquire_cred_service(acquire_name, type, oidset, flag);
+
+ if (enctype) {
+ int32_t enctypelist = enctype;
+
+ maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, cred,
+ 1, &enctypelist);
+ if (maj_stat)
+ errx(1, "gss_krb5_set_allowable_enctypes: %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+ }
+
+ if (target) {
+ gss_ctx_id_t context = GSS_C_NO_CONTEXT;
+ gss_buffer_desc out;
+
+ out.length = 0;
+ out.value = NULL;
+
+ maj_stat = gss_init_sec_context(&min_stat,
+ cred, &context,
+ target, mechoid,
+ GSS_C_MUTUAL_FLAG, 0, NULL,
+ GSS_C_NO_BUFFER, NULL,
+ &out, NULL, NULL);
+ if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
+ errx(1, "init_sec_context failed: %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+
+ gss_release_buffer(&min_stat, &out);
+ gss_delete_sec_context(&min_stat, &context, NULL);
+ }
+ gss_release_cred(&min_stat, &cred);
+ }
+
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/gssapi/test_common.c b/crypto/heimdal/lib/gssapi/test_common.c
new file mode 100644
index 0000000..8251aef
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/test_common.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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.
+ */
+
+#include "krb5/gsskrb5_locl.h"
+#include <err.h>
+#include "test_common.h"
+
+char *
+gssapi_err(OM_uint32 maj_stat, OM_uint32 min_stat, gss_OID mech)
+{
+ OM_uint32 disp_min_stat, disp_maj_stat;
+ gss_buffer_desc maj_error_message;
+ gss_buffer_desc min_error_message;
+ OM_uint32 msg_ctx = 0;
+
+ char *ret = NULL;
+
+ maj_error_message.length = 0;
+ maj_error_message.value = NULL;
+ min_error_message.length = 0;
+ min_error_message.value = NULL;
+
+ disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat,
+ GSS_C_GSS_CODE,
+ mech, &msg_ctx, &maj_error_message);
+ disp_maj_stat = gss_display_status(&disp_min_stat, min_stat,
+ GSS_C_MECH_CODE,
+ mech, &msg_ctx, &min_error_message);
+ if (asprintf(&ret, "gss-code: %lu %.*s -- mech-code: %lu %.*s",
+ (unsigned long)maj_stat,
+ (int)maj_error_message.length,
+ (char *)maj_error_message.value,
+ (unsigned long)min_stat,
+ (int)min_error_message.length,
+ (char *)min_error_message.value) < 0 || ret == NULL)
+ errx(1, "malloc");
+
+ gss_release_buffer(&disp_min_stat, &maj_error_message);
+ gss_release_buffer(&disp_min_stat, &min_error_message);
+
+ return ret;
+}
+
diff --git a/crypto/heimdal/lib/gssapi/test_common.h b/crypto/heimdal/lib/gssapi/test_common.h
new file mode 100644
index 0000000..fda2949
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/test_common.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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.
+ */
+
+/* $Id$ */
+
+char * gssapi_err(OM_uint32, OM_uint32, gss_OID);
diff --git a/crypto/heimdal/lib/gssapi/test_context.c b/crypto/heimdal/lib/gssapi/test_context.c
new file mode 100644
index 0000000..5bdf474
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/test_context.c
@@ -0,0 +1,970 @@
+/*
+ * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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.
+ */
+
+#include "krb5/gsskrb5_locl.h"
+#include <err.h>
+#include <getarg.h>
+#include <gssapi.h>
+#include <gssapi_krb5.h>
+#include <gssapi_spnego.h>
+#include <gssapi_ntlm.h>
+#include "test_common.h"
+
+static char *type_string;
+static char *mech_string;
+static char *ret_mech_string;
+static char *client_name;
+static char *client_password;
+static int dns_canon_flag = -1;
+static int mutual_auth_flag = 0;
+static int dce_style_flag = 0;
+static int wrapunwrap_flag = 0;
+static int iov_flag = 0;
+static int getverifymic_flag = 0;
+static int deleg_flag = 0;
+static int policy_deleg_flag = 0;
+static int server_no_deleg_flag = 0;
+static int ei_flag = 0;
+static char *gsskrb5_acceptor_identity = NULL;
+static char *session_enctype_string = NULL;
+static int client_time_offset = 0;
+static int server_time_offset = 0;
+static int max_loops = 0;
+static char *limit_enctype_string = NULL;
+static int version_flag = 0;
+static int verbose_flag = 0;
+static int help_flag = 0;
+
+static krb5_context context;
+static krb5_enctype limit_enctype = 0;
+
+static struct {
+ const char *name;
+ gss_OID oid;
+} o2n[] = {
+ { "krb5", NULL /* GSS_KRB5_MECHANISM */ },
+ { "spnego", NULL /* GSS_SPNEGO_MECHANISM */ },
+ { "ntlm", NULL /* GSS_NTLM_MECHANISM */ },
+ { "sasl-digest-md5", NULL /* GSS_SASL_DIGEST_MD5_MECHANISM */ }
+};
+
+static void
+init_o2n(void)
+{
+ o2n[0].oid = GSS_KRB5_MECHANISM;
+ o2n[1].oid = GSS_SPNEGO_MECHANISM;
+ o2n[2].oid = GSS_NTLM_MECHANISM;
+ o2n[3].oid = GSS_SASL_DIGEST_MD5_MECHANISM;
+}
+
+static gss_OID
+string_to_oid(const char *name)
+{
+ int i;
+ for (i = 0; i < sizeof(o2n)/sizeof(o2n[0]); i++)
+ if (strcasecmp(name, o2n[i].name) == 0)
+ return o2n[i].oid;
+ errx(1, "name '%s' not unknown", name);
+}
+
+static const char *
+oid_to_string(const gss_OID oid)
+{
+ int i;
+ for (i = 0; i < sizeof(o2n)/sizeof(o2n[0]); i++)
+ if (gss_oid_equal(oid, o2n[i].oid))
+ return o2n[i].name;
+ return "unknown oid";
+}
+
+static void
+loop(gss_OID mechoid,
+ gss_OID nameoid, const char *target,
+ gss_cred_id_t init_cred,
+ gss_ctx_id_t *sctx, gss_ctx_id_t *cctx,
+ gss_OID *actual_mech,
+ gss_cred_id_t *deleg_cred)
+{
+ int server_done = 0, client_done = 0;
+ int num_loops = 0;
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t gss_target_name;
+ gss_buffer_desc input_token, output_token;
+ OM_uint32 flags = 0, ret_cflags, ret_sflags;
+ gss_OID actual_mech_client;
+ gss_OID actual_mech_server;
+
+ *actual_mech = GSS_C_NO_OID;
+
+ flags |= GSS_C_INTEG_FLAG;
+ flags |= GSS_C_CONF_FLAG;
+
+ if (mutual_auth_flag)
+ flags |= GSS_C_MUTUAL_FLAG;
+ if (dce_style_flag)
+ flags |= GSS_C_DCE_STYLE;
+ if (deleg_flag)
+ flags |= GSS_C_DELEG_FLAG;
+ if (policy_deleg_flag)
+ flags |= GSS_C_DELEG_POLICY_FLAG;
+
+ input_token.value = rk_UNCONST(target);
+ input_token.length = strlen(target);
+
+ maj_stat = gss_import_name(&min_stat,
+ &input_token,
+ nameoid,
+ &gss_target_name);
+ if (GSS_ERROR(maj_stat))
+ err(1, "import name creds failed with: %d", maj_stat);
+
+ input_token.length = 0;
+ input_token.value = NULL;
+
+ while (!server_done || !client_done) {
+ num_loops++;
+
+ gsskrb5_set_time_offset(client_time_offset);
+
+ maj_stat = gss_init_sec_context(&min_stat,
+ init_cred,
+ cctx,
+ gss_target_name,
+ mechoid,
+ flags,
+ 0,
+ NULL,
+ &input_token,
+ &actual_mech_client,
+ &output_token,
+ &ret_cflags,
+ NULL);
+ if (GSS_ERROR(maj_stat))
+ errx(1, "init_sec_context: %s",
+ gssapi_err(maj_stat, min_stat, mechoid));
+ if (maj_stat & GSS_S_CONTINUE_NEEDED)
+ ;
+ else
+ client_done = 1;
+
+ gsskrb5_get_time_offset(&client_time_offset);
+
+ if (client_done && server_done)
+ break;
+
+ if (input_token.length != 0)
+ gss_release_buffer(&min_stat, &input_token);
+
+ gsskrb5_set_time_offset(server_time_offset);
+
+ maj_stat = gss_accept_sec_context(&min_stat,
+ sctx,
+ GSS_C_NO_CREDENTIAL,
+ &output_token,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ NULL,
+ &actual_mech_server,
+ &input_token,
+ &ret_sflags,
+ NULL,
+ deleg_cred);
+ if (GSS_ERROR(maj_stat))
+ errx(1, "accept_sec_context: %s",
+ gssapi_err(maj_stat, min_stat, actual_mech_server));
+
+ gsskrb5_get_time_offset(&server_time_offset);
+
+ if (output_token.length != 0)
+ gss_release_buffer(&min_stat, &output_token);
+
+ if (maj_stat & GSS_S_CONTINUE_NEEDED)
+ ;
+ else
+ server_done = 1;
+ }
+ if (output_token.length != 0)
+ gss_release_buffer(&min_stat, &output_token);
+ if (input_token.length != 0)
+ gss_release_buffer(&min_stat, &input_token);
+ gss_release_name(&min_stat, &gss_target_name);
+
+ if (deleg_flag || policy_deleg_flag) {
+ if (server_no_deleg_flag) {
+ if (*deleg_cred != GSS_C_NO_CREDENTIAL)
+ errx(1, "got delegated cred but didn't expect one");
+ } else if (*deleg_cred == GSS_C_NO_CREDENTIAL)
+ errx(1, "asked for delegarated cred but did get one");
+ } else if (*deleg_cred != GSS_C_NO_CREDENTIAL)
+ errx(1, "got deleg_cred cred but didn't ask");
+
+ if (gss_oid_equal(actual_mech_server, actual_mech_client) == 0)
+ errx(1, "mech mismatch");
+ *actual_mech = actual_mech_server;
+
+ if (max_loops && num_loops > max_loops)
+ errx(1, "num loops %d was lager then max loops %d",
+ num_loops, max_loops);
+
+ if (verbose_flag) {
+ printf("server time offset: %d\n", server_time_offset);
+ printf("client time offset: %d\n", client_time_offset);
+ printf("num loops %d\n", num_loops);
+ }
+}
+
+static void
+wrapunwrap(gss_ctx_id_t cctx, gss_ctx_id_t sctx, int flags, gss_OID mechoid)
+{
+ gss_buffer_desc input_token, output_token, output_token2;
+ OM_uint32 min_stat, maj_stat;
+ gss_qop_t qop_state;
+ int conf_state;
+
+ input_token.value = "foo";
+ input_token.length = 3;
+
+ maj_stat = gss_wrap(&min_stat, cctx, flags, 0, &input_token,
+ &conf_state, &output_token);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_wrap failed: %s",
+ gssapi_err(maj_stat, min_stat, mechoid));
+
+ maj_stat = gss_unwrap(&min_stat, sctx, &output_token,
+ &output_token2, &conf_state, &qop_state);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_unwrap failed: %s",
+ gssapi_err(maj_stat, min_stat, mechoid));
+
+ gss_release_buffer(&min_stat, &output_token);
+ gss_release_buffer(&min_stat, &output_token2);
+
+#if 0 /* doesn't work for NTLM yet */
+ if (!!conf_state != !!flags)
+ errx(1, "conf_state mismatch");
+#endif
+}
+
+#define USE_CONF 1
+#define USE_HEADER_ONLY 2
+#define USE_SIGN_ONLY 4
+#define FORCE_IOV 8
+
+static void
+wrapunwrap_iov(gss_ctx_id_t cctx, gss_ctx_id_t sctx, int flags, gss_OID mechoid)
+{
+ krb5_data token, header, trailer;
+ OM_uint32 min_stat, maj_stat;
+ gss_qop_t qop_state;
+ int conf_state, conf_state2;
+ gss_iov_buffer_desc iov[6];
+ unsigned char *p;
+ int iov_len;
+ char header_data[9] = "ABCheader";
+ char trailer_data[10] = "trailerXYZ";
+
+ char token_data[16] = "0123456789abcdef";
+
+ memset(&iov, 0, sizeof(iov));
+
+ if (flags & USE_SIGN_ONLY) {
+ header.data = header_data;
+ header.length = 9;
+ trailer.data = trailer_data;
+ trailer.length = 10;
+ } else {
+ header.data = NULL;
+ header.length = 0;
+ trailer.data = NULL;
+ trailer.length = 0;
+ }
+
+ token.data = token_data;
+ token.length = 16;
+
+ iov_len = sizeof(iov)/sizeof(iov[0]);
+
+ memset(iov, 0, sizeof(iov));
+
+ iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE;
+
+ if (header.length != 0) {
+ iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
+ iov[1].buffer.length = header.length;
+ iov[1].buffer.value = header.data;
+ } else {
+ iov[1].type = GSS_IOV_BUFFER_TYPE_EMPTY;
+ iov[1].buffer.length = 0;
+ iov[1].buffer.value = NULL;
+ }
+ iov[2].type = GSS_IOV_BUFFER_TYPE_DATA;
+ iov[2].buffer.length = token.length;
+ iov[2].buffer.value = token.data;
+ if (trailer.length != 0) {
+ iov[3].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
+ iov[3].buffer.length = trailer.length;
+ iov[3].buffer.value = trailer.data;
+ } else {
+ iov[3].type = GSS_IOV_BUFFER_TYPE_EMPTY;
+ iov[3].buffer.length = 0;
+ iov[3].buffer.value = NULL;
+ }
+ if (dce_style_flag) {
+ iov[4].type = GSS_IOV_BUFFER_TYPE_EMPTY;
+ } else {
+ iov[4].type = GSS_IOV_BUFFER_TYPE_PADDING | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE;
+ }
+ iov[4].buffer.length = 0;
+ iov[4].buffer.value = 0;
+ if (dce_style_flag) {
+ iov[5].type = GSS_IOV_BUFFER_TYPE_EMPTY;
+ } else if (flags & USE_HEADER_ONLY) {
+ iov[5].type = GSS_IOV_BUFFER_TYPE_EMPTY;
+ } else {
+ iov[5].type = GSS_IOV_BUFFER_TYPE_TRAILER | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE;
+ }
+ iov[5].buffer.length = 0;
+ iov[5].buffer.value = 0;
+
+ maj_stat = gss_wrap_iov(&min_stat, cctx, dce_style_flag || flags & USE_CONF, 0, &conf_state,
+ iov, iov_len);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_wrap_iov failed");
+
+ token.length =
+ iov[0].buffer.length +
+ iov[1].buffer.length +
+ iov[2].buffer.length +
+ iov[3].buffer.length +
+ iov[4].buffer.length +
+ iov[5].buffer.length;
+ token.data = emalloc(token.length);
+
+ p = token.data;
+ memcpy(p, iov[0].buffer.value, iov[0].buffer.length);
+ p += iov[0].buffer.length;
+ memcpy(p, iov[1].buffer.value, iov[1].buffer.length);
+ p += iov[1].buffer.length;
+ memcpy(p, iov[2].buffer.value, iov[2].buffer.length);
+ p += iov[2].buffer.length;
+ memcpy(p, iov[3].buffer.value, iov[3].buffer.length);
+ p += iov[3].buffer.length;
+ memcpy(p, iov[4].buffer.value, iov[4].buffer.length);
+ p += iov[4].buffer.length;
+ memcpy(p, iov[5].buffer.value, iov[5].buffer.length);
+ p += iov[5].buffer.length;
+
+ assert(p - ((unsigned char *)token.data) == token.length);
+
+ if ((flags & (USE_SIGN_ONLY|FORCE_IOV)) == 0) {
+ gss_buffer_desc input, output;
+
+ input.value = token.data;
+ input.length = token.length;
+
+ maj_stat = gss_unwrap(&min_stat, sctx, &input,
+ &output, &conf_state2, &qop_state);
+
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_unwrap from gss_wrap_iov failed: %s",
+ gssapi_err(maj_stat, min_stat, mechoid));
+
+ gss_release_buffer(&min_stat, &output);
+ } else {
+ maj_stat = gss_unwrap_iov(&min_stat, sctx, &conf_state2, &qop_state,
+ iov, iov_len);
+
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_unwrap_iov failed: %x %s", flags,
+ gssapi_err(maj_stat, min_stat, mechoid));
+
+ }
+ if (conf_state2 != conf_state)
+ errx(1, "conf state wrong for iov: %x", flags);
+
+
+ free(token.data);
+}
+
+static void
+getverifymic(gss_ctx_id_t cctx, gss_ctx_id_t sctx, gss_OID mechoid)
+{
+ gss_buffer_desc input_token, output_token;
+ OM_uint32 min_stat, maj_stat;
+ gss_qop_t qop_state;
+
+ input_token.value = "bar";
+ input_token.length = 3;
+
+ maj_stat = gss_get_mic(&min_stat, cctx, 0, &input_token,
+ &output_token);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_get_mic failed: %s",
+ gssapi_err(maj_stat, min_stat, mechoid));
+
+ maj_stat = gss_verify_mic(&min_stat, sctx, &input_token,
+ &output_token, &qop_state);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_verify_mic failed: %s",
+ gssapi_err(maj_stat, min_stat, mechoid));
+
+ gss_release_buffer(&min_stat, &output_token);
+}
+
+static void
+empty_release(void)
+{
+ gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
+ gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
+ gss_name_t name = GSS_C_NO_NAME;
+ gss_OID_set oidset = GSS_C_NO_OID_SET;
+ OM_uint32 junk;
+
+ gss_delete_sec_context(&junk, &ctx, NULL);
+ gss_release_cred(&junk, &cred);
+ gss_release_name(&junk, &name);
+ gss_release_oid_set(&junk, &oidset);
+}
+
+/*
+ *
+ */
+
+static struct getargs args[] = {
+ {"name-type",0, arg_string, &type_string, "type of name", NULL },
+ {"mech-type",0, arg_string, &mech_string, "type of mech", NULL },
+ {"ret-mech-type",0, arg_string, &ret_mech_string,
+ "type of return mech", NULL },
+ {"dns-canonicalize",0,arg_negative_flag, &dns_canon_flag,
+ "use dns to canonicalize", NULL },
+ {"mutual-auth",0, arg_flag, &mutual_auth_flag,"mutual auth", NULL },
+ {"client-name", 0, arg_string, &client_name, "client name", NULL },
+ {"client-password", 0, arg_string, &client_password, "client password", NULL },
+ {"limit-enctype",0, arg_string, &limit_enctype_string, "enctype", NULL },
+ {"dce-style",0, arg_flag, &dce_style_flag, "dce-style", NULL },
+ {"wrapunwrap",0, arg_flag, &wrapunwrap_flag, "wrap/unwrap", NULL },
+ {"iov", 0, arg_flag, &iov_flag, "wrap/unwrap iov", NULL },
+ {"getverifymic",0, arg_flag, &getverifymic_flag,
+ "get and verify mic", NULL },
+ {"delegate",0, arg_flag, &deleg_flag, "delegate credential", NULL },
+ {"policy-delegate",0, arg_flag, &policy_deleg_flag, "policy delegate credential", NULL },
+ {"server-no-delegate",0, arg_flag, &server_no_deleg_flag,
+ "server should get a credential", NULL },
+ {"export-import-cred",0, arg_flag, &ei_flag, "test export/import cred", NULL },
+ {"gsskrb5-acceptor-identity", 0, arg_string, &gsskrb5_acceptor_identity, "keytab", NULL },
+ {"session-enctype", 0, arg_string, &session_enctype_string, "enctype", NULL },
+ {"client-time-offset", 0, arg_integer, &client_time_offset, "time", NULL },
+ {"server-time-offset", 0, arg_integer, &server_time_offset, "time", NULL },
+ {"max-loops", 0, arg_integer, &max_loops, "time", NULL },
+ {"version", 0, arg_flag, &version_flag, "print version", NULL },
+ {"verbose", 'v', arg_flag, &verbose_flag, "verbose", NULL },
+ {"help", 0, arg_flag, &help_flag, NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args, sizeof(args)/sizeof(*args),
+ NULL, "service@host");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ int optind = 0;
+ OM_uint32 min_stat, maj_stat;
+ gss_ctx_id_t cctx, sctx;
+ void *ctx;
+ gss_OID nameoid, mechoid, actual_mech, actual_mech2;
+ gss_cred_id_t client_cred = GSS_C_NO_CREDENTIAL, deleg_cred = GSS_C_NO_CREDENTIAL;
+ gss_name_t cname = GSS_C_NO_NAME;
+ gss_buffer_desc credential_data = GSS_C_EMPTY_BUFFER;
+
+ setprogname(argv[0]);
+
+ init_o2n();
+
+ if (krb5_init_context(&context))
+ errx(1, "krb5_init_context");
+
+ cctx = sctx = GSS_C_NO_CONTEXT;
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
+ usage(1);
+
+ if (dns_canon_flag != -1)
+ gsskrb5_set_dns_canonicalize(dns_canon_flag);
+
+ if (type_string == NULL)
+ nameoid = GSS_C_NT_HOSTBASED_SERVICE;
+ else if (strcmp(type_string, "hostbased-service") == 0)
+ nameoid = GSS_C_NT_HOSTBASED_SERVICE;
+ else if (strcmp(type_string, "krb5-principal-name") == 0)
+ nameoid = GSS_KRB5_NT_PRINCIPAL_NAME;
+ else
+ errx(1, "%s not suppported", type_string);
+
+ if (mech_string == NULL)
+ mechoid = GSS_KRB5_MECHANISM;
+ else
+ mechoid = string_to_oid(mech_string);
+
+ if (gsskrb5_acceptor_identity) {
+ maj_stat = gsskrb5_register_acceptor_identity(gsskrb5_acceptor_identity);
+ if (maj_stat)
+ errx(1, "gsskrb5_acceptor_identity: %s",
+ gssapi_err(maj_stat, 0, GSS_C_NO_OID));
+ }
+
+ if (client_password) {
+ credential_data.value = client_password;
+ credential_data.length = strlen(client_password);
+ }
+
+ if (client_name) {
+ gss_buffer_desc cn;
+
+ cn.value = client_name;
+ cn.length = strlen(client_name);
+
+ maj_stat = gss_import_name(&min_stat, &cn, GSS_C_NT_USER_NAME, &cname);
+ if (maj_stat)
+ errx(1, "gss_import_name: %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+ }
+
+ if (client_password) {
+ maj_stat = gss_acquire_cred_with_password(&min_stat,
+ cname,
+ &credential_data,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ GSS_C_INITIATE,
+ &client_cred,
+ NULL,
+ NULL);
+ if (GSS_ERROR(maj_stat))
+ errx(1, "gss_acquire_cred_with_password: %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+ } else {
+ maj_stat = gss_acquire_cred(&min_stat,
+ cname,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ GSS_C_INITIATE,
+ &client_cred,
+ NULL,
+ NULL);
+ if (GSS_ERROR(maj_stat))
+ errx(1, "gss_acquire_cred: %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+ }
+
+ if (limit_enctype_string) {
+ krb5_error_code ret;
+
+ ret = krb5_string_to_enctype(context,
+ limit_enctype_string,
+ &limit_enctype);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_string_to_enctype");
+ }
+
+
+ if (limit_enctype) {
+ if (client_cred == NULL)
+ errx(1, "client_cred missing");
+
+ maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, client_cred,
+ 1, &limit_enctype);
+ if (maj_stat)
+ errx(1, "gss_krb5_set_allowable_enctypes: %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+ }
+
+ loop(mechoid, nameoid, argv[0], client_cred,
+ &sctx, &cctx, &actual_mech, &deleg_cred);
+
+ if (verbose_flag)
+ printf("resulting mech: %s\n", oid_to_string(actual_mech));
+
+ if (ret_mech_string) {
+ gss_OID retoid;
+
+ retoid = string_to_oid(ret_mech_string);
+
+ if (gss_oid_equal(retoid, actual_mech) == 0)
+ errx(1, "actual_mech mech is not the expected type %s",
+ ret_mech_string);
+ }
+
+ /* XXX should be actual_mech */
+ if (gss_oid_equal(mechoid, GSS_KRB5_MECHANISM)) {
+ time_t time;
+ gss_buffer_desc authz_data;
+ gss_buffer_desc in, out1, out2;
+ krb5_keyblock *keyblock, *keyblock2;
+ krb5_timestamp now;
+ krb5_error_code ret;
+
+ ret = krb5_timeofday(context, &now);
+ if (ret)
+ errx(1, "krb5_timeofday failed");
+
+ /* client */
+ maj_stat = gss_krb5_export_lucid_sec_context(&min_stat,
+ &cctx,
+ 1, /* version */
+ &ctx);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_krb5_export_lucid_sec_context failed: %s",
+ gssapi_err(maj_stat, min_stat, actual_mech));
+
+
+ maj_stat = gss_krb5_free_lucid_sec_context(&maj_stat, ctx);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_krb5_free_lucid_sec_context failed: %s",
+ gssapi_err(maj_stat, min_stat, actual_mech));
+
+ /* server */
+ maj_stat = gss_krb5_export_lucid_sec_context(&min_stat,
+ &sctx,
+ 1, /* version */
+ &ctx);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_krb5_export_lucid_sec_context failed: %s",
+ gssapi_err(maj_stat, min_stat, actual_mech));
+ maj_stat = gss_krb5_free_lucid_sec_context(&min_stat, ctx);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_krb5_free_lucid_sec_context failed: %s",
+ gssapi_err(maj_stat, min_stat, actual_mech));
+
+ maj_stat = gsskrb5_extract_authtime_from_sec_context(&min_stat,
+ sctx,
+ &time);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gsskrb5_extract_authtime_from_sec_context failed: %s",
+ gssapi_err(maj_stat, min_stat, actual_mech));
+
+ if (time > now)
+ errx(1, "gsskrb5_extract_authtime_from_sec_context failed: "
+ "time authtime is before now: %ld %ld",
+ (long)time, (long)now);
+
+ maj_stat = gsskrb5_extract_service_keyblock(&min_stat,
+ sctx,
+ &keyblock);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gsskrb5_export_service_keyblock failed: %s",
+ gssapi_err(maj_stat, min_stat, actual_mech));
+
+ krb5_free_keyblock(context, keyblock);
+
+ maj_stat = gsskrb5_get_subkey(&min_stat,
+ sctx,
+ &keyblock);
+ if (maj_stat != GSS_S_COMPLETE
+ && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY)))
+ errx(1, "gsskrb5_get_subkey server failed: %s",
+ gssapi_err(maj_stat, min_stat, actual_mech));
+
+ if (maj_stat != GSS_S_COMPLETE)
+ keyblock = NULL;
+ else if (limit_enctype && keyblock->keytype != limit_enctype)
+ errx(1, "gsskrb5_get_subkey wrong enctype");
+
+ maj_stat = gsskrb5_get_subkey(&min_stat,
+ cctx,
+ &keyblock2);
+ if (maj_stat != GSS_S_COMPLETE
+ && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY)))
+ errx(1, "gsskrb5_get_subkey client failed: %s",
+ gssapi_err(maj_stat, min_stat, actual_mech));
+
+ if (maj_stat != GSS_S_COMPLETE)
+ keyblock2 = NULL;
+ else if (limit_enctype && keyblock->keytype != limit_enctype)
+ errx(1, "gsskrb5_get_subkey wrong enctype");
+
+ if (keyblock || keyblock2) {
+ if (keyblock == NULL)
+ errx(1, "server missing token keyblock");
+ if (keyblock2 == NULL)
+ errx(1, "client missing token keyblock");
+
+ if (keyblock->keytype != keyblock2->keytype)
+ errx(1, "enctype mismatch");
+ if (keyblock->keyvalue.length != keyblock2->keyvalue.length)
+ errx(1, "key length mismatch");
+ if (memcmp(keyblock->keyvalue.data, keyblock2->keyvalue.data,
+ keyblock2->keyvalue.length) != 0)
+ errx(1, "key data mismatch");
+ }
+
+ if (session_enctype_string) {
+ krb5_enctype enctype;
+
+ ret = krb5_string_to_enctype(context,
+ session_enctype_string,
+ &enctype);
+
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_string_to_enctype");
+
+ if (enctype != keyblock->keytype)
+ errx(1, "keytype is not the expected %d != %d",
+ (int)enctype, (int)keyblock2->keytype);
+ }
+
+ if (keyblock)
+ krb5_free_keyblock(context, keyblock);
+ if (keyblock2)
+ krb5_free_keyblock(context, keyblock2);
+
+ maj_stat = gsskrb5_get_initiator_subkey(&min_stat,
+ sctx,
+ &keyblock);
+ if (maj_stat != GSS_S_COMPLETE
+ && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY)))
+ errx(1, "gsskrb5_get_initiator_subkey failed: %s",
+ gssapi_err(maj_stat, min_stat, actual_mech));
+
+ if (maj_stat == GSS_S_COMPLETE) {
+
+ if (limit_enctype && keyblock->keytype != limit_enctype)
+ errx(1, "gsskrb5_get_initiator_subkey wrong enctype");
+ krb5_free_keyblock(context, keyblock);
+ }
+
+ maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat,
+ sctx,
+ 128,
+ &authz_data);
+ if (maj_stat == GSS_S_COMPLETE)
+ gss_release_buffer(&min_stat, &authz_data);
+
+
+ memset(&out1, 0, sizeof(out1));
+ memset(&out2, 0, sizeof(out2));
+
+ in.value = "foo";
+ in.length = 3;
+
+ gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_FULL, &in,
+ 100, &out1);
+ gss_pseudo_random(&min_stat, cctx, GSS_C_PRF_KEY_FULL, &in,
+ 100, &out2);
+
+ if (out1.length != out2.length)
+ errx(1, "prf len mismatch");
+ if (memcmp(out1.value, out2.value, out1.length) != 0)
+ errx(1, "prf data mismatch");
+
+ gss_release_buffer(&min_stat, &out1);
+
+ gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_FULL, &in,
+ 100, &out1);
+
+ if (out1.length != out2.length)
+ errx(1, "prf len mismatch");
+ if (memcmp(out1.value, out2.value, out1.length) != 0)
+ errx(1, "prf data mismatch");
+
+ gss_release_buffer(&min_stat, &out1);
+ gss_release_buffer(&min_stat, &out2);
+
+ in.value = "bar";
+ in.length = 3;
+
+ gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_PARTIAL, &in,
+ 100, &out1);
+ gss_pseudo_random(&min_stat, cctx, GSS_C_PRF_KEY_PARTIAL, &in,
+ 100, &out2);
+
+ if (out1.length != out2.length)
+ errx(1, "prf len mismatch");
+ if (memcmp(out1.value, out2.value, out1.length) != 0)
+ errx(1, "prf data mismatch");
+
+ gss_release_buffer(&min_stat, &out1);
+ gss_release_buffer(&min_stat, &out2);
+
+ wrapunwrap_flag = 1;
+ getverifymic_flag = 1;
+ }
+
+ if (wrapunwrap_flag) {
+ wrapunwrap(cctx, sctx, 0, actual_mech);
+ wrapunwrap(cctx, sctx, 1, actual_mech);
+ wrapunwrap(sctx, cctx, 0, actual_mech);
+ wrapunwrap(sctx, cctx, 1, actual_mech);
+ }
+
+ if (iov_flag) {
+ wrapunwrap_iov(cctx, sctx, 0, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY|FORCE_IOV, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_CONF, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY, actual_mech);
+
+ wrapunwrap_iov(cctx, sctx, FORCE_IOV, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_CONF|FORCE_IOV, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY|FORCE_IOV, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|FORCE_IOV, actual_mech);
+
+ wrapunwrap_iov(cctx, sctx, USE_SIGN_ONLY|FORCE_IOV, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_CONF|USE_SIGN_ONLY|FORCE_IOV, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|USE_SIGN_ONLY|FORCE_IOV, actual_mech);
+
+/* works */
+ wrapunwrap_iov(cctx, sctx, 0, actual_mech);
+ wrapunwrap_iov(cctx, sctx, FORCE_IOV, actual_mech);
+
+ wrapunwrap_iov(cctx, sctx, USE_CONF, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_CONF|FORCE_IOV, actual_mech);
+
+ wrapunwrap_iov(cctx, sctx, USE_SIGN_ONLY, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_SIGN_ONLY|FORCE_IOV, actual_mech);
+
+ wrapunwrap_iov(cctx, sctx, USE_CONF|USE_SIGN_ONLY, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_CONF|USE_SIGN_ONLY|FORCE_IOV, actual_mech);
+
+ wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY|FORCE_IOV, actual_mech);
+
+ wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY, actual_mech);
+ wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|FORCE_IOV, actual_mech);
+ }
+
+ if (getverifymic_flag) {
+ getverifymic(cctx, sctx, actual_mech);
+ getverifymic(cctx, sctx, actual_mech);
+ getverifymic(sctx, cctx, actual_mech);
+ getverifymic(sctx, cctx, actual_mech);
+ }
+
+
+ gss_delete_sec_context(&min_stat, &cctx, NULL);
+ gss_delete_sec_context(&min_stat, &sctx, NULL);
+
+ if (deleg_cred != GSS_C_NO_CREDENTIAL) {
+ gss_cred_id_t cred2 = GSS_C_NO_CREDENTIAL;
+ gss_buffer_desc cb;
+
+ if (verbose_flag)
+ printf("checking actual mech (%s) on delegated cred\n",
+ oid_to_string(actual_mech));
+ loop(actual_mech, nameoid, argv[0], deleg_cred, &sctx, &cctx, &actual_mech2, &cred2);
+
+ gss_delete_sec_context(&min_stat, &cctx, NULL);
+ gss_delete_sec_context(&min_stat, &sctx, NULL);
+
+ gss_release_cred(&min_stat, &cred2);
+
+ /* try again using SPNEGO */
+ if (verbose_flag)
+ printf("checking spnego on delegated cred\n");
+ loop(GSS_SPNEGO_MECHANISM, nameoid, argv[0], deleg_cred, &sctx, &cctx,
+ &actual_mech2, &cred2);
+
+ gss_delete_sec_context(&min_stat, &cctx, NULL);
+ gss_delete_sec_context(&min_stat, &sctx, NULL);
+
+ gss_release_cred(&min_stat, &cred2);
+
+ /* check export/import */
+ if (ei_flag) {
+
+ maj_stat = gss_export_cred(&min_stat, deleg_cred, &cb);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "export failed: %s",
+ gssapi_err(maj_stat, min_stat, NULL));
+
+ maj_stat = gss_import_cred(&min_stat, &cb, &cred2);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "import failed: %s",
+ gssapi_err(maj_stat, min_stat, NULL));
+
+ gss_release_buffer(&min_stat, &cb);
+ gss_release_cred(&min_stat, &deleg_cred);
+
+ if (verbose_flag)
+ printf("checking actual mech (%s) on export/imported cred\n",
+ oid_to_string(actual_mech));
+ loop(actual_mech, nameoid, argv[0], cred2, &sctx, &cctx,
+ &actual_mech2, &deleg_cred);
+
+ gss_release_cred(&min_stat, &deleg_cred);
+
+ gss_delete_sec_context(&min_stat, &cctx, NULL);
+ gss_delete_sec_context(&min_stat, &sctx, NULL);
+
+ /* try again using SPNEGO */
+ if (verbose_flag)
+ printf("checking SPNEGO on export/imported cred\n");
+ loop(GSS_SPNEGO_MECHANISM, nameoid, argv[0], cred2, &sctx, &cctx,
+ &actual_mech2, &deleg_cred);
+
+ gss_release_cred(&min_stat, &deleg_cred);
+
+ gss_delete_sec_context(&min_stat, &cctx, NULL);
+ gss_delete_sec_context(&min_stat, &sctx, NULL);
+
+ gss_release_cred(&min_stat, &cred2);
+
+ } else {
+ gss_release_cred(&min_stat, &deleg_cred);
+ }
+
+ }
+
+ empty_release();
+
+ krb5_free_context(context);
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/gssapi/test_cred.c b/crypto/heimdal/lib/gssapi/test_cred.c
new file mode 100644
index 0000000..2342805
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/test_cred.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2003-2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <roken.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <gssapi.h>
+#include <gssapi_krb5.h>
+#include <gssapi_spnego.h>
+#include <err.h>
+#include <getarg.h>
+
+static void
+gss_print_errors (int min_stat)
+{
+ OM_uint32 new_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+ OM_uint32 ret;
+
+ do {
+ ret = gss_display_status (&new_stat,
+ min_stat,
+ GSS_C_MECH_CODE,
+ GSS_C_NO_OID,
+ &msg_ctx,
+ &status_string);
+ if (!GSS_ERROR(ret)) {
+ fprintf (stderr, "%.*s\n", (int)status_string.length,
+ (char *)status_string.value);
+ gss_release_buffer (&new_stat, &status_string);
+ }
+ } while (!GSS_ERROR(ret) && msg_ctx != 0);
+}
+
+static void
+gss_err(int exitval, int status, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vwarnx (fmt, args);
+ gss_print_errors (status);
+ va_end(args);
+ exit (exitval);
+}
+
+static void
+acquire_release_loop(gss_name_t name, int counter, gss_cred_usage_t usage)
+{
+ OM_uint32 maj_stat, min_stat;
+ gss_cred_id_t cred;
+ int i;
+
+ for (i = 0; i < counter; i++) {
+ maj_stat = gss_acquire_cred(&min_stat, name,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ usage,
+ &cred,
+ NULL,
+ NULL);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "aquire %d %d != GSS_S_COMPLETE",
+ i, (int)maj_stat);
+
+ maj_stat = gss_release_cred(&min_stat, &cred);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "release %d %d != GSS_S_COMPLETE",
+ i, (int)maj_stat);
+ }
+}
+
+
+static void
+acquire_add_release_add(gss_name_t name, gss_cred_usage_t usage)
+{
+ OM_uint32 maj_stat, min_stat;
+ gss_cred_id_t cred, cred2, cred3;
+
+ maj_stat = gss_acquire_cred(&min_stat, name,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ usage,
+ &cred,
+ NULL,
+ NULL);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "aquire %d != GSS_S_COMPLETE", (int)maj_stat);
+
+ maj_stat = gss_add_cred(&min_stat,
+ cred,
+ GSS_C_NO_NAME,
+ GSS_KRB5_MECHANISM,
+ usage,
+ GSS_C_INDEFINITE,
+ GSS_C_INDEFINITE,
+ &cred2,
+ NULL,
+ NULL,
+ NULL);
+
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "add_cred %d != GSS_S_COMPLETE", (int)maj_stat);
+
+ maj_stat = gss_release_cred(&min_stat, &cred);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "release %d != GSS_S_COMPLETE", (int)maj_stat);
+
+ maj_stat = gss_add_cred(&min_stat,
+ cred2,
+ GSS_C_NO_NAME,
+ GSS_KRB5_MECHANISM,
+ GSS_C_BOTH,
+ GSS_C_INDEFINITE,
+ GSS_C_INDEFINITE,
+ &cred3,
+ NULL,
+ NULL,
+ NULL);
+
+ maj_stat = gss_release_cred(&min_stat, &cred2);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat);
+
+ maj_stat = gss_release_cred(&min_stat, &cred3);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat);
+}
+
+static int version_flag = 0;
+static int help_flag = 0;
+
+static struct getargs args[] = {
+ {"version", 0, arg_flag, &version_flag, "print version", NULL },
+ {"help", 0, arg_flag, &help_flag, NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args, sizeof(args)/sizeof(*args),
+ NULL, "service@host");
+ exit (ret);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ struct gss_buffer_desc_struct name_buffer;
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t name;
+ int optidx = 0;
+
+ setprogname(argv[0]);
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ if (argc < 1)
+ errx(1, "argc < 1");
+
+ name_buffer.value = argv[0];
+ name_buffer.length = strlen(argv[0]);
+
+ maj_stat = gss_import_name(&min_stat, &name_buffer,
+ GSS_C_NT_HOSTBASED_SERVICE,
+ &name);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "import name error");
+
+ acquire_release_loop(name, 100, GSS_C_ACCEPT);
+ acquire_release_loop(name, 100, GSS_C_INITIATE);
+ acquire_release_loop(name, 100, GSS_C_BOTH);
+
+ acquire_add_release_add(name, GSS_C_ACCEPT);
+ acquire_add_release_add(name, GSS_C_INITIATE);
+ acquire_add_release_add(name, GSS_C_BOTH);
+
+ gss_release_name(&min_stat, &name);
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/gssapi/test_kcred.c b/crypto/heimdal/lib/gssapi/test_kcred.c
new file mode 100644
index 0000000..a22d4ec
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/test_kcred.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2003-2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <roken.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <gssapi.h>
+#include <gssapi_krb5.h>
+#include <gssapi_spnego.h>
+#include <krb5.h>
+#include <err.h>
+#include <getarg.h>
+
+static int version_flag = 0;
+static int help_flag = 0;
+
+static void
+copy_import(void)
+{
+ gss_cred_id_t cred1, cred2;
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t name1, name2;
+ OM_uint32 lifetime1, lifetime2;
+ gss_cred_usage_t usage1, usage2;
+ gss_OID_set mechs1, mechs2;
+ krb5_ccache id;
+ krb5_error_code ret;
+ krb5_context context;
+ int equal;
+
+ maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME, GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET, GSS_C_INITIATE,
+ &cred1, NULL, NULL);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_acquire_cred");
+
+ maj_stat = gss_inquire_cred(&min_stat, cred1, &name1, &lifetime1,
+ &usage1, &mechs1);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_inquire_cred");
+
+ ret = krb5_init_context(&context);
+ if (ret)
+ errx(1, "krb5_init_context");
+
+ ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_cc_new_unique");
+
+ maj_stat = gss_krb5_copy_ccache(&min_stat, cred1, id);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_krb5_copy_ccache");
+
+ maj_stat = gss_krb5_import_cred(&min_stat, id, NULL, NULL, &cred2);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_krb5_import_cred");
+
+ maj_stat = gss_inquire_cred(&min_stat, cred2, &name2, &lifetime2,
+ &usage2, &mechs2);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_inquire_cred 2");
+
+ maj_stat = gss_compare_name(&min_stat, name1, name2, &equal);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_compare_name");
+ if (!equal)
+ errx(1, "names not equal");
+
+ if (lifetime1 != lifetime2)
+ errx(1, "lifetime not equal %lu != %lu",
+ (unsigned long)lifetime1, (unsigned long)lifetime2);
+
+ if (usage1 != usage2) {
+ /* as long any of them is both are everything it ok */
+ if (usage1 != GSS_C_BOTH && usage2 != GSS_C_BOTH)
+ errx(1, "usages disjoined");
+ }
+
+ gss_release_name(&min_stat, &name2);
+ gss_release_oid_set(&min_stat, &mechs2);
+
+ maj_stat = gss_inquire_cred(&min_stat, cred2, &name2, &lifetime2,
+ &usage2, &mechs2);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_inquire_cred");
+
+ maj_stat = gss_compare_name(&min_stat, name1, name2, &equal);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_compare_name");
+ if (!equal)
+ errx(1, "names not equal");
+
+ if (lifetime1 != lifetime2)
+ errx(1, "lifetime not equal %lu != %lu",
+ (unsigned long)lifetime1, (unsigned long)lifetime2);
+
+ gss_release_cred(&min_stat, &cred1);
+ gss_release_cred(&min_stat, &cred2);
+
+ gss_release_name(&min_stat, &name1);
+ gss_release_name(&min_stat, &name2);
+
+#if 0
+ compare(mechs1, mechs2);
+#endif
+
+ gss_release_oid_set(&min_stat, &mechs1);
+ gss_release_oid_set(&min_stat, &mechs2);
+
+ krb5_cc_destroy(context, id);
+ krb5_free_context(context);
+}
+
+static struct getargs args[] = {
+ {"version", 0, arg_flag, &version_flag, "print version", NULL },
+ {"help", 0, arg_flag, &help_flag, NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args, sizeof(args)/sizeof(*args),
+ NULL, "");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ int optidx = 0;
+
+ setprogname(argv[0]);
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ copy_import();
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/gssapi/test_names.c b/crypto/heimdal/lib/gssapi/test_names.c
new file mode 100644
index 0000000..6546611
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/test_names.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <roken.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <gssapi.h>
+#include <gssapi_krb5.h>
+#include <gssapi_spnego.h>
+#include <err.h>
+#include <getarg.h>
+
+static void
+gss_print_errors (int min_stat)
+{
+ OM_uint32 new_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+ OM_uint32 ret;
+
+ do {
+ ret = gss_display_status (&new_stat,
+ min_stat,
+ GSS_C_MECH_CODE,
+ GSS_C_NO_OID,
+ &msg_ctx,
+ &status_string);
+ if (!GSS_ERROR(ret)) {
+ fprintf (stderr, "%.*s\n", (int)status_string.length,
+ (char *)status_string.value);
+ gss_release_buffer (&new_stat, &status_string);
+ }
+ } while (!GSS_ERROR(ret) && msg_ctx != 0);
+}
+
+static void
+gss_err(int exitval, int status, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vwarnx (fmt, args);
+ gss_print_errors (status);
+ va_end(args);
+ exit (exitval);
+}
+
+static int version_flag = 0;
+static int help_flag = 0;
+
+static struct getargs args[] = {
+ {"version", 0, arg_flag, &version_flag, "print version", NULL },
+ {"help", 0, arg_flag, &help_flag, NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args, sizeof(args)/sizeof(*args),
+ NULL, "service@host");
+ exit (ret);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ gss_buffer_desc name_buffer;
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t name, MNname, MNname2;
+ int optidx = 0;
+ char *str;
+ int len, equal;
+
+ setprogname(argv[0]);
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ gsskrb5_set_default_realm("MIT.EDU");
+
+ /*
+ * test import/export
+ */
+
+ str = NULL;
+ len = asprintf(&str, "ftp@freeze-arrow.mit.edu");
+ if (len < 0 || str == NULL)
+ errx(1, "asprintf");
+
+ name_buffer.value = str;
+ name_buffer.length = len;
+
+ maj_stat = gss_import_name(&min_stat, &name_buffer,
+ GSS_C_NT_HOSTBASED_SERVICE,
+ &name);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "import name error");
+ free(str);
+
+ maj_stat = gss_canonicalize_name (&min_stat,
+ name,
+ GSS_KRB5_MECHANISM,
+ &MNname);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "canonicalize name error");
+
+ maj_stat = gss_export_name(&min_stat,
+ MNname,
+ &name_buffer);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "export name error (KRB5)");
+
+ /*
+ * Import the exported name and compare
+ */
+
+ maj_stat = gss_import_name(&min_stat, &name_buffer,
+ GSS_C_NT_EXPORT_NAME,
+ &MNname2);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "import name error (exported KRB5 name)");
+
+
+ maj_stat = gss_compare_name(&min_stat, MNname, MNname2, &equal);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_compare_name");
+ if (!equal)
+ errx(1, "names not equal");
+
+ gss_release_name(&min_stat, &MNname2);
+ gss_release_buffer(&min_stat, &name_buffer);
+ gss_release_name(&min_stat, &MNname);
+ gss_release_name(&min_stat, &name);
+
+ /*
+ * Import oid less name and compare to mech name.
+ * Dovecot SASL lib does this.
+ */
+
+ str = NULL;
+ len = asprintf(&str, "lha");
+ if (len < 0 || str == NULL)
+ errx(1, "asprintf");
+
+ name_buffer.value = str;
+ name_buffer.length = len;
+
+ maj_stat = gss_import_name(&min_stat, &name_buffer,
+ GSS_C_NO_OID,
+ &name);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "import (no oid) name error");
+
+ maj_stat = gss_import_name(&min_stat, &name_buffer,
+ GSS_KRB5_NT_USER_NAME,
+ &MNname);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "import (krb5 mn) name error");
+
+ free(str);
+
+ maj_stat = gss_compare_name(&min_stat, name, MNname, &equal);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "gss_compare_name");
+ if (!equal)
+ errx(1, "names not equal");
+
+ gss_release_name(&min_stat, &MNname);
+ gss_release_name(&min_stat, &name);
+
+#if 0
+ maj_stat = gss_canonicalize_name (&min_stat,
+ name,
+ GSS_SPNEGO_MECHANISM,
+ &MNname);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "canonicalize name error");
+
+
+ maj_stat = gss_export_name(&maj_stat,
+ MNname,
+ &name_buffer);
+ if (maj_stat != GSS_S_COMPLETE)
+ gss_err(1, min_stat, "export name error (SPNEGO)");
+
+ gss_release_name(&min_stat, &MNname);
+ gss_release_buffer(&min_stat, &name_buffer);
+#endif
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/gssapi/test_ntlm.c b/crypto/heimdal/lib/gssapi/test_ntlm.c
new file mode 100644
index 0000000..9b289c2
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/test_ntlm.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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.
+ */
+
+#include "config.h"
+
+#include <roken.h>
+#include <stdio.h>
+#include <gssapi.h>
+#include <err.h>
+#include <getarg.h>
+#include "test_common.h"
+
+#include <krb5.h>
+#include <heimntlm.h>
+
+static int
+test_libntlm_v1(int flags)
+{
+ const char *user = "foo",
+ *domain = "mydomain",
+ *password = "digestpassword";
+ OM_uint32 maj_stat, min_stat;
+ gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
+ gss_buffer_desc input, output;
+ struct ntlm_type1 type1;
+ struct ntlm_type2 type2;
+ struct ntlm_type3 type3;
+ struct ntlm_buf data;
+ krb5_error_code ret;
+ gss_name_t src_name = GSS_C_NO_NAME;
+
+ memset(&type1, 0, sizeof(type1));
+ memset(&type2, 0, sizeof(type2));
+ memset(&type3, 0, sizeof(type3));
+
+ type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_TARGET|NTLM_NEG_NTLM|flags;
+ type1.domain = strdup(domain);
+ type1.hostname = NULL;
+ type1.os[0] = 0;
+ type1.os[1] = 0;
+
+ ret = heim_ntlm_encode_type1(&type1, &data);
+ if (ret)
+ errx(1, "heim_ntlm_encode_type1");
+
+ input.value = data.data;
+ input.length = data.length;
+
+ output.length = 0;
+ output.value = NULL;
+
+ maj_stat = gss_accept_sec_context(&min_stat,
+ &ctx,
+ GSS_C_NO_CREDENTIAL,
+ &input,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ NULL,
+ NULL,
+ &output,
+ NULL,
+ NULL,
+ NULL);
+ free(data.data);
+ if (GSS_ERROR(maj_stat))
+ errx(1, "accept_sec_context v1: %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+
+ if (output.length == 0)
+ errx(1, "output.length == 0");
+
+ data.data = output.value;
+ data.length = output.length;
+
+ ret = heim_ntlm_decode_type2(&data, &type2);
+ if (ret)
+ errx(1, "heim_ntlm_decode_type2");
+
+ gss_release_buffer(&min_stat, &output);
+
+ type3.flags = type2.flags;
+ type3.username = rk_UNCONST(user);
+ type3.targetname = type2.targetname;
+ type3.ws = rk_UNCONST("workstation");
+
+ {
+ struct ntlm_buf key;
+
+ heim_ntlm_nt_key(password, &key);
+
+ heim_ntlm_calculate_ntlm1(key.data, key.length,
+ type2.challenge,
+ &type3.ntlm);
+
+ if (flags & NTLM_NEG_KEYEX) {
+ struct ntlm_buf sessionkey;
+ heim_ntlm_build_ntlm1_master(key.data, key.length,
+ &sessionkey,
+ &type3.sessionkey);
+ free(sessionkey.data);
+ }
+ free(key.data);
+ }
+
+ ret = heim_ntlm_encode_type3(&type3, &data);
+ if (ret)
+ errx(1, "heim_ntlm_encode_type3");
+
+ input.length = data.length;
+ input.value = data.data;
+
+ maj_stat = gss_accept_sec_context(&min_stat,
+ &ctx,
+ GSS_C_NO_CREDENTIAL,
+ &input,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &src_name,
+ NULL,
+ &output,
+ NULL,
+ NULL,
+ NULL);
+ free(input.value);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "accept_sec_context v1 2 %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+
+ gss_release_buffer(&min_stat, &output);
+ gss_delete_sec_context(&min_stat, &ctx, NULL);
+
+ if (src_name == GSS_C_NO_NAME)
+ errx(1, "no source name!");
+
+ gss_display_name(&min_stat, src_name, &output, NULL);
+
+ printf("src_name: %.*s\n", (int)output.length, (char*)output.value);
+
+ gss_release_name(&min_stat, &src_name);
+ gss_release_buffer(&min_stat, &output);
+
+ return 0;
+}
+
+static int
+test_libntlm_v2(int flags)
+{
+ const char *user = "foo",
+ *domain = "mydomain",
+ *password = "digestpassword";
+ OM_uint32 maj_stat, min_stat;
+ gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
+ gss_buffer_desc input, output;
+ struct ntlm_type1 type1;
+ struct ntlm_type2 type2;
+ struct ntlm_type3 type3;
+ struct ntlm_buf data;
+ krb5_error_code ret;
+
+ memset(&type1, 0, sizeof(type1));
+ memset(&type2, 0, sizeof(type2));
+ memset(&type3, 0, sizeof(type3));
+
+ type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_NTLM|flags;
+ type1.domain = strdup(domain);
+ type1.hostname = NULL;
+ type1.os[0] = 0;
+ type1.os[1] = 0;
+
+ ret = heim_ntlm_encode_type1(&type1, &data);
+ if (ret)
+ errx(1, "heim_ntlm_encode_type1");
+
+ input.value = data.data;
+ input.length = data.length;
+
+ output.length = 0;
+ output.value = NULL;
+
+ maj_stat = gss_accept_sec_context(&min_stat,
+ &ctx,
+ GSS_C_NO_CREDENTIAL,
+ &input,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ NULL,
+ NULL,
+ &output,
+ NULL,
+ NULL,
+ NULL);
+ free(data.data);
+ if (GSS_ERROR(maj_stat))
+ errx(1, "accept_sec_context v2 %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+
+ if (output.length == 0)
+ errx(1, "output.length == 0");
+
+ data.data = output.value;
+ data.length = output.length;
+
+ ret = heim_ntlm_decode_type2(&data, &type2);
+ if (ret)
+ errx(1, "heim_ntlm_decode_type2");
+
+ type3.flags = type2.flags;
+ type3.username = rk_UNCONST(user);
+ type3.targetname = type2.targetname;
+ type3.ws = rk_UNCONST("workstation");
+
+ {
+ struct ntlm_buf key;
+ unsigned char ntlmv2[16];
+
+ heim_ntlm_nt_key(password, &key);
+
+ heim_ntlm_calculate_ntlm2(key.data, key.length,
+ user,
+ type2.targetname,
+ type2.challenge,
+ &type2.targetinfo,
+ ntlmv2,
+ &type3.ntlm);
+ free(key.data);
+
+ if (flags & NTLM_NEG_KEYEX) {
+ struct ntlm_buf sessionkey;
+ heim_ntlm_build_ntlm1_master(ntlmv2, sizeof(ntlmv2),
+ &sessionkey,
+ &type3.sessionkey);
+ free(sessionkey.data);
+ }
+ }
+
+ ret = heim_ntlm_encode_type3(&type3, &data);
+ if (ret)
+ errx(1, "heim_ntlm_encode_type3");
+
+ input.length = data.length;
+ input.value = data.data;
+
+ maj_stat = gss_accept_sec_context(&min_stat,
+ &ctx,
+ GSS_C_NO_CREDENTIAL,
+ &input,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ NULL,
+ NULL,
+ &output,
+ NULL,
+ NULL,
+ NULL);
+ free(input.value);
+ if (maj_stat != GSS_S_COMPLETE)
+ errx(1, "accept_sec_context v2 2 %s",
+ gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
+
+ gss_delete_sec_context(&min_stat, &ctx, NULL);
+
+ return 0;
+}
+
+
+
+static int version_flag = 0;
+static int help_flag = 0;
+
+static struct getargs args[] = {
+ {"version", 0, arg_flag, &version_flag, "print version", NULL },
+ {"help", 0, arg_flag, &help_flag, NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args, sizeof(args)/sizeof(*args),
+ NULL, "");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret = 0, optind = 0;
+
+ setprogname(argv[0]);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ ret += test_libntlm_v1(0);
+ ret += test_libntlm_v1(NTLM_NEG_KEYEX);
+
+ ret += test_libntlm_v2(0);
+ ret += test_libntlm_v2(NTLM_NEG_KEYEX);
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/gssapi/test_oid.c b/crypto/heimdal/lib/gssapi/test_oid.c
new file mode 100644
index 0000000..db5b7f7
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/test_oid.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <roken.h>
+#include <stdio.h>
+#include <gssapi.h>
+#include <gssapi_krb5.h>
+#include <gssapi_spnego.h>
+#include <err.h>
+
+int
+main(int argc, char **argv)
+{
+ OM_uint32 minor_status, maj_stat;
+ gss_buffer_desc data;
+ int ret;
+
+ maj_stat = gss_oid_to_str(&minor_status, GSS_KRB5_MECHANISM, &data);
+ if (GSS_ERROR(maj_stat))
+ errx(1, "gss_oid_to_str failed");
+
+ ret = strncmp(data.value, "1 2 840 113554 1 2 2", data.length);
+ gss_release_buffer(&maj_stat, &data);
+ if (ret)
+ return 1;
+
+ maj_stat = gss_oid_to_str(&minor_status, GSS_C_NT_EXPORT_NAME, &data);
+ if (GSS_ERROR(maj_stat))
+ errx(1, "gss_oid_to_str failed");
+
+ ret = strncmp(data.value, "1 3 6 1 5 6 4", data.length);
+ gss_release_buffer(&maj_stat, &data);
+ if (ret)
+ return 1;
+
+ return 0;
+}
diff --git a/crypto/heimdal/lib/gssapi/version-script.map b/crypto/heimdal/lib/gssapi/version-script.map
new file mode 100644
index 0000000..bcb79bf
--- /dev/null
+++ b/crypto/heimdal/lib/gssapi/version-script.map
@@ -0,0 +1,196 @@
+# $Id$
+
+HEIMDAL_GSS_2.0 {
+ global:
+# __gss_c_nt_anonymous;
+ __gss_c_nt_anonymous_oid_desc;
+ __gss_c_nt_export_name_oid_desc;
+ __gss_c_nt_hostbased_service_oid_desc;
+ __gss_c_nt_hostbased_service_x_oid_desc;
+ __gss_c_nt_machine_uid_name_oid_desc;
+ __gss_c_nt_string_uid_name_oid_desc;
+ __gss_c_nt_user_name_oid_desc;
+ __gss_krb5_nt_principal_name_oid_desc;
+ __gss_c_attr_stream_sizes_oid_desc;
+ __gss_c_cred_password_oid_desc;
+ __gss_c_cred_certificate_oid_desc;
+ __gss_c_attr_local_login_user;
+ gss_accept_sec_context;
+ gss_acquire_cred;
+ gss_acquire_cred_with_password;
+ gss_add_buffer_set_member;
+ gss_add_cred;
+ gss_add_cred_with_password;
+ gss_add_oid_set_member;
+ gss_authorize_localname;
+ gss_canonicalize_name;
+ gss_compare_name;
+ gss_context_query_attributes;
+ gss_context_time;
+ gss_create_empty_buffer_set;
+ gss_create_empty_oid_set;
+ gss_decapsulate_token;
+ gss_delete_name_attribute;
+ gss_delete_sec_context;
+ gss_display_name;
+ gss_display_name_ext;
+ gss_display_status;
+ gss_duplicate_name;
+ gss_duplicate_oid;
+ gss_encapsulate_token;
+ gss_export_cred;
+ gss_export_name;
+ gss_export_name_composite;
+ gss_export_sec_context;
+ gss_get_mic;
+ gss_get_name_attribute;
+ gss_import_cred;
+ gss_import_name;
+ gss_import_sec_context;
+ gss_indicate_mechs;
+ gss_init_sec_context;
+ gss_inquire_context;
+ gss_inquire_cred;
+ gss_inquire_cred_by_mech;
+ gss_inquire_cred_by_oid;
+ gss_inquire_mechs_for_name;
+ gss_inquire_name;
+ gss_inquire_names_for_mech;
+ gss_inquire_sec_context_by_oid;
+ gss_inquire_sec_context_by_oid;
+ gss_krb5_ccache_name;
+ gss_krb5_copy_ccache;
+ gss_krb5_export_lucid_sec_context;
+ gss_krb5_free_lucid_sec_context;
+ gss_krb5_get_tkt_flags;
+ gss_krb5_import_cred;
+ gss_krb5_set_allowable_enctypes;
+ gss_mg_collect_error;
+ gss_oid_equal;
+ gss_oid_to_str;
+ gss_pname_to_uid;
+ gss_process_context_token;
+ gss_pseudo_random;
+ gss_release_buffer;
+ gss_release_buffer_set;
+ gss_release_cred;
+ gss_release_iov_buffer;
+ gss_release_name;
+ gss_release_oid;
+ gss_release_oid_set;
+ gss_seal;
+ gss_set_cred_option;
+ gss_set_name_attribute;
+ gss_set_sec_context_option;
+ gss_sign;
+ gss_store_cred;
+ gss_test_oid_set_member;
+ gss_unseal;
+ gss_unwrap;
+ gss_unwrap_iov;
+ gss_userok;
+ gss_verify;
+ gss_verify_mic;
+ gss_wrap;
+ gss_wrap_iov;
+ gss_wrap_iov_length;
+ gss_wrap_size_limit;
+ gsskrb5_extract_authtime_from_sec_context;
+ gsskrb5_extract_authz_data_from_sec_context;
+ gsskrb5_extract_service_keyblock;
+ gsskrb5_get_initiator_subkey;
+ gsskrb5_get_subkey;
+ gsskrb5_get_time_offset;
+ gsskrb5_register_acceptor_identity;
+ gsskrb5_set_default_realm;
+ gsskrb5_set_dns_canonicalize;
+ gsskrb5_set_send_to_kdc;
+ gsskrb5_set_time_offset;
+ krb5_gss_register_acceptor_identity;
+ gss_display_mech_attr;
+ gss_inquire_attrs_for_mech;
+ gss_indicate_mechs_by_attrs;
+ gss_inquire_mech_for_saslname;
+ gss_inquire_saslname_for_mech;
+ gss_mo_get;
+ gss_mo_set;
+ gss_mo_list;
+ gss_mo_name;
+ gss_name_to_oid;
+ gss_oid_to_name;
+
+ # _gsskrb5cfx_ are really internal symbols, but export
+ # then now to make testing easier.
+ _gsskrb5cfx_wrap_length_cfx;
+ _gssapi_wrap_size_cfx;
+
+ __gss_krb5_copy_ccache_x_oid_desc;
+ __gss_krb5_get_tkt_flags_x_oid_desc;
+ __gss_krb5_extract_authz_data_from_sec_context_x_oid_desc;
+ __gss_krb5_compat_des3_mic_x_oid_desc;
+ __gss_krb5_register_acceptor_identity_x_oid_desc;
+ __gss_krb5_export_lucid_context_x_oid_desc;
+ __gss_krb5_export_lucid_context_v1_x_oid_desc;
+ __gss_krb5_set_dns_canonicalize_x_oid_desc;
+ __gss_krb5_get_subkey_x_oid_desc;
+ __gss_krb5_get_initiator_subkey_x_oid_desc;
+ __gss_krb5_get_acceptor_subkey_x_oid_desc;
+ __gss_krb5_send_to_kdc_x_oid_desc;
+ __gss_krb5_get_authtime_x_oid_desc;
+ __gss_krb5_get_service_keyblock_x_oid_desc;
+ __gss_krb5_set_allowable_enctypes_x_oid_desc;
+ __gss_krb5_set_default_realm_x_oid_desc;
+ __gss_krb5_ccache_name_x_oid_desc;
+ __gss_krb5_set_time_offset_x_oid_desc;
+ __gss_krb5_get_time_offset_x_oid_desc;
+ __gss_krb5_plugin_register_x_oid_desc;
+ __gss_ntlm_get_session_key_x_oid_desc;
+ __gss_c_nt_ntlm_oid_desc;
+ __gss_c_nt_dn_oid_desc;
+ __gss_krb5_nt_principal_name_referral_oid_desc;
+ __gss_c_ntlm_avguest_oid_desc;
+ __gss_c_ntlm_v1_oid_desc;
+ __gss_c_ntlm_v2_oid_desc;
+ __gss_c_ntlm_session_key_oid_desc;
+ __gss_c_ntlm_force_v1_oid_desc;
+ __gss_krb5_cred_no_ci_flags_x_oid_desc;
+ __gss_krb5_import_cred_x_oid_desc;
+ __gss_c_ma_sasl_mech_name_oid_desc;
+ __gss_c_ma_mech_name_oid_desc;
+ __gss_c_ma_mech_description_oid_desc;
+ __gss_sasl_digest_md5_mechanism_oid_desc;
+ __gss_krb5_mechanism_oid_desc;
+ __gss_ntlm_mechanism_oid_desc;
+ __gss_spnego_mechanism_oid_desc;
+ __gss_c_peer_has_updated_spnego_oid_desc;
+ __gss_c_ma_mech_concrete_oid_desc;
+ __gss_c_ma_mech_pseudo_oid_desc;
+ __gss_c_ma_mech_composite_oid_desc;
+ __gss_c_ma_mech_nego_oid_desc;
+ __gss_c_ma_mech_glue_oid_desc;
+ __gss_c_ma_not_mech_oid_desc;
+ __gss_c_ma_deprecated_oid_desc;
+ __gss_c_ma_not_dflt_mech_oid_desc;
+ __gss_c_ma_itok_framed_oid_desc;
+ __gss_c_ma_auth_init_oid_desc;
+ __gss_c_ma_auth_targ_oid_desc;
+ __gss_c_ma_auth_init_init_oid_desc;
+ __gss_c_ma_auth_targ_init_oid_desc;
+ __gss_c_ma_auth_init_anon_oid_desc;
+ __gss_c_ma_auth_targ_anon_oid_desc;
+ __gss_c_ma_deleg_cred_oid_desc;
+ __gss_c_ma_integ_prot_oid_desc;
+ __gss_c_ma_conf_prot_oid_desc;
+ __gss_c_ma_mic_oid_desc;
+ __gss_c_ma_wrap_oid_desc;
+ __gss_c_ma_prot_ready_oid_desc;
+ __gss_c_ma_replay_det_oid_desc;
+ __gss_c_ma_oos_det_oid_desc;
+ __gss_c_ma_cbindings_oid_desc;
+ __gss_c_ma_pfs_oid_desc;
+ __gss_c_ma_compress_oid_desc;
+ __gss_c_ma_ctx_trans_oid_desc;
+
+ local:
+ *;
+};
OpenPOWER on IntegriCloud