From 3ceee41d33d4ce6547df164ba84cd3369405306b Mon Sep 17 00:00:00 2001 From: Davide Beatrici Date: Fri, 20 Apr 2018 17:33:07 +0200 Subject: [PATCH 1/4] OpenVPN: hostname support OpenVPN sends the default gateway's MAC address, if the option --push-peer-info is enabled. It also sends the client's environment variables whose names start with "UV_". This commit adds some lines of code in OvsBeginIPCAsyncConnectionIfEmpty(), in order to set the hostname to "UV_HOSTNAME"'s value, which is defined by the user on their device. In case "UV_HOSTNAME" is not available, "IV_HWADDR"'s value (the default gateway's MAC address) is used instead. OvsParseOptions() has been adapted into a new function called OvsParsePeerInfo(), in order to parse the peer info string. --- src/Cedar/Interop_OpenVPN.c | 54 +++++++++++++++++++++++++++++++++++++ src/Cedar/Interop_OpenVPN.h | 1 + 2 files changed, 55 insertions(+) diff --git a/src/Cedar/Interop_OpenVPN.c b/src/Cedar/Interop_OpenVPN.c index 366ce95f..d248259b 100644 --- a/src/Cedar/Interop_OpenVPN.c +++ b/src/Cedar/Interop_OpenVPN.c @@ -673,6 +673,7 @@ void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, O if (se->IpcAsync == NULL) { + LIST *pi; IPC_PARAM p; ETHERIP_ID id; @@ -702,6 +703,24 @@ void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, O StrCpy(p.CryptName, sizeof(p.CryptName), c->CipherEncrypt->Name); } + // OpenVPN sends the default gateway's MAC address, + // if the option --push-peer-info is enabled. + // It also sends all of the client's environment + // variables whose names start with "UV_". + pi = OvsParsePeerInfo(c->ClientKey.PeerInfo); + + // Check presence of custom hostname + if (OvsHasOption(pi, "UV_HOSTNAME")) + { + StrCpy(p.ClientHostname, sizeof(p.ClientHostname), IniStrValue(pi, "UV_HOSTNAME")); + } + else // Use the default gateway's MAC address + { + StrCpy(p.ClientHostname, sizeof(p.ClientHostname), IniStrValue(pi, "IV_HWADDR")); + } + + OvsFreeOptions(pi); + if (se->Mode == OPENVPN_MODE_L3) { // L3 Mode @@ -1000,6 +1019,41 @@ LIST *OvsParseOptions(char *str) return o; } +// Parse the peer info string +LIST *OvsParsePeerInfo(char *str) +{ + LIST *o = NewListFast(NULL); + TOKEN_LIST *t; + + t = ParseTokenWithoutNullStr(str, "\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), "=\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 OvsFreeOptions(LIST *o) { diff --git a/src/Cedar/Interop_OpenVPN.h b/src/Cedar/Interop_OpenVPN.h index 4157206a..a1b3901a 100644 --- a/src/Cedar/Interop_OpenVPN.h +++ b/src/Cedar/Interop_OpenVPN.h @@ -362,6 +362,7 @@ BUF *OvsBuildKeyMethod2(OPENVPN_KEY_METHOD_2 *d); void OvsWriteStringToBuf(BUF *b, char *str, UINT max_size); LIST *OvsParseOptions(char *str); +LIST *OvsParsePeerInfo(char *str); void OvsFreeOptions(LIST *o); LIST *OvsNewOptions(); void OvsAddOption(LIST *o, char *key, char *value); From 86c82b8ccf852d11e1a01a2a9c0ae2fe576e9d19 Mon Sep 17 00:00:00 2001 From: Davide Beatrici Date: Wed, 4 Apr 2018 06:22:31 +0200 Subject: [PATCH 2/4] OpenVPN: rename generic functions --- src/Cedar/Interop_OpenVPN.c | 14 +++++++------- src/Cedar/Interop_OpenVPN.h | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Cedar/Interop_OpenVPN.c b/src/Cedar/Interop_OpenVPN.c index d248259b..7576d96a 100644 --- a/src/Cedar/Interop_OpenVPN.c +++ b/src/Cedar/Interop_OpenVPN.c @@ -710,7 +710,7 @@ void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, O pi = OvsParsePeerInfo(c->ClientKey.PeerInfo); // Check presence of custom hostname - if (OvsHasOption(pi, "UV_HOSTNAME")) + if (OvsHasEntry(pi, "UV_HOSTNAME")) { StrCpy(p.ClientHostname, sizeof(p.ClientHostname), IniStrValue(pi, "UV_HOSTNAME")); } @@ -719,7 +719,7 @@ void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, O StrCpy(p.ClientHostname, sizeof(p.ClientHostname), IniStrValue(pi, "IV_HWADDR")); } - OvsFreeOptions(pi); + OvsFreeList(pi); if (se->Mode == OPENVPN_MODE_L3) { @@ -932,7 +932,7 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C SetMdKey(c->MdRecv, c->ExpansionKey + 64, c->MdRecv->Size); SetMdKey(c->MdSend, c->ExpansionKey + 192, c->MdSend->Size); - OvsFreeOptions(o); + OvsFreeList(o); // Generate the response option string Format(c->ServerKey.OptionString, sizeof(c->ServerKey.OptionString), @@ -1055,7 +1055,7 @@ LIST *OvsParsePeerInfo(char *str) } // Release the option list -void OvsFreeOptions(LIST *o) +void OvsFreeList(LIST *o) { // Validate arguments if (o == NULL) @@ -1067,13 +1067,13 @@ void OvsFreeOptions(LIST *o) } // Create an Option List -LIST *OvsNewOptions() +LIST *OvsNewList() { return NewListFast(NULL); } // Add a value to the option list -void OvsAddOption(LIST *o, char *key, char *value) +void OvsAddEntry(LIST *o, char *key, char *value) { INI_ENTRY *e; // Validate arguments @@ -1105,7 +1105,7 @@ void OvsAddOption(LIST *o, char *key, char *value) } // Confirm whether there is specified option key string -bool OvsHasOption(LIST *o, char *key) +bool OvsHasEntry(LIST *o, char *key) { // Validate arguments if (o == NULL || key == NULL) diff --git a/src/Cedar/Interop_OpenVPN.h b/src/Cedar/Interop_OpenVPN.h index a1b3901a..ddd2244c 100644 --- a/src/Cedar/Interop_OpenVPN.h +++ b/src/Cedar/Interop_OpenVPN.h @@ -363,10 +363,10 @@ void OvsWriteStringToBuf(BUF *b, char *str, UINT max_size); LIST *OvsParseOptions(char *str); LIST *OvsParsePeerInfo(char *str); -void OvsFreeOptions(LIST *o); -LIST *OvsNewOptions(); -void OvsAddOption(LIST *o, char *key, char *value); -bool OvsHasOption(LIST *o, char *key); +void OvsFreeList(LIST *o); +LIST *OvsNewList(); +void OvsAddEntry(LIST *o, char *key, char *value); +bool OvsHasEntry(LIST *o, char *key); UINT OvsPeekStringFromFifo(FIFO *f, char *str, UINT str_size); void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c); bool OvsIsCompatibleL3IP(UINT ip); From 970e217380aea6cec1819815a0f7922d9fda81a1 Mon Sep 17 00:00:00 2001 From: Davide Beatrici Date: Thu, 5 Apr 2018 22:28:23 +0200 Subject: [PATCH 3/4] OpenVPN: merge OvsParseOptions() and OvsParsePeerInfo() into a single function --- src/Cedar/Interop_OpenVPN.c | 47 +++++-------------------------------- src/Cedar/Interop_OpenVPN.h | 7 ++++-- 2 files changed, 11 insertions(+), 43 deletions(-) diff --git a/src/Cedar/Interop_OpenVPN.c b/src/Cedar/Interop_OpenVPN.c index 7576d96a..9ebc1c33 100644 --- a/src/Cedar/Interop_OpenVPN.c +++ b/src/Cedar/Interop_OpenVPN.c @@ -707,7 +707,7 @@ void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, O // if the option --push-peer-info is enabled. // It also sends all of the client's environment // variables whose names start with "UV_". - pi = OvsParsePeerInfo(c->ClientKey.PeerInfo); + pi = OvsParseData(c->ClientKey.PeerInfo, OPENVPN_DATA_PEERINFO); // Check presence of custom hostname if (OvsHasEntry(pi, "UV_HOSTNAME")) @@ -832,7 +832,7 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C StrCpy(opt_str, sizeof(opt_str), s->Cedar->OpenVPNDefaultClientOption); } - o = OvsParseOptions(opt_str); + o = OvsParseData(opt_str, OPENVPN_DATA_OPTIONS); if (se->Mode == OPENVPN_MODE_UNKNOWN) { @@ -984,13 +984,13 @@ MD *OvsGetMd(char *name) return m; } -// Parse the option string -LIST *OvsParseOptions(char *str) +// Parse data string +LIST *OvsParseData(char *str, int type) { LIST *o = NewListFast(NULL); TOKEN_LIST *t; - t = ParseTokenWithoutNullStr(str, ","); + t = ParseTokenWithoutNullStr(str, type == OPENVPN_DATA_OPTIONS ? "," : "\n"); if (t != NULL) { UINT i; @@ -1002,42 +1002,7 @@ LIST *OvsParseOptions(char *str) char *line = t->Token[i]; Trim(line); - if (GetKeyAndValue(line, key, sizeof(key), value, sizeof(value), " \t")) - { - INI_ENTRY *e = ZeroMalloc(sizeof(INI_ENTRY)); - - e->Key = CopyStr(key); - e->Value = CopyStr(value); - - Add(o, e); - } - } - - FreeToken(t); - } - - return o; -} - -// Parse the peer info string -LIST *OvsParsePeerInfo(char *str) -{ - LIST *o = NewListFast(NULL); - TOKEN_LIST *t; - - t = ParseTokenWithoutNullStr(str, "\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), "=\t")) + if (GetKeyAndValue(line, key, sizeof(key), value, sizeof(value), type == OPENVPN_DATA_OPTIONS ? " \t" : "=\t")) { INI_ENTRY *e = ZeroMalloc(sizeof(INI_ENTRY)); diff --git a/src/Cedar/Interop_OpenVPN.h b/src/Cedar/Interop_OpenVPN.h index ddd2244c..c31d3d24 100644 --- a/src/Cedar/Interop_OpenVPN.h +++ b/src/Cedar/Interop_OpenVPN.h @@ -190,6 +190,10 @@ #define OPENVPN_MODE_L2 1 // TAP (Ethernet) #define OPENVPN_MODE_L3 2 // TUN (IP) +// Data +#define OPENVPN_DATA_OPTIONS 0 +#define OPENVPN_DATA_PEERINFO 1 + //// Type @@ -361,8 +365,7 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C BUF *OvsBuildKeyMethod2(OPENVPN_KEY_METHOD_2 *d); void OvsWriteStringToBuf(BUF *b, char *str, UINT max_size); -LIST *OvsParseOptions(char *str); -LIST *OvsParsePeerInfo(char *str); +LIST *OvsParseData(char *str, int type); void OvsFreeList(LIST *o); LIST *OvsNewList(); void OvsAddEntry(LIST *o, char *key, char *value); From a5bd4b33da96b6bc009d8f9dfc636151d01cc26e Mon Sep 17 00:00:00 2001 From: Davide Beatrici Date: Mon, 16 Apr 2018 18:20:09 +0200 Subject: [PATCH 4/4] Hamcore: add "push-peer-info" and "UV_HOSTNAME" to the OpenVPN sample configuration --- src/bin/hamcore/openvpn_sample.ovpn | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/bin/hamcore/openvpn_sample.ovpn b/src/bin/hamcore/openvpn_sample.ovpn index 2964712f..3b7c3868 100644 --- a/src/bin/hamcore/openvpn_sample.ovpn +++ b/src/bin/hamcore/openvpn_sample.ovpn @@ -19,6 +19,28 @@ # config file. Please refer the below descriptions carefully. +############################################################################### +# Custom hostname setting. +# +# Uncomment the line and replace "Hostname" with your desired string, if you +# want the server to use a specific hostname instead of the default gateway's +# hardware address. + +;setenv UV_HOSTNAME Hostname + + +############################################################################### +# Push extra info about the client to the server. +# +# The server currently uses: +# IV_HWADDR = Default gateway's MAC Address +# UV_HOSTNAME = Custom hostname +# +# They are required in order to set an hostname for the client. + +push-peer-info + + ############################################################################### # Specify the type of the layer of the VPN connection. #