ReactOS 0.4.15-dev-5667-ged97270
tcp.c
Go to the documentation of this file.
1/* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Protocol services - TCP layer
4 Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
5 Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
6 Copyright 2012-2013 Henrik Andersson <hean01@cendio.se> for Cendio AB
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "precomp.h"
23#ifdef WITH_SSL
24#include <sspi.h>
25#include <schannel.h>
26#endif
27
28#ifdef _WIN32
29#define socklen_t int
30#define TCP_CLOSE(_sck) closesocket(_sck)
31#define TCP_STRERROR "tcp error"
32#define TCP_SLEEP(_n) Sleep(_n)
33#define TCP_BLOCKS (WSAGetLastError() == WSAEWOULDBLOCK)
34#else /* _WIN32 */
35#define TCP_CLOSE(_sck) close(_sck)
36#define TCP_STRERROR strerror(errno)
37#define TCP_SLEEP(_n) sleep(_n)
38#define TCP_BLOCKS (errno == EWOULDBLOCK)
39#endif /* _WIN32 */
40
41#ifndef INADDR_NONE
42#define INADDR_NONE ((unsigned long) -1)
43#endif
44
45#ifdef WITH_SCARD
46#define STREAM_COUNT 8
47#else
48#define STREAM_COUNT 1
49#endif
50
51#ifdef WITH_SSL
52typedef struct
53{
54 CtxtHandle ssl_ctx;
56 char *ssl_buf;
57 char *extra_buf;
58 size_t extra_len;
59 char *peek_msg;
60 char *peek_msg_mem;
61 size_t peek_len;
62 DWORD security_flags;
63} netconn_t;
64static char * g_ssl_server = NULL;
65static RD_BOOL g_ssl_initialized = False;
69static netconn_t g_ssl1;
70static netconn_t *g_ssl = NULL;
71#endif /* WITH_SSL */
72static int g_sock;
73static struct stream g_in;
74static struct stream g_out[STREAM_COUNT];
76extern RD_BOOL g_user_quit;
79
80/* Initialise TCP transport data packet */
83{
84 static int cur_stream_id = 0;
86
87#ifdef WITH_SCARD
89#endif
90 result = &g_out[cur_stream_id];
91 cur_stream_id = (cur_stream_id + 1) % STREAM_COUNT;
92
93 if (maxlen > result->size)
94 {
95 result->data = (uint8 *) xrealloc(result->data, maxlen);
96 result->size = maxlen;
97 }
98
99 result->p = result->data;
100 result->end = result->data + result->size;
101#ifdef WITH_SCARD
103#endif
104 return result;
105}
106
107#ifdef WITH_SSL
108
109RD_BOOL send_ssl_chunk(const void *msg, size_t size)
110{
111 SecBuffer bufs[4] = {
113 {size, SECBUFFER_DATA, g_ssl->ssl_buf+g_ssl->ssl_sizes.cbHeader},
116 };
117 SecBufferDesc buf_desc = {SECBUFFER_VERSION, sizeof(bufs)/sizeof(*bufs), bufs};
119 int tcp_res;
120
121 memcpy(bufs[1].pvBuffer, msg, size);
122 res = EncryptMessage(&g_ssl->ssl_ctx, 0, &buf_desc, 0);
123 if (res != SEC_E_OK)
124 {
125 error("EncryptMessage failed: %d\n", res);
126 return False;
127 }
128
129 tcp_res = send(g_sock, g_ssl->ssl_buf, bufs[0].cbBuffer+bufs[1].cbBuffer+bufs[2].cbBuffer, 0);
130 if (tcp_res < 1)
131 {
132 error("send failed: %d (%s)\n", tcp_res, TCP_STRERROR);
133 return False;
134 }
135
136 return True;
137}
138
139DWORD read_ssl_chunk(void *buf, SIZE_T buf_size, BOOL blocking, SIZE_T *ret_size, BOOL *eof)
140{
141 const SIZE_T ssl_buf_size = g_ssl->ssl_sizes.cbHeader+g_ssl->ssl_sizes.cbMaximumMessage+g_ssl->ssl_sizes.cbTrailer;
142 SecBuffer bufs[4];
143 SecBufferDesc buf_desc = {SECBUFFER_VERSION, sizeof(bufs)/sizeof(*bufs), bufs};
144 SSIZE_T size, buf_len = 0;
145 int i;
147
148 //assert(conn->extra_len < ssl_buf_size);
149
150 if (g_ssl->extra_len)
151 {
152 memcpy(g_ssl->ssl_buf, g_ssl->extra_buf, g_ssl->extra_len);
153 buf_len = g_ssl->extra_len;
154 g_ssl->extra_len = 0;
155 xfree(g_ssl->extra_buf);
156 g_ssl->extra_buf = NULL;
157 }
158
159 size = recv(g_sock, g_ssl->ssl_buf+buf_len, ssl_buf_size-buf_len, 0);
160 if (size < 0)
161 {
162 if (!buf_len)
163 {
164 if (size == -1 && TCP_BLOCKS)
165 {
166 return WSAEWOULDBLOCK;
167 }
168 error("recv failed: %d (%s)\n", size, TCP_STRERROR);
169 return -1;//ERROR_INTERNET_CONNECTION_ABORTED;
170 }
171 }
172 else
173 {
174 buf_len += size;
175 }
176
177 if (!buf_len)
178 {
179 *eof = TRUE;
180 *ret_size = 0;
181 return ERROR_SUCCESS;
182 }
183
184 *eof = FALSE;
185
186 do
187 {
188 memset(bufs, 0, sizeof(bufs));
189 bufs[0].BufferType = SECBUFFER_DATA;
190 bufs[0].cbBuffer = buf_len;
191 bufs[0].pvBuffer = g_ssl->ssl_buf;
192
193 res = DecryptMessage(&g_ssl->ssl_ctx, &buf_desc, 0, NULL);
194 switch (res)
195 {
196 case SEC_E_OK:
197 break;
199 *eof = TRUE;
200 return ERROR_SUCCESS;
202 //assert(buf_len < ssl_buf_size);
203
204 size = recv(g_sock, g_ssl->ssl_buf+buf_len, ssl_buf_size-buf_len, 0);
205 if (size < 1)
206 {
207 if (size == -1 && TCP_BLOCKS)
208 {
209 /* FIXME: Optimize extra_buf usage. */
210 g_ssl->extra_buf = xmalloc(buf_len);
211 if (!g_ssl->extra_buf)
213
214 g_ssl->extra_len = buf_len;
215 memcpy(g_ssl->extra_buf, g_ssl->ssl_buf, g_ssl->extra_len);
216 return WSAEWOULDBLOCK;
217 }
218
219 error("recv failed: %d (%s)\n", size, TCP_STRERROR);
220 return -1;//ERROR_INTERNET_CONNECTION_ABORTED;
221 }
222
223 buf_len += size;
224 continue;
225 default:
226 error("DecryptMessage failed: %d\n", res);
227 return -1;//ERROR_INTERNET_CONNECTION_ABORTED;
228 }
229 }
230 while (res != SEC_E_OK);
231
232 for (i=0; i < sizeof(bufs)/sizeof(*bufs); i++)
233 {
234 if (bufs[i].BufferType == SECBUFFER_DATA)
235 {
236 size = min(buf_size, bufs[i].cbBuffer);
237 memcpy(buf, bufs[i].pvBuffer, size);
238 if (size < bufs[i].cbBuffer)
239 {
240 //assert(!conn->peek_len);
241 g_ssl->peek_msg_mem = g_ssl->peek_msg = xmalloc(bufs[i].cbBuffer - size);
242 if (!g_ssl->peek_msg)
244 g_ssl->peek_len = bufs[i].cbBuffer-size;
245 memcpy(g_ssl->peek_msg, (char*)bufs[i].pvBuffer+size, g_ssl->peek_len);
246 }
247
248 *ret_size = size;
249 }
250 }
251
252 for (i=0; i < sizeof(bufs)/sizeof(*bufs); i++)
253 {
254 if (bufs[i].BufferType == SECBUFFER_EXTRA)
255 {
256 g_ssl->extra_buf = xmalloc(bufs[i].cbBuffer);
257 if (!g_ssl->extra_buf)
259
260 g_ssl->extra_len = bufs[i].cbBuffer;
261 memcpy(g_ssl->extra_buf, bufs[i].pvBuffer, g_ssl->extra_len);
262 }
263 }
264
265 return ERROR_SUCCESS;
266}
267#endif /* WITH_SSL */
268/* Send TCP transport data packet */
269void
271{
272 int length = s->end - s->data;
273 int sent, total = 0;
274
275 if (g_network_error == True)
276 return;
277
278#ifdef WITH_SCARD
280#endif
281 while (total < length)
282 {
283#ifdef WITH_SSL
284 if (g_ssl)
285 {
286 const BYTE *ptr = s->data + total;
287 size_t chunk_size;
288
289 sent = 0;
290
291 while (length - total)
292 {
293 chunk_size = min(length - total, g_ssl->ssl_sizes.cbMaximumMessage);
294 if (!send_ssl_chunk(ptr, chunk_size))
295 {
296#ifdef WITH_SCARD
298#endif
299
300 //error("send_ssl_chunk: %d (%s)\n", sent, TCP_STRERROR);
302 return;
303 }
304
305 sent += chunk_size;
306 ptr += chunk_size;
307 length -= chunk_size;
308 }
309 }
310 else
311 {
312#endif /* WITH_SSL */
313 sent = send(g_sock, (const char *)s->data + total, length - total, 0);
314 if (sent <= 0)
315 {
316 if (sent == -1 && TCP_BLOCKS)
317 {
318 TCP_SLEEP(0);
319 sent = 0;
320 }
321 else
322 {
323#ifdef WITH_SCARD
325#endif
326
327 error("send: %d (%s)\n", sent, TCP_STRERROR);
329 return;
330 }
331 }
332#ifdef WITH_SSL
333 }
334#endif /* WITH_SSL */
335 total += sent;
336 }
337#ifdef WITH_SCARD
339#endif
340}
341
342/* Receive a message on the TCP layer */
343STREAM
345{
346 uint32 new_length, end_offset, p_offset;
347 int rcvd = 0;
348
349 if (g_network_error == True)
350 return NULL;
351
352 if (s == NULL)
353 {
354 /* read into "new" stream */
355 if (length > g_in.size)
356 {
357 g_in.data = (uint8 *) xrealloc(g_in.data, length);
358 g_in.size = length;
359 }
360 g_in.end = g_in.p = g_in.data;
361 s = &g_in;
362 }
363 else
364 {
365 /* append to existing stream */
366 new_length = (s->end - s->data) + length;
367 if (new_length > s->size)
368 {
369 p_offset = s->p - s->data;
370 end_offset = s->end - s->data;
371 s->data = (uint8 *) xrealloc(s->data, new_length);
372 s->size = new_length;
373 s->p = s->data + p_offset;
374 s->end = s->data + end_offset;
375 }
376 }
377
378 while (length > 0)
379 {
380#ifdef WITH_SSL
381 if (!g_ssl)
382#endif /* WITH_SSL */
383 {
384 if (!ui_select(g_sock))
385 {
386 /* User quit */
388 return NULL;
389 }
390 }
391
392#ifdef WITH_SSL
393 if (g_ssl)
394 {
395 SIZE_T size = 0;
396 BOOL eof;
397 DWORD res;
398
399 if (g_ssl->peek_msg)
400 {
401 size = min(length, g_ssl->peek_len);
402 memcpy(s->end, g_ssl->peek_msg, size);
403 g_ssl->peek_len -= size;
404 g_ssl->peek_msg += size;
405 s->end += size;
406
407 if (!g_ssl->peek_len)
408 {
409 xfree(g_ssl->peek_msg_mem);
410 g_ssl->peek_msg_mem = g_ssl->peek_msg = NULL;
411 }
412
413 return s;
414 }
415
416 do
417 {
418 res = read_ssl_chunk((BYTE*)s->end, length, TRUE, &size, &eof);
419 if (res != ERROR_SUCCESS)
420 {
421 if (res == WSAEWOULDBLOCK)
422 {
423 if (size)
424 {
426 }
427 }
428 else
429 {
430 error("read_ssl_chunk: %d (%s)\n", res, TCP_STRERROR);
432 return NULL;
433 }
434 break;
435 }
436 }
437 while (!size && !eof);
438 rcvd = size;
439 }
440 else
441 {
442#endif /* WITH_SSL */
443 rcvd = recv(g_sock, (char *)s->end, length, 0);
444 if (rcvd < 0)
445 {
446 if (rcvd == -1 && TCP_BLOCKS)
447 {
448 rcvd = 0;
449 }
450 else
451 {
452 error("recv: %d (%s)\n", rcvd, TCP_STRERROR);
454 return NULL;
455 }
456 }
457 else if (rcvd == 0)
458 {
459 error("Connection closed\n");
460 return NULL;
461 }
462#ifdef WITH_SSL
463 }
464#endif /* WITH_SSL */
465
466 s->end += rcvd;
467 length -= rcvd;
468 }
469
470 return s;
471}
472
473#ifdef WITH_SSL
474
477{
479
481 {
484
487 if (res == SEC_E_OK)
488 {
491 {
492 cred.grbitEnabledProtocols = prots.grbitProtocol & ~SP_PROT_TLS1_1PLUS_CLIENT;
496 }
497 }
498
500 }
501
502 if (res != SEC_E_OK)
503 {
504 error("ensure_cred_handle failed: %ld\n", res);
505 return False;
506 }
507
508 return True;
509}
510
511DWORD
512ssl_handshake(RD_BOOL compat_mode)
513{
514 SecBuffer out_buf = {0, SECBUFFER_TOKEN, NULL}, in_bufs[2] = {{0, SECBUFFER_TOKEN}, {0, SECBUFFER_EMPTY}};
515 SecBufferDesc out_desc = {SECBUFFER_VERSION, 1, &out_buf}, in_desc = {SECBUFFER_VERSION, 2, in_bufs};
516 SecHandle *cred = &cred_handle;
517 BYTE *read_buf;
518 SIZE_T read_buf_size = 2048;
519 ULONG attrs = 0;
524
527
528 if (!ensure_cred_handle())
529 return -1;
530
531 if (compat_mode) {
533 return -1;
534 cred = &compat_cred_handle;
535 }
536
537 read_buf = xmalloc(read_buf_size);
538 if (!read_buf)
539 return ERROR_OUTOFMEMORY;
540
541 if (!g_ssl_server)
542 return -1;
543
544 status = InitializeSecurityContextA(cred, NULL, g_ssl_server, isc_req_flags, 0, 0, NULL, 0,
545 &ctx, &out_desc, &attrs, NULL);
546
547 //assert(status != SEC_E_OK);
548
550 {
551 if (out_buf.cbBuffer)
552 {
553 //assert(status == SEC_I_CONTINUE_NEEDED);
554
555 size = send(g_sock, out_buf.pvBuffer, out_buf.cbBuffer, 0);
556 if (size != out_buf.cbBuffer)
557 {
558 error("send failed: %d (%s)\n", size, TCP_STRERROR);
559 status = -1;
560 break;
561 }
562
563 FreeContextBuffer(out_buf.pvBuffer);
564 out_buf.pvBuffer = NULL;
565 out_buf.cbBuffer = 0;
566 }
567
569 {
570 //assert(in_bufs[1].cbBuffer < read_buf_size);
571
572 memmove(read_buf, (BYTE*)in_bufs[0].pvBuffer+in_bufs[0].cbBuffer-in_bufs[1].cbBuffer, in_bufs[1].cbBuffer);
573 in_bufs[0].cbBuffer = in_bufs[1].cbBuffer;
574
575 in_bufs[1].BufferType = SECBUFFER_EMPTY;
576 in_bufs[1].cbBuffer = 0;
577 in_bufs[1].pvBuffer = NULL;
578 }
579
580 //assert(in_bufs[0].BufferType == SECBUFFER_TOKEN);
581 //assert(in_bufs[1].BufferType == SECBUFFER_EMPTY);
582
583 if (in_bufs[0].cbBuffer + 1024 > read_buf_size)
584 {
585 BYTE *new_read_buf = xrealloc(read_buf, read_buf_size + 1024);
586 if (!new_read_buf)
587 {
589 break;
590 }
591
592 in_bufs[0].pvBuffer = read_buf = new_read_buf;
593 read_buf_size += 1024;
594 }
595
596 size = recv(g_sock, (char *)read_buf + in_bufs[0].cbBuffer, read_buf_size - in_bufs[0].cbBuffer, 0);
597 if (size < 1)
598 {
599 error("recv failed: %d (%s)\n", size, TCP_STRERROR);
600 res = -1;
601 break;
602 }
603
604 in_bufs[0].cbBuffer += size;
605 in_bufs[0].pvBuffer = read_buf;
606 status = InitializeSecurityContextA(cred, &ctx, g_ssl_server, isc_req_flags, 0, 0, &in_desc,
607 0, NULL, &out_desc, &attrs, NULL);
608
609 if (status == SEC_E_OK) {
610 if (SecIsValidHandle(&g_ssl->ssl_ctx))
612 g_ssl->ssl_ctx = ctx;
613
614 if (in_bufs[1].BufferType == SECBUFFER_EXTRA)
615 {
616 //FIXME("SECBUFFER_EXTRA not supported\n");
617 }
618
620 if (status != SEC_E_OK)
621 {
622 //error("Can't determine ssl buffer sizes: %ld\n", status);
623 break;
624 }
625
627 + g_ssl->ssl_sizes.cbTrailer);
628 if (!g_ssl->ssl_buf)
629 {
630 res = GetLastError();
631 break;
632 }
633 }
634 }
635
637
638 if (status != SEC_E_OK || res != ERROR_SUCCESS)
639 {
640 error("Failed to establish SSL connection: %08x (%u)\n", status, res);
641 xfree(g_ssl->ssl_buf);
642 g_ssl->ssl_buf = NULL;
643 return res ? res : -1;
644 }
645
646 return ERROR_SUCCESS;
647}
648
649/* Establish a SSL/TLS 1.0 connection */
651tcp_tls_connect(void)
652{
653 int err;
654 char tcp_port_rdp_s[10];
655
656 if (!g_ssl_initialized)
657 {
658 g_ssl = &g_ssl1;
660
661 g_ssl_initialized = True;
662 }
663
664 snprintf(tcp_port_rdp_s, 10, "%d", g_tcp_port_rdp);
665 if ((err = ssl_handshake(FALSE)) != 0)
666 {
667 goto fail;
668 }
669
670 return True;
671
672 fail:
673 g_ssl = NULL;
674 return False;
675}
676
677/* Get public key from server of TLS 1.0 connection */
680{
681 const CERT_CONTEXT *cert = NULL;
683
684 s->data = s->p = NULL;
685 s->size = 0;
686
687 if (g_ssl == NULL)
688 goto out;
690 if (status != SEC_E_OK)
691 {
692 error("tcp_tls_get_server_pubkey: QueryContextAttributesW() failed %ld\n", status);
693 goto out;
694 }
695
696 s->size = cert->cbCertEncoded;
697 if (s->size < 1)
698 {
699 error("tcp_tls_get_server_pubkey: cert->cbCertEncoded = %ld\n", cert->cbCertEncoded);
700 goto out;
701 }
702
703 s->data = s->p = (unsigned char *)xmalloc(s->size);
704 memcpy(cert->pbCertEncoded, &s->p, s->size);
705 s->p = s->data;
706 s->end = s->p + s->size;
707
708 out:
709 if (cert)
711 return (s->size != 0);
712}
713#endif /* WITH_SSL */
714
715/* Establish a connection on the TCP layer */
718{
719 socklen_t option_len;
720 uint32 option_value;
721 int i;
722
723#ifdef IPv6
724
725 int n;
726 struct addrinfo hints, *res, *ressave;
727 char tcp_port_rdp_s[10];
728
729 snprintf(tcp_port_rdp_s, 10, "%d", g_tcp_port_rdp);
730
731 memset(&hints, 0, sizeof(struct addrinfo));
732 hints.ai_family = AF_UNSPEC;
733 hints.ai_socktype = SOCK_STREAM;
734
735 if ((n = getaddrinfo(server, tcp_port_rdp_s, &hints, &res)))
736 {
737 error("getaddrinfo: %s\n", gai_strerror(n));
738 return False;
739 }
740
741 ressave = res;
742 g_sock = -1;
743 while (res)
744 {
745 g_sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
746 if (!(g_sock < 0))
747 {
748 if (connect(g_sock, res->ai_addr, res->ai_addrlen) == 0)
749 break;
751 g_sock = -1;
752 }
753 res = res->ai_next;
754 }
755 freeaddrinfo(ressave);
756
757 if (g_sock == -1)
758 {
759 error("%s: unable to connect\n", server);
760 return False;
761 }
762
763#else /* no IPv6 support */
764
765 struct hostent *nslookup;
766 struct sockaddr_in servaddr;
767
768 if ((nslookup = gethostbyname(server)) != NULL)
769 {
770 memcpy(&servaddr.sin_addr, nslookup->h_addr, sizeof(servaddr.sin_addr));
771 }
772 else if ((servaddr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE)
773 {
774 error("%s: unable to resolve host\n", server);
775 return False;
776 }
777
778 if ((g_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
779 {
780 error("socket: %s\n", TCP_STRERROR);
781 return False;
782 }
783
784 servaddr.sin_family = AF_INET;
785 servaddr.sin_port = htons((uint16) g_tcp_port_rdp);
786
787 if (connect(g_sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
788 {
789 if (!g_reconnect_loop)
790 error("connect: %s\n", TCP_STRERROR);
791
793 g_sock = -1;
794 return False;
795 }
796
797#endif /* IPv6 */
798
799 option_value = 1;
800 option_len = sizeof(option_value);
801 setsockopt(g_sock, IPPROTO_TCP, TCP_NODELAY, (void *) &option_value, option_len);
802 /* receive buffer must be a least 16 K */
803 if (getsockopt(g_sock, SOL_SOCKET, SO_RCVBUF, (void *) &option_value, &option_len) == 0)
804 {
805 if (option_value < (1024 * 16))
806 {
807 option_value = 1024 * 16;
808 option_len = sizeof(option_value);
809 setsockopt(g_sock, SOL_SOCKET, SO_RCVBUF, (void *) &option_value,
810 option_len);
811 }
812 }
813
814 g_in.size = 4096;
815 g_in.data = (uint8 *) xmalloc(g_in.size);
816
817 for (i = 0; i < STREAM_COUNT; i++)
818 {
819 g_out[i].size = 4096;
820 g_out[i].data = (uint8 *) xmalloc(g_out[i].size);
821 }
822
823#ifdef WITH_SSL
824 g_ssl_server = xmalloc(strlen(server)+1);
825#endif /* WITH_SSL */
826
827 return True;
828}
829
830/* Disconnect on the TCP layer */
831void
833{
834#ifdef WITH_SSL
835 if (g_ssl)
836 {
837 xfree(g_ssl->peek_msg_mem);
838 g_ssl->peek_msg_mem = NULL;
839 g_ssl->peek_msg = NULL;
840 g_ssl->peek_len = 0;
841 xfree(g_ssl->ssl_buf);
842 g_ssl->ssl_buf = NULL;
843 xfree(g_ssl->extra_buf);
844 g_ssl->extra_buf = NULL;
845 g_ssl->extra_len = 0;
846 if (SecIsValidHandle(&g_ssl->ssl_ctx))
852 if (g_ssl_server)
853 {
854 xfree(g_ssl_server);
855 g_ssl_server = NULL;
856 }
857 g_ssl = NULL;
858 g_ssl_initialized = False;
859 }
860#endif /* WITH_SSL */
862 g_sock = -1;
863}
864
865char *
867{
868 static char ipaddr[32];
869 struct sockaddr_in sockaddr;
870 socklen_t len = sizeof(sockaddr);
871 if (getsockname(g_sock, (struct sockaddr *) &sockaddr, &len) == 0)
872 {
873 uint8 *ip = (uint8 *) & sockaddr.sin_addr;
874 sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
875 }
876 else
877 strcpy(ipaddr, "127.0.0.1");
878 return ipaddr;
879}
880
883{
884 struct sockaddr_in sockaddr;
885 socklen_t len = sizeof(sockaddr);
886 if (getpeername(g_sock, (struct sockaddr *) &sockaddr, &len))
887 return True;
888 return False;
889}
890
891/* reset the state of the tcp layer */
892/* Support for Session Directory */
893void
895{
896 int i;
897
898 /* Clear the incoming stream */
899 if (g_in.data != NULL)
900 xfree(g_in.data);
901 g_in.p = NULL;
902 g_in.end = NULL;
903 g_in.data = NULL;
904 g_in.size = 0;
905 g_in.iso_hdr = NULL;
906 g_in.mcs_hdr = NULL;
907 g_in.sec_hdr = NULL;
908 g_in.rdp_hdr = NULL;
909 g_in.channel_hdr = NULL;
910
911 /* Clear the outgoing stream(s) */
912 for (i = 0; i < STREAM_COUNT; i++)
913 {
914 if (g_out[i].data != NULL)
915 xfree(g_out[i].data);
916 g_out[i].p = NULL;
917 g_out[i].end = NULL;
918 g_out[i].data = NULL;
919 g_out[i].size = 0;
920 g_out[i].iso_hdr = NULL;
921 g_out[i].mcs_hdr = NULL;
922 g_out[i].sec_hdr = NULL;
923 g_out[i].rdp_hdr = NULL;
924 g_out[i].channel_hdr = NULL;
925 }
926}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define msg(x)
Definition: auth_time.c:54
#define TCP_PORT_RDP
Definition: constants.h:21
#define SCARD_LOCK_TCP
Definition: constants.h:579
void xfree(void *mem)
Definition: uimain.c:758
void scard_lock(int lock)
RD_BOOL tcp_tls_get_server_pubkey(STREAM s)
RD_BOOL tcp_tls_connect(void)
int ui_select(int rdp_socket)
Definition: uimain.c:164
void scard_unlock(int lock)
void * xmalloc(int size)
Definition: uimain.c:747
void * xrealloc(void *oldmem, size_t size)
Definition: uimain.c:736
void tcp_disconnect(void)
Definition: tcp.c:832
#define TCP_CLOSE(_sck)
Definition: tcp.c:35
static struct stream g_out[STREAM_COUNT]
Definition: tcp.c:74
void tcp_send(STREAM s)
Definition: tcp.c:270
int g_tcp_port_rdp
Definition: tcp.c:75
static struct stream g_in
Definition: tcp.c:73
#define STREAM_COUNT
Definition: tcp.c:48
#define INADDR_NONE
Definition: tcp.c:42
void tcp_reset_state(void)
Definition: tcp.c:894
STREAM tcp_recv(STREAM s, uint32 length)
Definition: tcp.c:344
#define TCP_STRERROR
Definition: tcp.c:36
RD_BOOL g_network_error
Definition: uimain.c:77
#define TCP_SLEEP(_n)
Definition: tcp.c:37
#define TCP_BLOCKS
Definition: tcp.c:38
char * tcp_get_address()
Definition: tcp.c:866
RD_BOOL g_user_quit
Definition: uimain.c:76
RD_BOOL tcp_connect(char *server)
Definition: tcp.c:717
RD_BOOL g_reconnect_loop
Definition: uimain.c:86
RD_BOOL tcp_is_connected()
Definition: tcp.c:882
STREAM tcp_init(uint32 maxlen)
Definition: tcp.c:82
static int g_sock
Definition: tcp.c:72
unsigned short uint16
Definition: types.h:30
unsigned int uint32
Definition: types.h:32
#define False
Definition: types.h:25
int RD_BOOL
Definition: types.h:21
#define True
Definition: types.h:24
unsigned char uint8
Definition: types.h:28
LONG_PTR SSIZE_T
Definition: basetsd.h:183
@ sent
Definition: msg.h:34
#define ssl_handshake
Definition: compat-1.3.h:2337
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
static BOOL send_ssl_chunk(struct netconn *conn, const void *msg, size_t size)
Definition: net.c:398
static BOOL read_ssl_chunk(struct netconn *conn, void *buf, SIZE_T buf_size, SIZE_T *ret_size, BOOL *eof)
Definition: net.c:448
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
#define IPPROTO_TCP
Definition: ip.h:196
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
size_t total
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
GLdouble s
Definition: gl.h:2039
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
const GLenum * bufs
Definition: glext.h:6026
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define read_buf
Definition: intsym.h:279
#define inet_addr(cp)
Definition: inet.h:98
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define htons(x)
Definition: module.h:213
int socklen_t
Definition: tcp.c:35
static PVOID ptr
Definition: dispmode.c:27
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static BYTE cert[]
Definition: msg.c:1437
#define min(a, b)
Definition: monoChain.cc:55
static SecHandle compat_cred_handle
static BOOL cred_handle_initialized
static BOOL have_compat_cred_handle
static SecHandle cred_handle
static BOOL ensure_cred_handle(void)
#define ISC_REQ_MANUAL_CRED_VALIDATION
Definition: sspi.h:381
#define ISC_REQ_CONFIDENTIALITY
Definition: sspi.h:366
LONG SECURITY_STATUS
Definition: sspi.h:34
#define SecIsValidHandle(x)
Definition: sspi.h:63
#define ISC_REQ_ALLOCATE_MEMORY
Definition: sspi.h:370
#define SECPKG_CRED_OUTBOUND
Definition: sspi.h:291
#define SECBUFFER_STREAM_TRAILER
Definition: sspi.h:165
#define SECBUFFER_STREAM_HEADER
Definition: sspi.h:166
#define SECBUFFER_TOKEN
Definition: sspi.h:161
#define ISC_REQ_SEQUENCE_DETECT
Definition: sspi.h:365
#define ISC_REQ_REPLAY_DETECT
Definition: sspi.h:364
#define SECBUFFER_DATA
Definition: sspi.h:160
#define ISC_REQ_USE_SESSION_KEY
Definition: sspi.h:367
#define UNISP_NAME_W
Definition: sspi.h:38
#define SECBUFFER_EXTRA
Definition: sspi.h:164
#define SecInvalidateHandle(x)
Definition: sspi.h:58
#define SECPKG_ATTR_STREAM_SIZES
Definition: sspi.h:525
#define SECBUFFER_VERSION
Definition: sspi.h:187
#define SECBUFFER_EMPTY
Definition: sspi.h:159
#define err(...)
static FILE * out
Definition: regtests2xml.c:44
#define SP_PROT_TLS1_1PLUS_CLIENT
Definition: schannel.h:52
#define SECPKG_ATTR_SUPPORTED_PROTOCOLS
Definition: schannel.h:74
#define SCHANNEL_CRED_VERSION
Definition: schannel.h:22
#define SECPKG_ATTR_REMOTE_CERT_CONTEXT
Definition: schannel.h:69
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
#define memset(x, y, z)
Definition: compat.h:39
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
INT WSAAPI getpeername(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:167
INT WSAAPI getsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:213
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
INT WSAAPI getsockopt(IN SOCKET s, IN INT level, IN INT optname, OUT CHAR FAR *optval, IN OUT INT FAR *optlen)
Definition: sockctrl.c:271
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
SECURITY_STATUS WINAPI FreeContextBuffer(PVOID pv)
Definition: sspi.c:699
DWORD grbitEnabledProtocols
Definition: schannel.h:96
ULONG cbBuffer
Definition: sspi.h:153
Definition: dhcpd.h:62
size_t extra_len
Definition: internet.h:77
char * extra_buf
Definition: internet.h:76
char * peek_msg_mem
Definition: internet.h:79
CtxtHandle ssl_ctx
Definition: internet.h:72
char * peek_msg
Definition: internet.h:78
size_t peek_len
Definition: internet.h:80
SecPkgContext_StreamSizes ssl_sizes
Definition: internet.h:73
char * ssl_buf
Definition: internet.h:75
struct in_addr sin_addr
Definition: winsock.h:512
short sin_family
Definition: winsock.h:510
u_short sin_port
Definition: winsock.h:511
Definition: ps.c:97
Definition: parse.h:23
#define TCP_NODELAY
Definition: tcpdef.h:117
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG
Definition: typedefs.h:59
static rfbScreenInfoPtr server
Definition: vnc.c:74
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
#define SEC_E_OK
Definition: winerror.h:2356
#define SEC_I_CONTEXT_EXPIRED
Definition: winerror.h:2933
#define WSAEWOULDBLOCK
Definition: winerror.h:1948
#define SEC_I_CONTINUE_NEEDED
Definition: winerror.h:2927
#define SEC_E_INCOMPLETE_MESSAGE
Definition: winerror.h:2934
#define SO_RCVBUF
Definition: winsock.h:189
#define SOL_SOCKET
Definition: winsock.h:398
#define AF_UNSPEC
Definition: winsock.h:344
#define snprintf
Definition: wintirpc.h:48
SECURITY_STATUS WINAPI EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
Definition: wrapper.c:1006
SECURITY_STATUS WINAPI AcquireCredentialsHandleW(SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse, PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
Definition: wrapper.c:105
SECURITY_STATUS WINAPI DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
Definition: wrapper.c:1036
SECURITY_STATUS WINAPI QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
Definition: wrapper.c:535
SECURITY_STATUS WINAPI QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
Definition: wrapper.c:177
SECURITY_STATUS WINAPI InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
Definition: wrapper.c:237
SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:450
SECURITY_STATUS WINAPI FreeCredentialsHandle(PCredHandle phCredential)
Definition: wrapper.c:151
#define getaddrinfo
Definition: wspiapi.h:44
#define freeaddrinfo
Definition: wspiapi.h:46
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193