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} p_cont_def_result_t;
211
212typedef enum
213{
214 reason_not_specified,
215 abstract_syntax_not_supported,
216 proposed_transfer_syntaxes_not_supported,
217 local_limit_exceeded
218} p_provider_reason_t;
219
220typedef struct
221{
222 p_cont_def_result_t result;
223 p_provider_reason_t reason;
224 p_syntax_id_t transfer_syntax;
225} p_result_t;
226
227/* Same order and number of elements as in bind request */
228
229typedef struct
230{
231 BYTE n_results; /* count */
232 BYTE reserved; /* alignment pad, m.b.z. */
233 UINT16 reserved2; /* alignment pad, m.b.z. */
234 p_result_t* p_results; /* size_is(n_results) */
236
237typedef struct
238{
239 BYTE major;
240 BYTE minor;
241} version_t;
243
244typedef struct
245{
246 BYTE n_protocols; /* count */
247 p_rt_version_t* p_protocols; /* size_is(n_protocols) */
249
250typedef struct
251{
252 UINT16 length;
253 char* port_spec; /* port string spec; size_is(length) */
254} port_any_t;
255
256#define REASON_NOT_SPECIFIED 0
257#define TEMPORARY_CONGESTION 1
258#define LOCAL_LIMIT_EXCEEDED 2
259#define CALLED_PADDR_UNKNOWN 3
260#define PROTOCOL_VERSION_NOT_SUPPORTED 4
261#define DEFAULT_CONTEXT_NOT_SUPPORTED 5
262#define USER_DATA_NOT_READABLE 6
263#define NO_PSAP_AVAILABLE 7
264
265typedef UINT16 rpcrt_reason_code_t;
266
267typedef struct
268{
269 BYTE rpc_vers;
270 BYTE rpc_vers_minor;
271 BYTE reserved[2];
272 BYTE packed_drep[4];
273 UINT32 reject_status;
274 BYTE reserved2[4];
276
277typedef struct
278{
279 rpcrt_reason_code_t reason_code;
280 rpcrt_optional_data_t rpc_info;
282
283typedef struct
284{
285 rpcrt_reason_code_t reason_code;
286 rpcrt_optional_data_t rpc_info;
288
289typedef struct
290{
291 BYTE signature[8];
293
295{
296 /* restore 4-byte alignment */
297
298 BYTE auth_type;
299 BYTE auth_level;
300 BYTE auth_pad_length;
301 BYTE auth_reserved;
302 UINT32 auth_context_id;
303
304 BYTE* auth_value;
305};
306
307typedef struct auth_verifier_co_s rpc_sec_trailer;
308typedef struct auth_verifier_co_s auth_verifier_co_t;
309
310/* Connection-oriented PDU Definitions */
311
312typedef struct
313{
315
316 UINT16 max_xmit_frag;
317 UINT16 max_recv_frag;
318 UINT32 assoc_group_id;
319
320 p_cont_list_t p_context_elem;
321
322 auth_verifier_co_t auth_verifier;
323
325
326typedef struct
327{
329
330 UINT16 max_xmit_frag;
331 UINT16 max_recv_frag;
332 UINT32 assoc_group_id;
333 port_any_t sec_addr;
334
335 /* restore 4-octet alignment */
336
337 p_result_list_t p_result_list;
338
339 auth_verifier_co_t auth_verifier;
341
342/* bind header */
343typedef struct
344{
346
347 UINT16 max_xmit_frag;
348 UINT16 max_recv_frag;
349 UINT32 assoc_group_id;
350
351 p_cont_list_t p_context_elem;
352
353 auth_verifier_co_t auth_verifier;
355
356typedef struct
357{
359
360 UINT16 max_xmit_frag;
361 UINT16 max_recv_frag;
362 UINT32 assoc_group_id;
363
364 port_any_t sec_addr;
365
366 /* restore 4-octet alignment */
367
368 p_result_list_t p_result_list;
369
370 auth_verifier_co_t auth_verifier;
372
373typedef struct
374{
376
377 UINT16 max_xmit_frag;
378 UINT16 max_recv_frag;
379
380 auth_verifier_co_t auth_verifier;
382
383typedef struct
384{
386
387 p_reject_reason_t provider_reject_reason;
388
391
392typedef struct
393{
395
396 auth_verifier_co_t auth_verifier;
397
399
400#pragma pack(pop)
401
402/* fault codes */
403
404typedef struct
405{
406 UINT32 code;
407 const char* name;
408 const char* category;
410
411#define DEFINE_RPC_FAULT_CODE(_code, cat) \
412 { \
413 _code, #_code, cat \
414 }
415
416#define nca_s_comm_failure 0x1C010001
417#define nca_s_op_rng_error 0x1C010002
418#define nca_s_unk_if 0x1C010003
419#define nca_s_wrong_boot_time 0x1C010006
420#define nca_s_you_crashed 0x1C010009
421#define nca_s_proto_error 0x1C01000B
422#define nca_s_out_args_too_big 0x1C010013
423#define nca_s_server_too_busy 0x1C010014
424#define nca_s_fault_string_too_long 0x1C010015
425#define nca_s_unsupported_type 0x1C010017
426#define nca_s_fault_int_div_by_zero 0x1C000001
427#define nca_s_fault_addr_error 0x1C000002
428#define nca_s_fault_fp_div_zero 0x1C000003
429#define nca_s_fault_fp_underflow 0x1C000004
430#define nca_s_fault_fp_overflow 0x1C000005
431#define nca_s_fault_invalid_tag 0x1C000006
432#define nca_s_fault_invalid_bound 0x1C000007
433#define nca_s_rpc_version_mismatch 0x1C000008
434#define nca_s_unspec_reject 0x1C000009
435#define nca_s_bad_actid 0x1C00000A
436#define nca_s_who_are_you_failed 0x1C00000B
437#define nca_s_manager_not_entered 0x1C00000C
438#define nca_s_fault_cancel 0x1C00000D
439#define nca_s_fault_ill_inst 0x1C00000E
440#define nca_s_fault_fp_error 0x1C00000F
441#define nca_s_fault_int_overflow 0x1C000010
442#define nca_s_fault_unspec 0x1C000012
443#define nca_s_fault_remote_comm_failure 0x1C000013
444#define nca_s_fault_pipe_empty 0x1C000014
445#define nca_s_fault_pipe_closed 0x1C000015
446#define nca_s_fault_pipe_order 0x1C000016
447#define nca_s_fault_pipe_discipline 0x1C000017
448#define nca_s_fault_pipe_comm_error 0x1C000018
449#define nca_s_fault_pipe_memory 0x1C000019
450#define nca_s_fault_context_mismatch 0x1C00001A
451#define nca_s_fault_remote_no_memory 0x1C00001B
452#define nca_s_invalid_pres_context_id 0x1C00001C
453#define nca_s_unsupported_authn_level 0x1C00001D
454#define nca_s_invalid_checksum 0x1C00001F
455#define nca_s_invalid_crc 0x1C000020
456#define nca_s_fault_user_defined 0x1C000021
457#define nca_s_fault_tx_open_failed 0x1C000022
458#define nca_s_fault_codeset_conv_error 0x1C000023
459#define nca_s_fault_object_not_found 0x1C000024
460#define nca_s_fault_no_client_stub 0x1C000025
461
462#pragma pack(push, 1)
463
464typedef struct
465{
467
468 UINT32 alloc_hint;
469 p_context_id_t p_cont_id;
470
471 BYTE cancel_count;
472 BYTE reserved;
473
474 UINT32 status;
475
476 /* align(8) */
477
478 BYTE* stub_data;
479
480 auth_verifier_co_t auth_verifier;
482
483typedef struct
484{
486
487 auth_verifier_co_t auth_verifier;
489
490typedef struct
491{
493
494 UINT32 alloc_hint;
495
496 p_context_id_t p_cont_id;
497 UINT16 opnum;
498
499 /* optional field for request, only present if the PFC_OBJECT_UUID field is non-zero */
500 p_uuid_t object;
501
502 /* align(8) */
503
504 BYTE* stub_data;
505
506 auth_verifier_co_t auth_verifier;
508
509typedef struct
510{
512
513 UINT32 alloc_hint;
514 p_context_id_t p_cont_id;
515
516 BYTE cancel_count;
517 BYTE reserved;
518
519 /* align(8) */
520
521 BYTE* stub_data;
522
523 auth_verifier_co_t auth_verifier;
525
526typedef struct
527{
530
531typedef union
532{
534 rpcconn_alter_context_hdr_t alter_context;
535 rpcconn_alter_context_response_hdr_t alter_context_response;
537 rpcconn_bind_ack_hdr_t bind_ack;
538 rpcconn_rpc_auth_3_hdr_t rpc_auth_3;
539 rpcconn_bind_nak_hdr_t bind_nak;
542 rpcconn_orphaned_hdr_t orphaned;
543 rpcconn_request_hdr_t request;
544 rpcconn_response_hdr_t response;
545 rpcconn_shutdown_hdr_t shutdown;
548
549#pragma pack(pop)
550
551typedef struct
552{
553 UINT32 Id;
554 LONG EvenLegs;
555 LONG NumLegs;
557
558typedef enum
559{
560 RPC_CLIENT_STATE_INITIAL,
561 RPC_CLIENT_STATE_ESTABLISHED,
562 RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK,
563 RPC_CLIENT_STATE_WAIT_UNSECURE_BIND_ACK,
564 RPC_CLIENT_STATE_WAIT_SECURE_ALTER_CONTEXT_RESPONSE,
565 RPC_CLIENT_STATE_CONTEXT_NEGOTIATED,
566 RPC_CLIENT_STATE_WAIT_RESPONSE,
567 RPC_CLIENT_STATE_FINAL
568} RPC_CLIENT_STATE;
569
570typedef enum
571{
572 RPC_CLIENT_CALL_STATE_INITIAL,
573 RPC_CLIENT_CALL_STATE_SEND_PDUS,
574 RPC_CLIENT_CALL_STATE_DISPATCHED,
575 RPC_CLIENT_CALL_STATE_RECEIVE_PDU,
576 RPC_CLIENT_CALL_STATE_COMPLETE,
577 RPC_CLIENT_CALL_STATE_FAULT,
578 RPC_CLIENT_CALL_STATE_FINAL
579} RPC_CLIENT_CALL_STATE;
580
581typedef struct
582{
583 UINT32 CallId;
584 UINT32 OpNum;
585 RPC_CLIENT_CALL_STATE State;
587
588typedef struct
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} RpcClient;
601
602typedef struct
603{
604 RpcClient* client;
605 BIO* bio;
606 rdpTls* tls;
607 rdpCredsspAuth* auth;
608 HttpContext* http;
609 GUID Cookie;
610 rdpRpc* rpc;
611} RpcChannel;
612
613/* Ping Originator */
614
615typedef struct
616{
617 UINT32 ConnectionTimeout;
618 UINT32 LastPacketSentTimestamp;
619 UINT32 KeepAliveInterval;
621
622/* Client In Channel */
623
624typedef enum
625{
626 CLIENT_IN_CHANNEL_STATE_INITIAL,
627 CLIENT_IN_CHANNEL_STATE_CONNECTED,
628 CLIENT_IN_CHANNEL_STATE_SECURITY,
629 CLIENT_IN_CHANNEL_STATE_NEGOTIATED,
630 CLIENT_IN_CHANNEL_STATE_OPENED,
631 CLIENT_IN_CHANNEL_STATE_OPENED_A4W,
632 CLIENT_IN_CHANNEL_STATE_FINAL
633} CLIENT_IN_CHANNEL_STATE;
634
635typedef struct
636{
637 /* Sending Channel */
638
639 RpcChannel common;
640
641 CLIENT_IN_CHANNEL_STATE State;
642
643 UINT32 PlugState;
644 void* SendQueue;
645 UINT32 BytesSent;
646 UINT32 SenderAvailableWindow;
647 UINT32 PeerReceiveWindow;
648
649 /* Ping Originator */
650
651 RpcPingOriginator PingOriginator;
653
654/* Client Out Channel */
655
656typedef enum
657{
658 CLIENT_OUT_CHANNEL_STATE_INITIAL,
659 CLIENT_OUT_CHANNEL_STATE_CONNECTED,
660 CLIENT_OUT_CHANNEL_STATE_SECURITY,
661 CLIENT_OUT_CHANNEL_STATE_NEGOTIATED,
662 CLIENT_OUT_CHANNEL_STATE_OPENED,
663 CLIENT_OUT_CHANNEL_STATE_OPENED_A6W,
664 CLIENT_OUT_CHANNEL_STATE_OPENED_A10W,
665 CLIENT_OUT_CHANNEL_STATE_OPENED_B3W,
666 CLIENT_OUT_CHANNEL_STATE_RECYCLED,
667 CLIENT_OUT_CHANNEL_STATE_FINAL
668} CLIENT_OUT_CHANNEL_STATE;
669
670typedef struct
671{
672 /* Receiving Channel */
673
674 RpcChannel common;
675
676 CLIENT_OUT_CHANNEL_STATE State;
677
678 UINT32 ReceiveWindow;
679 UINT32 ReceiveWindowSize;
680 UINT32 ReceiverAvailableWindow;
681 UINT32 BytesReceived;
682 UINT32 AvailableWindowAdvertised;
684
685/* Client Virtual Connection */
686
687typedef enum
688{
689 VIRTUAL_CONNECTION_STATE_INITIAL,
690 VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT,
691 VIRTUAL_CONNECTION_STATE_WAIT_A3W,
692 VIRTUAL_CONNECTION_STATE_WAIT_C2,
693 VIRTUAL_CONNECTION_STATE_OPENED,
694 VIRTUAL_CONNECTION_STATE_FINAL
695} VIRTUAL_CONNECTION_STATE;
696
697typedef struct
698{
699 GUID Cookie;
700 GUID AssociationGroupId;
701 VIRTUAL_CONNECTION_STATE State;
702 RpcInChannel* DefaultInChannel;
703 RpcInChannel* NonDefaultInChannel;
704 RpcOutChannel* DefaultOutChannel;
705 RpcOutChannel* NonDefaultOutChannel;
707
708/* Virtual Connection Cookie Table */
709
710#define RPC_UUID_FORMAT_STRING \
711 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
712#define RPC_UUID_FORMAT_ARGUMENTS(_rpc_uuid) \
713 _rpc_uuid[0], _rpc_uuid[1], _rpc_uuid[2], _rpc_uuid[3], _rpc_uuid[4], _rpc_uuid[5], \
714 _rpc_uuid[6], _rpc_uuid[7], _rpc_uuid[8], _rpc_uuid[9], _rpc_uuid[10], _rpc_uuid[11], \
715 _rpc_uuid[12], _rpc_uuid[13], _rpc_uuid[14], _rpc_uuid[15]
716
717typedef struct
718{
719 GUID Cookie;
720 UINT32 ReferenceCount;
721 RpcVirtualConnection* Reference;
723
725{
726 RPC_CLIENT_STATE State;
727
728 UINT32 result;
729
730 rdpCredsspAuth* auth;
731 UINT32 SendSeqNum;
732
733 RpcClient* client;
734
735 rdpTransport* transport;
736
737 UINT32 CallId;
738 UINT32 PipeCallId;
739
740 UINT32 StubCallId;
741 UINT32 StubFragCount;
742
743 BYTE rpc_vers;
744 BYTE rpc_vers_minor;
745 BYTE packed_drep[4];
746
747 UINT16 max_xmit_frag;
748 UINT16 max_recv_frag;
749
750 UINT32 ReceiveWindow;
751 UINT32 ChannelLifetime;
752 UINT32 KeepAliveInterval;
753 UINT32 CurrentKeepAliveTime;
754 UINT32 CurrentKeepAliveInterval;
755
756 RpcVirtualConnection* VirtualConnection;
757 wLog* log;
758};
759
760FREERDP_LOCAL const char* rpc_vc_state_str(VIRTUAL_CONNECTION_STATE state);
761FREERDP_LOCAL void rpc_pdu_header_print(wLog* log, const rpcconn_hdr_t* header);
762FREERDP_LOCAL rpcconn_common_hdr_t rpc_pdu_header_init(const rdpRpc* rpc);
763
764FREERDP_LOCAL size_t rpc_offset_align(size_t* offset, size_t alignment);
765FREERDP_LOCAL size_t rpc_offset_pad(size_t* offset, size_t pad);
766
767FREERDP_LOCAL BOOL rpc_get_stub_data_info(rdpRpc* rpc, const rpcconn_hdr_t* header, size_t* offset,
768 size_t* length);
769
770#define rpc_channel_write(channel, data, length) \
771 rpc_channel_write_int((channel), (data), (length), __FILE__, __LINE__, __func__)
772FREERDP_LOCAL SSIZE_T rpc_channel_write_int(RpcChannel* channel, const BYTE* data, size_t length,
773 const char* file, size_t line, const char* fkt);
774
775FREERDP_LOCAL SSIZE_T rpc_channel_read(RpcChannel* channel, wStream* s, size_t length);
776
777FREERDP_LOCAL void rpc_channel_free(RpcChannel* channel);
778
779WINPR_ATTR_MALLOC(rpc_channel_free, 1)
780FREERDP_LOCAL RpcOutChannel* rpc_out_channel_new(rdpRpc* rpc, const GUID* guid);
781FREERDP_LOCAL int rpc_out_channel_replacement_connect(RpcOutChannel* outChannel, uint32_t timeout);
782
783FREERDP_LOCAL BOOL rpc_in_channel_transition_to_state(RpcInChannel* inChannel,
784 CLIENT_IN_CHANNEL_STATE state);
785FREERDP_LOCAL BOOL rpc_out_channel_transition_to_state(RpcOutChannel* outChannel,
786 CLIENT_OUT_CHANNEL_STATE state);
787
788FREERDP_LOCAL BOOL rpc_virtual_connection_transition_to_state(rdpRpc* rpc,
789 RpcVirtualConnection* connection,
790 VIRTUAL_CONNECTION_STATE state);
791
792FREERDP_LOCAL BOOL rpc_connect(rdpRpc* rpc, UINT32 timeout);
793
794FREERDP_LOCAL void rpc_free(rdpRpc* rpc);
795
796WINPR_ATTR_MALLOC(rpc_free, 1)
797FREERDP_LOCAL rdpRpc* rpc_new(rdpTransport* transport);
798
799#endif /* FREERDP_LIB_CORE_GATEWAY_RPC_H */
ring buffer meta data
Definition ringbuffer.h:33