summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2017-05-10 15:28:44 -0300
committerRenato Botelho <renato@netgate.com>2017-05-10 15:28:44 -0300
commit6e0bfeb217a5c812dfe4f0d217a318476f5815ca (patch)
treed3d8e6938690e288a116f43d7ca8338044933526 /src
parentc79376011dc17a285678939b08f751ce78c4ff27 (diff)
parent11db9c8687a7e11fb5e94fe148f955a9496c1640 (diff)
downloadpfsense-6e0bfeb217a5c812dfe4f0d217a318476f5815ca.zip
pfsense-6e0bfeb217a5c812dfe4f0d217a318476f5815ca.tar.gz
Merge pull request #3579 from frankthetank/dyndns_dreamhost
Diffstat (limited to 'src')
-rw-r--r--src/etc/inc/dyndns.class290
-rw-r--r--src/etc/inc/services.inc4
-rw-r--r--src/usr/local/www/services_dyndns_edit.php23
3 files changed, 312 insertions, 5 deletions
diff --git a/src/etc/inc/dyndns.class b/src/etc/inc/dyndns.class
index ab3ba2d..3fa2613 100644
--- a/src/etc/inc/dyndns.class
+++ b/src/etc/inc/dyndns.class
@@ -61,6 +61,7 @@
* - DuiaDNS (www.duiadns.net)
* - DuiaDNS IPv6 (www.duiadns.net)
* - Hover (www.hover.com)
+ * - DreamHost DNS (www.dreamhost.com)
* +----------------------------------------------------+
* Requirements:
* - PHP version 4.0.2 or higher with the CURL Library and the PCRE Library
@@ -115,6 +116,8 @@
* DuiaDNS - Last Tested: 25 November 2016
* DuiaDNS IPv6 - Last Tested: 25 November 2016
* Hover - Last Tested: 15 February 2017
+ * DreamHost - Last Tested: 30 April 2017
+ * DreamHost IPv6 - Not Yet Tested
* +====================================================+
*
* @author E.Kristensen
@@ -162,6 +165,7 @@
var $_dnsDummyUpdateDone;
var $_forceUpdateNeeded;
var $_useIPv6;
+ var $_existingRecords;
/*
* Public Constructor Function (added 12 July 05) [beta]
@@ -238,6 +242,7 @@
case 'duiadns-v6':
case 'freedns-v6':
case 'cloudflare-v6':
+ case 'dreamhost-v6':
$this->_useIPv6 = true;
break;
default:
@@ -333,6 +338,17 @@
$this->_update();
}
break;
+ case 'dreamhost':
+ case 'dreamhost-v6':
+ $this->_lookup_current();
+ if (isset($this->status)) {
+ return;
+ }
+ foreach ($this->_existingRecords as $record) {
+ $this->_remove($record['existing_val']);
+ $this->_update();
+ }
+ break;
default:
$this->_error(6);
break;
@@ -869,6 +885,29 @@
log_error("HostID:{$hostID}, OldIP:{$hostIP}");
}
break;
+ case 'dreamhost':
+ case 'dreamhost-v6':
+ $needsIP = TRUE;
+ $isv6 = ($this->_dnsService === 'dreamhost-v6');
+ $server = 'https://api.dreamhost.com/';
+ $post_data['key'] = $this->_dnsPass;
+ $post_data['unique_id'] = uniqid($this->_dnsHost);
+ $post_data['cmd'] = 'dns-add_record';
+ $post_data['format'] = 'json';
+ $post_data['value'] = $this->_dnsIP;
+ $post_data['record'] = $this->_dnsHost;
+ $post_data['type'] = $isv6 ? 'AAAA' : 'A';
+ $post_data['comment'] = "Updated by pfSense:$this->_dnsUser on ".date('c');
+ $port = "";
+ if ($this->_dnsServer) {
+ $server = $this->_dnsServer;
+ }
+ if ($this->_dnsPort) {
+ $port = ":" . $this->_dnsPort;
+ }
+ curl_setopt($ch, CURLOPT_URL, $server . $port);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
+ break;
default:
break;
}
@@ -882,6 +921,191 @@
@curl_close($ch);
}
}
+
+ /**
+ * Private Function (added 23 Feb 17)
+ * Send Removal To Selected Service.
+ *
+ * Some services do not perform an inplace upgrade. If they do not then the solution
+ * is to remove the existing record and add a new record.
+ *
+ * @param unknown $existing_ip If required, an existing IP address for the record.
+ */
+ function _remove($existing_ip = NULL) {
+ $remove_allowed = false;
+ if ($this->_dnsVerboseLog) {
+ log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _remove() starting.'), $this->_dnsService, $this->_FQDN));
+ }
+
+ if (strstr($this->_dnsRequestIf, "_vip")) {
+ $parentif = get_configured_vip_interface($this->_dnsRequestIf);
+ $realparentif = convert_friendly_interface_to_real_interface_name($parentif);
+ } else {
+ $realparentif = $this->_dnsRequestIf;
+ }
+
+ $ch = curl_init();
+
+ if ($this->_useIPv6 == false) {
+ curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+ }
+
+ curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
+ curl_setopt($ch, CURLOPT_INTERFACE, 'if!' . $realparentif);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 120); // Completely empirical
+
+ switch ($this->_dnsService) {
+ case 'dreamhost':
+ case 'dreamhost-v6':
+ $server = 'https://api.dreamhost.com/';
+ $post_data['key'] = $this->_dnsPass;
+ $post_data['unique_id'] = uniqid($this->_dnsHost);
+ $post_data['cmd'] = 'dns-remove_record';
+ $post_data['format'] = 'json';
+ $post_data['value'] = $existing_ip;
+ $post_data['record'] = $this->_dnsHost;
+ $isv6 = ($this->_dnsService === 'dreamhost-v6');
+ $post_data['type'] = $isv6 ? 'AAAA' : 'A';
+ $port = "";
+ if ($this->_dnsServer) {
+ $server = $this->_dnsServer;
+ }
+ if ($this->_dnsPort) {
+ $port = ":" . $this->_dnsPort;
+ }
+ curl_setopt($ch, CURLOPT_URL, $server . $port);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
+ $remove_allowed = true;
+ break;
+ default:
+ break;
+ }
+ if ($remove_allowed) {
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $data = substr($response, $header_size);
+ $this->_checkStatus($ch, $data, $header);
+ @curl_close($ch);
+ }
+ }
+
+ /**
+ * Private Function (added 23 Feb 17)
+ * Retrieves current DNS records from an external API source.
+ *
+ * Some services cannot perform new operations without the caller
+ * providing existing record information.
+ */
+ function _lookup_current() {
+ $lookup_allowed = false;
+ if ($this->_dnsVerboseLog) {
+ log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _listCurrent() starting.'), $this->_dnsService, $this->_FQDN));
+ }
+
+ if (strstr($this->_dnsRequestIf, "_vip")) {
+ $parentif = get_configured_vip_interface($this->_dnsRequestIf);
+ $realparentif = convert_friendly_interface_to_real_interface_name($parentif);
+ } else {
+ $realparentif = $this->_dnsRequestIf;
+ }
+
+ $ch = curl_init();
+
+ if ($this->_useIPv6 == false) {
+ curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+ }
+
+ curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
+ curl_setopt($ch, CURLOPT_INTERFACE, 'if!' . $realparentif);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 120); // Completely empirical
+
+ switch ($this->_dnsService) {
+ case 'dreamhost':
+ case 'dreamhost-v6':
+ $server = 'https://api.dreamhost.com/';
+ $post_data['key'] = $this->_dnsPass;
+ $post_data['unique_id'] = uniqid($this->_dnsHost);
+ $post_data['cmd'] = 'dns-list_records';
+ $post_data['format'] = 'json';
+ $port = "";
+ if ($this->_dnsServer) {
+ $server = $this->_dnsServer;
+ }
+ if ($this->_dnsPort) {
+ $port = ":" . $this->_dnsPort;
+ }
+ curl_setopt($ch, CURLOPT_URL, $server . $port);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
+ $lookup_allowed = true;
+ break;
+ default:
+ break;
+ }
+ if ($lookup_allowed) {
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $data = substr($response, $header_size);
+ $this->_checkLookupStatus($ch, $data, $header);
+ @curl_close($ch);
+ }
+ }
+
+ /*
+ * Private Function (added 23 Feb 17)
+ * Retrieve Lookup Status from the provided data and/or header
+ */
+ function _checkLookupStatus($ch, $data, $header) {
+ if ($this->_dnsVerboseLog) {
+ log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkLookupStatus() starting.'), $this->_dnsService, $this->_FQDN));
+ }
+ $success_str = "(" . gettext("Success") . ") ";
+ $error_str = "(" . gettext("Error") . ") ";
+ $status_intro = "phpDynDNS ({$this->_dnsHost}): ";
+
+ if ($this->_dnsService != 'ods' && @curl_error($ch)) {
+ $status = gettext("Curl error occurred:") . " " . curl_error($ch);
+ log_error($status);
+ $this->status = $status;
+ return;
+ }
+ switch ($this->_dnsService) {
+ case 'dreamhost':
+ case 'dreamhost-v6':
+ $result = json_decode($data,true);
+ if($result["result"] != "success") {
+ log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
+ $this->_debug($data);
+ return;
+ } else {
+ foreach($result["data"] as $key => $row) {
+ if($row["record"] == $this->_dnsHost &&
+ (($row["type"] == "A" && !$this->_useIPv6)
+ || ($row["type"] == "AAAA" && $this->_useIPv6)
+ )) {
+ if($row["editable"] == 0) {
+ log_error($status_intro . "host " . $this->_dnsHost . " is not editable.");
+ continue;
+ }
+ $this->_existingRecords[]=array("record"=>$row["type"], "type"=>$row["type"], "existing_val"=>$row["value"]);
+ }
+ }
+ }
+ if (!is_array($this->_existingRecords)){
+ if ($this->_dnsVerboseLog) {
+ log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkLookupStatus() ending. No matching records found.'), $this->_dnsService, $this->_FQDN));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
/*
* Private Function (added 12 July 2005) [beta]
@@ -1543,6 +1767,72 @@
$this->_debug($data);
}
break;
+ case 'dreamhost':
+ case 'dreamhost-v6':
+ $result = json_decode($data,true);
+ if ($this->_dnsVerboseLog) {
+ log_error(sprintf(gettext('_checkStatus() results: %1$s'), $data));
+ }
+ switch ($result['data']) {
+ case 'success':
+ case 'record_added':
+ case 'record_removed':
+ $status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
+ $successful_update = true;
+ break;
+ case 'no_record':
+ case 'no_such_record ':
+ $status = $status_intro . $error_str . gettext("No record exists.");
+ break;
+ case 'no_type':
+ case 'no_such_type ':
+ $status = $status_intro . $error_str . gettext("No type exists.");
+ break;
+ case 'no_value':
+ case 'no_such_value ':
+ $status = $status_intro . $error_str . gettext("No value exists.");
+ break;
+ case 'no_such_zone':
+ $status = $status_intro . $error_str . gettext("No such zone exists.");
+ break;
+ case 'invalid_record':
+ $status = $status_intro . $error_str . gettext("The specified record is invalid.");
+ break;
+ case 'invalid_type':
+ $status = $status_intro . $error_str . gettext("The specified type is invalid.");
+ break;
+ case 'invalid_value':
+ $status = $status_intro . $error_str . gettext("The specified value is invalid.");
+ break;
+ case 'not_editable ':
+ $status = $status_intro . $error_str . gettext("Record is not editable.");
+ break;
+ case 'record_already_exists_not_editable':
+ $status = $status_intro . $error_str . gettext("Record exists but is not editable.");
+ break;
+ case 'record_already_exists_remove_first':
+ $status = $status_intro . $error_str . gettext("Record exists and must be removed before adding.");
+ break;
+ case 'internal_error_updating_zone':
+ $status = $status_intro . $error_str . gettext("A remote server error occurred updating the zone.");
+ break;
+ case 'internal_error_could_not_load_zone':
+ $status = $status_intro . $error_str . gettext("A remote server error occurred loading the zone.");
+ break;
+ case 'internal_error_could_not_update_zone':
+ $status = $status_intro . $error_str . gettext("A remote server error occurred updating the zone.");
+ break;
+ case 'internal_error_could_not_add_record':
+ $status = $status_intro . $error_str . gettext("A remote server error occurred adding a new record.");
+ break;
+ case 'internal_error_could_not_destroy_record ':
+ $status = $status_intro . $error_str . gettext("A remote server error occurred removing an existing record.");
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
}
if ($successful_update == true) {
diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc
index 392ad7b..f7aadd8 100644
--- a/src/etc/inc/services.inc
+++ b/src/etc/inc/services.inc
@@ -23,8 +23,8 @@
* limitations under the License.
*/
-define('DYNDNS_PROVIDER_VALUES', 'all-inkl citynetwork cloudflare cloudflare-v6 custom custom-v6 dnsexit dnsimple dnsmadeeasy dnsomatic duiadns duiadns-v6 dyndns dyndns-custom dyndns-static dyns easydns eurodns freedns freedns-v6 glesys googledomains gratisdns he-net he-net-v6 he-net-tunnelbroker hover loopia namecheap noip noip-free ods opendns ovh-dynhost route53 selfhost spdyn spdyn-v6 zoneedit');
-define('DYNDNS_PROVIDER_DESCRIPTIONS', 'All-Inkl.com,City Network,CloudFlare,CloudFlare (v6),Custom,Custom (v6),DNSexit,DNSimple,DNS Made Easy,DNS-O-Matic,DuiaDns.net,DuiaDns.net (v6),DynDNS (dynamic),DynDNS (custom),DynDNS (static),DyNS,easyDNS,Euro Dns,freeDNS,freeDNS (v6),GleSYS,Google Domains,GratisDNS,HE.net,HE.net (v6),HE.net Tunnelbroker,Hover,Loopia,Namecheap,No-IP,No-IP (free),ODS.org,OpenDNS,OVH DynHOST,Route 53,SelfHost,SPDYN,SPDYN (v6),ZoneEdit');
+define('DYNDNS_PROVIDER_VALUES', 'all-inkl citynetwork cloudflare cloudflare-v6 custom custom-v6 dnsexit dnsimple dnsmadeeasy dnsomatic dreamhost dreamhost-v6 duiadns duiadns-v6 dyndns dyndns-custom dyndns-static dyns easydns eurodns freedns freedns-v6 glesys googledomains gratisdns he-net he-net-v6 he-net-tunnelbroker hover loopia namecheap noip noip-free ods opendns ovh-dynhost route53 selfhost spdyn spdyn-v6 zoneedit');
+define('DYNDNS_PROVIDER_DESCRIPTIONS', 'All-Inkl.com,City Network,CloudFlare,CloudFlare (v6),Custom,Custom (v6),DNSexit,DNSimple,DNS Made Easy,DNS-O-Matic,DreamHost,Dreamhost (v6),DuiaDns.net,DuiaDns.net (v6),DynDNS (dynamic),DynDNS (custom),DynDNS (static),DyNS,easyDNS,Euro Dns,freeDNS,freeDNS (v6),GleSYS,Google Domains,GratisDNS,HE.net,HE.net (v6),HE.net Tunnelbroker,Hover,Loopia,Namecheap,No-IP,No-IP (free),ODS.org,OpenDNS,OVH DynHOST,Route 53,SelfHost,SPDYN,SPDYN (v6),ZoneEdit');
/* implement ipv6 route advertising daemon */
function services_radvd_configure($blacklist = array()) {
diff --git a/src/usr/local/www/services_dyndns_edit.php b/src/usr/local/www/services_dyndns_edit.php
index 173b3bb..99ec141 100644
--- a/src/usr/local/www/services_dyndns_edit.php
+++ b/src/usr/local/www/services_dyndns_edit.php
@@ -121,7 +121,7 @@ if ($_POST['save'] || $_POST['force']) {
$last_to_check = strrpos($host_to_check, '@');
if ($last_to_check !== false) {
$host_to_check = substr_replace(
- $host_to_check, '.', $last_to_check, 1);
+ $host_to_check, '.', $last_to_check, 1);
}
unset($last_to_check);
}
@@ -354,9 +354,10 @@ $section->addInput(new Form_Input(
'text',
$pconfig['username']
))->setHelp('Username is required for all types except Namecheap, FreeDNS and Custom Entries.%1$s' .
- 'DNS Made Easy: Dynamic DNS ID%1$s' .
+ 'DNS Made Easy: Dynamic DNS ID%1$s' .
'Route 53: Enter the Access Key ID.%1$s' .
'GleSYS: Enter the API user.%1$s' .
+ 'Dreamhost: Enter a value to appear in the DNS record comment.%1$s' .
'For Custom Entries, Username and Password represent HTTP Authentication username and passwords.', '<br />');
$section->addPassword(new Form_Input(
@@ -365,9 +366,10 @@ $section->addPassword(new Form_Input(
'password',
$pconfig['password']
))->setHelp('FreeDNS (freedns.afraid.org): Enter the "Authentication Token" provided by FreeDNS.%1$s' .
- 'DNS Made Easy: Dynamic DNS Password%1$s' .
+ 'DNS Made Easy: Dynamic DNS Password%1$s' .
'Route 53: Enter the Secret Access Key.%1$s' .
'GleSYS: Enter the API key.%1$s' .
+ 'Dreamhost: Enter the API Key.%1$s' .
'DNSimple: Enter the API token.', '<br />');
$section->addInput(new Form_Input(
@@ -486,6 +488,21 @@ events.push(function() {
hideInput('zoneid', true);
hideInput('ttl', true);
break;
+ case 'dreamhost':
+ case 'dreamhost-v6':
+ hideGroupInput('domainname', true);
+ hideInput('resultmatch', true);
+ hideInput('updateurl', true);
+ hideInput('requestif', true);
+ hideCheckbox('curl_ipresolve_v4', true);
+ hideCheckbox('curl_ssl_verifypeer', true);
+ hideInput('host', false);
+ hideInput('mx', true);
+ hideCheckbox('wildcard', true);
+ hideCheckbox('proxied', true);
+ hideInput('zoneid', true);
+ hideInput('ttl', true);
+ break;
case "cloudflare-v6":
case "cloudflare":
hideGroupInput('domainname', true);
OpenPOWER on IntegriCloud