Coverage Report

Created: 2026-07-16 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/libfreerdp/core/utils.c
Line
Count
Source
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * Terminal Server Gateway (utils)
4
 *
5
 * Copyright 2021 Armin Novak <armin.novak@thincast.com>
6
 * Copyright 2021 Thincast Technologies GmbH
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
#include <freerdp/config.h>
22
23
#include "settings.h"
24
25
#include <winpr/assert.h>
26
27
#include <freerdp/freerdp.h>
28
#include <freerdp/channels/cliprdr.h>
29
#include <freerdp/channels/rdpdr.h>
30
31
#include <freerdp/log.h>
32
#define TAG FREERDP_TAG("core.gateway.utils")
33
34
#include "utils.h"
35
36
#include "../core/rdp.h"
37
38
BOOL utils_str_copy(const char* value, char** dst)
39
0
{
40
0
  WINPR_ASSERT(dst);
41
42
0
  free(*dst);
43
0
  *dst = nullptr;
44
0
  if (!value)
45
0
    return TRUE;
46
47
0
  (*dst) = _strdup(value);
48
0
  return (*dst) != nullptr;
49
0
}
50
51
static BOOL utils_copy_smartcard_settings(const rdpSettings* settings, rdpSettings* origSettings)
52
0
{
53
  /* update original settings with provided smart card settings */
54
0
  origSettings->SmartcardLogon = settings->SmartcardLogon;
55
0
  origSettings->PasswordIsSmartcardPin = settings->PasswordIsSmartcardPin;
56
0
  if (!utils_str_copy(settings->ReaderName, &origSettings->ReaderName))
57
0
    return FALSE;
58
0
  if (!utils_str_copy(settings->CspName, &origSettings->CspName))
59
0
    return FALSE;
60
0
  if (!utils_str_copy(settings->ContainerName, &origSettings->ContainerName))
61
0
    return FALSE;
62
63
0
  return TRUE;
64
0
}
65
66
static BOOL utils_auth_skip(freerdp* instance, rdp_auth_reason reason, BOOL gateway)
67
0
{
68
0
  WINPR_ASSERT(instance);
69
0
  WINPR_ASSERT(instance->context);
70
71
0
  const char* password = freerdp_settings_get_string(
72
0
      instance->context->settings, gateway ? FreeRDP_GatewayPassword : FreeRDP_Password);
73
0
  const char* username = freerdp_settings_get_string(
74
0
      instance->context->settings, gateway ? FreeRDP_GatewayUsername : FreeRDP_Username);
75
76
0
  switch (reason)
77
0
  {
78
0
    case AUTH_TLS:
79
0
    case AUTH_RDP:
80
0
    case AUTH_SMARTCARD_PIN: /* in this case password is pin code */
81
0
    case AUTH_FIDO_PIN:
82
0
      if (username && password)
83
0
        return TRUE;
84
0
      break;
85
0
    default:
86
0
      break;
87
0
  }
88
89
0
  return FALSE;
90
0
}
91
92
auth_status utils_authenticate_gateway(freerdp* instance, rdp_auth_reason reason)
93
0
{
94
0
  rdpSettings* settings = nullptr;
95
0
  rdpSettings* origSettings = nullptr;
96
0
  BOOL prompt = FALSE;
97
0
  BOOL proceed = 0;
98
99
0
  WINPR_ASSERT(instance);
100
0
  WINPR_ASSERT(instance->context);
101
0
  WINPR_ASSERT(instance->context->settings);
102
0
  WINPR_ASSERT(instance->context->rdp);
103
0
  WINPR_ASSERT(instance->context->rdp->originalSettings);
104
105
0
  settings = instance->context->settings;
106
0
  origSettings = instance->context->rdp->originalSettings;
107
108
0
  if (freerdp_shall_disconnect_context(instance->context))
109
0
    return AUTH_FAILED;
110
111
0
  if (utils_str_is_empty(freerdp_settings_get_string(settings, FreeRDP_GatewayPassword)))
112
0
    prompt = TRUE;
113
0
  if (utils_str_is_empty(freerdp_settings_get_string(settings, FreeRDP_GatewayUsername)))
114
0
    prompt = TRUE;
115
116
0
  if (!prompt)
117
0
  {
118
0
    if (!utils_sync_credentials(settings, FALSE))
119
0
      return AUTH_FAILED;
120
0
    return AUTH_SKIP;
121
0
  }
122
0
  const BOOL skip = utils_auth_skip(instance, reason, TRUE);
123
0
  if (skip)
124
0
    return AUTH_SKIP;
125
126
0
#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
127
0
  WINPR_PRAGMA_DIAG_PUSH
128
0
  WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
129
0
#endif
130
131
#if defined(WITHOUT_FREERDP_3x_DEPRECATED)
132
  if (!instance->AuthenticateEx)
133
    return AUTH_NO_CREDENTIALS;
134
#else
135
0
  if (!instance->GatewayAuthenticate && !instance->AuthenticateEx)
136
0
    return AUTH_NO_CREDENTIALS;
137
138
0
  if (!instance->GatewayAuthenticate)
139
0
#endif
140
0
  {
141
0
    proceed =
142
0
        instance->AuthenticateEx(instance, &settings->GatewayUsername,
143
0
                                 &settings->GatewayPassword, &settings->GatewayDomain, reason);
144
0
    if (!proceed)
145
0
      return AUTH_CANCELLED;
146
0
  }
147
0
#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
148
0
  else
149
0
  {
150
0
    proceed =
151
0
        instance->GatewayAuthenticate(instance, &settings->GatewayUsername,
152
0
                                      &settings->GatewayPassword, &settings->GatewayDomain);
153
0
    if (!proceed)
154
0
      return AUTH_CANCELLED;
155
0
  }
156
0
#endif
157
158
0
#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
159
0
  WINPR_PRAGMA_DIAG_POP
160
0
#endif
161
162
0
  if (utils_str_is_empty(settings->GatewayUsername) ||
163
0
      utils_str_is_empty(settings->GatewayPassword))
164
0
    return AUTH_NO_CREDENTIALS;
165
166
0
  if (!utils_sync_credentials(settings, FALSE))
167
0
    return AUTH_FAILED;
168
169
  /* update original settings with provided user credentials */
170
0
  if (!utils_str_copy(settings->GatewayUsername, &origSettings->GatewayUsername))
171
0
    return AUTH_FAILED;
172
0
  if (!utils_str_copy(settings->GatewayDomain, &origSettings->GatewayDomain))
173
0
    return AUTH_FAILED;
174
0
  if (!utils_str_copy(settings->GatewayPassword, &origSettings->GatewayPassword))
175
0
    return AUTH_FAILED;
176
0
  if (!utils_sync_credentials(origSettings, FALSE))
177
0
    return AUTH_FAILED;
178
179
0
  if (!utils_copy_smartcard_settings(settings, origSettings))
180
0
    return AUTH_FAILED;
181
182
0
  return AUTH_SUCCESS;
183
0
}
184
185
auth_status utils_authenticate(freerdp* instance, rdp_auth_reason reason, BOOL override)
186
0
{
187
0
  rdpSettings* settings = nullptr;
188
0
  rdpSettings* origSettings = nullptr;
189
0
  BOOL prompt = !override;
190
0
  BOOL proceed = 0;
191
192
0
  WINPR_ASSERT(instance);
193
0
  WINPR_ASSERT(instance->context);
194
0
  WINPR_ASSERT(instance->context->settings);
195
0
  WINPR_ASSERT(instance->context->rdp);
196
0
  WINPR_ASSERT(instance->context->rdp->originalSettings);
197
198
0
  settings = instance->context->settings;
199
0
  origSettings = instance->context->rdp->originalSettings;
200
201
0
  if (freerdp_shall_disconnect_context(instance->context))
202
0
    return AUTH_FAILED;
203
204
0
  if (settings->ConnectChildSession)
205
0
    return AUTH_NO_CREDENTIALS;
206
207
  /* Ask for auth data if no or an empty username was specified or no password was given */
208
0
  if (utils_str_is_empty(freerdp_settings_get_string(settings, FreeRDP_Username)) ||
209
0
      (settings->Password == nullptr && settings->RedirectionPassword == nullptr))
210
0
    prompt = TRUE;
211
212
0
  const BOOL skip = utils_auth_skip(instance, reason, FALSE);
213
0
  if (!prompt || skip)
214
0
    return AUTH_SKIP;
215
216
0
  switch (reason)
217
0
  {
218
0
    case AUTH_RDP:
219
0
    case AUTH_TLS:
220
0
      if (settings->SmartcardLogon)
221
0
      {
222
0
        if (!utils_str_is_empty(settings->Password))
223
0
        {
224
0
          WLog_INFO(TAG, "Authentication via smartcard");
225
0
          return AUTH_SUCCESS;
226
0
        }
227
0
        reason = AUTH_SMARTCARD_PIN;
228
0
      }
229
0
      break;
230
0
    case AUTH_NLA:
231
0
      if (settings->SmartcardLogon)
232
0
        reason = AUTH_SMARTCARD_PIN;
233
0
      break;
234
0
    case AUTH_RDSTLS:
235
0
    default:
236
0
      break;
237
0
  }
238
239
0
#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
240
0
  WINPR_PRAGMA_DIAG_PUSH
241
0
  WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
242
0
#endif
243
244
  /* If no callback is specified still continue connection */
245
#if defined(WITHOUT_FREERDP_3x_DEPRECATED)
246
  if (!instance->AuthenticateEx)
247
    return AUTH_NO_CREDENTIALS;
248
#else
249
0
  if (!instance->Authenticate && !instance->AuthenticateEx)
250
0
    return AUTH_NO_CREDENTIALS;
251
0
  if (!instance->Authenticate)
252
0
#endif
253
0
  {
254
0
    proceed = instance->AuthenticateEx(instance, &settings->Username, &settings->Password,
255
0
                                       &settings->Domain, reason);
256
0
    if (!proceed)
257
0
      return AUTH_CANCELLED;
258
0
  }
259
0
#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
260
0
  else
261
0
  {
262
0
    proceed = instance->Authenticate(instance, &settings->Username, &settings->Password,
263
0
                                     &settings->Domain);
264
0
    if (!proceed)
265
0
      return AUTH_NO_CREDENTIALS;
266
0
  }
267
0
#endif
268
269
0
#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
270
0
  WINPR_PRAGMA_DIAG_POP
271
0
#endif
272
273
0
  if (utils_str_is_empty(settings->Username) || utils_str_is_empty(settings->Password))
274
0
    return AUTH_NO_CREDENTIALS;
275
276
0
  if (!utils_sync_credentials(settings, TRUE))
277
0
    return AUTH_FAILED;
278
279
  /* update original settings with provided user credentials */
280
0
  if (!utils_str_copy(settings->Username, &origSettings->Username))
281
0
    return AUTH_FAILED;
282
0
  if (!utils_str_copy(settings->Domain, &origSettings->Domain))
283
0
    return AUTH_FAILED;
284
0
  if (!utils_str_copy(settings->Password, &origSettings->Password))
285
0
    return AUTH_FAILED;
286
0
  if (!utils_sync_credentials(origSettings, TRUE))
287
0
    return AUTH_FAILED;
288
289
0
  if (!utils_copy_smartcard_settings(settings, origSettings))
290
0
    return AUTH_FAILED;
291
292
0
  return AUTH_SUCCESS;
293
0
}
294
295
BOOL utils_sync_credentials(rdpSettings* settings, BOOL toGateway)
296
0
{
297
0
  WINPR_ASSERT(settings);
298
0
  if (!settings->GatewayUseSameCredentials)
299
0
    return TRUE;
300
301
0
  if (toGateway)
302
0
  {
303
0
    if (!utils_str_copy(settings->Username, &settings->GatewayUsername))
304
0
      return FALSE;
305
0
    if (!utils_str_copy(settings->Domain, &settings->GatewayDomain))
306
0
      return FALSE;
307
0
    if (!utils_str_copy(settings->Password, &settings->GatewayPassword))
308
0
      return FALSE;
309
0
  }
310
0
  else
311
0
  {
312
0
    if (!utils_str_copy(settings->GatewayUsername, &settings->Username))
313
0
      return FALSE;
314
0
    if (!utils_str_copy(settings->GatewayDomain, &settings->Domain))
315
0
      return FALSE;
316
0
    if (!utils_str_copy(settings->GatewayPassword, &settings->Password))
317
0
      return FALSE;
318
0
  }
319
0
  return TRUE;
320
0
}
321
322
BOOL utils_persist_credentials(rdpSettings* settings, const rdpSettings* current)
323
0
{
324
0
  if (!settings || !current)
325
0
    return FALSE;
326
327
0
  const SSIZE_T keys[] = { FreeRDP_GatewayUsername, FreeRDP_GatewayDomain,
328
0
                         FreeRDP_GatewayPassword, FreeRDP_Username,
329
0
                         FreeRDP_Domain,          FreeRDP_Password };
330
331
0
  for (size_t x = 0; x < ARRAYSIZE(keys); x++)
332
0
  {
333
0
    const SSIZE_T key = keys[x];
334
0
    if (!freerdp_settings_copy_item(settings, current, key))
335
0
    {
336
0
      WLog_ERR(TAG, "Failed to copy %s from current to backup settings",
337
0
               freerdp_settings_get_name_for_key(key));
338
0
      return FALSE;
339
0
    }
340
0
  }
341
342
0
  return TRUE;
343
0
}
344
345
BOOL utils_str_is_empty(const char* str)
346
0
{
347
0
  if (!str)
348
0
    return TRUE;
349
0
  if (*str == '\0')
350
0
    return TRUE;
351
0
  return FALSE;
352
0
}
353
354
BOOL utils_abort_connect(rdpRdp* rdp)
355
950
{
356
950
  if (!rdp)
357
0
    return FALSE;
358
359
950
  return SetEvent(rdp->abortEvent);
360
950
}
361
362
BOOL utils_reset_abort(rdpRdp* rdp)
363
0
{
364
0
  WINPR_ASSERT(rdp);
365
366
0
  return ResetEvent(rdp->abortEvent);
367
0
}
368
369
HANDLE utils_get_abort_event(rdpRdp* rdp)
370
16.4k
{
371
16.4k
  WINPR_ASSERT(rdp);
372
16.4k
  return rdp->abortEvent;
373
16.4k
}
374
375
BOOL utils_abort_event_is_set(const rdpRdp* rdp)
376
65
{
377
65
  DWORD status = 0;
378
65
  WINPR_ASSERT(rdp);
379
65
  status = WaitForSingleObject(rdp->abortEvent, 0);
380
65
  return status == WAIT_OBJECT_0;
381
65
}
382
383
const char* utils_is_vsock(const char* hostname)
384
0
{
385
0
  if (!hostname)
386
0
    return nullptr;
387
388
0
  const char vsock[8] = { 'v', 's', 'o', 'c', 'k', ':', '/', '/' };
389
0
  if (strncmp(hostname, vsock, sizeof(vsock)) == 0)
390
0
    return &hostname[sizeof(vsock)];
391
0
  return nullptr;
392
0
}
393
394
static BOOL remove_rdpdr_type(rdpSettings* settings, UINT32 type)
395
0
{
396
0
  BOOL rc = TRUE;
397
0
  RDPDR_DEVICE* printer = nullptr;
398
0
  do
399
0
  {
400
0
    printer = freerdp_device_collection_find_type(settings, type);
401
0
    if (printer)
402
0
    {
403
0
      if (!freerdp_device_collection_del(settings, printer))
404
0
        rc = FALSE;
405
0
    }
406
0
    freerdp_device_free(printer);
407
0
  } while (printer);
408
0
  return rc;
409
0
}
410
411
static BOOL disable_clipboard(rdpSettings* settings)
412
0
{
413
0
  if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectClipboard, FALSE))
