ReactOS 0.4.16-dev-2491-g3dc6630
net.c
Go to the documentation of this file.
1/*
2 * Copyright 2008 Hans Leidekker for CodeWeavers
3 * Copyright 2013 Jacek Caban for CodeWeavers
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20#include <assert.h>
21#include <stdarg.h>
22
23#include "windef.h"
24#include "winbase.h"
25#include "ws2tcpip.h"
26#include "winhttp.h"
27#include "schannel.h"
28#include "winternl.h"
29
30#include "wine/debug.h"
31#include "winhttp_private.h"
32
34
35static int sock_send(int fd, const void *msg, size_t len, WSAOVERLAPPED *ovr)
36{
37 WSABUF wsabuf;
38 DWORD size;
39 int err;
40
41 wsabuf.len = len;
42 wsabuf.buf = (void *)msg;
43
44 if (!WSASend( (SOCKET)fd, &wsabuf, 1, &size, 0, ovr, NULL ))
45 {
46 assert( size == len );
47 return size;
48 }
50 if (!(ovr && err == WSA_IO_PENDING)) WARN( "send error %d\n", err );
51 return -1;
52}
53
55{
56 OVERLAPPED *completion_ovr;
58
59 while (1)
60 {
61 if (!GetQueuedCompletionStatus( conn->port, len, &key, &completion_ovr, INFINITE ))
62 {
63 WARN( "GetQueuedCompletionStatus failed, err %lu.\n", GetLastError() );
64 return FALSE;
65 }
66 if (completion_ovr == (OVERLAPPED *)ovr && (key == conn->socket || conn->socket == -1))
67 break;
68 ERR( "Unexpected completion key %Ix, completion ovr %p, ovr %p.\n", key, completion_ovr, ovr );
69 }
70 return TRUE;
71}
72
73static int sock_recv(int fd, void *msg, size_t len, int flags)
74{
75 int ret;
76 do
77 {
78 if ((ret = recv(fd, msg, len, flags)) == -1) WARN( "recv error %d\n", WSAGetLastError() );
79 }
80 while(ret == -1 && WSAGetLastError() == WSAEINTR);
81 return ret;
82}
83
84static DWORD netconn_verify_cert( PCCERT_CONTEXT cert, WCHAR *server, DWORD security_flags, BOOL check_revocation )
85{
86 HCERTSTORE store = cert->hCertStore;
87 BOOL ret;
88 CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } };
90 char oid_server_auth[] = szOID_PKIX_KP_SERVER_AUTH;
91 char *server_auth[] = { oid_server_auth };
93
94 TRACE("verifying %s\n", debugstr_w( server ));
96 chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = server_auth;
97 ret = CertGetCertificateChain( NULL, cert, NULL, store, &chainPara,
99 NULL, &chain );
100 if (ret)
101 {
102 if (chain->TrustStatus.dwErrorStatus)
103 {
104 static const DWORD supportedErrors =
108
109 if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_TIME_VALID)
110 {
111 if (!(security_flags & SECURITY_FLAG_IGNORE_CERT_DATE_INVALID))
113 }
114 else if ((chain->TrustStatus.dwErrorStatus &
116 (chain->TrustStatus.dwErrorStatus &
118 {
119 if (!(security_flags & SECURITY_FLAG_IGNORE_UNKNOWN_CA))
121 }
122 else if ((chain->TrustStatus.dwErrorStatus &
124 (chain->TrustStatus.dwErrorStatus &
127 else if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_REVOKED)
129 else if (chain->TrustStatus.dwErrorStatus &
131 {
132 if (!(security_flags & SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE))
134 }
135 else if (chain->TrustStatus.dwErrorStatus & ~supportedErrors)
137 }
138 if (!err)
139 {
140 CERT_CHAIN_POLICY_PARA policyPara;
141 SSL_EXTRA_CERT_CHAIN_POLICY_PARA sslExtraPolicyPara;
142 CERT_CHAIN_POLICY_STATUS policyStatus;
143 CERT_CHAIN_CONTEXT chainCopy;
144
145 /* Clear chain->TrustStatus.dwErrorStatus so
146 * CertVerifyCertificateChainPolicy will verify additional checks
147 * rather than stopping with an existing, ignored error.
148 */
149 memcpy(&chainCopy, chain, sizeof(chainCopy));
150 chainCopy.TrustStatus.dwErrorStatus = 0;
151 sslExtraPolicyPara.cbSize = sizeof(sslExtraPolicyPara);
152 sslExtraPolicyPara.dwAuthType = AUTHTYPE_SERVER;
153 sslExtraPolicyPara.pwszServerName = server;
154 sslExtraPolicyPara.fdwChecks = security_flags;
155 policyPara.cbSize = sizeof(policyPara);
156 policyPara.dwFlags = 0;
157 policyPara.pvExtraPolicyPara = &sslExtraPolicyPara;
159 &chainCopy, &policyPara,
160 &policyStatus );
161 /* Any error in the policy status indicates that the
162 * policy couldn't be verified.
163 */
164 if (ret && policyStatus.dwError)
165 {
166 if (policyStatus.dwError == CERT_E_CN_NO_MATCH)
168 else
170 }
171 }
173 }
174 else
176 TRACE( "returning %#lx\n", err );
177 return err;
178}
179
181
182void netconn_unload( void )
183{
185}
186
187static BOOL WINAPI winsock_startup( INIT_ONCE *once, void *param, void **ctx )
188{
189 int ret;
191 if (!(ret = WSAStartup( MAKEWORD(1,1), &data ))) winsock_loaded = TRUE;
192 else ERR( "WSAStartup failed: %d\n", ret );
193 return TRUE;
194}
195
196#ifdef __REACTOS__
197void winsock_init(void)
198#else
199static void winsock_init(void)
200#endif
201{
202 static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
204}
205
206static void set_blocking( struct netconn *conn, BOOL blocking )
207{
208 ULONG state = !blocking;
209 ioctlsocket( conn->socket, FIONBIO, &state );
210}
211
213 struct netconn **ret_conn )
214{
215 struct netconn *conn;
216 unsigned int addr_len;
217 DWORD ret;
218
219#ifndef __REACTOS__
220 winsock_init();
221#endif
222
223 if (!(conn = calloc( 1, sizeof(*conn) ))) return ERROR_OUTOFMEMORY;
224 conn->refs = 1;
225 conn->host = host;
226 conn->sockaddr = *sockaddr;
227 if ((conn->socket = WSASocketW( sockaddr->ss_family, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED )) == -1)
228 {
230 WARN( "unable to create socket (%lu)\n", ret );
231 free( conn );
232 return ret;
233 }
235 ERR( "SetFileCompletionNotificationModes failed.\n" );
236
237 switch (conn->sockaddr.ss_family)
238 {
239 case AF_INET:
240 addr_len = sizeof(struct sockaddr_in);
241 break;
242 case AF_INET6:
243 addr_len = sizeof(struct sockaddr_in6);
244 break;
245 default:
246 ERR( "unhandled family %u\n", conn->sockaddr.ss_family );
247 free( conn );
249 }
250
251 if (timeout > 0) set_blocking( conn, FALSE );
252
253 if (!connect( conn->socket, (const struct sockaddr *)&conn->sockaddr, addr_len )) ret = ERROR_SUCCESS;
254 else
255 {
258 {
259 TIMEVAL timeval = { timeout / 1000, (timeout % 1000) * 1000 };
260 FD_SET set_read, set_error;
261 int res;
262
263 FD_ZERO( &set_read );
264 FD_SET( conn->socket, &set_read );
265 FD_ZERO( &set_error );
266 FD_SET( conn->socket, &set_error );
267 if ((res = select( conn->socket + 1, NULL, &set_read, &set_error, &timeval )) > 0)
268 {
269 if (FD_ISSET(conn->socket, &set_read)) ret = ERROR_SUCCESS;
270 else assert( FD_ISSET(conn->socket, &set_error) );
271 }
272 else if (!res) ret = ERROR_WINHTTP_TIMEOUT;
273 }
274 }
275
276 if (timeout > 0) set_blocking( conn, TRUE );
277
278 if (ret)
279 {
280 WARN( "unable to connect to host (%lu)\n", ret );
281 closesocket( conn->socket );
282 free( conn );
284 }
285
286 *ret_conn = conn;
287 return ERROR_SUCCESS;
288}
289
290void netconn_addref( struct netconn *conn )
291{
292 InterlockedIncrement( &conn->refs );
293}
294
295void netconn_release( struct netconn *conn )
296{
297 if (InterlockedDecrement( &conn->refs )) return;
298 TRACE( "Closing connection %p.\n", conn );
299 if (conn->secure)
300 {
301 free( conn->peek_msg_mem );
302 free(conn->ssl_read_buf);
303 free(conn->ssl_write_buf);
304 free(conn->extra_buf);
306 }
307 if (conn->socket != -1)
308 closesocket( conn->socket );
309 release_host( conn->host );
310 if (conn->port)
311 CloseHandle( conn->port );
312 free(conn);
313}
314
316 BOOL check_revocation )
317{
318 SecBuffer out_buf = {0, SECBUFFER_TOKEN, NULL}, in_bufs[2] = {{0, SECBUFFER_TOKEN}, {0, SECBUFFER_EMPTY}};
319 SecBufferDesc out_desc = {SECBUFFER_VERSION, 1, &out_buf}, in_desc = {SECBUFFER_VERSION, 2, in_bufs};
320 BYTE *read_buf;
321 SIZE_T read_buf_size = 2048;
322 ULONG attrs = 0;
325 const CERT_CONTEXT *cert;
328
331
332 if (!(read_buf = malloc( read_buf_size ))) return ERROR_OUTOFMEMORY;
333
334 memset( &ctx, 0, sizeof(ctx) );
335 status = InitializeSecurityContextW(cred_handle, NULL, hostname, isc_req_flags, 0, 0, NULL, 0,
336 &ctx, &out_desc, &attrs, NULL);
337
339
341 if(out_buf.cbBuffer) {
343
344 TRACE( "sending %lu bytes\n", out_buf.cbBuffer );
345
346 size = sock_send(conn->socket, out_buf.pvBuffer, out_buf.cbBuffer, NULL);
347 if(size != out_buf.cbBuffer) {
348 ERR("send failed\n");
350 break;
351 }
352
353 FreeContextBuffer(out_buf.pvBuffer);
354 out_buf.pvBuffer = NULL;
355 out_buf.cbBuffer = 0;
356 }
357
359 assert(in_bufs[1].cbBuffer < read_buf_size);
360
361 memmove(read_buf, (BYTE*)in_bufs[0].pvBuffer+in_bufs[0].cbBuffer-in_bufs[1].cbBuffer, in_bufs[1].cbBuffer);
362 in_bufs[0].cbBuffer = in_bufs[1].cbBuffer;
363 }
364
365 assert(in_bufs[0].BufferType == SECBUFFER_TOKEN);
366 in_bufs[1].BufferType = SECBUFFER_EMPTY;
367 in_bufs[1].cbBuffer = 0;
368 in_bufs[1].pvBuffer = NULL;
369
370 if(in_bufs[0].cbBuffer + 1024 > read_buf_size) {
371 BYTE *new_read_buf;
372
373 new_read_buf = realloc(read_buf, read_buf_size + 1024);
374 if(!new_read_buf) {
376 break;
377 }
378
379 in_bufs[0].pvBuffer = read_buf = new_read_buf;
380 read_buf_size += 1024;
381 }
382
383 size = sock_recv(conn->socket, read_buf+in_bufs[0].cbBuffer, read_buf_size-in_bufs[0].cbBuffer, 0);
384 if(size < 1) {
386 break;
387 }
388
389 TRACE( "recv %Iu bytes\n", size );
390
391 in_bufs[0].cbBuffer += size;
392 in_bufs[0].pvBuffer = read_buf;
393 status = InitializeSecurityContextW(cred_handle, &ctx, hostname, isc_req_flags, 0, 0, &in_desc,
394 0, NULL, &out_desc, &attrs, NULL);
395 TRACE( "InitializeSecurityContext ret %#lx\n", status );
396
397 if(status == SEC_E_OK) {
398 if(in_bufs[1].BufferType == SECBUFFER_EXTRA)
399 FIXME("SECBUFFER_EXTRA not supported\n");
400
402 if(status != SEC_E_OK) {
403 WARN("Could not get sizes\n");
404 break;
405 }
406
408 if(status == SEC_E_OK) {
409 res = netconn_verify_cert(cert, hostname, security_flags, check_revocation);
411 if(res != ERROR_SUCCESS) {
412 WARN( "cert verify failed: %lu\n", res );
413 break;
414 }
415 }else {
416 WARN("Could not get cert\n");
417 break;
418 }
419
421 if(!conn->ssl_read_buf) {
423 break;
424 }
426 if(!conn->ssl_write_buf) {
428 break;
429 }
430 }
431 }
432
433 free(read_buf);
434
435 if(status != SEC_E_OK || res != ERROR_SUCCESS) {
436 WARN( "Failed to initialize security context: %#lx\n", status );
437 free(conn->ssl_read_buf);
438 conn->ssl_read_buf = NULL;
439 free(conn->ssl_write_buf);
440 conn->ssl_write_buf = NULL;
443 }
444
445
446 TRACE("established SSL connection\n");
447 conn->secure = TRUE;
448 conn->ssl_ctx = ctx;
449 return ERROR_SUCCESS;
450}
451
452static DWORD send_ssl_chunk( struct netconn *conn, const void *msg, size_t size, WSAOVERLAPPED *ovr )
453{
454 SecBuffer bufs[4] = {
459 };
462
463 memcpy( bufs[1].pvBuffer, msg, size );
464 if ((res = EncryptMessage(&conn->ssl_ctx, 0, &buf_desc, 0)) != SEC_E_OK)
465 {
466 WARN( "EncryptMessage failed: %#lx\n", res );
467 return res;
468 }
469
470 if (sock_send( conn->socket, conn->ssl_write_buf, bufs[0].cbBuffer + bufs[1].cbBuffer + bufs[2].cbBuffer, ovr ) < 1)
471 {
472 WARN("send failed\n");
473 return WSAGetLastError();
474 }
475
476 return ERROR_SUCCESS;
477}
478
479DWORD netconn_send( struct netconn *conn, const void *msg, size_t len, int *sent, WSAOVERLAPPED *ovr )
480{
481 DWORD err;
482
483 if (ovr && !conn->port)
484 {
485 if (!(conn->port = CreateIoCompletionPort( (HANDLE)(SOCKET)conn->socket, NULL, (ULONG_PTR)conn->socket, 0 )))
486 ERR( "Failed to create port.\n" );
487 }
488
489 if (conn->secure)
490 {
491 const BYTE *ptr = msg;
492 size_t chunk_size;
493 DWORD res;
494
495 *sent = 0;
496 while (len)
497 {
498 chunk_size = min( len, conn->ssl_sizes.cbMaximumMessage );
499 if ((res = send_ssl_chunk( conn, ptr, chunk_size, ovr )))
500 {
501 if (res == WSA_IO_PENDING) *sent += chunk_size;
502 return res;
503 }
504 *sent += chunk_size;
505 ptr += chunk_size;
506 len -= chunk_size;
507 }
508
509 return ERROR_SUCCESS;
510 }
511
512 if ((*sent = sock_send( conn->socket, msg, len, ovr )) < 0)
513 {
515 *sent = (err == WSA_IO_PENDING) ? len : 0;
516 return err;
517 }
518 return ERROR_SUCCESS;
519}
520
521static DWORD read_ssl_chunk( struct netconn *conn, void *buf, SIZE_T buf_size, SIZE_T *ret_size, BOOL *eof )
522{
523 const SIZE_T ssl_buf_size = conn->ssl_sizes.cbHeader+conn->ssl_sizes.cbMaximumMessage+conn->ssl_sizes.cbTrailer;
524 SecBuffer bufs[4];
526 SSIZE_T size, buf_len;
527 unsigned int i;
529
530 assert(conn->extra_len < ssl_buf_size);
531
532 if(conn->extra_len) {
533 memcpy(conn->ssl_read_buf, conn->extra_buf, conn->extra_len);
534 buf_len = conn->extra_len;
535 conn->extra_len = 0;
536 free(conn->extra_buf);
537 conn->extra_buf = NULL;
538 }else {
539 if ((buf_len = sock_recv( conn->socket, conn->ssl_read_buf + conn->extra_len, ssl_buf_size - conn->extra_len, 0)) < 0)
540 return WSAGetLastError();
541
542 if (!buf_len)
543 {
544 *eof = TRUE;
545 return ERROR_SUCCESS;
546 }
547 }
548
549 *ret_size = 0;
550 *eof = FALSE;
551
552 do {
553 memset(bufs, 0, sizeof(bufs));
554 bufs[0].BufferType = SECBUFFER_DATA;
555 bufs[0].cbBuffer = buf_len;
556 bufs[0].pvBuffer = conn->ssl_read_buf;
557
558 switch ((res = DecryptMessage( &conn->ssl_ctx, &buf_desc, 0, NULL )))
559 {
560 case SEC_E_OK:
561 break;
562
564 TRACE("renegotiate\n");
566
568 TRACE("context expired\n");
569 *eof = TRUE;
570 return ERROR_SUCCESS;
571
573 assert(buf_len < ssl_buf_size);
574
575 if ((size = sock_recv( conn->socket, conn->ssl_read_buf + buf_len, ssl_buf_size - buf_len, 0 )) < 1)
577
578 buf_len += size;
579 continue;
580
581 default:
582 WARN( "failed: %#lx\n", res );
583 return res;
584 }
585 } while (res != SEC_E_OK);
586
587 for(i = 0; i < ARRAY_SIZE(bufs); i++) {
588 if(bufs[i].BufferType == SECBUFFER_DATA) {
589 size = min(buf_size, bufs[i].cbBuffer);
590 memcpy(buf, bufs[i].pvBuffer, size);
591 if(size < bufs[i].cbBuffer) {
592 assert(!conn->peek_len);
593 conn->peek_msg_mem = conn->peek_msg = malloc(bufs[i].cbBuffer - size);
594 if(!conn->peek_msg)
595 return ERROR_OUTOFMEMORY;
596 conn->peek_len = bufs[i].cbBuffer-size;
597 memcpy(conn->peek_msg, (char*)bufs[i].pvBuffer+size, conn->peek_len);
598 }
599
600 *ret_size = size;
601 }
602 }
603
604 for(i = 0; i < ARRAY_SIZE(bufs); i++) {
605 if(bufs[i].BufferType == SECBUFFER_EXTRA) {
606 conn->extra_buf = malloc(bufs[i].cbBuffer);
607 if(!conn->extra_buf)
608 return ERROR_OUTOFMEMORY;
609
610 conn->extra_len = bufs[i].cbBuffer;
611 memcpy(conn->extra_buf, bufs[i].pvBuffer, conn->extra_len);
612 }
613 }
614
615 return ERROR_SUCCESS;
616}
617
618DWORD netconn_recv( struct netconn *conn, void *buf, size_t len, int flags, int *recvd )
619{
620 *recvd = 0;
621 if (!len) return ERROR_SUCCESS;
622
623 if (conn->secure)
624 {
625 SIZE_T size;
626 DWORD res;
627 BOOL eof;
628
629 if (conn->peek_msg)
630 {
631 *recvd = min( len, conn->peek_len );
632 memcpy( buf, conn->peek_msg, *recvd );
633 conn->peek_len -= *recvd;
634 conn->peek_msg += *recvd;
635
636 if (conn->peek_len == 0)
637 {
638 free( conn->peek_msg_mem );
639 conn->peek_msg_mem = NULL;
640 conn->peek_msg = NULL;
641 }
642 /* check if we have enough data from the peek buffer */
643 if (!(flags & MSG_WAITALL) || *recvd == len) return ERROR_SUCCESS;
644 }
645 size = *recvd;
646
647 do
648 {
649 SIZE_T cread = 0;
650 if ((res = read_ssl_chunk( conn, (BYTE *)buf + size, len - size, &cread, &eof )))
651 {
652 WARN( "read_ssl_chunk failed: %lu\n", res );
653 if (!size) return res;
654 break;
655 }
656 if (eof)
657 {
658 TRACE("EOF\n");
659 break;
660 }
661 size += cread;
662
663 } while (!size || ((flags & MSG_WAITALL) && size < len));
664
665 TRACE( "received %Iu bytes\n", size );
666 *recvd = size;
667 return ERROR_SUCCESS;
668 }
669
670 if ((*recvd = sock_recv( conn->socket, buf, len, flags )) < 0) return WSAGetLastError();
671 return ERROR_SUCCESS;
672}
673
674void netconn_cancel_io( struct netconn *conn )
675{
676 SOCKET socket = InterlockedExchange( (LONG *)&conn->socket, -1 );
677
679}
680
682{
683 return conn->secure ? conn->peek_len : 0;
684}
685
687{
688 int opt = send ? SO_SNDTIMEO : SO_RCVTIMEO;
689 if (setsockopt( netconn->socket, SOL_SOCKET, opt, (void *)&value, sizeof(value) ) == -1)
690 {
692 WARN( "setsockopt failed (%lu)\n", err );
693 return err;
694 }
695 return ERROR_SUCCESS;
696}
697
699{
700 SIZE_T size;
701 int len;
702 char b;
703 DWORD err;
704 BOOL eof;
705
707 if (netconn->secure)
708 {
709 while (!netconn->peek_msg && !(err = read_ssl_chunk( netconn, NULL, 0, &size, &eof )) && !eof)
710 ;
711
712 TRACE( "checking secure connection, err %lu\n", err );
713
715 {
717 return TRUE;
718 }
720 {
722 return FALSE;
723 }
724 }
725 len = sock_recv( netconn->socket, &b, 1, MSG_PEEK );
728
729 return len == 1 || (len == -1 && err == WSAEWOULDBLOCK);
730}
731
733{
735 int ret;
736
737 memset( &hints, 0, sizeof(hints) );
738 /* Prefer IPv4 to IPv6 addresses, since some web servers do not listen on
739 * their IPv6 addresses even though they have IPv6 addresses in the DNS.
740 */
741 hints.ai_family = AF_INET;
742
743 ret = GetAddrInfoW( name, NULL, &hints, &res );
744 if (ret != 0)
745 {
746 TRACE("failed to get IPv4 address of %s, retrying with IPv6\n", debugstr_w(name));
747 hints.ai_family = AF_INET6;
748 ret = GetAddrInfoW( name, NULL, &hints, &res );
749 if (ret != 0)
750 {
751 TRACE("failed to get address of %s\n", debugstr_w(name));
753 }
754 }
755 memcpy( sa, res->ai_addr, res->ai_addrlen );
756 switch (res->ai_family)
757 {
758 case AF_INET:
759 ((struct sockaddr_in *)sa)->sin_port = htons( port );
760 break;
761 case AF_INET6:
762 ((struct sockaddr_in6 *)sa)->sin6_port = htons( port );
763 break;
764 }
765
767 return ERROR_SUCCESS;
768}
769
771{
778};
779
781{
782 struct async_resolve *ret;
783
784 if (!(ret = malloc(sizeof(*ret))))
785 {
786 ERR( "No memory.\n" );
787 return NULL;
788 }
789 ret->ref = 1;
790 ret->hostname = wcsdup( hostname );
791 ret->port = port;
792 if (!(ret->done = CreateEventW( NULL, FALSE, FALSE, NULL )))
793 {
794 free( ret->hostname );
795 free( ret );
796 return NULL;
797 }
798 return ret;
799}
800
801static void async_resolve_release( struct async_resolve *async )
802{
803 if (InterlockedDecrement( &async->ref )) return;
804
805 free( async->hostname );
806 CloseHandle( async->done );
807 free( async );
808}
809
811{
812 struct async_resolve *async = ctx;
813
814 async->result = resolve_hostname( async->hostname, async->port, &async->addr );
815 SetEvent( async->done );
816 async_resolve_release( async );
817}
818
820{
821 DWORD ret;
822
824 else
825 {
826 struct async_resolve *async;
827
828 if (!(async = create_async_resolve( hostname, port )))
829 return ERROR_OUTOFMEMORY;
830
831 InterlockedIncrement( &async->ref );
833 {
834 InterlockedDecrement( &async->ref );
835 async_resolve_release( async );
836 return GetLastError();
837 }
839 else
840 {
841 *addr = async->addr;
842 ret = async->result;
843 }
844 async_resolve_release( async );
845 }
846
847 return ret;
848}
849
850const void *netconn_get_certificate( struct netconn *conn )
851{
852 const CERT_CONTEXT *ret;
854
855 if (!conn->secure) return NULL;
857 return res == SEC_E_OK ? ret : NULL;
858}
859
861{
864
865 if (!conn->secure) return 0;
867 if(res != SEC_E_OK)
868 WARN( "QueryContextAttributesW failed: %#lx\n", res );
869 return res == SEC_E_OK ? conn_info.dwCipherStrength : 0;
870}
@ sent
Definition: SystemMenu.c:27
#define FreeAddrInfoW(a)
Definition: addrinfo.c:21
INT WSAAPI GetAddrInfoW(IN PCWSTR pszNodeName, IN PCWSTR pszServiceName, IN const ADDRINFOW *ptHints, OUT PADDRINFOW *pptResult)
Definition: addrinfo.c:509
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedExchange
Definition: armddk.h:54
#define InterlockedDecrement
Definition: armddk.h:52
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
char * hostname
Definition: ftp.c:88
#define ARRAY_SIZE(A)
Definition: main.h:20
#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
#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
static HINSTANCE instance
Definition: main.c:40
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
BOOL WINAPI CertVerifyCertificateChainPolicy(LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
Definition: chain.c:3716
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:2879
VOID WINAPI CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT pChainContext)
Definition: chain.c:2960
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CALLBACK
Definition: compat.h:35
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
BOOL WINAPI DECLSPEC_HOTPATCH TrySubmitThreadpoolCallback(PTP_SIMPLE_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: threadpool.c:9
#define assert(_expr)
Definition: assert.h:32
static int eof(int fd)
Definition: io.h:21
static wchar_t * wcsdup(const wchar_t *str)
Definition: string.h:94
USHORT port
Definition: uri.c:228
ULONG netconn_query_data_available(struct netconn *conn)
Definition: net.c:681
void netconn_release(struct netconn *conn)
Definition: net.c:295
DWORD netconn_resolve(WCHAR *hostname, INTERNET_PORT port, struct sockaddr_storage *addr, int timeout)
Definition: net.c:819
DWORD netconn_secure_connect(struct netconn *conn, WCHAR *hostname, DWORD security_flags, CredHandle *cred_handle, BOOL check_revocation)
Definition: net.c:315
void netconn_cancel_io(struct netconn *conn)
Definition: net.c:674
const void * netconn_get_certificate(struct netconn *conn)
Definition: net.c:850
static void winsock_init(void)
Definition: net.c:199
DWORD netconn_recv(struct netconn *conn, void *buf, size_t len, int flags, int *recvd)
Definition: net.c:618
static BOOL winsock_loaded
Definition: net.c:180
static void CALLBACK resolve_proc(TP_CALLBACK_INSTANCE *instance, void *ctx)
Definition: net.c:810
static void async_resolve_release(struct async_resolve *async)
Definition: net.c:801
void netconn_unload(void)
Definition: net.c:182
static BOOL WINAPI winsock_startup(INIT_ONCE *once, void *param, void **ctx)
Definition: net.c:187
DWORD netconn_create(struct hostdata *host, const struct sockaddr_storage *sockaddr, int timeout, struct netconn **ret_conn)
Definition: net.c:212
void netconn_addref(struct netconn *conn)
Definition: net.c:290
BOOL netconn_is_alive(struct netconn *netconn)
Definition: net.c:698
static int sock_send(int fd, const void *msg, size_t len, WSAOVERLAPPED *ovr)
Definition: net.c:35
static DWORD read_ssl_chunk(struct netconn *conn, void *buf, SIZE_T buf_size, SIZE_T *ret_size, BOOL *eof)
Definition: net.c:521
static struct async_resolve * create_async_resolve(const WCHAR *hostname, INTERNET_PORT port)
Definition: net.c:780
static int sock_recv(int fd, void *msg, size_t len, int flags)
Definition: net.c:73
DWORD netconn_set_timeout(struct netconn *netconn, BOOL send, int value)
Definition: net.c:686
static DWORD send_ssl_chunk(struct netconn *conn, const void *msg, size_t size, WSAOVERLAPPED *ovr)
Definition: net.c:452
BOOL netconn_wait_overlapped_result(struct netconn *conn, WSAOVERLAPPED *ovr, DWORD *len)
Definition: net.c:54
int netconn_get_cipher_strength(struct netconn *conn)
Definition: net.c:860
static DWORD netconn_verify_cert(PCCERT_CONTEXT cert, WCHAR *server, DWORD security_flags, BOOL check_revocation)
Definition: net.c:84
DWORD netconn_send(struct netconn *conn, const void *msg, size_t len, int *sent, WSAOVERLAPPED *ovr)
Definition: net.c:479
static DWORD resolve_hostname(const WCHAR *name, INTERNET_PORT port, struct sockaddr_storage *sa)
Definition: net.c:732
static void set_blocking(struct netconn *conn, BOOL blocking)
Definition: net.c:206
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 WSASend(IN SOCKET s, IN LPWSABUF lpBuffers, IN DWORD dwBufferCount, OUT LPDWORD lpNumberOfBytesSent, IN DWORD dwFlags, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: send.c:145
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
return ret
Definition: mutex.c:146
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
#define INFINITE
Definition: serial.h:102
static void set_error(FCI_Int *fci, int oper, int err)
Definition: fci.c:196
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint res
Definition: glext.h:9613
GLsizeiptr size
Definition: glext.h:5919
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
GLbitfield flags
Definition: glext.h:7161
GLenum const GLvoid * addr
Definition: glext.h:9621
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 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
HANDLE WINAPI CreateIoCompletionPort(IN HANDLE FileHandle, IN HANDLE ExistingCompletionPort, IN ULONG_PTR CompletionKey, IN DWORD NumberOfConcurrentThreads)
Definition: iocompl.c:65
BOOL WINAPI SetFileCompletionNotificationModes(IN HANDLE FileHandle, IN UCHAR Flags)
Definition: iocompl.c:31
#define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
Definition: iocompl.c:22
BOOL WINAPI GetQueuedCompletionStatus(IN HANDLE CompletionHandle, IN LPDWORD lpNumberOfBytesTransferred, OUT PULONG_PTR lpCompletionKey, OUT LPOVERLAPPED *lpOverlapped, IN DWORD dwMilliseconds)
Definition: iocompl.c:131
#define b
Definition: ke_i.h:79
#define debugstr_w
Definition: kernel32.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define htons(x)
Definition: module.h:215
static PVOID ptr
Definition: dispmode.c:27
static BYTE cert[]
Definition: msg.c:1374
#define min(a, b)
Definition: monoChain.cc:55
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define ioctlsocket
Definition: ncftp.h:481
#define closesocket
Definition: ncftp.h:477
static SecHandle cred_handle
long LONG
Definition: pedump.c:60
#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 ISC_REQ_ALLOCATE_MEMORY
Definition: sspi.h:370
#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 SECBUFFER_EXTRA
Definition: sspi.h:164
#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(...)
void release_host(struct hostdata *host)
Definition: request.c:1449
#define calloc
Definition: rosglue.h:14
#define SECPKG_ATTR_CONNECTION_INFO
Definition: schannel.h:76
#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
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
SOCKET WSAAPI WSASocketW(IN INT af, IN INT type, IN INT protocol, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, IN GROUP g, IN DWORD dwFlags)
Definition: socklife.c:490
#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
ULONG cbBuffer
Definition: sspi.h:153
ULONG len
Definition: ws2def.h:525
CHAR FAR * buf
Definition: ws2def.h:526
INTERNET_PORT port
Definition: net.c:774
LONG ref
Definition: net.c:772
DWORD result
Definition: net.c:776
struct sockaddr_storage addr
Definition: net.c:775
WCHAR * hostname
Definition: net.c:773
HANDLE done
Definition: net.c:777
Definition: winsock.h:60
Definition: txthost.c:37
Definition: copy.c:22
Definition: name.c:39
SecPkgContext_StreamSizes ssl_sizes
char * peek_msg
char * ssl_write_buf
struct hostdata * host
char * extra_buf
char * peek_msg_mem
char * ssl_read_buf
CtxtHandle ssl_ctx
struct sockaddr_storage sockaddr
HANDLE port
size_t extra_len
size_t peek_len
Definition: ps.c:97
Definition: dhcpd.h:248
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
struct sock * chain
Definition: tcpcore.h:1
#define MAKEWORD(a, b)
Definition: typedefs.h:248
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:96
static rfbScreenInfoPtr server
Definition: vnc.c:74
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
RTL_RUN_ONCE INIT_ONCE
Definition: winbase.h:3680
#define WAIT_OBJECT_0
Definition: winbase.h:383
#define INIT_ONCE_STATIC_INIT
Definition: winbase.h:591
#define CERT_TRUST_IS_REVOKED
Definition: wincrypt.h:984
#define CERT_TRUST_REVOCATION_STATUS_UNKNOWN
Definition: wincrypt.h:988
#define CERT_TRUST_IS_OFFLINE_REVOCATION
Definition: wincrypt.h:998
#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_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
Definition: wincrypt.h:1171
#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_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_RENEGOTIATE
Definition: winerror.h:4335
#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
WORD INTERNET_PORT
Definition: winhttp.h:43
#define ERROR_WINHTTP_NAME_NOT_RESOLVED
Definition: winhttp.h:239
#define SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE
Definition: winhttp.h:346
#define ERROR_WINHTTP_SECURE_CERT_REVOKED
Definition: winhttp.h:269
#define ERROR_WINHTTP_CANNOT_CONNECT
Definition: winhttp.h:247
#define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
Definition: winhttp.h:344
#define ERROR_WINHTTP_SECURE_CERT_DATE_INVALID
Definition: winhttp.h:250
#define ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED
Definition: winhttp.h:252
#define ERROR_WINHTTP_TIMEOUT
Definition: winhttp.h:235
#define ERROR_WINHTTP_SECURE_INVALID_CERT
Definition: winhttp.h:268
#define ERROR_WINHTTP_SECURE_CERT_CN_INVALID
Definition: winhttp.h:251
#define ERROR_WINHTTP_SECURE_CERT_REV_FAILED
Definition: winhttp.h:254
#define ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE
Definition: winhttp.h:275
#define SECURITY_FLAG_IGNORE_UNKNOWN_CA
Definition: winhttp.h:343
#define ERROR_WINHTTP_SECURE_CHANNEL_ERROR
Definition: winhttp.h:265
#define ERROR_WINHTTP_SECURE_INVALID_CA
Definition: winhttp.h:253
struct _TP_CALLBACK_INSTANCE TP_CALLBACK_INSTANCE
Definition: winnt_old.h:4676
#define WSA_FLAG_OVERLAPPED
Definition: winsock2.h:460
#define WSA_IO_PENDING
Definition: winsock2.h:610
#define FD_ISSET(fd, set)
Definition: winsock.h:94
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
UINT_PTR SOCKET
Definition: winsock.h:41
#define MSG_PEEK
Definition: winsock.h:216
#define SOL_SOCKET
Definition: winsock.h:392
#define AF_INET6
Definition: winsock.h:363
#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 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 DeleteSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:450
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193