1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-12-25 01:29:53 +03:00

remove msvc compiling errors (#499)

This commit is contained in:
Moataz Elmasry 2018-04-20 01:19:32 +02:00
parent 2ab85711fa
commit 0dee90f181
3 changed files with 374 additions and 244 deletions

View File

@ -1,17 +1,17 @@
// SoftEther VPN Source Code
// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
//
// SoftEther VPN Server, Client and Bridge are free software under GPLv2.
//
// Copyright (c) 2012-2016 Daiyuu Nobori.
// Copyright (c) 2012-2016 SoftEther VPN Project, University of Tsukuba, Japan.
// Copyright (c) 2012-2016 SoftEther Corporation.
// Copyright (c) Daiyuu Nobori.
// Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
// Copyright (c) SoftEther Corporation.
//
// All Rights Reserved.
//
// http://www.softether.org/
//
// Author: Daiyuu Nobori
// Author: Daiyuu Nobori, Ph.D.
// Comments: Tetsuo Sugiyama, Ph.D.
//
// This program is free software; you can redistribute it and/or
@ -690,8 +690,11 @@ void UpdateClientThreadMain(UPDATE_CLIENT *c)
cert_hash = StrToBin(UPDATE_SERVER_CERT_HASH);
recv = HttpRequestEx2(&data, NULL, UPDATE_CONNECT_TIMEOUT, UPDATE_COMM_TIMEOUT, &ret, false, NULL, NULL,
NULL, ((cert_hash != NULL && cert_hash->Size == SHA1_SIZE) ? cert_hash->Buf : NULL),
StrCpy(data.SniString, sizeof(data.SniString), DDNS_SNI_VER_STRING);
recv = HttpRequestEx3(&data, NULL, UPDATE_CONNECT_TIMEOUT, UPDATE_COMM_TIMEOUT, &ret, false, NULL, NULL,
NULL, ((cert_hash != NULL && (cert_hash->Size % SHA1_SIZE) == 0) ? cert_hash->Buf : NULL),
(cert_hash != NULL ? (cert_hash->Size / SHA1_SIZE) : 0),
(bool *)&c->HaltFlag, 0, NULL, NULL);
FreeBuf(cert_hash);
@ -1312,7 +1315,6 @@ bool ServerAccept(CONNECTION *c)
FARM_MEMBER *f = NULL;
SERVER *server = NULL;
POLICY ticketed_policy;
UINT64 timestamp;
UCHAR unique[SHA1_SIZE], unique2[SHA1_SIZE];
CEDAR *cedar;
RPC_WINVER winver;
@ -1450,31 +1452,6 @@ bool ServerAccept(CONNECTION *c)
}
}
// Time inspection
timestamp = PackGetInt64(p, "timestamp");
if (timestamp != 0)
{
UINT64 now = SystemTime64();
UINT64 abs;
if (now >= timestamp)
{
abs = now - timestamp;
}
else
{
abs = timestamp - now;
}
if (abs > ALLOW_TIMESTAMP_DIFF)
{
// Time difference is too large
FreePack(p);
c->Err = ERR_BAD_CLOCK;
error_detail = "ERR_BAD_CLOCK";
goto CLEANUP;
}
}
// Get the client version
PackGetStr(p, "client_str", c->ClientStr, sizeof(c->ClientStr));
c->ClientVer = PackGetInt(p, "client_ver");
@ -1655,6 +1632,10 @@ bool ServerAccept(CONNECTION *c)
{
radius_login_opt.In_CheckVLanId = hub->Option->AssignVLanIdByRadiusAttribute;
radius_login_opt.In_DenyNoVlanId = hub->Option->DenyAllRadiusLoginWithNoVlanAssign;
if (hub->Option->UseHubNameAsRadiusNasId)
{
StrCpy(radius_login_opt.NasId, sizeof(radius_login_opt.NasId), hubname);
}
}
// Get the various flags
@ -1814,6 +1795,9 @@ bool ServerAccept(CONNECTION *c)
case AUTHTYPE_TICKET:
authtype_str = _UU("LH_AUTH_TICKET");
break;
case AUTHTYPE_OPENVPN_CERT:
authtype_str = _UU("LH_AUTH_OPENVPN_CERT");
break;
}
IPToStr(ip1, sizeof(ip1), &c->FirstSock->RemoteIP);
IPToStr(ip2, sizeof(ip2), &c->FirstSock->LocalIP);
@ -2147,6 +2131,50 @@ bool ServerAccept(CONNECTION *c)
}
break;
case AUTHTYPE_OPENVPN_CERT:
// For OpenVPN; mostly same as CLIENT_AUTHTYPE_CERT, but without
// signature verification, because it was already performed during TLS handshake.
if (c->IsInProc)
{
// Certificate authentication
cert_size = PackGetDataSize(p, "cert");
if (cert_size >= 1 && cert_size <= 100000)
{
cert_buf = ZeroMalloc(cert_size);
if (PackGetData(p, "cert", cert_buf))
{
BUF *b = NewBuf();
X *x;
WriteBuf(b, cert_buf, cert_size);
x = BufToX(b, false);
if (x != NULL && x->is_compatible_bit)
{
Debug("Got to SamAuthUserByCert %s\n", username); // XXX
// Check whether the certificate is valid.
auth_ret = SamAuthUserByCert(hub, username, x);
if (auth_ret)
{
// Copy the certificate
c->ClientX = CloneX(x);
}
}
FreeX(x);
FreeBuf(b);
}
Free(cert_buf);
}
}
else
{
// OpenVPN certificate authentication cannot be used directly by external clients
Unlock(hub->lock);
ReleaseHub(hub);
FreePack(p);
c->Err = ERR_AUTHTYPE_NOT_SUPPORTED;
goto CLEANUP;
}
break;
default:
// Unknown authentication method
Unlock(hub->lock);
@ -4574,7 +4602,7 @@ bool ClientSecureSign(CONNECTION *c, UCHAR *sign, UCHAR *random, X **x)
if (ret)
{
Copy(sign, ss->Signature, 128);
Copy(sign, ss->Signature, sizeof(ss->Signature));
*x = ss->ClientCert;
}
@ -5206,7 +5234,7 @@ REDIRECTED:
sess->EnableBulkOnRUDP = false;
sess->EnableHMacOnBulkOfRUDP = false;
if (s != NULL && s->IsRUDPSocket && s->BulkRecvKey != NULL && s->BulkSendKey != NULL)
if (s->IsRUDPSocket && s->BulkRecvKey != NULL && s->BulkSendKey != NULL)
{
// Bulk transfer on R-UDP
if (PackGetBool(p, "enable_bulk_on_rudp"))
@ -5853,7 +5881,7 @@ bool ClientUploadAuth(CONNECTION *c)
// Authentication by secure device
if (ClientSecureSign(c, sign, c->Random, &x))
{
p = PackLoginWithCert(o->HubName, a->Username, x, sign, 128);
p = PackLoginWithCert(o->HubName, a->Username, x, sign, x->bits / 8);
c->ClientX = CloneX(x);
FreeX(x);
}
@ -5876,9 +5904,6 @@ bool ClientUploadAuth(CONNECTION *c)
PackAddData(p, "ticket", c->Ticket, SHA1_SIZE);
}
// Current time
PackAddInt64(p, "timestamp", SystemTime64());
if (p == NULL)
{
// Error
@ -6674,7 +6699,10 @@ SOCK *SocksConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
if (c == NULL || proxy_host_name == NULL || proxy_port == 0 || server_host_name == NULL
|| server_port == 0)
{
c->Err = ERR_PROXY_CONNECT_FAILED;
if (c != NULL)
{
c->Err = ERR_PROXY_CONNECT_FAILED;
}
return NULL;
}
@ -6868,7 +6896,10 @@ SOCK *ProxyConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
if (c == NULL || proxy_host_name == NULL || proxy_port == 0 || server_host_name == NULL ||
server_port == 0)
{
c->Err = ERR_PROXY_CONNECT_FAILED;
if( c != NULL)
{
c->Err = ERR_PROXY_CONNECT_FAILED;
}
return NULL;
}
if (username != NULL && password != NULL &&
@ -7263,6 +7294,46 @@ PACK *PackLoginWithPlainPassword(char *hubname, char *username, void *plain_pass
return p;
}
// Generate a packet of OpenVPN certificate login
PACK *PackLoginWithOpenVPNCertificate(char *hubname, char *username, X *x)
{
PACK *p;
char cn_username[128];
BUF *cert_buf = NULL;
// Validate arguments
if (hubname == NULL || username == NULL || x == NULL)
{
return NULL;
}
p = NewPack();
PackAddStr(p, "method", "login");
PackAddStr(p, "hubname", hubname);
if (IsEmptyStr(username))
{
if (x->subject_name == NULL)
{
return NULL;
}
wcstombs(cn_username, x->subject_name->CommonName, 127);
cn_username[127] = '\0';
PackAddStr(p, "username", cn_username);
}
else
{
PackAddStr(p, "username", username);
}
PackAddInt(p, "authtype", AUTHTYPE_OPENVPN_CERT);
cert_buf = XToBuf(x, false);
PackAddBuf(p, "cert", cert_buf);
FreeBuf(cert_buf);
return p;
}
// Create a packet of password authentication login
PACK *PackLoginWithPassword(char *hubname, char *username, void *secure_password)
{
@ -7333,7 +7404,3 @@ void GenerateRC4KeyPair(RC4_KEY_PAIR *k)
Rand(k->ServerToClientKey, sizeof(k->ServerToClientKey));
}
// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
// Department of Computer Science has dozens of overly-enthusiastic geeks.
// Join us: http://www.tsukuba.ac.jp/english/admission/

View File

@ -1,17 +1,17 @@
// SoftEther VPN Source Code
// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
//
// SoftEther VPN Server, Client and Bridge are free software under GPLv2.
//
// Copyright (c) 2012-2016 Daiyuu Nobori.
// Copyright (c) 2012-2016 SoftEther VPN Project, University of Tsukuba, Japan.
// Copyright (c) 2012-2016 SoftEther Corporation.
// Copyright (c) Daiyuu Nobori.
// Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
// Copyright (c) SoftEther Corporation.
//
// All Rights Reserved.
//
// http://www.softether.org/
//
// Author: Daiyuu Nobori
// Author: Daiyuu Nobori, Ph.D.
// Comments: Tetsuo Sugiyama, Ph.D.
//
// This program is free software; you can redistribute it and/or
@ -872,17 +872,19 @@ UINT SmDDnsDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
// Get the ddns key from the server configuration file
static UINT SmDdnsGetKey(char *key, SM_DDNS *d){
RPC *rpc = d->s->Rpc;
RPC_CONFIG config;
UINT err;
BUF *buf;
FOLDER *root, *ddnsfolder;
RPC *rpc;
// Validate arguments
if(d == NULL || d->s == NULL || key == NULL){
return ERR_INTERNAL_ERROR;
}
rpc = d->s->Rpc;
Zero(&config, sizeof(config));
err = ScGetConfig(d->s->Rpc, &config);
if(err != ERR_NO_ERROR){
@ -17011,6 +17013,7 @@ void SmSslDlgInit(HWND hWnd, SM_SSL *s)
// Set the encryption algorithm list
cipher_list = GetCipherList();
SetFont(hWnd, C_CIPHER, GetFont("Tahoma", 8, false, false, false, false));
CbSetHeight(hWnd, C_CIPHER, 18);
for (i = 0;i < cipher_list->NumTokens;i++)
{
@ -18362,6 +18365,7 @@ void SmServerDlgInit(HWND hWnd, SM_SERVER *p)
void SmServerDlgRefresh(HWND hWnd, SM_SERVER *p)
{
RPC_ENUM_HUB t;
RPC_LISTENER_LIST t2;
DDNS_CLIENT_STATUS st;
RPC_AZURE_STATUS sta;
UINT i;
@ -18449,38 +18453,34 @@ void SmServerDlgRefresh(HWND hWnd, SM_SERVER *p)
}
// Listener list update
if (p != NULL)
Zero(&t2, sizeof(RPC_LISTENER_LIST));
if (CALL(hWnd, ScEnumListener(p->Rpc, &t2)))
{
RPC_LISTENER_LIST t;
Zero(&t, sizeof(RPC_LISTENER_LIST));
if (CALL(hWnd, ScEnumListener(p->Rpc, &t)))
LVB *b = LvInsertStart();
for (i = 0;i < t2.NumPort;i++)
{
LVB *b = LvInsertStart();
for (i = 0;i < t.NumPort;i++)
wchar_t tmp[MAX_SIZE];
wchar_t *status;
UINT icon;
UniFormat(tmp, sizeof(tmp), _UU("CM_LISTENER_TCP_PORT"), t2.Ports[i]);
status = _UU("CM_LISTENER_ONLINE");
icon = ICO_PROTOCOL;
if (t2.Errors[i])
{
wchar_t tmp[MAX_SIZE];
wchar_t *status;
UINT icon;
UniFormat(tmp, sizeof(tmp), _UU("CM_LISTENER_TCP_PORT"), t.Ports[i]);
status = _UU("CM_LISTENER_ONLINE");
icon = ICO_PROTOCOL;
if (t.Errors[i])
{
status = _UU("CM_LISTENER_ERROR");
icon = ICO_PROTOCOL_X;
}
else if (t.Enables[i] == false)
{
status = _UU("CM_LISTENER_OFFLINE");
icon = ICO_PROTOCOL_OFFLINE;
}
LvInsertAdd(b, icon, (void *)t.Ports[i], 2, tmp, status);
status = _UU("CM_LISTENER_ERROR");
icon = ICO_PROTOCOL_X;
}
LvInsertEnd(b, hWnd, L_LISTENER);
FreeRpcListenerList(&t);
else if (t2.Enables[i] == false)
{
status = _UU("CM_LISTENER_OFFLINE");
icon = ICO_PROTOCOL_OFFLINE;
}
LvInsertAdd(b, icon, (void *)t2.Ports[i], 2, tmp, status);
}
LvInsertEnd(b, hWnd, L_LISTENER);
FreeRpcListenerList(&t2);
}
// Get the DDNS client state
@ -20695,7 +20695,3 @@ void SMExec()
#endif // WIN32
// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
// Department of Computer Science has dozens of overly-enthusiastic geeks.
// Join us: http://www.tsukuba.ac.jp/english/admission/

View File

@ -1,17 +1,17 @@
// SoftEther VPN Source Code
// SoftEther VPN Source Code - Developer Edition Master Branch
// Mayaqua Kernel
//
// SoftEther VPN Server, Client and Bridge are free software under GPLv2.
//
// Copyright (c) 2012-2016 Daiyuu Nobori.
// Copyright (c) 2012-2016 SoftEther VPN Project, University of Tsukuba, Japan.
// Copyright (c) 2012-2016 SoftEther Corporation.
// Copyright (c) Daiyuu Nobori.
// Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
// Copyright (c) SoftEther Corporation.
//
// All Rights Reserved.
//
// http://www.softether.org/
//
// Author: Daiyuu Nobori
// Author: Daiyuu Nobori, Ph.D.
// Contributors:
// - nattoheaven (https://github.com/nattoheaven)
// Comments: Tetsuo Sugiyama, Ph.D.
@ -233,7 +233,12 @@ static COUNTER *getip_thread_counter = NULL;
static UINT max_getip_thread = 0;
static char *cipher_list = "RC4-MD5 RC4-SHA AES128-SHA AES256-SHA DES-CBC-SHA DES-CBC3-SHA DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA";
static char *cipher_list = "RC4-MD5 RC4-SHA AES128-SHA AES256-SHA DES-CBC-SHA DES-CBC3-SHA DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA AES128-GCM-SHA256 AES128-SHA256 AES256-GCM-SHA384 AES256-SHA256 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384"
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
" DHE-RSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305";
#endif
;
static LIST *ip_clients = NULL;
static LIST *local_mac_list = NULL;
@ -245,7 +250,7 @@ static UINT rand_port_numbers[256] = {0};
static bool g_use_privateip_file = false;
static bool g_source_ip_validation_force_disable = false;
static DH_CTX *dh_1024 = NULL;
static DH_CTX *dh_param = NULL;
typedef struct PRIVATE_IP_SUBNET
{
@ -1722,7 +1727,7 @@ void RUDPDo_NatT_Interrupt(RUDP_STACK *r)
PackAddInt64(p, "tran_id", r->NatT_TranId);
PackAddStr(p, "token", r->NatT_Token);
PackAddStr(p, "svc_name", r->SvcName);
PackAddStr(p, "product_str", CEDAR_PRODUCT_STR);
PackAddStr(p, "product_str", "SoftEther OSS");
PackAddInt64(p, "session_key", r->NatT_SessionKey);
PackAddInt(p, "nat_traversal_version", UDP_NAT_TRAVERSAL_VERSION);
@ -2654,7 +2659,7 @@ void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
CRYPT *c;
UCHAR crypt_key_src[SHA1_SIZE * 2];
UCHAR crypt_key[SHA1_SIZE];
UINT icmp_type;
UINT icmp_type = 0;
UCHAR sign[SHA1_SIZE];
UCHAR iv[SHA1_SIZE + 1];
// Validate arguments
@ -2724,16 +2729,16 @@ void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
// Start a socket for R-UDP Listening
SOCK *ListenRUDP(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode)
{
return ListenRUDPEx(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, NULL, 0);
return ListenRUDPEx(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, NULL, 0, NULL);
}
SOCK *ListenRUDPEx(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode,
volatile UINT *natt_global_udp_port, UCHAR rand_port_id)
volatile UINT *natt_global_udp_port, UCHAR rand_port_id, IP *listen_ip)
{
SOCK *s;
RUDP_STACK *r;
// Creating a R-UDP stack
r = NewRUDPServer(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, natt_global_udp_port, rand_port_id);
r = NewRUDPServer(svc_name, proc_interrupts, proc_rpc_recv, param, port, no_natt_register, over_dns_mode, natt_global_udp_port, rand_port_id, listen_ip);
if (r == NULL)
{
return NULL;
@ -5259,7 +5264,7 @@ SOCK *NewRUDPClientDirect(char *svc_name, IP *ip, UINT port, UINT *error_code, U
return NULL;
}
r = NewRUDP(false, svc_name, NULL, NULL, NULL, local_port, sock, sock_event, false, over_dns_mode, ip, NULL, 0);
r = NewRUDP(false, svc_name, NULL, NULL, NULL, local_port, sock, sock_event, false, over_dns_mode, ip, NULL, 0, NULL);
if (r == NULL)
{
*error_code = RUDP_ERROR_UNKNOWN;
@ -5318,7 +5323,7 @@ SOCK *NewRUDPClientDirect(char *svc_name, IP *ip, UINT port, UINT *error_code, U
}
// Creating a R-UDP server
RUDP_STACK *NewRUDPServer(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode, volatile UINT *natt_global_udp_port, UCHAR rand_port_id)
RUDP_STACK *NewRUDPServer(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, bool no_natt_register, bool over_dns_mode, volatile UINT *natt_global_udp_port, UCHAR rand_port_id, IP *listen_ip)
{
RUDP_STACK *r;
// Validate arguments
@ -5334,7 +5339,7 @@ RUDP_STACK *NewRUDPServer(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_inter
ListenTcpForPopupFirewallDialog();
r = NewRUDP(true, svc_name, proc_interrupts, proc_rpc_recv, param, port, NULL, NULL, no_natt_register, over_dns_mode, NULL, natt_global_udp_port, rand_port_id);
r = NewRUDP(true, svc_name, proc_interrupts, proc_rpc_recv, param, port, NULL, NULL, no_natt_register, over_dns_mode, NULL, natt_global_udp_port, rand_port_id, listen_ip);
if (r == NULL)
{
@ -5345,7 +5350,7 @@ RUDP_STACK *NewRUDPServer(char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_inter
}
// Creating a R-UDP
RUDP_STACK *NewRUDP(bool server_mode, char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, SOCK *sock, SOCK_EVENT *sock_event, bool server_no_natt_register, bool over_dns_mode, IP *client_target_ip, volatile UINT *natt_global_udp_port, UCHAR rand_port_id)
RUDP_STACK *NewRUDP(bool server_mode, char *svc_name, RUDP_STACK_INTERRUPTS_PROC *proc_interrupts, RUDP_STACK_RPC_RECV_PROC *proc_rpc_recv, void *param, UINT port, SOCK *sock, SOCK_EVENT *sock_event, bool server_no_natt_register, bool over_dns_mode, IP *client_target_ip, volatile UINT *natt_global_udp_port, UCHAR rand_port_id, IP *listen_ip)
{
RUDP_STACK *r;
char tmp[MAX_SIZE];
@ -5371,11 +5376,11 @@ RUDP_STACK *NewRUDP(bool server_mode, char *svc_name, RUDP_STACK_INTERRUPTS_PROC
{
if (rand_port_id == 0)
{
sock = NewUDP(port);
sock = NewUDPEx2(port, false, listen_ip);
}
else
{
sock = NewUDPEx2RandMachineAndExePath(false, NULL, 0, rand_port_id);
sock = NewUDPEx2RandMachineAndExePath(false, listen_ip, 0, rand_port_id);
}
}
@ -5804,14 +5809,58 @@ SOCK *ListenAnyPortEx2(bool local_only, bool disable_ca)
return NULL;
}
int cb_test(int a, X509_STORE_CTX *ctx)
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define X509_STORE_CTX_get0_cert(o) ((o)->cert)
#endif
// Verify client SSL certificate during TLS handshake.
//
// (actually, only save the certificate for later authentication in Protocol.c)
int SslCertVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx)
{
WHERE;
return 1;
SSL *ssl;
struct SslClientCertInfo *clientcert;
X509 *cert;
ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
clientcert = SSL_get_ex_data(ssl, GetSslClientCertIndex());
if (clientcert != NULL)
{
clientcert->PreverifyErr = X509_STORE_CTX_get_error(ctx);
clientcert->PreverifyErrMessage[0] = '\0';
if (!preverify_ok)
{
const char *msg = X509_verify_cert_error_string(clientcert->PreverifyErr);
StrCpy(clientcert->PreverifyErrMessage, PREVERIFY_ERR_MESSAGE_SIZE, msg);
Debug("SslCertVerifyCallback preverify error: '%s'\n", msg);
}
else
{
cert = X509_STORE_CTX_get0_cert(ctx);
if (cert != NULL)
{
X *tmpX = X509ToX(cert); // this only wraps cert, but we need to make a copy
X *copyX = CloneX(tmpX);
tmpX->do_not_free = true; // do not release inner X509 object
FreeX(tmpX);
clientcert->X = copyX;
}
}
}
return 1; /* allow the verification process to continue */
}
// Create a new SSL pipe
SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh)
{
return NewSslPipeEx(server_mode, x, k, dh, false, NULL);
}
// Create a new SSL pipe with extended options
SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert)
{
SSL_PIPE *s;
SSL *ssl;
@ -5821,7 +5870,8 @@ SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh)
{
if (server_mode)
{
SSL_CTX_set_ssl_version(ssl_ctx, TLSv1_server_method());
SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method());
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2);
AddChainSslCertOnDirectory(ssl_ctx);
@ -5832,10 +5882,13 @@ SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh)
}
else
{
SSL_CTX_set_ssl_version(ssl_ctx, TLSv1_client_method());
SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_client_method());
}
//SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, cb_test);
if (verify_peer)
{
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, SslCertVerifyCallback);
}
if (dh != NULL)
{
@ -5848,6 +5901,8 @@ SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh)
}
ssl = SSL_new(ssl_ctx);
SSL_set_ex_data(ssl, GetSslClientCertIndex(), clientcert);
}
Unlock(openssl_lock);
@ -6484,38 +6539,6 @@ L_LOOP:
#endif // OS_WIN32
// Get whether the aquirement of the Process ID of the TCP connection succeed
bool CanGetTcpProcessId()
{
UINT i;
bool ret = false;
LIST *o = GetTcpTableList();
if (o == NULL)
{
return false;
}
for (i = 0;i < LIST_NUM(o);i++)
{
TCPTABLE *t = LIST_DATA(o, i);
if (t->ProcessId != 0)
{
ret = true;
break;
}
}
FreeTcpTableList(o);
return ret;
}
#define USE_OLD_GETIP
// Set the arp_filter in Linux
@ -7367,7 +7390,7 @@ bool StrToIP6(IP *ip, char *str)
if (StartWith(tmp, "[") && EndWith(tmp, "]"))
{
// If the string is enclosed in square brackets, remove brackets
StrCpy(tmp, sizeof(tmp), &tmp[1]);
StrCpyAllowOverlap(tmp, sizeof(tmp), &tmp[1]);
if (StrLen(tmp) >= 1)
{
@ -9157,12 +9180,23 @@ void UnixSetSockEvent(SOCK_EVENT *event)
}
}
// This is a helper function for select()
int safe_fd_set(int fd, fd_set* fds, int* max_fd) {
FD_SET(fd, fds);
if (fd > *max_fd) {
*max_fd = fd;
}
return 0;
}
// Execute 'select' for the socket
void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, UINT timeout)
{
#ifdef UNIX_MACOS
int kq;
struct kevent *kevents;
fd_set rfds; //read descriptors
fd_set wfds; //write descriptors
int max_fd = 0; //maximum descriptor id
struct timeval tv; //timeval for timeout
#else // UNIX_MACOS
struct pollfd *p;
#endif // UNIX_MACOS
@ -9203,8 +9237,8 @@ void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, U
num = num_read_total + num_write_total;
#ifdef UNIX_MACOS
kq = kqueue();
kevents = ZeroMallocFast(sizeof(struct kevent) * (num + num_write_total));
FD_ZERO(&rfds); //zero out descriptor set for read descriptors
FD_ZERO(&wfds); //same for write
#else // UNIX_MACOS
p = ZeroMallocFast(sizeof(struct pollfd) * num);
#endif // UNIX_MACOS
@ -9216,7 +9250,7 @@ void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, U
if (reads[i] != INVALID_SOCKET)
{
#ifdef UNIX_MACOS
EV_SET(&kevents[n++], reads[i], EVFILT_READ, EV_ADD, 0, 0, NULL);
safe_fd_set(reads[i], &rfds, &max_fd);
#else // UNIX_MACOS
struct pollfd *pfd = &p[n++];
pfd->fd = reads[i];
@ -9230,8 +9264,7 @@ void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, U
if (writes[i] != INVALID_SOCKET)
{
#ifdef UNIX_MACOS
EV_SET(&kevents[n++], reads[i], EVFILT_READ, EV_ADD, 0, 0, NULL);
EV_SET(&kevents[n++], reads[i], EVFILT_WRITE, EV_ADD, 0, 0, NULL);
safe_fd_set(writes[i], &wfds, &max_fd);
#else // UNIX_MACOS
struct pollfd *pfd = &p[n++];
pfd->fd = writes[i];
@ -9243,15 +9276,9 @@ void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, U
if (num != 0)
{
#ifdef UNIX_MACOS
struct timespec kevent_timeout, *p_kevent_timeout;
if (timeout == INFINITE) {
p_kevent_timeout = NULL;
} else {
kevent_timeout.tv_sec = timeout / 1000;
kevent_timeout.tv_nsec = (timeout % 1000) * 1000000l;
p_kevent_timeout = &kevent_timeout;
}
kevent(kq, kevents, n, kevents, n, p_kevent_timeout);
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000l;
select(max_fd + 1, &rfds, &wfds, NULL, timeout == INFINITE ? NULL : &tv);
#else // UNIX_MACOS
poll(p, num, timeout == INFINITE ? -1 : (int)timeout);
#endif // UNIX_MACOS
@ -9261,12 +9288,9 @@ void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, U
SleepThread(timeout);
}
#ifdef UNIX_MACOS
Free(kevents);
close(kq);
#else // UNIX_MACOS
#ifndef UNIX_MACOS
Free(p);
#endif // UNIX_MACOS
#endif // not UNIX_MACOS
}
// Clean-up of the socket event
@ -9422,11 +9446,13 @@ void UnixInitAsyncSocket(SOCK *sock)
UnixSetSocketNonBlockingMode(sock->socket, true);
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
if (sock->ssl != NULL && sock->ssl->s3 != NULL)
{
sock->Ssl_Init_Async_SendAlert[0] = sock->ssl->s3->send_alert[0];
sock->Ssl_Init_Async_SendAlert[1] = sock->ssl->s3->send_alert[1];
}
#endif
}
// Initializing the socket library
@ -11127,27 +11153,6 @@ void FreeWaitThread()
WaitThreadList = NULL;
}
// Check the cipher list name
bool CheckCipherListName(char *name)
{
UINT i;
// Validate arguments
if (name == NULL)
{
return false;
}
for (i = 0;i < cipher_list_token->NumTokens;i++)
{
if (StrCmpi(cipher_list_token->Token[i], name) == 0)
{
return true;
}
}
return false;
}
// Renewing the IP address of the DHCP server
void RenewDhcp()
{
@ -12682,6 +12687,14 @@ bool RecvAll(SOCK *sock, void *data, UINT size, bool secure)
{
return false;
}
if (ret == SOCK_LATER)
{
// I suppose that this is safe because the RecvAll() function is used only
// if the sock->AsyncMode == true. And the Recv() function may return
// SOCK_LATER only if the sock->AsyncMode == false. Therefore the call of
// Recv() function in the RecvAll() function never returns SOCK_LATER.
return false;
}
recv_size += ret;
if (recv_size >= size)
{
@ -12764,7 +12777,6 @@ bool SendAll(SOCK *sock, void *data, UINT size, bool secure)
// Set the cipher algorithm name to want to use
void SetWantToUseCipher(SOCK *sock, char *name)
{
char tmp[254];
// Validate arguments
if (sock == NULL || name == NULL)
{
@ -12776,12 +12788,7 @@ void SetWantToUseCipher(SOCK *sock, char *name)
Free(sock->WaitToUseCipher);
}
Zero(tmp, sizeof(tmp));
StrCpy(tmp, sizeof(tmp), name);
StrCat(tmp, sizeof(tmp), " ");
StrCat(tmp, sizeof(tmp), cipher_list);
sock->WaitToUseCipher = CopyStr(tmp);
sock->WaitToUseCipher = CopyStr(name);
}
// Add all the chain certificates in the chain_certs directory
@ -12904,7 +12911,7 @@ bool AddChainSslCert(struct ssl_ctx_st *ctx, X *x)
// Start a TCP-SSL communication
bool StartSSL(SOCK *sock, X *x, K *priv)
{
return StartSSLEx(sock, x, priv, false, 0, NULL);
return StartSSLEx(sock, x, priv, true, 0, NULL);
}
bool StartSSLEx(SOCK *sock, X *x, K *priv, bool client_tls, UINT ssl_timeout, char *sni_hostname)
{
@ -12966,13 +12973,38 @@ bool StartSSLEx(SOCK *sock, X *x, K *priv, bool client_tls, UINT ssl_timeout, ch
{
if (sock->ServerMode)
{
if (sock->AcceptOnlyTls == false)
SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method());
#ifdef SSL_OP_NO_SSLv2
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2);
#endif // SSL_OP_NO_SSLv2
if (sock->SslAcceptSettings.AcceptOnlyTls)
{
SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method());
#ifdef SSL_OP_NO_SSLv3
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv3);
#endif // SSL_OP_NO_SSLv3
}
else
if (sock->SslAcceptSettings.Tls_Disable1_0)
{
SSL_CTX_set_ssl_version(ssl_ctx, TLSv1_method());
#ifdef SSL_OP_NO_TLSv1
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1);
#endif // SSL_OP_NO_TLSv1
}
if (sock->SslAcceptSettings.Tls_Disable1_1)
{
#ifdef SSL_OP_NO_TLSv1_1
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_1);
#endif // SSL_OP_NO_TLSv1_1
}
if (sock->SslAcceptSettings.Tls_Disable1_2)
{
#ifdef SSL_OP_NO_TLSv1_2
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_2);
#endif // SSL_OP_NO_TLSv1_2
}
Unlock(openssl_lock);
@ -12983,11 +13015,15 @@ bool StartSSLEx(SOCK *sock, X *x, K *priv, bool client_tls, UINT ssl_timeout, ch
{
if (client_tls == false)
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
SSL_CTX_set_ssl_version(ssl_ctx, SSLv3_method());
#else
SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method());
#endif
}
else
{
SSL_CTX_set_ssl_version(ssl_ctx, TLSv1_client_method());
SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_client_method());
}
}
sock->ssl = SSL_new(ssl_ctx);
@ -13003,6 +13039,7 @@ bool StartSSLEx(SOCK *sock, X *x, K *priv, bool client_tls, UINT ssl_timeout, ch
}
}
#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
}
Unlock(openssl_lock);
@ -13029,7 +13066,8 @@ bool StartSSLEx(SOCK *sock, X *x, K *priv, bool client_tls, UINT ssl_timeout, ch
// Set the cipher algorithm name to want to use
Lock(openssl_lock);
{
SSL_set_cipher_list(sock->ssl, sock->WaitToUseCipher);
if (SSL_set_cipher_list(sock->ssl, sock->WaitToUseCipher) == 0)
SSL_set_cipher_list(sock->ssl, DEFAULT_CIPHER_LIST);
}
Unlock(openssl_lock);
}
@ -13188,6 +13226,8 @@ bool StartSSLEx(SOCK *sock, X *x, K *priv, bool client_tls, UINT ssl_timeout, ch
return true;
}
#ifdef ENABLE_SSL_LOGGING
// Enable SSL logging
@ -13306,7 +13346,7 @@ void SetNoNeedToRead(SOCK *sock)
UINT SecureRecv(SOCK *sock, void *data, UINT size)
{
SOCKET s;
int ret, e = 0;
int ret, e = SSL_ERROR_NONE;
SSL *ssl;
#ifdef UNIX_SOLARIS
@ -13346,10 +13386,14 @@ UINT SecureRecv(SOCK *sock, void *data, UINT size)
e = SSL_get_error(ssl, ret);
if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
{
if (e == SSL_ERROR_SSL &&
if (e == SSL_ERROR_SSL
#if OPENSSL_VERSION_NUMBER < 0x10100000L
&&
sock->ssl->s3->send_alert[0] == SSL3_AL_FATAL &&
sock->ssl->s3->send_alert[0] != sock->Ssl_Init_Async_SendAlert[0] &&
sock->ssl->s3->send_alert[1] != sock->Ssl_Init_Async_SendAlert[1])
sock->ssl->s3->send_alert[1] != sock->Ssl_Init_Async_SendAlert[1]
#endif
)
{
Debug("%s %u SSL Fatal Error on ASYNC socket !!!\n", __FILE__, __LINE__);
Disconnect(sock);
@ -13432,10 +13476,14 @@ UINT SecureRecv(SOCK *sock, void *data, UINT size)
{
if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
{
if (e == SSL_ERROR_SSL &&
if (e == SSL_ERROR_SSL
#if OPENSSL_VERSION_NUMBER < 0x10100000L
&&
sock->ssl->s3->send_alert[0] == SSL3_AL_FATAL &&
sock->ssl->s3->send_alert[0] != sock->Ssl_Init_Async_SendAlert[0] &&
sock->ssl->s3->send_alert[1] != sock->Ssl_Init_Async_SendAlert[1])
sock->ssl->s3->send_alert[1] != sock->Ssl_Init_Async_SendAlert[1]
#endif
)
{
Debug("%s %u SSL Fatal Error on ASYNC socket !!!\n", __FILE__, __LINE__);
Disconnect(sock);
@ -13455,7 +13503,7 @@ UINT SecureRecv(SOCK *sock, void *data, UINT size)
UINT SecureSend(SOCK *sock, void *data, UINT size)
{
SOCKET s;
int ret, e;
int ret, e = SSL_ERROR_NONE;
SSL *ssl;
s = sock->socket;
ssl = sock->ssl;
@ -13820,6 +13868,10 @@ void DisableGetHostNameWhenAcceptInit()
// Initialize the connection acceptance
void AcceptInit(SOCK *s)
{
AcceptInitEx(s, false);
}
void AcceptInitEx(SOCK *s, bool no_lookup_hostname)
{
char tmp[MAX_SIZE];
// Validate arguments
@ -13830,7 +13882,7 @@ void AcceptInit(SOCK *s)
Zero(tmp, sizeof(tmp));
if (disable_gethostname_by_accept == false)
if (disable_gethostname_by_accept == false && no_lookup_hostname == false)
{
if (GetHostName(tmp, sizeof(tmp), &s->RemoteIP) == false ||
IsEmptyStr(tmp))
@ -14202,9 +14254,9 @@ SOCK *Listen(UINT port)
}
SOCK *ListenEx(UINT port, bool local_only)
{
return ListenEx2(port, local_only, false);
return ListenEx2(port, local_only, false, NULL);
}
SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca)
SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca, IP *listen_ip)
{
SOCKET s;
SOCK *sock;
@ -14233,7 +14285,14 @@ SOCK *ListenEx2(UINT port, bool local_only, bool enable_ca)
SetIP(&localhost, 127, 0, 0, 1);
addr.sin_port = htons((UINT)port);
*((UINT *)&addr.sin_addr) = htonl(INADDR_ANY);
if (listen_ip == NULL)
{
*((UINT *)&addr.sin_addr) = htonl(INADDR_ANY);
}
else
{
IPToInAddr(&addr.sin_addr, listen_ip);
}
addr.sin_family = AF_INET;
if (local_only)
@ -17537,7 +17596,7 @@ void IPToInAddr6(struct in6_addr *addr, IP *ip)
return;
}
Zero(addr, sizeof(struct in_addr));
Zero(addr, sizeof(struct in6_addr));
if (IsIP6(ip))
{
@ -17742,9 +17801,9 @@ DH *TmpDhCallback(SSL *ssl, int is_export, int keylength)
{
DH *ret = NULL;
if (dh_1024 != NULL)
if (dh_param != NULL)
{
ret = dh_1024->dh;
ret = dh_param->dh;
}
return ret;
@ -17768,6 +17827,10 @@ struct ssl_ctx_st *NewSSLCtx(bool server_mode)
SSL_CTX_set_tmp_dh_callback(ctx, TmpDhCallback);
#ifdef SSL_CTX_set_ecdh_auto
SSL_CTX_set_ecdh_auto(ctx, 1);
#endif // SSL_CTX_set_ecdh_auto
return ctx;
}
@ -17860,9 +17923,6 @@ void InitNetwork()
disable_cache = false;
dh_1024 = DhNewGroup2();
Zero(rand_port_numbers, sizeof(rand_port_numbers));
SetGetIpThreadMaxNum(DEFAULT_GETIP_THREAD_MAX_NUM);
@ -18270,7 +18330,7 @@ void SetCurrentGlobalIP(IP *ip, bool ipv6)
return;
}
if (IsZeroIp(ip));
if (IsZeroIp(ip))
{
return;
}
@ -18295,10 +18355,10 @@ void SetCurrentGlobalIP(IP *ip, bool ipv6)
void FreeNetwork()
{
if (dh_1024 != NULL)
if (dh_param != NULL)
{
DhFree(dh_1024);
dh_1024 = NULL;
DhFree(dh_param);
dh_param = NULL;
}
// Release of thread-related
@ -18372,27 +18432,6 @@ void FreeNetwork()
}
// Add a socket to socket list
void AddSockList(SOCKLIST *sl, SOCK *s)
{
// Validate arguments
if (sl == NULL || s == NULL)
{
return;
}
LockList(sl->SockList);
{
if (IsInList(sl->SockList, s) == false)
{
AddRef(s->ref);
Insert(sl->SockList, s);
}
}
UnlockList(sl->SockList);
}
// Remove the socket from socket list
void DelSockList(SOCKLIST *sl, SOCK *s)
{
@ -20062,6 +20101,11 @@ void UdpListenerThread(THREAD *thread, void *param)
{
IP *ip = LIST_DATA(iplist, i);
if (CmpIpAddr(ip, &u->ListenIP) != 0)
{
continue;
}
WriteBuf(ip_list_buf_new, ip, sizeof(IP));
for (j = 0;j < LIST_NUM(u->PortList);j++)
@ -20205,6 +20249,8 @@ LABEL_RESTART:
if (u->PollMyIpAndPort)
{
// Create a thread to get a NAT-T IP address if necessary
if (u->GetNatTIpThread == NULL)
{
// Create a thread to get a NAT-T IP address if necessary
if (u->GetNatTIpThread == NULL)
@ -20577,7 +20623,7 @@ void UdpListenerSendPacket(UDPLISTENER *u, UDPPACKET *packet)
}
// Creating a UDP listener
UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param)
UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param, IP *listen_ip)
{
UDPLISTENER *u;
// Validate arguments
@ -20593,6 +20639,11 @@ UDPLISTENER *NewUdpListener(UDPLISTENER_RECV_PROC *recv_proc, void *param)
u->PortList = NewList(NULL);
u->Event = NewSockEvent();
if (listen_ip)
{
Copy(&u->ListenIP, listen_ip, sizeof(IP));
}
u->RecvProc = recv_proc;
u->SendPacketList = NewList(NULL);
@ -22663,7 +22714,14 @@ bool GetSniNameFromSslPacket(UCHAR *packet_buf, UINT packet_size, char *sni, UIN
USHORT handshake_length;
// Validate arguments
if (packet_buf == NULL || packet_size == 0)
if (packet_buf == NULL || packet_size <= 11)
{
return false;
}
if (!(packet_buf[0] == 0x16 && packet_buf[1] >= 0x03 &&
packet_buf[5] == 0x01 && packet_buf[6] == 0x00 &&
packet_buf[9] >= 0x03))
{
return false;
}
@ -22677,7 +22735,7 @@ bool GetSniNameFromSslPacket(UCHAR *packet_buf, UINT packet_size, char *sni, UIN
version = Endian16(version);
handshake_length = Endian16(handshake_length);
if (version >= 0x0301)
if (content_type == 0x16 && version >= 0x0301)
{
UCHAR *handshake_data = Malloc(handshake_length);
@ -22794,9 +22852,12 @@ bool GetSniNameFromSslPacket(UCHAR *packet_buf, UINT packet_size, char *sni, UIN
if (ReadBuf(dbuf, name_buf, name_len) == name_len)
{
ret = true;
if (StrLen(name_buf) >= 1)
{
ret = true;
StrCpy(sni, sni_size, name_buf);
StrCpy(sni, sni_size, name_buf);
}
}
Free(name_buf);
@ -22850,6 +22911,12 @@ bool GetSniNameFromSslPacket(UCHAR *packet_buf, UINT packet_size, char *sni, UIN
return ret;
}
// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
// Department of Computer Science has dozens of overly-enthusiastic geeks.
// Join us: http://www.tsukuba.ac.jp/english/admission/
void SetDhParam(DH_CTX *dh)
{
if (dh_param)
{
DhFree(dh_param);
}
dh_param = dh;
}