--- /dev/null
+Index: lib/gssapi/ntlm/crypto.c
+===================================================================
+--- lib/gssapi/ntlm/crypto.c (revision 796)
++++ lib/gssapi/ntlm/crypto.c (working copy)
+@@ -1,6 +1,7 @@
+ /*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
++ * Copyright (c) 2008 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+@@ -194,10 +195,12 @@
+ v2_seal_message(const gss_buffer_t in,
+ unsigned char signkey[16],
+ uint32_t seq,
++ RC4_KEY *signsealkey,
+ RC4_KEY *sealkey,
+ gss_buffer_t out)
+ {
+ unsigned char *p;
++ unsigned char sealed_sig[16];
+ OM_uint32 ret;
+
+ if (in->length + 16 < in->length)
+@@ -207,14 +210,21 @@
+ if (p == NULL)
+ return ENOMEM;
+
+- RC4(sealkey, in->length, in->value, p);
+-
+- ret = v2_sign_message(in, signkey, sealkey, seq, &p[in->length]);
++ /* Must encrypt signature after encrypting the data, so don't specify signseal key here */
++ ret = v2_sign_message(in, signkey, NULL, seq, &p[in->length]);
+ if (ret) {
+ free(p);
+ return ret;
+ }
+
++ RC4(sealkey, in->length, in->value, p);
++
++ /* Instead deal with it here */
++ if (signsealkey) {
++ RC4(sealkey, 16, &p[in->length], sealed_sig);
++ memcpy(&p[in->length], sealed_sig, 16);
++ }
++
+ out->value = p;
+ out->length = in->length + 16;
+
+@@ -225,6 +235,7 @@
+ v2_unseal_message(gss_buffer_t in,
+ unsigned char signkey[16],
+ uint32_t seq,
++ RC4_KEY *signsealkey,
+ RC4_KEY *sealkey,
+ gss_buffer_t out)
+ {
+@@ -240,7 +251,7 @@
+
+ RC4(sealkey, out->length, in->value, out->value);
+
+- ret = v2_verify_message(out, signkey, sealkey, seq,
++ ret = v2_verify_message(out, signkey, signsealkey, seq,
+ ((const unsigned char *)in->value) + out->length);
+ if (ret) {
+ OM_uint32 junk;
+@@ -249,6 +260,103 @@
+ return ret;
+ }
+
++static OM_uint32
++v2_seal_message_ex(const gss_buffer_t in_to_sign,
++ const gss_buffer_t in_to_seal,
++ unsigned char signkey[16],
++ uint32_t seq,
++ RC4_KEY *signsealkey,
++ RC4_KEY *sealkey,
++ gss_buffer_t out_signature,
++ gss_buffer_t out_sealed)
++{
++ unsigned char *p;
++ unsigned char sealed_sig[16];
++ OM_uint32 ret;
++
++ out_sealed->value = malloc(in_to_seal->length);
++ if (out_sealed->value == NULL)
++ return ENOMEM;
++
++ out_signature->value = malloc(16);
++ if (out_signature->value == NULL) {
++ free(out_sealed->value);
++ return ENOMEM;
++ }
++
++ /* Must encrypt signature after encrypting the data, so don't specify signseal key here */
++ ret = v2_sign_message(in_to_sign, signkey, NULL, seq, out_signature->value);
++ if (ret) {
++ free(p);
++ return ret;
++ }
++
++ out_signature->length = 16;
++
++ RC4(sealkey, in_to_seal->length, in_to_seal->value, out_sealed->value);
++
++ out_sealed->length = in_to_sign->length;
++
++ /* Instead deal with it here */
++ if (signsealkey) {
++ RC4(sealkey, 16, out_signature->value, sealed_sig);
++ memcpy(out_signature->value, sealed_sig, 16);
++ }
++
++ return 0;
++}
++
++static OM_uint32
++v2_unseal_message_ex(gss_buffer_t in_signed,
++ gss_buffer_t in_sealed,
++ gss_buffer_t in_signature,
++ unsigned char signkey[16],
++ uint32_t seq,
++ RC4_KEY *signsealkey,
++ RC4_KEY *sealkey,
++ gss_buffer_t out_unsealed)
++{
++ OM_uint32 ret;
++ gss_buffer_desc unsealed_with_aead;
++
++ if (in_sealed->value < in_signed->value) {
++ return GSS_S_BAD_MIC;
++ }
++
++ if (&((char *)in_sealed->value)[in_sealed->length] > &((char *)in_signed->value)[in_signed->length]) {
++ return GSS_S_BAD_MIC;
++ }
++
++ if (in_signature->length < 16)
++ return GSS_S_BAD_MIC;
++
++ unsealed_with_aead.value = malloc(in_signed->length);
++ if (unsealed_with_aead.value == NULL)
++ return ENOMEM;
++
++ out_unsealed->length = in_sealed->length;
++ out_unsealed->value = malloc(out_unsealed->length);
++ if (out_unsealed->value == NULL) {
++ free(unsealed_with_aead.value);
++ return GSS_S_BAD_MIC;
++ }
++
++ RC4(sealkey, out_unsealed->length, in_sealed->value, out_unsealed->value);
++
++ memcpy(unsealed_with_aead.value, in_signed->value, in_signed->length);
++
++ /* Someone please check this is doing the right thing... */
++ memcpy(&((char *)unsealed_with_aead.value)[(char *)in_sealed->value - (char *)in_signed->value],
++ out_unsealed->value, out_unsealed->length);
++
++ ret = v2_verify_message(&unsealed_with_aead, signkey, sealkey, seq, in_signature->value);
++ if (ret) {
++ OM_uint32 junk;
++ gss_release_buffer(&junk, out_unsealed);
++ }
++ return ret;
++}
++
+ /*
+ *
+ */
+@@ -482,6 +590,7 @@
+ return v2_seal_message(input_message_buffer,
+ ctx->u.v2.send.signkey,
+ ctx->u.v2.send.seq++,
++ ctx->u.v2.send.signsealkey,
+ &ctx->u.v2.send.sealkey,
+ output_message_buffer);
+
+@@ -555,6 +664,7 @@
+ return v2_unseal_message(input_message_buffer,
+ ctx->u.v2.recv.signkey,
+ ctx->u.v2.recv.seq++,
++ ctx->u.v2.send.signsealkey,
+ &ctx->u.v2.recv.sealkey,
+ output_message_buffer);
+
+@@ -593,3 +703,134 @@
+
+ return GSS_S_UNAVAILABLE;
+ }
++/*
++ *
++ */
++
++OM_uint32 _gss_ntlm_wrap_ex
++(OM_uint32 * minor_status,
++ const gss_ctx_id_t context_handle,
++ int conf_req_flag,
++ gss_qop_t qop_req,
++ const gss_buffer_t associated_data_buffer,
++ const gss_buffer_t input_message_buffer,
++ int * conf_state,
++ gss_buffer_t output_token_buffer,
++ gss_buffer_t output_message_buffer
++ )
++{
++ ntlm_ctx ctx = (ntlm_ctx)context_handle;
++ OM_uint32 ret;
++
++ if (minor_status)
++ *minor_status = 0;
++ if (conf_state)
++ *conf_state = 0;
++ if (output_message_buffer == GSS_C_NO_BUFFER)
++ return GSS_S_FAILURE;
++
++
++ if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SEAL|NTLM_NEG_NTLM2_SESSION)) {
++
++ return v2_seal_message_ex(associated_data_buffer,
++ input_message_buffer,
++ ctx->u.v2.send.signkey,
++ ctx->u.v2.send.seq++,
++ ctx->u.v2.send.signsealkey,
++ &ctx->u.v2.send.sealkey,
++ output_token_buffer,
++ output_message_buffer);
++
++ } else if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SEAL)) {
++ OM_uint32 junk;
++
++ output_message_buffer->length = input_message_buffer->length;
++ output_message_buffer->value = malloc(output_message_buffer->length);
++ if (output_message_buffer->value == NULL) {
++ output_message_buffer->length = 0;
++ return GSS_S_FAILURE;
++ }
++
++
++ RC4(&ctx->u.v1.crypto_send.key, input_message_buffer->length,
++ input_message_buffer->value, output_message_buffer->value);
++
++ ret = _gss_ntlm_get_mic(minor_status, context_handle,
++ 0, input_message_buffer,
++ output_token_buffer);
++ if (ret) {
++ gss_release_buffer(&junk, output_message_buffer);
++ return ret;
++ }
++ return GSS_S_COMPLETE;
++ }
++
++ return GSS_S_UNAVAILABLE;
++}
++
++/*
++ *
++ */
++
++OM_uint32 _gss_ntlm_unwrap_ex
++(OM_uint32 * minor_status,
++ const gss_ctx_id_t context_handle,
++ const gss_buffer_t token_header_buffer,
++ const gss_buffer_t associated_data_buffer,
++ const gss_buffer_t input_message_buffer,
++ gss_buffer_t output_message_buffer,
++ int * conf_state,
++ gss_qop_t * qop_state
++ )
++{
++ ntlm_ctx ctx = (ntlm_ctx)context_handle;
++ OM_uint32 ret;
++
++ if (minor_status)
++ *minor_status = 0;
++ if (output_message_buffer) {
++ output_message_buffer->value = NULL;
++ output_message_buffer->length = 0;
++ }
++ if (conf_state)
++ *conf_state = 0;
++ if (qop_state)
++ *qop_state = 0;
++
++ if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SEAL|NTLM_NEG_NTLM2_SESSION)) {
++
++ return v2_unseal_message_ex(associated_data_buffer,
++ input_message_buffer,
++ token_header_buffer,
++ ctx->u.v2.recv.signkey,
++ ctx->u.v2.recv.seq++,
++ ctx->u.v2.recv.signsealkey,
++ &ctx->u.v2.recv.sealkey,
++ output_message_buffer);
++
++ } else if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SEAL)) {
++ OM_uint32 junk;
++
++ output_message_buffer->length = input_message_buffer->length;
++ output_message_buffer->value = malloc(output_message_buffer->length);
++ if (output_message_buffer->value == NULL) {
++ output_message_buffer->length = 0;
++ return GSS_S_FAILURE;
++ }
++
++ RC4(&ctx->u.v1.crypto_recv.key, output_message_buffer->length,
++ input_message_buffer->value, output_message_buffer->value);
++
++ ret = _gss_ntlm_verify_mic(minor_status, context_handle,
++ output_message_buffer,
++ token_header_buffer, NULL);
++ if (ret) {
++ gss_release_buffer(&junk, output_message_buffer);
++ return ret;
++ }
++
++ return GSS_S_COMPLETE;
++ }
++
++ return GSS_S_UNAVAILABLE;
++}
+Index: lib/gssapi/ntlm/external.c
+===================================================================
+--- lib/gssapi/ntlm/external.c (revision 796)
++++ lib/gssapi/ntlm/external.c (working copy)
+@@ -50,6 +50,8 @@
+ _gss_ntlm_verify_mic,
+ _gss_ntlm_wrap,
+ _gss_ntlm_unwrap,
++ _gss_ntlm_wrap_ex,
++ _gss_ntlm_unwrap_ex,
+ _gss_ntlm_display_status,
+ NULL,
+ _gss_ntlm_compare_name,