ReactOS  0.4.13-dev-99-g7e18b6d
netconnection.c File Reference
#include "ws2tcpip.h"
#include <time.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "wine/library.h"
#include "windef.h"
#include "winbase.h"
#include "wininet.h"
#include "winerror.h"
#include "wine/debug.h"
#include "internet.h"
Include dependency graph for netconnection.c:

Go to the source code of this file.

Macros

#define NONAMELESSUNION
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (wininet)
 
static DWORD netconn_verify_cert (netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTORE store)
 
static BOOL ensure_cred_handle (void)
 
static BOOL WINAPI winsock_startup (INIT_ONCE *once, void *param, void **context)
 
void init_winsock (void)
 
static void set_socket_blocking (netconn_t *conn, BOOL is_blocking)
 
static DWORD create_netconn_socket (server_t *server, netconn_t *netconn, DWORD timeout)
 
DWORD create_netconn (BOOL useSSL, server_t *server, DWORD security_flags, BOOL mask_errors, DWORD timeout, netconn_t **ret)
 
BOOL is_valid_netconn (netconn_t *netconn)
 
void close_netconn (netconn_t *netconn)
 
void free_netconn (netconn_t *netconn)
 
void NETCON_unload (void)
 
int sock_send (int fd, const void *msg, size_t len, int flags)
 
int sock_recv (int fd, void *msg, size_t len, int flags)
 
static DWORD netcon_secure_connect_setup (netconn_t *connection, BOOL compat_mode)
 
DWORD NETCON_secure_connect (netconn_t *connection, server_t *server)
 
static BOOL send_ssl_chunk (netconn_t *conn, const void *msg, size_t size)
 
DWORD NETCON_send (netconn_t *connection, const void *msg, size_t len, int flags, int *sent)
 
static BOOL read_ssl_chunk (netconn_t *conn, void *buf, SIZE_T buf_size, BOOL blocking, SIZE_T *ret_size, BOOL *eof)
 
DWORD NETCON_recv (netconn_t *connection, void *buf, size_t len, BOOL blocking, int *recvd)
 
BOOL NETCON_is_alive (netconn_t *netconn)
 
LPCVOID NETCON_GetCert (netconn_t *connection)
 
int NETCON_GetCipherStrength (netconn_t *connection)
 
DWORD NETCON_set_timeout (netconn_t *connection, BOOL send, DWORD value)
 

Variables

static SecHandle cred_handle
 
static SecHandle compat_cred_handle
 
static BOOL cred_handle_initialized
 
static BOOL have_compat_cred_handle
 
static CRITICAL_SECTION init_sechandle_cs = { &init_sechandle_cs_debug, -1, 0, 0, 0, 0 }
 
static CRITICAL_SECTION_DEBUG init_sechandle_cs_debug
 
static BOOL winsock_loaded = FALSE
 

Macro Definition Documentation

◆ NONAMELESSUNION

#define NONAMELESSUNION

Definition at line 24 of file netconnection.c.

Function Documentation

◆ close_netconn()

void close_netconn ( netconn_t netconn)

Definition at line 375 of file netconnection.c.

376 {
377  closesocket(netconn->socket);
378  netconn->socket = -1;
379 }
#define closesocket
Definition: main.c:39

Referenced by free_netconn(), and http_release_netconn().

◆ create_netconn()

DWORD create_netconn ( BOOL  useSSL,
server_t server,
DWORD  security_flags,
BOOL  mask_errors,
DWORD  timeout,
netconn_t **  ret 
)

Definition at line 343 of file netconnection.c.

344 {
345  netconn_t *netconn;
346  int result;
347 
348  netconn = heap_alloc_zero(sizeof(*netconn));
349  if(!netconn)
350  return ERROR_OUTOFMEMORY;
351 
352  netconn->socket = -1;
353  netconn->security_flags = security_flags | server->security_flags;
354  netconn->mask_errors = mask_errors;
355  list_init(&netconn->pool_entry);
356  SecInvalidateHandle(&netconn->ssl_ctx);
357 
359  if (result != ERROR_SUCCESS) {
360  heap_free(netconn);
361  return result;
362  }
363 
365  netconn->server = server;
366  *ret = netconn;
367  return result;
368 }
CtxtHandle ssl_ctx
static rfbScreenInfoPtr server
Definition: vnc.c:74
#define ERROR_SUCCESS
Definition: deptool.c:10
Definition: dhcpd.h:245
#define SecInvalidateHandle(x)
Definition: sspi.h:58
struct list pool_entry
Definition: internet.h:87
DWORD security_flags
Definition: internet.h:82
int ret
void server_addref(server_t *server)
Definition: http.c:224
BOOL mask_errors
Definition: internet.h:83
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD timeout)
GLuint64EXT * result
Definition: glext.h:11304
server_t * server
Definition: internet.h:75
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
static BOOL heap_free(void *mem)
Definition: appwiz.h:75

Referenced by open_http_connection().

◆ create_netconn_socket()

static DWORD create_netconn_socket ( server_t server,
netconn_t netconn,
DWORD  timeout 
)
static

Definition at line 292 of file netconnection.c.

