24 #include <winpr/crypto.h>
25 #include <winpr/print.h>
27 #include <freerdp/server/proxy/proxy_log.h>
28 #include <freerdp/server/proxy/proxy_server.h>
29 #include <freerdp/channels/drdynvc.h>
31 #include "pf_client.h"
33 #include "proxy_modules.h"
35 #include <freerdp/server/proxy/proxy_context.h>
37 #include "channels/pf_channel_rdpdr.h"
39 #define TAG PROXY_TAG("server")
41 static UINT32 ChannelId_Hash(
const void* key)
43 const UINT32* v = (
const UINT32*)key;
47 static BOOL ChannelId_Compare(
const void* pv1,
const void* pv2)
49 const UINT32* v1 = pv1;
50 const UINT32* v2 = pv2;
56 static BOOL dyn_intercept(pServerContext* ps,
const char* name)
58 if (strncmp(DRDYNVC_SVC_CHANNEL_NAME, name,
sizeof(DRDYNVC_SVC_CHANNEL_NAME)) != 0)
62 WINPR_ASSERT(ps->pdata);
64 const proxyConfig* cfg = ps->pdata->config;
68 if (!cfg->AudioOutput)
74 if (!cfg->VideoRedirection)
76 if (!cfg->CameraRedirection)
81 pServerStaticChannelContext* StaticChannelContext_new(pServerContext* ps,
const char* name,
84 pServerStaticChannelContext* ret = calloc(1,
sizeof(*ret));
87 PROXY_LOG_ERR(TAG, ps,
"error allocating channel context for '%s'", name);
91 ret->front_channel_id = id;
92 ret->channel_name = _strdup(name);
93 if (!ret->channel_name)
95 PROXY_LOG_ERR(TAG, ps,
"error allocating name in channel context for '%s'", name);
102 if (pf_modules_run_filter(ps->pdata->module, FILTER_TYPE_STATIC_INTERCEPT_LIST, ps->pdata,
105 ret->channelMode = PF_UTILS_CHANNEL_INTERCEPT;
106 else if (dyn_intercept(ps, name))
107 ret->channelMode = PF_UTILS_CHANNEL_INTERCEPT;
109 ret->channelMode = pf_utils_get_channel_mode(ps->pdata->config, name);
113 void StaticChannelContext_free(pServerStaticChannelContext* ctx)
118 IFCALL(ctx->contextDtor, ctx->context);
120 free(ctx->channel_name);
124 static void HashStaticChannelContext_free(
void* ptr)
126 pServerStaticChannelContext* ctx = (pServerStaticChannelContext*)ptr;
127 StaticChannelContext_free(ctx);
131 static void client_to_proxy_context_free(freerdp_peer* client, rdpContext* ctx);
132 static BOOL client_to_proxy_context_new(freerdp_peer* client, rdpContext* ctx)
135 pServerContext* context = (pServerContext*)ctx;
137 WINPR_ASSERT(client);
138 WINPR_ASSERT(context);
140 context->dynvcReady = NULL;
142 context->vcm = WTSOpenServerA((LPSTR)client->context);
144 if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE)
147 if (!(context->dynvcReady = CreateEvent(NULL, TRUE, FALSE, NULL)))
150 context->interceptContextMap = HashTable_New(FALSE);
151 if (!context->interceptContextMap)
153 if (!HashTable_SetupForStringData(context->interceptContextMap, FALSE))
155 obj = HashTable_ValueObject(context->interceptContextMap);
157 obj->fnObjectFree = intercept_context_entry_free;
160 context->channelsByFrontId = HashTable_New(FALSE);
161 if (!context->channelsByFrontId)
163 if (!HashTable_SetHashFunction(context->channelsByFrontId, ChannelId_Hash))
166 obj = HashTable_KeyObject(context->channelsByFrontId);
167 obj->fnObjectEquals = ChannelId_Compare;
169 obj = HashTable_ValueObject(context->channelsByFrontId);
170 obj->fnObjectFree = HashStaticChannelContext_free;
172 context->channelsByBackId = HashTable_New(FALSE);
173 if (!context->channelsByBackId)
175 if (!HashTable_SetHashFunction(context->channelsByBackId, ChannelId_Hash))
178 obj = HashTable_KeyObject(context->channelsByBackId);
179 obj->fnObjectEquals = ChannelId_Compare;
184 client_to_proxy_context_free(client, ctx);
190 void client_to_proxy_context_free(freerdp_peer* client, rdpContext* ctx)
192 pServerContext* context = (pServerContext*)ctx;
194 WINPR_UNUSED(client);
199 if (context->dynvcReady)
201 (void)CloseHandle(context->dynvcReady);
202 context->dynvcReady = NULL;
205 HashTable_Free(context->interceptContextMap);
206 HashTable_Free(context->channelsByFrontId);
207 HashTable_Free(context->channelsByBackId);
209 if (context->vcm && (context->vcm != INVALID_HANDLE_VALUE))
210 WTSCloseServer(context->vcm);
214 BOOL pf_context_init_server_context(freerdp_peer* client)
216 WINPR_ASSERT(client);
218 client->ContextSize =
sizeof(pServerContext);
219 client->ContextNew = client_to_proxy_context_new;
220 client->ContextFree = client_to_proxy_context_free;
222 return freerdp_peer_context_new(client);
225 static BOOL pf_context_revert_str_settings(rdpSettings* dst,
const rdpSettings* before,
size_t nr,
226 const FreeRDP_Settings_Keys_String* ids)
229 WINPR_ASSERT(before);
230 WINPR_ASSERT(ids || (nr == 0));
232 for (
size_t x = 0; x < nr; x++)
234 FreeRDP_Settings_Keys_String
id = ids[x];
243 void intercept_context_entry_free(
void* obj)
253 BOOL pf_context_copy_settings(rdpSettings* dst,
const rdpSettings* src)
256 rdpSettings* before_copy = NULL;
257 const FreeRDP_Settings_Keys_String to_revert[] = { FreeRDP_ConfigPath,
258 FreeRDP_CertificateName };
275 if (!pf_context_revert_str_settings(dst, before_copy, ARRAYSIZE(to_revert), to_revert))
301 pClientContext* pf_context_create_client_context(
const rdpSettings* clientSettings)
303 RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
304 pClientContext* pc = NULL;
305 rdpContext* context = NULL;
307 WINPR_ASSERT(clientSettings);
309 RdpClientEntry(&clientEntryPoints);
310 context = freerdp_client_context_new(&clientEntryPoints);
315 pc = (pClientContext*)context;
317 if (!pf_context_copy_settings(context->settings, clientSettings))
322 freerdp_client_context_free(context);
326 proxyData* proxy_data_new(
void)
330 proxyData* pdata = NULL;
332 pdata = calloc(1,
sizeof(proxyData));
336 if (!(pdata->abort_event = CreateEvent(NULL, TRUE, FALSE, NULL)))
339 if (!(pdata->gfx_server_ready = CreateEvent(NULL, TRUE, FALSE, NULL)))
342 winpr_RAND(&temp, 16);
343 hex = winpr_BinToHexString(temp, 16, FALSE);
347 CopyMemory(pdata->session_id, hex, PROXY_SESSION_ID_LENGTH);
348 pdata->session_id[PROXY_SESSION_ID_LENGTH] =
'\0';
351 if (!(pdata->modules_info = HashTable_New(FALSE)))
355 if (!HashTable_SetupForStringData(pdata->modules_info, FALSE))
360 WINPR_PRAGMA_DIAG_PUSH
361 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
362 proxy_data_free(pdata);
363 WINPR_PRAGMA_DIAG_POP
368 void proxy_data_set_client_context(proxyData* pdata, pClientContext* context)
371 WINPR_ASSERT(context);
373 context->pdata = pdata;
377 void proxy_data_set_server_context(proxyData* pdata, pServerContext* context)
380 WINPR_ASSERT(context);
382 context->pdata = pdata;
385 void proxy_data_free(proxyData* pdata)
390 if (pdata->abort_event)
391 (void)CloseHandle(pdata->abort_event);
393 if (pdata->client_thread)
394 (void)CloseHandle(pdata->client_thread);
396 if (pdata->gfx_server_ready)
397 (void)CloseHandle(pdata->gfx_server_ready);
399 if (pdata->modules_info)
400 HashTable_Free(pdata->modules_info);
403 freerdp_client_context_free(&pdata->pc->context);
408 void proxy_data_abort_connect(proxyData* pdata)
411 WINPR_ASSERT(pdata->abort_event);
412 (void)SetEvent(pdata->abort_event);
414 freerdp_abort_connect_context(&pdata->pc->context);
417 BOOL proxy_data_shall_disconnect(proxyData* pdata)
420 WINPR_ASSERT(pdata->abort_event);
421 return WaitForSingleObject(pdata->abort_event, 0) == WAIT_OBJECT_0;
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param)
Sets a string settings value. The param is copied.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
FREERDP_API BOOL freerdp_settings_set_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
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
FREERDP_API void freerdp_settings_free(rdpSettings *settings)
Free a settings struct with all data in it.
FREERDP_API BOOL freerdp_settings_copy(rdpSettings *dst, const rdpSettings *src)
Deep copies settings from src to dst.
FREERDP_API rdpSettings * freerdp_settings_clone(const rdpSettings *settings)
Creates a deep copy of settings.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.
This struct contains function pointer to initialize/free objects.