diff options
author | Andrew Bartlett <abartlet@samba.org> | 2006-11-13 03:19:59 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:25:31 -0500 |
commit | 5a6288f45891be30bd8e22978f61faf487214de6 (patch) | |
tree | b0eeb8a90125bc818ab6057a025da67facec916d /source4/heimdal/lib/gssapi/mech | |
parent | 9d7856122e9ddd1b87ff68215669bff3c28bcafd (diff) | |
download | samba-5a6288f45891be30bd8e22978f61faf487214de6.tar.gz samba-5a6288f45891be30bd8e22978f61faf487214de6.tar.bz2 samba-5a6288f45891be30bd8e22978f61faf487214de6.zip |
r19681: Update to current lorikeet-heimdal. I'm looking at using the realm
lookup plugin, the new PAC validation code as well as Heimdal's SPNEGO
implementation.
Andrew Bartlett
(This used to be commit 05421f45ed7811697ea491e26c9d991a7faa1a64)
Diffstat (limited to 'source4/heimdal/lib/gssapi/mech')
-rw-r--r-- | source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c | 163 | ||||
-rw-r--r-- | source4/heimdal/lib/gssapi/mech/gss_krb5.c | 38 |
2 files changed, 139 insertions, 62 deletions
diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c index d3a21464da..73207806a0 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c @@ -27,7 +27,108 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_accept_sec_context.c,v 1.6 2006/10/25 00:45:12 lha Exp $"); +RCSID("$Id: gss_accept_sec_context.c,v 1.7 2006/11/10 03:30:12 lha Exp $"); + +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 its 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 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 its 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 != 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 wiered mode of SPNEGO (in CIFS and + * SASL GSS-SPENGO where the first token is zero + * length and the acceptor returns a mech_list, lets + * home that is what is happening now. + */ + *mech_oid = spnego_mechanism; + return GSS_S_COMPLETE; + } + return status; +} + OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle, @@ -64,64 +165,12 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, * parse the input token to figure out the mechanism to use. */ if (*context_handle == GSS_C_NO_CONTEXT) { - unsigned char *p = input_token->value; - size_t len = input_token->length; - size_t a, b; gss_OID_desc mech_oid; - /* - * Token must start with [APPLICATION 0] SEQUENCE. - * But if it doesn't assume its DCE-STYLE Kerberos! - * And if it's not there at all, then we are requesting a mech list from SPNEGO - */ - if (len == 0) { - mech_oid = *GSS_SPNEGO_MECHANISM; - } else if (*p != 0x60) { - mech_oid = *GSS_KRB5_MECHANISM; - } else { - 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; - } + 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. diff --git a/source4/heimdal/lib/gssapi/mech/gss_krb5.c b/source4/heimdal/lib/gssapi/mech/gss_krb5.c index 34cdbeb3c1..76a2c2b637 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_krb5.c +++ b/source4/heimdal/lib/gssapi/mech/gss_krb5.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_krb5.c,v 1.20 2006/11/08 23:11:03 lha Exp $"); +RCSID("$Id: gss_krb5.c,v 1.21 2006/11/10 00:57:27 lha Exp $"); #include <krb5.h> #include <roken.h> @@ -421,13 +421,41 @@ gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *c) */ OM_uint32 -gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status, +gss_krb5_set_allowable_enctypes(OM_uint32 *min_status, gss_cred_id_t cred, OM_uint32 num_enctypes, - krb5_enctype *enctypes) + int32_t *enctypes) { - *minor_status = 0; - return GSS_S_COMPLETE; + OM_uint32 maj_status; + gss_buffer_desc buffer; + krb5_storage *sp; + krb5_data data; + + sp = krb5_storage_emem(); + if (sp == NULL) { + *min_status = ENOMEM; + maj_status = GSS_S_FAILURE; + goto out; + } + + while(*enctypes) { + krb5_store_int32(sp, *enctypes); + enctypes++; + } + + krb5_storage_to_data(sp, &data); + + buffer.value = data.data; + buffer.length = data.length; + + maj_status = gss_set_cred_option(min_status, + &cred, + GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X, + &buffer); +out: + if (sp) + krb5_storage_free(sp); + return maj_status; } /* |