293 {
294  int result;
295  ULONG flag;
296  DWORD res;
297 
298  init_winsock();
299 
300  assert(server->addr_len);
301  result = netconn->socket = socket(server->addr.ss_family, SOCK_STREAM, 0);
302  if(result != -1) {
303  set_socket_blocking(netconn, FALSE);
304  result = connect(netconn->socket, (struct sockaddr*)&server->addr, server->addr_len);
305  if(result == -1)
306  {
307  res = WSAGetLastError();
308  if (res == WSAEINPROGRESS || res == WSAEWOULDBLOCK) {
309  FD_SET set;
310  int res;
311  socklen_t len = sizeof(res);
312  TIMEVAL timeout_timeval = {0, timeout*1000};
313 
314  FD_ZERO(&set);
315  FD_SET(netconn->socket, &set);
316  res = select(netconn->socket+1, NULL, &set, NULL, &timeout_timeval);
317  if(!res || res == SOCKET_ERROR) {
318  closesocket(netconn->socket);
319  netconn->socket = -1;
321  }
322  if (!getsockopt(netconn->socket, SOL_SOCKET, SO_ERROR, (void *)&res, &len) && !res)
323  result = 0;
324  }
325  }
326  if(result == -1)
327  {
328  closesocket(netconn->socket);
329  netconn->socket = -1;
330  }
331  }
332  if(result == -1)
334 
335  flag = 1;
336  result = setsockopt(netconn->socket, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag));
337  if(result < 0)
338  WARN("setsockopt(TCP_NODELAY) failed\n");
339 
340  return ERROR_SUCCESS;
341 }
Definition: winsock.h:66
#define SOCKET_ERROR
Definition: winsock.h:333
static rfbScreenInfoPtr server
Definition: vnc.c:74
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WARN(fmt,...)
Definition: debug.h:111
#define WSAEWOULDBLOCK
Definition: winerror.h:1948
#define assert(x)
Definition: debug.h:53
Definition: dhcpd.h:245
#define SOL_SOCKET
Definition: winsock.h:398
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89
INT WSAAPI connect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: sockctrl.c:23
#define WSAEINPROGRESS
Definition: winerror.h:1949
#define ERROR_INTERNET_CANNOT_CONNECT
Definition: wininet.h:2018
void init_winsock(void)
#define TCP_NODELAY
Definition: tcpdef.h:117
#define closesocket
Definition: main.c:39
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 setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
smooth NULL
Definition: ftsmooth.c:416
#define SO_ERROR
Definition: winsock.h:194
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
static UINT set(struct ID3DXConstantTableImpl *table, IDirect3DDevice9 *device, struct ctab_constant *constant, const void **indata, D3DXPARAMETER_TYPE intype, UINT *size, UINT incol, D3DXPARAMETER_CLASS inclass, UINT index, BOOL is_pointer)
Definition: shader.c:1095
unsigned long DWORD
Definition: ntddk_ex.h:95
int socklen_t
Definition: tcp.c:35
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
GLenum GLsizei len
Definition: glext.h:6722
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
static void set_socket_blocking(netconn_t *conn, BOOL is_blocking)
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1
#define SOCK_STREAM
Definition: tcpip.h:118
Definition: _set.h:46
GLuint64EXT * result
Definition: glext.h:11304

Referenced by create_netconn(), and NETCON_secure_connect().

◆ ensure_cred_handle()

static BOOL ensure_cred_handle ( void  )
static

Definition at line 227 of file netconnection.c.

228 {
230 
232 
236 
238  NULL, NULL, &cred_handle, NULL);
239  if(res == SEC_E_OK) {
246  }
247  }
248 
250  }
251 
253 
254  if(res != SEC_E_OK) {
255  WARN("Failed: %08x\n", res);
256  return FALSE;
257  }
258 
259  return TRUE;
260 }
#define SECPKG_ATTR_SUPPORTED_PROTOCOLS
Definition: schannel.h:74
#define TRUE
Definition: types.h:120
#define SECPKG_CRED_OUTBOUND
Definition: sspi.h:277
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
#define WARN(fmt,...)
Definition: debug.h:111
static SecHandle cred_handle
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static BOOL cred_handle_initialized
SECURITY_STATUS WINAPI QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
Definition: wrapper.c:177
#define SCHANNEL_CRED_VERSION
Definition: schannel.h:22
smooth NULL
Definition: ftsmooth.c:416
DWORD grbitEnabledProtocols
Definition: schannel.h:96
static CRITICAL_SECTION init_sechandle_cs
LONG SECURITY_STATUS
Definition: sspi.h:34
static SecHandle compat_cred_handle
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SEC_E_OK
Definition: winerror.h:2356
#define SP_PROT_TLS1_1PLUS_CLIENT
Definition: schannel.h:52
#define UNISP_NAME_W
Definition: sspi.h:38
GLuint res
Definition: glext.h:9613
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static BOOL have_compat_cred_handle

Referenced by netcon_secure_connect_setup().

◆ free_netconn()

void free_netconn ( netconn_t netconn)

Definition at line 381 of file netconnection.c.

382 {
383  server_release(netconn->server);
384 
385  if (netconn->secure) {
386  heap_free(netconn->peek_msg_mem);
387  netconn->peek_msg_mem = NULL;
388  netconn->peek_msg = NULL;
389  netconn->peek_len = 0;
390  heap_free(netconn->ssl_buf);
391  netconn->ssl_buf = NULL;
392  heap_free(netconn->extra_buf);
393  netconn->extra_buf = NULL;
394  netconn->extra_len = 0;
395  if (SecIsValidHandle(&netconn->ssl_ctx))
396  DeleteSecurityContext(&netconn->ssl_ctx);
397  }
398 
399  close_netconn(netconn);
400  heap_free(netconn);
401 }
size_t extra_len
CtxtHandle ssl_ctx
void close_netconn(netconn_t *netconn)
#define SecIsValidHandle(x)
Definition: sspi.h:63
char * ssl_buf
size_t peek_len
void server_release(server_t *server)
Definition: http.c:229
char * extra_buf
smooth NULL
Definition: ftsmooth.c:416
char * peek_msg
server_t * server
Definition: internet.h:75
char * peek_msg_mem
SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:450
static BOOL heap_free(void *mem)
Definition: appwiz.h:75

Referenced by collect_connections(), and open_http_connection().

◆ init_winsock()

void init_winsock ( void  )

Definition at line 277 of file netconnection.c.

278 {
279  static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
281 }
static BOOL WINAPI winsock_startup(INIT_ONCE *once, void *param, void **context)
#define INIT_ONCE_STATIC_INIT
Definition: winbase.h:593
smooth NULL
Definition: ftsmooth.c:416
BOOL NTAPI InitOnceExecuteOnce(INIT_ONCE *once, PINIT_ONCE_FN func, void *param, void **context)

Referenced by create_netconn_socket(), FTP_Connect(), FTP_InitListenSocket(), InternetCheckConnectionW(), and InternetOpenW().

◆ is_valid_netconn()

◆ NETCON_GetCert()

LPCVOID NETCON_GetCert ( netconn_t connection)

Definition at line 883 of file netconnection.c.

884 {
885  const CERT_CONTEXT *ret;
887 
889  return res == SEC_E_OK ? ret : NULL;
890 }
CtxtHandle ssl_ctx
#define SECPKG_ATTR_REMOTE_CERT_CONTEXT
Definition: schannel.h:69
smooth NULL
Definition: ftsmooth.c:416
LONG SECURITY_STATUS
Definition: sspi.h:34
int ret
#define SEC_E_OK
Definition: winerror.h:2356
SECURITY_STATUS WINAPI QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
Definition: wrapper.c:535
GLuint res
Definition: glext.h:9613

Referenced by HTTPREQ_QueryOption().

◆ NETCON_GetCipherStrength()

int NETCON_GetCipherStrength ( netconn_t connection)

Definition at line 892 of file netconnection.c.

