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")
36#include "../core/rdp.h"
38BOOL utils_str_copy(
const char* value,
char** dst)
47 (*dst) = _strdup(value);
48 return (*dst) !=
nullptr;
51static BOOL utils_copy_smartcard_settings(
const rdpSettings* settings, rdpSettings* origSettings)
54 origSettings->SmartcardLogon = settings->SmartcardLogon;
55 origSettings->PasswordIsSmartcardPin = settings->PasswordIsSmartcardPin;
56 if (!utils_str_copy(settings->ReaderName, &origSettings->ReaderName))
58 if (!utils_str_copy(settings->CspName, &origSettings->CspName))
60 if (!utils_str_copy(settings->ContainerName, &origSettings->ContainerName))
66auth_status utils_authenticate_gateway(freerdp* instance, rdp_auth_reason reason)
68 rdpSettings* settings =
nullptr;
69 rdpSettings* origSettings =
nullptr;
73 WINPR_ASSERT(instance);
74 WINPR_ASSERT(instance->context);
75 WINPR_ASSERT(instance->context->settings);
76 WINPR_ASSERT(instance->context->rdp);
77 WINPR_ASSERT(instance->context->rdp->originalSettings);
79 settings = instance->context->settings;
80 origSettings = instance->context->rdp->originalSettings;
82 if (freerdp_shall_disconnect_context(instance->context))
92 if (!utils_sync_credentials(settings, FALSE))
97#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
98 WINPR_PRAGMA_DIAG_PUSH
99 WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
102#if defined(WITHOUT_FREERDP_3x_DEPRECATED)
103 if (!instance->AuthenticateEx)
104 return AUTH_NO_CREDENTIALS;
106 if (!instance->GatewayAuthenticate && !instance->AuthenticateEx)
107 return AUTH_NO_CREDENTIALS;
109 if (!instance->GatewayAuthenticate)
113 instance->AuthenticateEx(instance, &settings->GatewayUsername,
114 &settings->GatewayPassword, &settings->GatewayDomain, reason);
116 return AUTH_CANCELLED;
118#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
122 instance->GatewayAuthenticate(instance, &settings->GatewayUsername,
123 &settings->GatewayPassword, &settings->GatewayDomain);
125 return AUTH_CANCELLED;
129#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
130 WINPR_PRAGMA_DIAG_POP
133 if (utils_str_is_empty(settings->GatewayUsername) ||
134 utils_str_is_empty(settings->GatewayPassword))
135 return AUTH_NO_CREDENTIALS;
137 if (!utils_sync_credentials(settings, FALSE))
141 if (!utils_str_copy(settings->GatewayUsername, &origSettings->GatewayUsername))
143 if (!utils_str_copy(settings->GatewayDomain, &origSettings->GatewayDomain))
145 if (!utils_str_copy(settings->GatewayPassword, &origSettings->GatewayPassword))
147 if (!utils_sync_credentials(origSettings, FALSE))
150 if (!utils_copy_smartcard_settings(settings, origSettings))
156auth_status utils_authenticate(freerdp* instance, rdp_auth_reason reason, BOOL
override)
158 rdpSettings* settings =
nullptr;
159 rdpSettings* origSettings =
nullptr;
160 BOOL prompt = !
override;
163 WINPR_ASSERT(instance);
164 WINPR_ASSERT(instance->context);
165 WINPR_ASSERT(instance->context->settings);
166 WINPR_ASSERT(instance->context->rdp);
167 WINPR_ASSERT(instance->context->rdp->originalSettings);
169 settings = instance->context->settings;
170 origSettings = instance->context->rdp->originalSettings;
172 if (freerdp_shall_disconnect_context(instance->context))
175 if (settings->ConnectChildSession)
176 return AUTH_NO_CREDENTIALS;
180 (settings->Password ==
nullptr && settings->RedirectionPassword ==
nullptr))
190 if (settings->SmartcardLogon)
192 if (!utils_str_is_empty(settings->Password))
194 WLog_INFO(TAG,
"Authentication via smartcard");
197 reason = AUTH_SMARTCARD_PIN;
201 if (settings->SmartcardLogon)
202 reason = AUTH_SMARTCARD_PIN;
209#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
210 WINPR_PRAGMA_DIAG_PUSH
211 WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
215#if defined(WITHOUT_FREERDP_3x_DEPRECATED)
216 if (!instance->AuthenticateEx)
217 return AUTH_NO_CREDENTIALS;
219 if (!instance->Authenticate && !instance->AuthenticateEx)
220 return AUTH_NO_CREDENTIALS;
221 if (!instance->Authenticate)
224 proceed = instance->AuthenticateEx(instance, &settings->Username, &settings->Password,
225 &settings->Domain, reason);
227 return AUTH_CANCELLED;
229#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
232 proceed = instance->Authenticate(instance, &settings->Username, &settings->Password,
235 return AUTH_NO_CREDENTIALS;
239#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
240 WINPR_PRAGMA_DIAG_POP
243 if (utils_str_is_empty(settings->Username) || utils_str_is_empty(settings->Password))
244 return AUTH_NO_CREDENTIALS;
246 if (!utils_sync_credentials(settings, TRUE))
250 if (!utils_str_copy(settings->Username, &origSettings->Username))
252 if (!utils_str_copy(settings->Domain, &origSettings->Domain))
254 if (!utils_str_copy(settings->Password, &origSettings->Password))
256 if (!utils_sync_credentials(origSettings, TRUE))
259 if (!utils_copy_smartcard_settings(settings, origSettings))
265BOOL utils_sync_credentials(rdpSettings* settings, BOOL toGateway)
267 WINPR_ASSERT(settings);
268 if (!settings->GatewayUseSameCredentials)
273 if (!utils_str_copy(settings->Username, &settings->GatewayUsername))
275 if (!utils_str_copy(settings->Domain, &settings->GatewayDomain))
277 if (!utils_str_copy(settings->Password, &settings->GatewayPassword))
282 if (!utils_str_copy(settings->GatewayUsername, &settings->Username))
284 if (!utils_str_copy(settings->GatewayDomain, &settings->Domain))
286 if (!utils_str_copy(settings->GatewayPassword, &settings->Password))
292BOOL utils_persist_credentials(rdpSettings* settings,
const rdpSettings* current)
294 if (!settings || !current)
297 const SSIZE_T keys[] = { FreeRDP_GatewayUsername, FreeRDP_GatewayDomain,
298 FreeRDP_GatewayPassword, FreeRDP_Username,
299 FreeRDP_Domain, FreeRDP_Password };
301 for (
size_t x = 0; x < ARRAYSIZE(keys); x++)
303 const SSIZE_T key = keys[x];
306 WLog_ERR(TAG,
"Failed to copy %s from current to backup settings",
315BOOL utils_str_is_empty(
const char* str)
324BOOL utils_abort_connect(rdpRdp* rdp)
329 return SetEvent(rdp->abortEvent);
332BOOL utils_reset_abort(rdpRdp* rdp)
336 return ResetEvent(rdp->abortEvent);
339HANDLE utils_get_abort_event(rdpRdp* rdp)
342 return rdp->abortEvent;
345BOOL utils_abort_event_is_set(
const rdpRdp* rdp)
349 status = WaitForSingleObject(rdp->abortEvent, 0);
350 return status == WAIT_OBJECT_0;
353const char* utils_is_vsock(
const char* hostname)
358 const char vsock[8] = {
'v',
's',
'o',
'c',
'k',
':',
'/',
'/' };
359 if (strncmp(hostname, vsock,
sizeof(vsock)) == 0)
360 return &hostname[
sizeof(vsock)];
364static BOOL remove_rdpdr_type(rdpSettings* settings, UINT32 type)
370 printer = freerdp_device_collection_find_type(settings, type);
376 freerdp_device_free(printer);
381static BOOL disable_clipboard(rdpSettings* settings)
385 freerdp_static_channel_collection_del(settings, CLIPRDR_SVC_CHANNEL_NAME);
389static BOOL disable_drive(rdpSettings* settings)
396 return remove_rdpdr_type(settings, RDPDR_DTYP_FILESYSTEM);
399static BOOL disable_printers(rdpSettings* settings)
404 return remove_rdpdr_type(settings, RDPDR_DTYP_PRINT);
407static BOOL disable_port(rdpSettings* settings)
413 if (!remove_rdpdr_type(settings, RDPDR_DTYP_SERIAL))
415 return remove_rdpdr_type(settings, RDPDR_DTYP_PARALLEL);
418static BOOL disable_pnp(WINPR_ATTR_UNUSED rdpSettings* settings)
424static BOOL apply_gw_policy(rdpContext* context)
426 WINPR_ASSERT(context);
427 return utils_reload_channels(context);
430BOOL utils_apply_gateway_policy(wLog* log, rdpContext* context, UINT32 flags,
const char* module)
433 WINPR_ASSERT(context);
435 rdpSettings* settings = context->settings;
436 WINPR_ASSERT(settings);
438 if (flags & HTTP_TUNNEL_REDIR_ENABLE_ALL)
440 WLog_Print(log, WLOG_DEBUG,
"[%s] policy allows all redirections", module);
444 char buffer[128] = WINPR_C_ARRAY_INIT;
445 WLog_Print(log, WLOG_INFO,
"[%s] policy ignored on user request %s", module,
446 utils_redir_flags_to_string(flags, buffer,
sizeof(buffer)));
448 else if (flags & HTTP_TUNNEL_REDIR_DISABLE_ALL)
450 WLog_Print(log, WLOG_INFO,
"[%s] policy denies all redirections", module);
451 if (!disable_drive(settings))
453 if (!disable_printers(settings))
455 if (!disable_clipboard(settings))
457 if (!disable_port(settings))
459 if (!disable_pnp(settings))
461 if (!apply_gw_policy(context))
466 if (flags & HTTP_TUNNEL_REDIR_DISABLE_DRIVE)
468 WLog_Print(log, WLOG_INFO,
"[%s] policy denies drive redirections", module);
469 if (!disable_drive(settings))
472 if (flags & HTTP_TUNNEL_REDIR_DISABLE_PRINTER)
474 WLog_Print(log, WLOG_INFO,
"[%s] policy denies printer redirections", module);
475 if (!disable_printers(settings))
478 if (flags & HTTP_TUNNEL_REDIR_DISABLE_PORT)
480 WLog_Print(log, WLOG_INFO,
"[%s] policy denies port redirections", module);
481 if (!disable_port(settings))
484 if (flags & HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD)
486 WLog_Print(log, WLOG_INFO,
"[%s] policy denies clipboard redirections", module);
487 if (!disable_clipboard(settings))
490 if (flags & HTTP_TUNNEL_REDIR_DISABLE_PNP)
492 WLog_Print(log, WLOG_INFO,
"[%s] policy denies PNP redirections", module);
493 if (!disable_pnp(settings))
498 if (!apply_gw_policy(context))
505char* utils_redir_flags_to_string(UINT32 flags,
char* buffer,
size_t size)
507 winpr_str_append(
"{", buffer, size,
"");
508 if (flags & HTTP_TUNNEL_REDIR_ENABLE_ALL)
509 winpr_str_append(
"ENABLE_ALL", buffer, size,
"|");
510 if (flags & HTTP_TUNNEL_REDIR_DISABLE_ALL)
511 winpr_str_append(
"DISABLE_ALL", buffer, size,
"|");
512 if (flags & HTTP_TUNNEL_REDIR_DISABLE_DRIVE)
513 winpr_str_append(
"DISABLE_DRIVE", buffer, size,
"|");
514 if (flags & HTTP_TUNNEL_REDIR_DISABLE_PRINTER)
515 winpr_str_append(
"DISABLE_PRINTER", buffer, size,
"|");
516 if (flags & HTTP_TUNNEL_REDIR_DISABLE_PORT)
517 winpr_str_append(
"DISABLE_PORT", buffer, size,
"|");
518 if (flags & HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD)
519 winpr_str_append(
"DISABLE_CLIPBOARD", buffer, size,
"|");
520 if (flags & HTTP_TUNNEL_REDIR_DISABLE_PNP)
521 winpr_str_append(
"DISABLE_PNP", buffer, size,
"|");
523 char fbuffer[16] = WINPR_C_ARRAY_INIT;
524 (void)_snprintf(fbuffer,
sizeof(fbuffer),
"[0x%08" PRIx32
"]", flags);
526 winpr_str_append(fbuffer, buffer, size,
" ");
527 winpr_str_append(
"{", buffer, size,
"}");
531BOOL utils_reload_channels(rdpContext* context)
533 WINPR_ASSERT(context);
535 if (context->channels)
537 freerdp_channels_disconnect(context->channels, context->instance);
538 freerdp_channels_close(context->channels, context->instance);
539 freerdp_channels_free(context->channels);
542 context->channels = freerdp_channels_new(context->instance);
543 if (!context->channels)
546 freerdp_channels_register_instance(context->channels, context->instance);
549 IFCALLRET(context->instance->LoadChannels, rc, context->instance);
551 return freerdp_channels_pre_connect(context->channels, context->instance) == CHANNEL_RC_OK;
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.