From 3527717787bb75df8d41493ea957ef6d1db0e1da Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Sat, 30 Oct 2021 19:43:56 +0200 Subject: [PATCH] VPN / IPSec / Tunnel settings - new overview page, hook in phase1/2 delete actions. for https://github.com/opnsense/core/issues/5279 o since ikeid is unique for a phase1 entry, we should use it as a unique key there. o phase2 entries don't have a unique key, in which case we can only fallback to sequence, which has concurerrency issues. --- .../OPNsense/IPsec/Api/TunnelController.php | 73 +++++++++++++++++-- .../mvc/app/views/OPNsense/IPsec/tunnels.volt | 7 +- 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/src/opnsense/mvc/app/controllers/OPNsense/IPsec/Api/TunnelController.php b/src/opnsense/mvc/app/controllers/OPNsense/IPsec/Api/TunnelController.php index 61dc9da3b..a843d20c1 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/IPsec/Api/TunnelController.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/IPsec/Api/TunnelController.php @@ -143,8 +143,7 @@ class TunnelController extends ApiControllerBase $ph1proposal .= " + " . gettext("DH Group") . " {$p1->dhgroup}"; } $item = [ - "id" => $idx, - "ikeid" => intval((string)$p1->ikeid), + "id" => intval((string)$p1->ikeid), // ikeid should be unique "enabled" => empty((string)$p1->disabled) ? "1" : "0", "protocol" => $p1->protocol == "inet" ? "IPv4" : "IPv6", "iketype" => $ph1type[(string)$p1->iketype], @@ -193,7 +192,7 @@ class TunnelController extends ApiControllerBase $this->sessionClose(); $config = Config::getInstance()->object(); if (!empty($config->ipsec->phase2)) { - $idx = 0; + $p2idx = 0; $ifs = []; if ($config->interfaces->count() > 0) { foreach ($config->interfaces->children() as $key => $node) { @@ -203,7 +202,7 @@ class TunnelController extends ApiControllerBase foreach ($config->ipsec->phase2 as $p2) { $ikeid = intval((string)$p2->ikeid); if ($ikeid != $selected_ikeid) { - $idx++; + $p2idx++; continue; } $p2mode = array_search( @@ -272,7 +271,7 @@ class TunnelController extends ApiControllerBase $ph2proposal .= sprintf("+ %s %s", gettext("DH Group"), "{$p2->pfsgroup}"); } $item = [ - "id" => $idx, + "id" => $p2idx, "ikeid" => $ikeid, "enabled" => empty((string)$p2->disabled) ? "1" : "0", "protocol" => $p2->protocol == "esp" ? "ESP" : "AH", @@ -283,9 +282,71 @@ class TunnelController extends ApiControllerBase "description" => (string)$p2->descr ]; $items[] = $item; - $idx++; + $p2idx++; } } return $this->search($items); } + + /** + * delete phase 1 including associated phase 2 entries + */ + public function delPhase1Action($ikeid) + { + if ($this->request->isPost()) { + $phase_ids = []; + $this->sessionClose(); + Config::getInstance()->lock(); + $config = Config::getInstance()->object(); + foreach ([$config->ipsec->phase1, $config->ipsec->phase2] as $phid => $phase) { + $phase_ids[$phid] = []; + if (!empty($phase)) { + $idx = 0; + foreach ($phase as $p) { + if(intval((string)$p->ikeid) == intval($ikeid)) { + $phase_ids[$phid][] = $idx; + } + $idx++; + } + foreach (array_reverse($phase_ids[$phid]) as $idx) { + unset($phase[$idx]); + } + } + } + Config::getInstance()->save(); + if (!empty($phase_ids[0])) { + @touch("/tmp/ipsec.dirty"); + } + return [ + 'status' => 'ok', + 'phase1count' => count($phase_ids[0]), // should be 1 as ikeid is unique + 'phase2count' => count($phase_ids[1]), + ]; + } + return ['status' => 'failed']; + } + + + /** + * delete phase 2 entry + */ + public function delPhase2Action($seqid) + { + if ($this->request->isPost()) { + $phase_ids = []; + $this->sessionClose(); + Config::getInstance()->lock(); + $config = Config::getInstance()->object(); + if (isset($config->ipsec->phase2[intval($seqid)])) { + unset($config->ipsec->phase2[intval($seqid)]); + Config::getInstance()->save(); + if (!empty($phase_ids[0])) { + @touch("/tmp/ipsec.dirty"); + } + return ['status' => 'ok']; + } + return ['status' => 'not_found']; + } + return ['status' => 'failed']; + } } diff --git a/src/opnsense/mvc/app/views/OPNsense/IPsec/tunnels.volt b/src/opnsense/mvc/app/views/OPNsense/IPsec/tunnels.volt index 8ae137dba..9c29e19c6 100644 --- a/src/opnsense/mvc/app/views/OPNsense/IPsec/tunnels.volt +++ b/src/opnsense/mvc/app/views/OPNsense/IPsec/tunnels.volt @@ -27,6 +27,7 @@ }; const $grid_phase1 = $('#grid-phase1').UIBootgrid({ search: '/api/ipsec/tunnel/search_phase1', + del: '/api/ipsec/tunnel/del_phase1/', options: { formatters: formatters, multiSelect: false, @@ -45,6 +46,7 @@ }); const $grid_phase2 = $('#grid-phase2').UIBootgrid({ search: '/api/ipsec/tunnel/search_phase2', + del: '/api/ipsec/tunnel/del_phase2/', options: { formatters: formatters, useRequestHandlerOnGet: true, @@ -54,7 +56,7 @@ let current_rows = $("#grid-phase1").bootgrid("getCurrentRows"); $.each(rows, function(key, seq){ if (current_rows[seq] !== undefined) { - ids.push(current_rows[seq].ikeid); + ids.push(current_rows[seq].id); } }); if (ids.length > 0) { @@ -75,8 +77,7 @@ {{ lang._('Enabled') }} - {{ lang._('ID') }} - {{ lang._('ikeid') }} + {{ lang._('ikeid') }} {{ lang._('Type') }} {{ lang._('Remote Gateway') }} {{ lang._('Mode') }}