893 {
896 
897  if (!connection->secure)
898  return 0;
899 
900  res = QueryContextAttributesW(&connection->ssl_ctx, SECPKG_ATTR_CONNECTION_INFO, (void*)&conn_info);
901  if(res != SEC_E_OK)
902  WARN("QueryContextAttributesW failed: %08x\n", res);
903  return res == SEC_E_OK ? conn_info.dwCipherStrength : 0;
904 }
CtxtHandle ssl_ctx
#define WARN(fmt,...)
Definition: debug.h:111
LONG SECURITY_STATUS
Definition: sspi.h:34
#define SECPKG_ATTR_CONNECTION_INFO
Definition: schannel.h:76
#define SEC_E_OK
Definition: winerror.h:2356
SECURITY_STATUS WINAPI QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
Definition: wrapper.c:535
GLuint res
Definition: glext.h:9613

Referenced by HTTPREQ_QueryOption(), and netcon_secure_connect_setup().

◆ NETCON_is_alive()

BOOL NETCON_is_alive ( netconn_t netconn)

Definition at line 872 of file netconnection.c.

873 {
874  int len;
875  char b;
876 
877  set_socket_blocking(netconn, FALSE);
878  len = sock_recv(netconn->socket, &b, 1, MSG_PEEK);
879 
880  return len == 1 || (len == -1 && WSAGetLastError() == WSAEWOULDBLOCK);
881 }
int sock_recv(int fd, void *msg, size_t len, int flags)
#define WSAEWOULDBLOCK
Definition: winerror.h:1948
#define b
Definition: ke_i.h:79
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
GLenum GLsizei len
Definition: glext.h:6722
static void set_socket_blocking(netconn_t *conn, BOOL is_blocking)
#define MSG_PEEK
Definition: winsock.h:222

Referenced by open_http_connection().

◆ NETCON_recv()

DWORD NETCON_recv ( netconn_t connection,
void buf,
size_t  len,
BOOL  blocking,
int recvd 
)

Definition at line 820 of file netconnection.c.

821 {
822  *recvd = 0;
823  if (!len)
824  return ERROR_SUCCESS;
825 
826  if (!connection->secure)
827  {
828  set_socket_blocking(connection, blocking);
829  *recvd = sock_recv(connection->socket, buf, len, 0);
830  return *recvd == -1 ? WSAGetLastError() : ERROR_SUCCESS;
831  }
832  else
833  {
834  SIZE_T size = 0;
835  BOOL eof;
836  DWORD res;
837 
838  if(connection->peek_msg) {
839  size = min(len, connection->peek_len);
840  memcpy(buf, connection->peek_msg, size);
841  connection->peek_len -= size;
842  connection->peek_msg += size;
843 
844  if(!connection->peek_len) {
845  heap_free(connection->peek_msg_mem);
846  connection->peek_msg_mem = connection->peek_msg = NULL;
847  }
848 
849  *recvd = size;
850  return ERROR_SUCCESS;
851  }
852 
853  do {
854  res = read_ssl_chunk(connection, (BYTE*)buf, len, blocking, &size, &eof);
855  if(res != ERROR_SUCCESS) {
856  if(res == WSAEWOULDBLOCK) {
857  if(size)
858  res = ERROR_SUCCESS;
859  }else {
860  WARN("read_ssl_chunk failed\n");
861  }
862  break;
863  }
864  }while(!size && !eof);
865 
866  TRACE("received %ld bytes\n", size);
867  *recvd = size;
868  return res;
869  }
870 }
static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, BOOL blocking, SIZE_T *ret_size, BOOL *eof)
#define ERROR_SUCCESS
Definition: deptool.c:10
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define WARN(fmt,...)
Definition: debug.h:111
int sock_recv(int fd, void *msg, size_t len, int flags)
#define WSAEWOULDBLOCK
Definition: winerror.h:1948
size_t peek_len
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
GLsizeiptr size
Definition: glext.h:5919
unsigned long DWORD
Definition: ntddk_ex.h:95
char * peek_msg
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define min(a, b)
Definition: monoChain.cc:55
static void set_socket_blocking(netconn_t *conn, BOOL is_blocking)
GLuint res
Definition: glext.h:9613
char * peek_msg_mem
static BOOL heap_free(void *mem)
Definition: appwiz.h:75

Referenced by chunked_read(), netconn_drain_content(), netconn_read(), and read_more_data().

◆ NETCON_secure_connect()

DWORD NETCON_secure_connect ( netconn_t connection,
server_t server 
)

Definition at line 600 of file netconnection.c.

601 {
602  DWORD res;
603 
604  /* can't connect if we are already connected */
605  if(connection->secure) {
606  ERR("already connected\n");
608  }
609 
610  if(server != connection->server) {
611  server_release(connection->server);
613  connection->server = server;
614  }
615 
616  /* connect with given TLS options */
617  res = netcon_secure_connect_setup(connection, FALSE);
618  if (res == ERROR_SUCCESS)
619  return res;
620 
621  /* FIXME: when got version alert and FIN from server */
622  /* fallback to connect without TLSv1.1/TLSv1.2 */
624  {
625  closesocket(connection->socket);
626  res = create_netconn_socket(connection->server, connection, 500);
627  if (res != ERROR_SUCCESS)
628  return res;
629  res = netcon_secure_connect_setup(connection, TRUE);
630  }
631  return res;
632 }
#define TRUE
Definition: types.h:120
static rfbScreenInfoPtr server
Definition: vnc.c:74
#define ERROR_SUCCESS
Definition: deptool.c:10
void server_release(server_t *server)
Definition: http.c:229
#define ERROR_INTERNET_CANNOT_CONNECT
Definition: wininet.h:2018
#define closesocket
Definition: main.c:39
static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode)
unsigned long DWORD
Definition: ntddk_ex.h:95
void server_addref(server_t *server)
Definition: http.c:224
#define ERR(fmt,...)
Definition: debug.h:109
#define ERROR_INTERNET_SECURITY_CHANNEL_ERROR
Definition: wininet.h:2068
GLuint res
Definition: glext.h:9613
static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD timeout)
server_t * server
Definition: internet.h:75
static BOOL have_compat_cred_handle

Referenced by HTTP_HttpSendRequestW().

◆ netcon_secure_connect_setup()

static DWORD netcon_secure_connect_setup ( netconn_t connection,
BOOL  compat_mode 
)
static

Definition at line 436 of file netconnection.c.

