MVC / NetworkField: add strict option (disallow host bits in CIDR notation)

This commit is contained in:
Stephan de Wit 2023-03-03 16:07:18 +01:00
parent dcfa1cb0c0
commit df1fbfbb05
3 changed files with 57 additions and 2 deletions

View File

@ -94,6 +94,36 @@ class Util
return false;
}
/**
* is provided network strict (host bits not set)
* @param string $network network
* @return boolean
*/
public static function isStrict($network)
{
if (self::isSubnet($network)) {
list($net, $mask) = explode('/', $network);
$ip_net = inet_pton($net);
$bits = (strpos($net, ":") !== false && $mask <= 128) ? 128 : 32;
$ip_mask = "";
$significant_bits = $mask;
for ($i = 0; $i < $bits/8; $i++) {
if ($significant_bits >= 8) {
$ip_mask .= chr(0xFF);
$significant_bits -= 8;
} else {
$ip_mask .= chr(~(0xFF >> $significant_bits));
$significant_bits = 0;
}
}
return $ip_net == ($ip_net & $ip_mask);
}
return false;
}
/**
* is provided network a valid wildcard (https://en.wikipedia.org/wiki/Wildcard_mask)
* @param string $network network

View File

@ -75,6 +75,11 @@ class NetworkField extends BaseField
*/
private $internalAsList = false;
/**
* @var bool when set, host bits with a value other than zero are not allowed in the notation if a mask is provided
*/
private $internalStrict = false;
/**
* always lowercase / trim networks
* @param string $value
@ -150,6 +155,19 @@ class NetworkField extends BaseField
}
}
/**
* select if host bits are allowed in the notation
* @param $value
*/
public function setStrict($value)
{
if (trim(strtoupper($value)) == "Y") {
$this->internalStrict = true;
} else {
$this->internalStrict = false;
}
}
/**
* get valid options, descriptions and selected value
* @return array
@ -184,7 +202,8 @@ class NetworkField extends BaseField
'split' => $this->internalFieldSeparator,
'netMaskRequired' => $this->internalNetMaskRequired,
'netMaskAllowed' => $this->internalNetMaskAllowed,
'version' => $this->internalAddressFamily
'version' => $this->internalAddressFamily,
'strict' => $this->internalStrict
));
}
}

View File

@ -31,6 +31,7 @@
namespace OPNsense\Base\Validators;
use OPNsense\Base\BaseValidator;
use OPNsense\Firewall\Util;
use Phalcon\Messages\Message;
/**
@ -46,7 +47,7 @@ class NetworkValidator extends BaseValidator
* noPrivate : true, false (default)
* noSubnet : true, false (default)
* netMaskRequired : true, false (default)
*
* strict: : true, false (default)
*
* @param $validator
* @param string $attribute
@ -89,6 +90,7 @@ class NetworkValidator extends BaseValidator
if ($this->getOption('netMaskAllowed') === false) {
$result = false;
} else {
$cidr = $value;
$parts = explode("/", $value);
if (count($parts) > 2 || !ctype_digit($parts[1])) {
// more parts then expected or second part is not numeric
@ -108,6 +110,10 @@ class NetworkValidator extends BaseValidator
}
}
}
if ($this->getOption('strict') === true && !Util::isStrict($cidr)) {
$result = false;
}
}
} elseif ($this->getOption('netMaskRequired') === true) {
$result = false;