X-Original-To: alpine-aports@mail.alpinelinux.org Delivered-To: alpine-aports@mail.alpinelinux.org Received: from mail.alpinelinux.org (dallas-a1.alpinelinux.org [127.0.0.1]) by mail.alpinelinux.org (Postfix) with ESMTP id 46791DC0422 for ; Tue, 1 Dec 2015 22:17:30 +0000 (UTC) Received: from mail-wm0-f50.google.com (mail-wm0-f50.google.com [74.125.82.50]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (No client certificate requested) by mail.alpinelinux.org (Postfix) with ESMTPS id A1001DC010D for ; Tue, 1 Dec 2015 22:17:28 +0000 (UTC) Received: by wmuu63 with SMTP id u63so192028640wmu.0 for ; Tue, 01 Dec 2015 14:17:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kampka-net.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :content-type; bh=Rn6XPbyC7hBM9uULpZxc3LwmxSU4+1ZBeLtHHwZC8bI=; b=oNB3NQZHGSdsiCIJZEnxXOw8IE5M2dU43glygOtWcZGryCCjtbSeCbYa9+7KMONWV6 e1Q+Q3A0VcdxuQCshEtJWp2YCnD+rDsEjW4vpS+eLap2gzXVMQjsehGgzwKaENps1aaX lS7W5cZqNMPdEfagBDoxdbc37V46ueNNI8YiTRan/n/7gmFyvADsyFu7a4FalYVFDfjt j9170aCAsJ6HPEfVNPFvizNmvrgX2Vnzo/rI0aplf/ERLOI8DEVVza8gXS56hMfIzIMH xXWYtJAdkoIcqCrver25jJJg2sc9aaOcexU/m9wb6/h+6Ou0kCehkjBwGDyL1IHqJnzH 3bfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:content-type; bh=Rn6XPbyC7hBM9uULpZxc3LwmxSU4+1ZBeLtHHwZC8bI=; b=F80/EsxmtB9az3cxuqUgYn5DF0aQeFRfkdsKqgWDLSlcRrDWwbI2r5N63Ed0fzGC5Y sDzoLq5HSyOL2mqvaTOOQZVWvyQVm0MNAuyBI9q/CnjPvUBx9g+Z0m0C5ig1Xyb5l9Qt whGEweV5JqJjSAXQByJBlUiyR58+FQqXFi5sXbRz+Ce8idM2rJjf03nGHS/SpqoH+jvm LyR5dc4d1d/+sCO7Z7vAownoN7XR/vug+GHbLd195QXed1PoI+Jr324B0aJ2DXytLvuD e8oo8DNClPexnHoSiSc0lDqXo0seVFtG8E3B4EdwZ2KRixGrtv0goJQGrj+qIHWGwVXf Y3wQ== X-Gm-Message-State: ALoCoQlaRhOb+Jv+Ec3mYfbGP2I2Vrkqlxe/uxo/FlRYYjL5e0fP/umVTN81LcM/pTT1mu7BJP6n X-Received: by 10.28.224.86 with SMTP id x83mr753575wmg.36.1449008246982; Tue, 01 Dec 2015 14:17:26 -0800 (PST) X-Mailinglist: alpine-aports Precedence: list List-Id: Alpine Development List-Unsubscribe: List-Post: List-Help: List-Subscribe: MIME-Version: 1.0 References: <1449008076-25870-1-git-send-email-christian@kampka.net> In-Reply-To: <1449008076-25870-1-git-send-email-christian@kampka.net> From: Christian Kampka Date: Tue, 01 Dec 2015 22:17:17 +0000 Message-ID: Subject: [alpine-aports] Re: [PATCH] main/krb5: security fixes (CVE-2015-2694, CVE-2015-2695, CVE-2015-2696, CVE-2015-2697) To: alpine-aports@lists.alpinelinux.org Content-Type: multipart/alternative; boundary=001a114b0964d6bd3d0525dd8580 X-Virus-Scanned: ClamAV using ClamSMTP --001a114b0964d6bd3d0525dd8580 Content-Type: text/plain; charset=UTF-8 This patch applies against against the 3.2-stable branch. Christian Kampka schrieb am Di., 1. Dez. 2015 um 23:14 Uhr: > fixes: #4836 > --- > main/krb5/APKBUILD | 18 +- > main/krb5/CVE-2015-2694.patch | 101 ++++++ > main/krb5/CVE-2015-2695.patch | 564 ++++++++++++++++++++++++++++++++ > main/krb5/CVE-2015-2696.patch | 731 > ++++++++++++++++++++++++++++++++++++++++++ > main/krb5/CVE-2015-2697.patch | 50 +++ > 5 files changed, 1463 insertions(+), 1 deletion(-) > create mode 100644 main/krb5/CVE-2015-2694.patch > create mode 100644 main/krb5/CVE-2015-2695.patch > create mode 100644 main/krb5/CVE-2015-2696.patch > create mode 100644 main/krb5/CVE-2015-2697.patch > > diff --git a/main/krb5/APKBUILD b/main/krb5/APKBUILD > index d3ddfc9..fef6004 100644 > --- a/main/krb5/APKBUILD > +++ b/main/krb5/APKBUILD > @@ -1,7 +1,7 @@ > # Maintainer: Natanael Copa > pkgname=krb5 > pkgver=1.13.1 > -pkgrel=1 > +pkgrel=2 > > case $pkgver in > *.*.*) _ver=${pkgver%.*};; > @@ -22,6 +22,10 @@ subpackages="$pkgname-dev $pkgname-doc $pkgname-server > $pkgname-server-ldap:ldap $pkgname-pkinit $pkgname-libs" > source=" > http://web.mit.edu/kerberos/dist/krb5/${_ver}/krb5-$pkgver-signed.tar > mit-krb5_krb5-config_LDFLAGS.patch > + CVE-2015-2694.patch > + CVE-2015-2695.patch > + CVE-2015-2696.patch > + CVE-2015-2697.patch > > krb5kadmind.initd > krb5kdc.initd > @@ -120,16 +124,28 @@ libs() { > > md5sums="567586cdf02aa8c842c2fab7a94f3c1f krb5-1.13.1-signed.tar > c84a0c7d8014e3528524956ffdd1c3e9 mit-krb5_krb5-config_LDFLAGS.patch > +98d4792ff9576efab658be312ef7623f CVE-2015-2694.patch > +ca73fdd31a2d5c38993afbed909b5417 CVE-2015-2695.patch > +dc4c2a99b5b8a9bf7b306d614134c267 CVE-2015-2696.patch > +a2369d91ccef67f093af594d941ebc11 CVE-2015-2697.patch > 9c0e3bac122326cdbbbac068056ee8af krb5kadmind.initd > 71131479c07a2d89b30a2ea18dd64e74 krb5kdc.initd > d94873a6a1ac6277adf2d25458eda9e5 krb5kpropd.initd" > sha256sums="4df629fdf97f362cf81edbf38d613b32b492dd88c876cf3aa1c66562f296663e > krb5-1.13.1-signed.tar > 84007c7423f67db7a8b248b9643c49ef25f2d56ce15c2574eb41ecbf51bcd3f2 > mit-krb5_krb5-config_LDFLAGS.patch > +f3710f2f90542145a8921dc7c2b8241d8fdeccdcba3d50b1758aa0e2f8aeec73 > CVE-2015-2694.patch > +b83dd0714f1ab164f6eb50d173bec25bb851c739ed5b1c38b35e7a1910cff25b > CVE-2015-2695.patch > +add426d86d31c57dc8e1c1d9043f61c21f2e532e728d1d9c703b2616bf246d7c > CVE-2015-2696.patch > +e1d3d6a0dfede9d5a4af83d51c4f5fad13e917e4cb58672ff0ee3e8f34fe0379 > CVE-2015-2697.patch > 213a5b04f091e4644e856aabc38da586bd86c4616ab15f00eefca52fca7137d6 > krb5kadmind.initd > 577842c7fe4639a8e9dd349da40e514284dd53440bb71be58283faaf18508f9a > krb5kdc.initd > 1644639d83791bd871f3c89a53a7052ab52994d3ef03d1d675d4217130c1fa94 > krb5kpropd.initd" > sha512sums="f26dce8f682bd3fbf38a15df5f91722b573d4df4cc193f7ba8dc369cbbee8f4bc2a72f56513d2cf27697ce8baaf954afe04e3eefc15c2883fa1d5260145aef6e > krb5-1.13.1-signed.tar > 5a3782ff17b383f8cd0415fd13538ab56afd788130d6ad640e9f2682b7deaae7f25713ce358058ed771091040dccf62a3bc87e6fd473d505ec189a95debcc801 > mit-krb5_krb5-config_LDFLAGS.patch > +0c8ab8a1d6bfa31b3257c1ac4f99d9c14d4f8ed0c27da0e648f64e9e5e5717ca5d929def6fd1f04903b287786add4a93e8f1c1f96cea14d123c1574c174a532a > CVE-2015-2694.patch > +4e1499d799bed90b2857d24de29ea3bb7500b514a86c2a8f4596fb80f97f01445b7dd9d0cb19c1cfb1f03f5c6a8e2a2149a6278c720933181db8e188063dcc6a > CVE-2015-2695.patch > +d27e836a3e8a1ca6b711c0ce4f9f68cbd42d888cb9dcaf2dcb78fdc9ca7652865c124e14c7026b4e94a722a314a0c30f732cc00344973ee5a180f11901347ed1 > CVE-2015-2696.patch > +5f6a630b566c9f0cb02528fca3a789547e294acf5f3435eb62b79411187e4fcaaa58b81eff34e8ac6cbca3dacb076bd626a31687c04936b35bf7ab3e35965a31 > CVE-2015-2697.patch > 43b9885b7eb8d0d60920def688de482f2b1701288f9acb1bb21dc76b2395428ff304961959eb04ba5eafd0412bae35668d6d2c8223424b9337bc051eadf51682 > krb5kadmind.initd > ede15f15bbbc9d0227235067abe15245bb9713aea260d397379c63275ce74aea0db6c91c15d599e40c6e89612d76f3a0f8fdd21cbafa3f30d426d4310d3e2cec > krb5kdc.initd > 45be0d421efd41e9dd056125a750c90856586e990317456b68170d733b03cba9ecd18ab87603b20e49575e7839fb4a6d628255533f2631f9e8ddb7f3cc493a90 > krb5kpropd.initd" > diff --git a/main/krb5/CVE-2015-2694.patch b/main/krb5/CVE-2015-2694.patch > new file mode 100644 > index 0000000..6154965 > --- /dev/null > +++ b/main/krb5/CVE-2015-2694.patch > @@ -0,0 +1,101 @@ > +From df8afc60d970a7176a55ffe7ce21cfd57ba423cd Mon Sep 17 00:00:00 2001 > +From: Greg Hudson > +Date: Tue, 24 Mar 2015 12:02:37 -0400 > +Subject: [PATCH] Prevent requires_preauth bypass [CVE-2015-2694] > + > +In the OTP kdcpreauth module, don't set the TKT_FLG_PRE_AUTH bit until > +the request is successfully verified. In the PKINIT kdcpreauth > +module, don't respond with code 0 on empty input or an unconfigured > +realm. Together these bugs could cause the KDC preauth framework to > +erroneously treat a request as pre-authenticated. > + > +CVE-2015-2694: > + > +In MIT krb5 1.12 and later, when the KDC is configured with PKINIT > +support, an unauthenticated remote attacker can bypass the > +requires_preauth flag on a client principal and obtain a ciphertext > +encrypted in the principal's long-term key. This ciphertext could be > +used to conduct an off-line dictionary attack against the user's > +password. > + > + CVSSv2 Vector: AV:N/AC:M/Au:N/C:P/I:P/A:N/E:POC/RL:OF/RC:C > + > +(cherry picked from commit e3b5a5e5267818c97750b266df50b6a3d4649604) > + > +ticket: 8160 > +version_fixed: 1.13.2 > +status: resolved > +--- > + src/plugins/preauth/otp/main.c | 10 +++++++--- > + src/plugins/preauth/pkinit/pkinit_srv.c | 4 ++-- > + 2 files changed, 9 insertions(+), 5 deletions(-) > + > +diff --git a/src/plugins/preauth/otp/main.c > b/src/plugins/preauth/otp/main.c > +index bf9c6a8..7941b4a 100644 > +--- a/src/plugins/preauth/otp/main.c > ++++ b/src/plugins/preauth/otp/main.c > +@@ -42,6 +42,7 @@ static krb5_preauthtype otp_pa_type_list[] = > + struct request_state { > + krb5_kdcpreauth_verify_respond_fn respond; > + void *arg; > ++ krb5_enc_tkt_part *enc_tkt_reply; > + }; > + > + static krb5_error_code > +@@ -159,6 +160,9 @@ on_response(void *data, krb5_error_code retval, > otp_response response) > + if (retval == 0 && response != otp_response_success) > + retval = KRB5_PREAUTH_FAILED; > + > ++ if (retval == 0) > ++ rs.enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; > ++ > + rs.respond(rs.arg, retval, NULL, NULL, NULL); > + } > + > +@@ -263,8 +267,6 @@ otp_verify(krb5_context context, krb5_data *req_pkt, > krb5_kdc_req *request, > + krb5_data d, plaintext; > + char *config; > + > +- enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; > +- > + /* Get the FAST armor key. */ > + armor_key = cb->fast_armor(context, rock); > + if (armor_key == NULL) { > +@@ -298,12 +300,14 @@ otp_verify(krb5_context context, krb5_data > *req_pkt, krb5_kdc_req *request, > + goto error; > + } > + > +- /* Create the request state. */ > ++ /* Create the request state. Save the response callback, and the > ++ * enc_tkt_reply pointer so we can set the TKT_FLG_PRE_AUTH flag > later. */ > + rs = k5alloc(sizeof(struct request_state), &retval); > + if (rs == NULL) > + goto error; > + rs->arg = arg; > + rs->respond = respond; > ++ rs->enc_tkt_reply = enc_tkt_reply; > + > + /* Get the principal's OTP configuration string. */ > + retval = cb->get_string(context, rock, "otp", &config); > +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c > b/src/plugins/preauth/pkinit/pkinit_srv.c > +index 5639fca..edfce6f 100644 > +--- a/src/plugins/preauth/pkinit/pkinit_srv.c > ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c > +@@ -301,7 +301,7 @@ pkinit_server_verify_padata(krb5_context context, > + > + pkiDebug("pkinit_verify_padata: entered!\n"); > + if (data == NULL || data->length <= 0 || data->contents == NULL) { > +- (*respond)(arg, 0, NULL, NULL, NULL); > ++ (*respond)(arg, EINVAL, NULL, NULL, NULL); > + return; > + } > + > +@@ -313,7 +313,7 @@ pkinit_server_verify_padata(krb5_context context, > + > + plgctx = pkinit_find_realm_context(context, moddata, > request->server); > + if (plgctx == NULL) { > +- (*respond)(arg, 0, NULL, NULL, NULL); > ++ (*respond)(arg, EINVAL, NULL, NULL, NULL); > + return; > + } > + > diff --git a/main/krb5/CVE-2015-2695.patch b/main/krb5/CVE-2015-2695.patch > new file mode 100644 > index 0000000..08bc8ab > --- /dev/null > +++ b/main/krb5/CVE-2015-2695.patch > @@ -0,0 +1,564 @@ > +From b51b33f2bc5d1497ddf5bd107f791c101695000d Mon Sep 17 00:00:00 2001 > +From: Nicolas Williams > +Date: Mon, 14 Sep 2015 12:27:52 -0400 > +Subject: [PATCH] Fix SPNEGO context aliasing bugs [CVE-2015-2695] > + > +The SPNEGO mechanism currently replaces its context handle with the > +mechanism context handle upon establishment, under the assumption that > +most GSS functions are only called after context establishment. This > +assumption is incorrect, and can lead to aliasing violations for some > +programs. Maintain the SPNEGO context structure after context > +establishment and refer to it in all GSS methods. Add initiate and > +opened flags to the SPNEGO context structure for use in > +gss_inquire_context() prior to context establishment. > + > +CVE-2015-2695: > + > +In MIT krb5 1.5 and later, applications which call > +gss_inquire_context() on a partially-established SPNEGO context can > +cause the GSS-API library to read from a pointer using the wrong type, > +generally causing a process crash. This bug may go unnoticed, because > +the most common SPNEGO authentication scenario establishes the context > +after just one call to gss_accept_sec_context(). Java server > +applications using the native JGSS provider are vulnerable to this > +bug. A carefully crafted SPNEGO packet might allow the > +gss_inquire_context() call to succeed with attacker-determined > +results, but applications should not make access control decisions > +based on gss_inquire_context() results prior to context establishment. > + > + CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:C/E:POC/RL:OF/RC:C > + > +[ghudson@mit.edu: several bugfixes, style changes, and edge-case > +behavior changes; commit message and CVE description] > + > +ticket: 8244 > +target_version: 1.14 > +tags: pullup > +--- > + src/lib/gssapi/spnego/gssapiP_spnego.h | 2 + > + src/lib/gssapi/spnego/spnego_mech.c | 254 > ++++++++++++++++++++++++--------- > + 2 files changed, 192 insertions(+), 64 deletions(-) > + > +diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h > b/src/lib/gssapi/spnego/gssapiP_spnego.h > +index 57372de..5c82764 100644 > +--- a/src/lib/gssapi/spnego/gssapiP_spnego.h > ++++ b/src/lib/gssapi/spnego/gssapiP_spnego.h > +@@ -103,6 +103,8 @@ typedef struct { > + int firstpass; > + int mech_complete; > + int nego_done; > ++ int initiate; > ++ int opened; > + OM_uint32 ctx_flags; > + gss_name_t internal_name; > + gss_OID actual_mech; > +diff --git a/src/lib/gssapi/spnego/spnego_mech.c > b/src/lib/gssapi/spnego/spnego_mech.c > +index ef76e1f..7849c85 100644 > +--- a/src/lib/gssapi/spnego/spnego_mech.c > ++++ b/src/lib/gssapi/spnego/spnego_mech.c > +@@ -102,7 +102,7 @@ static OM_uint32 get_negotiable_mechs(OM_uint32 *, > spnego_gss_cred_id_t, > + gss_cred_usage_t, gss_OID_set *); > + static void release_spnego_ctx(spnego_gss_ctx_id_t *); > + static void check_spnego_options(spnego_gss_ctx_id_t); > +-static spnego_gss_ctx_id_t create_spnego_ctx(void); > ++static spnego_gss_ctx_id_t create_spnego_ctx(int); > + static int put_mech_set(gss_OID_set mechSet, gss_buffer_t buf); > + static int put_input_token(unsigned char **, gss_buffer_t, unsigned int); > + static int put_mech_oid(unsigned char **, gss_OID_const, unsigned int); > +@@ -454,7 +454,7 @@ check_spnego_options(spnego_gss_ctx_id_t spnego_ctx) > + } > + > + static spnego_gss_ctx_id_t > +-create_spnego_ctx(void) > ++create_spnego_ctx(int initiate) > + { > + spnego_gss_ctx_id_t spnego_ctx = NULL; > + spnego_ctx = (spnego_gss_ctx_id_t) > +@@ -477,6 +477,8 @@ create_spnego_ctx(void) > + spnego_ctx->mic_rcvd = 0; > + spnego_ctx->mech_complete = 0; > + spnego_ctx->nego_done = 0; > ++ spnego_ctx->opened = 0; > ++ spnego_ctx->initiate = initiate; > + spnego_ctx->internal_name = GSS_C_NO_NAME; > + spnego_ctx->actual_mech = GSS_C_NO_OID; > + > +@@ -642,7 +644,7 @@ init_ctx_new(OM_uint32 *minor_status, > + OM_uint32 ret; > + spnego_gss_ctx_id_t sc = NULL; > + > +- sc = create_spnego_ctx(); > ++ sc = create_spnego_ctx(1); > + if (sc == NULL) > + return GSS_S_FAILURE; > + > +@@ -659,10 +661,7 @@ init_ctx_new(OM_uint32 *minor_status, > + ret = GSS_S_FAILURE; > + goto cleanup; > + } > +- /* > +- * The actual context is not yet determined, set the output > +- * context handle to refer to the spnego context itself. > +- */ > ++ > + sc->ctx_handle = GSS_C_NO_CONTEXT; > + *ctx = (gss_ctx_id_t)sc; > + sc = NULL; > +@@ -1108,16 +1107,11 @@ spnego_gss_init_sec_context( > + } > + gss_release_buffer(&tmpmin, &mechtok_out); > + if (ret == GSS_S_COMPLETE) { > +- /* > +- * Now, switch the output context to refer to the > +- * negotiated mechanism's context. > +- */ > +- *context_handle = (gss_ctx_id_t)spnego_ctx->ctx_handle; > ++ spnego_ctx->opened = 1; > + if (actual_mech != NULL) > + *actual_mech = spnego_ctx->actual_mech; > + if (ret_flags != NULL) > + *ret_flags = spnego_ctx->ctx_flags; > +- release_spnego_ctx(&spnego_ctx); > + } else if (ret != GSS_S_CONTINUE_NEEDED) { > + if (spnego_ctx != NULL) { > + gss_delete_sec_context(&tmpmin, > +@@ -1285,7 +1279,7 @@ acc_ctx_hints(OM_uint32 *minor_status, > + if (ret != GSS_S_COMPLETE) > + goto cleanup; > + > +- sc = create_spnego_ctx(); > ++ sc = create_spnego_ctx(0); > + if (sc == NULL) { > + ret = GSS_S_FAILURE; > + goto cleanup; > +@@ -1367,7 +1361,7 @@ acc_ctx_new(OM_uint32 *minor_status, > + gss_release_buffer(&tmpmin, &sc->DER_mechTypes); > + assert(mech_wanted != GSS_C_NO_OID); > + } else > +- sc = create_spnego_ctx(); > ++ sc = create_spnego_ctx(0); > + if (sc == NULL) { > + ret = GSS_S_FAILURE; > + *return_token = NO_TOKEN_SEND; > +@@ -1750,13 +1744,12 @@ spnego_gss_accept_sec_context( > + ret = GSS_S_FAILURE; > + } > + if (ret == GSS_S_COMPLETE) { > +- *context_handle = (gss_ctx_id_t)sc->ctx_handle; > ++ sc->opened = 1; > + if (sc->internal_name != GSS_C_NO_NAME && > + src_name != NULL) { > + *src_name = sc->internal_name; > + sc->internal_name = GSS_C_NO_NAME; > + } > +- release_spnego_ctx(&sc); > + } else if (ret != GSS_S_CONTINUE_NEEDED) { > + if (sc != NULL) { > + gss_delete_sec_context(&tmpmin, &sc->ctx_handle, > +@@ -2069,8 +2062,13 @@ spnego_gss_unwrap( > + gss_qop_t *qop_state) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > + ret = gss_unwrap(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + input_message_buffer, > + output_message_buffer, > + conf_state, > +@@ -2090,8 +2088,13 @@ spnego_gss_wrap( > + gss_buffer_t output_message_buffer) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > + ret = gss_wrap(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + conf_req_flag, > + qop_req, > + input_message_buffer, > +@@ -2108,8 +2111,14 @@ spnego_gss_process_context_token( > + const gss_buffer_t token_buffer) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ /* SPNEGO doesn't have its own context tokens. */ > ++ if (!sc->opened) > ++ return (GSS_S_DEFECTIVE_TOKEN); > ++ > + ret = gss_process_context_token(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + token_buffer); > + > + return (ret); > +@@ -2133,19 +2142,9 @@ spnego_gss_delete_sec_context( > + if (*ctx == NULL) > + return (GSS_S_COMPLETE); > + > +- /* > +- * If this is still an SPNEGO mech, release it locally. > +- */ > +- if ((*ctx)->magic_num == SPNEGO_MAGIC_ID) { > +- (void) gss_delete_sec_context(minor_status, > +- &(*ctx)->ctx_handle, > +- output_token); > +- (void) release_spnego_ctx(ctx); > +- } else { > +- ret = gss_delete_sec_context(minor_status, > +- context_handle, > +- output_token); > +- } > ++ (void) gss_delete_sec_context(minor_status, &(*ctx)->ctx_handle, > ++ output_token); > ++ (void) release_spnego_ctx(ctx); > + > + return (ret); > + } > +@@ -2157,8 +2156,13 @@ spnego_gss_context_time( > + OM_uint32 *time_rec) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > + ret = gss_context_time(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + time_rec); > + return (ret); > + } > +@@ -2170,9 +2174,20 @@ spnego_gss_export_sec_context( > + gss_buffer_t interprocess_token) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = *(spnego_gss_ctx_id_t *)context_handle; > ++ > ++ /* We don't currently support exporting partially established > ++ * contexts. */ > ++ if (!sc->opened) > ++ return GSS_S_UNAVAILABLE; > ++ > + ret = gss_export_sec_context(minor_status, > +- context_handle, > ++ &sc->ctx_handle, > + interprocess_token); > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) { > ++ release_spnego_ctx(&sc); > ++ *context_handle = GSS_C_NO_CONTEXT; > ++ } > + return (ret); > + } > + > +@@ -2182,11 +2197,12 @@ spnego_gss_import_sec_context( > + const gss_buffer_t interprocess_token, > + gss_ctx_id_t *context_handle) > + { > +- OM_uint32 ret; > +- ret = gss_import_sec_context(minor_status, > +- interprocess_token, > +- context_handle); > +- return (ret); > ++ /* > ++ * Until we implement partial context exports, there are no SPNEGO > ++ * exported context tokens, only tokens for underlying mechs. So > just > ++ * return an error for now. > ++ */ > ++ return GSS_S_UNAVAILABLE; > + } > + #endif /* LEAN_CLIENT */ > + > +@@ -2203,16 +2219,48 @@ spnego_gss_inquire_context( > + int *opened) > + { > + OM_uint32 ret = GSS_S_COMPLETE; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (src_name != NULL) > ++ *src_name = GSS_C_NO_NAME; > ++ if (targ_name != NULL) > ++ *targ_name = GSS_C_NO_NAME; > ++ if (lifetime_rec != NULL) > ++ *lifetime_rec = 0; > ++ if (mech_type != NULL) > ++ *mech_type = (gss_OID)gss_mech_spnego; > ++ if (ctx_flags != NULL) > ++ *ctx_flags = 0; > ++ if (locally_initiated != NULL) > ++ *locally_initiated = sc->initiate; > ++ if (opened != NULL) > ++ *opened = sc->opened; > ++ > ++ if (sc->ctx_handle != GSS_C_NO_CONTEXT) { > ++ ret = gss_inquire_context(minor_status, sc->ctx_handle, > ++ src_name, targ_name, > lifetime_rec, > ++ mech_type, ctx_flags, NULL, > NULL); > ++ } > + > +- ret = gss_inquire_context(minor_status, > +- context_handle, > +- src_name, > +- targ_name, > +- lifetime_rec, > +- mech_type, > +- ctx_flags, > +- locally_initiated, > +- opened); > ++ if (!sc->opened) { > ++ /* > ++ * We are still doing SPNEGO negotiation, so report SPNEGO > as > ++ * the OID. After negotiation is complete we will report > the > ++ * underlying mechanism OID. > ++ */ > ++ if (mech_type != NULL) > ++ *mech_type = (gss_OID)gss_mech_spnego; > ++ > ++ /* > ++ * Remove flags we don't support with partially-established > ++ * contexts. (Change this to keep GSS_C_TRANS_FLAG if we > add > ++ * support for exporting partial SPNEGO contexts.) > ++ */ > ++ if (ctx_flags != NULL) { > ++ *ctx_flags &= ~GSS_C_PROT_READY_FLAG; > ++ *ctx_flags &= ~GSS_C_TRANS_FLAG; > ++ } > ++ } > + > + return (ret); > + } > +@@ -2227,8 +2275,13 @@ spnego_gss_wrap_size_limit( > + OM_uint32 *max_input_size) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > + ret = gss_wrap_size_limit(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + conf_req_flag, > + qop_req, > + req_output_size, > +@@ -2245,8 +2298,13 @@ spnego_gss_get_mic( > + gss_buffer_t message_token) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > + ret = gss_get_mic(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + qop_req, > + message_buffer, > + message_token); > +@@ -2262,8 +2320,13 @@ spnego_gss_verify_mic( > + gss_qop_t *qop_state) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > + ret = gss_verify_mic(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + msg_buffer, > + token_buffer, > + qop_state); > +@@ -2278,8 +2341,14 @@ spnego_gss_inquire_sec_context_by_oid( > + gss_buffer_set_t *data_set) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ /* There are no SPNEGO-specific OIDs for this function. */ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_UNAVAILABLE); > ++ > + ret = gss_inquire_sec_context_by_oid(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + desired_object, > + data_set); > + return (ret); > +@@ -2359,8 +2428,15 @@ spnego_gss_set_sec_context_option( > + const gss_buffer_t value) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)*context_handle; > ++ > ++ /* There are no SPNEGO-specific OIDs for this function, and we > cannot > ++ * construct an empty SPNEGO context with it. */ > ++ if (sc == NULL || sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_UNAVAILABLE); > ++ > + ret = gss_set_sec_context_option(minor_status, > +- context_handle, > ++ &sc->ctx_handle, > + desired_object, > + value); > + return (ret); > +@@ -2377,8 +2453,13 @@ spnego_gss_wrap_aead(OM_uint32 *minor_status, > + gss_buffer_t output_message_buffer) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > + ret = gss_wrap_aead(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + conf_req_flag, > + qop_req, > + input_assoc_buffer, > +@@ -2399,8 +2480,13 @@ spnego_gss_unwrap_aead(OM_uint32 *minor_status, > + gss_qop_t *qop_state) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > + ret = gss_unwrap_aead(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + input_message_buffer, > + input_assoc_buffer, > + output_payload_buffer, > +@@ -2419,8 +2505,13 @@ spnego_gss_wrap_iov(OM_uint32 *minor_status, > + int iov_count) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > + ret = gss_wrap_iov(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + conf_req_flag, > + qop_req, > + conf_state, > +@@ -2438,8 +2529,13 @@ spnego_gss_unwrap_iov(OM_uint32 *minor_status, > + int iov_count) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > + ret = gss_unwrap_iov(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + conf_state, > + qop_state, > + iov, > +@@ -2457,8 +2553,13 @@ spnego_gss_wrap_iov_length(OM_uint32 *minor_status, > + int iov_count) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > + ret = gss_wrap_iov_length(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + conf_req_flag, > + qop_req, > + conf_state, > +@@ -2475,8 +2576,13 @@ spnego_gss_complete_auth_token( > + gss_buffer_t input_message_buffer) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_UNAVAILABLE); > ++ > + ret = gss_complete_auth_token(minor_status, > +- context_handle, > ++ sc->ctx_handle, > + input_message_buffer); > + return (ret); > + } > +@@ -2721,8 +2827,13 @@ spnego_gss_pseudo_random(OM_uint32 *minor_status, > + gss_buffer_t prf_out) > + { > + OM_uint32 ret; > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > + ret = gss_pseudo_random(minor_status, > +- context, > ++ sc->ctx_handle, > + prf_key, > + prf_in, > + desired_output_len, > +@@ -2863,7 +2974,12 @@ spnego_gss_get_mic_iov(OM_uint32 *minor_status, > gss_ctx_id_t context_handle, > + gss_qop_t qop_req, gss_iov_buffer_desc *iov, > + int iov_count) > + { > +- return gss_get_mic_iov(minor_status, context_handle, qop_req, iov, > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > ++ return gss_get_mic_iov(minor_status, sc->ctx_handle, qop_req, iov, > + iov_count); > + } > + > +@@ -2872,7 +2988,12 @@ spnego_gss_verify_mic_iov(OM_uint32 *minor_status, > gss_ctx_id_t context_handle, > + gss_qop_t *qop_state, gss_iov_buffer_desc *iov, > + int iov_count) > + { > +- return gss_verify_mic_iov(minor_status, context_handle, qop_state, > iov, > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > ++ return gss_verify_mic_iov(minor_status, sc->ctx_handle, qop_state, > iov, > + iov_count); > + } > + > +@@ -2881,7 +3002,12 @@ spnego_gss_get_mic_iov_length(OM_uint32 > *minor_status, > + gss_ctx_id_t context_handle, gss_qop_t > qop_req, > + gss_iov_buffer_desc *iov, int iov_count) > + { > +- return gss_get_mic_iov_length(minor_status, context_handle, qop_req, > iov, > ++ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; > ++ > ++ if (sc->ctx_handle == GSS_C_NO_CONTEXT) > ++ return (GSS_S_NO_CONTEXT); > ++ > ++ return gss_get_mic_iov_length(minor_status, sc->ctx_handle, qop_req, > iov, > + iov_count); > + } > + > diff --git a/main/krb5/CVE-2015-2696.patch b/main/krb5/CVE-2015-2696.patch > new file mode 100644 > index 0000000..c1f50a5 > --- /dev/null > +++ b/main/krb5/CVE-2015-2696.patch > @@ -0,0 +1,731 @@ > +From e04f0283516e80d2f93366e0d479d13c9b5c8c2a Mon Sep 17 00:00:00 2001 > +From: Nicolas Williams > +Date: Mon, 14 Sep 2015 12:28:36 -0400 > +Subject: [PATCH] Fix IAKERB context aliasing bugs [CVE-2015-2696] > + > +The IAKERB mechanism currently replaces its context handle with the > +krb5 mechanism handle upon establishment, under the assumption that > +most GSS functions are only called after context establishment. This > +assumption is incorrect, and can lead to aliasing violations for some > +programs. Maintain the IAKERB context structure after context > +establishment and add new IAKERB entry points to refer to it with that > +type. Add initiate and established flags to the IAKERB context > +structure for use in gss_inquire_context() prior to context > +establishment. > + > +CVE-2015-2696: > + > +In MIT krb5 1.9 and later, applications which call > +gss_inquire_context() on a partially-established IAKERB context can > +cause the GSS-API library to read from a pointer using the wrong type, > +generally causing a process crash. Java server applications using the > +native JGSS provider are vulnerable to this bug. A carefully crafted > +IAKERB packet might allow the gss_inquire_context() call to succeed > +with attacker-determined results, but applications should not make > +access control decisions based on gss_inquire_context() results prior > +to context establishment. > + > + CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:C/E:POC/RL:OF/RC:C > + > +[ghudson@mit.edu: several bugfixes, style changes, and edge-case > +behavior changes; commit message and CVE description] > + > +ticket: 8244 > +target_version: 1.14 > +tags: pullup > +--- > + src/lib/gssapi/krb5/gssapiP_krb5.h | 114 ++++++++++++ > + src/lib/gssapi/krb5/gssapi_krb5.c | 105 +++++++++-- > + src/lib/gssapi/krb5/iakerb.c | 351 > +++++++++++++++++++++++++++++++++---- > + 3 files changed, 529 insertions(+), 41 deletions(-) > + > +diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h > b/src/lib/gssapi/krb5/gssapiP_krb5.h > +index 9aae12a..97e090d 100644 > +--- a/src/lib/gssapi/krb5/gssapiP_krb5.h > ++++ b/src/lib/gssapi/krb5/gssapiP_krb5.h > +@@ -621,6 +621,21 @@ OM_uint32 KRB5_CALLCONV > krb5_gss_accept_sec_context_ext > + ); > + #endif /* LEAN_CLIENT */ > + > ++OM_uint32 KRB5_CALLCONV krb5_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 */ > ++); > ++ > ++OM_uint32 KRB5_CALLCONV krb5_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 */ > ++); > ++ > + OM_uint32 KRB5_CALLCONV krb5_gss_process_context_token > + (OM_uint32*, /* minor_status */ > + gss_ctx_id_t, /* context_handle */ > +@@ -1302,6 +1317,105 @@ OM_uint32 KRB5_CALLCONV > + krb5_gss_import_cred(OM_uint32 *minor_status, gss_buffer_t token, > + gss_cred_id_t *cred_handle); > + > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_process_context_token(OM_uint32 *minor_status, > ++ const gss_ctx_id_t context_handle, > ++ const gss_buffer_t token_buffer); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_context_time(OM_uint32 *minor_status, gss_ctx_id_t > context_handle, > ++ OM_uint32 *time_rec); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_inquire_context(OM_uint32 *minor_status, > ++ 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 *opened); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_get_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handle, > ++ gss_qop_t qop_req, gss_buffer_t message_buffer, > ++ gss_buffer_t message_token); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t > context_handle, > ++ gss_qop_t qop_req, gss_iov_buffer_desc *iov, > ++ int iov_count); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_get_mic_iov_length(OM_uint32 *minor_status, > ++ gss_ctx_id_t context_handle, gss_qop_t > qop_req, > ++ gss_iov_buffer_desc *iov, int iov_count); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_verify_mic(OM_uint32 *minor_status, gss_ctx_id_t > context_handle, > ++ gss_buffer_t msg_buffer, gss_buffer_t token_buffer, > ++ gss_qop_t *qop_state); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t > context_handle, > ++ gss_qop_t *qop_state, gss_iov_buffer_desc *iov, > ++ int iov_count); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_wrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle, > ++ int conf_req_flag, gss_qop_t qop_req, > ++ gss_buffer_t input_message_buffer, int *conf_state, > ++ gss_buffer_t output_message_buffer); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_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); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_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); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_unwrap(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, > ++ gss_qop_t *qop_state); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_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); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_wrap_size_limit(OM_uint32 *minor_status, > ++ 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); > ++ > ++#ifndef LEAN_CLIENT > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_export_sec_context(OM_uint32 *minor_status, > ++ gss_ctx_id_t *context_handle, > ++ gss_buffer_t interprocess_token); > ++#endif /* LEAN_CLIENT */ > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_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); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_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); > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_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); > ++ > + /* Magic string to identify exported krb5 GSS credentials. Increment > this if > + * the format changes. */ > + #define CRED_EXPORT_MAGIC "K5C1" > +diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c > b/src/lib/gssapi/krb5/gssapi_krb5.c > +index 0be92e4..c4dfdd6 100644 > +--- a/src/lib/gssapi/krb5/gssapi_krb5.c > ++++ b/src/lib/gssapi/krb5/gssapi_krb5.c > +@@ -351,7 +351,7 @@ static struct { > + } > + }; > + > +-static OM_uint32 KRB5_CALLCONV > ++OM_uint32 KRB5_CALLCONV > + krb5_gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, > + const gss_ctx_id_t context_handle, > + const gss_OID desired_object, > +@@ -465,7 +465,7 @@ static struct { > + }; > + #endif > + > +-static OM_uint32 KRB5_CALLCONV > ++OM_uint32 KRB5_CALLCONV > + krb5_gss_set_sec_context_option (OM_uint32 *minor_status, > + gss_ctx_id_t *context_handle, > + const gss_OID desired_object, > +@@ -929,20 +929,103 @@ static struct gss_config krb5_mechanism = { > + krb5_gss_get_mic_iov_length, > + }; > + > ++/* Functions which use security contexts or acquire creds are > IAKERB-specific; > ++ * other functions can borrow from the krb5 mech. */ > ++static struct gss_config iakerb_mechanism = { > ++ { GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID }, > ++ NULL, > ++ iakerb_gss_acquire_cred, > ++ krb5_gss_release_cred, > ++ iakerb_gss_init_sec_context, > ++#ifdef LEAN_CLIENT > ++ NULL, > ++#else > ++ iakerb_gss_accept_sec_context, > ++#endif > ++ iakerb_gss_process_context_token, > ++ iakerb_gss_delete_sec_context, > ++ iakerb_gss_context_time, > ++ iakerb_gss_get_mic, > ++ iakerb_gss_verify_mic, > ++#if defined(IOV_SHIM_EXERCISE_WRAP) || defined(IOV_SHIM_EXERCISE) > ++ NULL, > ++#else > ++ iakerb_gss_wrap, > ++#endif > ++#if defined(IOV_SHIM_EXERCISE_UNWRAP) || defined(IOV_SHIM_EXERCISE) > ++ NULL, > ++#else > ++ iakerb_gss_unwrap, > ++#endif > ++ krb5_gss_display_status, > ++ krb5_gss_indicate_mechs, > ++ krb5_gss_compare_name, > ++ krb5_gss_display_name, > ++ krb5_gss_import_name, > ++ krb5_gss_release_name, > ++ krb5_gss_inquire_cred, > ++ NULL, /* add_cred */ > ++#ifdef LEAN_CLIENT > ++ NULL, > ++ NULL, > ++#else > ++ iakerb_gss_export_sec_context, > ++ NULL, > ++#endif > ++ krb5_gss_inquire_cred_by_mech, > ++ krb5_gss_inquire_names_for_mech, > ++ iakerb_gss_inquire_context, > ++ krb5_gss_internal_release_oid, > ++ iakerb_gss_wrap_size_limit, > ++ krb5_gss_localname, > ++ krb5_gss_authorize_localname, > ++ krb5_gss_export_name, > ++ krb5_gss_duplicate_name, > ++ krb5_gss_store_cred, > ++ iakerb_gss_inquire_sec_context_by_oid, > ++ krb5_gss_inquire_cred_by_oid, > ++ iakerb_gss_set_sec_context_option, > ++ krb5_gssspi_set_cred_option, > ++ krb5_gssspi_mech_invoke, > ++ NULL, /* wrap_aead */ > ++ NULL, /* unwrap_aead */ > ++ iakerb_gss_wrap_iov, > ++ iakerb_gss_unwrap_iov, > ++ iakerb_gss_wrap_iov_length, > ++ NULL, /* complete_auth_token */ > ++ NULL, /* acquire_cred_impersonate_name */ > ++ NULL, /* add_cred_impersonate_name */ > ++ NULL, /* display_name_ext */ > ++ krb5_gss_inquire_name, > ++ krb5_gss_get_name_attribute, > ++ krb5_gss_set_name_attribute, > ++ krb5_gss_delete_name_attribute, > ++ krb5_gss_export_name_composite, > ++ krb5_gss_map_name_to_any, > ++ krb5_gss_release_any_name_mapping, > ++ iakerb_gss_pseudo_random, > ++ NULL, /* set_neg_mechs */ > ++ krb5_gss_inquire_saslname_for_mech, > ++ krb5_gss_inquire_mech_for_saslname, > ++ krb5_gss_inquire_attrs_for_mech, > ++ krb5_gss_acquire_cred_from, > ++ krb5_gss_store_cred_into, > ++ iakerb_gss_acquire_cred_with_password, > ++ krb5_gss_export_cred, > ++ krb5_gss_import_cred, > ++ NULL, /* import_sec_context_by_mech */ > ++ NULL, /* import_name_by_mech */ > ++ NULL, /* import_cred_by_mech */ > ++ iakerb_gss_get_mic_iov, > ++ iakerb_gss_verify_mic_iov, > ++ iakerb_gss_get_mic_iov_length, > ++}; > ++ > + #ifdef _GSS_STATIC_LINK > + #include "mglueP.h" > + static int gss_iakerbmechglue_init(void) > + { > + struct gss_mech_config mech_iakerb; > +- struct gss_config iakerb_mechanism = krb5_mechanism; > +- > +- /* IAKERB mechanism mirrors krb5, but with different context SPIs */ > +- iakerb_mechanism.gss_accept_sec_context = > iakerb_gss_accept_sec_context; > +- iakerb_mechanism.gss_init_sec_context = > iakerb_gss_init_sec_context; > +- iakerb_mechanism.gss_delete_sec_context = > iakerb_gss_delete_sec_context; > +- iakerb_mechanism.gss_acquire_cred = iakerb_gss_acquire_cred; > +- iakerb_mechanism.gssspi_acquire_cred_with_password > +- = > iakerb_gss_acquire_cred_with_password; > + > + memset(&mech_iakerb, 0, sizeof(mech_iakerb)); > + mech_iakerb.mech = &iakerb_mechanism; > +diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c > +index f30de32..4662bd9 100644 > +--- a/src/lib/gssapi/krb5/iakerb.c > ++++ b/src/lib/gssapi/krb5/iakerb.c > +@@ -47,6 +47,8 @@ struct _iakerb_ctx_id_rec { > + gss_ctx_id_t gssc; > + krb5_data conv; /* conversation for checksumming > */ > + unsigned int count; /* number of round trips */ > ++ int initiate; > ++ int established; > + krb5_get_init_creds_opt *gic_opts; > + }; > + > +@@ -695,7 +697,7 @@ iakerb_get_initial_state(iakerb_ctx_id_t ctx, > + * Allocate and initialise an IAKERB context > + */ > + static krb5_error_code > +-iakerb_alloc_context(iakerb_ctx_id_t *pctx) > ++iakerb_alloc_context(iakerb_ctx_id_t *pctx, int initiate) > + { > + iakerb_ctx_id_t ctx; > + krb5_error_code code; > +@@ -709,6 +711,8 @@ iakerb_alloc_context(iakerb_ctx_id_t *pctx) > + ctx->magic = KG_IAKERB_CONTEXT; > + ctx->state = IAKERB_AS_REQ; > + ctx->count = 0; > ++ ctx->initiate = initiate; > ++ ctx->established = 0; > + > + code = krb5_gss_init_context(&ctx->k5c); > + if (code != 0) > +@@ -732,7 +736,7 @@ iakerb_gss_delete_sec_context(OM_uint32 *minor_status, > + gss_ctx_id_t *context_handle, > + gss_buffer_t output_token) > + { > +- OM_uint32 major_status = GSS_S_COMPLETE; > ++ iakerb_ctx_id_t iakerb_ctx = (iakerb_ctx_id_t)*context_handle; > + > + if (output_token != GSS_C_NO_BUFFER) { > + output_token->length = 0; > +@@ -740,23 +744,10 @@ iakerb_gss_delete_sec_context(OM_uint32 > *minor_status, > + } > + > + *minor_status = 0; > ++ *context_handle = GSS_C_NO_CONTEXT; > ++ iakerb_release_context(iakerb_ctx); > + > +- if (*context_handle != GSS_C_NO_CONTEXT) { > +- iakerb_ctx_id_t iakerb_ctx = (iakerb_ctx_id_t)*context_handle; > +- > +- if (iakerb_ctx->magic == KG_IAKERB_CONTEXT) { > +- iakerb_release_context(iakerb_ctx); > +- *context_handle = GSS_C_NO_CONTEXT; > +- } else { > +- assert(iakerb_ctx->magic == KG_CONTEXT); > +- > +- major_status = krb5_gss_delete_sec_context(minor_status, > +- context_handle, > +- output_token); > +- } > +- } > +- > +- return major_status; > ++ return GSS_S_COMPLETE; > + } > + > + static krb5_boolean > +@@ -802,7 +793,7 @@ iakerb_gss_accept_sec_context(OM_uint32 *minor_status, > + int initialContextToken = (*context_handle == GSS_C_NO_CONTEXT); > + > + if (initialContextToken) { > +- code = iakerb_alloc_context(&ctx); > ++ code = iakerb_alloc_context(&ctx, 0); > + if (code != 0) > + goto cleanup; > + > +@@ -854,11 +845,8 @@ iakerb_gss_accept_sec_context(OM_uint32 > *minor_status, > + time_rec, > + > delegated_cred_handle, > + &exts); > +- if (major_status == GSS_S_COMPLETE) { > +- *context_handle = ctx->gssc; > +- ctx->gssc = NULL; > +- iakerb_release_context(ctx); > +- } > ++ if (major_status == GSS_S_COMPLETE) > ++ ctx->established = 1; > + if (mech_type != NULL) > + *mech_type = (gss_OID)gss_mech_krb5; > + } > +@@ -897,7 +885,7 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status, > + int initialContextToken = (*context_handle == GSS_C_NO_CONTEXT); > + > + if (initialContextToken) { > +- code = iakerb_alloc_context(&ctx); > ++ code = iakerb_alloc_context(&ctx, 1); > + if (code != 0) { > + *minor_status = code; > + goto cleanup; > +@@ -983,11 +971,8 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status, > + ret_flags, > + time_rec, > + &exts); > +- if (major_status == GSS_S_COMPLETE) { > +- *context_handle = ctx->gssc; > +- ctx->gssc = GSS_C_NO_CONTEXT; > +- iakerb_release_context(ctx); > +- } > ++ if (major_status == GSS_S_COMPLETE) > ++ ctx->established = 1; > + if (actual_mech_type != NULL) > + *actual_mech_type = (gss_OID)gss_mech_krb5; > + } else { > +@@ -1010,3 +995,309 @@ iakerb_gss_init_sec_context(OM_uint32 > *minor_status, > + > + return major_status; > + } > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_unwrap(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, > ++ gss_qop_t *qop_state) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_unwrap(minor_status, ctx->gssc, input_message_buffer, > ++ output_message_buffer, conf_state, qop_state); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_wrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle, > ++ int conf_req_flag, gss_qop_t qop_req, > ++ gss_buffer_t input_message_buffer, int *conf_state, > ++ gss_buffer_t output_message_buffer) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_wrap(minor_status, ctx->gssc, conf_req_flag, qop_req, > ++ input_message_buffer, conf_state, > ++ output_message_buffer); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_process_context_token(OM_uint32 *minor_status, > ++ const gss_ctx_id_t context_handle, > ++ const gss_buffer_t token_buffer) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_DEFECTIVE_TOKEN; > ++ > ++ return krb5_gss_process_context_token(minor_status, ctx->gssc, > ++ token_buffer); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_context_time(OM_uint32 *minor_status, gss_ctx_id_t > context_handle, > ++ OM_uint32 *time_rec) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_context_time(minor_status, ctx->gssc, time_rec); > ++} > ++ > ++#ifndef LEAN_CLIENT > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_export_sec_context(OM_uint32 *minor_status, > ++ gss_ctx_id_t *context_handle, > ++ gss_buffer_t interprocess_token) > ++{ > ++ OM_uint32 maj; > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ /* We don't currently support exporting partially established > contexts. */ > ++ if (!ctx->established) > ++ return GSS_S_UNAVAILABLE; > ++ > ++ maj = krb5_gss_export_sec_context(minor_status, &ctx->gssc, > ++ interprocess_token); > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) { > ++ iakerb_release_context(ctx); > ++ *context_handle = GSS_C_NO_CONTEXT; > ++ } > ++ return maj; > ++} > ++ > ++/* > ++ * Until we implement partial context exports, there are no SPNEGO > exported > ++ * context tokens, only tokens for the underlying krb5 context. So we > do not > ++ * need to implement an iakerb_gss_import_sec_context() yet; it would be > ++ * unreachable except via a manually constructed token. > ++ */ > ++ > ++#endif /* LEAN_CLIENT */ > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_inquire_context(OM_uint32 *minor_status, > ++ 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 *initiate, int *opened) > ++{ > ++ OM_uint32 ret; > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (src_name != NULL) > ++ *src_name = GSS_C_NO_NAME; > ++ if (targ_name != NULL) > ++ *targ_name = GSS_C_NO_NAME; > ++ if (lifetime_rec != NULL) > ++ *lifetime_rec = 0; > ++ if (mech_type != NULL) > ++ *mech_type = (gss_OID)gss_mech_iakerb; > ++ if (ctx_flags != NULL) > ++ *ctx_flags = 0; > ++ if (initiate != NULL) > ++ *initiate = ctx->initiate; > ++ if (opened != NULL) > ++ *opened = ctx->established; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_COMPLETE; > ++ > ++ ret = krb5_gss_inquire_context(minor_status, ctx->gssc, src_name, > ++ targ_name, lifetime_rec, mech_type, > ++ ctx_flags, initiate, opened); > ++ > ++ if (!ctx->established) { > ++ /* Report IAKERB as the mech OID until the context is > established. */ > ++ if (mech_type != NULL) > ++ *mech_type = (gss_OID)gss_mech_iakerb; > ++ > ++ /* We don't support exporting partially-established contexts. */ > ++ if (ctx_flags != NULL) > ++ *ctx_flags &= ~GSS_C_TRANS_FLAG; > ++ } > ++ > ++ return ret; > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_wrap_size_limit(OM_uint32 *minor_status, > ++ 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) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_wrap_size_limit(minor_status, ctx->gssc, > conf_req_flag, > ++ qop_req, req_output_size, > max_input_size); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_get_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handle, > ++ gss_qop_t qop_req, gss_buffer_t message_buffer, > ++ gss_buffer_t message_token) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_get_mic(minor_status, ctx->gssc, qop_req, > message_buffer, > ++ message_token); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_verify_mic(OM_uint32 *minor_status, gss_ctx_id_t > context_handle, > ++ gss_buffer_t msg_buffer, gss_buffer_t token_buffer, > ++ gss_qop_t *qop_state) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_verify_mic(minor_status, ctx->gssc, msg_buffer, > ++ token_buffer, qop_state); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_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) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_UNAVAILABLE; > ++ > ++ return krb5_gss_inquire_sec_context_by_oid(minor_status, ctx->gssc, > ++ desired_object, data_set); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_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) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)*context_handle; > ++ > ++ if (ctx == NULL || ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_UNAVAILABLE; > ++ > ++ return krb5_gss_set_sec_context_option(minor_status, &ctx->gssc, > ++ desired_object, value); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_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) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_wrap_iov(minor_status, ctx->gssc, conf_req_flag, > qop_req, > ++ conf_state, iov, iov_count); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_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) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_unwrap_iov(minor_status, ctx->gssc, conf_state, > qop_state, > ++ iov, iov_count); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_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) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_wrap_iov_length(minor_status, ctx->gssc, > conf_req_flag, > ++ qop_req, conf_state, iov, iov_count); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_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) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_pseudo_random(minor_status, ctx->gssc, prf_key, > prf_in, > ++ desired_output_len, prf_out); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t > context_handle, > ++ gss_qop_t qop_req, gss_iov_buffer_desc *iov, > ++ int iov_count) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_get_mic_iov(minor_status, ctx->gssc, qop_req, iov, > ++ iov_count); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t > context_handle, > ++ gss_qop_t *qop_state, gss_iov_buffer_desc *iov, > ++ int iov_count) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_verify_mic_iov(minor_status, ctx->gssc, qop_state, > iov, > ++ iov_count); > ++} > ++ > ++OM_uint32 KRB5_CALLCONV > ++iakerb_gss_get_mic_iov_length(OM_uint32 *minor_status, > ++ gss_ctx_id_t context_handle, gss_qop_t > qop_req, > ++ gss_iov_buffer_desc *iov, int iov_count) > ++{ > ++ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; > ++ > ++ if (ctx->gssc == GSS_C_NO_CONTEXT) > ++ return GSS_S_NO_CONTEXT; > ++ > ++ return krb5_gss_get_mic_iov_length(minor_status, ctx->gssc, qop_req, > iov, > ++ iov_count); > ++} > diff --git a/main/krb5/CVE-2015-2697.patch b/main/krb5/CVE-2015-2697.patch > new file mode 100644 > index 0000000..af2f42a > --- /dev/null > +++ b/main/krb5/CVE-2015-2697.patch > @@ -0,0 +1,50 @@ > +From f0c094a1b745d91ef2f9a4eae2149aac026a5789 Mon Sep 17 00:00:00 2001 > +From: Greg Hudson > +Date: Fri, 25 Sep 2015 12:51:47 -0400 > +Subject: [PATCH] Fix build_principal memory bug [CVE-2015-2697] > + > +In build_principal_va(), use k5memdup0() instead of strdup() to make a > +copy of the realm, to ensure that we allocate the correct number of > +bytes and do not read past the end of the input string. This bug > +affects krb5_build_principal(), krb5_build_principal_va(), and > +krb5_build_principal_alloc_va(). krb5_build_principal_ext() is not > +affected. > + > +CVE-2015-2697: > + > +In MIT krb5 1.7 and later, an authenticated attacker may be able to > +cause a KDC to crash using a TGS request with a large realm field > +beginning with a null byte. If the KDC attempts to find a referral to > +answer the request, it constructs a principal name for lookup using > +krb5_build_principal() with the requested realm. Due to a bug in this > +function, the null byte causes only one byte be allocated for the > +realm field of the constructed principal, far less than its length. > +Subsequent operations on the lookup principal may cause a read beyond > +the end of the mapped memory region, causing the KDC process to crash. > + > +CVSSv2: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C > + > +ticket: 8252 (new) > +target_version: 1.14 > +tags: pullup > +--- > + src/lib/krb5/krb/bld_princ.c | 6 ++---- > + 1 file changed, 2 insertions(+), 4 deletions(-) > + > +diff --git a/src/lib/krb5/krb/bld_princ.c b/src/lib/krb5/krb/bld_princ.c > +index ab6fed8..8604268 100644 > +--- a/src/lib/krb5/krb/bld_princ.c > ++++ b/src/lib/krb5/krb/bld_princ.c > +@@ -40,10 +40,8 @@ build_principal_va(krb5_context context, > krb5_principal princ, > + data = malloc(size * sizeof(krb5_data)); > + if (!data) { retval = ENOMEM; } > + > +- if (!retval) { > +- r = strdup(realm); > +- if (!r) { retval = ENOMEM; } > +- } > ++ if (!retval) > ++ r = k5memdup0(realm, rlen, &retval); > + > + while (!retval && (component = va_arg(ap, char *))) { > + if (count == size) { > -- > 2.6.2 > > --001a114b0964d6bd3d0525dd8580 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
This patch applies against against the 3.2-stable branch.<= /div>
Christian Kampka <<= a href=3D"mailto:christian@kampka.net">christian@kampka.net> schrieb= am Di., 1. Dez. 2015 um 23:14=C2=A0Uhr:
fixes: #4836
---
=C2=A0main/krb5/APKBUILD=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 1= 8 +-
=C2=A0main/krb5/CVE-2015-2694.patch | 101 ++++++
=C2=A0main/krb5/CVE-2015-2695.patch | 564 ++++++++++++++++++++++++++++++++<= br> =C2=A0main/krb5/CVE-2015-2696.patch | 731 +++++++++++++++++++++++++++++++++= +++++++++
=C2=A0main/krb5/CVE-2015-2697.patch |=C2=A0 50 +++
=C2=A05 files changed, 1463 insertions(+), 1 deletion(-)
=C2=A0create mode 100644 main/krb5/CVE-2015-2694.patch
=C2=A0create mode 100644 main/krb5/CVE-2015-2695.patch
=C2=A0create mode 100644 main/krb5/CVE-2015-2696.patch
=C2=A0create mode 100644 main/krb5/CVE-2015-2697.patch

diff --git a/main/krb5/APKBUILD b/main/krb5/APKBUILD
index d3ddfc9..fef6004 100644
--- a/main/krb5/APKBUILD
+++ b/main/krb5/APKBUILD
@@ -1,7 +1,7 @@
=C2=A0# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
=C2=A0pkgname=3Dkrb5
=C2=A0pkgver=3D1.13.1
-pkgrel=3D1
+pkgrel=3D2

=C2=A0case $pkgver in
=C2=A0*.*.*) _ver=3D${pkgver%.*};;
@@ -22,6 +22,10 @@ subpackages=3D"$pkgname-dev $pkgname-doc $pkgname-s= erver
=C2=A0 =C2=A0 =C2=A0 =C2=A0 $pkgname-server-ldap:ldap $pkgname-pkinit $pkgn= ame-libs"
=C2=A0source=3D"http:/= /web.mit.edu/kerberos/dist/krb5/${_ver}/krb5-$pkgver-signed.tar
=C2=A0 =C2=A0 =C2=A0 =C2=A0 mit-krb5_krb5-config_LDFLAGS.patch
+=C2=A0 =C2=A0 =C2=A0 =C2=A0CVE-2015-2694.patch
+=C2=A0 =C2=A0 =C2=A0 =C2=A0CVE-2015-2695.patch
+=C2=A0 =C2=A0 =C2=A0 =C2=A0CVE-2015-2696.patch
+=C2=A0 =C2=A0 =C2=A0 =C2=A0CVE-2015-2697.patch