437 {
438  SecBuffer out_buf = {0, SECBUFFER_TOKEN, NULL}, in_bufs[2] = {{0, SECBUFFER_TOKEN}, {0, SECBUFFER_EMPTY}};
439  SecBufferDesc out_desc = {SECBUFFER_VERSION, 1, &out_buf}, in_desc = {SECBUFFER_VERSION, 2, in_bufs};
440  SecHandle *cred = &cred_handle;
441  BYTE *read_buf;
442  SIZE_T read_buf_size = 2048;
443  ULONG attrs = 0;
444  CtxtHandle ctx;
445  SSIZE_T size;
446  int bits;
447  const CERT_CONTEXT *cert;
450 
453 
454  if(!ensure_cred_handle())
456 
457  if(compat_mode) {
460  cred = &compat_cred_handle;
461  }
462 
463  read_buf = heap_alloc(read_buf_size);
464  if(!read_buf)
465  return ERROR_OUTOFMEMORY;
466 
467  status = InitializeSecurityContextW(cred, NULL, connection->server->name, isc_req_flags, 0, 0, NULL, 0,
468  &ctx, &out_desc, &attrs, NULL);
469 
470  assert(status != SEC_E_OK);
471 
472  set_socket_blocking(connection, TRUE);
473 
475  if(out_buf.cbBuffer) {
477 
478  TRACE("sending %u bytes\n", out_buf.cbBuffer);
479 
480  size = sock_send(connection->socket, out_buf.pvBuffer, out_buf.cbBuffer, 0);
481  if(size != out_buf.cbBuffer) {
482  ERR("send failed\n");
484  break;
485  }
486 
487  FreeContextBuffer(out_buf.pvBuffer);
488  out_buf.pvBuffer = NULL;
489  out_buf.cbBuffer = 0;
490  }
491 
493  assert(in_bufs[1].cbBuffer < read_buf_size);
494 
495  memmove(read_buf, (BYTE*)in_bufs[0].pvBuffer+in_bufs[0].cbBuffer-in_bufs[1].cbBuffer, in_bufs[1].cbBuffer);
496  in_bufs[0].cbBuffer = in_bufs[1].cbBuffer;
497 
498  in_bufs[1].BufferType = SECBUFFER_EMPTY;
499  in_bufs[1].cbBuffer = 0;
500  in_bufs[1].pvBuffer = NULL;
501  }
502 
503  assert(in_bufs[0].BufferType == SECBUFFER_TOKEN);
504  assert(in_bufs[1].BufferType == SECBUFFER_EMPTY);
505 
506  if(in_bufs[0].cbBuffer + 1024 > read_buf_size) {
507  BYTE *new_read_buf;
508 
509  new_read_buf = heap_realloc(read_buf, read_buf_size + 1024);
510  if(!new_read_buf) {
512  break;
513  }
514 
515  in_bufs[0].pvBuffer = read_buf = new_read_buf;
516  read_buf_size += 1024;
517  }
518 
519  size = sock_recv(connection->socket, read_buf+in_bufs[0].cbBuffer, read_buf_size-in_bufs[0].cbBuffer, 0);
520  if(size < 1) {
521  WARN("recv error\n");
523  break;
524  }
525 
526  TRACE("recv %lu bytes\n", size);
527 
528  in_bufs[0].cbBuffer += size;
529  in_bufs[0].pvBuffer = read_buf;
530  status = InitializeSecurityContextW(cred, &ctx, connection->server->name, isc_req_flags, 0, 0, &in_desc,
531  0, NULL, &out_desc, &attrs, NULL);
532  TRACE("InitializeSecurityContext ret %08x\n", status);
533 
534  if(status == SEC_E_OK) {
535  if(SecIsValidHandle(&connection->ssl_ctx))
536  DeleteSecurityContext(&connection->ssl_ctx);
537  connection->ssl_ctx = ctx;
538 
539  if(in_bufs[1].BufferType == SECBUFFER_EXTRA)
540  FIXME("SECBUFFER_EXTRA not supported\n");
541 
543  if(status != SEC_E_OK) {
544  WARN("Could not get sizes\n");
545  break;
546  }
547 
549  if(status == SEC_E_OK) {
550  res = netconn_verify_cert(connection, cert, cert->hCertStore);
552  if(res != ERROR_SUCCESS) {
553  WARN("cert verify failed: %u\n", res);
554  break;
555  }
556  }else {
557  WARN("Could not get cert\n");
558  break;
559  }
560 
561  connection->ssl_buf = heap_alloc(connection->ssl_sizes.cbHeader + connection->ssl_sizes.cbMaximumMessage
562  + connection->ssl_sizes.cbTrailer);
563  if(!connection->ssl_buf) {
564  res = GetLastError();
565  break;
566  }
567  }
568  }
569 
571 
572  if(status != SEC_E_OK || res != ERROR_SUCCESS) {
573  WARN("Failed to establish SSL connection: %08x (%u)\n", status, res);
574  heap_free(connection->ssl_buf);
575  connection->ssl_buf = NULL;
577  }
578 
579  TRACE("established SSL connection\n");
580  connection->secure = TRUE;
581  connection->security_flags |= SECURITY_FLAG_SECURE;
582 
583  bits = NETCON_GetCipherStrength(connection);
584  if (bits >= 128)
586  else if (bits >= 56)
588  else
590 
591  if(connection->mask_errors)
592  connection->server->security_flags = connection->security_flags;
593  return ERROR_SUCCESS;
594 }
#define ISC_REQ_SEQUENCE_DETECT
Definition: sspi.h:351
#define SECURITY_FLAG_STRENGTH_MEDIUM
Definition: winhttp.h:287
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
CtxtHandle ssl_ctx
#define TRUE
Definition: types.h:120
static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTORE store)
Definition: netconnection.c:46
#define SECURITY_FLAG_STRENGTH_STRONG
Definition: winhttp.h:288
#define ERROR_SUCCESS
Definition: deptool.c:10
SECURITY_STATUS WINAPI FreeContextBuffer(PVOID pv)
Definition: sspi.c:699
#define SecIsValidHandle(x)
Definition: sspi.h:63
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
#define WARN(fmt,...)
Definition: debug.h:111
int sock_recv(int fd, void *msg, size_t len, int flags)
#define SECPKG_ATTR_REMOTE_CERT_CONTEXT
Definition: schannel.h:69
static SecHandle cred_handle
#define assert(x)
Definition: debug.h:53
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
LONG_PTR SSIZE_T
Definition: basetsd.h:183
char * ssl_buf
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define SECBUFFER_EXTRA
Definition: sspi.h:150
unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size)
Definition: deflate.c:1167
#define ISC_REQ_MANUAL_CRED_VALIDATION
Definition: sspi.h:367
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define FIXME(fmt,...)
Definition: debug.h:110
smooth NULL
Definition: ftsmooth.c:416
#define SECBUFFER_EMPTY
Definition: sspi.h:145
int sock_send(int fd, const void *msg, size_t len, int flags)
#define SEC_I_CONTINUE_NEEDED
Definition: winerror.h:2927
static BYTE cert[]
Definition: msg.c:1437
DWORD security_flags
Definition: internet.h:82
LONG SECURITY_STATUS
Definition: sspi.h:34
static SecHandle compat_cred_handle
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
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
static BOOL ensure_cred_handle(void)
DWORD security_flags
Definition: internet.h:50
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ISC_REQ_USE_SESSION_KEY
Definition: sspi.h:353
#define SECPKG_ATTR_STREAM_SIZES
Definition: sspi.h:511
#define ISC_REQ_ALLOCATE_MEMORY
Definition: sspi.h:356
#define SECBUFFER_TOKEN
Definition: sspi.h:147
unsigned char BYTE
Definition: mem.h:68
WCHAR * name
Definition: internet.h:37
#define SEC_E_OK
Definition: winerror.h:2356
SECURITY_STATUS WINAPI QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
Definition: wrapper.c:535
#define ERR(fmt,...)
Definition: debug.h:109
BOOL mask_errors
Definition: internet.h:83
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define SECBUFFER_VERSION
Definition: sspi.h:173
ULONG cbBuffer
Definition: sspi.h:139
#define ERROR_INTERNET_SECURITY_CHANNEL_ERROR
Definition: wininet.h:2068
int NETCON_GetCipherStrength(netconn_t *connection)
static void set_socket_blocking(netconn_t *conn, BOOL is_blocking)
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1
#define ISC_REQ_CONFIDENTIALITY
Definition: sspi.h:352
#define SECURITY_FLAG_SECURE
Definition: winhttp.h:285
#define ISC_REQ_REPLAY_DETECT
Definition: sspi.h:350
static SERVICE_STATUS status
Definition: service.c:31
server_t * server
Definition: internet.h:75
SecPkgContext_StreamSizes ssl_sizes
#define SEC_E_INCOMPLETE_MESSAGE
Definition: winerror.h:2934
#define SECURITY_FLAG_STRENGTH_WEAK
Definition: winhttp.h:286
SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:450
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
static BOOL have_compat_cred_handle
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
Definition: ps.c:97

