2020-08-03 19:39:37 +00:00
|
|
|
From bedbb5ee1ad821b91f00d30361985e6863c0e6ba Mon Sep 17 00:00:00 2001
|
2020-07-22 21:28:11 +00:00
|
|
|
From: Greg Hudson <ghudson@mit.edu>
|
|
|
|
Date: Sat, 11 Jul 2020 21:57:30 -0400
|
|
|
|
Subject: [PATCH] Allow gss_unwrap_iov() of unpadded RC4 tokens
|
|
|
|
|
|
|
|
Windows Remote Management, when used with an RC4 session key, appears
|
|
|
|
to generate GSS wrap tokens with no padding instead of the expected
|
|
|
|
one byte (RFC 4757 section 7.3). These tokens cannot be decoded with
|
|
|
|
gss_unwrap() or a STREAM buffer (even with Microsoft SSPI), but SSPI
|
|
|
|
allows them to be decoded using explicit IOVs with either a
|
|
|
|
zero-length padding buffer or no padding buffer. Allow these cases to
|
|
|
|
work in kg_fixup_padding_iov(). (It is already possible to make this
|
|
|
|
work with HEADER | DATA | DATA, but only by
|
|
|
|
accident--kg_fixup_padding_iov() doesn't find a data buffer because
|
|
|
|
kg_locate_iov() only looks for singleton buffers, so it exits early.)
|
|
|
|
|
|
|
|
ticket: 8926 (new)
|
|
|
|
tags: pullup
|
|
|
|
target_version: 1.18-next
|
|
|
|
|
|
|
|
(cherry picked from commit 3f204ddd567715ef360b4bb0b32961b6a9877f9d)
|
|
|
|
---
|
|
|
|
src/lib/gssapi/krb5/util_crypt.c | 9 +++------
|
|
|
|
1 file changed, 3 insertions(+), 6 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c
|
|
|
|
index f7d3e92c4..d6c71aeb8 100644
|
|
|
|
--- a/src/lib/gssapi/krb5/util_crypt.c
|
|
|
|
+++ b/src/lib/gssapi/krb5/util_crypt.c
|
|
|
|
@@ -638,16 +638,13 @@ kg_fixup_padding_iov(OM_uint32 *minor_status, gss_iov_buffer_desc *iov,
|
|
|
|
data = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_DATA);
|
|
|
|
padding = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
|
|
|
|
|
|
|
|
- if (data == NULL) {
|
|
|
|
+ /* Do nothing if padding is absent or empty, to allow unwrapping of WinRM
|
|
|
|
+ * unpadded RC4 tokens using an explicit IOV array. */
|
|
|
|
+ if (data == NULL || padding == NULL || padding->buffer.length == 0) {
|
|
|
|
*minor_status = 0;
|
|
|
|
return GSS_S_COMPLETE;
|
|
|
|
}
|
|
|
|
|
|
|
|
- if (padding == NULL || padding->buffer.length == 0) {
|
|
|
|
- *minor_status = EINVAL;
|
|
|
|
- return GSS_S_FAILURE;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
p = (unsigned char *)padding->buffer.value;
|
|
|
|
padlength = p[padding->buffer.length - 1];
|
|
|
|
|