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
9b480ef0
Commit
9b480ef0
authored
Aug 12, 2006
by
Kai Blin
Committed by
Alexandre Julliard
Aug 14, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
secur32: Implement simple MakeSignature.
parent
c8c7bf61
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
208 additions
and
43 deletions
+208
-43
dispatcher.c
dlls/secur32/dispatcher.c
+4
-1
ntlm.c
dlls/secur32/ntlm.c
+153
-39
secur32_priv.h
dlls/secur32/secur32_priv.h
+23
-0
ntlm.c
dlls/secur32/tests/ntlm.c
+28
-3
No files found.
dlls/secur32/dispatcher.c
View file @
9b480ef0
/*
* Copyright 2005 Kai Blin
* Copyright 2005
, 2006
Kai Blin
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -114,6 +114,8 @@ SECURITY_STATUS fork_helper(PNegoHelper *new_helper, const char *prog,
helper
->
com_buf
=
NULL
;
helper
->
com_buf_size
=
0
;
helper
->
com_buf_offset
=
0
;
helper
->
session_key
=
NULL
;
helper
->
neg_flags
=
0
;
helper
->
pipe_in
=
pipe_in
[
0
];
close
(
pipe_in
[
1
]);
helper
->
pipe_out
=
pipe_out
[
1
];
...
...
@@ -262,6 +264,7 @@ void cleanup_helper(PNegoHelper helper)
HeapFree
(
GetProcessHeap
(),
0
,
helper
->
password
);
HeapFree
(
GetProcessHeap
(),
0
,
helper
->
com_buf
);
HeapFree
(
GetProcessHeap
(),
0
,
helper
->
session_key
);
/* closing stdin will terminate ntlm_auth */
close
(
helper
->
pipe_out
);
...
...
dlls/secur32/ntlm.c
View file @
9b480ef0
/*
* Copyright 2005 Kai Blin
* Copyright 2005
, 2006
Kai Blin
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -20,6 +20,7 @@
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
...
...
@@ -377,7 +378,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(
SECURITY_STATUS
ret
;
PNegoHelper
helper
;
ULONG
ctxt_attr
=
0
;
char
*
buffer
;
char
*
buffer
,
*
want_flags
=
NULL
;
PBYTE
bin
;
int
buffer_len
,
bin_len
,
max_len
=
NTLM_MAX_BUF
;
...
...
@@ -406,6 +407,8 @@ static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(
* base64 encoded password
* AF <base64 blob> client is done, blob should be
* sent to server with KK prefixed
* GF <string list> A string list of negotiated flags
* GK <base64 blob> base64 encoded session key
* BH <char reason> something broke
*/
/* The squid cache size is 2010 chars, and that's what ntlm_auth uses */
...
...
@@ -414,30 +417,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(
{
TRACE
(
"According to a MS whitepaper pszTargetName is ignored.
\n
"
);
}
/* Handle all the flags */
if
(
fContextReq
&
ISC_REQ_CONFIDENTIALITY
)
{
FIXME
(
"InitializeSecurityContext(): ISC_REQ_CONFIDENTIALITY stub
\n
"
);
}
if
(
fContextReq
&
ISC_REQ_CONNECTION
)
{
/* This is default, so we'll enable it */
ctxt_attr
|=
ISC_RET_CONNECTION
;
}
if
(
fContextReq
&
ISC_REQ_EXTENDED_ERROR
)
FIXME
(
"ISC_REQ_EXTENDED_ERROR
\n
"
);
if
(
fContextReq
&
ISC_REQ_INTEGRITY
)
FIXME
(
"ISC_REQ_INTEGRITY
\n
"
);
if
(
fContextReq
&
ISC_REQ_MUTUAL_AUTH
)
FIXME
(
"ISC_REQ_MUTUAL_AUTH
\n
"
);
if
(
fContextReq
&
ISC_REQ_REPLAY_DETECT
)
FIXME
(
"ISC_REQ_REPLAY_DETECT
\n
"
);
if
(
fContextReq
&
ISC_REQ_SEQUENCE_DETECT
)
FIXME
(
"ISC_REQ_SEQUENCE_DETECT
\n
"
);
if
(
fContextReq
&
ISC_REQ_STREAM
)
FIXME
(
"ISC_REQ_STREAM
\n
"
);
/* Done with the flags */
if
(
TargetDataRep
==
SECURITY_NETWORK_DREP
){
TRACE
(
"Setting SECURITY_NETWORK_DREP
\n
"
);
}
...
...
@@ -448,6 +428,38 @@ static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(
if
((
phContext
==
NULL
)
&&
(
pInput
==
NULL
))
{
TRACE
(
"First time in ISC()
\n
"
);
/* Allocate space for a maximal string of
* "SF NTLMSSP_FEATURE_SIGN NTLMSSP_FEATURE_SEAL
* NTLMSSP_FEATURE_SESSION_KEY"
*/
want_flags
=
HeapAlloc
(
GetProcessHeap
(),
0
,
73
);
if
(
want_flags
==
NULL
)
{
ret
=
SEC_E_INSUFFICIENT_MEMORY
;
goto
end
;
}
lstrcpyA
(
want_flags
,
"SF"
);
if
(
fContextReq
&
ISC_REQ_CONFIDENTIALITY
)
lstrcatA
(
want_flags
,
" NTLMSSP_FEATURE_SEAL"
);
if
(
fContextReq
&
ISC_REQ_CONNECTION
)
{
/* This is default, so we'll enable it */
ctxt_attr
|=
ISC_RET_CONNECTION
;
lstrcatA
(
want_flags
,
" NTLMSSP_FEATURE_SESSION_KEY"
);
}
if
(
fContextReq
&
ISC_REQ_EXTENDED_ERROR
)
FIXME
(
"ISC_REQ_EXTENDED_ERROR
\n
"
);
if
(
fContextReq
&
ISC_REQ_INTEGRITY
)
lstrcatA
(
want_flags
,
" NTLMSSP_FEATURE_SIGN"
);
if
(
fContextReq
&
ISC_REQ_MUTUAL_AUTH
)
FIXME
(
"ISC_REQ_MUTUAL_AUTH
\n
"
);
if
(
fContextReq
&
ISC_REQ_REPLAY_DETECT
)
FIXME
(
"ISC_REQ_REPLAY_DETECT
\n
"
);
if
(
fContextReq
&
ISC_REQ_SEQUENCE_DETECT
)
FIXME
(
"ISC_REQ_SEQUENCE_DETECT
\n
"
);
if
(
fContextReq
&
ISC_REQ_STREAM
)
FIXME
(
"ISC_REQ_STREAM
\n
"
);
/* Request a challenge request from ntlm_auth */
if
(
helper
->
password
==
NULL
)
{
...
...
@@ -474,6 +486,18 @@ static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(
goto
end
;
TRACE
(
"Helper returned %s
\n
"
,
debugstr_a
(
buffer
));
if
(
lstrlenA
(
want_flags
)
>
2
)
{
TRACE
(
"Want flags are '%s'
\n
"
,
debugstr_a
(
want_flags
));
lstrcpynA
(
buffer
,
want_flags
,
max_len
-
1
);
if
((
ret
=
run_helper
(
helper
,
buffer
,
max_len
,
&
buffer_len
))
!=
SEC_E_OK
)
goto
end
;
if
(
!
strncmp
(
buffer
,
"BH"
,
2
))
TRACE
(
"Helper doesn't understand new command set
\n
"
);
}
lstrcpynA
(
buffer
,
"YR"
,
max_len
-
1
);
if
((
ret
=
run_helper
(
helper
,
buffer
,
max_len
,
&
buffer_len
))
!=
SEC_E_OK
)
...
...
@@ -542,22 +566,73 @@ static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(
(
strncmp
(
buffer
,
"AF "
,
3
)
!=
0
))
{
TRACE
(
"Helper returned %c%c
\n
"
,
buffer
[
0
],
buffer
[
1
]);
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
HeapFree
(
GetProcessHeap
(),
0
,
bin
);
return
SEC_E_INVALID_TOKEN
;
ret
=
SEC_E_INVALID_TOKEN
;
goto
end
;
}
/* decode the blob and send it to server */
if
((
ret
=
decodeBase64
(
buffer
+
3
,
buffer_len
-
3
,
bin
,
max_len
,
&
bin_len
))
!=
SEC_E_OK
)
{
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
HeapFree
(
GetProcessHeap
(),
0
,
bin
);
return
ret
;
goto
end
;
}
TRACE
(
"Getting negotiated flags
\n
"
);
lstrcpynA
(
buffer
,
"GF"
,
max_len
-
1
);
if
((
ret
=
run_helper
(
helper
,
buffer
,
max_len
,
&
buffer_len
))
!=
SEC_E_OK
)
goto
end
;
if
(
buffer_len
<
3
)
{
TRACE
(
"No flags negotiated, or helper does not support GF command
\n
"
);
}
else
{
TRACE
(
"Negotiated %s
\n
"
,
debugstr_a
(
buffer
));
sscanf
(
buffer
+
3
,
"%lx"
,
&
(
helper
->
neg_flags
));
TRACE
(
"Stored 0x%08lx as flags
\n
"
,
helper
->
neg_flags
);
}
TRACE
(
"Getting session key
\n
"
);
lstrcpynA
(
buffer
,
"GK"
,
max_len
-
1
);
if
((
ret
=
run_helper
(
helper
,
buffer
,
max_len
,
&
buffer_len
))
!=
SEC_E_OK
)
goto
end
;
if
(
buffer_len
<
3
)
TRACE
(
"Helper does not support GK command
\n
"
);
else
{
if
(
strncmp
(
buffer
,
"BH "
,
3
)
==
0
)
{
TRACE
(
"Helper sent %s
\n
"
,
debugstr_a
(
buffer
+
3
));
helper
->
valid_session_key
=
FALSE
;
helper
->
session_key
=
HeapAlloc
(
GetProcessHeap
(),
0
,
16
);
/*FIXME: Generate the dummy session key = MD4(MD4(password))*/
memset
(
helper
->
session_key
,
0
,
16
);
}
else
if
(
strncmp
(
buffer
,
"GK "
,
3
)
==
0
)
{
if
((
ret
=
decodeBase64
(
buffer
+
3
,
buffer_len
-
3
,
bin
,
max_len
,
&
bin_len
))
!=
SEC_E_OK
)
{
TRACE
(
"Failed to decode session key
\n
"
);
}
TRACE
(
"Session key is %s
\n
"
,
debugstr_a
(
buffer
+
3
));
helper
->
valid_session_key
=
TRUE
;
if
(
!
helper
->
session_key
)
helper
->
session_key
=
HeapAlloc
(
GetProcessHeap
(),
0
,
bin_len
);
if
(
!
helper
->
session_key
)
{
TRACE
(
"Failed to allocate memory for session key
\n
"
);
ret
=
SEC_E_INTERNAL_ERROR
;
goto
end
;
}
memcpy
(
helper
->
session_key
,
bin
,
bin_len
);
}
}
phNewContext
->
dwUpper
=
ctxt_attr
;
phNewContext
->
dwLower
=
ret
;
phNewContext
->
dwLower
=
(
DWORD
)
helper
;
ret
=
SEC_E_OK
;
}
...
...
@@ -600,6 +675,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(
HeapFree
(
GetProcessHeap
(),
0
,
helper
->
password
);
}
end:
HeapFree
(
GetProcessHeap
(),
0
,
want_flags
);
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
HeapFree
(
GetProcessHeap
(),
0
,
bin
);
return
ret
;
...
...
@@ -1024,18 +1100,56 @@ static SECURITY_STATUS SEC_ENTRY ntlm_RevertSecurityContext(PCtxtHandle phContex
static
SECURITY_STATUS
SEC_ENTRY
ntlm_MakeSignature
(
PCtxtHandle
phContext
,
ULONG
fQOP
,
PSecBufferDesc
pMessage
,
ULONG
MessageSeqNo
)
{
SECURITY_STATUS
ret
;
PNegoHelper
helper
;
TRACE
(
"%p %ld %p %ld
\n
"
,
phContext
,
fQOP
,
pMessage
,
MessageSeqNo
);
if
(
phContext
)
if
(
!
phContext
)
return
SEC_E_INVALID_HANDLE
;
if
(
fQOP
)
FIXME
(
"Ignoring fQOP 0x%08lx"
,
fQOP
);
if
(
MessageSeqNo
)
FIXME
(
"Ignoring MessageSeqNo"
);
if
(
!
pMessage
||
!
pMessage
->
pBuffers
||
pMessage
->
cBuffers
<
2
||
pMessage
->
pBuffers
[
0
].
BufferType
!=
SECBUFFER_TOKEN
||
!
pMessage
->
pBuffers
[
0
].
pvBuffer
)
return
SEC_E_INVALID_TOKEN
;
if
(
pMessage
->
pBuffers
[
0
].
cbBuffer
<
16
)
return
SEC_E_BUFFER_TOO_SMALL
;
helper
=
(
PNegoHelper
)
phContext
->
dwLower
;
TRACE
(
"Negotiated flags are: 0x%08lx
\n
"
,
helper
->
neg_flags
);
if
(
helper
->
neg_flags
&
NTLMSSP_NEGOTIATE_NTLM2
)
{
ret
=
SEC_E_UNSUPPORTED_FUNCTION
;
FIXME
(
"Can't handle NTLMv2 signing yet. Aborting.
\n
"
);
return
SEC_E_UNSUPPORTED_FUNCTION
;
}
else
if
(
helper
->
neg_flags
&
NTLMSSP_NEGOTIATE_SIGN
)
{
ret
=
SEC_E_INVALID_HANDLE
;
FIXME
(
"Can't handle real signing yet. Aborting.
\n
"
);
return
SEC_E_UNSUPPORTED_FUNCTION
;
}
return
ret
;
if
(
helper
->
neg_flags
&
NTLMSSP_NEGOTIATE_KEY_EXCHANGE
)
{
FIXME
(
"Can't handle encrypted session key yet. Aborting.
\n
"
);
return
SEC_E_UNSUPPORTED_FUNCTION
;
}
if
(
helper
->
neg_flags
&
NTLMSSP_NEGOTIATE_ALWAYS_SIGN
)
{
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
;
return
SEC_E_OK
;
}
return
SEC_E_UNSUPPORTED_FUNCTION
;
}
/***********************************************************************
...
...
dlls/secur32/secur32_priv.h
View file @
9b480ef0
...
...
@@ -66,6 +66,9 @@ typedef struct _NegoHelper {
char
*
com_buf
;
int
com_buf_size
;
int
com_buf_offset
;
BYTE
*
session_key
;
BOOL
valid_session_key
;
unsigned
long
neg_flags
;
}
NegoHelper
,
*
PNegoHelper
;
/* Allocates space for and initializes a new provider. If fnTableA or fnTableW
...
...
@@ -121,4 +124,24 @@ SECURITY_STATUS encodeBase64(PBYTE in_buf, int in_len, char* out_buf,
SECURITY_STATUS
decodeBase64
(
char
*
in_buf
,
int
in_len
,
BYTE
*
out_buf
,
int
max_len
,
int
*
out_len
);
/* NTLMSSP flags indicating the negotiated features */
#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
#define NTLMSSP_NEGOTIATE_OEM 0x00000002
#define NTLMSSP_REQUEST_TARGET 0x00000004
#define NTLMSSP_NEGOTIATE_SIGN 0x00000010
#define NTLMSSP_NEGOTIATE_SEAL 0x00000020
#define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE 0x00000040
#define NTLMSSP_NEGOTIATE_LM_SESSION_KEY 0x00000080
#define NTLMSSP_NEGOTIATE_NTLM 0x00000200
#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x00001000
#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000
#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x00004000
#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
#define NTLMSSP_NEGOTIATE_TARGET_TYPE_DOMAIN 0x00010000
#define NTLMSSP_NEGOTIATE_TARGET_TYPE_SERVER 0x00020000
#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000
#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
#define NTLMSSP_NEGOTIATE_128 0x20000000
#define NTLMSSP_NEGOTIATE_KEY_EXCHANGE 0x40000000
#define NTLMSSP_NEGOTIATE_56 0x80000000
#endif
/* ndef __SECUR32_PRIV_H__ */
dlls/secur32/tests/ntlm.c
View file @
9b480ef0
...
...
@@ -673,7 +673,7 @@ static void testSignSeal()
SEC_WINNT_AUTH_IDENTITY
id
;
static
char
sec_pkg_name
[]
=
"NTLM"
;
PSecBufferDesc
crypt
=
NULL
;
PSecBuffer
data
=
NULL
;
PSecBuffer
data
=
NULL
,
fake_data
=
NULL
;
ULONG
qop
=
0
;
SecPkgContext_Sizes
ctxt_sizes
;
...
...
@@ -739,6 +739,28 @@ static void testSignSeal()
crypt
->
ulVersion
=
SECBUFFER_VERSION
;
crypt
->
cBuffers
=
2
;
if
((
fake_data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
SecBuffer
)
*
2
))
==
NULL
)
{
trace
(
"Failed to allocate the fake crypto buffer, aborting test.
\n
"
);
goto
end
;
}
crypt
->
pBuffers
=
fake_data
;
fake_data
[
0
].
BufferType
=
SECBUFFER_DATA
;
fake_data
[
0
].
cbBuffer
=
ctxt_sizes
.
cbSecurityTrailer
;
fake_data
[
0
].
pvBuffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
fake_data
[
0
].
cbBuffer
);
fake_data
[
1
].
BufferType
=
SECBUFFER_DATA
;
fake_data
[
1
].
cbBuffer
=
lstrlen
(
message
);
fake_data
[
1
].
pvBuffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
fake_data
[
1
].
cbBuffer
);
sec_status
=
pMakeSignature
(
client
.
ctxt
,
0
,
crypt
,
0
);
ok
(
sec_status
==
SEC_E_INVALID_TOKEN
,
"MakeSignature returned %s, not SEC_E_INVALID_TOKEN.
\n
"
,
getSecError
(
sec_status
));
if
((
data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
SecBuffer
)
*
2
))
==
NULL
)
{
trace
(
"Failed to allocate the crypto buffer, aborting test.
\n
"
);
...
...
@@ -761,12 +783,10 @@ static void testSignSeal()
* it is sent by the client or the server
*/
sec_status
=
pMakeSignature
(
client
.
ctxt
,
0
,
crypt
,
0
);
todo_wine
{
ok
(
sec_status
==
SEC_E_OK
,
"MakeSignature returned %s, not SEC_E_OK.
\n
"
,
getSecError
(
sec_status
));
ok
(
!
memcmp
(
crypt
->
pBuffers
[
0
].
pvBuffer
,
message_signature
,
crypt
->
pBuffers
[
0
].
cbBuffer
),
"Signature is not as expected.
\n
"
);
}
data
[
0
].
cbBuffer
=
sizeof
(
message_signature
);
memcpy
(
data
[
0
].
pvBuffer
,
message_signature
,
data
[
0
].
cbBuffer
);
...
...
@@ -807,6 +827,11 @@ end:
pDeleteSecurityContext
(
client
.
ctxt
);
pFreeCredentialsHandle
(
client
.
cred
);
if
(
fake_data
)
{
HeapFree
(
GetProcessHeap
(),
0
,
fake_data
[
0
].
pvBuffer
);
HeapFree
(
GetProcessHeap
(),
0
,
fake_data
[
1
].
pvBuffer
);
}
if
(
data
)
{
HeapFree
(
GetProcessHeap
(),
0
,
data
[
0
].
pvBuffer
);
...
...
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