Referenced by NETCON_secure_connect().

◆ NETCON_send()

DWORD NETCON_send ( netconn_t connection,
const void msg,
size_t  len,
int  flags,
int sent 
)

Definition at line 665 of file netconnection.c.

667 {
668  /* send is always blocking. */
669  set_socket_blocking(connection, TRUE);
670 
671  if(!connection->secure)
672  {
673  *sent = sock_send(connection->socket, msg, len, flags);
674  return *sent == -1 ? WSAGetLastError() : ERROR_SUCCESS;
675  }
676  else
677  {
678  const BYTE *ptr = msg;
679  size_t chunk_size;
680 
681  *sent = 0;
682 
683  while(len) {
684  chunk_size = min(len, connection->ssl_sizes.cbMaximumMessage);
685  if(!send_ssl_chunk(connection, ptr, chunk_size))
687 
688  *sent += chunk_size;
689  ptr += chunk_size;
690  len -= chunk_size;
691  }
692 
693  return ERROR_SUCCESS;
694  }
695 }
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
static PVOID ptr
Definition: dispmode.c:27
int sock_send(int fd, const void *msg, size_t len, int flags)
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
GLbitfield flags
Definition: glext.h:7161
Definition: msg.h:34
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
static BOOL send_ssl_chunk(netconn_t *conn, const void *msg, size_t size)
#define ERROR_INTERNET_SECURITY_CHANNEL_ERROR
Definition: wininet.h:2068
#define min(a, b)
Definition: monoChain.cc:55
static void set_socket_blocking(netconn_t *conn, BOOL is_blocking)
#define msg(x)
Definition: auth_time.c:54
SecPkgContext_StreamSizes ssl_sizes

Referenced by HTTP_HttpSendRequestW(), and HTTPREQ_WriteFile().

◆ NETCON_set_timeout()

DWORD NETCON_set_timeout ( netconn_t connection,
BOOL  send,
DWORD  value 
)

Definition at line 906 of file netconnection.c.

907 {
908  int result;
909 
910  result = setsockopt(connection->socket, SOL_SOCKET,
911  send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&value,
912  sizeof(value));
913  if (result == -1)
914  {
915  WARN("setsockopt failed\n");
916  return WSAGetLastError();
917  }
918  return ERROR_SUCCESS;
919 }
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WARN(fmt,...)
Definition: debug.h:111
#define SOL_SOCKET
Definition: winsock.h:398
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
#define SO_RCVTIMEO
Definition: winsock.h:193
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
#define SO_SNDTIMEO
Definition: winsock.h:192
GLuint64EXT * result
Definition: glext.h:11304

Referenced by HTTP_GetResponseHeaders(), and HTTP_HttpSendRequestW().

◆ NETCON_unload()

void NETCON_unload ( void  )

Definition at line 403 of file netconnection.c.

404 {
410  if(winsock_loaded)
411  WSACleanup();
412 }
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
static SecHandle cred_handle
SECURITY_STATUS WINAPI FreeCredentialsHandle(PCredHandle phCredential)
Definition: wrapper.c:151
static BOOL winsock_loaded
static BOOL cred_handle_initialized
static CRITICAL_SECTION init_sechandle_cs
static SecHandle compat_cred_handle
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
static BOOL have_compat_cred_handle

Referenced by DllMain().

◆ netconn_verify_cert()

static DWORD netconn_verify_cert ( netconn_t conn,
PCCERT_CONTEXT  cert,
HCERTSTORE  store 
)
static

Definition at line 46 of file netconnection.c.

