1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * Activation Sequence
4  *
5  * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include "activation.h"
25 #include "display.h"
26 
27 #define TAG FREERDP_TAG("core.activation")
28 
29 /*
30 static const char* const CTRLACTION_STRINGS[] =
31 {
32         "",
33         "CTRLACTION_REQUEST_CONTROL",
34         "CTRLACTION_GRANTED_CONTROL",
35         "CTRLACTION_DETACH",
36         "CTRLACTION_COOPERATE"
37 };
38 */
39 static BOOL rdp_recv_server_synchronize_pdu(rdpRdp* rdp, wStream* s);
40 static BOOL rdp_recv_client_font_list_pdu(wStream* s);
41 static BOOL rdp_recv_client_persistent_key_list_pdu(wStream* s);
42 static BOOL rdp_recv_server_font_map_pdu(rdpRdp* rdp, wStream* s);
43 static BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, wStream* s);
44 static BOOL rdp_send_server_font_map_pdu(rdpRdp* rdp);
45 
rdp_write_synchronize_pdu(wStream * s,rdpSettings * settings)46 static BOOL rdp_write_synchronize_pdu(wStream* s, rdpSettings* settings)
47 {
48 	if (Stream_GetRemainingCapacity(s) < 4)
49 		return FALSE;
50 	Stream_Write_UINT16(s, SYNCMSGTYPE_SYNC);    /* messageType (2 bytes) */
51 	Stream_Write_UINT16(s, settings->PduSource); /* targetUser (2 bytes) */
52 	return TRUE;
53 }
54 
rdp_recv_synchronize_pdu(rdpRdp * rdp,wStream * s)55 BOOL rdp_recv_synchronize_pdu(rdpRdp* rdp, wStream* s)
56 {
57 	if (rdp->settings->ServerMode)
58 		return rdp_recv_server_synchronize_pdu(rdp, s);
59 	else
60 		return rdp_recv_client_synchronize_pdu(rdp, s);
61 }
62 
rdp_recv_server_synchronize_pdu(rdpRdp * rdp,wStream * s)63 BOOL rdp_recv_server_synchronize_pdu(rdpRdp* rdp, wStream* s)
64 {
65 	rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;
66 	return TRUE;
67 }
68 
rdp_send_server_synchronize_pdu(rdpRdp * rdp)69 BOOL rdp_send_server_synchronize_pdu(rdpRdp* rdp)
70 {
71 	wStream* s = rdp_data_pdu_init(rdp);
72 	if (!s)
73 		return FALSE;
74 	if (!rdp_write_synchronize_pdu(s, rdp->settings))
75 	{
76 		Stream_Free(s, TRUE);
77 		return FALSE;
78 	}
79 	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->userId);
80 }
81 
rdp_recv_client_synchronize_pdu(rdpRdp * rdp,wStream * s)82 BOOL rdp_recv_client_synchronize_pdu(rdpRdp* rdp, wStream* s)
83 {
84 	UINT16 messageType;
85 	rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;
86 
87 	if (Stream_GetRemainingLength(s) < 4)
88 		return FALSE;
89 
90 	Stream_Read_UINT16(s, messageType); /* messageType (2 bytes) */
91 
92 	if (messageType != SYNCMSGTYPE_SYNC)
93 		return FALSE;
94 
95 	/* targetUser (2 bytes) */
96 	Stream_Seek_UINT16(s);
97 	return TRUE;
98 }
99 
rdp_send_client_synchronize_pdu(rdpRdp * rdp)100 BOOL rdp_send_client_synchronize_pdu(rdpRdp* rdp)
101 {
102 	wStream* s = rdp_data_pdu_init(rdp);
103 	if (!s)
104 		return FALSE;
105 	if (!rdp_write_synchronize_pdu(s, rdp->settings))
106 	{
107 		Stream_Free(s, TRUE);
108 		return FALSE;
109 	}
110 	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->userId);
111 }
112 
rdp_recv_control_pdu(wStream * s,UINT16 * action)113 static BOOL rdp_recv_control_pdu(wStream* s, UINT16* action)
114 {
115 	if (Stream_GetRemainingLength(s) < 8)
116 		return FALSE;
117 
118 	Stream_Read_UINT16(s, *action); /* action (2 bytes) */
119 	Stream_Seek_UINT16(s);          /* grantId (2 bytes) */
120 	Stream_Seek_UINT32(s);          /* controlId (4 bytes) */
121 	return TRUE;
122 }
123 
rdp_write_client_control_pdu(wStream * s,UINT16 action)124 static BOOL rdp_write_client_control_pdu(wStream* s, UINT16 action)
125 {
126 	if (Stream_GetRemainingCapacity(s) < 8)
127 		return FALSE;
128 	Stream_Write_UINT16(s, action); /* action (2 bytes) */
129 	Stream_Write_UINT16(s, 0);      /* grantId (2 bytes) */
130 	Stream_Write_UINT32(s, 0);      /* controlId (4 bytes) */
131 	return TRUE;
132 }
133 
rdp_recv_server_control_pdu(rdpRdp * rdp,wStream * s)134 BOOL rdp_recv_server_control_pdu(rdpRdp* rdp, wStream* s)
135 {
136 	UINT16 action;
137 
138 	if (rdp_recv_control_pdu(s, &action) == FALSE)
139 		return FALSE;
140 
141 	switch (action)
142 	{
143 		case CTRLACTION_COOPERATE:
144 			rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_COOPERATE_PDU;
145 			break;
146 
147 		case CTRLACTION_GRANTED_CONTROL:
148 			rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_GRANTED_PDU;
149 			rdp->resendFocus = TRUE;
150 			break;
151 	}
152 
153 	return TRUE;
154 }
155 
rdp_send_server_control_cooperate_pdu(rdpRdp * rdp)156 BOOL rdp_send_server_control_cooperate_pdu(rdpRdp* rdp)
157 {
158 	wStream* s = rdp_data_pdu_init(rdp);
159 	if (!s)
160 		return FALSE;
161 	if (Stream_GetRemainingCapacity(s) < 8)
162 	{
163 		Stream_Free(s, TRUE);
164 		return FALSE;
165 	}
166 	Stream_Write_UINT16(s, CTRLACTION_COOPERATE); /* action (2 bytes) */
167 	Stream_Write_UINT16(s, 0);                    /* grantId (2 bytes) */
168 	Stream_Write_UINT32(s, 0);                    /* controlId (4 bytes) */
169 	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->userId);
170 }
171 
rdp_send_server_control_granted_pdu(rdpRdp * rdp)172 BOOL rdp_send_server_control_granted_pdu(rdpRdp* rdp)
173 {
174 	wStream* s = rdp_data_pdu_init(rdp);
175 	if (!s)
176 		return FALSE;
177 	if (Stream_GetRemainingCapacity(s) < 8)
178 	{
179 		Stream_Free(s, TRUE);
180 		return FALSE;
181 	}
182 	Stream_Write_UINT16(s, CTRLACTION_GRANTED_CONTROL); /* action (2 bytes) */
183 	Stream_Write_UINT16(s, rdp->mcs->userId);           /* grantId (2 bytes) */
184 	Stream_Write_UINT32(s, 0x03EA);                     /* controlId (4 bytes) */
185 	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->userId);
186 }
187 
rdp_send_client_control_pdu(rdpRdp * rdp,UINT16 action)188 BOOL rdp_send_client_control_pdu(rdpRdp* rdp, UINT16 action)
189 {
190 	wStream* s = rdp_data_pdu_init(rdp);
191 	if (!s)
192 		return FALSE;
193 	if (!rdp_write_client_control_pdu(s, action))
194 	{
195 		Stream_Free(s, TRUE);
196 		return FALSE;
197 	}
198 	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->userId);
199 }
200 
rdp_write_persistent_list_entry(wStream * s,UINT32 key1,UINT32 key2)201 static BOOL rdp_write_persistent_list_entry(wStream* s, UINT32 key1, UINT32 key2)
202 {
203 	if (Stream_GetRemainingCapacity(s) < 8)
204 		return FALSE;
205 	Stream_Write_UINT32(s, key1); /* key1 (4 bytes) */
206 	Stream_Write_UINT32(s, key2); /* key2 (4 bytes) */
207 	return TRUE;
208 }
209 
rdp_write_client_persistent_key_list_pdu(wStream * s,const rdpSettings * settings)210 static BOOL rdp_write_client_persistent_key_list_pdu(wStream* s, const rdpSettings* settings)
211 {
212 	if (Stream_GetRemainingCapacity(s) < 24)
213 		return FALSE;
214 	Stream_Write_UINT16(s, 0);                                   /* numEntriesCache0 (2 bytes) */
215 	Stream_Write_UINT16(s, 0);                                   /* numEntriesCache1 (2 bytes) */
216 	Stream_Write_UINT16(s, 0);                                   /* numEntriesCache2 (2 bytes) */
217 	Stream_Write_UINT16(s, 0);                                   /* numEntriesCache3 (2 bytes) */
218 	Stream_Write_UINT16(s, 0);                                   /* numEntriesCache4 (2 bytes) */
219 	Stream_Write_UINT16(s, 0);                                   /* totalEntriesCache0 (2 bytes) */
220 	Stream_Write_UINT16(s, 0);                                   /* totalEntriesCache1 (2 bytes) */
221 	Stream_Write_UINT16(s, 0);                                   /* totalEntriesCache2 (2 bytes) */
222 	Stream_Write_UINT16(s, 0);                                   /* totalEntriesCache3 (2 bytes) */
223 	Stream_Write_UINT16(s, 0);                                   /* totalEntriesCache4 (2 bytes) */
224 	Stream_Write_UINT8(s, PERSIST_FIRST_PDU | PERSIST_LAST_PDU); /* bBitMask (1 byte) */
225 	Stream_Write_UINT8(s, 0);                                    /* pad1 (1 byte) */
226 	Stream_Write_UINT16(s, 0);                                   /* pad3 (2 bytes) */
227 	                                                             /* entries */
228 	return TRUE;
229 }
230 
rdp_send_client_persistent_key_list_pdu(rdpRdp * rdp)231 BOOL rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp)
232 {
233 	wStream* s = rdp_data_pdu_init(rdp);
234 	if (!s)
235 		return FALSE;
236 	if (!rdp_write_client_persistent_key_list_pdu(s, rdp->settings))
237 	{
238 		Stream_Free(s, TRUE);
239 		return FALSE;
240 	}
241 	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST, rdp->mcs->userId);
242 }
243 
rdp_recv_client_font_list_pdu(wStream * s)244 BOOL rdp_recv_client_font_list_pdu(wStream* s)
245 {
246 	/* 2.2.1.18 Client Font List PDU */
247 	return Stream_SafeSeek(s, 8);
248 }
249 
rdp_recv_client_persistent_key_list_pdu(wStream * s)250 BOOL rdp_recv_client_persistent_key_list_pdu(wStream* s)
251 {
252 	BYTE flags;
253 	size_t count = 0;
254 	UINT16 cache, x;
255 	/* 2.2.1.17.1 Persistent Key List PDU Data (TS_BITMAPCACHE_PERSISTENT_LIST_PDU) */
256 	if (Stream_GetRemainingLength(s) < 21)
257 		return FALSE;
258 	/* Read numEntriesCacheX for variable length data in PDU */
259 	for (x = 0; x < 5; x++)
260 	{
261 		Stream_Read_UINT16(s, cache);
262 		count += cache;
263 	}
264 
265 	/* Skip totalEntriesCacheX */
266 	if (!Stream_SafeSeek(s, 10))
267 		return FALSE;
268 
269 	Stream_Read_UINT8(s, flags);
270 
271 	/* Skip padding */
272 	if (!Stream_SafeSeek(s, 3))
273 		return FALSE;
274 	/* Skip actual entries sent by client */
275 	return Stream_SafeSeek(s, count * sizeof(UINT64));
276 }
277 
rdp_write_client_font_list_pdu(wStream * s,UINT16 flags)278 static BOOL rdp_write_client_font_list_pdu(wStream* s, UINT16 flags)
279 {
280 	if (Stream_GetRemainingCapacity(s) < 8)
281 		return FALSE;
282 	Stream_Write_UINT16(s, 0);     /* numberFonts (2 bytes) */
283 	Stream_Write_UINT16(s, 0);     /* totalNumFonts (2 bytes) */
284 	Stream_Write_UINT16(s, flags); /* listFlags (2 bytes) */
285 	Stream_Write_UINT16(s, 50);    /* entrySize (2 bytes) */
286 	return TRUE;
287 }
288 
rdp_send_client_font_list_pdu(rdpRdp * rdp,UINT16 flags)289 BOOL rdp_send_client_font_list_pdu(rdpRdp* rdp, UINT16 flags)
290 {
291 	wStream* s = rdp_data_pdu_init(rdp);
292 	if (!s)
293 		return FALSE;
294 	if (!rdp_write_client_font_list_pdu(s, flags))
295 	{
296 		Stream_Free(s, TRUE);
297 		return FALSE;
298 	}
299 	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_LIST, rdp->mcs->userId);
300 }
301 
rdp_recv_font_map_pdu(rdpRdp * rdp,wStream * s)302 BOOL rdp_recv_font_map_pdu(rdpRdp* rdp, wStream* s)
303 {
304 	if (rdp->settings->ServerMode)
305 		return rdp_recv_server_font_map_pdu(rdp, s);
306 	else
307 		return rdp_recv_client_font_map_pdu(rdp, s);
308 }
309 
rdp_recv_server_font_map_pdu(rdpRdp * rdp,wStream * s)310 BOOL rdp_recv_server_font_map_pdu(rdpRdp* rdp, wStream* s)
311 {
312 	rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
313 	return TRUE;
314 }
315 
rdp_recv_client_font_map_pdu(rdpRdp * rdp,wStream * s)316 BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, wStream* s)
317 {
318 	rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
319 
320 	if (Stream_GetRemainingLength(s) >= 8)
321 	{
322 		Stream_Seek_UINT16(s); /* numberEntries (2 bytes) */
323 		Stream_Seek_UINT16(s); /* totalNumEntries (2 bytes) */
324 		Stream_Seek_UINT16(s); /* mapFlags (2 bytes) */
325 		Stream_Seek_UINT16(s); /* entrySize (2 bytes) */
326 	}
327 
328 	return TRUE;
329 }
330 
rdp_send_server_font_map_pdu(rdpRdp * rdp)331 BOOL rdp_send_server_font_map_pdu(rdpRdp* rdp)
332 {
333 	wStream* s = rdp_data_pdu_init(rdp);
334 	if (!s)
335 		return FALSE;
336 	if (Stream_GetRemainingCapacity(s) < 8)
337 	{
338 		Stream_Free(s, TRUE);
339 		return FALSE;
340 	}
341 	Stream_Write_UINT16(s, 0);                              /* numberEntries (2 bytes) */
342 	Stream_Write_UINT16(s, 0);                              /* totalNumEntries (2 bytes) */
343 	Stream_Write_UINT16(s, FONTLIST_FIRST | FONTLIST_LAST); /* mapFlags (2 bytes) */
344 	Stream_Write_UINT16(s, 4);                              /* entrySize (2 bytes) */
345 	return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_MAP, rdp->mcs->userId);
346 }
347 
rdp_recv_deactivate_all(rdpRdp * rdp,wStream * s)348 BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s)
349 {
350 	UINT16 lengthSourceDescriptor;
351 	UINT32 timeout;
352 
353 	if (rdp->state == CONNECTION_STATE_ACTIVE)
354 		rdp->deactivation_reactivation = TRUE;
355 	else
356 		rdp->deactivation_reactivation = FALSE;
357 
358 	/*
359 	 * Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain
360 	 * the following fields.
361 	 */
362 	if (Stream_GetRemainingLength(s) > 0)
363 	{
364 		do
365 		{
366 			if (Stream_GetRemainingLength(s) < 4)
367 				break;
368 
369 			Stream_Read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */
370 
371 			if (Stream_GetRemainingLength(s) < 2)
372 				break;
373 
374 			Stream_Read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
375 
376 			if (Stream_GetRemainingLength(s) < lengthSourceDescriptor)
377 				break;
378 
379 			Stream_Seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */
380 		} while (0);
381 	}
382 
383 	rdp_client_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);
384 
385 	for (timeout = 0; timeout < rdp->settings->TcpAckTimeout; timeout += 100)
386 	{
387 		if (rdp_check_fds(rdp) < 0)
388 			return FALSE;
389 
390 		if (freerdp_shall_disconnect(rdp->instance))
391 			return TRUE;
392 
393 		if (rdp->state == CONNECTION_STATE_ACTIVE)
394 			return TRUE;
395 
396 		Sleep(100);
397 	}
398 
399 	WLog_ERR(TAG, "Timeout waiting for activation");
400 	return FALSE;
401 }
402 
rdp_send_deactivate_all(rdpRdp * rdp)403 BOOL rdp_send_deactivate_all(rdpRdp* rdp)
404 {
405 	wStream* s = rdp_send_stream_pdu_init(rdp);
406 	BOOL status = FALSE;
407 
408 	if (!s)
409 		return FALSE;
410 
411 	if (Stream_GetRemainingCapacity(s) < 7)
412 		goto fail;
413 	Stream_Write_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */
414 	Stream_Write_UINT16(s, 1);                      /* lengthSourceDescriptor (2 bytes) */
415 	Stream_Write_UINT8(s, 0);                       /* sourceDescriptor (should be 0x00) */
416 	status = rdp_send_pdu(rdp, s, PDU_TYPE_DEACTIVATE_ALL, rdp->mcs->userId);
417 fail:
418 	Stream_Release(s);
419 	return status;
420 }
421 
rdp_server_accept_client_control_pdu(rdpRdp * rdp,wStream * s)422 BOOL rdp_server_accept_client_control_pdu(rdpRdp* rdp, wStream* s)
423 {
424 	UINT16 action;
425 
426 	if (!rdp_recv_control_pdu(s, &action))
427 		return FALSE;
428 
429 	if (action == CTRLACTION_REQUEST_CONTROL)
430 	{
431 		if (!rdp_send_server_control_granted_pdu(rdp))
432 			return FALSE;
433 	}
434 
435 	return TRUE;
436 }
437 
rdp_server_accept_client_font_list_pdu(rdpRdp * rdp,wStream * s)438 BOOL rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, wStream* s)
439 {
440 	rdpSettings* settings = rdp->settings;
441 	freerdp_peer* peer = rdp->context->peer;
442 
443 	if (!rdp_recv_client_font_list_pdu(s))
444 		return FALSE;
445 
446 	if (settings->SupportMonitorLayoutPdu && settings->MonitorCount && peer->AdjustMonitorsLayout &&
447 	    peer->AdjustMonitorsLayout(peer))
448 	{
449 		/* client supports the monitorLayout PDU, let's send him the monitors if any */
450 		MONITOR_DEF* monitors = (MONITOR_DEF*)calloc(settings->MonitorCount, sizeof(MONITOR_DEF));
451 
452 		if (!monitors)
453 			return FALSE;
454 
455 		if (!display_convert_rdp_monitor_to_monitor_def(settings->MonitorCount,
456 		                                                settings->MonitorDefArray, &monitors))
457 		{
458 			free(monitors);
459 			return FALSE;
460 		}
461 
462 		if (!freerdp_display_send_monitor_layout(rdp->context, settings->MonitorCount, monitors))
463 		{
464 			free(monitors);
465 			return FALSE;
466 		}
467 
468 		free(monitors);
469 	}
470 
471 	if (!rdp_send_server_font_map_pdu(rdp))
472 		return FALSE;
473 
474 	if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_ACTIVE) < 0)
475 		return FALSE;
476 
477 	return TRUE;
478 }
479 
rdp_server_accept_client_persistent_key_list_pdu(rdpRdp * rdp,wStream * s)480 BOOL rdp_server_accept_client_persistent_key_list_pdu(rdpRdp* rdp, wStream* s)
481 {
482 	if (!rdp_recv_client_persistent_key_list_pdu(s))
483 		return FALSE;
484 
485 	// TODO: Actually do something with this
486 	return TRUE;
487 }
488