414
0
    return FALSE;
415
0
  freerdp_static_channel_collection_del(settings, CLIPRDR_SVC_CHANNEL_NAME);
416
0
  return TRUE;
417
0
}
418
419
static BOOL disable_drive(rdpSettings* settings)
420
0
{
421
0
  if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectDrives, FALSE))
422
0
    return FALSE;
423
0
  if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectHomeDrive, FALSE))
424
0
    return FALSE;
425
426
0
  return remove_rdpdr_type(settings, RDPDR_DTYP_FILESYSTEM);
427
0
}
428
429
static BOOL disable_printers(rdpSettings* settings)
430
0
{
431
0
  if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectPrinters, FALSE))
432
0
    return FALSE;
433
434
0
  return remove_rdpdr_type(settings, RDPDR_DTYP_PRINT);
435
0
}
436
437
static BOOL disable_port(rdpSettings* settings)
438
0
{
439
0
  if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectParallelPorts, FALSE))
440
0
    return FALSE;
441
0
  if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectSerialPorts, FALSE))
442
0
    return FALSE;
443
0
  if (!remove_rdpdr_type(settings, RDPDR_DTYP_SERIAL))
444
0
    return FALSE;
445
0
  return remove_rdpdr_type(settings, RDPDR_DTYP_PARALLEL);
