diff --git a/ajax/openvpn/activate_ovpncfg.php b/ajax/openvpn/activate_ovpncfg.php new file mode 100644 index 00000000..b8f822c2 --- /dev/null +++ b/ajax/openvpn/activate_ovpncfg.php @@ -0,0 +1,33 @@ +$return]; + echo json_encode($jsonData); +} + diff --git a/app/js/custom.js b/app/js/custom.js index 7a885472..dcb05797 100644 --- a/app/js/custom.js +++ b/app/js/custom.js @@ -248,6 +248,40 @@ $('#hostapdModal').on('shown.bs.modal', function (e) { $('#configureClientModal').on('shown.bs.modal', function (e) { }); +$('#ovpn-confirm-delete').on('click', '.btn-delete', function (e) { + var cfg_id = $(this).data('recordId'); + $.post('ajax/openvpn/del_ovpncfg.php',{'cfg_id':cfg_id},function(data){ + jsonData = JSON.parse(data); + $("#ovpn-confirm-delete").modal('hide'); + var row = $(document.getElementById("openvpn-client-row-" + cfg_id)); + row.fadeOut( "slow", function() { + row.remove(); + }); + }); +}); + +$('#ovpn-confirm-delete').on('show.bs.modal', function (e) { + var data = $(e.relatedTarget).data(); + $('.btn-delete', this).data('recordId', data.recordId); +}); + +$('#ovpn-confirm-activate').on('click', '.btn-activate', function (e) { + var cfg_id = $(this).data('recordId'); + $.post('ajax/openvpn/activate_ovpncfg.php',{'cfg_id':cfg_id},function(data){ + jsonData = JSON.parse(data); + $("#ovpn-confirm-activate").modal('hide'); + setTimeout(function(){ + window.location.reload(); + },300); + }); +}); + +$('#ovpn-confirm-activate').on('shown.bs.modal', function (e) { + var data = $(e.relatedTarget).data(); + $('.btn-activate', this).data('recordId', data.recordId); +}); + + /* Sets the wirelss channel select options based on hw_mode and country_code. diff --git a/includes/functions.php b/includes/functions.php index f1dec2c0..7593df18 100755 --- a/includes/functions.php +++ b/includes/functions.php @@ -224,6 +224,84 @@ function safefilerewrite($fileName, $dataToSave) } } +/** + * Prepends data to a file if not exists + * + * @param string $filename + * @param string $dataToSave + * @return boolean + */ +function file_prepend_data($filename, $dataToSave) +{ + $context = stream_context_create(); + $file = fopen($filename, 'r', 1, $context); + $file_data = readfile($file); + + if (!preg_match('/^'.$dataToSave.'/', $file_data)) { + $tmp_file = tempnam(sys_get_temp_dir(), 'php_prepend_'); + file_put_contents($tmp_file, $dataToSave); + file_put_contents($tmp_file, $file, FILE_APPEND); + fclose($file); + unlink($filename); + rename($tmp_file, $filename); + return true; + } else { + return false; + } +} + +/** + * Fetches a meta value from a file + * + * @param string $filename + * @param string $pattern + * @return string + */ +function file_get_meta($filename, $pattern) +{ + if(file_exists($filename)) { + $context = stream_context_create(); + $file_data = file_get_contents($filename, false, $context); + preg_match('/^'.$pattern.'/', $file_data, $matched); + return $matched[1]; + } else { + return false; + } +} + +/** + * Renames an openvpn client config with the 'filename' header comment + * + * @param string file + * @return boolean + */ +function file_move_config($file) +{ + if(file_exists($file)) { + $file_data = file_get_contents($file); + preg_match('/^#\sfilename\s(.*)/i', $file_data, $matched); + $renamed = pathinfo($file, PATHINFO_DIRNAME).'/'. + $matched[1] .'_'.pathinfo($file, PATHINFO_FILENAME).'.'. + pathinfo($file, PATHINFO_EXTENSION); + if (!file_exists($renamed)) { + $return = system("sudo mv $file $renamed", $return); + } else { + return false; + } + } +} + +/** + * Callback function for array_filter + * + * @param string $var + * @return filtered value + */ +function filter_comments($var) +{ + return $var[0] != '#'; +} + /** * Saves a CSRF token in the session */ diff --git a/includes/openvpn.php b/includes/openvpn.php index 6f9e40b5..810746a2 100755 --- a/includes/openvpn.php +++ b/includes/openvpn.php @@ -20,7 +20,9 @@ function DisplayOpenVPNConfig() if (isset($_POST['authPassword'])) { $authPassword = strip_tags(trim($_POST['authPassword'])); } - $return = SaveOpenVPNConfig($status, $_FILES['customFile'], $authUser, $authPassword); + if (is_uploaded_file( $_FILES["customFile"]["tmp_name"])) { + $return = SaveOpenVPNConfig($status, $_FILES['customFile'], $authUser, $authPassword); + } } elseif (isset($_POST['StartOpenVPN'])) { $status->addMessage('Attempting to start OpenVPN', 'info'); exec('sudo /bin/systemctl start openvpn-client@client', $return); @@ -47,8 +49,24 @@ function DisplayOpenVPNConfig() // parse client auth credentials if (!empty($auth)) { - $authUser = $auth[0]; - $authPassword = $auth[1]; + $auth = array_filter($auth, 'filter_comments'); + $authUser = current($auth); + $authPassword = next($auth); + } + $clients = preg_grep('~\login.(conf)$~', scandir(pathinfo(RASPI_OPENVPN_CLIENT_LOGIN, PATHINFO_DIRNAME))); + + $logEnable = 0; + if (!empty($_POST) && !isset($_POST['log-openvpn'])) { + $logOutput = ""; + $f = @fopen("/tmp/openvpn.log", "r+"); + if ($f !== false) { + ftruncate($f, 0); + fclose($f); + } + } elseif (isset($_POST['log-openvpn']) || filesize('/tmp/openvpn.log') >0) { + $logEnable = 1; + exec("sudo /etc/raspap/openvpn/openvpnlog.sh", $logOutput); + $logOutput = file_get_contents('/tmp/openvpn.log'); } echo renderTemplate( @@ -56,9 +74,12 @@ function DisplayOpenVPNConfig() "status", "serviceStatus", "openvpnstatus", + "logEnable", + "logOutput", "public_ip", "authUser", - "authPassword" + "authPassword", + "clients" ) ); } @@ -136,18 +157,27 @@ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword) ) { throw new RuntimeException('Unable to move uploaded file'); } + + // Good file upload, update auth credentials if present + $prepend = '# filename '.pathinfo($file['name'], PATHINFO_FILENAME) .PHP_EOL; if (!empty($authUser) && !empty($authPassword)) { $auth_flag = 1; // Move tmp authdata to /etc/openvpn/login.conf - $auth = $authUser .PHP_EOL . $authPassword .PHP_EOL; + $auth.= $authUser .PHP_EOL . $authPassword .PHP_EOL; file_put_contents($tmp_authdata, $auth); + file_prepend_data($tmp_authdata, $prepend); + file_move_config(RASPI_OPENVPN_CLIENT_LOGIN); + chmod($tmp_authdata, 0644); system("sudo cp $tmp_authdata " . RASPI_OPENVPN_CLIENT_LOGIN, $return); if ($return !=0) { $status->addMessage('Unable to save client auth credentials', 'danger'); } } + // Prepend filname tag to .ovpn client config + file_prepend_data($tmp_ovpnclient, $prepend); + // Set iptables rules and, optionally, auth-user-pass exec("sudo /etc/raspap/openvpn/configauth.sh $tmp_ovpnclient $auth_flag " .$_SESSION['ap_interface'], $return); foreach ($return as $line) { @@ -155,6 +185,8 @@ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword) } // Copy tmp client config to /etc/openvpn/client + file_move_config(RASPI_OPENVPN_CLIENT_CONFIG); + chmod($tmp_ovpnclient, 0644); system("sudo cp $tmp_ovpnclient " . RASPI_OPENVPN_CLIENT_CONFIG, $return); if ($return ==0) { $status->addMessage('OpenVPN client.conf uploaded successfully', 'info'); diff --git a/installers/common.sh b/installers/common.sh index 9f9c9d87..7edad9c6 100755 --- a/installers/common.sh +++ b/installers/common.sh @@ -313,9 +313,10 @@ function _create_openvpn_scripts() { _install_log "Creating OpenVPN control scripts" sudo mkdir $raspap_dir/openvpn || _install_status 1 "Unable to create directory '$raspap_dir/openvpn'" - # Move service auth control shell scripts + # Move service auth control & logging shell scripts sudo cp "$webroot_dir/installers/"configauth.sh "$raspap_dir/openvpn" || _install_status 1 "Unable to move auth control script" - # Make configauth.sh writable by www-data group + sudo cp "$webroot_dir/installers/"openvpnlog.sh "$raspap_dir/openvpn" || _install_status 1 "Unable to move logging script" + # Make scripts executable by www-data group sudo chown -c root:"$raspap_user" "$raspap_dir/openvpn/"*.sh || _install_status 1 "Unable change owner and/or group" sudo chmod 750 "$raspap_dir/openvpn/"*.sh || _install_status 1 "Unable to change file permissions" _install_status 0 diff --git a/installers/openvpnlog.sh b/installers/openvpnlog.sh new file mode 100755 index 00000000..96e79e2d --- /dev/null +++ b/installers/openvpnlog.sh @@ -0,0 +1,3 @@ +#!/bin/bash +touch /tmp/openvpn.log +grep -m 100 openvpn /var/log/syslog | sudo tee /tmp/openvpn.log diff --git a/installers/raspap.sudoers b/installers/raspap.sudoers index 00e1d1c7..49d4032b 100644 --- a/installers/raspap.sudoers +++ b/installers/raspap.sudoers @@ -20,6 +20,8 @@ www-data ALL=(ALL) NOPASSWD:/bin/systemctl stop openvpn-client@client www-data ALL=(ALL) NOPASSWD:/bin/systemctl disable openvpn-client@client www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/ovpnclient.ovpn /etc/openvpn/client/client.conf www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/authdata /etc/openvpn/client/login.conf +www-data ALL=(ALL) NOPASSWD:/bin/mv /etc/openvpn/client/*.conf /etc/openvpn/client/*.conf +www-data ALL=(ALL) NOPASSWD:/bin/rm /etc/openvpn/client/*.conf www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/dnsmasqdata /etc/dnsmasq.d/090_*.conf www-data ALL=(ALL) NOPASSWD:/bin/rm /etc/dnsmasq.d/090_*.conf www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/dhcpddata /etc/dhcpcd.conf @@ -34,6 +36,7 @@ www-data ALL=(ALL) NOPASSWD:/etc/raspap/hostapd/disablelog.sh www-data ALL=(ALL) NOPASSWD:/etc/raspap/hostapd/servicestart.sh www-data ALL=(ALL) NOPASSWD:/etc/raspap/lighttpd/configport.sh www-data ALL=(ALL) NOPASSWD:/etc/raspap/openvpn/configauth.sh +www-data ALL=(ALL) NOPASSWD:/etc/raspap/openvpn/openvpnlog.sh www-data ALL=(ALL) NOPASSWD:/bin/chmod o+r /tmp/hostapd.log www-data ALL=(ALL) NOPASSWD:/bin/chmod o+r /tmp/dnsmasq.log www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/dnsmasqdata /etc/dnsmasq.d/090_adblock.conf diff --git a/locale/en_US/LC_MESSAGES/messages.mo b/locale/en_US/LC_MESSAGES/messages.mo index 34d53bd3..451dd153 100644 Binary files a/locale/en_US/LC_MESSAGES/messages.mo and b/locale/en_US/LC_MESSAGES/messages.mo differ diff --git a/locale/en_US/LC_MESSAGES/messages.po b/locale/en_US/LC_MESSAGES/messages.po index 8c4d5f97..dcd715ae 100644 --- a/locale/en_US/LC_MESSAGES/messages.po +++ b/locale/en_US/LC_MESSAGES/messages.po @@ -677,6 +677,42 @@ msgstr "Attempting to start openvpn" msgid "Attempting to stop openvpn" msgstr "Attempting to stop openvpn" +msgid "Configurations" +msgstr "Configurations" + +msgid "Currently available OpenVPN client configurations are displayed below." +msgstr "Currently available OpenVPN client configurations are displayed below." + +msgid "Activating a configuraton will restart the openvpn-client service." +msgstr "Activating a configuraton will restart the openvpn-client service." + +msgid "Delete OpenVPN client" +msgstr "Delete OpenVPN client" + +msgid "Delete client configuration? This cannot be undone." +msgstr "Delete client configuration? This cannot be undone." + +msgid "Activate OpenVPN client" +msgstr "Activate OpenVPN client" + +msgid "Activate client configuration? This will restart the openvpn-client service." +msgstr "Activate client configuration? This will restart the openvpn-client service." + +msgid "Activate" +msgstr "Activate" + +msgid "Cancel" +msgstr "Cancel" + +msgid "Enable this option to log openvpn activity." +msgstr "Enable this option to log openvpn activity." + +msgid "Cancel" +msgstr "Cancel" + +msgid "Cancel" +msgstr "Cancel" + #: includes/torproxy.php msgid "TOR is not running" msgstr "TOR is not running" diff --git a/templates/openvpn.php b/templates/openvpn.php index 65976dee..4f76d6ec 100755 --- a/templates/openvpn.php +++ b/templates/openvpn.php @@ -1,3 +1,15 @@ + + + + ' , PHP_EOL; + } else { + echo '' , PHP_EOL; + } + ?> + + +
@@ -21,70 +33,59 @@ +
-
-

-
-
-
-
-
-
-
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- - -
-
-
-
-
- -
-
-
-
-

-
-
- '; - ?> -
-
-
- - - ' , PHP_EOL; - } else { - echo '' , PHP_EOL; - } - ?> - - -
+ + + +
+ + + +
- - - + + + + + + + + + diff --git a/templates/openvpn/configs.php b/templates/openvpn/configs.php new file mode 100644 index 00000000..6f8056fd --- /dev/null +++ b/templates/openvpn/configs.php @@ -0,0 +1,35 @@ +
+
+
+

+

+ +
openvpn-client service.") ?> +

+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
diff --git a/templates/openvpn/general.php b/templates/openvpn/general.php new file mode 100644 index 00000000..ddc751e7 --- /dev/null +++ b/templates/openvpn/general.php @@ -0,0 +1,37 @@ +
+

+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + +
+
+
+
+
+ +
+
+
+ diff --git a/templates/openvpn/logging.php b/templates/openvpn/logging.php new file mode 100644 index 00000000..0aef4217 --- /dev/null +++ b/templates/openvpn/logging.php @@ -0,0 +1,16 @@ + +
+

+

openvpn activity.") ?>

+ +
+ aria-describedby="log-openvpn"> + +
+
+
+ +
+
+
+