Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2021
- 70 participants
- 1934 messages
Re: [PATCH 5/5] user32: Read "Layout Id" from registry in GetKeyboardLayoutList.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=89601
Your paranoid android.
=== debiant2 (32 bit report) ===
user32:
win.c:10155: Test failed: Expected foreground window 0, got 00EB00D4
win.c:10161: Test failed: Expected foreground window 000E0120, got 00EB00D4
=== debiant2 (64 bit WoW report) ===
user32:
menu.c:2337: Test failed: test 27
April 30, 2021
Re: [PATCH] msado15: Use Recordset_Open in Connection_Execute
by Hans Leidekker
On Fri, 2021-04-30 at 16:56 +1000, Alistair Leslie-Hughes wrote:
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/msado15/connection.c | 36 +++++++++++++++++-------------------
1 file changed, 17 insertions(+), 19 deletions(-)
diff --git a/dlls/msado15/connection.c b/dlls/msado15/connection.c
index a3c9a450be6..2d43aff787f 100644
--- a/dlls/msado15/connection.c
+++ b/dlls/msado15/connection.c
@@ -339,51 +339,49 @@ static HRESULT WINAPI connection_Execute( _Connection *iface, BSTR command, VARI
{
struct connection *connection = impl_from_Connection( iface );
HRESULT hr;
- ICommandText *command_text;
- DBROWCOUNT affected;
- IUnknown *rowset;
_Recordset *recordset;
- ADORecordsetConstruction *construct;
+ VARIANT source, active;
+ IDispatch *dispatch;
FIXME( "%p, %s, %p, 0x%08x, %p Semi-stub\n", iface, debugstr_w(command), records_affected, options, record_set );
if (connection->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed );
- hr = create_command_text(connection->session, command, &command_text);
Since you're no longer using create_command_text here, please move the implementation
close to its only user and make it static.
April 30, 2021
[PATCH 6/6] msv1_0: Implement SpSealMessage and SpUnsealMessage.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/msv1_0/main.c | 75 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/dlls/msv1_0/main.c b/dlls/msv1_0/main.c
index 5e6372b138c..f61e3c90efe 100644
--- a/dlls/msv1_0/main.c
+++ b/dlls/msv1_0/main.c
@@ -1430,14 +1430,85 @@ static NTSTATUS NTAPI ntlm_SpVerifySignature( LSA_SEC_HANDLE handle, SecBufferDe
return verify_signature( ctx, ctx->flags, msg, idx );
}
+static NTSTATUS NTAPI ntlm_SpSealMessage( LSA_SEC_HANDLE handle, ULONG qop, SecBufferDesc *msg, ULONG msg_seq_no )
+{
+ int token_idx, data_idx;
+ struct ntlm_ctx *ctx;
+
+ TRACE( "%lx, %08x, %p %u\n", handle, qop, msg, msg_seq_no );
+ if (qop) FIXME( "ignoring quality of protection %08x\n", qop );
+ if (msg_seq_no) FIXME( "ignoring message sequence number %u\n", msg_seq_no );
+
+ if (!handle) return SEC_E_INVALID_HANDLE;
+
+ if (!msg || !msg->pBuffers || msg->cBuffers < 2 ||
+ (token_idx = get_buffer_index( msg, SECBUFFER_TOKEN )) == -1 ||
+ (data_idx = get_buffer_index( msg, SECBUFFER_DATA )) == -1) return SEC_E_INVALID_TOKEN;
+
+ if (msg->pBuffers[token_idx].cbBuffer < 16) return SEC_E_BUFFER_TOO_SMALL;
+
+ ctx = (struct ntlm_ctx *)handle;
+ if (ctx->flags & FLAG_NEGOTIATE_NTLM2 && ctx->flags & FLAG_NEGOTIATE_SEAL)
+ {
+ create_signature( ctx, ctx->flags, msg, token_idx, SIGN_SEND, FALSE );
+
+ arc4_process( &ctx->crypt.ntlm2.send_arc4info, msg->pBuffers[data_idx].pvBuffer,
+ msg->pBuffers[data_idx].cbBuffer );
+ if (ctx->flags & FLAG_NEGOTIATE_KEY_EXCHANGE)
+ arc4_process( &ctx->crypt.ntlm2.send_arc4info, (char *)msg->pBuffers[token_idx].pvBuffer + 4, 8 );
+ }
+ else
+ {
+ char *sig = msg->pBuffers[token_idx].pvBuffer;
+
+ create_signature( ctx, ctx->flags | FLAG_NEGOTIATE_SIGN, msg, token_idx, SIGN_SEND, FALSE );
+
+ arc4_process( &ctx->crypt.ntlm.arc4info, msg->pBuffers[data_idx].pvBuffer, msg->pBuffers[data_idx].cbBuffer );
+ arc4_process( &ctx->crypt.ntlm.arc4info, sig + 4, 12 );
+
+ if (ctx->flags & FLAG_NEGOTIATE_ALWAYS_SIGN || !ctx->flags) memset( sig + 4, 0, 4 );
+ }
+
+ return SEC_E_OK;
+}
+
+static NTSTATUS NTAPI ntlm_SpUnsealMessage( LSA_SEC_HANDLE handle, SecBufferDesc *msg, ULONG msg_seq_no, ULONG *qop )
+{
+ int token_idx, data_idx;
+ struct ntlm_ctx *ctx;
+
+ TRACE( "%lx, %p, %u, %p\n", handle, msg, msg_seq_no, qop );
+ if (msg_seq_no) FIXME( "ignoring message sequence number %u\n", msg_seq_no );
+
+ if (!handle) return SEC_E_INVALID_HANDLE;
+
+ if (!msg || !msg->pBuffers || msg->cBuffers < 2 ||
+ (token_idx = get_buffer_index( msg, SECBUFFER_TOKEN )) == -1 ||
+ (data_idx = get_buffer_index( msg, SECBUFFER_DATA )) == -1) return SEC_E_INVALID_TOKEN;
+
+ if (msg->pBuffers[token_idx].cbBuffer < 16) return SEC_E_BUFFER_TOO_SMALL;
+
+ ctx = (struct ntlm_ctx *)handle;
+ if (ctx->flags & FLAG_NEGOTIATE_NTLM2 && ctx->flags & FLAG_NEGOTIATE_SEAL)
+ arc4_process( &ctx->crypt.ntlm2.recv_arc4info, msg->pBuffers[data_idx].pvBuffer,
+ msg->pBuffers[data_idx].cbBuffer );
+ else
+ arc4_process( &ctx->crypt.ntlm.arc4info, msg->pBuffers[data_idx].pvBuffer,
+ msg->pBuffers[data_idx].cbBuffer);
+
+ /* make sure we use a session key for the signature check, SealMessage always does that,
+ even in the dummy case */
+ return verify_signature( ctx, ctx->flags | FLAG_NEGOTIATE_SIGN, msg, token_idx );
+}
+
static SECPKG_USER_FUNCTION_TABLE ntlm_user_table =
{
ntlm_SpInstanceInit,
NULL, /* SpInitUserModeContext */
ntlm_SpMakeSignature,
ntlm_SpVerifySignature,
- NULL, /* SpSealMessage */
- NULL, /* SpUnsealMessage */
+ ntlm_SpSealMessage,
+ ntlm_SpUnsealMessage,
NULL, /* SpGetContextToken */
NULL, /* SpQueryContextAttributes */
NULL, /* SpCompleteAuthToken */
--
2.30.2
April 30, 2021
[PATCH 5/6] msv1_0: Implement SpVerifySignature.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/msv1_0/main.c | 57 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/dlls/msv1_0/main.c b/dlls/msv1_0/main.c
index d9b9d16fa64..5e6372b138c 100644
--- a/dlls/msv1_0/main.c
+++ b/dlls/msv1_0/main.c
@@ -1375,12 +1375,67 @@ static NTSTATUS NTAPI ntlm_SpMakeSignature( LSA_SEC_HANDLE handle, ULONG qop, Se
return create_signature( ctx, ctx->flags, msg, idx, SIGN_SEND, TRUE );
}
+static NTSTATUS verify_signature( struct ntlm_ctx *ctx, unsigned int flags, SecBufferDesc *msg, int idx )
+{
+ NTSTATUS status;
+ unsigned int i;
+ SecBufferDesc desc;
+ SecBuffer *buf;
+ char sig[16];
+
+ if (!(buf = malloc( msg->cBuffers * sizeof(*buf) ))) return SEC_E_INSUFFICIENT_MEMORY;
+ desc.ulVersion = SECBUFFER_VERSION;
+ desc.cBuffers = msg->cBuffers;
+ desc.pBuffers = buf;
+
+ for (i = 0; i < msg->cBuffers; i++)
+ {
+ if (msg->pBuffers[i].BufferType == SECBUFFER_TOKEN)
+ {
+ buf[i].BufferType = SECBUFFER_TOKEN;
+ buf[i].cbBuffer = 16;
+ buf[i].pvBuffer = sig;
+ }
+ else
+ {
+ buf[i].BufferType = msg->pBuffers[i].BufferType;
+ buf[i].cbBuffer = msg->pBuffers[i].cbBuffer;
+ buf[i].pvBuffer = msg->pBuffers[i].pvBuffer;
+ }
+ }
+
+ if ((status = create_signature( ctx, flags, &desc, idx, SIGN_RECV, TRUE )) == SEC_E_OK)
+ {
+ if (memcmp( (char *)buf[idx].pvBuffer + 8, (char *)msg->pBuffers[idx].pvBuffer + 8, 8 ))
+ status = SEC_E_MESSAGE_ALTERED;
+ }
+
+ free( buf );
+ return status;
+}
+
+static NTSTATUS NTAPI ntlm_SpVerifySignature( LSA_SEC_HANDLE handle, SecBufferDesc *msg, ULONG msg_seq_no, ULONG *qop )
+{
+ struct ntlm_ctx *ctx = (struct ntlm_ctx *)handle;
+ int idx;
+
+ TRACE( "%lx, %p, %u, %p\n", handle, msg, msg_seq_no, qop );
+ if (msg_seq_no) FIXME( "ignoring message sequence number %u\n", msg_seq_no );
+
+ if (!handle) return SEC_E_INVALID_HANDLE;
+ if (!msg || !msg->pBuffers || msg->cBuffers < 2 || (idx = get_buffer_index( msg, SECBUFFER_TOKEN )) == -1)
+ return SEC_E_INVALID_TOKEN;
+ if (msg->pBuffers[idx].cbBuffer < 16) return SEC_E_BUFFER_TOO_SMALL;
+
+ return verify_signature( ctx, ctx->flags, msg, idx );
+}
+
static SECPKG_USER_FUNCTION_TABLE ntlm_user_table =
{
ntlm_SpInstanceInit,
NULL, /* SpInitUserModeContext */
ntlm_SpMakeSignature,
- NULL, /* SpVerifySignature */
+ ntlm_SpVerifySignature,
NULL, /* SpSealMessage */
NULL, /* SpUnsealMessage */
NULL, /* SpGetContextToken */
--
2.30.2
April 30, 2021
[PATCH 4/6] msv1_0: Implement SpMakeSignature.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/msv1_0/main.c | 199 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 198 insertions(+), 1 deletion(-)
diff --git a/dlls/msv1_0/main.c b/dlls/msv1_0/main.c
index e039b68c920..d9b9d16fa64 100644
--- a/dlls/msv1_0/main.c
+++ b/dlls/msv1_0/main.c
@@ -523,6 +523,26 @@ static void arc4_init( struct arc4_info *info, const char *key, unsigned int len
}
}
+static void arc4_process( struct arc4_info *info, char *buf, unsigned int len )
+{
+ char *state = info->state;
+ unsigned int x = info->x, y = info->y, a, b;
+
+ while (len--)
+ {
+ x = (x + 1) & 0xff;
+ a = state[x];
+ y = (y + a) & 0xff;
+ b = state[y];
+ state[x] = b;
+ state[y] = a;
+ *buf++ ^= state[(a + b) & 0xff];
+ }
+
+ info->x = x;
+ info->y = y;
+}
+
static int get_buffer_index( SecBufferDesc *desc, ULONG type )
{
int idx;
@@ -1178,11 +1198,188 @@ static NTSTATUS NTAPI ntlm_SpInstanceInit( ULONG version, SECPKG_DLL_FUNCTIONS *
return STATUS_SUCCESS;
}
+struct hmac_md5_ctx
+{
+ struct md5_ctx ctx;
+ char outer_padding[64];
+};
+
+static void hmac_md5_init( struct hmac_md5_ctx *ctx, const char *key, unsigned int key_len )
+{
+ char inner_padding[64], tmp_key[16];
+ unsigned int i;
+
+ if (key_len > 64)
+ {
+ struct md5_ctx tmp_ctx;
+
+ MD5Init( &tmp_ctx );
+ MD5Update( &tmp_ctx, key, key_len );
+ MD5Final( &tmp_ctx );
+ memcpy( tmp_key, tmp_ctx.digest, 16 );
+
+ key = tmp_key;
+ key_len = 16;
+ }
+
+ memset( inner_padding, 0, 64 );
+ memset( ctx->outer_padding, 0, 64 );
+ memcpy( inner_padding, key, key_len );
+ memcpy( ctx->outer_padding, key, key_len );
+
+ for (i = 0; i < 64; i++)
+ {
+ inner_padding[i] ^= 0x36;
+ ctx->outer_padding[i] ^= 0x5c;
+ }
+
+ MD5Init( &ctx->ctx );
+ MD5Update( &ctx->ctx, inner_padding, 64 );
+}
+
+static void hmac_md5_update( struct hmac_md5_ctx *ctx, const char *buf, unsigned int len )
+{
+ MD5Update( &ctx->ctx, buf, len );
+}
+
+static void hmac_md5_final( struct hmac_md5_ctx *ctx, char *digest )
+{
+ struct md5_ctx outer_ctx;
+ char inner_digest[16];
+
+ MD5Final( &ctx->ctx );
+ memcpy( inner_digest, ctx->ctx.digest, 16 );
+
+ MD5Init( &outer_ctx );
+ MD5Update( &outer_ctx, ctx->outer_padding, 64 );
+ MD5Update( &outer_ctx, inner_digest, 16 );
+ MD5Final( &outer_ctx );
+
+ memcpy( digest, outer_ctx.digest, 16 );
+}
+
+static SECURITY_STATUS create_signature( struct ntlm_ctx *ctx, unsigned int flags, SecBufferDesc *msg, int idx,
+ enum sign_direction dir, BOOL encrypt )
+{
+ unsigned int i, sign_version = 1;
+ char *sig = msg->pBuffers[idx].pvBuffer;
+
+ if (flags & FLAG_NEGOTIATE_NTLM2 && flags & FLAG_NEGOTIATE_SIGN)
+ {
+ char digest[16], seq_no[4];
+ struct hmac_md5_ctx hmac_md5;
+
+ if (dir == SIGN_SEND)
+ {
+ seq_no[0] = (ctx->crypt.ntlm2.send_seq_no >> 0) & 0xff;
+ seq_no[1] = (ctx->crypt.ntlm2.send_seq_no >> 8) & 0xff;
+ seq_no[2] = (ctx->crypt.ntlm2.send_seq_no >> 16) & 0xff;
+ seq_no[3] = (ctx->crypt.ntlm2.send_seq_no >> 24) & 0xff;
+ ctx->crypt.ntlm2.send_seq_no++;
+
+ hmac_md5_init( &hmac_md5, ctx->crypt.ntlm2.send_sign_key, 16 );
+ }
+ else
+ {
+ seq_no[0] = (ctx->crypt.ntlm2.recv_seq_no >> 0) & 0xff;
+ seq_no[1] = (ctx->crypt.ntlm2.recv_seq_no >> 8) & 0xff;
+ seq_no[2] = (ctx->crypt.ntlm2.recv_seq_no >> 16) & 0xff;
+ seq_no[3] = (ctx->crypt.ntlm2.recv_seq_no >> 24) & 0xff;
+ ctx->crypt.ntlm2.recv_seq_no++;
+
+ hmac_md5_init( &hmac_md5, ctx->crypt.ntlm2.recv_sign_key, 16 );
+ }
+
+ hmac_md5_update( &hmac_md5, seq_no, 4 );
+ for (i = 0; i < msg->cBuffers; ++i)
+ {
+ if (msg->pBuffers[i].BufferType & SECBUFFER_DATA)
+ hmac_md5_update( &hmac_md5, msg->pBuffers[i].pvBuffer, msg->pBuffers[i].cbBuffer );
+ }
+ hmac_md5_final( &hmac_md5, digest );
+
+ if (encrypt && flags & FLAG_NEGOTIATE_KEY_EXCHANGE)
+ {
+ if (dir == SIGN_SEND)
+ arc4_process( &ctx->crypt.ntlm2.send_arc4info, digest, 8 );
+ else
+ arc4_process( &ctx->crypt.ntlm2.recv_arc4info, digest, 8 );
+ }
+
+ sig[0] = (sign_version >> 0) & 0xff;
+ sig[1] = (sign_version >> 8) & 0xff;
+ sig[2] = (sign_version >> 16) & 0xff;
+ sig[3] = (sign_version >> 24) & 0xff;
+ memcpy( sig + 4, digest, 8 );
+ memcpy( sig + 12, seq_no, 4 );
+
+ msg->pBuffers[idx].cbBuffer = 16;
+ return SEC_E_OK;
+ }
+
+ if (flags & FLAG_NEGOTIATE_SIGN)
+ {
+ unsigned int crc = 0;
+
+ for (i = 0; i < msg->cBuffers; ++i)
+ {
+ if (msg->pBuffers[i].BufferType & SECBUFFER_DATA)
+ crc = RtlComputeCrc32( crc, msg->pBuffers[i].pvBuffer, msg->pBuffers[i].cbBuffer );
+ }
+
+ sig[0] = (sign_version >> 0) & 0xff;
+ sig[1] = (sign_version >> 8) & 0xff;
+ sig[2] = (sign_version >> 16) & 0xff;
+ sig[3] = (sign_version >> 24) & 0xff;
+ memset( sig + 4, 0, 4 );
+ sig[8] = (crc >> 0) & 0xff;
+ sig[9] = (crc >> 8) & 0xff;
+ sig[10] = (crc >> 16) & 0xff;
+ sig[11] = (crc >> 24) & 0xff;
+ sig[12] = (ctx->crypt.ntlm.seq_no >> 0) & 0xff;
+ sig[13] = (ctx->crypt.ntlm.seq_no >> 8) & 0xff;
+ sig[14] = (ctx->crypt.ntlm.seq_no >> 16) & 0xff;
+ sig[15] = (ctx->crypt.ntlm.seq_no >> 24) & 0xff;
+ ctx->crypt.ntlm.seq_no++;
+
+ if (encrypt) arc4_process( &ctx->crypt.ntlm.arc4info, sig + 4, 12 );
+ return SEC_E_OK;
+ }
+
+ if (flags & FLAG_NEGOTIATE_ALWAYS_SIGN || !flags)
+ {
+ /* create dummy signature */
+ memset( msg->pBuffers[idx].pvBuffer, 0, 16 );
+ memset( msg->pBuffers[idx].pvBuffer, 1, 1 );
+ msg->pBuffers[idx].cbBuffer = 16;
+ return SEC_E_OK;
+ }
+
+ return SEC_E_UNSUPPORTED_FUNCTION;
+}
+
+static NTSTATUS NTAPI ntlm_SpMakeSignature( LSA_SEC_HANDLE handle, ULONG qop, SecBufferDesc *msg, ULONG msg_seq_no )
+{
+ struct ntlm_ctx *ctx = (struct ntlm_ctx *)handle;
+ int idx;
+
+ TRACE( "%lx, 0x%08x, %p, %u\n", handle, qop, msg, msg_seq_no );
+ if (qop) FIXME( "ignoring quality of protection %08x\n", qop );
+ if (msg_seq_no) FIXME( "ignoring message sequence number %u\n", msg_seq_no );
+
+ if (!handle) return SEC_E_INVALID_HANDLE;
+ if (!msg || !msg->pBuffers || msg->cBuffers < 2 || (idx = get_buffer_index( msg, SECBUFFER_TOKEN )) == -1)
+ return SEC_E_INVALID_TOKEN;
+ if (msg->pBuffers[idx].cbBuffer < 16) return SEC_E_BUFFER_TOO_SMALL;
+
+ return create_signature( ctx, ctx->flags, msg, idx, SIGN_SEND, TRUE );
+}
+
static SECPKG_USER_FUNCTION_TABLE ntlm_user_table =
{
ntlm_SpInstanceInit,
NULL, /* SpInitUserModeContext */
- NULL, /* SpMakeSignature */
+ ntlm_SpMakeSignature,
NULL, /* SpVerifySignature */
NULL, /* SpSealMessage */
NULL, /* SpUnsealMessage */
--
2.30.2
April 30, 2021
[PATCH 3/6] msv1_0: Implement SpQueryContextAttributes.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/msv1_0/main.c | 76 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 75 insertions(+), 1 deletion(-)
diff --git a/dlls/msv1_0/main.c b/dlls/msv1_0/main.c
index 28cad0cb14c..e039b68c920 100644
--- a/dlls/msv1_0/main.c
+++ b/dlls/msv1_0/main.c
@@ -1047,6 +1047,80 @@ static NTSTATUS NTAPI ntlm_SpDeleteContext( LSA_SEC_HANDLE handle )
return SEC_E_OK;
}
+static SecPkgInfoW *build_package_info( const SecPkgInfoW *info )
+{
+ SecPkgInfoW *ret;
+ DWORD size_name = (wcslen(info->Name) + 1) * sizeof(WCHAR);
+ DWORD size_comment = (wcslen(info->Comment) + 1) * sizeof(WCHAR);
+
+ if (!(ret = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*ret) + size_name + size_comment ))) return NULL;
+ ret->fCapabilities = info->fCapabilities;
+ ret->wVersion = info->wVersion;
+ ret->wRPCID = info->wRPCID;
+ ret->cbMaxToken = info->cbMaxToken;
+ ret->Name = (SEC_WCHAR *)(ret + 1);
+ memcpy( ret->Name, info->Name, size_name );
+ ret->Comment = (SEC_WCHAR *)((char *)ret->Name + size_name);
+ memcpy( ret->Comment, info->Comment, size_comment );
+ return ret;
+}
+
+static NTSTATUS NTAPI ntlm_SpQueryContextAttributes( LSA_SEC_HANDLE handle, ULONG attr, void *buf )
+{
+ TRACE( "%lx, %u, %p\n", handle, attr, buf );
+
+ if (!handle) return SEC_E_INVALID_HANDLE;
+
+ switch (attr)
+ {
+#define X(x) case (x) : FIXME(#x" stub\n"); break
+ X(SECPKG_ATTR_ACCESS_TOKEN);
+ X(SECPKG_ATTR_AUTHORITY);
+ X(SECPKG_ATTR_DCE_INFO);
+ X(SECPKG_ATTR_KEY_INFO);
+ X(SECPKG_ATTR_LIFESPAN);
+ X(SECPKG_ATTR_NAMES);
+ X(SECPKG_ATTR_NATIVE_NAMES);
+ X(SECPKG_ATTR_PACKAGE_INFO);
+ X(SECPKG_ATTR_PASSWORD_EXPIRY);
+ X(SECPKG_ATTR_SESSION_KEY);
+ X(SECPKG_ATTR_STREAM_SIZES);
+ X(SECPKG_ATTR_TARGET_INFORMATION);
+ case SECPKG_ATTR_FLAGS:
+ {
+ SecPkgContext_Flags *flags = (SecPkgContext_Flags *)buf;
+ struct ntlm_ctx *ctx = (struct ntlm_ctx *)handle;
+
+ flags->Flags = 0;
+ if (ctx->flags & FLAG_NEGOTIATE_SIGN) flags->Flags |= ISC_RET_INTEGRITY;
+ if (ctx->flags & FLAG_NEGOTIATE_SEAL) flags->Flags |= ISC_RET_CONFIDENTIALITY;
+ return SEC_E_OK;
+ }
+ case SECPKG_ATTR_SIZES:
+ {
+ SecPkgContext_Sizes *sizes = (SecPkgContext_Sizes *)buf;
+ sizes->cbMaxToken = NTLM_MAX_BUF;
+ sizes->cbMaxSignature = 16;
+ sizes->cbBlockSize = 0;
+ sizes->cbSecurityTrailer = 16;
+ return SEC_E_OK;
+ }
+ case SECPKG_ATTR_NEGOTIATION_INFO:
+ {
+ SecPkgContext_NegotiationInfoW *info = (SecPkgContext_NegotiationInfoW *)buf;
+ if (!(info->PackageInfo = build_package_info( &ntlm_package_info ))) return SEC_E_INSUFFICIENT_MEMORY;
+ info->NegotiationState = SECPKG_NEGOTIATION_COMPLETE;
+ return SEC_E_OK;
+ }
+#undef X
+ default:
+ FIXME( "unknown attribute %u\n", attr );
+ break;
+ }
+
+ return SEC_E_UNSUPPORTED_FUNCTION;
+}
+
static SECPKG_FUNCTION_TABLE ntlm_table =
{
ntlm_LsaApInitializePackage,
@@ -1073,7 +1147,7 @@ static SECPKG_FUNCTION_TABLE ntlm_table =
NULL, /* ApplyControlToken */
NULL, /* GetUserInfo */
NULL, /* GetExtendedInformation */
- NULL, /* SpQueryContextAttributes */
+ ntlm_SpQueryContextAttributes,
NULL, /* SpAddCredentials */
NULL, /* SetExtendedInformation */
NULL, /* SetContextAttributes */
--
2.30.2
April 30, 2021
[PATCH 2/6] msv1_0: Implement SpAcceptLsaModeContext.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/msv1_0/main.c | 209 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 208 insertions(+), 1 deletion(-)
diff --git a/dlls/msv1_0/main.c b/dlls/msv1_0/main.c
index 4b0a636bd77..28cad0cb14c 100644
--- a/dlls/msv1_0/main.c
+++ b/dlls/msv1_0/main.c
@@ -829,6 +829,213 @@ done:
return status;
}
+static NTSTATUS NTAPI ntlm_SpAcceptLsaModeContext( LSA_SEC_HANDLE cred_handle, LSA_SEC_HANDLE ctx_handle,
+ SecBufferDesc *input, ULONG ctx_req, ULONG data_rep,
+ LSA_SEC_HANDLE *new_ctx_handle, SecBufferDesc *output,
+ ULONG *ctx_attr, TimeStamp *expiry, BOOLEAN *mapped_ctx,
+ SecBuffer *ctx_data )
+{
+ NTSTATUS status = SEC_E_INSUFFICIENT_MEMORY;
+ struct ntlm_ctx *ctx = NULL;
+ char *buf, *bin, *want_flags = NULL;
+ unsigned int len, bin_len;
+
+ TRACE( "%lx, %lx, %08x, %u, %p, %p, %p, %p, %p, %p, %p\n", cred_handle, ctx_handle, ctx_req, data_rep, input,
+ new_ctx_handle, output, ctx_attr, expiry, mapped_ctx, ctx_data );
+ if (ctx_req) FIXME( "ignoring flags %08x\n", ctx_req );
+
+ if (!(buf = malloc( NTLM_MAX_BUF ))) return SEC_E_INSUFFICIENT_MEMORY;
+ if (!(bin = malloc( NTLM_MAX_BUF ))) goto done;
+
+ if (!ctx_handle)
+ {
+ struct ntlm_cred *cred = (struct ntlm_cred *)cred_handle;
+ char *argv[3];
+
+ if (!cred || cred->mode != MODE_SERVER)
+ {
+ status = SEC_E_INVALID_HANDLE;
+ goto done;
+ }
+
+ if (!input || input->cBuffers < 1)
+ {
+ status = SEC_E_INCOMPLETE_MESSAGE;
+ goto done;
+ }
+
+ if (input->pBuffers[0].cbBuffer > NTLM_MAX_BUF)
+ {
+ status = SEC_E_INVALID_TOKEN;
+ goto done;
+ }
+ else bin_len = input->pBuffers[0].cbBuffer;
+
+ argv[0] = (char *)"ntlm_auth";
+ argv[1] = (char *)"--helper-protocol=squid-2.5-ntlmssp";
+ argv[2] = NULL;
+ if ((status = ntlm_funcs->fork( argv, &ctx )) != SEC_E_OK) goto done;
+ ctx->mode = MODE_SERVER;
+
+ if (!(want_flags = malloc( 73 )))
+ {
+ status = SEC_E_INSUFFICIENT_MEMORY;
+ goto done;
+ }
+ strcpy( want_flags, "SF" );
+ if (ctx_req & ASC_REQ_CONFIDENTIALITY) strcat( want_flags, " NTLMSSP_FEATURE_SEAL" );
+ if (ctx_req & ASC_REQ_CONNECTION)
+ {
+ strcat( want_flags, " NTLMSSP_FEATURE_SESSION_KEY" );
+ ctx->attrs |= ASC_RET_CONNECTION;
+ }
+ if (ctx_req & ASC_REQ_INTEGRITY) strcat( want_flags, " NTLMSSP_FEATURE_SIGN" );
+ if (ctx_req & ASC_REQ_ALLOCATE_MEMORY) FIXME( "ASC_REQ_ALLOCATE_MEMORY\n" );
+ if (ctx_req & ASC_REQ_EXTENDED_ERROR) FIXME( "ASC_REQ_EXTENDED_ERROR\n" );
+ if (ctx_req & ASC_REQ_MUTUAL_AUTH) FIXME( "ASC_REQ_MUTUAL_AUTH\n" );
+ if (ctx_req & ASC_REQ_REPLAY_DETECT) FIXME( "ASC_REQ_REPLAY_DETECT\n" );
+ if (ctx_req & ASC_REQ_SEQUENCE_DETECT) FIXME( "ASC_REQ_SEQUENCE_DETECT\n" );
+ if (ctx_req & ASC_REQ_STREAM) FIXME( "ASC_REQ_STREAM\n" );
+
+ if (strlen( want_flags ) > 3)
+ {
+ TRACE( "want flags are %s\n", debugstr_a(want_flags) );
+ strcpy( buf, want_flags );
+ if ((status = ntlm_funcs->chat( ctx, buf, NTLM_MAX_BUF, &len )) != SEC_E_OK) goto done;
+ if (!strncmp( buf, "BH", 2 )) ERR( "ntlm_auth doesn't understand new command set\n" );
+ }
+
+ memcpy( bin, input->pBuffers[0].pvBuffer, bin_len );
+ strcpy( buf, "YR " );
+ encode_base64( bin, bin_len, buf + 3 );
+
+ if ((status = ntlm_funcs->chat( ctx, buf, NTLM_MAX_BUF, &len )) != SEC_E_OK) goto done;
+ TRACE( "ntlm_auth returned %s\n", buf );
+ if (strncmp( buf, "TT ", 3))
+ {
+ status = SEC_E_INTERNAL_ERROR;
+ goto done;
+ }
+ bin_len = decode_base64( buf + 3, len - 3, bin );
+
+ if (!output || output->cBuffers < 1)
+ {
+ status = SEC_E_INSUFFICIENT_MEMORY;
+ goto done;
+ }
+ output->pBuffers[0].cbBuffer = bin_len;
+ output->pBuffers[0].BufferType = SECBUFFER_DATA;
+ memcpy( output->pBuffers[0].pvBuffer, bin, bin_len );
+
+ *new_ctx_handle = (LSA_SEC_HANDLE)ctx;
+ status = SEC_I_CONTINUE_NEEDED;
+ }
+ else
+ {
+ if (!input || input->cBuffers < 1)
+ {
+ status = SEC_E_INCOMPLETE_MESSAGE;
+ goto done;
+ }
+
+ ctx = (struct ntlm_ctx *)ctx_handle;
+ if (!ctx || ctx->mode != MODE_SERVER)
+ {
+ status = SEC_E_INVALID_HANDLE;
+ goto done;
+ }
+
+ if (input->pBuffers[0].cbBuffer > NTLM_MAX_BUF)
+ {
+ status = SEC_E_INVALID_TOKEN;
+ goto done;
+ }
+ else bin_len = input->pBuffers[0].cbBuffer;
+ memcpy( bin, input->pBuffers[0].pvBuffer, bin_len );
+
+ strcpy( buf, "KK " );
+ encode_base64( bin, bin_len, buf + 3 );
+
+ TRACE( "client sent %s\n", debugstr_a(buf) );
+ if ((status = ntlm_funcs->chat( ctx, buf, NTLM_MAX_BUF, &len )) != SEC_E_OK) goto done;
+ TRACE( "ntlm_auth returned %s\n", debugstr_a(buf) );
+
+ /* At this point, we get a NA if the user didn't authenticate, but a BH if ntlm_auth could not
+ * connect to winbindd. Apart from running Wine as root, there is no way to fix this for now,
+ * so just handle this as a failed login. */
+ if (strncmp( buf, "AF ", 3 ))
+ {
+ if (!strncmp( buf, "NA ", 3 ))
+ {
+ status = SEC_E_LOGON_DENIED;
+ goto done;
+ }
+ else
+ {
+ const char err_v3[] = "BH NT_STATUS_ACCESS_DENIED";
+ const char err_v4[] = "BH NT_STATUS_UNSUCCESSFUL";
+
+ if ((len >= strlen(err_v3) && !strncmp( buf, err_v3, strlen(err_v3) )) ||
+ (len >= strlen(err_v4) && !strncmp( buf, err_v4, strlen(err_v4) )))
+ {
+ TRACE( "connection to winbindd failed\n" );
+ status = SEC_E_LOGON_DENIED;
+ }
+ else status = SEC_E_INTERNAL_ERROR;
+ goto done;
+ }
+ }
+ output->pBuffers[0].cbBuffer = 0;
+
+ strcpy( buf, "GF" );
+ if ((status = ntlm_funcs->chat( ctx, buf, NTLM_MAX_BUF, &len )) != SEC_E_OK) goto done;
+ if (len < 3) ctx->flags = 0;
+ else sscanf( buf + 3, "%x", &ctx->flags );
+
+ strcpy( buf, "GK" );
+ if ((status = ntlm_funcs->chat( ctx, buf, NTLM_MAX_BUF, &len )) != SEC_E_OK) goto done;
+
+ if (!strncmp( buf, "BH", 2 )) TRACE( "no key negotiated\n" );
+ else if (!strncmp( buf, "GK ", 3 ))
+ {
+ bin_len = decode_base64( buf + 3, len - 3, bin );
+ TRACE( "session key is %s\n", debugstr_a(buf + 3) );
+ memcpy( ctx->session_key, bin, bin_len );
+ }
+
+ if (len < 3) memset( ctx->session_key, 0 , 16 );
+ else
+ {
+ if (!strncmp( buf, "BH ", 3 ))
+ {
+ TRACE( "helper sent %s\n", debugstr_a(buf + 3) );
+ /*FIXME: generate dummy session key = MD4(MD4(password))*/
+ memset( ctx->session_key, 0 , 16 );
+ }
+ else if (!strncmp( buf, "GK ", 3 ))
+ {
+ bin_len = decode_base64( buf + 3, len - 3, bin );
+ TRACE( "session key is %s\n", debugstr_a(buf + 3) );
+ memcpy( ctx->session_key, bin, 16 );
+ }
+ }
+ arc4_init( &ctx->crypt.ntlm.arc4info, ctx->session_key, 16 );
+ ctx->crypt.ntlm.seq_no = 0;
+
+ *new_ctx_handle = (LSA_SEC_HANDLE)ctx;
+ status = SEC_E_OK;
+ }
+
+done:
+ if (status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) ntlm_funcs->cleanup( ctx );
+ free( buf );
+ free( bin );
+ free( want_flags );
+
+ TRACE( "returning %08x\n", status );
+ return status;
+}
+
static NTSTATUS NTAPI ntlm_SpDeleteContext( LSA_SEC_HANDLE handle )
{
struct ntlm_ctx *ctx = (struct ntlm_ctx *)handle;
@@ -861,7 +1068,7 @@ static SECPKG_FUNCTION_TABLE ntlm_table =
NULL, /* GetCredentials */
NULL, /* DeleteCredentials */
ntlm_SpInitLsaModeContext,
- NULL, /* SpAcceptLsaModeContext */
+ ntlm_SpAcceptLsaModeContext,
ntlm_SpDeleteContext,
NULL, /* ApplyControlToken */
NULL, /* GetUserInfo */
--
2.30.2
April 30, 2021
[PATCH 1/6] msv1_0: Use RtlAllocateHeap to allocate output buffers.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/msv1_0/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/msv1_0/main.c b/dlls/msv1_0/main.c
index e07dcf6f352..4b0a636bd77 100644
--- a/dlls/msv1_0/main.c
+++ b/dlls/msv1_0/main.c
@@ -765,7 +765,8 @@ static NTSTATUS NTAPI ntlm_SpInitLsaModeContext( LSA_SEC_HANDLE cred_handle, LSA
if (ctx_req & ISC_REQ_ALLOCATE_MEMORY)
{
- if (!(output->pBuffers[idx].pvBuffer = malloc( bin_len )))
+ /* freed with secur32.FreeContextBuffer */
+ if (!(output->pBuffers[idx].pvBuffer = RtlAllocateHeap( GetProcessHeap(), 0, bin_len )))
{
status = SEC_E_INSUFFICIENT_MEMORY;
goto done;
--
2.30.2
April 30, 2021
Re: [PATCH 3/5] user32: Add a default VkKeyScanEx implementation.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=89599
Your paranoid android.
=== debiant2 (32 bit report) ===
user32:
win.c:10161: Test failed: Expected foreground window 000E0120, got 00EB00D4
win.c:10171: Test failed: Expected foreground window 000E0120, got 00000000
win.c:10173: Test failed: GetActiveWindow() = 00000000
win.c:10173: Test failed: GetFocus() = 00000000
win.c:10181: Test failed: Received WM_ACTIVATEAPP(1), did not expect it.
win.c:10197: Test failed: Expected foreground window 000E0120, got 00EB00D4
April 30, 2021
Re: [PATCH 2/5] user32: Add a default GetKeyNameTextW implementation.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=89598
Your paranoid android.
=== debiant2 (32 bit Chinese:China report) ===
user32:
win.c:10155: Test failed: Expected foreground window 0, got 00EB00D4
win.c:10161: Test failed: Expected foreground window 000E0120, got 00EB00D4
win.c:10173: Test failed: GetForegroundWindow() = 000E0120
win.c:10178: Test failed: Expected foreground window 000E0120, got 00EB00D4
win.c:10180: Test failed: GetActiveWindow() = 00000000
win.c:10180: Test failed: GetFocus() = 00000000
win.c:10182: Test failed: Received WM_ACTIVATEAPP(0), did not expect it.
win.c:10190: Test failed: Expected foreground window 000E0120, got 00000000
win.c:10192: Test failed: GetActiveWindow() = 00000000
win.c:10192: Test failed: GetFocus() = 00000000
win.c:10200: Test failed: Received WM_ACTIVATEAPP(1), did not expect it.
April 30, 2021