From f21b3dce0cb22fd99f93cc4a4d3df64c111c6daf Mon Sep 17 00:00:00 2001 From: Ante de Baas <5467398+antedebaas@users.noreply.github.com> Date: Mon, 19 Aug 2024 20:11:49 +0200 Subject: [PATCH] Extended DNS checking - 1st pass (#145) --- composer.json | 3 +- composer.lock | 63 ++++++++-- config/services.yaml | 3 + migrations/mysql/Version20240819175623.php | 31 +++++ .../postgresql/Version20240819175040.php | 34 ++++++ migrations/sqlite/Version20240819145909.php | 37 ++++++ src/Controller/DomainsController.php | 36 +++--- src/Entity/Domains.php | 30 +++++ src/Form/DomainFormType.php | 10 ++ src/Twig/PrintAExtention.php | 2 +- templates/domains/check.html.twig | 108 +++++++++++++++--- templates/domains/edit.html.twig | 32 ++++-- 12 files changed, 342 insertions(+), 47 deletions(-) create mode 100644 migrations/mysql/Version20240819175623.php create mode 100644 migrations/postgresql/Version20240819175040.php create mode 100644 migrations/sqlite/Version20240819145909.php diff --git a/composer.json b/composer.json index d83582e..bb4eb83 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,8 @@ "php": ">=8.2", "ext-ctype": "*", "ext-iconv": "*", - "antedebaas/dns-parser": "^1.2.0", + "antedebaas/dns-parser": "^1.2.1", + "buzzingpixel/twig-switch": "^1.0", "doctrine/doctrine-bundle": "^2.12", "doctrine/doctrine-migrations-bundle": "^3.2", "doctrine/orm": "^3.1", diff --git a/composer.lock b/composer.lock index e920c2a..268d9b3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "775a8da4e568eb23732e3290a07b8e46", + "content-hash": "5b0e87a3dd46fe1d6cd1208520992042", "packages": [ { "name": "antedebaas/dns-parser", - "version": "v1.2.0", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/antedebaas/dns-parser.git", - "reference": "ce2e35330f3eef8d787ed8496d23f188a8d2a3f9" + "reference": "1cf9f79c74173b8e5c635750efad3f2218c7c9cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/antedebaas/dns-parser/zipball/ce2e35330f3eef8d787ed8496d23f188a8d2a3f9", - "reference": "ce2e35330f3eef8d787ed8496d23f188a8d2a3f9", + "url": "https://api.github.com/repos/antedebaas/dns-parser/zipball/1cf9f79c74173b8e5c635750efad3f2218c7c9cc", + "reference": "1cf9f79c74173b8e5c635750efad3f2218c7c9cc", "shasum": "" }, "require": { @@ -74,9 +74,58 @@ ], "support": { "issues": "https://github.com/antedebaas/dns-parser/issues", - "source": "https://github.com/antedebaas/dns-parser/tree/v1.2.0" + "source": "https://github.com/antedebaas/dns-parser/tree/v1.2.1" }, - "time": "2024-08-18T15:00:13+00:00" + "time": "2024-08-19T17:38:44+00:00" + }, + { + "name": "buzzingpixel/twig-switch", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/buzzingpixel/twig-switch.git", + "reference": "f8e45f0ca0b68c1614733e02d163b22668be914a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/buzzingpixel/twig-switch/zipball/f8e45f0ca0b68c1614733e02d163b22668be914a", + "reference": "f8e45f0ca0b68c1614733e02d163b22668be914a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "twig/twig": "^2.7|^3.0" + }, + "require-dev": { + "phpmd/phpmd": "^2.6", + "roave/security-advisories": "dev-master", + "squizlabs/php_codesniffer": "^3.4" + }, + "type": "library", + "extra": { + "twigExtensions": [ + "buzzingpixel\\twigswitch\\SwitchTwigExtension" + ] + }, + "autoload": { + "psr-4": { + "buzzingpixel\\twigswitch\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "authors": [ + { + "name": "TJ Draper", + "email": "tj@buzzingpixel.com", + "homepage": "https://buzzingpixel.com" + } + ], + "description": "Provides a {% switch %} tag for Twig switch case statements", + "support": { + "issues": "https://github.com/buzzingpixel/twig-switch/issues", + "source": "https://github.com/buzzingpixel/twig-switch/tree/1.0.2" + }, + "time": "2020-06-21T00:42:23+00:00" }, { "name": "doctrine/cache", diff --git a/config/services.yaml b/config/services.yaml index 343ec55..2fcba37 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -24,6 +24,9 @@ services: - '../src/Entity/' - '../src/Kernel.php' + buzzingpixel\twigswitch\SwitchTwigExtension: + tags: ['twig.extension'] + # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous ones App\EventListener\KernelExceptionListener: diff --git a/migrations/mysql/Version20240819175623.php b/migrations/mysql/Version20240819175623.php new file mode 100644 index 0000000..fcc18a3 --- /dev/null +++ b/migrations/mysql/Version20240819175623.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE domains ADD bimiselector VARCHAR(255) DEFAULT NULL, ADD dkimselector VARCHAR(255) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE domains DROP bimiselector, DROP dkimselector'); + } +} diff --git a/migrations/postgresql/Version20240819175040.php b/migrations/postgresql/Version20240819175040.php new file mode 100644 index 0000000..7d8ae45 --- /dev/null +++ b/migrations/postgresql/Version20240819175040.php @@ -0,0 +1,34 @@ +addSql('ALTER TABLE domains ADD bimiselector VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE domains ADD dkimselector VARCHAR(255) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('ALTER TABLE domains DROP bimiselector'); + $this->addSql('ALTER TABLE domains DROP dkimselector'); + } +} diff --git a/migrations/sqlite/Version20240819145909.php b/migrations/sqlite/Version20240819145909.php new file mode 100644 index 0000000..2daeba4 --- /dev/null +++ b/migrations/sqlite/Version20240819145909.php @@ -0,0 +1,37 @@ +addSql('ALTER TABLE domains ADD COLUMN bimiselector VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE domains ADD COLUMN dkimselector VARCHAR(255) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE TEMPORARY TABLE __temp__domains AS SELECT id, fqdn, sts_version, sts_mode, sts_maxage, mailhost, bimisvgfile, bimivmcfile FROM domains'); + $this->addSql('DROP TABLE domains'); + $this->addSql('CREATE TABLE domains (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, fqdn VARCHAR(255) NOT NULL, sts_version VARCHAR(255) DEFAULT \'STSv1\' NOT NULL, sts_mode VARCHAR(255) DEFAULT \'enforce\' NOT NULL, sts_maxage INTEGER DEFAULT 86400 NOT NULL, mailhost VARCHAR(255) NOT NULL, bimisvgfile CLOB DEFAULT NULL, bimivmcfile CLOB DEFAULT NULL)'); + $this->addSql('INSERT INTO domains (id, fqdn, sts_version, sts_mode, sts_maxage, mailhost, bimisvgfile, bimivmcfile) SELECT id, fqdn, sts_version, sts_mode, sts_maxage, mailhost, bimisvgfile, bimivmcfile FROM __temp__domains'); + $this->addSql('DROP TABLE __temp__domains'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_8C7BBF9DC1A19758 ON domains (fqdn)'); + } +} diff --git a/src/Controller/DomainsController.php b/src/Controller/DomainsController.php index 6ff7b9f..9163cd1 100644 --- a/src/Controller/DomainsController.php +++ b/src/Controller/DomainsController.php @@ -20,6 +20,7 @@ use App\Repository\DomainsRepository; use Ante\DnsParser\Dns; +use Ante\DnsParser\TXTRecords; use App\Enums\TXTRecordStates; class DomainsController extends AbstractController @@ -108,12 +109,21 @@ public function check(Domains $domain, Request $request): Response return $this->render('not_found.html.twig', []); } - $dnsrecords = array(); + $dkimselector = $domain->getDkimselector(); + if($dkimselector == null || $dkimselector == '') { $dkimselector = 'default'; } + $bimiselector = $domain->getBimiselector(); + if($bimiselector == null || $bimiselector == '') { $bimiselector = 'default'; } + $selectors = array( + 'dkim' => $dkimselector, + 'bimi' => $bimiselector, + ); + + $dnsrecords = array(); $dns = new Dns(); $dnsrecords = array_merge($dnsrecords,$dns->getRecords($domain->getFqdn(), 'TXT')); - $dnsrecords = array_merge($dnsrecords,$dns->getRecords('default._domainkey.'.$domain->getFqdn(), 'TXT')); - $dnsrecords = array_merge($dnsrecords,$dns->getRecords('default._bimi.'.$domain->getFqdn(), 'TXT')); + $dnsrecords = array_merge($dnsrecords,$dns->getRecords($dkimselector.'._domainkey.'.$domain->getFqdn(), 'TXT')); + $dnsrecords = array_merge($dnsrecords,$dns->getRecords($bimiselector.'._bimi.'.$domain->getFqdn(), 'TXT')); $dnsrecords = array_merge($dnsrecords,$dns->getRecords('_mta-sts.'.$domain->getFqdn(), 'TXT')); $dnsrecords = array_merge($dnsrecords,$dns->getRecords('_dmarc.'.$domain->getFqdn(), 'TXT')); $dnsrecords = array_merge($dnsrecords,$dns->getRecords('_smtp._tls.'.$domain->getFqdn(), 'TXT')); @@ -126,6 +136,7 @@ public function check(Domains $domain, Request $request): Response return $this->render('domains/check.html.twig', [ 'domain' => $domain, 'validation' => $validation, + 'selectors' => $selectors, 'menuactive' => 'domains', 'breadcrumbs' => array( array('name' => $this->translator->trans("Domains"), 'url' => $this->router->generate('app_domains')), @@ -136,23 +147,20 @@ public function check(Domains $domain, Request $request): Response private function findvalidtxtrecords(array $records): array { $result = array( - 'SPF'=> TXTRecordStates::FAIL, - 'DKIM'=> TXTRecordStates::FAIL, - 'BIMI'=> TXTRecordStates::FAIL, - 'STS'=> TXTRecordStates::FAIL, - 'DMARC'=> TXTRecordStates::FAIL, - 'TLSRPT'=> TXTRecordStates::FAIL, + 'SPF'=> array(new TXTRecords\SPF1(""),TXTRecordStates::FAIL), + 'DKIM'=> array(new TXTRecords\DKIM1(""),TXTRecordStates::FAIL), + 'BIMI'=> array(new TXTRecords\BIMI1(""),TXTRecordStates::FAIL), + 'STS'=> array(new TXTRecords\STSV1(""),TXTRecordStates::FAIL), + 'DMARC'=> array(new TXTRecords\DMARC1(""),TXTRecordStates::FAIL), + 'TLSRPT'=> array(new TXTRecords\TLSRPTV1(""),TXTRecordStates::FAIL), ); foreach($records as $record) { if($record->v()->version() == 1) { - $result[$record->v()->type()] = TXTRecordStates::GOOD; + $result[$record->v()->type()] = array($record->v(),TXTRecordStates::GOOD); } } - if($result['BIMI'] == TXTRecordStates::FAIL) { - $result['BIMI'] = TXTRecordStates::WARNING; - } - + return $result; } diff --git a/src/Entity/Domains.php b/src/Entity/Domains.php index c2855e7..fe1a56d 100644 --- a/src/Entity/Domains.php +++ b/src/Entity/Domains.php @@ -52,6 +52,12 @@ class Domains #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $bimivmcfile = null; + #[ORM\Column(length: 255, nullable: true)] + private ?string $bimiselector = null; + + #[ORM\Column(length: 255, nullable: true)] + private ?string $dkimselector = null; + public function __construct() { $this->DMARC_Reports = new ArrayCollection(); @@ -296,4 +302,28 @@ public function setBimiVMCFile(?string $bimivmcfile): static return $this; } + + public function getBimiselector(): ?string + { + return $this->bimiselector; + } + + public function setBimiselector(?string $bimiselector): static + { + $this->bimiselector = $bimiselector; + + return $this; + } + + public function getDkimselector(): ?string + { + return $this->dkimselector; + } + + public function setDkimselector(?string $dkimselector): static + { + $this->dkimselector = $dkimselector; + + return $this; + } } diff --git a/src/Form/DomainFormType.php b/src/Form/DomainFormType.php index 59e1f77..3d61c65 100644 --- a/src/Form/DomainFormType.php +++ b/src/Form/DomainFormType.php @@ -70,6 +70,16 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'by_reference' => false, ]) + ->add('dkimselector', TextType::class, [ + 'label' => 'DKIM selector name', + 'data' => 'default', + ]) + + ->add('bimiselector', TextType::class, [ + 'label' => 'BIMI selector name', + 'data' => 'default', + ]) + ->add('bimisvgfile', FileType::class, [ 'label' => 'BIMI Logo SVG file', diff --git a/src/Twig/PrintAExtention.php b/src/Twig/PrintAExtention.php index 3a73dba..dd2ac31 100644 --- a/src/Twig/PrintAExtention.php +++ b/src/Twig/PrintAExtention.php @@ -15,7 +15,7 @@ public function getFilters(): array ]; } - public function printa(array $data): string + public function printa(object|array $data): string { return print_r($data); } diff --git a/templates/domains/check.html.twig b/templates/domains/check.html.twig index 1cddef4..abd6a63 100644 --- a/templates/domains/check.html.twig +++ b/templates/domains/check.html.twig @@ -8,22 +8,104 @@
This does rudumentary checks on the domain to see if it is configured correctly, it is not a guarantee that the domain is configured propery (yet).
{% for key,value in validation %} - {% if value.name == 'GOOD' %} -
Use full domain name (fqdn) without ending . (e.g.: "mail.domain.ext") @@ -104,19 +104,18 @@
- {{ form_row(form.bimisvgfile) }} - {{ form_row(form.bimivmcfile) }} -
++ {{ form_row(form.dkimselector) }} +
+{{ form_row(form.sts_version) }} @@ -127,7 +126,18 @@
+ {{ form_row(form.bimiselector) }} + {{ form_row(form.bimisvgfile) }} + {{ form_row(form.bimivmcfile) }} +
+