%PDF- %PDF-
| Direktori : /backups/router/usr/local/opnsense/mvc/app/controllers/OPNsense/OpenVPN/Api/ |
| Current File : //backups/router/usr/local/opnsense/mvc/app/controllers/OPNsense/OpenVPN/Api/ServiceController.php |
<?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;
use OPNsense\OpenVPN\OpenVPN;
/**
* 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] = [
'description' => (string)$cnf->description ?? '',
'enabled' => empty((string)$cnf->disable) ? '1' : '0'
];
}
}
}
foreach ((new OpenVPN())->Instances->Instance->iterateItems() as $node_uuid => $node) {
if ((string)$node->role == $role) {
$config_payload[$node_uuid] = [
'enabled' => (string)$node->enabled,
'description' => (string)$node->description
];
}
}
return $config_payload;
}
/**
* Search sessions
* @return array
*/
public function searchSessionsAction()
{
$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'] = '';
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;
unset($tmp['client_list']);
unset($tmp['routing_table']);
$records[] = $tmp;
}
} else {
$records[] = $stats;
}
}
}
// add non running enabled servers
foreach ($config_payload as $idx => $cnf) {
if (!in_array($idx, $vpnids) && !empty($cnf['enabled'])) {
$records[] = [
'id' => $idx,
'service_id' => "openvpn/" . $idx,
'type' => $role,
'description' => $cnf['description'],
];
}
}
}
// make sure all records contain the same amount of keys to prevent sorting issues.
$all_keys = [];
foreach ($records as $record) {
$all_keys = array_unique(array_merge(array_keys($record), $all_keys));
}
foreach ($records as &$record) {
foreach ($all_keys as $key) {
if (!isset($record[$key])) {
$record[$key] = 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'];
}
$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'];
}
(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'];
}
(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'];
}
(new Backend())->configdpRun('service restart', ['openvpn', $id]);
return ['result' => 'ok'];
}
/**
* @return array
*/
public function reconfigureAction()
{
if (!$this->request->isPost()) {
return ['result' => 'failed'];
}
$backend = new Backend();
$backend->configdRun('openvpn configure');
$backend->configdRun('interface invoke registration');
return ['result' => 'ok'];
}
}