Merge branch 'gateway' of https://github.com/dvincent-devolutions/FreeRDP
This commit is contained in:
commit
5f66420de6
@ -1167,16 +1167,62 @@ int rdg_write_data_packet(rdpRdg* rdg, BYTE* buf, int size)
|
|||||||
|
|
||||||
BOOL rdg_process_close_packet(rdpRdg* rdg)
|
BOOL rdg_process_close_packet(rdpRdg* rdg)
|
||||||
{
|
{
|
||||||
BYTE buffer[sizeof(RdgPacketHeader) + 4];
|
int status;
|
||||||
RdgPacketHeader* header = (RdgPacketHeader*)buffer;
|
wStream* sChunk;
|
||||||
|
int packetSize = 12;
|
||||||
|
char chunkSize[11];
|
||||||
|
|
||||||
|
sprintf_s(chunkSize, sizeof(chunkSize), "%X\r\n", packetSize);
|
||||||
|
|
||||||
|
sChunk = Stream_New(NULL, strlen(chunkSize) + packetSize + 2);
|
||||||
|
|
||||||
|
if (!sChunk)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
Stream_Write(sChunk, chunkSize, strlen(chunkSize));
|
||||||
|
|
||||||
|
Stream_Write_UINT16(sChunk, PKT_TYPE_CLOSE_CHANNEL_RESPONSE); /* Type */
|
||||||
|
Stream_Write_UINT16(sChunk, 0); /* Reserved */
|
||||||
|
Stream_Write_UINT32(sChunk, packetSize); /* Packet length */
|
||||||
|
|
||||||
|
Stream_Write_UINT32(sChunk, 0); /* Status code */
|
||||||
|
|
||||||
|
Stream_Write(sChunk, "\r\n", 2);
|
||||||
|
Stream_SealLength(sChunk);
|
||||||
|
|
||||||
|
status = tls_write_all(rdg->tlsIn, Stream_Buffer(sChunk), Stream_Length(sChunk));
|
||||||
|
Stream_Free(sChunk, TRUE);
|
||||||
|
|
||||||
|
return (status < 0 ? FALSE : TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
BOOL rdg_process_keep_alive_packet(rdpRdg* rdg)
|
||||||
header->type = PKT_TYPE_CLOSE_CHANNEL_RESPONSE;
|
{
|
||||||
header->packetLength = sizeof(buffer);
|
int status;
|
||||||
|
wStream* sChunk;
|
||||||
WLog_DBG(TAG, "Channel Close requested");
|
int packetSize = 8;
|
||||||
rdg->state = RDG_CLIENT_STATE_CLOSED;
|
char chunkSize[11];
|
||||||
return (rdg_write_data_packet(rdg, buffer, sizeof(buffer)) > 0 ? TRUE : FALSE);
|
|
||||||
|
sprintf_s(chunkSize, sizeof(chunkSize), "%X\r\n", packetSize);
|
||||||
|
|
||||||
|
sChunk = Stream_New(NULL, strlen(chunkSize) + packetSize + 2);
|
||||||
|
|
||||||
|
if (!sChunk)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
Stream_Write(sChunk, chunkSize, strlen(chunkSize));
|
||||||
|
|
||||||
|
Stream_Write_UINT16(sChunk, PKT_TYPE_KEEPALIVE); /* Type */
|
||||||
|
Stream_Write_UINT16(sChunk, 0); /* Reserved */
|
||||||
|
Stream_Write_UINT32(sChunk, packetSize); /* Packet length */
|
||||||
|
|
||||||
|
Stream_Write(sChunk, "\r\n", 2);
|
||||||
|
Stream_SealLength(sChunk);
|
||||||
|
|
||||||
|
status = tls_write_all(rdg->tlsIn, Stream_Buffer(sChunk), Stream_Length(sChunk));
|
||||||
|
Stream_Free(sChunk, TRUE);
|
||||||
|
|
||||||
|
return (status < 0 ? FALSE : TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL rdg_process_unknown_packet(rdpRdg* rdg, int type)
|
BOOL rdg_process_unknown_packet(rdpRdg* rdg, int type)
|
||||||
@ -1223,16 +1269,25 @@ BOOL rdg_process_control_packet(rdpRdg* rdg, int type, int packetLength)
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case PKT_TYPE_CLOSE_CHANNEL:
|
case PKT_TYPE_CLOSE_CHANNEL:
|
||||||
return rdg_process_close_packet(rdg);
|
EnterCriticalSection(&rdg->writeSection);
|
||||||
break;
|
status = rdg_process_close_packet(rdg);
|
||||||
|
LeaveCriticalSection(&rdg->writeSection);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PKT_TYPE_KEEPALIVE:
|
||||||
|
EnterCriticalSection(&rdg->writeSection);
|
||||||
|
status = rdg_process_keep_alive_packet(rdg);
|
||||||
|
LeaveCriticalSection(&rdg->writeSection);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
rdg_process_unknown_packet(rdg, type);
|
status = rdg_process_unknown_packet(rdg, type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream_Free(s, TRUE);
|
Stream_Free(s, TRUE);
|
||||||
|
|
||||||
return TRUE;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rdg_read_data_packet(rdpRdg* rdg, BYTE* buffer, int size)
|
int rdg_read_data_packet(rdpRdg* rdg, BYTE* buffer, int size)
|
||||||
@ -1255,7 +1310,7 @@ int rdg_read_data_packet(rdpRdg* rdg, BYTE* buffer, int size)
|
|||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (rdg->nonBlocking && !readCount)
|
if (!readCount)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1298,12 +1353,13 @@ int rdg_read_data_packet(rdpRdg* rdg, BYTE* buffer, int size)
|
|||||||
|
|
||||||
status = BIO_read(rdg->tlsOut->bio, buffer, readSize);
|
status = BIO_read(rdg->tlsOut->bio, buffer, readSize);
|
||||||
|
|
||||||
if (status < 0)
|
if (status <= 0)
|
||||||
{
|
{
|
||||||
if (!BIO_should_retry(rdg->tlsOut->bio))
|
if (!BIO_should_retry(rdg->tlsOut->bio))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rdg->packetRemainingCount -= status;
|
rdg->packetRemainingCount -= status;
|
||||||
@ -1330,7 +1386,9 @@ static int rdg_bio_write(BIO* bio, const char* buf, int num)
|
|||||||
|
|
||||||
BIO_clear_flags(bio, BIO_FLAGS_WRITE);
|
BIO_clear_flags(bio, BIO_FLAGS_WRITE);
|
||||||
|
|
||||||
|
EnterCriticalSection(&rdg->writeSection);
|
||||||
status = rdg_write_data_packet(rdg, (BYTE*) buf, num);
|
status = rdg_write_data_packet(rdg, (BYTE*) buf, num);
|
||||||
|
LeaveCriticalSection(&rdg->writeSection);
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
@ -1355,36 +1413,30 @@ static int rdg_bio_read(BIO* bio, char* buf, int size)
|
|||||||
int status;
|
int status;
|
||||||
rdpRdg* rdg = (rdpRdg*)bio->ptr;
|
rdpRdg* rdg = (rdpRdg*)bio->ptr;
|
||||||
|
|
||||||
BIO_clear_flags(bio, BIO_FLAGS_READ);
|
|
||||||
|
|
||||||
status = rdg_read_data_packet(rdg, (BYTE*) buf, size);
|
status = rdg_read_data_packet(rdg, (BYTE*) buf, size);
|
||||||
|
|
||||||
if (status < 0)
|
if (!status)
|
||||||
|
{
|
||||||
|
BIO_set_retry_read(bio);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (status < 0)
|
||||||
{
|
{
|
||||||
BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
|
BIO_clear_retry_flags(bio);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (status < size)
|
|
||||||
{
|
|
||||||
BIO_set_flags(bio, BIO_FLAGS_READ);
|
|
||||||
WSASetLastError(WSAEWOULDBLOCK);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BIO_clear_flags(bio, BIO_FLAGS_READ);
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rdg_bio_puts(BIO* bio, const char* str)
|
static int rdg_bio_puts(BIO* bio, const char* str)
|
||||||
{
|
{
|
||||||
return 1;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rdg_bio_gets(BIO* bio, char* str, int size)
|
static int rdg_bio_gets(BIO* bio, char* str, int size)
|
||||||
{
|
{
|
||||||
return 1;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long rdg_bio_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
|
static long rdg_bio_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
|
||||||
@ -1410,7 +1462,6 @@ static long rdg_bio_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
|
|||||||
}
|
}
|
||||||
else if (cmd == BIO_C_SET_NONBLOCK)
|
else if (cmd == BIO_C_SET_NONBLOCK)
|
||||||
{
|
{
|
||||||
rdg->nonBlocking = arg1;
|
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
else if (cmd == BIO_C_READ_BLOCKED)
|
else if (cmd == BIO_C_READ_BLOCKED)
|
||||||
@ -1536,6 +1587,8 @@ rdpRdg* rdg_new(rdpTransport* transport)
|
|||||||
|
|
||||||
if (!rdg->readEvent)
|
if (!rdg->readEvent)
|
||||||
goto rdg_alloc_error;
|
goto rdg_alloc_error;
|
||||||
|
|
||||||
|
InitializeCriticalSection(&rdg->writeSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rdg;
|
return rdg;
|
||||||
@ -1579,6 +1632,8 @@ void rdg_free(rdpRdg* rdg)
|
|||||||
CloseHandle(rdg->readEvent);
|
CloseHandle(rdg->readEvent);
|
||||||
rdg->readEvent = NULL;
|
rdg->readEvent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeleteCriticalSection(&rdg->writeSection);
|
||||||
|
|
||||||
free(rdg);
|
free(rdg);
|
||||||
}
|
}
|
||||||
|
@ -132,12 +132,12 @@ struct rdp_rdg
|
|||||||
rdpNtlm* ntlm;
|
rdpNtlm* ntlm;
|
||||||
HttpContext* http;
|
HttpContext* http;
|
||||||
HANDLE readEvent;
|
HANDLE readEvent;
|
||||||
|
CRITICAL_SECTION writeSection;
|
||||||
|
|
||||||
UUID guid;
|
UUID guid;
|
||||||
|
|
||||||
int state;
|
int state;
|
||||||
UINT16 packetRemainingCount;
|
UINT16 packetRemainingCount;
|
||||||
int nonBlocking;
|
|
||||||
int timeout;
|
int timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -159,6 +159,11 @@ static int bio_rdp_tls_read(BIO* bio, char* buf, int size)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
|
if (WSAGetLastError() == WSAEWOULDBLOCK)
|
||||||
|
{
|
||||||
|
BIO_set_flags(bio, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
|
BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user