1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2026-04-23 07:19:26 +03:00

Merge pull request #1522 from domosekai/tls

Implement complete server certificate verification
This commit is contained in:
Yihong Wu
2022-05-12 23:38:38 +08:00
committed by GitHub
34 changed files with 1212 additions and 477 deletions
+9 -2
View File
@@ -7350,6 +7350,7 @@ UINT StGetLink(ADMIN *a, RPC_CREATE_LINK *t)
Copy(&t->Policy, k->Policy, sizeof(POLICY));
t->CheckServerCert = k->CheckServerCert;
t->AddDefaultCA = k->AddDefaultCA;
t->ServerCert = CloneX(k->ServerCert);
}
Unlock(k->lock);
@@ -7465,6 +7466,7 @@ UINT StSetLink(ADMIN *a, RPC_CREATE_LINK *t)
k->Option->RequireMonitorMode = false; // Disable monitor mode
k->CheckServerCert = t->CheckServerCert;
k->AddDefaultCA = t->AddDefaultCA;
k->ServerCert = CloneX(t->ServerCert);
}
Unlock(k->lock);
@@ -7561,6 +7563,7 @@ UINT StCreateLink(ADMIN *a, RPC_CREATE_LINK *t)
// setting of verifying server certification
//
k->CheckServerCert = t->CheckServerCert;
k->AddDefaultCA = t->AddDefaultCA;
k->ServerCert = CloneX(t->ServerCert);
// stay this off-line
@@ -13635,6 +13638,7 @@ void InRpcCreateLink(RPC_CREATE_LINK *t, PACK *p)
InRpcPolicy(&t->Policy, p);
t->CheckServerCert = PackGetBool(p, "CheckServerCert");
t->AddDefaultCA = PackGetBool(p, "AddDefaultCA");
b = PackGetBuf(p, "ServerCert");
if (b != NULL)
{
@@ -13657,6 +13661,7 @@ void OutRpcCreateLink(PACK *p, RPC_CREATE_LINK *t)
OutRpcPolicy(p, &t->Policy);
PackAddBool(p, "CheckServerCert", t->CheckServerCert);
PackAddBool(p, "AddDefaultCA", t->AddDefaultCA);
if (t->ServerCert != NULL)
{
BUF *b;
@@ -13702,12 +13707,14 @@ void InRpcEnumLink(RPC_ENUM_LINK *t, PACK *p)
PackGetUniStrEx(p, "AccountName", e->AccountName, sizeof(e->AccountName), i);
PackGetStrEx(p, "Hostname", e->Hostname, sizeof(e->Hostname), i);
PackGetStrEx(p, "ConnectedHubName", e->HubName, sizeof(e->HubName), i);
if (PackGetStrEx(p, "ConnectedHubName", e->HubName, sizeof(e->HubName), i) == false)
{
PackGetStrEx(p, "TargetHubName", e->HubName, sizeof(e->HubName), i);
}
e->Online = PackGetBoolEx(p, "Online", i);
e->ConnectedTime = PackGetInt64Ex(p, "ConnectedTime", i);
e->Connected = PackGetBoolEx(p, "Connected", i);
e->LastError = PackGetIntEx(p, "LastError", i);
PackGetStrEx(p, "LinkHubName", e->HubName, sizeof(e->HubName), i);
}
}
void OutRpcEnumLink(PACK *p, RPC_ENUM_LINK *t)
+1
View File
@@ -436,6 +436,7 @@ struct RPC_CREATE_LINK
CLIENT_AUTH *ClientAuth; // Client authentication data
POLICY Policy; // Policy
bool CheckServerCert; // Validate the server certificate
bool AddDefaultCA; // Use default trust store
X *ServerCert; // Server certificate
};
+16 -1
View File
@@ -9,6 +9,7 @@
#include "Cedar.h"
#include "Command.h"
#include "Logging.h"
#include "Wpc.h"
#include "Mayaqua/Encrypt.h"
@@ -19,6 +20,7 @@
#include "Mayaqua/Object.h"
#include "Mayaqua/Pack.h"
#include "Mayaqua/Str.h"
#include "Mayaqua/Table.h"
#include "Mayaqua/Tick64.h"
#include <stdlib.h>
@@ -80,6 +82,9 @@ void AcWaitForRequest(AZURE_CLIENT *ac, SOCK *s, AZURE_PARAM *param)
{
SOCK *ns;
Debug("Connect Request from %r:%u\n", &client_ip, client_port);
char ipstr[128];
IPToStr(ipstr, sizeof(ipstr), &client_ip);
SLog(ac->Cedar, "LS_AZURE_START", ipstr, client_port);
// Create new socket and connect VPN Azure Server
if (ac->DDnsStatusCopy.InternetSetting.ProxyType == PROXY_DIRECT)
@@ -103,7 +108,10 @@ void AcWaitForRequest(AZURE_CLIENT *ac, SOCK *s, AZURE_PARAM *param)
SetTimeout(ns, param->DataTimeout);
if (StartSSLEx(ns, NULL, NULL, 0, NULL))
UINT ssl_err = 0;
Copy(&ns->SslAcceptSettings, &ac->Cedar->SslAcceptSettings, sizeof(SSL_ACCEPT_SETTINGS));
if (StartSSLEx3(ns, NULL, NULL, NULL, 0, NULL, NULL, &ssl_err))
{
// Check certification
char server_cert_hash_str[MAX_SIZE];
@@ -157,6 +165,13 @@ void AcWaitForRequest(AZURE_CLIENT *ac, SOCK *s, AZURE_PARAM *param)
}
}
}
else
{
if (ssl_err != 0)
{
SLog(ac->Cedar, "LS_AZURE_SSL_ERROR", GetUniErrorStr(ssl_err), ssl_err);
}
}
ReleaseSock(ns);
}
+32 -4
View File
@@ -6022,6 +6022,7 @@ void CmExportAccount(HWND hWnd, wchar_t *account_name)
t.StartupAccount = a->Startup;
t.CheckServerCert = a->CheckServerCert;
t.RetryOnServerCert = a->RetryOnServerCert;
t.AddDefaultCA = a->AddDefaultCA;
t.ServerCert = a->ServerCert;
t.ClientOption->FromAdminPack = false;
@@ -6161,6 +6162,7 @@ void CmImportAccountMainEx(HWND hWnd, wchar_t *filename, bool overwrite)
t->StartupAccount = get.StartupAccount;
t->CheckServerCert = get.CheckServerCert;
t->RetryOnServerCert = get.RetryOnServerCert;
t->AddDefaultCA = get.AddDefaultCA;
if (t->ServerCert != NULL)
{
FreeX(t->ServerCert);
@@ -6270,6 +6272,7 @@ void CmCopyAccount(HWND hWnd, wchar_t *account_name)
}
c.CheckServerCert = a->CheckServerCert;
c.RetryOnServerCert = a->RetryOnServerCert;
c.AddDefaultCA = a->AddDefaultCA;
c.StartupAccount = false; // Don't copy the startup attribute
CALL(hWnd, CcCreateAccount(cm->Client, &c));
@@ -6649,6 +6652,7 @@ void CmEditAccountDlgUpdate(HWND hWnd, CM_ACCOUNT *a)
// Host name
GetTxtA(hWnd, E_HOSTNAME, a->ClientOption->Hostname, sizeof(a->ClientOption->Hostname));
Trim(a->ClientOption->Hostname);
a->ClientOption->HintStr[0] = 0;
if (InStr(a->ClientOption->Hostname, "/tcp"))
{
@@ -6685,9 +6689,13 @@ void CmEditAccountDlgUpdate(HWND hWnd, CM_ACCOUNT *a)
// To validate the server certificate
a->CheckServerCert = IsChecked(hWnd, R_CHECK_CERT);
// Trust default CA list
a->AddDefaultCA = IsChecked(hWnd, R_TRUST_DEFAULT);
if (a->NatMode)
{
Disable(hWnd, R_CHECK_CERT);
Disable(hWnd, R_TRUST_DEFAULT);
Disable(hWnd, B_TRUST);
}
@@ -7030,6 +7038,7 @@ void CmEditAccountDlgUpdate(HWND hWnd, CM_ACCOUNT *a)
SetEnable(hWnd, S_STATIC7, false);
SetEnable(hWnd, S_STATIC11, false);
SetEnable(hWnd, R_CHECK_CERT, false);
SetEnable(hWnd, R_TRUST_DEFAULT, false);
SetEnable(hWnd, B_TRUST, false);
SetEnable(hWnd, B_SERVER_CERT, false);
SetEnable(hWnd, B_VIEW_SERVER_CERT, false);
@@ -7091,10 +7100,17 @@ void CmEditAccountDlgInit(HWND hWnd, CM_ACCOUNT *a)
SetText(hWnd, E_ACCOUNT_NAME, a->ClientOption->AccountName);
// Host name
SetTextA(hWnd, E_HOSTNAME, a->ClientOption->Hostname);
StrCpy(a->old_server_name, sizeof(a->old_server_name), a->ClientOption->Hostname);
char hostname[MAX_SIZE];
StrCpy(hostname, sizeof(hostname), a->ClientOption->Hostname);
if (IsEmptyStr(a->ClientOption->HintStr) == false)
{
StrCat(hostname, sizeof(hostname), "/");
StrCat(hostname, sizeof(hostname), a->ClientOption->HintStr);
}
SetTextA(hWnd, E_HOSTNAME, hostname);
StrCpy(a->old_server_name, sizeof(a->old_server_name), hostname);
if (InStr(a->ClientOption->Hostname, "/tcp"))
if (InStr(hostname, "/tcp"))
{
Check(hWnd, R_DISABLE_NATT, true);
}
@@ -7124,6 +7140,9 @@ void CmEditAccountDlgInit(HWND hWnd, CM_ACCOUNT *a)
// Verify the server certificate
Check(hWnd, R_CHECK_CERT, a->CheckServerCert);
// Trust default CA list
Check(hWnd, R_TRUST_DEFAULT, a->AddDefaultCA);
// LAN card list
if (a->NatMode == false && a->LinkMode == false)
{
@@ -7356,6 +7375,7 @@ UINT CmEditAccountDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, voi
case R_HTTPS:
case R_SOCKS:
case R_CHECK_CERT:
case R_TRUST_DEFAULT:
case C_TYPE:
case E_USERNAME:
case E_PASSWORD:
@@ -8762,6 +8782,7 @@ void CmEditAccountDlgOnOk(HWND hWnd, CM_ACCOUNT *a)
Copy(c.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
c.ClientAuth = CopyClientAuth(a->ClientAuth);
c.CheckServerCert = a->CheckServerCert;
c.AddDefaultCA = a->AddDefaultCA;
if (a->ServerCert != NULL)
{
c.ServerCert = CloneX(a->ServerCert);
@@ -8815,6 +8836,7 @@ void CmEditAccountDlgOnOk(HWND hWnd, CM_ACCOUNT *a)
Copy(t.ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
t.ClientAuth = CopyClientAuth(a->ClientAuth);
t.CheckServerCert = a->CheckServerCert;
t.AddDefaultCA = a->AddDefaultCA;
t.ServerCert = CloneX(a->ServerCert);
// Save the settings for cascade connection
@@ -9007,6 +9029,7 @@ CM_ACCOUNT *CmGetExistAccountObject(HWND hWnd, wchar_t *account_name)
a->EditMode = true;
a->CheckServerCert = c.CheckServerCert;
a->RetryOnServerCert = c.RetryOnServerCert;
a->AddDefaultCA = c.AddDefaultCA;
a->Startup = c.StartupAccount;
if (c.ServerCert != NULL)
{
@@ -9037,6 +9060,7 @@ CM_ACCOUNT *CmCreateNewAccountObject(HWND hWnd)
a->EditMode = false;
a->CheckServerCert = false;
a->RetryOnServerCert = false;
a->AddDefaultCA = false;
a->Startup = false;
a->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
@@ -9552,7 +9576,11 @@ void CmPrintStatusToListViewEx(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s, bool
}
else
{
if (StrLen(s->CipherName) != 0)
if (StrLen(s->CipherName) != 0 && StrLen(s->ProtocolName) != 0)
{
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_TRUE3"), s->ProtocolName, s->CipherName);
}
else if (StrLen(s->CipherName) != 0)
{
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_TRUE"), s->CipherName);
}
+1
View File
@@ -140,6 +140,7 @@ typedef struct CM_ACCOUNT
bool Startup; // Startup account
bool CheckServerCert; // Check the server certificate
bool RetryOnServerCert; // Retry on invalid server certificate
bool AddDefaultCA; // Use default trust store
X *ServerCert; // Server certificate
char old_server_name[MAX_HOST_NAME_LEN + 1]; // Old server name
bool Inited; // Initialization flag
+4
View File
@@ -869,6 +869,10 @@
#define ERR_VPNGATE_INCLIENT_CANT_STOP 146 // Can not be stopped if operating within VPN Client mode
#define ERR_NOT_SUPPORTED_FUNCTION_ON_OPENSOURCE 147 // It is a feature that is not supported in the open source version
#define ERR_SUSPENDING 148 // System is suspending
#define ERR_HOSTNAME_MISMATCH 149 // SSL hostname mismatch
#define ERR_SSL_PROTOCOL_VERSION 150 // SSL version not supported
#define ERR_SSL_SHARED_CIPHER 151 // Can't find common cipher
#define ERR_SSL_HANDSHAKE 152 // Other SSL handshake error
////////////////////////////
+69 -4
View File
@@ -1957,6 +1957,7 @@ RPC_CLIENT_CREATE_ACCOUNT *CiCfgToAccount(BUF *b)
t->StartupAccount = a->StartupAccount;
t->CheckServerCert = a->CheckServerCert;
t->RetryOnServerCert = a->RetryOnServerCert;
t->AddDefaultCA = a->AddDefaultCA;
t->ServerCert = a->ServerCert;
Free(a);
@@ -1981,6 +1982,7 @@ BUF *CiAccountToCfg(RPC_CLIENT_CREATE_ACCOUNT *t)
a.ClientAuth = t->ClientAuth;
a.CheckServerCert = t->CheckServerCert;
a.RetryOnServerCert = t->RetryOnServerCert;
a.AddDefaultCA = t->AddDefaultCA;
a.ServerCert = t->ServerCert;
a.StartupAccount = t->StartupAccount;
@@ -4315,6 +4317,13 @@ void InRpcClientOption(CLIENT_OPTION *c, PACK *p)
PackGetUniStr(p, "AccountName", c->AccountName, sizeof(c->AccountName));
PackGetStr(p, "Hostname", c->Hostname, sizeof(c->Hostname));
// Extract hint string from hostname
UINT i = SearchStrEx(c->Hostname, "/", 0, false);
if (i != INFINITE)
{
StrCpy(c->HintStr, sizeof(c->HintStr), c->Hostname + i + 1);
c->Hostname[i] = 0;
}
c->Port = PackGetInt(p, "Port");
c->PortUDP = PackGetInt(p, "PortUDP");
c->ProxyType = PackGetInt(p, "ProxyType");
@@ -4352,7 +4361,20 @@ void OutRpcClientOption(PACK *p, CLIENT_OPTION *c)
}
PackAddUniStr(p, "AccountName", c->AccountName);
PackAddStr(p, "Hostname", c->Hostname);
// Append hint string to hostname
if (IsEmptyStr(c->HintStr))
{
// No hint
PackAddStr(p, "Hostname", c->Hostname);
}
else
{
char hostname[MAX_SIZE];
StrCpy(hostname, sizeof(hostname), c->Hostname);
StrCat(hostname, sizeof(hostname), "/");
StrCat(hostname, sizeof(hostname), c->HintStr);
PackAddStr(p, "Hostname", hostname);
}
PackAddStr(p, "ProxyName", c->ProxyName);
PackAddStr(p, "ProxyUsername", c->ProxyUsername);
PackAddStr(p, "ProxyPassword", c->ProxyPassword);
@@ -4522,6 +4544,7 @@ void InRpcClientCreateAccount(RPC_CLIENT_CREATE_ACCOUNT *c, PACK *p)
c->StartupAccount = PackGetInt(p, "StartupAccount") ? true : false;
c->CheckServerCert = PackGetInt(p, "CheckServerCert") ? true : false;
c->RetryOnServerCert = PackGetInt(p, "RetryOnServerCert") ? true : false;
c->AddDefaultCA = PackGetInt(p, "AddDefaultCA") ? true : false;
b = PackGetBuf(p, "ServerCert");
if (b != NULL)
{
@@ -4545,6 +4568,7 @@ void OutRpcClientCreateAccount(PACK *p, RPC_CLIENT_CREATE_ACCOUNT *c)
PackAddInt(p, "StartupAccount", c->StartupAccount);
PackAddInt(p, "CheckServerCert", c->CheckServerCert);
PackAddInt(p, "RetryOnServerCert", c->RetryOnServerCert);
PackAddInt(p, "AddDefaultCA", c->AddDefaultCA);
if (c->ServerCert != NULL)
{
b = XToBuf(c->ServerCert, false);
@@ -4695,6 +4719,7 @@ void InRpcClientGetAccount(RPC_CLIENT_GET_ACCOUNT *c, PACK *p)
c->StartupAccount = PackGetInt(p, "StartupAccount") ? true : false;
c->CheckServerCert = PackGetInt(p, "CheckServerCert") ? true : false;
c->RetryOnServerCert = PackGetInt(p, "RetryOnServerCert") ? true : false;
c->AddDefaultCA = PackGetInt(p, "AddDefaultCA") ? true : false;
b = PackGetBuf(p, "ServerCert");
if (b != NULL)
{
@@ -4724,6 +4749,7 @@ void OutRpcClientGetAccount(PACK *p, RPC_CLIENT_GET_ACCOUNT *c)
PackAddInt(p, "StartupAccount", c->StartupAccount);
PackAddInt(p, "CheckServerCert", c->CheckServerCert);
PackAddInt(p, "RetryOnServerCert", c->RetryOnServerCert);
PackAddInt(p, "AddDefaultCA", c->AddDefaultCA);
if (c->ServerCert != NULL)
{
@@ -4810,6 +4836,7 @@ void InRpcClientGetConnectionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *s, PACK *p
PackGetStr(p, "ServerName", s->ServerName, sizeof(s->ServerName));
PackGetStr(p, "ServerProductName", s->ServerProductName, sizeof(s->ServerProductName));
PackGetStr(p, "ProtocolVersion", s->ProtocolName, sizeof(s->ProtocolName));
PackGetStr(p, "CipherName", s->CipherName, sizeof(s->CipherName));
PackGetStr(p, "SessionName", s->SessionName, sizeof(s->SessionName));
PackGetStr(p, "ConnectionName", s->ConnectionName, sizeof(s->ConnectionName));
@@ -4886,6 +4913,7 @@ void OutRpcClientGetConnectionStatus(PACK *p, RPC_CLIENT_GET_CONNECTION_STATUS *
PackAddStr(p, "ServerName", c->ServerName);
PackAddStr(p, "ServerProductName", c->ServerProductName);
PackAddStr(p, "ProtocolVersion", c->ProtocolName);
PackAddStr(p, "CipherName", c->CipherName);
PackAddStr(p, "SessionName", c->SessionName);
PackAddStr(p, "ConnectionName", c->ConnectionName);
@@ -5840,6 +5868,7 @@ void CiGetSessionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *st, SESSION *s)
if (st->UseEncrypt)
{
StrCpy(st->CipherName, sizeof(st->CipherName), s->Connection->CipherName);
StrCpy(st->ProtocolName, sizeof(st->ProtocolName), s->Connection->SslVersion);
}
// Use of compression
st->UseCompress = s->UseCompress;
@@ -6449,9 +6478,9 @@ bool CtConnect(CLIENT *c, RPC_CLIENT_CONNECT *connect)
// Register a procedure for secure device authentication
r->ClientAuth->SecureSignProc = CiSecureSignProc;
}
else if (r->ClientAuth->AuthType == CLIENT_AUTHTYPE_OPENSSLENGINE)
else if (r->ClientAuth->AuthType == CLIENT_AUTHTYPE_OPENSSLENGINE)
{
/* r->ClientAuth->ClientK = OpensslEngineToK("asdf"); */
/* r->ClientAuth->ClientK = OpensslEngineToK("asdf"); */
r->ClientAuth->SecureSignProc = NULL;
}
else
@@ -6599,6 +6628,9 @@ bool CtGetAccount(CLIENT *c, RPC_CLIENT_GET_ACCOUNT *a)
Lock(r->lock);
{
// Copy account name (restore the correct case)
UniStrCpy(a->AccountName, sizeof(a->AccountName), r->ClientOption->AccountName);
// Copy the client option
if (a->ClientOption != NULL)
{
@@ -6618,6 +6650,7 @@ bool CtGetAccount(CLIENT *c, RPC_CLIENT_GET_ACCOUNT *a)
a->CheckServerCert = r->CheckServerCert;
a->RetryOnServerCert = r->RetryOnServerCert;
a->AddDefaultCA = r->AddDefaultCA;
a->ServerCert = NULL;
if (r->ServerCert != NULL)
{
@@ -7029,6 +7062,12 @@ bool CtEnumAccount(CLIENT *c, RPC_CLIENT_ENUM_ACCOUNT *e)
// Server name
StrCpy(item->ServerName, sizeof(item->ServerName), a->ClientOption->Hostname);
// Append hint string to hostname
if (IsEmptyStr(a->ClientOption->HintStr) == false)
{
StrCat(item->ServerName, sizeof(item->ServerName), "/");
StrCat(item->ServerName, sizeof(item->ServerName), a->ClientOption->HintStr);
}
// Proxy type
item->ProxyType = a->ClientOption->ProxyType;
@@ -7146,6 +7185,7 @@ bool CtSetAccount(CLIENT *c, RPC_CLIENT_CREATE_ACCOUNT *a, bool inner)
ret->CheckServerCert = a->CheckServerCert;
ret->RetryOnServerCert = a->RetryOnServerCert;
ret->AddDefaultCA = a->AddDefaultCA;
if (a->ServerCert != NULL)
{
@@ -7245,6 +7285,7 @@ bool CtCreateAccount(CLIENT *c, RPC_CLIENT_CREATE_ACCOUNT *a, bool inner)
new_account->CheckServerCert = a->CheckServerCert;
new_account->RetryOnServerCert = a->RetryOnServerCert;
new_account->AddDefaultCA = a->AddDefaultCA;
if (a->ServerCert != NULL)
{
new_account->ServerCert = CloneX(a->ServerCert);
@@ -9221,6 +9262,13 @@ CLIENT_OPTION *CiLoadClientOption(FOLDER *f)
CfgGetUniStr(f, "AccountName", o->AccountName, sizeof(o->AccountName));
CfgGetStr(f, "Hostname", o->Hostname, sizeof(o->Hostname));
// Extract hint string from hostname
UINT i = SearchStrEx(o->Hostname, "/", 0, false);
if (i != INFINITE)
{
StrCpy(o->HintStr, sizeof(o->HintStr), o->Hostname + i + 1);
o->Hostname[i] = 0;
}
o->Port = CfgGetInt(f, "Port");
o->PortUDP = CfgGetInt(f, "PortUDP");
o->ProxyType = CfgGetInt(f, "ProxyType");
@@ -9302,6 +9350,7 @@ ACCOUNT *CiLoadClientAccount(FOLDER *f)
a->StartupAccount = CfgGetBool(f, "StartupAccount");
a->CheckServerCert = CfgGetBool(f, "CheckServerCert");
a->RetryOnServerCert = CfgGetBool(f, "RetryOnServerCert");
a->AddDefaultCA = CfgGetBool(f, "AddDefaultCA");
a->CreateDateTime = CfgGetInt64(f, "CreateDateTime");
a->UpdateDateTime = CfgGetInt64(f, "UpdateDateTime");
a->LastConnectDateTime = CfgGetInt64(f, "LastConnectDateTime");
@@ -9763,7 +9812,20 @@ void CiWriteClientOption(FOLDER *f, CLIENT_OPTION *o)
}
CfgAddUniStr(f, "AccountName", o->AccountName);
CfgAddStr(f, "Hostname", o->Hostname);
// Append hint string to hostname
if (IsEmptyStr(o->HintStr))
{
// No hint
CfgAddStr(f, "Hostname", o->Hostname);
}
else
{
char hostname[MAX_SIZE];
StrCpy(hostname, sizeof(hostname), o->Hostname);
StrCat(hostname, sizeof(hostname), "/");
StrCat(hostname, sizeof(hostname), o->HintStr);
CfgAddStr(f, "Hostname", hostname);
}
CfgAddInt(f, "Port", o->Port);
CfgAddInt(f, "PortUDP", o->PortUDP);
CfgAddInt(f, "ProxyType", o->ProxyType);
@@ -9927,6 +9989,9 @@ void CiWriteAccountData(FOLDER *f, ACCOUNT *a)
// Retry on invalid server certificate flag
CfgAddBool(f, "RetryOnServerCert", a->RetryOnServerCert);
// Add default SSL trust store
CfgAddBool(f, "AddDefaultCA", a->AddDefaultCA);
// Date and time
CfgAddInt64(f, "CreateDateTime", a->CreateDateTime);
CfgAddInt64(f, "UpdateDateTime", a->UpdateDateTime);
+3
View File
@@ -61,6 +61,7 @@ struct ACCOUNT
CLIENT_AUTH *ClientAuth; // Client authentication data
bool CheckServerCert; // Check the server certificate
bool RetryOnServerCert; // Retry on invalid server certificate
bool AddDefaultCA; // Use default trust store
X *ServerCert; // Server certificate
bool StartupAccount; // Start-up account
UCHAR ShortcutKey[SHA1_SIZE]; // Key
@@ -239,6 +240,7 @@ struct RPC_CLIENT_CREATE_ACCOUNT
bool StartupAccount; // Startup account
bool CheckServerCert; // Checking of the server certificate
bool RetryOnServerCert; // Retry on invalid server certificate
bool AddDefaultCA; // Use default trust store
X *ServerCert; // Server certificate
UCHAR ShortcutKey[SHA1_SIZE]; // Shortcut Key
};
@@ -292,6 +294,7 @@ struct RPC_CLIENT_GET_ACCOUNT
bool StartupAccount; // Startup account
bool CheckServerCert; // Check the server certificate
bool RetryOnServerCert; // Retry on invalid server certificate
bool AddDefaultCA; // Use default trust store
X *ServerCert; // Server certificate
UCHAR ShortcutKey[SHA1_SIZE]; // Shortcut Key
UINT64 CreateDateTime; // Creation date and time (Ver 3.0 or later)
+351 -241
View File
@@ -3109,6 +3109,8 @@ void PcMain(PC *pc)
{"AccountServerCertDisable", PcAccountServerCertDisable},
{"AccountRetryOnServerCertEnable", PcAccountRetryOnServerCertEnable},
{"AccountRetryOnServerCertDisable", PcAccountRetryOnServerCertDisable},
{"AccountDefaultCAEnable", PcAccountDefaultCAEnable},
{"AccountDefaultCADisable", PcAccountDefaultCADisable},
{"AccountServerCertSet", PcAccountServerCertSet},
{"AccountServerCertDelete", PcAccountServerCertDelete},
{"AccountServerCertGet", PcAccountServerCertGet},
@@ -4293,6 +4295,26 @@ UINT PcAccountCreate(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
return ret;
}
// Setup a RPC_CLIENT_CREATE_ACCOUNT from a RPC_CLIENT_GET_ACCOUNT
void SetRpcClientCreateAccountFromGetAccount(RPC_CLIENT_CREATE_ACCOUNT *c, RPC_CLIENT_GET_ACCOUNT *t)
{
if (c == NULL || t == NULL)
{
return;
}
Zero(c, sizeof(RPC_CLIENT_CREATE_ACCOUNT));
// Copy reference
c->ClientAuth = t->ClientAuth;
c->ClientOption = t->ClientOption;
c->CheckServerCert = t->CheckServerCert;
c->RetryOnServerCert = t->RetryOnServerCert;
c->AddDefaultCA = t->AddDefaultCA;
c->ServerCert = t->ServerCert;
c->StartupAccount = t->StartupAccount;
}
// Set the destination of the connection settings
UINT PcAccountSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
@@ -4333,16 +4355,10 @@ UINT PcAccountSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
// Success
t.ClientOption->Port = port;
StrCpy(t.ClientOption->Hostname, sizeof(t.ClientOption->Hostname), host);
t.ClientOption->HintStr[0] = 0;
StrCpy(t.ClientOption->HubName, sizeof(t.ClientOption->HubName), GetParamStr(o, "HUB"));
Zero(&c, sizeof(c));
c.ClientAuth = t.ClientAuth;
c.ClientOption = t.ClientOption;
c.CheckServerCert = t.CheckServerCert;
c.RetryOnServerCert = t.RetryOnServerCert;
c.ServerCert = t.ServerCert;
c.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&c, &t);
ret = CcSetAccount(pc->RemoteClient, &c);
}
@@ -4400,7 +4416,18 @@ UINT PcAccountGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
CtInsert(ct, _UU("CMD_ACCOUNT_COLUMN_NAME"), t.ClientOption->AccountName);
// Host name of the destination VPN Server
StrToUni(tmp, sizeof(tmp), t.ClientOption->Hostname);
if (IsEmptyStr(t.ClientOption->HintStr))
{
StrToUni(tmp, sizeof(tmp), t.ClientOption->Hostname);
}
else
{
char hostname[MAX_SIZE];
StrCpy(hostname, sizeof(hostname), t.ClientOption->Hostname);
StrCat(hostname, sizeof(hostname), "/");
StrCat(hostname, sizeof(hostname), t.ClientOption->HintStr);
StrToUni(tmp, sizeof(tmp), hostname);
}
CtInsert(ct, _UU("CMD_ACCOUNT_COLUMN_HOSTNAME"), tmp);
// The port number to connect to VPN Server
@@ -4444,6 +4471,8 @@ UINT PcAccountGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
CtInsert(ct, _UU("CMD_ACCOUNT_COLUMN_RETRY_ON_SERVER_CERT"),
t.RetryOnServerCert ? _UU("CMD_MSG_ENABLE") : _UU("CMD_MSG_DISABLE"));
CtInsert(ct, _UU("CMD_ACCOUNT_COLUMN_ADD_DEFAULT_CA"),
t.AddDefaultCA ? _UU("CMD_MSG_ENABLE") : _UU("CMD_MSG_DISABLE"));
}
// Device name to be used for the connection
@@ -4618,13 +4647,7 @@ UINT PcAccountUsernameSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
c->Write(c, _UU("CMD_AccountUsername_Notice"));
}
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -4676,13 +4699,7 @@ UINT PcAccountAnonymousSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param
// Change the settings
t.ClientAuth->AuthType = CLIENT_AUTHTYPE_ANONYMOUS;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -4758,13 +4775,7 @@ UINT PcAccountPasswordSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
if (ret == ERR_NO_ERROR)
{
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -4837,13 +4848,7 @@ UINT PcAccountCertSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
t.ClientAuth->ClientX = CloneX(x);
t.ClientAuth->ClientK = CloneK(k);
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -4958,13 +4963,7 @@ UINT PcAccountEncryptDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *par
// Change the settings
t.ClientOption->UseEncrypt = false;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5016,13 +5015,7 @@ UINT PcAccountEncryptEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *para
// Change the settings
t.ClientOption->UseEncrypt = true;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5074,13 +5067,7 @@ UINT PcAccountCompressEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *par
// Change the settings
t.ClientOption->UseCompress = true;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5132,13 +5119,7 @@ UINT PcAccountCompressDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *pa
// Change the settings
t.ClientOption->UseCompress = false;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5213,13 +5194,7 @@ UINT PcAccountHttpHeaderAdd(CONSOLE *c, char *cmd_name, wchar_t *str, void *para
if ((StrLen(s) + StrLen(t.ClientOption->CustomHttpHeader)) < sizeof(t.ClientOption->CustomHttpHeader)) {
StrCat(t.ClientOption->CustomHttpHeader, sizeof(s), s);
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5284,13 +5259,7 @@ UINT PcAccountHttpHeaderDelete(CONSOLE *c, char *cmd_name, wchar_t *str, void *p
RPC_CLIENT_CREATE_ACCOUNT z;
char *value = GetParamStr(o, "NAME");
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
Zero(z.ClientOption->CustomHttpHeader, sizeof(z.ClientOption->CustomHttpHeader));
@@ -5410,13 +5379,7 @@ UINT PcAccountProxyNone(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
// Change the settings
t.ClientOption->ProxyType = PROXY_DIRECT;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5482,13 +5445,7 @@ UINT PcAccountProxyHttp(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
Free(host);
}
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5554,13 +5511,7 @@ UINT PcAccountProxySocks(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
Free(host);
}
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5626,13 +5577,7 @@ UINT PcAccountProxySocks5(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
Free(host);
}
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5684,13 +5629,7 @@ UINT PcAccountServerCertEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *p
// Change the settings
t.CheckServerCert = true;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5742,13 +5681,7 @@ UINT PcAccountServerCertDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *
// Change the settings
t.CheckServerCert = false;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5800,13 +5733,7 @@ UINT PcAccountRetryOnServerCertEnable(CONSOLE *c, char *cmd_name, wchar_t *str,
// Change the settings
t.RetryOnServerCert = true;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5858,13 +5785,111 @@ UINT PcAccountRetryOnServerCertDisable(CONSOLE *c, char *cmd_name, wchar_t *str,
// Change the settings
t.RetryOnServerCert = false;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
if (ret != ERR_NO_ERROR)
{
// Error has occurred
CmdPrintError(c, ret);
}
CiFreeClientGetAccount(&t);
// Release of the parameter list
FreeParamValueList(o);
return ret;
}
// Enable trusting default CA list
UINT PcAccountDefaultCAEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
LIST *o;
PC *pc = (PC *)param;
UINT ret = ERR_NO_ERROR;
RPC_CLIENT_GET_ACCOUNT t;
// Parameter list that can be specified
PARAM args[] =
{
{"[name]", CmdPrompt, _UU("CMD_AccountCreate_Prompt_Name"), CmdEvalNotEmpty, NULL},
};
// Get the parameter list
o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
// RPC call
Zero(&t, sizeof(t));
UniStrCpy(t.AccountName, sizeof(t.AccountName), GetParamUniStr(o, "[name]"));
ret = CcGetAccount(pc->RemoteClient, &t);
if (ret == ERR_NO_ERROR)
{
RPC_CLIENT_CREATE_ACCOUNT z;
// Change the settings
t.AddDefaultCA = true;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
if (ret != ERR_NO_ERROR)
{
// Error has occurred
CmdPrintError(c, ret);
}
CiFreeClientGetAccount(&t);
// Release of the parameter list
FreeParamValueList(o);
return ret;
}
// Disable trusting default CA list
UINT PcAccountDefaultCADisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
LIST *o;
PC *pc = (PC *)param;
UINT ret = ERR_NO_ERROR;
RPC_CLIENT_GET_ACCOUNT t;
// Parameter list that can be specified
PARAM args[] =
{
{"[name]", CmdPrompt, _UU("CMD_AccountCreate_Prompt_Name"), CmdEvalNotEmpty, NULL},
};
// Get the parameter list
o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
// RPC call
Zero(&t, sizeof(t));
UniStrCpy(t.AccountName, sizeof(t.AccountName), GetParamUniStr(o, "[name]"));
ret = CcGetAccount(pc->RemoteClient, &t);
if (ret == ERR_NO_ERROR)
{
RPC_CLIENT_CREATE_ACCOUNT z;
// Change the settings
t.AddDefaultCA = false;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5930,13 +5955,7 @@ UINT PcAccountServerCertSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *para
}
t.ServerCert = CloneX(x);
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -5994,13 +6013,7 @@ UINT PcAccountServerCertDelete(CONSOLE *c, char *cmd_name, wchar_t *str, void *p
}
t.ServerCert = NULL;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -6049,23 +6062,20 @@ UINT PcAccountServerCertGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *para
if (ret == ERR_NO_ERROR)
{
RPC_CLIENT_CREATE_ACCOUNT z;
// Change the settings
if (t.ServerCert != NULL)
// Save the certificate
if (t.ServerCert == NULL)
{
FreeX(t.ServerCert);
c->Write(c, _UU("CMD_CERT_NOT_EXISTS"));
ret = ERR_INTERNAL_ERROR;
}
else
{
if (XToFileW(t.ServerCert, GetParamUniStr(o, "SAVECERT"), true) == false)
{
c->Write(c, _UU("CMD_SAVECERT_FAILED"));
ret = ERR_INTERNAL_ERROR;
}
}
t.ServerCert = NULL;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
ret = CcSetAccount(pc->RemoteClient, &z);
}
if (ret != ERR_NO_ERROR)
@@ -6140,12 +6150,7 @@ UINT PcAccountDetailSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
t.ClientOption->DisableQoS = GetParamYes(o, "NOQOS");
t.ClientOption->NoUdpAcceleration = GetParamYes(o, "DISABLEUDP");
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -6388,14 +6393,7 @@ UINT PcAccountNicSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
StrCpy(t.ClientOption->DeviceName, sizeof(t.ClientOption->DeviceName),
GetParamStr(o, "NICNAME"));
Zero(&c, sizeof(c));
c.ClientAuth = t.ClientAuth;
c.ClientOption = t.ClientOption;
c.CheckServerCert = t.CheckServerCert;
c.RetryOnServerCert = t.RetryOnServerCert;
c.ServerCert = t.ServerCert;
c.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&c, &t);
ret = CcSetAccount(pc->RemoteClient, &c);
}
@@ -6447,13 +6445,7 @@ UINT PcAccountStatusShow(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
// Change the settings
t.ClientOption->HideStatusWindow = false;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -6505,13 +6497,7 @@ UINT PcAccountStatusHide(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
// Change the settings
t.ClientOption->HideStatusWindow = true;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -6569,13 +6555,7 @@ UINT PcAccountSecureCertSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *para
StrCpy(t.ClientAuth->SecurePrivateKeyName, sizeof(t.ClientAuth->SecurePrivateKeyName),
GetParamStr(o, "KEYNAME"));
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -6627,24 +6607,19 @@ UINT PcAccountOpensslEngineCertSet(CONSOLE *c, char *cmd_name, wchar_t *str, voi
{
RPC_CLIENT_CREATE_ACCOUNT z;
t.ClientAuth->AuthType = CLIENT_AUTHTYPE_OPENSSLENGINE;
X *x;
x = FileToXW(GetParamUniStr(o, "LOADCERT"));
if (x == NULL)
{
X *x;
x = FileToXW(GetParamUniStr(o, "LOADCERT"));
if (x == NULL)
{
c->Write(c, _UU("CMD_LOADCERT_FAILED"));
}
}
StrCpy(t.ClientAuth->OpensslEnginePrivateKeyName, sizeof(t.ClientAuth->OpensslEnginePrivateKeyName),
GetParamStr(o, "KEYNAME"));
StrCpy(t.ClientAuth->OpensslEngineName, sizeof(t.ClientAuth->OpensslEngineName),
GetParamStr(o, "ENGINENAME"));
t.ClientAuth->ClientX = CloneX(x);
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -6709,13 +6684,7 @@ UINT PcAccountRetrySet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
t.ClientOption->NumRetry = (num == 999) ? INFINITE : num;
t.ClientOption->RetryInterval = interval;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -6768,13 +6737,7 @@ UINT PcAccountStartupSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
// Change the settings
t.StartupAccount = true;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -6826,13 +6789,7 @@ UINT PcAccountStartupRemove(CONSOLE *c, char *cmd_name, wchar_t *str, void *para
// Change the settings
t.StartupAccount = false;
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
ret = CcSetAccount(pc->RemoteClient, &z);
}
@@ -6889,12 +6846,7 @@ UINT PcAccountExport(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
UINT buf_size;
UCHAR bom[] = {0xef, 0xbb, 0xbf, };
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
SetRpcClientCreateAccountFromGetAccount(&z, &t);
b = CiAccountToCfg(&z);
@@ -7698,6 +7650,8 @@ void PsMain(PS *ps)
{"CascadeProxySocks5", PsCascadeProxySocks5},
{"CascadeServerCertEnable", PsCascadeServerCertEnable},
{"CascadeServerCertDisable", PsCascadeServerCertDisable},
{"CascadeDefaultCAEnable", PsCascadeDefaultCAEnable},
{"CascadeDefaultCADisable", PsCascadeDefaultCADisable},
{"CascadeServerCertSet", PsCascadeServerCertSet},
{"CascadeServerCertDelete", PsCascadeServerCertDelete},
{"CascadeServerCertGet", PsCascadeServerCertGet},
@@ -13117,6 +13071,7 @@ UINT PsCascadeSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
t.ClientOption->Port = port;
StrCpy(t.ClientOption->Hostname, sizeof(t.ClientOption->Hostname), host);
t.ClientOption->HintStr[0] = 0;
StrCpy(t.ClientOption->HubName, sizeof(t.ClientOption->HubName), GetParamStr(o, "HUB"));
Free(host);
@@ -13223,7 +13178,18 @@ UINT PsCascadeGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
CtInsert(ct, _UU("CMD_ACCOUNT_COLUMN_NAME"), t.ClientOption->AccountName);
// Host name of the destination VPN Server
StrToUni(tmp, sizeof(tmp), t.ClientOption->Hostname);
if (IsEmptyStr(t.ClientOption->HintStr))
{
StrToUni(tmp, sizeof(tmp), t.ClientOption->Hostname);
}
else
{
char hostname[MAX_SIZE];
StrCpy(hostname, sizeof(hostname), t.ClientOption->Hostname);
StrCat(hostname, sizeof(hostname), "/");
StrCat(hostname, sizeof(hostname), t.ClientOption->HintStr);
StrToUni(tmp, sizeof(tmp), hostname);
}
CtInsert(ct, _UU("CMD_ACCOUNT_COLUMN_HOSTNAME"), tmp);
// The port number to connect to VPN Server
@@ -13263,6 +13229,12 @@ UINT PsCascadeGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
CtInsert(ct, _UU("CMD_ACCOUNT_COLUMN_SERVER_CERT_NAME"), tmp);
}
if (t.CheckServerCert)
{
CtInsert(ct, _UU("CMD_ACCOUNT_COLUMN_ADD_DEFAULT_CA"),
t.AddDefaultCA ? _UU("CMD_MSG_ENABLE") : _UU("CMD_MSG_DISABLE"));
}
// Device name to be used for the connection
StrToUni(tmp, sizeof(tmp), t.ClientOption->DeviceName);
CtInsert(ct, _UU("CMD_ACCOUNT_COLUMN_DEVICE_NAME"), tmp);
@@ -14681,6 +14653,134 @@ UINT PsCascadeServerCertDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *
return 0;
}
// Enable trusting default CA list for cascade connection
UINT PsCascadeDefaultCAEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
LIST *o;
PS *ps = (PS *)param;
UINT ret = 0;
RPC_CREATE_LINK t;
// Parameter list that can be specified
PARAM args[] =
{
// "name", prompt_proc, prompt_param, eval_proc, eval_param
{"[name]", CmdPrompt, _UU("CMD_CascadeCreate_Prompt_Name"), CmdEvalNotEmpty, NULL},
};
// If virtual HUB is not selected, it's an error
if (ps->HubName == NULL)
{
c->Write(c, _UU("CMD_Hub_Not_Selected"));
return ERR_INVALID_PARAMETER;
}
o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
Zero(&t, sizeof(t));
StrCpy(t.HubName, sizeof(t.HubName), ps->HubName);
t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), GetParamUniStr(o, "[name]"));
// RPC call
ret = ScGetLink(ps->Rpc, &t);
if (ret != ERR_NO_ERROR)
{
// An error has occured
CmdPrintError(c, ret);
FreeParamValueList(o);
return ret;
}
else
{
// Data change
t.AddDefaultCA = true;
ret = ScSetLink(ps->Rpc, &t);
if (ret != ERR_NO_ERROR)
{
// An error has occured
CmdPrintError(c, ret);
FreeParamValueList(o);
return ret;
}
FreeRpcCreateLink(&t);
}
FreeParamValueList(o);
return 0;
}
// Disable trusting default CA list for cascade connection
UINT PsCascadeDefaultCADisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
LIST *o;
PS *ps = (PS *)param;
UINT ret = 0;
RPC_CREATE_LINK t;
// Parameter list that can be specified
PARAM args[] =
{
// "name", prompt_proc, prompt_param, eval_proc, eval_param
{"[name]", CmdPrompt, _UU("CMD_CascadeCreate_Prompt_Name"), CmdEvalNotEmpty, NULL},
};
// If virtual HUB is not selected, it's an error
if (ps->HubName == NULL)
{
c->Write(c, _UU("CMD_Hub_Not_Selected"));
return ERR_INVALID_PARAMETER;
}
o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
Zero(&t, sizeof(t));
StrCpy(t.HubName, sizeof(t.HubName), ps->HubName);
t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), GetParamUniStr(o, "[name]"));
// RPC call
ret = ScGetLink(ps->Rpc, &t);
if (ret != ERR_NO_ERROR)
{
// An error has occured
CmdPrintError(c, ret);
FreeParamValueList(o);
return ret;
}
else
{
// Data change
t.AddDefaultCA = false;
ret = ScSetLink(ps->Rpc, &t);
if (ret != ERR_NO_ERROR)
{
// An error has occured
CmdPrintError(c, ret);
FreeParamValueList(o);
return ret;
}
FreeRpcCreateLink(&t);
}
FreeParamValueList(o);
return 0;
}
// Server-specific certificate settings of cascade connection
UINT PsCascadeServerCertSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
@@ -15434,7 +15534,11 @@ void CmdPrintStatusToListViewEx(CT *ct, RPC_CLIENT_GET_CONNECTION_STATUS *s, boo
}
else
{
if (StrLen(s->CipherName) != 0)
if (StrLen(s->CipherName) != 0 && StrLen(s->ProtocolName) != 0)
{
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_TRUE3"), s->ProtocolName, s->CipherName);
}
else if (StrLen(s->CipherName) != 0)
{
UniFormat(tmp, sizeof(tmp), _UU("CM_ST_USE_ENCRYPT_TRUE"), s->CipherName);
}
@@ -24273,6 +24377,12 @@ UINT PsConnect(CONSOLE *c, char *host, UINT port, char *hub, char *adminhub, wch
Zero(&o, sizeof(o));
UniStrCpy(o.AccountName, sizeof(o.AccountName), L"VPNCMD");
StrCpy(o.Hostname, sizeof(o.Hostname), host);
UINT i = SearchStrEx(o.Hostname, "/", 0, false);
if (i != INFINITE)
{
StrCpy(o.HintStr, sizeof(o.HintStr), o.Hostname + i + 1);
o.Hostname[i] = 0;
}
o.Port = port;
o.ProxyType = PROXY_DIRECT;
@@ -24331,7 +24441,7 @@ UINT PsConnect(CONSOLE *c, char *host, UINT port, char *hub, char *adminhub, wch
PS *ps;
// Success
ps = NewPs(c, rpc, host, port, hub, adminhub, cmdline);
ps = NewPs(c, rpc, o.Hostname, port, hub, adminhub, cmdline);
PsMain(ps);
retcode = ps->LastError;
FreePs(ps);
+5
View File
@@ -342,6 +342,7 @@ UINT PcNicDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcNicList(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountList(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountCreate(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
void SetRpcClientCreateAccountFromGetAccount(RPC_CLIENT_CREATE_ACCOUNT *c, RPC_CLIENT_GET_ACCOUNT *t);
UINT PcAccountSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountDelete(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
@@ -365,6 +366,8 @@ UINT PcAccountServerCertEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *p
UINT PcAccountServerCertDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountRetryOnServerCertEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountRetryOnServerCertDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountDefaultCAEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountDefaultCADisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountServerCertSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountServerCertDelete(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountServerCertGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
@@ -510,6 +513,8 @@ UINT PsCascadeProxySocks(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeProxySocks5(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeServerCertEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeServerCertDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeDefaultCAEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeDefaultCADisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeServerCertSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeServerCertDelete(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PsCascadeServerCertGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
+13 -2
View File
@@ -28,6 +28,7 @@
#include "Mayaqua/Object.h"
#include "Mayaqua/Pack.h"
#include "Mayaqua/Str.h"
#include "Mayaqua/Table.h"
#include "Mayaqua/Tick64.h"
#include <stdlib.h>
@@ -3047,11 +3048,16 @@ void ConnectionAccept(CONNECTION *c)
// Start the SSL communication
Copy(&s->SslAcceptSettings, &c->Cedar->SslAcceptSettings, sizeof(SSL_ACCEPT_SETTINGS));
if (StartSSLEx2(s, x, k, chain, 0, NULL) == false)
UINT ssl_err = 0;
if (StartSSLEx3(s, x, k, chain, 0, NULL, NULL, &ssl_err) == false)
{
// Failed
AddNoSsl(c->Cedar, &s->RemoteIP);
Debug("ConnectionAccept(): StartSSL() failed\n");
if (ssl_err != 0)
{
SLog(c->Cedar, "LS_SSL_START_ERROR", c->Name, GetUniErrorStr(ssl_err), ssl_err);
}
FreeX(x);
FreeK(k);
FreeXList(chain);
@@ -3063,7 +3069,7 @@ void ConnectionAccept(CONNECTION *c)
FreeK(k);
FreeXList(chain);
SLog(c->Cedar, "LS_SSL_START", c->Name, s->CipherName);
SLog(c->Cedar, "LS_SSL_START", c->Name, s->SslVersion, s->CipherName);
Copy(c->CToken_Hash, ctoken_hash, SHA1_SIZE);
@@ -3399,6 +3405,11 @@ void CleanupConnection(CONNECTION *c)
Free(c->CipherName);
}
if (c->SslVersion != NULL)
{
Free(c->SslVersion);
}
Free(c);
}
+2
View File
@@ -105,6 +105,7 @@ struct CLIENT_OPTION
char pad12[3];
UCHAR HostUniqueKey[SHA1_SIZE]; // Host unique key
char CustomHttpHeader[HTTP_CUSTOM_HEADER_MAX_SIZE]; // Custom HTTP proxy header
char HintStr[MAX_HOST_NAME_LEN + 1]; // Hint string for NAT-T
};
// Client authentication data
@@ -222,6 +223,7 @@ struct CONNECTION
X *ServerX; // Server certificate
X *ClientX; // Client certificate
char *CipherName; // Encryption algorithm name
char *SslVersion; // SSL protocol version
UINT64 ConnectedTick; // Time it is connected
IP ClientIp; // Client IP address
char ClientHostname[MAX_HOST_NAME_LEN + 1]; // Client host name
+1
View File
@@ -31,6 +31,7 @@ struct LINK
UINT CurrentSendPacketQueueSize; // Current send packet queue size
UINT LastError; // Last error
bool CheckServerCert; // To check the server certificate
bool AddDefaultCA; // Use default trust store
X *ServerCert; // Server certificate
bool LockFlag; // Lock flag
bool *StopAllLinkFlag; // Stop all link flag
+106 -113
View File
@@ -1573,6 +1573,12 @@ bool ServerAccept(CONNECTION *c)
c->CipherName = NULL;
if (c->SslVersion != NULL)
{
Free(c->SslVersion);
}
c->SslVersion = NULL;
if (IsEmptyStr(tmp) == false)
{
c->CipherName = CopyStr(tmp);
@@ -1592,11 +1598,22 @@ bool ServerAccept(CONNECTION *c)
}
c->CipherName = NULL;
if (c->SslVersion != NULL)
{
Free(c->SslVersion);
}
c->SslVersion = NULL;
if (c->FirstSock != NULL && IsEmptyStr(c->FirstSock->CipherName) == false)
{
c->CipherName = CopyStr(c->FirstSock->CipherName);
}
if (c->FirstSock != NULL && IsEmptyStr(c->FirstSock->SslVersion) == false)
{
c->SslVersion = CopyStr(c->FirstSock->SslVersion);
}
Format(radius_login_opt.In_VpnProtocolState, sizeof(radius_login_opt.In_VpnProtocolState),
"L%u:%s", IPC_LAYER_2, "SEVPN");
}
@@ -4297,7 +4314,6 @@ bool ClientCheckServerCert(CONNECTION *c, bool *expired)
X *x;
CHECK_CERT_THREAD_PROC *p;
THREAD *thread;
CEDAR *cedar;
bool ret;
UINT64 start;
// Validate arguments
@@ -4312,31 +4328,10 @@ bool ClientCheckServerCert(CONNECTION *c, bool *expired)
}
auth = c->Session->ClientAuth;
cedar = c->Cedar;
if (auth->CheckCertProc == NULL && c->Session->LinkModeClient == false)
if (auth->CheckCertProc == NULL)
{
// No checking function
return true;
}
if (c->Session->LinkModeClient && c->Session->Link->CheckServerCert == false)
{
// It's in cascade connection mode, but do not check the server certificate
return true;
}
if (c->UseTicket)
{
// Check the certificate of the redirected VPN server
if (CompareX(c->FirstSock->RemoteX, c->ServerX) == false)
{
return false;
}
else
{
return true;
}
return false;
}
x = CloneX(c->FirstSock->RemoteX);
@@ -4346,63 +4341,6 @@ bool ClientCheckServerCert(CONNECTION *c, bool *expired)
return false;
}
if (CheckXDateNow(x))
{
// Check whether it is signed by the root certificate to trust
if (c->Session->LinkModeClient == false)
{
// Normal VPN Client mode
if (CheckSignatureByCa(cedar, x))
{
// This certificate can be trusted because it is signed
FreeX(x);
return true;
}
}
else
{
// Cascade connection mode
if (CheckSignatureByCaLinkMode(c->Session, x))
{
// This certificate can be trusted because it is signed
FreeX(x);
return true;
}
}
}
if (c->Session->LinkModeClient)
{
if (CheckXDateNow(x))
{
Lock(c->Session->Link->lock);
{
if (c->Session->Link->ServerCert != NULL)
{
if (CompareX(c->Session->Link->ServerCert, x))
{
Unlock(c->Session->Link->lock);
// Exactly match the certificate that is registered in the cascade configuration
FreeX(x);
return true;
}
}
}
Unlock(c->Session->Link->lock);
}
else
{
if (expired != NULL)
{
*expired = true;
}
}
// Verification failure at this point in the case of cascade connection mode
FreeX(x);
return false;
}
p = ZeroMalloc(sizeof(CHECK_CERT_THREAD_PROC));
p->ServerX = x;
p->CheckCertProc = auth->CheckCertProc;
@@ -4420,7 +4358,8 @@ bool ClientCheckServerCert(CONNECTION *c, bool *expired)
{
// Send a NOOP periodically for disconnection prevention
start = Tick64();
ClientUploadNoop(c);
// Do not send because we now ask for user permission before sending signature
//ClientUploadNoop(c);
}
if (p->UserSelected)
{
@@ -4479,10 +4418,43 @@ REDIRECTED:
s = ClientConnectToServer(c);
if (s == NULL)
{
// Do not retry if untrusted or hostname mismatched
if (c->Session->LinkModeClient == false && (c->Err == ERR_CERT_NOT_TRUSTED || c->Err == ERR_HOSTNAME_MISMATCH)
&& (c->Session->Account == NULL || ! c->Session->Account->RetryOnServerCert))
{
c->Session->ForceStopFlag = true;
}
PrintStatus(sess, L"free");
return false;
}
PrintStatus(sess, _UU("STATUS_5"));
// Prompt user whether to continue on verification errors
if ((c->Err == ERR_CERT_NOT_TRUSTED || c->Err == ERR_HOSTNAME_MISMATCH || c->Err == ERR_SERVER_CERT_EXPIRES) && ClientCheckServerCert(c, &expired) == false)
{
if (expired)
{
c->Err = ERR_SERVER_CERT_EXPIRES;
}
// Do not retry if untrusted or hostname mismatched
if (c->Session->LinkModeClient == false && (c->Err == ERR_CERT_NOT_TRUSTED || c->Err == ERR_HOSTNAME_MISMATCH)
&& (c->Session->Account == NULL || ! c->Session->Account->RetryOnServerCert))
{
c->Session->ForceStopFlag = true;
}
goto CLEANUP;
}
// Check the certificate of the redirected VPN server
if (c->UseTicket && CompareX(s->RemoteX, c->ServerX) == false)
{
c->Err = ERR_CERT_NOT_TRUSTED;
goto CLEANUP;
}
Copy(&server_ip, &s->RemoteIP, sizeof(IP));
if (c->Halt)
@@ -4534,8 +4506,6 @@ REDIRECTED:
goto CLEANUP;
}
PrintStatus(sess, _UU("STATUS_5"));
// Receive a Hello packet
Debug("Downloading Hello...\n");
if (ClientDownloadHello(c, s) == false)
@@ -4571,27 +4541,6 @@ REDIRECTED:
// During user authentication
c->Session->ClientStatus = CLIENT_STATUS_AUTH;
// Verify the server certificate by the client
if (ClientCheckServerCert(c, &expired) == false)
{
if (expired == false)
{
c->Err = ERR_CERT_NOT_TRUSTED;
}
else
{
c->Err = ERR_SERVER_CERT_EXPIRES;
}
if (c->Session->LinkModeClient == false && c->Err == ERR_CERT_NOT_TRUSTED
&& (c->Session->Account == NULL || ! c->Session->Account->RetryOnServerCert))
{
c->Session->ForceStopFlag = true;
}
goto CLEANUP;
}
PrintStatus(sess, _UU("STATUS_6"));
// Send the authentication data
@@ -5045,6 +4994,13 @@ REDIRECTED:
}
c->CipherName = CopyStr(c->FirstSock->CipherName);
if (c->SslVersion != NULL)
{
Free(c->SslVersion);
}
c->SslVersion = CopyStr(c->FirstSock->SslVersion);
}
Unlock(c->lock);
@@ -6220,16 +6176,29 @@ SOCK *ClientConnectToServer(CONNECTION *c)
SetTimeout(s, CONNECTING_TIMEOUT);
// Start the SSL communication
if (StartSSLEx(s, x, k, 0, c->ServerName) == false)
UINT err = 0;
if (StartSSLEx3(s, x, k, NULL, 0, c->ServerName, c->Session->SslOption, &err) == false)
{
// SSL communication start failure
Disconnect(s);
ReleaseSock(s);
c->FirstSock = NULL;
c->Err = ERR_SERVER_IS_NOT_VPN;
if (err != 0)
{
c->Err = err;
}
else
{
c->Err = ERR_SERVER_IS_NOT_VPN;
}
return NULL;
}
if (err != 0)
{
c->Err = err;
}
if (s->RemoteX == NULL)
{
// SSL communication start failure
@@ -6240,6 +6209,8 @@ SOCK *ClientConnectToServer(CONNECTION *c)
return NULL;
}
CLog(c->Cedar->Client, "LC_SSL_CONNECTED", c->Session->ClientOption->AccountName, s->SslVersion, s->CipherName);
return s;
}
@@ -6299,6 +6270,7 @@ SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect)
if (o->ProxyType == PROXY_DIRECT)
{
UINT ssl_err = 0;
UINT nat_t_err = 0;
wchar_t tmp[MAX_SIZE];
UniFormat(tmp, sizeof(tmp), _UU("STATUS_4"), hostname);
@@ -6308,9 +6280,10 @@ SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect)
{
// If additional_connect == false, enable trying to NAT-T connection
// If additional_connect == true, follow the IsRUDPSession setting in this session
sock = TcpIpConnectEx(hostname, c->ServerPort,
// In additional connect or redirect we do not need ssl verification as the certificate is always compared with a saved one
sock = TcpIpConnectEx2(hostname, c->ServerPort,
(bool *)cancel_flag, c->hWndForUI, &nat_t_err, (additional_connect ? (!sess->IsRUDPSession) : false),
true, &resolved_ip);
true, ((additional_connect || c->UseTicket) ? NULL : sess->SslOption), &ssl_err, o->HintStr, &resolved_ip);
}
else
{
@@ -6333,7 +6306,14 @@ SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect)
// Connection failure
if (nat_t_err != RUDP_ERROR_NAT_T_TWO_OR_MORE)
{
c->Err = ERR_CONNECT_FAILED;
if (ssl_err != 0)
{
c->Err = ssl_err;
}
else
{
c->Err = ERR_CONNECT_FAILED;
}
}
else
{
@@ -6342,6 +6322,11 @@ SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect)
return NULL;
}
if (ssl_err != 0)
{
c->Err = ssl_err;
}
}
else
{
@@ -6446,23 +6431,31 @@ UINT ProxyCodeToCedar(UINT code)
// TCP connection function
SOCK *TcpConnectEx3(char *hostname, UINT port, UINT timeout, bool *cancel_flag, void *hWnd, bool no_nat_t, UINT *nat_t_error_code, bool try_start_ssl, IP *ret_ip)
{
return TcpConnectEx4(hostname, port, timeout, cancel_flag, hWnd, no_nat_t, nat_t_error_code, try_start_ssl, NULL, NULL, NULL, ret_ip);
}
SOCK *TcpConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, void *hWnd, bool no_nat_t, UINT *nat_t_error_code, bool try_start_ssl, SSL_VERIFY_OPTION *ssl_option, UINT *ssl_err, char *hint_str, IP *ret_ip)
{
#ifdef OS_WIN32
if (hWnd == NULL)
{
#endif // OS_WIN32
return ConnectEx4(hostname, port, timeout, cancel_flag, (no_nat_t ? NULL : VPN_RUDP_SVC_NAME), nat_t_error_code, try_start_ssl, true, ret_ip);
return ConnectEx5(hostname, port, timeout, cancel_flag, (no_nat_t ? NULL : VPN_RUDP_SVC_NAME), nat_t_error_code, try_start_ssl, true, ssl_option, ssl_err, hint_str, ret_ip);
#ifdef OS_WIN32
}
else
{
return WinConnectEx3((HWND)hWnd, hostname, port, timeout, 0, NULL, NULL, nat_t_error_code, (no_nat_t ? NULL : VPN_RUDP_SVC_NAME), try_start_ssl);
return WinConnectEx4((HWND)hWnd, hostname, port, timeout, 0, NULL, NULL, nat_t_error_code, (no_nat_t ? NULL : VPN_RUDP_SVC_NAME), try_start_ssl, ssl_option, ssl_err, hint_str);
}
#endif // OS_WIN32
}
// Connect with TCP/IP
SOCK *TcpIpConnectEx(char *hostname, UINT port, bool *cancel_flag, void *hWnd, UINT *nat_t_error_code, bool no_nat_t, bool try_start_ssl, IP *ret_ip)
{
return TcpIpConnectEx2(hostname, port, cancel_flag, hWnd, nat_t_error_code, no_nat_t, try_start_ssl, NULL, NULL, NULL, ret_ip);
}
SOCK *TcpIpConnectEx2(char *hostname, UINT port, bool *cancel_flag, void *hWnd, UINT *nat_t_error_code, bool no_nat_t, bool try_start_ssl, SSL_VERIFY_OPTION *ssl_option, UINT *ssl_err, char *hint_str, IP *ret_ip)
{
SOCK *s = NULL;
UINT dummy_int = 0;
@@ -6477,7 +6470,7 @@ SOCK *TcpIpConnectEx(char *hostname, UINT port, bool *cancel_flag, void *hWnd, U
return NULL;
}
s = TcpConnectEx3(hostname, port, 0, cancel_flag, hWnd, no_nat_t, nat_t_error_code, try_start_ssl, ret_ip);
s = TcpConnectEx4(hostname, port, 0, cancel_flag, hWnd, no_nat_t, nat_t_error_code, try_start_ssl, ssl_option, ssl_err, hint_str, ret_ip);
if (s == NULL)
{
return NULL;
+2
View File
@@ -114,6 +114,7 @@ bool ServerAccept(CONNECTION *c);
bool ClientConnect(CONNECTION *c);
SOCK *ClientConnectToServer(CONNECTION *c);
SOCK *TcpIpConnectEx(char *hostname, UINT port, bool *cancel_flag, void *hWnd, UINT *nat_t_error_code, bool no_nat_t, bool try_start_ssl, IP *ret_ip);
SOCK *TcpIpConnectEx2(char *hostname, UINT port, bool *cancel_flag, void *hWnd, UINT *nat_t_error_code, bool no_nat_t, bool try_start_ssl, SSL_VERIFY_OPTION *ssl_option, UINT *ssl_err, char *hint_str, IP *ret_ip);
bool ClientUploadSignature(SOCK *s);
bool ClientDownloadHello(CONNECTION *c, SOCK *s);
bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str);
@@ -121,6 +122,7 @@ bool ServerUploadHello(CONNECTION *c);
bool ClientUploadAuth(CONNECTION *c);
SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect);
SOCK *TcpConnectEx3(char *hostname, UINT port, UINT timeout, bool *cancel_flag, void *hWnd, bool no_nat_t, UINT *nat_t_error_code, bool try_start_ssl, IP *ret_ip);
SOCK *TcpConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, void *hWnd, bool no_nat_t, UINT *nat_t_error_code, bool try_start_ssl, SSL_VERIFY_OPTION *ssl_option, UINT *ssl_err, char *hint_str, IP *ret_ip);
UINT ProxyCodeToCedar(UINT code);
+41 -2
View File
@@ -10286,6 +10286,7 @@ bool SmLinkEdit(HWND hWnd, SM_HUB *s, wchar_t *name)
a.ClientAuth = CopyClientAuth(t.ClientAuth);
Copy(&a.Policy, &t.Policy, sizeof(POLICY));
a.CheckServerCert = t.CheckServerCert;
a.AddDefaultCA = t.AddDefaultCA;
a.ServerCert = CloneX(t.ServerCert);
a.HideTrustCert = GetCapsBool(s->p->CapsList, "b_support_config_hub");
FreeRpcCreateLink(&t);
@@ -19360,7 +19361,14 @@ void SmEditSettingDlgInit(HWND hWnd, SM_EDIT_SETTING *p)
SetText(hWnd, E_ACCOUNT_NAME, s->Title);
// Host name
SetTextA(hWnd, E_HOSTNAME, s->ClientOption.Hostname);
char hostname[MAX_SIZE];
StrCpy(hostname, sizeof(hostname), s->ClientOption.Hostname);
if (IsEmptyStr(s->ClientOption.HintStr) == false)
{
StrCat(hostname, sizeof(hostname), "/");
StrCat(hostname, sizeof(hostname), s->ClientOption.HintStr);
}
SetTextA(hWnd, E_HOSTNAME, hostname);
// Port number
CbSetHeight(hWnd, C_PORT, 18);
@@ -19450,6 +19458,16 @@ void SmEditSettingDlgUpdate(HWND hWnd, SM_EDIT_SETTING *p)
GetTxtA(hWnd, E_HOSTNAME, tmp, sizeof(tmp));
Trim(tmp);
UINT i = SearchStrEx(tmp, "/", 0, false);
if (i != INFINITE)
{
StrCpy(s->ClientOption.HintStr, sizeof(s->ClientOption.HintStr), tmp + i + 1);
tmp[i] = 0;
}
else
{
s->ClientOption.HintStr[0] = 0;
}
if (StrCmpi(tmp, s->ClientOption.Hostname) != 0)
{
@@ -20211,6 +20229,13 @@ void SmLoadSettingList()
if (s != NULL)
{
// Migrate from old settings that mixed hint string with hostname
UINT i = SearchStrEx(s->ClientOption.Hostname, "/", 0, false);
if (i != INFINITE)
{
StrCpy(s->ClientOption.HintStr, sizeof(s->ClientOption.HintStr), s->ClientOption.Hostname + i + 1);
s->ClientOption.Hostname[i] = 0;
}
Add(sm->SettingList, s);
}
FreeBuf(b);
@@ -20273,6 +20298,7 @@ void SmInitDefaultSettingList()
Sha0(s->HashedPassword, "", 0);
UniStrCpy(s->ClientOption.AccountName, sizeof(s->ClientOption.AccountName), s->Title);
StrCpy(s->ClientOption.Hostname, sizeof(s->ClientOption.Hostname), "localhost");
s->ClientOption.HintStr[0] = 0;
s->ClientOption.Port = GC_DEFAULT_PORT;
Add(sm->SettingList, s);
@@ -20362,7 +20388,14 @@ void SmRefreshSettingEx(HWND hWnd, wchar_t *select_name)
UniFormat(tmp, sizeof(tmp), _UU("SM_MODE_HUB"), s->HubName);
}
StrToUni(tmp2, sizeof(tmp2), s->ClientOption.Hostname);
char hostname[MAX_SIZE];
StrCpy(hostname, sizeof(hostname), s->ClientOption.Hostname);
if (IsEmptyStr(s->ClientOption.HintStr) == false)
{
StrCat(hostname, sizeof(hostname), "/");
StrCat(hostname, sizeof(hostname), s->ClientOption.HintStr);
}
StrToUni(tmp2, sizeof(tmp2), hostname);
LvInsertAdd(b,
(s->ServerAdminMode ? ICO_SERVER_ONLINE : ICO_HUB),
@@ -20781,6 +20814,12 @@ void SmParseCommandLine()
UniStrCpy(o->AccountName, sizeof(o->AccountName), s->Title);
StrCpy(o->Hostname, sizeof(o->Hostname), host);
UINT i = SearchStrEx(o->Hostname, "/", 0, false);
if (i != INFINITE)
{
StrCpy(o->HintStr, sizeof(o->HintStr), o->Hostname + i + 1);
o->Hostname[i] = 0;
}
o->Port = port;
o->ProxyType = PROXY_DIRECT;
StrCpy(o->DeviceName, sizeof(o->DeviceName), "DUMMY");
+1 -1
View File
@@ -41,7 +41,7 @@ typedef struct SETTING
char HubName[MAX_HUBNAME_LEN + 1]; // HUB name
UCHAR HashedPassword[SHA1_SIZE]; // Password
CLIENT_OPTION ClientOption; // Client Option
UCHAR Reserved[10240 - sizeof(UINT) * 8 - SHA1_SIZE - HTTP_CUSTOM_HEADER_MAX_SIZE]; // Reserved area
UCHAR Reserved[10240 - sizeof(UINT) * 8 - SHA1_SIZE - HTTP_CUSTOM_HEADER_MAX_SIZE - MAX_HOST_NAME_LEN - 1]; // Reserved area
} SETTING;
// Structure declaration
+4 -10
View File
@@ -3400,6 +3400,7 @@ void SiWriteHubLinkCfg(FOLDER *f, LINK *k)
}
CfgAddBool(f, "CheckServerCert", k->CheckServerCert);
CfgAddBool(f, "AddDefaultCA", k->AddDefaultCA);
if (k->ServerCert != NULL)
{
@@ -3450,6 +3451,7 @@ void SiLoadHubLinkCfg(FOLDER *f, HUB *h)
{
BUF *b;
k->CheckServerCert = CfgGetBool(f, "CheckServerCert");
k->AddDefaultCA = CfgGetBool(f, "AddDefaultCA");
b = CfgGetBuf(f, "ServerCert");
if (b != NULL)
{
@@ -3457,16 +3459,8 @@ void SiLoadHubLinkCfg(FOLDER *f, HUB *h)
FreeBuf(b);
}
if (online)
{
k->Offline = true;
SetLinkOnline(k);
}
else
{
k->Offline = false;
SetLinkOffline(k);
}
k->Offline = !online;
ReleaseLink(k);
}
+50 -11
View File
@@ -1270,6 +1270,13 @@ void CleanupSession(SESSION *s)
Free(s->ClientAuth);
}
if (s->SslOption != NULL)
{
FreeXList(s->SslOption->CaList);
FreeX(s->SslOption->SavedCert);
Free(s->SslOption);
}
FreeTraffic(s->Traffic);
Free(s->Name);
@@ -1949,23 +1956,55 @@ SESSION *NewClientSessionEx(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *au
{
s->ClientAuth->ClientX = CloneX(s->ClientAuth->ClientX);
}
if (s->ClientAuth->ClientK != NULL)
{
if (s->ClientAuth->AuthType != CLIENT_AUTHTYPE_OPENSSLENGINE)
{
s->ClientAuth->ClientK = CloneK(s->ClientAuth->ClientK);
}
else
{
s->ClientAuth->ClientK = OpensslEngineToK(s->ClientAuth->OpensslEnginePrivateKeyName, s->ClientAuth->OpensslEngineName);
}
}
if (s->ClientAuth->ClientK != NULL)
{
if (s->ClientAuth->AuthType != CLIENT_AUTHTYPE_OPENSSLENGINE)
{
s->ClientAuth->ClientK = CloneK(s->ClientAuth->ClientK);
}
else
{
s->ClientAuth->ClientK = OpensslEngineToK(s->ClientAuth->OpensslEnginePrivateKeyName, s->ClientAuth->OpensslEngineName);
}
}
if (StrCmpi(s->ClientOption->DeviceName, LINK_DEVICE_NAME) == 0)
{
// Link client mode
s->LinkModeClient = true;
s->Link = (LINK *)s->PacketAdapter->Param;
if (s->Link != NULL && s->Link->CheckServerCert && s->Link->Hub->HubDb != NULL)
{
// Enable SSL peer verification
s->SslOption = ZeroMalloc(sizeof(SSL_VERIFY_OPTION));
s->SslOption->VerifyPeer = true;
s->SslOption->AddDefaultCA = s->Link->AddDefaultCA;
s->SslOption->VerifyHostname = true;
s->SslOption->SavedCert = CloneX(s->Link->ServerCert);
// Copy trusted CA
LIST *o = s->Link->Hub->HubDb->RootCertList;
s->SslOption->CaList = CloneXList(o);
}
}
else
{
if (account != NULL && account->CheckServerCert)
{
// Enable SSL peer verification
s->SslOption = ZeroMalloc(sizeof(SSL_VERIFY_OPTION));
s->SslOption->VerifyPeer = true;
#ifdef OS_WIN32
s->SslOption->PromptOnVerifyFail = true;
#endif
s->SslOption->AddDefaultCA = account->AddDefaultCA;
s->SslOption->VerifyHostname = true;
s->SslOption->SavedCert = CloneX(account->ServerCert);
// Copy trusted CA
LIST *o = cedar->CaList;
s->SslOption->CaList = CloneXList(o);
}
}
if (StrCmpi(s->ClientOption->DeviceName, SNAT_DEVICE_NAME) == 0)
+1
View File
@@ -91,6 +91,7 @@ struct SESSION
char ClientIP[64]; // Client IP
CLIENT_OPTION *ClientOption; // Client connection options
CLIENT_AUTH *ClientAuth; // Client authentication data
SSL_VERIFY_OPTION *SslOption; // SSL verification option
volatile bool Halt; // Halting flag
volatile bool CancelConnect; // Cancel the connection
EVENT *HaltEvent; // Halting event
+8 -1
View File
@@ -1329,7 +1329,7 @@ void WinConnectDlgThread(THREAD *thread, void *param)
nat_t_svc_name = d->nat_t_svc_name;
}
s = ConnectEx3(d->hostname, d->port, d->timeout, &d->cancel, nat_t_svc_name, &nat_t_error_code, d->try_start_ssl, false);
s = ConnectEx5(d->hostname, d->port, d->timeout, &d->cancel, nat_t_svc_name, &nat_t_error_code, d->try_start_ssl, false, d->ssl_option, d->ssl_err, d->hint_str, NULL);
d->ret_sock = s;
d->nat_t_error_code = nat_t_error_code;
@@ -1398,6 +1398,10 @@ UINT WinConnectDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *
// TCP connection with showing the UI
SOCK *WinConnectEx3(HWND hWnd, char *server, UINT port, UINT timeout, UINT icon_id, wchar_t *caption, wchar_t *info, UINT *nat_t_error_code, char *nat_t_svc_name, bool try_start_ssl)
{
return WinConnectEx4(hWnd, server, port, timeout, icon_id, caption, info, nat_t_error_code, nat_t_svc_name, try_start_ssl, NULL, NULL, NULL);
}
SOCK *WinConnectEx4(HWND hWnd, char *server, UINT port, UINT timeout, UINT icon_id, wchar_t *caption, wchar_t *info, UINT *nat_t_error_code, char *nat_t_svc_name, bool try_start_ssl, SSL_VERIFY_OPTION *ssl_option, UINT *ssl_err, char *hint_str)
{
wchar_t tmp[MAX_SIZE];
wchar_t tmp2[MAX_SIZE];
@@ -1440,6 +1444,9 @@ SOCK *WinConnectEx3(HWND hWnd, char *server, UINT port, UINT timeout, UINT icon_
d.timeout = timeout;
d.hostname = server;
d.port = port;
d.ssl_option = ssl_option;
d.ssl_err = ssl_err;
d.hint_str = hint_str;
StrCpy(d.nat_t_svc_name, sizeof(d.nat_t_svc_name), nat_t_svc_name);
Dialog(hWnd, D_CONNECT, WinConnectDlgProc, &d);
+4
View File
@@ -331,6 +331,9 @@ typedef struct WINCONNECT_DLG_DATA
char nat_t_svc_name[MAX_SIZE];
UINT nat_t_error_code;
bool try_start_ssl;
SSL_VERIFY_OPTION *ssl_option;
UINT *ssl_err;
char *hint_str;
} WINCONNECT_DLG_DATA;
HBITMAP ResizeBitmap(HBITMAP hSrc, UINT src_x, UINT src_y, UINT dst_x, UINT dst_y);
@@ -694,6 +697,7 @@ HFONT GetMeiryoFontEx(UINT font_size);
HFONT GetMeiryoFontEx2(UINT font_size, bool bold);
bool ShowWindowsNetworkConnectionDialog();
SOCK *WinConnectEx3(HWND hWnd, char *server, UINT port, UINT timeout, UINT icon_id, wchar_t *caption, wchar_t *info, UINT *nat_t_error_code, char *nat_t_svc_name, bool try_start_ssl);
SOCK *WinConnectEx4(HWND hWnd, char *server, UINT port, UINT timeout, UINT icon_id, wchar_t *caption, wchar_t *info, UINT *nat_t_error_code, char *nat_t_svc_name, bool try_start_ssl, SSL_VERIFY_OPTION *ssl_option, UINT *ssl_err, char *hint_str);
UINT WinConnectDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param);
void WinConnectDlgThread(THREAD *thread, void *param);
void NicInfo(UI_NICINFO *info);