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
44593a63
Commit
44593a63
authored
Apr 21, 2021
by
Hans Leidekker
Committed by
Alexandre Julliard
Apr 21, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kerberos: Move support for SpUnsealMessage to the Unix library.
Signed-off-by:
Hans Leidekker
<
hans@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
91200456
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
78 additions
and
247 deletions
+78
-247
krb5_ap.c
dlls/kerberos/krb5_ap.c
+1
-247
unixlib.c
dlls/kerberos/unixlib.c
+76
-0
unixlib.h
dlls/kerberos/unixlib.h
+1
-0
No files found.
dlls/kerberos/krb5_ap.c
View file @
44593a63
...
...
@@ -54,8 +54,6 @@ static HINSTANCE instance;
const
struct
krb5_funcs
*
krb5_funcs
=
NULL
;
#define KERBEROS_MAX_BUF 12000
#define KERBEROS_CAPS \
( SECPKG_FLAG_INTEGRITY \
| SECPKG_FLAG_PRIVACY \
...
...
@@ -600,162 +598,6 @@ static NTSTATUS NTAPI kerberos_SpGetInfo(SecPkgInfoW *info)
return
STATUS_SUCCESS
;
}
#ifdef SONAME_LIBGSSAPI_KRB5
WINE_DECLARE_DEBUG_CHANNEL
(
winediag
);
static
void
*
libgssapi_krb5_handle
;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
MAKE_FUNCPTR
(
gss_accept_sec_context
);
MAKE_FUNCPTR
(
gss_acquire_cred
);
MAKE_FUNCPTR
(
gss_delete_sec_context
);
MAKE_FUNCPTR
(
gss_display_status
);
MAKE_FUNCPTR
(
gss_get_mic
);
MAKE_FUNCPTR
(
gss_import_name
);
MAKE_FUNCPTR
(
gss_init_sec_context
);
MAKE_FUNCPTR
(
gss_inquire_context
);
MAKE_FUNCPTR
(
gss_release_buffer
);
MAKE_FUNCPTR
(
gss_release_cred
);
MAKE_FUNCPTR
(
gss_release_iov_buffer
);
MAKE_FUNCPTR
(
gss_release_name
);
MAKE_FUNCPTR
(
gss_unwrap
);
MAKE_FUNCPTR
(
gss_unwrap_iov
);
MAKE_FUNCPTR
(
gss_verify_mic
);
MAKE_FUNCPTR
(
gss_wrap
);
MAKE_FUNCPTR
(
gss_wrap_iov
);
#undef MAKE_FUNCPTR
static
BOOL
load_gssapi_krb5
(
void
)
{
if
(
!
(
libgssapi_krb5_handle
=
dlopen
(
SONAME_LIBGSSAPI_KRB5
,
RTLD_NOW
)))
{
ERR_
(
winediag
)(
"Failed to load libgssapi_krb5, Kerberos SSP support will not be available.
\n
"
);
return
FALSE
;
}
#define LOAD_FUNCPTR(f) \
if (!(p##f = dlsym( libgssapi_krb5_handle, #f ))) \
{ \
ERR( "Failed to load %s\n", #f ); \
goto fail; \
}
LOAD_FUNCPTR
(
gss_accept_sec_context
)
LOAD_FUNCPTR
(
gss_acquire_cred
)
LOAD_FUNCPTR
(
gss_delete_sec_context
)
LOAD_FUNCPTR
(
gss_display_status
)
LOAD_FUNCPTR
(
gss_get_mic
)
LOAD_FUNCPTR
(
gss_import_name
)
LOAD_FUNCPTR
(
gss_init_sec_context
)
LOAD_FUNCPTR
(
gss_inquire_context
)
LOAD_FUNCPTR
(
gss_release_buffer
)
LOAD_FUNCPTR
(
gss_release_cred
)
LOAD_FUNCPTR
(
gss_release_iov_buffer
)
LOAD_FUNCPTR
(
gss_release_name
)
LOAD_FUNCPTR
(
gss_unwrap
)
LOAD_FUNCPTR
(
gss_unwrap_iov
)
LOAD_FUNCPTR
(
gss_verify_mic
)
LOAD_FUNCPTR
(
gss_wrap
)
LOAD_FUNCPTR
(
gss_wrap_iov
)
#undef LOAD_FUNCPTR
return
TRUE
;
fail:
dlclose
(
libgssapi_krb5_handle
);
libgssapi_krb5_handle
=
NULL
;
return
FALSE
;
}
static
void
unload_gssapi_krb5
(
void
)
{
dlclose
(
libgssapi_krb5_handle
);
libgssapi_krb5_handle
=
NULL
;
}
static
inline
gss_ctx_id_t
ctxthandle_sspi_to_gss
(
LSA_SEC_HANDLE
ctxt
)
{
if
(
!
ctxt
)
return
GSS_C_NO_CONTEXT
;
return
(
gss_ctx_id_t
)
ctxt
;
}
static
NTSTATUS
status_gss_to_sspi
(
OM_uint32
status
)
{
switch
(
status
)
{
case
GSS_S_COMPLETE
:
return
SEC_E_OK
;
case
GSS_S_BAD_MECH
:
return
SEC_E_SECPKG_NOT_FOUND
;
case
GSS_S_BAD_SIG
:
return
SEC_E_MESSAGE_ALTERED
;
case
GSS_S_NO_CRED
:
return
SEC_E_NO_CREDENTIALS
;
case
GSS_S_NO_CONTEXT
:
return
SEC_E_INVALID_HANDLE
;
case
GSS_S_DEFECTIVE_TOKEN
:
return
SEC_E_INVALID_TOKEN
;
case
GSS_S_DEFECTIVE_CREDENTIAL
:
return
SEC_E_NO_CREDENTIALS
;
case
GSS_S_CREDENTIALS_EXPIRED
:
return
SEC_E_CONTEXT_EXPIRED
;
case
GSS_S_CONTEXT_EXPIRED
:
return
SEC_E_CONTEXT_EXPIRED
;
case
GSS_S_BAD_QOP
:
return
SEC_E_QOP_NOT_SUPPORTED
;
case
GSS_S_CONTINUE_NEEDED
:
return
SEC_I_CONTINUE_NEEDED
;
case
GSS_S_DUPLICATE_TOKEN
:
return
SEC_E_INVALID_TOKEN
;
case
GSS_S_OLD_TOKEN
:
return
SEC_E_INVALID_TOKEN
;
case
GSS_S_UNSEQ_TOKEN
:
return
SEC_E_OUT_OF_SEQUENCE
;
case
GSS_S_GAP_TOKEN
:
return
SEC_E_OUT_OF_SEQUENCE
;
case
GSS_S_FAILURE
:
return
SEC_E_INTERNAL_ERROR
;
default:
FIXME
(
"couldn't convert status 0x%08x to NTSTATUS
\n
"
,
status
);
return
SEC_E_INTERNAL_ERROR
;
}
}
static
void
trace_gss_status_ex
(
OM_uint32
code
,
int
type
)
{
OM_uint32
ret
,
minor_status
;
gss_buffer_desc
buf
;
OM_uint32
message_context
=
0
;
for
(;;)
{
ret
=
pgss_display_status
(
&
minor_status
,
code
,
type
,
GSS_C_NULL_OID
,
&
message_context
,
&
buf
);
if
(
GSS_ERROR
(
ret
))
{
TRACE
(
"gss_display_status(0x%08x,%d) returned %08x minor status %08x
\n
"
,
code
,
type
,
ret
,
minor_status
);
return
;
}
TRACE
(
"GSS-API error: 0x%08x: %s
\n
"
,
code
,
debugstr_an
(
buf
.
value
,
buf
.
length
)
);
pgss_release_buffer
(
&
minor_status
,
&
buf
);
if
(
!
message_context
)
return
;
}
}
static
void
trace_gss_status
(
OM_uint32
major_status
,
OM_uint32
minor_status
)
{
if
(
TRACE_ON
(
kerberos
))
{
trace_gss_status_ex
(
major_status
,
GSS_C_GSS_CODE
);
trace_gss_status_ex
(
minor_status
,
GSS_C_MECH_CODE
);
}
}
static
BOOL
is_dce_style_context
(
gss_ctx_id_t
ctxt_handle
)
{
OM_uint32
ret
,
minor_status
,
flags
;
ret
=
pgss_inquire_context
(
&
minor_status
,
ctxt_handle
,
NULL
,
NULL
,
NULL
,
NULL
,
&
flags
,
NULL
,
NULL
);
return
(
ret
==
GSS_S_COMPLETE
&&
(
flags
&
GSS_C_DCE_STYLE
));
}
static
int
get_buffer_index
(
SecBufferDesc
*
desc
,
DWORD
type
)
{
UINT
i
;
if
(
!
desc
)
return
-
1
;
for
(
i
=
0
;
i
<
desc
->
cBuffers
;
i
++
)
{
if
(
desc
->
pBuffers
[
i
].
BufferType
==
type
)
return
i
;
}
return
-
1
;
}
#endif
/* SONAME_LIBGSSAPI_KRB5 */
static
char
*
get_str_unixcp
(
const
UNICODE_STRING
*
str
)
{
char
*
ret
;
...
...
@@ -955,20 +797,12 @@ static NTSTATUS NTAPI kerberos_SpInitialize(ULONG_PTR package_id, SECPKG_PARAMET
WARN
(
"no Kerberos support
\n
"
);
return
STATUS_UNSUCCESSFUL
;
}
#ifdef SONAME_LIBGSSAPI_KRB5
if
(
load_gssapi_krb5
())
return
STATUS_SUCCESS
;
#endif
return
STATUS_SUCCESS
;
}
static
NTSTATUS
NTAPI
kerberos_SpShutdown
(
void
)
{
TRACE
(
"
\n
"
);
#ifdef SONAME_LIBGSSAPI_KRB5
unload_gssapi_krb5
();
#endif
return
STATUS_SUCCESS
;
}
...
...
@@ -1060,93 +894,14 @@ static NTSTATUS NTAPI kerberos_SpSealMessage( LSA_SEC_HANDLE context, ULONG qual
return
krb5_funcs
->
seal_message
(
context
,
message
,
quality_of_protection
);
}
#ifdef SONAME_LIBGSSAPI_KRB5
static
NTSTATUS
unseal_message_iov
(
gss_ctx_id_t
ctxt_handle
,
SecBufferDesc
*
message
,
ULONG
*
quality_of_protection
)
{
gss_iov_buffer_desc
iov
[
4
];
OM_uint32
ret
,
minor_status
;
int
token_idx
,
data_idx
,
conf_state
;
if
((
data_idx
=
get_buffer_index
(
message
,
SECBUFFER_DATA
))
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
if
((
token_idx
=
get_buffer_index
(
message
,
SECBUFFER_TOKEN
))
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
iov
[
0
].
type
=
GSS_IOV_BUFFER_TYPE_SIGN_ONLY
;
iov
[
0
].
buffer
.
length
=
0
;
iov
[
0
].
buffer
.
value
=
NULL
;
iov
[
1
].
type
=
GSS_IOV_BUFFER_TYPE_DATA
;
iov
[
1
].
buffer
.
length
=
message
->
pBuffers
[
data_idx
].
cbBuffer
;
iov
[
1
].
buffer
.
value
=
message
->
pBuffers
[
data_idx
].
pvBuffer
;
iov
[
2
].
type
=
GSS_IOV_BUFFER_TYPE_SIGN_ONLY
;
iov
[
2
].
buffer
.
length
=
0
;
iov
[
2
].
buffer
.
value
=
NULL
;
iov
[
3
].
type
=
GSS_IOV_BUFFER_TYPE_HEADER
;
iov
[
3
].
buffer
.
length
=
message
->
pBuffers
[
token_idx
].
cbBuffer
;
iov
[
3
].
buffer
.
value
=
message
->
pBuffers
[
token_idx
].
pvBuffer
;
ret
=
pgss_unwrap_iov
(
&
minor_status
,
ctxt_handle
,
&
conf_state
,
NULL
,
iov
,
4
);
TRACE
(
"gss_unwrap_iov returned %08x minor status %08x
\n
"
,
ret
,
minor_status
);
if
(
GSS_ERROR
(
ret
))
trace_gss_status
(
ret
,
minor_status
);
if
(
ret
==
GSS_S_COMPLETE
&&
quality_of_protection
)
{
*
quality_of_protection
=
(
conf_state
?
0
:
SECQOP_WRAP_NO_ENCRYPT
);
}
return
status_gss_to_sspi
(
ret
);
}
static
NTSTATUS
unseal_message
(
gss_ctx_id_t
ctxt_handle
,
SecBufferDesc
*
message
,
ULONG
*
quality_of_protection
)
{
gss_buffer_desc
input
,
output
;
OM_uint32
ret
,
minor_status
;
int
token_idx
,
data_idx
,
conf_state
;
DWORD
len_data
,
len_token
;
if
((
data_idx
=
get_buffer_index
(
message
,
SECBUFFER_DATA
))
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
if
((
token_idx
=
get_buffer_index
(
message
,
SECBUFFER_TOKEN
))
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
len_data
=
message
->
pBuffers
[
data_idx
].
cbBuffer
;
len_token
=
message
->
pBuffers
[
token_idx
].
cbBuffer
;
input
.
length
=
len_data
+
len_token
;
if
(
!
(
input
.
value
=
heap_alloc
(
input
.
length
)))
return
SEC_E_INSUFFICIENT_MEMORY
;
memcpy
(
input
.
value
,
message
->
pBuffers
[
data_idx
].
pvBuffer
,
len_data
);
memcpy
(
(
char
*
)
input
.
value
+
len_data
,
message
->
pBuffers
[
token_idx
].
pvBuffer
,
len_token
);
ret
=
pgss_unwrap
(
&
minor_status
,
ctxt_handle
,
&
input
,
&
output
,
&
conf_state
,
NULL
);
heap_free
(
input
.
value
);
TRACE
(
"gss_unwrap returned %08x minor status %08x
\n
"
,
ret
,
minor_status
);
if
(
GSS_ERROR
(
ret
))
trace_gss_status
(
ret
,
minor_status
);
if
(
ret
==
GSS_S_COMPLETE
)
{
if
(
quality_of_protection
)
*
quality_of_protection
=
(
conf_state
?
0
:
SECQOP_WRAP_NO_ENCRYPT
);
memcpy
(
message
->
pBuffers
[
data_idx
].
pvBuffer
,
output
.
value
,
len_data
);
pgss_release_buffer
(
&
minor_status
,
&
output
);
}
return
status_gss_to_sspi
(
ret
);
}
#endif
static
NTSTATUS
NTAPI
kerberos_SpUnsealMessage
(
LSA_SEC_HANDLE
context
,
SecBufferDesc
*
message
,
ULONG
message_seq_no
,
ULONG
*
quality_of_protection
)
{
#ifdef SONAME_LIBGSSAPI_KRB5
gss_ctx_id_t
ctxt_handle
;
TRACE
(
"(%lx %p %u %p)
\n
"
,
context
,
message
,
message_seq_no
,
quality_of_protection
);
if
(
message_seq_no
)
FIXME
(
"ignoring message_seq_no %u
\n
"
,
message_seq_no
);
if
(
!
context
)
return
SEC_E_INVALID_HANDLE
;
ctxt_handle
=
ctxthandle_sspi_to_gss
(
context
);
if
(
is_dce_style_context
(
ctxt_handle
))
return
unseal_message_iov
(
ctxt_handle
,
message
,
quality_of_protection
);
return
unseal_message
(
ctxt_handle
,
message
,
quality_of_protection
);
#else
FIXME
(
"(%lx %p %u %p)
\n
"
,
context
,
message
,
message_seq_no
,
quality_of_protection
);
return
SEC_E_UNSUPPORTED_FUNCTION
;
#endif
return
krb5_funcs
->
unseal_message
(
context
,
message
,
quality_of_protection
);
}
static
SECPKG_USER_FUNCTION_TABLE
kerberos_user_table
=
...
...
@@ -1175,7 +930,6 @@ NTSTATUS NTAPI SpUserModeInitialize(ULONG lsa_version, PULONG package_version,
*
package_version
=
SECPKG_INTERFACE_VERSION
;
*
table
=
&
kerberos_user_table
;
*
table_count
=
1
;
return
STATUS_SUCCESS
;
}
...
...
dlls/kerberos/unixlib.c
View file @
44593a63
...
...
@@ -734,6 +734,81 @@ static NTSTATUS CDECL seal_message( LSA_SEC_HANDLE context, SecBufferDesc *msg,
return
seal_message_no_vector
(
ctx
,
msg
,
qop
);
}
static
NTSTATUS
unseal_message_vector
(
gss_ctx_id_t
ctx
,
SecBufferDesc
*
msg
,
ULONG
*
qop
)
{
gss_iov_buffer_desc
iov
[
4
];
OM_uint32
ret
,
minor_status
;
int
token_idx
,
data_idx
,
conf_state
;
if
((
data_idx
=
get_buffer_index
(
msg
,
SECBUFFER_DATA
))
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
if
((
token_idx
=
get_buffer_index
(
msg
,
SECBUFFER_TOKEN
))
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
iov
[
0
].
type
=
GSS_IOV_BUFFER_TYPE_SIGN_ONLY
;
iov
[
0
].
buffer
.
length
=
0
;
iov
[
0
].
buffer
.
value
=
NULL
;
iov
[
1
].
type
=
GSS_IOV_BUFFER_TYPE_DATA
;
iov
[
1
].
buffer
.
length
=
msg
->
pBuffers
[
data_idx
].
cbBuffer
;
iov
[
1
].
buffer
.
value
=
msg
->
pBuffers
[
data_idx
].
pvBuffer
;
iov
[
2
].
type
=
GSS_IOV_BUFFER_TYPE_SIGN_ONLY
;
iov
[
2
].
buffer
.
length
=
0
;
iov
[
2
].
buffer
.
value
=
NULL
;
iov
[
3
].
type
=
GSS_IOV_BUFFER_TYPE_HEADER
;
iov
[
3
].
buffer
.
length
=
msg
->
pBuffers
[
token_idx
].
cbBuffer
;
iov
[
3
].
buffer
.
value
=
msg
->
pBuffers
[
token_idx
].
pvBuffer
;
ret
=
pgss_unwrap_iov
(
&
minor_status
,
ctx
,
&
conf_state
,
NULL
,
iov
,
4
);
TRACE
(
"gss_unwrap_iov returned %08x minor status %08x
\n
"
,
ret
,
minor_status
);
if
(
GSS_ERROR
(
ret
))
trace_gss_status
(
ret
,
minor_status
);
if
(
ret
==
GSS_S_COMPLETE
&&
qop
)
{
*
qop
=
(
conf_state
?
0
:
SECQOP_WRAP_NO_ENCRYPT
);
}
return
status_gss_to_sspi
(
ret
);
}
static
NTSTATUS
unseal_message_no_vector
(
gss_ctx_id_t
ctx
,
SecBufferDesc
*
msg
,
ULONG
*
qop
)
{
gss_buffer_desc
input
,
output
;
OM_uint32
ret
,
minor_status
;
int
token_idx
,
data_idx
,
conf_state
;
DWORD
len_data
,
len_token
;
if
((
data_idx
=
get_buffer_index
(
msg
,
SECBUFFER_DATA
))
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
if
((
token_idx
=
get_buffer_index
(
msg
,
SECBUFFER_TOKEN
))
==
-
1
)
return
SEC_E_INVALID_TOKEN
;
len_data
=
msg
->
pBuffers
[
data_idx
].
cbBuffer
;
len_token
=
msg
->
pBuffers
[
token_idx
].
cbBuffer
;
input
.
length
=
len_data
+
len_token
;
if
(
!
(
input
.
value
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
input
.
length
)))
return
SEC_E_INSUFFICIENT_MEMORY
;
memcpy
(
input
.
value
,
msg
->
pBuffers
[
data_idx
].
pvBuffer
,
len_data
);
memcpy
(
(
char
*
)
input
.
value
+
len_data
,
msg
->
pBuffers
[
token_idx
].
pvBuffer
,
len_token
);
ret
=
pgss_unwrap
(
&
minor_status
,
ctx
,
&
input
,
&
output
,
&
conf_state
,
NULL
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
input
.
value
);
TRACE
(
"gss_unwrap returned %08x minor status %08x
\n
"
,
ret
,
minor_status
);
if
(
GSS_ERROR
(
ret
))
trace_gss_status
(
ret
,
minor_status
);
if
(
ret
==
GSS_S_COMPLETE
)
{
if
(
qop
)
*
qop
=
(
conf_state
?
0
:
SECQOP_WRAP_NO_ENCRYPT
);
memcpy
(
msg
->
pBuffers
[
data_idx
].
pvBuffer
,
output
.
value
,
len_data
);
pgss_release_buffer
(
&
minor_status
,
&
output
);
}
return
status_gss_to_sspi
(
ret
);
}
static
NTSTATUS
CDECL
unseal_message
(
LSA_SEC_HANDLE
context
,
SecBufferDesc
*
msg
,
ULONG
*
qop
)
{
gss_ctx_id_t
ctx
=
ctxhandle_sspi_to_gss
(
context
);
if
(
is_dce_style_context
(
ctx
))
return
unseal_message_vector
(
ctx
,
msg
,
qop
);
return
unseal_message_no_vector
(
ctx
,
msg
,
qop
);
}
static
NTSTATUS
CDECL
verify_signature
(
LSA_SEC_HANDLE
context
,
SecBufferDesc
*
msg
,
ULONG
*
qop
)
{
OM_uint32
ret
,
minor_status
;
...
...
@@ -767,6 +842,7 @@ static const struct krb5_funcs funcs =
make_signature
,
query_context_attributes
,
seal_message
,
unseal_message
,
verify_signature
,
};
...
...
dlls/kerberos/unixlib.h
View file @
44593a63
...
...
@@ -34,6 +34,7 @@ struct krb5_funcs
NTSTATUS
(
CDECL
*
make_signature
)(
LSA_SEC_HANDLE
,
SecBufferDesc
*
);
NTSTATUS
(
CDECL
*
query_context_attributes
)(
LSA_SEC_HANDLE
,
ULONG
,
void
*
);
NTSTATUS
(
CDECL
*
seal_message
)(
LSA_SEC_HANDLE
,
SecBufferDesc
*
,
ULONG
);
NTSTATUS
(
CDECL
*
unseal_message
)(
LSA_SEC_HANDLE
,
SecBufferDesc
*
,
ULONG
*
);
NTSTATUS
(
CDECL
*
verify_signature
)(
LSA_SEC_HANDLE
,
SecBufferDesc
*
,
ULONG
*
);
};
...
...
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