=C2=A0 =C2=A0 =C2=A0 =C2=A0 krb5kadmind.initd
=C2=A0 =C2=A0 =C2=A0 =C2=A0 krb5kdc.initd
@@ -120,16 +124,28 @@ libs() {

=C2=A0md5sums=3D"567586cdf02aa8c842c2fab7a94f3c1f=C2=A0 krb5-1.13.1-si= gned.tar
=C2=A0c84a0c7d8014e3528524956ffdd1c3e9=C2=A0 mit-krb5_krb5-config_LDFLAGS.p= atch
+98d4792ff9576efab658be312ef7623f=C2=A0 CVE-2015-2694.patch
+ca73fdd31a2d5c38993afbed909b5417=C2=A0 CVE-2015-2695.patch
+dc4c2a99b5b8a9bf7b306d614134c267=C2=A0 CVE-2015-2696.patch
+a2369d91ccef67f093af594d941ebc11=C2=A0 CVE-2015-2697.patch
=C2=A09c0e3bac122326cdbbbac068056ee8af=C2=A0 krb5kadmind.initd
=C2=A071131479c07a2d89b30a2ea18dd64e74=C2=A0 krb5kdc.initd
=C2=A0d94873a6a1ac6277adf2d25458eda9e5=C2=A0 krb5kpropd.initd"
=C2=A0sha256sums=3D"4df629fdf97f362cf81edbf38d613b32b492dd88c876cf3aa1= c66562f296663e=C2=A0 krb5-1.13.1-signed.tar
=C2=A084007c7423f67db7a8b248b9643c49ef25f2d56ce15c2574eb41ecbf51bcd3f2=C2= =A0 mit-krb5_krb5-config_LDFLAGS.patch
+f3710f2f90542145a8921dc7c2b8241d8fdeccdcba3d50b1758aa0e2f8aeec73=C2=A0 CVE= -2015-2694.patch
+b83dd0714f1ab164f6eb50d173bec25bb851c739ed5b1c38b35e7a1910cff25b=C2=A0 CVE= -2015-2695.patch
+add426d86d31c57dc8e1c1d9043f61c21f2e532e728d1d9c703b2616bf246d7c=C2=A0 CVE= -2015-2696.patch
+e1d3d6a0dfede9d5a4af83d51c4f5fad13e917e4cb58672ff0ee3e8f34fe0379=C2=A0 CVE= -2015-2697.patch
=C2=A0213a5b04f091e4644e856aabc38da586bd86c4616ab15f00eefca52fca7137d6=C2= =A0 krb5kadmind.initd
=C2=A0577842c7fe4639a8e9dd349da40e514284dd53440bb71be58283faaf18508f9a=C2= =A0 krb5kdc.initd
=C2=A01644639d83791bd871f3c89a53a7052ab52994d3ef03d1d675d4217130c1fa94=C2= =A0 krb5kpropd.initd"
=C2=A0sha512sums=3D"f26dce8f682bd3fbf38a15df5f91722b573d4df4cc193f7ba8= dc369cbbee8f4bc2a72f56513d2cf27697ce8baaf954afe04e3eefc15c2883fa1d5260145ae= f6e=C2=A0 krb5-1.13.1-signed.tar
=C2=A05a3782ff17b383f8cd0415fd13538ab56afd788130d6ad640e9f2682b7deaae7f2571= 3ce358058ed771091040dccf62a3bc87e6fd473d505ec189a95debcc801=C2=A0 mit-krb5_= krb5-config_LDFLAGS.patch
+0c8ab8a1d6bfa31b3257c1ac4f99d9c14d4f8ed0c27da0e648f64e9e5e5717ca5d929def6f= d1f04903b287786add4a93e8f1c1f96cea14d123c1574c174a532a=C2=A0 CVE-2015-2694.= patch
+4e1499d799bed90b2857d24de29ea3bb7500b514a86c2a8f4596fb80f97f01445b7dd9d0cb= 19c1cfb1f03f5c6a8e2a2149a6278c720933181db8e188063dcc6a=C2=A0 CVE-2015-2695.= patch
+d27e836a3e8a1ca6b711c0ce4f9f68cbd42d888cb9dcaf2dcb78fdc9ca7652865c124e14c7= 026b4e94a722a314a0c30f732cc00344973ee5a180f11901347ed1=C2=A0 CVE-2015-2696.= patch
+5f6a630b566c9f0cb02528fca3a789547e294acf5f3435eb62b79411187e4fcaaa58b81eff= 34e8ac6cbca3dacb076bd626a31687c04936b35bf7ab3e35965a31=C2=A0 CVE-2015-2697.= patch
=C2=A043b9885b7eb8d0d60920def688de482f2b1701288f9acb1bb21dc76b2395428ff3049= 61959eb04ba5eafd0412bae35668d6d2c8223424b9337bc051eadf51682=C2=A0 krb5kadmi= nd.initd
=C2=A0ede15f15bbbc9d0227235067abe15245bb9713aea260d397379c63275ce74aea0db6c= 91c15d599e40c6e89612d76f3a0f8fdd21cbafa3f30d426d4310d3e2cec=C2=A0 krb5kdc.i= nitd
=C2=A045be0d421efd41e9dd056125a750c90856586e990317456b68170d733b03cba9ecd18= ab87603b20e49575e7839fb4a6d628255533f2631f9e8ddb7f3cc493a90=C2=A0 krb5kprop= d.initd"
diff --git a/main/krb5/CVE-2015-2694.patch b/main/krb5/CVE-2015-2694.patch<= br> new file mode 100644
index 0000000..6154965
--- /dev/null
+++ b/main/krb5/CVE-2015-2694.patch
@@ -0,0 +1,101 @@
+From df8afc60d970a7176a55ffe7ce21cfd57ba423cd Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Tue, 24 Mar 2015 12:02:37 -0400
+Subject: [PATCH] Prevent requires_preauth bypass [CVE-2015-2694]
+
+In the OTP kdcpreauth module, don't set the TKT_FLG_PRE_AUTH bit until=
+the request is successfully verified.=C2=A0 In the PKINIT kdcpreauth
+module, don't respond with code 0 on empty input or an unconfigured +realm.=C2=A0 Together these bugs could cause the KDC preauth framework to<= br> +erroneously treat a request as pre-authenticated.
+
+CVE-2015-2694:
+
+In MIT krb5 1.12 and later, when the KDC is configured with PKINIT
+support, an unauthenticated remote attacker can bypass the
+requires_preauth flag on a client principal and obtain a ciphertext
+encrypted in the principal's long-term key.=C2=A0 This ciphertext coul= d be
+used to conduct an off-line dictionary attack against the user's
+password.
+
+=C2=A0 =C2=A0 CVSSv2 Vector: AV:N/AC:M/Au:N/C:P/I:P/A:N/E:POC/RL:OF/RC:C +
+(cherry picked from commit e3b5a5e5267818c97750b266df50b6a3d4649604)
+
+ticket: 8160
+version_fixed: 1.13.2
+status: resolved
+---
+ src/plugins/preauth/otp/main.c=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | 10 +++= ++++---
+ src/plugins/preauth/pkinit/pkinit_srv.c |=C2=A0 4 ++--
+ 2 files changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/src/plugins/preauth/otp/main.c b/src/plugins/preauth/otp/main= .c
+index bf9c6a8..7941b4a 100644
+--- a/src/plugins/preauth/otp/main.c
++++ b/src/plugins/preauth/otp/main.c
+@@ -42,6 +42,7 @@ static krb5_preauthtype otp_pa_type_list[] =3D
+ struct request_state {
+=C2=A0 =C2=A0 =C2=A0krb5_kdcpreauth_verify_respond_fn respond;
+=C2=A0 =C2=A0 =C2=A0void *arg;
++=C2=A0 =C2=A0 krb5_enc_tkt_part *enc_tkt_reply;
+ };
+
+ static krb5_error_code
+@@ -159,6 +160,9 @@ on_response(void *data, krb5_error_code retval, otp_re= sponse response)
+=C2=A0 =C2=A0 =C2=A0if (retval =3D=3D 0 && response !=3D otp_respo= nse_success)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0retval =3D KRB5_PREAUTH_FAILED;
+
++=C2=A0 =C2=A0 if (retval =3D=3D 0)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 rs.enc_tkt_reply->flags |=3D TKT_FLG_PRE_A= UTH;
++
+=C2=A0 =C2=A0 =C2=A0rs.respond(rs.arg, retval, NULL, NULL, NULL);
+ }
+
+@@ -263,8 +267,6 @@ otp_verify(krb5_context context, krb5_data *req_pkt, k= rb5_kdc_req *request,
+=C2=A0 =C2=A0 =C2=A0krb5_data d, plaintext;
+=C2=A0 =C2=A0 =C2=A0char *config;
+
+-=C2=A0 =C2=A0 enc_tkt_reply->flags |=3D TKT_FLG_PRE_AUTH;
+-
+=C2=A0 =C2=A0 =C2=A0/* Get the FAST armor key. */
+=C2=A0 =C2=A0 =C2=A0armor_key =3D cb->fast_armor(context, rock);
+=C2=A0 =C2=A0 =C2=A0if (armor_key =3D=3D NULL) {
+@@ -298,12 +300,14 @@ otp_verify(krb5_context context, krb5_data *req_pkt,= krb5_kdc_req *request,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto error;
+=C2=A0 =C2=A0 =C2=A0}
+
+-=C2=A0 =C2=A0 /* Create the request state. */
++=C2=A0 =C2=A0 /* Create the request state.=C2=A0 Save the response callba= ck, and the
++=C2=A0 =C2=A0 =C2=A0* enc_tkt_reply pointer so we can set the TKT_FLG_PRE= _AUTH flag later. */
+=C2=A0 =C2=A0 =C2=A0rs =3D k5alloc(sizeof(struct request_state), &retv= al);
+=C2=A0 =C2=A0 =C2=A0if (rs =3D=3D NULL)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto error;
+=C2=A0 =C2=A0 =C2=A0rs->arg =3D arg;
+=C2=A0 =C2=A0 =C2=A0rs->respond =3D respond;
++=C2=A0 =C2=A0 rs->enc_tkt_reply =3D enc_tkt_reply;
+
+=C2=A0 =C2=A0 =C2=A0/* Get the principal's OTP configuration string. *= /
+=C2=A0 =C2=A0 =C2=A0retval =3D cb->get_string(context, rock, "otp&= quot;, &config);
+diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth= /pkinit/pkinit_srv.c
+index 5639fca..edfce6f 100644
+--- a/src/plugins/preauth/pkinit/pkinit_srv.c
++++ b/src/plugins/preauth/pkinit/pkinit_srv.c
+@@ -301,7 +301,7 @@ pkinit_server_verify_padata(krb5_context context,
+
+=C2=A0 =C2=A0 =C2=A0pkiDebug("pkinit_verify_padata: entered!\n")= ;
+=C2=A0 =C2=A0 =C2=A0if (data =3D=3D NULL || data->length <=3D 0 || d= ata->contents =3D=3D NULL) {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 (*respond)(arg, 0, NULL, NULL, NULL);
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 (*respond)(arg, EINVAL, NULL, NULL, NULL); +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return;
+=C2=A0 =C2=A0 =C2=A0}
+
+@@ -313,7 +313,7 @@ pkinit_server_verify_padata(krb5_context context,
+
+=C2=A0 =C2=A0 =C2=A0plgctx =3D pkinit_find_realm_context(context, moddata,= request->server);
+=C2=A0 =C2=A0 =C2=A0if (plgctx =3D=3D NULL) {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 (*respond)(arg, 0, NULL, NULL, NULL);
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 (*respond)(arg, EINVAL, NULL, NULL, NULL); +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return;
+=C2=A0 =C2=A0 =C2=A0}
+
diff --git a/main/krb5/CVE-2015-2695.patch b/main/krb5/CVE-2015-2695.patch<= br> new file mode 100644
index 0000000..08bc8ab
--- /dev/null
+++ b/main/krb5/CVE-2015-2695.patch
@@ -0,0 +1,564 @@
+From b51b33f2bc5d1497ddf5bd107f791c101695000d Mon Sep 17 00:00:00 2001
+From: Nicolas Williams <nico@twosigma.com>
+Date: Mon, 14 Sep 2015 12:27:52 -0400
+Subject: [PATCH] Fix SPNEGO context aliasing bugs [CVE-2015-2695]
+
+The SPNEGO mechanism currently replaces its context handle with the
+mechanism context handle upon establishment, under the assumption that
+most GSS functions are only called after context establishment.=C2=A0 This=
+assumption is incorrect, and can lead to aliasing violations for some
+programs.=C2=A0 Maintain the SPNEGO context structure after context
+establishment and refer to it in all GSS methods.=C2=A0 Add initiate and +opened flags to the SPNEGO context structure for use in
+gss_inquire_context() prior to context establishment.
+
+CVE-2015-2695:
+
+In MIT krb5 1.5 and later, applications which call
+gss_inquire_context() on a partially-established SPNEGO context can
+cause the GSS-API library to read from a pointer using the wrong type,
+generally causing a process crash.=C2=A0 This bug may go unnoticed, becaus= e
+the most common SPNEGO authentication scenario establishes the context
+after just one call to gss_accept_sec_context().=C2=A0 Java server
+applications using the native JGSS provider are vulnerable to this
+bug.=C2=A0 A carefully crafted SPNEGO packet might allow the
+gss_inquire_context() call to succeed with attacker-determined
+results, but applications should not make access control decisions
+based on gss_inquire_context() results prior to context establishment.
+
+=C2=A0 =C2=A0 CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:C/E:POC/RL:OF/RC:C +
+[ghudson@mit.edu:= several bugfixes, style changes, and edge-case
+behavior changes; commit message and CVE description]
+
+ticket: 8244
+target_version: 1.14
+tags: pullup
+---
+ src/lib/gssapi/spnego/gssapiP_spnego.h |=C2=A0 =C2=A02 +
+ src/lib/gssapi/spnego/spnego_mech.c=C2=A0 =C2=A0 | 254 ++++++++++++++++++= ++++++---------
+ 2 files changed, 192 insertions(+), 64 deletions(-)
+
+diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h b/src/lib/gssapi/spneg= o/gssapiP_spnego.h
+index 57372de..5c82764 100644
+--- a/src/lib/gssapi/spnego/gssapiP_spnego.h
++++ b/src/lib/gssapi/spnego/gssapiP_spnego.h
+@@ -103,6 +103,8 @@ typedef struct {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0int firstpass;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0int mech_complete;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0int nego_done;
++=C2=A0 =C2=A0 =C2=A0 int initiate;
++=C2=A0 =C2=A0 =C2=A0 int opened;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ctx_flags;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0gss_name_t internal_name;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0gss_OID actual_mech;
+diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/s= pnego_mech.c
+index ef76e1f..7849c85 100644
+--- a/src/lib/gssapi/spnego/spnego_mech.c
++++ b/src/lib/gssapi/spnego/spnego_mech.c
+@@ -102,7 +102,7 @@ static OM_uint32 get_negotiable_mechs(OM_uint32 *, spn= ego_gss_cred_id_t,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_cred_usage_t= , gss_OID_set *);
+ static void release_spnego_ctx(spnego_gss_ctx_id_t *);
+ static void check_spnego_options(spnego_gss_ctx_id_t);
+-static spnego_gss_ctx_id_t create_spnego_ctx(void);
++static spnego_gss_ctx_id_t create_spnego_ctx(int);
+ static int put_mech_set(gss_OID_set mechSet, gss_buffer_t buf);
+ static int put_input_token(unsigned char **, gss_buffer_t, unsigned int);=
+ static int put_mech_oid(unsigned char **, gss_OID_const, unsigned int); +@@ -454,7 +454,7 @@ check_spnego_options(spnego_gss_ctx_id_t spnego_ctx) + }
+
+ static spnego_gss_ctx_id_t
+-create_spnego_ctx(void)
++create_spnego_ctx(int initiate)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0spnego_gss_ctx_id_t spnego_ctx =3D NULL;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0spnego_ctx =3D (spnego_gss_ctx_id_t)
+@@ -477,6 +477,8 @@ create_spnego_ctx(void)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0spnego_ctx->mic_rcvd =3D 0;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0spnego_ctx->mech_complete =3D 0;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0spnego_ctx->nego_done =3D 0;
++=C2=A0 =C2=A0 =C2=A0 spnego_ctx->opened =3D 0;
++=C2=A0 =C2=A0 =C2=A0 spnego_ctx->initiate =3D initiate;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0spnego_ctx->internal_name =3D GSS_C_NO_NAME;=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0spnego_ctx->actual_mech =3D GSS_C_NO_OID; +
+@@ -642,7 +644,7 @@ init_ctx_new(OM_uint32 *minor_status,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0spnego_gss_ctx_id_t sc =3D NULL;
+
+-=C2=A0 =C2=A0 =C2=A0 sc =3D create_spnego_ctx();
++=C2=A0 =C2=A0 =C2=A0 sc =3D create_spnego_ctx(1);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (sc =3D=3D NULL)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return GSS_S_FAILUR= E;
+
+@@ -659,10 +661,7 @@ init_ctx_new(OM_uint32 *minor_status,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D GSS_S_FAILU= RE;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+-=C2=A0 =C2=A0 =C2=A0 /*
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0* The actual context is not yet determined, se= t the output
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0* context handle to refer to the spnego contex= t itself.
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0*/
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0sc->ctx_handle =3D GSS_C_NO_CONTEXT;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0*ctx =3D (gss_ctx_id_t)sc;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0sc =3D NULL;
+@@ -1108,16 +1107,11 @@ spnego_gss_init_sec_context(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0gss_release_buffer(&tmpmin, &mechtok_ou= t);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret =3D=3D GSS_S_COMPLETE) {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* Now, switch the = output context to refer to the
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* negotiated mecha= nism's context.
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*/
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *context_handle =3D (gss= _ctx_id_t)spnego_ctx->ctx_handle;
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 spnego_ctx->opened = =3D 1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (actual_mech != =3D NULL)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0*actual_mech =3D spnego_ctx->actual_mech;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret_flags !=3D = NULL)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0*ret_flags =3D spnego_ctx->ctx_flags;
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 release_spnego_ctx(&= spnego_ctx);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0} else if (ret !=3D GSS_S_CONTINUE_NEEDED) { +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (spnego_ctx !=3D= NULL) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0gss_delete_sec_context(&tmpmin,
+@@ -1285,7 +1279,7 @@ acc_ctx_hints(OM_uint32 *minor_status,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret !=3D GSS_S_COMPLETE)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup;
+
+-=C2=A0 =C2=A0 =C2=A0 sc =3D create_spnego_ctx();
++=C2=A0 =C2=A0 =C2=A0 sc =3D create_spnego_ctx(0);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (sc =3D=3D NULL) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D GSS_S_FAILU= RE;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup;
+@@ -1367,7 +1361,7 @@ acc_ctx_new(OM_uint32 *minor_status,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_release_buffer(= &tmpmin, &sc->DER_mechTypes);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0assert(mech_wanted = !=3D GSS_C_NO_OID);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0} else
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sc =3D create_spnego_ctx= ();
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sc =3D create_spnego_ctx= (0);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (sc =3D=3D NULL) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D GSS_S_FAILU= RE;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*return_token =3D N= O_TOKEN_SEND;
+@@ -1750,13 +1744,12 @@ spnego_gss_accept_sec_context(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0ret =3D GSS_S_FAILURE;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret =3D=3D GSS_S_COMPLETE) {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *context_handle =3D (gss= _ctx_id_t)sc->ctx_handle;
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sc->opened =3D 1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (sc->internal= _name !=3D GSS_C_NO_NAME &&
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0src_n= ame !=3D NULL) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0*src_name =3D sc->internal_name;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0sc->internal_name =3D GSS_C_NO_NAME;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 release_spnego_ctx(&= sc);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0} else if (ret !=3D GSS_S_CONTINUE_NEEDED) { +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (sc !=3D NULL) {=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0gss_delete_sec_context(&tmpmin, &sc->ctx_handle,
+@@ -2069,8 +2062,13 @@ spnego_gss_unwrap(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_qop_t *qop_stat= e)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT= );
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_unwrap(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0input_message_buffer,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0output_message_buffer,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0conf_state,
+@@ -2090,8 +2088,13 @@ spnego_gss_wrap(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_buffer_t output= _message_buffer)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT= );
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_wrap(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 context_ha= ndle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sc->ctx= _handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0conf_= req_flag,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0qop_r= eq,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0input= _message_buffer,
+@@ -2108,8 +2111,14 @@ spnego_gss_process_context_token(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const gss_buffer_t token_buffer)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 /* SPNEGO doesn't have its own context tokens. *= /
++=C2=A0 =C2=A0 =C2=A0 if (!sc->opened)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_DEFECTIVE_= TOKEN);
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_process_context_token(minor_status,=
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 context_handle,=
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sc->ctx_hand= le,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0token_buf= fer);
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return (ret);
+@@ -2133,19 +2142,9 @@ spnego_gss_delete_sec_context(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (*ctx =3D=3D NULL)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (GSS_S_COMPL= ETE);
+
+-=C2=A0 =C2=A0 =C2=A0 /*
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0* If this is still an SPNEGO mech, release it = locally.
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0*/
+-=C2=A0 =C2=A0 =C2=A0 if ((*ctx)->magic_num =3D=3D SPNEGO_MAGIC_ID) { +-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (void) gss_delete_sec_co= ntext(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &(*ctx)->ctx_handle, +-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 output_token);
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (void) release_spnego_ct= x(ctx);
+-=C2=A0 =C2=A0 =C2=A0 } else {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret =3D gss_delete_sec_c= ontext(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 context_handle,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 output_token);
+-=C2=A0 =C2=A0 =C2=A0 }
++=C2=A0 =C2=A0 =C2=A0 (void) gss_delete_sec_context(minor_status, &(*c= tx)->ctx_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 output_token);
++=C2=A0 =C2=A0 =C2=A0 (void) release_spnego_ctx(ctx);
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return (ret);
+ }
+@@ -2157,8 +2156,13 @@ spnego_gss_context_time(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0OM_uint32=C2=A0 =C2=A0 =C2=A0 =C2=A0*time_rec)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT= );
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_context_time(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0time_rec);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return (ret);
+ }
+@@ -2170,9 +2174,20 @@ spnego_gss_export_sec_context(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_buffer_t interprocess_token)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D *(spnego_gss_ctx_id_t *)c= ontext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 /* We don't currently support exporting partiall= y established
++=C2=A0 =C2=A0 =C2=A0 =C2=A0* contexts. */
++=C2=A0 =C2=A0 =C2=A0 if (!sc->opened)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_UNAVAILABLE= ;
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_export_sec_context(minor_status, +-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0interprocess_token); ++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT) {
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 release_spnego_ctx(&= sc);
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *context_handle =3D GSS_= C_NO_CONTEXT;
++=C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return (ret);
+ }
+
+@@ -2182,11 +2197,12 @@ spnego_gss_import_sec_context(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0const gss_buffer_t=C2=A0 =C2=A0 =C2=A0 interpro= cess_token,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0gss_ctx_id_t=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 *context_handle)
+ {
+-=C2=A0 =C2=A0 =C2=A0 OM_uint32 ret;
+-=C2=A0 =C2=A0 =C2=A0 ret =3D gss_import_sec_context(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 interprocess_token,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 context_handle);
+-=C2=A0 =C2=A0 =C2=A0 return (ret);
++=C2=A0 =C2=A0 =C2=A0 /*
++=C2=A0 =C2=A0 =C2=A0 =C2=A0* Until we implement partial context exports, = there are no SPNEGO
++=C2=A0 =C2=A0 =C2=A0 =C2=A0* exported context tokens, only tokens for und= erlying mechs.=C2=A0 So just
++=C2=A0 =C2=A0 =C2=A0 =C2=A0* return an error for now.
++=C2=A0 =C2=A0 =C2=A0 =C2=A0*/
++=C2=A0 =C2=A0 =C2=A0 return GSS_S_UNAVAILABLE;
+ }
+ #endif /* LEAN_CLIENT */
+
+@@ -2203,16 +2219,48 @@ spnego_gss_inquire_context(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0int=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*opened)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret =3D GSS_S_COMPLETE;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (src_name !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *src_name =3D GSS_C_NO_N= AME;
++=C2=A0 =C2=A0 =C2=A0 if (targ_name !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *targ_name =3D GSS_C_NO_= NAME;
++=C2=A0 =C2=A0 =C2=A0 if (lifetime_rec !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *lifetime_rec =3D 0;
++=C2=A0 =C2=A0 =C2=A0 if (mech_type !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *mech_type =3D (gss_OID)= gss_mech_spnego;
++=C2=A0 =C2=A0 =C2=A0 if (ctx_flags !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *ctx_flags =3D 0;
++=C2=A0 =C2=A0 =C2=A0 if (locally_initiated !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *locally_initiated =3D s= c->initiate;
++=C2=A0 =C2=A0 =C2=A0 if (opened !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *opened =3D sc->opene= d;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle !=3D GSS_C_NO_CONTEXT) {
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret =3D gss_inquire_cont= ext(minor_status, sc->ctx_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 src_name= , targ_name, lifetime_rec,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 mech_typ= e, ctx_flags, NULL, NULL);
++=C2=A0 =C2=A0 =C2=A0 }
+
+-=C2=A0 =C2=A0 =C2=A0 ret =3D gss_inquire_context(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 context_handle,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 src_name,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 targ_name,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 lifetime_rec,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 mech_type,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ctx_flags,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 locally_initiated,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 opened);
++=C2=A0 =C2=A0 =C2=A0 if (!sc->opened) {
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* We are still doi= ng SPNEGO negotiation, so report SPNEGO as
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* the OID.=C2=A0 A= fter negotiation is complete we will report the
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* underlying mecha= nism OID.
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*/
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (mech_type !=3D NULL)=
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 *mech_type =3D (gss_OID)gss_mech_spnego;
++
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* Remove flags we = don't support with partially-established
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* contexts.=C2=A0 = (Change this to keep GSS_C_TRANS_FLAG if we add
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* support for expo= rting partial SPNEGO contexts.)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*/
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (ctx_flags !=3D NULL)= {
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 *ctx_flags &=3D ~GSS_C_PROT_READY_FLAG;
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 *ctx_flags &=3D ~GSS_C_TRANS_FLAG;
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
++=C2=A0 =C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return (ret);
+ }
+@@ -2227,8 +2275,13 @@ spnego_gss_wrap_size_limit(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32=C2=A0 =C2=A0 =C2=A0 =C2=A0*max_input_= size)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT= );
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_wrap_size_limit(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0conf_req_flag,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0qop_req,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0req_output_size,
+@@ -2245,8 +2298,13 @@ spnego_gss_get_mic(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_buffer_t messag= e_token)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT= );
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_get_mic(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 context_ha= ndle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sc->ctx= _handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0qop_r= eq,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0messa= ge_buffer,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0messa= ge_token);
+@@ -2262,8 +2320,13 @@ spnego_gss_verify_mic(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_qop_t *qop_stat= e)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT= );
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_verify_mic(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0msg_buffer,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0token_buffer,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0qop_state);
+@@ -2278,8 +2341,14 @@ spnego_gss_inquire_sec_context_by_oid(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_buffer_set_t *d= ata_set)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 /* There are no SPNEGO-specific OIDs for this functi= on. */
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_UNAVAILABL= E);
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_inquire_sec_context_by_oid(minor_st= atus,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0desired_object,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0data_set);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return (ret);
+@@ -2359,8 +2428,15 @@ spnego_gss_set_sec_context_option(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const gss_buffer_t = value)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)*con= text_handle;
++
++=C2=A0 =C2=A0 =C2=A0 /* There are no SPNEGO-specific OIDs for this functi= on, and we cannot
++=C2=A0 =C2=A0 =C2=A0 =C2=A0* construct an empty SPNEGO context with it. *= /
++=C2=A0 =C2=A0 =C2=A0 if (sc =3D=3D NULL || sc->ctx_handle =3D=3D GSS_C= _NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_UNAVAILABL= E);
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_set_sec_context_option(minor_status= ,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 &sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0desired_object,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0value);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return (ret);
+@@ -2377,8 +2453,13 @@ spnego_gss_wrap_aead(OM_uint32 *minor_status,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_= buffer_t output_message_buffer)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT= );
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_wrap_aead(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0conf_req_flag,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0qop_req,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0input_assoc_buffer,
+@@ -2399,8 +2480,13 @@ spnego_gss_unwrap_aead(OM_uint32 *minor_status,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 gss_qop_t *qop_state)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT= );
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_unwrap_aead(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0input_message_buffer,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0input_assoc_buffer,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0output_payload_buffer,
+@@ -2419,8 +2505,13 @@ spnego_gss_wrap_iov(OM_uint32 *minor_status,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int i= ov_count)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT= );
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_wrap_iov(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 conf_req_flag,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 qop_req,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 conf_state,
+@@ -2438,8 +2529,13 @@ spnego_gss_unwrap_iov(OM_uint32 *minor_status,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0int iov_count)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT= );
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_unwrap_iov(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 conf_state,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 qop_state,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 iov,
+@@ -2457,8 +2553,13 @@ spnego_gss_wrap_iov_length(OM_uint32 *minor_status,=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 int iov_count)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT= );
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_wrap_iov_length(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0conf_req_flag,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0qop_req,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0conf_state,
+@@ -2475,8 +2576,13 @@ spnego_gss_complete_auth_token(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_buffer_t input_= message_buffer)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext_handle;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_UNAVAILABL= E);
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_complete_auth_token(minor_status, +-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0input_message_bu= ffer);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return (ret);
+ }
+@@ -2721,8 +2827,13 @@ spnego_gss_pseudo_random(OM_uint32 *minor_status, +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 gss_buffer_t prf_out)
+ {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 ret;
++=C2=A0 =C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)cont= ext;
++
++=C2=A0 =C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT= );
++
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D gss_pseudo_random(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 context,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sc->ctx_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0prf_key,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0prf_in,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0desired_output_len,
+@@ -2863,7 +2974,12 @@ spnego_gss_get_mic_iov(OM_uint32 *minor_status, gss= _ctx_id_t context_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 gss_qop_t qop_req, gss_iov_buffer_desc *iov,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 int iov_count)
+ {
+-=C2=A0 =C2=A0 return gss_get_mic_iov(minor_status, context_handle, qop_re= q, iov,
++=C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)context_han= dle;
++
++=C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT);
++
++=C2=A0 =C2=A0 return gss_get_mic_iov(minor_status, sc->ctx_handle, qop= _req, iov,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 iov_count);
+ }
+
+@@ -2872,7 +2988,12 @@ spnego_gss_verify_mic_iov(OM_uint32 *minor_status, = gss_ctx_id_t context_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0gss_qop_t *qop_state, gss_iov_buffer_desc *iov,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0int iov_count)
+ {
+-=C2=A0 =C2=A0 return gss_verify_mic_iov(minor_status, context_handle, qop= _state, iov,
++=C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)context_han= dle;
++
++=C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT);
++
++=C2=A0 =C2=A0 return gss_verify_mic_iov(minor_status, sc->ctx_handle, = qop_state, iov,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0iov_count);
+ }
+
+@@ -2881,7 +3002,12 @@ spnego_gss_get_mic_iov_length(OM_uint32 *minor_stat= us,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_ctx_id_t context_handle, gss_qop_t qop_r= eq,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_iov_buffer_desc *iov, int iov_count)
+ {
+-=C2=A0 =C2=A0 return gss_get_mic_iov_length(minor_status, context_handle,= qop_req, iov,
++=C2=A0 =C2=A0 spnego_gss_ctx_id_t sc =3D (spnego_gss_ctx_id_t)context_han= dle;
++
++=C2=A0 =C2=A0 if (sc->ctx_handle =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (GSS_S_NO_CONTEXT);
++
++=C2=A0 =C2=A0 return gss_get_mic_iov_length(minor_status, sc->ctx_hand= le, qop_req, iov,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0iov_count);
+ }
+
diff --git a/main/krb5/CVE-2015-2696.patch b/main/krb5/CVE-2015-2696.patch<= br> new file mode 100644
index 0000000..c1f50a5
--- /dev/null
+++ b/main/krb5/CVE-2015-2696.patch
@@ -0,0 +1,731 @@
+From e04f0283516e80d2f93366e0d479d13c9b5c8c2a Mon Sep 17 00:00:00 2001
+From: Nicolas Williams <nico@twosigma.com>
+Date: Mon, 14 Sep 2015 12:28:36 -0400
+Subject: [PATCH] Fix IAKERB context aliasing bugs [CVE-2015-2696]
+
+The IAKERB mechanism currently replaces its context handle with the
+krb5 mechanism handle upon establishment, under the assumption that
+most GSS functions are only called after context establishment.=C2=A0 This=
+assumption is incorrect, and can lead to aliasing violations for some
+programs.=C2=A0 Maintain the IAKERB context structure after context
+establishment and add new IAKERB entry points to refer to it with that
+type.=C2=A0 Add initiate and established flags to the IAKERB context
+structure for use in gss_inquire_context() prior to context
+establishment.
+
+CVE-2015-2696:
+
+In MIT krb5 1.9 and later, applications which call
+gss_inquire_context() on a partially-established IAKERB context can
+cause the GSS-API library to read from a pointer using the wrong type,
+generally causing a process crash.=C2=A0 Java server applications using th= e
+native JGSS provider are vulnerable to this bug.=C2=A0 A carefully crafted=
+IAKERB packet might allow the gss_inquire_context() call to succeed
+with attacker-determined results, but applications should not make
+access control decisions based on gss_inquire_context() results prior
+to context establishment.
+
+=C2=A0 =C2=A0 CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:C/E:POC/RL:OF/RC:C +
+[ghudson@mit.edu:= several bugfixes, style changes, and edge-case
+behavior changes; commit message and CVE description]
+
+ticket: 8244
+target_version: 1.14
+tags: pullup
+---
+ src/lib/gssapi/krb5/gssapiP_krb5.h | 114 ++++++++++++
+ src/lib/gssapi/krb5/gssapi_krb5.c=C2=A0 | 105 +++++++++--
+ src/lib/gssapi/krb5/iakerb.c=C2=A0 =C2=A0 =C2=A0 =C2=A0| 351 ++++++++++++= +++++++++++++++++++++----
+ 3 files changed, 529 insertions(+), 41 deletions(-)
+
+diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssa= piP_krb5.h
+index 9aae12a..97e090d 100644
+--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
++++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
+@@ -621,6 +621,21 @@ OM_uint32 KRB5_CALLCONV krb5_gss_accept_sec_context_e= xt
+ );
+ #endif /* LEAN_CLIENT */
+
++OM_uint32 KRB5_CALLCONV krb5_gss_inquire_sec_context_by_oid
++(OM_uint32*,=C2=A0 =C2=A0 =C2=A0 =C2=A0/* minor_status */
++ const gss_ctx_id_t,
++ /* context_handle */
++ const gss_OID,=C2=A0 =C2=A0 /* desired_object */
++ gss_buffer_set_t* /* data_set */
++);
++
++OM_uint32 KRB5_CALLCONV krb5_gss_set_sec_context_option
++(OM_uint32*,=C2=A0 =C2=A0 =C2=A0 =C2=A0/* minor_status */
++ gss_ctx_id_t*,=C2=A0 =C2=A0 /* context_handle */
++ const gss_OID,=C2=A0 =C2=A0 /* desired_object */
++ const gss_buffer_t/* value */
++);
++
+ OM_uint32 KRB5_CALLCONV krb5_gss_process_context_token
+ (OM_uint32*,=C2=A0 =C2=A0 =C2=A0 =C2=A0/* minor_status */
+=C2=A0 gss_ctx_id_t,=C2=A0 =C2=A0 =C2=A0/* context_handle */
+@@ -1302,6 +1317,105 @@ OM_uint32 KRB5_CALLCONV
+ krb5_gss_import_cred(OM_uint32 *minor_status, gss_buffer_t token,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 gss_cred_id_t *cred_handle);
+
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_process_context_token(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const gss_ctx_id_t context_han= dle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const gss_buffer_t token_buffe= r);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_context_time(OM_uint32 *minor_status, gss_ctx_id_t context_han= dle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 OM_uint32 *time_rec);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_inquire_context(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_ctx_id_t context_handle, gss_name_t *src_name,<= br> ++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_name_t *targ_name, OM_uint32 *lifetime_rec,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_OID *mech_type, OM_uint32 *ctx_flags,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0int *locally_initiated, int *opened);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_get_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handle,<= br> ++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_= qop_t qop_req, gss_buffer_t message_buffer,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_= buffer_t message_token);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_hand= le,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0gss_qop_t qop_req, gss_iov_buffer_desc *iov,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0int iov_count);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_get_mic_iov_length(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_ctx_id_t context_handle, gss_qop_t qop_= req,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_iov_buffer_desc *iov, int iov_count); ++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_verify_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handl= e,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 gss_buffer_t msg_buffer, gss_buffer_t token_buffer,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 gss_qop_t *qop_state);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_h= andle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 gss_qop_t *qop_state, gss_iov_buffer_desc *iov,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 int iov_count);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_wrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int conf_req_flag= , gss_qop_t qop_req,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_buffer_t inpu= t_message_buffer, int *conf_state,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_buffer_t outp= ut_message_buffer);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_wrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,=
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int= conf_req_flag, gss_qop_t qop_req, int *conf_state,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss= _iov_buffer_desc *iov, int iov_count);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_wrap_iov_length(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_ctx_id_t context_handle, int conf_req_flag,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_qop_t qop_req, int *conf_state,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_iov_buffer_desc *iov, int iov_count);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_unwrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle, ++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_buffer= _t input_message_buffer,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_buffer= _t output_message_buffer, int *conf_state,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_qop_t = *qop_state);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_unwrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handl= e,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 int *conf_state, gss_qop_t *qop_state,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 gss_iov_buffer_desc *iov, int iov_count);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_wrap_size_limit(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_ctx_id_t context_handle, int conf_req_flag,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_qop_t qop_req, OM_uint32 req_output_size,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 *max_input_size);
++
++#ifndef LEAN_CLIENT
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_export_sec_context(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_ctx_id_t *context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_buffer_t interprocess_token);
++#endif /* LEAN_CLIENT */
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_inquire_sec_context_by_oid(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 const gss_ctx_i= d_t context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 const gss_OID d= esired_object,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_buffer_set_= t *data_set);
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_set_sec_context_option(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_ctx_id_t *context_handle,=
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 const gss_OID desired_object,=
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 const gss_buffer_t value); ++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_pseudo_random(OM_uint32 *minor_status, gss_ctx_id_t context_ha= ndle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0int prf_key, const gss_buffer_t prf_in,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0ssize_t desired_output_len, gss_buffer_t prf_out);
++
+ /* Magic string to identify exported krb5 GSS credentials.=C2=A0 Incremen= t this if
+=C2=A0 * the format changes. */
+ #define CRED_EXPORT_MAGIC "K5C1"
+diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssap= i_krb5.c
+index 0be92e4..c4dfdd6 100644
+--- a/src/lib/gssapi/krb5/gssapi_krb5.c
++++ b/src/lib/gssapi/krb5/gssapi_krb5.c
+@@ -351,7 +351,7 @@ static struct {
+=C2=A0 =C2=A0 =C2=A0}
+ };
+
+-static OM_uint32 KRB5_CALLCONV
++OM_uint32 KRB5_CALLCONV
+ krb5_gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 const gss_ctx_i= d_t context_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 const gss_OID d= esired_object,
+@@ -465,7 +465,7 @@ static struct {
+ };
+ #endif
+
+-static OM_uint32 KRB5_CALLCONV
++OM_uint32 KRB5_CALLCONV
+ krb5_gss_set_sec_context_option (OM_uint32 *minor_status,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_ctx_id_t *context_handle,=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 const gss_OID desired_object,=
+@@ -929,20 +929,103 @@ static struct gss_config krb5_mechanism =3D {
+=C2=A0 =C2=A0 =C2=A0krb5_gss_get_mic_iov_length,
+ };
+
++/* Functions which use security contexts or acquire creds are IAKERB-spec= ific;
++ * other functions can borrow from the krb5 mech. */
++static struct gss_config iakerb_mechanism =3D {
++=C2=A0 =C2=A0 { GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID },
++=C2=A0 =C2=A0 NULL,
++=C2=A0 =C2=A0 iakerb_gss_acquire_cred,
++=C2=A0 =C2=A0 krb5_gss_release_cred,
++=C2=A0 =C2=A0 iakerb_gss_init_sec_context,
++#ifdef LEAN_CLIENT
++=C2=A0 =C2=A0 NULL,
++#else
++=C2=A0 =C2=A0 iakerb_gss_accept_sec_context,
++#endif
++=C2=A0 =C2=A0 iakerb_gss_process_context_token,
++=C2=A0 =C2=A0 iakerb_gss_delete_sec_context,
++=C2=A0 =C2=A0 iakerb_gss_context_time,
++=C2=A0 =C2=A0 iakerb_gss_get_mic,
++=C2=A0 =C2=A0 iakerb_gss_verify_mic,
++#if defined(IOV_SHIM_EXERCISE_WRAP) || defined(IOV_SHIM_EXERCISE)
++=C2=A0 =C2=A0 NULL,
++#else
++=C2=A0 =C2=A0 iakerb_gss_wrap,
++#endif
++#if defined(IOV_SHIM_EXERCISE_UNWRAP) || defined(IOV_SHIM_EXERCISE)
++=C2=A0 =C2=A0 NULL,
++#else
++=C2=A0 =C2=A0 iakerb_gss_unwrap,
++#endif
++=C2=A0 =C2=A0 krb5_gss_display_status,
++=C2=A0 =C2=A0 krb5_gss_indicate_mechs,
++=C2=A0 =C2=A0 krb5_gss_compare_name,
++=C2=A0 =C2=A0 krb5_gss_display_name,
++=C2=A0 =C2=A0 krb5_gss_import_name,
++=C2=A0 =C2=A0 krb5_gss_release_name,
++=C2=A0 =C2=A0 krb5_gss_inquire_cred,
++=C2=A0 =C2=A0 NULL,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 /* add_cred */
++#ifdef LEAN_CLIENT
++=C2=A0 =C2=A0 NULL,
++=C2=A0 =C2=A0 NULL,
++#else
++=C2=A0 =C2=A0 iakerb_gss_export_sec_context,
++=C2=A0 =C2=A0 NULL,
++#endif
++=C2=A0 =C2=A0 krb5_gss_inquire_cred_by_mech,
++=C2=A0 =C2=A0 krb5_gss_inquire_names_for_mech,
++=C2=A0 =C2=A0 iakerb_gss_inquire_context,
++=C2=A0 =C2=A0 krb5_gss_internal_release_oid,
++=C2=A0 =C2=A0 iakerb_gss_wrap_size_limit,
++=C2=A0 =C2=A0 krb5_gss_localname,
++=C2=A0 =C2=A0 krb5_gss_authorize_localname,
++=C2=A0 =C2=A0 krb5_gss_export_name,
++=C2=A0 =C2=A0 krb5_gss_duplicate_name,
++=C2=A0 =C2=A0 krb5_gss_store_cred,
++=C2=A0 =C2=A0 iakerb_gss_inquire_sec_context_by_oid,
++=C2=A0 =C2=A0 krb5_gss_inquire_cred_by_oid,
++=C2=A0 =C2=A0 iakerb_gss_set_sec_context_option,
++=C2=A0 =C2=A0 krb5_gssspi_set_cred_option,
++=C2=A0 =C2=A0 krb5_gssspi_mech_invoke,
++=C2=A0 =C2=A0 NULL,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 /* wrap_aead */
++=C2=A0 =C2=A0 NULL,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 /* unwrap_aead */
++=C2=A0 =C2=A0 iakerb_gss_wrap_iov,
++=C2=A0 =C2=A0 iakerb_gss_unwrap_iov,
++=C2=A0 =C2=A0 iakerb_gss_wrap_iov_length,
++=C2=A0 =C2=A0 NULL,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* complete_auth_token */
++=C2=A0 =C2=A0 NULL,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* acquire_cred_impersonate_name */
++=C2=A0 =C2=A0 NULL,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* add_cred_impersonate_name */
++=C2=A0 =C2=A0 NULL,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* display_name_ext */
++=C2=A0 =C2=A0 krb5_gss_inquire_name,
++=C2=A0 =C2=A0 krb5_gss_get_name_attribute,
++=C2=A0 =C2=A0 krb5_gss_set_name_attribute,
++=C2=A0 =C2=A0 krb5_gss_delete_name_attribute,
++=C2=A0 =C2=A0 krb5_gss_export_name_composite,
++=C2=A0 =C2=A0 krb5_gss_map_name_to_any,
++=C2=A0 =C2=A0 krb5_gss_release_any_name_mapping,
++=C2=A0 =C2=A0 iakerb_gss_pseudo_random,
++=C2=A0 =C2=A0 NULL,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* set_neg_mechs */
++=C2=A0 =C2=A0 krb5_gss_inquire_saslname_for_mech,
++=C2=A0 =C2=A0 krb5_gss_inquire_mech_for_saslname,
++=C2=A0 =C2=A0 krb5_gss_inquire_attrs_for_mech,
++=C2=A0 =C2=A0 krb5_gss_acquire_cred_from,
++=C2=A0 =C2=A0 krb5_gss_store_cred_into,
++=C2=A0 =C2=A0 iakerb_gss_acquire_cred_with_password,
++=C2=A0 =C2=A0 krb5_gss_export_cred,
++=C2=A0 =C2=A0 krb5_gss_import_cred,
++=C2=A0 =C2=A0 NULL,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* import_sec_context_by_mech */
++=C2=A0 =C2=A0 NULL,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* import_name_by_mech */
++=C2=A0 =C2=A0 NULL,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* import_cred_by_mech */
++=C2=A0 =C2=A0 iakerb_gss_get_mic_iov,
++=C2=A0 =C2=A0 iakerb_gss_verify_mic_iov,
++=C2=A0 =C2=A0 iakerb_gss_get_mic_iov_length,
++};
++
+ #ifdef _GSS_STATIC_LINK
+ #include "mglueP.h"
+ static int gss_iakerbmechglue_init(void)
+ {
+=C2=A0 =C2=A0 =C2=A0struct gss_mech_config mech_iakerb;
+-=C2=A0 =C2=A0 struct gss_config iakerb_mechanism =3D krb5_mechanism;
+-
+-=C2=A0 =C2=A0 /* IAKERB mechanism mirrors krb5, but with different contex= t SPIs */
+-=C2=A0 =C2=A0 iakerb_mechanism.gss_accept_sec_context =3D iakerb_gss_acce= pt_sec_context;
+-=C2=A0 =C2=A0 iakerb_mechanism.gss_init_sec_context=C2=A0 =C2=A0=3D iaker= b_gss_init_sec_context;
+-=C2=A0 =C2=A0 iakerb_mechanism.gss_delete_sec_context =3D iakerb_gss_dele= te_sec_context;
+-=C2=A0 =C2=A0 iakerb_mechanism.gss_acquire_cred=C2=A0 =C2=A0 =C2=A0 =C2= =A0=3D iakerb_gss_acquire_cred;
+-=C2=A0 =C2=A0 iakerb_mechanism.gssspi_acquire_cred_with_password
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D iakerb_gss_acquire= _cred_with_password;
+
+=C2=A0 =C2=A0 =C2=A0memset(&mech_iakerb, 0, sizeof(mech_iakerb));
+=C2=A0 =C2=A0 =C2=A0mech_iakerb.mech =3D &iakerb_mechanism;
+diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c +index f30de32..4662bd9 100644
+--- a/src/lib/gssapi/krb5/iakerb.c
++++ b/src/lib/gssapi/krb5/iakerb.c
+@@ -47,6 +47,8 @@ struct _iakerb_ctx_id_rec {
+=C2=A0 =C2=A0 =C2=A0gss_ctx_id_t gssc;
+=C2=A0 =C2=A0 =C2=A0krb5_data conv;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* conversation for checksumming */ +=C2=A0 =C2=A0 =C2=A0unsigned int count;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0/* number of round trips */
++=C2=A0 =C2=A0 int initiate;
++=C2=A0 =C2=A0 int established;
+=C2=A0 =C2=A0 =C2=A0krb5_get_init_creds_opt *gic_opts;
+ };
+
+@@ -695,7 +697,7 @@ iakerb_get_initial_state(iakerb_ctx_id_t ctx,
+=C2=A0 * Allocate and initialise an IAKERB context
+=C2=A0 */
+ static krb5_error_code
+-iakerb_alloc_context(iakerb_ctx_id_t *pctx)
++iakerb_alloc_context(iakerb_ctx_id_t *pctx, int initiate)
+ {
+=C2=A0 =C2=A0 =C2=A0iakerb_ctx_id_t ctx;
+=C2=A0 =C2=A0 =C2=A0krb5_error_code code;
+@@ -709,6 +711,8 @@ iakerb_alloc_context(iakerb_ctx_id_t *pctx)
+=C2=A0 =C2=A0 =C2=A0ctx->magic =3D KG_IAKERB_CONTEXT;
+=C2=A0 =C2=A0 =C2=A0ctx->state =3D IAKERB_AS_REQ;
+=C2=A0 =C2=A0 =C2=A0ctx->count =3D 0;
++=C2=A0 =C2=A0 ctx->initiate =3D initiate;
++=C2=A0 =C2=A0 ctx->established =3D 0;
+
+=C2=A0 =C2=A0 =C2=A0code =3D krb5_gss_init_context(&ctx->k5c);
+=C2=A0 =C2=A0 =C2=A0if (code !=3D 0)
+@@ -732,7 +736,7 @@ iakerb_gss_delete_sec_context(OM_uint32 *minor_status,=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_ctx_id_t *context_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_buffer_t output_token)
+ {
+-=C2=A0 =C2=A0 OM_uint32 major_status =3D GSS_S_COMPLETE;
++=C2=A0 =C2=A0 iakerb_ctx_id_t iakerb_ctx =3D (iakerb_ctx_id_t)*context_ha= ndle;
+
+=C2=A0 =C2=A0 =C2=A0if (output_token !=3D GSS_C_NO_BUFFER) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0output_token->length =3D 0;
+@@ -740,23 +744,10 @@ iakerb_gss_delete_sec_context(OM_uint32 *minor_statu= s,
+=C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0*minor_status =3D 0;
++=C2=A0 =C2=A0 *context_handle =3D GSS_C_NO_CONTEXT;
++=C2=A0 =C2=A0 iakerb_release_context(iakerb_ctx);
+
+-=C2=A0 =C2=A0 if (*context_handle !=3D GSS_C_NO_CONTEXT) {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 iakerb_ctx_id_t iakerb_ctx =3D (iakerb_ctx_id= _t)*context_handle;
+-
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (iakerb_ctx->magic =3D=3D KG_IAKERB_CON= TEXT) {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iakerb_release_context(iakerb_c= tx);
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *context_handle =3D GSS_C_NO_CO= NTEXT;
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 } else {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 assert(iakerb_ctx->magic =3D= =3D KG_CONTEXT);
+-
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 major_status =3D krb5_gss_delet= e_sec_context(minor_status,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0context_handle,
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0output_token);
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+-=C2=A0 =C2=A0 }
+-
+-=C2=A0 =C2=A0 return major_status;
++=C2=A0 =C2=A0 return GSS_S_COMPLETE;
+ }
+
+ static krb5_boolean
+@@ -802,7 +793,7 @@ iakerb_gss_accept_sec_context(OM_uint32 *minor_status,=
+=C2=A0 =C2=A0 =C2=A0int initialContextToken =3D (*context_handle =3D=3D GS= S_C_NO_CONTEXT);
+
+=C2=A0 =C2=A0 =C2=A0if (initialContextToken) {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 code =3D iakerb_alloc_context(&ctx);
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 code =3D iakerb_alloc_context(&ctx, 0); +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (code !=3D 0)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup;
+
+@@ -854,11 +845,8 @@ iakerb_gss_accept_sec_context(OM_uint32 *minor_status= ,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 time_rec,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 delegated_cred_handle,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &exts);
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (major_status =3D=3D GSS_S_COMPLETE) {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *context_handle =3D ctx->gss= c;
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ctx->gssc =3D NULL;
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iakerb_release_context(ctx); +-=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (major_status =3D=3D GSS_S_COMPLETE)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ctx->established =3D 1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (mech_type !=3D NULL)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*mech_type =3D (gss_OID)gs= s_mech_krb5;
+=C2=A0 =C2=A0 =C2=A0}
+@@ -897,7 +885,7 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status, +=C2=A0 =C2=A0 =C2=A0int initialContextToken =3D (*context_handle =3D=3D GS= S_C_NO_CONTEXT);
+
+=C2=A0 =C2=A0 =C2=A0if (initialContextToken) {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 code =3D iakerb_alloc_context(&ctx);
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 code =3D iakerb_alloc_context(&ctx, 1); +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (code !=3D 0) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*minor_status =3D code; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup;
+@@ -983,11 +971,8 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status,<= br> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret_flags,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 time_rec,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &exts);
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (major_status =3D=3D GSS_S_COMPLETE) {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *context_handle =3D ctx->gss= c;
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ctx->gssc =3D GSS_C_NO_CONTE= XT;
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iakerb_release_context(ctx); +-=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (major_status =3D=3D GSS_S_COMPLETE)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ctx->established =3D 1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (actual_mech_type !=3D NULL)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*actual_mech_type =3D (gss= _OID)gss_mech_krb5;
+=C2=A0 =C2=A0 =C2=A0} else {
+@@ -1010,3 +995,309 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status= ,
+
+=C2=A0 =C2=A0 =C2=A0return major_status;
+ }
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_unwrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle, ++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_buffer= _t input_message_buffer,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_buffer= _t output_message_buffer, int *conf_state,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_qop_t = *qop_state)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_unwrap(minor_status, ctx->gssc, input_me= ssage_buffer,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0output_message_buffer, conf_state, qop_state);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_wrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int conf_req_flag= , gss_qop_t qop_req,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_buffer_t inpu= t_message_buffer, int *conf_state,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_buffer_t outp= ut_message_buffer)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_wrap(minor_status, ctx->gssc, conf_req_f= lag, qop_req,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0input_message_buffer, conf_state,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0output_message_buffer);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_process_context_token(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const gss_ctx_id_t context_han= dle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const gss_buffer_t token_buffe= r)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_DEFECTIVE_TOKEN;
++
++=C2=A0 =C2=A0 return krb5_gss_process_context_token(minor_status, ctx->= ;gssc,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 t= oken_buffer);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_context_time(OM_uint32 *minor_status, gss_ctx_id_t context_han= dle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 OM_uint32 *time_rec)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_context_time(minor_status, ctx->gssc, ti= me_rec);
++}
++
++#ifndef LEAN_CLIENT
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_export_sec_context(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_ctx_id_t *context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_buffer_t interprocess_token)
++{
++=C2=A0 =C2=A0 OM_uint32 maj;
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 /* We don't currently support exporting partially estab= lished contexts. */
++=C2=A0 =C2=A0 if (!ctx->established)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_UNAVAILABLE;
++
++=C2=A0 =C2=A0 maj =3D krb5_gss_export_sec_context(minor_status, &ctx-= >gssc,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 interprocess_to= ken);
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT) {
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 iakerb_release_context(ctx);
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 *context_handle =3D GSS_C_NO_CONTEXT;
++=C2=A0 =C2=A0 }
++=C2=A0 =C2=A0 return maj;
++}
++
++/*
++ * Until we implement partial context exports, there are no SPNEGO export= ed
++ * context tokens, only tokens for the underlying krb5 context.=C2=A0 So = we do not
++ * need to implement an iakerb_gss_import_sec_context() yet; it would be<= br> ++ * unreachable except via a manually constructed token.
++ */
++
++#endif /* LEAN_CLIENT */
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_inquire_context(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_ctx_id_t context_handle, gss_name_t *src_name,<= br> ++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_name_t *targ_name, OM_uint32 *lifetime_rec,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_OID *mech_type, OM_uint32 *ctx_flags,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0int *initiate, int *opened)
++{
++=C2=A0 =C2=A0 OM_uint32 ret;
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (src_name !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 *src_name =3D GSS_C_NO_NAME;
++=C2=A0 =C2=A0 if (targ_name !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 *targ_name =3D GSS_C_NO_NAME;
++=C2=A0 =C2=A0 if (lifetime_rec !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 *lifetime_rec =3D 0;
++=C2=A0 =C2=A0 if (mech_type !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 *mech_type =3D (gss_OID)gss_mech_iakerb;
++=C2=A0 =C2=A0 if (ctx_flags !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 *ctx_flags =3D 0;
++=C2=A0 =C2=A0 if (initiate !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 *initiate =3D ctx->initiate;
++=C2=A0 =C2=A0 if (opened !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 *opened =3D ctx->established;
++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_COMPLETE;
++
++=C2=A0 =C2=A0 ret =3D krb5_gss_inquire_context(minor_status, ctx->gssc= , src_name,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0targ_name, lifetime_rec= , mech_type,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ctx_flags, initiate, op= ened);
++
++=C2=A0 =C2=A0 if (!ctx->established) {
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Report IAKERB as the mech OID until the co= ntext is established. */
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (mech_type !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *mech_type =3D (gss_OID)gss_mec= h_iakerb;
++
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* We don't support exporting partially-e= stablished contexts. */
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (ctx_flags !=3D NULL)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *ctx_flags &=3D ~GSS_C_TRAN= S_FLAG;
++=C2=A0 =C2=A0 }
++
++=C2=A0 =C2=A0 return ret;
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_wrap_size_limit(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_ctx_id_t context_handle, int conf_req_flag,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_qop_t qop_req, OM_uint32 req_output_size,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0OM_uint32 *max_input_size)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_wrap_size_limit(minor_status, ctx->gssc,= conf_req_flag,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 qop_req, req_output_si= ze, max_input_size);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_get_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handle,<= br> ++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_= qop_t qop_req, gss_buffer_t message_buffer,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0gss_= buffer_t message_token)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_get_mic(minor_status, ctx->gssc, qop_req= , message_buffer,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 message_token);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_verify_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handl= e,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 gss_buffer_t msg_buffer, gss_buffer_t token_buffer,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 gss_qop_t *qop_state)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_verify_mic(minor_status, ctx->gssc, msg_= buffer,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0token_buffer, qop_state);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_inquire_sec_context_by_oid(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 const gss_ctx_i= d_t context_handle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 const gss_OID d= esired_object,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_buffer_set_= t *data_set)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_UNAVAILABLE;
++
++=C2=A0 =C2=A0 return krb5_gss_inquire_sec_context_by_oid(minor_status, ct= x->gssc,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0desired_object, data_set);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_set_sec_context_option(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_ctx_id_t *context_handle,=
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 const gss_OID desired_object,=
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 const gss_buffer_t value)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)*context_handle; ++
++=C2=A0 =C2=A0 if (ctx =3D=3D NULL || ctx->gssc =3D=3D GSS_C_NO_CONTEXT= )
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_UNAVAILABLE;
++
++=C2=A0 =C2=A0 return krb5_gss_set_sec_context_option(minor_status, &c= tx->gssc,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0desired_object, value);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_wrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,=
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int= conf_req_flag, gss_qop_t qop_req, int *conf_state,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss= _iov_buffer_desc *iov, int iov_count)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_wrap_iov(minor_status, ctx->gssc, conf_r= eq_flag, qop_req,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0conf_state, iov, iov_count);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_unwrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handl= e,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 int *conf_state, gss_qop_t *qop_state,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 gss_iov_buffer_desc *iov, int iov_count)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_unwrap_iov(minor_status, ctx->gssc, conf= _state, qop_state,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0iov, iov_count);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_wrap_iov_length(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_ctx_id_t context_handle, int conf_req_flag,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_qop_t qop_req, int *conf_state,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0gss_iov_buffer_desc *iov, int iov_count)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_wrap_iov_length(minor_status, ctx->gssc,= conf_req_flag,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 qop_req, conf_state, i= ov, iov_count);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_pseudo_random(OM_uint32 *minor_status, gss_ctx_id_t context_ha= ndle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0int prf_key, const gss_buffer_t prf_in,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0ssize_t desired_output_len, gss_buffer_t prf_out)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_pseudo_random(minor_status, ctx->gssc, p= rf_key, prf_in,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 desired_output_len, prf_out);=
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_hand= le,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0gss_qop_t qop_req, gss_iov_buffer_desc *iov,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0int iov_count)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_get_mic_iov(minor_status, ctx->gssc, qop= _req, iov,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iov_count);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_h= andle,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 gss_qop_t *qop_state, gss_iov_buffer_desc *iov,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 int iov_count)
++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_verify_mic_iov(minor_status, ctx->gssc, = qop_state, iov,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0iov_count);
++}
++
++OM_uint32 KRB5_CALLCONV
++iakerb_gss_get_mic_iov_length(OM_uint32 *minor_status,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_ctx_id_t context_handle, gss_qop_t qop_= req,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gss_iov_buffer_desc *iov, int iov_count) ++{
++=C2=A0 =C2=A0 iakerb_ctx_id_t ctx =3D (iakerb_ctx_id_t)context_handle; ++
++=C2=A0 =C2=A0 if (ctx->gssc =3D=3D GSS_C_NO_CONTEXT)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 return GSS_S_NO_CONTEXT;
++
++=C2=A0 =C2=A0 return krb5_gss_get_mic_iov_length(minor_status, ctx->gs= sc, qop_req, iov,
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0iov_count= );
++}
diff --git a/main/krb5/CVE-2015-2697.patch b/main/krb5/CVE-2015-2697.patch<= br> new file mode 100644
index 0000000..af2f42a
--- /dev/null
+++ b/main/krb5/CVE-2015-2697.patch
@@ -0,0 +1,50 @@
+From f0c094a1b745d91ef2f9a4eae2149aac026a5789 Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Fri, 25 Sep 2015 12:51:47 -0400
+Subject: [PATCH] Fix build_principal memory bug [CVE-2015-2697]
+
+In build_principal_va(), use k5memdup0() instead of strdup() to make a
+copy of the realm, to ensure that we allocate the correct number of
+bytes and do not read past the end of the input string.=C2=A0 This bug
+affects krb5_build_principal(), krb5_build_principal_va(), and
+krb5_build_principal_alloc_va().=C2=A0 krb5_build_principal_ext() is not +affected.
+
+CVE-2015-2697:
+
+In MIT krb5 1.7 and later, an authenticated attacker may be able to
+cause a KDC to crash using a TGS request with a large realm field
+beginning with a null byte.=C2=A0 If the KDC attempts to find a referral t= o
+answer the request, it constructs a principal name for lookup using
+krb5_build_principal() with the requested realm.=C2=A0 Due to a bug in thi= s
+function, the null byte causes only one byte be allocated for the
+realm field of the constructed principal, far less than its length.
+Subsequent operations on the lookup principal may cause a read beyond
+the end of the mapped memory region, causing the KDC process to crash.
+
+CVSSv2: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C
+
+ticket: 8252 (new)
+target_version: 1.14
+tags: pullup
+---
+ src/lib/krb5/krb/bld_princ.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/src/lib/krb5/krb/bld_princ.c b/src/lib/krb5/krb/bld_princ.c +index ab6fed8..8604268 100644
+--- a/src/lib/krb5/krb/bld_princ.c
++++ b/src/lib/krb5/krb/bld_princ.c
+@@ -40,10 +40,8 @@ build_principal_va(krb5_context context, krb5_principal= princ,
+=C2=A0 =C2=A0 =C2=A0data =3D malloc(size * sizeof(krb5_data));
+=C2=A0 =C2=A0 =C2=A0if (!data) { retval =3D ENOMEM; }
+
+-=C2=A0 =C2=A0 if (!retval) {
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 r =3D strdup(realm);
+-=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!r) { retval =3D ENOMEM; }
+-=C2=A0 =C2=A0 }
++=C2=A0 =C2=A0 if (!retval)
++=C2=A0 =C2=A0 =C2=A0 =C2=A0 r =3D k5memdup0(realm, rlen, &retval); +
+=C2=A0 =C2=A0 =C2=A0while (!retval && (component =3D va_arg(ap, ch= ar *))) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (count =3D=3D size) {
--
2.6.2

--001a114b0964d6bd3d0525dd8580-- --- Unsubscribe: alpine-aports+unsubscribe@lists.alpinelinux.org Help: alpine-aports+help@lists.alpinelinux.org ---