mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-13 08:09:41 +00:00
VPN: IPsec: Security Policy Database - Manual assignments linking to connection children (https://github.com/opnsense/core/issues/6451)
Add connection child as option for manual SPDs, to make sure these are easily selectable we'll extend ModelRelationField to include a method to return it's value (so we can combine parent descriptions)
This commit is contained in:
parent
1f4afe7433
commit
f384afa8f9
@ -43,7 +43,7 @@ class ManualSPDController extends ApiMutableModelControllerBase
|
||||
{
|
||||
return $this->searchBase(
|
||||
'SPDs.SPD',
|
||||
['enabled', 'description', 'origin', 'reqid', 'source', 'destination']
|
||||
['enabled', 'description', 'origin', 'reqid', 'connection_child', 'source', 'destination']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -13,6 +13,15 @@
|
||||
to reconnect in order to add the entry as we use an updown event.
|
||||
</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>spd.connection_child</id>
|
||||
<label>Connection child</label>
|
||||
<type>dropdown</type>
|
||||
<help>
|
||||
Connection child to register this manual item on. Please note that an established tunnel needs
|
||||
to reconnect in order to add the entry as we use an updown event.
|
||||
</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>spd.source</id>
|
||||
<label>Source network</label>
|
||||
|
||||
@ -105,7 +105,11 @@ class ModelRelationField extends BaseListField
|
||||
$descriptions = [];
|
||||
foreach ($displayKeys as $displayKey) {
|
||||
if ($node->$displayKey != null) {
|
||||
$descriptions[] = (string)$node->$displayKey;
|
||||
if ($node->$displayKey->getObjectType() == 'ModelRelationField') {
|
||||
$descriptions[] = $node->$displayKey->display_value();
|
||||
} else {
|
||||
$descriptions[] = (string)$node->$displayKey;
|
||||
}
|
||||
} else {
|
||||
$descriptions[] = "";
|
||||
}
|
||||
@ -206,6 +210,19 @@ class ModelRelationField extends BaseListField
|
||||
return parent::getNodeData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string string display value of this field
|
||||
*/
|
||||
public function display_value()
|
||||
{
|
||||
$tmp = [];
|
||||
foreach (explode(',', $this->internalValue) as $key) {
|
||||
$tmp[] = $this->internalOptionList[$key] ?? '';
|
||||
}
|
||||
return implode(',', $tmp);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* retrieve field validators for this field type
|
||||
* @return array returns Text/regex validator
|
||||
|
||||
@ -45,6 +45,7 @@ class Swanctl extends BaseModel
|
||||
{
|
||||
$messages = parent::performValidation($validateFullModel);
|
||||
$vtis = [];
|
||||
$spds = [];
|
||||
|
||||
foreach ($this->getFlatNodes() as $key => $node) {
|
||||
if ($validateFullModel || $node->isFieldChanged()) {
|
||||
@ -54,6 +55,8 @@ class Swanctl extends BaseModel
|
||||
$parentTagName = $parentNode->getInternalXMLTagName();
|
||||
if ($parentTagName === 'VTI') {
|
||||
$vtis[$parentKey] = $parentNode;
|
||||
} elseif ($parentTagName === 'SPD') {
|
||||
$spds[$parentKey] = $parentNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,6 +74,17 @@ class Swanctl extends BaseModel
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($spds as $key => $node) {
|
||||
if (
|
||||
((string)$node->reqid == '' && (string)$node->connection_child == '') ||
|
||||
((string)$node->reqid != '' && (string)$node->connection_child != '')
|
||||
) {
|
||||
$messages->appendMessage(
|
||||
new Message(gettext("Either reqid or child must be set"), $key . ".connection_child")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
@ -174,12 +188,9 @@ class Swanctl extends BaseModel
|
||||
if (!isset($data['connections'][$parent]['children'])) {
|
||||
$data['connections'][$parent]['children'] = [];
|
||||
}
|
||||
if (!empty($thisnode['reqid'])) {
|
||||
// trigger updown event handler when a reqid is set.
|
||||
// currently this only handles manual spd entries, we may extend/refactor the script later
|
||||
// if needed
|
||||
$thisnode['updown'] = '/usr/local/opnsense/scripts/ipsec/updown_event.py';
|
||||
}
|
||||
$thisnode['updown'] = '/usr/local/opnsense/scripts/ipsec/updown_event.py --connection_child ';
|
||||
$thisnode['updown'] .= $node_uuid;
|
||||
|
||||
$data['connections'][$parent]['children'][$node_uuid] = $thisnode;
|
||||
} else {
|
||||
$data['connections'][$parent][$key . '-' . $node_uuid] = $thisnode;
|
||||
|
||||
@ -413,8 +413,17 @@
|
||||
<reqid type="IntegerField">
|
||||
<MinimumValue>1</MinimumValue>
|
||||
<MaximumValue>65535</MaximumValue>
|
||||
<Required>Y</Required>
|
||||
</reqid>
|
||||
<connection_child type="ModelRelationField">
|
||||
<Model>
|
||||
<host>
|
||||
<source>OPNsense.IPsec.Swanctl</source>
|
||||
<items>children.child</items>
|
||||
<display>connection,description</display>
|
||||
<display_format>%s - %s</display_format>
|
||||
</host>
|
||||
</Model>
|
||||
</connection_child>
|
||||
<source type="NetworkField">
|
||||
<Required>Y</Required>
|
||||
<WildcardEnabled>N</WildcardEnabled>
|
||||
|
||||
@ -158,6 +158,7 @@
|
||||
<th data-column-id="origin" data-type="string" data-visible="false">{{ lang._('Origin') }}</th>
|
||||
<th data-column-id="enabled" data-width="6em" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
|
||||
<th data-column-id="reqid" data-type="string">{{ lang._('Reqid') }}</th>
|
||||
<th data-column-id="connection_child" data-type="string">{{ lang._('Child') }}</th>
|
||||
<th data-column-id="source" data-type="string">{{ lang._('Source') }}</th>
|
||||
<th data-column-id="destination" data-type="string">{{ lang._('Destination') }}</th>
|
||||
<th data-column-id="description" data-type="string">{{ lang._('Description') }}</th>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#!/usr/local/bin/python3
|
||||
|
||||
"""
|
||||
Copyright (c) 2022 Ad Schellevis <ad@opnsense.org>
|
||||
Copyright (c) 2022-2023 Ad Schellevis <ad@opnsense.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -44,6 +44,7 @@ spd_add_cmd = 'spdadd -%(ipproto)s %(source)s %(destination)s any ' \
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--connection_child', help='uuid of the connection child')
|
||||
parser.add_argument('--reqid', default=os.environ.get('PLUTO_REQID'))
|
||||
parser.add_argument('--local', default=os.environ.get('PLUTO_ME'))
|
||||
parser.add_argument('--remote', default=os.environ.get('PLUTO_PEER'))
|
||||
@ -56,28 +57,32 @@ if __name__ == '__main__':
|
||||
if os.path.exists(spd_filename):
|
||||
cnf = ConfigParser()
|
||||
cnf.read(spd_filename)
|
||||
conf_section = 'spd_%s' % cmd_args.reqid
|
||||
if cnf.has_section(conf_section):
|
||||
spds = {}
|
||||
for opt in cnf.options(conf_section):
|
||||
if opt.count('_') == 1:
|
||||
tmp = opt.split('_')
|
||||
seqid = tmp[1]
|
||||
if seqid not in spds:
|
||||
spds[seqid] = {
|
||||
'reqid': cmd_args.reqid,
|
||||
'local' : cmd_args.local,
|
||||
'remote' : cmd_args.remote,
|
||||
'destination': os.environ.get('PLUTO_PEER_CLIENT')
|
||||
}
|
||||
if cnf.get(conf_section, opt).strip() != '':
|
||||
spds[seqid][tmp[0]] = cnf.get(conf_section, opt).strip()
|
||||
# (re)aaply manual policies if specified
|
||||
cur_spds = list_spds(req_id=cmd_args.reqid, automatic=False)
|
||||
spds = []
|
||||
for section in cnf.sections():
|
||||
if cnf.get(section, 'reqid') == cmd_args.reqid \
|
||||
or cnf.get(section, 'connection_child') == cmd_args.connection_child:
|
||||
spds.append({
|
||||
'reqid': cmd_args.reqid,
|
||||
'local' : cmd_args.local,
|
||||
'remote' : cmd_args.remote,
|
||||
'destination': os.environ.get('PLUTO_PEER_CLIENT')
|
||||
})
|
||||
for opt in cnf.options(section):
|
||||
if cnf.get(section, opt).strip() != '':
|
||||
spds[-1][opt] = cnf.get(section, opt).strip()
|
||||
|
||||
# (re)apply manual policies if specified
|
||||
cur_spds = list_spds(automatic=False)
|
||||
set_key = []
|
||||
for spd in cur_spds:
|
||||
set_key.append('spddelete -n %(src)s %(dst)s any -P %(direction)s;' % spd)
|
||||
for spd in spds.values():
|
||||
policy_found = False
|
||||
for mspd in spds:
|
||||
if mspd['source'] == spd['src'] and mspd['destination'] == spd['dst']:
|
||||
policy_found = True
|
||||
if policy_found or spd['reqid'] == cmd_args.reqid:
|
||||
set_key.append('spddelete -n %(src)s %(dst)s any -P %(direction)s;' % spd)
|
||||
|
||||
for spd in spds:
|
||||
if None in spd.values():
|
||||
# incomplete, skip
|
||||
continue
|
||||
|
||||
@ -3,19 +3,16 @@
|
||||
# Do not edit this file manually.
|
||||
#
|
||||
|
||||
{% set prev_spd = {'reqid' : None } %}
|
||||
{% for spd in helpers.toList('OPNsense.Swanctl.SPDs.SPD', 'reqid', 'int') %}
|
||||
{% for spd in helpers.toList('OPNsense.Swanctl.SPDs.SPD') %}
|
||||
{% if spd.enabled == '1' %}
|
||||
{% if prev_spd.reqid != spd.reqid %}
|
||||
|
||||
[spd_{{spd.reqid}}]
|
||||
{% endif %}
|
||||
protocol_{{loop.index}}={{spd.protocol}}
|
||||
reqid_{{loop.index}}={{spd.reqid}}
|
||||
source_{{loop.index}}={{spd.source}}
|
||||
destination_{{loop.index}}={{spd.destination}}
|
||||
description_{{loop.index}}={{spd.description}}
|
||||
uuid_{{loop.index}}={{spd['uuid']}}
|
||||
{% do prev_spd.update({'reqid': spd.reqid}) %}
|
||||
[spd_{{spd['@uuid']|replace('-', '')}}]
|
||||
protocol ={{spd.protocol}}
|
||||
reqid = {{spd.reqid}}
|
||||
connection_child = {{spd.connection_child}}
|
||||
source = {{spd.source}}
|
||||
destination = {{spd.destination}}
|
||||
description = {{spd.description}}
|
||||
uuid = {{spd['@uuid']}}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user