Blame SOURCES/Refactor-krb5-GSS-checksum-handling.patch

0ba406
From 4f14a2f48b52e59c472847a5522fd0cf52927755 Mon Sep 17 00:00:00 2001
9c4c6b
From: Alexander Scheel <ascheel@redhat.com>
9c4c6b
Date: Fri, 30 Jun 2017 16:03:01 -0400
9c4c6b
Subject: [PATCH] Refactor krb5 GSS checksum handling
9c4c6b
9c4c6b
Separate out checksum handling from kg_accept_krb5() into a new helper
9c4c6b
process_checksum().
9c4c6b
9c4c6b
[ghudson@mit.edu: simplified checksum processing and made it use
9c4c6b
k5-input.h instead of TREAD_ macros; moved more flag handling into
9c4c6b
helper]
9c4c6b
9c4c6b
[iboukris: adjusted helper function arguments, allowing access to the
9c4c6b
full authenticator for subsequent changes]
9c4c6b
9c4c6b
(cherry picked from commit 64d56233f9816a2a93f6e8d3030c8ed6ce397735)
9c4c6b
[rharwood@redhat.com: problem with typo fix commit, I think]
9c4c6b
(cherry picked from commit a34b7c50e62c19f80d39ece6a72017dac781df64)
9c4c6b
---
9c4c6b
 src/lib/gssapi/krb5/accept_sec_context.c | 383 +++++++++++------------
9c4c6b
 1 file changed, 179 insertions(+), 204 deletions(-)
9c4c6b
9c4c6b
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
9c4c6b
index c5bddb1e8..70dd7fc0c 100644
9c4c6b
--- a/src/lib/gssapi/krb5/accept_sec_context.c
9c4c6b
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
9c4c6b
@@ -98,6 +98,7 @@
9c4c6b
  */
9c4c6b
 
9c4c6b
 #include "k5-int.h"
9c4c6b
+#include "k5-input.h"
9c4c6b
 #include "gssapiP_krb5.h"
9c4c6b
 #ifdef HAVE_MEMORY_H
9c4c6b
 #include <memory.h>
9c4c6b
@@ -413,6 +414,174 @@ kg_process_extension(krb5_context context,
9c4c6b
     return code;
9c4c6b
 }
9c4c6b
 
