Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
cd8332ae
Commit
cd8332ae
authored
Nov 04, 2006
by
Kai Blin
Committed by
Alexandre Julliard
Nov 04, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
secur32: Fix handling of buffers that don't have the SECBUFFER_TOKEN as the first buffer.
Thanks to Robert Shearman for catching this one and providing some of the test code.
parent
e1bfe4c1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
144 additions
and
31 deletions
+144
-31
ntlm.c
dlls/secur32/ntlm.c
+91
-27
secur32_priv.h
dlls/secur32/secur32_priv.h
+1
-1
ntlm.c
dlls/secur32/tests/ntlm.c
+50
-1
util.c
dlls/secur32/util.c
+2
-2
No files found.
dlls/secur32/ntlm.c
View file @
cd8332ae
...
...
@@ -1207,6 +1207,8 @@ static SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG
{
PNegoHelper
helper
;
ULONG
sign_version
=
1
;
UINT
i
;
int
token_idx
=
-
1
;
TRACE
(
"%p %d %p %d
\n
"
,
phContext
,
fQOP
,
pMessage
,
MessageSeqNo
);
if
(
!
phContext
)
...
...
@@ -1218,12 +1220,22 @@ static SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG
if
(
MessageSeqNo
)
FIXME
(
"Ignoring MessageSeqNo
\n
"
);
if
(
!
pMessage
||
!
pMessage
->
pBuffers
||
pMessage
->
cBuffers
<
2
||
pMessage
->
pBuffers
[
0
].
BufferType
!=
SECBUFFER_TOKEN
||
!
pMessage
->
pBuffers
[
0
].
pvBuffer
)
if
(
!
pMessage
||
!
pMessage
->
pBuffers
||
pMessage
->
cBuffers
<
2
)
return
SEC_E_INVALID_TOKEN
;
if
(
pMessage
->
pBuffers
[
0
].
cbBuffer
<
16
)
for
(
i
=
0
;
i
<
pMessage
->
cBuffers
;
++
i
)
{
if
(
pMessage
->
pBuffers
[
i
].
BufferType
==
SECBUFFER_TOKEN
)
{
token_idx
=
i
;
break
;
}
}
/* If we didn't find a SECBUFFER_TOKEN type buffer */
if
(
token_idx
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
if
(
pMessage
->
pBuffers
[
token_idx
].
cbBuffer
<
16
)
return
SEC_E_BUFFER_TOO_SMALL
;
helper
=
(
PNegoHelper
)
phContext
->
dwLower
;
...
...
@@ -1235,9 +1247,17 @@ static SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG
}
if
(
helper
->
neg_flags
&
NTLMSSP_NEGOTIATE_SIGN
)
{
PBYTE
sig
=
pMessage
->
pBuffers
[
0
].
pvBuffer
;
ULONG
crc
=
ComputeCrc32
(
pMessage
->
pBuffers
[
1
].
pvBuffer
,
pMessage
->
pBuffers
[
1
].
cbBuffer
);
PBYTE
sig
=
pMessage
->
pBuffers
[
token_idx
].
pvBuffer
;
ULONG
crc
=
0U
;
for
(
i
=
0
;
i
<
pMessage
->
cBuffers
;
++
i
)
{
if
(
pMessage
->
pBuffers
[
i
].
BufferType
&
SECBUFFER_DATA
)
{
crc
=
ComputeCrc32
(
pMessage
->
pBuffers
[
i
].
pvBuffer
,
pMessage
->
pBuffers
[
i
].
cbBuffer
,
crc
);
}
}
sig
[
0
]
=
(
sign_version
>>
0
)
&
0xff
;
sig
[
1
]
=
(
sign_version
>>
8
)
&
0xff
;
...
...
@@ -1269,9 +1289,9 @@ static SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG
{
TRACE
(
"Generating dummy signature
\n
"
);
/* A dummy signature is 0x01 followed by 15 bytes of 0x00 */
memset
(
pMessage
->
pBuffers
[
0
].
pvBuffer
,
0
,
16
);
memset
(
pMessage
->
pBuffers
[
0
].
pvBuffer
,
0x01
,
1
);
pMessage
->
pBuffers
[
0
].
cbBuffer
=
16
;
memset
(
pMessage
->
pBuffers
[
token_idx
].
pvBuffer
,
0
,
16
);
memset
(
pMessage
->
pBuffers
[
token_idx
].
pvBuffer
,
0x01
,
1
);
pMessage
->
pBuffers
[
token_idx
].
cbBuffer
=
16
;
return
SEC_E_OK
;
}
...
...
@@ -1286,17 +1306,28 @@ static SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext,
{
PNegoHelper
helper
;
ULONG
fQOP
=
0
;
UINT
i
;
int
token_idx
=
-
1
;
TRACE
(
"%p %p %d %p
\n
"
,
phContext
,
pMessage
,
MessageSeqNo
,
pfQOP
);
if
(
!
phContext
)
return
SEC_E_INVALID_HANDLE
;
if
(
!
pMessage
||
!
pMessage
->
pBuffers
||
pMessage
->
cBuffers
<
2
||
pMessage
->
pBuffers
[
0
].
BufferType
!=
SECBUFFER_TOKEN
||
!
pMessage
->
pBuffers
[
0
].
pvBuffer
)
if
(
!
pMessage
||
!
pMessage
->
pBuffers
||
pMessage
->
cBuffers
<
2
)
return
SEC_E_INVALID_TOKEN
;
for
(
i
=
0
;
i
<
pMessage
->
cBuffers
;
++
i
)
{
if
(
pMessage
->
pBuffers
[
i
].
BufferType
==
SECBUFFER_TOKEN
)
{
token_idx
=
i
;
break
;
}
}
if
(
token_idx
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
if
(
pMessage
->
pBuffers
[
0
].
cbBuffer
<
16
)
if
(
pMessage
->
pBuffers
[
token_idx
].
cbBuffer
<
16
)
return
SEC_E_BUFFER_TOO_SMALL
;
if
(
MessageSeqNo
)
...
...
@@ -1329,7 +1360,8 @@ static SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext,
ntlm_MakeSignature
(
phContext
,
fQOP
,
&
local_desc
,
MessageSeqNo
);
if
(
memcmp
(((
PBYTE
)
local_buff
[
0
].
pvBuffer
)
+
8
,
((
PBYTE
)
pMessage
->
pBuffers
[
0
].
pvBuffer
)
+
8
,
8
))
if
(
memcmp
(((
PBYTE
)
local_buff
[
0
].
pvBuffer
)
+
8
,
((
PBYTE
)
pMessage
->
pBuffers
[
token_idx
].
pvBuffer
)
+
8
,
8
))
return
SEC_E_MESSAGE_ALTERED
;
return
SEC_E_OK
;
...
...
@@ -1346,7 +1378,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext,
const
BYTE
dummy_sig
[]
=
{
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
};
TRACE
(
"Assuming dummy signature.
\n
"
);
if
(
memcmp
(
pMessage
->
pBuffers
[
0
].
pvBuffer
,
dummy_sig
,
sizeof
(
dummy_sig
))
!=
0
)
if
(
memcmp
(
pMessage
->
pBuffers
[
token_idx
].
pvBuffer
,
dummy_sig
,
sizeof
(
dummy_sig
))
!=
0
)
{
TRACE
(
"Failed to verify the packet signature. Not a dummy signature?
\n
"
);
return
SEC_E_MESSAGE_ALTERED
;
...
...
@@ -1389,6 +1421,9 @@ static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext,
ULONG
fQOP
,
PSecBufferDesc
pMessage
,
ULONG
MessageSeqNo
)
{
PNegoHelper
helper
;
UINT
i
;
int
token_idx
=
-
1
;
TRACE
(
"(%p %d %p %d)
\n
"
,
phContext
,
fQOP
,
pMessage
,
MessageSeqNo
);
if
(
!
phContext
)
...
...
@@ -1400,12 +1435,22 @@ static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext,
if
(
MessageSeqNo
)
FIXME
(
"Ignoring MessageSeqNo
\n
"
);
if
(
!
pMessage
||
!
pMessage
->
pBuffers
||
pMessage
->
cBuffers
<
2
||
pMessage
->
pBuffers
[
0
].
BufferType
!=
SECBUFFER_TOKEN
||
!
pMessage
->
pBuffers
[
0
].
pvBuffer
)
if
(
!
pMessage
||
!
pMessage
->
pBuffers
||
pMessage
->
cBuffers
<
2
)
return
SEC_E_INVALID_TOKEN
;
if
(
pMessage
->
pBuffers
[
0
].
cbBuffer
<
16
)
for
(
i
=
0
;
i
<
pMessage
->
cBuffers
;
++
i
)
{
if
(
pMessage
->
pBuffers
[
i
].
BufferType
==
SECBUFFER_TOKEN
)
{
token_idx
=
i
;
break
;
}
}
if
(
token_idx
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
if
(
pMessage
->
pBuffers
[
token_idx
].
cbBuffer
<
16
)
return
SEC_E_BUFFER_TOO_SMALL
;
helper
=
(
PNegoHelper
)
phContext
->
dwLower
;
...
...
@@ -1417,11 +1462,19 @@ static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext,
}
else
{
PBYTE
sig
=
pMessage
->
pBuffers
[
0
].
pvBuffer
;
ULONG
crc
=
ComputeCrc32
(
pMessage
->
pBuffers
[
1
].
pvBuffer
,
pMessage
->
pBuffers
[
1
].
cbBuffer
);
PBYTE
sig
=
pMessage
->
pBuffers
[
token_idx
].
pvBuffer
;
ULONG
crc
=
0U
;
ULONG
sign_version
=
1l
;
for
(
i
=
0
;
i
<
pMessage
->
cBuffers
;
++
i
)
{
if
(
pMessage
->
pBuffers
[
i
].
BufferType
&
SECBUFFER_DATA
)
{
crc
=
ComputeCrc32
(
pMessage
->
pBuffers
[
i
].
pvBuffer
,
pMessage
->
pBuffers
[
i
].
cbBuffer
,
crc
);
}
}
sig
[
0
]
=
(
sign_version
>>
0
)
&
0xff
;
sig
[
1
]
=
(
sign_version
>>
8
)
&
0xff
;
sig
[
2
]
=
(
sign_version
>>
16
)
&
0xff
;
...
...
@@ -1459,6 +1512,8 @@ static SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext,
SECURITY_STATUS
ret
;
ULONG
ntlmssp_flags_save
;
PNegoHelper
helper
;
UINT
i
;
int
token_idx
=
-
1
;
TRACE
(
"(%p %p %d %p)
\n
"
,
phContext
,
pMessage
,
MessageSeqNo
,
pfQOP
);
if
(
!
phContext
)
...
...
@@ -1467,12 +1522,21 @@ static SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext,
if
(
MessageSeqNo
)
FIXME
(
"Ignoring MessageSeqNo
\n
"
);
if
(
!
pMessage
||
!
pMessage
->
pBuffers
||
pMessage
->
cBuffers
<
2
||
pMessage
->
pBuffers
[
0
].
BufferType
!=
SECBUFFER_TOKEN
||
!
pMessage
->
pBuffers
[
0
].
pvBuffer
)
if
(
!
pMessage
||
!
pMessage
->
pBuffers
||
pMessage
->
cBuffers
<
2
)
return
SEC_E_INVALID_TOKEN
;
for
(
i
=
0
;
i
<
pMessage
->
cBuffers
;
++
i
)
{
if
(
pMessage
->
pBuffers
[
i
].
BufferType
==
SECBUFFER_TOKEN
)
{
token_idx
=
i
;
break
;
}
}
if
(
token_idx
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
if
(
pMessage
->
pBuffers
[
0
].
cbBuffer
<
16
)
if
(
pMessage
->
pBuffers
[
token_idx
].
cbBuffer
<
16
)
return
SEC_E_BUFFER_TOO_SMALL
;
helper
=
(
PNegoHelper
)
phContext
->
dwLower
;
...
...
dlls/secur32/secur32_priv.h
View file @
cd8332ae
...
...
@@ -134,7 +134,7 @@ SECURITY_STATUS decodeBase64(char *in_buf, int in_len, BYTE *out_buf,
int
max_len
,
int
*
out_len
);
/* Functions from util.c */
ULONG
ComputeCrc32
(
const
BYTE
*
pData
,
INT
iLen
);
ULONG
ComputeCrc32
(
const
BYTE
*
pData
,
INT
iLen
,
ULONG
initial_crc
);
SECURITY_STATUS
SECUR32_CreateNTLMv1SessionKey
(
PBYTE
password
,
int
len
,
PBYTE
session_key
);
arc4_info
*
SECUR32_arc4Alloc
(
void
);
void
SECUR32_arc4Init
(
arc4_info
*
a4i
,
const
BYTE
*
key
,
unsigned
int
keyLen
);
...
...
dlls/secur32/tests/ntlm.c
View file @
cd8332ae
...
...
@@ -111,6 +111,8 @@ static BYTE message_binary[] =
static
char
message
[]
=
"Hello, world!"
;
static
char
message_header
[]
=
"Header Test"
;
static
BYTE
crypt_trailer_client
[]
=
{
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0xe8
,
0xc7
,
0xaa
,
0x26
,
0x16
,
0x39
,
0x07
,
0x4e
};
...
...
@@ -119,6 +121,14 @@ static BYTE crypt_message_client[] =
{
0x86
,
0x9c
,
0x5a
,
0x10
,
0x78
,
0xb3
,
0x30
,
0x98
,
0x46
,
0x15
,
0xa0
,
0x31
,
0xd9
};
static
BYTE
crypt_trailer_client2
[]
=
{
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0xc5
,
0xa7
,
0xf7
,
0x0f
,
0x5b
,
0x25
,
0xbe
,
0xa4
};
static
BYTE
crypt_message_client2
[]
=
{
0x20
,
0x6c
,
0x01
,
0xab
,
0xb0
,
0x4c
,
0x93
,
0xe4
,
0x1e
,
0xfc
,
0xe1
,
0xfa
,
0xfe
};
static
BYTE
crypt_trailer_server
[]
=
{
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x1c
,
0x46
,
0x2e
,
0x77
,
0xeb
,
0xf0
,
0xf6
,
0x9e
};
...
...
@@ -674,7 +684,7 @@ static void testSignSeal()
SEC_WINNT_AUTH_IDENTITY
id
;
static
char
sec_pkg_name
[]
=
"NTLM"
;
SecBufferDesc
crypt
;
SecBuffer
data
[
2
],
fake_data
[
2
];
SecBuffer
data
[
2
],
fake_data
[
2
]
,
complex_data
[
4
]
;
ULONG
qop
=
0
;
SecPkgContext_Sizes
ctxt_sizes
;
...
...
@@ -807,6 +817,45 @@ static void testSignSeal()
crypt
.
pBuffers
[
1
].
cbBuffer
),
"Failed to decrypt message correctly.
\n
"
);
trace
(
"Testing with more than one buffer.
\n
"
);
crypt
.
cBuffers
=
sizeof
(
complex_data
)
/
sizeof
(
complex_data
[
0
]);
crypt
.
pBuffers
=
complex_data
;
complex_data
[
0
].
BufferType
=
SECBUFFER_DATA
|
SECBUFFER_READONLY_WITH_CHECKSUM
;
complex_data
[
0
].
cbBuffer
=
sizeof
(
message_header
);
complex_data
[
0
].
pvBuffer
=
message_header
;
complex_data
[
1
].
BufferType
=
SECBUFFER_DATA
;
complex_data
[
1
].
cbBuffer
=
lstrlen
(
message
);
complex_data
[
1
].
pvBuffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
data
[
1
].
cbBuffer
);
memcpy
(
complex_data
[
1
].
pvBuffer
,
message
,
complex_data
[
1
].
cbBuffer
);
complex_data
[
2
].
BufferType
=
SECBUFFER_DATA
|
SECBUFFER_READONLY_WITH_CHECKSUM
;
complex_data
[
2
].
cbBuffer
=
sizeof
(
message_header
);
complex_data
[
2
].
pvBuffer
=
message_header
;
complex_data
[
3
].
BufferType
=
SECBUFFER_TOKEN
;
complex_data
[
3
].
cbBuffer
=
ctxt_sizes
.
cbSecurityTrailer
;
complex_data
[
3
].
pvBuffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
complex_data
[
3
].
cbBuffer
);
/* We should get a dummy signature again. */
sec_status
=
pMakeSignature
(
client
.
ctxt
,
0
,
&
crypt
,
0
);
ok
(
sec_status
==
SEC_E_OK
,
"MakeSignature returned %s, not SEC_E_OK.
\n
"
,
getSecError
(
sec_status
));
ok
(
!
memcmp
(
crypt
.
pBuffers
[
3
].
pvBuffer
,
message_signature
,
crypt
.
pBuffers
[
3
].
cbBuffer
),
"Signature is not as expected.
\n
"
);
sec_status
=
pEncryptMessage
(
client
.
ctxt
,
0
,
&
crypt
,
0
);
ok
(
sec_status
==
SEC_E_OK
,
"EncryptMessage returned %s, not SEC_E_OK.
\n
"
,
getSecError
(
sec_status
));
ok
(
!
memcmp
(
crypt
.
pBuffers
[
3
].
pvBuffer
,
crypt_trailer_client2
,
crypt
.
pBuffers
[
3
].
cbBuffer
),
"Crypt trailer not as expected.
\n
"
);
ok
(
!
memcmp
(
crypt
.
pBuffers
[
1
].
pvBuffer
,
crypt_message_client2
,
crypt
.
pBuffers
[
1
].
cbBuffer
),
"Crypt message not as expected.
\n
"
);
end:
cleanupBuffers
(
&
client
);
cleanupBuffers
(
&
server
);
...
...
dlls/secur32/util.c
View file @
cd8332ae
...
...
@@ -93,9 +93,9 @@ VOID WINAPI MD4Init( MD4_CTX *ctx );
VOID
WINAPI
MD4Update
(
MD4_CTX
*
ctx
,
const
unsigned
char
*
buf
,
unsigned
int
len
);
VOID
WINAPI
MD4Final
(
MD4_CTX
*
ctx
);
ULONG
ComputeCrc32
(
const
BYTE
*
pData
,
INT
iLen
)
ULONG
ComputeCrc32
(
const
BYTE
*
pData
,
INT
iLen
,
ULONG
initial_crc
)
{
ULONG
crc
=
~
0U
;
ULONG
crc
=
~
initial_crc
;
while
(
iLen
>
0
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment