diff --git a/app/css/all.css b/app/css/all.css index 7f07c51f..023eb15b 100644 --- a/app/css/all.css +++ b/app/css/all.css @@ -89,7 +89,7 @@ License: GNU General Public License v3.0 border: 1px solid #d1d3e2; border-radius: .35rem; font-family: Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace; - font-size: 0.9rem; + font-size: 0.8rem; } .dhcp-static-leases { diff --git a/config/vpn-providers.json b/config/vpn-providers.json index 45b3bb96..029c534a 100644 --- a/config/vpn-providers.json +++ b/config/vpn-providers.json @@ -6,10 +6,14 @@ "bin_path": "/usr/bin/expressvpn", "install_page": "https://www.expressvpn.com/support/vpn-setup/app-for-linux/", "cmd_overrides": { - "countries": "list" + "countries": "list all", + "log": "diagnostics" }, - "status": { - "connected": "connected" + "regex": { + "status": "\/not connected\/", + "pattern": "\/^(.{2,5})\\s(?:.{1,28})(.{1,26}).*$\/", + "replace": "$1,$2", + "slice": 3 } }, { @@ -26,10 +30,12 @@ "bin_path": "/usr/bin/nordvpn", "install_page": "https://nordvpn.com/download/linux/", "cmd_overrides": { + "log": "status" }, - "status": { - "connected": "connected", - "disconnected": "disconnected" + "regex": { + "status": "\/status: (\\w+)\/", + "pattern": "(\\w+)\\s+", + "replace": "$1,$1\\n" } }, { diff --git a/includes/provider.php b/includes/provider.php index 521ae7f7..fce7e8dd 100755 --- a/includes/provider.php +++ b/includes/provider.php @@ -32,9 +32,7 @@ function DisplayProviderConfig() $providerVersion = shell_exec("sudo $binPath -v"); // fetch account info - $cmd = getCliOverride($id, 'cmd_overrides', 'account'); - exec("sudo $binPath $cmd", $acct); - $accountInfo = stripArtifacts($acct); + $accountInfo = getAccountInfo($id, $binPath, $providerName); // fetch available countries $countries = getCountries($id, $binPath); @@ -150,11 +148,13 @@ function getCliOverride($id, $group, $item) function getProviderStatus($id, $binPath) { $cmd = getCliOverride($id, 'cmd_overrides', 'status'); + $pattern = getCliOverride($id, 'regex', 'status'); exec("sudo $binPath $cmd", $cmd_raw); - $cmd_raw = stripArtifacts($cmd_raw[0]); - if (preg_match('/Status: (\w+)/', $cmd_raw, $match)) { - $cli = getCliOverride($id, 'status', 'connected'); - $status = strtolower($match[1]) == $cli ? "up" : "down"; + $cmd_raw = strtolower(stripArtifacts($cmd_raw[0])); + if (preg_match($pattern, $cmd_raw, $match)) { + $status = "down"; + } else { + $status = "up"; } return $status; } @@ -168,16 +168,39 @@ function getProviderStatus($id, $binPath) */ function getCountries($id, $binPath) { + $countries = []; $cmd = getCliOverride($id, 'cmd_overrides', 'countries'); - $output = shell_exec("sudo $binPath $cmd"); - $output = stripArtifacts($output, '\s'); - $arrTmp = explode(",", $output); - $countries = array_combine($arrTmp, $arrTmp); + $pattern = getCliOverride($id, 'regex', 'pattern'); + $replace = getCliOverride($id, 'regex', 'replace'); + $slice = getCliOverride($id, 'regex', 'slice'); + exec("sudo $binPath $cmd", $output); + + // CLI country output differs considerably between different providers. + // Ideally, custom parsing would be avoided in favor of a pure regex solution + switch ($id) { + case 1: // expressvpn + $output = array_slice($output, $slice); + foreach ($output as $item) { + $item = preg_replace($pattern, $replace, $item); + $parts = explode(',', $item); + $key = trim($parts[0]); + $value = trim($parts[1]); + $countries[$key] = $value; + } + break; + case 3: // nordvpn + $output = stripArtifacts($output,'\s'); + $arrTmp = explode(",", $output[0]); + $countries = array_combine($arrTmp, $arrTmp); + foreach ($countries as $key => $value) { + $countries[$key] = str_replace("_", " ", $value); + } + break; + default: + break; + } $select = array(' ' => 'Select a country...'); $countries = $select + $countries; - foreach ($countries as $key => $value) { - $countries[$key] = str_replace("_", " ", $value); - } return $countries; } @@ -191,7 +214,7 @@ function getCountries($id, $binPath) */ function getProviderLog($id, $binPath, &$country) { - $cmd = getCliOverride($id, 'cmd_overrides', 'status'); + $cmd = getCliOverride($id, 'cmd_overrides', 'log'); exec("sudo $binPath $cmd", $cmd_raw); $output = stripArtifacts($cmd_raw); foreach ($output as $item) { @@ -203,3 +226,23 @@ function getProviderLog($id, $binPath, &$country) return $providerLog; } +/** + * Retrieves provider account info + * + * @param integer $id + * @param string $binPath + * @param string $providerName + * @return array + */ +function getAccountInfo($id, $binPath, $providerName) +{ + $cmd = getCliOverride($id, 'cmd_overrides', 'account'); + exec("sudo $binPath $cmd", $acct); + $accountInfo = stripArtifacts($acct); + if (empty($accountInfo)) { + $msg = sprintf(_("Account details not available from %s's Linux CLI."), $providerName); + $accountInfo[] = $msg; + } + return $accountInfo; +} +