From 0de43c8b85fe95b912b52586cdafc5e293134020 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 4 Sep 2018 15:49:21 +0200 Subject: [PATCH] Added /smartcard-logon option to set flag. (Stripped version of #4837 by @informatimago) --- client/X11/xf_client.c | 2 +- client/common/client.c | 6 +++ client/common/cmdline.c | 23 ++++++++++ client/common/cmdline.h | 3 +- include/freerdp/settings.h | 9 ++-- libfreerdp/common/settings.c | 7 +++ libfreerdp/core/info.c | 85 +++++++++++++++++++++++++++++++++++- libfreerdp/core/info.h | 2 + libfreerdp/core/settings.c | 1 + 9 files changed, 132 insertions(+), 6 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 7583d80cf..6b5d88e07 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1132,7 +1132,7 @@ static BOOL xf_pre_connect(freerdp* instance) if (!freerdp_client_load_addins(channels, instance->settings)) return FALSE; - if (!settings->Username && !settings->CredentialsFromStdin) + if (!settings->Username && !settings->CredentialsFromStdin && !settings->SmartcardLogon) { char* login_name = getlogin(); diff --git a/client/common/client.c b/client/common/client.c index ef5db9708..bdc259970 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -425,6 +425,12 @@ fail: BOOL client_cli_authenticate(freerdp* instance, char** username, char** password, char** domain) { + if (instance->settings->SmartcardLogon) + { + WLog_INFO(TAG, "Authentication via smartcard"); + return TRUE; + } + return client_cli_authenticate_raw(instance, FALSE, username, password, domain); } diff --git a/client/common/cmdline.c b/client/common/cmdline.c index ddbf9e6e3..89f95fddb 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1288,6 +1288,18 @@ static BOOL ends_with(const char* str, const char* ext) return strncmp(&str[strLen - extLen], ext, extLen) == 0; } + +static void activate_smartcard_logon_rdp(rdpSettings* settings) +{ + settings->SmartcardLogon = TRUE; + settings->RdpSecurity = TRUE; + settings->TlsSecurity = FALSE; + settings->NlaSecurity = FALSE; + settings->ExtSecurity = FALSE; + /* TODO: why not? settings->UseRdpSecurityLayer = TRUE; */ + freerdp_set_param_bool(settings, FreeRDP_PasswordIsSmartcardPin, TRUE); +} + int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, int argc, char** argv, BOOL allowUnknown) { @@ -2746,6 +2758,17 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, { settings->FIPSMode = TRUE; } + CommandLineSwitchCase(arg, "smartcard-logon") + { + if (!((0 == arg->Value) || (0 == strcmp(arg->Value, "rdp")) || (0 == strcmp(arg->Value, "")))) + { + /* Later, we may implement --smartcard-logon:kerberos-sso or other variants. */ + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + } + + if (!settings->SmartcardLogon) + activate_smartcard_logon_rdp(settings); + } CommandLineSwitchDefault(arg) { } diff --git a/client/common/cmdline.h b/client/common/cmdline.h index f49be3abb..f75605256 100644 --- a/client/common/cmdline.h +++ b/client/common/cmdline.h @@ -157,7 +157,8 @@ static COMMAND_LINE_ARGUMENT_A args[] = { "shell-dir", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Shell working directory" }, { "size", COMMAND_LINE_VALUE_REQUIRED, "x or %[wh]", "1024x768", NULL, -1, NULL, "Screen size" }, { "smart-sizing", COMMAND_LINE_VALUE_OPTIONAL, "x", NULL, NULL, -1, NULL, "Scale remote desktop to window size" }, - { "smartcard", COMMAND_LINE_VALUE_OPTIONAL, "[,]", NULL, NULL, -1, NULL, "Redirect smartcard device" }, + { "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_OPTIONAL, "[rdp]", NULL, NULL, -1, NULL, "Selects Smartcard Logon authentication (thru rdp)" }, { "sound", COMMAND_LINE_VALUE_OPTIONAL, "[sys:,][dev:,][format:,][rate:,][channel:,][latency:,][quality:]", NULL, NULL, -1, "audio", "Audio output (sound)" }, { "span", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Span screen over multiple monitors" }, { "spn-class", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "SPN authentication service class" }, diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index dea0114b4..96d5dea8b 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -649,8 +649,10 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_TargetNetPorts (1230) #define FreeRDP_RedirectionAcceptedCert (1231) #define FreeRDP_RedirectionAcceptedCertLength (1232) +#define FreeRDP_RedirectionPreferType (1233) #define FreeRDP_Password51 (1280) #define FreeRDP_Password51Length (1281) +#define FreeRDP_SmartcardLogon (1282) #define FreeRDP_KerberosKdc (1344) #define FreeRDP_KerberosRealm (1345) #define FreeRDP_IgnoreCertificate (1408) @@ -1092,9 +1094,10 @@ struct rdp_settings */ /* Credentials Cache */ - ALIGN64 BYTE* Password51; /* 1280 */ - ALIGN64 UINT32 Password51Length; /* 1281 */ - UINT64 padding1344[1344 - 1282]; /* 1282 */ + ALIGN64 BYTE* Password51; /* 1280 */ + ALIGN64 UINT32 Password51Length; /* 1281 */ + ALIGN64 BOOL SmartcardLogon; /* 1282 */ + UINT64 padding1344[1344 - 1283]; /* 1283 */ /* Kerberos Authentication */ ALIGN64 char* KerberosKdc; /* 1344 */ diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index e339c67ad..2043be2d9 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -1147,6 +1147,9 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id) case FreeRDP_RedirectClipboard: return settings->RedirectClipboard; + case FreeRDP_SmartcardLogon: + return settings->SmartcardLogon; + default: WLog_ERR(TAG, "freerdp_get_param_bool: unknown id: %d", id); return -1; @@ -1685,6 +1688,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) settings->RedirectClipboard = param; break; + case FreeRDP_SmartcardLogon: + settings->SmartcardLogon = param; + break; + default: WLog_ERR(TAG, "freerdp_set_param_bool: unknown id %d (param = %"PRId32")", id, param); return -1; diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index aa1ff84b7..b07fd9a01 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -43,6 +43,67 @@ static const char* const INFO_TYPE_LOGON_STRINGS[4] = "Logon Extended Info" }; +static struct +{ + UINT32 flag; + const char* label; +} const info_flags[] = +{ + {INFO_MOUSE, "INFO_MOUSE"}, + {INFO_DISABLECTRLALTDEL, "INFO_DISABLECTRLALTDEL"}, + {INFO_AUTOLOGON, "INFO_AUTOLOGON"}, + {INFO_UNICODE, "INFO_UNICODE"}, + {INFO_MAXIMIZESHELL, "INFO_MAXIMIZESHELL"}, + {INFO_LOGONNOTIFY, "INFO_LOGONNOTIFY"}, + {INFO_COMPRESSION, "INFO_COMPRESSION"}, + {INFO_ENABLEWINDOWSKEY, "INFO_ENABLEWINDOWSKEY"}, + {INFO_REMOTECONSOLEAUDIO, "INFO_REMOTECONSOLEAUDIO"}, + {INFO_FORCE_ENCRYPTED_CS_PDU, "INFO_FORCE_ENCRYPTED_CS_PDU"}, + {INFO_RAIL, "INFO_RAIL"}, + {INFO_LOGONERRORS, "INFO_LOGONERRORS"}, + {INFO_MOUSE_HAS_WHEEL, "INFO_MOUSE_HAS_WHEEL"}, + {INFO_PASSWORD_IS_SC_PIN, "INFO_PASSWORD_IS_SC_PIN"}, + {INFO_NOAUDIOPLAYBACK, "INFO_NOAUDIOPLAYBACK"}, + {INFO_USING_SAVED_CREDS, "INFO_USING_SAVED_CREDS"}, + {INFO_AUDIOCAPTURE, "INFO_AUDIOCAPTURE"}, + {INFO_VIDEO_DISABLE, "INFO_VIDEO_DISABLE"}, + {INFO_HIDEF_RAIL_SUPPORTED, "INFO_HIDEF_RAIL_SUPPORTED"}, +}; + +FREERDP_LOCAL char* rdp_info_package_flags_description(UINT32 flags) +{ + char* result; + size_t maximum_size = 0; + size_t i; + + for (i = 0; i < ARRAYSIZE(info_flags); i ++) + { + maximum_size += strlen(info_flags[i].label) + 1; + } + + result = malloc(maximum_size); + + if (!result) + { + return 0; + } + + result[0] = '\0'; + + for (i = 0; i < ARRAYSIZE(info_flags); i ++) + { + if (info_flags[i].flag & flags) + { + strcat(result, info_flags[i].label); + strcat(result, "|"); + } + } + + result[strlen(result) - 1] = '\0'; /* remove last "|" */ + return result; +} + + static BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp) { BYTE ClientRandom[32]; @@ -421,6 +482,10 @@ static BOOL rdp_read_info_packet(rdpRdp* rdp, wStream* s) settings->RemoteConsoleAudio = ((flags & INFO_REMOTECONSOLEAUDIO) ? TRUE : FALSE); settings->CompressionEnabled = ((flags & INFO_COMPRESSION) ? TRUE : FALSE); settings->LogonNotify = ((flags & INFO_LOGONNOTIFY) ? TRUE : FALSE); + settings->MouseHasWheel = ((flags & INFO_MOUSE_HAS_WHEEL) ? TRUE : FALSE); + settings->DisableCtrlAltDel = ((flags & INFO_DISABLECTRLALTDEL) ? TRUE : FALSE); + settings->ForceEncryptedCsPdu = ((flags & INFO_FORCE_ENCRYPTED_CS_PDU) ? TRUE : FALSE); + settings->PasswordIsSmartcardPin = ((flags & INFO_PASSWORD_IS_SC_PIN) ? TRUE : FALSE); if (flags & INFO_COMPRESSION) { @@ -643,7 +708,15 @@ static void rdp_write_info_packet(rdpRdp* rdp, wStream* s) INFO_LOGONERRORS | INFO_MAXIMIZESHELL | INFO_ENABLEWINDOWSKEY | - INFO_DISABLECTRLALTDEL; + INFO_DISABLECTRLALTDEL | + INFO_MOUSE_HAS_WHEEL | + INFO_FORCE_ENCRYPTED_CS_PDU; + + if (settings->SmartcardLogon) + { + flags |= INFO_AUTOLOGON; + flags |= INFO_PASSWORD_IS_SC_PIN; + } if (settings->AudioCapture) flags |= INFO_AUDIOCAPTURE; @@ -678,6 +751,16 @@ static void rdp_write_info_packet(rdpRdp* rdp, wStream* s) if (settings->PasswordIsSmartcardPin) flags |= INFO_PASSWORD_IS_SC_PIN; + { + char* flags_description = rdp_info_package_flags_description(flags); + + if (flags_description) + { + WLog_DBG(TAG, "Client Info Packet Flags = %s", flags_description); + free(flags_description); + } + } + if (settings->Domain) { cbDomain = ConvertToUnicode(CP_UTF8, 0, settings->Domain, -1, &domainW, 0) * 2; diff --git a/libfreerdp/core/info.h b/libfreerdp/core/info.h index 20980d57e..860ff69a8 100644 --- a/libfreerdp/core/info.h +++ b/libfreerdp/core/info.h @@ -65,4 +65,6 @@ FREERDP_LOCAL BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s); FREERDP_LOCAL BOOL rdp_send_save_session_info(rdpContext* context, UINT32 type, void* data); +FREERDP_LOCAL char* rdp_info_package_flags_description(UINT32 flags); + #endif /* FREERDP_LIB_CORE_INFO_H */ diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 27e50c18d..9f9c7db5d 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -611,6 +611,7 @@ rdpSettings* freerdp_settings_new(DWORD flags) goto out_fail; settings->ActionScript = _strdup("~/.config/freerdp/action.sh"); + settings->SmartcardLogon = FALSE; return settings; out_fail: free(settings->HomePath);