ReactOS 0.4.16-dev-257-g6aa11ac
net.c File Reference
#include "config.h"
#include "ws2tcpip.h"
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#include "windef.h"
#include "winbase.h"
#include "winhttp.h"
#include "schannel.h"
#include "wine/debug.h"
#include "wine/library.h"
#include "winhttp_private.h"
Include dependency graph for net.c:

Go to the source code of this file.

Classes

struct  async_resolve
 

Macros

#define NONAMELESSUNION
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (winhttp)
 
static int sock_send (int fd, const void *msg, size_t len, int flags)
 
static int sock_recv (int fd, void *msg, size_t len, int flags)
 
static DWORD netconn_verify_cert (PCCERT_CONTEXT cert, WCHAR *server, DWORD security_flags, BOOL check_revocation)
 
void netconn_unload (void)
 
static BOOL WINAPI winsock_startup (INIT_ONCE *once, void *param, void **ctx)
 
static void winsock_init (void)
 
static void set_blocking (struct netconn *conn, BOOL blocking)
 
struct netconnnetconn_create (struct hostdata *host, const struct sockaddr_storage *sockaddr, int timeout)
 
void netconn_close (struct netconn *conn)
 
BOOL netconn_secure_connect (struct netconn *conn, WCHAR *hostname, DWORD security_flags, CredHandle *cred_handle, BOOL check_revocation)
 
static BOOL send_ssl_chunk (struct netconn *conn, const void *msg, size_t size)
 
BOOL netconn_send (struct netconn *conn, const void *msg, size_t len, int *sent)
 
static BOOL read_ssl_chunk (struct netconn *conn, void *buf, SIZE_T buf_size, SIZE_T *ret_size, BOOL *eof)
 
BOOL netconn_recv (struct netconn *conn, void *buf, size_t len, int flags, int *recvd)
 
ULONG netconn_query_data_available (struct netconn *conn)
 
DWORD netconn_set_timeout (struct netconn *netconn, BOOL send, int value)
 
BOOL netconn_is_alive (struct netconn *netconn)
 
static DWORD resolve_hostname (const WCHAR *name, INTERNET_PORT port, struct sockaddr_storage *sa)
 
static void CALLBACK resolve_proc (TP_CALLBACK_INSTANCE *instance, void *ctx)
 
BOOL netconn_resolve (WCHAR *hostname, INTERNET_PORT port, struct sockaddr_storage *addr, int timeout)
 
const voidnetconn_get_certificate (struct netconn *conn)
 
int netconn_get_cipher_strength (struct netconn *conn)
 

Variables

static BOOL winsock_loaded
 

Macro Definition Documentation

◆ NONAMELESSUNION

#define NONAMELESSUNION

Definition at line 21 of file net.c.

Function Documentation

◆ netconn_close()

void netconn_close ( struct netconn conn)

Definition at line 250 of file net.c.

251{
252 if (conn->secure)
253 {
254 heap_free( conn->peek_msg_mem );
255 heap_free(conn->ssl_buf);
256 heap_free(conn->extra_buf);
258 }
259 closesocket( conn->socket );
260 release_host( conn->host );
261 heap_free(conn);
262}
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define closesocket
Definition: ncftp.h:477
void release_host(struct hostdata *host)
Definition: request.c:1494
struct hostdata * host
char * extra_buf
char * peek_msg_mem
CtxtHandle ssl_ctx
char * ssl_buf
SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:450

Referenced by close_connection(), connection_collector(), handle_redirect(), and open_connection().

◆ netconn_create()

struct netconn * netconn_create ( struct hostdata host,
const struct sockaddr_storage sockaddr,
int  timeout 
)

Definition at line 186 of file net.c.

