Update file inclusion paths in multiple PHP files: Adjusted paths to use the new backend directory structure, ensuring consistent access to functions and configuration files across the application.

This commit is contained in:
𝓜𝓪𝓬𝓮™
2026-04-02 13:46:08 +02:00
parent b4ab365314
commit c8386a8f4b
34 changed files with 2879 additions and 25 deletions

View File

@@ -0,0 +1,365 @@
<?php
/**
* HexaDNS - WHOIS Lookup API
*
* Ruft WHOIS-Informationen für eine Domain ab
*
* Verwendung: GET /api/whois-lookup.php?domain=example.com
*/
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}
$domain = isset($_GET['domain']) ? trim($_GET['domain']) : '';
if (empty($domain)) {
http_response_code(400);
echo json_encode(['error' => 'Domain-Parameter fehlt']);
exit;
}
// Nur Root-Domain extrahieren
$domain = extractRootDomain($domain);
if (!preg_match('/^[a-zA-Z0-9][a-zA-Z0-9\-]*\.[a-zA-Z]{2,}$/', $domain)) {
http_response_code(400);
echo json_encode(['error' => 'Ungültiges Domain-Format']);
exit;
}
$startTime = microtime(true);
$whoisData = performWhoisLookup($domain);
$queryTime = round((microtime(true) - $startTime) * 1000, 2);
if ($whoisData === null) {
http_response_code(500);
echo json_encode(['error' => 'WHOIS-Abfrage fehlgeschlagen']);
exit;
}
echo json_encode([
'success' => true,
'domain' => $domain,
'query_time_ms' => $queryTime,
'timestamp' => date('Y-m-d H:i:s'),
'whois' => $whoisData
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
/**
* Extrahiert die Root-Domain (ohne Subdomain)
*/
function extractRootDomain(string $domain): string {
$domain = strtolower($domain);
$domain = preg_replace('/^(https?:\/\/)?(www\.)?/', '', $domain);
$domain = explode('/', $domain)[0];
$parts = explode('.', $domain);
if (count($parts) > 2) {
// Einfache Logik: nimm die letzten 2 Teile
// (funktioniert nicht perfekt für .co.uk etc., aber gut genug)
return implode('.', array_slice($parts, -2));
}
return $domain;
}
/**
* Führt WHOIS-Lookup durch
*/
function performWhoisLookup(string $domain): ?array {
// Primär: Socket-basierte Abfrage (funktioniert ohne shell_exec)
$whoisRaw = whoisViaSocket($domain);
// Fallback: Shell-Kommando (sicher escaped)
if (empty($whoisRaw) && function_exists('shell_exec')) {
$escapedDomain = escapeshellarg($domain);
$whoisRaw = @shell_exec("whois {$escapedDomain} 2>/dev/null");
}
if (empty($whoisRaw)) {
return null;
}
// Parse WHOIS-Daten
return parseWhoisData($whoisRaw, $domain);
}
/**
* WHOIS-Abfrage über Socket (unabhängig von shell_exec)
*/
function whoisViaSocket(string $domain): ?string {
$whoisServer = getWhoisServer($domain);
if (!$whoisServer) {
return null;
}
$result = queryWhoisServer($whoisServer, $domain);
// Prüfe auf Weiterleitungen zu anderen WHOIS-Servern
if ($result && preg_match('/Registrar WHOIS Server:\s*(\S+)/i', $result, $matches)) {
$referralServer = trim($matches[1]);
if ($referralServer && $referralServer !== $whoisServer) {
$referralResult = queryWhoisServer($referralServer, $domain);
if ($referralResult) {
$result = $referralResult;
}
}
}
return $result;
}
/**
* Abfrage an einen spezifischen WHOIS-Server
*/
function queryWhoisServer(string $server, string $domain): ?string {
$port = 43;
$timeout = 10;
$socket = @fsockopen($server, $port, $errno, $errstr, $timeout);
if (!$socket) {
return null;
}
// Setze Stream-Timeout
stream_set_timeout($socket, $timeout);
// Sende Anfrage
fwrite($socket, $domain . "\r\n");
// Lese Antwort
$response = '';
while (!feof($socket)) {
$response .= fread($socket, 8192);
}
fclose($socket);
return !empty($response) ? $response : null;
}
/**
* Ermittelt den zuständigen WHOIS-Server für eine TLD
*/
function getWhoisServer(string $domain): ?string {
$parts = explode('.', $domain);
$tld = strtolower(end($parts));
// Bekannte WHOIS-Server nach TLD
$whoisServers = [
// Generische TLDs
'com' => 'whois.verisign-grs.com',
'net' => 'whois.verisign-grs.com',
'org' => 'whois.pir.org',
'info' => 'whois.afilias.net',
'biz' => 'whois.biz',
'name' => 'whois.nic.name',
'mobi' => 'whois.dotmobiregistry.net',
'pro' => 'whois.registrypro.pro',
'aero' => 'whois.aero',
'asia' => 'whois.nic.asia',
'cat' => 'whois.nic.cat',
'coop' => 'whois.nic.coop',
'edu' => 'whois.educause.edu',
'gov' => 'whois.dotgov.gov',
'int' => 'whois.iana.org',
'jobs' => 'whois.nic.jobs',
'mil' => 'whois.nic.mil',
'museum' => 'whois.museum',
'post' => 'whois.dotpostregistry.net',
'tel' => 'whois.nic.tel',
'travel' => 'whois.nic.travel',
'xxx' => 'whois.nic.xxx',
// Neue gTLDs
'app' => 'whois.nic.google',
'dev' => 'whois.nic.google',
'page' => 'whois.nic.google',
'blog' => 'whois.nic.blog',
'cloud' => 'whois.nic.cloud',
'shop' => 'whois.nic.shop',
'store' => 'whois.nic.store',
'online' => 'whois.nic.online',
'site' => 'whois.nic.site',
'website' => 'whois.nic.website',
'tech' => 'whois.nic.tech',
'io' => 'whois.nic.io',
'co' => 'whois.nic.co',
'me' => 'whois.nic.me',
'tv' => 'whois.nic.tv',
'cc' => 'ccwhois.verisign-grs.com',
'ws' => 'whois.website.ws',
// Europäische ccTLDs
'de' => 'whois.denic.de',
'at' => 'whois.nic.at',
'ch' => 'whois.nic.ch',
'li' => 'whois.nic.li',
'uk' => 'whois.nic.uk',
'fr' => 'whois.nic.fr',
'it' => 'whois.nic.it',
'es' => 'whois.nic.es',
'pt' => 'whois.dns.pt',
'nl' => 'whois.domain-registry.nl',
'be' => 'whois.dns.be',
'pl' => 'whois.dns.pl',
'cz' => 'whois.nic.cz',
'sk' => 'whois.sk-nic.sk',
'hu' => 'whois.nic.hu',
'ro' => 'whois.rotld.ro',
'bg' => 'whois.register.bg',
'hr' => 'whois.dns.hr',
'si' => 'whois.register.si',
'rs' => 'whois.rnids.rs',
'gr' => 'grwhois.ics.forth.gr',
'dk' => 'whois.punktum.dk',
'se' => 'whois.iis.se',
'no' => 'whois.norid.no',
'fi' => 'whois.fi',
'ie' => 'whois.iedr.ie',
'eu' => 'whois.eu',
'lu' => 'whois.dns.lu',
// Andere ccTLDs
'ru' => 'whois.tcinet.ru',
'ua' => 'whois.ua',
'us' => 'whois.nic.us',
'ca' => 'whois.cira.ca',
'mx' => 'whois.mx',
'br' => 'whois.registro.br',
'ar' => 'whois.nic.ar',
'au' => 'whois.auda.org.au',
'nz' => 'whois.srs.net.nz',
'jp' => 'whois.jprs.jp',
'kr' => 'whois.kr',
'cn' => 'whois.cnnic.cn',
'in' => 'whois.registry.in',
'sg' => 'whois.sgnic.sg',
'hk' => 'whois.hkirc.hk',
'tw' => 'whois.twnic.net.tw',
'za' => 'whois.registry.net.za',
];
// Spezielle Behandlung für .co.uk, .com.au etc.
if (count($parts) >= 2) {
$sld = $parts[count($parts) - 2];
$combinedTld = $sld . '.' . $tld;
$secondLevelTlds = [
'co.uk' => 'whois.nic.uk',
'org.uk' => 'whois.nic.uk',
'me.uk' => 'whois.nic.uk',
'com.au' => 'whois.auda.org.au',
'net.au' => 'whois.auda.org.au',
'org.au' => 'whois.auda.org.au',
'co.nz' => 'whois.srs.net.nz',
'com.br' => 'whois.registro.br',
];
if (isset($secondLevelTlds[$combinedTld])) {
return $secondLevelTlds[$combinedTld];
}
}
return $whoisServers[$tld] ?? 'whois.iana.org';
}
/**
* Parsed WHOIS-Rohdaten in strukturiertes Format
*/
function parseWhoisData(string $raw, string $domain): array {
$data = [
'raw' => $raw,
'parsed' => [
'domain_name' => $domain,
'registrar' => null,
'registrar_url' => null,
'creation_date' => null,
'expiration_date' => null,
'updated_date' => null,
'status' => [],
'nameservers' => [],
'dnssec' => null,
]
];
$lines = explode("\n", $raw);
foreach ($lines as $line) {
$line = trim($line);
if (empty($line) || strpos($line, '%') === 0 || strpos($line, '#') === 0) {
continue;
}
// Key: Value Format
if (strpos($line, ':') !== false) {
list($key, $value) = array_map('trim', explode(':', $line, 2));
$keyLower = strtolower($key);
// Registrar
if (strpos($keyLower, 'registrar') !== false && strpos($keyLower, 'abuse') === false && strpos($keyLower, 'url') === false) {
if (empty($data['parsed']['registrar'])) {
$data['parsed']['registrar'] = $value;
}
}
// Registrar URL
if (strpos($keyLower, 'registrar') !== false && strpos($keyLower, 'url') !== false) {
$data['parsed']['registrar_url'] = $value;
}
// Erstellungsdatum
if (preg_match('/(creation|created|registered)/i', $keyLower) && strpos($keyLower, 'registrar') === false) {
if (empty($data['parsed']['creation_date'])) {
$data['parsed']['creation_date'] = $value;
}
}
// Ablaufdatum
if (preg_match('/(expir|paid-till)/i', $keyLower)) {
if (empty($data['parsed']['expiration_date'])) {
$data['parsed']['expiration_date'] = $value;
}
}
// Aktualisierungsdatum
if (preg_match('/(updated|modified|changed)/i', $keyLower) && strpos($keyLower, 'registrar') === false) {
if (empty($data['parsed']['updated_date'])) {
$data['parsed']['updated_date'] = $value;
}
}
// Status
if (preg_match('/(status|state)/i', $keyLower) && !empty($value)) {
$data['parsed']['status'][] = $value;
}
// Nameserver
if (preg_match('/^(name.?server|nserver)/i', $keyLower) && !empty($value)) {
$ns = strtolower(explode(' ', $value)[0]);
if (!in_array($ns, $data['parsed']['nameservers'])) {
$data['parsed']['nameservers'][] = $ns;
}
}
// DNSSEC
if (strpos($keyLower, 'dnssec') !== false) {
$data['parsed']['dnssec'] = $value;
}
}
}
// Status einzigartig machen
$data['parsed']['status'] = array_unique($data['parsed']['status']);
return $data;
}