From c7ae8dc93c0d4dd4d34d0ac8e3a2c631ebe776db Mon Sep 17 00:00:00 2001 From: Casey Erdmann <14339392+3ndG4me@users.noreply.github.com> Date: Sun, 28 Oct 2018 19:36:42 -0400 Subject: [PATCH] Update OpenVPNConnect to 1.1 (#47) --- OpenVPNConnect/api/module.php | 113 ++++++++++++++++++++++++++++------ OpenVPNConnect/js/module.js | 55 +++++++++++++++-- OpenVPNConnect/log/status.log | 0 OpenVPNConnect/log/vpn.log | 0 OpenVPNConnect/module.html | 22 ++++++- OpenVPNConnect/module.info | 4 +- 6 files changed, 166 insertions(+), 28 deletions(-) create mode 100644 OpenVPNConnect/log/status.log create mode 100644 OpenVPNConnect/log/vpn.log diff --git a/OpenVPNConnect/api/module.php b/OpenVPNConnect/api/module.php index 804a9f9..f114e82 100644 --- a/OpenVPNConnect/api/module.php +++ b/OpenVPNConnect/api/module.php @@ -20,35 +20,50 @@ class OpenVPNConnect extends Module{ case 'stopVPN': $this->stopVPN(); break; + case 'checkVPNStatus': + $this->checkVPNStatus(); + break; case 'initializeModule': $this->initializeModule(); break; case 'handleDependencies': $this->handleDependencies(); break; + case 'handleDependenciesSDCard': + $this->handleDependenciesSDCard(); + break; case 'checkDependencies': $this->checkDependencies(); break; case 'uploadFile': $this->uploadFile(); + break; } } // Checks the dependencies using the pineapple API functions private function checkDependencies(){ - + $installedFlag = false; if($this->checkDependency('openvpn')){ $installLabel = 'success'; $installLabelText = 'Installed'; + $installButtonWidth = "90px"; + $installLabelSDText = "Installed (SD Card)"; + $installedFlag = true; }else{ $installLabel = 'danger'; - $installLabelText = 'Not Installed'; + $installLabelText = 'Not Installed (Local Storage)'; + $installButtonWidth = "210px"; + $installLabelSDText = "Not Installed (SD Card)"; } $this->response = array("success" => true, "label" => $installLabel, - "text" => $installLabelText); + "text" => $installLabelText, + "buttonWidth" => $installButtonWidth, + "textSD" => $installLabelSDText, + "installed" => $installedFlag); } @@ -87,27 +102,60 @@ class OpenVPNConnect extends Module{ } // Handles dependency installation and removal - private function handleDependencies(){ + private function handleDependencies($sd){ if($this->checkDependency('openvpn')){ - exec('opkg remove openvpn-openssl'); + $this->execBackground('opkg remove openvpn-openssl'); $messsage = "Dependencies should now be removed! Note: the vpn_config directory is NOT removed in this process. Please wait for the page to refresh..."; }else{ - $this->installDependency('openvpn-openssl'); - $messsage = "Depedencies should now be installed! Please wait for the page to refresh..."; + if($sd){ + $this->execBackground('opkg update'); + $this->execBackground('opkg install openvpn-openssl --dest sd'); + $messsage = "Depedencies should now be installed! (Installed to SD card) Please wait for the page to refresh..."; + }else{ + $this->installDependency('openvpn-openssl'); + $messsage = "Depedencies should now be installed! (Installed to local storage) Please wait for the page to refresh..."; + } + } $this->response = array("success" => true, - "content" => $messsage); + "content" => $messsage, + "test" => $sd); } - // Builds the openvpn command string and calls it to star the VPN + // Helper function to handle dependency installation and removal for sd card. Passes the SD flag to the real handleDependencies() function + private function handleDependenciesSDCard(){ + + $sd = true; + + return handleDependencies($sd); + + } + + + // Checks whether or not OpenVPN is currently running + private function checkVPNStatus(){ + $result = exec("pgrep openvpn"); + + if($result){ + $this->response = array("success" => true, + "content" => "VPN Running..."); + return; + } + + $this->response = array("success" => true, + "content" => "VPN Stopped..."); + + } + + // Builds the openvpn command string and calls it to start the VPN private function startVPN(){ $inputData = $this->request->data; - $open_vpn_cmd = "openvpn --config "; + $open_vpn_cmd = "openvpn --log /pineapple/modules/OpenVPNConnect/log/vpn.log --status /pineapple/modules/OpenVPNConnect/log/status.log --config "; if($inputData[0] != ''){ $config_name = $inputData[0]; @@ -118,27 +166,42 @@ class OpenVPNConnect extends Module{ return; } - if($inputData[1] != ''){ + + if($inputData[1] != '' && $inputData[2] != ''){ + //Create auth.txt file for openvpn command to read in + $config_user = $inputData[1]; + $config_pass = $inputData[2]; + $config_string = $config_user . PHP_EOL . $config_pass; + $auth_file = fopen("/tmp/vpn_auth.txt", "w"); + fwrite($auth_file, $config_string); + fclose($auth_file); + $open_vpn_cmd .= "--auth-nocache --auth-user-pass /tmp/vpn_auth.txt "; + + }else if($inputData[2] != ''){ //Create password file for openvpn command to read in - $config_pass = $inputData[1]; + $config_pass = $inputData[2]; $pass_file = fopen("/tmp/vpn_pass.txt", "w"); fwrite($pass_file, $config_pass); fclose($pass_file); $open_vpn_cmd .= "--auth-nocache --askpass /tmp/vpn_pass.txt "; } - if($inputData[2] != ''){ - $openvpn_flags = $inputData[2]; + + if($inputData[3] != ''){ + $openvpn_flags = $inputData[3]; $open_vpn_cmd .= $openvpn_flags; } - if($inputData[3] == true){ + if($inputData[4] == true){ //Share VPN With Clients Connecting - $this->execBackground("iptables -t nat -A POSTROUTING -s 172.16.42.0/24 -o tun0 -j MASQUERADE"); - $this->execBackground("iptables -A FORWARD -s 172.16.42.0/24 -o tun0 -j ACCEPT"); - $this->execBackground("iptables -A FORWARD -d 172.16.42.0/24 -m state --state ESTABLISHED,RELATED -i tun0 -j ACCEPT"); + $gateway = $this->uciGet("network.lan.gateway"); + $netmask = $this->uciGet("network.lan.netmask"); + + $this->execBackground("iptables -t nat -A POSTROUTING -s ". $gateway ."/". $netmask. " -o tun0 -j MASQUERADE"); + $this->execBackground("iptables -A FORWARD -s ". $gateway ."/". $netmask . " -o tun0 -j ACCEPT"); + $this->execBackground("iptables -A FORWARD -d ". $gateway ."/". $netmask ." -m state --state ESTABLISHED,RELATED -i tun0 -j ACCEPT"); } $result = $this->execBackground($open_vpn_cmd); @@ -151,10 +214,20 @@ class OpenVPNConnect extends Module{ // Calls pkill to kill the OpenVPN process and stop the VPN private function stopVPN(){ - //Remove password file that could have been created, don't want any creds lying around ;) + //Remove any creds files that could have been created, don't want any creds lying around ;) + unlink("/tmp/vpn_auth.txt"); unlink("/tmp/vpn_pass.txt"); - exec("pkill openvpn"); + //Delete any iptable rules that may have been created for sharing connection with clients + $gateway = $this->uciGet("network.lan.gateway"); + $netmask = $this->uciGet("network.lan.netmask"); + + $this->execBackground("iptables -t nat -D POSTROUTING -s ". $gateway ."/". $netmask. " -o tun0 -j MASQUERADE"); + $this->execBackground("iptables -D FORWARD -s ". $gateway ."/". $netmask . " -o tun0 -j ACCEPT"); + $this->execBackground("iptables -D FORWARD -d ". $gateway ."/". $netmask ." -m state --state ESTABLISHED,RELATED -i tun0 -j ACCEPT"); + + //Kill openvpn + $this->execBackground("pkill openvpn"); $this->response = array("success" => true, "content" => "VPN Stopped..."); diff --git a/OpenVPNConnect/js/module.js b/OpenVPNConnect/js/module.js index f337edf..3201417 100644 --- a/OpenVPNConnect/js/module.js +++ b/OpenVPNConnect/js/module.js @@ -4,6 +4,7 @@ registerController('openVPNConnectController', ['$api', '$scope', '$timeout', '$ // Workspace Variables. Each value is populated by the form or displays to the form. $scope.workspace = {config: "", + user: "", pass: "", flags: "", sharedconnection: false, @@ -18,14 +19,17 @@ registerController('openVPNConnectController', ['$api', '$scope', '$timeout', '$ */ $scope.content = ""; $scope.installLabel = "default"; - $scope.installLabelText = "Checking..." + $scope.installLabelText = "Checking..."; + $scope.installSDLabelText = "Checking..."; $scope.selectedFiles = []; + $scope.hideSDDependency = false; $scope.uploading = false; + $scope.installButtonWidth = "210px"; - // Call a function to install/uninstall dependencies for the module + // Call a function to install/uninstall dependencies for the module (install to local storage) $scope.handleDependencies = function(){ - $scope.workspace.setupcontent = "Handling dependencies please wait..."; + $scope.workspace.setupcontent = "Handling dependencies (local storage) please wait..."; $api.request({ module: 'OpenVPNConnect', @@ -44,6 +48,28 @@ registerController('openVPNConnectController', ['$api', '$scope', '$timeout', '$ } + // Call a function to install/uninstall dependencies for the module (install to the SD card) + $scope.handleDependenciesSDCard = function(){ + + $scope.workspace.setupcontent = "Handling dependencies (SD card) please wait..."; + + $api.request({ + module: 'OpenVPNConnect', + action: 'handleDependenciesSDCard', + }, function(response) { + if (response.success === true) { + + $scope.workspace.setupcontent = response.content; + + checkDependencies(); + + $timeout(function() {$window.location.reload();}, 5000); + } + //console.log(response) //Log the response to the console, this is useful for debugging. + }); + + } + /* Checks the current status of the dependencies for the module and displays it via the dependency install/uninstall button to the user. This is checked each time the app is loaded or when the user @@ -57,6 +83,11 @@ registerController('openVPNConnectController', ['$api', '$scope', '$timeout', '$ if (response.success === true) { $scope.installLabel = response.label; $scope.installLabelText = response.text; + $scope.installSDLabelText = response.textSD; + $scope.installButtonWidth = response.buttonWidth; + if(response.installed){ + $scope.hideSDDependency = true; + } } //console.log(response) //Log the response to the console, this is useful for debugging. }); @@ -65,6 +96,22 @@ registerController('openVPNConnectController', ['$api', '$scope', '$timeout', '$ // Call the checkDependencies function on page load checkDependencies(); + // Function to check if the VPN is currently running or not when re-visiting the module + var checkVPNStatus = function() { + $api.request({ + module: 'OpenVPNConnect', + action: 'checkVPNStatus' + }, function(response) { + if (response.success === true) { + $scope.workspace.outputcontent = response.content; + } + //console.log(response) //Log the response to the console, this is useful for debugging. + }); + } + + // Call checkVPNStatus function on page load + checkVPNStatus(); + /* Initializes module by creating necessary folder structures and scanning for uploaded certs this function is called each time the app is loaded to make sure the module is set up correctly */ @@ -100,7 +147,6 @@ registerController('openVPNConnectController', ['$api', '$scope', '$timeout', '$ $scope.workspace.config = cert; } - /* Calls the startVPN function, passes all the form params to the API to run the OpenVPN command Users can pass a config, an option password, and optional command line flags to run with the openvpn command line utility. Also the shared connection open lets the user share the @@ -111,6 +157,7 @@ registerController('openVPNConnectController', ['$api', '$scope', '$timeout', '$ module: 'OpenVPNConnect', action: 'startVPN', data: [$scope.workspace.config, + $scope.workspace.user, $scope.workspace.pass, $scope.workspace.flags, $scope.workspace.sharedconnection] diff --git a/OpenVPNConnect/log/status.log b/OpenVPNConnect/log/status.log new file mode 100644 index 0000000..e69de29 diff --git a/OpenVPNConnect/log/vpn.log b/OpenVPNConnect/log/vpn.log new file mode 100644 index 0000000..e69de29 diff --git a/OpenVPNConnect/module.html b/OpenVPNConnect/module.html index 4a07d8c..d43b031 100644 --- a/OpenVPNConnect/module.html +++ b/OpenVPNConnect/module.html @@ -13,7 +13,8 @@
- + +
@@ -58,7 +59,12 @@

- + + Clear +

+ +

+ Clear

@@ -136,6 +142,18 @@

    +
  • + 1.0.2 +
  • +
      +
    • Added in current status when revisiting page, logging, and ability to install dependencies to SD card or local storage. Also squashed some bugs :)
    • +
    +
  • + 1.0.1 +
  • +
      +
    • Minor Revisions: Added better iptables management with dynamic gateway and the ability to use auth-user-pass. Unofficial Release (Github Only)
    • +
  • 1.0
  • diff --git a/OpenVPNConnect/module.info b/OpenVPNConnect/module.info index 554bd3f..465f474 100644 --- a/OpenVPNConnect/module.info +++ b/OpenVPNConnect/module.info @@ -6,5 +6,5 @@ "tetra" ], "title": "OpenVPNConnect", - "version": "1.0" -} \ No newline at end of file + "version": "1.1" +}