HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/be.naniguide.com/vendor/louis/spfcheck/src/DNSRecordGetterDirect.php
<?php
/**
 * DNSRecordGetterDirect
 *
 * @author    Brian Tafoya <[email protected]>
 */

namespace Mika56\SPFCheck;

use Mika56\SPFCheck\Exception\DNSLookupException;
use Mika56\SPFCheck\Exception\DNSLookupLimitReachedException;
use PurplePixie\PhpDns\DNSQuery;

class DNSRecordGetterDirect implements DNSRecordGetterInterface
{

    protected $requestCount = 0;
    protected $requestMXCount = 0;
    protected $requestPTRCount = 0;
    protected $nameserver = "8.8.8.8";
    protected $port = 53;
    protected $timeout = 30;
    protected $udp = true;
    protected $tcpFallback;

    const DNS_A = 'A';
    const DNS_CNAME = "CNAME";
    const DNS_HINFO = "HINFO";
    const DNS_CAA = "CAA";
    const DNS_MX = "MX";
    const DNS_NS = "NS";
    const DNS_PTR = "PTR";
    const DNS_SOA = "SOA";
    const DNS_TXT = "TXT";
    const DNS_AAAA = "AAAA";
    const DNS_SRV = "SRV";
    const DNS_NAPTR = "NAPTR";
    const DNS_A6 = "A6";
    const DNS_ALL = "ALL";
    const DNS_ANY = "ANY";

    /**
     * DNSRecordGetter constructor.
     *
     * @param string $nameserver
     * @param int $port
     * @param int $timeout
     * @param bool $udp
     * @param bool $tcpFallback
     */
    public function __construct($nameserver = "8.8.8.8", $port = 53, $timeout = 30, $udp = true, $tcpFallback = true)
    {
        $this->nameserver  = $nameserver;
        $this->port        = $port;
        $this->timeout     = $timeout;
        $this->udp         = $udp;
        $this->tcpFallback = $tcpFallback;
    }

    /**
     * @param $domain string The domain to get SPF record
     * @return string[] The SPF record(s)
     * @throws DNSLookupException
     */
    public function getSPFRecordForDomain($domain)
    {
        $records = $this->dns_get_record($domain, "TXT");
        if (false === $records) {
            throw new DNSLookupException;
        }

        $spfRecords = array();
        foreach ($records as $record) {
            if ($record['type'] == 'TXT') {
                $txt = strtolower($record['txt']);
                // An SPF record can be empty (no mechanism)
                if ($txt == 'v=spf1' || stripos($txt, 'v=spf1 ') === 0) {
                    $spfRecords[] = $txt;
                }
            }
        }

        return $spfRecords;
    }

    public function resolveA($domain, $ip4only = false)
    {
        $records = $this->dns_get_record($domain, "A");

        if (!$ip4only) {
            $ip6 = $this->dns_get_record($domain, "AAAA");
            if ($ip6) {
                $records = array_merge($records, $ip6);
            }
        }

        if (false === $records) {
            throw new DNSLookupException;
        }

        $addresses = [];

        foreach ($records as $record) {
            if ($record['type'] === "A") {
                $addresses[] = $record['ip'];
            } elseif ($record['type'] === 'AAAA') {
                $addresses[] = $record['ipv6'];
            }
        }

        return $addresses;
    }

    public function resolveMx($domain)
    {
        $records = $this->dns_get_record($domain, "MX");
        if (false === $records) {
            throw new DNSLookupException;
        }

        $addresses = [];

        foreach ($records as $record) {
            if ($record['type'] === "MX") {
                $addresses[] = $record['target'];
            }
        }

        return $addresses;
    }

    public function resolvePtr($ipAddress)
    {
        if (stripos($ipAddress, '.') !== false) {
            // IPv4
            $revIp = implode('.', array_reverse(explode('.', $ipAddress))).'.in-addr.arpa';
        } else {
            $literal = implode(':', array_map(function ($b) {
                return sprintf('%04x', $b);
            }, unpack('n*', inet_pton($ipAddress))));
            $revIp   = strtolower(implode('.', array_reverse(str_split(str_replace(':', '', $literal))))).'.ip6.arpa';
        }

        $revs = array_map(function ($e) {
            return $e['target'];
        }, $this->dns_get_record($revIp, "PTR"));

        return $revs;
    }