187{
188 struct netconn *conn;
189 unsigned int addr_len;
190 BOOL ret = FALSE;
191
192#ifndef __REACTOS__
193 winsock_init();
194#endif
195
196 conn = heap_alloc_zero(sizeof(*conn));
197 if (!conn) return NULL;
198 conn->host = host;
199 conn->sockaddr = *sockaddr;
200 if ((conn->socket = socket( sockaddr->ss_family, SOCK_STREAM, 0 )) == -1)
201 {
202 WARN("unable to create socket (%u)\n", WSAGetLastError());
203 heap_free(conn);
204 return NULL;
205 }
206
207 switch (conn->sockaddr.ss_family)
208 {
209 case AF_INET:
210 addr_len = sizeof(struct sockaddr_in);
211 break;
212 case AF_INET6:
213 addr_len = sizeof(struct sockaddr_in6);
214 break;
215 default:
216 assert(0);
217 }
218
219 if (timeout > 0) set_blocking( conn, FALSE );
220
221 if (!connect( conn->socket, (const struct sockaddr *)&conn->sockaddr, addr_len )) ret = TRUE;
222 else
223 {
226 {
227 FD_SET set;
228 TIMEVAL timeval = { 0, timeout * 1000 };
229 int res;
230
231 FD_ZERO( &set );
232 FD_SET( conn->socket, &set );
233 if ((res = select( conn->socket + 1, NULL, &set, NULL, &timeval )) > 0) ret = TRUE;
235 }
236 }
237
238 if (timeout > 0) set_blocking( conn, TRUE );
239
240 if (!ret)
241 {
242 WARN("unable to connect to host (%u)\n", GetLastError());
243 closesocket( conn->socket );
244 heap_free( conn );
245 return NULL;
246 }
247 return conn;
248}
#define WARN(fmt,...)
Definition: precomp.h:61
Definition: _set.h:50
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define SetLastError(x)
Definition: compat.h:752
static void winsock_init(void)
Definition: net.c:173
static void set_blocking(struct netconn *conn, BOOL blocking)
Definition: net.c:180
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
#define assert(x)
Definition: debug.h:53
#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
GLuint res
Definition: glext.h:9613
#define err(...)
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
Definition: winsock.h:66
struct sockaddr_storage sockaddr
Definition: dhcpd.h:245
int ret
char * host
Definition: whois.c:55
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WSAEWOULDBLOCK
Definition: winerror.h:1948
#define WSAEINPROGRESS
Definition: winerror.h:1949
#define ERROR_WINHTTP_TIMEOUT
Definition: winhttp.h:189
int PASCAL FAR WSAGetLastError(void)
Definition: dllmain.c:112
#define FD_ZERO(set)
Definition: winsock.h:96
#define AF_INET6
Definition: winsock.h:369
#define FD_SET(fd, set)
Definition: winsock.h:89

Referenced by open_connection().

◆ netconn_get_certificate()

const void * netconn_get_certificate ( struct netconn conn)

Definition at line 758 of file net.c.

759{
760 const CERT_CONTEXT *ret;
762
763 if (!conn->secure) return NULL;
765 return res == SEC_E_OK ? ret : NULL;
766}
LONG SECURITY_STATUS
Definition: sspi.h:34
#define SECPKG_ATTR_REMOTE_CERT_CONTEXT
Definition: schannel.h:69
#define SEC_E_OK
Definition: winerror.h:2356
SECURITY_STATUS WINAPI QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
Definition: wrapper.c:535

Referenced by open_connection().

◆ netconn_get_cipher_strength()

int netconn_get_cipher_strength ( struct netconn conn)

Definition at line 768 of file net.c.

769{
772
773 if (!conn->secure) return 0;
775 if(res != SEC_E_OK)
776 WARN("QueryContextAttributesW failed: %08x\n", res);
777 return res == SEC_E_OK ? conn_info.dwCipherStrength : 0;
778}
#define SECPKG_ATTR_CONNECTION_INFO
Definition: schannel.h:76

Referenced by request_query_option().

◆ netconn_is_alive()

BOOL netconn_is_alive ( struct netconn netconn)

Definition at line 608 of file net.c.

609{
610 int len;
611 char b;
612 DWORD err;
613
615 len = sock_recv( netconn->socket, &b, 1, MSG_PEEK );
618
619 return len == 1 || (len == -1 && err == WSAEWOULDBLOCK);
620}
static int sock_recv(int fd, void *msg, size_t len, int flags)
Definition: net.c:49
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLsizei len
Definition: glext.h:6722
#define b
Definition: ke_i.h:79
#define MSG_PEEK
Definition: winsock.h:222

Referenced by open_connection().

◆ netconn_query_data_available()

ULONG netconn_query_data_available ( struct netconn conn)

Definition at line 591 of file net.c.

592{
593 return conn->secure ? conn->peek_len : 0;
594}
size_t peek_len

Referenced by query_data_available().

◆ netconn_recv()

BOOL netconn_recv ( struct netconn conn,
void buf,
size_t  len,
int  flags,
int recvd 
)

Definition at line 539 of file net.c.

