21#include <freerdp/config.h>
25#include <winpr/assert.h>
27#include <freerdp/freerdp.h>
28#include <freerdp/channels/cliprdr.h>
29#include <freerdp/channels/rdpdr.h>
31#include <freerdp/log.h>
32#define TAG FREERDP_TAG("core.gateway.utils")
40#include "../core/rdp.h"
42BOOL utils_str_copy(
const char* value,
char** dst)
51 (*dst) = _strdup(value);
52 return (*dst) !=
nullptr;
56static BOOL utils_copy_smartcard_settings(
const rdpSettings* settings, rdpSettings* origSettings)
59 origSettings->SmartcardLogon = settings->SmartcardLogon;
60 origSettings->PasswordIsSmartcardPin = settings->PasswordIsSmartcardPin;
61 if (!utils_str_copy(settings->ReaderName, &origSettings->ReaderName))
63 if (!utils_str_copy(settings->CspName, &origSettings->CspName))
65 if (!utils_str_copy(settings->ContainerName, &origSettings->ContainerName))
72static BOOL utils_auth_skip(freerdp* instance, rdp_auth_reason reason, BOOL gateway)
74 WINPR_ASSERT(instance);
75 WINPR_ASSERT(instance->context);
78 instance->context->settings, gateway ? FreeRDP_GatewayPassword : FreeRDP_Password);
80 instance->context->settings, gateway ? FreeRDP_GatewayUsername : FreeRDP_Username);
86 case AUTH_SMARTCARD_PIN:
88 if (username && password)
98auth_status utils_authenticate_gateway(freerdp* instance, rdp_auth_reason reason)
100 rdpSettings* settings =
nullptr;
101 rdpSettings* origSettings =
nullptr;
105 WINPR_ASSERT(instance);
106 WINPR_ASSERT(instance->context);
107 WINPR_ASSERT(instance->context->settings);
108 WINPR_ASSERT(instance->context->rdp);
109 WINPR_ASSERT(instance->context->rdp->originalSettings);
111 settings = instance->context->settings;
112 origSettings = instance->context->rdp->originalSettings;
114 if (freerdp_shall_disconnect_context(instance->context))
124 if (!utils_sync_credentials(settings, FALSE))
128 const BOOL skip = utils_auth_skip(instance, reason, TRUE);
132#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
133 WINPR_PRAGMA_DIAG_PUSH
134 WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
137#if defined(WITHOUT_FREERDP_3x_DEPRECATED)
138 if (!instance->AuthenticateEx)
139 return AUTH_NO_CREDENTIALS;
141 if (!instance->GatewayAuthenticate && !instance->AuthenticateEx)
142 return AUTH_NO_CREDENTIALS;
144 if (!instance->GatewayAuthenticate)
148 instance->AuthenticateEx(instance, &settings->GatewayUsername,
149 &settings->GatewayPassword, &settings->GatewayDomain, reason);
151 return AUTH_CANCELLED;
153#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
157 instance->GatewayAuthenticate(instance, &settings->GatewayUsername,
158 &settings->GatewayPassword, &settings->GatewayDomain);
160 return AUTH_CANCELLED;
164#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
165 WINPR_PRAGMA_DIAG_POP
168 if (utils_str_is_empty(settings->GatewayUsername) ||
169 utils_str_is_empty(settings->GatewayPassword))
170 return AUTH_NO_CREDENTIALS;
172 if (!utils_sync_credentials(settings, FALSE))
176 if (!utils_str_copy(settings->GatewayUsername, &origSettings->GatewayUsername))
178 if (!utils_str_copy(settings->GatewayDomain, &origSettings->GatewayDomain))
180 if (!utils_str_copy(settings->GatewayPassword, &origSettings->GatewayPassword))
182 if (!utils_sync_credentials(origSettings, FALSE))
185 if (!utils_copy_smartcard_settings(settings, origSettings))
191auth_status utils_authenticate(freerdp* instance, rdp_auth_reason reason, BOOL
override)
193 rdpSettings* settings =
nullptr;
194 rdpSettings* origSettings =
nullptr;
195 BOOL prompt = !
override;
198 WINPR_ASSERT(instance);
199 WINPR_ASSERT(instance->context);
200 WINPR_ASSERT(instance->context->settings);
201 WINPR_ASSERT(instance->context->rdp);
202 WINPR_ASSERT(instance->context->rdp->originalSettings);
204 settings = instance->context->settings;
205 origSettings = instance->context->rdp->originalSettings;
207 if (freerdp_shall_disconnect_context(instance->context))
210 if (settings->ConnectChildSession)
211 return AUTH_NO_CREDENTIALS;
215 (settings->Password ==
nullptr && settings->RedirectionPassword ==
nullptr))
218 const BOOL skip = utils_auth_skip(instance, reason, FALSE);
226 if (settings->SmartcardLogon)
228 if (!utils_str_is_empty(settings->Password))
230 WLog_INFO(TAG,
"Authentication via smartcard");
233 reason = AUTH_SMARTCARD_PIN;
237 if (settings->SmartcardLogon)
238 reason = AUTH_SMARTCARD_PIN;
245#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
246 WINPR_PRAGMA_DIAG_PUSH
247 WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
251#if defined(WITHOUT_FREERDP_3x_DEPRECATED)
252 if (!instance->AuthenticateEx)
253 return AUTH_NO_CREDENTIALS;
255 if (!instance->Authenticate && !instance->AuthenticateEx)
256 return AUTH_NO_CREDENTIALS;
257 if (!instance->Authenticate)
260 proceed = instance->AuthenticateEx(instance, &settings->Username, &settings->Password,
261 &settings->Domain, reason);
263 return AUTH_CANCELLED;
265#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
268 proceed = instance->Authenticate(instance, &settings->Username, &settings->Password,
271 return AUTH_NO_CREDENTIALS;
275#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
276 WINPR_PRAGMA_DIAG_POP
279 if (utils_str_is_empty(settings->Username) || utils_str_is_empty(settings->Password))
280 return AUTH_NO_CREDENTIALS;
282 if (!utils_sync_credentials(settings, TRUE))
286 if (!utils_str_copy(settings->Username, &origSettings->Username))
288 if (!utils_str_copy(settings->Domain, &origSettings->Domain))
290 if (!utils_str_copy(settings->Password, &origSettings->Password))
292 if (!utils_sync_credentials(origSettings, TRUE))
295 if (!utils_copy_smartcard_settings(settings, origSettings))
301BOOL utils_sync_credentials(rdpSettings* settings, BOOL toGateway)
303 WINPR_ASSERT(settings);
304 if (!settings->GatewayUseSameCredentials)
309 if (!utils_str_copy(settings->Username, &settings->GatewayUsername))
311 if (!utils_str_copy(settings->Domain, &settings->GatewayDomain))
313 if (!utils_str_copy(settings->Password, &settings->GatewayPassword))
318 if (!utils_str_copy(settings->GatewayUsername, &settings->Username))
320 if (!utils_str_copy(settings->GatewayDomain, &settings->Domain))
322 if (!utils_str_copy(settings->GatewayPassword, &settings->Password))
328BOOL utils_persist_credentials(rdpSettings* settings,
const rdpSettings* current)
330 if (!settings || !current)
333 const SSIZE_T keys[] = { FreeRDP_GatewayUsername, FreeRDP_GatewayDomain,
334 FreeRDP_GatewayPassword, FreeRDP_Username,
335 FreeRDP_Domain, FreeRDP_Password };
337 for (
size_t x = 0; x < ARRAYSIZE(keys); x++)
339 const SSIZE_T key = keys[x];
342 WLog_ERR(TAG,
"Failed to copy %s from current to backup settings",
351BOOL utils_str_is_empty(
const char* str)
360BOOL utils_abort_connect(rdpRdp* rdp)
365 return SetEvent(rdp->abortEvent);
368BOOL utils_reset_abort(rdpRdp* rdp)
372 return ResetEvent(rdp->abortEvent);
375HANDLE utils_get_abort_event(rdpRdp* rdp)
378 return rdp->abortEvent;
381BOOL utils_abort_event_is_set(
const rdpRdp* rdp)
385 status = WaitForSingleObject(rdp->abortEvent, 0);
386 return status == WAIT_OBJECT_0;
389const char* utils_is_vsock(
const char* hostname)
394 const char vsock[8] = {
'v',
's',
'o',
'c',
'k',
':',
'/',
'/' };
395 if (strncmp(hostname, vsock,
sizeof(vsock)) == 0)
396 return &hostname[
sizeof(vsock)];
401static BOOL remove_rdpdr_type(rdpSettings* settings, UINT32 type)
407 printer = freerdp_device_collection_find_type(settings, type);
413 freerdp_device_free(printer);
419static BOOL disable_clipboard(rdpSettings* settings)
423 freerdp_static_channel_collection_del(settings, CLIPRDR_SVC_CHANNEL_NAME);
428static BOOL disable_drive(rdpSettings* settings)
435 return remove_rdpdr_type(settings, RDPDR_DTYP_FILESYSTEM);
439static BOOL disable_printers(rdpSettings* settings)
444 return remove_rdpdr_type(settings, RDPDR_DTYP_PRINT);
448static BOOL disable_port(rdpSettings* settings)
454 if (!remove_rdpdr_type(settings, RDPDR_DTYP_SERIAL))
456 return remove_rdpdr_type(settings, RDPDR_DTYP_PARALLEL);
460static BOOL disable_pnp(WINPR_ATTR_UNUSED rdpSettings* settings)
467static BOOL apply_gw_policy(rdpContext* context)
469 WINPR_ASSERT(context);
470 return utils_reload_channels(context);
473BOOL utils_apply_gateway_policy(wLog* log, rdpContext* context, UINT32 flags,
const char* module)
476 WINPR_ASSERT(context);
478 rdpSettings* settings = context->settings;
479 WINPR_ASSERT(settings);
481 if (flags & HTTP_TUNNEL_REDIR_ENABLE_ALL)
483 WLog_Print(log, WLOG_DEBUG,
"[%s] policy allows all redirections", module);
487 char buffer[128] = WINPR_C_ARRAY_INIT;
488 WLog_Print(log, WLOG_INFO,
"[%s] policy ignored on user request %s", module,
489 utils_redir_flags_to_string(flags, buffer,
sizeof(buffer)));
491 else if (flags & HTTP_TUNNEL_REDIR_DISABLE_ALL)
493 WLog_Print(log, WLOG_INFO,
"[%s] policy denies all redirections", module);
494 if (!disable_drive(settings))
496 if (!disable_printers(settings))
498 if (!disable_clipboard(settings))
500 if (!disable_port(settings))
502 if (!disable_pnp(settings))
504 if (!apply_gw_policy(context))
509 if (flags & HTTP_TUNNEL_REDIR_DISABLE_DRIVE)
511 WLog_Print(log, WLOG_INFO,
"[%s] policy denies drive redirections", module);
512 if (!disable_drive(settings))
515 if (flags & HTTP_TUNNEL_REDIR_DISABLE_PRINTER)
517 WLog_Print(log, WLOG_INFO,
"[%s] policy denies printer redirections", module);
518 if (!disable_printers(settings))
521 if (flags & HTTP_TUNNEL_REDIR_DISABLE_PORT)
523 WLog_Print(log, WLOG_INFO,
"[%s] policy denies port redirections", module);
524 if (!disable_port(settings))
527 if (flags & HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD)
529 WLog_Print(log, WLOG_INFO,
"[%s] policy denies clipboard redirections", module);
530 if (!disable_clipboard(settings))
533 if (flags & HTTP_TUNNEL_REDIR_DISABLE_PNP)
535 WLog_Print(log, WLOG_INFO,
"[%s] policy denies PNP redirections", module);
536 if (!disable_pnp(settings))
541 if (!apply_gw_policy(context))
548char* utils_redir_flags_to_string(UINT32 flags,
char* buffer,
size_t size)
550 winpr_str_append(
"{", buffer, size,
"");
551 if (flags & HTTP_TUNNEL_REDIR_ENABLE_ALL)
552 winpr_str_append(
"ENABLE_ALL", buffer, size,
"|");
553 if (flags & HTTP_TUNNEL_REDIR_DISABLE_ALL)
554 winpr_str_append(
"DISABLE_ALL", buffer, size,
"|");
555 if (flags & HTTP_TUNNEL_REDIR_DISABLE_DRIVE)
556 winpr_str_append(
"DISABLE_DRIVE", buffer, size,
"|");
557 if (flags & HTTP_TUNNEL_REDIR_DISABLE_PRINTER)
558 winpr_str_append(
"DISABLE_PRINTER", buffer, size,
"|");
559 if (flags & HTTP_TUNNEL_REDIR_DISABLE_PORT)
560 winpr_str_append(
"DISABLE_PORT", buffer, size,
"|");
561 if (flags & HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD)
562 winpr_str_append(
"DISABLE_CLIPBOARD", buffer, size,
"|");
563 if (flags & HTTP_TUNNEL_REDIR_DISABLE_PNP)
564 winpr_str_append(
"DISABLE_PNP", buffer, size,
"|");
566 char fbuffer[16] = WINPR_C_ARRAY_INIT;
567 (void)_snprintf(fbuffer,
sizeof(fbuffer),
"[0x%08" PRIx32
"]", flags);
569 winpr_str_append(fbuffer, buffer, size,
" ");
570 winpr_str_append(
"{", buffer, size,
"}");
574BOOL utils_reload_channels(rdpContext* context)
576 WINPR_ASSERT(context);
578 if (context->channels)
580 freerdp_channels_disconnect(context->channels, context->instance);
581 freerdp_channels_close(context->channels, context->instance);
582 freerdp_channels_free(context->channels);
585 context->channels = freerdp_channels_new(context->instance);
586 if (!context->channels)
589 freerdp_channels_register_instance(context->channels, context->instance);
592 IFCALLRET(context->instance->LoadChannels, rc, context->instance);
594 return freerdp_channels_pre_connect(context->channels, context->instance) == CHANNEL_RC_OK;
598const char* guid2str(
const GUID* guid,
char* buffer,
size_t len)
602 RPC_CSTR strguid =
nullptr;
604 RPC_STATUS rpcStatus = UuidToStringA(guid, &strguid);
606 if (rpcStatus != RPC_S_OK)
609 (void)sprintf_s(buffer, len,
"%s", strguid);
610 RpcStringFreeA(&strguid);
615static BOOL isValidIPv4(
const char* ipAddress)
617 struct sockaddr_in sa = WINPR_C_ARRAY_INIT;
618 int result = inet_pton(AF_INET, ipAddress, &(sa.sin_addr));
623static BOOL isValidIPv6(
const char* ipAddress)
625 struct sockaddr_in6 sa = WINPR_C_ARRAY_INIT;
626 int result = inet_pton(AF_INET6, ipAddress, &(sa.sin6_addr));
630BOOL utils_is_valid_ip(
const char* ipAddress)
632 return isValidIPv4(ipAddress) || isValidIPv6(ipAddress);
635BOOL utils_set_umask(
void)
638 (void)umask(S_IRWXG | S_IRWXO);
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL val)
Sets a BOOL settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_copy_item(rdpSettings *dst, const rdpSettings *src, SSIZE_T id)
copies one setting identified by id from src to dst
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_device_collection_del(rdpSettings *settings, const RDPDR_DEVICE *device)
Removed a device from the settings, returns ownership of the allocated device to caller.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_name_for_key(SSIZE_T key)
Returns the type name for a key.