From 1e816de8cfa2309e91879bde10965afcb21698e2 Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Fri, 14 Dec 2018 11:51:19 +0100 Subject: [PATCH] refactor domainValidate() function; allow underscore in CNAME and SRV entries Signed-off-by: Michael Kaufmann --- .../api/commands/class.DomainZones.php | 4 +- .../validate/function.validateDomain.php | 38 ++++++++++--------- tests/DomainZones/DomainZonesTest.php | 27 +++++++++++++ 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/lib/classes/api/commands/class.DomainZones.php b/lib/classes/api/commands/class.DomainZones.php index 748006d2..bef5d986 100644 --- a/lib/classes/api/commands/class.DomainZones.php +++ b/lib/classes/api/commands/class.DomainZones.php @@ -162,7 +162,7 @@ class DomainZones extends ApiCommand implements ResourceEntity // add domain name $content .= '.' . $domain; } - if (! validateDomain($content)) { + if (! validateDomain($content, true)) { $errors[] = $this->lng['error']['dns_cname_invaliddom']; } else { // check whether there are RR-records for the same resource @@ -208,7 +208,7 @@ class DomainZones extends ApiCommand implements ResourceEntity $target = substr($target, 0, - 1); } } - if ($target != '.' && ! validateDomain($target)) { + if ($target != '.' && ! validateDomain($target, true)) { $errors[] = $this->lng['error']['dns_srv_needdom']; } else { // check whether there is a CNAME-record for the same resource diff --git a/lib/functions/validate/function.validateDomain.php b/lib/functions/validate/function.validateDomain.php index 1711c698..3d6f4a3c 100644 --- a/lib/functions/validate/function.validateDomain.php +++ b/lib/functions/validate/function.validateDomain.php @@ -2,7 +2,6 @@ /** * This file is part of the Froxlor project. - * Copyright (c) 2003-2009 the SysCP Team (see authors). * Copyright (c) 2010 the Froxlor Team (see authors). * * For the full copyright and license information, please view the COPYING @@ -10,7 +9,6 @@ * COPYING file online at http://files.froxlor.org/misc/COPYING.txt * * @copyright (c) the authors - * @author Florian Lippert (2003-2009) * @author Froxlor team (2010-) * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt * @package Functions @@ -18,24 +16,30 @@ */ /** - * Check if the submitted string is a valid domainname, i.e. - * it consists only of the following characters ([a-z0-9][a-z0-9\-]+\.)+[a-z]{2,4} - * - * @param string The domainname which should be checked. + * Check if the submitted string is a valid domainname * + * @param string $domainname + * The domainname which should be checked. + * @param bool $allow_underscore + * optional if true, allowes the underscore character in a domain label (DKIM etc.) + * * @return string|boolean the domain-name if the domain is valid, false otherwise */ -function validateDomain($domainname) { +function validateDomain($domainname, $allow_underscore = false) +{ + if (is_string($domainname)) { + $char_validation = '([a-z\d](-*[a-z\d])*)(\.?([a-z\d](-*[a-z\d])*))*\.([a-z\d])+'; + if ($allow_underscore) { + $char_validation = '([a-z\d\_](-*[a-z\d\_])*)(\.([a-z\d\_](-*[a-z\d])*))*(\.?([a-z\d](-*[a-z\d])*))+\.([a-z\d])+'; + } - // we add http:// because this makes a domain valid for the filter; - $domainname_tmp = 'http://' . $domainname; - - // we just always use our regex - $pattern = '/^http:\/\/([a-z0-9]([a-z0-9\-]{0,61}[a-z0-9])?\.)+[a-z0-9\-]{2,63}$/i'; - if (preg_match($pattern, $domainname_tmp)) { - return $domainname; + if (preg_match("/^" . $char_validation . "$/i", $domainname) && // valid chars check + preg_match("/^.{1,253}$/", $domainname) && // overall length check + preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domainname)) // length of each label + { + return $domainname; + } } - return false; } @@ -46,8 +50,8 @@ function validateDomain($domainname) { * * @return string|boolean hostname on success, else false */ -function validateLocalHostname($hostname) { - +function validateLocalHostname($hostname) +{ $pattern = '/^([a-zA-Z0-9\-])+$/i'; if (preg_match($pattern, $hostname)) { return $hostname; diff --git a/tests/DomainZones/DomainZonesTest.php b/tests/DomainZones/DomainZonesTest.php index 6e93881a..2f47abc0 100644 --- a/tests/DomainZones/DomainZonesTest.php +++ b/tests/DomainZones/DomainZonesTest.php @@ -330,6 +330,33 @@ class DomainZonesTest extends TestCase DomainZones::getLocal($admin_userdata, $data)->add(); } + /** + * @depends testAdminDomainZonesAddCname + */ + public function testAdminDomainZonesAddCnameUnderscore() + { + global $admin_userdata; + + $data = [ + 'domainname' => 'test2.local', + 'record' => 'dkimtest', + 'type' => 'CNAME', + 'content' => 'test._domainkey.myhost.tld.' + ]; + $json_result = DomainZones::getLocal($admin_userdata, $data)->add(); + $result = json_decode($json_result, true)['data']; + $this->assertTrue(count($result) > 1); + $found = false; + foreach ($result as $entry) { + if (substr($entry, strlen('test._domainkey.myhost.tld.') * -1) == 'test._domainkey.myhost.tld.') { + $found = true; + break; + } + } + $this->assertTrue($found); + $this->assertEquals('dkimtest 18000 IN CNAME test._domainkey.myhost.tld.', $entry); + } + public function testAdminDomainZonesAddNS() { global $admin_userdata;