540{
541 *recvd = 0;
542 if (!len) return TRUE;
543
544 if (conn->secure)
545 {
546 SIZE_T size, cread;
547 BOOL res, eof;
548
549 if (conn->peek_msg)
550 {
551 *recvd = min( len, conn->peek_len );
552 memcpy( buf, conn->peek_msg, *recvd );
553 conn->peek_len -= *recvd;
554 conn->peek_msg += *recvd;
555
556 if (conn->peek_len == 0)
557 {
558 heap_free( conn->peek_msg_mem );
559 conn->peek_msg_mem = NULL;
560 conn->peek_msg = NULL;
561 }
562 /* check if we have enough data from the peek buffer */
563 if (!(flags & MSG_WAITALL) || *recvd == len) return TRUE;
564 }
565 size = *recvd;
566
567 do {
568 res = read_ssl_chunk(conn, (BYTE*)buf+size, len-size, &cread, &eof);
569 if(!res) {
570 WARN("read_ssl_chunk failed\n");
571 if(!size)
572 return FALSE;
573 break;
574 }
575
576 if(eof) {
577 TRACE("EOF\n");
578 break;
579 }
580
581 size += cread;
582 }while(!size || ((flags & MSG_WAITALL) && size < len));
583
584 TRACE("received %ld bytes\n", size);
585 *recvd = size;
586 return TRUE;
587 }
588 return ((*recvd = sock_recv( conn->socket, buf, len, flags )) != -1);
589}
static BOOL read_ssl_chunk(struct netconn *conn, void *buf, SIZE_T buf_size, SIZE_T *ret_size, BOOL *eof)
Definition: net.c:448
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define min(a, b)
Definition: monoChain.cc:55
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
#define TRACE(s)
Definition: solgame.cpp:4
char * peek_msg
ULONG_PTR SIZE_T
Definition: typedefs.h:80
unsigned char BYTE
Definition: xxhash.c:193

Referenced by read_more_data().

◆ netconn_resolve()

BOOL netconn_resolve ( WCHAR hostname,
INTERNET_PORT  port,
struct sockaddr_storage addr,
int  timeout 
)

Definition at line 725 of file net.c.

726{
727 DWORD ret;
728
730 else
731 {
732 struct async_resolve async;
733
734 async.hostname = hostname;
735 async.port = port;
736 async.addr = addr;
737 if (!(async.done = CreateEventW( NULL, FALSE, FALSE, NULL ))) return FALSE;
738 if (!TrySubmitThreadpoolCallback( resolve_proc, &async, NULL ))
739 {
740 CloseHandle( async.done );
741 return FALSE;
742 }
744 else ret = async.result;
745 CloseHandle( async.done );
746 }
747
748 if (ret)
749 {
750 SetLastError( ret );
751 return FALSE;
752 }
753 return TRUE;
754}
char * hostname
Definition: ftp.c:88
#define CloseHandle
Definition: compat.h:739
USHORT port
Definition: uri.c:228
static void CALLBACK resolve_proc(TP_CALLBACK_INSTANCE *instance, void *ctx)
Definition: net.c:718
static DWORD resolve_hostname(const WCHAR *name, INTERNET_PORT port, struct sockaddr_storage *sa)
Definition: net.c:622
GLenum const GLvoid * addr
Definition: glext.h:9621
const WCHAR * hostname
Definition: net.c:711
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:651
#define WAIT_OBJECT_0
Definition: winbase.h:432

Referenced by open_connection().

◆ netconn_secure_connect()

BOOL netconn_secure_connect ( struct netconn conn,
WCHAR hostname,
DWORD  security_flags,
CredHandle cred_handle,
BOOL  check_revocation 
)

Definition at line 264 of file net.c.

