|
@@ -0,0 +1,127 @@
|
|
|
+<?php
|
|
|
+function get_spf_allowed_hosts($domain)
|
|
|
+{
|
|
|
+ $hosts = array();
|
|
|
+
|
|
|
+ $records = dns_get_record($domain, DNS_TXT);
|
|
|
+ foreach ($records as $record)
|
|
|
+ {
|
|
|
+ $txt = explode(' ', $record['entries'][0]);
|
|
|
+ if (array_shift($txt) != 'v=spf1') // only handle SPF records
|
|
|
+ continue;
|
|
|
+
|
|
|
+ foreach ($txt as $mech)
|
|
|
+ {
|
|
|
+ $qual = substr($mech, 0, 1);
|
|
|
+ if ($qual == '-' || $qual == '~') // only handle pass or neutral records
|
|
|
+ continue(2);
|
|
|
+
|
|
|
+ if ($qual == '+' || $qual == '?')
|
|
|
+ $mech = substr($mech, 1); // remove the qualifier
|
|
|
+
|
|
|
+ if (strpos($mech, '=') !== FALSE) // handle a modifier
|
|
|
+ {
|
|
|
+ $mod = explode('=', $mech);
|
|
|
+ if ($mod[0] == 'redirect') // handle a redirect
|
|
|
+ {
|
|
|
+ $hosts = get_spf_allowed_hosts($mod[1]);
|
|
|
+ return $hosts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ unset($cidr);
|
|
|
+ if (strpos($mech, ':') !== FALSE) // handle a domain specification
|
|
|
+ {
|
|
|
+ $split = explode(':', $mech);
|
|
|
+ $mech = array_shift($split);
|
|
|
+ $domain = implode(':', $split);
|
|
|
+ if (strpos($domain, '/') !== FALSE) // remove CIDR specification
|
|
|
+ {
|
|
|
+ $split = explode('/', $domain);
|
|
|
+ $domain = $split[0];
|
|
|
+ $cidr = $split[1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $new_hosts = array();
|
|
|
+ if ($mech == 'include') // handle an inclusion
|
|
|
+ {
|
|
|
+ $new_hosts = get_spf_allowed_hosts($domain);
|
|
|
+ }
|
|
|
+ elseif ($mech == 'a') // handle a mechanism
|
|
|
+ {
|
|
|
+ $new_hosts = get_a_hosts($domain);
|
|
|
+ }
|
|
|
+ elseif ($mech == 'mx') // handle mx mechanism
|
|
|
+ {
|
|
|
+ $new_hosts = get_mx_hosts($domain);
|
|
|
+ }
|
|
|
+ elseif ($mech == 'ip4' || $mech == 'ip6') // handle ip mechanism
|
|
|
+ {
|
|
|
+ $new_hosts = array($domain);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isset($cidr)) // add CIDR specification if present
|
|
|
+ {
|
|
|
+ foreach ($new_hosts as &$host)
|
|
|
+ {
|
|
|
+ $host .= '/' . $cidr;
|
|
|
+ }
|
|
|
+ unset($host);
|
|
|
+ }
|
|
|
+
|
|
|
+ $hosts = array_unique(array_merge($hosts,$new_hosts), SORT_REGULAR);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $hosts;
|
|
|
+}
|
|
|
+
|
|
|
+function get_mx_hosts($domain)
|
|
|
+{
|
|
|
+ $hosts = array();
|
|
|
+
|
|
|
+ $mx_records = dns_get_record($domain, DNS_MX);
|
|
|
+ foreach ($mx_records as $mx_record)
|
|
|
+ {
|
|
|
+ $new_hosts = get_a_hosts($mx_record['target']);
|
|
|
+ $hosts = array_unique(array_merge($hosts,$new_hosts), SORT_REGULAR);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $hosts;
|
|
|
+}
|
|
|
+
|
|
|
+function get_a_hosts($domain)
|
|
|
+{
|
|
|
+ $hosts = array();
|
|
|
+
|
|
|
+ $a_records = dns_get_record($domain, DNS_A);
|
|
|
+ foreach ($a_records as $a_record)
|
|
|
+ {
|
|
|
+ $hosts[] = $a_record['ip'];
|
|
|
+ }
|
|
|
+ $a_records = dns_get_record($domain, DNS_AAAA);
|
|
|
+ foreach ($a_records as $a_record)
|
|
|
+ {
|
|
|
+ $hosts[] = $a_record['ipv6'];
|
|
|
+ }
|
|
|
+
|
|
|
+ return $hosts;
|
|
|
+}
|
|
|
+
|
|
|
+function get_outgoing_hosts_best_guess($domain)
|
|
|
+{
|
|
|
+ // try the SPF record to get hosts that are allowed to send outgoing mails for this domain
|
|
|
+ $hosts = get_spf_allowed_hosts($domain);
|
|
|
+ if ($hosts) return $hosts;
|
|
|
+
|
|
|
+ // try the MX record to get mail servers for this domain
|
|
|
+ $hosts = get_mx_hosts($domain);
|
|
|
+ if ($hosts) return $hosts;
|
|
|
+
|
|
|
+ // fall back to the A record to get the host name for this domain
|
|
|
+ return get_a_hosts($domain);
|
|
|
+}
|
|
|
+?>
|