// Check whether some enterprise functions are restricted
//
// ** Hints by Daiyuu Nobori, written on March 19, 2014 **
//
// The following 'enterprise functions' are implemented on SoftEther VPN Server
// since March 19, 2014. However, these functions are disabled on
// SoftEther VPN Servers which run in Japan and China.
//
// - RADIUS / NT Domain user authentication
// - RSA certificate authentication
// - Deep-inspect packet logging
// - Source IP address control list
// - syslog transfer
//
// The SoftEther VPN Project intentionally disables these functions for users
// in Japan and China. The reason is: Daiyuu Nobori, the chief author of
// SoftEther VPN, has been liable to observe the existing agreements and
// restrictions between him and some companies. The agreements have regulated
// the region-limited restriction to implement and distribute the above
// enterprise functions on the SoftEther VPN open-source program.
//
// Therefore, the SoftEther VPN Project distributes the binary program and
// the source code with the "SiIsEnterpriseFunctionsRestrictedOnOpenSource"
// function. This function identifies whether the SoftEther VPN Server
// program is running in either Japan or China. If the restricted region is
// detected, then the above enterprise functions will be disabled.
//
// Please note that the above restriction has been imposed only on the
// original binaries and source codes from the SoftEther VPN Project.
// Anyone, except Daiyuu Nobori, who understands and writes the C language
// program can remove this restriction at his own risk.
//
bool SiIsEnterpriseFunctionsRestrictedOnOpenSource(CEDAR *c)
{
char region[128];
bool ret = false;
// Validate arguments
if (c == NULL)
{
return false;
}
SiGetCurrentRegion(c, region, sizeof(region));
if (StrCmpi(region, "JP") == 0 || StrCmpi(region, "RU") == 0)
{
ret = true;
}
return ret;
}
// Update the current region
void SiUpdateCurrentRegion(CEDAR *c, char *region, bool force_update)
{
bool changed = false;
// Validate arguments
if (c == NULL)
{
return;
}
if (IsEmptyStr(region) == false)
{
Lock(c->CurrentRegionLock);
{
if (StrCmpi(c->CurrentRegion, region) != 0)
{
StrCpy(c->CurrentRegion, sizeof(c->CurrentRegion), region);
changed = true;
}
}
Unlock(c->CurrentRegionLock);
}
if (force_update)
{
changed = true;
}
if (changed)
{
FlushServerCaps(c->Server);
}
}
// Create a server
SERVER *SiNewServer(bool bridge)
{
return SiNewServerEx(bridge, false, false);
}
SERVER *SiNewServerEx(bool bridge, bool in_client_inner_server, bool relay_server)
{
SERVER *s;
LISTENER *inproc;
LISTENER *azure;
LISTENER *rudp;
SetGetIpThreadMaxNum(DEFAULT_GETIP_THREAD_MAX_NUM);
s = ZeroMalloc(sizeof(SERVER));
SetEraserCheckInterval(0);
SiInitHubCreateHistory(s);
InitServerCapsCache(s);
Rand(s->MyRandomKey, sizeof(s->MyRandomKey));
s->lock = NewLock();
s->OpenVpnSstpConfigLock = NewLock();
s->SaveCfgLock = NewLock();
s->ref = NewRef();
s->Cedar = NewCedar(NULL, NULL);
s->Cedar->Server = s;
#ifdef OS_WIN32
s->IsInVm = MsIsInVm();
#else // OS_WIN32
s->IsInVm = UnixIsInVm();
#endif // OS_WIN32
#ifdef ENABLE_AZURE_SERVER
if (IsFileExists("@azureserver.config"))
{
DisableRDUPServerGlobally();
s->AzureServer = NewAzureServer(s->Cedar);
SleepThread(500);
}
#endif // ENABLE_AZURE_SERVER
s->Cedar->CheckExpires = true;
s->ServerListenerList = NewList(CompareServerListener);
s->StartTime = SystemTime64();
s->Syslog = NewSysLog(NULL, 0);
s->SyslogLock = NewLock();
s->TasksFromFarmControllerLock = NewLock();
if (bridge)
{
SetCedarVpnBridge(s->Cedar);
}
#ifdef OS_WIN32
if (IsHamMode() == false)
{
RegistWindowsFirewallAll();
}
#endif
s->Keep = StartKeep();
// Log related
MakeDir(bridge == false ? SERVER_LOG_DIR_NAME : BRIDGE_LOG_DIR_NAME);
s->Logger = NewLog(bridge == false ? SERVER_LOG_DIR_NAME : BRIDGE_LOG_DIR_NAME, SERVER_LOG_PERFIX, LOG_SWITCH_DAY);
SLog(s->Cedar, "L_LINE");
SLog(s->Cedar, "LS_START_2", s->Cedar->ServerStr, s->Cedar->VerString);
SLog(s->Cedar, "LS_START_3", s->Cedar->BuildInfo);
SLog(s->Cedar, "LS_START_UTF8");
SLog(s->Cedar, "LS_START_1");
// Initialize the configuration
SiInitConfiguration(s);
SetFifoCurrentReallocMemSize(MEM_FIFO_REALLOC_MEM_SIZE);
if (s->DisableIntelAesAcceleration)
{
// Disable the Intel AES acceleration
DisableIntelAesAccel();
}
// Raise the priority
if (s->NoHighPriorityProcess == false)
{
OSSetHighPriority();
}
#ifdef OS_UNIX
UnixSetHighOomScore();
#endif // OS_UNIX
if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
{
// Start a connection to the controller
s->FarmController = SiStartConnectToController(s);
}
else if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
{
FARM_MEMBER *f;
// Start operating as a controller
s->FarmMemberList = NewList(NULL);
f = ZeroMalloc(sizeof(FARM_MEMBER));
f->Cedar = s->Cedar;
GetMachineName(f->hostname, sizeof(f->hostname));
f->Me = true;
f->HubList = NewList(CompareHubList);
f->Weight = s->Weight;
s->Me = f;
Add(s->FarmMemberList, f);
SiStartFarmControl(s);
s->FarmControllerInited = true;
}
// Start a in-processlistener
inproc = NewListener(s->Cedar, LISTENER_INPROC, 0);
ReleaseListener(inproc);
// Start a listener for Azure
if (s->AzureClient != NULL)
{
azure = NewListener(s->Cedar, LISTENER_REVERSE, 0);
ReleaseListener(azure);
}
// Start a R-UDP listener
if (s->DisableNatTraversal == false && s->Cedar->Bridge == false)
{
rudp = NewListenerEx4(s->Cedar, LISTENER_RUDP, 0, TCPAcceptedThread, NULL, false, false,
&s->NatTGlobalUdpPort, RAND_PORT_ID_SERVER_LISTEN);
ReleaseListener(rudp);
}
// Start a VPN-over-ICMP listener
s->DynListenerIcmp = NewDynamicListener(s->Cedar, &s->EnableVpnOverIcmp, LISTENER_ICMP, 0);
// Start a VPN-over-DNS listener
s->DynListenerDns = NewDynamicListener(s->Cedar, &s->EnableVpnOverDns, LISTENER_DNS, 53);
SiInitDeadLockCheck(s);
SiUpdateCurrentRegion(s->Cedar, "", true);
return s;
}