From a7b051b590b80a7a473d9eb890c3fd37175ff78f Mon Sep 17 00:00:00 2001 From: David Fort Date: Wed, 2 Jul 2025 09:47:02 +0200 Subject: [PATCH 1/2] nla: fix reading of TsCspDetail Due to a bug in the tag comparison, ReaderName, CardName, CspName and containerName were not read on server side during a smartcard logon, leading to incomplete settings. --- libfreerdp/core/nla.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 759431893..c53881141 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -1112,7 +1112,7 @@ static BOOL set_creds_octetstring_to_settings(WinPrAsn1Decoder* dec, WinPrAsn1_t if (optional) { WinPrAsn1_tagId itemTag = 0; - if (!WinPrAsn1DecPeekTag(dec, &itemTag) || (itemTag != tagId)) + if (!WinPrAsn1DecPeekTag(dec, &itemTag) || (itemTag != (ER_TAG_CONTEXTUAL | tagId))) return TRUE; } From 6e7f5c63553ecc9612d82964dc194413ff2ad698 Mon Sep 17 00:00:00 2001 From: David Fort Date: Wed, 2 Jul 2025 10:01:57 +0200 Subject: [PATCH 2/2] negotiate: add user2user filtering This patch adds the possibility to disable kerberos user2user in the SPnego SSPI module, so you can set "!u2u" in the authPackageList to disable user2user kerberos. It also does a few cleanups (FALSE instead of 0, and defaulting to no kerberos when kerberos support is not compiled in). --- winpr/libwinpr/sspi/Negotiate/negotiate.c | 44 ++++++++++++++++------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/winpr/libwinpr/sspi/Negotiate/negotiate.c b/winpr/libwinpr/sspi/Negotiate/negotiate.c index 9c4c9397c..14dcefc18 100644 --- a/winpr/libwinpr/sspi/Negotiate/negotiate.c +++ b/winpr/libwinpr/sspi/Negotiate/negotiate.c @@ -249,7 +249,8 @@ static BOOL negotiate_get_dword(HKEY hKey, const char* subkey, DWORD* pdwValue) return TRUE; } -static BOOL negotiate_get_config_from_auth_package_list(void* pAuthData, BOOL* kerberos, BOOL* ntlm) +static BOOL negotiate_get_config_from_auth_package_list(void* pAuthData, BOOL* kerberos, BOOL* ntlm, + BOOL* u2u) { char* tok_ctx = NULL; char* tok_ptr = NULL; @@ -271,14 +272,18 @@ static BOOL negotiate_get_config_from_auth_package_list(void* pAuthData, BOOL* k PackageInclude = FALSE; } - if (!_stricmp(PackageName, "ntlm")) + if (_stricmp(PackageName, "ntlm") == 0) { *ntlm = PackageInclude; } - else if (!_stricmp(PackageName, "kerberos")) + else if (_stricmp(PackageName, "kerberos") == 0) { *kerberos = PackageInclude; } + else if (_stricmp(PackageName, "u2u") == 0) + { + *u2u = PackageInclude; + } else { WLog_WARN(TAG, "Unknown authentication package name: %s", PackageName); @@ -291,22 +296,29 @@ static BOOL negotiate_get_config_from_auth_package_list(void* pAuthData, BOOL* k return TRUE; } -static BOOL negotiate_get_config(void* pAuthData, BOOL* kerberos, BOOL* ntlm) +static BOOL negotiate_get_config(void* pAuthData, BOOL* kerberos, BOOL* ntlm, BOOL* u2u) { HKEY hKey = NULL; LONG rc = 0; WINPR_ASSERT(kerberos); WINPR_ASSERT(ntlm); + WINPR_ASSERT(u2u); #if !defined(WITH_KRB5_NO_NTLM_FALLBACK) *ntlm = TRUE; #else *ntlm = FALSE; #endif +#if defined(WITH_KRB5) *kerberos = TRUE; + *u2u = TRUE; +#else + *kerberos = FALSE; + *u2u = FALSE; +#endif - if (negotiate_get_config_from_auth_package_list(pAuthData, kerberos, ntlm)) + if (negotiate_get_config_from_auth_package_list(pAuthData, kerberos, ntlm, u2u)) { return TRUE; // use explicit authentication package list } @@ -1406,10 +1418,11 @@ static SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleW( void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { - BOOL kerberos = 0; - BOOL ntlm = 0; + BOOL kerberos = FALSE; + BOOL ntlm = FALSE; + BOOL u2u = FALSE; - if (!negotiate_get_config(pAuthData, &kerberos, &ntlm)) + if (!negotiate_get_config(pAuthData, &kerberos, &ntlm, &u2u)) return SEC_E_INTERNAL_ERROR; MechCred* creds = calloc(MECH_COUNT, sizeof(MechCred)); @@ -1423,7 +1436,9 @@ static SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleW( const SecPkg* pkg = MechTable[i].pkg; cred->mech = &MechTable[i]; - if (!kerberos && _tcsncmp(pkg->name, KERBEROS_SSP_NAME, ARRAYSIZE(KERBEROS_SSP_NAME)) == 0) + if (!kerberos && sspi_gss_oid_compare(MechTable[i].oid, &kerberos_OID)) + continue; + if (!u2u && sspi_gss_oid_compare(MechTable[i].oid, &kerberos_u2u_OID)) continue; if (!ntlm && _tcsncmp(SecPkgTable[i].name, NTLM_SSP_NAME, ARRAYSIZE(NTLM_SSP_NAME)) == 0) continue; @@ -1448,10 +1463,11 @@ static SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleA( void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { - BOOL kerberos = 0; - BOOL ntlm = 0; + BOOL kerberos = FALSE; + BOOL ntlm = FALSE; + BOOL u2u = FALSE; - if (!negotiate_get_config(pAuthData, &kerberos, &ntlm)) + if (!negotiate_get_config(pAuthData, &kerberos, &ntlm, &u2u)) return SEC_E_INTERNAL_ERROR; MechCred* creds = calloc(MECH_COUNT, sizeof(MechCred)); @@ -1466,7 +1482,9 @@ static SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleA( cred->mech = &MechTable[i]; - if (!kerberos && _tcsncmp(pkg->name, KERBEROS_SSP_NAME, ARRAYSIZE(KERBEROS_SSP_NAME)) == 0) + if (!kerberos && sspi_gss_oid_compare(MechTable[i].oid, &kerberos_OID)) + continue; + if (!u2u && sspi_gss_oid_compare(MechTable[i].oid, &kerberos_u2u_OID)) continue; if (!ntlm && _tcsncmp(SecPkgTable[i].name, NTLM_SSP_NAME, ARRAYSIZE(NTLM_SSP_NAME)) == 0) continue;