1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-08-25 22:12:58 +03:00

Merge PR #1911: Fix 7 vulnerabilities, add softether.net after-2038 year certificate hash, add vpncmd message about Developer Edition

This commit is contained in:
Davide Beatrici 2023-10-09 18:01:47 +02:00 committed by GitHub
commit 6a170ac691
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 774 additions and 91 deletions

View File

@ -726,9 +726,8 @@ void AdminWebProcPost(CONNECTION *c, SOCK *s, HTTP_HEADER *h, UINT post_data_siz
if (RecvAll(s, data, post_data_size, s->SecureMode))
{
c->JsonRpcAuthed = true;
#ifndef GC_SOFTETHER_OSS
RemoveDosEntry(c->Listener, s);
#endif // GC_SOFTETHER_OSS
// Divide url_target into URL and query string
StrCpy(url, sizeof(url), url_target);
@ -767,9 +766,8 @@ void AdminWebProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target)
}
c->JsonRpcAuthed = true;
#ifndef GC_SOFTETHER_OSS
RemoveDosEntry(c->Listener, s);
#endif // GC_SOFTETHER_OSS
// Divide url_target into URL and query string
StrCpy(url, sizeof(url), url_target);
@ -1199,9 +1197,7 @@ void JsonRpcProcOptions(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target
c->JsonRpcAuthed = true;
#ifndef GC_SOFTETHER_OSS
RemoveDosEntry(c->Listener, s);
#endif // GC_SOFTETHER_OSS
AdminWebSendBody(s, 200, "OK", NULL, 0, NULL, NULL, NULL, h);
}
@ -1228,9 +1224,7 @@ void JsonRpcProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target)
c->JsonRpcAuthed = true;
#ifndef GC_SOFTETHER_OSS
RemoveDosEntry(c->Listener, s);
#endif // GC_SOFTETHER_OSS
// Divide url_target into URL and query string
StrCpy(url, sizeof(url), url_target);
@ -1357,9 +1351,7 @@ void JsonRpcProcPost(CONNECTION *c, SOCK *s, HTTP_HEADER *h, UINT post_data_size
c->JsonRpcAuthed = true;
#ifndef GC_SOFTETHER_OSS
RemoveDosEntry(c->Listener, s);
#endif // GC_SOFTETHER_OSS
if (json_req == NULL || json_req_object == NULL)
{

View File

@ -322,6 +322,34 @@ void DecrementNoSsl(CEDAR *c, IP *ip, UINT num_dec)
UnlockList(c->NonSslList);
}
// Check whether the specified IP address is in Non-SSL connection list
bool IsInNoSsl(CEDAR *c, IP *ip)
{
bool ret = false;
// Validate arguments
if (c == NULL || ip == NULL)
{
return false;
}
LockList(c->NonSslList);
{
NON_SSL *n = SearchNoSslList(c, ip);
if (n != NULL)
{
if (n->EntryExpires > Tick64() && n->Count > NON_SSL_MIN_COUNT)
{
n->EntryExpires = Tick64() + (UINT64)NON_SSL_ENTRY_EXPIRES;
ret = true;
}
}
}
UnlockList(c->NonSslList);
return ret;
}
// Add new entry to Non-SSL connection list
bool AddNoSsl(CEDAR *c, IP *ip)
{
@ -704,6 +732,47 @@ void DelConnection(CEDAR *cedar, CONNECTION *c)
UnlockList(cedar->ConnectionList);
}
// Get the number of unestablished connections
UINT GetUnestablishedConnections(CEDAR *cedar)
{
UINT i, ret;
// Validate arguments
if (cedar == NULL)
{
return 0;
}
ret = 0;
LockList(cedar->ConnectionList);
{
for (i = 0;i < LIST_NUM(cedar->ConnectionList);i++)
{
CONNECTION *c = LIST_DATA(cedar->ConnectionList, i);
switch (c->Type)
{
case CONNECTION_TYPE_CLIENT:
case CONNECTION_TYPE_INIT:
case CONNECTION_TYPE_LOGIN:
case CONNECTION_TYPE_ADDITIONAL:
switch (c->Status)
{
case CONNECTION_STATUS_ACCEPTED:
case CONNECTION_STATUS_NEGOTIATION:
case CONNECTION_STATUS_USERAUTH:
ret++;
break;
}
break;
}
}
}
UnlockList(cedar->ConnectionList);
return ret + Count(cedar->AcceptingSockets);
}
// Add connection to Cedar
void AddConnection(CEDAR *cedar, CONNECTION *c)
{

View File

@ -1022,6 +1022,7 @@ void DelHubEx(CEDAR *c, HUB *h, bool no_lock);
void StopAllHub(CEDAR *c);
void StopAllConnection(CEDAR *c);
void AddConnection(CEDAR *cedar, CONNECTION *c);
UINT GetUnestablishedConnections(CEDAR *cedar);
void DelConnection(CEDAR *cedar, CONNECTION *c);
void SetCedarCipherList(CEDAR *cedar, char *name);
void InitCedar();
@ -1046,6 +1047,7 @@ bool AddNoSsl(CEDAR *c, IP *ip);
void DecrementNoSsl(CEDAR *c, IP *ip, UINT num_dec);
void DeleteOldNoSsl(CEDAR *c);
NON_SSL *SearchNoSslList(CEDAR *c, IP *ip);
bool IsInNoSsl(CEDAR *c, IP *ip);
void FreeTinyLog(TINY_LOG *t);
void WriteTinyLog(TINY_LOG *t, char *str);
TINY_LOG *NewTinyLog();

View File

@ -5155,6 +5155,22 @@ void CiRpcAccepted(CLIENT *c, SOCK *s)
retcode = 0;
}
if (retcode == 0)
{
if (IsLocalHostIP(&s->RemoteIP) == false)
{
// If the RPC client is from network check whether the password is empty
UCHAR empty_password_hash[20];
Sha0(empty_password_hash, "", 0);
if (Cmp(empty_password_hash, hashed_password, SHA1_SIZE) == 0 ||
IsZero(hashed_password, SHA1_SIZE))
{
// Regard it as incorrect password
retcode = 1;
}
}
}
Lock(c->lock);
{
if (c->Config.AllowRemoteConfig == false)
@ -5258,14 +5274,21 @@ void CiRpcServerThread(THREAD *thread, void *param)
// Open the port
listener = NULL;
for (i = CLIENT_CONFIG_PORT;i < (CLIENT_CONFIG_PORT + 5);i++)
if (c->Config.DisableRpcDynamicPortListener == false)
{
listener = Listen(i);
if (listener != NULL)
for (i = CLIENT_CONFIG_PORT;i < (CLIENT_CONFIG_PORT + 5);i++)
{
break;
listener = ListenEx(i, !c->Config.AllowRemoteConfig);
if (listener != NULL)
{
break;
}
}
}
else
{
listener = ListenEx(CLIENT_CONFIG_PORT, !c->Config.AllowRemoteConfig);
}
if (listener == NULL)
{
@ -9028,6 +9051,12 @@ void CiInitConfiguration(CLIENT *c)
c->Config.UseKeepConnect = false; // Don't use the connection maintenance function by default in the Client
// Eraser
c->Eraser = NewEraser(c->Logger, 0);
#ifdef OS_WIN32
c->Config.DisableRpcDynamicPortListener = false;
#else // OS_WIN32
c->Config.DisableRpcDynamicPortListener = true;
#endif // OS_WIN32
}
else
{
@ -9174,6 +9203,19 @@ void CiLoadClientConfig(CLIENT_CONFIG *c, FOLDER *f)
c->AllowRemoteConfig = CfgGetBool(f, "AllowRemoteConfig");
c->KeepConnectInterval = MAKESURE(CfgGetInt(f, "KeepConnectInterval"), KEEP_INTERVAL_MIN, KEEP_INTERVAL_MAX);
c->NoChangeWcmNetworkSettingOnWindows8 = CfgGetBool(f, "NoChangeWcmNetworkSettingOnWindows8");
if (CfgIsItem(f, "DisableRpcDynamicPortListener"))
{
c->DisableRpcDynamicPortListener = CfgGetBool(f, "DisableRpcDynamicPortListener");
}
else
{
#ifdef OS_WIN32
c->DisableRpcDynamicPortListener = false;
#else // OS_WIN32
c->DisableRpcDynamicPortListener = true;
#endif // OS_WIN32
}
}
// Read the client authentication data
@ -9748,6 +9790,7 @@ void CiWriteClientConfig(FOLDER *cc, CLIENT_CONFIG *config)
CfgAddBool(cc, "AllowRemoteConfig", config->AllowRemoteConfig);
CfgAddInt(cc, "KeepConnectInterval", config->KeepConnectInterval);
CfgAddBool(cc, "NoChangeWcmNetworkSettingOnWindows8", config->NoChangeWcmNetworkSettingOnWindows8);
CfgAddBool(cc, "DisableRpcDynamicPortListener", config->DisableRpcDynamicPortListener);
}
// Write the client authentication data

View File

@ -87,6 +87,7 @@ struct CLIENT_CONFIG
UINT KeepConnectProtocol; // Protocol
UINT KeepConnectInterval; // Interval
bool NoChangeWcmNetworkSettingOnWindows8; // Don't change the WCM network settings on Windows 8
bool DisableRpcDynamicPortListener;
};
// Version acquisition