266{
267 SecBuffer out_buf = {0, SECBUFFER_TOKEN, NULL}, in_bufs[2] = {{0, SECBUFFER_TOKEN}, {0, SECBUFFER_EMPTY}};
268 SecBufferDesc out_desc = {SECBUFFER_VERSION, 1, &out_buf}, in_desc = {SECBUFFER_VERSION, 2, in_bufs};
269 BYTE *read_buf;
270 SIZE_T read_buf_size = 2048;
271 ULONG attrs = 0;
274 const CERT_CONTEXT *cert;
277
280
281 read_buf = heap_alloc(read_buf_size);
282 if(!read_buf)
283 return FALSE;
284
285 status = InitializeSecurityContextW(cred_handle, NULL, hostname, isc_req_flags, 0, 0, NULL, 0,
286 &ctx, &out_desc, &attrs, NULL);
287
289
291 if(out_buf.cbBuffer) {
293
294 TRACE("sending %u bytes\n", out_buf.cbBuffer);
295
296 size = sock_send(conn->socket, out_buf.pvBuffer, out_buf.cbBuffer, 0);
297 if(size != out_buf.cbBuffer) {
298 ERR("send failed\n");
300 break;
301 }
302
303 FreeContextBuffer(out_buf.pvBuffer);
304 out_buf.pvBuffer = NULL;
305 out_buf.cbBuffer = 0;
306 }
307
309 assert(in_bufs[1].cbBuffer < read_buf_size);
310
311 memmove(read_buf, (BYTE*)in_bufs[0].pvBuffer+in_bufs[0].cbBuffer-in_bufs[1].cbBuffer, in_bufs[1].cbBuffer);
312 in_bufs[0].cbBuffer = in_bufs[1].cbBuffer;
313
314 in_bufs[1].BufferType = SECBUFFER_EMPTY;
315 in_bufs[1].cbBuffer = 0;
316 in_bufs[1].pvBuffer = NULL;
317 }
318
319 assert(in_bufs[0].BufferType == SECBUFFER_TOKEN);
320 assert(in_bufs[1].BufferType == SECBUFFER_EMPTY);
321
322 if(in_bufs[0].cbBuffer + 1024 > read_buf_size) {
323 BYTE *new_read_buf;
324
325 new_read_buf = heap_realloc(read_buf, read_buf_size + 1024);
326 if(!new_read_buf) {
328 break;
329 }
330
331 in_bufs[0].pvBuffer = read_buf = new_read_buf;
332 read_buf_size += 1024;
333 }
334
335 size = sock_recv(conn->socket, read_buf+in_bufs[0].cbBuffer, read_buf_size-in_bufs[0].cbBuffer, 0);
336 if(size < 1) {
338 break;
339 }
340
341 TRACE("recv %lu bytes\n", size);
342
343 in_bufs[0].cbBuffer += size;
344 in_bufs[0].pvBuffer = read_buf;
345 status = InitializeSecurityContextW(cred_handle, &ctx, hostname, isc_req_flags, 0, 0, &in_desc,
346 0, NULL, &out_desc, &attrs, NULL);
347 TRACE("InitializeSecurityContext ret %08x\n", status);
348
349 if(status == SEC_E_OK) {
350 if(in_bufs[1].BufferType == SECBUFFER_EXTRA)
351 FIXME("SECBUFFER_EXTRA not supported\n");
352
354 if(status != SEC_E_OK) {
355 WARN("Could not get sizes\n");
356 break;
357 }
358
360 if(status == SEC_E_OK) {
361 res = netconn_verify_cert(cert, hostname, security_flags, check_revocation);
363 if(res != ERROR_SUCCESS) {
364 WARN("cert verify failed: %u\n", res);
365 break;
366 }
367 }else {
368 WARN("Could not get cert\n");
369 break;
370 }
371
373 if(!conn->ssl_buf) {
374 res = GetLastError();
375 break;
376 }
377 }
378 }
379
381
382 if(status != SEC_E_OK || res != ERROR_SUCCESS) {
383 WARN("Failed to initialize security context failed: %08x\n", status);
384 heap_free(conn->ssl_buf);
385 conn->ssl_buf = NULL;
388 return FALSE;
389 }
390
391
392 TRACE("established SSL connection\n");
393 conn->secure = TRUE;
394 conn->ssl_ctx = ctx;
395 return TRUE;
396}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
LONG_PTR SSIZE_T
Definition: basetsd.h:181
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
static int sock_send(int fd, const void *msg, size_t len, int flags)
Definition: net.c:38
static DWORD netconn_verify_cert(PCCERT_CONTEXT cert, WCHAR *server, DWORD security_flags, BOOL check_revocation)
Definition: net.c:60
#define read_buf
Definition: intsym.h:279
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static BYTE cert[]
Definition: msg.c:1437
static SecHandle cred_handle
#define ISC_REQ_MANUAL_CRED_VALIDATION
Definition: sspi.h:381
#define ISC_REQ_CONFIDENTIALITY
Definition: sspi.h:366
#define ISC_REQ_ALLOCATE_MEMORY
Definition: sspi.h:370
#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 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
SECURITY_STATUS WINAPI FreeContextBuffer(PVOID pv)
Definition: sspi.c:699
ULONG cbBuffer
Definition: sspi.h:153
SecPkgContext_StreamSizes ssl_sizes
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59
#define SEC_I_CONTINUE_NEEDED
Definition: winerror.h:2927
#define SEC_E_INCOMPLETE_MESSAGE
Definition: winerror.h:2934
#define ERROR_WINHTTP_SECURE_CHANNEL_ERROR
Definition: winhttp.h:219
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

Referenced by open_connection().

