diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 57289145d..1ca4ec377 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1378,7 +1378,11 @@ static BOOL ends_with(const char* str, const char* ext) static void activate_smartcard_logon_rdp(rdpSettings* settings) { settings->SmartcardLogon = TRUE; - /* TODO: why not? settings->UseRdpSecurityLayer = TRUE; */ + + settings->NlaSecurity = FALSE; + settings->TlsSecurity = TRUE; + settings->RedirectSmartCards = TRUE; + settings->DeviceRedirection = TRUE; freerdp_settings_set_bool(settings, FreeRDP_PasswordIsSmartcardPin, TRUE); } @@ -1445,6 +1449,39 @@ static BOOL prepare_default_settings(rdpSettings* settings, COMMAND_LINE_ARGUMEN return freerdp_set_connection_type(settings, CONNECTION_TYPE_AUTODETECT); } +static BOOL read_pem_file(rdpSettings* settings, size_t id, const char* file) +{ + INT64 s; + int rs; + size_t r, fr; + char* ptr; + BOOL rc = FALSE; + FILE* fp = winpr_fopen(file, "r"); + if (!fp) + return FALSE; + rs = _fseeki64(fp, 0, SEEK_END); + if (rc < 0) + goto fail; + s = _ftelli64(fp); + if (s < 0) + goto fail; + rs = _fseeki64(fp, 0, SEEK_SET); + if (rc < 0) + goto fail; + + if (!freerdp_settings_set_string_len(settings, id, NULL, s + 1)) + goto fail; + + ptr = freerdp_settings_get_string(settings, id); + fr = fread(ptr, (size_t)s, 1, fp); + if (fr != 1) + goto fail; + rc = TRUE; +fail: + fclose(fp); + return rc; +} + int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, int argc, char** argv, BOOL allowUnknown) { @@ -3211,8 +3248,49 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "smartcard-logon") { + size_t count; + union + { + char** p; + const char** pc; + } ptr; + if (!settings->SmartcardLogon) activate_smartcard_logon_rdp(settings); + + ptr.p = CommandLineParseCommaSeparatedValuesEx("smartcard-logon", arg->Value, &count); + if (ptr.pc) + { + size_t x; + for (x = 1; x < count; x++) + { + const char* cur = ptr.pc[x]; + if (strncmp("cert:", cur, 5) == 0) + { + const char* f = &cur[5]; + if (!read_pem_file(settings, FreeRDP_SmartcardCertificate, f)) + { + free(ptr.p); + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + } + } + else if (strncmp("key:", cur, 4) == 0) + { + const char* f = &cur[4]; + if (!read_pem_file(settings, FreeRDP_SmartcardPrivateKey, f)) + { + free(ptr.p); + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + } + } + else + { + free(ptr.p); + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + } + } + } + free(ptr.p); } CommandLineSwitchCase(arg, "tune") diff --git a/client/common/cmdline.h b/client/common/cmdline.h index 41190ba05..8f3ceb3dc 100644 --- a/client/common/cmdline.h +++ b/client/common/cmdline.h @@ -336,8 +336,10 @@ static const COMMAND_LINE_ARGUMENT_A global_cmd_args[] = { "Scale remote desktop to window size" }, { "smartcard", COMMAND_LINE_VALUE_OPTIONAL, "[,...]", NULL, NULL, -1, NULL, "Redirect the smartcard devices containing any of the in their names." }, - { "smartcard-logon", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Activates Smartcard Logon authentication. (EXPERIMENTAL: NLA not supported)" }, + { "smartcard-logon", COMMAND_LINE_VALUE_OPTIONAL, "[cert:,key:]", NULL, NULL, -1, + NULL, + "Activates Smartcard (optional certificate) Logon authentication. (EXPERIMENTAL: NLA not " + "supported)" }, { "sound", COMMAND_LINE_VALUE_OPTIONAL, "[sys:,][dev:,][format:,][rate:,][channel:,][latency:<" "latency>,][quality:]",