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