mirror of
				https://github.com/billz/raspap-webgui.git
				synced 2025-03-01 10:31:47 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			319 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			319 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
<?php
 | 
						||
 | 
						||
require_once 'includes/config.php';
 | 
						||
 | 
						||
/*
 | 
						||
 * Display VPN provider configuration
 | 
						||
 */
 | 
						||
function DisplayProviderConfig()
 | 
						||
{
 | 
						||
    // initialize status object
 | 
						||
    $status = new \RaspAP\Messages\StatusMessage;
 | 
						||
 | 
						||
    // set defaults
 | 
						||
    $id = $_SESSION["providerID"];
 | 
						||
    $binPath = getProviderValue($id, "bin_path");
 | 
						||
    $providerName = getProviderValue($id, "name");
 | 
						||
    $providerVersion = getProviderVersion($id, $binPath);
 | 
						||
    $installPage = getProviderValue($id, "install_page");
 | 
						||
    $publicIP = get_public_ip();
 | 
						||
    $serviceStatus = 'down';
 | 
						||
    $statusDisplay = 'down';
 | 
						||
    $ctlState = '';
 | 
						||
 | 
						||
    if (!file_exists($binPath)) {
 | 
						||
        $status->addMessage(sprintf(_('Expected %s binary not found at: %s'), $providerName, $binPath), 'warning');
 | 
						||
        $status->addMessage(sprintf(_('Visit the <a href="%s" target="_blank">installation instructions</a> for %s\'s Linux CLI.'), $installPage, $providerName), 'warning');
 | 
						||
        $ctlState = 'disabled';
 | 
						||
        $providerVersion = 'not found';
 | 
						||
    } elseif (empty($providerVersion)) {
 | 
						||
        $status->addMessage(sprintf(_('Unable to execute %s binary found at: %s'), $providerName, $binPath), 'warning');
 | 
						||
        $status->addMessage(_('Check that binary is executable and permissions exist in raspap.sudoers'), 'warning');
 | 
						||
        $ctlState = 'disabled';
 | 
						||
        $providerVersion = 'not found';
 | 
						||
    } else {
 | 
						||
        // fetch provider status
 | 
						||
        $serviceStatus = getProviderStatus($id, $binPath);
 | 
						||
        $statusDisplay = $serviceStatus == "down" ? "inactive" : "active";
 | 
						||
 | 
						||
        // fetch provider log
 | 
						||
        $providerLog = getProviderLog($id, $binPath, $country);
 | 
						||
 | 
						||
        // fetch account info
 | 
						||
        $accountInfo = getAccountInfo($id, $binPath, $providerName);
 | 
						||
        $accountLink = getProviderValue($id, "account_page");
 | 
						||
 | 
						||
        // fetch available countries
 | 
						||
        $countries = getCountries($id, $binPath);
 | 
						||
    }
 | 
						||
 | 
						||
    if (!RASPI_MONITOR_ENABLED) {
 | 
						||
        if (isset($_POST['SaveProviderSettings'])) {
 | 
						||
            if (isset($_POST['country'])) {
 | 
						||
                $country = escapeshellarg(trim($_POST['country']));
 | 
						||
                if (strlen($country) == 0) {
 | 
						||
                    $status->addMessage('Select a country from the server location list', 'danger');
 | 
						||
                } else {
 | 
						||
                    $return = saveProviderConfig($status, $binPath, $country, $id);
 | 
						||
                }
 | 
						||
            }
 | 
						||
        } elseif (isset($_POST['StartProviderVPN'])) {
 | 
						||
            $status->addMessage('Attempting to connect VPN provider', 'info');
 | 
						||
            $cmd = getCliOverride($id, 'cmd_overrides', 'connect');
 | 
						||
            exec("sudo $binPath $cmd", $return);
 | 
						||
            $return = stripArtifacts($return);
 | 
						||
            foreach ($return as $line) {
 | 
						||
                if (strlen(trim($line)) > 0) {
 | 
						||
                    $line = preg_replace('/\e\[\?[0-9]*l\s(.*)\e.*$/', '$1', $line);
 | 
						||
                    $line = preg_replace('/\e\[0m\e\[[0-9;]*m(.*)/', '$1', $line);
 | 
						||
                    $status->addMessage($line, 'info');
 | 
						||
                }
 | 
						||
            }
 | 
						||
        } elseif (isset($_POST['StopProviderVPN'])) {
 | 
						||
            $status->addMessage('Attempting to disconnect VPN provider', 'info');
 | 
						||
            $cmd = getCliOverride($id, 'cmd_overrides', 'disconnect');
 | 
						||
            exec("sudo $binPath $cmd", $return);
 | 
						||
            $return = stripArtifacts($return);
 | 
						||
            foreach ($return as $line) {
 | 
						||
                if (strlen(trim($line)) > 0) {
 | 
						||
                    $line = preg_replace('/\[1;33;49m(.*)\[0m/', '$1', $line);
 | 
						||
                    $status->addMessage($line, 'info');
 | 
						||
                }
 | 
						||
            }
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    echo renderTemplate(
 | 
						||
        "provider", compact(
 | 
						||
            "status",
 | 
						||
            "serviceStatus",
 | 
						||
            "statusDisplay",
 | 
						||
            "providerName",
 | 
						||
            "providerVersion",
 | 
						||
            "accountInfo",
 | 
						||
            "accountLink",
 | 
						||
            "countries",
 | 
						||
            "country",
 | 
						||
            "providerLog",
 | 
						||
            "publicIP",
 | 
						||
            "ctlState"
 | 
						||
        )
 | 
						||
    );
 | 
						||
}
 | 
						||
 | 
						||
/**
 | 
						||
 * Validates VPN provider settings 
 | 
						||
 *
 | 
						||
 * @param object $status
 | 
						||
 * @param string $binPath
 | 
						||
 * @param string $country
 | 
						||
 * @param integer $id (optional)
 | 
						||
 */
 | 
						||
function saveProviderConfig($status, $binPath, $country, $id = null)
 | 
						||
{
 | 
						||
    $status->addMessage(sprintf(_('Attempting to connect to %s'),$country), 'info');
 | 
						||
    $cmd = getCliOverride($id, 'cmd_overrides', 'connect');
 | 
						||
    // mullvad requires relay set location before connect
 | 
						||
    if ($id == 2) {
 | 
						||
        exec("sudo $binPath relay set location $country", $return);
 | 
						||
        exec("sudo $binPath $cmd", $return);
 | 
						||
    } else {
 | 
						||
        exec("sudo $binPath $cmd $country", $return);
 | 
						||
    }
 | 
						||
    $return = stripArtifacts($return);
 | 
						||
    foreach ($return as $line) {
 | 
						||
        if ( strlen(trim($line)) >0 ) {
 | 
						||
            $status->addMessage($line, 'info');
 | 
						||
        }
 | 
						||
    }
 | 
						||
}
 | 
						||
 | 
						||
/**
 | 
						||
 * Removes artifacts from shell_exec string values
 | 
						||
 *
 | 
						||
 * @param string $output
 | 
						||
 * @param string $pattern
 | 
						||
 * @return string $result
 | 
						||
 */
 | 
						||
function stripArtifacts($output, $pattern = null)
 | 
						||
{
 | 
						||
    $result = preg_replace('/[-\/\n\t\\\\'.$pattern.'|]/', '', $output);
 | 
						||
    return $result;
 | 
						||
}
 | 
						||
 | 
						||
/**
 | 
						||
 * Retrieves an override for provider CLI
 | 
						||
 *
 | 
						||
 * @param integer $id
 | 
						||
 * @param string $group
 | 
						||
 * @param string $item
 | 
						||
 * @return string $override
 | 
						||
 */
 | 
						||
function getCliOverride($id, $group, $item)
 | 
						||
{
 | 
						||
    $obj = json_decode(file_get_contents(RASPI_CONFIG_PROVIDERS), true);
 | 
						||
    if ($obj === null) {
 | 
						||
        return false;
 | 
						||
    } else {
 | 
						||
        $id--;
 | 
						||
        if (empty($obj['providers'][$id][$group][$item])) {
 | 
						||
            return $item;
 | 
						||
        } else {
 | 
						||
            return $obj['providers'][$id][$group][$item];
 | 
						||
        }
 | 
						||
    }
 | 
						||
}
 | 
						||
 | 
						||
/**
 | 
						||
 * Retreives VPN provider status
 | 
						||
 *
 | 
						||
 * @param integer $id
 | 
						||
 * @param string $binPath
 | 
						||
 * @return string $status
 | 
						||
 */
 | 
						||
function getProviderStatus($id, $binPath)
 | 
						||
{
 | 
						||
    $cmd = getCliOverride($id, 'cmd_overrides', 'status');
 | 
						||
    $pattern = getCliOverride($id, 'regex', 'status');
 | 
						||
    exec("sudo $binPath $cmd", $cmd_raw);
 | 
						||
    $cmd_raw = strtolower(stripArtifacts($cmd_raw[0]));
 | 
						||
 | 
						||
    if (!empty($cmd_raw[0])) {
 | 
						||
        if (preg_match($pattern, $cmd_raw, $match)) {
 | 
						||
            $status =  "down";
 | 
						||
        } else {
 | 
						||
            $status = "up";
 | 
						||
        }
 | 
						||
    } else {
 | 
						||
        $status = "down";
 | 
						||
    }
 | 
						||
    return $status;
 | 
						||
}
 | 
						||
 | 
						||
/**
 | 
						||
 * Retrieves available countries
 | 
						||
 *
 | 
						||
 * @param integer $id
 | 
						||
 * @param string $binPath
 | 
						||
 * @return array $countries
 | 
						||
 */
 | 
						||
function getCountries($id, $binPath)
 | 
						||
{
 | 
						||
    $countries = [];
 | 
						||
    $cmd = getCliOverride($id, 'cmd_overrides', 'countries');
 | 
						||
    $pattern = getCliOverride($id, 'regex', 'pattern');
 | 
						||
    $replace = getCliOverride($id, 'regex', 'replace');
 | 
						||
    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
 | 
						||
        $slice = getCliOverride($id, 'regex', 'slice');
 | 
						||
        $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 2: // mullvad
 | 
						||
        foreach ($output as $item) {
 | 
						||
            $item = preg_replace($pattern, $replace, $item);
 | 
						||
            if (strlen(trim($item) >0)) {
 | 
						||
                preg_match('/\s+([a-z0-9-]+)\s.*$/', $item, $match);
 | 
						||
                if (count($match) > 1) {
 | 
						||
                    $key = $match[1];
 | 
						||
                    $item = str_pad($item, strlen($item)+16,' ', STR_PAD_LEFT);
 | 
						||
                    $countries[$key] = $item;
 | 
						||
                } else {
 | 
						||
                    preg_match('/\(([a-z]+)\)/', $item, $match);
 | 
						||
                    $key = $match[1];
 | 
						||
                    if (strlen($match[1]) == 3) {
 | 
						||
                        $item = str_pad($item, strlen($item)+8,' ', STR_PAD_LEFT);
 | 
						||
                    }
 | 
						||
                    $countries[$key] = $item;
 | 
						||
                }
 | 
						||
            }
 | 
						||
        }
 | 
						||
        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;
 | 
						||
    return $countries;
 | 
						||
}
 | 
						||
 | 
						||
/**
 | 
						||
 * Retrieves provider log
 | 
						||
 *
 | 
						||
 * @param integer $id
 | 
						||
 * @param string $binPath
 | 
						||
 * @param string $country
 | 
						||
 * @return string $log
 | 
						||
 */
 | 
						||
function getProviderLog($id, $binPath, &$country)
 | 
						||
{
 | 
						||
    $providerLog = '';
 | 
						||
    $cmd = getCliOverride($id, 'cmd_overrides', 'log');
 | 
						||
    exec("sudo $binPath $cmd", $cmd_raw);
 | 
						||
    $output = stripArtifacts($cmd_raw);
 | 
						||
    foreach ($output as $item) {
 | 
						||
        if (preg_match('/Country: (\w+)/', $item, $match)) {
 | 
						||
            $country = $match[1];
 | 
						||
        }
 | 
						||
        $providerLog.= ltrim($item) .PHP_EOL;
 | 
						||
    }
 | 
						||
    return $providerLog;
 | 
						||
}
 | 
						||
 | 
						||
/**
 | 
						||
 * Retrieves provider version information
 | 
						||
 *
 | 
						||
 * @param integer $id
 | 
						||
 * @param string $binPath
 | 
						||
 * @return string $version
 | 
						||
 */
 | 
						||
function getProviderVersion($id, $binPath)
 | 
						||
{
 | 
						||
    $cmd = getCliOverride($id, 'cmd_overrides', 'version');
 | 
						||
    $version = shell_exec("sudo $binPath $cmd");
 | 
						||
    $version = preg_replace('/^[^\w]+\s*/', '', $version);
 | 
						||
    return $version;
 | 
						||
}
 | 
						||
 | 
						||
/**
 | 
						||
 * 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);
 | 
						||
 | 
						||
    foreach ($acct as &$item) {
 | 
						||
        $item = preg_replace('/^[^\w]+\s*/', '', $item);
 | 
						||
    }
 | 
						||
    if (empty($acct)) {
 | 
						||
        $msg = sprintf(_("Account information not available from %s's Linux CLI."), $providerName);
 | 
						||
        $acct[] = $msg;
 | 
						||
    }
 | 
						||
    return $acct;
 | 
						||
}
 | 
						||
 |