mirror of
https://github.com/Froxlor/Froxlor.git
synced 2024-09-21 02:17:34 +00:00
Ensure that DMARC entries are generated as subdomain, Allow overwriting of DMARC and SPF subdomain records (#1237)
* Ensure that DMARC entries are generated as subdomain - see https://datatracker.ietf.org/doc/html/rfc7489#section-6.1 * Add tests for DNS DMARC * Allow custom SPF and DMARC subdomain records to replace default records * Improve tests for DMARC, add DMARC tests for subdomain
This commit is contained in:
parent
953baec023
commit
686ca84a30
@ -212,7 +212,7 @@ class Dns
|
||||
}
|
||||
if (Settings::Get('dmarc.use_dmarc') == '1') {
|
||||
// check for DMARC content later
|
||||
self::addRequiredEntry('@DMARC@.' . $sub_record, 'TXT', $required_entries);
|
||||
self::addRequiredEntry('@DMARC@', 'TXT', $required_entries);
|
||||
}
|
||||
if (Settings::Get('antispam.activated') == '1' && $domain['dkim'] == '1') {
|
||||
// check for DKIM content later
|
||||
@ -239,19 +239,28 @@ class Dns
|
||||
}
|
||||
if (Settings::Get('spf.use_spf') == '1'
|
||||
&& $entry['type'] == 'TXT'
|
||||
&& $entry['record'] == '@'
|
||||
&& (strtolower(substr($entry['content'], 0, 7)) == '"v=spf1' || strtolower(substr($entry['content'], 0, 6)) == 'v=spf1')
|
||||
) {
|
||||
// unset special spf required-entry
|
||||
if ($entry['record'] == '@') {
|
||||
unset($required_entries[$entry['type']][md5("@SPF@")]);
|
||||
} else {
|
||||
// subdomain
|
||||
unset($required_entries[$entry['type']][md5("@SPF@." . $entry['record'])]);
|
||||
}
|
||||
}
|
||||
if (Settings::Get('dmarc.use_dmarc') == '1'
|
||||
&& $entry['type'] == 'TXT'
|
||||
&& $entry['record'] == '@'
|
||||
&& ($entry['record'] == '_dmarc' || substr($entry['record'], 0, 7) == '_dmarc.')
|
||||
&& (strtolower(substr($entry['content'], 0, 9)) == '"v=dmarc1' || strtolower(substr($entry['content'], 0, 8)) == 'v=dmarc1')
|
||||
) {
|
||||
// unset special dmarc required-entry
|
||||
if ($entry['record'] == '_dmarc') {
|
||||
unset($required_entries[$entry['type']][md5("@DMARC@")]);
|
||||
} else {
|
||||
// subdomain
|
||||
unset($required_entries[$entry['type']][md5("@DMARC@" . substr($entry['record'], 6))]);
|
||||
}
|
||||
}
|
||||
if (empty($primary_ns) && $entry['record'] == '@' && $entry['type'] == 'NS') {
|
||||
// use the first NS entry pertaining to the current domain as primary ns
|
||||
@ -392,12 +401,12 @@ class Dns
|
||||
} elseif ($record == '@DMARC@') {
|
||||
// dmarc for main-domain
|
||||
$txt_content = Settings::Get('dmarc.dmarc_entry');
|
||||
$zonerecords[] = new DnsEntry('@', 'TXT', self::encloseTXTContent($txt_content));
|
||||
$zonerecords[] = new DnsEntry('_dmarc', 'TXT', self::encloseTXTContent($txt_content));
|
||||
} elseif (strlen($record) > 8 && substr($record, 0, 8) == '@DMARC@.') {
|
||||
// dmarc for subdomain
|
||||
$txt_content = Settings::Get('dmarc.dmarc_entry');
|
||||
$sub_record = substr($record, 8);
|
||||
$zonerecords[] = new DnsEntry($sub_record, 'TXT', self::encloseTXTContent($txt_content));
|
||||
$zonerecords[] = new DnsEntry('_dmarc.' . $sub_record, 'TXT', self::encloseTXTContent($txt_content));
|
||||
} elseif (!empty($dkim_entries)) {
|
||||
// DKIM entries
|
||||
$dkim_record = 'dkim' . $domain['dkim_id'] . '._domainkey';
|
||||
|
@ -2,9 +2,11 @@
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Api\Commands\Admins;
|
||||
use Froxlor\Api\Commands\Customers;
|
||||
use Froxlor\Api\Commands\DomainZones;
|
||||
use Froxlor\Api\Commands\Domains;
|
||||
use Froxlor\Api\Commands\SubDomains;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -63,6 +65,89 @@ class DomainZonesTest extends TestCase
|
||||
DomainZones::getLocal($customer_userdata, $data)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @depends testCustomerDomainZonesGet
|
||||
*/
|
||||
public function testCustomerDomainZonesGetWithDMARC()
|
||||
{
|
||||
global $admin_userdata;
|
||||
|
||||
Settings::Set('dmarc.use_dmarc', 1, true);
|
||||
|
||||
// get customer
|
||||
$json_result = Customers::getLocal($admin_userdata, array(
|
||||
'loginname' => 'test1'
|
||||
))->get();
|
||||
$customer_userdata = json_decode($json_result, true)['data'];
|
||||
|
||||
$data = [
|
||||
'domainname' => 'test2.local'
|
||||
];
|
||||
$json_result = DomainZones::getLocal($customer_userdata, $data)->get();
|
||||
$result = json_decode($json_result, true)['data'];
|
||||
$this->assertTrue(count($result) > 1);
|
||||
$foundCnt = 0;
|
||||
$foundStr = '';
|
||||
foreach ($result as $entry) {
|
||||
if (substr($entry, 0, 7) == '_dmarc ') {
|
||||
$foundCnt++;
|
||||
$foundStr = $entry;
|
||||
}
|
||||
}
|
||||
$this->assertEquals(1, $foundCnt);
|
||||
$resstr = preg_replace('/\s+/', '', $foundStr);
|
||||
$against = preg_replace('/\s+/', '', '_dmarc 604800 IN TXT v=DMARC1;p=none;');
|
||||
$this->assertEquals($against, $resstr);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @depends testCustomerDomainZonesGetWithDMARC
|
||||
*/
|
||||
public function testCustomerDomainZonesGetWithDMARCSubdomain()
|
||||
{
|
||||
global $admin_userdata;
|
||||
|
||||
// enable isemaildomain for subdomain
|
||||
$json_result = Admins::getLocal($admin_userdata, array(
|
||||
'loginname' => 'reseller'
|
||||
))->get();
|
||||
$reseller_userdata = json_decode($json_result, true)['data'];
|
||||
$reseller_userdata['adminsession'] = 1;
|
||||
$data = [
|
||||
'domainname' => 'mysub2.test2.local',
|
||||
'isemaildomain' => 1,
|
||||
'customerid' => 1
|
||||
];
|
||||
$json_result = SubDomains::getLocal($reseller_userdata, $data)->update();
|
||||
|
||||
// get customer
|
||||
$json_result = Customers::getLocal($admin_userdata, array(
|
||||
'loginname' => 'test1'
|
||||
))->get();
|
||||
$customer_userdata = json_decode($json_result, true)['data'];
|
||||
|
||||
$data = [
|
||||
'domainname' => 'test2.local'
|
||||
];
|
||||
$json_result = DomainZones::getLocal($customer_userdata, $data)->get();
|
||||
$result = json_decode($json_result, true)['data'];
|
||||
$foundCnt = 0;
|
||||
$foundStr = '';
|
||||
$this->assertTrue(count($result) > 1);
|
||||
foreach ($result as $entry) {
|
||||
if (substr($entry, 0, 14) == '_dmarc.mysub2 ') {
|
||||
$foundCnt++;
|
||||
$foundStr = $entry;
|
||||
}
|
||||
}
|
||||
$this->assertEquals(1, $foundCnt);
|
||||
$resstr = preg_replace('/\s+/', '', $foundStr);
|
||||
$against = preg_replace('/\s+/', '', '_dmarc.mysub2 604800 IN TXT v=DMARC1;p=none;');
|
||||
$this->assertEquals($against, $resstr);
|
||||
}
|
||||
|
||||
public function testAdminDomainZonesUpdate()
|
||||
{
|
||||
global $admin_userdata;
|
||||
@ -872,6 +957,68 @@ class DomainZonesTest extends TestCase
|
||||
$this->assertEquals('_test1 18000 IN TXT aw yeah', $entry);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @depends testCustomerDomainZonesGetWithDMARC
|
||||
*/
|
||||
public function testAdminDomainZonesAddTXTCustomDMARC()
|
||||
{
|
||||
global $admin_userdata;
|
||||
|
||||
$data = [
|
||||
'domainname' => 'test2.local',
|
||||
'record' => '_dmarc',
|
||||
'type' => 'TXT',
|
||||
'content' => 'v=DMARC1;p=none;overwrite=TRUE'
|
||||
];
|
||||
$json_result = DomainZones::getLocal($admin_userdata, $data)->add();
|
||||
$result = json_decode($json_result, true)['data'];
|
||||
$this->assertTrue(count($result) > 1);
|
||||
$foundCnt = 0;
|
||||
$foundStr = '';
|
||||
foreach ($result as $entry) {
|
||||
if (substr($entry, 0, 7) == '_dmarc ') {
|
||||
$foundCnt++;
|
||||
$foundStr = $entry;
|
||||
}
|
||||
}
|
||||
$this->assertEquals(1, $foundCnt);
|
||||
$resstr = preg_replace('/\s+/', '', $foundStr);
|
||||
$against = preg_replace('/\s+/', '', '_dmarc 18000 IN TXT v=DMARC1;p=none;overwrite=TRUE');
|
||||
$this->assertEquals($against, $resstr);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @depends testCustomerDomainZonesGetWithDMARCSubdomain
|
||||
*/
|
||||
public function testAdminDomainZonesAddTXTCustomDMARCSubdomain()
|
||||
{
|
||||
global $admin_userdata;
|
||||
|
||||
$data = [
|
||||
'domainname' => 'test2.local',
|
||||
'record' => '_dmarc.mysub2',
|
||||
'type' => 'TXT',
|
||||
'content' => 'v=DMARC1;p=none;overwrite=TRUE'
|
||||
];
|
||||
$json_result = DomainZones::getLocal($admin_userdata, $data)->add();
|
||||
$result = json_decode($json_result, true)['data'];
|
||||
$this->assertTrue(count($result) > 1);
|
||||
$foundCnt = 0;
|
||||
$foundStr = '';
|
||||
foreach ($result as $entry) {
|
||||
if (substr($entry, 0, 14) == '_dmarc.mysub2 ') {
|
||||
$foundCnt++;
|
||||
$foundStr = $entry;
|
||||
}
|
||||
}
|
||||
$this->assertEquals(1, $foundCnt);
|
||||
$resstr = preg_replace('/\s+/', '', $foundStr);
|
||||
$against = preg_replace('/\s+/', '', '_dmarc.mysub2 18000 IN TXT v=DMARC1;p=none;overwrite=TRUE');
|
||||
$this->assertEquals($against, $resstr);
|
||||
}
|
||||
|
||||
public function testAdminDomainZonesAddSRV()
|
||||
{
|
||||
global $admin_userdata;
|
||||
|
Loading…
Reference in New Issue
Block a user