    public function exists($domain)
    {
        try {
            return count($this->resolveA($domain, true)) > 0;
        } catch (DNSLookupException $e) {
            return false;
        }
    }

    public function dns_get_record($question, $type)
    {
        $response = array();

        $dnsquery = new DNSQuery($this->nameserver, (int)$this->port, (int)$this->timeout, $this->udp, false, false);
        $result   = $dnsquery->query($question, $type);

        // Retry if we get an too big for UDP error
        if ($this->udp && $this->tcpFallback && $dnsquery->hasError() && $dnsquery->getLasterror() == "Response too big for UDP, retry with TCP") {
            $dnsquery = new DNSQuery($this->nameserver, (int)$this->port, (int)$this->timeout, false, false, false);
            $result   = $dnsquery->query($question, $type);
        }

        if ($dnsquery->hasError()) {
            throw new DNSLookupException($dnsquery->getLasterror());
        }

        foreach ($result as $index => $record) {

            $extras = array();

            // additional data
            if (count($record->getExtras()) > 0) {
                foreach ($record->getExtras() as $key => $val) {
                    // We don't want to echo binary data
                    if ($key != 'ipbin') {
                        $extras[$key] = $val;
                    }
                }
            }

            switch ($type) {
                default:
                    throw new \Exception("Unsupported type ".$type.".");
                    break;
                case "A":
                    $response[] = array(
                        "host"  => $record->getDomain(),
                        "class" => "IN",
                        "ttl"   => $record->getTtl(),
                        "type"  => $record->getTypeid(),
                        "ip"    => $record->getData(),
                    );
                    break;
                case "AAAA":
                    $response[] = array(
                        "host"  => $record->getDomain(),
                        "class" => "IN",
                        "ttl"   => $record->getTtl(),
                        "type"  => $record->getTypeid(),
                        "ipv6"  => $record->getData(),
                    );
                    break;
                case "MX":
                    $response[] = array(
                        "host"   => $record->getDomain(),
                        "class"  => "IN",
                        "ttl"    => $record->getTtl(),
                        "type"   => $record->getTypeid(),
                        "pri"    => $extras["level"],
                        "target" => $record->getData(),
                    );
                    break;
                case "TXT":
                    $response[] = array(
                        "host"    => $record->getDomain(),
                        "class"   => "IN",
                        "ttl"     => $record->getTtl(),
                        "type"    => $record->getTypeid(),
                        "txt"     => $record->getData(),
                        "entries" => array($record->getData()),
                    );
                    break;
                case "PTR":
                    $response[] = array(
                        "host"   => $record->getDomain(),
                        "class"  => "IN",
                        "ttl"    => $record->getTtl(),
                        "type"   => $record->getTypeid(),
                        "target" => $record->getData(),
                    );
                    break;
            }

        }

        return $response;
    }

    /**
     * @codeCoverageIgnore
     */
    public function resetRequestCount()
    {
        trigger_error('DNSRecordGetterInterface::resetRequestCount() is deprecated. Please use resetRequestCounts() instead', E_USER_DEPRECATED);
        $this->resetRequestCounts();
    }

    public function countRequest()
    {
        if (++$this->requestCount > 10) {
            throw new DNSLookupLimitReachedException();
        }
    }

    public function resetRequestCounts()
    {
        $this->requestCount    = 0;
        $this->requestMXCount  = 0;
        $this->requestPTRCount = 0;
    }

    public function countMxRequest()
    {
        if (++$this->requestMXCount > 10) {
            throw new DNSLookupLimitReachedException();
        }
    }

    public function countPtrRequest()
    {
        if (++$this->requestPTRCount > 10) {
            throw new DNSLookupLimitReachedException();
        }
    }
}