2
* FreeRDP: A Remote Desktop Protocol Implementation
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>
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
13
* http://www.apache.org/licenses/LICENSE-2.0
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.
22
#ifndef FREERDP_CORE_RPC_H
23
#define FREERDP_CORE_RPC_H
25
#include <winpr/wtypes.h>
26
#include <winpr/stream.h>
27
#include <winpr/collections.h>
28
#include <winpr/interlocked.h>
30
typedef struct rdp_rpc rdpRpc;
32
#define DEFINE_RPC_COMMON_FIELDS() \
34
BYTE rpc_vers_minor; \
37
BYTE packed_drep[4]; \
42
#define RPC_COMMON_FIELDS_LENGTH 16
46
DEFINE_RPC_COMMON_FIELDS();
49
UINT16 NumberOfCommands;
52
#define RTS_PDU_HEADER_LENGTH 20
54
#define RPC_PDU_FLAG_STUB 0x00000001
56
typedef struct _RPC_PDU
64
#include "../transport.h"
72
#include <winpr/sspi.h>
73
#include <winpr/interlocked.h>
75
#include <freerdp/types.h>
76
#include <freerdp/settings.h>
77
#include <freerdp/crypto/tls.h>
78
#include <freerdp/crypto/crypto.h>
79
#include <freerdp/utils/debug.h>
80
#include <winpr/print.h>
84
* DCE 1.1: Remote Procedure Call
85
* Document Number: C706
86
* http://pubs.opengroup.org/onlinepubs/9629399/
89
#define PTYPE_REQUEST 0x00
90
#define PTYPE_PING 0x01
91
#define PTYPE_RESPONSE 0x02
92
#define PTYPE_FAULT 0x03
93
#define PTYPE_WORKING 0x04
94
#define PTYPE_NOCALL 0x05
95
#define PTYPE_REJECT 0x06
96
#define PTYPE_ACK 0x07
97
#define PTYPE_CL_CANCEL 0x08
98
#define PTYPE_FACK 0x09
99
#define PTYPE_CANCEL_ACK 0x0A
100
#define PTYPE_BIND 0x0B
101
#define PTYPE_BIND_ACK 0x0C
102
#define PTYPE_BIND_NAK 0x0D
103
#define PTYPE_ALTER_CONTEXT 0x0E
104
#define PTYPE_ALTER_CONTEXT_RESP 0x0F
105
#define PTYPE_RPC_AUTH_3 0x10
106
#define PTYPE_SHUTDOWN 0x11
107
#define PTYPE_CO_CANCEL 0x12
108
#define PTYPE_ORPHANED 0x13
109
#define PTYPE_RTS 0x14
111
#define PFC_FIRST_FRAG 0x01
112
#define PFC_LAST_FRAG 0x02
113
#define PFC_PENDING_CANCEL 0x04
114
#define PFC_SUPPORT_HEADER_SIGN 0x04
115
#define PFC_RESERVED_1 0x08
116
#define PFC_CONC_MPX 0x10
117
#define PFC_DID_NOT_EXECUTE 0x20
118
#define PFC_MAYBE 0x40
119
#define PFC_OBJECT_UUID 0x80
121
/* Minimum fragment sizes */
122
#define RPC_CO_MUST_RECV_FRAG_SIZE 1432
123
#define RPC_CL_MUST_RECV_FRAG_SIZE 1464
126
* The PDU maximum header length is enough
127
* to contain either the RPC common fields
128
* or all fields up to the stub data in PDUs
129
* that use it (request, response, fault)
131
#define RPC_PDU_HEADER_MAX_LENGTH 32
135
DEFINE_RPC_COMMON_FIELDS();
136
} rpcconn_common_hdr_t;
138
typedef UINT16 p_context_id_t;
139
typedef UINT16 p_reject_reason_t;
145
UINT16 time_hi_and_version;
146
BYTE clock_seq_hi_and_reserved;
151
#define ndr_c_int_big_endian 0
152
#define ndr_c_int_little_endian 1
153
#define ndr_c_float_ieee 0
154
#define ndr_c_float_vax 1
155
#define ndr_c_float_cray 2
156
#define ndr_c_float_ibm 3
157
#define ndr_c_char_ascii 0
158
#define ndr_c_char_ebcdic 1
166
} ndr_format_t, *ndr_format_p_t;
168
typedef struct ndr_context_handle
170
UINT32 context_handle_attributes;
171
p_uuid_t context_handle_uuid;
172
} ndr_context_handle;
182
p_context_id_t p_cont_id;
183
BYTE n_transfer_syn; /* number of items */
184
BYTE reserved; /* alignment pad, m.b.z. */
185
p_syntax_id_t abstract_syntax; /* transfer syntax list */
186
p_syntax_id_t* transfer_syntaxes; /* size_is(n_transfer_syn) */
191
BYTE n_context_elem; /* number of items */
192
BYTE reserved; /* alignment pad, m.b.z. */
193
UINT16 reserved2; /* alignment pad, m.b.z. */
194
p_cont_elem_t* p_cont_elem; /* size_is(n_cont_elem) */
202
} p_cont_def_result_t;
206
reason_not_specified,
207
abstract_syntax_not_supported,
208
proposed_transfer_syntaxes_not_supported,
210
} p_provider_reason_t;
214
p_cont_def_result_t result;
215
p_provider_reason_t reason;
216
p_syntax_id_t transfer_syntax;
219
/* Same order and number of elements as in bind request */
223
BYTE n_results; /* count */
224
BYTE reserved; /* alignment pad, m.b.z. */
225
UINT16 reserved2; /* alignment pad, m.b.z. */
226
p_result_t* p_results; /* size_is(n_results) */
234
typedef version_t p_rt_version_t;
238
BYTE n_protocols; /* count */
239
p_rt_version_t* p_protocols; /* size_is(n_protocols) */
240
} p_rt_versions_supported_t;
245
char* port_spec; /* port string spec; size_is(length) */
248
#define REASON_NOT_SPECIFIED 0
249
#define TEMPORARY_CONGESTION 1
250
#define LOCAL_LIMIT_EXCEEDED 2
251
#define CALLED_PADDR_UNKNOWN 3
252
#define PROTOCOL_VERSION_NOT_SUPPORTED 4
253
#define DEFAULT_CONTEXT_NOT_SUPPORTED 5
254
#define USER_DATA_NOT_READABLE 6
255
#define NO_PSAP_AVAILABLE 7
257
typedef UINT16 rpcrt_reason_code_t;
265
UINT32 reject_status;
267
} rpcrt_optional_data_t;
271
rpcrt_reason_code_t reason_code;
272
rpcrt_optional_data_t rpc_info;
273
} rpcconn_reject_optional_data_t;
277
rpcrt_reason_code_t reason_code;
278
rpcrt_optional_data_t rpc_info;
279
} rpcconn_disc_optional_data_t;
284
} rpc_sec_verification_trailer;
286
struct auth_verifier_co_s
288
/* restore 4-byte alignment */
292
BYTE auth_pad_length;
294
UINT32 auth_context_id;
299
typedef struct auth_verifier_co_s rpc_sec_trailer;
300
typedef struct auth_verifier_co_s auth_verifier_co_t;
302
/* Connection-oriented PDU Definitions */
306
DEFINE_RPC_COMMON_FIELDS();
308
UINT16 max_xmit_frag;
309
UINT16 max_recv_frag;
310
UINT32 assoc_group_id;
312
p_cont_list_t p_context_elem;
314
auth_verifier_co_t auth_verifier;
316
} rpcconn_alter_context_hdr_t;
320
DEFINE_RPC_COMMON_FIELDS();
322
UINT16 max_xmit_frag;
323
UINT16 max_recv_frag;
324
UINT32 assoc_group_id;
327
/* restore 4-octet alignment */
329
p_result_list_t p_result_list;
331
auth_verifier_co_t auth_verifier;
332
} rpcconn_alter_context_response_hdr_t;
337
DEFINE_RPC_COMMON_FIELDS();
339
UINT16 max_xmit_frag;
340
UINT16 max_recv_frag;
341
UINT32 assoc_group_id;
343
p_cont_list_t p_context_elem;
345
auth_verifier_co_t auth_verifier;
346
} rpcconn_bind_hdr_t;
350
DEFINE_RPC_COMMON_FIELDS();
352
UINT16 max_xmit_frag;
353
UINT16 max_recv_frag;
354
UINT32 assoc_group_id;
358
/* restore 4-octet alignment */
360
p_result_list_t p_result_list;
362
auth_verifier_co_t auth_verifier;
363
} rpcconn_bind_ack_hdr_t;
367
DEFINE_RPC_COMMON_FIELDS();
369
UINT16 max_xmit_frag;
370
UINT16 max_recv_frag;
372
auth_verifier_co_t auth_verifier;
373
} rpcconn_rpc_auth_3_hdr_t;
377
DEFINE_RPC_COMMON_FIELDS();
379
p_reject_reason_t provider_reject_reason;
381
p_rt_versions_supported_t versions;
382
} rpcconn_bind_nak_hdr_t;
386
DEFINE_RPC_COMMON_FIELDS();
388
auth_verifier_co_t auth_verifier;
390
} rpcconn_cancel_hdr_t;
394
struct _RPC_FAULT_CODE
399
typedef struct _RPC_FAULT_CODE RPC_FAULT_CODE;
401
#define DEFINE_RPC_FAULT_CODE(_code) { _code , #_code },
403
#define nca_s_comm_failure 0x1C010001
404
#define nca_s_op_rng_error 0x1C010002
405
#define nca_s_unk_if 0x1C010003
406
#define nca_s_wrong_boot_time 0x1C010006
407
#define nca_s_you_crashed 0x1C010009
408
#define nca_s_proto_error 0x1C01000B
409
#define nca_s_out_args_too_big 0x1C010013
410
#define nca_s_server_too_busy 0x1C010014
411
#define nca_s_fault_string_too_long 0x1C010015
412
#define nca_s_unsupported_type 0x1C010017
413
#define nca_s_fault_int_div_by_zero 0x1C000001
414
#define nca_s_fault_addr_error 0x1C000002
415
#define nca_s_fault_fp_div_zero 0x1C000003
416
#define nca_s_fault_fp_underflow 0x1C000004
417
#define nca_s_fault_fp_overflow 0x1C000005
418
#define nca_s_fault_invalid_tag 0x1C000006
419
#define nca_s_fault_invalid_bound 0x1C000007
420
#define nca_s_rpc_version_mismatch 0x1C000008
421
#define nca_s_unspec_reject 0x1C000009
422
#define nca_s_bad_actid 0x1C00000A
423
#define nca_s_who_are_you_failed 0x1C00000B
424
#define nca_s_manager_not_entered 0x1C00000C
425
#define nca_s_fault_cancel 0x1C00000D
426
#define nca_s_fault_ill_inst 0x1C00000E
427
#define nca_s_fault_fp_error 0x1C00000F
428
#define nca_s_fault_int_overflow 0x1C000010
429
#define nca_s_fault_unspec 0x1C000012
430
#define nca_s_fault_remote_comm_failure 0x1C000013
431
#define nca_s_fault_pipe_empty 0x1C000014
432
#define nca_s_fault_pipe_closed 0x1C000015
433
#define nca_s_fault_pipe_order 0x1C000016
434
#define nca_s_fault_pipe_discipline 0x1C000017
435
#define nca_s_fault_pipe_comm_error 0x1C000018
436
#define nca_s_fault_pipe_memory 0x1C000019
437
#define nca_s_fault_context_mismatch 0x1C00001A
438
#define nca_s_fault_remote_no_memory 0x1C00001B
439
#define nca_s_invalid_pres_context_id 0x1C00001C
440
#define nca_s_unsupported_authn_level 0x1C00001D
441
#define nca_s_invalid_checksum 0x1C00001F
442
#define nca_s_invalid_crc 0x1C000020
443
#define nca_s_fault_user_defined 0x1C000021
444
#define nca_s_fault_tx_open_failed 0x1C000022
445
#define nca_s_fault_codeset_conv_error 0x1C000023
446
#define nca_s_fault_object_not_found 0x1C000024
447
#define nca_s_fault_no_client_stub 0x1C000025
451
DEFINE_RPC_COMMON_FIELDS();
454
p_context_id_t p_cont_id;
465
auth_verifier_co_t auth_verifier;
466
} rpcconn_fault_hdr_t;
470
DEFINE_RPC_COMMON_FIELDS();
472
auth_verifier_co_t auth_verifier;
473
} rpcconn_orphaned_hdr_t;
477
DEFINE_RPC_COMMON_FIELDS();
481
p_context_id_t p_cont_id;
484
/* optional field for request, only present if the PFC_OBJECT_UUID field is non-zero */
491
auth_verifier_co_t auth_verifier;
492
} rpcconn_request_hdr_t;
496
DEFINE_RPC_COMMON_FIELDS();
499
p_context_id_t p_cont_id;
508
auth_verifier_co_t auth_verifier;
509
} rpcconn_response_hdr_t;
513
DEFINE_RPC_COMMON_FIELDS();
514
} rpcconn_shutdown_hdr_t;
518
rpcconn_common_hdr_t common;
519
rpcconn_alter_context_hdr_t alter_context;
520
rpcconn_alter_context_response_hdr_t alter_context_response;
521
rpcconn_bind_hdr_t bind;
522
rpcconn_bind_ack_hdr_t bind_ack;
523
rpcconn_rpc_auth_3_hdr_t rpc_auth_3;
524
rpcconn_bind_nak_hdr_t bind_nak;
525
rpcconn_cancel_hdr_t cancel;
526
rpcconn_fault_hdr_t fault;
527
rpcconn_orphaned_hdr_t orphaned;
528
rpcconn_request_hdr_t request;
529
rpcconn_response_hdr_t response;
530
rpcconn_shutdown_hdr_t shutdown;
531
rpcconn_rts_hdr_t rts;
534
struct _RPC_SECURITY_PROVIDER_INFO
540
typedef struct _RPC_SECURITY_PROVIDER_INFO RPC_SECURITY_PROVIDER_INFO;
542
enum _RPC_CLIENT_STATE
544
RPC_CLIENT_STATE_INITIAL,
545
RPC_CLIENT_STATE_ESTABLISHED,
546
RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK,
547
RPC_CLIENT_STATE_WAIT_UNSECURE_BIND_ACK,
548
RPC_CLIENT_STATE_WAIT_SECURE_ALTER_CONTEXT_RESPONSE,
549
RPC_CLIENT_STATE_CONTEXT_NEGOTIATED,
550
RPC_CLIENT_STATE_WAIT_RESPONSE,
551
RPC_CLIENT_STATE_FINAL
553
typedef enum _RPC_CLIENT_STATE RPC_CLIENT_STATE;
555
enum _RPC_CLIENT_CALL_STATE
557
RPC_CLIENT_CALL_STATE_INITIAL,
558
RPC_CLIENT_CALL_STATE_SEND_PDUS,
559
RPC_CLIENT_CALL_STATE_DISPATCHED,
560
RPC_CLIENT_CALL_STATE_RECEIVE_PDU,
561
RPC_CLIENT_CALL_STATE_COMPLETE,
562
RPC_CLIENT_CALL_STATE_FAULT,
563
RPC_CLIENT_CALL_STATE_FINAL
565
typedef enum _RPC_CLIENT_CALL_STATE RPC_CLIENT_CALL_STATE;
567
struct rpc_client_call
571
RPC_CLIENT_CALL_STATE State;
573
typedef struct rpc_client_call RpcClientCall;
580
typedef enum _TSG_CHANNEL TSG_CHANNEL;
582
/* Ping Originator */
584
struct rpc_ping_originator
586
UINT32 ConnectionTimeout;
587
UINT32 LastPacketSentTimestamp;
588
UINT32 KeepAliveInterval;
590
typedef struct rpc_ping_originator RpcPingOriginator;
592
/* Client In Channel */
594
enum _CLIENT_IN_CHANNEL_STATE
596
CLIENT_IN_CHANNEL_STATE_INITIAL,
597
CLIENT_IN_CHANNEL_STATE_OPENED,
598
CLIENT_IN_CHANNEL_STATE_OPENED_A4W,
599
CLIENT_IN_CHANNEL_STATE_FINAL
601
typedef enum _CLIENT_IN_CHANNEL_STATE CLIENT_IN_CHANNEL_STATE;
603
struct rpc_in_channel
605
/* Sending Channel */
607
CLIENT_IN_CHANNEL_STATE State;
614
UINT32 SenderAvailableWindow;
615
UINT32 PeerReceiveWindow;
617
/* Ping Originator */
619
RpcPingOriginator PingOriginator;
621
typedef struct rpc_in_channel RpcInChannel;
623
/* Client Out Channel */
625
enum _CLIENT_OUT_CHANNEL_STATE
627
CLIENT_OUT_CHANNEL_STATE_INITIAL,
628
CLIENT_OUT_CHANNEL_STATE_OPENED,
629
CLIENT_OUT_CHANNEL_STATE_OPENED_A6W,
630
CLIENT_OUT_CHANNEL_STATE_OPENED_A10W,
631
CLIENT_OUT_CHANNEL_STATE_OPENED_B3W,
632
CLIENT_OUT_CHANNEL_STATE_FINAL
634
typedef enum _CLIENT_OUT_CHANNEL_STATE CLIENT_OUT_CHANNEL_STATE;
636
struct rpc_out_channel
638
/* Receiving Channel */
640
CLIENT_OUT_CHANNEL_STATE State;
644
UINT32 ReceiveWindow;
645
UINT32 ReceiveWindowSize;
646
UINT32 ReceiverAvailableWindow;
647
UINT32 BytesReceived;
648
UINT32 AvailableWindowAdvertised;
650
typedef struct rpc_out_channel RpcOutChannel;
652
/* Client Virtual Connection */
654
enum _VIRTUAL_CONNECTION_STATE
656
VIRTUAL_CONNECTION_STATE_INITIAL,
657
VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT,
658
VIRTUAL_CONNECTION_STATE_WAIT_A3W,
659
VIRTUAL_CONNECTION_STATE_WAIT_C2,
660
VIRTUAL_CONNECTION_STATE_OPENED,
661
VIRTUAL_CONNECTION_STATE_FINAL
663
typedef enum _VIRTUAL_CONNECTION_STATE VIRTUAL_CONNECTION_STATE;
665
struct rpc_virtual_connection
667
BYTE Cookie[16]; /* Virtual Connection Cookie */
668
VIRTUAL_CONNECTION_STATE State; /* Virtual Connection State */
669
RpcInChannel* DefaultInChannel; /* Default IN Channel */
670
RpcInChannel* NonDefaultInChannel; /* Non-Default IN Channel */
671
BYTE DefaultInChannelCookie[16]; /* Default IN Channel Cookie */
672
BYTE NonDefaultInChannelCookie[16]; /* Non-Default Default IN Channel Cookie */
673
RpcOutChannel* DefaultOutChannel; /* Default OUT Channel */
674
RpcOutChannel* NonDefaultOutChannel; /* Non-Default OUT Channel */
675
BYTE DefaultOutChannelCookie[16]; /* Default OUT Channel Cookie */
676
BYTE NonDefaultOutChannelCookie[16]; /* Non-Default Default OUT Channel Cookie */
677
BYTE AssociationGroupId[16]; /* AssociationGroupId */
679
typedef struct rpc_virtual_connection RpcVirtualConnection;
681
/* Virtual Connection Cookie Table */
683
#define RPC_UUID_FORMAT_STRING "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
684
#define RPC_UUID_FORMAT_ARGUMENTS(_rpc_uuid) \
685
_rpc_uuid[0], _rpc_uuid[1], _rpc_uuid[2], _rpc_uuid[3], _rpc_uuid[4], _rpc_uuid[5], _rpc_uuid[6], _rpc_uuid[7], \
686
_rpc_uuid[8], _rpc_uuid[9], _rpc_uuid[10], _rpc_uuid[11], _rpc_uuid[12], _rpc_uuid[13], _rpc_uuid[14], _rpc_uuid[15]
688
struct rpc_virtual_connection_cookie_entry
691
UINT32 ReferenceCount;
692
RpcVirtualConnection* Reference;
694
typedef struct rpc_virtual_connection_cookie_entry RpcVirtualConnectionCookieEntry;
705
wQueue* ReceiveQueue;
708
wQueue* FragmentPool;
709
wQueue* FragmentQueue;
711
wArrayList* ClientCallList;
715
BOOL SynchronousSend;
716
BOOL SynchronousReceive;
718
typedef struct rpc_client RpcClient;
722
RPC_CLIENT_STATE State;
732
rdpNtlmHttp* NtlmHttpIn;
733
rdpNtlmHttp* NtlmHttpOut;
735
rdpSettings* settings;
736
rdpTransport* transport;
742
UINT32 StubFragCount;
748
UINT16 max_xmit_frag;
749
UINT16 max_recv_frag;
751
UINT32 ReceiveWindow;
753
UINT32 ChannelLifetime;
754
UINT32 ChannelLifetimeSet;
756
UINT32 KeepAliveInterval;
757
UINT32 CurrentKeepAliveTime;
758
UINT32 CurrentKeepAliveInterval;
760
RpcVirtualConnection* VirtualConnection;
762
wArrayList* VirtualConnectionCookieTable;
765
BOOL rpc_connect(rdpRpc* rpc);
767
void rpc_pdu_header_print(rpcconn_hdr_t* header);
768
void rpc_pdu_header_init(rdpRpc* rpc, rpcconn_hdr_t* header);
770
UINT32 rpc_offset_align(UINT32* offset, UINT32 alignment);
771
UINT32 rpc_offset_pad(UINT32* offset, UINT32 pad);
773
int rpc_out_read(rdpRpc* rpc, BYTE* data, int length);
775
int rpc_out_write(rdpRpc* rpc, BYTE* data, int length);
776
int rpc_in_write(rdpRpc* rpc, BYTE* data, int length);
778
BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* length);
780
int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum);
782
rdpRpc* rpc_new(rdpTransport* transport);
783
void rpc_free(rdpRpc* rpc);
785
#ifdef WITH_DEBUG_TSG
786
#define WITH_DEBUG_RPC
789
#ifdef WITH_DEBUG_RPC
790
#define DEBUG_RPC(fmt, ...) DEBUG_CLASS(RPC, fmt, ## __VA_ARGS__)
792
#define DEBUG_RPC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
795
#endif /* FREERDP_CORE_RPC_H */