◆ netconn_send()

BOOL netconn_send ( struct netconn conn,
const void msg,
size_t  len,
int sent 
)

Definition at line 424 of file net.c.

425{
426 if (conn->secure)
427 {
428 const BYTE *ptr = msg;
429 size_t chunk_size;
430
431 *sent = 0;
432
433 while(len) {
434 chunk_size = min(len, conn->ssl_sizes.cbMaximumMessage);
435 if(!send_ssl_chunk(conn, ptr, chunk_size))
436 return FALSE;
437
438 *sent += chunk_size;
439 ptr += chunk_size;
440 len -= chunk_size;
441 }
442
443 return TRUE;
444 }
445 return ((*sent = sock_send( conn->socket, msg, len, 0 )) != -1);
446}
@ sent
Definition: SystemMenu.c:27
#define msg(x)
Definition: auth_time.c:54
static BOOL send_ssl_chunk(struct netconn *conn, const void *msg, size_t size)
Definition: net.c:398
static PVOID ptr
Definition: dispmode.c:27

Referenced by secure_proxy_connect(), send_request(), and write_data().

◆ netconn_set_timeout()

DWORD netconn_set_timeout ( struct netconn netconn,
BOOL  send,
int  value 
)

Definition at line 596 of file net.c.

597{
598 int opt = send ? SO_SNDTIMEO : SO_RCVTIMEO;
599 if (setsockopt( netconn->socket, SOL_SOCKET, opt, (void *)&value, sizeof(value) ) == -1)
600 {
602 WARN("setsockopt failed (%u)\n", err );
603 return err;
604 }
605 return ERROR_SUCCESS;
606}
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
Definition: pdh_main.c:94
#define SOL_SOCKET
Definition: winsock.h:398
#define SO_SNDTIMEO
Definition: winsock.h:192
#define SO_RCVTIMEO
Definition: winsock.h:193

Referenced by open_connection(), receive_response(), and WinHttpSetTimeouts().

◆ netconn_unload()

void netconn_unload ( void  )

Definition at line 156 of file net.c.

157{
159}
static BOOL winsock_loaded
Definition: net.c:154
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60

Referenced by DllMain().

◆ netconn_verify_cert()

static DWORD netconn_verify_cert ( PCCERT_CONTEXT  cert,
WCHAR server,
DWORD  security_flags,
BOOL  check_revocation 
)
static

Definition at line 60 of file net.c.