47 {
48  BOOL ret;
49  CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } };
51  char oid_server_auth[] = szOID_PKIX_KP_SERVER_AUTH;
52  char *server_auth[] = { oid_server_auth };
53  DWORD err = ERROR_SUCCESS, errors;
54 
55  static const DWORD supportedErrors =
61 
62  TRACE("verifying %s\n", debugstr_w(conn->server->name));
63 
65  chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = server_auth;
66  if (!(ret = CertGetCertificateChain(NULL, cert, NULL, store, &chainPara, 0, NULL, &chain))) {
67  TRACE("failed\n");
68  return GetLastError();
69  }
70 
71  errors = chain->TrustStatus.dwErrorStatus;
72 
73  do {
74  /* This seems strange, but that's what tests show */
75  if(errors & CERT_TRUST_IS_PARTIAL_CHAIN) {
76  WARN("ERROR_INTERNET_SEC_CERT_REV_FAILED\n");
78  if(conn->mask_errors)
81  break;
82  }
83 
84  if (chain->TrustStatus.dwErrorStatus & ~supportedErrors) {
85  WARN("error status %x\n", chain->TrustStatus.dwErrorStatus & ~supportedErrors);
87  errors &= supportedErrors;
88  if(!conn->mask_errors)
89  break;
90  WARN("unknown error flags\n");
91  }
92 
93  if(errors & CERT_TRUST_IS_NOT_TIME_VALID) {
94  WARN("CERT_TRUST_IS_NOT_TIME_VALID\n");
97  if(!conn->mask_errors)
98  break;
100  }
101  errors &= ~CERT_TRUST_IS_NOT_TIME_VALID;
102  }
103 
104  if(errors & CERT_TRUST_IS_UNTRUSTED_ROOT) {
105  WARN("CERT_TRUST_IS_UNTRUSTED_ROOT\n");
108  if(!conn->mask_errors)
109  break;
111  }
112  errors &= ~CERT_TRUST_IS_UNTRUSTED_ROOT;
113  }
114 
115  if(errors & CERT_TRUST_IS_PARTIAL_CHAIN) {
116  WARN("CERT_TRUST_IS_PARTIAL_CHAIN\n");
119  if(!conn->mask_errors)
120  break;
122  }
123  errors &= ~CERT_TRUST_IS_PARTIAL_CHAIN;
124  }
125 
126  if(errors & CERT_TRUST_IS_NOT_SIGNATURE_VALID) {
127  WARN("CERT_TRUST_IS_NOT_SIGNATURE_VALID\n");
130  if(!conn->mask_errors)
131  break;
133  }
135  }
136 
137  if(errors & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) {
138  WARN("CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n");
141  if(!conn->mask_errors)
142  break;
143  WARN("CERT_TRUST_IS_NOT_VALID_FOR_USAGE, unknown error flags\n");
144  }
146  }
147 
150  err = ERROR_SUCCESS;
151  }
152  }while(0);
153 
154  if(!err || conn->mask_errors) {
155  CERT_CHAIN_POLICY_PARA policyPara;
156  SSL_EXTRA_CERT_CHAIN_POLICY_PARA sslExtraPolicyPara;
157  CERT_CHAIN_POLICY_STATUS policyStatus;
158  CERT_CHAIN_CONTEXT chainCopy;
159 
160  /* Clear chain->TrustStatus.dwErrorStatus so
161  * CertVerifyCertificateChainPolicy will verify additional checks
162  * rather than stopping with an existing, ignored error.
163  */
164  memcpy(&chainCopy, chain, sizeof(chainCopy));
165  chainCopy.TrustStatus.dwErrorStatus = 0;
166  sslExtraPolicyPara.u.cbSize = sizeof(sslExtraPolicyPara);
167  sslExtraPolicyPara.dwAuthType = AUTHTYPE_SERVER;
168  sslExtraPolicyPara.pwszServerName = conn->server->name;
169  sslExtraPolicyPara.fdwChecks = conn->security_flags;
170  policyPara.cbSize = sizeof(policyPara);
171  policyPara.dwFlags = 0;
172  policyPara.pvExtraPolicyPara = &sslExtraPolicyPara;
174  &chainCopy, &policyPara, &policyStatus);
175  /* Any error in the policy status indicates that the
176  * policy couldn't be verified.
177  */
178  if(ret) {
179  if(policyStatus.dwError == CERT_E_CN_NO_MATCH) {
180  WARN("CERT_E_CN_NO_MATCH\n");
181  if(conn->mask_errors)
184  }else if(policyStatus.dwError) {
185  WARN("policyStatus.dwError %x\n", policyStatus.dwError);
186  if(conn->mask_errors)
187  WARN("unknown error flags for policy status %x\n", policyStatus.dwError);
189  }
190  }else {
191  err = GetLastError();
192  }
193  }
194 
195  if(err) {
196  WARN("failed %u\n", err);
198  if(conn->server->cert_chain) {
200  conn->server->cert_chain = NULL;
201  }
202  if(conn->mask_errors)
204  return err;
205  }
206 
207  /* FIXME: Reuse cached chain */
208  if(conn->server->cert_chain)
210  else
211  conn->server->cert_chain = chain;
212  return ERROR_SUCCESS;
213 }
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
#define ERROR_INTERNET_SEC_CERT_CN_INVALID
Definition: wininet.h:2026
CERT_ENHKEY_USAGE Usage
Definition: wincrypt.h:1048
#define SECURITY_FLAG_IGNORE_UNKNOWN_CA
Definition: winhttp.h:281
#define CERT_TRUST_IS_NOT_TIME_VALID
Definition: wincrypt.h:870
#define ERROR_SUCCESS
Definition: deptool.c:10
#define ERROR_INTERNET_SEC_CERT_REV_FAILED
Definition: wininet.h:2044
#define WARN(fmt,...)
Definition: debug.h:111
const CERT_CHAIN_CONTEXT * cert_chain
Definition: internet.h:51
CERT_USAGE_MATCH RequestedUsage
Definition: wincrypt.h:1070
#define assert(x)
Definition: debug.h:53
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define szOID_PKIX_KP_SERVER_AUTH
Definition: wincrypt.h:3294
VOID WINAPI CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT pChainContext)
Definition: chain.c:2960
#define CERT_E_CN_NO_MATCH
Definition: winerror.h:3131
BOOL WINAPI CertVerifyCertificateChainPolicy(LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus)
Definition: chain.c:3716
#define SECURITY_FLAG_IGNORE_REVOCATION
Definition: wininet.h:829
#define CERT_CHAIN_POLICY_SSL
Definition: wincrypt.h:965
unsigned int BOOL
Definition: ntddk_ex.h:94
#define debugstr_w
Definition: kernel32.h:32
smooth NULL
Definition: ftsmooth.c:416
#define ERROR_INTERNET_SEC_CERT_ERRORS
Definition: wininet.h:2042
struct sock * chain
Definition: tcpcore.h:1164
static BYTE cert[]
Definition: msg.c:1437
DWORD security_flags
Definition: internet.h:82
CERT_TRUST_STATUS TrustStatus
Definition: wincrypt.h:939
#define _SECURITY_ERROR_FLAGS_MASK
Definition: internet.h:477
#define TRACE(s)
Definition: solgame.cpp:4
DWORD security_flags
Definition: internet.h:50
unsigned long DWORD
Definition: ntddk_ex.h:95
#define _SECURITY_FLAG_CERT_INVALID_CN
Definition: internet.h:474
#define CERT_TRUST_IS_NOT_SIGNATURE_VALID
Definition: wincrypt.h:873
int ret
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
WCHAR * name
Definition: internet.h:37
#define err(...)
#define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
Definition: winhttp.h:282
BOOL mask_errors
Definition: internet.h:83
#define ERROR_INTERNET_SEC_CERT_DATE_INVALID
Definition: wininet.h:2025
#define ERROR_INTERNET_INVALID_CA
Definition: wininet.h:2033
#define CERT_TRUST_IS_NOT_VALID_FOR_USAGE
Definition: wincrypt.h:874
#define ERROR_INTERNET_SEC_INVALID_CERT
Definition: wininet.h:2076
DWORD cUsageIdentifier
Definition: wincrypt.h:719
#define SECURITY_FLAG_IGNORE_WRONG_USAGE
Definition: wininet.h:831
#define _SECURITY_FLAG_CERT_INVALID_DATE
Definition: internet.h:475
#define CERT_TRUST_IS_UNTRUSTED_ROOT
Definition: wincrypt.h:875
LPSTR * rgpszUsageIdentifier
Definition: wincrypt.h:720
#define _SECURITY_FLAG_CERT_INVALID_CA
Definition: internet.h:473
#define AUTHTYPE_SERVER
Definition: wincrypt.h:1035
server_t * server
Definition: internet.h:75
#define CERT_TRUST_IS_PARTIAL_CHAIN
Definition: wincrypt.h:891
#define _SECURITY_FLAG_CERT_REV_FAILED
Definition: internet.h:472