View File

@ -24496,6 +24496,34 @@ void CmdPrintAbout(CONSOLE *c)
c->Write(c, tmp);
// Showing an explanation of the purpose of the Developer Edition and the difference from the Stable Editon by Daiyuu Nobori
/*
* Welcome to the Developer Edition of SoftEther VPN.
Please note: SoftEther VPN Developer Edition (Version 5.x) has accepted
great code contributions on GitHub from many excellent open source
developers. This edition contains some very bright experimental code.
The experimental code in this Developer Edition has *NOT* been fully
reviewed by Daiyuu Nobori (the first original author of SoftEther VPN)
and has not been endorsed by him for stability and quality. It is his
policy to encourage many developers to contribute code with their
creative minds and ambitions. The succession of low-level system
software and network developers is of critical importance worldwide,
and SoftEther VPN Developer Edition is very important to increase
the number of such great developers.
- If you are a programmer of VPN software, or if you want a variety of
experimental code, this edition is very suitable for you.
- On the other hand, if you are building VPNs for mission-critical
business systems that require stability and security,
Stable Edition (Version 4.x) is highly recommended.
- All code in Stable Edition is reviewed by Daiyuu Nobori. He is also
responsible for porting features from the Developer Edition
to the Stable Edition.
- SoftEther VPN Stable Edition can be downloaded at:
https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/
*/
c->Write(c, L"\nWelcome to the Developer Edition of SoftEther VPN.\n\nPlease note: SoftEther VPN Developer Edition (Version 5.x) has accepted\ngreat code contributions on GitHub from many excellent open source\ndevelopers. This edition contains some very bright experimental code.\n The experimental code in this Developer Edition has *NOT* been fully\nreviewed by Daiyuu Nobori (the first original author of SoftEther VPN)\nand has not been endorsed by him for stability and quality. It is his\npolicy to encourage many developers to contribute code with their\ncreative minds and ambitions. The succession of low-level system\nsoftware and network developers is of critical importance worldwide,\nand SoftEther VPN Developer Edition is very important to increase\nthe number of such great developers.\n- If you are a programmer of VPN software, or if you want a variety of\n experimental code, this edition is very suitable for you.\n- On the other hand, if you are building VPNs for mission-critical\n business systems that require stability and security,\n Stable Edition (Version 4.x) is highly recommended.\n- All code in Stable Edition is reviewed by Daiyuu Nobori. He is also\n responsible for porting features from the Developer Edition\n to the Stable Edition.\n- SoftEther VPN Stable Edition can be downloaded at:\n https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/\n\n");
ReleaseCedar(cedar);
}

View File

@ -541,13 +541,9 @@ UINT DCRegister(DDNS_CLIENT *c, bool ipv6, DDNS_REGISTER_PARAM *p, char *replace
}
}
Format(url2, sizeof(url2), "%s?v=%I64u", url, Rand64());
Format(url3, sizeof(url3), url2, key_hash_str[2], key_hash_str[3]);
ReplaceStr(url3, sizeof(url3), url3, "https://", "http://");
ReplaceStr(url3, sizeof(url3), url3, ".servers", ".open.servers");
cert_hash = StrToBin(DDNS_CERT_HASH);

View File

