From 8a75e8f54e6fba3e0592a19c2275d4cc96fe9ec6 Mon Sep 17 00:00:00 2001 From: kubistika Date: Sun, 8 Sep 2019 18:10:50 +0300 Subject: [PATCH] server: proxy: refactor --- server/proxy/modules/demo/demo.c | 1 - server/proxy/pf_client.c | 135 +++++++++++++++++++++------------------ server/proxy/pf_context.c | 24 +++++-- server/proxy/pf_context.h | 15 ++--- server/proxy/pf_server.c | 27 +++----- 5 files changed, 107 insertions(+), 95 deletions(-) diff --git a/server/proxy/modules/demo/demo.c b/server/proxy/modules/demo/demo.c index 4a147a5..1219235 100644 --- a/server/proxy/modules/demo/demo.c +++ b/server/proxy/modules/demo/demo.c @@ -35,7 +35,6 @@ static BOOL demo_filter_mouse_event(moduleOperations* module, rdpContext* contex if (event_data->x % 100 == 0) { - module->AbortConnect(module, context); printf("filter_demo: mouse x is currently %"PRIu16"\n", event_data->x); } diff --git a/server/proxy/pf_client.c b/server/proxy/pf_client.c index 05be671..c82da67 100644 --- a/server/proxy/pf_client.c +++ b/server/proxy/pf_client.c @@ -53,16 +53,13 @@ #define TAG PROXY_TAG("client") -/** - * Re-negotiate with original client after negotiation between the proxy - * and the target has finished. - */ static BOOL proxy_server_reactivate(rdpContext* ps, const rdpContext* pc) { if (!pf_context_copy_settings(ps->settings, pc->settings)) return FALSE; - /* DesktopResize causes internal function rdp_server_reactivate to be called, + /* + * DesktopResize causes internal function rdp_server_reactivate to be called, * which causes the reactivation. */ if (!ps->update->DesktopResize(ps)) @@ -74,17 +71,17 @@ static BOOL proxy_server_reactivate(rdpContext* ps, const rdpContext* pc) static void pf_OnErrorInfo(void* ctx, ErrorInfoEventArgs* e) { pClientContext* pc = (pClientContext*) ctx; - proxyData* pdata = pc->pdata; - rdpContext* ps = (rdpContext*)pdata->ps; + pServerContext* ps = pc->pdata->ps; - if (e->code != ERRINFO_NONE) - { - const char* errorMessage = freerdp_get_error_info_string(e->code); - WLog_WARN(TAG, "Proxy's client received error info pdu from server: (0x%08"PRIu32"): %s", e->code, errorMessage); - /* forward error back to client */ - freerdp_set_error_info(ps->rdp, e->code); - freerdp_send_error_info(ps->rdp); - } + if (e->code == ERRINFO_NONE) + return; + + WLog_WARN(TAG, "received error info code: 0x%08"PRIu32", msg: %s", e->code, + freerdp_get_error_info_string(e->code)); + + /* forward error back to client */ + freerdp_set_error_info(ps->context.rdp, e->code); + freerdp_send_error_info(ps->context.rdp); } static BOOL pf_client_load_rdpsnd(pClientContext* pc, proxyConfig* config) @@ -130,22 +127,28 @@ static BOOL pf_client_pre_connect(freerdp* instance) * as the client's settings are copied from the server's, GlyphSupportLevel might not be * GLYPH_SUPPORT_NONE. the proxy currently do not support GDI & GLYPH_SUPPORT_CACHE, so * GlyphCacheSupport must be explicitly set to GLYPH_SUPPORT_NONE. + * + * Also, OrderSupport need to be zeroed, because it is currently not supported. */ settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE; + ZeroMemory(instance->settings->OrderSupport, 32); settings->OsMajorType = OSMAJORTYPE_UNIX; settings->OsMinorType = OSMINORTYPE_NATIVE_XSERVER; - /** - * settings->OrderSupport is initialized at this point. - * Only override it if you plan to implement custom order - * callbacks or deactiveate certain features. - */ + settings->SupportDynamicChannels = TRUE; - /* currently not supporting GDI orders */ - ZeroMemory(instance->settings->OrderSupport, 32); + /* Multimon */ + settings->UseMultimon = TRUE; + + /* Sound */ + settings->AudioPlayback = FALSE; + settings->DeviceRedirection = TRUE; + + /* Display control */ + settings->SupportDisplayControl = config->DisplayControl; + settings->DynamicResolutionUpdate = config->DisplayControl; - /** * Register the channel listeners. * They are required to set up / tear down channels if they are loaded. @@ -224,6 +227,12 @@ static BOOL pf_client_post_connect(freerdp* instance) } pf_client_register_update_callbacks(update); + + /* + * after the connection fully established and settings were negotiated with target server, send + * a reactivation sequence to the client with the negotiated settings. This way, settings are + * synchorinized between proxy's peer and and remote target. + */ return proxy_server_reactivate(ps, context); } @@ -257,6 +266,44 @@ static void pf_client_post_disconnect(freerdp* instance) proxy_data_abort_connect(pdata); } +static BOOL pf_client_connect(freerdp* instance) +{ + pClientContext* pc = (pClientContext*) instance->context; + rdpSettings* settings = pc->context.settings; + + /* on first try, proxy client should always try to connect with NLA */ + settings->NlaSecurity = TRUE; + pc->during_connect_process = TRUE; + + if (!freerdp_connect(instance)) + { + if (settings->NlaSecurity) + { + WLog_ERR(TAG, "freerdp_connect() failed, trying to connect without NLA"); + + /* disable NLA, enable TLS */ + settings->NlaSecurity = FALSE; + settings->RdpSecurity = TRUE; + settings->TlsSecurity = TRUE; + + pc->during_connect_process = FALSE; + if (!freerdp_connect(instance)) + { + WLog_ERR(TAG, "connection failure"); + return FALSE; + } + } + else + { + WLog_ERR(TAG, "connection failure"); + return FALSE; + } + } + + pc->during_connect_process = FALSE; + return TRUE; +} + /** * RDP main loop. * Connects RDP, loops while running and handles event and dispatch, cleans up @@ -272,9 +319,6 @@ static DWORD WINAPI pf_client_thread_proc(LPVOID arg) DWORD status; HANDLE handles[65]; - if (!pf_modules_run_hook(HOOK_TYPE_CLIENT_PRE_CONNECT, (rdpContext*) ps)) - return FALSE; - /* * during redirection, freerdp's abort event might be overriden (reset) by the library, after * the server set it in order to shutdown the connection. it means that the server might signal @@ -284,42 +328,11 @@ static DWORD WINAPI pf_client_thread_proc(LPVOID arg) */ handles[64] = pdata->abort_event; - /* on first try, proxy client should always try to connect with NLA */ - instance->settings->NlaSecurity = TRUE; - - /* - * Only set the `during_connect_process` flag if NlaSecurity is enabled. - * If NLASecurity isn't enabled, the connection should be closed right after the first failure. - */ - if (instance->settings->NlaSecurity) - pc->during_connect_process = TRUE; - - if (!freerdp_connect(instance)) - { - if (instance->settings->NlaSecurity) - { - WLog_ERR(TAG, "freerdp_connect() failed, trying to connect without NLA"); - - /* disable NLA, enable TLS */ - instance->settings->NlaSecurity = FALSE; - instance->settings->RdpSecurity = TRUE; - instance->settings->TlsSecurity = TRUE; - - pc->during_connect_process = FALSE; - if (!freerdp_connect(instance)) - { - WLog_ERR(TAG, "connection failure"); - return 0; - } - } - else - { - WLog_ERR(TAG, "connection failure"); - return 0; - } - } + if (!pf_modules_run_hook(HOOK_TYPE_CLIENT_PRE_CONNECT, (rdpContext*) ps)) + return FALSE; - pc->during_connect_process = FALSE; + if (!pf_client_connect(instance)) + return FALSE; while (!freerdp_shall_disconnect(instance)) { diff --git a/server/proxy/pf_context.c b/server/proxy/pf_context.c index 48e4c09..62b859c 100644 --- a/server/proxy/pf_context.c +++ b/server/proxy/pf_context.c @@ -26,6 +26,9 @@ static BOOL client_to_proxy_context_new(freerdp_peer* client, pServerContext* context) { + context->dynvcReady = NULL; + context->modules_info = NULL; + context->modules_info = HashTable_New(TRUE); if (!context->modules_info) return FALSE; @@ -33,12 +36,24 @@ static BOOL client_to_proxy_context_new(freerdp_peer* client, context->vcm = WTSOpenServerA((LPSTR) client->context); if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE) - goto fail_open_server; + goto error; + + if (!(context->dynvcReady = CreateEvent(NULL, TRUE, FALSE, NULL))) + goto error; return TRUE; -fail_open_server: + +error: HashTable_Free(context->modules_info); + WTSCloseServer((HANDLE)context->vcm); context->vcm = NULL; + + if (context->dynvcReady) + { + CloseHandle(context->dynvcReady); + context->dynvcReady = NULL; + } + return FALSE; } @@ -62,11 +77,12 @@ static void client_to_proxy_context_free(freerdp_peer* client, HashTable_Free(context->modules_info); } -BOOL init_p_server_context(freerdp_peer* client) +BOOL pf_context_init_server_context(freerdp_peer* client) { client->ContextSize = sizeof(pServerContext); client->ContextNew = (psPeerContextNew) client_to_proxy_context_new; client->ContextFree = (psPeerContextFree) client_to_proxy_context_free; + return freerdp_peer_context_new(client); } @@ -122,7 +138,7 @@ BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src) return TRUE; } -rdpContext* p_client_context_create(rdpSettings* clientSettings) +rdpContext* pf_context_create_client_context(rdpSettings* clientSettings) { RDP_CLIENT_ENTRY_POINTS clientEntryPoints; rdpContext* context; diff --git a/server/proxy/pf_context.h b/server/proxy/pf_context.h index ffce870..defe1d5 100644 --- a/server/proxy/pf_context.h +++ b/server/proxy/pf_context.h @@ -34,7 +34,6 @@ #include "pf_config.h" #include "pf_server.h" -#include "pf_modules.h" typedef struct proxy_data proxyData; @@ -43,7 +42,7 @@ typedef struct proxy_data proxyData; */ struct p_server_context { - rdpContext _context; + rdpContext context; proxyData* pdata; @@ -65,7 +64,7 @@ typedef struct p_server_context pServerContext; */ struct p_client_context { - rdpContext _context; + rdpContext context; proxyData* pdata; @@ -100,18 +99,14 @@ struct proxy_data HANDLE client_thread; }; -/* client */ -rdpContext* p_client_context_create(rdpSettings* clientSettings); +BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src); +BOOL pf_context_init_server_context(freerdp_peer* client); +rdpContext* pf_context_create_client_context(rdpSettings* clientSettings); -/* pdata */ proxyData* proxy_data_new(void); void proxy_data_free(proxyData* pdata); -BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src); BOOL proxy_data_shall_disconnect(proxyData* pdata); void proxy_data_abort_connect(proxyData* pdata); -/* server */ -BOOL init_p_server_context(freerdp_peer* client); - #endif /* FREERDP_SERVER_PROXY_PFCONTEXT_H */ diff --git a/server/proxy/pf_server.c b/server/proxy/pf_server.c index fd5b3f1..d5080b5 100644 --- a/server/proxy/pf_server.c +++ b/server/proxy/pf_server.c @@ -143,10 +143,10 @@ static BOOL pf_server_post_connect(freerdp_peer* client) ps = (pServerContext*)client->context; pdata = ps->pdata; - pc = p_client_context_create(client->settings); + pc = pf_context_create_client_context(client->settings); if (pc == NULL) { - WLog_ERR(TAG, "pf_server_post_connect(): p_client_context_create failed!"); + WLog_ERR(TAG, "pf_server_post_connect(): pf_context_create_client_context failed!"); return FALSE; } @@ -209,15 +209,10 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg) proxyConfig* config; freerdp_peer* client = (freerdp_peer*)arg; - if (!init_p_server_context(client)) + if (!pf_context_init_server_context(client)) goto out_free_peer; ps = (pServerContext*)client->context; - if (!(ps->dynvcReady = CreateEvent(NULL, TRUE, FALSE, NULL))) - { - WLog_ERR(TAG, "pf_server_post_connect(): CreateEvent failed!"); - goto out_free_peer; - } if (!(pdata = ps->pdata = proxy_data_new())) { @@ -225,18 +220,15 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg) goto out_free_peer; } + pdata->ps = ps; + config = pdata->config = client->ContextExtra; + /* currently not supporting GDI orders */ ZeroMemory(client->settings->OrderSupport, 32); client->update->autoCalculateBitmapData = FALSE; - pdata->ps = ps; - /* keep configuration in proxyData */ - pdata->config = client->ContextExtra; - config = pdata->config; - client->settings->UseMultimon = TRUE; - client->settings->AudioPlayback = FALSE; - client->settings->DeviceRedirection = TRUE; + + client->settings->SupportMonitorLayoutPdu = TRUE; client->settings->SupportGraphicsPipeline = config->GFX; - client->settings->SupportDynamicChannels = TRUE; client->settings->CertificateFile = _strdup("server.crt"); client->settings->PrivateKeyFile = _strdup("server.key"); client->settings->RdpKeyFile = _strdup("server.key"); @@ -248,9 +240,6 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg) goto out_free_peer; } - client->settings->SupportDisplayControl = config->DisplayControl; - client->settings->DynamicResolutionUpdate = config->DisplayControl; - client->settings->SupportMonitorLayoutPdu = TRUE; client->settings->RdpSecurity = config->RdpSecurity; client->settings->TlsSecurity = config->TlsSecurity; client->settings->NlaSecurity = config->NlaSecurity; -- 2.7.4