libfreerdp-core: added fallback to RPC.
This commit is contained in:
parent
3c4bee3d95
commit
205ccb70c8
@ -162,7 +162,6 @@ BOOL rdg_send_handshake(rdpRdg* rdg)
|
||||
rdg->state = RDG_CLIENT_STATE_HANDSHAKE;
|
||||
}
|
||||
|
||||
WLog_WARN(TAG, "Handshake sent");
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -194,8 +193,6 @@ BOOL rdg_send_tunnel_request(rdpRdg* rdg)
|
||||
rdg->state = RDG_CLIENT_STATE_TUNNEL_CREATE;
|
||||
}
|
||||
|
||||
WLog_WARN(TAG, "Tunnel sent");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -236,8 +233,6 @@ BOOL rdg_send_tunnel_authorization(rdpRdg* rdg)
|
||||
rdg->state = RDG_CLIENT_STATE_TUNNEL_AUTHORIZE;
|
||||
}
|
||||
|
||||
WLog_WARN(TAG, "Tunnel authorization sent");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -260,9 +255,9 @@ BOOL rdg_send_channel_create(rdpRdg* rdg)
|
||||
Stream_Write_UINT32(s, packetSize); /* PacketLength (4 bytes) */
|
||||
|
||||
Stream_Write_UINT8(s, 1); /* Number of resources. (1 byte) */
|
||||
Stream_Write_UINT8(s, 0); /* Number of alternative resources. (1 byte) */
|
||||
Stream_Write_UINT16(s, 3389); /* Port, this seems to be the standard... ? (2 bytes) */
|
||||
Stream_Write_UINT16(s, 3); /* Protocol number, set according to an example... ? (2 bytes) */
|
||||
Stream_Write_UINT8(s, 0); /* Number of alternative resources (1 byte) */
|
||||
Stream_Write_UINT16(s, rdg->settings->ServerPort); /* Resource port (2 bytes) */
|
||||
Stream_Write_UINT16(s, 3); /* Protocol number (2 bytes) */
|
||||
Stream_Write_UINT16(s, serverNameLen * 2);
|
||||
|
||||
for (i = 0; i < serverNameLen; i++)
|
||||
@ -281,8 +276,6 @@ BOOL rdg_send_channel_create(rdpRdg* rdg)
|
||||
rdg->state = RDG_CLIENT_STATE_CHANNEL_CREATE;
|
||||
}
|
||||
|
||||
WLog_WARN(TAG, "Channel create sent");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -293,7 +286,7 @@ wStream* rdg_build_http_request(rdpRdg* rdg, char* method)
|
||||
SecBuffer* ntlmToken = NULL;
|
||||
char* base64NtlmToken = NULL;
|
||||
|
||||
assert(rdg != NULL && method != NULL);
|
||||
assert(method != NULL);
|
||||
|
||||
request = http_request_new();
|
||||
|
||||
@ -346,6 +339,15 @@ BOOL rdg_process_out_channel_response(rdpRdg* rdg, HttpResponse* response)
|
||||
BYTE* ntlmTokenData = NULL;
|
||||
rdpNtlm* ntlm = rdg->ntlm;
|
||||
|
||||
if (response->StatusCode != HTTP_STATUS_DENIED)
|
||||
{
|
||||
WLog_INFO(TAG, "RDG not supported");
|
||||
rdg->state = RDG_CLIENT_STATE_NOT_FOUND;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WLog_INFO(TAG, "Out Channel authorization required");
|
||||
|
||||
if (ListDictionary_Contains(response->Authenticates, "NTLM"))
|
||||
{
|
||||
token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM");
|
||||
@ -396,6 +398,7 @@ BOOL rdg_process_out_channel_authorization(rdpRdg* rdg, HttpResponse* response)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WLog_INFO(TAG, "Out Channel authorization complete");
|
||||
rdg->state = RDG_CLIENT_STATE_OUT_CHANNEL_AUTHORIZED;
|
||||
|
||||
return TRUE;
|
||||
@ -410,6 +413,8 @@ BOOL rdg_process_in_channel_response(rdpRdg* rdg, HttpResponse* response)
|
||||
BYTE* ntlmTokenData = NULL;
|
||||
rdpNtlm* ntlm = rdg->ntlm;
|
||||
|
||||
WLog_INFO(TAG, "In Channel authorization required");
|
||||
|
||||
if (ListDictionary_Contains(response->Authenticates, "NTLM"))
|
||||
{
|
||||
token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM");
|
||||
@ -465,6 +470,7 @@ BOOL rdg_process_in_channel_authorization(rdpRdg* rdg, HttpResponse* response)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WLog_INFO(TAG, "In Channel authorization complete");
|
||||
rdg->state = RDG_CLIENT_STATE_IN_CHANNEL_AUTHORIZED;
|
||||
|
||||
s = rdg_build_http_request(rdg, "RDG_IN_DATA");
|
||||
@ -482,7 +488,7 @@ BOOL rdg_process_handshake_response(rdpRdg* rdg, wStream* s)
|
||||
{
|
||||
HRESULT errorCode;
|
||||
|
||||
WLog_WARN(TAG, "Handshake response received");
|
||||
WLog_INFO(TAG, "Handshake response recieved");
|
||||
|
||||
if (rdg->state != RDG_CLIENT_STATE_HANDSHAKE)
|
||||
{
|
||||
@ -494,6 +500,7 @@ BOOL rdg_process_handshake_response(rdpRdg* rdg, wStream* s)
|
||||
|
||||
if (FAILED(errorCode))
|
||||
{
|
||||
WLog_INFO(TAG, "Handshake error %x", errorCode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -504,7 +511,7 @@ BOOL rdg_process_tunnel_response(rdpRdg* rdg, wStream* s)
|
||||
{
|
||||
HRESULT errorCode;
|
||||
|
||||
WLog_WARN(TAG, "Tunnel response received");
|
||||
WLog_INFO(TAG, "Tunnel response received");
|
||||
|
||||
if (rdg->state != RDG_CLIENT_STATE_TUNNEL_CREATE)
|
||||
{
|
||||
@ -516,6 +523,7 @@ BOOL rdg_process_tunnel_response(rdpRdg* rdg, wStream* s)
|
||||
|
||||
if (FAILED(errorCode))
|
||||
{
|
||||
WLog_INFO(TAG, "Tunnel creation error %x", errorCode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -526,7 +534,7 @@ BOOL rdg_process_tunnel_authorization_response(rdpRdg* rdg, wStream* s)
|
||||
{
|
||||
HRESULT errorCode;
|
||||
|
||||
WLog_WARN(TAG, "Tunnel authorization response received");
|
||||
WLog_INFO(TAG, "Tunnel authorization received");
|
||||
|
||||
if (rdg->state != RDG_CLIENT_STATE_TUNNEL_AUTHORIZE)
|
||||
{
|
||||
@ -538,6 +546,7 @@ BOOL rdg_process_tunnel_authorization_response(rdpRdg* rdg, wStream* s)
|
||||
|
||||
if (FAILED(errorCode))
|
||||
{
|
||||
WLog_INFO(TAG, "Tunnel authorization error %x", errorCode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -548,7 +557,7 @@ BOOL rdg_process_channel_response(rdpRdg* rdg, wStream* s)
|
||||
{
|
||||
HRESULT errorCode;
|
||||
|
||||
WLog_WARN(TAG, "Channel create response received");
|
||||
WLog_INFO(TAG, "Channel response received");
|
||||
|
||||
if (rdg->state != RDG_CLIENT_STATE_CHANNEL_CREATE)
|
||||
{
|
||||
@ -560,6 +569,7 @@ BOOL rdg_process_channel_response(rdpRdg* rdg, wStream* s)
|
||||
|
||||
if (FAILED(errorCode))
|
||||
{
|
||||
WLog_INFO(TAG, "Channel error %x", errorCode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -597,7 +607,7 @@ BOOL rdg_process_packet(rdpRdg* rdg, wStream* s)
|
||||
|
||||
case PKT_TYPE_DATA:
|
||||
assert(FALSE);
|
||||
break;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -679,6 +689,8 @@ UINT32 rdg_get_event_handles(rdpRdg* rdg, HANDLE* events)
|
||||
{
|
||||
UINT32 nCount = 0;
|
||||
|
||||
assert(rdg != NULL);
|
||||
|
||||
if (events)
|
||||
events[nCount] = rdg->readEvent;
|
||||
nCount++;
|
||||
@ -704,6 +716,8 @@ BOOL rdg_check_event_handles(rdpRdg* rdg)
|
||||
{
|
||||
HANDLE event = NULL;
|
||||
|
||||
assert(rdg != NULL);
|
||||
|
||||
BIO_get_event(rdg->tlsOut->bio, &event);
|
||||
|
||||
if (WaitForSingleObject(event, 0) == WAIT_OBJECT_0)
|
||||
@ -767,8 +781,6 @@ BOOL rdg_send_out_channel_request(rdpRdg*rdg)
|
||||
wStream* s = NULL;
|
||||
int status;
|
||||
|
||||
assert(rdg != NULL);
|
||||
|
||||
rdg->ntlm = ntlm_new();
|
||||
|
||||
if (!rdg->ntlm)
|
||||
@ -806,8 +818,6 @@ BOOL rdg_send_in_channel_request(rdpRdg*rdg)
|
||||
int status;
|
||||
wStream* s = NULL;
|
||||
|
||||
assert(rdg != NULL);
|
||||
|
||||
rdg->ntlm = ntlm_new();
|
||||
|
||||
if (!rdg->ntlm)
|
||||
@ -848,7 +858,7 @@ BOOL rdg_tls_out_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int tim
|
||||
BIO* bufferedBio = NULL;
|
||||
rdpSettings* settings = rdg->settings;
|
||||
|
||||
assert(rdg != NULL && hostname != NULL);
|
||||
assert(hostname != NULL);
|
||||
|
||||
sockfd = freerdp_tcp_connect(settings, settings->GatewayHostname, settings->GatewayPort, timeout);
|
||||
|
||||
@ -875,11 +885,12 @@ BOOL rdg_tls_out_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int tim
|
||||
}
|
||||
|
||||
bufferedBio = BIO_push(bufferedBio, socketBio);
|
||||
rdg->bioOut = bufferedBio;
|
||||
bufferedBio = bufferedBio;
|
||||
status = BIO_set_nonblock(bufferedBio, TRUE);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
BIO_free_all(bufferedBio);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -904,7 +915,7 @@ BOOL rdg_tls_in_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int time
|
||||
BIO* bufferedBio = NULL;
|
||||
rdpSettings* settings = rdg->settings;
|
||||
|
||||
assert(rdg != NULL && hostname != NULL);
|
||||
assert(hostname != NULL);
|
||||
|
||||
sockfd = freerdp_tcp_connect(settings, settings->GatewayHostname, settings->GatewayPort, timeout);
|
||||
|
||||
@ -929,11 +940,12 @@ BOOL rdg_tls_in_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int time
|
||||
}
|
||||
|
||||
bufferedBio = BIO_push(bufferedBio, socketBio);
|
||||
rdg->bioIn = bufferedBio;
|
||||
bufferedBio = bufferedBio;
|
||||
status = BIO_set_nonblock(bufferedBio, TRUE);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
BIO_free_all(bufferedBio);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -956,7 +968,7 @@ BOOL rdg_out_channel_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int
|
||||
UINT32 nCount;
|
||||
HANDLE events[8];
|
||||
|
||||
assert(rdg != NULL && hostname != NULL);
|
||||
assert(hostname != NULL);
|
||||
|
||||
status = rdg_tls_out_connect(rdg, hostname, port, timeout);
|
||||
|
||||
@ -991,7 +1003,7 @@ BOOL rdg_in_channel_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int
|
||||
UINT32 nCount;
|
||||
HANDLE events[8];
|
||||
|
||||
assert(rdg != NULL && hostname != NULL);
|
||||
assert(hostname != NULL);
|
||||
|
||||
status = rdg_tls_in_connect(rdg, hostname, port, timeout);
|
||||
|
||||
@ -1049,6 +1061,8 @@ BOOL rdg_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int timeout)
|
||||
{
|
||||
BOOL status;
|
||||
|
||||
assert(rdg != NULL);
|
||||
|
||||
status = rdg_out_channel_connect(rdg, hostname, port, timeout);
|
||||
|
||||
if (!status)
|
||||
@ -1067,7 +1081,6 @@ BOOL rdg_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int timeout)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int rdg_write_data_packet(rdpRdg* rdg, BYTE* buf, int size)
|
||||
{
|
||||
int status;
|
||||
@ -1106,6 +1119,76 @@ int rdg_write_data_packet(rdpRdg* rdg, BYTE* buf, int size)
|
||||
return size;
|
||||
}
|
||||
|
||||
BOOL rdg_process_close_packet(rdpRdg* rdg)
|
||||
{
|
||||
BYTE buffer[sizeof(RdgPacketHeader) + 4];
|
||||
RdgPacketHeader* header = (RdgPacketHeader*)buffer;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
header->type = PKT_TYPE_CLOSE_CHANNEL_RESPONSE;
|
||||
header->packetLength = sizeof(buffer);
|
||||
|
||||
WLog_INFO(TAG, "Channel Close requested");
|
||||
rdg->state = RDG_CLIENT_STATE_CLOSED;
|
||||
return (rdg_write_data_packet(rdg, buffer, sizeof(buffer)) > 0 ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
BOOL rdg_process_unknown_packet(rdpRdg* rdg, int type)
|
||||
{
|
||||
WLog_WARN(TAG, "Unknown Control Packet received: %X", type);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rdg_process_control_packet(rdpRdg* rdg, int type, int packetLength)
|
||||
{
|
||||
wStream* s;
|
||||
int readCount = 0;
|
||||
int status;
|
||||
int payloadSize = packetLength - sizeof(RdgPacketHeader);
|
||||
|
||||
if (payloadSize)
|
||||
{
|
||||
s = Stream_New(NULL, payloadSize);
|
||||
if (!s)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (readCount < payloadSize)
|
||||
{
|
||||
status = BIO_read(rdg->tlsOut->bio, Stream_Pointer(s), sizeof(RdgPacketHeader) - readCount);
|
||||
|
||||
if (status <= 0)
|
||||
{
|
||||
if (!BIO_should_retry(rdg->tlsOut->bio))
|
||||
{
|
||||
Stream_Free(s, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Stream_Seek(s, status);
|
||||
readCount += status;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case PKT_TYPE_CLOSE_CHANNEL:
|
||||
return rdg_process_close_packet(rdg);
|
||||
break;
|
||||
default:
|
||||
rdg_process_unknown_packet(rdg, type);
|
||||
break;
|
||||
}
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int rdg_read_data_packet(rdpRdg* rdg, BYTE* buffer, int size)
|
||||
{
|
||||
RdgPacketHeader header;
|
||||
@ -1138,7 +1221,11 @@ int rdg_read_data_packet(rdpRdg* rdg, BYTE* buffer, int size)
|
||||
|
||||
if (header.type != PKT_TYPE_DATA)
|
||||
{
|
||||
/* Add better handling here !!! */
|
||||
status = rdg_process_control_packet(rdg, header.type, header.packetLength);
|
||||
if (!status)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1161,10 +1248,9 @@ int rdg_read_data_packet(rdpRdg* rdg, BYTE* buffer, int size)
|
||||
}
|
||||
}
|
||||
|
||||
readCount = 0;
|
||||
readSize = (rdg->packetRemainingCount < size ? rdg->packetRemainingCount : size);
|
||||
|
||||
status = BIO_read(rdg->tlsOut->bio, buffer + readCount, readSize - readCount);
|
||||
status = BIO_read(rdg->tlsOut->bio, buffer, readSize);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
@ -1174,9 +1260,7 @@ int rdg_read_data_packet(rdpRdg* rdg, BYTE* buffer, int size)
|
||||
}
|
||||
}
|
||||
|
||||
readCount += status;
|
||||
|
||||
rdg->packetRemainingCount -= readCount;
|
||||
rdg->packetRemainingCount -= status;
|
||||
|
||||
pending = BIO_pending(rdg->tlsOut->bio);
|
||||
|
||||
@ -1185,7 +1269,7 @@ int rdg_read_data_packet(rdpRdg* rdg, BYTE* buffer, int size)
|
||||
else
|
||||
ResetEvent(rdg->readEvent);
|
||||
|
||||
return readSize;
|
||||
return status;
|
||||
}
|
||||
|
||||
long rdg_bio_callback(BIO* bio, int mode, const char* argp, int argi, long argl, long ret)
|
||||
@ -1275,51 +1359,31 @@ static long rdg_bio_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
|
||||
{
|
||||
if (arg2)
|
||||
{
|
||||
//*((ULONG_PTR*)arg2) = (ULONG_PTR)tsg->rpc->client->PipeEvent;
|
||||
//status = 1;
|
||||
BIO_get_event(rdg->tlsOut->bio, arg2);
|
||||
status = 1;
|
||||
}
|
||||
}
|
||||
else if (cmd == BIO_C_SET_NONBLOCK)
|
||||
{
|
||||
//return BIO_ctrl(tlsOut->bio, cmd, arg1, arg2);
|
||||
|
||||
rdg->nonBlocking = arg1;
|
||||
status = 1;
|
||||
}
|
||||
else if (cmd == BIO_C_READ_BLOCKED)
|
||||
{
|
||||
//status = BIO_read_blocked(tlsOut->bio);
|
||||
//status = 0;
|
||||
status = 0;
|
||||
}
|
||||
else if (cmd == BIO_C_WRITE_BLOCKED)
|
||||
{
|
||||
//status = BIO_write_blocked(tlsIn->bio);
|
||||
//status = 0;
|
||||
status = 0;
|
||||
}
|
||||
else if (cmd == BIO_C_WAIT_READ)
|
||||
{
|
||||
int timeout = (int)arg1;
|
||||
return BIO_wait_read(tlsOut->bio, timeout);
|
||||
|
||||
//if (BIO_read_blocked(tlsOut->bio))
|
||||
// return BIO_wait_read(tlsOut->bio, timeout);
|
||||
//else if (BIO_write_blocked(tlsIn->bio))
|
||||
// return BIO_wait_write(tlsIn->bio, timeout);
|
||||
//else
|
||||
// status = 0;
|
||||
}
|
||||
else if (cmd == BIO_C_WAIT_WRITE)
|
||||
{
|
||||
//int timeout = (int)arg1;
|
||||
|
||||
//if (BIO_write_blocked(tlsIn->bio))
|
||||
// status = BIO_wait_write(tlsIn->bio, timeout);
|
||||
//else if (BIO_read_blocked(tlsOut->bio))
|
||||
// status = BIO_wait_read(tlsOut->bio, timeout);
|
||||
//else
|
||||
// status = 0;
|
||||
status = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@ -117,6 +117,7 @@ enum
|
||||
RDG_CLIENT_STATE_OPENED,
|
||||
RDG_CLIENT_STATE_CLOSE,
|
||||
RDG_CLIENT_STATE_CLOSED,
|
||||
RDG_CLIENT_STATE_NOT_FOUND,
|
||||
};
|
||||
|
||||
|
||||
@ -127,8 +128,6 @@ struct rdp_rdg
|
||||
{
|
||||
rdpContext* context;
|
||||
rdpSettings* settings;
|
||||
BIO* bioIn;
|
||||
BIO* bioOut;
|
||||
BIO* frontBio;
|
||||
rdpTls* tlsIn;
|
||||
rdpTls* tlsOut;
|
||||
@ -138,14 +137,8 @@ struct rdp_rdg
|
||||
|
||||
UUID guid;
|
||||
|
||||
//UINT32 tunnelId;
|
||||
//UINT32 negotiatedCapsFlags;
|
||||
//UUID nonce;
|
||||
//LPWSTR serverCert;
|
||||
//LPWSTR consentMsg;
|
||||
|
||||
int state;
|
||||
int packetRemainingCount;
|
||||
UINT16 packetRemainingCount;
|
||||
int nonBlocking;
|
||||
int timeout;
|
||||
};
|
||||
|
@ -214,26 +214,34 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
|
||||
return FALSE;
|
||||
}
|
||||
status = rdg_connect(transport->rdg, hostname, port, timeout);
|
||||
if (!status)
|
||||
if (status)
|
||||
{
|
||||
return FALSE;
|
||||
transport->frontBio = transport->rdg->frontBio;
|
||||
BIO_set_nonblock(transport->frontBio, 0);
|
||||
transport->layer = TRANSPORT_LAYER_TSG;
|
||||
|
||||
status = TRUE;
|
||||
}
|
||||
transport->frontBio = transport->rdg->frontBio;
|
||||
BIO_set_nonblock(transport->frontBio, 0);
|
||||
transport->layer = TRANSPORT_LAYER_TSG;
|
||||
else
|
||||
{
|
||||
if (transport->rdg->state != RDG_CLIENT_STATE_NOT_FOUND)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//transport->tsg = tsg_new(transport);
|
||||
transport->tsg = tsg_new(transport);
|
||||
|
||||
//if (!transport->tsg)
|
||||
// return FALSE;
|
||||
if (!transport->tsg)
|
||||
return FALSE;
|
||||
|
||||
//if (!tsg_connect(transport->tsg, hostname, port, timeout))
|
||||
// return FALSE;
|
||||
if (!tsg_connect(transport->tsg, hostname, port, timeout))
|
||||
return FALSE;
|
||||
|
||||
//transport->frontBio = transport->tsg->bio;
|
||||
//transport->layer = TRANSPORT_LAYER_TSG;
|
||||
transport->frontBio = transport->tsg->bio;
|
||||
transport->layer = TRANSPORT_LAYER_TSG;
|
||||
|
||||
status = TRUE;
|
||||
status = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user