1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * RPC over HTTP
4  *
5  * Copyright 2012 Fujitsu Technology Solutions GmbH
6  * Copyright 2012 Dmitrij Jasnov <dmitrij.jasnov@ts.fujitsu.com>
7  * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@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 #ifndef FREERDP_LIB_CORE_GATEWAY_RPC_H
23 #define FREERDP_LIB_CORE_GATEWAY_RPC_H
24 
25 #include <winpr/wtypes.h>
26 #include <winpr/stream.h>
27 #include <winpr/collections.h>
28 #include <winpr/interlocked.h>
29 
30 #include <freerdp/log.h>
31 #include <freerdp/utils/ringbuffer.h>
32 
33 typedef struct rdp_rpc rdpRpc;
34 
35 #pragma pack(push, 1)
36 
37 typedef struct
38 {
39 	BYTE rpc_vers;
40 	BYTE rpc_vers_minor;
41 	BYTE ptype;
42 	BYTE pfc_flags;
43 	BYTE packed_drep[4];
44 	UINT16 frag_length;
45 	UINT16 auth_length;
46 	UINT32 call_id;
47 } rpcconn_common_hdr_t;
48 
49 #define RPC_COMMON_FIELDS_LENGTH sizeof(rpcconn_common_hdr_t)
50 
51 typedef struct
52 {
53 	rpcconn_common_hdr_t header;
54 
55 	UINT16 Flags;
56 	UINT16 NumberOfCommands;
57 } rpcconn_rts_hdr_t;
58 
59 #define RTS_PDU_HEADER_LENGTH 20
60 
61 #define RPC_PDU_FLAG_STUB 0x00000001
62 
63 typedef struct _RPC_PDU
64 {
65 	wStream* s;
66 	UINT32 Type;
67 	UINT32 Flags;
68 	UINT32 CallId;
69 } RPC_PDU, *PRPC_PDU;
70 
71 #pragma pack(pop)
72 
73 #include "../tcp.h"
74 #include "../transport.h"
75 
76 #include "http.h"
77 #include "ntlm.h"
78 
79 #include <time.h>
80 
81 #include <winpr/sspi.h>
82 #include <winpr/interlocked.h>
83 
84 #include <freerdp/types.h>
85 #include <freerdp/settings.h>
86 #include <freerdp/crypto/tls.h>
87 #include <freerdp/crypto/crypto.h>
88 #include <freerdp/api.h>
89 
90 #include <winpr/print.h>
91 
92 /**
93  * CAE Specification
94  * DCE 1.1: Remote Procedure Call
95  * Document Number: C706
96  * http://pubs.opengroup.org/onlinepubs/9629399/
97  */
98 
99 #define PTYPE_REQUEST 0x00
100 #define PTYPE_PING 0x01
101 #define PTYPE_RESPONSE 0x02
102 #define PTYPE_FAULT 0x03
103 #define PTYPE_WORKING 0x04
104 #define PTYPE_NOCALL 0x05
105 #define PTYPE_REJECT 0x06
106 #define PTYPE_ACK 0x07
107 #define PTYPE_CL_CANCEL 0x08
108 #define PTYPE_FACK 0x09
109 #define PTYPE_CANCEL_ACK 0x0A
110 #define PTYPE_BIND 0x0B
111 #define PTYPE_BIND_ACK 0x0C
112 #define PTYPE_BIND_NAK 0x0D
113 #define PTYPE_ALTER_CONTEXT 0x0E
114 #define PTYPE_ALTER_CONTEXT_RESP 0x0F
115 #define PTYPE_RPC_AUTH_3 0x10
116 #define PTYPE_SHUTDOWN 0x11
117 #define PTYPE_CO_CANCEL 0x12
118 #define PTYPE_ORPHANED 0x13
119 #define PTYPE_RTS 0x14
120 
121 #define PFC_FIRST_FRAG 0x01
122 #define PFC_LAST_FRAG 0x02
123 #define PFC_PENDING_CANCEL 0x04
124 #define PFC_SUPPORT_HEADER_SIGN 0x04
125 #define PFC_RESERVED_1 0x08
126 #define PFC_CONC_MPX 0x10
127 #define PFC_DID_NOT_EXECUTE 0x20
128 #define PFC_MAYBE 0x40
129 #define PFC_OBJECT_UUID 0x80
130 
131 /* Minimum fragment sizes */
132 #define RPC_CO_MUST_RECV_FRAG_SIZE 1432
133 #define RPC_CL_MUST_RECV_FRAG_SIZE 1464
134 
135 /**
136  * The PDU maximum header length is enough
137  * to contain either the RPC common fields
138  * or all fields up to the stub data in PDUs
139  * that use it (request, response, fault)
140  */
141 #define RPC_PDU_HEADER_MAX_LENGTH 32
142 
143 #pragma pack(push, 1)
144 
145 typedef UINT16 p_context_id_t;
146 typedef UINT16 p_reject_reason_t;
147 
148 typedef struct
149 {
150 	UINT32 time_low;
151 	UINT16 time_mid;
152 	UINT16 time_hi_and_version;
153 	BYTE clock_seq_hi_and_reserved;
154 	BYTE clock_seq_low;
155 	BYTE node[6];
156 } p_uuid_t;
157 
158 #define ndr_c_int_big_endian 0
159 #define ndr_c_int_little_endian 1
160 #define ndr_c_float_ieee 0
161 #define ndr_c_float_vax 1
162 #define ndr_c_float_cray 2
163 #define ndr_c_float_ibm 3
164 #define ndr_c_char_ascii 0
165 #define ndr_c_char_ebcdic 1
166 
167 typedef struct
168 {
169 	BYTE int_rep;
170 	BYTE char_rep;
171 	BYTE float_rep;
172 	BYTE reserved;
173 } ndr_format_t, *ndr_format_p_t;
174 
175 typedef struct ndr_context_handle
176 {
177 	UINT32 context_handle_attributes;
178 	p_uuid_t context_handle_uuid;
179 } ndr_context_handle;
180 
181 typedef struct
182 {
183 	p_uuid_t if_uuid;
184 	UINT32 if_version;
185 } p_syntax_id_t;
186 
187 typedef struct
188 {
189 	p_context_id_t p_cont_id;
190 	BYTE n_transfer_syn;              /* number of items */
191 	BYTE reserved;                    /* alignment pad, m.b.z. */
192 	p_syntax_id_t abstract_syntax;    /* transfer syntax list */
193 	p_syntax_id_t* transfer_syntaxes; /* size_is(n_transfer_syn) */
194 } p_cont_elem_t;
195 
196 typedef struct
197 {
198 	BYTE n_context_elem;        /* number of items */
199 	BYTE reserved;              /* alignment pad, m.b.z. */
200 	UINT16 reserved2;           /* alignment pad, m.b.z. */
201 	p_cont_elem_t* p_cont_elem; /* size_is(n_cont_elem) */
202 } p_cont_list_t;
203 
204 typedef enum
205 {
206 	acceptance,
207 	user_rejection,
208 	provider_rejection
209 } p_cont_def_result_t;
210 
211 typedef enum
212 {
213 	reason_not_specified,
214 	abstract_syntax_not_supported,
215 	proposed_transfer_syntaxes_not_supported,
216 	local_limit_exceeded
217 } p_provider_reason_t;
218 
219 typedef struct
220 {
221 	p_cont_def_result_t result;
222 	p_provider_reason_t reason;
223 	p_syntax_id_t transfer_syntax;
224 } p_result_t;
225 
226 /* Same order and number of elements as in bind request */
227 
228 typedef struct
229 {
230 	BYTE n_results;        /* count */
231 	BYTE reserved;         /* alignment pad, m.b.z. */
232 	UINT16 reserved2;      /* alignment pad, m.b.z. */
233 	p_result_t* p_results; /* size_is(n_results) */
234 } p_result_list_t;
235 
236 typedef struct
237 {
238 	BYTE major;
239 	BYTE minor;
240 } version_t;
241 typedef version_t p_rt_version_t;
242 
243 typedef struct
244 {
245 	BYTE n_protocols;            /* count */
246 	p_rt_version_t* p_protocols; /* size_is(n_protocols) */
247 } p_rt_versions_supported_t;
248 
249 typedef struct
250 {
251 	UINT16 length;
252 	char* port_spec; /* port string spec; size_is(length) */
253 } port_any_t;
254 
255 #define REASON_NOT_SPECIFIED 0
256 #define TEMPORARY_CONGESTION 1
257 #define LOCAL_LIMIT_EXCEEDED 2
258 #define CALLED_PADDR_UNKNOWN 3
259 #define PROTOCOL_VERSION_NOT_SUPPORTED 4
260 #define DEFAULT_CONTEXT_NOT_SUPPORTED 5
261 #define USER_DATA_NOT_READABLE 6
262 #define NO_PSAP_AVAILABLE 7
263 
264 typedef UINT16 rpcrt_reason_code_t;
265 
266 typedef struct
267 {
268 	BYTE rpc_vers;
269 	BYTE rpc_vers_minor;
270 	BYTE reserved[2];
271 	BYTE packed_drep[4];
272 	UINT32 reject_status;
273 	BYTE reserved2[4];
274 } rpcrt_optional_data_t;
275 
276 typedef struct
277 {
278 	rpcrt_reason_code_t reason_code;
279 	rpcrt_optional_data_t rpc_info;
280 } rpcconn_reject_optional_data_t;
281 
282 typedef struct
283 {
284 	rpcrt_reason_code_t reason_code;
285 	rpcrt_optional_data_t rpc_info;
286 } rpcconn_disc_optional_data_t;
287 
288 typedef struct
289 {
290 	BYTE signature[8];
291 } rpc_sec_verification_trailer;
292 
293 struct auth_verifier_co_s
294 {
295 	/* restore 4-byte alignment */
296 
297 	BYTE auth_type;
298 	BYTE auth_level;
299 	BYTE auth_pad_length;
300 	BYTE auth_reserved;
301 	UINT32 auth_context_id;
302 
303 	BYTE* auth_value;
304 };
305 
306 typedef struct auth_verifier_co_s rpc_sec_trailer;
307 typedef struct auth_verifier_co_s auth_verifier_co_t;
308 
309 /* Connection-oriented PDU Definitions */
310 
311 typedef struct
312 {
313 	rpcconn_common_hdr_t header;
314 
315 	UINT16 max_xmit_frag;
316 	UINT16 max_recv_frag;
317 	UINT32 assoc_group_id;
318 
319 	p_cont_list_t p_context_elem;
320 
321 	auth_verifier_co_t auth_verifier;
322 
323 } rpcconn_alter_context_hdr_t;
324 
325 typedef struct
326 {
327 	rpcconn_common_hdr_t header;
328 
329 	UINT16 max_xmit_frag;
330 	UINT16 max_recv_frag;
331 	UINT32 assoc_group_id;
332 	port_any_t sec_addr;
333 
334 	/* restore 4-octet alignment */
335 
336 	p_result_list_t p_result_list;
337 
338 	auth_verifier_co_t auth_verifier;
339 } rpcconn_alter_context_response_hdr_t;
340 
341 /*  bind header */
342 typedef struct
343 {
344 	rpcconn_common_hdr_t header;
345 
346 	UINT16 max_xmit_frag;
347 	UINT16 max_recv_frag;
348 	UINT32 assoc_group_id;
349 
350 	p_cont_list_t p_context_elem;
351 
352 	auth_verifier_co_t auth_verifier;
353 } rpcconn_bind_hdr_t;
354 
355 typedef struct
356 {
357 	rpcconn_common_hdr_t header;
358 
359 	UINT16 max_xmit_frag;
360 	UINT16 max_recv_frag;
361 	UINT32 assoc_group_id;
362 
363 	port_any_t sec_addr;
364 
365 	/* restore 4-octet alignment */
366 
367 	p_result_list_t p_result_list;
368 
369 	auth_verifier_co_t auth_verifier;
370 } rpcconn_bind_ack_hdr_t;
371 
372 typedef struct
373 {
374 	rpcconn_common_hdr_t header;
375 
376 	UINT16 max_xmit_frag;
377 	UINT16 max_recv_frag;
378 
379 	auth_verifier_co_t auth_verifier;
380 } rpcconn_rpc_auth_3_hdr_t;
381 
382 typedef struct
383 {
384 	rpcconn_common_hdr_t header;
385 
386 	p_reject_reason_t provider_reject_reason;
387 
388 	p_rt_versions_supported_t versions;
389 } rpcconn_bind_nak_hdr_t;
390 
391 typedef struct
392 {
393 	rpcconn_common_hdr_t header;
394 
395 	auth_verifier_co_t auth_verifier;
396 
397 } rpcconn_cancel_hdr_t;
398 
399 /* fault codes */
400 
401 struct _RPC_FAULT_CODE
402 {
403 	UINT32 code;
404 	const char* name;
405 	const char* category;
406 };
407 typedef struct _RPC_FAULT_CODE RPC_FAULT_CODE;
408 
409 #define DEFINE_RPC_FAULT_CODE(_code, cat) \
410 	{                                     \
411 		_code, #_code, cat                \
412 	}
413 
414 #define nca_s_comm_failure 0x1C010001
415 #define nca_s_op_rng_error 0x1C010002
416 #define nca_s_unk_if 0x1C010003
417 #define nca_s_wrong_boot_time 0x1C010006
418 #define nca_s_you_crashed 0x1C010009
419 #define nca_s_proto_error 0x1C01000B
420 #define nca_s_out_args_too_big 0x1C010013
421 #define nca_s_server_too_busy 0x1C010014
422 #define nca_s_fault_string_too_long 0x1C010015
423 #define nca_s_unsupported_type 0x1C010017
424 #define nca_s_fault_int_div_by_zero 0x1C000001
425 #define nca_s_fault_addr_error 0x1C000002
426 #define nca_s_fault_fp_div_zero 0x1C000003
427 #define nca_s_fault_fp_underflow 0x1C000004
428 #define nca_s_fault_fp_overflow 0x1C000005
429 #define nca_s_fault_invalid_tag 0x1C000006
430 #define nca_s_fault_invalid_bound 0x1C000007
431 #define nca_s_rpc_version_mismatch 0x1C000008
432 #define nca_s_unspec_reject 0x1C000009
433 #define nca_s_bad_actid 0x1C00000A
434 #define nca_s_who_are_you_failed 0x1C00000B
435 #define nca_s_manager_not_entered 0x1C00000C
436 #define nca_s_fault_cancel 0x1C00000D
437 #define nca_s_fault_ill_inst 0x1C00000E
438 #define nca_s_fault_fp_error 0x1C00000F
439 #define nca_s_fault_int_overflow 0x1C000010
440 #define nca_s_fault_unspec 0x1C000012
441 #define nca_s_fault_remote_comm_failure 0x1C000013
442 #define nca_s_fault_pipe_empty 0x1C000014
443 #define nca_s_fault_pipe_closed 0x1C000015
444 #define nca_s_fault_pipe_order 0x1C000016
445 #define nca_s_fault_pipe_discipline 0x1C000017
446 #define nca_s_fault_pipe_comm_error 0x1C000018
447 #define nca_s_fault_pipe_memory 0x1C000019
448 #define nca_s_fault_context_mismatch 0x1C00001A
449 #define nca_s_fault_remote_no_memory 0x1C00001B
450 #define nca_s_invalid_pres_context_id 0x1C00001C
451 #define nca_s_unsupported_authn_level 0x1C00001D
452 #define nca_s_invalid_checksum 0x1C00001F
453 #define nca_s_invalid_crc 0x1C000020
454 #define nca_s_fault_user_defined 0x1C000021
455 #define nca_s_fault_tx_open_failed 0x1C000022
456 #define nca_s_fault_codeset_conv_error 0x1C000023
457 #define nca_s_fault_object_not_found 0x1C000024
458 #define nca_s_fault_no_client_stub 0x1C000025
459 
460 typedef struct
461 {
462 	rpcconn_common_hdr_t header;
463 
464 	UINT32 alloc_hint;
465 	p_context_id_t p_cont_id;
466 
467 	BYTE cancel_count;
468 	BYTE reserved;
469 
470 	UINT32 status;
471 
472 	/* align(8) */
473 
474 	BYTE* stub_data;
475 
476 	auth_verifier_co_t auth_verifier;
477 } rpcconn_fault_hdr_t;
478 
479 typedef struct
480 {
481 	rpcconn_common_hdr_t header;
482 
483 	auth_verifier_co_t auth_verifier;
484 } rpcconn_orphaned_hdr_t;
485 
486 typedef struct
487 {
488 	rpcconn_common_hdr_t header;
489 
490 	UINT32 alloc_hint;
491 
492 	p_context_id_t p_cont_id;
493 	UINT16 opnum;
494 
495 	/* optional field for request, only present if the PFC_OBJECT_UUID field is non-zero */
496 	p_uuid_t object;
497 
498 	/* align(8) */
499 
500 	BYTE* stub_data;
501 
502 	auth_verifier_co_t auth_verifier;
503 } rpcconn_request_hdr_t;
504 
505 typedef struct
506 {
507 	rpcconn_common_hdr_t header;
508 
509 	UINT32 alloc_hint;
510 	p_context_id_t p_cont_id;
511 
512 	BYTE cancel_count;
513 	BYTE reserved;
514 
515 	/* align(8) */
516 
517 	BYTE* stub_data;
518 
519 	auth_verifier_co_t auth_verifier;
520 } rpcconn_response_hdr_t;
521 
522 typedef struct
523 {
524 	rpcconn_common_hdr_t header;
525 } rpcconn_shutdown_hdr_t;
526 
527 typedef union
528 {
529 	rpcconn_common_hdr_t common;
530 	rpcconn_alter_context_hdr_t alter_context;
531 	rpcconn_alter_context_response_hdr_t alter_context_response;
532 	rpcconn_bind_hdr_t bind;
533 	rpcconn_bind_ack_hdr_t bind_ack;
534 	rpcconn_rpc_auth_3_hdr_t rpc_auth_3;
535 	rpcconn_bind_nak_hdr_t bind_nak;
536 	rpcconn_cancel_hdr_t cancel;
537 	rpcconn_fault_hdr_t fault;
538 	rpcconn_orphaned_hdr_t orphaned;
539 	rpcconn_request_hdr_t request;
540 	rpcconn_response_hdr_t response;
541 	rpcconn_shutdown_hdr_t shutdown;
542 	rpcconn_rts_hdr_t rts;
543 } rpcconn_hdr_t;
544 
545 #pragma pack(pop)
546 
547 struct _RPC_SECURITY_PROVIDER_INFO
548 {
549 	UINT32 Id;
550 	LONG EvenLegs;
551 	LONG NumLegs;
552 };
553 typedef struct _RPC_SECURITY_PROVIDER_INFO RPC_SECURITY_PROVIDER_INFO;
554 
555 enum _RPC_CLIENT_STATE
556 {
557 	RPC_CLIENT_STATE_INITIAL,
558 	RPC_CLIENT_STATE_ESTABLISHED,
559 	RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK,
560 	RPC_CLIENT_STATE_WAIT_UNSECURE_BIND_ACK,
561 	RPC_CLIENT_STATE_WAIT_SECURE_ALTER_CONTEXT_RESPONSE,
562 	RPC_CLIENT_STATE_CONTEXT_NEGOTIATED,
563 	RPC_CLIENT_STATE_WAIT_RESPONSE,
564 	RPC_CLIENT_STATE_FINAL
565 };
566 typedef enum _RPC_CLIENT_STATE RPC_CLIENT_STATE;
567 
568 enum _RPC_CLIENT_CALL_STATE
569 {
570 	RPC_CLIENT_CALL_STATE_INITIAL,
571 	RPC_CLIENT_CALL_STATE_SEND_PDUS,
572 	RPC_CLIENT_CALL_STATE_DISPATCHED,
573 	RPC_CLIENT_CALL_STATE_RECEIVE_PDU,
574 	RPC_CLIENT_CALL_STATE_COMPLETE,
575 	RPC_CLIENT_CALL_STATE_FAULT,
576 	RPC_CLIENT_CALL_STATE_FINAL
577 };
578 typedef enum _RPC_CLIENT_CALL_STATE RPC_CLIENT_CALL_STATE;
579 
580 struct rpc_client_call
581 {
582 	UINT32 CallId;
583 	UINT32 OpNum;
584 	RPC_CLIENT_CALL_STATE State;
585 };
586 typedef struct rpc_client_call RpcClientCall;
587 
588 struct rpc_client
589 {
590 	rdpContext* context;
591 	RPC_PDU* pdu;
592 	HANDLE PipeEvent;
593 	RingBuffer ReceivePipe;
594 	wStream* ReceiveFragment;
595 	CRITICAL_SECTION PipeLock;
596 	wArrayList* ClientCallList;
597 	char* host;
598 	UINT16 port;
599 	BOOL isProxy;
600 };
601 typedef struct rpc_client RpcClient;
602 
603 struct rpc_channel
604 {
605 	RpcClient* client;
606 	BIO* bio;
607 	rdpTls* tls;
608 	rdpNtlm* ntlm;
609 	HttpContext* http;
610 	BYTE Cookie[16];
611 };
612 typedef struct rpc_channel RpcChannel;
613 
614 /* Ping Originator */
615 
616 struct rpc_ping_originator
617 {
618 	UINT32 ConnectionTimeout;
619 	UINT32 LastPacketSentTimestamp;
620 	UINT32 KeepAliveInterval;
621 };
622 typedef struct rpc_ping_originator RpcPingOriginator;
623 
624 /* Client In Channel */
625 
626 enum _CLIENT_IN_CHANNEL_STATE
627 {
628 	CLIENT_IN_CHANNEL_STATE_INITIAL,
629 	CLIENT_IN_CHANNEL_STATE_CONNECTED,
630 	CLIENT_IN_CHANNEL_STATE_SECURITY,
631 	CLIENT_IN_CHANNEL_STATE_NEGOTIATED,
632 	CLIENT_IN_CHANNEL_STATE_OPENED,
633 	CLIENT_IN_CHANNEL_STATE_OPENED_A4W,
634 	CLIENT_IN_CHANNEL_STATE_FINAL
635 };
636 typedef enum _CLIENT_IN_CHANNEL_STATE CLIENT_IN_CHANNEL_STATE;
637 
638 struct rpc_in_channel
639 {
640 	/* Sending Channel */
641 
642 	RpcChannel common;
643 
644 	CLIENT_IN_CHANNEL_STATE State;
645 
646 	UINT32 PlugState;
647 	void* SendQueue;
648 	UINT32 BytesSent;
649 	UINT32 SenderAvailableWindow;
650 	UINT32 PeerReceiveWindow;
651 
652 	/* Ping Originator */
653 
654 	RpcPingOriginator PingOriginator;
655 };
656 typedef struct rpc_in_channel RpcInChannel;
657 
658 /* Client Out Channel */
659 
660 enum _CLIENT_OUT_CHANNEL_STATE
661 {
662 	CLIENT_OUT_CHANNEL_STATE_INITIAL,
663 	CLIENT_OUT_CHANNEL_STATE_CONNECTED,
664 	CLIENT_OUT_CHANNEL_STATE_SECURITY,
665 	CLIENT_OUT_CHANNEL_STATE_NEGOTIATED,
666 	CLIENT_OUT_CHANNEL_STATE_OPENED,
667 	CLIENT_OUT_CHANNEL_STATE_OPENED_A6W,
668 	CLIENT_OUT_CHANNEL_STATE_OPENED_A10W,
669 	CLIENT_OUT_CHANNEL_STATE_OPENED_B3W,
670 	CLIENT_OUT_CHANNEL_STATE_RECYCLED,
671 	CLIENT_OUT_CHANNEL_STATE_FINAL
672 };
673 typedef enum _CLIENT_OUT_CHANNEL_STATE CLIENT_OUT_CHANNEL_STATE;
674 
675 struct rpc_out_channel
676 {
677 	/* Receiving Channel */
678 
679 	RpcChannel common;
680 
681 	CLIENT_OUT_CHANNEL_STATE State;
682 
683 	UINT32 ReceiveWindow;
684 	UINT32 ReceiveWindowSize;
685 	UINT32 ReceiverAvailableWindow;
686 	UINT32 BytesReceived;
687 	UINT32 AvailableWindowAdvertised;
688 };
689 typedef struct rpc_out_channel RpcOutChannel;
690 
691 /* Client Virtual Connection */
692 
693 enum _VIRTUAL_CONNECTION_STATE
694 {
695 	VIRTUAL_CONNECTION_STATE_INITIAL,
696 	VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT,
697 	VIRTUAL_CONNECTION_STATE_WAIT_A3W,
698 	VIRTUAL_CONNECTION_STATE_WAIT_C2,
699 	VIRTUAL_CONNECTION_STATE_OPENED,
700 	VIRTUAL_CONNECTION_STATE_FINAL
701 };
702 typedef enum _VIRTUAL_CONNECTION_STATE VIRTUAL_CONNECTION_STATE;
703 
704 struct rpc_virtual_connection
705 {
706 	BYTE Cookie[16];
707 	BYTE AssociationGroupId[16];
708 	VIRTUAL_CONNECTION_STATE State;
709 	RpcInChannel* DefaultInChannel;
710 	RpcInChannel* NonDefaultInChannel;
711 	RpcOutChannel* DefaultOutChannel;
712 	RpcOutChannel* NonDefaultOutChannel;
713 };
714 typedef struct rpc_virtual_connection RpcVirtualConnection;
715 
716 /* Virtual Connection Cookie Table */
717 
718 #define RPC_UUID_FORMAT_STRING \
719 	"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
720 #define RPC_UUID_FORMAT_ARGUMENTS(_rpc_uuid)                                                  \
721 	_rpc_uuid[0], _rpc_uuid[1], _rpc_uuid[2], _rpc_uuid[3], _rpc_uuid[4], _rpc_uuid[5],       \
722 	    _rpc_uuid[6], _rpc_uuid[7], _rpc_uuid[8], _rpc_uuid[9], _rpc_uuid[10], _rpc_uuid[11], \
723 	    _rpc_uuid[12], _rpc_uuid[13], _rpc_uuid[14], _rpc_uuid[15]
724 
725 struct rpc_virtual_connection_cookie_entry
726 {
727 	BYTE Cookie[16];
728 	UINT32 ReferenceCount;
729 	RpcVirtualConnection* Reference;
730 };
731 typedef struct rpc_virtual_connection_cookie_entry RpcVirtualConnectionCookieEntry;
732 
733 struct rdp_rpc
734 {
735 	RPC_CLIENT_STATE State;
736 
737 	UINT32 result;
738 
739 	rdpNtlm* ntlm;
740 	int SendSeqNum;
741 
742 	RpcClient* client;
743 
744 	rdpContext* context;
745 	rdpSettings* settings;
746 	rdpTransport* transport;
747 
748 	UINT32 CallId;
749 	UINT32 PipeCallId;
750 
751 	UINT32 StubCallId;
752 	UINT32 StubFragCount;
753 
754 	BYTE rpc_vers;
755 	BYTE rpc_vers_minor;
756 	BYTE packed_drep[4];
757 
758 	UINT16 max_xmit_frag;
759 	UINT16 max_recv_frag;
760 
761 	UINT32 ReceiveWindow;
762 	UINT32 ChannelLifetime;
763 	UINT32 KeepAliveInterval;
764 	UINT32 CurrentKeepAliveTime;
765 	UINT32 CurrentKeepAliveInterval;
766 
767 	RpcVirtualConnection* VirtualConnection;
768 };
769 
770 FREERDP_LOCAL void rpc_pdu_header_print(const rpcconn_hdr_t* header);
771 FREERDP_LOCAL rpcconn_common_hdr_t rpc_pdu_header_init(const rdpRpc* rpc);
772 
773 FREERDP_LOCAL size_t rpc_offset_align(size_t* offset, size_t alignment);
774 FREERDP_LOCAL size_t rpc_offset_pad(size_t* offset, size_t pad);
775 
776 FREERDP_LOCAL BOOL rpc_get_stub_data_info(const rpcconn_hdr_t* header, size_t* offset,
777                                           size_t* length);
778 
779 FREERDP_LOCAL SSIZE_T rpc_channel_write(RpcChannel* channel, const BYTE* data, size_t length);
780 
781 FREERDP_LOCAL SSIZE_T rpc_channel_read(RpcChannel* channel, wStream* s, size_t length);
782 
783 FREERDP_LOCAL void rpc_channel_free(RpcChannel* channel);
784 
785 FREERDP_LOCAL RpcOutChannel* rpc_out_channel_new(rdpRpc* rpc);
786 FREERDP_LOCAL int rpc_out_channel_replacement_connect(RpcOutChannel* outChannel, int timeout);
787 
788 FREERDP_LOCAL BOOL rpc_in_channel_transition_to_state(RpcInChannel* inChannel,
789                                                       CLIENT_IN_CHANNEL_STATE state);
790 FREERDP_LOCAL BOOL rpc_out_channel_transition_to_state(RpcOutChannel* outChannel,
791                                                        CLIENT_OUT_CHANNEL_STATE state);
792 
793 FREERDP_LOCAL BOOL rpc_virtual_connection_transition_to_state(rdpRpc* rpc,
794                                                               RpcVirtualConnection* connection,
795                                                               VIRTUAL_CONNECTION_STATE state);
796 
797 FREERDP_LOCAL BOOL rpc_connect(rdpRpc* rpc, UINT32 timeout);
798 
799 FREERDP_LOCAL rdpRpc* rpc_new(rdpTransport* transport);
800 FREERDP_LOCAL void rpc_free(rdpRpc* rpc);
801 
802 #endif /* FREERDP_LIB_CORE_GATEWAY_RPC_H */
803