1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-10 03:30:39 +03:00

Merge PR #733: Mayaqua/OS: improve UnixGetOsInfo() so that it retrieves info on recent Linux/BSD systems

This commit is contained in:
Davide Beatrici 2018-10-07 04:39:09 +02:00 committed by GitHub
commit 66b906378f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 174 additions and 127 deletions

View File

@ -690,19 +690,19 @@ void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, O
// if the option --push-peer-info is enabled. // if the option --push-peer-info is enabled.
// It also sends all of the client's environment // It also sends all of the client's environment
// variables whose names start with "UV_". // variables whose names start with "UV_".
pi = OvsParseData(c->ClientKey.PeerInfo, OPENVPN_DATA_PEERINFO); pi = NewEntryList(c->ClientKey.PeerInfo, "\n", "=\t");
// Check presence of custom hostname // Check presence of custom hostname
if (OvsHasEntry(pi, "UV_HOSTNAME")) if (EntryListHasKey(pi, "UV_HOSTNAME"))
{ {
StrCpy(p.ClientHostname, sizeof(p.ClientHostname), IniStrValue(pi, "UV_HOSTNAME")); StrCpy(p.ClientHostname, sizeof(p.ClientHostname), EntryListStrValue(pi, "UV_HOSTNAME"));
} }
else // Use the default gateway's MAC address else // Use the default gateway's MAC address
{ {
StrCpy(p.ClientHostname, sizeof(p.ClientHostname), IniStrValue(pi, "IV_HWADDR")); StrCpy(p.ClientHostname, sizeof(p.ClientHostname), EntryListStrValue(pi, "IV_HWADDR"));
} }
OvsFreeList(pi); FreeEntryList(pi);
if (se->Mode == OPENVPN_MODE_L3) if (se->Mode == OPENVPN_MODE_L3)
{ {
@ -814,13 +814,13 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
StrCpy(opt_str, sizeof(opt_str), s->Cedar->OpenVPNDefaultClientOption); StrCpy(opt_str, sizeof(opt_str), s->Cedar->OpenVPNDefaultClientOption);
} }
o = OvsParseData(opt_str, OPENVPN_DATA_OPTIONS); o = NewEntryList(opt_str, ",", " \t");
if (se->Mode == OPENVPN_MODE_UNKNOWN) if (se->Mode == OPENVPN_MODE_UNKNOWN)
{ {
UINT mtu; UINT mtu;
// Layer // Layer
if (StrCmpi(IniStrValue(o, "dev-type"), "tun") == 0) if (StrCmpi(EntryListStrValue(o, "dev-type"), "tun") == 0)
{ {
// L3 // L3
se->Mode = OPENVPN_MODE_L3; se->Mode = OPENVPN_MODE_L3;
@ -832,7 +832,7 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
} }
// Link MTU // Link MTU
mtu = IniIntValue(o, "link-mtu"); mtu = EntryListIntValue(o, "link-mtu");
if (mtu == 0) if (mtu == 0)
{ {
mtu = OPENVPN_MTU_LINK; mtu = OPENVPN_MTU_LINK;
@ -840,7 +840,7 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
se->LinkMtu = mtu; se->LinkMtu = mtu;
// Tun MTU // Tun MTU
mtu = IniIntValue(o, "tun-mtu"); mtu = EntryListIntValue(o, "tun-mtu");
if (mtu == 0) if (mtu == 0)
{ {
mtu = OPENVPN_MTU_TUN; mtu = OPENVPN_MTU_TUN;
@ -876,12 +876,12 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
} }
// Encryption algorithm // Encryption algorithm
cipher_name = IniStrValue(o, "cipher"); cipher_name = EntryListStrValue(o, "cipher");
c->CipherEncrypt = OvsGetCipher(cipher_name); c->CipherEncrypt = OvsGetCipher(cipher_name);
c->CipherDecrypt = OvsGetCipher(cipher_name); c->CipherDecrypt = OvsGetCipher(cipher_name);
// Hash algorithm // Hash algorithm
c->MdSend = OvsGetMd(IniStrValue(o, "auth")); c->MdSend = OvsGetMd(EntryListStrValue(o, "auth"));
c->MdRecv = NewMd(c->MdSend->Name); c->MdRecv = NewMd(c->MdSend->Name);
// Random number generation // Random number generation
@ -915,7 +915,7 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
SetMdKey(c->MdRecv, c->ExpansionKey + 64, c->MdRecv->Size); SetMdKey(c->MdRecv, c->ExpansionKey + 64, c->MdRecv->Size);
SetMdKey(c->MdSend, c->ExpansionKey + 192, c->MdSend->Size); SetMdKey(c->MdSend, c->ExpansionKey + 192, c->MdSend->Size);
OvsFreeList(o); FreeEntryList(o);
// We pass the cipher name sent from the OpenVPN client, unless it's a different cipher, to prevent a message such as: // We pass the cipher name sent from the OpenVPN client, unless it's a different cipher, to prevent a message such as:
// WARNING: 'cipher' is used inconsistently, local='cipher AES-128-GCM', remote='cipher aes-128-gcm' // WARNING: 'cipher' is used inconsistently, local='cipher AES-128-GCM', remote='cipher aes-128-gcm'
@ -982,70 +982,6 @@ MD *OvsGetMd(char *name)
return m; return m;
} }
// Parse data string
LIST *OvsParseData(char *str, int type)
{
LIST *o = NewListFast(NULL);
TOKEN_LIST *t;
t = ParseTokenWithoutNullStr(str, type == OPENVPN_DATA_OPTIONS ? "," : "\n");
if (t != NULL)
{
UINT i;
for (i = 0;i < t->NumTokens;i++)
{
char key[MAX_SIZE];
char value[MAX_SIZE];
char *line = t->Token[i];
Trim(line);
if (GetKeyAndValue(line, key, sizeof(key), value, sizeof(value), type == OPENVPN_DATA_OPTIONS ? " \t" : "=\t"))
{
INI_ENTRY *e = ZeroMalloc(sizeof(INI_ENTRY));
e->Key = CopyStr(key);
e->Value = CopyStr(value);
Add(o, e);
}
}
FreeToken(t);
}
return o;
}
// Release the option list
void OvsFreeList(LIST *o)
{
// Validate arguments
if (o == NULL)
{
return;
}
FreeIni(o);
}
// Confirm whether there is specified option key string
bool OvsHasEntry(LIST *o, char *key)
{
// Validate arguments
if (o == NULL || key == NULL)
{
return false;
}
if (GetIniEntry(o, key) != NULL)
{
return true;
}
return false;
}
// Build the data from KEY_METHOD2 // Build the data from KEY_METHOD2
BUF *OvsBuildKeyMethod2(OPENVPN_KEY_METHOD_2 *d) BUF *OvsBuildKeyMethod2(OPENVPN_KEY_METHOD_2 *d)
{ {

View File

@ -184,10 +184,6 @@
#define OPENVPN_MODE_L2 1 // TAP (Ethernet) #define OPENVPN_MODE_L2 1 // TAP (Ethernet)
#define OPENVPN_MODE_L3 2 // TUN (IP) #define OPENVPN_MODE_L3 2 // TUN (IP)
// Data
#define OPENVPN_DATA_OPTIONS 0
#define OPENVPN_DATA_PEERINFO 1
//// Type //// Type
@ -359,9 +355,6 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
BUF *OvsBuildKeyMethod2(OPENVPN_KEY_METHOD_2 *d); BUF *OvsBuildKeyMethod2(OPENVPN_KEY_METHOD_2 *d);
void OvsWriteStringToBuf(BUF *b, char *str, UINT max_size); void OvsWriteStringToBuf(BUF *b, char *str, UINT max_size);
LIST *OvsParseData(char *str, int type);
void OvsFreeList(LIST *o);
bool OvsHasEntry(LIST *o, char *key);
UINT OvsPeekStringFromFifo(FIFO *f, char *str, UINT str_size); UINT OvsPeekStringFromFifo(FIFO *f, char *str, UINT str_size);
void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c); void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c);
UINT OvsCalcTcpMss(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c); UINT OvsCalcTcpMss(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c);

View File

@ -2155,6 +2155,81 @@ LIST *NewListEx2(COMPARE *cmp, bool fast, bool fast_malloc)
return o; return o;
} }
// Parses a string by identifying its parts using the specified separators
LIST *NewEntryList(char *src, char *key_separator, char *value_separator)
{
LIST *o = NewListFast(NULL);
TOKEN_LIST *t;
t = ParseTokenWithoutNullStr(src, key_separator);
if (t != NULL)
{
UINT i;
for (i = 0; i < t->NumTokens; i++)
{
char key[MAX_SIZE];
char value[MAX_SIZE];
char *line = t->Token[i];
Trim(line);
if (GetKeyAndValue(line, key, sizeof(key), value, sizeof(value), value_separator))
{
INI_ENTRY *e = ZeroMalloc(sizeof(INI_ENTRY));
e->Key = CopyStr(key);
e->Value = CopyStr(value);
Add(o, e);
}
}
FreeToken(t);
}
return o;
}
// Checks whether the list contains the specified entry
bool EntryListHasKey(LIST *o, char *key)
{
// Validate arguments
if (o == NULL || key == NULL)
{
return false;
}
if (GetIniEntry(o, key) != NULL)
{
return true;
}
return false;
}
// Gets the value of the specified key from the entry list
char *EntryListStrValue(LIST *o, char *key)
{
return IniStrValue(o, key);
}
UINT EntryListIntValue(LIST *o, char *key)
{
return IniIntValue(o, key);
}
// Release the entry list
void FreeEntryList(LIST *o)
{
// Validate arguments
if (o == NULL)
{
return;
}
FreeIni(o);
}
// Read all data from FIFO // Read all data from FIFO
BUF *ReadFifoAll(FIFO *f) BUF *ReadFifoAll(FIFO *f)
{ {

View File

@ -380,6 +380,11 @@ LIST *NewListFast(COMPARE *cmp);
LIST *NewListEx(COMPARE *cmp, bool fast); LIST *NewListEx(COMPARE *cmp, bool fast);
LIST *NewListEx2(COMPARE *cmp, bool fast, bool fast_malloc); LIST *NewListEx2(COMPARE *cmp, bool fast, bool fast_malloc);
LIST *NewListSingle(void *p); LIST *NewListSingle(void *p);
LIST *NewEntryList(char *src, char *key_separator, char *value_separator);
bool EntryListHasKey(LIST *o, char *key);
char *EntryListStrValue(LIST *o, char *key);
UINT EntryListIntValue(LIST *o, char *key);
void FreeEntryList(LIST *o);
LIST *CloneList(LIST *o); LIST *CloneList(LIST *o);
void CopyToArray(LIST *o, void *p); void CopyToArray(LIST *o, void *p);
void *ToArray(LIST *o); void *ToArray(LIST *o);

View File

@ -2412,6 +2412,33 @@ void TrimCrlf(char *str)
} }
} }
// Remove quotes at the beginning and at the end of the string
void TrimQuotes(char *str)
{
UINT len = 0;
// Validate arguments
if (str == NULL)
{
return;
}
len = StrLen(str);
if (len == 0)
{
return;
}
if (str[len - 1] == '\"')
{
str[len - 1] = 0;
}
if (str[0] == '\"')
{
Move(str, str + 1, len);
}
}
// Remove white spaces of the both side of the string // Remove white spaces of the both side of the string
void Trim(char *str) void Trim(char *str)
{ {

View File

@ -155,6 +155,7 @@ bool ToBool(char *str);
int ToInti(char *str); int ToInti(char *str);
void ToStr(char *str, UINT i); void ToStr(char *str, UINT i);
void TrimCrlf(char *str); void TrimCrlf(char *str);
void TrimQuotes(char *str);
void Trim(char *str); void Trim(char *str);
void TrimRight(char *str); void TrimRight(char *str);
void TrimLeft(char *str); void TrimLeft(char *str);

View File

@ -125,6 +125,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <sys/utsname.h>
#include <Mayaqua/Mayaqua.h> #include <Mayaqua/Mayaqua.h>
#ifdef UNIX_MACOS #ifdef UNIX_MACOS
@ -1057,6 +1058,8 @@ void UnixAlert(char *msg, char *caption)
// Get the information of the current OS // Get the information of the current OS
void UnixGetOsInfo(OS_INFO *info) void UnixGetOsInfo(OS_INFO *info)
{ {
struct utsname unix_info;
// Validate arguments // Validate arguments
if (info == NULL) if (info == NULL)
{ {
@ -1079,68 +1082,75 @@ void UnixGetOsInfo(OS_INFO *info)
info->OsType = OSTYPE_UNIX_UNKNOWN; info->OsType = OSTYPE_UNIX_UNKNOWN;
#endif #endif
info->OsServicePack = 0; info->OsSystemName = CopyStr(OsTypeToStr(info->OsType));
info->KernelName = CopyStr("UNIX");
if (info->OsType != OSTYPE_LINUX) if (uname(&unix_info) > -1)
{ {
info->OsSystemName = CopyStr("UNIX"); info->OsProductName = CopyStr(unix_info.sysname);
info->OsProductName = CopyStr("UNIX"); info->OsVersion = CopyStr(unix_info.release);
info->KernelVersion = CopyStr(unix_info.version);
} }
else else
{ {
info->OsSystemName = CopyStr("Linux"); Debug("UnixGetOsInfo(): uname() failed with error: %s\n", strerror(errno));
info->OsProductName = CopyStr("Linux");
}
if (info->OsType == OSTYPE_LINUX) info->OsProductName = CopyStr(OsTypeToStr(info->OsType));
info->OsVersion = CopyStr("Unknown");
info->KernelVersion = CopyStr("Unknown");
}
#ifdef UNIX_LINUX
{ {
// Get the distribution name on Linux BUF *buffer = ReadDump("/etc/os-release");
BUF *b; if (buffer == NULL)
b = ReadDump("/etc/redhat-release");
if (b != NULL)
{ {
info->OsVersion = CfgReadNextLine(b); buffer = ReadDump("/usr/lib/os-release");
info->OsVendorName = CopyStr("Red Hat, Inc.");
FreeBuf(b);
} }
else
if (buffer != NULL)
{ {
b = ReadDump("/etc/turbolinux-release"); LIST *values = NewEntryList(buffer->Buf, "\n", "=");
if (b != NULL)
FreeBuf(buffer);
if (EntryListHasKey(values, "NAME"))
{ {
info->OsVersion = CfgReadNextLine(b); char *str = EntryListStrValue(values, "NAME");
info->OsVendorName = CopyStr("Turbolinux, Inc."); TrimQuotes(str);
FreeBuf(b); Free(info->OsProductName);
info->OsProductName = CopyStr(str);
}
if (EntryListHasKey(values, "HOME_URL"))
{
char *str = EntryListStrValue(values, "HOME_URL");
TrimQuotes(str);
info->OsVendorName = CopyStr(str);
}
if (EntryListHasKey(values, "VERSION"))
{
char *str = EntryListStrValue(values, "VERSION");
TrimQuotes(str);
Free(info->OsVersion);
info->OsVersion = CopyStr(str);
} }
else else
{ {
info->OsVersion = CopyStr("Unknown Linux Version"); // Debian testing/sid doesn't provide the version in /etc/os-release
info->OsVendorName = CopyStr("Unknown Vendor"); buffer = ReadDump("/etc/debian_version");
if (buffer != NULL)
{
Free(info->OsVersion);
info->OsVersion = CfgReadNextLine(buffer);
FreeBuf(buffer);
}
} }
}
info->KernelName = CopyStr("Linux Kernel"); FreeEntryList(values);
b = ReadDump("/proc/sys/kernel/osrelease");
if (b != NULL)
{
info->KernelVersion = CfgReadNextLine(b);
FreeBuf(b);
}
else
{
info->KernelVersion = CopyStr("Unknown Version");
} }
} }
else #endif
{
// In other cases
Free(info->OsProductName);
info->OsProductName = CopyStr(OsTypeToStr(info->OsType));
info->OsVersion = CopyStr("Unknown Version");
info->KernelName = CopyStr(OsTypeToStr(info->OsType));
info->KernelVersion = CopyStr("Unknown Version");
}
} }
// Examine whether the current OS is supported by the PacketiX VPN Kernel // Examine whether the current OS is supported by the PacketiX VPN Kernel