61{
62 HCERTSTORE store = cert->hCertStore;
63 BOOL ret;
64 CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } };
66 char oid_server_auth[] = szOID_PKIX_KP_SERVER_AUTH;
67 char *server_auth[] = { oid_server_auth };
69
70 TRACE("verifying %s\n", debugstr_w( server ));
72 chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = server_auth;
73 ret = CertGetCertificateChain( NULL, cert, NULL, store, &chainPara,
75 NULL, &chain );
76 if (ret)
77 {
78 if (chain->TrustStatus.dwErrorStatus)
79 {
80 static const DWORD supportedErrors =
84
85 if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_TIME_VALID)
86 {
87 if (!(security_flags & SECURITY_FLAG_IGNORE_CERT_DATE_INVALID))
89 }
90 else if (chain->TrustStatus.dwErrorStatus &
92 {
93 if (!(security_flags & SECURITY_FLAG_IGNORE_UNKNOWN_CA))
95 }
96 else if ((chain->TrustStatus.dwErrorStatus &
98 (chain->TrustStatus.dwErrorStatus &
101 else if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_REVOKED)
103 else if (chain->TrustStatus.dwErrorStatus &
105 {
106 if (!(security_flags & SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE))
108 }
109 else if (chain->TrustStatus.dwErrorStatus & ~supportedErrors)
111 }
112 if (!err)
113 {
114 CERT_CHAIN_POLICY_PARA policyPara;
115 SSL_EXTRA_CERT_CHAIN_POLICY_PARA sslExtraPolicyPara;
116 CERT_CHAIN_POLICY_STATUS policyStatus;
117 CERT_CHAIN_CONTEXT chainCopy;
118
119 /* Clear chain->TrustStatus.dwErrorStatus so
120 * CertVerifyCertificateChainPolicy will verify additional checks
121 * rather than stopping with an existing, ignored error.
122 */
123 memcpy(&chainCopy, chain, sizeof(chainCopy));
124 chainCopy.TrustStatus.dwErrorStatus = 0;
125 sslExtraPolicyPara.u.cbSize = sizeof(sslExtraPolicyPara);
126 sslExtraPolicyPara.dwAuthType = AUTHTYPE_SERVER;
127 sslExtraPolicyPara.pwszServerName = server;
128 sslExtraPolicyPara.fdwChecks = security_flags;
129 policyPara.cbSize = sizeof(policyPara);
130 policyPara.dwFlags = 0;
131 policyPara.pvExtraPolicyPara = &sslExtraPolicyPara;
133 &chainCopy, &policyPara,
134 &policyStatus );
135 /* Any error in the policy status indicates that the
136 * policy couldn't be verified.
137 */
138 if (ret && policyStatus.dwError)
139 {
140 if (policyStatus.dwError == CERT_E_CN_NO_MATCH)
142 else
144 }
145 }
147 }
148 else
150 TRACE("returning %08x\n", err);
151 return err;
152}
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 debugstr_w
Definition: kernel32.h:32
CERT_TRUST_STATUS TrustStatus
Definition: wincrypt.h:939
CERT_USAGE_MATCH RequestedUsage
Definition: wincrypt.h:1070
CERT_ENHKEY_USAGE Usage
Definition: wincrypt.h:1048
DWORD cUsageIdentifier
Definition: wincrypt.h:719
LPSTR * rgpszUsageIdentifier
Definition: wincrypt.h:720
struct sock * chain
Definition: tcpcore.h:1
static rfbScreenInfoPtr server
Definition: vnc.c:74
#define CERT_TRUST_IS_REVOKED
Definition: wincrypt.h:872
#define CERT_TRUST_REVOCATION_STATUS_UNKNOWN
Definition: wincrypt.h:876
#define CERT_TRUST_IS_OFFLINE_REVOCATION
Definition: wincrypt.h:886
#define AUTHTYPE_SERVER
Definition: wincrypt.h:1035
#define szOID_PKIX_KP_SERVER_AUTH
Definition: wincrypt.h:3294
#define CERT_CHAIN_POLICY_SSL
Definition: wincrypt.h:965
#define CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
Definition: wincrypt.h:1058
#define CERT_TRUST_IS_NOT_VALID_FOR_USAGE
Definition: wincrypt.h:874
#define CERT_TRUST_IS_UNTRUSTED_ROOT
Definition: wincrypt.h:875
#define CERT_TRUST_IS_NOT_TIME_VALID
Definition: wincrypt.h:870
#define CERT_E_CN_NO_MATCH
Definition: winerror.h:3131
#define SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE
Definition: winhttp.h:284
#define ERROR_WINHTTP_SECURE_CERT_REVOKED
Definition: winhttp.h:223
#define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
Definition: winhttp.h:282
#define ERROR_WINHTTP_SECURE_CERT_DATE_INVALID
Definition: winhttp.h:204
#define ERROR_WINHTTP_SECURE_INVALID_CERT
Definition: winhttp.h:222
#define ERROR_WINHTTP_SECURE_CERT_CN_INVALID
Definition: winhttp.h:205
#define ERROR_WINHTTP_SECURE_CERT_REV_FAILED
Definition: winhttp.h:208
#define ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE
Definition: winhttp.h:227
#define SECURITY_FLAG_IGNORE_UNKNOWN_CA
Definition: winhttp.h:281
#define ERROR_WINHTTP_SECURE_INVALID_CA
Definition: winhttp.h:207

Referenced by netconn_secure_connect().

◆ read_ssl_chunk()

static BOOL read_ssl_chunk ( struct netconn conn,
void buf,
SIZE_T  buf_size,
SIZE_T ret_size,
BOOL eof 
)
static

Definition at line 448 of file net.c.

449{
450 const SIZE_T ssl_buf_size = conn->ssl_sizes.cbHeader+conn->ssl_sizes.cbMaximumMessage+conn->ssl_sizes.cbTrailer;
451 SecBuffer bufs[4];
453 SSIZE_T size, buf_len;
454 unsigned int i;
456
457 assert(conn->extra_len < ssl_buf_size);
458
459 if(conn->extra_len) {
460 memcpy(conn->ssl_buf, conn->extra_buf, conn->extra_len);
461 buf_len = conn->extra_len;
462 conn->extra_len = 0;
463 heap_free(conn->extra_buf);
464 conn->extra_buf = NULL;
465 }else {
466 buf_len = sock_recv(conn->socket, conn->ssl_buf+conn->extra_len, ssl_buf_size-conn->extra_len, 0);
467 if(buf_len < 0)
468 return FALSE;
469
470 if(!buf_len) {
471 *eof = TRUE;
472 return TRUE;
473 }
474 }
475
476 *ret_size = 0;
477 *eof = FALSE;
478
479 do {
480 memset(bufs, 0, sizeof(bufs));
481 bufs[0].BufferType = SECBUFFER_DATA;
482 bufs[0].cbBuffer = buf_len;
483 bufs[0].pvBuffer = conn->ssl_buf;
484
485 res = DecryptMessage(&conn->ssl_ctx, &buf_desc, 0, NULL);
486 switch(res) {
487 case SEC_E_OK:
488 break;
490 TRACE("context expired\n");
491 *eof = TRUE;
492 return TRUE;
494 assert(buf_len < ssl_buf_size);
495
496 size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0);
497 if(size < 1)
498 return FALSE;
499
500 buf_len += size;
501 continue;
502 default:
503 WARN("failed: %08x\n", res);
504 return FALSE;
505 }
506 } while(res != SEC_E_OK);
507
508 for(i = 0; i < ARRAY_SIZE(bufs); i++) {
509 if(bufs[i].BufferType == SECBUFFER_DATA) {
510 size = min(buf_size, bufs[i].cbBuffer);
511 memcpy(buf, bufs[i].pvBuffer, size);
512 if(size < bufs[i].cbBuffer) {
513 assert(!conn->peek_len);
514 conn->peek_msg_mem = conn->peek_msg = heap_alloc(bufs[i].cbBuffer - size);
515 if(!conn->peek_msg)
516 return FALSE;
517 conn->peek_len = bufs[i].cbBuffer-size;
518 memcpy(conn->peek_msg, (char*)bufs[i].pvBuffer+size, conn->peek_len);
519 }
520
521 *ret_size = size;
522 }
523 }
524
525 for(i = 0; i < ARRAY_SIZE(bufs); i++) {
526 if(bufs[i].BufferType == SECBUFFER_EXTRA) {
527 conn->extra_buf = heap_alloc(bufs[i].cbBuffer);
528 if(!conn->extra_buf)
529 return FALSE;
530
531 conn->extra_len = bufs[i].cbBuffer;
532 memcpy(conn->extra_buf, bufs[i].pvBuffer, conn->extra_len);
533 }
534 }
535
536 return TRUE;
537}
#define ARRAY_SIZE(A)
Definition: main.h:20
const GLenum * bufs
Definition: glext.h:6026
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 SECBUFFER_DATA
Definition: sspi.h:160
#define memset(x, y, z)
Definition: compat.h:39
size_t extra_len
#define SEC_I_CONTEXT_EXPIRED
Definition: winerror.h:2933
SECURITY_STATUS WINAPI DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
Definition: wrapper.c:1036