9c4c6b
+/* The length of the MD5 channel bindings in an 0x8003 checksum */
9c4c6b
+#define CB_MD5_LEN 16
9c4c6b
+
9c4c6b
+/* The minimum length of an 0x8003 checksum value (4-byte channel bindings
9c4c6b
+ * length, 16-byte channel bindings, 4-byte flags) */
9c4c6b
+#define MIN_8003_LEN (4 + CB_MD5_LEN + 4)
9c4c6b
+
9c4c6b
+/* The flags we accept from the initiator's authenticator checksum. */
9c4c6b
+#define INITIATOR_FLAGS (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |           \
9c4c6b
+                         GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |        \
9c4c6b
+                         GSS_C_SEQUENCE_FLAG | GSS_C_DCE_STYLE |        \
9c4c6b
+                         GSS_C_IDENTIFY_FLAG | GSS_C_EXTENDED_ERROR_FLAG)
9c4c6b
+
9c4c6b
+/*
9c4c6b
+ * The krb5 GSS mech appropriates the authenticator checksum field from RFC
9c4c6b
+ * 4120 to store structured data instead of a checksum, indicated with checksum
9c4c6b
+ * type 0x8003 (see RFC 4121 section 4.1.1).  Some implementations instead send
9c4c6b
+ * no checksum, or a regular checksum over empty data.
9c4c6b
+ *
9c4c6b
+ * Interpret the checksum.  Read delegated creds into *deleg_out if it is not
9c4c6b
+ * NULL.  Set *flags_out to the allowed subset of token flags, plus
9c4c6b
+ * GSS_C_DELEG_FLAG if a delegated credential was present.  Process any
9c4c6b
+ * extensions found using exts.  On error, set *code_out to a krb5_error code
9c4c6b
+ * for use as a minor status value.
9c4c6b
+ */
9c4c6b
+static OM_uint32
9c4c6b
+process_checksum(OM_uint32 *minor_status, krb5_context context,
9c4c6b
+                 gss_channel_bindings_t acceptor_cb,
9c4c6b
+                 krb5_auth_context auth_context, krb5_flags ap_req_options,
9c4c6b
+                 krb5_authenticator *authenticator, krb5_gss_ctx_ext_t exts,
9c4c6b
+                 krb5_gss_cred_id_t *deleg_out, krb5_ui_4 *flags_out,
9c4c6b
+                 krb5_error_code *code_out)
9c4c6b
+{
9c4c6b
+    krb5_error_code code = 0;
9c4c6b
+    OM_uint32 status, option_id, token_flags;
9c4c6b
+    size_t cb_len, option_len;
9c4c6b
+    krb5_boolean valid;
9c4c6b
+    krb5_key subkey;
9c4c6b
+    krb5_data option, empty = empty_data();
9c4c6b
+    krb5_checksum cb_cksum;
9c4c6b
+    const uint8_t *token_cb, *option_bytes;
9c4c6b
+    struct k5input in;
9c4c6b
+    const krb5_checksum *cksum = authenticator->checksum;
9c4c6b
+
9c4c6b
+    cb_cksum.contents = NULL;
9c4c6b
+
9c4c6b
+    if (cksum == NULL) {
9c4c6b
+        /*
9c4c6b
+         * Some SMB client implementations use handcrafted GSSAPI code that
9c4c6b
+         * does not provide a checksum.  MS-KILE documents that the Microsoft
9c4c6b
+         * implementation considers a missing checksum acceptable; the server
9c4c6b
+         * assumes all flags are unset in this case, and does not check channel
9c4c6b
+         * bindings.
9c4c6b
+         */
9c4c6b
+        *flags_out = 0;
9c4c6b
+    } else if (cksum->checksum_type != CKSUMTYPE_KG_CB) {
9c4c6b
+        /* Samba sends a regular checksum. */
9c4c6b
+        code = krb5_auth_con_getkey_k(context, auth_context, &subkey);
9c4c6b
+        if (code) {
9c4c6b
+            status = GSS_S_FAILURE;
9c4c6b
+            goto fail;
9c4c6b
+        }
9c4c6b
+
9c4c6b
+        /* Verifying the checksum ensures that this authenticator wasn't
9c4c6b
+         * replayed from one with a checksum over actual data. */
9c4c6b
+        code = krb5_k_verify_checksum(context, subkey,
9c4c6b
+                                      KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM, &empty,
9c4c6b
+                                      cksum, &valid);
9c4c6b
+        krb5_k_free_key(context, subkey);
9c4c6b
+        if (code || !valid) {
9c4c6b
+            status = GSS_S_BAD_SIG;
9c4c6b
+            goto fail;
9c4c6b
+        }
9c4c6b
+
9c4c6b
+        /* Use ap_options from the request to guess the mutual flag. */
9c4c6b
+        *flags_out = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
9c4c6b
+        if (ap_req_options & AP_OPTS_MUTUAL_REQUIRED)
9c4c6b
+            *flags_out |= GSS_C_MUTUAL_FLAG;
9c4c6b
+    } else {
9c4c6b
+        /* The checksum must contain at least a fixed 24-byte part. */
9c4c6b
+        if (cksum->length < MIN_8003_LEN) {
9c4c6b
+            status = GSS_S_BAD_BINDINGS;
9c4c6b
+            goto fail;
9c4c6b
+        }
9c4c6b
+
9c4c6b
+        k5_input_init(&in, cksum->contents, cksum->length);
9c4c6b
+        cb_len = k5_input_get_uint32_le(&in);
9c4c6b
+        if (cb_len != CB_MD5_LEN) {
9c4c6b
+            code = KG_BAD_LENGTH;
9c4c6b
+            status = GSS_S_FAILURE;
9c4c6b
+            goto fail;
9c4c6b
+        }
9c4c6b
+
9c4c6b
+        token_cb = k5_input_get_bytes(&in, cb_len);
9c4c6b
+        if (acceptor_cb != GSS_C_NO_CHANNEL_BINDINGS) {
9c4c6b
+            code = kg_checksum_channel_bindings(context, acceptor_cb,
9c4c6b
+                                                &cb_cksum);
9c4c6b
+            if (code) {
9c4c6b
+                status = GSS_S_BAD_BINDINGS;
9c4c6b
+                goto fail;
9c4c6b
+            }
9c4c6b
+            assert(cb_cksum.length == cb_len);
9c4c6b
+            if (k5_bcmp(token_cb, cb_cksum.contents, cb_len) != 0) {
9c4c6b
+                status = GSS_S_BAD_BINDINGS;
9c4c6b
+                goto fail;
9c4c6b
+            }
9c4c6b
+        }
9c4c6b
+
9c4c6b
+        /* Read the token flags and accept some of them as context flags. */
9c4c6b
+        token_flags = k5_input_get_uint32_le(&in);
9c4c6b
+        *flags_out = token_flags & INITIATOR_FLAGS;
9c4c6b
+
9c4c6b
+        /* Read the delegated credential if present. */
9c4c6b
+        if (in.len >= 4 && (token_flags & GSS_C_DELEG_FLAG)) {
9c4c6b
+            option_id = k5_input_get_uint16_le(&in);
9c4c6b
+            option_len = k5_input_get_uint16_le(&in);
9c4c6b
+            option_bytes = k5_input_get_bytes(&in, option_len);
9c4c6b
+            option = make_data((uint8_t *)option_bytes, option_len);
9c4c6b
+            if (in.status) {
9c4c6b
+                code = KG_BAD_LENGTH;
9c4c6b
+                status = GSS_S_FAILURE;
9c4c6b
+                goto fail;
9c4c6b
+            }
9c4c6b
+            if (option_id != KRB5_GSS_FOR_CREDS_OPTION) {
9c4c6b
+                status = GSS_S_FAILURE;
9c4c6b
+                goto fail;
9c4c6b
+            }
9c4c6b
+
9c4c6b
+            /* Store the delegated credential. */
9c4c6b
+            code = rd_and_store_for_creds(context, auth_context, &option,
9c4c6b
+                                          deleg_out);
9c4c6b
+            if (code) {
9c4c6b
+                status = GSS_S_FAILURE;
9c4c6b
+                goto fail;
9c4c6b
+            }
9c4c6b
+            *flags_out |= GSS_C_DELEG_FLAG;
9c4c6b
+        }
9c4c6b
+
9c4c6b
+        /* Process any extensions at the end of the checksum.  Extensions use
9c4c6b
+         * 4-byte big-endian tag and length instead of 2-byte little-endian. */
9c4c6b
+        while (in.len > 0) {
9c4c6b
+            option_id = k5_input_get_uint32_be(&in);
9c4c6b
+            option_len = k5_input_get_uint32_be(&in);
9c4c6b
+            option_bytes = k5_input_get_bytes(&in, option_len);
9c4c6b
+            option = make_data((uint8_t *)option_bytes, option_len);
9c4c6b
+            if (in.status) {
9c4c6b
+                code = KG_BAD_LENGTH;
9c4c6b
+                status = GSS_S_FAILURE;
9c4c6b
+                goto fail;
9c4c6b
+            }
9c4c6b
+
9c4c6b
+            code = kg_process_extension(context, auth_context, option_id,
9c4c6b
+                                        &option, exts);
9c4c6b
+            if (code) {
9c4c6b
+                status = GSS_S_FAILURE;
9c4c6b
+                goto fail;
9c4c6b
+            }
9c4c6b
+        }
9c4c6b
+    }
9c4c6b
+
9c4c6b
+    status = GSS_S_COMPLETE;
9c4c6b
+
9c4c6b
+fail:
9c4c6b
+    free(cb_cksum.contents);
9c4c6b
+    *code_out = code;
9c4c6b
+    return status;
9c4c6b
+}
9c4c6b
+
9c4c6b
 static OM_uint32