Referenced by netcon_secure_connect_setup().

◆ read_ssl_chunk()

static BOOL read_ssl_chunk ( netconn_t conn,
void buf,
SIZE_T  buf_size,
BOOL  blocking,
SIZE_T ret_size,
BOOL eof 
)
static

Definition at line 697 of file netconnection.c.

698 {
699  const SIZE_T ssl_buf_size = conn->ssl_sizes.cbHeader+conn->ssl_sizes.cbMaximumMessage+conn->ssl_sizes.cbTrailer;
700  SecBuffer bufs[4];
701  SecBufferDesc buf_desc = {SECBUFFER_VERSION, sizeof(bufs)/sizeof(*bufs), bufs};
702  SSIZE_T size, buf_len = 0;
703  int i;
705 
706  assert(conn->extra_len < ssl_buf_size);
707 
708  if(conn->extra_len) {
709  memcpy(conn->ssl_buf, conn->extra_buf, conn->extra_len);
710  buf_len = conn->extra_len;
711  conn->extra_len = 0;
712  heap_free(conn->extra_buf);
713  conn->extra_buf = NULL;
714  }
715 
716  set_socket_blocking(conn, blocking && !buf_len);
717  size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0);
718  if(size < 0) {
719  if(!buf_len) {
721  TRACE("would block\n");
722  return WSAEWOULDBLOCK;
723  }
724  WARN("recv failed\n");
726  }
727  }else {
728  buf_len += size;
729  }
730 
731  if(!buf_len) {
732  TRACE("EOF\n");
733  *eof = TRUE;
734  *ret_size = 0;
735  return ERROR_SUCCESS;
736  }
737 
738  *eof = FALSE;
739 
740  do {
741  memset(bufs, 0, sizeof(bufs));
742  bufs[0].BufferType = SECBUFFER_DATA;
743  bufs[0].cbBuffer = buf_len;
744  bufs[0].pvBuffer = conn->ssl_buf;
745 
746  res = DecryptMessage(&conn->ssl_ctx, &buf_desc, 0, NULL);
747  switch(res) {
748  case SEC_E_OK:
749  break;
751  TRACE("context expired\n");
752  *eof = TRUE;
753  return ERROR_SUCCESS;
755  assert(buf_len < ssl_buf_size);
756 
757  set_socket_blocking(conn, blocking);
758  size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0);
759  if(size < 1) {
760  if(size < 0 && WSAGetLastError() == WSAEWOULDBLOCK) {
761  TRACE("would block\n");
762 
763  /* FIXME: Optimize extra_buf usage. */
764  conn->extra_buf = heap_alloc(buf_len);
765  if(!conn->extra_buf)
767 
768  conn->extra_len = buf_len;
769  memcpy(conn->extra_buf, conn->ssl_buf, conn->extra_len);
770  return WSAEWOULDBLOCK;
771  }
772 
774  }
775 
776  buf_len += size;
777  continue;
778  default:
779  WARN("failed: %08x\n", res);
781  }
782  } while(res != SEC_E_OK);
783 
784  for(i=0; i < sizeof(bufs)/sizeof(*bufs); i++) {
785  if(bufs[i].BufferType == SECBUFFER_DATA) {
786  size = min(buf_size, bufs[i].cbBuffer);
787  memcpy(buf, bufs[i].pvBuffer, size);
788  if(size < bufs[i].cbBuffer) {
789  assert(!conn->peek_len);
790  conn->peek_msg_mem = conn->peek_msg = heap_alloc(bufs[i].cbBuffer - size);
791  if(!conn->peek_msg)
793  conn->peek_len = bufs[i].cbBuffer-size;
794  memcpy(conn->peek_msg, (char*)bufs[i].pvBuffer+size, conn->peek_len);
795  }
796 
797  *ret_size = size;
798  }
799  }
800 
801  for(i=0; i < sizeof(bufs)/sizeof(*bufs); i++) {
802  if(bufs[i].BufferType == SECBUFFER_EXTRA) {
803  conn->extra_buf = heap_alloc(bufs[i].cbBuffer);
804  if(!conn->extra_buf)
806 
807  conn->extra_len = bufs[i].cbBuffer;
808  memcpy(conn->extra_buf, bufs[i].pvBuffer, conn->extra_len);
809  }
810  }
811 
812  return ERROR_SUCCESS;
813 }
size_t extra_len
#define ERROR_INTERNET_CONNECTION_ABORTED
Definition: wininet.h:2019
CtxtHandle ssl_ctx
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
const GLenum * bufs
Definition: glext.h:6026
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define SEC_I_CONTEXT_EXPIRED
Definition: winerror.h:2933
#define WARN(fmt,...)
Definition: debug.h:111
int sock_recv(int fd, void *msg, size_t len, int flags)
#define WSAEWOULDBLOCK
Definition: winerror.h:1948
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define SECBUFFER_DATA
Definition: sspi.h:146
#define assert(x)
Definition: debug.h:53
LONG_PTR SSIZE_T
Definition: basetsd.h:183
char * ssl_buf
size_t peek_len
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define SECBUFFER_EXTRA
Definition: sspi.h:150
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
char * extra_buf
smooth NULL
Definition: ftsmooth.c:416
LONG SECURITY_STATUS
Definition: sspi.h:34
#define TRACE(s)
Definition: solgame.cpp:4
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
GLsizeiptr size
Definition: glext.h:5919
char * peek_msg
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define SEC_E_OK
Definition: winerror.h:2356
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define SECBUFFER_VERSION
Definition: sspi.h:173
#define min(a, b)
Definition: monoChain.cc:55
SECURITY_STATUS WINAPI DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
Definition: wrapper.c:1036
static void set_socket_blocking(netconn_t *conn, BOOL is_blocking)
GLuint res
Definition: glext.h:9613
#define memset(x, y, z)
Definition: compat.h:39
SecPkgContext_StreamSizes ssl_sizes
#define SEC_E_INCOMPLETE_MESSAGE
Definition: winerror.h:2934
char * peek_msg_mem
static BOOL heap_free(void *mem)
Definition: appwiz.h:75

