summaryrefslogtreecommitdiffstats
path: root/include/freerdp/server/proxy
diff options
context:
space:
mode:
Diffstat (limited to 'include/freerdp/server/proxy')
-rw-r--r--include/freerdp/server/proxy/proxy_config.h235
-rw-r--r--include/freerdp/server/proxy/proxy_context.h186
-rw-r--r--include/freerdp/server/proxy/proxy_log.h53
-rw-r--r--include/freerdp/server/proxy/proxy_modules_api.h241
-rw-r--r--include/freerdp/server/proxy/proxy_server.h115
-rw-r--r--include/freerdp/server/proxy/proxy_types.h57
6 files changed, 887 insertions, 0 deletions
diff --git a/include/freerdp/server/proxy/proxy_config.h b/include/freerdp/server/proxy/proxy_config.h
new file mode 100644
index 0000000..237fdf3
--- /dev/null
+++ b/include/freerdp/server/proxy/proxy_config.h
@@ -0,0 +1,235 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Proxy Server
+ *
+ * Copyright 2021-2023 Armin Novak <armin.novak@thincast.com>
+ * Copyright 2021-2023 Thincast Technologies GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef FREERDP_SERVER_PROXY_CONFIG_H
+#define FREERDP_SERVER_PROXY_CONFIG_H
+
+#include <winpr/wtypes.h>
+#include <winpr/ini.h>
+
+#include <freerdp/api.h>
+#include <freerdp/server/proxy/proxy_modules_api.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ typedef struct proxy_config proxyConfig;
+
+ struct proxy_config
+ {
+ /* server */
+ char* Host;
+ UINT16 Port;
+
+ /* target */
+ BOOL FixedTarget;
+ char* TargetHost;
+ UINT16 TargetPort;
+ char* TargetUser;
+ char* TargetDomain;
+ char* TargetPassword;
+
+ /* input */
+ BOOL Keyboard;
+ BOOL Mouse;
+ BOOL Multitouch;
+
+ /* server security */
+ BOOL ServerTlsSecurity;
+ BOOL ServerRdpSecurity;
+ BOOL ServerNlaSecurity;
+
+ /* client security */
+ BOOL ClientNlaSecurity;
+ BOOL ClientTlsSecurity;
+ BOOL ClientRdpSecurity;
+ BOOL ClientAllowFallbackToTls;
+
+ /* channels */
+ BOOL GFX;
+ BOOL DisplayControl;
+ BOOL Clipboard;
+ BOOL AudioOutput;
+ BOOL AudioInput;
+ BOOL RemoteApp;
+ BOOL DeviceRedirection;
+ BOOL VideoRedirection;
+ BOOL CameraRedirection;
+
+ BOOL PassthroughIsBlacklist;
+ char** Passthrough;
+ size_t PassthroughCount;
+ char** Intercept;
+ size_t InterceptCount;
+
+ /* clipboard specific settings */
+ BOOL TextOnly;
+ UINT32 MaxTextLength;
+
+ /* gfx settings */
+ BOOL DecodeGFX;
+
+ /* modules */
+ char** Modules; /* module file names to load */
+ size_t ModulesCount;
+
+ char** RequiredPlugins; /* required plugin names */
+ size_t RequiredPluginsCount;
+
+ char* CertificateFile;
+ char* CertificateContent;
+
+ char* PrivateKeyFile;
+ char* PrivateKeyContent;
+
+ /* Data extracted from CertificateContent or CertificateFile (evaluation in this order) */
+ char* CertificatePEM;
+ size_t CertificatePEMLength;
+
+ /* Data extracted from PrivateKeyContent or PrivateKeyFile (evaluation in this order) */
+ char* PrivateKeyPEM;
+ size_t PrivateKeyPEMLength;
+
+ wIniFile* ini;
+
+ /* target continued */
+ UINT32 TargetTlsSecLevel;
+ };
+
+ /**
+ * @brief pf_server_config_dump Dumps a default INI configuration file
+ * @param file The file to write to. Existing files are truncated.
+ * @return TRUE for success, FALSE if the file could not be written.
+ */
+ FREERDP_API BOOL pf_server_config_dump(const char* file);
+
+ /**
+ * @brief server_config_load_ini Create a proxyConfig from a already loaded
+ * INI file.
+ *
+ * @param ini A pointer to the parsed INI file. Must NOT be NULL.
+ *
+ * @return A proxyConfig or NULL in case of failure.
+ */
+ FREERDP_API proxyConfig* server_config_load_ini(wIniFile* ini);
+ /**
+ * @brief pf_server_config_load_file Create a proxyConfig from a INI file found at path.
+ *
+ * @param path The path of the INI file
+ *
+ * @return A proxyConfig or NULL in case of failure.
+ */
+ FREERDP_API proxyConfig* pf_server_config_load_file(const char* path);
+
+ /**
+ * @brief pf_server_config_load_buffer Create a proxyConfig from a memory string buffer in INI
+ * file format
+ *
+ * @param buffer A pointer to the '\0' terminated INI string.
+ *
+ * @return A proxyConfig or NULL in case of failure.
+ */
+ FREERDP_API proxyConfig* pf_server_config_load_buffer(const char* buffer);
+
+ /**
+ * @brief pf_server_config_print Print the configuration to stdout
+ *
+ * @param config A pointer to the configuration to print. Must NOT be NULL.
+ */
+ FREERDP_API void pf_server_config_print(const proxyConfig* config);
+
+ /**
+ * @brief pf_server_config_free Releases all resources associated with proxyConfig
+ *
+ * @param config A pointer to the proxyConfig to clean up. Might be NULL.
+ */
+ FREERDP_API void pf_server_config_free(proxyConfig* config);
+
+ /**
+ * @brief pf_config_required_plugins_count
+ *
+ * @param config A pointer to the proxyConfig. Must NOT be NULL.
+ *
+ * @return The number of required plugins configured.
+ */
+ FREERDP_API size_t pf_config_required_plugins_count(const proxyConfig* config);
+
+ /**
+ * @brief pf_config_required_plugin
+ * @param config A pointer to the proxyConfig. Must NOT be NULL.
+ * @param index The index of the plugin to return
+ *
+ * @return The name of the plugin or NULL.
+ */
+ FREERDP_API const char* pf_config_required_plugin(const proxyConfig* config, size_t index);
+
+ /**
+ * @brief pf_config_modules_count
+ *
+ * @param config A pointer to the proxyConfig. Must NOT be NULL.
+ *
+ * @return The number of proxy modules configured.
+ */
+ FREERDP_API size_t pf_config_modules_count(const proxyConfig* config);
+
+ /**
+ * @brief pf_config_modules
+ * @param config A pointer to the proxyConfig. Must NOT be NULL.
+ *
+ * @return An array of strings of size pf_config_modules_count with the module names.
+ */
+ FREERDP_API const char** pf_config_modules(const proxyConfig* config);
+
+ /**
+ * @brief pf_config_clone Create a copy of the configuration
+ * @param dst A pointer that receives the newly allocated copy
+ * @param config The source configuration to copy
+ *
+ * @return TRUE for success, FALSE otherwise
+ */
+ FREERDP_API BOOL pf_config_clone(proxyConfig** dst, const proxyConfig* config);
+
+ /**
+ * @brief pf_config_plugin Register a proxy plugin handling event filtering
+ * defined in the configuration.
+ *
+ * @param plugins_manager The plugin manager
+ * @param userdata A proxyConfig* to use as reference
+ *
+ * @return TRUE for success, FALSE for failure
+ */
+ FREERDP_API BOOL pf_config_plugin(proxyPluginsManager* plugins_manager, void* userdata);
+
+ /**
+ * @brief pf_config_get get a value for a section/key
+ * @param config A pointer to the proxyConfig. Must NOT be NULL.
+ * @param section The name of the section the key is in, must not be \b NULL
+ * @param key The name of the key to look for. Must not be \b NULL
+ *
+ * @return A pointer to the value for \b section/key or \b NULL if not found
+ */
+ FREERDP_API const char* pf_config_get(const proxyConfig* config, const char* section,
+ const char* key);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* FREERDP_SERVER_PROXY_CONFIG_H */
diff --git a/include/freerdp/server/proxy/proxy_context.h b/include/freerdp/server/proxy/proxy_context.h
new file mode 100644
index 0000000..0132c66
--- /dev/null
+++ b/include/freerdp/server/proxy/proxy_context.h
@@ -0,0 +1,186 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Proxy Server
+ *
+ * Copyright 2019 Mati Shabtay <matishabtay@gmail.com>
+ * Copyright 2019 Kobi Mizrachi <kmizrachi18@gmail.com>
+ * Copyright 2019 Idan Freiberg <speidy@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FREERDP_SERVER_PROXY_PFCONTEXT_H
+#define FREERDP_SERVER_PROXY_PFCONTEXT_H
+
+#include <freerdp/api.h>
+#include <freerdp/types.h>
+
+#include <freerdp/freerdp.h>
+#include <freerdp/channels/wtsvc.h>
+
+#include <freerdp/server/proxy/proxy_config.h>
+#include <freerdp/server/proxy/proxy_types.h>
+
+#define PROXY_SESSION_ID_LENGTH 32
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ typedef struct proxy_data proxyData;
+ typedef struct proxy_module proxyModule;
+ typedef struct p_server_static_channel_context pServerStaticChannelContext;
+
+ typedef struct s_InterceptContextMapEntry
+ {
+ void (*free)(struct s_InterceptContextMapEntry*);
+ } InterceptContextMapEntry;
+
+ /* All proxy interception channels derive from this base struct
+ * and set their cleanup function accordingly. */
+ FREERDP_API void intercept_context_entry_free(void* obj);
+ typedef PfChannelResult (*proxyChannelDataFn)(proxyData* pdata,
+ const pServerStaticChannelContext* channel,
+ const BYTE* xdata, size_t xsize, UINT32 flags,
+ size_t totalSizepServer);
+ typedef void (*proxyChannelContextDtor)(void* context);
+
+ /** @brief per channel configuration */
+ struct p_server_static_channel_context
+ {
+ char* channel_name;
+ UINT32 front_channel_id;
+ UINT32 back_channel_id;
+ pf_utils_channel_mode channelMode;
+ proxyChannelDataFn onFrontData;
+ proxyChannelDataFn onBackData;
+ proxyChannelContextDtor contextDtor;
+ void* context;
+ };
+
+ void StaticChannelContext_free(pServerStaticChannelContext* ctx);
+
+ /**
+ * Wraps rdpContext and holds the state for the proxy's server.
+ */
+ struct p_server_context
+ {
+ rdpContext context;
+
+ proxyData* pdata;
+
+ HANDLE vcm;
+ HANDLE dynvcReady;
+
+ wHashTable* interceptContextMap;
+ wHashTable* channelsByFrontId;
+ wHashTable* channelsByBackId;
+ };
+ typedef struct p_server_context pServerContext;
+
+ WINPR_ATTR_MALLOC(StaticChannelContext_free, 1)
+ pServerStaticChannelContext* StaticChannelContext_new(pServerContext* ps, const char* name,
+ UINT32 id);
+
+ /**
+ * Wraps rdpContext and holds the state for the proxy's client.
+ */
+ typedef struct p_client_context pClientContext;
+
+ struct p_client_context
+ {
+ rdpContext context;
+
+ proxyData* pdata;
+
+ /*
+ * In a case when freerdp_connect fails,
+ * Used for NLA fallback feature, to check if the server should close the connection.
+ * When it is set to TRUE, proxy's client knows it shouldn't signal the server thread to
+ * closed the connection when pf_client_post_disconnect is called, because it is trying to
+ * connect reconnect without NLA. It must be set to TRUE before the first try, and to FALSE
+ * after the connection fully established, to ensure graceful shutdown of the connection
+ * when it will be closed.
+ */
+ BOOL allow_next_conn_failure;
+
+ BOOL connected; /* Set after client post_connect. */
+
+ pReceiveChannelData client_receive_channel_data_original;
+ wQueue* cached_server_channel_data;
+ BOOL (*sendChannelData)(pClientContext* pc, const proxyChannelDataEventInfo* ev);
+
+ /* X509 specific */
+ char* remote_hostname;
+ wStream* remote_pem;
+ UINT16 remote_port;
+ UINT32 remote_flags;
+
+ BOOL input_state_sync_pending;
+ UINT32 input_state;
+
+ wHashTable* interceptContextMap;
+ UINT32 computerNameLen;
+ BOOL computerNameUnicode;
+ union
+ {
+ WCHAR* wc;
+ char* c;
+ void* v;
+ } computerName;
+ };
+
+ /**
+ * Holds data common to both sides of a proxy's session.
+ */
+ struct proxy_data
+ {
+ proxyModule* module;
+ const proxyConfig* config;
+
+ pServerContext* ps;
+ pClientContext* pc;
+
+ HANDLE abort_event;
+ HANDLE client_thread;
+ HANDLE gfx_server_ready;
+
+ char session_id[PROXY_SESSION_ID_LENGTH + 1];
+
+ /* used to external modules to store per-session info */
+ wHashTable* modules_info;
+ psPeerReceiveChannelData server_receive_channel_data_original;
+ };
+
+ FREERDP_API BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src);
+ FREERDP_API BOOL pf_context_init_server_context(freerdp_peer* client);
+
+ WINPR_ATTR_MALLOC(freerdp_client_context_free, 1)
+ FREERDP_API pClientContext* pf_context_create_client_context(const rdpSettings* clientSettings);
+
+ FREERDP_API void proxy_data_free(proxyData* pdata);
+
+ WINPR_ATTR_MALLOC(proxy_data_free, 1)
+ FREERDP_API proxyData* proxy_data_new(void);
+ FREERDP_API void proxy_data_set_client_context(proxyData* pdata, pClientContext* context);
+ FREERDP_API void proxy_data_set_server_context(proxyData* pdata, pServerContext* context);
+
+ FREERDP_API BOOL proxy_data_shall_disconnect(proxyData* pdata);
+ FREERDP_API void proxy_data_abort_connect(proxyData* pdata);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SERVER_PROXY_PFCONTEXT_H */
diff --git a/include/freerdp/server/proxy/proxy_log.h b/include/freerdp/server/proxy/proxy_log.h
new file mode 100644
index 0000000..3f3be2c
--- /dev/null
+++ b/include/freerdp/server/proxy/proxy_log.h
@@ -0,0 +1,53 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Proxy Server
+ *
+ * Copyright 2019 Mati Shabtay <matishabtay@gmail.com>
+ * Copyright 2019 Kobi Mizrachi <kmizrachi18@gmail.com>
+ * Copyright 2019 Idan Freiberg <speidy@gmail.com>
+ * Copyright 2021 Armin Novak <anovak@thincast.com>
+ * Copyright 2021 Thincast Technologies GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FREERDP_SERVER_PROXY_LOG_H
+#define FREERDP_SERVER_PROXY_LOG_H
+
+#include <winpr/wlog.h>
+#include <freerdp/log.h>
+
+#define PROXY_TAG(tag) FREERDP_TAG("proxy." tag)
+
+/*
+ * log format in proxy is:
+ * "[SessionID=%s]: Log message"
+ * SessionID is optional, but if they should be written to the log,
+ * that's the format.
+ */
+
+/* log macros that prepends session id and function name tp the log message */
+#define PROXY_LOG_INFO(_tag, _context, _format, ...) \
+ WLog_INFO(TAG, "[SessionID=%s]: " _format, \
+ (_context && _context->pdata) ? _context->pdata->session_id : "null", ##__VA_ARGS__)
+#define PROXY_LOG_ERR(_tag, _context, _format, ...) \
+ WLog_ERR(TAG, "[SessionID=%s]: " _format, \
+ (_context && _context->pdata) ? _context->pdata->session_id : "null", ##__VA_ARGS__)
+#define PROXY_LOG_DBG(_tag, _context, _format, ...) \
+ WLog_DBG(TAG, "[SessionID=%s]: " _format, \
+ (_context && _context->pdata) ? _context->pdata->session_id : "null", ##__VA_ARGS__)
+#define PROXY_LOG_WARN(_tag, _context, _format, ...) \
+ WLog_WARN(TAG, "[SessionID=%s]: " _format, \
+ (_context && _context->pdata) ? _context->pdata->session_id : "null", ##__VA_ARGS__)
+
+#endif /* FREERDP_SERVER_PROXY_LOG_H */
diff --git a/include/freerdp/server/proxy/proxy_modules_api.h b/include/freerdp/server/proxy/proxy_modules_api.h
new file mode 100644
index 0000000..1887f90
--- /dev/null
+++ b/include/freerdp/server/proxy/proxy_modules_api.h
@@ -0,0 +1,241 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Proxy Server
+ *
+ * Copyright 2019 Kobi Mizrachi <kmizrachi18@gmail.com>
+ * Copyright 2019 Idan Freiberg <speidy@gmail.com>
+ * Copyright 2021 Armin Novak <anovak@thincast.com>
+ * Copyright 2021 Thincast Technologies GmbH
+ * Copyright 2023 Armin Novak <anovak@thincast.com>
+ * Copyright 2023 Thincast Technologies GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FREERDP_SERVER_PROXY_MODULES_API_H
+#define FREERDP_SERVER_PROXY_MODULES_API_H
+
+#include <winpr/winpr.h>
+#include <winpr/stream.h>
+#include <winpr/sspi.h>
+
+#include <freerdp/server/proxy/proxy_types.h>
+
+#define MODULE_TAG(module) "proxy.modules." module
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ typedef struct proxy_data proxyData;
+ typedef struct proxy_module proxyModule;
+ typedef struct proxy_plugin proxyPlugin;
+ typedef struct proxy_plugins_manager proxyPluginsManager;
+
+ /* hook callback. should return TRUE on success or FALSE on error. */
+ typedef BOOL (*proxyHookFn)(proxyPlugin*, proxyData*, void*);
+
+ /*
+ * Filter callback:
+ * It MUST return TRUE if the related event should be proxied,
+ * or FALSE if it should be ignored.
+ */
+ typedef BOOL (*proxyFilterFn)(proxyPlugin*, proxyData*, void*);
+
+ /* describes a plugin: name, description and callbacks to execute.
+ *
+ * This is public API, so always add new fields at the end of the struct to keep
+ * some backward compatibility.
+ */
+ struct proxy_plugin
+ {
+ const char* name; /* 0: unique module name */
+ const char* description; /* 1: module description */
+
+ UINT64 reserved1[32 - 2]; /* 2-32 */
+
+ BOOL (*PluginUnload)(proxyPlugin* plugin); /* 33 */
+ UINT64 reserved2[66 - 34]; /* 34 - 65 */
+
+ /* proxy hooks. a module can set these function pointers to register hooks */
+ proxyHookFn ClientInitConnect; /* 66 custom=rdpContext* */
+ proxyHookFn ClientUninitConnect; /* 67 custom=rdpContext* */
+ proxyHookFn ClientPreConnect; /* 68 custom=rdpContext* */
+ proxyHookFn ClientPostConnect; /* 69 custom=rdpContext* */
+ proxyHookFn ClientPostDisconnect; /* 70 custom=rdpContext* */
+ proxyHookFn ClientX509Certificate; /* 71 custom=rdpContext* */
+ proxyHookFn ClientLoginFailure; /* 72 custom=rdpContext* */
+ proxyHookFn ClientEndPaint; /* 73 custom=rdpContext* */
+ proxyHookFn ClientRedirect; /* 74 custom=rdpContext* */
+ proxyHookFn ClientLoadChannels; /* 75 custom=rdpContext* */
+ UINT64 reserved3[96 - 76]; /* 76-95 */
+
+ proxyHookFn ServerPostConnect; /* 96 custom=freerdp_peer* */
+ proxyHookFn ServerPeerActivate; /* 97 custom=freerdp_peer* */
+ proxyHookFn ServerChannelsInit; /* 98 custom=freerdp_peer* */
+ proxyHookFn ServerChannelsFree; /* 99 custom=freerdp_peer* */
+ proxyHookFn ServerSessionEnd; /* 100 custom=freerdp_peer* */
+ proxyHookFn ServerSessionInitialize; /* 101 custom=freerdp_peer* */
+ proxyHookFn ServerSessionStarted; /* 102 custom=freerdp_peer* */
+
+ UINT64 reserved4[128 - 103]; /* 103 - 127 */
+
+ /* proxy filters. a module can set these function pointers to register filters */
+ proxyFilterFn KeyboardEvent; /* 128 */
+ proxyFilterFn MouseEvent; /* 129 */
+ proxyFilterFn ClientChannelData; /* 130 passthrough channels data */
+ proxyFilterFn ServerChannelData; /* 131 passthrough channels data */
+ proxyFilterFn DynamicChannelCreate; /* 132 passthrough drdynvc channel create data */
+ proxyFilterFn ServerFetchTargetAddr; /* 133 */
+ proxyFilterFn ServerPeerLogon; /* 134 */
+ proxyFilterFn ChannelCreate; /* 135 passthrough drdynvc channel create data */
+ proxyFilterFn UnicodeEvent; /* 136 */
+ proxyFilterFn MouseExEvent; /* 137 */
+
+ /* proxy dynamic channel filters:
+ *
+ * - a function that returns the list of channels to intercept
+ * - a function to call with the data received
+ */
+ proxyFilterFn DynChannelToIntercept; /* 138 */
+ proxyFilterFn DynChannelIntercept; /* 139 */
+ proxyFilterFn StaticChannelToIntercept; /* 140 */
+ UINT64 reserved5[160 - 141]; /* 141-159 */
+
+ /* Runtime data fields */
+ proxyPluginsManager* mgr; /* 160 */ /** Set during plugin registration */
+ void* userdata; /* 161 */ /** Custom data provided with RegisterPlugin, memory managed
+ outside of plugin. */
+ void* custom; /* 162 */ /** Custom configuration data, must be allocated in RegisterPlugin
+ and freed in PluginUnload */
+
+ UINT64 reserved6[192 - 163]; /* 163-191 Add some filler data to allow for new callbacks or
+ * fields without breaking API */
+ };
+
+ /*
+ * Main API for use by external modules.
+ * Supports:
+ * - Registering a plugin.
+ * - Setting/getting plugin's per-session specific data.
+ * - Aborting a session.
+ */
+ struct proxy_plugins_manager
+ {
+ /* 0 used for registering a fresh new proxy plugin. */
+ BOOL (*RegisterPlugin)(struct proxy_plugins_manager* mgr, const proxyPlugin* plugin);
+
+ /* 1 used for setting plugin's per-session info. */
+ BOOL (*SetPluginData)(struct proxy_plugins_manager* mgr, const char*, proxyData*, void*);
+
+ /* 2 used for getting plugin's per-session info. */
+ void* (*GetPluginData)(struct proxy_plugins_manager* mgr, const char*, proxyData*);
+
+ /* 3 used for aborting a session. */
+ void (*AbortConnect)(struct proxy_plugins_manager* mgr, proxyData*);
+
+ UINT64 reserved[128 - 4]; /* 4-127 reserved fields */
+ };
+
+ typedef BOOL (*proxyModuleEntryPoint)(proxyPluginsManager* plugins_manager, void* userdata);
+
+/* filter events parameters */
+#define WINPR_PACK_PUSH
+#include <winpr/pack.h>
+typedef struct proxy_keyboard_event_info
+{
+ UINT16 flags;
+ UINT16 rdp_scan_code;
+} proxyKeyboardEventInfo;
+
+typedef struct proxy_unicode_event_info
+{
+ UINT16 flags;
+ UINT16 code;
+} proxyUnicodeEventInfo;
+
+typedef struct proxy_mouse_event_info
+{
+ UINT16 flags;
+ UINT16 x;
+ UINT16 y;
+} proxyMouseEventInfo;
+
+typedef struct proxy_mouse_ex_event_info
+{
+ UINT16 flags;
+ UINT16 x;
+ UINT16 y;
+} proxyMouseExEventInfo;
+
+typedef struct
+{
+ /* channel metadata */
+ const char* channel_name;
+ UINT16 channel_id;
+
+ /* actual data */
+ const BYTE* data;
+ size_t data_len;
+ size_t total_size;
+ UINT32 flags;
+} proxyChannelDataEventInfo;
+
+typedef struct
+{
+ /* out values */
+ char* target_address;
+ UINT16 target_port;
+
+ /*
+ * If this value is set to true by a plugin, target info will be fetched from config and proxy
+ * will connect any client to the same remote server.
+ */
+ ProxyFetchTargetMethod fetch_method;
+} proxyFetchTargetEventInfo;
+
+typedef struct server_peer_logon
+{
+ const SEC_WINNT_AUTH_IDENTITY* identity;
+ BOOL automatic;
+} proxyServerPeerLogon;
+
+typedef struct dyn_channel_intercept_data
+{
+ const char* name;
+ UINT32 channelId;
+ wStream* data;
+ BOOL isBackData;
+ BOOL first;
+ BOOL last;
+ BOOL rewritten;
+ size_t packetSize;
+ PfChannelResult result;
+} proxyDynChannelInterceptData;
+
+typedef struct dyn_channel_to_intercept_data
+{
+ const char* name;
+ UINT32 channelId;
+ BOOL intercept;
+} proxyChannelToInterceptData;
+
+#define WINPR_PACK_POP
+#include <winpr/pack.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SERVER_PROXY_MODULES_API_H */
diff --git a/include/freerdp/server/proxy/proxy_server.h b/include/freerdp/server/proxy/proxy_server.h
new file mode 100644
index 0000000..39e738f
--- /dev/null
+++ b/include/freerdp/server/proxy/proxy_server.h
@@ -0,0 +1,115 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Proxy Server
+ *
+ * Copyright 2021 Armin Novak <armin.novak@thincast.com>
+ * Copyright 2021 Thincast Technologies GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef FREERDP_SERVER_PROXY_SERVER_H
+#define FREERDP_SERVER_PROXY_SERVER_H
+
+#include <freerdp/api.h>
+#include <freerdp/server/proxy/proxy_config.h>
+#include <freerdp/server/proxy/proxy_modules_api.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ typedef struct proxy_server proxyServer;
+
+ /**
+ * @brief pf_server_free Cleans up a (stopped) proxy server instance.
+ *
+ * @param server The proxy server to clean up. Might be NULL.
+ */
+ FREERDP_API void pf_server_free(proxyServer* server);
+
+ /**
+ * @brief pf_server_new Creates a new proxy server instance
+ *
+ * @param config The proxy server configuration to use. Must NOT be NULL.
+ *
+ * @return A new proxy server instance or NULL on failure.
+ */
+ WINPR_ATTR_MALLOC(pf_server_free, 1)
+ FREERDP_API proxyServer* pf_server_new(const proxyConfig* config);
+
+ /**
+ * @brief pf_server_add_module Allows registering proxy modules that are
+ * build-in instead of shipped as separate
+ * module loaded at runtime.
+ *
+ * @param server A proxy instance to add the module to. Must NOT be NULL
+ * @param ep The proxy entry function to add. Must NOT be NULL
+ * @param userdata Custom data for the module. May be NULL
+ *
+ * @return TRUE for success, FALSE otherwise.
+ */
+ FREERDP_API BOOL pf_server_add_module(proxyServer* server, proxyModuleEntryPoint ep,
+ void* userdata);
+
+ /**
+ * @brief pf_server_start Starts the proxy, binding the configured port.
+ *
+ * @param server The server instance. Must NOT be NULL.
+ *
+ * @return TRUE for success, FALSE on error
+ */
+ FREERDP_API BOOL pf_server_start(proxyServer* server);
+
+ /**
+ * @brief pf_server_start_from_socket Starts the proxy using an existing bound socket
+ *
+ * @param server The server instance. Must NOT be NULL.
+ * @param socket The bound socket to wait for events on.
+ *
+ * @return TRUE for success, FALSE on error
+ */
+ FREERDP_API BOOL pf_server_start_from_socket(proxyServer* server, int socket);
+
+ /**
+ * @brief pf_server_start_with_peer_socket Use existing peer socket
+ *
+ * @param server The server instance. Must NOT be NULL.
+ * @param socket Ready to use peer socket
+ *
+ * @return TRUE for success, FALSE on error
+ */
+ FREERDP_API BOOL pf_server_start_with_peer_socket(proxyServer* server, int socket);
+
+ /**
+ * @brief pf_server_stop Stops a server instance asynchronously.
+ * Can be called from any thread to stop a running server instance.
+ * @param server A pointer to the server instance to stop. May be NULL.
+ */
+ FREERDP_API void pf_server_stop(proxyServer* server);
+
+ /**
+ * @brief pf_server_run This (blocking) function runs the main loop of the
+ * proxy.
+ *
+ * @param server The server instance. Must NOT be NULL.
+ *
+ * @return TRUE for successful termination, FALSE otherwise.
+ */
+ FREERDP_API BOOL pf_server_run(proxyServer* server);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SERVER_PROXY_SERVER_H */
diff --git a/include/freerdp/server/proxy/proxy_types.h b/include/freerdp/server/proxy/proxy_types.h
new file mode 100644
index 0000000..98ee4b1
--- /dev/null
+++ b/include/freerdp/server/proxy/proxy_types.h
@@ -0,0 +1,57 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * FreeRDP Proxy enum types
+ *
+ * Copyright 2023 Armin Novak <armin.novak@thincast.com>
+ * Copyright 2023 Thincast Technologies GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FREERDP_SERVER_PROXY_TYPES_H
+#define FREERDP_SERVER_PROXY_TYPES_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /** @brief how is handled a channel */
+ typedef enum
+ {
+ PF_UTILS_CHANNEL_NOT_HANDLED, /*!< channel not handled */
+ PF_UTILS_CHANNEL_BLOCK, /*!< block and drop traffic on this channel */
+ PF_UTILS_CHANNEL_PASSTHROUGH, /*!< pass traffic from this channel */
+ PF_UTILS_CHANNEL_INTERCEPT /*!< inspect traffic from this channel */
+ } pf_utils_channel_mode;
+
+ /** @brief result of a channel treatment */
+ typedef enum
+ {
+ PF_CHANNEL_RESULT_PASS, /*!< pass the packet as is */
+ PF_CHANNEL_RESULT_DROP, /*!< drop the packet */
+ PF_CHANNEL_RESULT_ERROR /*!< error during packet treatment */
+ } PfChannelResult;
+ typedef enum
+ {
+ PROXY_FETCH_TARGET_METHOD_DEFAULT,
+ PROXY_FETCH_TARGET_METHOD_CONFIG,
+ PROXY_FETCH_TARGET_METHOD_LOAD_BALANCE_INFO,
+ PROXY_FETCH_TARGET_USE_CUSTOM_ADDR
+ } ProxyFetchTargetMethod;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FREERDP_SERVER_PROXY_TYPES_H */