9c4c6b
 kg_accept_krb5(minor_status, context_handle,
9c4c6b
                verifier_cred_handle, input_token,
9c4c6b
@@ -433,17 +602,13 @@ kg_accept_krb5(minor_status, context_handle,
9c4c6b
     krb5_gss_ctx_ext_t exts;
9c4c6b
 {
9c4c6b
     krb5_context context;
9c4c6b
-    unsigned char *ptr, *ptr2;
9c4c6b
+    unsigned char *ptr;
9c4c6b
     char *sptr;
9c4c6b
-    OM_uint32 tmp;
9c4c6b
-    size_t md5len;
9c4c6b
     krb5_gss_cred_id_t cred = 0;
9c4c6b
     krb5_data ap_rep, ap_req;
9c4c6b
-    unsigned int i;
9c4c6b
     krb5_error_code code;
9c4c6b
     krb5_address addr, *paddr;
9c4c6b
     krb5_authenticator *authdat = 0;
9c4c6b
-    krb5_checksum reqcksum;
9c4c6b
     krb5_gss_name_t name = NULL;
9c4c6b
     krb5_ui_4 gss_flags = 0;
9c4c6b
     krb5_gss_ctx_id_rec *ctx = NULL;
9c4c6b
@@ -451,8 +616,6 @@ kg_accept_krb5(minor_status, context_handle,
9c4c6b
     gss_buffer_desc token;
9c4c6b
     krb5_auth_context auth_context = NULL;
9c4c6b
     krb5_ticket * ticket = NULL;
9c4c6b
-    int option_id;
9c4c6b
-    krb5_data option;
9c4c6b
     const gss_OID_desc *mech_used = NULL;
9c4c6b
     OM_uint32 major_status = GSS_S_FAILURE;
9c4c6b
     OM_uint32 tmp_minor_status;
9c4c6b
@@ -463,7 +626,6 @@ kg_accept_krb5(minor_status, context_handle,
9c4c6b
     krb5int_access kaccess;
9c4c6b
     int cred_rcache = 0;
9c4c6b
     int no_encap = 0;
9c4c6b
-    int token_deleg_flag = 0;
9c4c6b
     krb5_flags ap_req_options = 0;
9c4c6b
     krb5_enctype negotiated_etype;
9c4c6b
     krb5_authdata_context ad_context = NULL;
9c4c6b
@@ -489,7 +651,6 @@ kg_accept_krb5(minor_status, context_handle,
9c4c6b
     output_token->length = 0;
9c4c6b
     output_token->value = NULL;
9c4c6b
     token.value = 0;
9c4c6b
-    reqcksum.contents = 0;
9c4c6b
     ap_req.data = 0;
9c4c6b
     ap_rep.data = 0;
9c4c6b
 
9c4c6b
@@ -654,195 +815,16 @@ kg_accept_krb5(minor_status, context_handle,
9c4c6b
 
9c4c6b
     krb5_auth_con_getauthenticator(context, auth_context, &authdat);
9c4c6b
 
9c4c6b
-    if (authdat->checksum == NULL) {
9c4c6b
-        /*
9c4c6b
-         * Some SMB client implementations use handcrafted GSSAPI code that
9c4c6b
-         * does not provide a checksum.  MS-KILE documents that the Microsoft
9c4c6b
-         * implementation considers a missing checksum acceptable; the server
9c4c6b
-         * assumes all flags are unset in this case, and does not check channel
9c4c6b
-         * bindings.
9c4c6b
-         */
9c4c6b
-        gss_flags = 0;
9c4c6b
-    } else if (authdat->checksum->checksum_type != CKSUMTYPE_KG_CB) {
9c4c6b
-        /* Samba does not send 0x8003 GSS-API checksums */
9c4c6b
-        krb5_boolean valid;
9c4c6b
-        krb5_key subkey;
9c4c6b
-        krb5_data zero;
9c4c6b
+    major_status = process_checksum(minor_status, context, input_chan_bindings,
9c4c6b
+                                    auth_context, ap_req_options,
9c4c6b
+                                    authdat, exts,
9c4c6b
+                                    delegated_cred_handle ? &deleg_cred : NULL,
9c4c6b
+                                    &gss_flags, &code);
9c4c6b
 
9c4c6b
-        code = krb5_auth_con_getkey_k(context, auth_context, &subkey);
9c4c6b
-        if (code) {
9c4c6b
-            major_status = GSS_S_FAILURE;
9c4c6b
-            goto fail;
9c4c6b
-        }
9c4c6b
+    if (major_status != GSS_S_COMPLETE)
9c4c6b
+        goto fail;
9c4c6b
 
9c4c6b
-        zero.length = 0;
9c4c6b
-        zero.data = "";
9c4c6b
-
9c4c6b
-        code = krb5_k_verify_checksum(context,
9c4c6b
-                                      subkey,
9c4c6b
-                                      KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
9c4c6b
-                                      &zero,
9c4c6b
-                                      authdat->checksum,
9c4c6b
-                                      &valid);
9c4c6b
-        krb5_k_free_key(context, subkey);
9c4c6b
-        if (code || !valid) {
9c4c6b
-            major_status = GSS_S_BAD_SIG;
9c4c6b
-            goto fail;
9c4c6b
-        }
9c4c6b
-
9c4c6b
-        /* Use ap_options from the request to guess the mutual flag. */
9c4c6b
-        gss_flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
9c4c6b
-        if (ap_req_options & AP_OPTS_MUTUAL_REQUIRED)
9c4c6b
-            gss_flags |= GSS_C_MUTUAL_FLAG;
9c4c6b
-    } else {
9c4c6b
-        /* gss krb5 v1 */
9c4c6b
-
9c4c6b
-        /* stash this now, for later. */
9c4c6b
-        code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &md5len);
9c4c6b
-        if (code) {
9c4c6b
-            major_status = GSS_S_FAILURE;
9c4c6b
-            goto fail;
9c4c6b
-        }
9c4c6b
-
9c4c6b
-        /* verify that the checksum is correct */
9c4c6b
-
9c4c6b
-        /*
9c4c6b
-          The checksum may be either exactly 24 bytes, in which case
9c4c6b
-          no options are specified, or greater than 24 bytes, in which case
9c4c6b
-          one or more options are specified. Currently, the only valid
9c4c6b
-          option is KRB5_GSS_FOR_CREDS_OPTION ( = 1 ).
9c4c6b
-        */
9c4c6b
-
9c4c6b
-        if ((authdat->checksum->checksum_type != CKSUMTYPE_KG_CB) ||
9c4c6b
-            (authdat->checksum->length < 24)) {
9c4c6b
-            code = 0;
9c4c6b
-            major_status = GSS_S_BAD_BINDINGS;
9c4c6b
-            goto fail;
9c4c6b
-        }
9c4c6b
-
9c4c6b
-        ptr = (unsigned char *) authdat->checksum->contents;
9c4c6b
-
9c4c6b
-        TREAD_INT(ptr, tmp, 0);
9c4c6b
-
9c4c6b
-        if (tmp != md5len) {
9c4c6b
-            code = KG_BAD_LENGTH;
9c4c6b
-            major_status = GSS_S_FAILURE;
9c4c6b
-            goto fail;
9c4c6b
-        }
9c4c6b
-
9c4c6b
-        /*
9c4c6b
-          The following section of code attempts to implement the
9c4c6b
-          optional channel binding facility as described in RFC2743.
9c4c6b
-
9c4c6b
-          Since this facility is optional channel binding may or may
9c4c6b
-          not have been provided by either the client or the server.
9c4c6b
-
9c4c6b
-          If the server has specified input_chan_bindings equal to
9c4c6b
-          GSS_C_NO_CHANNEL_BINDINGS then we skip the check.  If
9c4c6b
-          the server does provide channel bindings then we compute
9c4c6b
-          a checksum and compare against those provided by the
9c4c6b
-          client.         */
9c4c6b
-
9c4c6b
-        if ((code = kg_checksum_channel_bindings(context,
9c4c6b
-                                                 input_chan_bindings,
9c4c6b
-                                                 &reqcksum))) {
9c4c6b
-            major_status = GSS_S_BAD_BINDINGS;
9c4c6b
-            goto fail;
9c4c6b
-        }
9c4c6b
-
9c4c6b
-        /* Always read the clients bindings - eventhough we might ignore them */
9c4c6b
-        TREAD_STR(ptr, ptr2, reqcksum.length);
9c4c6b
-
9c4c6b
-        if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS ) {
9c4c6b
-            if (memcmp(ptr2, reqcksum.contents, reqcksum.length) != 0) {
9c4c6b
-                xfree(reqcksum.contents);
9c4c6b
-                reqcksum.contents = 0;
9c4c6b
-                code = 0;
9c4c6b
-                major_status = GSS_S_BAD_BINDINGS;
9c4c6b
-                goto fail;
9c4c6b
-            }
9c4c6b
-
9c4c6b
-        }
9c4c6b
-
9c4c6b
-        xfree(reqcksum.contents);
9c4c6b
-        reqcksum.contents = 0;
9c4c6b
-
9c4c6b
-        /* Read the token flags.  Remember if GSS_C_DELEG_FLAG was set, but
9c4c6b
-         * mask it out until we actually read a delegated credential. */
9c4c6b
-        TREAD_INT(ptr, gss_flags, 0);
9c4c6b
-        token_deleg_flag = (gss_flags & GSS_C_DELEG_FLAG);
9c4c6b
-        gss_flags &= ~GSS_C_DELEG_FLAG;
9c4c6b
-
9c4c6b
-        /* if the checksum length > 24, there are options to process */
9c4c6b
-
9c4c6b
-        i = authdat->checksum->length - 24;
9c4c6b
-        if (i && token_deleg_flag) {
9c4c6b
-            if (i >= 4) {
9c4c6b
-                TREAD_INT16(ptr, option_id, 0);
9c4c6b
-                TREAD_INT16(ptr, option.length, 0);
9c4c6b
-                i -= 4;
9c4c6b
-
9c4c6b
-                if (i < option.length) {
9c4c6b
-                    code = KG_BAD_LENGTH;
9c4c6b
-                    major_status = GSS_S_FAILURE;
9c4c6b
-                    goto fail;
9c4c6b
-                }
9c4c6b
-
9c4c6b
-                /* have to use ptr2, since option.data is wrong type and
9c4c6b
-                   macro uses ptr as both lvalue and rvalue */
9c4c6b
-
9c4c6b
-                TREAD_STR(ptr, ptr2, option.length);
9c4c6b
-                option.data = (char *) ptr2;
9c4c6b
-
9c4c6b
-                i -= option.length;
9c4c6b
-
9c4c6b
-                if (option_id != KRB5_GSS_FOR_CREDS_OPTION) {
9c4c6b
-                    major_status = GSS_S_FAILURE;
9c4c6b
-                    goto fail;
9c4c6b
-                }
9c4c6b
-
9c4c6b
-                /* store the delegated credential */
9c4c6b
-
9c4c6b
-                code = rd_and_store_for_creds(context, auth_context, &option,
9c4c6b
-                                              (delegated_cred_handle) ?
9c4c6b
-                                              &deleg_cred : NULL);
9c4c6b
-                if (code) {
9c4c6b
-                    major_status = GSS_S_FAILURE;
9c4c6b
-                    goto fail;
9c4c6b
-                }
9c4c6b
-
9c4c6b
-                gss_flags |= GSS_C_DELEG_FLAG;
9c4c6b
-            } /* if i >= 4 */
9c4c6b
-            /* ignore any additional trailing data, for now */
9c4c6b
-        }
9c4c6b
-        while (i > 0) {
9c4c6b
-            /* Process Type-Length-Data options */
9c4c6b
-            if (i < 8) {
9c4c6b
-                code = KG_BAD_LENGTH;
9c4c6b
-                major_status = GSS_S_FAILURE;
9c4c6b
-                goto fail;
9c4c6b
-            }
9c4c6b
-            TREAD_INT(ptr, option_id, 1);
9c4c6b
-            TREAD_INT(ptr, option.length, 1);
9c4c6b
-            i -= 8;
9c4c6b
-            if (i < option.length) {
9c4c6b
-                code = KG_BAD_LENGTH;
9c4c6b
-                major_status = GSS_S_FAILURE;
9c4c6b
-                goto fail;
9c4c6b
-            }
9c4c6b
-            TREAD_STR(ptr, ptr2, option.length);
9c4c6b
-            option.data = (char *)ptr2;
9c4c6b
-
9c4c6b
-            i -= option.length;
9c4c6b
-
9c4c6b
-            code = kg_process_extension(context, auth_context,
9c4c6b
-                                        option_id, &option, exts);
9c4c6b
-            if (code != 0) {
9c4c6b
-                major_status = GSS_S_FAILURE;
9c4c6b
-                goto fail;
9c4c6b
-            }
9c4c6b
-        }
9c4c6b
-    }
9c4c6b
+    major_status = GSS_S_FAILURE;
9c4c6b
 
9c4c6b
     if (exts->iakerb.conv && !exts->iakerb.verified) {
9c4c6b
         major_status = GSS_S_BAD_SIG;
9c4c6b
@@ -869,12 +851,7 @@ kg_accept_krb5(minor_status, context_handle,
9c4c6b
     ctx->mech_used = (gss_OID) mech_used;
9c4c6b
     ctx->auth_context = auth_context;
9c4c6b
     ctx->initiate = 0;
9c4c6b
-    ctx->gss_flags = (GSS_C_TRANS_FLAG |
9c4c6b
-                      ((gss_flags) & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |
9c4c6b
-                                      GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
9c4c6b
-                                      GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG |
9c4c6b
-                                      GSS_C_DCE_STYLE | GSS_C_IDENTIFY_FLAG |
9c4c6b
-                                      GSS_C_EXTENDED_ERROR_FLAG)));
9c4c6b
+    ctx->gss_flags = gss_flags | GSS_C_TRANS_FLAG;
9c4c6b
     ctx->seed_init = 0;
9c4c6b
     ctx->cred_rcache = cred_rcache;
9c4c6b
 
9c4c6b
@@ -1161,8 +1138,6 @@ fail:
9c4c6b
 
9c4c6b
         krb5_auth_con_free(context, auth_context);
9c4c6b
     }
9c4c6b
-    if (reqcksum.contents)
9c4c6b
-        xfree(reqcksum.contents);
9c4c6b
     if (ap_rep.data)
9c4c6b
         krb5_free_data_contents(context, &ap_rep);
9c4c6b
     if (major_status == GSS_S_COMPLETE ||