Skip to content

Commit

Permalink
VPN: OpenVPN: Connection Status - refactor to MVC
Browse files Browse the repository at this point in the history
PR: #6382

(cherry picked from commit b9a1633)
(cherry picked from commit fa30a8c)
(cherry picked from commit 16492ce)
(cherry picked from commit b50e529)
(cherry picked from commit c897054)
  • Loading branch information
AdSchellevis authored and fichtner committed Mar 28, 2023
1 parent 4ac3e1d commit 30e38b0
Show file tree
Hide file tree
Showing 12 changed files with 530 additions and 314 deletions.
5 changes: 4 additions & 1 deletion plist
Expand Up @@ -381,7 +381,9 @@
/usr/local/opnsense/mvc/app/controllers/OPNsense/Monit/forms/services.xml
/usr/local/opnsense/mvc/app/controllers/OPNsense/Monit/forms/tests.xml
/usr/local/opnsense/mvc/app/controllers/OPNsense/OpenVPN/Api/ExportController.php
/usr/local/opnsense/mvc/app/controllers/OPNsense/OpenVPN/Api/ServiceController.php
/usr/local/opnsense/mvc/app/controllers/OPNsense/OpenVPN/ExportController.php
/usr/local/opnsense/mvc/app/controllers/OPNsense/OpenVPN/StatusController.php
/usr/local/opnsense/mvc/app/controllers/OPNsense/OpenVPN/forms/export_options.xml
/usr/local/opnsense/mvc/app/controllers/OPNsense/Proxy/Api/ServiceController.php
/usr/local/opnsense/mvc/app/controllers/OPNsense/Proxy/Api/SettingsController.php
Expand Down Expand Up @@ -710,6 +712,7 @@
/usr/local/opnsense/mvc/app/views/OPNsense/Monit/index.volt
/usr/local/opnsense/mvc/app/views/OPNsense/Monit/status.volt
/usr/local/opnsense/mvc/app/views/OPNsense/OpenVPN/export.volt
/usr/local/opnsense/mvc/app/views/OPNsense/OpenVPN/status.volt
/usr/local/opnsense/mvc/app/views/OPNsense/Proxy/index.volt
/usr/local/opnsense/mvc/app/views/OPNsense/Routes/index.volt
/usr/local/opnsense/mvc/app/views/OPNsense/Syslog/index.volt
Expand Down Expand Up @@ -922,6 +925,7 @@
/usr/local/opnsense/scripts/openssh/ssh_query.py
/usr/local/opnsense/scripts/openvpn/client_connect.php
/usr/local/opnsense/scripts/openvpn/client_disconnect.sh
/usr/local/opnsense/scripts/openvpn/kill_session.py
/usr/local/opnsense/scripts/openvpn/ovpn_event.py
/usr/local/opnsense/scripts/openvpn/ovpn_status.py
/usr/local/opnsense/scripts/openvpn/tls_verify.php
Expand Down Expand Up @@ -1956,7 +1960,6 @@
/usr/local/www/status_habackup.php
/usr/local/www/status_interfaces.php
/usr/local/www/status_ntpd.php
/usr/local/www/status_openvpn.php
/usr/local/www/status_wireless.php
/usr/local/www/system_advanced_admin.php
/usr/local/www/system_advanced_firewall.php
Expand Down
@@ -0,0 +1,221 @@
<?php

