mirror of
https://github.com/billz/raspap-webgui.git
synced 2025-03-01 10:31:47 +00:00
Merge pull request #45 from RaspAP/feature/wg-extended
Extend WG functionality
This commit is contained in:
@@ -721,13 +721,15 @@ function validateCidr($cidr)
|
||||
}
|
||||
|
||||
// Validates a host or FQDN
|
||||
function validate_host($host) {
|
||||
function validate_host($host)
|
||||
{
|
||||
return preg_match('/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i', $host);
|
||||
}
|
||||
|
||||
// Gets night mode toggle value
|
||||
// @return boolean
|
||||
function getNightmode(){
|
||||
function getNightmode()
|
||||
{
|
||||
if ($_COOKIE['theme'] == 'lightsout.css') {
|
||||
return true;
|
||||
} else {
|
||||
@@ -736,7 +738,8 @@ function getNightmode(){
|
||||
}
|
||||
|
||||
// search array for matching string and return only first matching group
|
||||
function preg_only_match($pat,$haystack) {
|
||||
function preg_only_match($pat,$haystack)
|
||||
{
|
||||
$match = "";
|
||||
if(!empty($haystack) && !empty($pat)) {
|
||||
if(!is_array($haystack)) $haystack = array($haystack);
|
||||
@@ -754,10 +757,34 @@ function qr_encode($str)
|
||||
return preg_replace('/(?<!\\\)([\":;,])/', '\\\\\1', $str);
|
||||
}
|
||||
|
||||
function evalHexSequence($string) {
|
||||
function evalHexSequence($string)
|
||||
{
|
||||
$evaluator = function ($input) {
|
||||
return hex2bin($input[1]);
|
||||
};
|
||||
return preg_replace_callback('/\\\x(..)/', $evaluator, $string);
|
||||
}
|
||||
|
||||
/* File upload callback object
|
||||
*
|
||||
*/
|
||||
class validation
|
||||
{
|
||||
public function check_name_length($object)
|
||||
{
|
||||
if (strlen($object->file['filename']) > 255) {
|
||||
$object->set_error('File name is too long.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Resolves public IP address
|
||||
*
|
||||
* @return string $public_ip
|
||||
*/
|
||||
function get_public_ip()
|
||||
{
|
||||
exec('wget https://ipinfo.io/ip -qO -', $public_ip);
|
||||
return $public_ip[0];
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
require_once 'includes/status_messages.php';
|
||||
require_once 'includes/config.php';
|
||||
require_once 'includes/wifi_functions.php';
|
||||
require_once 'app/lib/uploader.php';
|
||||
|
||||
getWifiInterface();
|
||||
|
||||
@@ -41,11 +42,9 @@ function DisplayOpenVPNConfig()
|
||||
}
|
||||
|
||||
exec('pidof openvpn | wc -l', $openvpnstatus);
|
||||
exec('wget https://ipinfo.io/ip -qO -', $return);
|
||||
|
||||
$serviceStatus = $openvpnstatus[0] == 0 ? "down" : "up";
|
||||
$auth = file(RASPI_OPENVPN_CLIENT_LOGIN, FILE_IGNORE_NEW_LINES);
|
||||
$public_ip = $return[0];
|
||||
$public_ip = get_public_ip();
|
||||
|
||||
// parse client auth credentials
|
||||
if (!empty($auth)) {
|
||||
@@ -100,8 +99,8 @@ function DisplayOpenVPNConfig()
|
||||
*/
|
||||
function SaveOpenVPNConfig($status, $file, $authUser, $authPassword)
|
||||
{
|
||||
$tmp_ovpnclient = '/tmp/ovpnclient.ovpn';
|
||||
$tmp_authdata = '/tmp/authdata';
|
||||
define('KB', 1024);
|
||||
$tmp_destdir = '/tmp/';
|
||||
$auth_flag = 0;
|
||||
|
||||
try {
|
||||
@@ -110,66 +109,28 @@ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword)
|
||||
throw new RuntimeException('Invalid parameters');
|
||||
}
|
||||
|
||||
// Parse returned errors
|
||||
switch ($file['error']) {
|
||||
case UPLOAD_ERR_OK:
|
||||
break;
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
throw new RuntimeException('OpenVPN configuration file not sent');
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
throw new RuntimeException('Exceeded filesize limit');
|
||||
default:
|
||||
throw new RuntimeException('Unknown errors');
|
||||
}
|
||||
$upload = \RaspAP\Uploader\Upload::factory('ovpn',$tmp_destdir);
|
||||
$upload->set_max_file_size(64*KB);
|
||||
$upload->set_allowed_mime_types(array('ovpn' => 'text/plain'));
|
||||
$upload->file($file);
|
||||
|
||||
// Validate extension
|
||||
$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
|
||||
if ($ext != 'ovpn') {
|
||||
throw new RuntimeException('Invalid file extension');
|
||||
}
|
||||
$validation = new validation;
|
||||
$upload->callbacks($validation, array('check_name_length'));
|
||||
$results = $upload->upload();
|
||||
|
||||
// Validate MIME type
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
if (false === $ext = array_search(
|
||||
$finfo->file($file['tmp_name']),
|
||||
array(
|
||||
'ovpn' => 'text/plain'
|
||||
),
|
||||
true
|
||||
)
|
||||
) {
|
||||
throw new RuntimeException('Invalid file format');
|
||||
}
|
||||
|
||||
// Validate filesize
|
||||
define('KB', 1024);
|
||||
if ($file['size'] > 64*KB) {
|
||||
throw new RuntimeException('File size limit exceeded');
|
||||
}
|
||||
|
||||
// Use safe filename, save to /tmp
|
||||
if (!move_uploaded_file(
|
||||
$file['tmp_name'],
|
||||
sprintf(
|
||||
'/tmp/%s.%s',
|
||||
'ovpnclient',
|
||||
$ext
|
||||
)
|
||||
)
|
||||
) {
|
||||
throw new RuntimeException('Unable to move uploaded file');
|
||||
if (!empty($results['errors'])) {
|
||||
throw new RuntimeException($results['errors'][0]);
|
||||
}
|
||||
|
||||
// Good file upload, update auth credentials if present
|
||||
if (!empty($authUser) && !empty($authPassword)) {
|
||||
$auth_flag = 1;
|
||||
// Move tmp authdata to /etc/openvpn/login.conf
|
||||
$auth.= $authUser .PHP_EOL . $authPassword .PHP_EOL;
|
||||
$tmp_authdata = $tmp_destdir .'ovpn/authdata';
|
||||
$auth = $authUser .PHP_EOL . $authPassword .PHP_EOL;
|
||||
file_put_contents($tmp_authdata, $auth);
|
||||
chmod($tmp_authdata, 0644);
|
||||
$client_auth = RASPI_OPENVPN_CLIENT_PATH.pathinfo($file['name'], PATHINFO_FILENAME).'_login.conf';
|
||||
system("sudo cp $tmp_authdata $client_auth", $return);
|
||||
system("sudo mv $tmp_authdata $client_auth", $return);
|
||||
system("sudo rm ".RASPI_OPENVPN_CLIENT_LOGIN, $return);
|
||||
system("sudo ln -s $client_auth ".RASPI_OPENVPN_CLIENT_LOGIN, $return);
|
||||
if ($return !=0) {
|
||||
@@ -178,14 +139,16 @@ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword)
|
||||
}
|
||||
|
||||
// Set iptables rules and, optionally, auth-user-pass
|
||||
exec("sudo /etc/raspap/openvpn/configauth.sh $tmp_ovpnclient $auth_flag " .$_SESSION['ap_interface'], $return);
|
||||
$tmp_ovpn = $results['full_path'];
|
||||
exec("sudo /etc/raspap/openvpn/configauth.sh $tmp_ovpn $auth_flag " .$_SESSION['ap_interface'], $return);
|
||||
foreach ($return as $line) {
|
||||
$status->addMessage($line, 'info');
|
||||
}
|
||||
|
||||
// Move uploaded ovpn config from /tmp and create symlink
|
||||
$client_ovpn = RASPI_OPENVPN_CLIENT_PATH.pathinfo($file['name'], PATHINFO_FILENAME).'_client.conf';
|
||||
chmod($tmp_ovpnclient, 0644);
|
||||
system("sudo cp $tmp_ovpnclient $client_ovpn", $return);
|
||||
chmod($tmp_ovpn, 0644);
|
||||
system("sudo mv $tmp_ovpn $client_ovpn", $return);
|
||||
system("sudo rm ".RASPI_OPENVPN_CLIENT_CONFIG, $return);
|
||||
system("sudo ln -s $client_ovpn ".RASPI_OPENVPN_CLIENT_CONFIG, $return);
|
||||
|
||||
@@ -201,3 +164,4 @@ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword)
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,8 +10,13 @@ function DisplayWireGuardConfig()
|
||||
{
|
||||
$status = new StatusMessages();
|
||||
if (!RASPI_MONITOR_ENABLED) {
|
||||
if (isset($_POST['savewgsettings'])) {
|
||||
$optRules = $_POST['wgRules'];
|
||||
$optConf = $_POST['wgCnfOpt'];
|
||||
$optSrvEnable = $_POST['wgSrvEnable'];
|
||||
if (isset($_POST['savewgsettings']) && $optConf == 'manual' && $optSrvEnable == 1 ) {
|
||||
SaveWireGuardConfig($status);
|
||||
} elseif (isset($_POST['savewgsettings']) && $optConf == 'upload' && is_uploaded_file($_FILES["wgFile"]["tmp_name"])) {
|
||||
SaveWireGuardUpload($status, $_FILES['wgFile'], $optRules);
|
||||
} elseif (isset($_POST['startwg'])) {
|
||||
$status->addMessage('Attempting to start WireGuard', 'info');
|
||||
exec('sudo /bin/systemctl start wg-quick@wg0', $return);
|
||||
@@ -27,7 +32,7 @@ function DisplayWireGuardConfig()
|
||||
}
|
||||
}
|
||||
|
||||
// fetch wg config
|
||||
// fetch server config
|
||||
exec('sudo cat '. RASPI_WIREGUARD_CONFIG, $return);
|
||||
$conf = ParseConfig($return);
|
||||
$wg_srvpubkey = exec('sudo cat '. RASPI_WIREGUARD_PATH .'wg-server-public.key', $return);
|
||||
@@ -39,7 +44,7 @@ function DisplayWireGuardConfig()
|
||||
$wg_senabled = true;
|
||||
}
|
||||
|
||||
// todo: iterate multiple peer configs
|
||||
// fetch client config
|
||||
exec('sudo cat '. RASPI_WIREGUARD_PATH.'client.conf', $preturn);
|
||||
$conf = ParseConfig($preturn);
|
||||
$wg_pipaddress = ($conf['Address'] == '') ? getDefaultNetValue('wireguard','peer','Address') : $conf['Address'];
|
||||
@@ -55,12 +60,15 @@ function DisplayWireGuardConfig()
|
||||
exec('pidof wg-crypt-wg0 | wc -l', $wgstatus);
|
||||
$serviceStatus = $wgstatus[0] == 0 ? "down" : "up";
|
||||
$wg_state = ($wgstatus[0] > 0);
|
||||
$public_ip = get_public_ip();
|
||||
|
||||
echo renderTemplate(
|
||||
"wireguard", compact(
|
||||
"status",
|
||||
"wg_state",
|
||||
"serviceStatus",
|
||||
"public_ip",
|
||||
"optRules",
|
||||
"wg_log",
|
||||
"peer_id",
|
||||
"wg_srvpubkey",
|
||||
@@ -79,6 +87,71 @@ function DisplayWireGuardConfig()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates uploaded .conf file, adds iptables post-up and
|
||||
* post-down rules.
|
||||
*
|
||||
* @param object $status
|
||||
* @param object $file
|
||||
* @param boolean $optRules
|
||||
* @return object $status
|
||||
*/
|
||||
function SaveWireGuardUpload($status, $file, $optRules)
|
||||
{
|
||||
define('KB', 1024);
|
||||
$tmp_destdir = '/tmp/';
|
||||
$auth_flag = 0;
|
||||
|
||||
try {
|
||||
// If undefined or multiple files, treat as invalid
|
||||
if (!isset($file['error']) || is_array($file['error'])) {
|
||||
throw new RuntimeException('Invalid parameters');
|
||||
}
|
||||
|
||||
$upload = \RaspAP\Uploader\Upload::factory('wg',$tmp_destdir);
|
||||
$upload->set_max_file_size(64*KB);
|
||||
$upload->set_allowed_mime_types(array('text/plain'));
|
||||
$upload->file($file);
|
||||
|
||||
$validation = new validation;
|
||||
$upload->callbacks($validation, array('check_name_length'));
|
||||
$results = $upload->upload();
|
||||
|
||||
if (!empty($results['errors'])) {
|
||||
throw new RuntimeException($results['errors'][0]);
|
||||
}
|
||||
|
||||
// Valid upload, get file contents
|
||||
$tmp_wgconfig = $results['full_path'];
|
||||
$tmp_contents = file_get_contents($tmp_wgconfig);
|
||||
|
||||
// Set iptables rules
|
||||
if (isset($optRules) && !preg_match('/PostUp|PostDown/m',$tmp_contents)) {
|
||||
$rules[] = 'PostUp = '.getDefaultNetValue('wireguard','server','PostUp');
|
||||
$rules[] = 'PostDown = '.getDefaultNetValue('wireguard','server','PostDown');
|
||||
$rules[] = '';
|
||||
$rules = join(PHP_EOL, $rules);
|
||||
$rules = preg_replace('/wlan0/m', $_SESSION['ap_interface'], $rules);
|
||||
$tmp_contents = preg_replace('/^\s*$/ms', $rules, $tmp_contents, 1);
|
||||
file_put_contents($tmp_wgconfig, $tmp_contents);
|
||||
}
|
||||
|
||||
// Move processed file from tmp to destination
|
||||
system("sudo mv $tmp_wgconfig ". RASPI_WIREGUARD_CONFIG, $return);
|
||||
|
||||
if ($return ==0) {
|
||||
$status->addMessage('WireGuard configuration uploaded successfully', 'info');
|
||||
} else {
|
||||
$status->addMessage('Unable to save WireGuard configuration', 'danger');
|
||||
}
|
||||
return $status;
|
||||
|
||||
} catch (RuntimeException $e) {
|
||||
$status->addMessage($e->getMessage(), 'danger');
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate user input, save wireguard configuration
|
||||
*
|
||||
|
Reference in New Issue
Block a user