Merge branch 'gateway' of https://github.com/dvincent-devolutions/FreeRDP into gateway
This commit is contained in:
commit
dfee7710e1
@ -864,6 +864,57 @@ int rpc_out_channel_connect(RpcOutChannel* outChannel, int timeout)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rpc_out_channel_replacement_connect(RpcOutChannel* outChannel, int timeout)
|
||||
{
|
||||
HttpResponse* response = NULL;
|
||||
rdpRpc* rpc = outChannel->rpc;
|
||||
int status = 0;
|
||||
|
||||
/* Connect OUT Channel */
|
||||
|
||||
if (rpc_channel_tls_connect((RpcChannel*)outChannel, timeout) < 0)
|
||||
return -1;
|
||||
|
||||
rpc_out_channel_transition_to_state(outChannel, CLIENT_OUT_CHANNEL_STATE_CONNECTED);
|
||||
|
||||
if (rpc_ncacn_http_ntlm_init(rpc, (RpcChannel*)outChannel) < 0)
|
||||
return FALSE;
|
||||
|
||||
/* Send OUT Channel Request */
|
||||
|
||||
if (rpc_ncacn_http_send_out_channel_request(rpc, outChannel, TRUE) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rpc_ncacn_http_send_out_channel_request failure");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rpc_out_channel_transition_to_state(outChannel, CLIENT_OUT_CHANNEL_STATE_SECURITY);
|
||||
|
||||
/* Receive response. */
|
||||
response = http_response_recv(outChannel->tls);
|
||||
|
||||
if (!response)
|
||||
return -1;
|
||||
|
||||
status = rpc_ncacn_http_recv_out_channel_response(rpc, outChannel, response);
|
||||
http_response_free(response);
|
||||
if ( status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rpc_ncacn_http_recv_out_channel_response failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Send OUT Channel Request */
|
||||
|
||||
if (rpc_ncacn_http_send_out_channel_request(rpc, outChannel, TRUE) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rpc_ncacn_http_send_out_channel_request failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL rpc_connect(rdpRpc* rpc, int timeout)
|
||||
{
|
||||
RpcInChannel* inChannel;
|
||||
|
@ -779,7 +779,8 @@ RpcInChannel* rpc_client_in_channel_new(rdpRpc* rpc);
|
||||
void rpc_in_channel_free(RpcInChannel* inChannel);
|
||||
|
||||
RpcOutChannel* rpc_out_channel_new(rdpRpc* rpc);
|
||||
void rpc_client_out_channel_free(RpcOutChannel* outChannel);
|
||||
int rpc_out_channel_replacement_connect(RpcOutChannel* outChannel, int timeout);
|
||||
void rpc_out_channel_free(RpcOutChannel* outChannel);
|
||||
|
||||
int rpc_in_channel_transition_to_state(RpcInChannel* inChannel, CLIENT_IN_CHANNEL_STATE state);
|
||||
int rpc_out_channel_transition_to_state(RpcOutChannel* outChannel, CLIENT_OUT_CHANNEL_STATE state);
|
||||
|
@ -604,6 +604,9 @@ int rpc_client_out_channel_recv(rdpRpc* rpc)
|
||||
|
||||
status = rpc_client_recv_fragment(rpc, fragment);
|
||||
|
||||
/* In case the channel recycling completed, reinitialise the local outChannel pointer. */
|
||||
outChannel = rpc->VirtualConnection->DefaultOutChannel;
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
|
@ -805,7 +805,7 @@ int rts_send_OUT_R2_A7_pdu(rdpRpc* rpc)
|
||||
BYTE* buffer;
|
||||
rpcconn_rts_hdr_t header;
|
||||
BYTE* SuccessorChannelCookie;
|
||||
RpcOutChannel* outChannel = rpc->VirtualConnection->DefaultOutChannel;
|
||||
RpcInChannel* inChannel = rpc->VirtualConnection->DefaultInChannel;
|
||||
RpcOutChannel* nextOutChannel = rpc->VirtualConnection->NonDefaultOutChannel;
|
||||
|
||||
rts_pdu_header_init(&header);
|
||||
@ -827,7 +827,7 @@ int rts_send_OUT_R2_A7_pdu(rdpRpc* rpc)
|
||||
rts_cookie_command_write(&buffer[28], SuccessorChannelCookie); /* SuccessorChannelCookie (20 bytes) */
|
||||
rts_version_command_write(&buffer[48]); /* Version (8 bytes) */
|
||||
|
||||
status = rpc_out_channel_write(outChannel, buffer, header.frag_length);
|
||||
status = rpc_in_channel_write(inChannel, buffer, header.frag_length);
|
||||
|
||||
free(buffer);
|
||||
|
||||
@ -839,7 +839,7 @@ int rts_send_OUT_R2_C1_pdu(rdpRpc* rpc)
|
||||
int status;
|
||||
BYTE* buffer;
|
||||
rpcconn_rts_hdr_t header;
|
||||
RpcOutChannel* outChannel = rpc->VirtualConnection->DefaultOutChannel;
|
||||
RpcOutChannel* nextOutChannel = rpc->VirtualConnection->NonDefaultOutChannel;
|
||||
|
||||
rts_pdu_header_init(&header);
|
||||
header.frag_length = 24;
|
||||
@ -856,7 +856,7 @@ int rts_send_OUT_R2_C1_pdu(rdpRpc* rpc)
|
||||
CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
|
||||
rts_empty_command_write(&buffer[20]); /* Empty command (4 bytes) */
|
||||
|
||||
status = rpc_out_channel_write(outChannel, buffer, header.frag_length);
|
||||
status = rpc_out_channel_write(nextOutChannel, buffer, header.frag_length);
|
||||
|
||||
free(buffer);
|
||||
|
||||
@ -900,7 +900,7 @@ int rts_send_OUT_R1_A3_pdu(rdpRpc* rpc)
|
||||
rts_cookie_command_write(&buffer[68], SuccessorChannelCookie); /* SuccessorChannelCookie (20 bytes) */
|
||||
rts_receive_window_size_command_write(&buffer[88], ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */
|
||||
|
||||
status = rpc_out_channel_write(outChannel, buffer, header.frag_length);
|
||||
status = rpc_out_channel_write(nextOutChannel, buffer, header.frag_length);
|
||||
|
||||
free(buffer);
|
||||
|
||||
@ -921,6 +921,12 @@ int rts_recv_OUT_R1_A2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
WLog_ERR(TAG, "TS Gateway channel recycling is incomplete");
|
||||
|
||||
connection->NonDefaultOutChannel = rpc_out_channel_new(rpc);
|
||||
rpc_out_channel_replacement_connect(connection->NonDefaultOutChannel, 5000);//TODO: check for timeout value.
|
||||
|
||||
rts_send_OUT_R1_A3_pdu(rpc);
|
||||
|
||||
rpc_out_channel_transition_to_state(connection->NonDefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED_A6W);
|
||||
rpc_out_channel_transition_to_state(connection->DefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED_A6W);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -928,19 +934,28 @@ int rts_recv_OUT_R1_A2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
int rts_recv_OUT_R2_A6_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
int status;
|
||||
UINT32 offset;
|
||||
UINT32 Destination = 0;
|
||||
rpcconn_rts_hdr_t* header = (rpcconn_rts_hdr_t*)buffer;
|
||||
|
||||
offset = 24;
|
||||
offset += rts_destination_command_read(rpc, &buffer[offset], length - offset, &Destination) + 4;
|
||||
offset += rts_empty_command_read(rpc, &buffer[offset], length - offset) + 4;
|
||||
|
||||
WLog_DBG(TAG, "Destination: %d", Destination);
|
||||
if (rpc->VirtualConnection->DefaultOutChannel->State != CLIENT_OUT_CHANNEL_STATE_OPENED_A6W)
|
||||
{
|
||||
/* Wrong state to receive this PDU. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = rts_send_OUT_R2_C1_pdu(rpc);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = rts_send_OUT_R2_A7_pdu(rpc);
|
||||
if (status < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
rpc_out_channel_transition_to_state(rpc->VirtualConnection->NonDefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED_B3W);
|
||||
rpc_out_channel_transition_to_state(rpc->VirtualConnection->DefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED_B3W);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -948,9 +963,30 @@ int rts_recv_OUT_R2_A6_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
int rts_recv_OUT_R2_B3_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
UINT32 offset;
|
||||
RpcOutChannel* temp;
|
||||
HttpResponse* response;
|
||||
int status;
|
||||
|
||||
offset = 24;
|
||||
offset += rts_ance_command_read(rpc, &buffer[offset], length - offset) + 4;
|
||||
if (rpc->VirtualConnection->DefaultOutChannel->State != CLIENT_OUT_CHANNEL_STATE_OPENED_B3W)
|
||||
{
|
||||
/* Wrong state to receive this PDU. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
rpc_out_channel_free(rpc->VirtualConnection->DefaultOutChannel);
|
||||
rpc->VirtualConnection->DefaultOutChannel = rpc->VirtualConnection->NonDefaultOutChannel;
|
||||
rpc->VirtualConnection->NonDefaultOutChannel = NULL;
|
||||
|
||||
rpc_out_channel_transition_to_state(rpc->VirtualConnection->DefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED);
|
||||
|
||||
response = http_response_recv(rpc->VirtualConnection->DefaultOutChannel->tls);
|
||||
|
||||
if (!response)
|
||||
return -1;
|
||||
|
||||
status = rpc_ncacn_http_recv_out_channel_response(rpc, rpc->VirtualConnection->DefaultOutChannel, response);
|
||||
http_response_free(response);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -985,6 +1021,14 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
status = rts_recv_OUT_R1_A2_pdu(rpc, buffer, length);
|
||||
break;
|
||||
|
||||
case RTS_PDU_OUT_R2_A6:
|
||||
status = rts_recv_OUT_R2_A6_pdu(rpc, buffer, length);
|
||||
break;
|
||||
|
||||
case RTS_PDU_OUT_R2_B3:
|
||||
status = rts_recv_OUT_R2_B3_pdu(rpc, buffer, length);
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "unimplemented signature id: 0x%08X", SignatureId);
|
||||
rts_print_pdu_signature(rpc, &signature);
|
||||
|
Loading…
Reference in New Issue
Block a user