diff --git a/src/Cedar/Interop_OpenVPN.c b/src/Cedar/Interop_OpenVPN.c index 366ce95f..9ebc1c33 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 = OvsParseData(c->ClientKey.PeerInfo, OPENVPN_DATA_PEERINFO); + + // Check presence of custom hostname + if (OvsHasEntry(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")); + } + + OvsFreeList(pi); + if (se->Mode == OPENVPN_MODE_L3) { // L3 Mode @@ -813,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) { @@ -913,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), @@ -965,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; @@ -983,7 +1002,7 @@ LIST *OvsParseOptions(char *str) 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)); @@ -1001,7 +1020,7 @@ LIST *OvsParseOptions(char *str) } // Release the option list -void OvsFreeOptions(LIST *o) +void OvsFreeList(LIST *o) { // Validate arguments if (o == NULL) @@ -1013,13 +1032,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 @@ -1051,7 +1070,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 4157206a..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,11 +365,11 @@ 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); -void OvsFreeOptions(LIST *o); -LIST *OvsNewOptions(); -void OvsAddOption(LIST *o, char *key, char *value); -bool OvsHasOption(LIST *o, char *key); +LIST *OvsParseData(char *str, int type); +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); 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. #