Referenced by NETCON_recv().

◆ send_ssl_chunk()

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

Definition at line 634 of file netconnection.c.

635 {
636  SecBuffer bufs[4] = {
638  {size, SECBUFFER_DATA, conn->ssl_buf+conn->ssl_sizes.cbHeader},
640  {0, SECBUFFER_EMPTY, NULL}
641  };
642  SecBufferDesc buf_desc = {SECBUFFER_VERSION, sizeof(bufs)/sizeof(*bufs), bufs};
644 
645  memcpy(bufs[1].pvBuffer, msg, size);
646  res = EncryptMessage(&conn->ssl_ctx, 0, &buf_desc, 0);
647  if(res != SEC_E_OK) {
648  WARN("EncryptMessage failed\n");
649  return FALSE;
650  }
651 
652  if(sock_send(conn->socket, conn->ssl_buf, bufs[0].cbBuffer+bufs[1].cbBuffer+bufs[2].cbBuffer, 0) < 1) {
653  WARN("send failed\n");
654  return FALSE;
655  }
656 
657  return TRUE;
658 }
CtxtHandle ssl_ctx
#define TRUE
Definition: types.h:120
#define SECBUFFER_STREAM_HEADER
Definition: sspi.h:152
const GLenum * bufs
Definition: glext.h:6026
#define WARN(fmt,...)
Definition: debug.h:111
#define SECBUFFER_DATA
Definition: sspi.h:146
char * ssl_buf
smooth NULL
Definition: ftsmooth.c:416
#define SECBUFFER_EMPTY
Definition: sspi.h:145
int sock_send(int fd, const void *msg, size_t len, int flags)
LONG SECURITY_STATUS
Definition: sspi.h:34
GLsizeiptr size
Definition: glext.h:5919
#define SECBUFFER_STREAM_TRAILER
Definition: sspi.h:151
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define SEC_E_OK
Definition: winerror.h:2356
#define SECBUFFER_VERSION
Definition: sspi.h:173
#define msg(x)
Definition: auth_time.c:54
GLuint res
Definition: glext.h:9613
SecPkgContext_StreamSizes ssl_sizes
SECURITY_STATUS WINAPI EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
Definition: wrapper.c:1006

Referenced by NETCON_send().

◆ set_socket_blocking()

static void set_socket_blocking ( netconn_t conn,
BOOL  is_blocking 
)
static

Definition at line 283 of file netconnection.c.

284 {
285  if(conn->is_blocking != is_blocking) {
286  ULONG arg = !is_blocking;
287  ioctlsocket(conn->socket, FIONBIO, &arg);
288  }
289  conn->is_blocking = is_blocking;
290 }
#define ioctlsocket
Definition: main.c:40
BOOL is_blocking
Definition: internet.h:72
#define FIONBIO
Definition: winsock.h:149
unsigned int ULONG
Definition: retypes.h:1

Referenced by create_netconn_socket(), NETCON_is_alive(), NETCON_recv(), netcon_secure_connect_setup(), NETCON_send(), and read_ssl_chunk().

◆ sock_recv()

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

Definition at line 425 of file netconnection.c.

426 {
427  int ret;
428  do
429  {
430  ret = recv(fd, msg, len, flags);
431  }
432  while(ret == -1 && WSAGetLastError() == WSAEINTR);
433  return ret;
434 }
static int fd
Definition: io.c:51
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
GLbitfield flags
Definition: glext.h:7161
int ret
GLenum GLsizei len
Definition: glext.h:6722
#define msg(x)
Definition: auth_time.c:54
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
#define WSAEINTR
Definition: winerror.h:1942

Referenced by NETCON_is_alive(), NETCON_recv(), netcon_secure_connect_setup(), and read_ssl_chunk().

◆ sock_send()

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

Definition at line 414 of file netconnection.c.

415 {
416  int ret;
417  do
418  {
419  ret = send(fd, msg, len, flags);
420  }
421  while(ret == -1 && WSAGetLastError() == WSAEINTR);
422  return ret;
423 }
static int fd
Definition: io.c:51
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
GLbitfield flags
Definition: glext.h:7161
int ret
GLenum GLsizei len
Definition: glext.h:6722
#define msg(x)
Definition: auth_time.c:54
#define WSAEINTR
Definition: winerror.h:1942

Referenced by netcon_secure_connect_setup(), NETCON_send(), and send_ssl_chunk().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( wininet  )

◆ winsock_startup()

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

Definition at line 264 of file netconnection.c.

265 {
266  WSADATA wsa_data;
267  DWORD res;
268 
269  res = WSAStartup(MAKEWORD(2,2), &wsa_data);
270  if(res == ERROR_SUCCESS)
272  else
273  ERR("WSAStartup failed: %u\n", res);
274  return TRUE;
275 }
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
#define MAKEWORD(a, b)
Definition: typedefs.h:247
static BOOL winsock_loaded
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ERR(fmt,...)
Definition: debug.h:109
GLuint res
Definition: glext.h:9613

Referenced by init_winsock().

Variable Documentation

◆ compat_cred_handle

SecHandle compat_cred_handle
static

◆ cred_handle

◆ cred_handle_initialized

BOOL cred_handle_initialized
static

Definition at line 216 of file netconnection.c.

Referenced by ensure_cred_handle(), NETCON_unload(), and tcp_disconnect().

◆ have_compat_cred_handle

BOOL have_compat_cred_handle
static

◆ init_sechandle_cs

static CRITICAL_SECTION init_sechandle_cs = { &init_sechandle_cs_debug, -1, 0, 0, 0, 0 }
static

Definition at line 218 of file netconnection.c.

Referenced by ensure_cred_handle(), and NETCON_unload().

◆ init_sechandle_cs_debug

CRITICAL_SECTION_DEBUG init_sechandle_cs_debug
static
Initial value:
= {
0, 0, { (DWORD_PTR)(__FILE__ ": init_sechandle_cs") }
}
#define DWORD_PTR
Definition: treelist.c:76
static CRITICAL_SECTION init_sechandle_cs
static CRITICAL_SECTION_DEBUG init_sechandle_cs_debug
LIST_ENTRY ProcessLocksList
Definition: winbase.h:848

Definition at line 219 of file netconnection.c.

◆ winsock_loaded

BOOL winsock_loaded = FALSE
static

Definition at line 262 of file netconnection.c.

Referenced by NETCON_unload(), and winsock_startup().