Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
0527cf89
Commit
0527cf89
authored
Apr 09, 2020
by
Hans Leidekker
Committed by
Alexandre Julliard
Apr 09, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
secur32: Add TLS application protocol negotiation support.
Signed-off-by:
Hans Leidekker
<
hans@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
86d20a47
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
323 additions
and
42 deletions
+323
-42
schannel.c
dlls/secur32/schannel.c
+19
-6
schannel_gnutls.c
dlls/secur32/schannel_gnutls.c
+112
-0
secur32_priv.h
dlls/secur32/secur32_priv.h
+3
-1
schannel.c
dlls/secur32/tests/schannel.c
+163
-35
sspi.h
include/sspi.h
+26
-0
No files found.
dlls/secur32/schannel.c
View file @
0527cf89
...
...
@@ -786,6 +786,8 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
struct
schan_credentials
*
cred
;
SIZE_T
expected_size
=
~
0UL
;
SECURITY_STATUS
ret
;
SecBuffer
*
buffer
;
int
idx
;
TRACE
(
"%p %p %s 0x%08x %d %d %p %d %p %p %p %p
\n
"
,
phCredential
,
phContext
,
debugstr_w
(
pszTargetName
),
fContextReq
,
Reserved1
,
TargetDataRep
,
pInput
,
...
...
@@ -842,6 +844,13 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
heap_free
(
target
);
}
}
if
(
pInput
&&
(
idx
=
schan_find_sec_buffer_idx
(
pInput
,
0
,
SECBUFFER_APPLICATION_PROTOCOLS
))
!=
-
1
)
{
buffer
=
&
pInput
->
pBuffers
[
idx
];
schan_imp_set_application_protocols
(
ctx
->
session
,
buffer
->
pvBuffer
,
buffer
->
cbBuffer
);
}
phNewContext
->
dwLower
=
handle
;
phNewContext
->
dwUpper
=
0
;
}
...
...
@@ -849,8 +858,6 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
{
SIZE_T
record_size
=
0
;
unsigned
char
*
ptr
;
SecBuffer
*
buffer
;
int
idx
;
if
(
!
pInput
)
return
SEC_E_INCOMPLETE_MESSAGE
;
...
...
@@ -1003,6 +1010,7 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
PCtxtHandle
context_handle
,
ULONG
attribute
,
PVOID
buffer
)
{
struct
schan_context
*
ctx
;
SECURITY_STATUS
status
;
TRACE
(
"context_handle %p, attribute %#x, buffer %p
\n
"
,
context_handle
,
attribute
,
buffer
);
...
...
@@ -1015,7 +1023,7 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
case
SECPKG_ATTR_STREAM_SIZES
:
{
SecPkgContext_ConnectionInfo
info
;
SECURITY_STATUS
status
=
schan_imp_get_connection_info
(
ctx
->
session
,
&
info
);
status
=
schan_imp_get_connection_info
(
ctx
->
session
,
&
info
);
if
(
status
==
SEC_E_OK
)
{
SecPkgContext_StreamSizes
*
stream_sizes
=
buffer
;
...
...
@@ -1039,7 +1047,7 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
case
SECPKG_ATTR_KEY_INFO
:
{
SecPkgContext_ConnectionInfo
conn_info
;
SECURITY_STATUS
status
=
schan_imp_get_connection_info
(
ctx
->
session
,
&
conn_info
);
status
=
schan_imp_get_connection_info
(
ctx
->
session
,
&
conn_info
);
if
(
status
==
SEC_E_OK
)
{
SecPkgContext_KeyInfoW
*
info
=
buffer
;
...
...
@@ -1054,7 +1062,6 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
case
SECPKG_ATTR_REMOTE_CERT_CONTEXT
:
{
PCCERT_CONTEXT
*
cert
=
buffer
;
SECURITY_STATUS
status
;
status
=
ensure_remote_cert
(
ctx
);
if
(
status
!=
SEC_E_OK
)
...
...
@@ -1075,7 +1082,6 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
ALG_ID
hash_alg
=
CALG_SHA_256
;
BYTE
hash
[
1024
];
DWORD
hash_size
;
SECURITY_STATUS
status
;
char
*
p
;
BOOL
r
;
...
...
@@ -1109,6 +1115,11 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
memcpy
(
p
,
hash
,
hash_size
);
return
SEC_E_OK
;
}
case
SECPKG_ATTR_APPLICATION_PROTOCOL
:
{
SecPkgContext_ApplicationProtocol
*
protocol
=
buffer
;
return
schan_imp_get_application_protocol
(
ctx
->
session
,
protocol
);
}
default:
FIXME
(
"Unhandled attribute %#x
\n
"
,
attribute
);
...
...
@@ -1143,6 +1154,8 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesA(
return
schan_QueryContextAttributesW
(
context_handle
,
attribute
,
buffer
);
case
SECPKG_ATTR_ENDPOINT_BINDINGS
:
return
schan_QueryContextAttributesW
(
context_handle
,
attribute
,
buffer
);
case
SECPKG_ATTR_APPLICATION_PROTOCOL
:
return
schan_QueryContextAttributesW
(
context_handle
,
attribute
,
buffer
);
default:
FIXME
(
"Unhandled attribute %#x
\n
"
,
attribute
);
...
...
dlls/secur32/schannel_gnutls.c
View file @
0527cf89
...
...
@@ -50,6 +50,11 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
/* Not present in gnutls version < 2.9.10. */
static
int
(
*
pgnutls_cipher_get_block_size
)(
gnutls_cipher_algorithm_t
);
/* Not present in gnutls version < 3.2.0. */
static
int
(
*
pgnutls_alpn_get_selected_protocol
)(
gnutls_session_t
,
gnutls_datum_t
*
);
static
int
(
*
pgnutls_alpn_set_protocols
)(
gnutls_session_t
,
const
gnutls_datum_t
*
,
unsigned
,
unsigned
int
);
/* Not present in gnutls version < 3.3.0. */
static
int
(
*
pgnutls_privkey_import_rsa_raw
)(
gnutls_privkey_t
,
const
gnutls_datum_t
*
,
const
gnutls_datum_t
*
,
const
gnutls_datum_t
*
,
...
...
@@ -114,6 +119,10 @@ MAKE_FUNCPTR(gnutls_x509_privkey_deinit);
#define GNUTLS_KX_ECDHE_PSK 14
#endif
#if GNUTLS_VERSION_MAJOR < 3 || (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR < 2)
#define GNUTLS_ALPN_SERVER_PRECEDENCE (1<<1)
#endif
static
int
compat_cipher_get_block_size
(
gnutls_cipher_algorithm_t
cipher
)
{
switch
(
cipher
)
{
...
...
@@ -153,6 +162,19 @@ static int compat_gnutls_privkey_import_rsa_raw(gnutls_privkey_t key, const gnut
return
GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
}
static
int
compat_gnutls_alpn_get_selected_protocol
(
gnutls_session_t
session
,
gnutls_datum_t
*
protocol
)
{
FIXME
(
"
\n
"
);
return
GNUTLS_E_INVALID_REQUEST
;
}
static
int
compat_gnutls_alpn_set_protocols
(
gnutls_session_t
session
,
const
gnutls_datum_t
*
protocols
,
unsigned
size
,
unsigned
int
flags
)
{
FIXME
(
"
\n
"
);
return
GNUTLS_E_INVALID_REQUEST
;
}
static
ssize_t
schan_pull_adapter
(
gnutls_transport_ptr_t
transport
,
void
*
buff
,
size_t
buff_len
)
{
...
...
@@ -599,6 +621,86 @@ again:
return
SEC_E_OK
;
}
static
unsigned
int
parse_alpn_protocol_list
(
unsigned
char
*
buffer
,
unsigned
int
buflen
,
gnutls_datum_t
*
list
)
{
unsigned
int
len
,
offset
=
0
,
count
=
0
;
while
(
buflen
)
{
len
=
buffer
[
offset
++
];
buflen
--
;
if
(
!
len
||
len
>
buflen
)
return
0
;
if
(
list
)
{
list
[
count
].
data
=
&
buffer
[
offset
];
list
[
count
].
size
=
len
;
}
buflen
-=
len
;
offset
+=
len
;
count
++
;
}
return
count
;
}
void
schan_imp_set_application_protocols
(
schan_imp_session
session
,
unsigned
char
*
buffer
,
unsigned
int
buflen
)
{
gnutls_session_t
s
=
(
gnutls_session_t
)
session
;
unsigned
int
extension_len
,
extension
,
count
=
0
,
offset
=
0
;
unsigned
short
list_len
;
gnutls_datum_t
*
protocols
;
int
ret
;
if
(
sizeof
(
extension_len
)
>
buflen
)
return
;
extension_len
=
*
(
unsigned
int
*
)
&
buffer
[
offset
];
offset
+=
sizeof
(
extension_len
);
if
(
offset
+
sizeof
(
extension
)
>
buflen
)
return
;
extension
=
*
(
unsigned
int
*
)
&
buffer
[
offset
];
if
(
extension
!=
SecApplicationProtocolNegotiationExt_ALPN
)
{
FIXME
(
"extension %u not supported
\n
"
,
extension
);
return
;
}
offset
+=
sizeof
(
extension
);
if
(
offset
+
sizeof
(
list_len
)
>
buflen
)
return
;
list_len
=
*
(
unsigned
short
*
)
&
buffer
[
offset
];
offset
+=
sizeof
(
list_len
);
if
(
offset
+
list_len
>
buflen
)
return
;
count
=
parse_alpn_protocol_list
(
&
buffer
[
offset
],
list_len
,
NULL
);
if
(
!
count
||
!
(
protocols
=
heap_alloc
(
count
*
sizeof
(
*
protocols
))))
return
;
parse_alpn_protocol_list
(
&
buffer
[
offset
],
list_len
,
protocols
);
if
((
ret
=
pgnutls_alpn_set_protocols
(
s
,
protocols
,
count
,
GNUTLS_ALPN_SERVER_PRECEDENCE
)
<
0
))
{
pgnutls_perror
(
ret
);
}
heap_free
(
protocols
);
}
SECURITY_STATUS
schan_imp_get_application_protocol
(
schan_imp_session
session
,
SecPkgContext_ApplicationProtocol
*
protocol
)
{
gnutls_session_t
s
=
(
gnutls_session_t
)
session
;
gnutls_datum_t
selected
;
memset
(
protocol
,
0
,
sizeof
(
*
protocol
));
if
(
pgnutls_alpn_get_selected_protocol
(
s
,
&
selected
)
<
0
)
return
SEC_E_OK
;
if
(
selected
.
size
<=
sizeof
(
protocol
->
ProtocolId
))
{
protocol
->
ProtoNegoStatus
=
SecApplicationProtocolNegotiationStatus_Success
;
protocol
->
ProtoNegoExt
=
SecApplicationProtocolNegotiationExt_ALPN
;
protocol
->
ProtocolIdSize
=
selected
.
size
;
memcpy
(
protocol
->
ProtocolId
,
selected
.
data
,
selected
.
size
);
TRACE
(
"returning %s
\n
"
,
debugstr_an
((
const
char
*
)
selected
.
data
,
selected
.
size
));
}
return
SEC_E_OK
;
}
static
WCHAR
*
get_key_container_path
(
const
CERT_CONTEXT
*
ctx
)
{
static
const
WCHAR
rsabaseW
[]
=
...
...
@@ -935,6 +1037,16 @@ BOOL schan_imp_init(void)
WARN
(
"gnutls_cipher_get_block_size not found
\n
"
);
pgnutls_cipher_get_block_size
=
compat_cipher_get_block_size
;
}
if
(
!
(
pgnutls_alpn_set_protocols
=
dlsym
(
libgnutls_handle
,
"gnutls_alpn_set_protocols"
)))
{
WARN
(
"gnutls_alpn_set_protocols not found
\n
"
);
pgnutls_alpn_set_protocols
=
compat_gnutls_alpn_set_protocols
;
}
if
(
!
(
pgnutls_alpn_get_selected_protocol
=
dlsym
(
libgnutls_handle
,
"gnutls_alpn_get_selected_protocol"
)))
{
WARN
(
"gnutls_alpn_get_selected_protocol not found
\n
"
);
pgnutls_alpn_get_selected_protocol
=
compat_gnutls_alpn_get_selected_protocol
;
}
if
(
!
(
pgnutls_privkey_export_x509
=
dlsym
(
libgnutls_handle
,
"gnutls_privkey_export_x509"
)))
{
WARN
(
"gnutls_privkey_export_x509 not found
\n
"
);
...
...
dlls/secur32/secur32_priv.h
View file @
0527cf89
...
...
@@ -248,6 +248,8 @@ extern void schan_imp_free_certificate_credentials(schan_credentials*) DECLSPEC_
extern
DWORD
schan_imp_enabled_protocols
(
void
)
DECLSPEC_HIDDEN
;
extern
BOOL
schan_imp_init
(
void
)
DECLSPEC_HIDDEN
;
extern
void
schan_imp_deinit
(
void
)
DECLSPEC_HIDDEN
;
extern
void
schan_imp_set_application_protocols
(
schan_imp_session
,
unsigned
char
*
,
unsigned
int
)
DECLSPEC_HIDDEN
;
extern
SECURITY_STATUS
schan_imp_get_application_protocol
(
schan_imp_session
,
SecPkgContext_ApplicationProtocol
*
)
DECLSPEC_HIDDEN
;
#endif
/* ndef __SECUR32_PRIV_H__ */
dlls/secur32/tests/schannel.c
View file @
0527cf89
...
...
@@ -670,14 +670,41 @@ static void test_InitializeSecurityContext(void)
FreeCredentialsHandle
(
&
cred_handle
);
}
static
SOCKET
create_ssl_socket
(
const
char
*
hostname
)
{
struct
hostent
*
host
;
struct
sockaddr_in
addr
;
SOCKET
sock
;
if
(
!
(
host
=
gethostbyname
(
hostname
)))
{
skip
(
"Can't resolve
\"
%s
\"\n
"
,
hostname
);
return
-
1
;
}
addr
.
sin_family
=
host
->
h_addrtype
;
addr
.
sin_addr
=
*
(
struct
in_addr
*
)
host
->
h_addr_list
[
0
];
addr
.
sin_port
=
htons
(
443
);
if
((
sock
=
socket
(
host
->
h_addrtype
,
SOCK_STREAM
,
0
))
==
-
1
)
{
skip
(
"Can't create socket
\n
"
);
return
1
;
}
if
(
connect
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
==
-
1
)
{
skip
(
"Can't connect to
\"
%s
\"\n
"
,
hostname
);
closesocket
(
sock
);
return
-
1
;
}
return
sock
;
}
static
void
test_communication
(
void
)
{
int
ret
;
WSADATA
wsa_data
;
SOCKET
sock
;
struct
hostent
*
host
;
struct
sockaddr_in
addr
;
SECURITY_STATUS
status
;
ULONG
attrs
;
...
...
@@ -705,36 +732,7 @@ static void test_communication(void)
}
/* Create a socket and connect to test.winehq.org */
ret
=
WSAStartup
(
0x0202
,
&
wsa_data
);
if
(
ret
)
{
skip
(
"Can't init winsock 2.2
\n
"
);
return
;
}
host
=
gethostbyname
(
"test.winehq.org"
);
if
(
!
host
)
{
skip
(
"Can't resolve test.winehq.org
\n
"
);
return
;
}
addr
.
sin_family
=
host
->
h_addrtype
;
addr
.
sin_addr
=
*
(
struct
in_addr
*
)
host
->
h_addr_list
[
0
];
addr
.
sin_port
=
htons
(
443
);
sock
=
socket
(
host
->
h_addrtype
,
SOCK_STREAM
,
0
);
if
(
sock
==
SOCKET_ERROR
)
{
skip
(
"Can't create socket
\n
"
);
return
;
}
ret
=
connect
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
));
if
(
ret
==
SOCKET_ERROR
)
{
skip
(
"Can't connect to test.winehq.org
\n
"
);
return
;
}
if
((
sock
=
create_ssl_socket
(
"test.winehq.org"
))
==
-
1
)
return
;
/* Create client credentials */
init_cred
(
&
cred
);
...
...
@@ -952,7 +950,7 @@ todo_wine
status
=
pQueryContextAttributesA
(
&
context
,
SECPKG_ATTR_STREAM_SIZES
,
&
sizes
);
ok
(
status
==
SEC_E_OK
,
"QueryContextAttributesW(SECPKG_ATTR_STREAM_SIZES) failed: %08x
\n
"
,
status
);
status
=
QueryContextAttributesA
(
&
context
,
SECPKG_ATTR_NEGOTIATION_INFO
,
&
info
);
status
=
p
QueryContextAttributesA
(
&
context
,
SECPKG_ATTR_NEGOTIATION_INFO
,
&
info
);
ok
(
status
==
SEC_E_UNSUPPORTED_FUNCTION
,
"QueryContextAttributesA returned %08x
\n
"
,
status
);
reset_buffers
(
&
buffers
[
0
]);
...
...
@@ -1037,12 +1035,142 @@ todo_wine
closesocket
(
sock
);
}
static
void
test_application_protocol_negotiation
(
void
)
{
int
ret
;
SOCKET
sock
;
SECURITY_STATUS
status
;
ULONG
attrs
;
SCHANNEL_CRED
cred
;
CredHandle
cred_handle
;
CtxtHandle
context
;
SecPkgContext_ApplicationProtocol
protocol
;
SecBufferDesc
buffers
[
3
];
SecBuffer
*
buf
;
unsigned
buf_size
=
8192
;
unsigned
char
*
alpn_buffer
;
unsigned
int
*
extension_len
;
unsigned
short
*
list_len
;
int
list_start_index
,
offset
=
0
;
if
(
!
pQueryContextAttributesA
)
{
win_skip
(
"Required secur32 functions not available
\n
"
);
return
;
}
if
((
sock
=
create_ssl_socket
(
"test.winehq.org"
))
==
-
1
)
return
;
init_cred
(
&
cred
);
cred
.
grbitEnabledProtocols
=
SP_PROT_TLS1_CLIENT
;
cred
.
dwFlags
=
SCH_CRED_NO_DEFAULT_CREDS
|
SCH_CRED_MANUAL_CRED_VALIDATION
;
status
=
AcquireCredentialsHandleA
(
NULL
,
(
SEC_CHAR
*
)
UNISP_NAME_A
,
SECPKG_CRED_OUTBOUND
,
NULL
,
&
cred
,
NULL
,
NULL
,
&
cred_handle
,
NULL
);
ok
(
status
==
SEC_E_OK
,
"got %08x
\n
"
,
status
);
if
(
status
!=
SEC_E_OK
)
return
;
init_buffers
(
&
buffers
[
0
],
4
,
buf_size
);
init_buffers
(
&
buffers
[
1
],
4
,
buf_size
);
init_buffers
(
&
buffers
[
2
],
1
,
128
);
alpn_buffer
=
buffers
[
2
].
pBuffers
[
0
].
pvBuffer
;
extension_len
=
(
unsigned
int
*
)
&
alpn_buffer
[
offset
];
offset
+=
sizeof
(
*
extension_len
);
*
(
unsigned
int
*
)
&
alpn_buffer
[
offset
]
=
SecApplicationProtocolNegotiationExt_ALPN
;
offset
+=
sizeof
(
unsigned
int
);
list_len
=
(
unsigned
short
*
)
&
alpn_buffer
[
offset
];
offset
+=
sizeof
(
*
list_len
);
list_start_index
=
offset
;
alpn_buffer
[
offset
++
]
=
sizeof
(
"http/1.1"
)
-
1
;
memcpy
(
&
alpn_buffer
[
offset
],
"http/1.1"
,
sizeof
(
"http/1.1"
)
-
1
);
offset
+=
sizeof
(
"http/1.1"
)
-
1
;
alpn_buffer
[
offset
++
]
=
sizeof
(
"h2"
)
-
1
;
memcpy
(
&
alpn_buffer
[
offset
],
"h2"
,
sizeof
(
"h2"
)
-
1
);
offset
+=
sizeof
(
"h2"
)
-
1
;
*
list_len
=
offset
-
list_start_index
;
*
extension_len
=
*
list_len
+
sizeof
(
*
extension_len
)
+
sizeof
(
*
list_len
);
buffers
[
2
].
pBuffers
[
0
].
BufferType
=
SECBUFFER_APPLICATION_PROTOCOLS
;
buffers
[
2
].
pBuffers
[
0
].
cbBuffer
=
offset
;
buffers
[
0
].
pBuffers
[
0
].
BufferType
=
SECBUFFER_TOKEN
;
status
=
InitializeSecurityContextA
(
&
cred_handle
,
NULL
,
(
SEC_CHAR
*
)
"localhost"
,
ISC_REQ_CONFIDENTIALITY
|
ISC_REQ_STREAM
,
0
,
0
,
&
buffers
[
2
],
0
,
&
context
,
&
buffers
[
0
],
&
attrs
,
NULL
);
ok
(
status
==
SEC_I_CONTINUE_NEEDED
,
"got %08x
\n
"
,
status
);
buf
=
&
buffers
[
0
].
pBuffers
[
0
];
send
(
sock
,
buf
->
pvBuffer
,
buf
->
cbBuffer
,
0
);
buf
->
cbBuffer
=
buf_size
;
buf
=
&
buffers
[
1
].
pBuffers
[
0
];
buf
->
cbBuffer
=
buf_size
;
ret
=
receive_data
(
sock
,
buf
);
if
(
ret
==
-
1
)
return
;
buffers
[
1
].
pBuffers
[
0
].
BufferType
=
SECBUFFER_TOKEN
;
status
=
InitializeSecurityContextA
(
&
cred_handle
,
&
context
,
(
SEC_CHAR
*
)
"localhost"
,
ISC_REQ_CONFIDENTIALITY
|
ISC_REQ_STREAM
|
ISC_REQ_USE_SUPPLIED_CREDS
,
0
,
0
,
&
buffers
[
1
],
0
,
NULL
,
&
buffers
[
0
],
&
attrs
,
NULL
);
buffers
[
1
].
pBuffers
[
0
].
cbBuffer
=
buf_size
;
while
(
status
==
SEC_I_CONTINUE_NEEDED
)
{
buf
=
&
buffers
[
0
].
pBuffers
[
0
];
send
(
sock
,
buf
->
pvBuffer
,
buf
->
cbBuffer
,
0
);
buf
->
cbBuffer
=
buf_size
;
buf
=
&
buffers
[
1
].
pBuffers
[
0
];
ret
=
receive_data
(
sock
,
buf
);
if
(
ret
==
-
1
)
return
;
buf
->
BufferType
=
SECBUFFER_TOKEN
;
status
=
InitializeSecurityContextA
(
&
cred_handle
,
&
context
,
(
SEC_CHAR
*
)
"localhost"
,
ISC_REQ_USE_SUPPLIED_CREDS
,
0
,
0
,
&
buffers
[
1
],
0
,
NULL
,
&
buffers
[
0
],
&
attrs
,
NULL
);
buffers
[
1
].
pBuffers
[
0
].
cbBuffer
=
buf_size
;
}
ok
(
status
==
SEC_E_OK
||
broken
(
status
==
SEC_E_ILLEGAL_MESSAGE
)
/* winxp */
,
"got %08x
\n
"
,
status
);
if
(
status
!=
SEC_E_OK
)
{
skip
(
"Handshake failed
\n
"
);
return
;
}
memset
(
&
protocol
,
0
,
sizeof
(
protocol
));
status
=
pQueryContextAttributesA
(
&
context
,
SECPKG_ATTR_APPLICATION_PROTOCOL
,
&
protocol
);
ok
(
status
==
SEC_E_OK
||
broken
(
status
==
SEC_E_UNSUPPORTED_FUNCTION
)
/* win2k8 */
,
"got %08x
\n
"
,
status
);
if
(
status
==
SEC_E_OK
)
{
ok
(
protocol
.
ProtoNegoStatus
==
SecApplicationProtocolNegotiationStatus_Success
,
"got %u
\n
"
,
protocol
.
ProtoNegoStatus
);
ok
(
protocol
.
ProtoNegoExt
==
SecApplicationProtocolNegotiationExt_ALPN
,
"got %u
\n
"
,
protocol
.
ProtoNegoExt
);
ok
(
protocol
.
ProtocolIdSize
==
8
,
"got %u
\n
"
,
protocol
.
ProtocolIdSize
);
ok
(
!
memcmp
(
protocol
.
ProtocolId
,
"http/1.1"
,
8
),
"wrong protocol id
\n
"
);
}
DeleteSecurityContext
(
&
context
);
FreeCredentialsHandle
(
&
cred_handle
);
free_buffers
(
&
buffers
[
0
]);
free_buffers
(
&
buffers
[
1
]);
free_buffers
(
&
buffers
[
2
]);
closesocket
(
sock
);
}
START_TEST
(
schannel
)
{
WSADATA
wsa_data
;
pQueryContextAttributesA
=
(
void
*
)
GetProcAddress
(
GetModuleHandleA
(
"secur32.dll"
),
"QueryContextAttributesA"
);
WSAStartup
(
0x0202
,
&
wsa_data
);
test_cread_attrs
();
testAcquireSecurityContext
();
test_InitializeSecurityContext
();
test_communication
();
test_application_protocol_negotiation
();
}
include/sspi.h
View file @
0527cf89
...
...
@@ -201,6 +201,7 @@ typedef struct _SecBuffer
#define SECBUFFER_MECHLIST_SIGNATURE 12
#define SECBUFFER_TARGET 13
#define SECBUFFER_CHANNEL_BINDINGS 14
#define SECBUFFER_APPLICATION_PROTOCOLS 18
#define SECBUFFER_ATTRMASK 0xf0000000
#define SECBUFFER_READONLY 0x80000000
...
...
@@ -497,6 +498,7 @@ typedef SECURITY_STATUS (SEC_ENTRY *QUERY_CONTEXT_ATTRIBUTES_FN_W)(PCtxtHandle,
#define SECPKG_ATTR_NEGO_PKG_INFO 31
#define SECPKG_ATTR_NEGO_STATUS 32
#define SECPKG_ATTR_CONTEXT_DELETED 33
#define SECPKG_ATTR_APPLICATION_PROTOCOL 35
#define SECPKG_ATTR_SUBJECT_SECURITY_ATTRIBUTES 128
#define SECPKG_ATTR_NEGO_INFO_FLAG_NO_KERBEROS 0x1
...
...
@@ -712,6 +714,30 @@ typedef struct _SecPkgContext_Bindings
SEC_CHANNEL_BINDINGS
*
Bindings
;
}
SecPkgContext_Bindings
,
*
PSecPkgContext_Bindings
;
typedef
enum
_SEC_APPLICATION_PROTOCOL_NEGOTIATION_STATUS
{
SecApplicationProtocolNegotiationStatus_None
,
SecApplicationProtocolNegotiationStatus_Success
,
SecApplicationProtocolNegotiationStatus_SelectedClientOnly
}
SEC_APPLICATION_PROTOCOL_NEGOTIATION_STATUS
,
*
PSEC_APPLICATION_PROTOCOL_NEGOTIATION_STATUS
;
typedef
enum
_SEC_APPLICATION_PROTOCOL_NEGOTIATION_EXT
{
SecApplicationProtocolNegotiationExt_None
,
SecApplicationProtocolNegotiationExt_NPN
,
SecApplicationProtocolNegotiationExt_ALPN
}
SEC_APPLICATION_PROTOCOL_NEGOTIATION_EXT
,
*
PSEC_APPLICATION_PROTOCOL_NEGOTIATION_EXT
;
#define MAX_PROTOCOL_ID_SIZE 0xff
typedef
struct
_SecPkgContext_ApplicationProtocol
{
SEC_APPLICATION_PROTOCOL_NEGOTIATION_STATUS
ProtoNegoStatus
;
SEC_APPLICATION_PROTOCOL_NEGOTIATION_EXT
ProtoNegoExt
;
unsigned
char
ProtocolIdSize
;
unsigned
char
ProtocolId
[
MAX_PROTOCOL_ID_SIZE
];
}
SecPkgContext_ApplicationProtocol
,
*
PSecPkgContext_ApplicationProtocol
;
SECURITY_STATUS
SEC_ENTRY
ImpersonateSecurityContext
(
PCtxtHandle
phContext
);
typedef
SECURITY_STATUS
(
SEC_ENTRY
*
IMPERSONATE_SECURITY_CONTEXT_FN
)
...
...
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