Referenced by netconn_recv(), and tcp_recv().

◆ resolve_hostname()

static DWORD resolve_hostname ( const WCHAR name,
INTERNET_PORT  port,
struct sockaddr_storage sa 
)
static

Definition at line 622 of file net.c.

623{
625 int ret;
626
627 memset( &hints, 0, sizeof(hints) );
628 /* Prefer IPv4 to IPv6 addresses, since some web servers do not listen on
629 * their IPv6 addresses even though they have IPv6 addresses in the DNS.
630 */
631 hints.ai_family = AF_INET;
632
633 ret = GetAddrInfoW( name, NULL, &hints, &res );
634 if (ret != 0)
635 {
636 TRACE("failed to get IPv4 address of %s, retrying with IPv6\n", debugstr_w(name));
637 hints.ai_family = AF_INET6;
638 ret = GetAddrInfoW( name, NULL, &hints, &res );
639 if (ret != 0)
640 {
641 TRACE("failed to get address of %s\n", debugstr_w(name));
643 }
644 }
645 memcpy( sa, res->ai_addr, res->ai_addrlen );
646 switch (res->ai_family)
647 {
648 case AF_INET:
649 ((struct sockaddr_in *)sa)->sin_port = htons( port );
650 break;
651 case AF_INET6:
652 ((struct sockaddr_in6 *)sa)->sin6_port = htons( port );
653 break;
654 }
655
657 return ERROR_SUCCESS;
658}
#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
#define htons(x)
Definition: module.h:215
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
Definition: name.c:39
#define ERROR_WINHTTP_NAME_NOT_RESOLVED
Definition: winhttp.h:193

Referenced by netconn_resolve(), and resolve_proc().

◆ resolve_proc()

static void CALLBACK resolve_proc ( TP_CALLBACK_INSTANCE instance,
void ctx 
)
static

Definition at line 718 of file net.c.

