2 * FreeRDP: A Remote Desktop Protocol Implementation
3 * Remote Desktop Gateway (RDG)
5 * Copyright 2015 Denis Vincent <dvincent@devolutions.net>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
26 #include <winpr/crt.h>
27 #include <winpr/synch.h>
28 #include <winpr/print.h>
29 #include <winpr/stream.h>
30 #include <winpr/winsock.h>
32 #include <freerdp/log.h>
33 #include <freerdp/error.h>
34 #include <freerdp/utils/ringbuffer.h>
39 #define TAG FREERDP_TAG("core.gateway.rdg")
43 typedef struct rdg_packet_header
52 BOOL rdg_write_packet(rdpRdg* rdg, wStream* sPacket)
58 sprintf_s(chunkSize, sizeof(chunkSize), "%X\r\n", (unsigned int) Stream_Length(sPacket));
59 sChunk = Stream_New(NULL, strlen(chunkSize) + Stream_Length(sPacket) + 2);
64 Stream_Write(sChunk, chunkSize, strlen(chunkSize));
65 Stream_Write(sChunk, Stream_Buffer(sPacket), Stream_Length(sPacket));
66 Stream_Write(sChunk, "\r\n", 2);
67 Stream_SealLength(sChunk);
69 status = tls_write_all(rdg->tlsIn, Stream_Buffer(sChunk), Stream_Length(sChunk));
70 Stream_Free(sChunk, TRUE);
78 wStream* rdg_receive_packet(rdpRdg* rdg)
82 RdgPacketHeader* packet;
85 s = Stream_New(NULL, 1024);
90 packet = (RdgPacketHeader*) Stream_Buffer(s);
92 while (readCount < sizeof(RdgPacketHeader))
94 status = BIO_read(rdg->tlsOut->bio, Stream_Pointer(s), sizeof(RdgPacketHeader) - readCount);
102 Stream_Seek(s, readCount);
105 if (Stream_Capacity(s) < packet->packetLength)
107 if (!Stream_EnsureCapacity(s, packet->packetLength))
109 Stream_Free(s, TRUE);
112 packet = (RdgPacketHeader*) Stream_Buffer(s);
115 while (readCount < packet->packetLength)
117 status = BIO_read(rdg->tlsOut->bio, Stream_Pointer(s), packet->packetLength - readCount);
125 Stream_Seek(s, readCount);
128 Stream_SealLength(s);
133 BOOL rdg_send_handshake(rdpRdg* rdg)
138 s = Stream_New(NULL, 14);
143 Stream_Write_UINT16(s, PKT_TYPE_HANDSHAKE_REQUEST); /* Type (2 bytes) */
144 Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */
145 Stream_Write_UINT32(s, 14); /* PacketLength (4 bytes) */
147 Stream_Write_UINT8(s, 1); /* VersionMajor (1 byte) */
148 Stream_Write_UINT8(s, 0); /* VersionMinor (1 byte) */
149 Stream_Write_UINT16(s, 0); /* ClientVersion (2 bytes), must be 0 */
150 Stream_Write_UINT16(s, 0); /* ExtendedAuthentication (2 bytes) */
152 Stream_SealLength(s);
154 status = rdg_write_packet(rdg, s);
155 Stream_Free(s, TRUE);
159 rdg->state = RDG_CLIENT_STATE_HANDSHAKE;
165 BOOL rdg_send_tunnel_request(rdpRdg* rdg)
170 s = Stream_New(NULL, 16);
175 Stream_Write_UINT16(s, PKT_TYPE_TUNNEL_CREATE); /* Type (2 bytes) */
176 Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */
177 Stream_Write_UINT32(s, 16); /* PacketLength (4 bytes) */
179 Stream_Write_UINT32(s, HTTP_CAPABILITY_TYPE_QUAR_SOH); /* CapabilityFlags (4 bytes) */
180 Stream_Write_UINT16(s, 0); /* FieldsPresent (2 bytes) */
181 Stream_Write_UINT16(s, 0); /* Reserved (2 bytes), must be 0 */
183 Stream_SealLength(s);
185 status = rdg_write_packet(rdg, s);
186 Stream_Free(s, TRUE);
190 rdg->state = RDG_CLIENT_STATE_TUNNEL_CREATE;
196 BOOL rdg_send_tunnel_authorization(rdpRdg* rdg)
201 char* clientName = rdg->settings->ClientHostname;
202 UINT16 clientNameLen = strlen(clientName) + 1;
203 UINT32 packetSize = 12 + clientNameLen * 2;
205 s = Stream_New(NULL, packetSize);
210 Stream_Write_UINT16(s, PKT_TYPE_TUNNEL_AUTH); /* Type (2 bytes) */
211 Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */
212 Stream_Write_UINT32(s, packetSize); /* PacketLength (4 bytes) */
214 Stream_Write_UINT16(s, 0); /* FieldsPresent (2 bytes) */
215 Stream_Write_UINT16(s, clientNameLen * 2); /* Client name string length */
217 for (i = 0; i < clientNameLen; i++)
219 Stream_Write_UINT16(s, clientName[i]);
222 Stream_SealLength(s);
224 status = rdg_write_packet(rdg, s);
226 Stream_Free(s, TRUE);
230 rdg->state = RDG_CLIENT_STATE_TUNNEL_AUTHORIZE;
236 BOOL rdg_send_channel_create(rdpRdg* rdg)
241 char* serverName = rdg->settings->ServerHostname;
242 UINT16 serverNameLen = strlen(serverName) + 1;
243 UINT32 packetSize = 16 + serverNameLen * 2;
245 s = Stream_New(NULL, packetSize);
250 Stream_Write_UINT16(s, PKT_TYPE_CHANNEL_CREATE); /* Type (2 bytes) */
251 Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */
252 Stream_Write_UINT32(s, packetSize); /* PacketLength (4 bytes) */
254 Stream_Write_UINT8(s, 1); /* Number of resources. (1 byte) */
255 Stream_Write_UINT8(s, 0); /* Number of alternative resources (1 byte) */
256 Stream_Write_UINT16(s, rdg->settings->ServerPort); /* Resource port (2 bytes) */
257 Stream_Write_UINT16(s, 3); /* Protocol number (2 bytes) */
258 Stream_Write_UINT16(s, serverNameLen * 2);
260 for (i = 0; i < serverNameLen; i++)
262 Stream_Write_UINT16(s, serverName[i]);
265 Stream_SealLength(s);
267 status = rdg_write_packet(rdg, s);
269 Stream_Free(s, TRUE);
273 rdg->state = RDG_CLIENT_STATE_CHANNEL_CREATE;
279 wStream* rdg_build_http_request(rdpRdg* rdg, char* method)
282 HttpRequest* request = NULL;
283 SecBuffer* ntlmToken = NULL;
284 char* base64NtlmToken = NULL;
286 assert(method != NULL);
288 request = http_request_new();
293 http_request_set_method(request, method);
294 http_request_set_uri(request, rdg->http->URI);
296 if (!request->Method || !request->URI)
301 ntlmToken = rdg->ntlm->outputBuffer;
304 base64NtlmToken = crypto_base64_encode(ntlmToken->pvBuffer, ntlmToken->cbBuffer);
308 http_request_set_auth_scheme(request, "NTLM");
309 http_request_set_auth_param(request, base64NtlmToken);
311 free(base64NtlmToken);
313 if (!request->AuthScheme || !request->AuthParam)
318 if (rdg->state == RDG_CLIENT_STATE_IN_CHANNEL_AUTHORIZED)
320 http_request_set_transfer_encoding(request, "chunked");
323 s = http_request_write(rdg->http, request);
324 http_request_free(request);
327 Stream_SealLength(s);
331 BOOL rdg_process_out_channel_response(rdpRdg* rdg, HttpResponse* response)
335 char* token64 = NULL;
336 int ntlmTokenLength = 0;
337 BYTE* ntlmTokenData = NULL;
338 rdpNtlm* ntlm = rdg->ntlm;
340 if (response->StatusCode != HTTP_STATUS_DENIED)
342 WLog_DBG(TAG, "RDG not supported");
343 rdg->state = RDG_CLIENT_STATE_NOT_FOUND;
347 WLog_DBG(TAG, "Out Channel authorization required");
349 if (ListDictionary_Contains(response->Authenticates, "NTLM"))
351 token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM");
358 crypto_base64_decode(token64, strlen(token64), &ntlmTokenData, &ntlmTokenLength);
361 if (ntlmTokenData && ntlmTokenLength)
363 ntlm->inputBuffer[0].pvBuffer = ntlmTokenData;
364 ntlm->inputBuffer[0].cbBuffer = ntlmTokenLength;
367 ntlm_authenticate(ntlm);
369 s = rdg_build_http_request(rdg, "RDG_OUT_DATA");
374 status = tls_write_all(rdg->tlsOut, Stream_Buffer(s), Stream_Length(s));
376 Stream_Free(s, TRUE);
378 ntlm_free(rdg->ntlm);
386 rdg->state = RDG_CLIENT_STATE_OUT_CHANNEL_AUTHORIZE;
391 BOOL rdg_process_out_channel_authorization(rdpRdg* rdg, HttpResponse* response)
393 if (response->StatusCode != HTTP_STATUS_OK)
395 rdg->state = RDG_CLIENT_STATE_CLOSED;
399 WLog_DBG(TAG, "Out Channel authorization complete");
400 rdg->state = RDG_CLIENT_STATE_OUT_CHANNEL_AUTHORIZED;
405 BOOL rdg_process_in_channel_response(rdpRdg* rdg, HttpResponse* response)
409 char* token64 = NULL;
410 int ntlmTokenLength = 0;
411 BYTE* ntlmTokenData = NULL;
412 rdpNtlm* ntlm = rdg->ntlm;
414 WLog_DBG(TAG, "In Channel authorization required");
416 if (ListDictionary_Contains(response->Authenticates, "NTLM"))
418 token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM");
425 crypto_base64_decode(token64, strlen(token64), &ntlmTokenData, &ntlmTokenLength);
428 if (ntlmTokenData && ntlmTokenLength)
430 ntlm->inputBuffer[0].pvBuffer = ntlmTokenData;
431 ntlm->inputBuffer[0].cbBuffer = ntlmTokenLength;
434 ntlm_authenticate(ntlm);
436 s = rdg_build_http_request(rdg, "RDG_IN_DATA");
441 status = tls_write_all(rdg->tlsIn, Stream_Buffer(s), Stream_Length(s));
443 Stream_Free(s, TRUE);
445 ntlm_free(rdg->ntlm);
453 rdg->state = RDG_CLIENT_STATE_IN_CHANNEL_AUTHORIZE;
458 BOOL rdg_process_in_channel_authorization(rdpRdg* rdg, HttpResponse* response)
463 if (response->StatusCode != HTTP_STATUS_OK)
465 rdg->state = RDG_CLIENT_STATE_CLOSED;
469 WLog_DBG(TAG, "In Channel authorization complete");
470 rdg->state = RDG_CLIENT_STATE_IN_CHANNEL_AUTHORIZED;
472 s = rdg_build_http_request(rdg, "RDG_IN_DATA");
477 status = tls_write_all(rdg->tlsIn, Stream_Buffer(s), Stream_Length(s));
482 Stream_Free(s, TRUE);
487 BOOL rdg_process_handshake_response(rdpRdg* rdg, wStream* s)
491 WLog_DBG(TAG, "Handshake response received");
493 if (rdg->state != RDG_CLIENT_STATE_HANDSHAKE)
498 if (Stream_GetRemainingLength(s) < 12)
502 Stream_Read_UINT32(s, errorCode);
504 if (FAILED(errorCode))
506 WLog_DBG(TAG, "Handshake error %x", errorCode);
510 return rdg_send_tunnel_request(rdg);
513 BOOL rdg_process_tunnel_response(rdpRdg* rdg, wStream* s)
517 WLog_DBG(TAG, "Tunnel response received");
519 if (rdg->state != RDG_CLIENT_STATE_TUNNEL_CREATE)
524 if (Stream_GetRemainingLength(s) < 14)
528 Stream_Read_UINT32(s, errorCode);
530 if (FAILED(errorCode))
532 WLog_DBG(TAG, "Tunnel creation error %x", errorCode);
536 return rdg_send_tunnel_authorization(rdg);
539 BOOL rdg_process_tunnel_authorization_response(rdpRdg* rdg, wStream* s)
543 WLog_DBG(TAG, "Tunnel authorization received");
545 if (rdg->state != RDG_CLIENT_STATE_TUNNEL_AUTHORIZE)
550 if (Stream_GetRemainingLength(s) < 12)
554 Stream_Read_UINT32(s, errorCode);
556 if (FAILED(errorCode))
558 WLog_DBG(TAG, "Tunnel authorization error %x", errorCode);
562 return rdg_send_channel_create(rdg);
565 BOOL rdg_process_channel_response(rdpRdg* rdg, wStream* s)
569 WLog_DBG(TAG, "Channel response received");
571 if (rdg->state != RDG_CLIENT_STATE_CHANNEL_CREATE)
576 if (Stream_GetRemainingLength(s) < 12)
580 Stream_Read_UINT32(s, errorCode);
582 if (FAILED(errorCode))
584 WLog_DBG(TAG, "Channel error %x", errorCode);
588 rdg->state = RDG_CLIENT_STATE_OPENED;
593 BOOL rdg_process_packet(rdpRdg* rdg, wStream* s)
598 Stream_SetPosition(s, 0);
600 if (Stream_GetRemainingLength(s) < 2)
603 Stream_Peek_UINT16(s, type);
607 case PKT_TYPE_HANDSHAKE_RESPONSE:
608 status = rdg_process_handshake_response(rdg, s);
611 case PKT_TYPE_TUNNEL_RESPONSE:
612 status = rdg_process_tunnel_response(rdg, s);
615 case PKT_TYPE_TUNNEL_AUTH_RESPONSE:
616 status = rdg_process_tunnel_authorization_response(rdg, s);
619 case PKT_TYPE_CHANNEL_RESPONSE:
620 status = rdg_process_channel_response(rdg, s);
632 BOOL rdg_out_channel_recv(rdpRdg* rdg)
636 HttpResponse* response = NULL;
640 case RDG_CLIENT_STATE_OUT_CHANNEL_REQUEST:
641 response = http_response_recv(rdg->tlsOut);
646 status = rdg_process_out_channel_response(rdg, response);
647 http_response_free(response);
650 case RDG_CLIENT_STATE_OUT_CHANNEL_AUTHORIZE:
651 response = http_response_recv(rdg->tlsOut);
656 status = rdg_process_out_channel_authorization(rdg, response);
657 http_response_free(response);
661 s = rdg_receive_packet(rdg);
664 status = rdg_process_packet(rdg, s);
665 Stream_Free(s, TRUE);
672 BOOL rdg_in_channel_recv(rdpRdg* rdg)
675 HttpResponse* response = NULL;
679 case RDG_CLIENT_STATE_IN_CHANNEL_REQUEST:
680 response = http_response_recv(rdg->tlsIn);
685 status = rdg_process_in_channel_response(rdg, response);
686 http_response_free(response);
689 case RDG_CLIENT_STATE_IN_CHANNEL_AUTHORIZE:
690 response = http_response_recv(rdg->tlsIn);
695 status = rdg_process_in_channel_authorization(rdg, response);
696 http_response_free(response);
703 DWORD rdg_get_event_handles(rdpRdg* rdg, HANDLE* events, DWORD count)
709 if (events && (nCount < count))
710 events[nCount++] = rdg->readEvent;
714 if (rdg->tlsOut && rdg->tlsOut->bio)
716 if (events && (nCount < count))
718 BIO_get_event(rdg->tlsOut->bio, &events[nCount]);
725 if (rdg->tlsIn && rdg->tlsIn->bio)
727 if (events && (nCount < count))
729 BIO_get_event(rdg->tlsIn->bio, &events[nCount]);
739 BOOL rdg_check_event_handles(rdpRdg* rdg)
745 BIO_get_event(rdg->tlsOut->bio, &event);
747 if (WaitForSingleObject(event, 0) == WAIT_OBJECT_0)
749 return rdg_out_channel_recv(rdg);
752 BIO_get_event(rdg->tlsIn->bio, &event);
754 if (WaitForSingleObject(event, 0) == WAIT_OBJECT_0)
756 return rdg_in_channel_recv(rdg);
762 BOOL rdg_ncacn_http_ntlm_init(rdpRdg* rdg, rdpTls* tls)
764 rdpNtlm* ntlm = rdg->ntlm;
765 rdpContext* context = rdg->context;
766 rdpSettings* settings = context->settings;
767 freerdp* instance = context->instance;
769 if (!settings->GatewayPassword || !settings->GatewayUsername || !strlen(settings->GatewayPassword) || !strlen(settings->GatewayUsername))
771 if (instance->GatewayAuthenticate)
773 BOOL proceed = instance->GatewayAuthenticate(instance, &settings->GatewayUsername, &settings->GatewayPassword, &settings->GatewayDomain);
777 freerdp_set_last_error(context, FREERDP_ERROR_CONNECT_CANCELLED);
781 if (settings->GatewayUseSameCredentials)
783 if (settings->GatewayUsername)
785 free(settings->Username);
786 if (!(settings->Username = _strdup(settings->GatewayUsername)))
789 if (settings->GatewayDomain)
791 free(settings->Domain);
792 if (!(settings->Domain = _strdup(settings->GatewayDomain)))
795 if (settings->GatewayPassword)
797 free(settings->Password);
798 if (!(settings->Password = _strdup(settings->GatewayPassword)))
805 if (!ntlm_client_init(ntlm, TRUE, settings->GatewayUsername, settings->GatewayDomain, settings->GatewayPassword, tls->Bindings))
810 if (!ntlm_client_make_spn(ntlm, _T("HTTP"), settings->GatewayHostname))
818 BOOL rdg_send_out_channel_request(rdpRdg*rdg)
823 rdg->ntlm = ntlm_new();
828 status = rdg_ncacn_http_ntlm_init(rdg, rdg->tlsOut);
833 status = ntlm_authenticate(rdg->ntlm);
838 s = rdg_build_http_request(rdg, "RDG_OUT_DATA");
843 status = tls_write_all(rdg->tlsOut, Stream_Buffer(s), Stream_Length(s));
845 Stream_Free(s, TRUE);
850 rdg->state = RDG_CLIENT_STATE_OUT_CHANNEL_REQUEST;
855 BOOL rdg_send_in_channel_request(rdpRdg*rdg)
860 rdg->ntlm = ntlm_new();
865 status = rdg_ncacn_http_ntlm_init(rdg, rdg->tlsIn);
870 status = ntlm_authenticate(rdg->ntlm);
875 s = rdg_build_http_request(rdg, "RDG_IN_DATA");
880 status = tls_write_all(rdg->tlsIn, Stream_Buffer(s), Stream_Length(s));
882 Stream_Free(s, TRUE);
887 rdg->state = RDG_CLIENT_STATE_IN_CHANNEL_REQUEST;
892 BOOL rdg_tls_out_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int timeout)
896 BIO* socketBio = NULL;
897 BIO* bufferedBio = NULL;
898 rdpSettings* settings = rdg->settings;
900 assert(hostname != NULL);
902 sockfd = freerdp_tcp_connect(settings, settings->GatewayHostname, settings->GatewayPort, timeout);
909 socketBio = BIO_new(BIO_s_simple_socket());
917 BIO_set_fd(socketBio, sockfd, BIO_CLOSE);
918 bufferedBio = BIO_new(BIO_s_buffered_socket());
926 bufferedBio = BIO_push(bufferedBio, socketBio);
927 status = BIO_set_nonblock(bufferedBio, TRUE);
931 BIO_free_all(bufferedBio);
935 rdg->tlsOut->hostname = settings->GatewayHostname;
936 rdg->tlsOut->port = settings->GatewayPort;
937 rdg->tlsOut->isGatewayTransport = TRUE;
938 status = tls_connect(rdg->tlsOut, bufferedBio);
948 BOOL rdg_tls_in_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int timeout)
952 BIO* socketBio = NULL;
953 BIO* bufferedBio = NULL;
954 rdpSettings* settings = rdg->settings;
956 assert(hostname != NULL);
958 sockfd = freerdp_tcp_connect(settings, settings->GatewayHostname, settings->GatewayPort, timeout);
963 socketBio = BIO_new(BIO_s_simple_socket());
971 BIO_set_fd(socketBio, sockfd, BIO_CLOSE);
972 bufferedBio = BIO_new(BIO_s_buffered_socket());
980 bufferedBio = BIO_push(bufferedBio, socketBio);
981 status = BIO_set_nonblock(bufferedBio, TRUE);
985 BIO_free_all(bufferedBio);
989 rdg->tlsIn->hostname = settings->GatewayHostname;
990 rdg->tlsIn->port = settings->GatewayPort;
991 rdg->tlsIn->isGatewayTransport = TRUE;
992 status = tls_connect(rdg->tlsIn, bufferedBio);
1002 BOOL rdg_out_channel_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int timeout)
1008 assert(hostname != NULL);
1010 status = rdg_tls_out_connect(rdg, hostname, port, timeout);
1015 status = rdg_send_out_channel_request(rdg);
1020 nCount = rdg_get_event_handles(rdg, events, 8);
1025 while (rdg->state <= RDG_CLIENT_STATE_OUT_CHANNEL_AUTHORIZE)
1027 WaitForMultipleObjects(nCount, events, FALSE, 100);
1028 status = rdg_check_event_handles(rdg);
1032 rdg->context->rdp->transport->layer = TRANSPORT_LAYER_CLOSED;
1040 BOOL rdg_in_channel_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int timeout)
1046 assert(hostname != NULL);
1048 status = rdg_tls_in_connect(rdg, hostname, port, timeout);
1053 status = rdg_send_in_channel_request(rdg);
1058 nCount = rdg_get_event_handles(rdg, events, 8);
1063 while (rdg->state <= RDG_CLIENT_STATE_IN_CHANNEL_AUTHORIZE)
1065 WaitForMultipleObjects(nCount, events, FALSE, 100);
1066 status = rdg_check_event_handles(rdg);
1070 rdg->context->rdp->transport->layer = TRANSPORT_LAYER_CLOSED;
1078 BOOL rdg_tunnel_connect(rdpRdg* rdg)
1084 rdg_send_handshake(rdg);
1086 nCount = rdg_get_event_handles(rdg, events, 8);
1091 while (rdg->state < RDG_CLIENT_STATE_OPENED)
1093 WaitForMultipleObjects(nCount, events, FALSE, 100);
1094 status = rdg_check_event_handles(rdg);
1098 rdg->context->rdp->transport->layer = TRANSPORT_LAYER_CLOSED;
1106 BOOL rdg_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int timeout)
1110 assert(rdg != NULL);
1112 status = rdg_out_channel_connect(rdg, hostname, port, timeout);
1117 status = rdg_in_channel_connect(rdg, hostname, port, timeout);
1122 status = rdg_tunnel_connect(rdg);
1130 int rdg_write_data_packet(rdpRdg* rdg, BYTE* buf, int size)
1134 int packetSize = size + 10;
1140 sprintf_s(chunkSize, sizeof(chunkSize), "%X\r\n", packetSize);
1142 sChunk = Stream_New(NULL, strlen(chunkSize) + packetSize + 2);
1147 Stream_Write(sChunk, chunkSize, strlen(chunkSize));
1149 Stream_Write_UINT16(sChunk, PKT_TYPE_DATA); /* Type */
1150 Stream_Write_UINT16(sChunk, 0); /* Reserved */
1151 Stream_Write_UINT32(sChunk, packetSize); /* Packet length */
1153 Stream_Write_UINT16(sChunk, size); /* Data size */
1154 Stream_Write(sChunk, buf, size); /* Data */
1156 Stream_Write(sChunk, "\r\n", 2);
1157 Stream_SealLength(sChunk);
1159 status = tls_write_all(rdg->tlsIn, Stream_Buffer(sChunk), Stream_Length(sChunk));
1160 Stream_Free(sChunk, TRUE);
1168 BOOL rdg_process_close_packet(rdpRdg* rdg)
1172 int packetSize = 12;
1175 sprintf_s(chunkSize, sizeof(chunkSize), "%X\r\n", packetSize);
1177 sChunk = Stream_New(NULL, strlen(chunkSize) + packetSize + 2);
1182 Stream_Write(sChunk, chunkSize, strlen(chunkSize));
1184 Stream_Write_UINT16(sChunk, PKT_TYPE_CLOSE_CHANNEL_RESPONSE); /* Type */
1185 Stream_Write_UINT16(sChunk, 0); /* Reserved */
1186 Stream_Write_UINT32(sChunk, packetSize); /* Packet length */
1188 Stream_Write_UINT32(sChunk, 0); /* Status code */
1190 Stream_Write(sChunk, "\r\n", 2);
1191 Stream_SealLength(sChunk);
1193 status = tls_write_all(rdg->tlsIn, Stream_Buffer(sChunk), Stream_Length(sChunk));
1194 Stream_Free(sChunk, TRUE);
1196 return (status < 0 ? FALSE : TRUE);
1199 BOOL rdg_process_keep_alive_packet(rdpRdg* rdg)
1206 sprintf_s(chunkSize, sizeof(chunkSize), "%X\r\n", packetSize);
1208 sChunk = Stream_New(NULL, strlen(chunkSize) + packetSize + 2);
1213 Stream_Write(sChunk, chunkSize, strlen(chunkSize));
1215 Stream_Write_UINT16(sChunk, PKT_TYPE_KEEPALIVE); /* Type */
1216 Stream_Write_UINT16(sChunk, 0); /* Reserved */
1217 Stream_Write_UINT32(sChunk, packetSize); /* Packet length */
1219 Stream_Write(sChunk, "\r\n", 2);
1220 Stream_SealLength(sChunk);
1222 status = tls_write_all(rdg->tlsIn, Stream_Buffer(sChunk), Stream_Length(sChunk));
1223 Stream_Free(sChunk, TRUE);
1225 return (status < 0 ? FALSE : TRUE);
1228 BOOL rdg_process_unknown_packet(rdpRdg* rdg, int type)
1230 WLog_WARN(TAG, "Unknown Control Packet received: %X", type);
1235 BOOL rdg_process_control_packet(rdpRdg* rdg, int type, int packetLength)
1240 int payloadSize = packetLength - sizeof(RdgPacketHeader);
1244 s = Stream_New(NULL, payloadSize);
1250 while (readCount < payloadSize)
1252 status = BIO_read(rdg->tlsOut->bio, Stream_Pointer(s), sizeof(RdgPacketHeader) - readCount);
1256 if (!BIO_should_retry(rdg->tlsOut->bio))
1258 Stream_Free(s, TRUE);
1264 Stream_Seek(s, status);
1265 readCount += status;
1271 case PKT_TYPE_CLOSE_CHANNEL:
1272 EnterCriticalSection(&rdg->writeSection);
1273 status = rdg_process_close_packet(rdg);
1274 LeaveCriticalSection(&rdg->writeSection);
1277 case PKT_TYPE_KEEPALIVE:
1278 EnterCriticalSection(&rdg->writeSection);
1279 status = rdg_process_keep_alive_packet(rdg);
1280 LeaveCriticalSection(&rdg->writeSection);
1284 status = rdg_process_unknown_packet(rdg, type);
1288 Stream_Free(s, TRUE);
1293 int rdg_read_data_packet(rdpRdg* rdg, BYTE* buffer, int size)
1295 RdgPacketHeader header;
1301 if (!rdg->packetRemainingCount)
1303 while (readCount < sizeof(RdgPacketHeader))
1305 status = BIO_read(rdg->tlsOut->bio, (BYTE*)(&header) + readCount, sizeof(RdgPacketHeader) - readCount);
1309 if (!BIO_should_retry(rdg->tlsOut->bio))
1320 readCount += status;
1323 if (header.type != PKT_TYPE_DATA)
1325 status = rdg_process_control_packet(rdg, header.type, header.packetLength);
1335 while (readCount < 2)
1337 status = BIO_read(rdg->tlsOut->bio, (BYTE*)(&rdg->packetRemainingCount) + readCount, 2 - readCount);
1341 if (!BIO_should_retry(rdg->tlsOut->bio))
1348 readCount += status;
1352 readSize = (rdg->packetRemainingCount < size ? rdg->packetRemainingCount : size);
1354 status = BIO_read(rdg->tlsOut->bio, buffer, readSize);
1358 if (!BIO_should_retry(rdg->tlsOut->bio))
1365 rdg->packetRemainingCount -= status;
1367 pending = BIO_pending(rdg->tlsOut->bio);
1370 SetEvent(rdg->readEvent);
1372 ResetEvent(rdg->readEvent);
1377 long rdg_bio_callback(BIO* bio, int mode, const char* argp, int argi, long argl, long ret)
1382 static int rdg_bio_write(BIO* bio, const char* buf, int num)
1385 rdpRdg* rdg = (rdpRdg*)bio->ptr;
1387 BIO_clear_flags(bio, BIO_FLAGS_WRITE);
1389 EnterCriticalSection(&rdg->writeSection);
1390 status = rdg_write_data_packet(rdg, (BYTE*) buf, num);
1391 LeaveCriticalSection(&rdg->writeSection);
1395 BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
1398 else if (status < num)
1400 BIO_set_flags(bio, BIO_FLAGS_WRITE);
1401 WSASetLastError(WSAEWOULDBLOCK);
1405 BIO_clear_flags(bio, BIO_FLAGS_WRITE);
1411 static int rdg_bio_read(BIO* bio, char* buf, int size)
1414 rdpRdg* rdg = (rdpRdg*)bio->ptr;
1416 status = rdg_read_data_packet(rdg, (BYTE*) buf, size);
1420 BIO_set_retry_read(bio);
1423 else if (status < 0)
1425 BIO_clear_retry_flags(bio);
1432 static int rdg_bio_puts(BIO* bio, const char* str)
1437 static int rdg_bio_gets(BIO* bio, char* str, int size)
1442 static long rdg_bio_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
1445 rdpRdg* rdg = (rdpRdg*)bio->ptr;
1446 rdpTls* tlsOut = rdg->tlsOut;
1447 rdpTls* tlsIn = rdg->tlsIn;
1449 if (cmd == BIO_CTRL_FLUSH)
1451 (void)BIO_flush(tlsOut->bio);
1452 (void)BIO_flush(tlsIn->bio);
1455 else if (cmd == BIO_C_GET_EVENT)
1459 BIO_get_event(rdg->tlsOut->bio, arg2);
1463 else if (cmd == BIO_C_SET_NONBLOCK)
1467 else if (cmd == BIO_C_READ_BLOCKED)
1471 else if (cmd == BIO_C_WRITE_BLOCKED)
1475 else if (cmd == BIO_C_WAIT_READ)
1477 int timeout = (int)arg1;
1478 return BIO_wait_read(tlsOut->bio, timeout);
1480 else if (cmd == BIO_C_WAIT_WRITE)
1488 static int rdg_bio_new(BIO* bio)
1493 bio->flags = BIO_FLAGS_SHOULD_RETRY;
1497 static int rdg_bio_free(BIO* bio)
1502 static BIO_METHOD rdg_bio_methods =
1516 BIO_METHOD* BIO_s_rdg(void)
1518 return &rdg_bio_methods;
1521 rdpRdg* rdg_new(rdpTransport* transport)
1524 RPC_CSTR stringUuid;
1525 char bracedUuid[40];
1526 RPC_STATUS rpcStatus;
1528 assert(transport != NULL);
1530 rdg = (rdpRdg*) calloc(1, sizeof(rdpRdg));
1534 rdg->state = RDG_CLIENT_STATE_INITIAL;
1535 rdg->context = transport->context;
1536 rdg->settings = rdg->context->settings;
1538 UuidCreate(&rdg->guid);
1540 rpcStatus = UuidToStringA(&rdg->guid, &stringUuid);
1542 if (rpcStatus == RPC_S_OUT_OF_MEMORY)
1543 goto rdg_alloc_error;
1545 sprintf_s(bracedUuid, sizeof(bracedUuid), "{%s}", stringUuid);
1546 RpcStringFreeA(&stringUuid);
1548 rdg->tlsOut = tls_new(rdg->settings);
1551 goto rdg_alloc_error;
1553 rdg->tlsIn = tls_new(rdg->settings);
1556 goto rdg_alloc_error;
1558 rdg->http = http_context_new();
1561 goto rdg_alloc_error;
1563 http_context_set_uri(rdg->http, "/remoteDesktopGateway/");
1564 http_context_set_accept(rdg->http, "*/*");
1565 http_context_set_cache_control(rdg->http, "no-cache");
1566 http_context_set_pragma(rdg->http, "no-cache");
1567 http_context_set_connection(rdg->http, "Keep-Alive");
1568 http_context_set_user_agent(rdg->http, "MS-RDGateway/1.0");
1569 http_context_set_host(rdg->http, rdg->settings->GatewayHostname);
1570 http_context_set_rdg_connection_id(rdg->http, bracedUuid);
1572 if (!rdg->http->URI || !rdg->http->Accept || !rdg->http->CacheControl ||
1573 !rdg->http->Pragma || !rdg->http->Connection || !rdg->http->UserAgent
1574 || !rdg->http->Host || !rdg->http->RdgConnectionId)
1576 goto rdg_alloc_error;
1579 rdg->frontBio = BIO_new(BIO_s_rdg());
1582 goto rdg_alloc_error;
1584 rdg->frontBio->ptr = rdg;
1586 rdg->readEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1588 if (!rdg->readEvent)
1589 goto rdg_alloc_error;
1591 InitializeCriticalSection(&rdg->writeSection);
1601 void rdg_free(rdpRdg* rdg)
1608 tls_free(rdg->tlsOut);
1614 tls_free(rdg->tlsIn);
1620 http_context_free(rdg->http);
1626 ntlm_free(rdg->ntlm);
1632 CloseHandle(rdg->readEvent);
1633 rdg->readEvent = NULL;
1636 DeleteCriticalSection(&rdg->writeSection);