446
0
}
447
448
static BOOL disable_pnp(WINPR_ATTR_UNUSED rdpSettings* settings)
449
0
{
450
  // TODO(akallabeth): [MS-RDPEPNP] related stuff is disabled.
451
0
  return TRUE;
452
0
}
453
454
static BOOL apply_gw_policy(rdpContext* context)
455
0
{
456
0
  WINPR_ASSERT(context);
457
0
  return utils_reload_channels(context);
458
0
}
459
460
BOOL utils_apply_gateway_policy(wLog* log, rdpContext* context, UINT32 flags, const char* module)
461
0
{
462
0
  WINPR_ASSERT(log);
463
0
  WINPR_ASSERT(context);
464
465
0
  rdpSettings* settings = context->settings;
466
0
  WINPR_ASSERT(settings);
467
468
0
  if (flags & HTTP_TUNNEL_REDIR_ENABLE_ALL)
469
0
  {
470
0
    WLog_Print(log, WLOG_DEBUG, "[%s] policy allows all redirections", module);
471
0
  }
472
0
  else if (freerdp_settings_get_bool(settings, FreeRDP_GatewayIgnoreRedirectionPolicy))
473
0
  {
474
0
    char buffer[128] = WINPR_C_ARRAY_INIT;
475
0
    WLog_Print(log, WLOG_INFO, "[%s] policy ignored on user request %s", module,
476
0
               utils_redir_flags_to_string(flags, buffer, sizeof(buffer)));
477
0
  }
478
0
  else if (flags & HTTP_TUNNEL_REDIR_DISABLE_ALL)
479
0
  {
480
0
    WLog_Print(log, WLOG_INFO, "[%s] policy denies all redirections", module);
481
0
    if (!disable_drive(settings))
482
0
      return FALSE;
483
0
    if (!disable_printers(settings))
484
0
      return FALSE;
485
0
    if (!disable_clipboard(settings))
486
0
      return FALSE;
487
0
    if (!disable_port(settings))
488
0
      return FALSE;
489
0
    if (!disable_pnp(settings))
490
0
      return FALSE;
491
0
    if (!apply_gw_policy(context))
492
0
      return FALSE;
493
0
  }
494
0
  else
495
0
  {
496
0
    if (flags & HTTP_TUNNEL_REDIR_DISABLE_DRIVE)
497
0
    {
498
0
      WLog_Print(log, WLOG_INFO, "[%s] policy denies drive redirections", module);
499
0
      if (!disable_drive(settings))
500
0
        return FALSE;
501
0
    }
502
0
    if (flags & HTTP_TUNNEL_REDIR_DISABLE_PRINTER)
503
0
    {
504
0
      WLog_Print(log, WLOG_INFO, "[%s] policy denies printer redirections", module);
505
0
      if (!disable_printers(settings))
506
0
        return FALSE;
507
0
    }
508
0
    if (flags & HTTP_TUNNEL_REDIR_DISABLE_PORT)
509
0
    {
510
0
      WLog_Print(log, WLOG_INFO, "[%s] policy denies port redirections", module);
511
0
      if (!disable_port(settings))
512
0
        return FALSE;
513
0
    }
514
0
    if (flags & HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD)
515
0
    {
516
0
      WLog_Print(log, WLOG_INFO, "[%s] policy denies clipboard redirections", module);
517
0
      if (!disable_clipboard(settings))
518
0
        return FALSE;
519
0
    }
520
0
    if (flags & HTTP_TUNNEL_REDIR_DISABLE_PNP)
521
0
    {
522
0
      WLog_Print(log, WLOG_INFO, "[%s] policy denies PNP redirections", module);
523
0
      if (!disable_pnp(settings))
524
0
        return FALSE;
525
0
    }
526
0
    if (flags != 0)
527
0
    {
528
0
      if (!apply_gw_policy(context))
529
0
        return FALSE;
530
0
    }
531
0
  }
532
0
  return TRUE;
533
0
}
534
535
char* utils_redir_flags_to_string(UINT32 flags, char* buffer, size_t size)
536
0
{
537
0
  winpr_str_append("{", buffer, size, "");
538
0
  if (flags & HTTP_TUNNEL_REDIR_ENABLE_ALL)
539
0
    winpr_str_append("ENABLE_ALL", buffer, size, "|");
540
0
  if (flags & HTTP_TUNNEL_REDIR_DISABLE_ALL)
541
0
    winpr_str_append("DISABLE_ALL", buffer, size, "|");
542
0
  if (flags & HTTP_TUNNEL_REDIR_DISABLE_DRIVE)
543
0
    winpr_str_append("DISABLE_DRIVE", buffer, size, "|");
544
0
  if (flags & HTTP_TUNNEL_REDIR_DISABLE_PRINTER)
545
0
    winpr_str_append("DISABLE_PRINTER", buffer, size, "|");
546
0
  if (flags & HTTP_TUNNEL_REDIR_DISABLE_PORT)
547
0
    winpr_str_append("DISABLE_PORT", buffer, size, "|");
548
0
  if (flags & HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD)
549
0
    winpr_str_append("DISABLE_CLIPBOARD", buffer, size, "|");
550
0
  if (flags & HTTP_TUNNEL_REDIR_DISABLE_PNP)
551
0
    winpr_str_append("DISABLE_PNP", buffer, size, "|");
552
553
0
  char fbuffer[16] = WINPR_C_ARRAY_INIT;
554
0
  (void)_snprintf(fbuffer, sizeof(fbuffer), "[0x%08" PRIx32 "]", flags);
555
556
0
  winpr_str_append(fbuffer, buffer, size, " ");
557
0
  winpr_str_append("{", buffer, size, "}");
558
0
  return buffer;
559
0
}
560
561
BOOL utils_reload_channels(rdpContext* context)
562
0
{
563
0
  WINPR_ASSERT(context);
564
565
0
  if (context->channels)
566
0
  {
567
0
    freerdp_channels_disconnect(context->channels, context->instance);
568
0
    freerdp_channels_close(context->channels, context->instance);
569
0
    freerdp_channels_free(context->channels);
570
0
  }
571
572
0
  context->channels = freerdp_channels_new(context->instance);
573
0
  if (!context->channels)
574
0
    return FALSE;
575
576
0
  freerdp_channels_register_instance(context->channels, context->instance);
577
578
0
  BOOL rc = TRUE;
579
0
  IFCALLRET(context->instance->LoadChannels, rc, context->instance);
580
0
  if (rc)
581
0
    return freerdp_channels_pre_connect(context->channels, context->instance) == CHANNEL_RC_OK;
582
0
  return rc;
583
0
}
584
585
const char* guid2str(const GUID* guid, char* buffer, size_t len)
586
65.9k
{
587
65.9k
  if (!guid)
588
0
    return nullptr;
589
65.9k
  RPC_CSTR strguid = nullptr;
590
591
65.9k
  RPC_STATUS rpcStatus = UuidToStringA(guid, &strguid);
592
593
65.9k
  if (rpcStatus != RPC_S_OK)
594
0
    return nullptr;
595
596
65.9k
  (void)sprintf_s(buffer, len, "%s", strguid);
597
65.9k
  RpcStringFreeA(&strguid);
598
65.9k
  return buffer;
599
65.9k
}
600
601
static BOOL isValidIPv4(const char* ipAddress)
602
7
{
603
7
  struct sockaddr_in sa = WINPR_C_ARRAY_INIT;
604
7
  int result = inet_pton(AF_INET, ipAddress, &(sa.sin_addr));
605
7
  return result != 0;
606
7
}
607
608
static BOOL isValidIPv6(const char* ipAddress)
609
7
{
610
7
  struct sockaddr_in6 sa = WINPR_C_ARRAY_INIT;
611
7
  int result = inet_pton(AF_INET6, ipAddress, &(sa.sin6_addr));
612
7
  return result != 0;
613
7
}
614
615
BOOL utils_is_valid_ip(const char* ipAddress)
616
7
{
617
7
  return isValidIPv4(ipAddress) || isValidIPv6(ipAddress);
618
7
}