diff --git a/etc/inc/dyndns.class b/etc/inc/dyndns.class index b64cb866f9..e5ae147f6f 100644 --- a/etc/inc/dyndns.class +++ b/etc/inc/dyndns.class @@ -21,10 +21,12 @@ * - HE.net (dns.he.net) * - HE.net Tunnelbroker IP update (ipv4.tunnelbroker.net) * - SelfHost (selfhost.de) - * - Amazon Route 53 (aws.amazon.com) + * - Amazon Route 53 (aws.amazon.com) + * - DNS-O-Matic (dnsomatic.com) + * - Custom DDNS (any URL) * +----------------------------------------------------+ * Requirements: - * - PHP version 4.0.2 or higher with CURL Library + * - PHP version 4.0.2 or higher with the CURL Library and the PCRE Library * +----------------------------------------------------+ * Public Functions * - updatedns() @@ -56,7 +58,8 @@ * HE.net - Last Tested: NEVER * HE.net Tunnel - Last Tested: 28 June 2011 * SelfHost - Last Tested: 26 December 2011 -+ * Amazon Route 53 - Last tested: 01 April 2012 + * Amazon Route 53 - Last tested: 01 April 2012 + * DNS-O-Matic - Last Tested: 9 September 2010 * +====================================================+ * * @author E.Kristensen @@ -65,6 +68,7 @@ * @updated 13 October 05 at 21:02:42 GMT * * DNSexit/OpenDNS support and multiwan extension for pfSense by Ermal Luçi + * Custom DNS support by Matt Corallo * */ @@ -78,8 +82,6 @@ var $_dnsPass; var $_dnsHost; var $_dnsIP; - /* This is needed for support on addresses behind NAT. */ - var $_ifIP; var $_dnsWildcard; var $_dnsMX; var $_dnsBackMX; @@ -91,24 +93,33 @@ var $status; var $_debugID; var $_if; + var $_dnsResultMatch; + var $_dnsRequestIf; + var $_dnsRequestIfIP; /* * Public Constructor Function (added 12 July 05) [beta] * - Gets the dice rolling for the update. + * - $dnsResultMatch should only be used with $dnsService = 'custom' + * - $dnsResultMatch is parsed for '%IP%', which is the IP the provider was updated to, + * - it is otherwise expected to be exactly identical to what is returned by the Prover. + * - $dnsUser, and $dnsPass indicate HTTP Auth for custom DNS, if they are needed in the URL (GET Variables), include them in $dnsUpdateURL. + * - $For custom requests, $dnsUpdateURL is parsed for '%IP%', which is replaced with the new IP. */ function updatedns ($dnsService = '', $dnsHost = '', $dnsUser = '', $dnsPass = '', $dnsWildcard = 'OFF', $dnsMX = '', $dnsIf = '', $dnsBackMX = '', $dnsServer = '', $dnsPort = '', $dnsUpdateURL = '', $forceUpdate = false, - $dnsZoneID ='', $dnsTTL='') { + $dnsZoneID ='', $dnsTTL='', $dnsResultMatch = '', $dnsRequestIf = '', + $dnsID = '') { global $config, $g; - $this->_cacheFile = "{$g['conf_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($dnsHost) . ".cache"; - $this->_debugFile = "{$g['varetc_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($dnsHost) . ".debug"; + $this->_cacheFile = "{$g['conf_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($dnsHost) . "{$dnsID}.cache"; + $this->_debugFile = "{$g['varetc_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($dnsHost) . "{$dnsID}.debug"; log_error("DynDns: updatedns() starting"); - $dyndnslck = lock($dnsHost, LOCK_EX); + $dyndnslck = lock("DDNS".$dnsID, LOCK_EX); if (!$dnsService) $this->_error(2); switch ($dnsService) { @@ -119,11 +130,13 @@ if (!$dnsPass) $this->_error(4); if (!$dnsHost) $this->_error(5); break; - case 'route53': - if (!$dnsZoneID) $this->_error(8); - if (!$dnsTTL) $this->_error(9); - break; - + case 'route53': + if (!$dnsZoneID) $this->_error(8); + if (!$dnsTTL) $this->_error(9); + break; + case 'custom': + if (!$dnsUpdateURL) $this->_error(7); + break; default: if (!$dnsUser) $this->_error(3); if (!$dnsPass) $this->_error(4); @@ -141,11 +154,15 @@ $this->_dnsZoneID = $dnsZoneID; $this->_dnsTTL = $dnsTTL; $this->_if = get_real_interface($dnsIf); - $this->_ifIP = get_interface_ip($dnsIf); + $this->_checkIP(); + $this->_dnsUpdateURL = $dnsUpdateURL; + $this->_dnsResultMatch = $dnsResultMatch; + $this->_dnsRequestIf = get_real_interface($dnsRequestIf); + $this->_dnsRequestIfIP = get_interface_ip($dnsRequestIf); // Ensure that we where able to lookup the IP - if(!is_ipaddr($this->_ifIP)) { - log_error("There was an error trying to determine the IP for interface - {$dnsIf}({$this->_if}). Probably interface has no ip or is down. Dyndns update not possible for {$dnsService}."); + if(!is_ipaddr($this->_dnsIP)) { + log_error("There was an error trying to determine the public IP for interface - {$dnsIf}({$this->_if}). Probably interface is not a WAN interface."); unlock($dyndnslck); return; } @@ -171,16 +188,15 @@ case 'loopia': case 'staticcling': case 'dnsexit': + case 'custom': case 'opendns': case 'namecheap': case 'he-net': case 'selfhost': + case 'he-net-tunnelbroker': case 'route53': $this->_update(); break; - case 'he-net-tunnelbroker': - $this->_update(); - break; default: $this->_error(6); break; @@ -203,7 +219,7 @@ curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); - curl_setopt($ch, CURLOPT_INTERFACE, $this->_ifIP); + curl_setopt($ch, CURLOPT_INTERFACE, $this->_dnsRequestIfIP); curl_setopt($ch, CURLOPT_TIMEOUT, 120); // Completely empirical } @@ -496,6 +512,17 @@ } $this->_checkStatus(0, $result); break; + case 'custom': + log_error("Custom DDNS: DNS update() starting."); + if (strstr($this->dnsUpdateURL, "%IP%")) {$needsIP = TRUE;} else {$needsIP = FALSE;} + if ($this->_dnsUser != '') { + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_setopt($ch, CURLOPT_USERPWD, "{$this->_dnsUser}:{$this->_dnsPass}"); + } + $server = str_replace("%IP%", $this->_dnsIP, $this->_dnsUpdateURL); + log_error("Sending request to: ".$server); + curl_setopt($ch, CURLOPT_URL, $server); + break; default: break; } @@ -786,7 +813,7 @@ $this->_debug($data); } break; - case 'staticcling': + case 'staticcling': if (preg_match("/invalid ip/i", $data)) { $status = "phpDynDNS: (Error) Bad Request - The IP provided was invalid."; } else if (preg_match('/required info missing/i', $data)) { @@ -894,6 +921,25 @@ case 'route53': $successful_update = true; break; + case 'custom': + $successful_update = false; + if ($this->_dnsResultMatch == "") { + $successful_update = true; + }else { + $this->_dnsResultMatch = str_replace("%IP%", $this->_dnsIP, $this->_dnsResultMatch); + $matches = preg_split("/(?_dnsResultMatch); + foreach($matches as $match) { + $match= str_replace("\\|", "|", $match); + if(strcmp($match, trim($data, "\t\n\r")) == 0) + $successful_update = true; + } + unset ($matches); + } + if ($successful_update == true) + $status = "phpDynDNS: (Success) IP Address Updated Successfully!"; + else + $status = "phpDynDNS: (Error) Result did not match."; + break; } if($successful_update == true) { @@ -976,7 +1022,6 @@ log_error("DynDns: Current WAN IP could not be determined, skipping update process."); return false; } - $this->_dnsIP = $wan_ip; $log_error = "DynDns: Current WAN IP: {$wan_ip} "; if (file_exists($this->_cacheFile)) { @@ -1052,7 +1097,6 @@ $ip_address = find_interface_ip($this->_if); if (!is_ipaddr($ip_address)) return 0; - $this->_ifIP = $ip_address; if (is_private_ip($ip_address)) { $hosttocheck = "checkip.dyndns.org"; $try = 0; @@ -1086,6 +1130,8 @@ } else log_error("DynDns debug information: {$ip_address} extracted from local system."); + $this->_dnsIP = $ip_address; + return $ip_address; } diff --git a/etc/inc/services.inc b/etc/inc/services.inc index 91aba0c7e2..f5b2c489e1 100644 --- a/etc/inc/services.inc +++ b/etc/inc/services.inc @@ -1312,10 +1312,13 @@ function services_dyndns_configure_client($conf) { $dnsBackMX = NULL, $dnsServer = NULL, $dnsPort = NULL, - $dnsUpdateURL = NULL, + $dnsUpdateURL = "{$conf['updateurl']}", $forceUpdate = $conf['force'], $dnsZoneID=$conf['zoneid'], - $dnsTTL=$conf['ttl']); + $dnsTTL=$conf['ttl'], + $dnsResultMatch = "{$conf['resultmatch']}", + $dnsRequestIf = "{$conf['requestif']}", + $dnsID = "{$conf['id']}"); } function services_dyndns_configure($int = "") { diff --git a/usr/local/www/services_dyndns.php b/usr/local/www/services_dyndns.php index 06f944b305..7953331997 100755 --- a/usr/local/www/services_dyndns.php +++ b/usr/local/www/services_dyndns.php @@ -47,8 +47,17 @@ $a_dyndns = &$config['dyndnses']['dyndns']; if ($_GET['act'] == "del") { unset($a_dyndns[$_GET['id']]); + for($i = 0; $i < count($a_dyndns); $i++) { + $a_dyndns[$i]['id'] = $i; + } + + //FIXME: Instead of rechecking all interfaces and removing the cache files, gracefully move all cache files to the appropriate ID number. + mwexec("/bin/rm {$g['conf_path']}/dyndns_*.cache"); + write_config(); + services_dyndns_configure(); + header("Location: services_dyndns.php"); exit; } @@ -114,8 +123,8 @@ include("head.inc"); +
@@ -154,10 +215,10 @@ include("head.inc"); - + + + + + + - + - + - + @@ -231,6 +306,30 @@ include("head.inc");
+ + + + + + + + @@ -272,17 +371,7 @@ include("head.inc");
-
+ +
+
@@ -190,7 +264,7 @@ include("head.inc");
@@ -200,18 +274,19 @@ include("head.inc");
>
-
+

+
+ +
+
+ +
+ +
+
+ +
+ +
+ +
+ +