diff --git a/Application/Controller/Admin/SpfChecker.php b/Application/Controller/Admin/SpfChecker.php index c94bbc1..3388cee 100644 --- a/Application/Controller/Admin/SpfChecker.php +++ b/Application/Controller/Admin/SpfChecker.php @@ -16,7 +16,10 @@ declare(strict_types=1); namespace D3\MailConfigChecker\Application\Controller\Admin; use Assert\InvalidArgumentException; +use D3\MailAuthenticationCheck\DMARCCheck; +use D3\MailAuthenticationCheck\Model\DMARCResult; use D3\MailConfigChecker\Application\Model\Constants; +use D3\MailConfigChecker\Application\Model\DmarcResult as OxDmarcResult; use D3\MailConfigChecker\Application\Model\SpfResult; use Mika56\SPFCheck\DNS\DNSRecordGetter; use Mika56\SPFCheck\Model\Query; @@ -33,6 +36,7 @@ class SpfChecker extends AdminDetailsController public function render() { $this->checkSpf(); + $this->checkDmarc(); return parent::render(); } @@ -47,10 +51,24 @@ class SpfChecker extends AdminDetailsController } ); - $this->addTplParam('result', $result); + $this->addTplParam('spf_result', $result); } - protected function getMailDomains() + protected function checkDmarc() + { + $result = []; + $mailDomains = $this->getMailDomains(); + array_walk( + $mailDomains, + function ($domain) use (&$result) { + $this->checkDmarcByDomain($domain, $result); + } + ); + + $this->addTplParam('dmarc_result', $result); + } + + protected function getMailDomains(): array { /** @var Shop $shop */ $shop = Registry::getConfig()->getActiveShop(); @@ -120,4 +138,41 @@ class SpfChecker extends AdminDetailsController return 'danger'; } } + + public function checkDmarcByDomain($domain, &$summarize) + { + try { + $check = new DMARCCheck(new DNSRecordGetter()); + $query = new Query('', $domain); + $record = $check->getResult($query)->getRecord(); + + switch ( $record->getRejectPolicy()->getValue() ) { + case DMARCResult::REJECT_QUARANTINE: + case DMARCResult::REJECT_REJECT: + $status = OxDmarcResult::SET; + break; + case DMARCResult::REJECT_NONE: + $status = OxDmarcResult::MISSING; + break; + default: + $status = OxDmarcResult::ERROR; + } + + $summarize[$domain] = oxNew( OxDmarcResult::class, $status, $record->getRawRecord()); + } catch (\LogicException) { + $summarize[$domain] = oxNew( OxDmarcResult::class, OxDmarcResult::MISSING, ''); + } + } + + public function getDmarcStatusColor(OxDmarcResult $result) + { + switch ($result->getStatus()) { + case SpfResult::SET: + return 'success'; + case SpfResult::ERROR: + return 'warning'; + default: + return 'danger'; + } + } } diff --git a/Application/Model/DmarcResult.php b/Application/Model/DmarcResult.php new file mode 100644 index 0000000..5d6e0a4 --- /dev/null +++ b/Application/Model/DmarcResult.php @@ -0,0 +1,42 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +namespace D3\MailConfigChecker\Application\Model; + +class DmarcResult +{ + public const SET = 'set'; + public const MISSING = 'missing'; + public const ERROR = 'error'; + + protected $status; + protected $record; + + public function __construct(string $status, ?string $record = null) + { + $this->status = $status; + $this->record = $record; + } + + public function getStatus() + { + return $this->status; + } + + public function getRecord() + { + return $this->record; + } +} diff --git a/Application/Model/SpfResult.php b/Application/Model/SpfResult.php index 6cd9b8d..e8e1cfe 100644 --- a/Application/Model/SpfResult.php +++ b/Application/Model/SpfResult.php @@ -17,7 +17,7 @@ namespace D3\MailConfigChecker\Application\Model; class SpfResult { - public const SET = 'set'; + public const SET = 'set'; public const MISSING = 'missing'; public const ERROR = 'error'; diff --git a/Application/views/de/translations.php b/Application/views/de/translations.php index 88bd999..e6569ce 100644 --- a/Application/views/de/translations.php +++ b/Application/views/de/translations.php @@ -19,7 +19,7 @@ return [ 'D3_TAB_MAILCHECKER_MODULEDESCRIPTION' => 'Beschreibung', 'D3_TAB_MAILCHECKER_CONFIGCHECK' => 'Konfigurationsprüfung', 'D3_TAB_MAILCHECKER_SMTPCHECK' => 'SMTP Check', - 'D3_TAB_MAILCHECKER_SPFCHECK' => 'SPF Check', + 'D3_TAB_MAILCHECKER_SPFCHECK' => 'Authentisierung Check', 'D3_TAB_MAILCHECKER_TESTMAIL' => 'Testmail', 'D3_MAILCHECKER_INFO_1' => 'Dieses Modul kann Ihnen helfen, um Schwierigkeiten beim Versand von Mails oder bei nicht zugestellten Mails zu identifizieren. Gehen Sie bitte die folgenden Tabs durch. Nötige Nacharbeiten werden Ihnen dort angezeigt.', @@ -54,6 +54,9 @@ return [ 'D3_MAILCHECKER_SMTPCHECK_NOTRANSMIT' => 'Datenübertragung nicht erfolgreich', 'D3_MAILCHECKER_SMTPCHECK_SUCCESS' => 'Die SMTP-Kommunikation wurde erfolgreich abgeschlossen.', + 'D3_MAILCHECKER_RECORD' => 'Eintrag', + + 'D3_MAILCHECKER_SPFRESULT_HL' => 'SPF (Herkunftsprüfung)', 'D3_MAILCHECKER_SPFRESULT_DESC' => 'Mit dem Sender Policy Framework (SPF) definiert der Domaininhaber, welcher Server E-Mails mit dem Domainabsender versenden darf. Diese Angabe wird vom Empfangsserver geprüft. Fehlt der SPF-Eintrag, werden E-Mails üblicherweise als Spam klassifiziert.', 'D3_MAILCHECKER_SPFRESULT_SET' => 'Es ist ein SPF-Eintrag gesetzt', 'D3_MAILCHECKER_SPFRESULT_MISSING' => 'Es ist kein SPF-Eintrag gesetzt, dieser sollte dringend nachgetragen werden', @@ -63,6 +66,15 @@ return [ 'D3_MAILCHECKER_SPFRESULT_LINK_GENERATOR' => 'SPF Generator', 'D3_MAILCHECKER_SPFRESULT_LINK_BLACKLISTCHECK' => 'Blacklist Check', + 'D3_MAILCHECKER_DMARCRESULT_HL' => 'DMARC (Ablehnungsrichtlinien und Berichterstattung)', + 'D3_MAILCHECKER_DMARCRESULT_DESC' => 'Der DMARC-Eintrag definiert, wie mit Mails umgegangen wird, bei denen die Authentisierungsprüfungen fehlgeschlagen sind. Dort können auch Mailadressen für Reporte angegeben werden.', + 'D3_MAILCHECKER_DMARCRESULT_SET' => 'Es ist ein DMARC-Eintrag gesetzt, das Verhalten ist nicht auf "ignorieren" gestellt.', + 'D3_MAILCHECKER_DMARCRESULT_MISSING' => 'Es ist kein DMARC-Eintrag gesetzt oder mit "ignorieren" konfiguriert. Dies sollte dringend geändert werden.', + 'D3_MAILCHECKER_DMARCRESULT_ERROR' => 'Der DMARC-Eintrag kann nicht geprüft werden', + 'D3_MAILCHECKER_DMARCRESULT_LINKS' => 'weiterführende Links', + 'D3_MAILCHECKER_DMARCRESULT_LINK_ANALYSIS' => 'DMARC Analyse', + 'D3_MAILCHECKER_DMARCRESULT_LINK_GENERATOR' => 'DMARC Generator', + 'D3_MAILCHECKER_TESTMAIL_DESC' => 'Die Testmail wird auf identischem Weg geschickt, den auch alle regulären Mails aus dem Shop nehmen (z.B. Bestellbestätigungen, ...) und kann z.B. zur Headeranalyse dienen.', 'D3_MAILCHECKER_TESTMAIL_HEADERANALYSIS' => 'Email Header Analyzer', 'D3_MAILCHECKER_TESTMAIL_SUBJECT' => 'Betreff', diff --git a/Application/views/en/translations.php b/Application/views/en/translations.php index 241ee87..df15e2b 100644 --- a/Application/views/en/translations.php +++ b/Application/views/en/translations.php @@ -19,7 +19,7 @@ return [ "D3_TAB_MAILCHECKER_MODULEDESCRIPTION" => "Description", "D3_TAB_MAILCHECKER_CONFIGCHECK" => "Configuration check", "D3_TAB_MAILCHECKER_SMTPCHECK" => "SMTP check", - "D3_TAB_MAILCHECKER_SPFCHECK" => "SPF check", + "D3_TAB_MAILCHECKER_SPFCHECK" => "Authentication check", "D3_TAB_MAILCHECKER_TESTMAIL" => "Test email", "D3_MAILCHECKER_ASSERTIONS_FAILED" => "The following %d checks failed:", "D3_MAILCHECKER_ASSERTIONS_NOTSET" => "is not (correctly) set", @@ -47,6 +47,10 @@ return [ "D3_MAILCHECKER_SMTPCHECK_TRANSMIT" => "Data transfer", "D3_MAILCHECKER_SMTPCHECK_NOTRANSMIT" => "Data transfer not successful", "D3_MAILCHECKER_SMTPCHECK_SUCCESS" => "SMTP communication was completed successfully.", + + 'D3_MAILCHECKER_RECORD' => 'Record', + + 'D3_MAILCHECKER_SPFRESULT_HL' => 'SPF (Origin verification)', "D3_MAILCHECKER_SPFRESULT_DESC" => "With the Sender Policy Framework (SPF), the domain owner defines which server is allowed to send emails with the domain sender. This information is checked by the receiving server. If the SPF entry is missing, emails are usually sent as ", "D3_MAILCHECKER_SPFRESULT_SET" => "An SPF entry is set", "D3_MAILCHECKER_SPFRESULT_MISSING" => "There is no SPF entry set, this should be added urgently", @@ -55,6 +59,16 @@ return [ "D3_MAILCHECKER_SPFRESULT_LINK_ANALYSIS" => "SPF analysis", "D3_MAILCHECKER_SPFRESULT_LINK_GENERATOR" => "SPF generator", "D3_MAILCHECKER_SPFRESULT_LINK_BLACKLISTCHECK" => "Blacklist check", + + 'D3_MAILCHECKER_DMARCRESULT_HL' => 'DMARC (Reject policy and reporting)', + 'D3_MAILCHECKER_DMARCRESULT_DESC' => 'The DMARC entry defines how to deal with mails for which the authentication checks have failed. Mail addresses for reports can also be specified there.', + 'D3_MAILCHECKER_DMARCRESULT_SET' => 'A DMARC entry is set, the behaviour is not set to ‘ignore’.', + 'D3_MAILCHECKER_DMARCRESULT_MISSING' => 'No DMARC entry is set or configured with ‘ignore’. This should be changed urgently.', + 'D3_MAILCHECKER_DMARCRESULT_ERROR' => 'The DMARC record cannot be checked', + 'D3_MAILCHECKER_DMARCRESULT_LINKS' => 'Related Links', + 'D3_MAILCHECKER_DMARCRESULT_LINK_ANALYSIS' => 'DMARC analysis', + 'D3_MAILCHECKER_DMARCRESULT_LINK_GENERATOR' => 'DMARC generator', + "D3_MAILCHECKER_TESTMAIL_DESC" => "The test email is sent in the same way as all regular emails from the shop (e.g..B. order confirmations, ...) and can ", "D3_MAILCHECKER_TESTMAIL_HEADERANALYSIS" => "Email Header Analyzer", "D3_MAILCHECKER_TESTMAIL_SUBJECT" => "Regarding", diff --git a/views/smarty/admin/mailTester.tpl b/views/smarty/admin/mailTester.tpl index f214200..13da046 100644 --- a/views/smarty/admin/mailTester.tpl +++ b/views/smarty/admin/mailTester.tpl @@ -1,5 +1,5 @@ [{include file="headitem.tpl" title="d3mxd3cleartmp"|oxmultilangassign}] -[{include file="@d3mailconfigchecker/admin/inc_bootstrap"}] +[{include file="@d3mailconfigchecker/admin/inc_bootstrap.tpl"}] [{if $readonly}] [{assign var="readonly" value="readonly disabled"}] diff --git a/views/smarty/admin/mailconfigcheck.tpl b/views/smarty/admin/mailconfigcheck.tpl index efbf30d..3accf55 100644 --- a/views/smarty/admin/mailconfigcheck.tpl +++ b/views/smarty/admin/mailconfigcheck.tpl @@ -1,5 +1,5 @@ [{include file="headitem.tpl" title="d3mxd3cleartmp"|oxmultilangassign}] -[{include file="@d3mailconfigchecker/admin/inc_bootstrap"}] +[{include file="@d3mailconfigchecker/admin/inc_bootstrap.tpl"}]