mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-14 08:34:39 +00:00
VPN / IPSec / Tunnel settings - work in progress for https://github.com/opnsense/core/issues/5279
This commit is contained in:
parent
fe727d2be1
commit
dfe3932166
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 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\IPsec\Api;
|
||||
|
||||
use OPNsense\Base\ApiControllerBase;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
|
||||
/**
|
||||
* Class TunnelController
|
||||
* @package OPNsense\IPsec\Api
|
||||
*/
|
||||
class TunnelController extends ApiControllerBase
|
||||
{
|
||||
private function search($records)
|
||||
{
|
||||
$itemsPerPage = intval($this->request->getPost('rowCount', 'int', 9999));
|
||||
$currentPage = intval($this->request->getPost('current', 'int', 1));
|
||||
$offset = ($currentPage - 1) * $itemsPerPage;
|
||||
$entry_keys = array_keys($records);
|
||||
if ($this->request->hasPost('searchPhrase') && $this->request->getPost('searchPhrase') !== '') {
|
||||
$searchPhrase = (string)$this->request->getPost('searchPhrase');
|
||||
$entry_keys = array_filter($entry_keys, function ($key) use ($searchPhrase, $records) {
|
||||
foreach ($records[$key] as $itemval) {
|
||||
if (stripos($itemval, $searchPhrase) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
$formatted = array_map(function ($value) use (&$records) {
|
||||
foreach ($records[$value] as $ekey => $evalue) {
|
||||
$item[$ekey] = $evalue;
|
||||
}
|
||||
return $item;
|
||||
}, array_slice($entry_keys, $offset, $itemsPerPage));
|
||||
|
||||
if ($this->request->hasPost('sort') && is_array($this->request->getPost('sort'))) {
|
||||
$keys = array_keys($this->request->getPost('sort'));
|
||||
$order = $this->request->getPost('sort')[$keys[0]];
|
||||
$keys = array_column($formatted, $keys[0]);
|
||||
array_multisort($keys, $order == 'asc' ? SORT_ASC : SORT_DESC, $formatted);
|
||||
}
|
||||
|
||||
return [
|
||||
'total' => count($entry_keys),
|
||||
'rowCount' => $itemsPerPage,
|
||||
'current' => $currentPage,
|
||||
'rows' => $formatted,
|
||||
];
|
||||
}
|
||||
public function searchPhase1Action()
|
||||
{
|
||||
$items = [];
|
||||
$this->sessionClose();
|
||||
$config = Config::getInstance()->object();
|
||||
if (!empty($config->ipsec->phase1)) {
|
||||
$idx = 0;
|
||||
$ifs = [];
|
||||
if ($config->interfaces->count() > 0) {
|
||||
foreach ($config->interfaces->children() as $key => $node) {
|
||||
$ifs[(string)$node->if] = !empty((string)$node->descr) ? (string)$node->descr : $key;
|
||||
}
|
||||
if ($config->virtualip->count() > 0) {
|
||||
foreach ($config->virtualip->children() as $node) {
|
||||
if (!empty((string)$node->vhid)) {
|
||||
$key = (string)$node->interface . "_vip". (string)$node->vhid;
|
||||
} else {
|
||||
$key = (string)$node->subnet;
|
||||
}
|
||||
$ifs[$key] = "$node->subnet ({$node->descr})";
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($config->ipsec->phase1 as $p1) {
|
||||
$interface = (string)$p1->interface;
|
||||
$ph1type= ['ikev1' => 'IKE', 'ikev2' => 'IKEv2', 'ike' => 'auto'];
|
||||
$item = [
|
||||
"id" => $idx,
|
||||
"disabled" => !empty((string)$p1->disabled),
|
||||
"protocol" => $p1->protocol == "inet" ? "IPv4" : "IPv6",
|
||||
"iketype" => $ph1type[(string)$p1->iketype],
|
||||
"interface" => !empty($ifs[$interface]) ? $ifs[$interface] : $interface,
|
||||
"remote_gateway" => (string)$p1->{"remote-gateway"},
|
||||
"mobile" => !empty((string)$p1->mobile),
|
||||
"mode" => (string)$p1->mode,
|
||||
"description" => (string)$p1->descr
|
||||
];
|
||||
$item['type'] = "{$item['protocol']} {$item['iketype']}";
|
||||
$items[] = $item;
|
||||
$idx++;
|
||||
}
|
||||
}
|
||||
return $this->search($items);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 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\IPsec;
|
||||
|
||||
/**
|
||||
* Class TunnelsController
|
||||
* @package OPNsense\IPsec
|
||||
*/
|
||||
class TunnelsController extends \OPNsense\Base\IndexController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->pick('OPNsense/IPsec/tunnels');
|
||||
}
|
||||
}
|
||||
98
src/opnsense/mvc/app/views/OPNsense/IPsec/tunnels.volt
Normal file
98
src/opnsense/mvc/app/views/OPNsense/IPsec/tunnels.volt
Normal file
@ -0,0 +1,98 @@
|
||||
|
||||
<script>
|
||||
$(function () {
|
||||
const $grid = $('#grid-phase1').UIBootgrid({
|
||||
search: '/api/ipsec/tunnel/search_phase1',
|
||||
options: {
|
||||
formatters: {
|
||||
"commands": function (column, row) {
|
||||
return '<button type="button" class="btn btn-xs btn-default command-edit bootgrid-tooltip" data-row-id="' + row.id + '"><span class="fa fa-fw fa-pencil"></span></button> ' +
|
||||
'<button type="button" class="btn btn-xs btn-default command-copy bootgrid-tooltip" data-row-id="' + row.id + '"><span class="fa fa-fw fa-clone"></span></button>' +
|
||||
'<button type="button" class="btn btn-xs btn-default command-delete bootgrid-tooltip" data-row-id="' + row.id + '"><span class="fa fa-fw fa-trash-o"></span></button>';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div class="tab-content content-box col-xs-12 __mb">
|
||||
<table id="grid-phase1" class="table table-condensed table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="id" data-type="numeric" data-identifier="true" data-visible="false">ID</th>
|
||||
<th data-column-id="type" data-type="string">{{ lang._('Type') }}</th>
|
||||
<th data-column-id="remote_gateway" data-width="20em" data-type="string">{{ lang._('Remote Gateway') }}</th>
|
||||
<th data-column-id="mode" data-width="20em" data-type="string">{{ lang._('Mode') }}</th>
|
||||
<th data-column-id="proposal" data-type="string">{{ lang._('Phase 1 Proposal') }}</th>
|
||||
<th data-column-id="authentication" data-type="string">{{ lang._('Authentication') }}</th>
|
||||
<th data-column-id="description" data-type="string">{{ lang._('Description') }}</th>
|
||||
<th data-column-id="commands" data-width="7em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan=7></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-primary">
|
||||
<span class="fa fa-fw fa-plus"></span>
|
||||
</button>
|
||||
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default">
|
||||
<span class="fa fa-fw fa-trash-o"></span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-content content-box col-xs-12 __mb">
|
||||
<table id="grid-phase2" class="table table-condensed table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="id" data-type="numeric" data-identifier="true" data-visible="false">ID</th>
|
||||
<th data-column-id="type" data-type="string">{{ lang._('Type') }}</th>
|
||||
<th data-column-id="local_subnet" data-width="20em" data-type="string">{{ lang._('Local Subnet') }}</th>
|
||||
<th data-column-id="remote_subnet" data-width="20em" data-type="string">{{ lang._('Remote Subnet') }}</th>
|
||||
<th data-column-id="proposal" data-type="string">{{ lang._('Phase 2 Proposal') }}</th>
|
||||
<th data-column-id="description" data-type="string">{{ lang._('Description') }}</th>
|
||||
<th data-column-id="commands" data-width="7em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan=6></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-primary">
|
||||
<span class="fa fa-fw fa-plus"></span>
|
||||
</button>
|
||||
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default">
|
||||
<span class="fa fa-fw fa-trash-o"></span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-content content-box col-xs-12 __mb">
|
||||
<table class="table table-condensed">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<input name="enable" type="checkbox" id="enable" value="yes" checked="checked"/>
|
||||
<strong>{{ lang._('Enable IPsec') }}</strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="submit" name="save" class="btn btn-primary" value="{{ lang._('Save') }}" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user