FreeRDP
connection.c File Reference
#include <freerdp/config.h>
#include "settings.h"
#include "info.h"
#include "input.h"
#include "rdp.h"
#include "peer.h"
#include "connection.h"
#include "transport.h"
#include <winpr/crt.h>
#include <winpr/crypto.h>
#include <winpr/ssl.h>
#include <freerdp/log.h>
#include <freerdp/error.h>
#include <freerdp/listener.h>
#include "../cache/pointer.h"
#include "../crypto/crypto.h"
#include "../crypto/privatekey.h"
#include "../crypto/certificate.h"
#include "gateway/arm.h"
#include "utils.h"

Macros

#define TAG   FREERDP_TAG("core.connection")
 

Functions

static BOOL rdp_set_state (rdpRdp *rdp, CONNECTION_STATE state)
 
static BOOL rdp_client_reset_codecs (rdpContext *context)
 
static BOOL rdp_client_wait_for_activation (rdpRdp *rdp)
 
BOOL rdp_client_connect (rdpRdp *rdp)
 
BOOL rdp_client_disconnect (rdpRdp *rdp)
 
BOOL rdp_client_disconnect_and_clear (rdpRdp *rdp)
 
static BOOL rdp_client_reconnect_channels (rdpRdp *rdp, BOOL redirect)
 
static BOOL rdp_client_redirect_resolvable (const char *host)
 
static BOOL rdp_client_redirect_try_fqdn (rdpSettings *settings)
 
static BOOL rdp_client_redirect_try_ip (rdpSettings *settings)
 
static BOOL rdp_client_redirect_try_netbios (rdpSettings *settings)
 
BOOL rdp_client_redirect (rdpRdp *rdp)
 
BOOL rdp_client_reconnect (rdpRdp *rdp)
 
static BOOL rdp_client_establish_keys (rdpRdp *rdp)
 
static BOOL rdp_update_client_random (rdpSettings *settings, const BYTE *crypt_random, size_t crypt_random_len)
 
BOOL rdp_server_establish_keys (rdpRdp *rdp, wStream *s)
 
static BOOL rdp_client_send_client_info_and_change_state (rdpRdp *rdp)
 
BOOL rdp_client_skip_mcs_channel_join (rdpRdp *rdp)
 
static BOOL rdp_client_join_channel (rdpRdp *rdp, UINT16 ChannelId)
 
BOOL rdp_client_connect_mcs_channel_join_confirm (rdpRdp *rdp, wStream *s)
 
BOOL rdp_client_connect_auto_detect (rdpRdp *rdp, wStream *s)
 
state_run_t rdp_client_connect_license (rdpRdp *rdp, wStream *s)
 
state_run_t rdp_client_connect_demand_active (rdpRdp *rdp, wStream *s)
 
state_run_t rdp_client_connect_finalize (rdpRdp *rdp)
 
BOOL rdp_client_transition_to_state (rdpRdp *rdp, CONNECTION_STATE state)
 
BOOL rdp_server_accept_nego (rdpRdp *rdp, wStream *s)
 
static BOOL rdp_update_encryption_level (rdpSettings *settings)
 
BOOL rdp_server_accept_mcs_connect_initial (rdpRdp *rdp, wStream *s)
 
BOOL rdp_server_accept_mcs_erect_domain_request (rdpRdp *rdp, wStream *s)
 
static BOOL rdp_server_skip_mcs_channel_join (rdpRdp *rdp)
 
BOOL rdp_server_accept_mcs_attach_user_request (rdpRdp *rdp, wStream *s)
 
BOOL rdp_server_accept_mcs_channel_join_request (rdpRdp *rdp, wStream *s)
 
static BOOL rdp_server_send_sync (rdpRdp *rdp)
 
BOOL rdp_server_accept_confirm_active (rdpRdp *rdp, wStream *s, UINT16 pduLength)
 
BOOL rdp_server_reactivate (rdpRdp *rdp)
 
