[proxy] implement dynamic channel filter
* Allow modules to configure intercept channels * Allow modules to rewrite packets
This commit is contained in:
parent
2067a480e9
commit
f26079edf2
@ -26,6 +26,7 @@
|
|||||||
#include <freerdp/channels/wtsvc.h>
|
#include <freerdp/channels/wtsvc.h>
|
||||||
|
|
||||||
#include <freerdp/server/proxy/proxy_config.h>
|
#include <freerdp/server/proxy/proxy_config.h>
|
||||||
|
#include <freerdp/server/proxy/proxy_types.h>
|
||||||
|
|
||||||
#define PROXY_SESSION_ID_LENGTH 32
|
#define PROXY_SESSION_ID_LENGTH 32
|
||||||
|
|
||||||
@ -46,24 +47,6 @@ extern "C"
|
|||||||
/* All proxy interception channels derive from this base struct
|
/* All proxy interception channels derive from this base struct
|
||||||
* and set their cleanup function accordingly. */
|
* and set their cleanup function accordingly. */
|
||||||
FREERDP_API void intercept_context_entry_free(void* obj);
|
FREERDP_API void intercept_context_entry_free(void* obj);
|
||||||
|
|
||||||
/** @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 PfChannelResult (*proxyChannelDataFn)(proxyData* pdata,
|
typedef PfChannelResult (*proxyChannelDataFn)(proxyData* pdata,
|
||||||
const pServerStaticChannelContext* channel,
|
const pServerStaticChannelContext* channel,
|
||||||
const BYTE* xdata, size_t xsize, UINT32 flags,
|
const BYTE* xdata, size_t xsize, UINT32 flags,
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
* Copyright 2019 Idan Freiberg <speidy@gmail.com>
|
* Copyright 2019 Idan Freiberg <speidy@gmail.com>
|
||||||
* Copyright 2021 Armin Novak <anovak@thincast.com>
|
* Copyright 2021 Armin Novak <anovak@thincast.com>
|
||||||
* Copyright 2021 Thincast Technologies GmbH
|
* 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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -23,114 +25,130 @@
|
|||||||
#ifndef FREERDP_SERVER_PROXY_MODULES_API_H
|
#ifndef FREERDP_SERVER_PROXY_MODULES_API_H
|
||||||
#define FREERDP_SERVER_PROXY_MODULES_API_H
|
#define FREERDP_SERVER_PROXY_MODULES_API_H
|
||||||
|
|
||||||
#include <freerdp/freerdp.h>
|
|
||||||
#include <winpr/winpr.h>
|
#include <winpr/winpr.h>
|
||||||
|
#include <winpr/stream.h>
|
||||||
#include <winpr/sspi.h>
|
#include <winpr/sspi.h>
|
||||||
|
|
||||||
|
#include <freerdp/server/proxy/proxy_types.h>
|
||||||
|
|
||||||
#define MODULE_TAG(module) "proxy.modules." module
|
#define MODULE_TAG(module) "proxy.modules." module
|
||||||
|
|
||||||
typedef struct proxy_data proxyData;
|
#ifdef __cplusplus
|
||||||
typedef struct proxy_module proxyModule;
|
extern "C"
|
||||||
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 */
|
#endif
|
||||||
const char* description; /* 1: module description */
|
|
||||||
|
|
||||||
UINT64 reserved1[32 - 2]; /* 2-32 */
|
typedef struct proxy_data proxyData;
|
||||||
|
typedef struct proxy_module proxyModule;
|
||||||
|
typedef struct proxy_plugin proxyPlugin;
|
||||||
|
typedef struct proxy_plugins_manager proxyPluginsManager;
|
||||||
|
|
||||||
BOOL (*PluginUnload)(proxyPlugin* plugin); /* 33 */
|
/* hook callback. should return TRUE on success or FALSE on error. */
|
||||||
UINT64 reserved2[66 - 34]; /* 34 - 65 */
|
typedef BOOL (*proxyHookFn)(proxyPlugin*, proxyData*, void*);
|
||||||
|
|
||||||
/* proxy hooks. a module can set these function pointers to register hooks */
|
/*
|
||||||
proxyHookFn ClientInitConnect; /* 66 custom=rdpContext* */
|
* Filter callback:
|
||||||
proxyHookFn ClientUninitConnect; /* 67 custom=rdpContext* */
|
* It MUST return TRUE if the related event should be proxied,
|
||||||
proxyHookFn ClientPreConnect; /* 68 custom=rdpContext* */
|
* or FALSE if it should be ignored.
|
||||||
proxyHookFn ClientPostConnect; /* 69 custom=rdpContext* */
|
*/
|
||||||
proxyHookFn ClientPostDisconnect; /* 70 custom=rdpContext* */
|
typedef BOOL (*proxyFilterFn)(proxyPlugin*, proxyData*, void*);
|
||||||
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* */
|
/* describes a plugin: name, description and callbacks to execute.
|
||||||
proxyHookFn ServerPeerActivate; /* 97 custom=freerdp_peer* */
|
*
|
||||||
proxyHookFn ServerChannelsInit; /* 98 custom=freerdp_peer* */
|
* This is public API, so always add new fields at the end of the struct to keep
|
||||||
proxyHookFn ServerChannelsFree; /* 99 custom=freerdp_peer* */
|
* some backward compatibility.
|
||||||
proxyHookFn ServerSessionEnd; /* 100 custom=freerdp_peer* */
|
*/
|
||||||
proxyHookFn ServerSessionInitialize; /* 101 custom=freerdp_peer* */
|
struct proxy_plugin
|
||||||
proxyHookFn ServerSessionStarted; /* 102 custom=freerdp_peer* */
|
{
|
||||||
|
const char* name; /* 0: unique module name */
|
||||||
|
const char* description; /* 1: module description */
|
||||||
|
|
||||||
UINT64 reserved4[128 - 103]; /* 103 - 127 */
|
UINT64 reserved1[32 - 2]; /* 2-32 */
|
||||||
|
|
||||||
/* proxy filters. a module can set these function pointers to register filters */
|
BOOL (*PluginUnload)(proxyPlugin* plugin); /* 33 */
|
||||||
proxyFilterFn KeyboardEvent; /* 128 */
|
UINT64 reserved2[66 - 34]; /* 34 - 65 */
|
||||||
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 */
|
|
||||||
UINT64 reserved5[160 - 138]; /* 138-159 */
|
|
||||||
|
|
||||||
/* Runtime data fields */
|
/* proxy hooks. a module can set these function pointers to register hooks */
|
||||||
proxyPluginsManager* mgr; /* 160 */ /** Set during plugin registration */
|
proxyHookFn ClientInitConnect; /* 66 custom=rdpContext* */
|
||||||
void* userdata; /* 161 */ /** Custom data provided with RegisterPlugin, memory managed
|
proxyHookFn ClientUninitConnect; /* 67 custom=rdpContext* */
|
||||||
outside of plugin. */
|
proxyHookFn ClientPreConnect; /* 68 custom=rdpContext* */
|
||||||
void* custom; /* 162 */ /** Custom configuration data, must be allocated in RegisterPlugin and
|
proxyHookFn ClientPostConnect; /* 69 custom=rdpContext* */
|
||||||
freed in PluginUnload */
|
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 */
|
||||||
|
|
||||||
UINT64 reserved6[192 - 163]; /* 163-191 Add some filler data to allow for new callbacks or
|
proxyHookFn ServerPostConnect; /* 96 custom=freerdp_peer* */
|
||||||
* fields without breaking API */
|
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 */
|
||||||
* 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. */
|
/* proxy filters. a module can set these function pointers to register filters */
|
||||||
BOOL (*SetPluginData)(struct proxy_plugins_manager* mgr, const char*, proxyData*, void*);
|
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 */
|
||||||
|
|
||||||
/* 2 used for getting plugin's per-session info. */
|
/* proxy dynamic channel filters:
|
||||||
void* (*GetPluginData)(struct proxy_plugins_manager* mgr, const char*, proxyData*);
|
*
|
||||||
|
* - 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 */
|
||||||
|
|
||||||
/* 3 used for aborting a session. */
|
/* Runtime data fields */
|
||||||
void (*AbortConnect)(struct proxy_plugins_manager* mgr, proxyData*);
|
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 reserved[128 - 4]; /* 4-127 reserved fields */
|
UINT64 reserved6[192 - 163]; /* 163-191 Add some filler data to allow for new callbacks or
|
||||||
};
|
* fields without breaking API */
|
||||||
|
};
|
||||||
|
|
||||||
typedef BOOL (*proxyModuleEntryPoint)(proxyPluginsManager* plugins_manager, void* userdata);
|
/*
|
||||||
|
* 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 */
|
/* filter events parameters */
|
||||||
#define WINPR_PACK_PUSH
|
#define WINPR_PACK_PUSH
|
||||||
@ -174,14 +192,6 @@ typedef struct
|
|||||||
UINT32 flags;
|
UINT32 flags;
|
||||||
} proxyChannelDataEventInfo;
|
} proxyChannelDataEventInfo;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/* out values */
|
/* out values */
|
||||||
@ -200,7 +210,32 @@ typedef struct server_peer_logon
|
|||||||
const SEC_WINNT_AUTH_IDENTITY* identity;
|
const SEC_WINNT_AUTH_IDENTITY* identity;
|
||||||
BOOL automatic;
|
BOOL automatic;
|
||||||
} proxyServerPeerLogon;
|
} 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
|
#define WINPR_PACK_POP
|
||||||
#include <winpr/pack.h>
|
#include <winpr/pack.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* FREERDP_SERVER_PROXY_MODULES_API_H */
|
#endif /* FREERDP_SERVER_PROXY_MODULES_API_H */
|
||||||
|
48
include/freerdp/server/proxy/proxy_types.h
Normal file
48
include/freerdp/server/proxy/proxy_types.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* 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
|
||||||
|
|
||||||
|
/** @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;
|
||||||
|
|
||||||
|
#endif /* FREERDP_SERVER_PROXY_TYPES_H */
|
@ -87,6 +87,35 @@ typedef enum
|
|||||||
DYNCVC_READ_INCOMPLETE /*!< missing bytes to read the complete packet */
|
DYNCVC_READ_INCOMPLETE /*!< missing bytes to read the complete packet */
|
||||||
} DynvcReadResult;
|
} DynvcReadResult;
|
||||||
|
|
||||||
|
static PfChannelResult data_cb(pServerContext* ps, pServerDynamicChannelContext* channel,
|
||||||
|
BOOL isBackData, ChannelStateTracker* tracker, BOOL firstPacket,
|
||||||
|
BOOL lastPacket)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(ps);
|
||||||
|
WINPR_ASSERT(channel);
|
||||||
|
WINPR_ASSERT(tracker);
|
||||||
|
WINPR_ASSERT(ps->pdata);
|
||||||
|
|
||||||
|
wStream* currentPacket = channelTracker_getCurrentPacket(tracker);
|
||||||
|
proxyDynChannelInterceptData dyn = { .name = channel->channelName,
|
||||||
|
.channelId = channel->channelId,
|
||||||
|
.data = currentPacket,
|
||||||
|
.isBackData = isBackData,
|
||||||
|
.first = firstPacket,
|
||||||
|
.last = lastPacket,
|
||||||
|
.rewritten = FALSE,
|
||||||
|
.packetSize = channelTracker_getCurrentPacketSize(tracker),
|
||||||
|
.result = PF_CHANNEL_RESULT_ERROR };
|
||||||
|
Stream_SealLength(dyn.data);
|
||||||
|
if (!pf_modules_run_filter(ps->pdata->module, FILTER_TYPE_INTERCEPT_CHANNEL, ps->pdata, &dyn))
|
||||||
|
return PF_CHANNEL_RESULT_ERROR;
|
||||||
|
|
||||||
|
channelTracker_setCurrentPacketSize(tracker, dyn.packetSize);
|
||||||
|
if (dyn.rewritten)
|
||||||
|
return channelTracker_flushCurrent(tracker, firstPacket, lastPacket, !isBackData);
|
||||||
|
return dyn.result;
|
||||||
|
}
|
||||||
|
|
||||||
static pServerDynamicChannelContext* DynamicChannelContext_new(pServerContext* ps, const char* name,
|
static pServerDynamicChannelContext* DynamicChannelContext_new(pServerContext* ps, const char* name,
|
||||||
UINT32 id)
|
UINT32 id)
|
||||||
{
|
{
|
||||||
@ -106,15 +135,24 @@ static pServerDynamicChannelContext* DynamicChannelContext_new(pServerContext* p
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->channelMode = pf_utils_get_channel_mode(ps->pdata->config, name);
|
ret->frontTracker.dataCallback = data_cb;
|
||||||
|
ret->backTracker.dataCallback = data_cb;
|
||||||
|
|
||||||
|
proxyChannelToInterceptData dyn = { .name = name, .channelId = id, .intercept = FALSE };
|
||||||
|
if (pf_modules_run_filter(ps->pdata->module, FILTER_TYPE_DYN_INTERCEPT_LIST, ps->pdata, &dyn) &&
|
||||||
|
dyn.intercept)
|
||||||
|
ret->channelMode = PF_UTILS_CHANNEL_INTERCEPT;
|
||||||
|
else
|
||||||
|
ret->channelMode = pf_utils_get_channel_mode(ps->pdata->config, name);
|
||||||
ret->openStatus = CHANNEL_OPENSTATE_OPENED;
|
ret->openStatus = CHANNEL_OPENSTATE_OPENED;
|
||||||
ret->packetReassembly = (ret->channelMode == PF_UTILS_CHANNEL_INTERCEPT);
|
ret->packetReassembly = (ret->channelMode == PF_UTILS_CHANNEL_INTERCEPT);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DynamicChannelContext_free(pServerDynamicChannelContext* c)
|
static void DynamicChannelContext_free(void* ptr)
|
||||||
{
|
{
|
||||||
|
pServerDynamicChannelContext* c = (pServerDynamicChannelContext*)ptr;
|
||||||
if (!c)
|
if (!c)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -137,8 +175,10 @@ static UINT32 ChannelId_Hash(const void* key)
|
|||||||
return *v;
|
return *v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL ChannelId_Compare(const UINT32* v1, const UINT32* v2)
|
static BOOL ChannelId_Compare(const void* objA, const void* objB)
|
||||||
{
|
{
|
||||||
|
const UINT32* v1 = objA;
|
||||||
|
const UINT32* v2 = objB;
|
||||||
return (*v1 == *v2);
|
return (*v1 == *v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,10 +597,10 @@ static DynChannelContext* DynChannelContext_new(proxyData* pdata,
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
obj = HashTable_KeyObject(dyn->channels);
|
obj = HashTable_KeyObject(dyn->channels);
|
||||||
obj->fnObjectEquals = (OBJECT_EQUALS_FN)ChannelId_Compare;
|
obj->fnObjectEquals = ChannelId_Compare;
|
||||||
|
|
||||||
obj = HashTable_ValueObject(dyn->channels);
|
obj = HashTable_ValueObject(dyn->channels);
|
||||||
obj->fnObjectFree = (OBJECT_FREE_FN)DynamicChannelContext_free;
|
obj->fnObjectFree = DynamicChannelContext_free;
|
||||||
|
|
||||||
return dyn;
|
return dyn;
|
||||||
|
|
||||||
@ -575,9 +615,11 @@ static PfChannelResult pf_dynvc_back_data(proxyData* pdata,
|
|||||||
size_t totalSize)
|
size_t totalSize)
|
||||||
{
|
{
|
||||||
WINPR_ASSERT(channel);
|
WINPR_ASSERT(channel);
|
||||||
|
|
||||||
DynChannelContext* dyn = (DynChannelContext*)channel->context;
|
DynChannelContext* dyn = (DynChannelContext*)channel->context;
|
||||||
WINPR_UNUSED(pdata);
|
WINPR_UNUSED(pdata);
|
||||||
WINPR_ASSERT(dyn);
|
WINPR_ASSERT(dyn);
|
||||||
|
|
||||||
return channelTracker_update(dyn->backTracker, xdata, xsize, flags, totalSize);
|
return channelTracker_update(dyn->backTracker, xdata, xsize, flags, totalSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,9 +629,11 @@ static PfChannelResult pf_dynvc_front_data(proxyData* pdata,
|
|||||||
size_t totalSize)
|
size_t totalSize)
|
||||||
{
|
{
|
||||||
WINPR_ASSERT(channel);
|
WINPR_ASSERT(channel);
|
||||||
|
|
||||||
DynChannelContext* dyn = (DynChannelContext*)channel->context;
|
DynChannelContext* dyn = (DynChannelContext*)channel->context;
|
||||||
WINPR_UNUSED(pdata);
|
WINPR_UNUSED(pdata);
|
||||||
WINPR_ASSERT(dyn);
|
WINPR_ASSERT(dyn);
|
||||||
|
|
||||||
return channelTracker_update(dyn->frontTracker, xdata, xsize, flags, totalSize);
|
return channelTracker_update(dyn->frontTracker, xdata, xsize, flags, totalSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
#include "pf_client.h"
|
#include "pf_client.h"
|
||||||
#include "pf_utils.h"
|
#include "pf_utils.h"
|
||||||
|
#include "proxy_modules.h"
|
||||||
|
|
||||||
#include <freerdp/server/proxy/proxy_context.h>
|
#include <freerdp/server/proxy/proxy_context.h>
|
||||||
|
|
||||||
#include "channels/pf_channel_rdpdr.h"
|
#include "channels/pf_channel_rdpdr.h"
|
||||||
@ -65,7 +67,14 @@ pServerStaticChannelContext* StaticChannelContext_new(pServerContext* ps, const
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->channelMode = pf_utils_get_channel_mode(ps->pdata->config, name);
|
proxyChannelToInterceptData channel = { .name = name, .channelId = id, .intercept = FALSE };
|
||||||
|
|
||||||
|
if (pf_modules_run_filter(ps->pdata->module, FILTER_TYPE_STATIC_INTERCEPT_LIST, ps->pdata,
|
||||||
|
&channel) &&
|
||||||
|
channel.intercept)
|
||||||
|
ret->channelMode = PF_UTILS_CHANNEL_INTERCEPT;
|
||||||
|
else
|
||||||
|
ret->channelMode = pf_utils_get_channel_mode(ps->pdata->config, name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,6 +292,18 @@ static BOOL pf_modules_ArrayList_ForEachFkt(void* data, size_t index, va_list ap
|
|||||||
result = IFCALLRESULT(TRUE, plugin->ServerPeerLogon, plugin, pdata, param);
|
result = IFCALLRESULT(TRUE, plugin->ServerPeerLogon, plugin, pdata, param);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FILTER_TYPE_INTERCEPT_CHANNEL:
|
||||||
|
result = IFCALLRESULT(TRUE, plugin->DynChannelIntercept, plugin, pdata, param);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FILTER_TYPE_DYN_INTERCEPT_LIST:
|
||||||
|
result = IFCALLRESULT(TRUE, plugin->DynChannelToIntercept, plugin, pdata, param);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FILTER_TYPE_STATIC_INTERCEPT_LIST:
|
||||||
|
result = IFCALLRESULT(TRUE, plugin->StaticChannelToIntercept, plugin, pdata, param);
|
||||||
|
break;
|
||||||
|
|
||||||
case FILTER_LAST:
|
case FILTER_LAST:
|
||||||
default:
|
default:
|
||||||
WLog_ERR(TAG, "invalid filter called");
|
WLog_ERR(TAG, "invalid filter called");
|
||||||
|
@ -39,6 +39,9 @@ typedef enum
|
|||||||
FILTER_TYPE_SERVER_PEER_LOGON, /* proxyServerPeerLogon */
|
FILTER_TYPE_SERVER_PEER_LOGON, /* proxyServerPeerLogon */
|
||||||
FILTER_TYPE_CLIENT_PASSTHROUGH_CHANNEL_CREATE, /* proxyChannelDataEventInfo */
|
FILTER_TYPE_CLIENT_PASSTHROUGH_CHANNEL_CREATE, /* proxyChannelDataEventInfo */
|
||||||
|
|
||||||
|
FILTER_TYPE_STATIC_INTERCEPT_LIST, /* proxyChannelToInterceptData */
|
||||||
|
FILTER_TYPE_DYN_INTERCEPT_LIST, /* proxyChannelToInterceptData */
|
||||||
|
FILTER_TYPE_INTERCEPT_CHANNEL, /* proxyDynChannelInterceptData */
|
||||||
FILTER_LAST
|
FILTER_LAST
|
||||||
} PF_FILTER_TYPE;
|
} PF_FILTER_TYPE;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user