Files
wevads-platform/scripts/api_auth-wizard.php
2026-02-26 04:53:11 +01:00

180 lines
6.8 KiB
PHP
Executable File

<?php
/**
* EMAIL AUTHENTICATION WIZARD
* Auto-configure SPF, DKIM, DMARC, BIMI
*/
header('Content-Type: application/json');
$pdo = new PDO("pgsql:host=localhost;dbname=adx_system", "admin", "admin123", [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$pdo->exec("
CREATE TABLE IF NOT EXISTS admin.domain_auth (
id SERIAL PRIMARY KEY,
domain VARCHAR(255) UNIQUE,
spf_record TEXT,
spf_status VARCHAR(50) DEFAULT 'pending',
dkim_selector VARCHAR(100) DEFAULT 'default',
dkim_public_key TEXT,
dkim_private_key TEXT,
dkim_status VARCHAR(50) DEFAULT 'pending',
dmarc_policy VARCHAR(20) DEFAULT 'none',
dmarc_record TEXT,
dmarc_status VARCHAR(50) DEFAULT 'pending',
bimi_logo_url TEXT,
bimi_status VARCHAR(50) DEFAULT 'pending',
last_check TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
");
class AuthWizard {
private $pdo;
public function __construct($pdo) { $this->pdo = $pdo; }
public function analyzeDomain($domain) {
$results = [
'domain' => $domain,
'spf' => $this->checkSPF($domain),
'dkim' => $this->checkDKIM($domain),
'dmarc' => $this->checkDMARC($domain),
'mx' => $this->checkMX($domain)
];
$results['score'] = $this->calculateScore($results);
$results['recommendations'] = $this->generateRecommendations($results);
return $results;
}
private function checkSPF($domain) {
$records = @dns_get_record($domain, DNS_TXT);
foreach ($records ?: [] as $r) {
if (strpos($r['txt'] ?? '', 'v=spf1') === 0) {
return ['found' => true, 'record' => $r['txt'], 'valid' => true];
}
}
return ['found' => false, 'record' => null, 'valid' => false];
}
private function checkDKIM($domain, $selector = 'default') {
$dkimDomain = "$selector._domainkey.$domain";
$records = @dns_get_record($dkimDomain, DNS_TXT);
foreach ($records ?: [] as $r) {
if (strpos($r['txt'] ?? '', 'v=DKIM1') !== false) {
return ['found' => true, 'selector' => $selector, 'record' => $r['txt']];
}
}
return ['found' => false, 'selector' => $selector, 'record' => null];
}
private function checkDMARC($domain) {
$dmarcDomain = "_dmarc.$domain";
$records = @dns_get_record($dmarcDomain, DNS_TXT);
foreach ($records ?: [] as $r) {
if (strpos($r['txt'] ?? '', 'v=DMARC1') === 0) {
preg_match('/p=(\w+)/', $r['txt'], $m);
return ['found' => true, 'record' => $r['txt'], 'policy' => $m[1] ?? 'none'];
}
}
return ['found' => false, 'record' => null, 'policy' => null];
}
private function checkMX($domain) {
$records = @dns_get_record($domain, DNS_MX);
return ['found' => !empty($records), 'records' => $records ?: []];
}
private function calculateScore($results) {
$score = 0;
if ($results['spf']['found']) $score += 25;
if ($results['dkim']['found']) $score += 25;
if ($results['dmarc']['found']) $score += 25;
if ($results['dmarc']['policy'] === 'reject') $score += 15;
elseif ($results['dmarc']['policy'] === 'quarantine') $score += 10;
if ($results['mx']['found']) $score += 10;
return $score;
}
private function generateRecommendations($results) {
$recs = [];
if (!$results['spf']['found']) {
$recs[] = ['type' => 'spf', 'priority' => 'high', 'message' => 'Add SPF record', 'record' => 'v=spf1 include:_spf.google.com ~all'];
}
if (!$results['dkim']['found']) {
$recs[] = ['type' => 'dkim', 'priority' => 'high', 'message' => 'Configure DKIM signing'];
}
if (!$results['dmarc']['found']) {
$recs[] = ['type' => 'dmarc', 'priority' => 'high', 'message' => 'Add DMARC record', 'record' => 'v=DMARC1; p=none; rua=mailto:dmarc@' . $results['domain']];
} elseif ($results['dmarc']['policy'] === 'none') {
$recs[] = ['type' => 'dmarc', 'priority' => 'medium', 'message' => 'Upgrade DMARC to quarantine or reject'];
}
return $recs;
}
public function generateDKIM($domain, $selector = 'default') {
// Generate DKIM key pair
$config = ['digest_alg' => 'sha256', 'private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_RSA];
$res = openssl_pkey_new($config);
openssl_pkey_export($res, $privateKey);
$publicKey = openssl_pkey_get_details($res)['key'];
// Format for DNS
$publicKeyClean = str_replace(['-----BEGIN PUBLIC KEY-----', '-----END PUBLIC KEY-----', "\n", "\r"], '', $publicKey);
$dkimRecord = "v=DKIM1; k=rsa; p=$publicKeyClean";
// Save to database
$this->pdo->prepare("INSERT INTO admin.domain_auth (domain, dkim_selector, dkim_public_key, dkim_private_key) VALUES (?, ?, ?, ?) ON CONFLICT (domain) DO UPDATE SET dkim_selector = ?, dkim_public_key = ?, dkim_private_key = ?")
->execute([$domain, $selector, $publicKey, $privateKey, $selector, $publicKey, $privateKey]);
return [
'domain' => $domain,
'selector' => $selector,
'dns_record' => "$selector._domainkey.$domain",
'dns_value' => $dkimRecord,
'private_key' => $privateKey
];
}
public function generateRecords($domain) {
return [
'spf' => [
'type' => 'TXT',
'name' => '@',
'value' => 'v=spf1 ip4:89.167.40.150 include:_spf.google.com ~all'
],
'dkim' => [
'type' => 'TXT',
'name' => 'default._domainkey',
'value' => 'v=DKIM1; k=rsa; p=[YOUR_PUBLIC_KEY]'
],
'dmarc' => [
'type' => 'TXT',
'name' => '_dmarc',
'value' => "v=DMARC1; p=quarantine; rua=mailto:dmarc@$domain; pct=100"
]
];
}
}
$wizard = new AuthWizard($pdo);
$action = $_POST['action'] ?? $_GET['action'] ?? '';
switch ($action) {
case 'analyze':
echo json_encode($wizard->analyzeDomain($_GET['domain'] ?? $_POST['domain']));
break;
case 'generate_dkim':
echo json_encode($wizard->generateDKIM($_POST['domain'], $_POST['selector'] ?? 'default'));
break;
case 'generate_records':
echo json_encode($wizard->generateRecords($_GET['domain']));
break;
case 'domains':
echo json_encode(['domains' => $pdo->query("SELECT * FROM admin.domain_auth ORDER BY domain")->fetchAll(PDO::FETCH_ASSOC)]);
break;
default:
echo json_encode(['name' => 'Auth Wizard', 'actions' => ['analyze','generate_dkim','generate_records','domains']]);
}