Smartcard tls logon fix (#7709)
* Early return authenticate if TLS smartcard logon * Removed obsolete SmartcardPin and unified AuthenticateEx calls * Remove password-is-pin from command line The setting is implied by smartcard-logon and only of interest in server side code, so the setting is useless * Rework AUTH_SMARTCARD_PIN Just prompt for PIN and not user/domain if this is requested. * Fixed a memory leak in nla.c * Align credentail prompt * Handle AUTH_NLA & smartcard, just ask for PIN * Added assertions, removed duplicate password prompt check * Move smartcard logon after credential prompt
This commit is contained in:
parent
ce63397323
commit
704289ffee
@ -230,43 +230,12 @@ static BOOL freerdp_client_settings_post_process(rdpSettings* settings)
|
||||
}
|
||||
|
||||
/* deal with the smartcard / smartcard logon stuff */
|
||||
if (settings->SmartcardEmulation)
|
||||
{
|
||||
/* if no pin is defined on the smartcard emulation use the user password */
|
||||
if (!settings->SmartcardPin)
|
||||
{
|
||||
if (!settings->Password)
|
||||
{
|
||||
WLog_ERR(TAG, "No pin or password defined for smartcard emu");
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_SmartcardPin, settings->Password))
|
||||
{
|
||||
WLog_ERR(TAG, "error when setting smartcard pin to user password");
|
||||
goto out_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settings->SmartcardLogon)
|
||||
{
|
||||
settings->TlsSecurity = TRUE;
|
||||
settings->RedirectSmartCards = TRUE;
|
||||
settings->DeviceRedirection = TRUE;
|
||||
freerdp_settings_set_bool(settings, FreeRDP_PasswordIsSmartcardPin, TRUE);
|
||||
|
||||
if (!settings->Password && settings->SmartcardEmulation)
|
||||
{
|
||||
/* when no user password is provided, in the case of smartcard emulation for smartcard
|
||||
* logon take the smartcard pin as user password to match PasswordIsSmartcardPin
|
||||
*/
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_Password, settings->SmartcardPin))
|
||||
{
|
||||
WLog_ERR(TAG, "error when setting smartcard pin to user password");
|
||||
goto out_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -423,20 +392,22 @@ static BOOL client_cli_authenticate_raw(freerdp* instance, rdp_auth_reason reaso
|
||||
char** password, char** domain)
|
||||
{
|
||||
static const size_t password_size = 512;
|
||||
const char* auth[] = { "Username: ", "Domain: ", "Password: " };
|
||||
const char* authPin[] = { "Username: ", "Domain: ", "Pin: " };
|
||||
const char* auth[] = { "Username: ", "Domain: ", "Password: " };
|
||||
const char* authPin[] = { "Username: ", "Domain: ", "Smartcard-Pin: " };
|
||||
const char* gw[] = { "GatewayUsername: ", "GatewayDomain: ", "GatewayPassword: " };
|
||||
const char** prompt;
|
||||
BOOL pinOnly = FALSE;
|
||||
|
||||
switch (reason)
|
||||
{
|
||||
case AUTH_NLA:
|
||||
case AUTH_TLS:
|
||||
case AUTH_RDP:
|
||||
prompt = auth;
|
||||
break;
|
||||
case AUTH_SMARTCARD_PIN:
|
||||
prompt = authPin;
|
||||
pinOnly = TRUE;
|
||||
break;
|
||||
case AUTH_TLS:
|
||||
case AUTH_RDP:
|
||||
case AUTH_NLA:
|
||||
prompt = auth;
|
||||
break;
|
||||
case GW_AUTH_HTTP:
|
||||
case GW_AUTH_RDG:
|
||||
@ -450,7 +421,7 @@ static BOOL client_cli_authenticate_raw(freerdp* instance, rdp_auth_reason reaso
|
||||
if (!username || !password || !domain)
|
||||
return FALSE;
|
||||
|
||||
if (!*username)
|
||||
if (!*username && !pinOnly)
|
||||
{
|
||||
size_t username_size = 0;
|
||||
printf("%s", prompt[0]);
|
||||
@ -468,7 +439,7 @@ static BOOL client_cli_authenticate_raw(freerdp* instance, rdp_auth_reason reaso
|
||||
}
|
||||
}
|
||||
|
||||
if (!*domain)
|
||||
if (!*domain && !pinOnly)
|
||||
{
|
||||
size_t domain_size = 0;
|
||||
printf("%s", prompt[1]);
|
||||
|
@ -889,10 +889,6 @@ static int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_A
|
||||
else
|
||||
settings->MultitransportFlags = 0;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "password-is-pin")
|
||||
{
|
||||
settings->PasswordIsSmartcardPin = enable;
|
||||
}
|
||||
CommandLineSwitchEnd(arg)
|
||||
|
||||
return status
|
||||
@ -3396,7 +3392,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
setSmartcardEmulation },
|
||||
{ "key:", FreeRDP_SmartcardPrivateKey, CMDLINE_SUBOPTION_FILE,
|
||||
setSmartcardEmulation },
|
||||
{ "pin:", FreeRDP_SmartcardPin, CMDLINE_SUBOPTION_STRING, NULL },
|
||||
{ "pin:", FreeRDP_Password, CMDLINE_SUBOPTION_STRING, NULL },
|
||||
{ "csp:", FreeRDP_CspName, CMDLINE_SUBOPTION_STRING, NULL },
|
||||
{ "reader:", FreeRDP_ReaderName, CMDLINE_SUBOPTION_STRING, NULL },
|
||||
{ "card:", FreeRDP_CardName, CMDLINE_SUBOPTION_STRING, NULL },
|
||||
|
@ -276,8 +276,6 @@ static const COMMAND_LINE_ARGUMENT_A global_cmd_args[] = {
|
||||
"Redirect parallel device" },
|
||||
{ "parent-window", COMMAND_LINE_VALUE_REQUIRED, "<window-id>", NULL, NULL, -1, NULL,
|
||||
"Parent window id" },
|
||||
{ "password-is-pin", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
|
||||
"Use smart card authentication with password as smart card PIN" },
|
||||
{ "pcb", COMMAND_LINE_VALUE_REQUIRED, "<blob>", NULL, NULL, -1, NULL, "Preconnection Blob" },
|
||||
{ "pcid", COMMAND_LINE_VALUE_REQUIRED, "<id>", NULL, NULL, -1, NULL, "Preconnection Id" },
|
||||
{ "pheight", COMMAND_LINE_VALUE_REQUIRED, "<height>", NULL, NULL, -1, NULL,
|
||||
|
@ -661,7 +661,6 @@ typedef struct
|
||||
#define FreeRDP_PromptForCredentials (1283)
|
||||
#define FreeRDP_SmartcardCertificate (1285)
|
||||
#define FreeRDP_SmartcardPrivateKey (1286)
|
||||
#define FreeRDP_SmartcardPin (1287)
|
||||
#define FreeRDP_SmartcardEmulation (1288)
|
||||
#define FreeRDP_Pkcs11Module (1289)
|
||||
#define FreeRDP_PkinitAnchors (1290)
|
||||
@ -1159,7 +1158,7 @@ struct rdp_settings
|
||||
/* Settings used for smartcard emulation */
|
||||
ALIGN64 char* SmartcardCertificate; /* 1285 */
|
||||
ALIGN64 char* SmartcardPrivateKey; /* 1286 */
|
||||
ALIGN64 char* SmartcardPin; /* 1287 */
|
||||
UINT64 padding1287[1288 - 1287]; /* 1287 */
|
||||
ALIGN64 BOOL SmartcardEmulation; /* 1288 */
|
||||
ALIGN64 char* Pkcs11Module; /* 1289 */
|
||||
ALIGN64 char* PkinitAnchors; /* 1290 */
|
||||
|
@ -2550,9 +2550,6 @@ const char* freerdp_settings_get_string(const rdpSettings* settings, size_t id)
|
||||
case FreeRDP_SmartcardCertificate:
|
||||
return settings->SmartcardCertificate;
|
||||
|
||||
case FreeRDP_SmartcardPin:
|
||||
return settings->SmartcardPin;
|
||||
|
||||
case FreeRDP_SmartcardPrivateKey:
|
||||
return settings->SmartcardPrivateKey;
|
||||
|
||||
@ -2811,9 +2808,6 @@ char* freerdp_settings_get_string_writable(rdpSettings* settings, size_t id)
|
||||
case FreeRDP_SmartcardCertificate:
|
||||
return settings->SmartcardCertificate;
|
||||
|
||||
case FreeRDP_SmartcardPin:
|
||||
return settings->SmartcardPin;
|
||||
|
||||
case FreeRDP_SmartcardPrivateKey:
|
||||
return settings->SmartcardPrivateKey;
|
||||
|
||||
@ -3082,9 +3076,6 @@ BOOL freerdp_settings_set_string_(rdpSettings* settings, size_t id, const char*
|
||||
case FreeRDP_SmartcardCertificate:
|
||||
return update_string(&settings->SmartcardCertificate, cnv.cc, len, cleanup);
|
||||
|
||||
case FreeRDP_SmartcardPin:
|
||||
return update_string(&settings->SmartcardPin, cnv.cc, len, cleanup);
|
||||
|
||||
case FreeRDP_SmartcardPrivateKey:
|
||||
return update_string(&settings->SmartcardPrivateKey, cnv.cc, len, cleanup);
|
||||
|
||||
|
@ -383,7 +383,6 @@ static const struct settings_str_entry settings_map[] = {
|
||||
{ FreeRDP_ServerHostname, 7, "FreeRDP_ServerHostname" },
|
||||
{ FreeRDP_ShellWorkingDirectory, 7, "FreeRDP_ShellWorkingDirectory" },
|
||||
{ FreeRDP_SmartcardCertificate, 7, "FreeRDP_SmartcardCertificate" },
|
||||
{ FreeRDP_SmartcardPin, 7, "FreeRDP_SmartcardPin" },
|
||||
{ FreeRDP_SmartcardPrivateKey, 7, "FreeRDP_SmartcardPrivateKey" },
|
||||
{ FreeRDP_TargetNetAddress, 7, "FreeRDP_TargetNetAddress" },
|
||||
{ FreeRDP_TransportDumpFile, 7, "FreeRDP_TransportDumpFile" },
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <freerdp/peer.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/sam.h>
|
||||
#include <winpr/sspi.h>
|
||||
#include <winpr/print.h>
|
||||
@ -171,6 +172,8 @@ static BOOL nla_sec_buffer_alloc(SecBuffer* buffer, size_t size)
|
||||
sspi_SecBufferFree(buffer);
|
||||
if (!sspi_SecBufferAlloc(buffer, size))
|
||||
return FALSE;
|
||||
|
||||
WINPR_ASSERT(buffer);
|
||||
buffer->BufferType = SECBUFFER_TOKEN;
|
||||
return TRUE;
|
||||
}
|
||||
@ -181,6 +184,8 @@ static BOOL nla_sec_buffer_alloc_from_data(SecBuffer* buffer, const BYTE* data,
|
||||
BYTE* pb;
|
||||
if (!nla_sec_buffer_alloc(buffer, offset + size))
|
||||
return FALSE;
|
||||
|
||||
WINPR_ASSERT(buffer);
|
||||
pb = buffer->pvBuffer;
|
||||
memcpy(&pb[offset], data, size);
|
||||
return TRUE;
|
||||
@ -541,10 +546,21 @@ static BOOL nla_adjust_settings_from_smartcard(rdpNla* nla)
|
||||
SmartcardCerts* certs = NULL;
|
||||
const SmartcardCertInfo* info = NULL;
|
||||
DWORD count;
|
||||
rdpSettings* settings = nla->settings;
|
||||
SEC_WINPR_KERBEROS_SETTINGS* kerbSettings = &nla->kerberosSettings;
|
||||
rdpSettings* settings;
|
||||
SEC_WINPR_KERBEROS_SETTINGS* kerbSettings;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
settings = nla->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
if (!settings->SmartcardLogon)
|
||||
return TRUE;
|
||||
|
||||
kerbSettings = &nla->kerberosSettings;
|
||||
WINPR_ASSERT(kerbSettings);
|
||||
|
||||
if (!settings->CspName)
|
||||
{
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_CspName, MS_SCARD_PROV_A))
|
||||
@ -636,33 +652,6 @@ static BOOL nla_adjust_settings_from_smartcard(rdpNla* nla)
|
||||
}
|
||||
|
||||
setup_pin:
|
||||
if (!settings->SmartcardPin)
|
||||
{
|
||||
if (settings->SmartcardEmulation)
|
||||
{
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_SmartcardPin, ""))
|
||||
{
|
||||
WLog_ERR(TAG, "error setting pin");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp* instance = nla->instance;
|
||||
if (!instance->AuthenticateEx)
|
||||
{
|
||||
WLog_ERR(TAG, "no pin configured and no instance->AuthenticateEx callback");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!instance->AuthenticateEx(instance, &settings->Username, &settings->SmartcardPin,
|
||||
&settings->Domain, AUTH_SMARTCARD_PIN))
|
||||
{
|
||||
WLog_ERR(TAG, "no pin code entered");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
@ -676,64 +665,16 @@ static BOOL nla_client_setup_identity(rdpNla* nla)
|
||||
WINPR_SAM* sam;
|
||||
WINPR_SAM_ENTRY* entry;
|
||||
BOOL PromptPassword = FALSE;
|
||||
rdpSettings* settings = nla->settings;
|
||||
freerdp* instance = nla->instance;
|
||||
rdpSettings* settings;
|
||||
freerdp* instance;
|
||||
|
||||
if (settings->SmartcardLogon)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
{
|
||||
SEC_WINNT_AUTH_IDENTITY_EXA* identityEx;
|
||||
CERT_CREDENTIAL_INFO certInfo = { sizeof(CERT_CREDENTIAL_INFO), { 0 } };
|
||||
LPSTR marshalledCredentials;
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
identityEx = &nla->identityEx;
|
||||
memcpy(certInfo.rgbHashOfCert, nla->kerberosSettings.certSha1,
|
||||
sizeof(certInfo.rgbHashOfCert));
|
||||
settings = nla->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
if (!CredMarshalCredentialA(CertCredential, &certInfo, &marshalledCredentials))
|
||||
{
|
||||
WLog_ERR(TAG, "error marshalling cert credentials");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
identityEx->Version = SEC_WINNT_AUTH_IDENTITY_VERSION;
|
||||
identityEx->Length = sizeof(*identityEx);
|
||||
identityEx->User = (BYTE*)marshalledCredentials;
|
||||
identityEx->UserLength = strlen(marshalledCredentials);
|
||||
if (!(identityEx->Password = (BYTE*)_strdup(settings->SmartcardPin)))
|
||||
return FALSE;
|
||||
identityEx->PasswordLength = strlen(settings->SmartcardPin);
|
||||
identityEx->Domain = NULL;
|
||||
identityEx->DomainLength = 0;
|
||||
identityEx->Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
|
||||
identityEx->PackageList = NULL;
|
||||
identityEx->PackageListLength = 0;
|
||||
|
||||
nla->identityPtr = identityEx;
|
||||
}
|
||||
#else
|
||||
{
|
||||
SEC_WINNT_AUTH_IDENTITY_EXA* identityEx = &nla->identityWinPr.identityEx;
|
||||
|
||||
identityEx->Version = SEC_WINNT_AUTH_IDENTITY_VERSION;
|
||||
identityEx->Length = sizeof(nla->identityWinPr);
|
||||
identityEx->User = (BYTE*)settings->Username;
|
||||
identityEx->UserLength = strlen(settings->Username);
|
||||
identityEx->Domain = (BYTE*)settings->Domain;
|
||||
identityEx->DomainLength = strlen(settings->Domain);
|
||||
identityEx->Password = (BYTE*)settings->SmartcardPin;
|
||||
identityEx->PasswordLength = strlen(settings->SmartcardPin);
|
||||
identityEx->Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
|
||||
identityEx->PackageList = NULL;
|
||||
identityEx->PackageListLength = 0;
|
||||
|
||||
nla->identityPtr = &nla->identityWinPr;
|
||||
} /* smartcard logon */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
instance = nla->instance;
|
||||
WINPR_ASSERT(instance);
|
||||
|
||||
/* */
|
||||
if ((utils_str_is_empty(settings->Username) ||
|
||||
@ -795,6 +736,61 @@ static BOOL nla_client_setup_identity(rdpNla* nla)
|
||||
nla_identity_free(nla->identity);
|
||||
nla->identity = NULL;
|
||||
}
|
||||
else if (settings->SmartcardLogon)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
{
|
||||
SEC_WINNT_AUTH_IDENTITY_EXA* identityEx;
|
||||
CERT_CREDENTIAL_INFO certInfo = { sizeof(CERT_CREDENTIAL_INFO), { 0 } };
|
||||
LPSTR marshalledCredentials;
|
||||
|
||||
identityEx = &nla->identityEx;
|
||||
memcpy(certInfo.rgbHashOfCert, nla->kerberosSettings.certSha1,
|
||||
sizeof(certInfo.rgbHashOfCert));
|
||||
|
||||
if (!CredMarshalCredentialA(CertCredential, &certInfo, &marshalledCredentials))
|
||||
{
|
||||
WLog_ERR(TAG, "error marshalling cert credentials");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
identityEx->Version = SEC_WINNT_AUTH_IDENTITY_VERSION;
|
||||
identityEx->Length = sizeof(*identityEx);
|
||||
identityEx->User = (BYTE*)marshalledCredentials;
|
||||
identityEx->UserLength = strlen(marshalledCredentials);
|
||||
if (!(identityEx->Password = (BYTE*)_strdup(settings->Password)))
|
||||
return FALSE;
|
||||
identityEx->PasswordLength = strlen(settings->Password);
|
||||
identityEx->Domain = NULL;
|
||||
identityEx->DomainLength = 0;
|
||||
identityEx->Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
|
||||
identityEx->PackageList = NULL;
|
||||
identityEx->PackageListLength = 0;
|
||||
|
||||
nla->identityPtr = identityEx;
|
||||
}
|
||||
#else
|
||||
{
|
||||
SEC_WINNT_AUTH_IDENTITY_EXA* identityEx = &nla->identityWinPr.identityEx;
|
||||
|
||||
identityEx->Version = SEC_WINNT_AUTH_IDENTITY_VERSION;
|
||||
identityEx->Length = sizeof(nla->identityWinPr);
|
||||
identityEx->User = (BYTE*)settings->Username;
|
||||
identityEx->UserLength = strlen(settings->Username);
|
||||
identityEx->Domain = (BYTE*)settings->Domain;
|
||||
identityEx->DomainLength = strlen(settings->Domain);
|
||||
identityEx->Password = (BYTE*)settings->Password;
|
||||
identityEx->PasswordLength = strlen(settings->Password);
|
||||
identityEx->Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
|
||||
identityEx->PackageList = NULL;
|
||||
identityEx->PackageListLength = 0;
|
||||
|
||||
nla->identityPtr = &nla->identityWinPr;
|
||||
} /* smartcard logon */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL usePassword = TRUE;
|
||||
@ -857,6 +853,11 @@ static BOOL parseKerberosDeltat(const char* value, INT32* dest, const char* mess
|
||||
{
|
||||
INT32 v;
|
||||
const char* ptr;
|
||||
|
||||
WINPR_ASSERT(value);
|
||||
WINPR_ASSERT(dest);
|
||||
WINPR_ASSERT(message);
|
||||
|
||||
/* determine the format :
|
||||
* h:m[:s] (3:00:02) deltat in hours/minutes
|
||||
* <n>d<n>h<n>m<n>s 1d4h deltat in day/hours/minutes/seconds
|
||||
@ -963,8 +964,16 @@ static BOOL parseKerberosDeltat(const char* value, INT32* dest, const char* mess
|
||||
|
||||
static BOOL nla_setup_kerberos(rdpNla* nla)
|
||||
{
|
||||
SEC_WINPR_KERBEROS_SETTINGS* kerbSettings = &nla->kerberosSettings;
|
||||
rdpSettings* settings = nla->settings;
|
||||
SEC_WINPR_KERBEROS_SETTINGS* kerbSettings;
|
||||
rdpSettings* settings;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
settings = nla->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
kerbSettings = &nla->kerberosSettings;
|
||||
WINPR_ASSERT(kerbSettings);
|
||||
|
||||
if (settings->KerberosLifeTime &&
|
||||
!parseKerberosDeltat(settings->KerberosLifeTime, &kerbSettings->lifeTime, "lifetime"))
|
||||
@ -1012,7 +1021,12 @@ static int nla_client_init(rdpNla* nla)
|
||||
char* spn;
|
||||
size_t length;
|
||||
rdpTls* tls = NULL;
|
||||
rdpSettings* settings = nla->settings;
|
||||
rdpSettings* settings;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
settings = nla->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
nla_set_state(nla, NLA_STATE_INITIAL);
|
||||
|
||||
@ -1022,7 +1036,7 @@ static int nla_client_init(rdpNla* nla)
|
||||
if (!nla_setup_kerberos(nla))
|
||||
return -1;
|
||||
|
||||
if (settings->SmartcardLogon && !nla_adjust_settings_from_smartcard(nla))
|
||||
if (!nla_adjust_settings_from_smartcard(nla))
|
||||
return -1;
|
||||
|
||||
if (!nla_client_setup_identity(nla))
|
||||
@ -1124,6 +1138,9 @@ int nla_client_begin(rdpNla* nla)
|
||||
int rc = -1;
|
||||
SecBuffer outputBuffer = { 0 };
|
||||
SecBufferDesc outputBufferDesc = { 0 };
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
if (nla_client_init(nla) < 1)
|
||||
goto fail;
|
||||
|
||||
@ -1183,6 +1200,8 @@ static int nla_client_recv_nego_token(rdpNla* nla)
|
||||
SecBufferDesc inputBufferDesc = { 0 };
|
||||
SecBufferDesc outputBufferDesc = { 0 };
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
inputBufferDesc.ulVersion = SECBUFFER_VERSION;
|
||||
inputBufferDesc.cBuffers = 1;
|
||||
inputBufferDesc.pBuffers = &inputBuffer;
|
||||
@ -1250,6 +1269,8 @@ fail:
|
||||
|
||||
static int nla_client_recv_pub_key_auth(rdpNla* nla)
|
||||
{
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
/* Verify Server Public Key Echo */
|
||||
if (nla->peerVersion < 5)
|
||||
nla->status = nla_decrypt_public_key_echo(nla);
|
||||
@ -1299,6 +1320,8 @@ static int nla_client_recv_pub_key_auth(rdpNla* nla)
|
||||
|
||||
static int nla_client_recv(rdpNla* nla)
|
||||
{
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
switch (nla_get_state(nla))
|
||||
{
|
||||
case NLA_STATE_NEGO_TOKEN:
|
||||
@ -1320,6 +1343,9 @@ static int nla_client_authenticate(rdpNla* nla)
|
||||
int rc = -1;
|
||||
wStream* s;
|
||||
int status;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
s = Stream_New(NULL, 4096);
|
||||
|
||||
if (!s)
|
||||
@ -1361,7 +1387,12 @@ fail:
|
||||
|
||||
static int nla_server_init(rdpNla* nla)
|
||||
{
|
||||
rdpTls* tls = transport_get_tls(nla->transport);
|
||||
rdpTls* tls;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
tls = transport_get_tls(nla->transport);
|
||||
WINPR_ASSERT(tls);
|
||||
|
||||
if (!nla_sec_buffer_alloc_from_data(&nla->PublicKey, tls->PublicKey, 0, tls->PublicKeyLength))
|
||||
{
|
||||
@ -1438,6 +1469,9 @@ static wStream* nla_server_recv_stream(rdpNla* nla)
|
||||
{
|
||||
wStream* s = NULL;
|
||||
int status = -1;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
s = Stream_New(NULL, 4096);
|
||||
|
||||
if (!s)
|
||||
@ -1465,6 +1499,9 @@ fail:
|
||||
static int nla_server_authenticate(rdpNla* nla)
|
||||
{
|
||||
int res = -1;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
if (nla_server_init(nla) < 1)
|
||||
goto fail_auth;
|
||||
|
||||
@ -1719,6 +1756,8 @@ fail_auth:
|
||||
|
||||
int nla_authenticate(rdpNla* nla)
|
||||
{
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
if (nla->server)
|
||||
return nla_server_authenticate(nla);
|
||||
else
|
||||
@ -1729,6 +1768,8 @@ static void ap_integer_increment_le(BYTE* number, size_t size)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
WINPR_ASSERT(number || (size == 0));
|
||||
|
||||
for (index = 0; index < size; index++)
|
||||
{
|
||||
if (number[index] < 0xFF)
|
||||
@ -1748,6 +1789,8 @@ static void ap_integer_decrement_le(BYTE* number, size_t size)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
WINPR_ASSERT(number || (size == 0));
|
||||
|
||||
for (index = 0; index < size; index++)
|
||||
{
|
||||
if (number[index] > 0)
|
||||
@ -1767,6 +1810,8 @@ SECURITY_STATUS nla_encrypt_public_key_echo(rdpNla* nla)
|
||||
{
|
||||
SECURITY_STATUS status;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
if (!nla_sec_buffer_alloc_from_buffer(&nla->pubKeyAuth, &nla->PublicKey,
|
||||
nla->ContextSizes.cbSecurityTrailer))
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
@ -1790,6 +1835,9 @@ SECURITY_STATUS nla_encrypt_public_key_hash(rdpNla* nla)
|
||||
SECURITY_STATUS status = SEC_E_INTERNAL_ERROR;
|
||||
WINPR_DIGEST_CTX* sha256 = NULL;
|
||||
BYTE* hash;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
const ULONG auth_data_length =
|
||||
(nla->ContextSizes.cbSecurityTrailer + WINPR_SHA256_DIGEST_LENGTH);
|
||||
const BYTE* hashMagic = nla->server ? ServerClientHashMagic : ClientServerHashMagic;
|
||||
@ -1893,6 +1941,9 @@ SECURITY_STATUS nla_decrypt_public_key_hash(rdpNla* nla)
|
||||
WINPR_DIGEST_CTX* sha256 = NULL;
|
||||
BYTE serverClientHash[WINPR_SHA256_DIGEST_LENGTH];
|
||||
SECURITY_STATUS status = SEC_E_INVALID_TOKEN;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
const BYTE* hashMagic = nla->server ? ClientServerHashMagic : ServerClientHashMagic;
|
||||
const BYTE* decryptedHash;
|
||||
const size_t hashSize =
|
||||
@ -1954,6 +2005,9 @@ BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s)
|
||||
{
|
||||
size_t length;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (!nla->identity)
|
||||
{
|
||||
WLog_ERR(TAG, "nla->identity is NULL!");
|
||||
@ -2048,6 +2102,7 @@ static BOOL nla_read_ts_credentials(rdpNla* nla, SecBuffer* data, size_t offset)
|
||||
size_t ts_password_creds_length = 0;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
if (!data)
|
||||
return FALSE;
|
||||
|
||||
@ -2087,8 +2142,10 @@ static BOOL nla_encode_ts_credentials(rdpNla* nla)
|
||||
wStream* s;
|
||||
size_t length;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TSCredentials_t cr = { 0 };
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
rdpSettings* settings = nla->settings;
|
||||
|
||||
if (settings->SmartcardLogon)
|
||||
@ -2096,7 +2153,7 @@ static BOOL nla_encode_ts_credentials(rdpNla* nla)
|
||||
TSSmartCardCreds_t smartcardCreds = { 0 };
|
||||
TSCspDataDetail_t cspData = { 0 };
|
||||
|
||||
smartcardCreds.pin = settings->SmartcardPin ? settings->SmartcardPin : "";
|
||||
smartcardCreds.pin = settings->Password ? settings->Password : "";
|
||||
|
||||
/*smartcardCreds.userHint = settings->UserHint;
|
||||
smartcardCreds.domainHint = settings->DomainHint;*/
|
||||
@ -2167,6 +2224,8 @@ static SECURITY_STATUS nla_encrypt_ts_credentials(rdpNla* nla)
|
||||
{
|
||||
SECURITY_STATUS status;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
if (!nla_encode_ts_credentials(nla))
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
@ -2185,6 +2244,8 @@ static SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla)
|
||||
{
|
||||
SECURITY_STATUS status;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
if (nla->authInfo.cbBuffer < 1)
|
||||
{
|
||||
WLog_ERR(TAG, "nla_decrypt_ts_credentials missing authInfo buffer");
|
||||
@ -2210,6 +2271,8 @@ static size_t nla_sizeof_nego_token(size_t length)
|
||||
|
||||
static size_t nla_sizeof_nego_tokens(const SecBuffer* buffer)
|
||||
{
|
||||
WINPR_ASSERT(buffer);
|
||||
|
||||
size_t length = buffer->cbBuffer;
|
||||
if (length == 0)
|
||||
return 0;
|
||||
@ -2222,6 +2285,8 @@ static size_t nla_sizeof_nego_tokens(const SecBuffer* buffer)
|
||||
|
||||
static size_t nla_sizeof_pub_key_auth(const SecBuffer* buffer)
|
||||
{
|
||||
WINPR_ASSERT(buffer);
|
||||
|
||||
size_t length = buffer->cbBuffer;
|
||||
if (length == 0)
|
||||
return 0;
|
||||
@ -2232,6 +2297,8 @@ static size_t nla_sizeof_pub_key_auth(const SecBuffer* buffer)
|
||||
|
||||
static size_t nla_sizeof_auth_info(const SecBuffer* buffer)
|
||||
{
|
||||
WINPR_ASSERT(buffer);
|
||||
|
||||
size_t length = buffer->cbBuffer;
|
||||
if (length == 0)
|
||||
return 0;
|
||||
@ -2242,6 +2309,8 @@ static size_t nla_sizeof_auth_info(const SecBuffer* buffer)
|
||||
|
||||
static size_t nla_sizeof_client_nonce(const SecBuffer* buffer)
|
||||
{
|
||||
WINPR_ASSERT(buffer);
|
||||
|
||||
size_t length = buffer->cbBuffer;
|
||||
if (length == 0)
|
||||
return 0;
|
||||
@ -2261,6 +2330,8 @@ static BOOL nla_client_write_nego_token(wStream* s, const SecBuffer* negoToken)
|
||||
{
|
||||
const size_t nego_tokens_length = nla_sizeof_nego_tokens(negoToken);
|
||||
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (Stream_GetRemainingCapacity(s) < nego_tokens_length)
|
||||
return FALSE;
|
||||
|
||||
@ -2301,6 +2372,9 @@ BOOL nla_send(rdpNla* nla)
|
||||
size_t ts_request_length;
|
||||
size_t error_code_context_length = 0;
|
||||
size_t error_code_length = 0;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
const size_t nego_tokens_length = nla_sizeof_nego_tokens(&nla->negoToken);
|
||||
const size_t pub_key_auth_length = nla_sizeof_pub_key_auth(&nla->pubKeyAuth);
|
||||
const size_t auth_info_length = nla_sizeof_auth_info(&nla->authInfo);
|
||||
@ -2389,6 +2463,9 @@ static int nla_decode_ts_request(rdpNla* nla, wStream* s)
|
||||
size_t length;
|
||||
UINT32 version = 0;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
WLog_DBG(TAG, "<<----- receiving...");
|
||||
|
||||
/* TSRequest */
|
||||
@ -2471,6 +2548,9 @@ fail:
|
||||
|
||||
int nla_recv_pdu(rdpNla* nla, wStream* s)
|
||||
{
|
||||
WINPR_ASSERT(nla);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (nla_decode_ts_request(nla, s) < 1)
|
||||
return -1;
|
||||
|
||||
@ -2536,7 +2616,11 @@ int nla_recv_pdu(rdpNla* nla, wStream* s)
|
||||
int nla_server_recv(rdpNla* nla)
|
||||
{
|
||||
int status = -1;
|
||||
wStream* s = nla_server_recv_stream(nla);
|
||||
wStream* s;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
s = nla_server_recv_stream(nla);
|
||||
if (!s)
|
||||
goto fail;
|
||||
status = nla_decode_ts_request(nla, s);
|
||||
@ -2548,6 +2632,7 @@ fail:
|
||||
|
||||
void nla_buffer_free(rdpNla* nla)
|
||||
{
|
||||
WINPR_ASSERT(nla);
|
||||
sspi_SecBufferFree(&nla->negoToken);
|
||||
sspi_SecBufferFree(&nla->pubKeyAuth);
|
||||
sspi_SecBufferFree(&nla->authInfo);
|
||||
|
@ -392,7 +392,6 @@ static const size_t string_list_indices[] = {
|
||||
FreeRDP_ServerHostname,
|
||||
FreeRDP_ShellWorkingDirectory,
|
||||
FreeRDP_SmartcardCertificate,
|
||||
FreeRDP_SmartcardPin,
|
||||
FreeRDP_SmartcardPrivateKey,
|
||||
FreeRDP_TargetNetAddress,
|
||||
FreeRDP_TransportDumpFile,
|
||||
|
@ -107,6 +107,28 @@ auth_status utils_authenticate(freerdp* instance, rdp_auth_reason reason, BOOL o
|
||||
if (!prompt)
|
||||
return AUTH_SKIP;
|
||||
|
||||
switch (reason)
|
||||
{
|
||||
case AUTH_RDP:
|
||||
case AUTH_TLS:
|
||||
if (instance->settings->SmartcardLogon)
|
||||
{
|
||||
if (!utils_str_is_empty(settings->Password))
|
||||
{
|
||||
WLog_INFO(TAG, "Authentication via smartcard");
|
||||
return AUTH_SUCCESS;
|
||||
}
|
||||
reason = AUTH_SMARTCARD_PIN;
|
||||
}
|
||||
break;
|
||||
case AUTH_NLA:
|
||||
if (instance->settings->SmartcardLogon)
|
||||
reason = AUTH_SMARTCARD_PIN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* If no callback is specified still continue connection */
|
||||
if (!instance->Authenticate && !instance->AuthenticateEx)
|
||||
return AUTH_NO_CREDENTIALS;
|
||||
|
@ -304,7 +304,7 @@ static SCardHandle* scard_handle_new(SmartcardEmulationContext* smartcard, SCARD
|
||||
const char* key =
|
||||
freerdp_settings_get_string(smartcard->settings, FreeRDP_SmartcardPrivateKey);
|
||||
|
||||
const char* pin = freerdp_settings_get_string(smartcard->settings, FreeRDP_SmartcardPin);
|
||||
const char* pin = freerdp_settings_get_string(smartcard->settings, FreeRDP_Password);
|
||||
|
||||
if (!vgids_init(hdl->vgids, pem, key, pin))
|
||||
goto fail;
|
||||
@ -2690,7 +2690,7 @@ BOOL Emulate_IsConfigured(SmartcardEmulationContext* context)
|
||||
|
||||
pem = freerdp_settings_get_string(context->settings, FreeRDP_SmartcardCertificate);
|
||||
key = freerdp_settings_get_string(context->settings, FreeRDP_SmartcardPrivateKey);
|
||||
pin = freerdp_settings_get_string(context->settings, FreeRDP_SmartcardPin);
|
||||
pin = freerdp_settings_get_string(context->settings, FreeRDP_Password);
|
||||
|
||||
/* Cache result only, if no initialization arguments changed. */
|
||||
if ((context->pem == pem) && (context->key == key) && (context->pin == pin))
|
||||
|
Loading…
Reference in New Issue
Block a user