@ -18,7 +18,11 @@
"439BAFA75A6EE5671FC9F9A02D34FF29881761A0" \
"EFAC5FA0CDD14E0F864EED58A73C35D7E33B62F3" \
"74DF99D4B1B5F0488A388B50D347D26013DC67A5" \
"6EBB39AFCA8C900635CFC11218CF293A612457E4"
"6EBB39AFCA8C900635CFC11218CF293A612457E4" \
"05A9386C5E2B233F7BAB2479620EAAA2793709ED" \
"A811C64BB715351E36B6C1E022648D8BE0ACD128" \
"BD264DB3B0B1B3ABA0AF3074AA574ED1EF3B42D7" \
"9AB61D691536645DD55A8730FC6D2CDF33C8C73F"
#define DDNS_SNI_VER_STRING "DDNS"
@ -43,7 +47,7 @@
#define DDNS_URL2_V4_ALT "http://get-my-ip.ddns.uxcom.jp/ddns/getmyip.ashx"
#define DDNS_URL2_V6_ALT "http://get-my-ip-v6.ddns.uxcom.jp/ddns/getmyip.ashx"
#define DDNS_RPC_MAX_RECV_SIZE DYN32(DDNS_RPC_MAX_RECV_SIZE, (128 * 1024 * 1024))
#define DDNS_RPC_MAX_RECV_SIZE DYN32(DDNS_RPC_MAX_RECV_SIZE, (38 * 1024 * 1024))
// Connection Timeout
#define DDNS_CONNECT_TIMEOUT DYN32(DDNS_CONNECT_TIMEOUT, (15 * 1000))

View File