static BOOL rdp_is_active_peer_state (CONNECTION_STATE state)
 
static BOOL rdp_is_active_client_state (CONNECTION_STATE state)
 
BOOL rdp_is_active_state (const rdpRdp *rdp)
 
BOOL rdp_server_transition_to_state (rdpRdp *rdp, CONNECTION_STATE state)
 
const char * rdp_client_connection_state_string (int state)
 
const char * rdp_state_string (CONNECTION_STATE state)
 
CONNECTION_STATE rdp_get_state (const rdpRdp *rdp)
 
const char * rdp_get_state_string (const rdpRdp *rdp)
 
BOOL rdp_channels_from_mcs (rdpSettings *settings, const rdpRdp *rdp)
 
state_run_t rdp_client_connect_confirm_active (rdpRdp *rdp, wStream *s)
 

Variables

static const BYTE fips_ivec [8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }
 

Macro Definition Documentation

◆ TAG

#define TAG   FREERDP_TAG("core.connection")

Function Documentation

◆ rdp_channels_from_mcs()

BOOL rdp_channels_from_mcs ( rdpSettings *  settings,
const rdpRdp *  rdp 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_connect()

BOOL rdp_client_connect ( rdpRdp *  rdp)

Establish RDP Connection based on the settings given in the 'rdp' parameter. msdn{cc240452}

Parameters
rdpRDP module
Returns
true if the connection succeeded. FALSE otherwise.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_connect_auto_detect()

BOOL rdp_client_connect_auto_detect ( rdpRdp *  rdp,
wStream s 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_connect_confirm_active()

state_run_t rdp_client_connect_confirm_active ( rdpRdp *  rdp,
wStream s 
)

The server may request a different desktop size during Deactivation-Reactivation sequence. In this case, the UI should be informed and do actual window resizing at this point.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_connect_demand_active()

state_run_t rdp_client_connect_demand_active ( rdpRdp *  rdp,
wStream s 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_connect_finalize()

state_run_t rdp_client_connect_finalize ( rdpRdp *  rdp)

[MS-RDPBCGR] 1.3.1.1 - 8. The client-to-server PDUs sent during this phase have no dependencies on any of the server-to- client PDUs; they may be sent as a single batch, provided that sequencing is maintained.

[MS-RDPBCGR] 2.2.1.17 Client persistent key list must be sent if a bitmap is stored in persistent bitmap cache or the server has advertised support for bitmap host cache and a deactivation reactivation sequence is not in progress.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_connect_license()

state_run_t rdp_client_connect_license ( rdpRdp *  rdp,
wStream s 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_connect_mcs_channel_join_confirm()

BOOL rdp_client_connect_mcs_channel_join_confirm ( rdpRdp *  rdp,
wStream s 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_connection_state_string()

const char* rdp_client_connection_state_string ( int  state)

◆ rdp_client_disconnect()

BOOL rdp_client_disconnect ( rdpRdp *  rdp)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_disconnect_and_clear()

BOOL rdp_client_disconnect_and_clear ( rdpRdp *  rdp)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_establish_keys()

static BOOL rdp_client_establish_keys ( rdpRdp *  rdp)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_join_channel()

static BOOL rdp_client_join_channel ( rdpRdp *  rdp,
UINT16  ChannelId 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_reconnect()

BOOL rdp_client_reconnect ( rdpRdp *  rdp)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_reconnect_channels()

static BOOL rdp_client_reconnect_channels ( rdpRdp *  rdp,
BOOL  redirect 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_redirect()

BOOL rdp_client_redirect ( rdpRdp *  rdp)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_redirect_resolvable()

static BOOL rdp_client_redirect_resolvable ( const char *  host)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_redirect_try_fqdn()

static BOOL rdp_client_redirect_try_fqdn ( rdpSettings *  settings)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_redirect_try_ip()

static BOOL rdp_client_redirect_try_ip ( rdpSettings *  settings)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_redirect_try_netbios()

static BOOL rdp_client_redirect_try_netbios ( rdpSettings *  settings)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_reset_codecs()

static BOOL rdp_client_reset_codecs ( rdpContext *  context)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_send_client_info_and_change_state()

static BOOL rdp_client_send_client_info_and_change_state ( rdpRdp *  rdp)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_skip_mcs_channel_join()

BOOL rdp_client_skip_mcs_channel_join ( rdpRdp *  rdp)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_transition_to_state()

BOOL rdp_client_transition_to_state ( rdpRdp *  rdp,
CONNECTION_STATE  state 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_client_wait_for_activation()

static BOOL rdp_client_wait_for_activation ( rdpRdp *  rdp)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_get_state()

CONNECTION_STATE rdp_get_state ( const rdpRdp *  rdp)
Here is the caller graph for this function:

◆ rdp_get_state_string()

const char* rdp_get_state_string ( const rdpRdp *  rdp)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_is_active_client_state()

static BOOL rdp_is_active_client_state ( CONNECTION_STATE  state)
static
Here is the caller graph for this function:

◆ rdp_is_active_peer_state()

static BOOL rdp_is_active_peer_state ( CONNECTION_STATE  state)
static
Here is the caller graph for this function:

◆ rdp_is_active_state()

BOOL rdp_is_active_state ( const rdpRdp *  rdp)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_server_accept_confirm_active()

BOOL rdp_server_accept_confirm_active ( rdpRdp *  rdp,
wStream s,
UINT16  pduLength 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_server_accept_mcs_attach_user_request()

BOOL rdp_server_accept_mcs_attach_user_request ( rdpRdp *  rdp,
wStream s 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_server_accept_mcs_channel_join_request()

BOOL rdp_server_accept_mcs_channel_join_request ( rdpRdp *  rdp,
wStream s 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_server_accept_mcs_connect_initial()

BOOL rdp_server_accept_mcs_connect_initial ( rdpRdp *  rdp,
wStream s 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_server_accept_mcs_erect_domain_request()

BOOL rdp_server_accept_mcs_erect_domain_request ( rdpRdp *  rdp,
wStream s 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_server_accept_nego()

BOOL rdp_server_accept_nego ( rdpRdp *  rdp,
wStream s 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_server_establish_keys()

BOOL rdp_server_establish_keys ( rdpRdp *  rdp,
wStream s 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_server_reactivate()

BOOL rdp_server_reactivate ( rdpRdp *  rdp)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_server_send_sync()

static BOOL rdp_server_send_sync ( rdpRdp *  rdp)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_server_skip_mcs_channel_join()

static BOOL rdp_server_skip_mcs_channel_join ( rdpRdp *  rdp)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_server_transition_to_state()

BOOL rdp_server_transition_to_state ( rdpRdp *  rdp,
CONNECTION_STATE  state 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_set_state()

BOOL rdp_set_state ( rdpRdp *  rdp,
CONNECTION_STATE  state 
)
static
                             Connection Sequence

client server | | |--------------------—X.224 Connection Request PDU------------------—>| |<-------------------—X.224 Connection Confirm PDU-------------------—| |----—MCS Connect-Initial PDU with GCC Conference Create Request----—>| |<--—MCS Connect-Response PDU with GCC Conference Create Response----—| |---------------------—MCS Erect Domain Request PDU-----------------—>| |---------------------—MCS Attach User Request PDU------------------—>| |<--------------------—MCS Attach User Confirm PDU-------------------—| |---------------------—MCS Channel Join Request PDU-----------------—>| |<--------------------—MCS Channel Join Confirm PDU------------------—| |-------------------------—Security Exchange PDU--------------------—>| |----------------------------—Client Info PDU-----------------------—>| |<------------------—License Error PDU - Valid Client----------------—| |<--------------------------—Demand Active PDU-----------------------—| |---------------------------—Confirm Active PDU---------------------—>| |----------------------------—Synchronize PDU-----------------------—>| |------------------------—Control PDU - Cooperate-------------------—>| |---------------------—Control PDU - Request Control----------------—>| |-----------------------—Persistent Key List PDU(s)-----------------—>| |-----------------------------—Font List PDU------------------------—>| |<---------------------------—Synchronize PDU------------------------—| |<-----------------------—Control PDU - Cooperate--------------------—| |<--------------------—Control PDU - Granted Control-----------------—| |<----------------------------—Font Map PDU--------------------------—| Connection Sequence

  1. Connection Initiation: The client initiates the connection by sending the server a Class 0 X.224 Connection Request PDU (section 2.2.1.1). The server responds with a Class 0 X.224 Connection Confirm PDU (section 2.2.1.2). From this point, all subsequent data sent between client and server is wrapped in an X.224 Data Protocol Data Unit (PDU).
  2. Basic Settings Exchange: Basic settings are exchanged between the client and server by using the MCS Connect Initial PDU (section 2.2.1.3) and MCS Connect Response PDU (section 2.2.1.4). The Connect Initial PDU contains a Generic Conference Control (GCC) Conference Create Request, while the Connect Response PDU contains a GCC Conference Create Response. These two GCC packets contain concatenated blocks of settings data (such as core data, security data, and network data) which are read by client and server.
  3. Channel Connection: The client sends an MCS Erect Domain Request PDU (section 2.2.1.5), followed by an MCS Attach User Request PDU (section 2.2.1.6) to attach the primary user identity to the MCS domain. The server responds with an MCS Attach User Confirm PDU (section 2.2.1.7) containing the User Channel ID. The client then proceeds to join the user channel, the input/output (I/O) channel, and all of the static virtual channels (the I/O and static virtual channel IDs are obtained from the data embedded in the GCC packets) by using multiple MCS Channel Join Request PDUs (section 2.2.1.8). The server confirms each channel with an MCS Channel Join Confirm PDU (section 2.2.1.9). (The client only sends a Channel Join Request after it has received the Channel Join Confirm for the previously sent request.)
        From this point, all subsequent data sent from the client to the server is wrapped in an MCS
    
    Send Data Request PDU, while data sent from the server to the client is wrapped in an MCS Send Data Indication PDU. This is in addition to the data being wrapped by an X.224 Data PDU.
  4. RDP Security Commencement: If Standard RDP Security mechanisms (section 5.3) are being employed and encryption is in force (this is determined by examining the data embedded in the GCC Conference Create Response packet) then the client sends a Security Exchange PDU (section 2.2.1.10) containing an encrypted 32-byte random number to the server. This random number is encrypted with the public key of the server as described in section 5.3.4.1 (the server's public key, as well as a 32-byte server-generated random number, are both obtained from the data embedded in the GCC Conference Create Response packet). The client and server then utilize the two 32-byte random numbers to generate session keys which are used to encrypt and validate the integrity of subsequent RDP traffic.
        From this point, all subsequent RDP traffic can be encrypted and a security header is included
    
    with the data if encryption is in force. (The Client Info PDU (section 2.2.1.11) and licensing PDUs ([MS-RDPELE] section 2.2.2) are an exception in that they always have a security header). The Security Header follows the X.224 and MCS Headers and indicates whether the attached data is encrypted. Even if encryption is in force, server-to-client traffic may not always be encrypted, while client-to-server traffic must always be encrypted (encryption of licensing PDUs is optional, however).
  5. Secure Settings Exchange: Secure client data (such as the username, password, and auto-reconnect cookie) is sent to the server by using the Client Info PDU (section 2.2.1.11).
  6. Optional Connect-Time Auto-Detection: During the optional connect-time auto-detect phase the goal is to determine characteristics of the network, such as the round-trip latency time and the bandwidth of the link between the server and client. This is accomplished by exchanging a collection of PDUs (specified in section 2.2.1.4) over a predetermined period of time with enough data to ensure that the results are statistically relevant.
  7. Licensing: The goal of the licensing exchange is to transfer a license from the server to the client. The client stores this license and on subsequent connections sends the license to the server for validation. However, in some situations the client may not be issued a license to store. In effect, the packets exchanged during this phase of the protocol depend on the licensing mechanisms employed by the server. Within the context of this document, it is assumed that the client will not be issued a license to store. For details regarding more advanced licensing scenarios that take place during the Licensing Phase, see [MS-RDPELE] section 1.3.
  8. Optional Multitransport Bootstrapping: After the connection has been secured and the Licensing Phase has run to completion, the server can choose to initiate multitransport connections ([MS-RDPEMT] section 1.3). The Initiate Multitransport Request PDU (section 2.2.15.1) is sent by the server to the client and results in the out-of-band creation of a multitransport connection using messages from the RDP-UDP, TLS, DTLS, and multitransport protocols ([MS-RDPEMT] section 1.3.1).
  9. Capabilities Exchange: The server sends the set of capabilities it supports to the client in a Demand Active PDU (section 2.2.1.13.1). The client responds with its capabilities by sending a Confirm Active PDU (section 2.2.1.13.2).
  10. Connection Finalization: The client and server exchange PDUs to finalize the connection details. The client-to-server PDUs sent during this phase have no dependencies on any of the server-to-client PDUs; they may be sent as a single batch, provided that sequencing is maintained.

        - The Client Synchronize PDU (section 2.2.1.14) is sent after transmitting the Confirm Active
    

    PDU.

    • The Client Control (Cooperate) PDU (section 2.2.1.15) is sent after transmitting the Client Synchronize PDU.
    • The Client Control (Request Control) PDU (section 2.2.1.16) is sent after transmitting the Client Control (Cooperate) PDU.
    • The optional Persistent Key List PDUs (section 2.2.1.17) are sent after transmitting the Client Control (Request Control) PDU.
    • The Font List PDU (section 2.2.1.18) is sent after transmitting the Persistent Key List PDUs or, if the Persistent Key List PDUs were not sent, it is sent after transmitting the Client Control (Request Control) PDU (section 2.2.1.16).
          The server-to-client PDUs sent during the Connection Finalization Phase have dependencies on the
      
      client-to-server PDUs.
          - The optional Monitor Layout PDU (section 2.2.12.1) has no dependency on any client-to-server
      
      PDUs and is sent after the Demand Active PDU.
    • The Server Synchronize PDU (section 2.2.1.19) is sent in response to the Confirm Active PDU.
    • The Server Control (Cooperate) PDU (section 2.2.1.20) is sent after transmitting the Server Synchronize PDU.
    • The Server Control (Granted Control) PDU (section 2.2.1.21) is sent in response to the Client Control (Request Control) PDU.
    • The Font Map PDU (section 2.2.1.22) is sent in response to the Font List PDU.

    Once the client has sent the Confirm Active PDU, it can start sending mouse and keyboard input to the server, and upon receipt of the Font List PDU the server can start sending graphics output to the client.

        Besides input and graphics data, other data that can be exchanged between client and server
    

    after the connection has been finalized includes connection management information and virtual channel messages (exchanged between client-side plug-ins and server-side applications).

Here is the caller graph for this function:

◆ rdp_state_string()

const char* rdp_state_string ( CONNECTION_STATE  state)
Here is the caller graph for this function:

◆ rdp_update_client_random()

static BOOL rdp_update_client_random ( rdpSettings *  settings,
const BYTE crypt_random,
size_t  crypt_random_len 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rdp_update_encryption_level()

static BOOL rdp_update_encryption_level ( rdpSettings *  settings)
static

Re: settings->EncryptionLevel: This is configured/set by the server implementation and serves the same purpose as the "Encryption Level" setting in the RDP-Tcp configuration dialog of Microsoft's Remote Desktop Session Host Configuration. Re: settings->EncryptionMethods: at this point this setting contains the client's supported encryption methods we've received in gcc_read_client_security_data()

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ fips_ivec

const BYTE fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }
static