719{
720 struct async_resolve *async = ctx;
721 async->result = resolve_hostname( async->hostname, async->port, async->addr );
722 SetEvent( async->done );
723}
INTERNET_PORT port
Definition: net.c:712
DWORD result
Definition: net.c:714
struct sockaddr_storage * addr
Definition: net.c:713
HANDLE done
Definition: net.c:715
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733

Referenced by netconn_resolve().

◆ send_ssl_chunk()

static BOOL send_ssl_chunk ( struct netconn conn,
const void msg,
size_t  size 
)
static

Definition at line 398 of file net.c.

399{
400 SecBuffer bufs[4] = {
405 };
408
409 memcpy(bufs[1].pvBuffer, msg, size);
410 res = EncryptMessage(&conn->ssl_ctx, 0, &buf_desc, 0);
411 if(res != SEC_E_OK) {
412 WARN("EncryptMessage failed\n");
413 return FALSE;
414 }
415
416 if(sock_send(conn->socket, conn->ssl_buf, bufs[0].cbBuffer+bufs[1].cbBuffer+bufs[2].cbBuffer, 0) < 1) {
417 WARN("send failed\n");
418 return FALSE;
419 }
420
421 return TRUE;
422}
#define SECBUFFER_STREAM_TRAILER
Definition: sspi.h:165
#define SECBUFFER_STREAM_HEADER
Definition: sspi.h:166
SECURITY_STATUS WINAPI EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
Definition: wrapper.c:1006

Referenced by netconn_send(), and tcp_send().

◆ set_blocking()

static void set_blocking ( struct netconn conn,
BOOL  blocking 
)
static

Definition at line 180 of file net.c.

181{
182 ULONG state = !blocking;
183 ioctlsocket( conn->socket, FIONBIO, &state );
184}
static int state
Definition: maze.c:121
#define ioctlsocket
Definition: ncftp.h:481
#define FIONBIO
Definition: winsock.h:149

Referenced by netconn_create(), and netconn_is_alive().

◆ sock_recv()

static int sock_recv ( int  fd,
void msg,
size_t  len,
int  flags 
)
static

Definition at line 49 of file net.c.

50{
51 int ret;
52 do
53 {
54 if ((ret = recv(fd, msg, len, flags)) == -1) WARN("recv error %u\n", WSAGetLastError());
55 }
56 while(ret == -1 && WSAGetLastError() == WSAEINTR);
57 return ret;
58}
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
static int fd
Definition: io.c:51
#define WSAEINTR
Definition: winerror.h:1942

Referenced by FTP_GetNextLine(), FTP_ReceiveRequestData(), FTP_RetrieveFileData(), FTPFILE_QueryDataAvailable(), FTPFILE_ReadFile(), netconn_is_alive(), netconn_recv(), netconn_secure_connect(), and read_ssl_chunk().

◆ sock_send()

static int sock_send ( int  fd,
const void msg,
size_t  len,
int  flags 
)
static

Definition at line 38 of file net.c.

39{
40 int ret;
41 do
42 {
43 if ((ret = send(fd, msg, len, flags)) == -1) WARN("send error %u\n", WSAGetLastError());
44 }
45 while(ret == -1 && WSAGetLastError() == WSAEINTR);
46 return ret;
47}

Referenced by FTP_SendCommandA(), FTP_SendData(), FtpCommandW(), FTPFILE_WriteFile(), netconn_secure_connect(), netconn_send(), and send_ssl_chunk().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( winhttp  )

◆ winsock_init()

static void winsock_init ( void  )
static

Definition at line 173 of file net.c.

175{
176 static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
178}
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
static BOOL WINAPI winsock_startup(INIT_ONCE *once, void *param, void **ctx)
Definition: net.c:161
RTL_RUN_ONCE INIT_ONCE
Definition: winbase.h:3956
#define INIT_ONCE_STATIC_INIT
Definition: winbase.h:637

Referenced by netconn_create().

◆ winsock_startup()

static BOOL WINAPI winsock_startup ( INIT_ONCE once,
void param,
void **  ctx 
)
static

Definition at line 161 of file net.c.

162{
163 int ret;
165 if (!(ret = WSAStartup( MAKEWORD(1,1), &data ))) winsock_loaded = TRUE;
166 else ERR( "WSAStartup failed: %d\n", ret );
167 return TRUE;
168}
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define MAKEWORD(a, b)
Definition: typedefs.h:248

Referenced by winsock_init().

Variable Documentation

◆ winsock_loaded

BOOL winsock_loaded
static

Definition at line 154 of file net.c.

Referenced by netconn_unload(), and winsock_startup().