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 | |
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')
-rw-r--r-- | source4/heimdal/lib/gssapi/gssapi/gssapi.h | 53 | ||||
-rw-r--r-- | source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h | 8 | ||||
-rw-r--r-- | source4/heimdal/lib/gssapi/krb5/gkrb5_err.et | 30 | ||||
-rw-r--r-- | source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h | 3 | ||||
-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 |
6 files changed, 179 insertions, 116 deletions
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h index 238907653e..f89e5dfbee 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gssapi.h,v 1.5 2006/10/19 07:11:14 lha Exp $ */ +/* $Id: gssapi.h,v 1.6 2006/11/10 00:39:50 lha Exp $ */ #ifndef GSSAPI_GSSAPI_H_ #define GSSAPI_GSSAPI_H_ @@ -378,57 +378,6 @@ extern gss_OID GSS_SASL_DIGEST_MD5_MECHANISM; #define GSS_S_GAP_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 4)) /* - * From RFC1964: - * - * 4.1.1. Non-Kerberos-specific codes - */ - -#define GSS_KRB5_S_G_BAD_SERVICE_NAME 1 - /* "No @ in SERVICE-NAME name string" */ -#define GSS_KRB5_S_G_BAD_STRING_UID 2 - /* "STRING-UID-NAME contains nondigits" */ -#define GSS_KRB5_S_G_NOUSER 3 - /* "UID does not resolve to username" */ -#define GSS_KRB5_S_G_VALIDATE_FAILED 4 - /* "Validation error" */ -#define GSS_KRB5_S_G_BUFFER_ALLOC 5 - /* "Couldn't allocate gss_buffer_t data" */ -#define GSS_KRB5_S_G_BAD_MSG_CTX 6 - /* "Message context invalid" */ -#define GSS_KRB5_S_G_WRONG_SIZE 7 - /* "Buffer is the wrong size" */ -#define GSS_KRB5_S_G_BAD_USAGE 8 - /* "Credential usage type is unknown" */ -#define GSS_KRB5_S_G_UNKNOWN_QOP 9 - /* "Unknown quality of protection specified" */ - - /* - * 4.1.2. Kerberos-specific-codes - */ - -#define GSS_KRB5_S_KG_CCACHE_NOMATCH 10 - /* "Principal in credential cache does not match desired name" */ -#define GSS_KRB5_S_KG_KEYTAB_NOMATCH 11 - /* "No principal in keytab matches desired name" */ -#define GSS_KRB5_S_KG_TGT_MISSING 12 - /* "Credential cache has no TGT" */ -#define GSS_KRB5_S_KG_NO_SUBKEY 13 - /* "Authenticator has no subkey" */ -#define GSS_KRB5_S_KG_CONTEXT_ESTABLISHED 14 - /* "Context is already fully established" */ -#define GSS_KRB5_S_KG_BAD_SIGN_TYPE 15 - /* "Unknown signature type in token" */ -#define GSS_KRB5_S_KG_BAD_LENGTH 16 - /* "Invalid field length in token" */ -#define GSS_KRB5_S_KG_CTX_INCOMPLETE 17 - /* "Attempt to use incomplete security context" */ - -/* - * This is used to make sure mechs that don't want to have external - * references don't get any prototypes, and thus can get warnings. - */ - -/* * Finally, function prototypes for the GSS-API routines. */ diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h index f06a994008..ecd90a6656 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gssapi_krb5.h,v 1.14 2006/11/08 23:01:01 lha Exp $ */ +/* $Id: gssapi_krb5.h,v 1.17 2006/11/10 01:05:34 lha Exp $ */ #ifndef GSSAPI_KRB5_H_ #define GSSAPI_KRB5_H_ @@ -78,6 +78,7 @@ extern gss_OID GSS_KRB5_GET_AUTHTIME_X; extern gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X; /* Extensions creds */ extern gss_OID GSS_KRB5_IMPORT_CRED_X; +extern gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X; /* * kerberos mechanism specific functions @@ -205,6 +206,11 @@ gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *kctx); +OM_uint32 +gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status, + gss_cred_id_t cred, + OM_uint32 num_enctypes, + int32_t *enctypes); #ifdef __cplusplus } diff --git a/source4/heimdal/lib/gssapi/krb5/gkrb5_err.et b/source4/heimdal/lib/gssapi/krb5/gkrb5_err.et new file mode 100644 index 0000000000..97e98c5e1e --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/gkrb5_err.et @@ -0,0 +1,30 @@ +# +# extended gss krb5 error messages +# + +id "$Id: gkrb5_err.et,v 1.1 2006/11/09 23:52:17 lha Exp $" + +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" diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h index ea7a561b5b..39c800bf31 100644 --- a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h +++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gsskrb5_locl.h,v 1.7 2006/11/07 17:57:43 lha Exp $ */ +/* $Id: gsskrb5_locl.h,v 1.8 2006/11/10 00:36:40 lha Exp $ */ #ifndef GSSKRB5_LOCL_H #define GSSKRB5_LOCL_H @@ -41,6 +41,7 @@ #endif #include <krb5_locl.h> +#include <gkrb5_err.h> #include <gssapi.h> #include <gssapi_mech.h> #include <assert.h> 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; } /* |