From 6f639686cf96327534a2256bf202aad8f197e6ca Mon Sep 17 00:00:00 2001 From: Martin Fleisz Date: Thu, 16 Feb 2023 11:18:30 +0100 Subject: [PATCH] core: Allow change to smart card logon in Authentication callbacks This PR adds a few changes so that a client is able to change the authentication/logon type in the Authentication callback. I.e. if the client was started without user/domain the authentication callback is now able to activate smart card logon by setting the SmartcardLogon setting along with csp/container/reader name. --- libfreerdp/core/gateway/rdg.c | 62 +++++++++++++++++++---------------- libfreerdp/core/nla.c | 35 +++++++++++--------- libfreerdp/core/utils.c | 21 ++++++++++++ 3 files changed, 75 insertions(+), 43 deletions(-) diff --git a/libfreerdp/core/gateway/rdg.c b/libfreerdp/core/gateway/rdg.c index aa2316188..c31d42bab 100644 --- a/libfreerdp/core/gateway/rdg.c +++ b/libfreerdp/core/gateway/rdg.c @@ -1686,51 +1686,57 @@ static BOOL rdg_auth_init(rdpRdg* rdg, rdpTls* tls, TCHAR* authPkg) if (!credssp_auth_init(rdg->auth, authPkg, tls->Bindings)) return FALSE; - if (freerdp_settings_get_bool(settings, FreeRDP_SmartcardLogon)) + bool doSCLogon = freerdp_settings_get_bool(settings, FreeRDP_SmartcardLogon); + if (doSCLogon) { if (!smartcard_getCert(context, &rdg->smartcard, TRUE)) return FALSE; if (!rdg_get_gateway_credentials(context, AUTH_SMARTCARD_PIN)) return FALSE; -#ifdef _WIN32 - { - CERT_CREDENTIAL_INFO certInfo = { sizeof(CERT_CREDENTIAL_INFO), { 0 } }; - LPSTR marshalledCredentials; - - memcpy(certInfo.rgbHashOfCert, rdg->smartcard->sha1Hash, - sizeof(certInfo.rgbHashOfCert)); - - if (!CredMarshalCredentialA(CertCredential, &certInfo, &marshalledCredentials)) - { - WLog_ERR(TAG, "error marshalling cert credentials"); - return FALSE; - } - - if (sspi_SetAuthIdentityA(&identity, marshalledCredentials, NULL, - settings->GatewayPassword) < 0) - return FALSE; - - CredFree(marshalledCredentials); - } -#else - if (sspi_SetAuthIdentityA(&identity, settings->GatewayUsername, settings->GatewayDomain, - settings->GatewayPassword) < 0) - return FALSE; -#endif } else { if (!rdg_get_gateway_credentials(context, GW_AUTH_RDG)) return FALSE; + /* Auth callback might changed logon to smartcard so check again */ + doSCLogon = freerdp_settings_get_bool(settings, FreeRDP_SmartcardLogon); + if (doSCLogon && !smartcard_getCert(context, &rdg->smartcard, TRUE)) + return FALSE; + } + +#ifdef _WIN32 + if (doSCLogon) + { + CERT_CREDENTIAL_INFO certInfo = { sizeof(CERT_CREDENTIAL_INFO), { 0 } }; + LPSTR marshalledCredentials; + + memcpy(certInfo.rgbHashOfCert, rdg->smartcard->sha1Hash, sizeof(certInfo.rgbHashOfCert)); + + if (!CredMarshalCredentialA(CertCredential, &certInfo, &marshalledCredentials)) + { + WLog_ERR(TAG, "error marshaling cert credentials"); + return FALSE; + } + + if (sspi_SetAuthIdentityA(&identity, marshalledCredentials, NULL, + settings->GatewayPassword) < 0) + return FALSE; + + CredFree(marshalledCredentials); + } + else +#else + { if (sspi_SetAuthIdentityA(&identity, settings->GatewayUsername, settings->GatewayDomain, settings->GatewayPassword) < 0) return FALSE; } +#endif - if (!credssp_auth_setup_client(rdg->auth, "HTTP", settings->GatewayHostname, &identity, - rdg->smartcard ? rdg->smartcard->pkinitArgs : NULL)) + if (!credssp_auth_setup_client(rdg->auth, "HTTP", settings->GatewayHostname, &identity, + rdg->smartcard ? rdg->smartcard->pkinitArgs : NULL)) { sspi_FreeAuthIdentity(&identity); return FALSE; diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 8c8cbe973..b3bd409b5 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -323,6 +323,7 @@ static BOOL nla_client_setup_identity(rdpNla* nla) } #endif + BOOL smartCardLogonWasDisabled = !settings->SmartcardLogon; if (PromptPassword) { switch (utils_authenticate(instance, AUTH_NLA, TRUE)) @@ -350,24 +351,28 @@ static BOOL nla_client_setup_identity(rdpNla* nla) else if (settings->SmartcardLogon) { #ifdef _WIN32 + CERT_CREDENTIAL_INFO certInfo = { sizeof(CERT_CREDENTIAL_INFO), { 0 } }; + LPSTR marshalledCredentials; + + if (smartCardLogonWasDisabled) { - CERT_CREDENTIAL_INFO certInfo = { sizeof(CERT_CREDENTIAL_INFO), { 0 } }; - LPSTR marshalledCredentials; - - memcpy(certInfo.rgbHashOfCert, nla->certSha1, sizeof(certInfo.rgbHashOfCert)); - - if (!CredMarshalCredentialA(CertCredential, &certInfo, &marshalledCredentials)) - { - WLog_ERR(TAG, "error marshalling cert credentials"); + if (!nla_adjust_settings_from_smartcard(nla)) return FALSE; - } - - if (sspi_SetAuthIdentityA(nla->identity, marshalledCredentials, NULL, - settings->Password) < 0) - return FALSE; - - CredFree(marshalledCredentials); } + + memcpy(certInfo.rgbHashOfCert, nla->certSha1, sizeof(certInfo.rgbHashOfCert)); + + if (!CredMarshalCredentialA(CertCredential, &certInfo, &marshalledCredentials)) + { + WLog_ERR(TAG, "error marshalling cert credentials"); + return FALSE; + } + + if (sspi_SetAuthIdentityA(nla->identity, marshalledCredentials, NULL, settings->Password) < + 0) + return FALSE; + + CredFree(marshalledCredentials); #else if (sspi_SetAuthIdentityA(nla->identity, settings->Username, settings->Domain, settings->Password) < 0) diff --git a/libfreerdp/core/utils.c b/libfreerdp/core/utils.c index e501b7f5c..4cbf09111 100644 --- a/libfreerdp/core/utils.c +++ b/libfreerdp/core/utils.c @@ -44,6 +44,21 @@ BOOL utils_str_copy(const char* value, char** dst) return (*dst) != NULL; } +static BOOL utils_copy_smartcard_settings(const rdpSettings* settings, rdpSettings* origSettings) +{ + /* update original settings with provided smart card settings */ + origSettings->SmartcardLogon = settings->SmartcardLogon; + origSettings->PasswordIsSmartcardPin = settings->PasswordIsSmartcardPin; + if (!utils_str_copy(settings->ReaderName, &origSettings->ReaderName)) + return FALSE; + if (!utils_str_copy(settings->CspName, &origSettings->CspName)) + return FALSE; + if (!utils_str_copy(settings->ContainerName, &origSettings->ContainerName)) + return FALSE; + + return TRUE; +} + auth_status utils_authenticate_gateway(freerdp* instance, rdp_auth_reason reason) { rdpSettings* settings; @@ -103,6 +118,9 @@ auth_status utils_authenticate_gateway(freerdp* instance, rdp_auth_reason reason if (!utils_sync_credentials(origSettings, FALSE)) return AUTH_FAILED; + if (!utils_copy_smartcard_settings(settings, origSettings)) + return AUTH_FAILED; + return AUTH_SUCCESS; } @@ -185,6 +203,9 @@ auth_status utils_authenticate(freerdp* instance, rdp_auth_reason reason, BOOL o if (!utils_sync_credentials(origSettings, TRUE)) return AUTH_FAILED; + if (!utils_copy_smartcard_settings(settings, origSettings)) + return AUTH_FAILED; + return AUTH_SUCCESS; }