2023-10-13 17:46:44 +00:00
< ? php
require_once 'includes/config.php' ;
2023-10-15 19:29:34 +00:00
/*
2023-10-25 13:07:46 +00:00
* Display VPN provider configuration
2023-10-13 17:46:44 +00:00
*/
function DisplayProviderConfig ()
{
2023-10-25 13:07:46 +00:00
// initialize status object
2023-10-13 17:46:44 +00:00
$status = new \RaspAP\Messages\StatusMessage ;
2023-10-16 08:44:46 +00:00
2023-10-25 13:07:46 +00:00
// set defaults
2023-10-16 08:44:46 +00:00
$id = $_SESSION [ " providerID " ];
$binPath = getProviderValue ( $id , " bin_path " );
2023-10-25 13:07:46 +00:00
$providerName = getProviderValue ( $id , " name " );
$providerVersion = getProviderVersion ( $id , $binPath );
$installPage = getProviderValue ( $id , " install_page " );
2023-10-16 08:44:46 +00:00
$publicIP = get_public_ip ();
2023-10-25 13:07:46 +00:00
$serviceStatus = 'down' ;
$statusDisplay = 'down' ;
2023-10-28 16:00:34 +00:00
$ctlState = '' ;
2023-10-15 19:29:34 +00:00
if ( ! file_exists ( $binPath )) {
2023-10-25 13:07:46 +00:00
$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' );
2023-10-15 19:29:34 +00:00
$ctlState = 'disabled' ;
$providerVersion = 'not found' ;
} else {
// fetch provider status
2023-10-16 08:44:46 +00:00
$serviceStatus = getProviderStatus ( $id , $binPath );
$statusDisplay = $serviceStatus == " down " ? " inactive " : " active " ;
// fetch provider log
2023-10-18 07:50:57 +00:00
$providerLog = getProviderLog ( $id , $binPath , $country );
2023-10-15 19:29:34 +00:00
// fetch account info
2023-10-19 12:07:26 +00:00
$accountInfo = getAccountInfo ( $id , $binPath , $providerName );
2023-10-25 13:07:46 +00:00
$accountLink = getProviderValue ( $id , " account_page " );
2023-10-15 19:29:34 +00:00
// fetch available countries
2023-10-16 08:44:46 +00:00
$countries = getCountries ( $id , $binPath );
2023-10-15 19:29:34 +00:00
}
2023-10-13 17:46:44 +00:00
if ( ! RASPI_MONITOR_ENABLED ) {
if ( isset ( $_POST [ 'SaveProviderSettings' ])) {
2023-10-18 07:50:57 +00:00
if ( isset ( $_POST [ 'country' ])) {
2024-03-08 20:14:33 +00:00
$country = escapeshellarg ( trim ( $_POST [ 'country' ]));
2023-10-18 07:50:57 +00:00
if ( strlen ( $country ) == 0 ) {
$status -> addMessage ( 'Select a country from the server location list' , 'danger' );
2023-10-25 13:38:49 +00:00
} else {
$return = saveProviderConfig ( $status , $binPath , $country , $id );
2023-10-18 07:50:57 +00:00
}
2023-10-13 17:46:44 +00:00
}
} elseif ( isset ( $_POST [ 'StartProviderVPN' ])) {
2023-10-15 19:29:34 +00:00
$status -> addMessage ( 'Attempting to connect VPN provider' , 'info' );
2023-10-16 08:44:46 +00:00
$cmd = getCliOverride ( $id , 'cmd_overrides' , 'connect' );
exec ( " sudo $binPath $cmd " , $return );
2023-10-18 07:50:57 +00:00
$return = stripArtifacts ( $return );
2023-10-13 17:46:44 +00:00
foreach ( $return as $line ) {
2023-10-26 08:57:06 +00:00
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' );
}
2023-10-13 17:46:44 +00:00
}
} elseif ( isset ( $_POST [ 'StopProviderVPN' ])) {
2023-10-15 19:29:34 +00:00
$status -> addMessage ( 'Attempting to disconnect VPN provider' , 'info' );
2023-10-18 07:50:57 +00:00
$cmd = getCliOverride ( $id , 'cmd_overrides' , 'disconnect' );
exec ( " sudo $binPath $cmd " , $return );
$return = stripArtifacts ( $return );
2023-10-13 17:46:44 +00:00
foreach ( $return as $line ) {
2023-10-25 13:38:49 +00:00
if ( strlen ( trim ( $line )) > 0 ) {
2023-10-25 16:01:26 +00:00
$line = preg_replace ( '/\[1;33;49m(.*)\[0m/' , '$1' , $line );
2023-10-25 13:38:49 +00:00
$status -> addMessage ( $line , 'info' );
}
2023-10-13 17:46:44 +00:00
}
}
}
echo renderTemplate (
" provider " , compact (
" status " ,
" serviceStatus " ,
2023-10-16 08:44:46 +00:00
" statusDisplay " ,
2023-10-13 17:46:44 +00:00
" providerName " ,
2023-10-15 19:29:34 +00:00
" providerVersion " ,
" accountInfo " ,
2023-10-25 13:07:46 +00:00
" accountLink " ,
2023-10-15 19:29:34 +00:00
" countries " ,
2023-10-18 07:50:57 +00:00
" country " ,
2023-10-13 17:46:44 +00:00
" providerLog " ,
2023-10-16 08:44:46 +00:00
" publicIP " ,
2023-10-15 19:29:34 +00:00
" ctlState "
2023-10-13 17:46:44 +00:00
)
);
}
/**
2024-08-10 17:25:54 +00:00
* Validates VPN provider settings
2023-10-13 17:46:44 +00:00
*
2023-10-20 15:43:59 +00:00
* @ param object $status
* @ param string $binPath
* @ param string $country
* @ param integer $id ( optional )
2023-10-13 17:46:44 +00:00
*/
2023-10-20 15:43:59 +00:00
function saveProviderConfig ( $status , $binPath , $country , $id = null )
2023-10-13 17:46:44 +00:00
{
2023-10-25 13:38:49 +00:00
$status -> addMessage ( sprintf ( _ ( 'Attempting to connect to %s' ), $country ), 'info' );
2023-10-18 07:50:57 +00:00
$cmd = getCliOverride ( $id , 'cmd_overrides' , 'connect' );
2023-10-26 14:29:32 +00:00
// mullvad requires relay set location before connect
if ( $id == 2 ) {
exec ( " sudo $binPath relay set location $country " , $return );
exec ( " sudo $binPath $cmd " , $return );
2023-10-20 15:43:59 +00:00
} else {
exec ( " sudo $binPath $cmd $country " , $return );
}
2023-10-18 07:50:57 +00:00
$return = stripArtifacts ( $return );
foreach ( $return as $line ) {
2023-10-20 15:43:59 +00:00
if ( strlen ( trim ( $line )) > 0 ) {
$status -> addMessage ( $line , 'info' );
}
2023-10-18 07:50:57 +00:00
}
2023-10-13 17:46:44 +00:00
}
2023-10-15 19:29:34 +00:00
/**
* Removes artifacts from shell_exec string values
*
* @ param string $output
* @ param string $pattern
* @ return string $result
*/
function stripArtifacts ( $output , $pattern = null )
{
2023-10-25 13:07:46 +00:00
$result = preg_replace ( '/[-\/\n\t\\\\' . $pattern . '|]/' , '' , $output );
2023-10-15 19:29:34 +00:00
return $result ;
}
2023-10-16 08:44:46 +00:00
/**
* 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 -- ;
2023-10-28 16:00:34 +00:00
if ( empty ( $obj [ 'providers' ][ $id ][ $group ][ $item ])) {
2023-10-16 08:44:46 +00:00
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 )
{
2023-10-18 07:50:57 +00:00
$cmd = getCliOverride ( $id , 'cmd_overrides' , 'status' );
2023-10-19 12:07:26 +00:00
$pattern = getCliOverride ( $id , 'regex' , 'status' );
2023-10-18 07:50:57 +00:00
exec ( " sudo $binPath $cmd " , $cmd_raw );
2023-10-19 12:07:26 +00:00
$cmd_raw = strtolower ( stripArtifacts ( $cmd_raw [ 0 ]));
2023-10-25 13:38:49 +00:00
2023-10-25 13:07:46 +00:00
if ( ! empty ( $cmd_raw [ 0 ])) {
if ( preg_match ( $pattern , $cmd_raw , $match )) {
$status = " down " ;
} else {
$status = " up " ;
}
2023-10-19 12:07:26 +00:00
} else {
2023-10-25 13:07:46 +00:00
$status = " down " ;
2023-10-18 07:50:57 +00:00
}
return $status ;
2023-10-16 08:44:46 +00:00
}
/**
* Retrieves available countries
*
* @ param integer $id
* @ param string $binPath
* @ return array $countries
*/
function getCountries ( $id , $binPath )
{
2023-10-19 12:07:26 +00:00
$countries = [];
2023-10-16 08:44:46 +00:00
$cmd = getCliOverride ( $id , 'cmd_overrides' , 'countries' );
2023-10-19 12:07:26 +00:00
$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
2023-10-28 16:00:34 +00:00
$slice = getCliOverride ( $id , 'regex' , 'slice' );
2023-10-19 12:07:26 +00:00
$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 ;
2023-10-20 15:43:59 +00:00
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 ;
2023-10-19 12:07:26 +00:00
case 3 : // nordvpn
$arrTmp = explode ( " , " , $output [ 0 ]);
2024-08-10 17:25:54 +00:00
foreach ( $output as $key => $value ) {
$countries [ $value ] = str_replace ( " _ " , " " , $value );
2023-10-19 12:07:26 +00:00
}
break ;
default :
break ;
}
2023-10-25 13:07:46 +00:00
$select = array ( ' ' => _ ( " Select a country... " ));
2023-10-18 07:50:57 +00:00
$countries = $select + $countries ;
2023-10-16 08:44:46 +00:00
return $countries ;
}
2023-10-18 07:50:57 +00:00
/**
* Retrieves provider log
*
* @ param integer $id
* @ param string $binPath
* @ param string $country
* @ return string $log
*/
function getProviderLog ( $id , $binPath , & $country )
{
2023-10-28 16:00:34 +00:00
$providerLog = '' ;
2023-10-19 12:07:26 +00:00
$cmd = getCliOverride ( $id , 'cmd_overrides' , 'log' );
2023-10-18 07:50:57 +00:00
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 ;
}
2023-10-20 15:43:59 +00:00
/**
* 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 " );
2023-10-25 13:07:46 +00:00
$version = preg_replace ( '/^[^\w]+\s*/' , '' , $version );
2023-10-20 15:43:59 +00:00
return $version ;
}
2023-10-19 12:07:26 +00:00
/**
* 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 );
2023-10-25 13:07:46 +00:00
foreach ( $acct as & $item ) {
$item = preg_replace ( '/^[^\w]+\s*/' , '' , $item );
}
if ( empty ( $acct )) {
2023-10-19 16:18:14 +00:00
$msg = sprintf ( _ ( " Account information not available from %s's Linux CLI. " ), $providerName );
2023-10-25 13:07:46 +00:00
$acct [] = $msg ;
2023-10-19 12:07:26 +00:00
}
2023-10-25 13:07:46 +00:00
return $acct ;
2023-10-19 12:07:26 +00:00
}