From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kerberos/krb5_ap.c | 59 ++++++++++++++++++++++++++++++++++++----- dlls/kerberos/unixlib.c | 11 ++++---- dlls/kerberos/unixlib.h | 11 +++++--- 3 files changed, 66 insertions(+), 15 deletions(-)
diff --git a/dlls/kerberos/krb5_ap.c b/dlls/kerberos/krb5_ap.c index efd425dc0ee..9fea8c85d89 100644 --- a/dlls/kerberos/krb5_ap.c +++ b/dlls/kerberos/krb5_ap.c @@ -77,6 +77,11 @@ static const SecPkgInfoW infoW = static ULONG kerberos_package_id; static LSA_DISPATCH_TABLE lsa_dispatch;
+struct cred_handle +{ + UINT64 handle; +}; + static const char *debugstr_us( const UNICODE_STRING *us ) { if (!us) return "<null>"; @@ -285,6 +290,7 @@ static NTSTATUS NTAPI kerberos_SpAcquireCredentialsHandle( char *principal = NULL, *username = NULL, *password = NULL; SEC_WINNT_AUTH_IDENTITY_W *id = auth_data; NTSTATUS status = SEC_E_INSUFFICIENT_MEMORY; + struct cred_handle *cred_handle; ULONG exptime;
TRACE( "%s, %#lx, %p, %p, %p, %p, %p, %p\n", debugstr_us(principal_us), credential_use, @@ -303,10 +309,19 @@ static NTSTATUS NTAPI kerberos_SpAcquireCredentialsHandle( if (!(password = get_password_unixcp( id->Password, id->PasswordLength ))) goto done; }
+ if (!(cred_handle = calloc( 1, sizeof(*cred_handle) ))) + { + status = SEC_E_INSUFFICIENT_MEMORY; + goto done; + } + { struct acquire_credentials_handle_params params = { principal, credential_use, username, password, - credential, &exptime }; - status = KRB5_CALL( acquire_credentials_handle, ¶ms ); + &cred_handle->handle, &exptime }; + if (!(status = KRB5_CALL( acquire_credentials_handle, ¶ms ))) + *credential = (LSA_SEC_HANDLE)cred_handle; + else + free( cred_handle ); expiry_to_timestamp( exptime, expiry ); }
@@ -319,9 +334,18 @@ done:
static NTSTATUS NTAPI kerberos_SpFreeCredentialsHandle( LSA_SEC_HANDLE credential ) { + struct cred_handle *cred_handle = (void *)credential; + struct free_credentials_handle_params params; + NTSTATUS status; + TRACE( "%Ix\n", credential ); - if (!credential) return SEC_E_INVALID_HANDLE; - return KRB5_CALL( free_credentials_handle, (void *)credential ); + + if (!cred_handle) return SEC_E_INVALID_HANDLE; + + params.credential = cred_handle->handle; + status = KRB5_CALL( free_credentials_handle, ¶ms ); + free(cred_handle); + return status; }
static NTSTATUS NTAPI kerberos_SpInitLsaModeContext( LSA_SEC_HANDLE credential, LSA_SEC_HANDLE context, @@ -345,8 +369,19 @@ static NTSTATUS NTAPI kerberos_SpInitLsaModeContext( LSA_SEC_HANDLE credential, if (target_name && !(target = get_str_unixcp( target_name ))) return SEC_E_INSUFFICIENT_MEMORY; else { - struct initialize_context_params params = { credential, context, target, context_req, input, - new_context, output, context_attr, &exptime }; + struct cred_handle *cred_handle = (struct cred_handle *)credential; + struct initialize_context_params params; + + params.credential = cred_handle ? cred_handle->handle : 0; + params.context = context; + params.target_name = target; + params.context_req = context_req; + params.input = input; + params.new_context = new_context; + params.output = output; + params.context_attr = context_attr; + params.expiry = &exptime; + status = KRB5_CALL( initialize_context, ¶ms ); if (!status) { @@ -372,7 +407,17 @@ static NTSTATUS NTAPI kerberos_SpAcceptLsaModeContext( LSA_SEC_HANDLE credential
if (context || input || credential) { - struct accept_context_params params = { credential, context, input, new_context, output, context_attr, &exptime }; + struct cred_handle *cred_handle = (struct cred_handle *)credential; + struct accept_context_params params; + + params.credential = cred_handle ? cred_handle->handle : 0; + params.context = context; + params.input = input; + params.new_context = new_context; + params.output = output; + params.context_attr = context_attr; + params.expiry = &exptime; + status = KRB5_CALL( accept_context, ¶ms ); if (!status) { diff --git a/dlls/kerberos/unixlib.c b/dlls/kerberos/unixlib.c index 10d2628b794..66d151488b3 100644 --- a/dlls/kerberos/unixlib.c +++ b/dlls/kerberos/unixlib.c @@ -491,9 +491,9 @@ static inline gss_ctx_id_t ctxhandle_sspi_to_gss( LSA_SEC_HANDLE handle ) return (gss_ctx_id_t)handle; }
-static inline gss_cred_id_t credhandle_sspi_to_gss( LSA_SEC_HANDLE handle ) +static inline gss_cred_id_t credhandle_sspi_to_gss( UINT64 handle ) { - return (gss_cred_id_t)handle; + return (gss_cred_id_t)(ULONG_PTR)handle; }
static inline void ctxhandle_gss_to_sspi( gss_ctx_id_t handle, LSA_SEC_HANDLE *ctx ) @@ -501,9 +501,9 @@ static inline void ctxhandle_gss_to_sspi( gss_ctx_id_t handle, LSA_SEC_HANDLE *c *ctx = (LSA_SEC_HANDLE)handle; }
-static inline void credhandle_gss_to_sspi( gss_cred_id_t handle, LSA_SEC_HANDLE *cred ) +static inline void credhandle_gss_to_sspi( gss_cred_id_t handle, UINT64 *cred ) { - *cred = (LSA_SEC_HANDLE)handle; + *cred = (ULONG_PTR)handle; }
static ULONG flags_gss_to_asc_ret( ULONG flags ) @@ -665,8 +665,9 @@ static NTSTATUS delete_context( void *args )
static NTSTATUS free_credentials_handle( void *args ) { + const struct free_credentials_handle_params *params = args; OM_uint32 ret, minor_status; - gss_cred_id_t cred = credhandle_sspi_to_gss( (LSA_SEC_HANDLE)args ); + gss_cred_id_t cred = credhandle_sspi_to_gss( params->credential );
ret = pgss_release_cred( &minor_status, &cred ); TRACE( "gss_release_cred returned %#x minor status %#x\n", ret, minor_status ); diff --git a/dlls/kerberos/unixlib.h b/dlls/kerberos/unixlib.h index 4a31712bfe8..7c3f97f436d 100644 --- a/dlls/kerberos/unixlib.h +++ b/dlls/kerberos/unixlib.h @@ -25,7 +25,7 @@
struct accept_context_params { - LSA_SEC_HANDLE credential; + UINT64 credential; LSA_SEC_HANDLE context; SecBufferDesc *input; LSA_SEC_HANDLE *new_context; @@ -40,13 +40,18 @@ struct acquire_credentials_handle_params ULONG credential_use; const char *username; const char *password; - LSA_SEC_HANDLE *credential; + UINT64 *credential; ULONG *expiry; };
+struct free_credentials_handle_params +{ + UINT64 credential; +}; + struct initialize_context_params { - LSA_SEC_HANDLE credential; + UINT64 credential; LSA_SEC_HANDLE context; const char *target_name; ULONG context_req;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kerberos/krb5_ap.c | 59 ++++++++++++++++++++++++++++++++++------- dlls/kerberos/unixlib.c | 11 ++++---- dlls/kerberos/unixlib.h | 23 +++++++++------- 3 files changed, 69 insertions(+), 24 deletions(-)
diff --git a/dlls/kerberos/krb5_ap.c b/dlls/kerberos/krb5_ap.c index 9fea8c85d89..cc6df975d25 100644 --- a/dlls/kerberos/krb5_ap.c +++ b/dlls/kerberos/krb5_ap.c @@ -82,6 +82,24 @@ struct cred_handle UINT64 handle; };
+struct context_handle +{ + UINT64 handle; +}; + +static LSA_SEC_HANDLE create_context_handle( struct context_handle *ctx, UINT64 new_context ) +{ + UINT64 context = ctx ? ctx->handle : 0; + if (new_context && new_context != context) + { + struct context_handle *new_ctx = malloc(sizeof(*new_ctx)); + new_ctx->handle = new_context; + return (LSA_SEC_HANDLE)new_ctx; + } + else + return (LSA_SEC_HANDLE)ctx; +} + static const char *debugstr_us( const UNICODE_STRING *us ) { if (!us) return "<null>"; @@ -370,14 +388,16 @@ static NTSTATUS NTAPI kerberos_SpInitLsaModeContext( LSA_SEC_HANDLE credential, else { struct cred_handle *cred_handle = (struct cred_handle *)credential; + struct context_handle *context_handle = (struct context_handle *)context; struct initialize_context_params params; + UINT64 new_context_handle = 0;
params.credential = cred_handle ? cred_handle->handle : 0; - params.context = context; + params.context = context_handle ? context_handle->handle : 0; params.target_name = target; params.context_req = context_req; params.input = input; - params.new_context = new_context; + params.new_context = &new_context_handle; params.output = output; params.context_attr = context_attr; params.expiry = &exptime; @@ -385,6 +405,7 @@ static NTSTATUS NTAPI kerberos_SpInitLsaModeContext( LSA_SEC_HANDLE credential, status = KRB5_CALL( initialize_context, ¶ms ); if (!status) { + *new_context = create_context_handle( context_handle, new_context_handle ); *mapped_context = TRUE; expiry_to_timestamp( exptime, expiry ); } @@ -408,12 +429,14 @@ static NTSTATUS NTAPI kerberos_SpAcceptLsaModeContext( LSA_SEC_HANDLE credential if (context || input || credential) { struct cred_handle *cred_handle = (struct cred_handle *)credential; + struct context_handle *context_handle = (struct context_handle *)context; struct accept_context_params params; + UINT64 new_context_handle = 0;
params.credential = cred_handle ? cred_handle->handle : 0; - params.context = context; + params.context = context_handle ? context_handle->handle : 0; params.input = input; - params.new_context = new_context; + params.new_context = &new_context_handle; params.output = output; params.context_attr = context_attr; params.expiry = &exptime; @@ -421,6 +444,7 @@ static NTSTATUS NTAPI kerberos_SpAcceptLsaModeContext( LSA_SEC_HANDLE credential status = KRB5_CALL( accept_context, ¶ms ); if (!status) { + *new_context = create_context_handle( context_handle, new_context_handle ); *mapped_context = TRUE; expiry_to_timestamp( exptime, expiry ); } @@ -431,9 +455,18 @@ static NTSTATUS NTAPI kerberos_SpAcceptLsaModeContext( LSA_SEC_HANDLE credential
static NTSTATUS NTAPI kerberos_SpDeleteContext( LSA_SEC_HANDLE context ) { + struct context_handle *context_handle = (void *)context; + struct delete_context_params params; + NTSTATUS status; + TRACE( "%Ix\n", context ); + if (!context) return SEC_E_INVALID_HANDLE; - return KRB5_CALL( delete_context, (void *)context ); + + params.context = context_handle->handle; + status = KRB5_CALL( delete_context, ¶ms ); + free( context_handle ); + return status; }
static SecPkgInfoW *build_package_info( const SecPkgInfoW *info ) @@ -456,6 +489,8 @@ static SecPkgInfoW *build_package_info( const SecPkgInfoW *info )
static NTSTATUS NTAPI kerberos_SpQueryContextAttributes( LSA_SEC_HANDLE context, ULONG attribute, void *buffer ) { + struct context_handle *context_handle = (void *)context; + TRACE( "%Ix, %lu, %p\n", context, attribute, buffer );
if (!context) return SEC_E_INVALID_HANDLE; @@ -477,7 +512,7 @@ static NTSTATUS NTAPI kerberos_SpQueryContextAttributes( LSA_SEC_HANDLE context, X(SECPKG_ATTR_TARGET_INFORMATION); case SECPKG_ATTR_SIZES: { - struct query_context_attributes_params params = { context, attribute, buffer }; + struct query_context_attributes_params params = { context_handle->handle, attribute, buffer }; return KRB5_CALL( query_context_attributes, ¶ms ); } case SECPKG_ATTR_NEGOTIATION_INFO: @@ -584,7 +619,8 @@ static NTSTATUS SEC_ENTRY kerberos_SpMakeSignature( LSA_SEC_HANDLE context, ULON
if (context) { - struct make_signature_params params = { context, message }; + struct context_handle *context_handle = (void *)context; + struct make_signature_params params = { context_handle->handle, message }; return KRB5_CALL( make_signature, ¶ms ); } else return SEC_E_INVALID_HANDLE; @@ -598,7 +634,8 @@ static NTSTATUS NTAPI kerberos_SpVerifySignature( LSA_SEC_HANDLE context, SecBuf
if (context) { - struct verify_signature_params params = { context, message, quality_of_protection }; + struct context_handle *context_handle = (void *)context; + struct verify_signature_params params = { context_handle->handle, message, quality_of_protection }; return KRB5_CALL( verify_signature, ¶ms ); } else return SEC_E_INVALID_HANDLE; @@ -612,7 +649,8 @@ static NTSTATUS NTAPI kerberos_SpSealMessage( LSA_SEC_HANDLE context, ULONG qual
if (context) { - struct seal_message_params params = { context, message, quality_of_protection }; + struct context_handle *context_handle = (void *)context; + struct seal_message_params params = { context_handle->handle, message, quality_of_protection }; return KRB5_CALL( seal_message, ¶ms ); } else return SEC_E_INVALID_HANDLE; @@ -626,7 +664,8 @@ static NTSTATUS NTAPI kerberos_SpUnsealMessage( LSA_SEC_HANDLE context, SecBuffe
if (context) { - struct unseal_message_params params = { context, message, quality_of_protection }; + struct context_handle *context_handle = (void *)context; + struct unseal_message_params params = { context_handle->handle, message, quality_of_protection }; return KRB5_CALL( unseal_message, ¶ms ); } else return SEC_E_INVALID_HANDLE; diff --git a/dlls/kerberos/unixlib.c b/dlls/kerberos/unixlib.c index 66d151488b3..4d74dd7eb1f 100644 --- a/dlls/kerberos/unixlib.c +++ b/dlls/kerberos/unixlib.c @@ -486,9 +486,9 @@ static void trace_gss_status( OM_uint32 major_status, OM_uint32 minor_status ) } }
-static inline gss_ctx_id_t ctxhandle_sspi_to_gss( LSA_SEC_HANDLE handle ) +static inline gss_ctx_id_t ctxhandle_sspi_to_gss( UINT64 handle ) { - return (gss_ctx_id_t)handle; + return (gss_ctx_id_t)(ULONG_PTR)handle; }
static inline gss_cred_id_t credhandle_sspi_to_gss( UINT64 handle ) @@ -496,9 +496,9 @@ static inline gss_cred_id_t credhandle_sspi_to_gss( UINT64 handle ) return (gss_cred_id_t)(ULONG_PTR)handle; }
-static inline void ctxhandle_gss_to_sspi( gss_ctx_id_t handle, LSA_SEC_HANDLE *ctx ) +static inline void ctxhandle_gss_to_sspi( gss_ctx_id_t handle, UINT64 *ctx ) { - *ctx = (LSA_SEC_HANDLE)handle; + *ctx = (ULONG_PTR)handle; }
static inline void credhandle_gss_to_sspi( gss_cred_id_t handle, UINT64 *cred ) @@ -654,8 +654,9 @@ static NTSTATUS acquire_credentials_handle( void *args )
static NTSTATUS delete_context( void *args ) { + const struct delete_context_params *params = args; OM_uint32 ret, minor_status; - gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( (LSA_SEC_HANDLE)args ); + gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( params->context );
ret = pgss_delete_sec_context( &minor_status, &ctx_handle, GSS_C_NO_BUFFER ); TRACE( "gss_delete_sec_context returned %#x minor status %#x\n", ret, minor_status ); diff --git a/dlls/kerberos/unixlib.h b/dlls/kerberos/unixlib.h index 7c3f97f436d..2634182ef51 100644 --- a/dlls/kerberos/unixlib.h +++ b/dlls/kerberos/unixlib.h @@ -26,9 +26,9 @@ struct accept_context_params { UINT64 credential; - LSA_SEC_HANDLE context; + UINT64 context; SecBufferDesc *input; - LSA_SEC_HANDLE *new_context; + UINT64 *new_context; SecBufferDesc *output; ULONG *context_attr; ULONG *expiry; @@ -44,6 +44,11 @@ struct acquire_credentials_handle_params ULONG *expiry; };
+struct delete_context_params +{ + UINT64 context; +}; + struct free_credentials_handle_params { UINT64 credential; @@ -52,11 +57,11 @@ struct free_credentials_handle_params struct initialize_context_params { UINT64 credential; - LSA_SEC_HANDLE context; + UINT64 context; const char *target_name; ULONG context_req; SecBufferDesc *input; - LSA_SEC_HANDLE *new_context; + UINT64 *new_context; SecBufferDesc *output; ULONG *context_attr; ULONG *expiry; @@ -64,13 +69,13 @@ struct initialize_context_params
struct make_signature_params { - LSA_SEC_HANDLE context; + UINT64 context; SecBufferDesc *msg; };
struct query_context_attributes_params { - LSA_SEC_HANDLE context; + UINT64 context; unsigned attr; void *buf; }; @@ -83,21 +88,21 @@ struct query_ticket_cache_params
struct seal_message_params { - LSA_SEC_HANDLE context; + UINT64 context; SecBufferDesc *msg; unsigned qop; };
struct unseal_message_params { - LSA_SEC_HANDLE context; + UINT64 context; SecBufferDesc *msg; ULONG *qop; };
struct verify_signature_params { - LSA_SEC_HANDLE context; + UINT64 context; SecBufferDesc *msg; ULONG *qop; };
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kerberos/krb5_ap.c | 27 ++++++++++++++++++++++++--- dlls/kerberos/unixlib.c | 20 ++++++-------------- dlls/kerberos/unixlib.h | 6 ++++-- 3 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/dlls/kerberos/krb5_ap.c b/dlls/kerberos/krb5_ap.c index cc6df975d25..5cc2623c4ad 100644 --- a/dlls/kerberos/krb5_ap.c +++ b/dlls/kerberos/krb5_ap.c @@ -100,6 +100,17 @@ static LSA_SEC_HANDLE create_context_handle( struct context_handle *ctx, UINT64 return (LSA_SEC_HANDLE)ctx; }
+static int get_buffer_index( const 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; +} + static const char *debugstr_us( const UNICODE_STRING *us ) { if (!us) return "<null>"; @@ -421,6 +432,7 @@ static NTSTATUS NTAPI kerberos_SpAcceptLsaModeContext( LSA_SEC_HANDLE credential { NTSTATUS status = SEC_E_INVALID_HANDLE; ULONG exptime; + int idx;
TRACE( "%Ix, %Ix, %#lx, %lu, %p, %p, %p, %p, %p, %p, %p\n", credential, context, context_req, target_data_rep, input, new_context, output, context_attr, expiry, mapped_context, context_data ); @@ -430,17 +442,26 @@ static NTSTATUS NTAPI kerberos_SpAcceptLsaModeContext( LSA_SEC_HANDLE credential { struct cred_handle *cred_handle = (struct cred_handle *)credential; struct context_handle *context_handle = (struct context_handle *)context; - struct accept_context_params params; + struct accept_context_params params = { 0 }; UINT64 new_context_handle = 0;
params.credential = cred_handle ? cred_handle->handle : 0; params.context = context_handle ? context_handle->handle : 0; - params.input = input; params.new_context = &new_context_handle; - params.output = output; params.context_attr = context_attr; params.expiry = &exptime;
+ if (input) + { + if ((idx = get_buffer_index( input, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; + params.input_token = input->pBuffers[idx].pvBuffer; + params.input_token_length = input->pBuffers[idx].cbBuffer; + } + if ((idx = get_buffer_index( output, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; + params.output_token = output->pBuffers[idx].pvBuffer; + params.output_token_length = &output->pBuffers[idx].cbBuffer; + + /* FIXME: check if larger output buffer exists */ status = KRB5_CALL( accept_context, ¶ms ); if (!status) { diff --git a/dlls/kerberos/unixlib.c b/dlls/kerberos/unixlib.c index 4d74dd7eb1f..45d8f0b02da 100644 --- a/dlls/kerberos/unixlib.c +++ b/dlls/kerberos/unixlib.c @@ -528,17 +528,9 @@ static NTSTATUS accept_context( void *args ) gss_cred_id_t cred_handle = credhandle_sspi_to_gss( params->credential ); gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( params->context ); gss_buffer_desc input_token, output_token; - int idx; - - if (!params->input) input_token.length = 0; - else - { - if ((idx = get_buffer_index( params->input, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; - input_token.length = params->input->pBuffers[idx].cbBuffer; - input_token.value = params->input->pBuffers[idx].pvBuffer; - }
- if ((idx = get_buffer_index( params->output, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; + input_token.length = params->input_token_length; + input_token.value = params->input_token; output_token.length = 0; output_token.value = NULL;
@@ -548,16 +540,16 @@ static NTSTATUS accept_context( void *args ) if (GSS_ERROR( ret )) trace_gss_status( ret, minor_status ); if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { - if (output_token.length > params->output->pBuffers[idx].cbBuffer) /* FIXME: check if larger buffer exists */ + if (output_token.length > *params->output_token_length) /* FIXME: check if larger buffer exists */ { TRACE( "buffer too small %lu > %u\n", - (SIZE_T)output_token.length, (unsigned int)params->output->pBuffers[idx].cbBuffer ); + (SIZE_T)output_token.length, (unsigned int)*params->output_token_length ); pgss_release_buffer( &minor_status, &output_token ); pgss_delete_sec_context( &minor_status, &ctx_handle, GSS_C_NO_BUFFER ); return SEC_E_BUFFER_TOO_SMALL; } - params->output->pBuffers[idx].cbBuffer = output_token.length; - memcpy( params->output->pBuffers[idx].pvBuffer, output_token.value, output_token.length ); + *params->output_token_length = output_token.length; + memcpy( params->output_token, output_token.value, output_token.length ); pgss_release_buffer( &minor_status, &output_token );
ctxhandle_gss_to_sspi( ctx_handle, params->new_context ); diff --git a/dlls/kerberos/unixlib.h b/dlls/kerberos/unixlib.h index 2634182ef51..4fada1e1618 100644 --- a/dlls/kerberos/unixlib.h +++ b/dlls/kerberos/unixlib.h @@ -27,9 +27,11 @@ struct accept_context_params { UINT64 credential; UINT64 context; - SecBufferDesc *input; + BYTE *input_token; + ULONG input_token_length; UINT64 *new_context; - SecBufferDesc *output; + BYTE *output_token; + ULONG *output_token_length; ULONG *context_attr; ULONG *expiry; };
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kerberos/krb5_ap.c | 14 +++++++++++++- dlls/kerberos/unixlib.c | 14 ++++---------- dlls/kerberos/unixlib.h | 5 ++++- 3 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/dlls/kerberos/krb5_ap.c b/dlls/kerberos/krb5_ap.c index 5cc2623c4ad..50d58538836 100644 --- a/dlls/kerberos/krb5_ap.c +++ b/dlls/kerberos/krb5_ap.c @@ -641,7 +641,19 @@ static NTSTATUS SEC_ENTRY kerberos_SpMakeSignature( LSA_SEC_HANDLE context, ULON if (context) { struct context_handle *context_handle = (void *)context; - struct make_signature_params params = { context_handle->handle, message }; + struct make_signature_params params; + int data_idx, token_idx; + + /* FIXME: multiple data buffers, read-only buffers */ + 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; + + params.context = context_handle->handle; + params.data_length = message->pBuffers[data_idx].cbBuffer; + params.data = message->pBuffers[data_idx].pvBuffer; + params.token_length = &message->pBuffers[token_idx].cbBuffer; + params.token = message->pBuffers[token_idx].pvBuffer; + return KRB5_CALL( make_signature, ¶ms ); } else return SEC_E_INVALID_HANDLE; diff --git a/dlls/kerberos/unixlib.c b/dlls/kerberos/unixlib.c index 45d8f0b02da..100a905b066 100644 --- a/dlls/kerberos/unixlib.c +++ b/dlls/kerberos/unixlib.c @@ -753,18 +753,12 @@ static NTSTATUS initialize_context( void *args ) static NTSTATUS make_signature( void *args ) { struct make_signature_params *params = args; - SecBufferDesc *msg = params->msg; OM_uint32 ret, minor_status; gss_buffer_desc data_buffer, token_buffer; gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( params->context ); - int data_idx, token_idx; - - /* FIXME: multiple data buffers, read-only buffers */ - if ((data_idx = get_buffer_index( msg, SECBUFFER_DATA )) == -1) return SEC_E_INVALID_TOKEN; - data_buffer.length = msg->pBuffers[data_idx].cbBuffer; - data_buffer.value = msg->pBuffers[data_idx].pvBuffer;
- if ((token_idx = get_buffer_index( msg, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; + data_buffer.length = params->data_length; + data_buffer.value = params->data; token_buffer.length = 0; token_buffer.value = NULL;
@@ -773,8 +767,8 @@ static NTSTATUS make_signature( void *args ) if (GSS_ERROR( ret )) trace_gss_status( ret, minor_status ); if (ret == GSS_S_COMPLETE) { - memcpy( msg->pBuffers[token_idx].pvBuffer, token_buffer.value, token_buffer.length ); - msg->pBuffers[token_idx].cbBuffer = token_buffer.length; + memcpy( params->token, token_buffer.value, token_buffer.length ); + *params->token_length = token_buffer.length; pgss_release_buffer( &minor_status, &token_buffer ); }
diff --git a/dlls/kerberos/unixlib.h b/dlls/kerberos/unixlib.h index 4fada1e1618..b5a058b855c 100644 --- a/dlls/kerberos/unixlib.h +++ b/dlls/kerberos/unixlib.h @@ -72,7 +72,10 @@ struct initialize_context_params struct make_signature_params { UINT64 context; - SecBufferDesc *msg; + BYTE *data; + ULONG data_length; + BYTE *token; + ULONG *token_length; };
struct query_context_attributes_params
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kerberos/krb5_ap.c | 13 ++++++++++++- dlls/kerberos/unixlib.c | 13 ++++--------- dlls/kerberos/unixlib.h | 5 ++++- 3 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/dlls/kerberos/krb5_ap.c b/dlls/kerberos/krb5_ap.c index 50d58538836..cecbd66e3a6 100644 --- a/dlls/kerberos/krb5_ap.c +++ b/dlls/kerberos/krb5_ap.c @@ -668,7 +668,18 @@ static NTSTATUS NTAPI kerberos_SpVerifySignature( LSA_SEC_HANDLE context, SecBuf if (context) { struct context_handle *context_handle = (void *)context; - struct verify_signature_params params = { context_handle->handle, message, quality_of_protection }; + struct verify_signature_params params; + int data_idx, token_idx; + + 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; + + params.context = context_handle->handle; + params.data_length = message->pBuffers[data_idx].cbBuffer; + params.data = message->pBuffers[data_idx].pvBuffer; + params.token_length = message->pBuffers[token_idx].cbBuffer; + params.token = message->pBuffers[token_idx].pvBuffer; + return KRB5_CALL( verify_signature, ¶ms ); } else return SEC_E_INVALID_HANDLE; diff --git a/dlls/kerberos/unixlib.c b/dlls/kerberos/unixlib.c index 100a905b066..6404b6ab190 100644 --- a/dlls/kerberos/unixlib.c +++ b/dlls/kerberos/unixlib.c @@ -996,19 +996,14 @@ static NTSTATUS unseal_message( void *args ) static NTSTATUS verify_signature( void *args ) { struct verify_signature_params *params = args; - SecBufferDesc *msg = params->msg; OM_uint32 ret, minor_status; gss_buffer_desc data_buffer, token_buffer; gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( params->context ); - int data_idx, token_idx;
- if ((data_idx = get_buffer_index( msg, SECBUFFER_DATA )) == -1) return SEC_E_INVALID_TOKEN; - data_buffer.length = msg->pBuffers[data_idx].cbBuffer; - data_buffer.value = msg->pBuffers[data_idx].pvBuffer; - - if ((token_idx = get_buffer_index( msg, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; - token_buffer.length = msg->pBuffers[token_idx].cbBuffer; - token_buffer.value = msg->pBuffers[token_idx].pvBuffer; + data_buffer.length = params->data_length; + data_buffer.value = params->data; + token_buffer.length = params->token_length; + token_buffer.value = params->token;
ret = pgss_verify_mic( &minor_status, ctx_handle, &data_buffer, &token_buffer, NULL ); TRACE( "gss_verify_mic returned %#x minor status %#x\n", ret, minor_status ); diff --git a/dlls/kerberos/unixlib.h b/dlls/kerberos/unixlib.h index b5a058b855c..e7ce7e0b4f3 100644 --- a/dlls/kerberos/unixlib.h +++ b/dlls/kerberos/unixlib.h @@ -108,7 +108,10 @@ struct unseal_message_params struct verify_signature_params { UINT64 context; - SecBufferDesc *msg; + BYTE *data; + ULONG data_length; + BYTE *token; + ULONG token_length; ULONG *qop; };
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kerberos/krb5_ap.c | 15 +++++++++++- dlls/kerberos/unixlib.c | 52 +++++++++++++++++------------------------ dlls/kerberos/unixlib.h | 5 +++- 3 files changed, 40 insertions(+), 32 deletions(-)
diff --git a/dlls/kerberos/krb5_ap.c b/dlls/kerberos/krb5_ap.c index cecbd66e3a6..c531ca6f73c 100644 --- a/dlls/kerberos/krb5_ap.c +++ b/dlls/kerberos/krb5_ap.c @@ -694,7 +694,20 @@ static NTSTATUS NTAPI kerberos_SpSealMessage( LSA_SEC_HANDLE context, ULONG qual if (context) { struct context_handle *context_handle = (void *)context; - struct seal_message_params params = { context_handle->handle, message, quality_of_protection }; + struct seal_message_params params; + int data_idx, token_idx; + + /* FIXME: multiple data buffers, read-only buffers */ + 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; + + params.context = context_handle->handle; + params.data_length = message->pBuffers[data_idx].cbBuffer; + params.data = message->pBuffers[data_idx].pvBuffer; + params.token_length = &message->pBuffers[token_idx].cbBuffer; + params.token = message->pBuffers[token_idx].pvBuffer; + params.qop = quality_of_protection; + return KRB5_CALL( seal_message, ¶ms ); } else return SEC_E_INVALID_HANDLE; diff --git a/dlls/kerberos/unixlib.c b/dlls/kerberos/unixlib.c index 6404b6ab190..21a536f83fc 100644 --- a/dlls/kerberos/unixlib.c +++ b/dlls/kerberos/unixlib.c @@ -815,33 +815,29 @@ static NTSTATUS query_context_attributes( void *args ) return SEC_E_UNSUPPORTED_FUNCTION; }
-static NTSTATUS seal_message_vector( gss_ctx_id_t ctx, SecBufferDesc *msg, unsigned qop ) +static NTSTATUS seal_message_vector( gss_ctx_id_t ctx, const struct seal_message_params *params ) { gss_iov_buffer_desc iov[4]; OM_uint32 ret, minor_status; - int token_idx, data_idx, conf_flag, conf_state; + int conf_flag, conf_state;
- if (!qop) + if (!params->qop) conf_flag = 1; /* confidentiality + integrity */ - else if (qop == SECQOP_WRAP_NO_ENCRYPT) + else if (params->qop == SECQOP_WRAP_NO_ENCRYPT) conf_flag = 0; /* only integrity */ else { - FIXME( "QOP %#x not supported\n", qop ); + FIXME( "QOP %#x not supported\n", params->qop ); return SEC_E_UNSUPPORTED_FUNCTION; }
- /* FIXME: multiple data buffers, read-only buffers */ - 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 | GSS_IOV_BUFFER_FLAG_ALLOCATE; 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[1].buffer.length = params->data_length; + iov[1].buffer.value = params->data;
iov[2].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY | GSS_IOV_BUFFER_FLAG_ALLOCATE; iov[2].buffer.length = 0; @@ -856,52 +852,48 @@ static NTSTATUS seal_message_vector( gss_ctx_id_t ctx, SecBufferDesc *msg, unsig if (GSS_ERROR( ret )) trace_gss_status( ret, minor_status ); if (ret == GSS_S_COMPLETE) { - memcpy( msg->pBuffers[token_idx].pvBuffer, iov[3].buffer.value, iov[3].buffer.length ); - msg->pBuffers[token_idx].cbBuffer = iov[3].buffer.length; + memcpy( params->token, iov[3].buffer.value, iov[3].buffer.length ); + *params->token_length = iov[3].buffer.length; pgss_release_iov_buffer( &minor_status, iov, 4 ); }
return status_gss_to_sspi( ret ); }
-static NTSTATUS seal_message_no_vector( gss_ctx_id_t ctx, SecBufferDesc *msg, unsigned qop ) +static NTSTATUS seal_message_no_vector( gss_ctx_id_t ctx, const struct seal_message_params *params ) { gss_buffer_desc input, output; OM_uint32 ret, minor_status; - int token_idx, data_idx, conf_flag, conf_state; + int conf_flag, conf_state;
- if (!qop) + if (!params->qop) conf_flag = 1; /* confidentiality + integrity */ - else if (qop == SECQOP_WRAP_NO_ENCRYPT) + else if (params->qop == SECQOP_WRAP_NO_ENCRYPT) conf_flag = 0; /* only integrity */ else { - FIXME( "QOP %#x not supported\n", qop ); + FIXME( "QOP %#x not supported\n", params->qop ); return SEC_E_UNSUPPORTED_FUNCTION; }
- /* FIXME: multiple data buffers, read-only buffers */ - 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; - - input.length = msg->pBuffers[data_idx].cbBuffer; - input.value = msg->pBuffers[data_idx].pvBuffer; + input.length = params->data_length; + input.value = params->data;
ret = pgss_wrap( &minor_status, ctx, conf_flag, GSS_C_QOP_DEFAULT, &input, &conf_state, &output ); TRACE( "gss_wrap returned %#x minor status %#x\n", ret, minor_status ); if (GSS_ERROR( ret )) trace_gss_status( ret, minor_status ); if (ret == GSS_S_COMPLETE) { - unsigned len_data = msg->pBuffers[data_idx].cbBuffer, len_token = msg->pBuffers[token_idx].cbBuffer; + unsigned len_data = params->data_length, len_token = *params->token_length; if (len_token < output.length - len_data) { TRACE( "buffer too small %lu > %u\n", (SIZE_T)output.length - len_data, len_token ); pgss_release_buffer( &minor_status, &output ); return SEC_E_BUFFER_TOO_SMALL; } - memcpy( msg->pBuffers[data_idx].pvBuffer, output.value, len_data ); - memcpy( msg->pBuffers[token_idx].pvBuffer, (char *)output.value + len_data, output.length - len_data ); - msg->pBuffers[token_idx].cbBuffer = output.length - len_data; + memcpy( params->data, output.value, len_data ); + memcpy( params->token, (char *)output.value + len_data, output.length - len_data ); + *params->token_length = output.length - len_data; pgss_release_buffer( &minor_status, &output ); }
@@ -913,8 +905,8 @@ static NTSTATUS seal_message( void *args ) struct seal_message_params *params = args; gss_ctx_id_t ctx = ctxhandle_sspi_to_gss( params->context );
- if (is_dce_style_context( ctx )) return seal_message_vector( ctx, params->msg, params->qop ); - return seal_message_no_vector( ctx, params->msg, params->qop ); + if (is_dce_style_context( ctx )) return seal_message_vector( ctx, params ); + return seal_message_no_vector( ctx, params ); }
static NTSTATUS unseal_message_vector( gss_ctx_id_t ctx, SecBufferDesc *msg, ULONG *qop ) diff --git a/dlls/kerberos/unixlib.h b/dlls/kerberos/unixlib.h index e7ce7e0b4f3..5753ae1a2da 100644 --- a/dlls/kerberos/unixlib.h +++ b/dlls/kerberos/unixlib.h @@ -94,7 +94,10 @@ struct query_ticket_cache_params struct seal_message_params { UINT64 context; - SecBufferDesc *msg; + BYTE *data; + ULONG data_length; + BYTE *token; + ULONG *token_length; unsigned qop; };
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kerberos/krb5_ap.c | 14 +++++++++++++- dlls/kerberos/unixlib.c | 42 ++++++++++++++++++----------------------- dlls/kerberos/unixlib.h | 5 ++++- 3 files changed, 35 insertions(+), 26 deletions(-)
diff --git a/dlls/kerberos/krb5_ap.c b/dlls/kerberos/krb5_ap.c index c531ca6f73c..8d72e97cbf9 100644 --- a/dlls/kerberos/krb5_ap.c +++ b/dlls/kerberos/krb5_ap.c @@ -722,7 +722,19 @@ static NTSTATUS NTAPI kerberos_SpUnsealMessage( LSA_SEC_HANDLE context, SecBuffe if (context) { struct context_handle *context_handle = (void *)context; - struct unseal_message_params params = { context_handle->handle, message, quality_of_protection }; + struct unseal_message_params params; + int data_idx, token_idx; + + 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; + + params.context = context_handle->handle; + params.data_length = message->pBuffers[data_idx].cbBuffer; + params.data = message->pBuffers[data_idx].pvBuffer; + params.token_length = message->pBuffers[token_idx].cbBuffer; + params.token = message->pBuffers[token_idx].pvBuffer; + params.qop = quality_of_protection; + return KRB5_CALL( unseal_message, ¶ms ); } else return SEC_E_INVALID_HANDLE; diff --git a/dlls/kerberos/unixlib.c b/dlls/kerberos/unixlib.c index 21a536f83fc..119d2d1dcf9 100644 --- a/dlls/kerberos/unixlib.c +++ b/dlls/kerberos/unixlib.c @@ -909,58 +909,52 @@ static NTSTATUS seal_message( void *args ) return seal_message_no_vector( ctx, params ); }
-static NTSTATUS unseal_message_vector( gss_ctx_id_t ctx, SecBufferDesc *msg, ULONG *qop ) +static NTSTATUS unseal_message_vector( gss_ctx_id_t ctx, const struct unseal_message_params *params ) { 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; + int conf_state;
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[1].buffer.length = params->data_length; + iov[1].buffer.value = params->data;
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; + iov[3].buffer.length = params->token_length; + iov[3].buffer.value = params->token;
ret = pgss_unwrap_iov( &minor_status, ctx, &conf_state, NULL, iov, 4 ); TRACE( "gss_unwrap_iov returned %#x minor status %#x\n", ret, minor_status ); if (GSS_ERROR( ret )) trace_gss_status( ret, minor_status ); - if (ret == GSS_S_COMPLETE && qop) + if (ret == GSS_S_COMPLETE && params->qop) { - *qop = (conf_state ? 0 : SECQOP_WRAP_NO_ENCRYPT); + *params->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 ) +static NTSTATUS unseal_message_no_vector( gss_ctx_id_t ctx, const struct unseal_message_params *params ) { gss_buffer_desc input, output; OM_uint32 ret, minor_status; - int token_idx, data_idx, conf_state; DWORD len_data, len_token; + int 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; - - len_data = msg->pBuffers[data_idx].cbBuffer; - len_token = msg->pBuffers[token_idx].cbBuffer; + len_data = params->data_length; + len_token = params->token_length;
input.length = len_data + len_token; if (!(input.value = malloc( 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 ); + memcpy( input.value, params->data, len_data ); + memcpy( (char *)input.value + len_data, params->token, len_token );
ret = pgss_unwrap( &minor_status, ctx, &input, &output, &conf_state, NULL ); free( input.value ); @@ -968,8 +962,8 @@ static NTSTATUS unseal_message_no_vector( gss_ctx_id_t ctx, SecBufferDesc *msg, 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 ); + if (params->qop) *params->qop = (conf_state ? 0 : SECQOP_WRAP_NO_ENCRYPT); + memcpy( params->data, output.value, len_data ); pgss_release_buffer( &minor_status, &output ); }
@@ -981,8 +975,8 @@ static NTSTATUS unseal_message( void *args ) struct unseal_message_params *params = args; gss_ctx_id_t ctx = ctxhandle_sspi_to_gss( params->context );
- if (is_dce_style_context( ctx )) return unseal_message_vector( ctx, params->msg, params->qop ); - return unseal_message_no_vector( ctx, params->msg, params->qop ); + if (is_dce_style_context( ctx )) return unseal_message_vector( ctx, params ); + return unseal_message_no_vector( ctx, params ); }
static NTSTATUS verify_signature( void *args ) diff --git a/dlls/kerberos/unixlib.h b/dlls/kerberos/unixlib.h index 5753ae1a2da..0bdb8a3ec74 100644 --- a/dlls/kerberos/unixlib.h +++ b/dlls/kerberos/unixlib.h @@ -104,7 +104,10 @@ struct seal_message_params struct unseal_message_params { UINT64 context; - SecBufferDesc *msg; + BYTE *data; + ULONG data_length; + BYTE *token; + ULONG token_length; ULONG *qop; };
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kerberos/krb5_ap.c | 16 +++++++++++++--- dlls/kerberos/unixlib.c | 31 ++++++------------------------- dlls/kerberos/unixlib.h | 6 ++++-- 3 files changed, 23 insertions(+), 30 deletions(-)
diff --git a/dlls/kerberos/krb5_ap.c b/dlls/kerberos/krb5_ap.c index 8d72e97cbf9..2010995b7e0 100644 --- a/dlls/kerberos/krb5_ap.c +++ b/dlls/kerberos/krb5_ap.c @@ -400,19 +400,29 @@ static NTSTATUS NTAPI kerberos_SpInitLsaModeContext( LSA_SEC_HANDLE credential, { struct cred_handle *cred_handle = (struct cred_handle *)credential; struct context_handle *context_handle = (struct context_handle *)context; - struct initialize_context_params params; + struct initialize_context_params params = { 0 }; UINT64 new_context_handle = 0; + int idx;
params.credential = cred_handle ? cred_handle->handle : 0; params.context = context_handle ? context_handle->handle : 0; params.target_name = target; params.context_req = context_req; - params.input = input; params.new_context = &new_context_handle; - params.output = output; params.context_attr = context_attr; params.expiry = &exptime;
+ idx = get_buffer_index( input, SECBUFFER_TOKEN ); + if (idx != -1) + { + params.input_token = input->pBuffers[idx].pvBuffer; + params.input_token_length = input->pBuffers[idx].cbBuffer; + } + + if ((idx = get_buffer_index( output, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; + params.output_token = output->pBuffers[idx].pvBuffer; + params.output_token_length = &output->pBuffers[idx].cbBuffer; + status = KRB5_CALL( initialize_context, ¶ms ); if (!status) { diff --git a/dlls/kerberos/unixlib.c b/dlls/kerberos/unixlib.c index 119d2d1dcf9..38b1cf50895 100644 --- a/dlls/kerberos/unixlib.c +++ b/dlls/kerberos/unixlib.c @@ -419,17 +419,6 @@ static BOOL is_dce_style_context( gss_ctx_id_t ctx ) 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; -} - static NTSTATUS status_gss_to_sspi( OM_uint32 status ) { switch (status) @@ -707,16 +696,9 @@ static NTSTATUS initialize_context( void *args ) gss_buffer_desc input_token, output_token; gss_name_t target = GSS_C_NO_NAME; NTSTATUS status; - int idx;
- if ((idx = get_buffer_index( params->input, SECBUFFER_TOKEN )) == -1) input_token.length = 0; - else - { - input_token.length = params->input->pBuffers[idx].cbBuffer; - input_token.value = params->input->pBuffers[idx].pvBuffer; - } - - if ((idx = get_buffer_index( params->output, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; + input_token.length = params->input_token_length; + input_token.value = params->input_token; output_token.length = 0; output_token.value = NULL;
@@ -729,16 +711,15 @@ static NTSTATUS initialize_context( void *args ) if (GSS_ERROR( ret )) trace_gss_status( ret, minor_status ); if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { - if (output_token.length > params->output->pBuffers[idx].cbBuffer) /* FIXME: check if larger buffer exists */ + if (output_token.length > *params->output_token_length) /* FIXME: check if larger buffer exists */ { - TRACE( "buffer too small %lu > %u\n", - (SIZE_T)output_token.length, (unsigned int)params->output->pBuffers[idx].cbBuffer ); + TRACE( "buffer too small %lu > %u\n", (SIZE_T)output_token.length, (unsigned int)*params->output_token_length); pgss_release_buffer( &minor_status, &output_token ); pgss_delete_sec_context( &minor_status, &ctx_handle, GSS_C_NO_BUFFER ); return SEC_E_INCOMPLETE_MESSAGE; } - params->output->pBuffers[idx].cbBuffer = output_token.length; - memcpy( params->output->pBuffers[idx].pvBuffer, output_token.value, output_token.length ); + *params->output_token_length = output_token.length; + memcpy( params->output_token, output_token.value, output_token.length ); pgss_release_buffer( &minor_status, &output_token );
ctxhandle_gss_to_sspi( ctx_handle, params->new_context ); diff --git a/dlls/kerberos/unixlib.h b/dlls/kerberos/unixlib.h index 0bdb8a3ec74..f811f583bb2 100644 --- a/dlls/kerberos/unixlib.h +++ b/dlls/kerberos/unixlib.h @@ -62,9 +62,11 @@ struct initialize_context_params UINT64 context; const char *target_name; ULONG context_req; - SecBufferDesc *input; + BYTE *input_token; + ULONG input_token_length; + BYTE *output_token; + ULONG *output_token_length; UINT64 *new_context; - SecBufferDesc *output; ULONG *context_attr; ULONG *expiry; };
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kerberos/unixlib.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/dlls/kerberos/unixlib.c b/dlls/kerberos/unixlib.c index 38b1cf50895..95e832e81d3 100644 --- a/dlls/kerberos/unixlib.c +++ b/dlls/kerberos/unixlib.c @@ -303,16 +303,13 @@ static NTSTATUS copy_tickets_to_client( struct ticket_list *list, KERB_QUERY_TKT return STATUS_SUCCESS; }
-static NTSTATUS query_ticket_cache( void *args ) +static NTSTATUS kerberos_fill_ticket_list( struct ticket_list *list ) { - struct query_ticket_cache_params *params = args; NTSTATUS status; krb5_error_code err; krb5_context ctx; krb5_cccol_cursor cursor = NULL; krb5_ccache cache; - ULONG i; - struct ticket_list list = { 0 };
if ((err = p_krb5_init_context( &ctx ))) return krb5_error_to_status( err ); if ((err = p_krb5_cccol_cursor_new( ctx, &cursor ))) @@ -330,7 +327,7 @@ static NTSTATUS query_ticket_cache( void *args ) } if (!cache) break;
- status = copy_tickets_from_cache( ctx, cache, &list ); + status = copy_tickets_from_cache( ctx, cache, list ); p_krb5_cc_close( ctx, cache ); if (status != STATUS_SUCCESS) goto done; } @@ -339,6 +336,18 @@ done: if (cursor) p_krb5_cccol_cursor_free( ctx, &cursor ); if (ctx) p_krb5_free_context( ctx );
+ return status; +} + +static NTSTATUS query_ticket_cache( void *args ) +{ + struct query_ticket_cache_params *params = args; + struct ticket_list list = { 0 }; + NTSTATUS status; + ULONG i; + + status = kerberos_fill_ticket_list( &list ); + if (status == STATUS_SUCCESS) status = copy_tickets_to_client( &list, params->resp, params->out_size );
for (i = 0; i < list.count; i++)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kerberos/unixlib.c | 325 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+)
diff --git a/dlls/kerberos/unixlib.c b/dlls/kerberos/unixlib.c index 95e832e81d3..a918959dbe5 100644 --- a/dlls/kerberos/unixlib.c +++ b/dlls/kerberos/unixlib.c @@ -1012,4 +1012,329 @@ unixlib_entry_t __wine_unix_call_funcs[] = verify_signature, };
+#ifdef _WIN64 + +typedef ULONG PTR32; + +static NTSTATUS wow64_accept_context( void *args ) +{ + struct + { + UINT64 credential; + UINT64 context; + PTR32 input_token; + ULONG input_token_length; + PTR32 new_context; + PTR32 output_token; + PTR32 output_token_length; + PTR32 context_attr; + PTR32 expiry; + } const *params32 = args; + struct accept_context_params params = + { + params32->credential, + params32->context, + ULongToPtr(params32->input_token), + params32->input_token_length, + ULongToPtr(params32->new_context), + ULongToPtr(params32->output_token), + ULongToPtr(params32->output_token_length), + ULongToPtr(params32->context_attr), + ULongToPtr(params32->expiry), + }; + return accept_context( ¶ms ); +} + +static NTSTATUS wow64_acquire_credentials_handle( void *args ) +{ + struct + { + PTR32 principal; + ULONG credential_use; + PTR32 username; + PTR32 password; + PTR32 credential; + PTR32 expiry; + } const *params32 = args; + struct acquire_credentials_handle_params params = + { + ULongToPtr(params32->principal), + params32->credential_use, + ULongToPtr(params32->username), + ULongToPtr(params32->password), + ULongToPtr(params32->credential), + ULongToPtr(params32->expiry), + }; + return acquire_credentials_handle( ¶ms ); +} + +static NTSTATUS wow64_delete_context( void *args ) +{ + struct + { + UINT64 context; + } const *params32 = args; + struct delete_context_params params = + { + params32->context, + }; + return delete_context( ¶ms ); +} + +static NTSTATUS wow64_free_credentials_handle( void *args ) +{ + struct + { + UINT64 credential; + } const *params32 = args; + struct free_credentials_handle_params params = + { + params32->credential, + }; + return free_credentials_handle( ¶ms ); +} + +static NTSTATUS wow64_initialize_context( void *args ) +{ + struct + { + UINT64 credential; + UINT64 context; + PTR32 target_name; + ULONG context_req; + PTR32 input_token; + ULONG input_token_length; + PTR32 output_token; + PTR32 output_token_length; + PTR32 new_context; + PTR32 context_attr; + PTR32 expiry; + } const *params32 = args; + struct initialize_context_params params = + { + params32->credential, + params32->context, + ULongToPtr(params32->target_name), + params32->context_req, + ULongToPtr(params32->input_token), + params32->input_token_length, + ULongToPtr(params32->output_token), + ULongToPtr(params32->output_token_length), + ULongToPtr(params32->new_context), + ULongToPtr(params32->context_attr), + ULongToPtr(params32->expiry), + }; + return initialize_context( ¶ms ); +} + +static NTSTATUS wow64_make_signature( void *args ) +{ + struct + { + UINT64 context; + PTR32 data; + ULONG data_length; + PTR32 token; + PTR32 token_length; + } const *params32 = args; + struct make_signature_params params = + { + params32->context, + ULongToPtr(params32->data), + params32->data_length, + ULongToPtr(params32->token), + ULongToPtr(params32->token_length), + }; + return make_signature( ¶ms ); +} + +static NTSTATUS wow64_query_context_attributes( void *args ) +{ + struct + { + UINT64 context; + ULONG attr; + PTR32 buf; + } const *params32 = args; + struct query_context_attributes_params params = + { + params32->context, + params32->attr, + ULongToPtr(params32->buf), + }; + return query_context_attributes( ¶ms ); +} + +struct KERB_TICKET_CACHE_INFO32 +{ + UNICODE_STRING32 ServerName; + UNICODE_STRING32 RealmName; + LARGE_INTEGER StartTime; + LARGE_INTEGER EndTime; + LARGE_INTEGER RenewTime; + LONG EncryptionType; + ULONG TicketFlags; +}; + +struct KERB_QUERY_TKT_CACHE_RESPONSE32 +{ + KERB_PROTOCOL_MESSAGE_TYPE MessageType; + ULONG CountOfTickets; + struct KERB_TICKET_CACHE_INFO32 Tickets[ANYSIZE_ARRAY]; +}; + +static void copy_ticket_ustr_64to32( const UNICODE_STRING *str, UNICODE_STRING32 *str32, ULONG *client_str ) +{ + str32->Length = str->Length; + str32->MaximumLength = str->MaximumLength; + str32->Buffer = *client_str; + memcpy( ULongToPtr(str32->Buffer), str->Buffer, str->MaximumLength ); + *client_str += str->MaximumLength; +} + +static NTSTATUS copy_tickets_to_client32( struct ticket_list *list, struct KERB_QUERY_TKT_CACHE_RESPONSE32 *resp, + ULONG *out_size ) +{ + ULONG i, size, size_fixed; + ULONG client_str; + + size = size_fixed = offsetof( struct KERB_QUERY_TKT_CACHE_RESPONSE32, Tickets[list->count] ); + for (i = 0; i < list->count; i++) + { + size += list->tickets[i].RealmName.MaximumLength; + size += list->tickets[i].ServerName.MaximumLength; + } + if (!resp || size > *out_size) + { + *out_size = size; + return STATUS_BUFFER_TOO_SMALL; + } + *out_size = size; + + resp->MessageType = KerbQueryTicketCacheMessage; + resp->CountOfTickets = list->count; + client_str = PtrToUlong(resp) + size_fixed; + + for (i = 0; i < list->count; i++) + { + copy_ticket_ustr_64to32( &list->tickets[i].ServerName, &resp->Tickets[i].ServerName, &client_str ); + copy_ticket_ustr_64to32( &list->tickets[i].RealmName, &resp->Tickets[i].RealmName, &client_str ); + resp->Tickets[i].StartTime = list->tickets[i].StartTime; + resp->Tickets[i].EndTime = list->tickets[i].EndTime; + resp->Tickets[i].RenewTime = list->tickets[i].RenewTime; + resp->Tickets[i].EncryptionType = list->tickets[i].EncryptionType; + resp->Tickets[i].TicketFlags = list->tickets[i].TicketFlags; + } + return STATUS_SUCCESS; +} + +static NTSTATUS wow64_query_ticket_cache( void *args ) +{ + struct + { + PTR32 resp; + PTR32 out_size; + } const *params32 = args; + struct ticket_list list = { 0 }; + NTSTATUS status; + ULONG i; + + status = kerberos_fill_ticket_list( &list ); + if (status == STATUS_SUCCESS) + status = copy_tickets_to_client32( &list, ULongToPtr(params32->resp), ULongToPtr(params32->out_size) ); + + for (i = 0; i < list.count; i++) + { + free( list.tickets[i].RealmName.Buffer ); + free( list.tickets[i].ServerName.Buffer ); + } + return status; + +} + +static NTSTATUS wow64_seal_message( void *args ) +{ + struct + { + UINT64 context; + PTR32 data; + ULONG data_length; + PTR32 token; + PTR32 token_length; + } const *params32 = args; + struct seal_message_params params = + { + params32->context, + ULongToPtr(params32->data), + params32->data_length, + ULongToPtr(params32->token), + ULongToPtr(params32->token_length), + }; + return seal_message( ¶ms ); +} + +static NTSTATUS wow64_unseal_message( void *args ) +{ + struct + { + UINT64 context; + PTR32 data; + ULONG data_length; + PTR32 token; + ULONG token_length; + PTR32 qop; + } const *params32 = args; + struct unseal_message_params params = + { + params32->context, + ULongToPtr(params32->data), + params32->data_length, + ULongToPtr(params32->token), + params32->token_length, + ULongToPtr(params32->qop), + }; + return unseal_message( ¶ms ); +} + +static NTSTATUS wow64_verify_signature( void *args ) +{ + struct + { + UINT64 context; + PTR32 data; + ULONG data_length; + PTR32 token; + ULONG token_length; + PTR32 qop; + } const *params32 = args; + struct verify_signature_params params = + { + params32->context, + ULongToPtr(params32->data), + params32->data_length, + ULongToPtr(params32->token), + params32->token_length, + ULongToPtr(params32->qop), + }; + return verify_signature( ¶ms ); +} + +unixlib_entry_t __wine_unix_call_wow64_funcs[] = +{ + process_attach, + wow64_accept_context, + wow64_acquire_credentials_handle, + wow64_delete_context, + wow64_free_credentials_handle, + wow64_initialize_context, + wow64_make_signature, + wow64_query_context_attributes, + wow64_query_ticket_cache, + wow64_seal_message, + wow64_unseal_message, + wow64_verify_signature, +}; + +#endif /* _WIN64 */ + #endif /* defined(SONAME_LIBKRB5) && defined(SONAME_LIBGSSAPI_KRB5) */
Hans Leidekker (@hans) commented about dlls/kerberos/krb5_ap.c:
{ struct context_handle *context_handle = (void *)context;
struct verify_signature_params params = { context_handle->handle, message, quality_of_protection };
struct verify_signature_params params;
int data_idx, token_idx;
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;
params.context = context_handle->handle;
params.data_length = message->pBuffers[data_idx].cbBuffer;
params.data = message->pBuffers[data_idx].pvBuffer;
params.token_length = message->pBuffers[token_idx].cbBuffer;
params.token = message->pBuffers[token_idx].pvBuffer;
return KRB5_CALL( verify_signature, ¶ms );
quality_of_protection should still be passed to the Unix call.