mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-19 19:15:22 +00:00
Firewall: Automation: Filter - allow TCP/UDP combination in protocol selection, closes https://github.com/opnsense/core/issues/7962
This commit is contained in:
parent
0a408b3d57
commit
bcb5bae3e6
@ -42,7 +42,7 @@ abstract class Rule
|
||||
protected static $aliasMap = [];
|
||||
|
||||
/* ease the reuse of parsing for pf keywords by using class constants */
|
||||
const PARSE_PROTO = 'parseReplaceSimple,tcp/udp:{tcp udp}|a/n:"a/n",proto ';
|
||||
const PARSE_PROTO = 'parseReplaceSimple,tcp/udp:{tcp udp}|TCP/UDP:{tcp udp}|a/n:"a/n",proto ';
|
||||
|
||||
protected function loadAliasMap()
|
||||
{
|
||||
|
||||
@ -34,10 +34,23 @@ namespace OPNsense\Base\FieldTypes;
|
||||
*/
|
||||
class ProtocolField extends BaseListField
|
||||
{
|
||||
private $additionalOptions = [];
|
||||
|
||||
/**
|
||||
* @var array cached collected protocols
|
||||
*/
|
||||
private static $internalStaticOptionList = array();
|
||||
private static $internalStaticOptionList = [];
|
||||
|
||||
/**
|
||||
* setter for maximum value
|
||||
* @param integer $value
|
||||
*/
|
||||
public function setAddOptions($value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$this->additionalOptions = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generate validation data (list of protocols)
|
||||
@ -46,20 +59,26 @@ class ProtocolField extends BaseListField
|
||||
{
|
||||
/* IPv6 extension headers are skipped by the packet filter, we cannot police them */
|
||||
$ipv6_ext = array('IPV6-ROUTE', 'IPV6-FRAG', 'IPV6-OPTS', 'IPV6-NONXT', 'MOBILITY-HEADER');
|
||||
if (empty(self::$internalStaticOptionList)) {
|
||||
self::$internalStaticOptionList = array('any' => gettext('any'));
|
||||
$opt_hash = empty($this->additionalOptions) ? hash('sha256', json_encode($this->additionalOptions)) : '-';
|
||||
if (empty(self::$internalStaticOptionList[$opt_hash])) {
|
||||
self::$internalStaticOptionList[$opt_hash] = ['any' => gettext('any')];
|
||||
foreach (explode("\n", file_get_contents('/etc/protocols')) as $line) {
|
||||
if (substr($line, 0, 1) != "#") {
|
||||
$parts = preg_split('/\s+/', $line);
|
||||
if (count($parts) >= 4 && $parts[1] > 0) {
|
||||
$protocol = trim(strtoupper($parts[0]));
|
||||
if (!in_array($protocol, $ipv6_ext) && !isset(self::$internalStaticOptionList[$protocol])) {
|
||||
self::$internalStaticOptionList[$protocol] = $protocol;
|
||||
self::$internalStaticOptionList[$opt_hash][$protocol] = $protocol;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* append additional options */
|
||||
foreach ($this->additionalOptions as $prop => $value) {
|
||||
self::$internalStaticOptionList[$opt_hash][$prop] = $value;
|
||||
}
|
||||
asort(self::$internalStaticOptionList[$opt_hash], SORT_NATURAL | SORT_FLAG_CASE);
|
||||
}
|
||||
$this->internalOptionList = self::$internalStaticOptionList;
|
||||
$this->internalOptionList = self::$internalStaticOptionList[$opt_hash];
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,20 +41,20 @@ class Filter extends BaseModel
|
||||
public function performValidation($validateFullModel = false)
|
||||
{
|
||||
$config = Config::getInstance()->object();
|
||||
|
||||
$port_protos = ['TCP', 'UDP', 'TCP/UDP'];
|
||||
// standard model validations
|
||||
$messages = parent::performValidation($validateFullModel);
|
||||
foreach ([$this->rules->rule, $this->snatrules->rule] as $rules) {
|
||||
foreach ($rules->iterateItems() as $rule) {
|
||||
if ($validateFullModel || $rule->isFieldChanged()) {
|
||||
// port / protocol validation
|
||||
if (!empty((string)$rule->source_port) && !in_array($rule->protocol, ['TCP', 'UDP'])) {
|
||||
if (!empty((string)$rule->source_port) && !in_array($rule->protocol, $port_protos)) {
|
||||
$messages->appendMessage(new Message(
|
||||
gettext("Source ports are only valid for tcp or udp type rules."),
|
||||
$rule->source_port->__reference
|
||||
));
|
||||
}
|
||||
if (!empty((string)$rule->destination_port) && !in_array($rule->protocol, ['TCP', 'UDP'])) {
|
||||
if (!empty((string)$rule->destination_port) && !in_array($rule->protocol, $port_protos)) {
|
||||
$messages->appendMessage(new Message(
|
||||
gettext("Destination ports are only valid for tcp or udp type rules."),
|
||||
$rule->destination_port->__reference
|
||||
@ -100,7 +100,7 @@ class Filter extends BaseModel
|
||||
$rule->target->__reference
|
||||
));
|
||||
}
|
||||
if (!empty((string)$rule->target_port) && !in_array($rule->protocol, ['TCP', 'UDP'])) {
|
||||
if (!empty((string)$rule->target_port) && !in_array($rule->protocol, $port_protos)) {
|
||||
$messages->appendMessage(new Message(
|
||||
gettext("Target ports are only valid for tcp or udp type rules."),
|
||||
$rule->target_port->__reference
|
||||
|
||||
@ -57,6 +57,9 @@
|
||||
<protocol type="ProtocolField">
|
||||
<Required>Y</Required>
|
||||
<Default>any</Default>
|
||||
<AddOptions>
|
||||
<opt1 value='TCP/UDP'>TCP/UDP</opt1>
|
||||
</AddOptions>
|
||||
</protocol>
|
||||
<!-- XXX: should map internally to 'source' => array('network' => $source_net, "not" => true|false) -->
|
||||
<source_net type="NetworkAliasField">
|
||||
@ -148,6 +151,9 @@
|
||||
<protocol type="ProtocolField">
|
||||
<Required>Y</Required>
|
||||
<Default>any</Default>
|
||||
<AddOptions>
|
||||
<opt1 value='TCP/UDP'>TCP/UDP</opt1>
|
||||
</AddOptions>
|
||||
</protocol>
|
||||
<source_net type="NetworkAliasField">
|
||||
<Default>any</Default>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user