diff --git a/client/common/cmdline.c b/client/common/cmdline.c index a48d3ef6f..ca3e2833d 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -2463,6 +2463,11 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, return rc; } } + CommandLineSwitchCase(arg, "server-name") + { + if (!freerdp_settings_set_string(settings, FreeRDP_UserSpecifiedServerName, arg->Value)) + return COMMAND_LINE_ERROR_MEMORY; + } CommandLineSwitchCase(arg, "shell") { if (!freerdp_settings_set_string(settings, FreeRDP_AlternateShell, arg->Value)) diff --git a/client/common/cmdline.h b/client/common/cmdline.h index daadb979f..238343c00 100644 --- a/client/common/cmdline.h +++ b/client/common/cmdline.h @@ -337,6 +337,8 @@ static const COMMAND_LINE_ARGUMENT_A global_cmd_args[] = { "TLS protocol security" }, { "serial", COMMAND_LINE_VALUE_OPTIONAL, "[,[,[,permissive]]]", NULL, NULL, -1, "tty", "Redirect serial device" }, + { "server-name", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "User-specified server name to use for validation (TLS, Kerberos)" }, { "shell", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Alternate shell" }, { "shell-dir", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Shell working directory" }, diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index a3d351f5c..9aee398ae 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -516,6 +516,7 @@ typedef struct #define FreeRDP_MaxTimeInCheckLoop (26) #define FreeRDP_AcceptedCert (27) #define FreeRDP_AcceptedCertLength (28) +#define FreeRDP_UserSpecifiedServerName (29) #define FreeRDP_ThreadingFlags (64) #define FreeRDP_RdpVersion (128) #define FreeRDP_DesktopWidth (129) @@ -944,7 +945,8 @@ struct rdp_settings ALIGN64 UINT32 MaxTimeInCheckLoop; /* 26 */ ALIGN64 char* AcceptedCert; /* 27 */ ALIGN64 UINT32 AcceptedCertLength; /* 28 */ - UINT64 padding0064[64 - 29]; /* 29 */ + ALIGN64 char* UserSpecifiedServerName; /* 29 */ + UINT64 padding0064[64 - 30]; /* 30 */ /* resource management related options */ ALIGN64 UINT32 ThreadingFlags; /* 64 */ @@ -1828,6 +1830,8 @@ extern "C" FREERDP_API const char* freerdp_settings_get_name_for_key(size_t key); FREERDP_API UINT32 freerdp_settings_get_codecs_flags(const rdpSettings* settings); + FREERDP_API const char* freerdp_settings_get_server_name(const rdpSettings* settings); + FREERDP_API char* freerdp_rail_support_flags_to_string(UINT32 flags, char* buffer, size_t length); diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index aaba6d970..91614c047 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -1686,6 +1686,16 @@ UINT32 freerdp_settings_get_codecs_flags(const rdpSettings* settings) return flags; } +const char* freerdp_settings_get_server_name(const rdpSettings* settings) +{ + const char* hostname = settings->ServerHostname; + + if (settings->UserSpecifiedServerName) + hostname = settings->UserSpecifiedServerName; + + return hostname; +} + #if defined(WITH_FREERDP_DEPRECATED) ADDIN_ARGV* freerdp_static_channel_clone(ADDIN_ARGV* channel) { diff --git a/libfreerdp/common/settings_getters.c b/libfreerdp/common/settings_getters.c index 255a4c917..bddd26b85 100644 --- a/libfreerdp/common/settings_getters.c +++ b/libfreerdp/common/settings_getters.c @@ -2603,6 +2603,9 @@ const char* freerdp_settings_get_string(const rdpSettings* settings, size_t id) case FreeRDP_TransportDumpFile: return settings->TransportDumpFile; + case FreeRDP_UserSpecifiedServerName: + return settings->UserSpecifiedServerName; + case FreeRDP_Username: return settings->Username; @@ -2870,6 +2873,9 @@ char* freerdp_settings_get_string_writable(rdpSettings* settings, size_t id) case FreeRDP_TransportDumpFile: return settings->TransportDumpFile; + case FreeRDP_UserSpecifiedServerName: + return settings->UserSpecifiedServerName; + case FreeRDP_Username: return settings->Username; @@ -3147,6 +3153,9 @@ BOOL freerdp_settings_set_string_(rdpSettings* settings, size_t id, const char* case FreeRDP_TransportDumpFile: return update_string(&settings->TransportDumpFile, cnv.cc, len, cleanup); + case FreeRDP_UserSpecifiedServerName: + return update_string(&settings->UserSpecifiedServerName, cnv.cc, len, cleanup); + case FreeRDP_Username: return update_string(&settings->Username, cnv.cc, len, cleanup); diff --git a/libfreerdp/common/settings_str.c b/libfreerdp/common/settings_str.c index f65d7d7b0..3f9fc0774 100644 --- a/libfreerdp/common/settings_str.c +++ b/libfreerdp/common/settings_str.c @@ -394,6 +394,7 @@ static const struct settings_str_entry settings_map[] = { { FreeRDP_TargetNetAddress, 7, "FreeRDP_TargetNetAddress" }, { FreeRDP_TlsSecretsFile, 7, "FreeRDP_TlsSecretsFile" }, { FreeRDP_TransportDumpFile, 7, "FreeRDP_TransportDumpFile" }, + { FreeRDP_UserSpecifiedServerName, 7, "FreeRDP_UserSpecifiedServerName" }, { FreeRDP_Username, 7, "FreeRDP_Username" }, { FreeRDP_WindowTitle, 7, "FreeRDP_WindowTitle" }, { FreeRDP_WmClass, 7, "FreeRDP_WmClass" }, diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index 43011628d..302b83731 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -267,8 +267,10 @@ BOOL rdp_client_connect(rdpRdp* rdp) settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; } + const char* hostname = freerdp_settings_get_server_name(settings); + nego_init(rdp->nego); - nego_set_target(rdp->nego, settings->ServerHostname, settings->ServerPort); + nego_set_target(rdp->nego, hostname, settings->ServerPort); if (settings->GatewayEnabled) { diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 8f5ff33be..ca89f78c8 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -469,8 +469,9 @@ static int nla_client_init(rdpNla* nla) if (!nla_client_setup_identity(nla)) return -1; - if (!credssp_auth_setup_client(nla->auth, "TERMSRV", settings->ServerHostname, nla->identity, - nla->pkinitArgs)) + const char* hostname = freerdp_settings_get_server_name(settings); + + if (!credssp_auth_setup_client(nla->auth, "TERMSRV", hostname, nla->identity, nla->pkinitArgs)) return -1; tls = transport_get_tls(nla->transport); diff --git a/libfreerdp/core/test/settings_property_lists.h b/libfreerdp/core/test/settings_property_lists.h index bdf1c1da9..181101a6d 100644 --- a/libfreerdp/core/test/settings_property_lists.h +++ b/libfreerdp/core/test/settings_property_lists.h @@ -403,6 +403,7 @@ static const size_t string_list_indices[] = { FreeRDP_TargetNetAddress, FreeRDP_TlsSecretsFile, FreeRDP_TransportDumpFile, + FreeRDP_UserSpecifiedServerName, FreeRDP_Username, FreeRDP_WindowTitle, FreeRDP_WmClass, diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index bf8b34548..6e780b7cd 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -330,7 +330,7 @@ BOOL transport_connect_nla(rdpTransport* transport) if (settings->AuthenticationServiceClass) { if (!nla_set_service_principal(rdp->nla, settings->AuthenticationServiceClass, - settings->ServerHostname)) + freerdp_settings_get_server_name(settings))) return FALSE; }