ReactOS 0.4.17-dev-1190-g4c812f4
netconnection.c
Go to the documentation of this file.
1#ifdef __REACTOS__
2#include "precomp.h"
3#else
4/*
5 * Wininet - networking layer
6 *
7 * Copyright 2002 TransGaming Technologies Inc.
8 * Copyright 2013 Jacek Caban for CodeWeavers
9 *
10 * David Hammerton
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include "ws2tcpip.h"
28
29#include <time.h>
30#include <stdarg.h>
31#include <stdlib.h>
32#include <string.h>
33#include <stdio.h>
34#include <assert.h>
35
36#include "windef.h"
37#include "winbase.h"
38#include "wininet.h"
39#include "winerror.h"
40
41#include "wine/debug.h"
42#include "internet.h"
43#endif /* defined(__REACTOS__) */
44
46
48{
49 BOOL ret;
50 CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } };
52 char oid_server_auth[] = szOID_PKIX_KP_SERVER_AUTH;
53 char *server_auth[] = { oid_server_auth };
54 DWORD err = ERROR_SUCCESS, errors;
55
56 static const DWORD supportedErrors =
62
63 TRACE("verifying %s\n", debugstr_w(conn->server->name));
64
66 chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = server_auth;
67 if (!(ret = CertGetCertificateChain(NULL, cert, NULL, store, &chainPara, 0, NULL, &chain))) {
68 TRACE("failed\n");
69 return GetLastError();
70 }
71
72 errors = chain->TrustStatus.dwErrorStatus;
73
74 do {
75 /* This seems strange, but that's what tests show */
76 if(errors & CERT_TRUST_IS_PARTIAL_CHAIN) {
77 WARN("ERROR_INTERNET_SEC_CERT_REV_FAILED\n");
79 if(conn->mask_errors)
82 break;
83 }
84
85 if (chain->TrustStatus.dwErrorStatus & ~supportedErrors) {
86 WARN("error status %lx\n", chain->TrustStatus.dwErrorStatus & ~supportedErrors);
88 errors &= supportedErrors;
89 if(!conn->mask_errors)
90 break;
91 WARN("unknown error flags\n");
92 }
93
94 if(errors & CERT_TRUST_IS_NOT_TIME_VALID) {
95 WARN("CERT_TRUST_IS_NOT_TIME_VALID\n");
98 if(!conn->mask_errors)
99 break;
101 }
102 errors &= ~CERT_TRUST_IS_NOT_TIME_VALID;
103 }
104
105 if(errors & CERT_TRUST_IS_UNTRUSTED_ROOT) {
106 WARN("CERT_TRUST_IS_UNTRUSTED_ROOT\n");
109 if(!conn->mask_errors)
110 break;
112 }
113 errors &= ~CERT_TRUST_IS_UNTRUSTED_ROOT;
114 }
115
116 if(errors & CERT_TRUST_IS_PARTIAL_CHAIN) {
117 WARN("CERT_TRUST_IS_PARTIAL_CHAIN\n");
120 if(!conn->mask_errors)
121 break;
123 }
124 errors &= ~CERT_TRUST_IS_PARTIAL_CHAIN;
125 }
126
128 WARN("CERT_TRUST_IS_NOT_SIGNATURE_VALID\n");
131 if(!conn->mask_errors)
132 break;
134 }
135 errors &= ~CERT_TRUST_IS_NOT_SIGNATURE_VALID;
136 }
137
139 WARN("CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n");
142 if(!conn->mask_errors)
143 break;
144 WARN("CERT_TRUST_IS_NOT_VALID_FOR_USAGE, unknown error flags\n");
145 }
146 errors &= ~CERT_TRUST_IS_NOT_VALID_FOR_USAGE;
147 }
148
152 }
153 }while(0);
154
155 if(!err || conn->mask_errors) {
156 CERT_CHAIN_POLICY_PARA policyPara;
157 SSL_EXTRA_CERT_CHAIN_POLICY_PARA sslExtraPolicyPara;
158 CERT_CHAIN_POLICY_STATUS policyStatus;
159 CERT_CHAIN_CONTEXT chainCopy;
160
161 /* Clear chain->TrustStatus.dwErrorStatus so
162 * CertVerifyCertificateChainPolicy will verify additional checks
163 * rather than stopping with an existing, ignored error.
164 */
165 memcpy(&chainCopy, chain, sizeof(chainCopy));
166 chainCopy.TrustStatus.dwErrorStatus = 0;
167 sslExtraPolicyPara.cbSize = sizeof(sslExtraPolicyPara);
168 sslExtraPolicyPara.dwAuthType = AUTHTYPE_SERVER;
169 sslExtraPolicyPara.pwszServerName = conn->server->name;
170 sslExtraPolicyPara.fdwChecks = conn->security_flags;
171 policyPara.cbSize = sizeof(policyPara);
172 policyPara.dwFlags = 0;
173 policyPara.pvExtraPolicyPara = &sslExtraPolicyPara;
175 &chainCopy, &policyPara, &policyStatus);
176 /* Any error in the policy status indicates that the
177 * policy couldn't be verified.
178 */
179 if(ret) {
180 if(policyStatus.dwError == CERT_E_CN_NO_MATCH) {
181 WARN("CERT_E_CN_NO_MATCH\n");
182 if(conn->mask_errors)
185 }else if(policyStatus.dwError) {
186 WARN("policyStatus.dwError %lx\n", policyStatus.dwError);
187 if(conn->mask_errors)
188 WARN("unknown error flags for policy status %lx\n", policyStatus.dwError);
190 }
191 }else {
192 err = GetLastError();
193 }
194 }
195
196 if(err) {
197 WARN("failed %lu\n", err);
199 if(conn->server->cert_chain) {
201 conn->server->cert_chain = NULL;
202 }
203 if(conn->mask_errors)
205 return err;
206 }
207
208 /* FIXME: Reuse cached chain */
209 if(conn->server->cert_chain)
211 else
212 conn->server->cert_chain = chain;
213 return ERROR_SUCCESS;
214}
215
218
221 0, 0, &init_sechandle_cs,
224 0, 0, { (DWORD_PTR)(__FILE__ ": init_sechandle_cs") }
225};
227
229{
231
233
237
240 if(res == SEC_E_OK) {
243 cred.grbitEnabledProtocols = prots.grbitProtocol & ~SP_PROT_TLS1_1PLUS_CLIENT;
247 }
248 }
249
251 }
252
254
255 if(res != SEC_E_OK) {
256 WARN("Failed: %08lx\n", res);
257 return FALSE;
258 }
259
260 return TRUE;
261}
262
264
265static BOOL WINAPI winsock_startup(INIT_ONCE *once, void *param, void **context)
266{
267 WSADATA wsa_data;
268 DWORD res;
269
270#ifdef __REACTOS__
271 res = WSAStartup(MAKEWORD(2,2), &wsa_data);
272#else
273 res = WSAStartup(MAKEWORD(1,1), &wsa_data);
274#endif
275 if(res == ERROR_SUCCESS)
277 else
278 ERR("WSAStartup failed: %lu\n", res);
279 return TRUE;
280}
281
282void init_winsock(void)
283{
286}
287
288static void set_socket_blocking(netconn_t *conn, BOOL is_blocking)
289{
290 if(conn->is_blocking != is_blocking) {
291 ULONG arg = !is_blocking;
292 ioctlsocket(conn->socket, FIONBIO, &arg);
293 }
294 conn->is_blocking = is_blocking;
295}
296
298{
299 int result;
300 ULONG flag;
301 DWORD res;
302
303 init_winsock();
304
305 assert(server->addr_len);
306 result = netconn->socket = socket(server->addr.ss_family, SOCK_STREAM, 0);
307 if(result != -1) {
309 result = connect(netconn->socket, (struct sockaddr*)&server->addr, server->addr_len);
310 if(result == -1)
311 {
313 if (res == WSAEINPROGRESS || res == WSAEWOULDBLOCK) {
314 FD_SET set;
315 int res;
316 socklen_t len = sizeof(res);
317 TIMEVAL timeout_timeval = {0, timeout*1000};
318
319 FD_ZERO(&set);
321 res = select(netconn->socket+1, NULL, &set, NULL, &timeout_timeval);
322 if(!res || res == SOCKET_ERROR) {
324 netconn->socket = -1;
326 }
327 if (!getsockopt(netconn->socket, SOL_SOCKET, SO_ERROR, (void *)&res, &len) && !res)
328 result = 0;
329 }
330 }
331 if(result == -1)
332 {
334 netconn->socket = -1;
335 }
336 }
337 if(result == -1)
339
340 flag = 1;
342 if(result < 0)
343 WARN("setsockopt(TCP_NODELAY) failed\n");
344
345 return ERROR_SUCCESS;
346}
347
349{
351 int result;
352
353 netconn = calloc(1, sizeof(*netconn));
354 if(!netconn)
355 return ERROR_OUTOFMEMORY;
356
357 netconn->socket = -1;
358 netconn->security_flags = security_flags | server->security_flags;
359 netconn->mask_errors = mask_errors;
360 list_init(&netconn->pool_entry);
362
364 if (result != ERROR_SUCCESS) {
365 free(netconn);
366 return result;
367 }
368
370 netconn->server = server;
371 *ret = netconn;
372 return result;
373}
374
376{
377 return netconn && netconn->socket != -1;
378}
379
381{
383 netconn->socket = -1;
384}
385
387{
388 server_release(netconn->server);
389
390 if (netconn->secure) {
394 netconn->peek_len = 0;
395 free(netconn->ssl_buf);
396 netconn->ssl_buf = NULL;
399 netconn->extra_len = 0;
400 }
403
405 free(netconn);
406}
407
409{
416 WSACleanup();
417}
418
419int sock_send(int fd, const void *msg, size_t len, int flags)
420{
421 int ret;
422 do
423 {
424 ret = send(fd, msg, len, flags);
425 }
426 while(ret == -1 && WSAGetLastError() == WSAEINTR);
427 return ret;
428}
429
430int sock_recv(int fd, void *msg, size_t len, int flags)
431{
432 int ret;
433 do
434 {
435 ret = recv(fd, msg, len, flags);
436 }
437 while(ret == -1 && WSAGetLastError() == WSAEINTR);
438 return ret;
439}
440
442{
443 SecBuffer out_buf = {0, SECBUFFER_TOKEN, NULL}, in_bufs[2] = {{0, SECBUFFER_TOKEN}, {0, SECBUFFER_EMPTY}};
444 SecBufferDesc out_desc = {SECBUFFER_VERSION, 1, &out_buf}, in_desc = {SECBUFFER_VERSION, 2, in_bufs};
445 SecHandle *cred = &cred_handle;
446 BYTE *read_buf;
447 SIZE_T read_buf_size = 2048;
448 ULONG attrs = 0;
451 int bits;
452 const CERT_CONTEXT *cert;
455
458
459 if(!ensure_cred_handle())
461
462 if(compat_mode) {
465 cred = &compat_cred_handle;
466 }
467
468 read_buf = malloc(read_buf_size);
469 if(!read_buf)
470 return ERROR_OUTOFMEMORY;
471
472 status = InitializeSecurityContextW(cred, NULL, connection->server->name, isc_req_flags, 0, 0, NULL, 0,
473 &ctx, &out_desc, &attrs, NULL);
474
476
478
480 if(out_buf.cbBuffer) {
482
483 TRACE("sending %lu bytes\n", out_buf.cbBuffer);
484
485 size = sock_send(connection->socket, out_buf.pvBuffer, out_buf.cbBuffer, 0);
486 if(size != out_buf.cbBuffer) {
487 ERR("send failed\n");
489 break;
490 }
491
492 FreeContextBuffer(out_buf.pvBuffer);
493 out_buf.pvBuffer = NULL;
494 out_buf.cbBuffer = 0;
495 }
496
498 assert(in_bufs[1].cbBuffer < read_buf_size);
499
500 memmove(read_buf, (BYTE*)in_bufs[0].pvBuffer+in_bufs[0].cbBuffer-in_bufs[1].cbBuffer, in_bufs[1].cbBuffer);
501 in_bufs[0].cbBuffer = in_bufs[1].cbBuffer;
502 }
503
504 assert(in_bufs[0].BufferType == SECBUFFER_TOKEN);
505 in_bufs[1].BufferType = SECBUFFER_EMPTY;
506 in_bufs[1].cbBuffer = 0;
507 in_bufs[1].pvBuffer = NULL;
508
509 if(in_bufs[0].cbBuffer + 1024 > read_buf_size) {
510 BYTE *new_read_buf;
511
512 new_read_buf = realloc(read_buf, read_buf_size + 1024);
513 if(!new_read_buf) {
515 break;
516 }
517
518 in_bufs[0].pvBuffer = read_buf = new_read_buf;
519 read_buf_size += 1024;
520 }
521
522 size = sock_recv(connection->socket, read_buf+in_bufs[0].cbBuffer, read_buf_size-in_bufs[0].cbBuffer, 0);
523 if(size < 1) {
524 WARN("recv error\n");
526 break;
527 }
528
529 TRACE("recv %Iu bytes\n", size);
530
531 in_bufs[0].cbBuffer += size;
532 in_bufs[0].pvBuffer = read_buf;
533 status = InitializeSecurityContextW(cred, &ctx, connection->server->name, isc_req_flags, 0, 0, &in_desc,
534 0, NULL, &out_desc, &attrs, NULL);
535 TRACE("InitializeSecurityContext ret %08lx\n", status);
536
537 if(status == SEC_E_OK) {
538 if(SecIsValidHandle(&connection->ssl_ctx))
540 connection->ssl_ctx = ctx;
541
542 if(in_bufs[1].BufferType == SECBUFFER_EXTRA)
543 FIXME("SECBUFFER_EXTRA not supported\n");
544
546 if(status != SEC_E_OK) {
547 WARN("Could not get sizes\n");
548 break;
549 }
550
552 if(status == SEC_E_OK) {
553 res = netconn_verify_cert(connection, cert, cert->hCertStore);
555 if(res != ERROR_SUCCESS) {
556 WARN("cert verify failed: %lu\n", res);
557 break;
558 }
559 }else {
560 WARN("Could not get cert\n");
561 break;
562 }
563
564 connection->ssl_buf = malloc(connection->ssl_sizes.cbHeader + connection->ssl_sizes.cbMaximumMessage
565 + connection->ssl_sizes.cbTrailer);
566 if(!connection->ssl_buf) {
567 res = GetLastError();
568 break;
569 }
570 }
571 }
572
573 free(read_buf);
574
575 if(status != SEC_E_OK || res != ERROR_SUCCESS) {
576 WARN("Failed to establish SSL connection: %08lx (%lu)\n", status, res);
577 free(connection->ssl_buf);
578 connection->ssl_buf = NULL;
580 }
581
582 TRACE("established SSL connection\n");
583 connection->secure = TRUE;
584 connection->security_flags |= SECURITY_FLAG_SECURE;
585
587 if (bits >= 128)
588 connection->security_flags |= SECURITY_FLAG_STRENGTH_STRONG;
589 else if (bits >= 56)
590 connection->security_flags |= SECURITY_FLAG_STRENGTH_MEDIUM;
591 else
592 connection->security_flags |= SECURITY_FLAG_STRENGTH_WEAK;
593
594 if(connection->mask_errors)
595 connection->server->security_flags = connection->security_flags;
596 return ERROR_SUCCESS;
597}
598
599/******************************************************************************
600 * NETCON_secure_connect
601 * Initiates a secure connection over an existing plaintext connection.
602 */
604{
605 DWORD res;
606
607 /* can't connect if we are already connected */
608 if(connection->secure) {
609 ERR("already connected\n");
611 }
612
613 if(server != connection->server) {
614 server_release(connection->server);
616 connection->server = server;
617 }
618
619 /* connect with given TLS options */
621 if (res == ERROR_SUCCESS)
622 return res;
623
624 /* FIXME: when got version alert and FIN from server */
625 /* fallback to connect without TLSv1.1/TLSv1.2 */
627 {
628 closesocket(connection->socket);
630 if (res != ERROR_SUCCESS)
631 return res;
633 }
634 return res;
635}
636
637static BOOL send_ssl_chunk(netconn_t *conn, const void *msg, size_t size)
638{
639 SecBuffer bufs[4] = {
644 };
647
648 memcpy(bufs[1].pvBuffer, msg, size);
649 res = EncryptMessage(&conn->ssl_ctx, 0, &buf_desc, 0);
650 if(res != SEC_E_OK) {
651 WARN("EncryptMessage failed\n");
652 return FALSE;
653 }
654
655 if(sock_send(conn->socket, conn->ssl_buf, bufs[0].cbBuffer+bufs[1].cbBuffer+bufs[2].cbBuffer, 0) < 1) {
656 WARN("send failed\n");
657 return FALSE;
658 }
659
660 return TRUE;
661}
662
663/******************************************************************************
664 * NETCON_send
665 * Basically calls 'send()' unless we should use SSL
666 * number of chars send is put in *sent
667 */
668DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags,
669 int *sent /* out */)
670{
671 /* send is always blocking. */
673
674 if(!connection->secure)
675 {
676 *sent = sock_send(connection->socket, msg, len, flags);
677 return *sent == -1 ? WSAGetLastError() : ERROR_SUCCESS;
678 }
679 else
680 {
681 const BYTE *ptr = msg;
682 size_t chunk_size;
683
684 *sent = 0;
685
686 while(len) {
687 chunk_size = min(len, connection->ssl_sizes.cbMaximumMessage);
688 if(!send_ssl_chunk(connection, ptr, chunk_size))
690
691 *sent += chunk_size;
692 ptr += chunk_size;
693 len -= chunk_size;
694 }
695
696 return ERROR_SUCCESS;
697 }
698}
699
700static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, BOOL blocking, SIZE_T *ret_size, BOOL *eof)
701{
702 const SIZE_T ssl_buf_size = conn->ssl_sizes.cbHeader+conn->ssl_sizes.cbMaximumMessage+conn->ssl_sizes.cbTrailer;
703 SecBuffer bufs[4];
705 SSIZE_T size, buf_len = 0;
706 int i;
708
709 assert(conn->extra_len < ssl_buf_size);
710
711 if(conn->extra_len) {
712 memcpy(conn->ssl_buf, conn->extra_buf, conn->extra_len);
713 buf_len = conn->extra_len;
714 conn->extra_len = 0;
715 free(conn->extra_buf);
716 conn->extra_buf = NULL;
717 }
718
719 set_socket_blocking(conn, blocking && !buf_len);
720 size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0);
721 if(size < 0) {
722 if(!buf_len) {
724 TRACE("would block\n");
725 return WSAEWOULDBLOCK;
726 }
727 WARN("recv failed\n");
729 }
730 }else {
731 buf_len += size;
732 }
733
734 if(!buf_len) {
735 TRACE("EOF\n");
736 *eof = TRUE;
737 *ret_size = 0;
738 return ERROR_SUCCESS;
739 }
740
741 *eof = FALSE;
742
743 do {
744 memset(bufs, 0, sizeof(bufs));
745 bufs[0].BufferType = SECBUFFER_DATA;
746 bufs[0].cbBuffer = buf_len;
747 bufs[0].pvBuffer = conn->ssl_buf;
748
749 res = DecryptMessage(&conn->ssl_ctx, &buf_desc, 0, NULL);
750 switch(res) {
751 case SEC_E_OK:
752 break;
754 TRACE("context expired\n");
755 *eof = TRUE;
756 return ERROR_SUCCESS;
758 assert(buf_len < ssl_buf_size);
759
760 set_socket_blocking(conn, blocking);
761 size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0);
762 if(size < 1) {
763 if(size < 0 && WSAGetLastError() == WSAEWOULDBLOCK) {
764 TRACE("would block\n");
765
766 /* FIXME: Optimize extra_buf usage. */
767 conn->extra_buf = malloc(buf_len);
768 if(!conn->extra_buf)
770
771 conn->extra_len = buf_len;
772 memcpy(conn->extra_buf, conn->ssl_buf, conn->extra_len);
773 return WSAEWOULDBLOCK;
774 }
775
777 }
778
779 buf_len += size;
780 continue;
781 default:
782 WARN("failed: %08lx\n", res);
784 }
785 } while(res != SEC_E_OK);
786
787 for(i = 0; i < ARRAY_SIZE(bufs); i++) {
788 if(bufs[i].BufferType == SECBUFFER_DATA) {
789 size = min(buf_size, bufs[i].cbBuffer);
790 memcpy(buf, bufs[i].pvBuffer, size);
791 if(size < bufs[i].cbBuffer) {
792 assert(!conn->peek_len);
793 conn->peek_msg_mem = conn->peek_msg = malloc(bufs[i].cbBuffer - size);
794 if(!conn->peek_msg)
796 conn->peek_len = bufs[i].cbBuffer-size;
797 memcpy(conn->peek_msg, (char*)bufs[i].pvBuffer+size, conn->peek_len);
798 }
799
800 *ret_size = size;
801 }
802 }
803
804 for(i = 0; i < ARRAY_SIZE(bufs); i++) {
805 if(bufs[i].BufferType == SECBUFFER_EXTRA) {
806 conn->extra_buf = malloc(bufs[i].cbBuffer);
807 if(!conn->extra_buf)
809
810 conn->extra_len = bufs[i].cbBuffer;
811 memcpy(conn->extra_buf, bufs[i].pvBuffer, conn->extra_len);
812 }
813 }
814
815 return ERROR_SUCCESS;
816}
817
818/******************************************************************************
819 * NETCON_recv
820 * Basically calls 'recv()' unless we should use SSL
821 * number of chars received is put in *recvd
822 */
823DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, BOOL blocking, int *recvd)
824{
825 *recvd = 0;
826 if (!len)
827 return ERROR_SUCCESS;
828
829 if (!connection->secure)
830 {
832 *recvd = sock_recv(connection->socket, buf, len, 0);
833 return *recvd == -1 ? WSAGetLastError() : ERROR_SUCCESS;
834 }
835 else
836 {
837 SIZE_T size = 0;
838 BOOL eof;
839 DWORD res;
840
841 if(connection->peek_msg) {
842 size = min(len, connection->peek_len);
843 memcpy(buf, connection->peek_msg, size);
844 connection->peek_len -= size;
845 connection->peek_msg += size;
846
847 if(!connection->peek_len) {
848 free(connection->peek_msg_mem);
849 connection->peek_msg_mem = connection->peek_msg = NULL;
850 }
851
852 *recvd = size;
853 return ERROR_SUCCESS;
854 }
855
856 do {
857 res = read_ssl_chunk(connection, (BYTE*)buf, len, blocking, &size, &eof);
858 if(res != ERROR_SUCCESS) {
859 if(res == WSAEWOULDBLOCK) {
860 if(size)
862 }else {
863 WARN("read_ssl_chunk failed\n");
864 }
865 break;
866 }
867 }while(!size && !eof);
868
869 TRACE("received %Id bytes\n", size);
870 *recvd = size;
871 return res;
872 }
873}
874
876{
877 int len;
878 char b;
879
882
883 return len == 1 || (len == -1 && WSAGetLastError() == WSAEWOULDBLOCK);
884}
885
887{
888 const CERT_CONTEXT *ret;
890
892 return res == SEC_E_OK ? ret : NULL;
893}
894
896{
899
900 if (!connection->secure)
901 return 0;
902
903 res = QueryContextAttributesW(&connection->ssl_ctx, SECPKG_ATTR_CONNECTION_INFO, (void*)&conn_info);
904 if(res != SEC_E_OK)
905 WARN("QueryContextAttributesW failed: %08lx\n", res);
906 return res == SEC_E_OK ? conn_info.dwCipherStrength : 0;
907}
908
910{
911 int result;
912
914 send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&value,
915 sizeof(value));
916 if (result == -1)
917 {
918 WARN("setsockopt failed\n");
919 return WSAGetLastError();
920 }
921 return ERROR_SUCCESS;
922}
@ sent
Definition: SystemMenu.c:27
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
LONG_PTR SSIZE_T
Definition: basetsd.h:175
Definition: _set.h:50
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#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:369
BOOL WINAPI CertVerifyCertificateChainPolicy(LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
Definition: chain.c:3806
BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, PCCERT_CONTEXT pCertContext, LPFILETIME pTime, HCERTSTORE hAdditionalStore, PCERT_CHAIN_PARA pChainPara, DWORD dwFlags, LPVOID pvReserved, PCCERT_CHAIN_CONTEXT *ppChainContext)
Definition: chain.c:2875
VOID WINAPI CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT pChainContext)
Definition: chain.c:2956
HINTERNET connection
Definition: port.c:65
BOOL WINAPI InitOnceExecuteOnce(_Inout_ PINIT_ONCE InitOnce, _In_ __callback PINIT_ONCE_FN InitFn, _Inout_opt_ PVOID Parameter, _Outptr_opt_result_maybenull_ LPVOID *Context)
Definition: InitOnce.c:12
#define assert(_expr)
Definition: assert.h:32
static int eof(int fd)
Definition: io.h:21
void server_release(server_t *server)
Definition: http.c:148
void server_addref(server_t *server)
Definition: http.c:143
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
return ret
Definition: mutex.c:147
#define IPPROTO_TCP
Definition: ip.h:197
#define SOCK_STREAM
Definition: tcpip.h:118
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint res
Definition: glext.h:9613
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
const GLenum * bufs
Definition: glext.h:6026
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLuint64EXT * result
Definition: glext.h:11304
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
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 flag
Definition: glfuncs.h:52
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 bits
Definition: infblock.c:15
#define _SECURITY_FLAG_CERT_REV_FAILED
Definition: internet.h:440
#define _SECURITY_FLAG_CERT_INVALID_CN
Definition: internet.h:442
#define _SECURITY_ERROR_FLAGS_MASK
Definition: internet.h:445
#define _SECURITY_FLAG_CERT_INVALID_DATE
Definition: internet.h:443
#define _SECURITY_FLAG_CERT_INVALID_CA
Definition: internet.h:441
#define read_buf
Definition: intsym.h:279
#define b
Definition: ke_i.h:79
#define debugstr_w
Definition: kernel32.h:32
CONST void * LPCVOID
Definition: minwindef.h:164
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
int socklen_t
Definition: tcp.c:35
static PVOID ptr
Definition: dispmode.c:27
static BYTE cert[]
Definition: msg.c:1374
static void ULONG ULONG * ret_size
Definition: time.c:40
#define min(a, b)
Definition: monoChain.cc:55
#define ioctlsocket
Definition: ncftp.h:481
#define closesocket
Definition: ncftp.h:477
LONG SECURITY_STATUS
Definition: ncrypt.h:31
DWORD NETCON_secure_connect(netconn_t *connection, server_t *server)
static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, BOOL blocking, SIZE_T *ret_size, BOOL *eof)
static SecHandle compat_cred_handle
static CRITICAL_SECTION init_sechandle_cs
static BOOL cred_handle_initialized
static CRITICAL_SECTION_DEBUG init_sechandle_cs_debug
static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD timeout)
BOOL is_valid_netconn(netconn_t *netconn)
int NETCON_GetCipherStrength(netconn_t *connection)
static BOOL have_compat_cred_handle
static void set_socket_blocking(netconn_t *conn, BOOL is_blocking)
int sock_send(int fd, const void *msg, size_t len, int flags)
static BOOL winsock_loaded
DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags, int *sent)
void NETCON_unload(void)
int sock_recv(int fd, void *msg, size_t len, int flags)
DWORD create_netconn(server_t *server, DWORD security_flags, BOOL mask_errors, DWORD timeout, netconn_t **ret)
static BOOL WINAPI winsock_startup(INIT_ONCE *once, void *param, void **context)
LPCVOID NETCON_GetCert(netconn_t *connection)
static SecHandle cred_handle
void init_winsock(void)
void free_netconn(netconn_t *netconn)
BOOL NETCON_is_alive(netconn_t *netconn)
void close_netconn(netconn_t *netconn)
static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode)
static BOOL send_ssl_chunk(netconn_t *conn, const void *msg, size_t size)
DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value)
static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTORE store)
Definition: netconnection.c:47
DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, BOOL blocking, int *recvd)
static BOOL ensure_cred_handle(void)
short WCHAR
Definition: pedump.c:58
#define ISC_REQ_MANUAL_CRED_VALIDATION
Definition: sspi.h:381
#define ISC_REQ_CONFIDENTIALITY
Definition: sspi.h:366
#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(...)
#define calloc
Definition: rosglue.h:14
SIZE_T cbBuffer
Definition: sc_lib_mldsa.h:405
#define SP_PROT_TLS1_1PLUS_CLIENT
Definition: schannel.h:52
#define SECPKG_ATTR_CONNECTION_INFO
Definition: schannel.h:76
#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
static int fd
Definition: io.c:51
#define memset(x, y, z)
Definition: compat.h:39
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
#define TRACE(s)
Definition: solgame.cpp:4
SECURITY_STATUS WINAPI FreeContextBuffer(PVOID pv)
Definition: sspi.c:699
CERT_TRUST_STATUS TrustStatus
Definition: wincrypt.h:1051
CERT_USAGE_MATCH RequestedUsage
Definition: wincrypt.h:1183
CERT_ENHKEY_USAGE Usage
Definition: wincrypt.h:1161
DWORD cUsageIdentifier
Definition: wincrypt.h:831
LPSTR * rgpszUsageIdentifier
Definition: wincrypt.h:832
DWORD grbitEnabledProtocols
Definition: schannel.h:96
ULONG cbBuffer
Definition: sspi.h:153
Definition: http.c:7783
Definition: winsock.h:60
BOOL is_blocking
Definition: internet.h:70
size_t extra_len
Definition: internet.h:76
char * extra_buf
Definition: internet.h:75
char * peek_msg_mem
Definition: internet.h:78
CtxtHandle ssl_ctx
Definition: internet.h:71
char * peek_msg
Definition: internet.h:77
size_t peek_len
Definition: internet.h:79
int socket
Definition: internet.h:68
DWORD security_flags
Definition: internet.h:80
SecPkgContext_StreamSizes ssl_sizes
Definition: internet.h:72
char * ssl_buf
Definition: internet.h:74
server_t * server
Definition: internet.h:73
BOOL mask_errors
Definition: internet.h:81
char * peek_msg
char * extra_buf
char * peek_msg_mem
CtxtHandle ssl_ctx
size_t extra_len
size_t peek_len
WCHAR * name
Definition: internet.h:35
const CERT_CHAIN_CONTEXT * cert_chain
Definition: internet.h:49
DWORD security_flags
Definition: internet.h:48
Definition: ps.c:97
Definition: dhcpd.h:248
struct sock * chain
Definition: tcpcore.h:1
#define TCP_NODELAY
Definition: tcpdef.h:117
#define DWORD_PTR
Definition: treelist.c:76
#define MAKEWORD(a, b)
Definition: typedefs.h:248
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:64
static INIT_ONCE init_once
Definition: vfwcapture.c:981
static rfbScreenInfoPtr server
Definition: vnc.c:74
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
RTL_RUN_ONCE INIT_ONCE
Definition: winbase.h:3654
#define INIT_ONCE_STATIC_INIT
Definition: winbase.h:591
#define AUTHTYPE_SERVER
Definition: wincrypt.h:1148
#define szOID_PKIX_KP_SERVER_AUTH
Definition: wincrypt.h:3450
#define CERT_CHAIN_POLICY_SSL
Definition: wincrypt.h:1077
#define CERT_TRUST_IS_PARTIAL_CHAIN
Definition: wincrypt.h:1003
#define CERT_TRUST_IS_NOT_VALID_FOR_USAGE
Definition: wincrypt.h:986
#define CERT_TRUST_IS_NOT_SIGNATURE_VALID
Definition: wincrypt.h:985
#define CERT_TRUST_IS_UNTRUSTED_ROOT
Definition: wincrypt.h:987
#define CERT_TRUST_IS_NOT_TIME_VALID
Definition: wincrypt.h:982
#define WINAPI
Definition: msvc.h:6
#define SEC_E_OK
Definition: winerror.h:3450
#define SEC_I_CONTEXT_EXPIRED
Definition: winerror.h:4330
#define WSAEWOULDBLOCK
Definition: winerror.h:2851
#define CERT_E_CN_NO_MATCH
Definition: winerror.h:4645
#define SEC_I_CONTINUE_NEEDED
Definition: winerror.h:4324
#define WSAEINPROGRESS
Definition: winerror.h:2852
#define WSAEINTR
Definition: winerror.h:2841
#define SEC_E_INCOMPLETE_MESSAGE
Definition: winerror.h:4332
#define SECURITY_FLAG_STRENGTH_MEDIUM
Definition: winhttp.h:349
#define SECURITY_FLAG_STRENGTH_WEAK
Definition: winhttp.h:348
#define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
Definition: winhttp.h:344
#define SECURITY_FLAG_SECURE
Definition: winhttp.h:347
#define SECURITY_FLAG_STRENGTH_STRONG
Definition: winhttp.h:350
#define SECURITY_FLAG_IGNORE_UNKNOWN_CA
Definition: winhttp.h:343
#define ERROR_INTERNET_SEC_CERT_CN_INVALID
Definition: wininet.h:2026
#define ERROR_INTERNET_SECURITY_CHANNEL_ERROR
Definition: wininet.h:2069
#define ERROR_INTERNET_CONNECTION_ABORTED
Definition: wininet.h:2019
#define ERROR_INTERNET_INVALID_CA
Definition: wininet.h:2033
#define ERROR_INTERNET_SEC_CERT_DATE_INVALID
Definition: wininet.h:2025
#define SECURITY_FLAG_IGNORE_WRONG_USAGE
Definition: wininet.h:831
#define SECURITY_FLAG_IGNORE_REVOCATION
Definition: wininet.h:829
#define ERROR_INTERNET_CANNOT_CONNECT
Definition: wininet.h:2018
#define ERROR_INTERNET_SEC_CERT_REV_FAILED
Definition: wininet.h:2044
#define ERROR_INTERNET_SEC_CERT_ERRORS
Definition: wininet.h:2042
#define ERROR_INTERNET_SEC_INVALID_CERT
Definition: wininet.h:2077
#define SO_ERROR
Definition: winsock.h:188
int PASCAL FAR WSAGetLastError(void)
Definition: dllmain.c:131
#define FD_ZERO(set)
Definition: winsock.h:90
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60
#define MSG_PEEK
Definition: winsock.h:216
#define SOCKET_ERROR
Definition: winsock.h:327
#define SOL_SOCKET
Definition: winsock.h:392
#define SO_SNDTIMEO
Definition: winsock.h:186
#define FD_SET(fd, set)
Definition: winsock.h:83
#define SO_RCVTIMEO
Definition: winsock.h:187
#define FIONBIO
Definition: winsock.h:143
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 InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
Definition: wrapper.c:301
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 DeleteSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:450
SECURITY_STATUS WINAPI FreeCredentialsHandle(PCredHandle phCredential)
Definition: wrapper.c:151
unsigned char BYTE
Definition: xxhash.c:193