Merge pull request #679 from pquerner/#564
Allow CIDR and Netmask in mysql_host_access; fixes #564
This commit is contained in:
@@ -135,7 +135,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
|||||||
{
|
{
|
||||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
|
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
|
||||||
|
|
||||||
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip'), false, 'invalidip', false, false, false, true);
|
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip'), false, 'invalidip', false, false, false, false, true);
|
||||||
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, 80), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
|
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, 80), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
|
||||||
'stringisempty',
|
'stringisempty',
|
||||||
'myport'
|
'myport'
|
||||||
@@ -332,7 +332,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
|||||||
'id' => $id
|
'id' => $id
|
||||||
));
|
));
|
||||||
|
|
||||||
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip', true, $result['ip']), false, 'invalidip', false, false, false, true);
|
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip', true, $result['ip']), false, 'invalidip', false, false, false, false, true);
|
||||||
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, $result['port']), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
|
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, $result['port']), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
|
||||||
'stringisempty',
|
'stringisempty',
|
||||||
'myport'
|
'myport'
|
||||||
|
|||||||
@@ -252,6 +252,28 @@ class Store
|
|||||||
|
|
||||||
public static function storeSettingMysqlAccessHost($fieldname, $fielddata, $newfieldvalue)
|
public static function storeSettingMysqlAccessHost($fieldname, $fielddata, $newfieldvalue)
|
||||||
{
|
{
|
||||||
|
$ips = $newfieldvalue;
|
||||||
|
//Convert cidr to netmask for mysql, if needed be
|
||||||
|
if(strpos($ips, ',') !== false) {
|
||||||
|
$ips = explode(',', $ips);
|
||||||
|
}
|
||||||
|
if(is_array($ips) && count($ips) > 0) {
|
||||||
|
$newfieldvalue = [];
|
||||||
|
foreach ($ips as $ip) {
|
||||||
|
$org_ip = $ip;
|
||||||
|
$ip_cidr = explode("/", $ip);
|
||||||
|
if (count($ip_cidr) === 2) {
|
||||||
|
$ip = $ip_cidr[0];
|
||||||
|
if (strlen($ip_cidr[1]) <= 2) {
|
||||||
|
$ip_cidr[1] = \Froxlor\Validate\Validate::cidr2NetmaskAddr($org_ip);
|
||||||
|
}
|
||||||
|
$newfieldvalue[] = $ip . '/' . $ip_cidr[1];
|
||||||
|
} else {
|
||||||
|
$newfieldvalue[] = $org_ip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$newfieldvalue = implode(',', $newfieldvalue);
|
||||||
|
}
|
||||||
$returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue);
|
$returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue);
|
||||||
|
|
||||||
if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'mysql_access_host') {
|
if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'mysql_access_host') {
|
||||||
|
|||||||
@@ -77,8 +77,7 @@ class Check
|
|||||||
$mysql_access_host_array = array_map('trim', explode(',', $newfieldvalue));
|
$mysql_access_host_array = array_map('trim', explode(',', $newfieldvalue));
|
||||||
|
|
||||||
foreach ($mysql_access_host_array as $host_entry) {
|
foreach ($mysql_access_host_array as $host_entry) {
|
||||||
|
if (Validate::validate_ip2($host_entry, true, 'invalidip', true, true, true, true, false) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
|
||||||
if (Validate::validate_ip2($host_entry, true, 'invalidip', true, true) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
|
|
||||||
return array(
|
return array(
|
||||||
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
|
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
|
||||||
'invalidmysqlhost',
|
'invalidmysqlhost',
|
||||||
|
|||||||
@@ -62,32 +62,78 @@ class Validate
|
|||||||
\Froxlor\UI\Response::standard_error($lng, $fieldname, $throw_exception);
|
\Froxlor\UI\Response::standard_error($lng, $fieldname, $throw_exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether it is a valid ip
|
* Converts CIDR to a netmask address
|
||||||
*
|
*
|
||||||
* @param string $ip
|
* @thx to https://stackoverflow.com/a/5711080/3020926
|
||||||
* ip-address to check
|
* @param string $cidr
|
||||||
* @param bool $return_bool
|
*
|
||||||
* whether to return bool or call \Froxlor\UI\Response::standard_error()
|
* @return string
|
||||||
* @param string $lng
|
*/
|
||||||
* index for error-message (if $return_bool is false)
|
public static function cidr2NetmaskAddr ($cidr) {
|
||||||
* @param bool $allow_localhost
|
|
||||||
* whether to allow 127.0.0.1
|
$ta = substr ($cidr, strpos ($cidr, '/') + 1) * 1;
|
||||||
* @param bool $allow_priv
|
$netmask = str_split (str_pad (str_pad ('', $ta, '1'), 32, '0'), 8);
|
||||||
* whether to allow private network addresses
|
|
||||||
* @param bool $allow_cidr
|
foreach ($netmask as &$element) {
|
||||||
* whether to allow CIDR values e.g. 10.10.10.10/16
|
$element = bindec ($element);
|
||||||
*
|
}
|
||||||
* @return string|bool ip address on success, false on failure
|
|
||||||
*/
|
return implode ('.', $netmask);
|
||||||
public static function validate_ip2($ip, $return_bool = false, $lng = 'invalidip', $allow_localhost = false, $allow_priv = false, $allow_cidr = false, $throw_exception = false)
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if an $address (IP) is IPv6
|
||||||
|
*
|
||||||
|
* @param $address
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function is_ipv6($address) {
|
||||||
|
return filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether it is a valid ip
|
||||||
|
*
|
||||||
|
* @param string $ip
|
||||||
|
* ip-address to check
|
||||||
|
* @param bool $return_bool
|
||||||
|
* whether to return bool or call \Froxlor\UI\Response::standard_error()
|
||||||
|
* @param string $lng
|
||||||
|
* index for error-message (if $return_bool is false)
|
||||||
|
* @param bool $allow_localhost
|
||||||
|
* whether to allow 127.0.0.1
|
||||||
|
* @param bool $allow_priv
|
||||||
|
* whether to allow private network addresses
|
||||||
|
* @param bool $allow_cidr
|
||||||
|
* whether to allow CIDR values e.g. 10.10.10.10/16
|
||||||
|
* @param bool $cidr_as_netmask
|
||||||
|
* whether to format CIDR nodation to netmask notation
|
||||||
|
*
|
||||||
|
* @param bool $throw_exception
|
||||||
|
* whether to throw an exception on failure
|
||||||
|
*
|
||||||
|
* @return string|bool ip address on success, false on failure
|
||||||
|
*/
|
||||||
|
public static function validate_ip2($ip, $return_bool = false, $lng = 'invalidip', $allow_localhost = false, $allow_priv = false, $allow_cidr = false, $cidr_as_netmask = false, $throw_exception = false)
|
||||||
{
|
{
|
||||||
$cidr = "";
|
$cidr = "";
|
||||||
if ($allow_cidr) {
|
if ($allow_cidr) {
|
||||||
$org_ip = $ip;
|
$org_ip = $ip;
|
||||||
$ip_cidr = explode("/", $ip);
|
$ip_cidr = explode("/", $ip);
|
||||||
if (count($ip_cidr) == 2) {
|
if (count($ip_cidr) === 2) {
|
||||||
|
if(strlen($ip_cidr[1]) <= 2 && in_array((int)$ip_cidr[1], array_values(range(1, 32)), TRUE) === false) {
|
||||||
|
\Froxlor\UI\Response::standard_error($lng, $ip, $throw_exception);
|
||||||
|
}
|
||||||
|
if ($cidr_as_netmask && self::is_ipv6($ip_cidr[0])) {
|
||||||
|
//MySQL does not handle CIDR of IPv6 addresses, return error
|
||||||
|
\Froxlor\UI\Response::standard_error($lng, $ip, $throw_exception);
|
||||||
|
}
|
||||||
$ip = $ip_cidr[0];
|
$ip = $ip_cidr[0];
|
||||||
|
if ($cidr_as_netmask && strlen($ip_cidr[1]) <= 2) {
|
||||||
|
$ip_cidr[1] = self::cidr2NetmaskAddr($org_ip);
|
||||||
|
}
|
||||||
$cidr = "/" . $ip_cidr[1];
|
$cidr = "/" . $ip_cidr[1];
|
||||||
} else {
|
} else {
|
||||||
$ip = $org_ip;
|
$ip = $org_ip;
|
||||||
|
|||||||
@@ -569,7 +569,7 @@ $lng['serversettings']['apacheconf_htpasswddir']['description'] = 'Where should
|
|||||||
|
|
||||||
$lng['error']['formtokencompromised'] = 'The request seems to be compromised. For security reasons you were logged out.';
|
$lng['error']['formtokencompromised'] = 'The request seems to be compromised. For security reasons you were logged out.';
|
||||||
$lng['serversettings']['mysql_access_host']['title'] = 'MySQL-Access-Hosts';
|
$lng['serversettings']['mysql_access_host']['title'] = 'MySQL-Access-Hosts';
|
||||||
$lng['serversettings']['mysql_access_host']['description'] = 'A comma separated list of hosts from which users should be allowed to connect to the MySQL-Server.';
|
$lng['serversettings']['mysql_access_host']['description'] = 'A comma separated list of hosts from which users should be allowed to connect to the MySQL-Server. To allow a subnet the netmask or cidr syntax is valid.';
|
||||||
|
|
||||||
// ADDED IN 1.2.18-svn1
|
// ADDED IN 1.2.18-svn1
|
||||||
|
|
||||||
|
|||||||
@@ -564,7 +564,7 @@ $lng['serversettings']['apacheconf_htpasswddir']['description'] = 'Wo sollen die
|
|||||||
|
|
||||||
$lng['error']['formtokencompromised'] = 'Das Formular scheint manipuliert worden zu sein. Aus Sicherheitsgründen wurden Sie ausgelogged.';
|
$lng['error']['formtokencompromised'] = 'Das Formular scheint manipuliert worden zu sein. Aus Sicherheitsgründen wurden Sie ausgelogged.';
|
||||||
$lng['serversettings']['mysql_access_host']['title'] = 'MySQL-Access-Hosts';
|
$lng['serversettings']['mysql_access_host']['title'] = 'MySQL-Access-Hosts';
|
||||||
$lng['serversettings']['mysql_access_host']['description'] = 'Eine durch Komma getrennte Liste mit den Hostnamen aller Hostnames/IP-Adressen, von denen sich die Benutzer einloggen dürfen.';
|
$lng['serversettings']['mysql_access_host']['description'] = 'Eine durch Komma getrennte Liste mit den Hostnamen aller Hostnames/IP-Adressen, von denen sich die Benutzer einloggen dürfen. Um ein Subnetz zu erlauben ist die Netzmaske oder CIDR Syntax erlaubt.';
|
||||||
|
|
||||||
// ADDED IN 1.2.18-svn1
|
// ADDED IN 1.2.18-svn1
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class ValidateTest extends TestCase
|
|||||||
|
|
||||||
public function testValidateIp()
|
public function testValidateIp()
|
||||||
{
|
{
|
||||||
$result = Validate::validate_ip2("12.34.56.78", false, 'invalidip', false, false, false, true);
|
$result = Validate::validate_ip2("12.34.56.78", false, 'invalidip', false, false, false, false, true);
|
||||||
$this->assertEquals("12.34.56.78", $result);
|
$this->assertEquals("12.34.56.78", $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,12 +58,12 @@ class ValidateTest extends TestCase
|
|||||||
{
|
{
|
||||||
$this->expectException("Exception");
|
$this->expectException("Exception");
|
||||||
$this->expectExceptionCode(400);
|
$this->expectExceptionCode(400);
|
||||||
Validate::validate_ip2("10.0.0.1", false, 'invalidip', false, false, false, true);
|
Validate::validate_ip2("10.0.0.1", false, 'invalidip', false, false, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateIpPrivNotAllowedBool()
|
public function testValidateIpPrivNotAllowedBool()
|
||||||
{
|
{
|
||||||
$result = Validate::validate_ip2("10.0.0.1", true, 'invalidip', false, false, false, true);
|
$result = Validate::validate_ip2("10.0.0.1", true, 'invalidip', false, false, false, false, true);
|
||||||
$this->assertFalse($result);
|
$this->assertFalse($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,32 +71,49 @@ class ValidateTest extends TestCase
|
|||||||
{
|
{
|
||||||
$this->expectException("Exception");
|
$this->expectException("Exception");
|
||||||
$this->expectExceptionCode(400);
|
$this->expectExceptionCode(400);
|
||||||
Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, false, true);
|
Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateIpCidrNotAllowedBool()
|
public function testValidateIpCidrNotAllowedBool()
|
||||||
{
|
{
|
||||||
$result = Validate::validate_ip2("12.34.56.78/24", true, 'invalidip', false, false, false, true);
|
$result = Validate::validate_ip2("12.34.56.78/24", true, 'invalidip', false, false, false, false, true);
|
||||||
$this->assertFalse($result);
|
$this->assertFalse($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateIpCidr()
|
public function testValidateIpCidr()
|
||||||
{
|
{
|
||||||
$result = Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, true, true);
|
$result = Validate::validate_ip2("12.34.56.78/24", false, 'invalidip', false, false, true, false, true);
|
||||||
$this->assertEquals("12.34.56.78/24", $result);
|
$this->assertEquals("12.34.56.78/24", $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testValidateIpv6Disallowed()
|
||||||
|
{
|
||||||
|
$this->expectException("Exception");
|
||||||
|
$this->expectExceptionCode(400);
|
||||||
|
Validate::validate_ip2("2620:0:2d0:200::7/32", false, 'invalidip', false, false, true, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
public function testValidateIpLocalhostAllowed()
|
public function testValidateIpLocalhostAllowed()
|
||||||
{
|
{
|
||||||
$result = Validate::validate_ip2("127.0.0.1/32", false, 'invalidip', true, false, true, true);
|
$result = Validate::validate_ip2("127.0.0.1/32", false, 'invalidip', true, false, true, false, true);
|
||||||
$this->assertEquals("127.0.0.1/32", $result);
|
$this->assertEquals("127.0.0.1/32", $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testValidateCidrNoationToNetmaskNotationIPv4()
|
||||||
|
{
|
||||||
|
$result = Validate::validate_ip2("1.1.1.1/4", false, 'invalidip', true, false, true, true, true);
|
||||||
|
$this->assertEquals("1.1.1.1/240.0.0.0", $result);
|
||||||
|
$result = Validate::validate_ip2("8.8.8.8/18", false, 'invalidip', true, false, true, true, true);
|
||||||
|
$this->assertEquals("8.8.8.8/255.255.192.0", $result);
|
||||||
|
$result = Validate::validate_ip2("8.8.8.8/1", false, 'invalidip', true, false, true, true, true);
|
||||||
|
$this->assertEquals("8.8.8.8/128.0.0.0", $result);
|
||||||
|
}
|
||||||
|
|
||||||
public function testValidateIpLocalhostAllowedWrongIp()
|
public function testValidateIpLocalhostAllowedWrongIp()
|
||||||
{
|
{
|
||||||
$this->expectException("Exception");
|
$this->expectException("Exception");
|
||||||
$this->expectExceptionCode(400);
|
$this->expectExceptionCode(400);
|
||||||
Validate::validate_ip2("127.0.0.2", false, 'invalidip', true, false, false, true);
|
Validate::validate_ip2("127.0.0.2", false, 'invalidip', true, false, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidateUrl()
|
public function testValidateUrl()
|
||||||
|
|||||||
Reference in New Issue
Block a user