From 3a8dce07ea0262b240025bd68b63801578ca63f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 24 Feb 2023 11:34:14 -0500 Subject: [PATCH] expose last NLA/CredSSP SSPI error code (freerdp_get_nla_sspi_error) --- include/freerdp/freerdp.h | 2 ++ libfreerdp/core/credssp_auth.c | 8 ++++++++ libfreerdp/core/credssp_auth.h | 1 + libfreerdp/core/freerdp.c | 13 +++++++++++++ libfreerdp/core/nla.c | 6 ++++++ libfreerdp/core/nla.h | 1 + 6 files changed, 31 insertions(+) diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index a75d3204e..c21f18edd 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -631,6 +631,8 @@ owned by rdpRdp */ FREERDP_API BOOL freerdp_nla_impersonate(rdpContext* context); FREERDP_API BOOL freerdp_nla_revert_to_self(rdpContext* context); + FREERDP_API UINT32 freerdp_get_nla_sspi_error(rdpContext* context); + FREERDP_API void clearChannelError(rdpContext* context); FREERDP_API HANDLE getChannelErrorEventHandle(rdpContext* context); FREERDP_API UINT getChannelError(rdpContext* context); diff --git a/libfreerdp/core/credssp_auth.c b/libfreerdp/core/credssp_auth.c index c91d197fb..e269acc2c 100644 --- a/libfreerdp/core/credssp_auth.c +++ b/libfreerdp/core/credssp_auth.c @@ -65,6 +65,7 @@ struct rdp_credssp_auth SecBuffer output_buffer; ULONG flags; SecPkgContext_Sizes sizes; + SECURITY_STATUS sspi_error; enum AUTH_STATE state; #ifdef UNICODE char* pkgNameA; @@ -441,6 +442,7 @@ int credssp_auth_authenticate(rdpCredsspAuth* auth) WLog_ERR(TAG, "%s failed with %s [0x%08X]", auth->server ? "AcceptSecurityContext" : "InitializeSecurityContext", GetSecurityStatusString(status), status); + auth->sspi_error = status; return -1; } } @@ -653,6 +655,12 @@ const char* credssp_auth_pkg_name(rdpCredsspAuth* auth) #endif } +UINT32 credssp_auth_sspi_error(rdpCredsspAuth* auth) +{ + WINPR_ASSERT(auth); + return (UINT32)auth->sspi_error; +} + void credssp_auth_free(rdpCredsspAuth* auth) { SEC_WINPR_KERBEROS_SETTINGS* krb_settings; diff --git a/libfreerdp/core/credssp_auth.h b/libfreerdp/core/credssp_auth.h index 81493e464..54b108ed5 100644 --- a/libfreerdp/core/credssp_auth.h +++ b/libfreerdp/core/credssp_auth.h @@ -56,6 +56,7 @@ FREERDP_LOCAL BOOL credssp_auth_have_output_token(rdpCredsspAuth* auth); FREERDP_LOCAL BOOL credssp_auth_is_complete(rdpCredsspAuth* auth); FREERDP_LOCAL const char* credssp_auth_pkg_name(rdpCredsspAuth* auth); FREERDP_LOCAL size_t credssp_auth_trailer_size(rdpCredsspAuth* auth); +FREERDP_LOCAL UINT32 credssp_auth_sspi_error(rdpCredsspAuth* auth); FREERDP_LOCAL void credssp_auth_free(rdpCredsspAuth* auth); #endif /* FREERDP_LIB_CORE_CREDSSP_AUTH_H */ diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index fab6ff02d..436ce4fe4 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -1131,6 +1131,19 @@ BOOL freerdp_nla_revert_to_self(rdpContext* context) return nla_revert_to_self(nla); } +UINT32 freerdp_get_nla_sspi_error(rdpContext* context) +{ + rdpNla* nla; + + WINPR_ASSERT(context); + WINPR_ASSERT(context->rdp); + WINPR_ASSERT(context->rdp->transport); + + nla = transport_get_nla(context->rdp->transport); + + return nla_get_sspi_error(nla); +} + HANDLE getChannelErrorEventHandle(rdpContext* context) { WINPR_ASSERT(context); diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index c5cdbd362..3abc969ef 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -1790,3 +1790,9 @@ DWORD nla_get_error(rdpNla* nla) return ERROR_INTERNAL_ERROR; return nla->errorCode; } + +UINT32 nla_get_sspi_error(rdpNla* nla) +{ + WINPR_ASSERT(nla); + return credssp_auth_sspi_error(nla->auth); +} diff --git a/libfreerdp/core/nla.h b/libfreerdp/core/nla.h index 6a03dbca8..527f749b9 100644 --- a/libfreerdp/core/nla.h +++ b/libfreerdp/core/nla.h @@ -57,6 +57,7 @@ FREERDP_LOCAL BOOL nla_set_state(rdpNla* nla, NLA_STATE state); FREERDP_LOCAL const char* nla_get_state_str(NLA_STATE state); FREERDP_LOCAL DWORD nla_get_error(rdpNla* nla); +FREERDP_LOCAL UINT32 nla_get_sspi_error(rdpNla* nla); FREERDP_LOCAL BOOL nla_set_service_principal(rdpNla* nla, const char* service, const char* hostname);