/*
* Copyright (C) 2023 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

namespace OPNsense\OpenVPN\Api;

use OPNsense\Base\ApiControllerBase;
use OPNsense\Core\Config;
use OPNsense\Core\Backend;

/**
* Class ServiceController
* @package OPNsense\OpenVPN
*/
class ServiceController extends ApiControllerBase
{
private function getConfigs($role)
{
$config = Config::getInstance()->object();
$config_payload = [];
$cnf_section = 'openvpn-' . $role;
if (!empty($config->openvpn->$cnf_section)) {
foreach ($config->openvpn->$cnf_section as $cnf) {
if (!empty((string)$cnf->vpnid)) {
$config_payload[(string)$cnf->vpnid] = $cnf;
}
}
}
return $config_payload;
}

/**
* Search sessions
* @return array
*/
public function searchSessionsAction()
{
$this->sessionClose();
$data = json_decode((new Backend())->configdRun('openvpn connections client,server') ?? '', true) ?? [];
$records = [];
$roles = ['client', 'server'];
if ($this->request->has('type') && is_array($this->request->get('type'))) {
$roles = array_intersect($this->request->get('type'), $roles);
}
foreach ($roles as $role) {
$config_payload = $this->getConfigs($role);
$vpnids = [];
if (!empty($data[$role])) {
foreach ($data[$role] as $idx => $stats) {
$vpnids[] = $idx;
$stats['type'] = $role;
$stats['id'] = $idx;
$stats['description'] = '';
$stats['connected_since'] = null;
if (!empty($stats['timestamp'])) {
$stats['connected_since'] = date('Y-m-d H:i:s', $stats['timestamp']);
}
if (!empty($config_payload[$idx])) {
$stats['description'] = (string)$config_payload[$idx]->description ?? '';
}
if (!empty($stats['client_list'])) {
foreach ($stats['client_list'] as $client) {
$tmp = array_merge($stats, $client);
$tmp['id'] .= '_' . $client['real_address'];
$tmp['is_client'] = true;
$records[] = $tmp;
}
} else {
$records[] = $stats;
}
}
}
// add non running enabled servers
foreach ($config_payload as $idx => $cnf) {
if (!in_array($idx, $vpnids) && empty((string)$cnf->disable)) {
$records[] = [
'id' => $idx,
'service_id' => "openvpn/" . $idx,
'type' => $role,
'description' => (string)$cnf->description ?? '',
'connected_since' => null,
'status' => null
];
}
}
}
return $this->searchRecordsetBase($records);
}

/**
* Search routes
* @return array
*/
public function searchRoutesAction()
{
$records = [];
$data = json_decode((new Backend())->configdRun('openvpn connections client,server') ?? '', true) ?? [];
$records = [];
$roles = ['client', 'server'];
if ($this->request->has('type') && is_array($this->request->get('type'))) {
$roles = array_intersect($this->request->get('type'), $roles);
}
foreach ($roles as $role) {
if (!empty($data[$role])) {
$config_payload = $this->getConfigs($role);
foreach ($data[$role] as $idx => $payload) {
if (!empty($payload['routing_table'])) {
foreach ($payload['routing_table'] as $route_entry) {
$route_entry['type'] = $role;
$route_entry['id'] = $idx;
$route_entry['description'] = '';
if (!empty($config_payload[$idx])) {
$route_entry['description'] = (string)$config_payload[$idx]->description ?? '';
}
$records[] = $route_entry;
}
}
}
}
}
return $this->searchRecordsetBase($records);
}

/**
* kill session by source ip:port or common name
* @return array
*/
public function killSessionAction()
{
if (!$this->request->isPost()) {
return ['result' => 'failed'];
}
$this->sessionClose();
$server_id = $this->request->get('server_id', null);
$session_id = $this->request->get('session_id', null);
if ($server_id != null && $session_id != null) {
$data = json_decode((new Backend())->configdpRun('openvpn kill', [$server_id, $session_id]) ?? '', true);
if (!empty($data)) {
return $data;
}
return ['result' => 'failed'];
} else {
return ['status' => 'invalid'];
}
}

/**
* @param int $id server/client id to start
* @return array
*/
public function startServiceAction($id = null)
{
if (!$this->request->isPost() || $id == null) {
return ['result' => 'failed'];
}

$this->sessionClose();

(new Backend())-> configdpRun('service start', ['openvpn', $id]);

return ['result' => 'ok'];
}

/**
* @param int $id server/client id to stop
* @return array
*/
public function stopServiceAction($id = null)
{
if (!$this->request->isPost() || $id == null) {
return ['result' => 'failed'];
}

$this->sessionClose();

(new Backend())-> configdpRun('service stop', ['openvpn', $id]);

return ['result' => 'ok'];
}

/**
* @param int $id server/client id to restart
* @return array
*/
public function restartServiceAction($id = null)
{
if (!$this->request->isPost() || $id == null) {
return ['result' => 'failed'];
}

$this->sessionClose();

(new Backend())-> configdpRun('service restart', ['openvpn', $id]);

return ['result' => 'ok'];
}
}
@@ -0,0 +1,47 @@
<?php

/*
* Copyright (C) 2023 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

namespace OPNsense\OpenVPN;

use OPNsense\Base\IndexController as BaseIndexController;

/**
* Class StatusController
* @package OPNsense\OpenVPN
*/
class StatusController extends BaseIndexController
{
/**
* default index page
* @throws \Exception
*/
public function indexAction()
{
$this->view->pick('OPNsense/OpenVPN/status');
}
}
3 changes: 2 additions & 1 deletion src/opnsense/mvc/app/models/OPNsense/Core/ACL/ACL.xml
Expand Up @@ -514,7 +514,8 @@
<page-status-openvpn>
<name>Status: OpenVPN</name>
<patterns>
<pattern>status_openvpn.php*</pattern>
<pattern>ui/openvpn/status</pattern>
<pattern>api/openvpn/service/*</pattern>
</patterns>
</page-status-openvpn>
<page-status-services>
Expand Down
2 changes: 1 addition & 1 deletion src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml
Expand Up @@ -217,7 +217,7 @@
<ClientExport order="40" VisibleName="Client Export" url="/ui/openvpn/export">
<Edit url="/ui/openvpn/export?*" visibility="hidden"/>
</ClientExport>
<Status order="60" VisibleName="Connection Status" url="/status_openvpn.php"/>
<Status order="60" VisibleName="Connection Status" url="/ui/openvpn/status"/>
<LogFile order="70" VisibleName="Log File" url="/ui/diagnostics/log/core/openvpn"/>
</OpenVPN>
</VPN>
Expand Down

0 comments on commit 30e38b0

Please sign in to comment.