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.
This commit is contained in:
Martin Fleisz
2023-02-16 11:18:30 +01:00
committed by akallabeth
parent b8a709ccda
commit 6f639686cf
3 changed files with 75 additions and 43 deletions

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;
}