Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/SoftEtherVPN/SoftEtherVPN_Stable.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Cedar/Protocol.c')
-rw-r--r--src/Cedar/Protocol.c191
1 files changed, 160 insertions, 31 deletions
diff --git a/src/Cedar/Protocol.c b/src/Cedar/Protocol.c
index ec078ab9..f11d5957 100644
--- a/src/Cedar/Protocol.c
+++ b/src/Cedar/Protocol.c
@@ -3,9 +3,9 @@
//
// SoftEther VPN Server, Client and Bridge are free software under GPLv2.
//
-// Copyright (c) 2012-2014 Daiyuu Nobori.
-// Copyright (c) 2012-2014 SoftEther VPN Project, University of Tsukuba, Japan.
-// Copyright (c) 2012-2014 SoftEther Corporation.
+// Copyright (c) 2012-2016 Daiyuu Nobori.
+// Copyright (c) 2012-2016 SoftEther VPN Project, University of Tsukuba, Japan.
+// Copyright (c) 2012-2016 SoftEther Corporation.
//
// All Rights Reserved.
//
@@ -842,24 +842,24 @@ void GenerateMachineUniqueHash(void *data)
{
BUF *b;
char name[64];
- char ip_str[64];
- IP ip;
OS_INFO *osinfo;
+ UINT64 iphash = 0;
// Validate arguments
if (data == NULL)
{
return;
}
+ iphash = GetHostIPAddressListHash();
+
b = NewBuf();
GetMachineName(name, sizeof(name));
- GetMachineIp(&ip);
- IPToStr(ip_str, sizeof(ip_str), &ip);
osinfo = GetOsInfo();
WriteBuf(b, name, StrLen(name));
- WriteBuf(b, ip_str, StrLen(ip_str));
+
+ WriteBufInt64(b, iphash);
WriteBuf(b, &osinfo->OsType, sizeof(osinfo->OsType));
WriteBuf(b, osinfo->KernelName, StrLen(osinfo->KernelName));
@@ -1265,6 +1265,7 @@ bool ServerAccept(CONNECTION *c)
RC4_KEY_PAIR key_pair;
UINT authtype;
POLICY *policy;
+ UINT assigned_vlan_id = 0;
HUB *hub;
SESSION *s = NULL;
UINT64 user_expires = 0;
@@ -1323,6 +1324,7 @@ bool ServerAccept(CONNECTION *c)
char *error_detail = NULL;
char *error_detail_2 = NULL;
char ctoken_hash_str[64];
+ EAP_CLIENT *release_me_eap_client = NULL;
// Validate arguments
if (c == NULL)
@@ -1330,6 +1332,8 @@ bool ServerAccept(CONNECTION *c)
return false;
}
+ GenerateMachineUniqueHash(unique2);
+
Zero(ctoken_hash_str, sizeof(ctoken_hash_str));
Zero(mschap_v2_server_response_20, sizeof(mschap_v2_server_response_20));
@@ -1593,6 +1597,16 @@ bool ServerAccept(CONNECTION *c)
goto CLEANUP;
}
+ if (hub->ForceDisableComm)
+ {
+ // Commnunication function is disabled
+ FreePack(p);
+ c->Err = ERR_SERVER_CANT_ACCEPT;
+ error_detail = "ERR_COMM_DISABLED";
+ ReleaseHub(hub);
+ goto CLEANUP;
+ }
+
if (GetGlobalServerFlag(GSF_DISABLE_AC) == 0)
{
if (hub->HubDb != NULL && c->FirstSock != NULL)
@@ -1623,6 +1637,8 @@ bool ServerAccept(CONNECTION *c)
USER *user;
USERGROUP *group;
char plain_password[MAX_PASSWORD_LEN + 1];
+ RADIUS_LOGIN_OPTION radius_login_opt;
+
if (hub->Halt || hub->Offline)
{
// HUB is off-line
@@ -1633,6 +1649,18 @@ bool ServerAccept(CONNECTION *c)
goto CLEANUP;
}
+ Zero(&radius_login_opt, sizeof(radius_login_opt));
+
+ if (hub->Option != NULL)
+ {
+ radius_login_opt.In_CheckVLanId = hub->Option->AssignVLanIdByRadiusAttribute;
+ radius_login_opt.In_DenyNoVlanId = hub->Option->DenyAllRadiusLoginWithNoVlanAssign;
+ if (hub->Option->UseHubNameAsRadiusNasId == true)
+ {
+ StrCpy(radius_login_opt.NasId, sizeof(radius_login_opt.NasId), hubname);
+ }
+ }
+
// Get the various flags
use_encrypt = PackGetInt(p, "use_encrypt") == 0 ? false : true;
use_compress = PackGetInt(p, "use_compress") == 0 ? false : true;
@@ -1652,6 +1680,14 @@ bool ServerAccept(CONNECTION *c)
if (c->IsInProc)
{
char tmp[MAX_SIZE];
+ UINT64 ptr;
+
+ ptr = PackGetInt64(p, "release_me_eap_client");
+ if (ptr != 0)
+ {
+ release_me_eap_client = (EAP_CLIENT *)ptr;
+ }
+
PackGetStr(p, "inproc_postfix", c->InProcPrefix, sizeof(c->InProcPrefix));
Zero(tmp, sizeof(tmp));
PackGetStr(p, "inproc_cryptname", tmp, sizeof(tmp));
@@ -1997,7 +2033,7 @@ bool ServerAccept(CONNECTION *c)
if (fail_ext_user_auth == false)
{
- auth_ret = SamAuthUserByPlainPassword(c, hub, username, plain_password, false, mschap_v2_server_response_20);
+ auth_ret = SamAuthUserByPlainPassword(c, hub, username, plain_password, false, mschap_v2_server_response_20, &radius_login_opt);
}
if (auth_ret && pol == NULL)
@@ -2028,7 +2064,7 @@ bool ServerAccept(CONNECTION *c)
// If there is asterisk user, log on as the user
if (b)
{
- auth_ret = SamAuthUserByPlainPassword(c, hub, username, plain_password, true, mschap_v2_server_response_20);
+ auth_ret = SamAuthUserByPlainPassword(c, hub, username, plain_password, true, mschap_v2_server_response_20, &radius_login_opt);
if (auth_ret && pol == NULL)
{
pol = SamGetUserPolicy(hub, "*");
@@ -2180,6 +2216,28 @@ bool ServerAccept(CONNECTION *c)
// Authentication success
FreePack(p);
+ // Check the assigned VLAN ID
+ if (radius_login_opt.Out_IsRadiusLogin)
+ {
+ if (radius_login_opt.In_CheckVLanId)
+ {
+ if (radius_login_opt.Out_VLanId != 0)
+ {
+ assigned_vlan_id = radius_login_opt.Out_VLanId;
+ }
+
+ if (radius_login_opt.In_DenyNoVlanId && assigned_vlan_id == 0 || assigned_vlan_id >= 4096)
+ {
+ // Deny this session
+ Unlock(hub->lock);
+ ReleaseHub(hub);
+ c->Err = ERR_ACCESS_DENIED;
+ error_detail = "In_DenyNoVlanId";
+ goto CLEANUP;
+ }
+ }
+ }
+
if (StrCmpi(username, ADMINISTRATOR_USERNAME) != 0)
{
// Get the policy
@@ -2468,8 +2526,6 @@ bool ServerAccept(CONNECTION *c)
policy->NoRouting = true;
}
- GenerateMachineUniqueHash(unique2);
-
if (Cmp(unique, unique2, SHA1_SIZE) == 0)
{
// It's a localhost session
@@ -2707,6 +2763,12 @@ bool ServerAccept(CONNECTION *c)
}
}
+ if (use_encrypt == false && c->FirstSock->IsReverseAcceptedSocket)
+ {
+ // On VPN Azure, SSL encryption is mandated.
+ use_encrypt = true;
+ }
+
if (use_client_license || use_bridge_license)
{
// Examine whether not to conflict with the limit of simultaneous connections
@@ -2859,6 +2921,18 @@ bool ServerAccept(CONNECTION *c)
// Remove the connection from Cedar
DelConnection(c->Cedar, c);
+ // VLAN ID
+ if (assigned_vlan_id != 0)
+ {
+ if (policy != NULL)
+ {
+ if (policy->VLanId == 0)
+ {
+ policy->VLanId = assigned_vlan_id;
+ }
+ }
+ }
+
// Create a Session
StrLower(username);
s = NewServerSessionEx(c->Cedar, c, hub, username, policy, c->IsInProc);
@@ -2867,6 +2941,8 @@ bool ServerAccept(CONNECTION *c)
s->LocalHostSession = local_host_session;
s->NormalClient = true;
+ IPToStr(s->ClientIP, sizeof(s->ClientIP), &c->ClientIp);
+
if (c->FirstSock->IsRUDPSocket)
{
// R-UDP session
@@ -2940,8 +3016,11 @@ bool ServerAccept(CONNECTION *c)
if (s->UseUdpAcceleration)
{
+ bool no_nat_t = false;
+
+
// Initialize the UDP acceleration function
- s->UdpAccel = NewUdpAccel(c->Cedar, (c->FirstSock->IsRUDPSocket ? NULL : &c->FirstSock->LocalIP), false, c->FirstSock->IsRUDPSocket, false);
+ s->UdpAccel = NewUdpAccel(c->Cedar, (c->FirstSock->IsRUDPSocket ? NULL : &c->FirstSock->LocalIP), false, c->FirstSock->IsRUDPSocket, no_nat_t);
if (s->UdpAccel == NULL)
{
s->UseUdpAcceleration = false;
@@ -3044,6 +3123,7 @@ bool ServerAccept(CONNECTION *c)
s->QoS = qos;
s->NoReconnectToSession = no_reconnect_to_session;
+
if (policy != NULL)
{
s->VLanId = policy->VLanId;
@@ -3239,6 +3319,11 @@ bool ServerAccept(CONNECTION *c)
NodeInfoToStr(tmp, sizeof(tmp), &s->NodeInfo);
HLog(hub, "LH_NODE_INFO", s->Name, tmp);
+
+ if (s->VLanId != 0)
+ {
+ HLog(hub, "LH_VLAN_ID", s->Name, s->VLanId);
+ }
}
// Shift the connection to the tunneling mode
@@ -3752,6 +3837,11 @@ CLEANUP:
SLog(c->Cedar, "LS_CONNECTION_ERROR", c->Name, GetUniErrorStr(c->Err), c->Err);
+ if (release_me_eap_client != NULL)
+ {
+ ReleaseEapClient(release_me_eap_client);
+ }
+
return ret;
}
@@ -5983,8 +6073,9 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
SOCK *s;
UINT num = 0, max = 19;
SERVER *server;
+ char hostname[64];
char *vpn_http_target = HTTP_VPN_TARGET2;
- bool check_hostname = false;
+ bool check_hostname = true;
// Validate arguments
if (c == NULL)
{
@@ -5992,13 +6083,15 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
}
-
+ strcpy(hostname, "");
server = c->Cedar->Server;
s = c->FirstSock;
while (true)
{
+ bool not_found_error = false;
+
num++;
if (num > max)
{
@@ -6020,7 +6113,6 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
if (check_hostname && (StrCmpi(h->Version, "HTTP/1.1") == 0 || StrCmpi(h->Version, "HTTP/1.2") == 0))
{
HTTP_VALUE *v;
- char hostname[64];
Zero(hostname, sizeof(hostname));
@@ -6042,6 +6134,8 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
}
+
+
// Interpret
if (StrCmpi(h->Method, "POST") == 0)
{
@@ -6067,7 +6161,7 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
return false;
}
// Check the Target
- if (StrCmpi(h->Target, vpn_http_target) != 0)
+ if ((StrCmpi(h->Target, vpn_http_target) != 0) || not_found_error)
{
// Target is invalid
HttpSendNotFound(s, h->Target);
@@ -6253,6 +6347,12 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
}
}
+ if ((b == false) && (StartWith(h->Target, "/wiki")))
+ {
+ HttpSendRedirect(s, h->Target, hostname);
+ b = true;
+ }
+
if (b == false)
{
// Not Found
@@ -6387,12 +6487,15 @@ SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect, bool no_tls
UINT nat_t_err = 0;
bool is_additonal_rudp_session = false;
UCHAR uc = 0;
+ IP ret_ip;
// Validate arguments
if (c == NULL)
{
return NULL;
}
+ Zero(&ret_ip, sizeof(IP));
+
sess = c->Session;
if (sess != NULL)
@@ -6405,12 +6508,25 @@ SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect, bool no_tls
o = c->Session->ClientOption;
+ if (additional_connect)
+ {
+ if (sess != NULL)
+ {
+ Copy(&ret_ip, &sess->ServerIP_CacheForNextConnect, sizeof(IP));
+ }
+ }
+
if (c->RestoreServerNameAndPort && additional_connect)
{
// Restore to the original server name and port number
c->RestoreServerNameAndPort = false;
- StrCpy(c->ServerName, sizeof(c->ServerName), o->Hostname);
+ if (StrCmpi(c->ServerName, o->Hostname) != 0)
+ {
+ StrCpy(c->ServerName, sizeof(c->ServerName), o->Hostname);
+ Zero(&ret_ip, sizeof(IP));
+ }
+
c->ServerPort = o->Port;
}
@@ -6430,7 +6546,7 @@ SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect, bool no_tls
// If additional_connect == true, follow the IsRUDPSession setting in this session
s = TcpIpConnectEx(host_for_direct_connection, port_for_direct_connection,
(bool *)cancel_flag, hWnd, &nat_t_err, (additional_connect ? (!is_additonal_rudp_session) : false),
- true, no_tls);
+ true, no_tls, &ret_ip);
}
}
else
@@ -6495,9 +6611,9 @@ SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect, bool no_tls
// SOCKS connection
- s = SocksConnectEx(c, host_for_direct_connection, port_for_direct_connection,
+ s = SocksConnectEx2(c, host_for_direct_connection, port_for_direct_connection,
c->ServerName, c->ServerPort, o->ProxyUsername,
- additional_connect, (bool *)cancel_flag, hWnd);
+ additional_connect, (bool *)cancel_flag, hWnd, 0, &ret_ip);
if (s == NULL)
{
// Connection failure
@@ -6522,6 +6638,19 @@ SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect, bool no_tls
Copy(&c->Session->ServerIP, &s->RemoteIP, sizeof(IP));
}
}
+
+ if (IsZeroIP(&ret_ip) == false)
+ {
+ if (c->Session != NULL)
+ {
+ if (additional_connect == false)
+ {
+ Copy(&c->Session->ServerIP_CacheForNextConnect, &ret_ip, sizeof(IP));
+
+ Debug("Saved ServerIP_CacheForNextConnect: %s = %r\n", c->ServerName, &ret_ip);
+ }
+ }
+ }
}
return s;
@@ -6542,12 +6671,12 @@ SOCK *SocksConnectEx(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
{
return SocksConnectEx2(c, proxy_host_name, proxy_port,
server_host_name, server_port, username, additional_connect, cancel_flag,
- hWnd, 0);
+ hWnd, 0, NULL);
}
SOCK *SocksConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
char *server_host_name, UINT server_port,
char *username, bool additional_connect,
- bool *cancel_flag, void *hWnd, UINT timeout)
+ bool *cancel_flag, void *hWnd, UINT timeout, IP *ret_ip)
{
SOCK *s = NULL;
IP ip;
@@ -6575,7 +6704,7 @@ SOCK *SocksConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
}
// Connection
- s = TcpConnectEx3(proxy_host_name, proxy_port, timeout, cancel_flag, hWnd, true, NULL, false, false);
+ s = TcpConnectEx3(proxy_host_name, proxy_port, timeout, cancel_flag, hWnd, true, NULL, false, false, ret_ip);
if (s == NULL)
{
// Failure
@@ -6779,7 +6908,7 @@ SOCK *ProxyConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
}
// Connection
- s = TcpConnectEx3(proxy_host_name, proxy_port, timeout, cancel_flag, hWnd, true, NULL, false, false);
+ s = TcpConnectEx3(proxy_host_name, proxy_port, timeout, cancel_flag, hWnd, true, NULL, false, false, NULL);
if (s == NULL)
{
// Failure
@@ -6931,15 +7060,15 @@ SOCK *ProxyConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
// TCP connection function
SOCK *TcpConnectEx2(char *hostname, UINT port, UINT timeout, bool *cancel_flag, void *hWnd, bool try_start_ssl, bool ssl_no_tls)
{
- return TcpConnectEx3(hostname, port, timeout, cancel_flag, hWnd, false, NULL, try_start_ssl, ssl_no_tls);
+ return TcpConnectEx3(hostname, port, timeout, cancel_flag, hWnd, false, NULL, try_start_ssl, ssl_no_tls, NULL);
}
-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, bool ssl_no_tls)
+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, bool ssl_no_tls, IP *ret_ip)
{
#ifdef OS_WIN32
if (hWnd == NULL)
{
#endif // OS_WIN32
- return ConnectEx3(hostname, port, timeout, cancel_flag, (no_nat_t ? NULL : VPN_RUDP_SVC_NAME), nat_t_error_code, try_start_ssl, ssl_no_tls, false);
+ return ConnectEx4(hostname, port, timeout, cancel_flag, (no_nat_t ? NULL : VPN_RUDP_SVC_NAME), nat_t_error_code, try_start_ssl, ssl_no_tls, true, ret_ip);
#ifdef OS_WIN32
}
else
@@ -6952,9 +7081,9 @@ SOCK *TcpConnectEx3(char *hostname, UINT port, UINT timeout, bool *cancel_flag,
// Connect with TCP/IP
SOCK *TcpIpConnect(char *hostname, UINT port, bool try_start_ssl, bool ssl_no_tls)
{
- return TcpIpConnectEx(hostname, port, NULL, NULL, NULL, false, try_start_ssl, ssl_no_tls);
+ return TcpIpConnectEx(hostname, port, NULL, NULL, NULL, false, try_start_ssl, ssl_no_tls, NULL);
}
-SOCK *TcpIpConnectEx(char *hostname, UINT port, bool *cancel_flag, void *hWnd, UINT *nat_t_error_code, bool no_nat_t, bool try_start_ssl, bool ssl_no_tls)
+SOCK *TcpIpConnectEx(char *hostname, UINT port, bool *cancel_flag, void *hWnd, UINT *nat_t_error_code, bool no_nat_t, bool try_start_ssl, bool ssl_no_tls, IP *ret_ip)
{
SOCK *s = NULL;
UINT dummy_int = 0;
@@ -6969,7 +7098,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, ssl_no_tls);
+ s = TcpConnectEx3(hostname, port, 0, cancel_flag, hWnd, no_nat_t, nat_t_error_code, try_start_ssl, ssl_no_tls, ret_ip);
if (s == NULL)
{
return NULL;