diff options
Diffstat (limited to 'include/freerdp/server/proxy')
-rw-r--r-- | include/freerdp/server/proxy/proxy_config.h | 235 | ||||
-rw-r--r-- | include/freerdp/server/proxy/proxy_context.h | 186 | ||||
-rw-r--r-- | include/freerdp/server/proxy/proxy_log.h | 53 | ||||
-rw-r--r-- | include/freerdp/server/proxy/proxy_modules_api.h | 241 | ||||
-rw-r--r-- | include/freerdp/server/proxy/proxy_server.h | 115 | ||||
-rw-r--r-- | include/freerdp/server/proxy/proxy_types.h | 57 |
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 */ |