summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/gssapi
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/gssapi')
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi.h53
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h8
-rw-r--r--source4/heimdal/lib/gssapi/krb5/gkrb5_err.et30
-rw-r--r--source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h3
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c163
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_krb5.c38
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;
}
/*