138 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| error_reporting(0);
 | |
| 
 | |
| function get_spf_allowed_hosts($check_domain)
 | |
| {
 | |
| 	$hosts = array();
 | |
| 	
 | |
| 	$records = dns_get_record($check_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' && $check_domain != $domain) // 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();
 | |
|   try {
 | |
|     $mx_records = dns_get_record($domain, DNS_MX);
 | |
|     if ($mx_records) {
 | |
|       foreach ($mx_records as $mx_record) {
 | |
|         $new_hosts = get_a_hosts($mx_record['target']);
 | |
|         $hosts = array_unique(array_merge($hosts,$new_hosts), SORT_REGULAR);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   catch (Exception $e) {
 | |
|     if ($e->getMessage() !== 'dns_get_record(): A temporary server error occurred.') {
 | |
|       throw $e;
 | |
|     }
 | |
|     $mx_records = false;
 | |
|   }
 | |
| 	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);
 | |
| }
 | |
| ?>
 | 
