From 4fe3501bc48cb4e92274d3860fc03ad156d49549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 29 Nov 2012 01:33:19 -0500 Subject: [PATCH] libfreerdp-core: refactoring of sequencing of TSG connection --- client/X11/xf_keyboard.c | 2 + libfreerdp/core/gateway/rpc.c | 5 ++ libfreerdp/core/gateway/rpc.h | 3 +- libfreerdp/core/gateway/rpc_bind.c | 90 ++++++++++++++++++------------ libfreerdp/core/gateway/rpc_bind.h | 2 +- libfreerdp/core/gateway/rts.c | 6 ++ libfreerdp/core/gateway/tsg.c | 2 + 7 files changed, 73 insertions(+), 37 deletions(-) diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index f6a52ac16..eec8b8012 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -31,6 +31,8 @@ #include #include +#include + #include "xf_keyboard.h" void xf_kbd_init(xfInfo* xfi) diff --git a/libfreerdp/core/gateway/rpc.c b/libfreerdp/core/gateway/rpc.c index 9143b953b..d65659485 100644 --- a/libfreerdp/core/gateway/rpc.c +++ b/libfreerdp/core/gateway/rpc.c @@ -569,6 +569,11 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) return length; } +int rpc_recv(rdpRpc* rpc, RPC_PDU* pdu) +{ + return 0; +} + BOOL rpc_connect(rdpRpc* rpc) { rpc->TlsIn = rpc->transport->TlsIn; diff --git a/libfreerdp/core/gateway/rpc.h b/libfreerdp/core/gateway/rpc.h index 3a12e8d3f..d2d23a14d 100644 --- a/libfreerdp/core/gateway/rpc.h +++ b/libfreerdp/core/gateway/rpc.h @@ -793,9 +793,10 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* l int rpc_recv_pdu_header(rdpRpc* rpc, BYTE* header); RPC_PDU* rpc_recv_pdu(rdpRpc* rpc); - int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum); +int rpc_recv(rdpRpc* rpc, RPC_PDU* pdu); + rdpRpc* rpc_new(rdpTransport* transport); void rpc_free(rdpRpc* rpc); diff --git a/libfreerdp/core/gateway/rpc_bind.c b/libfreerdp/core/gateway/rpc_bind.c index 40cdc6279..fec93378b 100644 --- a/libfreerdp/core/gateway/rpc_bind.c +++ b/libfreerdp/core/gateway/rpc_bind.c @@ -213,18 +213,12 @@ int rpc_send_bind_pdu(rdpRpc* rpc) * abstract GSS_Init_sec_context call, which returns an auth_token and continue status in this example. */ -int rpc_recv_bind_ack_pdu(rdpRpc* rpc) +int rpc_recv_bind_ack_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) { - RPC_PDU* pdu; BYTE* auth_data; rpcconn_hdr_t* header; - pdu = rpc_recv_dequeue_pdu(rpc); - - if (!pdu) - return -1; - - header = (rpcconn_hdr_t*) pdu->Buffer; + header = (rpcconn_hdr_t*) buffer; rpc->max_recv_frag = header->bind_ack.max_xmit_frag; rpc->max_xmit_frag = header->bind_ack.max_recv_frag; @@ -232,12 +226,12 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc) rpc->ntlm->inputBuffer.cbBuffer = header->common.auth_length; rpc->ntlm->inputBuffer.pvBuffer = malloc(header->common.auth_length); - auth_data = pdu->Buffer + (header->common.frag_length - header->common.auth_length); + auth_data = buffer + (header->common.frag_length - header->common.auth_length); CopyMemory(rpc->ntlm->inputBuffer.pvBuffer, auth_data, header->common.auth_length); ntlm_authenticate(rpc->ntlm); - return pdu->Length; + return (int) length; } /** @@ -254,7 +248,7 @@ int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) UINT32 length; rpcconn_rpc_auth_3_hdr_t* auth_3_pdu; - DEBUG_RPC("Sending auth_3 PDU"); + DEBUG_RPC("Sending rpc_auth_3 PDU"); auth_3_pdu = (rpcconn_rpc_auth_3_hdr_t*) malloc(sizeof(rpcconn_rpc_auth_3_hdr_t)); ZeroMemory(auth_3_pdu, sizeof(rpcconn_rpc_auth_3_hdr_t)); @@ -329,33 +323,59 @@ int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) int rpc_secure_bind(rdpRpc* rpc) { - if (rpc->State != RPC_CLIENT_STATE_ESTABLISHED) + int status; + RPC_PDU* pdu; + + rpc->client->SynchronousSend = FALSE; + rpc->client->SynchronousReceive = TRUE; + + while (rpc->State != RPC_CLIENT_STATE_CONTEXT_NEGOTIATED) { - printf("rpc_secure_bind: invalid state, expected RPC_CLIENT_STATE_ESTABLISHED\n"); - return -1; + if (rpc->State == RPC_CLIENT_STATE_ESTABLISHED) + { + status = rpc_send_bind_pdu(rpc); + + if (status <= 0) + { + printf("rpc_secure_bind: error sending bind pdu!\n"); + return -1; + } + + rpc->State = RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK; + } + else if (rpc->State == RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK) + { + pdu = rpc_recv_dequeue_pdu(rpc); + + if (!pdu) + { + printf("rpc_secure_bind: error receiving bind ack pdu!\n"); + return -1; + } + + if (rpc_recv_bind_ack_pdu(rpc, pdu->Buffer, pdu->Length) <= 0) + { + printf("rpc_secure_bind: error receiving bind ack pdu!\n"); + return -1; + } + + if (rpc_send_rpc_auth_3_pdu(rpc) <= 0) + { + printf("rpc_secure_bind: error sending rpc_auth_3 pdu!\n"); + return -1; + } + + rpc->State = RPC_CLIENT_STATE_CONTEXT_NEGOTIATED; + } + else + { + printf("rpc_secure_bind: invalid state: %d\n", rpc->State); + return -1; + } } - if (rpc_send_bind_pdu(rpc) <= 0) - { - printf("rpc_send_bind_pdu error!\n"); - return -1; - } - - rpc->State = RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK; - - if (rpc_recv_bind_ack_pdu(rpc) <= 0) - { - printf("rpc_recv_bind_ack_pdu error!\n"); - return -1; - } - - if (rpc_send_rpc_auth_3_pdu(rpc) <= 0) - { - printf("rpc_send_rpc_auth_3 error!\n"); - return -1; - } - - rpc->State = RPC_CLIENT_STATE_CONTEXT_NEGOTIATED; + rpc->client->SynchronousSend = FALSE; + rpc->client->SynchronousReceive = FALSE; return 0; } diff --git a/libfreerdp/core/gateway/rpc_bind.h b/libfreerdp/core/gateway/rpc_bind.h index f9186500e..4712d30a3 100644 --- a/libfreerdp/core/gateway/rpc_bind.h +++ b/libfreerdp/core/gateway/rpc_bind.h @@ -25,7 +25,7 @@ #include int rpc_send_bind_pdu(rdpRpc* rpc); -int rpc_recv_bind_ack_pdu(rdpRpc* rpc); +int rpc_recv_bind_ack_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length); int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc); int rpc_secure_bind(rdpRpc* rpc); diff --git a/libfreerdp/core/gateway/rts.c b/libfreerdp/core/gateway/rts.c index 7ef506ed3..78a26832f 100644 --- a/libfreerdp/core/gateway/rts.c +++ b/libfreerdp/core/gateway/rts.c @@ -87,6 +87,9 @@ BOOL rts_connect(rdpRpc* rpc) rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_INITIAL; DEBUG_RTS("VIRTUAL_CONNECTION_STATE_INITIAL"); + rpc->client->SynchronousSend = TRUE; + rpc->client->SynchronousReceive = TRUE; + if (!rpc_ntlm_http_out_connect(rpc)) { printf("rpc_out_connect_http error!\n"); @@ -231,6 +234,9 @@ BOOL rts_connect(rdpRpc* rpc) rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_OPENED; DEBUG_RTS("VIRTUAL_CONNECTION_STATE_OPENED"); + rpc->client->SynchronousSend = FALSE; + rpc->client->SynchronousReceive = FALSE; + return TRUE; } diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 63f335837..5b2ec4e09 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -940,6 +940,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) tsg->state = TSG_STATE_INITIAL; rpc->client->SynchronousSend = TRUE; + rpc->client->SynchronousReceive = TRUE; /* * Sequential processing rules for connection process: @@ -1080,6 +1081,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) return FALSE; rpc->client->SynchronousSend = TRUE; + rpc->client->SynchronousReceive = TRUE; return TRUE; }