diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 7e0a17ef..4cad25e2 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -266,6 +266,7 @@ patch_enable_all () enable_rpcrt4_Pipe_Transport="$1" enable_rpcrt4_RpcBindingServerFromClient="$1" enable_secur32_ANSI_NTLM_Credentials="$1" + enable_secur32_Zero_Buffer_Length="$1" enable_server_ClipCursor="$1" enable_server_CreateProcess_ACLs="$1" enable_server_Desktop_Refcount="$1" @@ -962,6 +963,9 @@ patch_enable () secur32-ANSI_NTLM_Credentials) enable_secur32_ANSI_NTLM_Credentials="$2" ;; + secur32-Zero_Buffer_Length) + enable_secur32_Zero_Buffer_Length="$2" + ;; server-ClipCursor) enable_server_ClipCursor="$2" ;; @@ -5676,6 +5680,21 @@ if test "$enable_secur32_ANSI_NTLM_Credentials" -eq 1; then ) >> "$patchlist" fi +# Patchset secur32-Zero_Buffer_Length +# | +# | This patchset fixes the following Wine bugs: +# | * [#40271] Set buffer size to zero when InitializeSecurityContextW returns no data +# | +# | Modified files: +# | * dlls/secur32/schannel.c, dlls/secur32/tests/schannel.c +# | +if test "$enable_secur32_Zero_Buffer_Length" -eq 1; then + patch_apply secur32-Zero_Buffer_Length/0001-secur32-Set-output-buffer-size-to-zero-during-handsh.patch + ( + echo '+ { "Michael Müller", "secur32: Set output buffer size to zero during handshake when no data needs to be sent.", 1 },'; + ) >> "$patchlist" +fi + # Patchset server-ClipCursor # | # | This patchset fixes the following Wine bugs: diff --git a/patches/secur32-Zero_Buffer_Length/0001-secur32-Set-output-buffer-size-to-zero-during-handsh.patch b/patches/secur32-Zero_Buffer_Length/0001-secur32-Set-output-buffer-size-to-zero-during-handsh.patch new file mode 100644 index 00000000..2015951b --- /dev/null +++ b/patches/secur32-Zero_Buffer_Length/0001-secur32-Set-output-buffer-size-to-zero-during-handsh.patch @@ -0,0 +1,88 @@ +From 26a78718c5c5d3f03174784b0823cb5d892963c4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 8 May 2016 21:52:06 +0200 +Subject: secur32: Set output buffer size to zero during handshake when no data + needs to be sent. + +--- + dlls/secur32/schannel.c | 19 ++++++++++++------- + dlls/secur32/tests/schannel.c | 10 ++++++++-- + 2 files changed, 20 insertions(+), 9 deletions(-) + +diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c +index c6cc4d1..e238da4 100644 +--- a/dlls/secur32/schannel.c ++++ b/dlls/secur32/schannel.c +@@ -892,6 +892,18 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW( + /* Perform the TLS handshake */ + ret = schan_imp_handshake(ctx->session); + ++ out_buffers = &transport.out; ++ if (out_buffers->current_buffer_idx != -1) ++ { ++ SecBuffer *buffer = &out_buffers->desc->pBuffers[out_buffers->current_buffer_idx]; ++ buffer->cbBuffer = out_buffers->offset; ++ } ++ else if (out_buffers->desc && out_buffers->desc->cBuffers > 0) ++ { ++ SecBuffer *buffer = &out_buffers->desc->pBuffers[0]; ++ buffer->cbBuffer = 0; ++ } ++ + if(transport.in.offset && transport.in.offset != pInput->pBuffers[0].cbBuffer) { + if(pInput->cBuffers<2 || pInput->pBuffers[1].BufferType!=SECBUFFER_EMPTY) + return SEC_E_INVALID_TOKEN; +@@ -900,13 +912,6 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW( + pInput->pBuffers[1].cbBuffer = pInput->pBuffers[0].cbBuffer-transport.in.offset; + } + +- out_buffers = &transport.out; +- if (out_buffers->current_buffer_idx != -1) +- { +- SecBuffer *buffer = &out_buffers->desc->pBuffers[out_buffers->current_buffer_idx]; +- buffer->cbBuffer = out_buffers->offset; +- } +- + *pfContextAttr = 0; + if (ctx->req_ctx_attr & ISC_REQ_REPLAY_DETECT) + *pfContextAttr |= ISC_RET_REPLAY_DETECT; +diff --git a/dlls/secur32/tests/schannel.c b/dlls/secur32/tests/schannel.c +index 51c22d5..6773525 100644 +--- a/dlls/secur32/tests/schannel.c ++++ b/dlls/secur32/tests/schannel.c +@@ -822,7 +822,6 @@ todo_wine + ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, + 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL); + ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status); +-todo_wine + ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n"); + + buffers[0].pBuffers[0].cbBuffer = 0; +@@ -832,9 +831,15 @@ todo_wine + todo_wine + ok(status == SEC_E_INSUFFICIENT_MEMORY || status == SEC_E_INVALID_TOKEN, + "Expected SEC_E_INSUFFICIENT_MEMORY or SEC_E_INVALID_TOKEN, got %08x\n", status); ++ ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n"); + +- buffers[0].pBuffers[0].cbBuffer = buf_size; ++ status = pInitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost", ++ ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, ++ 0, 0, NULL, 0, &context, NULL, &attrs, NULL); ++todo_wine ++ ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status); + ++ buffers[0].pBuffers[0].cbBuffer = buf_size; + status = pInitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost", + ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, + 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL); +@@ -907,6 +912,7 @@ todo_wine + buffers[1].pBuffers[0].cbBuffer = buf_size; + } + ++ ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n"); + ok(status == SEC_E_OK || broken(status == SEC_E_INVALID_TOKEN) /* WinNT */, + "InitializeSecurityContext failed: %08x\n", status); + if(status != SEC_E_OK) { +-- +2.8.0 + diff --git a/patches/secur32-Zero_Buffer_Length/definition b/patches/secur32-Zero_Buffer_Length/definition new file mode 100644 index 00000000..6c0d6467 --- /dev/null +++ b/patches/secur32-Zero_Buffer_Length/definition @@ -0,0 +1 @@ +Fixes: [40271] Set buffer size to zero when InitializeSecurityContextW returns no data