@ -17,6 +17,7 @@
#include "Mayaqua/Memory.h"
#include "Mayaqua/Object.h"
#include "Mayaqua/Str.h"
#include "Mayaqua/Tick64.h"
static bool disable_dos = false;
static UINT max_connections_per_ip = DEFAULT_MAX_CONNECTIONS_PER_IP;
@ -181,6 +182,11 @@ void TCPAcceptedThread(THREAD *t, void *param)
ConnectionAccept(c);
flag1 = c->flag1;
if (c->JsonRpcAuthed)
{
RemoveDosEntry(r, s);
}
// Release
SLog(r->Cedar, "LS_CONNECTION_END_1", c->Name);
ReleaseListener(c->Listener);
@ -221,6 +227,46 @@ void TCPAccepted(LISTENER *r, SOCK *s)
num_clients_from_this_ip = GetNumIpClient(&s->RemoteIP);
#ifdef USE_DOS_ATTACK_DETECTION
if (disable_dos == false && r->DisableDos == false && r->Protocol != LISTENER_INPROC)
{
UINT max_uec, now_uec;
// DOS attack check
if (CheckDosAttack(r, s) == false)
{
Debug("DOS Attack 1 !!\n");
IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
SLog(r->Cedar, "LS_LISTENER_DOS", r->Port, tmp, s->RemotePort);
return;
}
if (StrCmpi(s->UnderlayProtocol, SOCK_UNDERLAY_NATIVE_V6) == 0 ||
StrCmpi(s->UnderlayProtocol, SOCK_UNDERLAY_NATIVE_V4) == 0)
{
if (IsInNoSsl(r->Cedar, &s->RemoteIP))
{
Debug("DOS Attack 2 !!\n");
IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
SLog(r->Cedar, "LS_LISTENER_DOS", r->Port, tmp, s->RemotePort);
return;
}
}
if (num_clients_from_this_ip > GetMaxConnectionsPerIp())
{
Debug("DOS Attack 3 !!\n");
IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
SLog(r->Cedar, "LS_LISTENER_DOS", r->Port, tmp, s->RemotePort);
return;
}
max_uec = GetMaxUnestablishedConnections();
now_uec = GetUnestablishedConnections(cedar);
if (now_uec > max_uec)
{
Debug("DOS Attack 4 !!\n");
SLog(r->Cedar, "LS_LISTENER_MAXUEC", max_uec, now_uec);
return;
}
}
#endif // USE_DOS_ATTACK_DETECTION
IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
@ -239,6 +285,169 @@ void TCPAccepted(LISTENER *r, SOCK *s)
ReleaseThread(t);
}
// Remove a DOS entry
bool RemoveDosEntry(LISTENER *r, SOCK *s)
{
DOS *d;
bool ok = false;
// Validate arguments
if (r == NULL || s == NULL)
{
return false;
}
LockList(r->DosList);
{
// Delete old entries from the DOS attack list
RefreshDosList(r);
// Search the table
d = SearchDosList(r, &s->RemoteIP);
if (d != NULL)
{
Delete(r->DosList, d);
Free(d);
ok = true;
}
}
UnlockList(r->DosList);
return ok;
}
// Check whether this is a DOS attack
bool CheckDosAttack(LISTENER *r, SOCK *s)
{
DOS *d;
bool ok = true;
// Validate arguments
if (r == NULL || s == NULL)
{
return false;
}
LockList(r->DosList);
{
// Delete old entries from the DOS attack list
RefreshDosList(r);
// Search the table
d = SearchDosList(r, &s->RemoteIP);
if (d != NULL)
{
// There is a entry already
// This should mean being under a DOS attack
d->LastConnectedTick = Tick64();
d->CurrentExpireSpan = MIN(d->CurrentExpireSpan * (UINT64)2, DOS_TABLE_EXPIRES_MAX);
d->AccessCount++;
if (d->AccessCount > DOS_TABLE_MAX_LIMIT_PER_IP)
{
ok = false;
}
}
else
{
// Create a new entry
d = ZeroMalloc(sizeof(DOS));
d->CurrentExpireSpan = (UINT64)DOS_TABLE_EXPIRES_FIRST;
d->FirstConnectedTick = d->LastConnectedTick = Tick64();
d->AccessCount = 1;
d->DeleteEntryTick = d->FirstConnectedTick + (UINT64)DOS_TABLE_EXPIRES_TOTAL;
Copy(&d->IpAddress, &s->RemoteIP, sizeof(IP));
Add(r->DosList, d);
}
}
UnlockList(r->DosList);
return ok;
}
// Delete old entries from the DOS attack list
void RefreshDosList(LISTENER *r)
{
// Validate arguments
if (r == NULL)
{
return;
}
if (r->DosListLastRefreshTime == 0 ||
(r->DosListLastRefreshTime + (UINT64)DOS_TABLE_REFRESH_INTERVAL) <= Tick64())
{
UINT i;
LIST *o;
r->DosListLastRefreshTime = Tick64();
o = NewListFast(NULL);
for (i = 0;i < LIST_NUM(r->DosList);i++)
{
DOS *d = LIST_DATA(r->DosList, i);
if ((d->LastConnectedTick + d->CurrentExpireSpan) <= Tick64() ||
(d->DeleteEntryTick <= Tick64()))
{
Add(o, d);
}
}
for (i = 0;i < LIST_NUM(o);i++)
{
DOS *d = LIST_DATA(o, i);
Delete(r->DosList, d);
Free(d);
}
ReleaseList(o);
}
}
// Search the DOS attack list by the IP address
DOS *SearchDosList(LISTENER *r, IP *ip)
{
DOS *d, t;
// Validate arguments
if (r == NULL || ip == NULL)
{
return NULL;
}
Copy(&t.IpAddress, ip, sizeof(IP));
d = Search(r->DosList, &t);
if (d != NULL)
{
if ((d->LastConnectedTick + d->CurrentExpireSpan) <= Tick64() ||
(d->DeleteEntryTick <= Tick64()))
{
// Delete old entries
Delete(r->DosList, d);
Free(d);
return NULL;
}
}
return d;
}
// Comparison of DOS attack list entries
int CompareDos(void *p1, void *p2)
{
DOS *d1, *d2;
if (p1 == NULL || p2 == NULL)
{
return 0;
}
d1 = *(DOS **)p1;
d2 = *(DOS **)p2;
if (d1 == NULL || d2 == NULL)
{
return 0;
}
return CmpIpAddr(&d1->IpAddress, &d2->IpAddress);
}
// UDP listener main loop
void ListenerUDPMainLoop(LISTENER *r)
@ -653,6 +862,13 @@ void CleanupListener(LISTENER *r)
return;
}
// Release the DOS attack list
for (i = 0;i < LIST_NUM(r->DosList);i++)
{
DOS *d = LIST_DATA(r->DosList, i);
Free(d);
}
ReleaseList(r->DosList);
if (r->Sock != NULL)
{
@ -802,6 +1018,7 @@ LISTENER *NewListenerEx5(CEDAR *cedar, UINT proto, UINT port, THREAD_PROC *proc,
r->Port = port;
r->Event = NewEvent();
r->DosList = NewList(CompareDos);
r->LocalOnly = local_only;
r->ShadowIPv6 = shadow_ipv6;

View File

@ -10,12 +10,24 @@
#include "CedarType.h"
#include "Mayaqua/MayaType.h"
#include "Mayaqua/Kernel.h"
#include "Mayaqua/Network.h"
// Function to call when receiving a new connection
typedef void (NEW_CONNECTION_PROC)(CONNECTION *c);
// DOS attack list
struct DOS
{
IP IpAddress; // IP address
UINT64 FirstConnectedTick; // Time which a client connects at the first time
UINT64 LastConnectedTick; // Time which a client connected at the last time
UINT64 CurrentExpireSpan; // Current time-out period of this record
UINT64 DeleteEntryTick; // Time planned to delete this entry
UINT AccessCount; // The number of accesses
};
// Listener structure
struct LISTENER
@ -31,6 +43,8 @@ struct LISTENER
volatile bool Halt; // Halting flag
UINT Status; // State
LIST *DosList; // DOS attack list
UINT64 DosListLastRefreshTime; // Time that the DOS list is refreshed at the last
THREAD_PROC *ThreadProc; // Thread procedure
void *ThreadParam; // Thread parameters
@ -105,6 +119,11 @@ void FreeDynamicListener(DYNAMIC_LISTENER *d);
bool ListenerRUDPRpcRecvProc(RUDP_STACK *r, UDPPACKET *p);
void ListenerSetProcRecvRpcEnable(bool b);
int CompareDos(void *p1, void *p2);
DOS *SearchDosList(LISTENER *r, IP *ip);
void RefreshDosList(LISTENER *r);
bool CheckDosAttack(LISTENER *r, SOCK *s);
bool RemoveDosEntry(LISTENER *r, SOCK *s);
#endif // LISTENER_H

View File

@ -313,8 +313,16 @@ BUF *WpcDataEntryToBuf(WPC_ENTRY *e)
}
data_size = e->Size + 4096;
data = Malloc(data_size);
size = DecodeSafe64(data, e->Data, e->Size);
data = ZeroMalloc(data_size);
if (e->Size >= 1)
{
size = DecodeSafe64(data, e->Data, e->Size);
}
else
{
size = 0;
}
b = NewBuf();
WriteBuf(b, data, size);

View File

@ -712,7 +712,8 @@ UINT RsaPublicSize(K *k)
// Hash a pointer to a 32-bit
UINT HashPtrToUINT(void *p)
{
UCHAR hash_data[MD5_SIZE];
UCHAR hash_data[SHA256_SIZE];
UCHAR hash_src[CANARY_RAND_SIZE + sizeof(void *)];
UINT ret;
// Validate arguments
if (p == NULL)
@ -720,7 +721,11 @@ UINT HashPtrToUINT(void *p)
return 0;
}
Md5(hash_data, &p, sizeof(p));
Zero(hash_src, sizeof(hash_src));
Copy(hash_src + 0, GetCanaryRand(CANARY_RAND_ID_PTR_KEY_HASH), CANARY_RAND_SIZE);
Copy(hash_src + CANARY_RAND_SIZE, p, sizeof(void *));
Sha2_256(hash_data, hash_src, sizeof(hash_src));
Copy(&ret, hash_data, sizeof(ret));

View File

@ -2100,7 +2100,31 @@ void AbortExitEx(char *msg)
f = fopen("abort_error_log.txt", "w");
if (f != NULL)
{
SYSTEMTIME time = { 0 };
char time_str[128] = { 0 };
char *crlf = "\r\n";
char *tag = "---------";
LocalTime(&time);
sprintf(time_str, "%04u-%02u-%02u %02u:%02u:%02u",
time.wYear, time.wMonth, time.wDay,
time.wHour, time.wMinute, time.wSecond);
fwrite(tag, 1, strlen(tag), f);
fwrite(crlf, 1, strlen(crlf), f);
fwrite(time_str, 1, strlen(time_str), f);
fwrite(crlf, 1, strlen(crlf), f);
fwrite(msg, 1, strlen(msg), f);
fwrite(crlf, 1, strlen(crlf), f);
fwrite(crlf, 1, strlen(crlf), f);
fclose(f);
}

View File

@ -123,11 +123,7 @@ typedef int (COMPARE)(void *p1, void *p2);
#define GET_ABS(a) ((a) >= 0 ? (a) : -(a))
// Convert the pointer to UINT
#ifdef CPU_64
#define POINTER_TO_KEY(p) HashPtrToUINT(p)
#else
#define POINTER_TO_KEY(p) (UINT)(p)
#endif
#define POINTER_TO_KEY(p) (HashPtrToUINT(p))
// Compare the pointer and UINT
#define COMPARE_POINTER_AND_KEY(p, i) (POINTER_TO_KEY(p) == (i))
@ -282,7 +278,8 @@ typedef struct TRACKING_LIST TRACKING_LIST;
typedef struct IO IO;
// Memory.h
typedef struct MEMTAG MEMTAG;
typedef struct MEMTAG1 MEMTAG1;
typedef struct MEMTAG2 MEMTAG2;
typedef struct BUF BUF;
typedef struct FIFO FIFO;
typedef struct LIST LIST;

View File

@ -65,6 +65,8 @@ void InitProcessCallOnce()
{
init_proc_once_flag = true;
InitCanaryRand();
#ifdef OS_WIN32
MsInitProcessCallOnce();
#endif // OS_WIN32

View File

@ -16,10 +16,16 @@
#include "Object.h"
#include "OS.h"
#include "Str.h"
#include "Tick64.h"
#include "Tracking.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef OS_UNIX
#include <sys/time.h>
#endif
#include <zlib.h>
@ -34,6 +40,105 @@
static UINT fifo_current_realloc_mem_size = FIFO_REALLOC_MEM_SIZE;
static bool canary_inited = false;
typedef struct CANARY_RAND_DATA
{
UCHAR Data[CANARY_RAND_SIZE + 4];
} CANARY_RAND_DATA;
static CANARY_RAND_DATA canary_rand_data[NUM_CANARY_RAND] = { 0 };
static UINT64 canary_memtag_magic1 = 0;
static UINT64 canary_memtag_magic2 = 0;
UCHAR *GetCanaryRand(UINT id)
{
if (id >= NUM_CANARY_RAND)
{
id = NUM_CANARY_RAND - 1;
}
return &((canary_rand_data[id].Data)[0]);
}
void InitCanaryRand()
{
SYSTEMTIME st = { 0 };
char random_seed[1024] = { 0 };
UINT64 t1 = 0, t2 = 0;
if (canary_inited)
{
return;
}
#ifdef OS_WIN32
Win32GetSystemTime(&st);
memcpy(&t1, ((UCHAR *)&st) + 0, 8);
memcpy(&t2, ((UCHAR *)&st) + 8, 8);
#else // OS_WIN32
struct timeval tv = { 0 };
struct timezone tz = { 0 };
gettimeofday(&tv, &tz);
t1 = (UINT64)tv.tv_sec;
t2 = (UINT64)tv.tv_usec;
#endif // OS_WIN32
{
UINT64 dos_rand = (UINT64)rand();
UINT64 tick1 = TickHighresNano64(true);
UINT64 tick2 = TickHighresNano64(true);
UINT i;
void *p1 = malloc(1);
void *p2 = malloc(1);
for (i = 0;i < NUM_CANARY_RAND;i++)
{
// using sprintf() here is safe.
sprintf(random_seed,
"%u "
"%llu "
"%llu "
"%llu "
"%llu "
"%llu "
"%llu "
"%llu "
"%llu "
"%llu "
"%llu "
"%llu "
"%u "
,
i,
(UINT64)InitCanaryRand,
(UINT64)&canary_inited,
(UINT64) & ((canary_rand_data[0].Data)[0]),
(UINT64)&random_seed[0],
tick1,
tick2,
dos_rand,
(UINT64)p1,
(UINT64)p2,
t1,
t2,
~i
);
Sha0(canary_rand_data[i].Data, random_seed, (UINT)strlen(random_seed));
}
free(p1);
free(p2);
canary_memtag_magic1 = *((UINT64 *)(GetCanaryRand(CANARY_RAND_ID_MEMTAG_MAGIC) + 0));
canary_memtag_magic2 = *((UINT64 *)(GetCanaryRand(CANARY_RAND_ID_MEMTAG_MAGIC) + 8));
canary_inited = true;
}
}
// New PRand
PRAND *NewPRand(void *key, UINT key_size)
{
@ -3114,6 +3219,10 @@ void AdjustBufSize(BUF *b, UINT new_size)
while (b->SizeReserved < new_size)
{
if (b->SizeReserved > 0x7FFFFFFF)
{
AbortExitEx("AdjustBufSize(): too large buffer size");
}
b->SizeReserved = b->SizeReserved * 2;
}
b->Buf = ReAlloc(b->Buf, b->SizeReserved);
@ -3515,33 +3624,52 @@ void *Malloc(UINT size)
}
void *MallocEx(UINT size, bool zero_clear_when_free)
{
MEMTAG *tag;
MEMTAG1 *tag1;
MEMTAG2 *tag2;
UINT real_size;
if (canary_inited == false)
{
InitCanaryRand();
}
if (size > MAX_MALLOC_MEM_SIZE)
{
AbortExitEx("MallocEx() error: too large size");
}
real_size = CALC_MALLOCSIZE(size);
tag = InternalMalloc(real_size);
tag1 = InternalMalloc(real_size);
Zero(tag, sizeof(MEMTAG));
tag->Magic = MEMTAG_MAGIC;
tag->Size = size;
tag->ZeroFree = zero_clear_when_free;
tag1->Magic = canary_memtag_magic1 ^ ((UINT64)tag1 * GOLDEN_RATION_PRIME_U64);
tag1->Size = size;
tag1->ZeroFree = zero_clear_when_free;
return MEMTAG_TO_POINTER(tag);
tag2 = (MEMTAG2 *)(((UCHAR *)tag1) + CALC_MALLOCSIZE(tag1->Size) - sizeof(MEMTAG2));
tag2->Magic = canary_memtag_magic2 ^ ((UINT64)tag2 * GOLDEN_RATION_PRIME_U64);
return MEMTAG1_TO_POINTER(tag1);
}
// Get memory size
UINT GetMemSize(void *addr)
{
MEMTAG *tag;
MEMTAG1 *tag;
if (canary_inited == false)
{
InitCanaryRand();
}
// Validate arguments
if (IS_NULL_POINTER(addr))
{
return 0;
}
tag = POINTER_TO_MEMTAG(addr);
CheckMemTag(tag);
tag = POINTER_TO_MEMTAG1(addr);
CheckMemTag1(tag);
return tag->Size;
}
@ -3549,20 +3677,35 @@ UINT GetMemSize(void *addr)
// ReAlloc
void *ReAlloc(void *addr, UINT size)
{
MEMTAG *tag;
MEMTAG1 *tag1;
MEMTAG2 *tag2;
bool zerofree;
if (canary_inited == false)
{
InitCanaryRand();
}
if (size > MAX_MALLOC_MEM_SIZE)
{
AbortExitEx("ReAlloc() error: too large size");
}
// Validate arguments
if (IS_NULL_POINTER(addr))
{
return NULL;
}
tag = POINTER_TO_MEMTAG(addr);
CheckMemTag(tag);
tag1 = POINTER_TO_MEMTAG1(addr);
CheckMemTag1(tag1);
zerofree = tag->ZeroFree;
tag2 = (MEMTAG2 *)(((UCHAR *)tag1) + CALC_MALLOCSIZE(tag1->Size) - sizeof(MEMTAG2));
CheckMemTag2(tag2);
if (tag->Size == size)
zerofree = tag1->ZeroFree;
if (tag1->Size == size)
{
// No size change
return addr;
@ -3574,10 +3717,10 @@ void *ReAlloc(void *addr, UINT size)
// Size changed (zero clearing required)
void *new_p = MallocEx(size, true);
if (tag->Size <= size)
if (tag1->Size <= size)
{
// Size expansion
Copy(new_p, addr, tag->Size);
Copy(new_p, addr, tag1->Size);
}
else
{
@ -3593,13 +3736,22 @@ void *ReAlloc(void *addr, UINT size)
else
{
// Size changed
MEMTAG *tag2 = InternalReAlloc(tag, CALC_MALLOCSIZE(size));
MEMTAG1 *tag1_new;
MEMTAG2 *tag2_new;
Zero(tag2, sizeof(MEMTAG));
tag2->Magic = MEMTAG_MAGIC;
tag2->Size = size;
tag1->Magic = 0;
tag2->Magic = 0;
return MEMTAG_TO_POINTER(tag2);
tag1_new = InternalReAlloc(tag1, CALC_MALLOCSIZE(size));
tag1_new->Magic = canary_memtag_magic1 ^ ((UINT64)tag1_new * GOLDEN_RATION_PRIME_U64);
tag1_new->Size = size;
tag1_new->ZeroFree = 0;
tag2_new = (MEMTAG2 *)(((UCHAR *)tag1_new) + CALC_MALLOCSIZE(size) - sizeof(MEMTAG2));
tag2_new->Magic = canary_memtag_magic2 ^ ((UINT64)tag2_new * GOLDEN_RATION_PRIME_U64);
return MEMTAG1_TO_POINTER(tag1_new);
}
}
}
@ -3607,25 +3759,35 @@ void *ReAlloc(void *addr, UINT size)
// Free
void Free(void *addr)
{
MEMTAG *tag;
MEMTAG1 *tag1;
MEMTAG2 *tag2;
// Validate arguments
if (IS_NULL_POINTER(addr))
{
return;
}
tag = POINTER_TO_MEMTAG(addr);
CheckMemTag(tag);
if (canary_inited == false)
{
InitCanaryRand();
}
if (tag->ZeroFree)
tag1 = POINTER_TO_MEMTAG1(addr);
CheckMemTag1(tag1);
tag2 = (MEMTAG2 *)(((UCHAR *)tag1) + CALC_MALLOCSIZE(tag1->Size) - sizeof(MEMTAG2));
CheckMemTag2(tag2);
if (tag1->ZeroFree)
{
// Zero clear
Zero(addr, tag->Size);
Zero(addr, tag1->Size);
}
// Memory release
tag->Magic = 0;
InternalFree(tag);
tag1->Magic = 0;
tag2->Magic = 0;
InternalFree(tag1);
}
// Free and set pointer's value to NULL
@ -3635,24 +3797,36 @@ void FreeSafe(void **addr)
*addr = NULL;
}
// Check the memtag
void CheckMemTag(MEMTAG *tag)
// Check the memtag1
void CheckMemTag1(MEMTAG1 *tag)
{
if (IsTrackingEnabled() == false)
{
return;
}
// Validate arguments
if (tag == NULL)
{
AbortExitEx("CheckMemTag: tag == NULL");
AbortExitEx("CheckMemTag1: tag1 == NULL");
return;
}
if (tag->Magic != MEMTAG_MAGIC)
if (tag->Magic != (canary_memtag_magic1 ^ ((UINT64)tag * GOLDEN_RATION_PRIME_U64)))
{
AbortExitEx("CheckMemTag: tag->Magic != MEMTAG_MAGIC");
AbortExitEx("CheckMemTag1: tag1->Magic != canary_memtag_magic1");
return;
}
}
// Check the memtag2
void CheckMemTag2(MEMTAG2 *tag)
{
// Validate arguments
if (tag == NULL)
{
AbortExitEx("CheckMemTag2: tag2 == NULL");
return;
}
if (tag->Magic != (canary_memtag_magic2 ^ ((UINT64)tag * GOLDEN_RATION_PRIME_U64)))
{
AbortExitEx("CheckMemTag2: tag2->Magic != canary_memtag_magic2");
return;
}
}

View File

@ -14,29 +14,38 @@
#define MallocFast Malloc
#define ZeroMallocFast ZeroMalloc
#define MAX_MALLOC_MEM_SIZE (0xffffffff - 64)
// Memory size that can be passed to the kernel at a time
#define MAX_SEND_BUF_MEM_SIZE (10 * 1024 * 1024)
// The magic number for memory tag
#define MEMTAG_MAGIC 0x49414449
#define CALC_MALLOCSIZE(size) ((MAX(size, 1)) + sizeof(MEMTAG))
#define MEMTAG_TO_POINTER(p) ((void *)(((UCHAR *)(p)) + sizeof(MEMTAG)))
#define POINTER_TO_MEMTAG(p) ((MEMTAG *)(((UCHAR *)(p)) - sizeof(MEMTAG)))
#define IS_NULL_POINTER(p) (((p) == NULL) || ((POINTER_TO_UINT64(p) == (UINT64)sizeof(MEMTAG))))
#define CALC_MALLOCSIZE(size) (((MAX(size, 1) + 7) / 8) * 8 + sizeof(MEMTAG1) + sizeof(MEMTAG2))
#define MEMTAG1_TO_POINTER(p) ((void *)(((UCHAR *)(p)) + sizeof(MEMTAG1)))
#define POINTER_TO_MEMTAG1(p) ((MEMTAG1 *)(((UCHAR *)(p)) - sizeof(MEMTAG1)))
#define IS_NULL_POINTER(p) (((p) == NULL) || ((POINTER_TO_UINT64(p) == (UINT64)sizeof(MEMTAG1))))
#define PTR_TO_PTR(p) ((void **)(&p))
// Golden Ratio Prime
// From https://github.com/torvalds/linux/blob/88c5083442454e5e8a505b11fa16f32d2879651e/include/linux/hash.h
#define GOLDEN_RATION_PRIME_U32 ((UINT32)0x61C88647)
#define GOLDEN_RATION_PRIME_U64 ((UINT64)7046029254386353131ULL) // 0x61C8864680B583EB
// Fixed size of a block of memory pool
#define MEMPOOL_MAX_SIZE 3000
// Memory tag
struct MEMTAG
// Memory tag 1
struct MEMTAG1
{
UINT Magic;
UINT64 Magic;
UINT Size;
bool ZeroFree;
UINT Padding;
};
// Memory tag 2
struct MEMTAG2
{
UINT64 Magic;
};
// Buffer
@ -174,7 +183,8 @@ void *ZeroMallocEx(UINT size, bool zero_clear_when_free);
void *ReAlloc(void *addr, UINT size);
void Free(void *addr);
void FreeSafe(void **addr);
void CheckMemTag(MEMTAG *tag);
void CheckMemTag1(MEMTAG1 *tag);
void CheckMemTag2(MEMTAG2 *tag);
UINT GetMemSize(void *addr);
void *InternalMalloc(UINT size);
@ -364,5 +374,14 @@ LIST *NewStrList();
void ReleaseStrList(LIST *o);
bool AddStrToStrListDistinct(LIST *o, char *str);
#define NUM_CANARY_RAND 32
#define CANARY_RAND_ID_MEMTAG_MAGIC 0
#define CANARY_RAND_SIZE 20
#define CANARY_RAND_ID_PTR_KEY_HASH 1
void InitCanaryRand();
UCHAR *GetCanaryRand(UINT id);
#endif // MEMORY_H

View File

@ -1191,7 +1191,9 @@ void RUDPProcess_NatT_Recv(RUDP_STACK *r, UDPPACKET *udp)
bool is_ok = PackGetBool(p, "ok");
UINT64 tran_id = PackGetInt64(p, "tran_id");
ExtractAndApplyDynList(p);
// This ExtractAndApplyDynList() calling was removed because it is not actually used and could be abused by
// illegal UDP packets that spoof the source IP address. 2023-6-14 Daiyuu Nobori
// ExtractAndApplyDynList(p);
if (r->ServerMode)
{

View File

@ -34,6 +34,23 @@ UINT64 TickHighres64()
}
UINT64 TickHighresNano64(bool raw)
{
UINT64 ret = 0;
#ifdef OS_WIN32
ret = (UINT64)(MsGetHiResTimeSpan(MsGetHiResCounter()) * 1000000000.0f);
#else // OS_WIN32
ret = UnixGetHighresTickNano64(raw);
#endif // OS_WIN32
return ret;
}
// Convert the Tick value to time
UINT64 Tick64ToTime64(UINT64 tick)
{

View File

@ -49,6 +49,7 @@ UINT64 Diff64(UINT64 a, UINT64 b);
UINT64 Tick64ToTime64(UINT64 tick);
UINT64 TickToTime(UINT64 tick);
UINT64 TickHighres64();
UINT64 TickHighresNano64(bool raw);
#endif // TICK64_H

View File

@ -2008,6 +2008,68 @@ void UnixGetSystemTime(SYSTEMTIME *system_time)
pthread_mutex_unlock(&get_time_lock);
}
UINT64 UnixGetHighresTickNano64(bool raw)
{
#if defined(OS_WIN32) || defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC) || defined(CLOCK_HIGHRES)
struct timespec t;
UINT64 ret;
static bool akirame = false;
if (akirame)
{
return UnixGetTick64() * 1000000ULL;
}
Zero(&t, sizeof(t));
if (raw == false)
{
// Function to get the boot time of the system
// Be careful. The Implementation is depend on the system.
#ifdef CLOCK_HIGHRES
clock_gettime(CLOCK_HIGHRES, &t);
#else // CLOCK_HIGHRES
#ifdef CLOCK_MONOTONIC
clock_gettime(CLOCK_MONOTONIC, &t);
#else // CLOCK_MONOTONIC
clock_gettime(CLOCK_REALTIME, &t);
#endif // CLOCK_MONOTONIC
#endif // CLOCK_HIGHRES
}
else
{
// Function to get the boot time of the system
// Be careful. The Implementation is depend on the system.
#ifdef CLOCK_HIGHRES
clock_gettime(CLOCK_HIGHRES, &t);
#else // CLOCK_HIGHRES
#ifdef CLOCK_MONOTONIC_RAW
clock_gettime(CLOCK_MONOTONIC_RAW, &t);
#else // CLOCK_MONOTONIC_RAW
#ifdef CLOCK_MONOTONIC
clock_gettime(CLOCK_MONOTONIC, &t);
#else // CLOCK_MONOTONIC
clock_gettime(CLOCK_REALTIME, &t);
#endif // CLOCK_MONOTONIC
#endif // CLOCK_MONOTONIC_RAW
#endif // CLOCK_HIGHRES
}
ret = ((UINT64)((UINT)t.tv_sec)) * 1000000000LL + (UINT64)t.tv_nsec;
if (akirame == false && ret == 0)
{
ret = UnixGetTick64() * 1000000ULL;
akirame = true;
}
return ret;
#else
return UnixGetTick64() * 1000000ULL;
#endif
}
// Get the system timer (64bit)
UINT64 UnixGetTick64()
{

View File

@ -117,6 +117,7 @@ void UnixSetThreadPriorityRealtime();
void UnixSetResourceLimit(UINT id, UINT64 value);
bool UnixIs64BitRlimSupported();
UINT64 UnixGetTick64();
UINT64 UnixGetHighresTickNano64(bool raw);
void UnixSigChldHandler(int sig);
void UnixCloseIO();
void UnixGetCurrentDir(char *dir, UINT size);

View File

@ -2482,7 +2482,7 @@ STATIC1 您可以更改 VPN Client 的设置
STATIC2 远程管理(&E)
STATIC3 您可以通过使用 VPN Client 管理器远程模式从另一台计算机上远程管理 VPN Client 服务程序。
R_ALLOW_REMOTE_CONFIG 允许 VPN Client 服务的远程管理(&R)
S_WARNING 建议您在允许远程管理时设置密码。在菜单里选择“工具” >“设置密码”来设置密码。
S_WARNING 如果你允许远程管理,你必须设置一个密码。在菜单里选择“工具” >“设置密码”来设置密码。必须重新启动 VPN Client 服务,以应用远程管理可用性的配置变化。
STATIC4 在通讯闲置一段时间后自动断开互联网连接的环境下,可以通过向互联网上任意主机发送假数据包的方式来保持互联网连接。
R_USE_KEEP_CONNECT 使用保持 Internet 连接功能(&K)
S_HOSTNAME 主机名(&H):
@ -7028,13 +7028,13 @@ CMD_AccountImport_OK 连接设置 "%s" 已导入。
# RemoteEnable 命令
CMD_RemoteEnable 允许 VPN 客户服务的远程管理
CMD_RemoteEnable_Help 对 VPN Client 服务,从本地主机以外的远程计算机上,允许通过命令行管理设施或 VPN Client 管理器员进行连接和管理。
CMD_RemoteEnable_Help 对 VPN Client 服务,从本地主机以外的远程计算机上,允许通过命令行管理设施或 VPN Client 管理器员进行连接和管理。必须重新启动 VPN Client 服务,以应用远程管理可用性的配置变化。如果你允许远程管理,你必须设置一个密码。
CMD_RemoteEnable_Args RemoteEnable
# RemoteDisable 命令
CMD_RemoteDisable 禁止 VPN 客户服务的远程管理
CMD_RemoteDisable_Help 对 VPN Client 服务,从本地主机以外的远程计算机上,禁止通过命令行管理设施或 VPN Client 管理器员进行连接和管理。
CMD_RemoteDisable_Help 对 VPN Client 服务,从本地主机以外的远程计算机上,禁止通过命令行管理设施或 VPN Client 管理器员进行连接和管理。必须重新启动 VPN 客户端服务,以应用远程管理可用性的配置变化。
CMD_RemoteDisable_Args RemoteDisable

View File

@ -2466,7 +2466,7 @@ STATIC1 You can modify the settings for VPN Client.
STATIC2 R&emote Management:
STATIC3 You can remotely manage the VPN Client Service Program from another computer by using VPN Client Manager Remote Mode.
R_ALLOW_REMOTE_CONFIG Allow &Remote Management of VPN Client Service
S_WARNING It is recommended to set a password if you allow remote management. From the menu bar, choose Tools -> Set Password to set the password.
S_WARNING You must set a password if you allow remote management. From the menu bar, choose Tools -> Set Password to set the password. The VPN Client service must be restarted to apply the change of remote management availability.
STATIC4 For environments where Internet connections will automatically be disconnected when idle, you can keep alive the Internet connection by sending dummy packets to any host on the Internet.
R_USE_KEEP_CONNECT Use &Keep Alive Internet Connection Function
S_HOSTNAME &Host Name:
@ -7016,13 +7016,13 @@ CMD_AccountImport_OK The VPN Connection Setting "%s" has been imported.
# RemoteEnable command
CMD_RemoteEnable Allow Remote Management of VPN Client Service
CMD_RemoteEnable_Help Use this to allow management of a VPN Client service from a remote computer that is not localhost, via a remote connection by Command Line Management Utility or VPN Client Manager.
CMD_RemoteEnable_Help Use this to allow management of a VPN Client service from a remote computer that is not localhost, via a remote connection by Command Line Management Utility or VPN Client Manager. The VPN Client service must be restarted to apply the change of remote management availability. You must set a password if you allow remote management.
CMD_RemoteEnable_Args RemoteEnable
# RemoteDisable command
CMD_RemoteDisable Deny Remote Management of VPN Client Service
CMD_RemoteDisable_Help Use this to deny management of a VPN Client service from a remote computer that is not localhost, via a remote connection by Command Line Management Utility or VPN Client Manager.
CMD_RemoteDisable_Help Use this to deny management of a VPN Client service from a remote computer that is not localhost, via a remote connection by Command Line Management Utility or VPN Client Manager. The VPN Client service must be restarted to apply the change of remote management availability.
CMD_RemoteDisable_Args RemoteDisable

View File

@ -2469,7 +2469,7 @@ STATIC1 VPN Client の動作に関する設定を変更できます。
STATIC2 リモート管理の設定(&E)
STATIC3 VPN Client サービスプログラムを別のコンピュータ上から VPN クライアント接続マネージャによってリモート管理することが可能です。
R_ALLOW_REMOTE_CONFIG VPN Client サービスのリモート管理を許可する(&R)
S_WARNING リモート管理を許可する場合、パスワードを設定しておくことを強くお勧めします。パスワードは [ツール] メニューの [パスワードの設定] をクリックして設定することができます。
S_WARNING リモート管理を許可する場合、パスワードを設定する必要があります。パスワードは [ツール] メニューの [パスワードの設定] をクリックして設定することができます。リモート管理の可否の変更の設定適用には、VPN Client サービスを再起動する必要があります。
STATIC4 一定期間無通信状態が続くと接続が自動的に切断されるようなネットワーク接続環境の場合、インターネット上の任意のサーバーに対して一定間隔ごとにパケットを送信することにより、インターネット接続を維持することができます。
R_USE_KEEP_CONNECT インターネット接続の維持機能を使用する(&K)
S_HOSTNAME ホスト名(&H):
@ -7022,13 +7022,13 @@ CMD_AccountImport_OK 接続設定 "%s" としてインポートしました。
# RemoteEnable コマンド
CMD_RemoteEnable VPN Client サービスのリモート管理の許可
CMD_RemoteEnable_Help VPN Client サービスに、localhost 以外のリモートコンピュータから、コマンドライン管理ユーティリティまたは VPN クライアント接続マネージャでリモート接続して管理することを許可します。
CMD_RemoteEnable_Help VPN Client サービスに、localhost 以外のリモートコンピュータから、コマンドライン管理ユーティリティまたは VPN クライアント接続マネージャでリモート接続して管理することを許可します。注意: リモート管理の可否の変更の設定適用には、VPN Client サービスを再起動する必要があります。リモート管理を許可する場合、パスワードを設定する必要があります。
CMD_RemoteEnable_Args RemoteEnable
# RemoteDisable コマンド
CMD_RemoteDisable VPN Client サービスのリモート管理の禁止
CMD_RemoteDisable_Help VPN Client サービスに、localhost 以外のリモートコンピュータからコマンドライン管理ユーティリティまたは VPN クライアント接続マネージャでリモート接続して管理することを禁止します。
CMD_RemoteDisable_Help VPN Client サービスに、localhost 以外のリモートコンピュータからコマンドライン管理ユーティリティまたは VPN クライアント接続マネージャでリモート接続して管理することを禁止します。注意: リモート管理の可否の変更の設定適用には、VPN Client サービスを再起動する必要があります。
CMD_RemoteDisable_Args RemoteDisable