1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * FreeRDP Proxy Server
4  *
5  * Copyright 2019 Mati Shabtay <matishabtay@gmail.com>
6  * Copyright 2019 Kobi Mizrachi <kmizrachi18@gmail.com>
7  * Copyright 2019 Idan Freiberg <speidy@gmail.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *     http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 #include <freerdp/client/rail.h>
23 #include <freerdp/server/rail.h>
24 
25 #include "pf_rail.h"
26 #include "pf_context.h"
27 #include "pf_log.h"
28 
29 #define TAG PROXY_TAG("rail")
30 
pf_rail_context_init(pServerContext * ps)31 BOOL pf_rail_context_init(pServerContext* ps)
32 {
33 	RailServerContext* rail;
34 	rail = ps->rail = rail_server_context_new(ps->vcm);
35 
36 	if (!rail)
37 	{
38 		return FALSE;
39 	}
40 
41 	/*
42 	 * when mstsc reconnects, it doesn't wait for a second handshake, so update all handshake flags
43 	 * to be SET, then set them again when the remote server sends his handshake.
44 	 */
45 	rail_server_set_handshake_ex_flags(rail,
46 	                                   TS_RAIL_ORDER_HANDSHAKEEX_FLAGS_HIDEF |
47 	                                       TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_EXTENDED_SPI_SUPPORTED |
48 	                                       TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_SNAP_ARRANGE_SUPPORTED);
49 
50 	rail->rdpcontext = (rdpContext*)ps;
51 	return TRUE;
52 }
53 
pf_rail_client_on_open(RailClientContext * context,BOOL * sendHandshake)54 static UINT pf_rail_client_on_open(RailClientContext* context, BOOL* sendHandshake)
55 {
56 	if (NULL != sendHandshake)
57 		*sendHandshake = FALSE;
58 
59 	return CHANNEL_RC_OK;
60 }
61 
62 /* Callbacks from client side */
pf_rail_server_handshake(RailClientContext * client,const RAIL_HANDSHAKE_ORDER * handshake)63 static UINT pf_rail_server_handshake(RailClientContext* client,
64                                      const RAIL_HANDSHAKE_ORDER* handshake)
65 {
66 	proxyData* pdata = (proxyData*)client->custom;
67 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
68 	WLog_DBG(TAG, __FUNCTION__);
69 	return server->ServerHandshake(server, handshake);
70 }
71 
pf_rail_server_handshake_ex(RailClientContext * client,const RAIL_HANDSHAKE_EX_ORDER * handshakeEx)72 static UINT pf_rail_server_handshake_ex(RailClientContext* client,
73                                         const RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
74 {
75 	proxyData* pdata = (proxyData*)client->custom;
76 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
77 	WLog_DBG(TAG, __FUNCTION__);
78 	return server->ServerHandshakeEx(server, handshakeEx);
79 }
80 
pf_rail_server_sysparam(RailClientContext * client,const RAIL_SYSPARAM_ORDER * sysparam)81 static UINT pf_rail_server_sysparam(RailClientContext* client, const RAIL_SYSPARAM_ORDER* sysparam)
82 {
83 	proxyData* pdata = (proxyData*)client->custom;
84 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
85 	WLog_DBG(TAG, __FUNCTION__);
86 	return server->ServerSysparam(server, sysparam);
87 }
88 
pf_rail_server_local_move_size(RailClientContext * client,const RAIL_LOCALMOVESIZE_ORDER * localMoveSize)89 static UINT pf_rail_server_local_move_size(RailClientContext* client,
90                                            const RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
91 {
92 	proxyData* pdata = (proxyData*)client->custom;
93 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
94 	WLog_DBG(TAG, __FUNCTION__);
95 	return server->ServerLocalMoveSize(server, localMoveSize);
96 }
97 
pf_rail_server_min_max_info(RailClientContext * client,const RAIL_MINMAXINFO_ORDER * minMaxInfo)98 static UINT pf_rail_server_min_max_info(RailClientContext* client,
99                                         const RAIL_MINMAXINFO_ORDER* minMaxInfo)
100 {
101 	proxyData* pdata = (proxyData*)client->custom;
102 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
103 	WLog_DBG(TAG, __FUNCTION__);
104 	return server->ServerMinMaxInfo(server, minMaxInfo);
105 }
106 
pf_rail_server_taskbar_info(RailClientContext * client,const RAIL_TASKBAR_INFO_ORDER * taskbarInfo)107 static UINT pf_rail_server_taskbar_info(RailClientContext* client,
108                                         const RAIL_TASKBAR_INFO_ORDER* taskbarInfo)
109 {
110 	proxyData* pdata = (proxyData*)client->custom;
111 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
112 	WLog_DBG(TAG, __FUNCTION__);
113 	return server->ServerTaskbarInfo(server, taskbarInfo);
114 }
115 
pf_rail_server_langbar_info(RailClientContext * client,const RAIL_LANGBAR_INFO_ORDER * langbarInfo)116 static UINT pf_rail_server_langbar_info(RailClientContext* client,
117                                         const RAIL_LANGBAR_INFO_ORDER* langbarInfo)
118 {
119 	proxyData* pdata = (proxyData*)client->custom;
120 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
121 	WLog_DBG(TAG, __FUNCTION__);
122 	return server->ServerLangbarInfo(server, langbarInfo);
123 }
124 
pf_rail_server_exec_result(RailClientContext * client,const RAIL_EXEC_RESULT_ORDER * execResult)125 static UINT pf_rail_server_exec_result(RailClientContext* client,
126                                        const RAIL_EXEC_RESULT_ORDER* execResult)
127 {
128 	proxyData* pdata = (proxyData*)client->custom;
129 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
130 	WLog_DBG(TAG, __FUNCTION__);
131 	return server->ServerExecResult(server, execResult);
132 }
133 
pf_rail_server_z_order_sync(RailClientContext * client,const RAIL_ZORDER_SYNC * zOrderSync)134 static UINT pf_rail_server_z_order_sync(RailClientContext* client,
135                                         const RAIL_ZORDER_SYNC* zOrderSync)
136 {
137 	proxyData* pdata = (proxyData*)client->custom;
138 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
139 	WLog_DBG(TAG, __FUNCTION__);
140 	return server->ServerZOrderSync(server, zOrderSync);
141 }
142 
pf_rail_server_cloak(RailClientContext * client,const RAIL_CLOAK * cloak)143 static UINT pf_rail_server_cloak(RailClientContext* client, const RAIL_CLOAK* cloak)
144 {
145 	proxyData* pdata = (proxyData*)client->custom;
146 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
147 	WLog_DBG(TAG, __FUNCTION__);
148 	return server->ServerCloak(server, cloak);
149 }
150 
151 static UINT
pf_rail_server_power_display_request(RailClientContext * client,const RAIL_POWER_DISPLAY_REQUEST * powerDisplayRequest)152 pf_rail_server_power_display_request(RailClientContext* client,
153                                      const RAIL_POWER_DISPLAY_REQUEST* powerDisplayRequest)
154 {
155 	proxyData* pdata = (proxyData*)client->custom;
156 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
157 	WLog_DBG(TAG, __FUNCTION__);
158 	return server->ServerPowerDisplayRequest(server, powerDisplayRequest);
159 }
160 
pf_rail_server_get_appid_resp(RailClientContext * client,const RAIL_GET_APPID_RESP_ORDER * getAppidResp)161 static UINT pf_rail_server_get_appid_resp(RailClientContext* client,
162                                           const RAIL_GET_APPID_RESP_ORDER* getAppidResp)
163 {
164 	proxyData* pdata = (proxyData*)client->custom;
165 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
166 	WLog_DBG(TAG, __FUNCTION__);
167 	return server->ServerGetAppidResp(server, getAppidResp);
168 }
169 
pf_rail_server_get_appid_resp_ex(RailClientContext * client,const RAIL_GET_APPID_RESP_EX * getAppidRespEx)170 static UINT pf_rail_server_get_appid_resp_ex(RailClientContext* client,
171                                              const RAIL_GET_APPID_RESP_EX* getAppidRespEx)
172 {
173 	proxyData* pdata = (proxyData*)client->custom;
174 	RailServerContext* server = (RailServerContext*)pdata->ps->rail;
175 	WLog_DBG(TAG, __FUNCTION__);
176 	return server->ServerGetAppidRespEx(server, getAppidRespEx);
177 }
178 
179 /* Callbacks from server side */
180 
pf_rail_client_handshake(RailServerContext * server,const RAIL_HANDSHAKE_ORDER * handshake)181 static UINT pf_rail_client_handshake(RailServerContext* server,
182                                      const RAIL_HANDSHAKE_ORDER* handshake)
183 {
184 	proxyData* pdata = (proxyData*)server->custom;
185 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
186 	WLog_DBG(TAG, __FUNCTION__);
187 	return client->ClientHandshake(client, handshake);
188 }
189 
pf_rail_client_client_status(RailServerContext * server,const RAIL_CLIENT_STATUS_ORDER * clientStatus)190 static UINT pf_rail_client_client_status(RailServerContext* server,
191                                          const RAIL_CLIENT_STATUS_ORDER* clientStatus)
192 {
193 	proxyData* pdata = (proxyData*)server->custom;
194 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
195 	WLog_DBG(TAG, __FUNCTION__);
196 	return client->ClientInformation(client, clientStatus);
197 }
198 
pf_rail_client_exec(RailServerContext * server,const RAIL_EXEC_ORDER * exec)199 static UINT pf_rail_client_exec(RailServerContext* server, const RAIL_EXEC_ORDER* exec)
200 {
201 	proxyData* pdata = (proxyData*)server->custom;
202 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
203 	WLog_DBG(TAG, __FUNCTION__);
204 	return client->ClientExecute(client, exec);
205 }
206 
pf_rail_client_sysparam(RailServerContext * server,const RAIL_SYSPARAM_ORDER * sysparam)207 static UINT pf_rail_client_sysparam(RailServerContext* server, const RAIL_SYSPARAM_ORDER* sysparam)
208 {
209 	proxyData* pdata = (proxyData*)server->custom;
210 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
211 	WLog_DBG(TAG, __FUNCTION__);
212 	return client->ClientSystemParam(client, sysparam);
213 }
214 
pf_rail_client_activate(RailServerContext * server,const RAIL_ACTIVATE_ORDER * activate)215 static UINT pf_rail_client_activate(RailServerContext* server, const RAIL_ACTIVATE_ORDER* activate)
216 {
217 	proxyData* pdata = (proxyData*)server->custom;
218 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
219 	WLog_DBG(TAG, __FUNCTION__);
220 	return client->ClientActivate(client, activate);
221 }
222 
pf_rail_client_sysmenu(RailServerContext * server,const RAIL_SYSMENU_ORDER * sysmenu)223 static UINT pf_rail_client_sysmenu(RailServerContext* server, const RAIL_SYSMENU_ORDER* sysmenu)
224 {
225 	proxyData* pdata = (proxyData*)server->custom;
226 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
227 	WLog_DBG(TAG, __FUNCTION__);
228 	return client->ClientSystemMenu(client, sysmenu);
229 }
230 
pf_rail_client_syscommand(RailServerContext * server,const RAIL_SYSCOMMAND_ORDER * syscommand)231 static UINT pf_rail_client_syscommand(RailServerContext* server,
232                                       const RAIL_SYSCOMMAND_ORDER* syscommand)
233 {
234 	proxyData* pdata = (proxyData*)server->custom;
235 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
236 	WLog_DBG(TAG, __FUNCTION__);
237 	return client->ClientSystemCommand(client, syscommand);
238 }
239 
pf_rail_client_notify_event(RailServerContext * server,const RAIL_NOTIFY_EVENT_ORDER * notifyEvent)240 static UINT pf_rail_client_notify_event(RailServerContext* server,
241                                         const RAIL_NOTIFY_EVENT_ORDER* notifyEvent)
242 {
243 	proxyData* pdata = (proxyData*)server->custom;
244 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
245 	WLog_DBG(TAG, __FUNCTION__);
246 	return client->ClientNotifyEvent(client, notifyEvent);
247 }
248 
pf_rail_client_window_move(RailServerContext * server,const RAIL_WINDOW_MOVE_ORDER * windowMove)249 static UINT pf_rail_client_window_move(RailServerContext* server,
250                                        const RAIL_WINDOW_MOVE_ORDER* windowMove)
251 {
252 	proxyData* pdata = (proxyData*)server->custom;
253 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
254 	WLog_DBG(TAG, __FUNCTION__);
255 	return client->ClientWindowMove(client, windowMove);
256 }
257 
pf_rail_client_snap_arrange(RailServerContext * server,const RAIL_SNAP_ARRANGE * snapArrange)258 static UINT pf_rail_client_snap_arrange(RailServerContext* server,
259                                         const RAIL_SNAP_ARRANGE* snapArrange)
260 {
261 	proxyData* pdata = (proxyData*)server->custom;
262 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
263 	WLog_DBG(TAG, __FUNCTION__);
264 	return client->ClientSnapArrange(client, snapArrange);
265 }
266 
pf_rail_client_get_appid_req(RailServerContext * server,const RAIL_GET_APPID_REQ_ORDER * getAppidReq)267 static UINT pf_rail_client_get_appid_req(RailServerContext* server,
268                                          const RAIL_GET_APPID_REQ_ORDER* getAppidReq)
269 {
270 	proxyData* pdata = (proxyData*)server->custom;
271 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
272 	WLog_DBG(TAG, __FUNCTION__);
273 	return client->ClientGetAppIdRequest(client, getAppidReq);
274 }
275 
pf_rail_client_langbar_info(RailServerContext * server,const RAIL_LANGBAR_INFO_ORDER * langbarInfo)276 static UINT pf_rail_client_langbar_info(RailServerContext* server,
277                                         const RAIL_LANGBAR_INFO_ORDER* langbarInfo)
278 {
279 	proxyData* pdata = (proxyData*)server->custom;
280 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
281 	WLog_DBG(TAG, __FUNCTION__);
282 	return client->ClientLanguageBarInfo(client, langbarInfo);
283 }
284 
pf_rail_client_language_ime_info(RailServerContext * server,const RAIL_LANGUAGEIME_INFO_ORDER * languageImeInfo)285 static UINT pf_rail_client_language_ime_info(RailServerContext* server,
286                                              const RAIL_LANGUAGEIME_INFO_ORDER* languageImeInfo)
287 {
288 	proxyData* pdata = (proxyData*)server->custom;
289 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
290 	WLog_DBG(TAG, __FUNCTION__);
291 	return client->ClientLanguageIMEInfo(client, languageImeInfo);
292 }
293 
pf_rail_client_compartment_info(RailServerContext * server,const RAIL_COMPARTMENT_INFO_ORDER * compartmentInfo)294 static UINT pf_rail_client_compartment_info(RailServerContext* server,
295                                             const RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo)
296 {
297 	WLog_DBG(TAG, __FUNCTION__);
298 	return 0;
299 }
300 
pf_rail_client_cloak(RailServerContext * server,const RAIL_CLOAK * cloak)301 static UINT pf_rail_client_cloak(RailServerContext* server, const RAIL_CLOAK* cloak)
302 {
303 	proxyData* pdata = (proxyData*)server->custom;
304 	RailClientContext* client = (RailClientContext*)pdata->pc->rail;
305 	WLog_DBG(TAG, __FUNCTION__);
306 	return client->ClientCloak(client, cloak);
307 }
308 
pf_rail_pipeline_init(RailClientContext * client,RailServerContext * server,proxyData * pdata)309 void pf_rail_pipeline_init(RailClientContext* client, RailServerContext* server, proxyData* pdata)
310 {
311 	/* Set server and client side references to proxy data */
312 	client->custom = (void*)pdata;
313 	server->custom = (void*)pdata;
314 	/* Set client callbacks */
315 	client->OnOpen = pf_rail_client_on_open;
316 	client->ServerHandshake = pf_rail_server_handshake;
317 	client->ServerHandshakeEx = pf_rail_server_handshake_ex;
318 	client->ServerSystemParam = pf_rail_server_sysparam;
319 	client->ServerLocalMoveSize = pf_rail_server_local_move_size;
320 	client->ServerMinMaxInfo = pf_rail_server_min_max_info;
321 	client->ServerTaskBarInfo = pf_rail_server_taskbar_info;
322 	client->ServerLanguageBarInfo = pf_rail_server_langbar_info;
323 	client->ServerExecuteResult = pf_rail_server_exec_result;
324 	client->ServerZOrderSync = pf_rail_server_z_order_sync;
325 	client->ServerCloak = pf_rail_server_cloak;
326 	client->ServerPowerDisplayRequest = pf_rail_server_power_display_request;
327 	client->ServerGetAppIdResponse = pf_rail_server_get_appid_resp;
328 	client->ServerGetAppidResponseExtended = pf_rail_server_get_appid_resp_ex;
329 	/* Set server callbacks */
330 	server->ClientHandshake = pf_rail_client_handshake;
331 	server->ClientClientStatus = pf_rail_client_client_status;
332 	server->ClientExec = pf_rail_client_exec;
333 	server->ClientSysparam = pf_rail_client_sysparam;
334 	server->ClientActivate = pf_rail_client_activate;
335 	server->ClientSysmenu = pf_rail_client_sysmenu;
336 	server->ClientSyscommand = pf_rail_client_syscommand;
337 	server->ClientNotifyEvent = pf_rail_client_notify_event;
338 	server->ClientGetAppidReq = pf_rail_client_get_appid_req;
339 	server->ClientWindowMove = pf_rail_client_window_move;
340 	server->ClientSnapArrange = pf_rail_client_snap_arrange;
341 	server->ClientLangbarInfo = pf_rail_client_langbar_info;
342 	server->ClientLanguageImeInfo = pf_rail_client_language_ime_info;
343 	server->ClientCompartmentInfo = pf_rail_client_compartment_info;
344 	server->ClientCloak = pf_rail_client_cloak;
345 }
346