Project

General

Profile

Download (100 KB) Statistics
| Branch: | Tag: | Revision:
1 d237be68 Scott Ullrich
<?php
2 ac24dc24 Renato Botelho
/*
3
 * dyndns.class
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6 38809d47 Renato Botelho do Couto
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2019 Rubicon Communications, LLC (Netgate)
9 ac24dc24 Renato Botelho
 * All rights reserved.
10
 *
11 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
12
 * you may not use this file except in compliance with the License.
13
 * You may obtain a copy of the License at
14 ac24dc24 Renato Botelho
 *
15 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
16 ac24dc24 Renato Botelho
 *
17 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
18
 * distributed under the License is distributed on an "AS IS" BASIS,
19
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
 * See the License for the specific language governing permissions and
21
 * limitations under the License.
22 ac24dc24 Renato Botelho
 */
23
24 1fa2f630 Erik Kristensen
	/*
25
	 * PHP.updateDNS (pfSense version)
26
	 *
27
	 * +====================================================+
28
	 *  Services Supported:
29 9b8dc821 Scott Ullrich
	 *    - DynDns (dyndns.org) [dynamic, static, custom]
30 1fa2f630 Erik Kristensen
	 *    - No-IP (no-ip.com)
31
	 *    - EasyDNS (easydns.com)
32
	 *    - DHS (www.dhs.org)
33 9b8dc821 Scott Ullrich
	 *    - HN (hn.org) -- incomplete checking!
34 1fa2f630 Erik Kristensen
	 *    - DynS (dyns.org)
35
	 *    - ZoneEdit (zoneedit.com)
36 9b8dc821 Scott Ullrich
	 *    - FreeDNS (freedns.afraid.org)
37 ac16181a TechSmurf
	 *    - FreeDNS IPv6 (freedns.afraid.org)
38 9b8dc821 Scott Ullrich
	 *    - Loopia (loopia.se)
39
	 *    - StaticCling (staticcling.org)
40 0a1b0183 Ermal Luçi
	 *    - DNSexit (dnsexit.com)
41 2d78b166 Ermal Luçi
	 *    - OpenDNS (opendns.com)
42 61c30081 jim-p
	 *    - Namecheap (namecheap.com)
43 8ea77433 Chris Wells
	 *    - HE.net (dns.he.net)
44 da40615d Daniel Becker
	 *    - HE.net IPv6 (dns.he.net)
45 38a481ad jim-p
	 *    - HE.net Tunnelbroker IP update (ipv4.tunnelbroker.net)
46 fb403496 Gerald Raaf
	 *    - SelfHost (selfhost.de)
47 37f3e704 Matt Corallo
	 *    - Amazon Route 53 (aws.amazon.com)
48
	 *    - DNS-O-Matic (dnsomatic.com)
49
	 *    - Custom DDNS (any URL)
50 da40615d Daniel Becker
	 *    - Custom DDNS IPv6 (any URL)
51 c5e1ce90 robjarsen
	 *    - Cloudflare (www.cloudflare.com)
52
	 *    - Cloudflare IPv6 (www.cloudflare.com)
53 1e0b1727 Phil Davis
	 *    - Eurodns (eurodns.com)
54 edfe22f8 Eric Vantillard
	 *    - Gandi LiveDNS (www.gandi.net)
55 1e0b1727 Phil Davis
	 *    - GratisDNS (gratisdns.dk)
56 a0b470ee Chris Buechler
	 *    - City Network (citynetwork.se)
57 e0a4147b surrural
	 *    - GleSYS (glesys.com)
58 916d683e surrural
	 *    - DNSimple (dnsimple.com)
59 6c92b378 Christopher Fazendin
	 *    - Google Domains (domains.google.com)
60 c5ecdc25 Jose Luis Duran
	 *    - DNS Made Easy (www.dnsmadeeasy.com)
61 1c2c08bd exii1988
	 *    - SPDYN (spdyn.de)
62
	 *    - SPDYN IPv6 (spdyn.de)
63 575b1dcf Christoph Filnkößl
	 *    - All-Inkl (all-inkl.com)
64 19b7263e Ionut
	 *    - DuiaDNS (www.duiadns.net)
65
	 *    - DuiaDNS IPv6 (www.duiadns.net)
66 74533d41 xygrec
	 *    - Hover (www.hover.com)
67 9a3ec9a5 frank
	 *    - DreamHost DNS (www.dreamhost.com)
68 745d3779 Wagner Sartori Junior
	 *    - ClouDNS (www.cloudns.net)
69 456ba14f Sam Neely
	 *    - GoDaddy (www.godaddy.com)
70 1ac3c88a martgras
	 *    - Azure DNS (azure.microsoft.com)
71 1fa2f630 Erik Kristensen
	 * +----------------------------------------------------+
72
	 *  Requirements:
73 37f3e704 Matt Corallo
	 *    - PHP version 4.0.2 or higher with the CURL Library and the PCRE Library
74 1fa2f630 Erik Kristensen
	 * +----------------------------------------------------+
75
	 *  Public Functions
76
	 *    - updatedns()
77
	 *
78
	 *  Private Functions
79
	 *    - _update()
80
	 *    - _checkStatus()
81
	 *    - _error()
82
	 *    - _detectChange()
83
	 *    - _debug()
84 22de7804 Bill Marquette
	 *    - _checkIP()
85 1fa2f630 Erik Kristensen
	 * +----------------------------------------------------+
86 01c155f2 Phil Davis
	 *  DynDNS Dynamic  - Last Tested: 12 July 2005
87
	 *  DynDNS Static   - Last Tested: NEVER
88
	 *  DynDNS Custom   - Last Tested: NEVER
89
	 *  No-IP           - Last Tested: 20 July 2008
90
	 *  HN.org          - Last Tested: 12 July 2005
91
	 *  EasyDNS         - Last Tested: 20 July 2008
92
	 *  DHS             - Last Tested: 12 July 2005
93
	 *  ZoneEdit        - Last Tested: NEVER
94
	 *  Dyns            - Last Tested: NEVER
95
	 *  ODS             - Last Tested: 02 August 2005
96 ac16181a TechSmurf
	 *  FreeDNS         - Last Tested: 01 May 2016
97
	 *  FreeDNS IPv6    - Last Tested: 01 May 2016
98 cedc8184 kristoffer-ekenstam
	 *  Loopia          - Last Tested: 21 August 2019
99 01c155f2 Phil Davis
	 *  StaticCling     - Last Tested: 27 April 2006
100
	 *  DNSexit         - Last Tested: 20 July 2008
101
	 *  OpenDNS         - Last Tested: 4 August 2008
102
	 *  Namecheap       - Last Tested: 31 August 2010
103
	 *  HE.net          - Last Tested: 7 July 2013
104
	 *  HE.net IPv6     - Last Tested: 7 July 2013
105
	 *  HE.net Tunnel   - Last Tested: 28 June 2011
106 8d8405ba Jason McCormick
	 *  SelfHost        - Last Tested: 26 December 2011
107 ac5ee07e Jason D. McCormick
	 *  Amazon Route 53 - Last Tested: 04 February 2017
108 1e0b1727 Phil Davis
	 *  DNS-O-Matic     - Last Tested: 9 September 2010
109 07a84ece robjarsen
	 *  Cloudflare      - Last Tested: 05 September 2016
110
	 *  Cloudflare IPv6 - Last Tested: 17 July 2016
111 1e0b1727 Phil Davis
	 *  Eurodns         - Last Tested: 27 June 2013
112
	 *  GratisDNS       - Last Tested: 15 August 2012
113
	 *  OVH DynHOST     - Last Tested: NEVER
114
	 *  City Network    - Last Tested: 13 November 2013
115
	 *  GleSYS          - Last Tested: 3 February 2015
116
	 *  DNSimple        - Last Tested: 09 February 2015
117 6c92b378 Christopher Fazendin
	 *  Google Domains  - Last Tested: 27 April 2015
118 c5ecdc25 Jose Luis Duran
	 *  DNS Made Easy   - Last Tested: 27 April 2015
119 1c2c08bd exii1988
	 *  SPDYN           - Last Tested: 02 July 2016
120
	 *  SPDYN IPv6      - Last Tested: 02 July 2016
121 575b1dcf Christoph Filnkößl
	 *  All-Inkl        - Last Tested: 12 November 2016
122 19b7263e Ionut
	 *  DuiaDNS         - Last Tested: 25 November 2016
123
	 *  DuiaDNS IPv6    - Last Tested: 25 November 2016
124 74533d41 xygrec
	 *  Hover           - Last Tested: 15 February 2017
125 9d26673d frank
	 *  DreamHost       - Last Tested: 30 April 2017
126
	 *  DreamHost IPv6  - Not Yet Tested
127 745d3779 Wagner Sartori Junior
	 *  ClouDNS         - Last Tested: 22 August 2017
128 456ba14f Sam Neely
	 *  GoDaddy         - Last Tested: 22 November 2017
129
	 *  GoDaddy IPv6    - Last Tested: 22 November 2017
130 544674ad Grant Sheehan
	 *  DigitalOcean    - Not Yet Tested
131 1ac3c88a martgras
	 *  Azure DNS       - Last Tested: 08 March 2018
132 edfe22f8 Eric Vantillard
	 *  Gandi LiveDNS   - Not Yet Tested
133 1fa2f630 Erik Kristensen
	 * +====================================================+
134
	 *
135 e24b26e9 Scott Ullrich
	 * @author 	E.Kristensen
136 1fa2f630 Erik Kristensen
	 * @link    	http://www.idylldesigns.com/projects/phpdns/
137 0da417be Erik Kristensen
	 * @version 	0.8
138 e24b26e9 Scott Ullrich
	 * @updated	13 October 05 at 21:02:42 GMT
139 1fa2f630 Erik Kristensen
	 *
140 d98a2e6a Jose Luis Duran
	 * DNSexit/OpenDNS support and multiwan extension for pfSense by Ermal Luçi
141 37f3e704 Matt Corallo
	 * Custom DNS support by Matt Corallo
142 0a1b0183 Ermal Luçi
	 *
143 1fa2f630 Erik Kristensen
	 */
144
145
	class updatedns {
146 67ee1ec5 Ermal Luçi
		var $_cacheFile;
147 d7e6f573 Daniel Becker
		var $_cacheFile_v6;
148 67ee1ec5 Ermal Luçi
		var $_debugFile;
149 ce9a9572 Philip Soeberg
		var $_UserAgent = 'phpDynDNS/0.7';
150 1fa2f630 Erik Kristensen
		var $_errorVerbosity = 0;
151
		var $_dnsService;
152
		var $_dnsUser;
153
		var $_dnsPass;
154
		var $_dnsHost;
155 6635aa0f jim-p
		var $_dnsDomain;
156
		var $_FQDN;
157 1fa2f630 Erik Kristensen
		var $_dnsIP;
158
		var $_dnsWildcard;
159 e10d25b4 CarlGill
		var $_dnsProxied;
160 1fa2f630 Erik Kristensen
		var $_dnsMX;
161
		var $_dnsBackMX;
162 9b8dc821 Scott Ullrich
		var $_dnsServer;
163
		var $_dnsPort;
164
		var $_dnsUpdateURL;
165 cd132e86 Edson Brandi
		var $_dnsZoneID;
166
		var $_dnsTTL;
167 1fa2f630 Erik Kristensen
		var $status;
168
		var $_debugID;
169 67ee1ec5 Ermal Luçi
		var $_if;
170 37f3e704 Matt Corallo
		var $_dnsResultMatch;
171
		var $_dnsRequestIf;
172
		var $_dnsRequestIfIP;
173 87b91672 Phil Davis
		var $_dnsVerboseLog;
174 aa79f351 Sebastian Chrostek
		var $_curlIpresolveV4;
175
		var $_curlSslVerifypeer;
176 f5e293e6 Phil Davis
		var $_dnsMaxCacheAgeDays;
177 0333f968 Phil Davis
		var $_dnsDummyUpdateDone;
178
		var $_forceUpdateNeeded;
179 b4025ccd Daniel Becker
		var $_useIPv6;
180 9a3ec9a5 frank
		var $_existingRecords;
181 1e0b1727 Phil Davis
182
		/*
183 1fa2f630 Erik Kristensen
		 * Public Constructor Function (added 12 July 05) [beta]
184 1e0b1727 Phil Davis
		 *   - Gets the dice rolling for the update.
185 37f3e704 Matt Corallo
		 *   - $dnsResultMatch should only be used with $dnsService = 'custom'
186 1e0b1727 Phil Davis
		 *   -  $dnsResultMatch is parsed for '%IP%', which is the IP the provider was updated to,
187 1bf52c67 Phil Davis
		 *   -  it is otherwise expected to be exactly identical to what is returned by the Provider.
188 37f3e704 Matt Corallo
		 *   - $dnsUser, and $dnsPass indicate HTTP Auth for custom DNS, if they are needed in the URL (GET Variables), include them in $dnsUpdateURL.
189
		 *   - $For custom requests, $dnsUpdateURL is parsed for '%IP%', which is replaced with the new IP.
190 1fa2f630 Erik Kristensen
		 */
191 d43154fe Renato Botelho do Couto
		function __construct($dnsService = '', $dnsHost = '', $dnsDomain = '', $dnsUser = '', $dnsPass = '',
192 e10d25b4 CarlGill
					$dnsWildcard = 'OFF', $dnsProxied = false, $dnsMX = '', $dnsIf = '', $dnsBackMX = '',
193 1e0b1727 Phil Davis
					$dnsServer = '', $dnsPort = '', $dnsUpdateURL = '', $forceUpdate = false,
194
					$dnsZoneID ='', $dnsTTL='', $dnsResultMatch = '', $dnsRequestIf = '',
195
					$dnsID = '', $dnsVerboseLog = false, $curlIpresolveV4 = false, $curlSslVerifypeer = true) {
196
197 2446fffa jim-p
			global $config, $g, $dyndns_split_domain_types;
198
			if (in_array($dnsService, $dyndns_split_domain_types)) {
199 6635aa0f jim-p
				$this->_FQDN = $dnsHost . "." . $dnsDomain;
200
			} else {
201
				$this->_FQDN = $dnsHost;
202
			}
203
204
			$this->_cacheFile = "{$g['conf_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($this->_FQDN) . "{$dnsID}.cache";
205
			$this->_cacheFile_v6 = "{$g['conf_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($this->_FQDN) . "{$dnsID}_v6.cache";
206
			$this->_debugFile = "{$g['varetc_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($this->_FQDN) . "{$dnsID}.debug";
207 67ee1ec5 Ermal Luçi
208 aa79f351 Sebastian Chrostek
			$this->_curlIpresolveV4 = $curlIpresolveV4;
209
			$this->_curlSslVerifypeer = $curlSslVerifypeer;
210 87b91672 Phil Davis
			$this->_dnsVerboseLog = $dnsVerboseLog;
211 1e0b1727 Phil Davis
			if ($this->_dnsVerboseLog) {
212 9557ca30 Phil Davis
				log_error(gettext("Dynamic DNS: updatedns() starting"));
213 1e0b1727 Phil Davis
			}
214 71070cc5 Ermal
215 37f3e704 Matt Corallo
			$dyndnslck = lock("DDNS".$dnsID, LOCK_EX);
216 71070cc5 Ermal
217 1fa2f630 Erik Kristensen
			if (!$dnsService) $this->_error(2);
218 ce6d1106 jim-p
			switch ($dnsService) {
219
			case 'freedns':
220 ac16181a TechSmurf
			case 'freedns-v6':
221 ce6d1106 jim-p
				if (!$dnsHost) $this->_error(5);
222
				break;
223 2446fffa jim-p
			case "namecheap":
224
				if (!$dnsPass) $this->_error(4);
225
				if (!$dnsHost) $this->_error(5);
226
				if (!$dnsDomain) $this->_error(5);
227
				break;
228
			case "cloudflare-v6":
229
			case "cloudflare":
230
			case "gratisdns":
231 74533d41 xygrec
			case "hover":
232 2446fffa jim-p
				if (!$dnsUser) $this->_error(3);
233 9b8dc821 Scott Ullrich
				if (!$dnsPass) $this->_error(4);
234
				if (!$dnsHost) $this->_error(5);
235 6635aa0f jim-p
				if (!$dnsDomain) $this->_error(5);
236 ce6d1106 jim-p
				break;
237 44c64da1 Matthew Fine
			case 'route53-v6':
238 37f3e704 Matt Corallo
			case 'route53':
239
				if (!$dnsZoneID) $this->_error(8);
240
				if (!$dnsTTL) $this->_error(9);
241
				break;
242 745d3779 Wagner Sartori Junior
			case 'cloudns':
243 456ba14f Sam Neely
			case "godaddy":
244
			case "godaddy-v6":
245 745d3779 Wagner Sartori Junior
				if (!$dnsUser) $this->_error(3);
246
				if (!$dnsPass) $this->_error(4);
247
				if (!$dnsHost) $this->_error(5);
248
				if (!$dnsDomain) $this->_error(5);
249
				if (!$dnsTTL) $this->_error(9);
250
				break;
251 544674ad Grant Sheehan
			case 'digitalocean':
252 0c43f825 Matthew Fine
			case 'digitalocean-v6':
253 b923a825 Tom Embt
			case 'linode':
254
			case 'linode-v6':
255 544674ad Grant Sheehan
				if (!$dnsPass) $this->_error(4);
256
				if (!$dnsHost) $this->_error(5);
257
				if (!$dnsDomain) $this->_error(5);
258 32cb54c3 Grant Sheehan
				if (!$dnsTTL) $this->_error(9);
259
				break;
260 bf905930 Steve Beaver
			case 'azure':
261
			case 'azurev6':
262 1ac3c88a martgras
				if (!$dnsUser) $this->_error(3);
263
				if (!$dnsPass) $this->_error(4);
264
				if (!$dnsHost) $this->_error(5);
265
				if (!$dnsZoneID) $this->_error(8);
266
				if (!$dnsTTL) $this->_error(9);
267 544674ad Grant Sheehan
				break;
268 edfe22f8 Eric Vantillard
			case 'gandi-livedns': // NOTE: same as digitalocean
269
				if (!$dnsPass) $this->_error(4);//API key
270
				if (!$dnsHost) $this->_error(5); //DNS Record to update
271
				if (!$dnsDomain) $this->_error(5);//domain
272
				if (!$dnsTTL) $this->_error(9);//ttl
273
				break;
274 37f3e704 Matt Corallo
			case 'custom':
275 45ff6b8f jim-p
			case 'custom-v6':
276 37f3e704 Matt Corallo
				if (!$dnsUpdateURL) $this->_error(7);
277
				break;
278 ce6d1106 jim-p
			default:
279
				if (!$dnsUser) $this->_error(3);
280
				if (!$dnsPass) $this->_error(4);
281 99295d7b Scott Ullrich
				if (!$dnsHost) $this->_error(5);
282 9b8dc821 Scott Ullrich
			}
283 1e0b1727 Phil Davis
284 b4025ccd Daniel Becker
			switch ($dnsService) {
285 1e0b1727 Phil Davis
				case 'he-net-v6':
286 0c43f825 Matthew Fine
				case 'digitalocean-v6':
287 1e0b1727 Phil Davis
				case 'custom-v6':
288 1c2c08bd exii1988
				case 'spdyn-v6':
289 44c64da1 Matthew Fine
				case 'route53-v6':
290 19b7263e Ionut
				case 'duiadns-v6':
291 ac16181a TechSmurf
				case 'freedns-v6':
292 3a05e4c3 Austin Seipp
				case 'cloudflare-v6':
293 9a3ec9a5 frank
				case 'dreamhost-v6':
294 456ba14f Sam Neely
				case 'godaddy-v6':
295 1ac3c88a martgras
				case 'azurev6':
296 b923a825 Tom Embt
				case 'linode-v6':
297 1e0b1727 Phil Davis
					$this->_useIPv6 = true;
298
					break;
299
				default:
300
					$this->_useIPv6 = false;
301 b4025ccd Daniel Becker
			}
302 1fa2f630 Erik Kristensen
			$this->_dnsService = strtolower($dnsService);
303
			$this->_dnsUser = $dnsUser;
304 86584ded jim-p
			$this->_dnsPass = base64_decode($dnsPass);
305 1fa2f630 Erik Kristensen
			$this->_dnsHost = $dnsHost;
306 6635aa0f jim-p
			$this->_dnsDomain = $dnsDomain;
307 9b8dc821 Scott Ullrich
			$this->_dnsServer = $dnsServer;
308
			$this->_dnsPort = $dnsPort;
309
			$this->_dnsWildcard = $dnsWildcard;
310 e10d25b4 CarlGill
			$this->_dnsProxied = $dnsProxied;
311 9b8dc821 Scott Ullrich
			$this->_dnsMX = $dnsMX;
312 0c7bb880 Phil Davis
			$this->_dnsZoneID = $dnsZoneID;
313
			$this->_dnsTTL = $dnsTTL;
314 bf001dec smos
			$this->_if = get_failover_interface($dnsIf);
315 fffbfef0 Matt Corallo
			$this->_checkIP();
316 37f3e704 Matt Corallo
			$this->_dnsUpdateURL = $dnsUpdateURL;
317
			$this->_dnsResultMatch = $dnsResultMatch;
318 bf001dec smos
			$this->_dnsRequestIf = get_failover_interface($dnsRequestIf);
319 1e0b1727 Phil Davis
			if ($this->_dnsVerboseLog) {
320 9557ca30 Phil Davis
				log_error(sprintf(gettext('Dynamic DNS (%1$s): running get_failover_interface for %2$s. found %3$s'), $this->_FQDN, $dnsRequestIf, $this->_dnsRequestIf));
321 1e0b1727 Phil Davis
			}
322 37f3e704 Matt Corallo
			$this->_dnsRequestIfIP = get_interface_ip($dnsRequestIf);
323 f5e293e6 Phil Davis
			$this->_dnsMaxCacheAgeDays = 25;
324 0333f968 Phil Davis
			$this->_dnsDummyUpdateDone = false;
325
			$this->_forceUpdateNeeded = $forceUpdate;
326 1e0b1727 Phil Davis
327 0c7bb880 Phil Davis
			// Ensure that we were able to lookup the IP
328 1e0b1727 Phil Davis
			if (!is_ipaddr($this->_dnsIP)) {
329 140a87c5 Chris Buechler
				log_error(sprintf(gettext('Dynamic DNS (%1$s) There was an error trying to determine the public IP for interface - %2$s (%3$s %4$s).'), $this->_FQDN, $dnsIf, $this->_if, $this->_dnsIP));
330 fffbfef0 Matt Corallo
				unlock($dyndnslck);
331
				return;
332
			}
333 07a3b40b sullrich
334 1fa2f630 Erik Kristensen
			$this->_debugID = rand(1000000, 9999999);
335 1e0b1727 Phil Davis
336 d7e6f573 Daniel Becker
			if ($forceUpdate == false && $this->_detectChange() == false) {
337 1fa2f630 Erik Kristensen
				$this->_error(10);
338
			} else {
339 9d96a475 Ermal Lu?i
				switch ($this->_dnsService) {
340 1e0b1727 Phil Davis
					case 'glesys':
341
					case 'dnsomatic':
342
					case 'dyndns':
343
					case 'dyndns-static':
344
					case 'dyndns-custom':
345
					case 'dhs':
346
					case 'noip':
347
					case 'noip-free':
348
					case 'easydns':
349
					case 'hn':
350
					case 'zoneedit':
351
					case 'dyns':
352
					case 'ods':
353
					case 'freedns':
354 ac16181a TechSmurf
					case 'freedns-v6':
355 1e0b1727 Phil Davis
					case 'loopia':
356
					case 'staticcling':
357
					case 'dnsexit':
358
					case 'custom':
359
					case 'custom-v6':
360
					case 'opendns':
361
					case 'namecheap':
362
					case 'he-net':
363
					case 'he-net-v6':
364 19b7263e Ionut
					case 'duiadns':
365
					case 'duiadns-v6':
366 1e0b1727 Phil Davis
					case 'selfhost':
367
					case 'he-net-tunnelbroker':
368
					case 'route53':
369 44c64da1 Matthew Fine
					case 'route53-v6':
370 1e0b1727 Phil Davis
					case 'cloudflare':
371 3a05e4c3 Austin Seipp
					case 'cloudflare-v6':
372 1e0b1727 Phil Davis
					case 'eurodns':
373
					case 'gratisdns':
374
					case 'ovh-dynhost':
375
					case 'citynetwork':
376
					case 'dnsimple':
377 c5ecdc25 Jose Luis Duran
					case 'googledomains':
378
					case 'dnsmadeeasy':
379 1c2c08bd exii1988
					case 'spdyn':
380
					case 'spdyn-v6':
381 575b1dcf Christoph Filnkößl
					case 'all-inkl':
382 745d3779 Wagner Sartori Junior
					case 'cloudns':
383 74533d41 xygrec
					case 'hover':
384 544674ad Grant Sheehan
					case 'digitalocean':
385 0c43f825 Matthew Fine
					case 'digitalocean-v6':
386 456ba14f Sam Neely
					case 'godaddy':
387
					case 'godaddy-v6':
388 ed5b58a7 Tom Embt
					case 'azure':
389
					case 'azurev6':
390 b923a825 Tom Embt
					case 'linode':
391
					case 'linode-v6':
392 edfe22f8 Eric Vantillard
					case 'gandi-livedns':
393 0333f968 Phil Davis
						$this->_update();
394 1e0b1727 Phil Davis
						if ($this->_dnsDummyUpdateDone == true) {
395
							// If a dummy update was needed, then sleep a while and do the update again to put the proper address back.
396
							// Some providers (e.g. No-IP free accounts) need to have at least 1 address change every month.
397
							// If the address has not changed recently, or the user did "Force Update", then the code does
398
							// a dummy address change for providers like this.
399
							sleep(10);
400
							$this->_update();
401
						}
402
						break;
403 9a3ec9a5 frank
					case 'dreamhost':
404
					case 'dreamhost-v6':
405
						$this->_lookup_current();
406
						if (isset($this->status)) {
407
							return;
408
						}
409
						foreach ($this->_existingRecords as $record) {
410
							$this->_remove($record['existing_val']);
411
							$this->_update();
412
						}
413
						break;
414 1e0b1727 Phil Davis
					default:
415
						$this->_error(6);
416
						break;
417 1fa2f630 Erik Kristensen
				}
418 9d96a475 Ermal Lu?i
			}
419 71070cc5 Ermal
420
			unlock($dyndnslck);
421 1fa2f630 Erik Kristensen
		}
422 1e0b1727 Phil Davis
423 1fa2f630 Erik Kristensen
		/*
424
		 * Private Function (added 12 July 05) [beta]
425
		 *   Send Update To Selected Service.
426
		 */
427
		function _update() {
428 1e0b1727 Phil Davis
429
			if ($this->_dnsVerboseLog) {
430 9557ca30 Phil Davis
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _update() starting.'), $this->_dnsService, $this->_FQDN));
431 1e0b1727 Phil Davis
			}
432 b37b4034 Phil Davis
433 f1d3adf1 Chris Buechler
			if (strstr($this->_dnsRequestIf, "_vip")) {
434 ac5c0cfe Chris Buechler
				$parentif = get_configured_vip_interface($this->_dnsRequestIf);
435 f1d3adf1 Chris Buechler
				$realparentif = convert_friendly_interface_to_real_interface_name($parentif);
436
			} else {
437
				$realparentif = $this->_dnsRequestIf;
438
			}
439 1e0b1727 Phil Davis
440 0ec4b3b4 Chris Buechler
			$ch = curl_init();
441
442 becd6caa Chris Buechler
			if ($this->_useIPv6 == false) {
443 4e322e2c Phil Davis
				curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
444 becd6caa Chris Buechler
			}
445
446 15dcf132 PiBa-NL
			if ($this->_dnsService != 'ods') {
447 1fa2f630 Erik Kristensen
				curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
448
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
449 f1d3adf1 Chris Buechler
				curl_setopt($ch, CURLOPT_INTERFACE, 'if!' . $realparentif);
450 93b8df2a Ermal
				curl_setopt($ch, CURLOPT_TIMEOUT, 120); // Completely empirical
451 1fa2f630 Erik Kristensen
			}
452
453
			switch ($this->_dnsService) {
454 197cf433 McB
				case 'glesys':
455
					$needsIP = TRUE;
456
					$server = 'https://api.glesys.com/domain/updaterecord/format/json';
457
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
458 6635aa0f jim-p
					$post_data['recordid'] = $this->_FQDN;
459 197cf433 McB
					$post_data['data'] = $this->_dnsIP;
460
					curl_setopt($ch, CURLOPT_URL, $server);
461
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
462
					break;
463 1fa2f630 Erik Kristensen
				case 'dyndns':
464
				case 'dyndns-static':
465 52e95286 Ermal
				case 'dyndns-custom':
466 1fa2f630 Erik Kristensen
					$needsIP = FALSE;
467 1e0b1727 Phil Davis
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") {
468
						$this->_dnsWildcard = "ON";
469
					}
470 1fa2f630 Erik Kristensen
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
471 9b8dc821 Scott Ullrich
					$server = "https://members.dyndns.org/nic/update";
472
					$port = "";
473 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
474 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
475 1e0b1727 Phil Davis
					}
476
					if ($this->_dnsPort) {
477 9b8dc821 Scott Ullrich
						$port = ":" . $this->_dnsPort;
478 1e0b1727 Phil Davis
					}
479 52e95286 Ermal
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?system=dyndns&hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard='.$this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NO');
480 1fa2f630 Erik Kristensen
					break;
481
				case 'dhs':
482 34c9962b Chris Buechler
					// DHS is disabled in the GUI because the following doesn't work.
483 1fa2f630 Erik Kristensen
					$needsIP = TRUE;
484 a255e1f7 Scott Ullrich
					$post_data['hostscmd'] = 'edit';
485
					$post_data['hostscmdstage'] = '2';
486
					$post_data['type'] = '4';
487
					$post_data['updatetype'] = 'Online';
488
					$post_data['mx'] = $this->_dnsMX;
489
					$post_data['mx2'] = '';
490
					$post_data['txt'] = '';
491
					$post_data['offline_url'] = '';
492
					$post_data['cloak'] = 'Y';
493
					$post_data['cloak_title'] = '';
494
					$post_data['ip'] = $this->_dnsIP;
495
					$post_data['domain'] = 'dyn.dhs.org';
496
					$post_data['hostname'] = $this->_dnsHost;
497
					$post_data['submit'] = 'Update';
498 9b8dc821 Scott Ullrich
					$server = "https://members.dhs.org/nic/hosts";
499
					$port = "";
500 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
501 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
502 1e0b1727 Phil Davis
					}
503
					if ($this->_dnsPort) {
504
						$port = ":" . $this->_dnsPort;
505
					}
506 34c9962b Chris Buechler
					curl_setopt($ch, CURLOPT_URL, $server . $port);
507 1fa2f630 Erik Kristensen
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
508
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
509
					break;
510
				case 'noip':
511 0333f968 Phil Davis
				case 'noip-free':
512 1fa2f630 Erik Kristensen
					$needsIP = TRUE;
513 64746cf6 Chris Buechler
					$server = "https://dynupdate.no-ip.com/ducupdate.php";
514 9b8dc821 Scott Ullrich
					$port = "";
515 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
516 472da675 Phil Davis
						$server = $this->_dnsServer;
517 1e0b1727 Phil Davis
					}
518
					if ($this->_dnsPort) {
519 9b8dc821 Scott Ullrich
						$port = ":" . $this->_dnsPort;
520 1e0b1727 Phil Davis
					}
521
					if (($this->_dnsService == "noip-free") &&
522 ae52d165 Renato Botelho
					    ($this->_forceUpdateNeeded == true) &&
523
					    ($this->_dnsDummyUpdateDone == false)) {
524 0333f968 Phil Davis
						// Update the IP to a dummy value to force No-IP free accounts to see a change.
525
						$iptoset = "192.168.1.1";
526
						$this->_dnsDummyUpdateDone = true;
527 9557ca30 Phil Davis
						log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): Processing dummy update on No-IP free account. IP temporarily set to %3$s'), $this->_dnsService, $this->_dnsHost, $iptoset));
528 0333f968 Phil Davis
					} else {
529
						$iptoset = $this->_dnsIP;
530
					}
531 70a84c25 Tiago Barrionuevo
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?username=' . urlencode($this->_dnsUser) . '&pass=' . urlencode($this->_dnsPass) . '&h[]=' . $this->_dnsHost.'&ip=' . $iptoset);
532 1fa2f630 Erik Kristensen
					break;
533
				case 'easydns':
534
					$needsIP = TRUE;
535
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
536 64746cf6 Chris Buechler
					$server = "https://members.easydns.com/dyn/dyndns.php";
537 9b8dc821 Scott Ullrich
					$port = "";
538 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
539 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
540 1e0b1727 Phil Davis
					}
541
					if ($this->_dnsPort) {
542 9b8dc821 Scott Ullrich
						$port = ":" . $this->_dnsPort;
543 1e0b1727 Phil Davis
					}
544 cd8f5ccd Scott Ullrich
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard=' . $this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=' . $this->_dnsBackMX);
545 1fa2f630 Erik Kristensen
					break;
546
				case 'hn':
547
					$needsIP = TRUE;
548
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
549 9b8dc821 Scott Ullrich
					$server = "http://dup.hn.org/vanity/update";
550
					$port = "";
551 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
552 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
553 1e0b1727 Phil Davis
					}
554
					if ($this->_dnsPort) {
555 9b8dc821 Scott Ullrich
						$port = ":" . $this->_dnsPort;
556 1e0b1727 Phil Davis
					}
557 cd8f5ccd Scott Ullrich
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?ver=1&IP=' . $this->_dnsIP);
558 1fa2f630 Erik Kristensen
					break;
559
				case 'zoneedit':
560
					$needsIP = FALSE;
561 89a75ca9 Bill Marquette
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
562
563 9b8dc821 Scott Ullrich
					$server = "https://dynamic.zoneedit.com/auth/dynamic.html";
564
					$port = "";
565 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
566 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
567 1e0b1727 Phil Davis
					}
568
					if ($this->_dnsPort) {
569 9b8dc821 Scott Ullrich
						$port = ":" . $this->_dnsPort;
570 1e0b1727 Phil Davis
					}
571 176d24e1 Phil Davis
					curl_setopt($ch, CURLOPT_URL, "{$server}{$port}?host=" . $this->_dnsHost . '&dnsto=' . $this->_dnsIP);
572 1fa2f630 Erik Kristensen
					break;
573
				case 'dyns':
574
					$needsIP = FALSE;
575 ea46d833 Chris Buechler
					$server = "http://www.dyns.net/postscript011.php";
576 9b8dc821 Scott Ullrich
					$port = "";
577 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
578 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
579 1e0b1727 Phil Davis
					}
580
					if ($this->_dnsPort) {
581
						$port = ":" . $this->_dnsPort;
582
					}
583 fdcaa527 Ermal Luçi
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?username=' . urlencode($this->_dnsUser) . '&password=' . $this->_dnsPass . '&host=' . $this->_dnsHost);
584 1fa2f630 Erik Kristensen
					break;
585
				case 'ods':
586
					$needsIP = FALSE;
587 9b8dc821 Scott Ullrich
					$misc_errno = 0;
588
					$misc_error = "";
589
					$server = "ods.org";
590
					$port = "";
591 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
592 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
593 1e0b1727 Phil Davis
					}
594
					if ($this->_dnsPort) {
595
						$port = ":" . $this->_dnsPort;
596
					}
597 9b8dc821 Scott Ullrich
					$this->con['socket'] = fsockopen("{$server}{$port}", "7070", $misc_errno, $misc_error, 30);
598 1fa2f630 Erik Kristensen
					/* Check that we have connected */
599
					if (!$this->con['socket']) {
600
						print "error! could not connect.";
601
						break;
602
					}
603
					/* Here is the loop. Read the incoming data (from the socket connection) */
604
					while (!feof($this->con['socket'])) {
605
						$this->con['buffer']['all'] = trim(fgets($this->con['socket'], 4096));
606
						$code = substr($this->con['buffer']['all'], 0, 3);
607
						sleep(1);
608 1e0b1727 Phil Davis
						switch ($code) {
609 1fa2f630 Erik Kristensen
							case 100:
610
								fputs($this->con['socket'], "LOGIN ".$this->_dnsUser." ".$this->_dnsPass."\n");
611
								break;
612
							case 225:
613
								fputs($this->con['socket'], "DELRR ".$this->_dnsHost." A\n");
614
								break;
615
							case 901:
616
								fputs($this->con['socket'], "ADDRR ".$this->_dnsHost." A ".$this->_dnsIP."\n");
617
								break;
618
							case 795:
619
								fputs($this->con['socket'], "QUIT\n");
620
								break;
621
						}
622
					}
623 425ba708 Ermal
					$this->_checkStatus(0, $code);
624 1fa2f630 Erik Kristensen
					break;
625 9b8dc821 Scott Ullrich
				case 'freedns':
626 ac16181a TechSmurf
				case 'freedns-v6':
627 44857365 9Lukas5
					$needIP = TRUE;
628
					curl_setopt($ch, CURLOPT_URL, 'https://freedns.afraid.org/dynamic/update.php?' . $this->_dnsPass . '&address=' . $this->_dnsIP);
629 9b8dc821 Scott Ullrich
					break;
630 0a1b0183 Ermal Luçi
				case 'dnsexit':
631
					$needsIP = TRUE;
632 64746cf6 Chris Buechler
					curl_setopt($ch, CURLOPT_URL, 'https://www.dnsexit.com/RemoteUpdate.sv?login='.$this->_dnsUser. '&password='.$this->_dnsPass.'&host='.$this->_dnsHost.'&myip='.$this->_dnsIP);
633 0a1b0183 Ermal Luçi
					break;
634 9b8dc821 Scott Ullrich
				case 'loopia':
635
					$needsIP = TRUE;
636 cedc8184 kristoffer-ekenstam
					if(isset($this->_dnsWildcard) && $this->_dnsWildcard == TRUE) {
637
						$this->_dnsWildcard = "ON";
638
					} else {
639
						$this->_dnsWildcard = "OFF";
640
					}
641
					curl_setopt($ch, CURLOPT_USERPWD, "{$this->_dnsUser}:{$this->_dnsPass}");
642
					curl_setopt($ch, CURLOPT_URL, "https://dyndns.loopia.se/?system=custom&hostname={$this->_dnsHost}&myip={$this->_dnsIP}&wildcard={$this->_dnsWildcard}&mx={$this->_dnsMX}&backmx=NO");
643 9b8dc821 Scott Ullrich
					break;
644 2d78b166 Ermal Luçi
				case 'opendns':
645
					$needsIP = FALSE;
646
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") $this->_dnsWildcard = "ON";
647
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
648 6bccf4ca smos
					$server = "https://updates.opendns.com/nic/update?hostname=". $this->_dnsHost;
649 2d78b166 Ermal Luçi
					$port = "";
650 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
651 2d78b166 Ermal Luçi
						$server = $this->_dnsServer;
652 1e0b1727 Phil Davis
					}
653
					if ($this->_dnsPort) {
654 2d78b166 Ermal Luçi
						$port = ":" . $this->_dnsPort;
655 1e0b1727 Phil Davis
					}
656 2d78b166 Ermal Luçi
					curl_setopt($ch, CURLOPT_URL, $server .$port);
657
					break;
658
659 d74b5b8b sullrich
				case 'staticcling':
660
					$needsIP = FALSE;
661 64746cf6 Chris Buechler
					curl_setopt($ch, CURLOPT_URL, 'https://www.staticcling.org/update.html?login='.$this->_dnsUser.'&pass='.$this->_dnsPass);
662 1e0b1727 Phil Davis
					break;
663 52e6fdfd Scott Dale
				case 'dnsomatic':
664 1e0b1727 Phil Davis
					/* Example syntax
665 52e6fdfd Scott Dale
						https://username:password@updates.dnsomatic.com/nic/update?hostname=yourhostname&myip=ipaddress&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG
666
					*/
667
					$needsIP = FALSE;
668 1e0b1727 Phil Davis
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") {
669
						$this->_dnsWildcard = "ON";
670
					}
671 99438649 swatspyder
					/*
672
					Reference: https://www.dnsomatic.com/wiki/api
673
						DNS-O-Matic usernames are 3-25 characters.
674
						DNS-O-Matic passwords are 6-20 characters.
675
						All ASCII letters and numbers accepted.
676
						Dots, dashes, and underscores allowed, but not at the beginning or end of the string.
677
					Required: "rawurlencode" http://www.php.net/manual/en/function.rawurlencode.php
678
						Encodes the given string according to RFC 3986.
679
					*/
680
					$server = "https://" . rawurlencode($this->_dnsUser) . ":" . rawurlencode($this->_dnsPass) . "@updates.dnsomatic.com/nic/update?hostname=";
681 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
682 52e6fdfd Scott Dale
						$server = $this->_dnsServer;
683 1e0b1727 Phil Davis
					}
684
					if ($this->_dnsPort) {
685 52e6fdfd Scott Dale
						$port = ":" . $this->_dnsPort;
686 1e0b1727 Phil Davis
					}
687 52e6fdfd Scott Dale
					curl_setopt($ch, CURLOPT_URL, $server . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard='.$this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NOCHG');
688
					break;
689 61c30081 jim-p
				case 'namecheap':
690
					/* Example:
691
						https://dynamicdns.park-your-domain.com/update?host=[host_name]&domain=[domain.com]&password=[domain_password]&ip=[your_ip]
692
					*/
693
					$needsIP = FALSE;
694 4178d033 jim-p
					$dnspass = trim($this->_dnsPass);
695 6635aa0f jim-p
					$server = "https://dynamicdns.park-your-domain.com/update?host={$this->_dnsHost}&domain={$this->_dnsDomain}&password={$dnspass}&ip={$this->_dnsIP}";
696 61c30081 jim-p
					curl_setopt($ch, CURLOPT_URL, $server);
697 8ea77433 Chris Wells
					break;
698 19b7263e Ionut
				case 'duiadns':
699
				case 'duiadns-v6':
700
					$needsIP = FALSE;
701
					$server = "https://ipv4.duiadns.net/dyndns.duia?";
702
					curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
703
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
704
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
705
					curl_setopt($ch, CURLOPT_URL, $server . 'hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
706
					break;
707 8ea77433 Chris Wells
				case 'he-net':
708 d7e6f573 Daniel Becker
				case 'he-net-v6':
709 8ea77433 Chris Wells
					$needsIP = FALSE;
710
					$server = "https://dyn.dns.he.net/nic/update?";
711 086cf944 Phil Davis
					curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
712 393dac91 Chris Buechler
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
713 16fea0ce Cedric Ohle
					curl_setopt($ch, CURLOPT_URL, $server . 'hostname=' . $this->_dnsHost . '&password=' . $this->_dnsPass . '&myip=' . $this->_dnsIP);
714 8ea77433 Chris Wells
					break;
715 38a481ad jim-p
				case 'he-net-tunnelbroker':
716
					$needsIP = FALSE;
717
					$server = "https://ipv4.tunnelbroker.net/ipv4_end.php?";
718
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
719
					curl_setopt($ch, CURLOPT_URL, $server . 'tid=' . $this->_dnsHost);
720
					break;
721 fb403496 Gerald Raaf
				case 'selfhost':
722
					$needsIP = FALSE;
723 1e0b1727 Phil Davis
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") {
724
						$this->_dnsWildcard = "ON";
725
					}
726 fb403496 Gerald Raaf
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
727
					$server = "https://carol.selfhost.de/nic/update";
728
					$port = "";
729 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
730 fb403496 Gerald Raaf
						$server = $this->_dnsServer;
731 1e0b1727 Phil Davis
					}
732
					if ($this->_dnsPort) {
733 fb403496 Gerald Raaf
						$port = ":" . $this->_dnsPort;
734 1e0b1727 Phil Davis
					}
735 fb403496 Gerald Raaf
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?system=dyndns&hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard='.$this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NO');
736
					break;
737 c5e1ce90 robjarsen
				case 'route53':
738 16b16366 Jason McCormick
					require_once("r53.class");
739
					$r53 = new Route53($this->_dnsUser, $this->_dnsPass);
740 b2cb7364 Jason D. McCormick
					$apiurl = $r53->getApiUrl($this->_dnsZoneID);
741 16b16366 Jason McCormick
					$xmlreq = $r53->getRequestBody($this->_dnsHost, $this->_dnsIP, $this->_dnsTTL);
742 56632443 Jason D. McCormick
					$httphead = $r53->getHttpPostHeaders($this->_dnsZoneID, "us-east-1", hash("sha256",$xmlreq));
743 cc5adcaa Jason McCormick
					curl_setopt($ch, CURLOPT_HTTPHEADER, $httphead);
744
					if($this->_dnsVerboseLog){
745 19e87bb3 Bryan Stenson
						log_error(sprintf("Sending request to: %s", $apiurl));
746 cc5adcaa Jason McCormick
						foreach($httphead as $hv){
747
							log_error(sprintf("Header: %s", $hv));
748 0c7bb880 Phil Davis
						}
749 16b16366 Jason McCormick
						log_error(sprintf("XMLPOST: %s", $xmlreq));
750 0c7bb880 Phil Davis
					}
751 cc5adcaa Jason McCormick
					curl_setopt($ch, CURLOPT_URL, $apiurl);
752
					curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlreq);
753 0c7bb880 Phil Davis
					break;
754 c5e1ce90 robjarsen
				case 'route53-v6':
755 44c64da1 Matthew Fine
					require_once("r53.class");
756
					$r53 = new Route53($this->_dnsUser, $this->_dnsPass);
757
					$apiurl = $r53->getApiUrl($this->_dnsZoneID);
758
					$xmlreq = $r53->getRequestBodyV6($this->_dnsHost, $this->_dnsIP, $this->_dnsTTL);
759
					$httphead = $r53->getHttpPostHeaders($this->_dnsZoneID, "us-east-1", hash("sha256",$xmlreq));
760
					curl_setopt($ch, CURLOPT_HTTPHEADER, $httphead);
761
					if($this->_dnsVerboseLog){
762 19e87bb3 Bryan Stenson
						log_error(sprintf("Sending request to: %s", $apiurl));
763 44c64da1 Matthew Fine
						foreach($httphead as $hv){
764
							log_error(sprintf("Header: %s", $hv));
765
						}
766
						log_error(sprintf("XMLPOST: %s", $xmlreq));
767
					}
768
					curl_setopt($ch, CURLOPT_URL, $apiurl);
769
					curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlreq);
770
					break;
771 37f3e704 Matt Corallo
				case 'custom':
772 da40615d Daniel Becker
				case 'custom-v6':
773 37f3e704 Matt Corallo
					if (strstr($this->dnsUpdateURL, "%IP%")) {$needsIP = TRUE;} else {$needsIP = FALSE;}
774
					if ($this->_dnsUser != '') {
775 1e0b1727 Phil Davis
						if ($this->_curlIpresolveV4) {
776 086cf944 Phil Davis
							curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
777 1e0b1727 Phil Davis
						}
778
						if ($this->_curlSslVerifypeer) {
779 aa79f351 Sebastian Chrostek
							curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
780 1e0b1727 Phil Davis
						} else {
781 aa79f351 Sebastian Chrostek
							curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
782 1e0b1727 Phil Davis
						}
783 37f3e704 Matt Corallo
						curl_setopt($ch, CURLOPT_USERPWD, "{$this->_dnsUser}:{$this->_dnsPass}");
784
					}
785
					$server = str_replace("%IP%", $this->_dnsIP, $this->_dnsUpdateURL);
786 1e0b1727 Phil Davis
					if ($this->_dnsVerboseLog) {
787 9557ca30 Phil Davis
						log_error(sprintf(gettext("Sending request to: %s"), $server));
788 1e0b1727 Phil Davis
					}
789 37f3e704 Matt Corallo
					curl_setopt($ch, CURLOPT_URL, $server);
790
					break;
791 3a05e4c3 Austin Seipp
				case 'cloudflare-v6':
792 e26e1f76 Andrew Senetar
				case 'cloudflare':
793 6534026b jim-p
					$this->_FQDN = ltrim($this->_FQDN, '@.');
794 3a05e4c3 Austin Seipp
					$isv6 = ($this->_dnsService === 'cloudflare-v6');
795
					$recordType = $isv6 ? "AAAA" : "A";
796 e26e1f76 Andrew Senetar
					$needsIP = TRUE;
797 22d95a68 doktornotor
					$dnsServer ='api.cloudflare.com';
798 4e322e2c Phil Davis
					$dnsHost = str_replace(' ', '', $this->_dnsHost);
799 22d95a68 doktornotor
800
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
801
					curl_setopt($ch, CURLOPT_HTTPHEADER, array(
802
						'X-Auth-Email: '.$this->_dnsUser.'',
803
						'X-Auth-Key: '.$this->_dnsPass.'',
804
						'Content-Type: application/json'
805
					));
806
807
					// Get zone ID
808 2446fffa jim-p
					$getZoneId = "https://{$dnsServer}/client/v4/zones/?name={$this->_dnsDomain}";
809 b37b4034 Phil Davis
					curl_setopt($ch, CURLOPT_URL, $getZoneId);
810 22d95a68 doktornotor
					$output = json_decode(curl_exec($ch));
811
					$zone = $output->result[0]->id;
812 4e322e2c Phil Davis
					if ($zone) { // If zone ID was found get host ID
813 2446fffa jim-p
						$getHostId = "https://{$dnsServer}/client/v4/zones/{$zone}/dns_records?name={$this->_FQDN}&type={$recordType}";
814 b37b4034 Phil Davis
						curl_setopt($ch, CURLOPT_URL, $getHostId);
815 22d95a68 doktornotor
						$output = json_decode(curl_exec($ch));
816
						$host = $output->result[0]->id;
817 4e322e2c Phil Davis
						if ($host) { // If host ID was found update host
818 22d95a68 doktornotor
							$hostData = array(
819
								"content" => "{$this->_dnsIP}",
820 3a05e4c3 Austin Seipp
								"type" => "{$recordType}",
821 e10d25b4 CarlGill
								"proxied" => $this->_dnsProxied,
822 e93a7c71 calvinbui
								"name" => "{$this->_dnsHost}"
823 22d95a68 doktornotor
							);
824
							$data_json = json_encode($hostData);
825
							$updateHostId = "https://{$dnsServer}/client/v4/zones/{$zone}/dns_records/{$host}";
826 b37b4034 Phil Davis
							curl_setopt($ch, CURLOPT_URL, $updateHostId);
827 22d95a68 doktornotor
							curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
828 4e322e2c Phil Davis
							curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
829 22d95a68 doktornotor
						}
830
					}
831 e26e1f76 Andrew Senetar
					break;
832 1e0b1727 Phil Davis
				case 'eurodns':
833 ec66caa6 John Byron
					$needsIP = TRUE;
834
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
835 874599b9 johnbyronent
					$server = "https://update.eurodyndns.org/update/";
836 ec66caa6 John Byron
					$port = "";
837 1e0b1727 Phil Davis
					if ($this->_dnsPort) {
838 ec66caa6 John Byron
						$port = ":" . $this->_dnsPort;
839 1e0b1727 Phil Davis
					}
840 ec66caa6 John Byron
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
841 5458bc59 Scavy
					break;
842
				case 'gratisdns':
843 3e31a7f8 mortencombat
					$needsIP = TRUE;
844 5458bc59 Scavy
					$server = "https://ssl.gratisdns.dk/ddns.phtml";
845 2446fffa jim-p
					curl_setopt($ch, CURLOPT_URL, $server . '?u=' . $this->_dnsUser . '&p=' . $this->_dnsPass . '&h=' . $this->_dnsHost . '&d=' . $this->_dnsDomain . '&i=' . $this->_dnsIP);
846 5458bc59 Scavy
					break;
847 a4a56eb0 Stéphane
				case 'ovh-dynhost':
848
					$needsIP = FALSE;
849
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") $this->_dnsWildcard = "ON";
850
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
851
					$server = "https://www.ovh.com/nic/update";
852
					$port = "";
853 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
854 a4a56eb0 Stéphane
						$server = $this->_dnsServer;
855 1e0b1727 Phil Davis
					}
856
					if ($this->_dnsPort) {
857 a4a56eb0 Stéphane
						$port = ":" . $this->_dnsPort;
858 1e0b1727 Phil Davis
					}
859 a4a56eb0 Stéphane
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?system=dyndns&hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard='.$this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NO');
860
					break;
861 2206f1b9 Mathias Andersson
				case 'citynetwork':
862
					$needsIP = TRUE;
863
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
864
					$server = 'https://dyndns.citynetwork.se/nic/update';
865
					$port = "";
866 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
867 2206f1b9 Mathias Andersson
						$server = $this->_dnsServer;
868 1e0b1727 Phil Davis
					}
869
					if ($this->_dnsPort) {
870 2206f1b9 Mathias Andersson
						$port = ":" . $this->_dnsPort;
871 1e0b1727 Phil Davis
					}
872 2206f1b9 Mathias Andersson
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
873
					break;
874 916d683e surrural
				case 'dnsimple':
875 9e69907e Aaron Kalin
					/* Uses DNSimple's v2 REST API
876
					   Requires the Account ID as the username (found in the URL when pull up the domain)
877
					   And an API Token for the password (generated in the User Settings -> API tokens area of the website)
878
					   Piggybacks on Route 53's ZoneID field for the DNSimple record ID to update
879
					   The DNS record MUST exist before it can update since it performs a PATCH operation
880
					   Data sent as JSON over HTTPS */
881 916d683e surrural
					$needsIP = TRUE;
882 d2cad3b5 Aaron Kalin
					$server = 'https://api.dnsimple.com/v2/';
883
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
884
					curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-Type: application/json', 'Authorization: Bearer ' . $this->_dnsPass));
885
					curl_setopt($ch, CURLOPT_URL, $server . $this->_dnsUser . '/zones/' . $this->_dnsHost . '/records/' . $this->_dnsZoneID);
886
					curl_setopt($ch, CURLOPT_POSTFIELDS, '{"content":"' . $this->_dnsIP . '","ttl":"' . $this->_dnsTTL . '"}');
887 916d683e surrural
					break;
888 456ba14f Sam Neely
				case 'godaddy':
889
				case 'godaddy-v6':
890
					/* Uses GoDaddy's REST API
891
					   Requires username and Account API sso-key passed in header
892
					   Data sent as JSON */
893
					$needsIP = TRUE;
894
					$server = 'https://api.godaddy.com/v1/domains/';
895
					$recordType = $this->_useIPv6 ? "AAAA" : "A";
896
					$url = $server  . $this->_dnsDomain . '/records/' . $recordType . '/' . $this->_dnsHost;
897
					$jsondata = '[{"data":"' . $this->_dnsIP . '","ttl":' . $this->_dnsTTL . '}]';
898
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
899
					curl_setopt($ch, CURLOPT_HTTPHEADER, array(
900
						'Accept: application/json',
901
						'Content-Type: application/json',
902
						'Authorization: sso-key ' . $this->_dnsUser . ':' . $this->_dnsPass
903
					));
904
					curl_setopt($ch, CURLOPT_URL, $url);
905
					curl_setopt($ch, CURLOPT_POSTFIELDS, $jsondata);
906
					break;
907 c5ecdc25 Jose Luis Duran
				case 'googledomains':
908 6c92b378 Christopher Fazendin
					$needsIP = FALSE;
909
					$post_data['username:password'] = $this->_dnsUser . ':' . $this->_dnsPass;
910
					$post_data['hostname'] = $this->_dnsHost;
911
					$post_data['myip'] = $this->_dnsIP;
912
					$post_data['offline'] = 'no';
913 404ff523 Christopher Fazendin
					$server = "https://domains.google.com/nic/update";
914 6c92b378 Christopher Fazendin
					$port = "";
915
					curl_setopt($ch, CURLOPT_URL, 'https://domains.google.com/nic/update');
916
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
917
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
918
					break;
919 c5ecdc25 Jose Luis Duran
				case 'dnsmadeeasy':
920
					$needsIP = TRUE;
921
					$server = "https://cp.dnsmadeeasy.com/servlet/updateip";
922
					curl_setopt($ch, CURLOPT_URL, $server . '?username=' . $this->_dnsUser . '&password=' . $this->_dnsPass . '&id=' . $this->_dnsHost . '&ip=' . $this->_dnsIP);
923
					break;
924 1c2c08bd exii1988
				case 'spdyn':
925
				case 'spdyn-v6':
926 f3ee8545 Rene Schuster
					$needsIP = FALSE;
927
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
928 1c2c08bd exii1988
					$server = "https://update.spdyn.de/nic/update";
929 f3ee8545 Rene Schuster
					$port = "";
930 4e322e2c Phil Davis
					if ($this->_dnsServer) {
931 f3ee8545 Rene Schuster
						$server = $this->_dnsServer;
932 4e322e2c Phil Davis
					}
933
					if ($this->_dnsPort) {
934 f3ee8545 Rene Schuster
						$port = ":" . $this->_dnsPort;
935 4e322e2c Phil Davis
					}
936 f3ee8545 Rene Schuster
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
937
					break;
938 575b1dcf Christoph Filnkößl
				case 'all-inkl':
939
					$needsIP = FALSE;
940
					$server = 'https://dyndns.kasserver.com/';
941
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
942
					curl_setopt($ch, CURLOPT_URL, $server . 'myip=' . $this->_dnsIP);
943
					break;
944 74533d41 xygrec
				case 'hover':
945
					$needsIP = FALSE;
946
					$port = "";
947
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
948 61c813f9 xygrec
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
949 74533d41 xygrec
950
					//step 1: login to API
951
					$post_data['username'] = $this->_dnsUser;
952
					$post_data['password'] = $this->_dnsPass;
953
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
954
					curl_setopt($ch, CURLOPT_URL, "https://www.hover.com/api/login");
955
					curl_setopt($ch, CURLOPT_HEADER, 1); //return the full headers to extract the cookies
956
					$output = curl_exec($ch);
957
958
					//extract the cookies
959
					preg_match_all("/^Set-cookie: (.*?);/ism", $output, $cookies);
960
					if( count($cookies[1]) > 0 ){
961
						$cookie_data = implode("; ",$cookies[1]);
962
					}
963
964
					//step 2: find the id of the A record
965
					$post_data = null;
966
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
967
					curl_setopt($ch, CURLOPT_COOKIE, $cookie_data);
968
					curl_setopt($ch, CURLOPT_HEADER, 0);
969
					curl_setopt($ch, CURLOPT_URL, "https://www.hover.com/api/dns");
970
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
971
972
					$output = curl_exec($ch);
973
					preg_match("/^{\"succeeded\":true.*?domain_name\":\"{$this->_dnsDomain}.*?entries.*?{\"id\":\"([^\"]*?)\",\"name\":\"{$this->_dnsHost}\".*?\$/", $output, $hostID);
974
					$hostID = $hostID[1];
975
					preg_match("/^{\"succeeded\":true.*?domain_name\":\"{$this->_dnsDomain}.*?entries.*?{[^\}]*?\"name\":\"{$this->_dnsHost}\".*?content\":\"([^\"]*?)\".*?\$/", $output, $hostIP);
976
					$hostIP = $hostIP[1];
977
978
					//step 3: update the IP
979
					if ($hostID) {
980
						curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
981 61c813f9 xygrec
						curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
982 74533d41 xygrec
						curl_setopt($ch, CURLOPT_COOKIE, $cookie_data);
983
						$post_data['content'] = $this->_dnsIP;
984
						curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
985
						curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
986
						curl_setopt($ch, CURLOPT_URL, "https://www.hover.com/api/dns/{$hostID}");
987
						log_error("HostID:{$hostID}, OldIP:{$hostIP}");
988
					}
989
					break;
990 9a3ec9a5 frank
				case 'dreamhost':
991
				case 'dreamhost-v6':
992
					$needsIP = TRUE;
993
					$isv6 = ($this->_dnsService === 'dreamhost-v6');
994
					$server = 'https://api.dreamhost.com/';
995 a71deb5a frank
					$post_data['key'] = $this->_dnsPass;
996 9a3ec9a5 frank
					$post_data['unique_id'] = uniqid($this->_dnsHost);
997
					$post_data['cmd'] = 'dns-add_record';
998
					$post_data['format'] = 'json';
999
					$post_data['value'] = $this->_dnsIP;
1000
					$post_data['record'] = $this->_dnsHost;
1001
					$post_data['type'] = $isv6 ? 'AAAA' : 'A';
1002 a71deb5a frank
					$post_data['comment'] = "Updated by pfSense:$this->_dnsUser on ".date('c');
1003 9a3ec9a5 frank
					$port = "";
1004
					if ($this->_dnsServer) {
1005
						$server = $this->_dnsServer;
1006
					}
1007
					if ($this->_dnsPort) {
1008
						$port = ":" . $this->_dnsPort;
1009
					}
1010
					curl_setopt($ch, CURLOPT_URL, $server . $port);
1011
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1012
					break;
1013 544674ad Grant Sheehan
				case 'digitalocean':
1014 0c43f825 Matthew Fine
				case 'digitalocean-v6':
1015 544674ad Grant Sheehan
					// Get record ID
1016
					$server = 'https://api.digitalocean.com/v2/domains/';
1017 0c43f825 Matthew Fine
					$isv6 = ($this->_dnsService === 'digitalocean-v6');
1018 544674ad Grant Sheehan
					$url = $server . $this->_dnsDomain . '/records';
1019 32cb54c3 Grant Sheehan
					curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: Bearer {$this->_dnsPass}"));
1020 544674ad Grant Sheehan
					curl_setopt($ch, CURLOPT_URL, $url);
1021
					$output = json_decode(curl_exec($ch));
1022 7c957a56 Stephen Jones
					if (!is_array($output->domain_records)) {
1023
						$output->domain_records = array();
1024
					}
1025 544674ad Grant Sheehan
					foreach($output->domain_records as $dnsRecord) {
1026 5878d529 Grant Sheehan
						// NS records are named @ in DO's API, so check type as well 
1027
						// https://redmine.pfsense.org/issues/9171
1028
						if ($this->_dnsHost == $dnsRecord->name && $dnsRecord->type == 'A') {
1029 32cb54c3 Grant Sheehan
							$recordID = $dnsRecord->id;
1030 544674ad Grant Sheehan
							break;
1031
						}
1032
					}
1033
1034 32cb54c3 Grant Sheehan
					// Create/update record
1035
					if ($recordID == null) {
1036
						$url = $server . $this->_dnsDomain . '/records';
1037
					} else {
1038
						$url = $server . $this->_dnsDomain . '/records/' . $recordID;
1039
						curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
1040
					}
1041 0c43f825 Matthew Fine
					$post_data['type'] = $isv6 ? 'AAAA' : 'A';
1042 32cb54c3 Grant Sheehan
					$post_data['ttl'] = $this->_dnsTTL;
1043 544674ad Grant Sheehan
					$post_data['name'] = $this->_dnsHost;
1044
					$post_data['data'] = $this->_dnsIP;
1045
					curl_setopt($ch, CURLOPT_URL, $url);
1046
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1047
					break;
1048 745d3779 Wagner Sartori Junior
				case 'cloudns':
1049
					/* Uses ClouDNS REST API
1050
					   Requires auth-id or sub-auth-id or sub-auth-user */
1051
					// Step 1: Find the Record ID
1052
					$url = 'https://api.cloudns.net/dns/records.json';
1053
					$post_data['auth-id'] = $this->_dnsUser;
1054
					$post_data['auth-password'] = $this->_dnsPass;
1055
					$post_data['domain-name'] = $this->_dnsDomain;
1056
					$post_data['host'] = $this->_dnsHost;
1057
					$post_data['type'] = 'a';
1058
					curl_setopt($ch, CURLOPT_URL, $url);
1059
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1060
					$output = json_decode(curl_exec($ch));
1061
					$recordID = key(get_object_vars($output));
1062
1063
					// Step 2: Set the record
1064
					$needsIP = TRUE;
1065
					$url = 'https://api.cloudns.net/dns/mod-record.json';
1066
					$post_data = array();
1067
					$post_data['auth-id'] = $this->_dnsUser;
1068
					$post_data['auth-password'] = $this->_dnsPass;
1069
					$post_data['domain-name'] = $this->_dnsDomain;
1070
					$post_data['record-id'] = $recordID;
1071
					$post_data['host'] = $this->_dnsHost;
1072
					$post_data['record'] = $this->_dnsIP;
1073
					$post_data['ttl'] = $this->_dnsTTL;
1074
					curl_setopt($ch, CURLOPT_URL, $url);
1075
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1076
					break;
1077 ed5b58a7 Tom Embt
				case 'azurev6':
1078
				case 'azure':
1079
					$hostname = "{$this->_dnsHost}";
1080
					$resourceid = trim($this->_dnsZoneID);
1081
					$app_id = $this->_dnsUser;
1082
					$client_secret = $this->_dnsPass;
1083
					$newip = $this->_dnsIP;
1084
					$newttl = $this->_dnsTTL;
1085
						// ensure resourceid starts with / and has no trailing /
1086
					$resourceid = '/' . trim($resourceid, '/');
1087
						// extract subscription id from resource id
1088
					preg_match('/\\/subscriptions\\/(?<sid>[^\\/]*)/', $resourceid, $result);
1089
					$subscriptionid = isset($result['sid']) ? $result['sid'] : '';
1090
					if (isset($result['sid'])) {
1091
						$subscriptionid = $result['sid'];
1092
					} else {
1093
						log_error("Azure subscription id not found in resource id");
1094
						return false;
1095
					}
1096
						// find tenant id from subscription id
1097
					curl_setopt($ch, CURLOPT_URL, "https://management.azure.com/subscriptions/" . $subscriptionid . "?api-version=2016-09-01");
1098
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1099
					curl_setopt($ch, CURLOPT_HEADER, 1);
1100
					curl_setopt($ch, CURLOPT_NOBODY, 1);
1101
					$output = curl_exec($ch);
1102
					$pattern = '/Bearer authorization_uri="https:\\/\\/login.windows.net\\/(?<tid>[^"]*)/i';
1103
					preg_match($pattern, $output, $result);
1104
					if (isset($result['tid'])) {
1105
						$tenantid = $result['tid'];
1106
					} else {
1107
						log_error("Tenant ID not found");
1108
						return false;
1109
					}
1110
						// get an bearer token
1111
					curl_setopt($ch, CURLOPT_URL, "https://login.microsoftonline.com/" . $tenantid . "/oauth2/token");
1112
					curl_setopt($ch, CURLOPT_POST, 1);
1113
					$body = "resource=" . urlencode("https://management.core.windows.net/") . "&grant_type=client_credentials&client_id=" . $app_id . "&client_secret=" . urlencode($client_secret);
1114
					curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
1115
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1116
					$server_output = curl_exec($ch);
1117
					$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1118
					preg_match("/\"access_token\":\"(?<tok>[^\"]*)\"/", $server_output, $result);
1119
					if (isset($result['tok'])) {
1120
						$bearertoken = $result['tok'];
1121
					} else {
1122
						log_error("no valid bearer token");
1123
						return false;
1124
					}
1125
						// Update the DNS record
1126
					if ($this->_useIPv6) {
1127
						$url = "https://management.azure.com" . $resourceid . "/AAAA/" . $hostname . "?api-version=2017-09-01";
1128
						$body = '{"properties":{"TTL":"' . $newttl . '", "AAAARecords":[{"ipv6Address":"' . $newip . '"}]}}';
1129
					} else {
1130
						$url = "https://management.azure.com" . $resourceid . "/A/" . $hostname . "?api-version=2017-09-01";
1131
						$body = '{"properties":{"TTL":"' . $newttl . '", "ARecords":[{"ipv4Address":"' . $newip . '"}]}}';
1132
					}
1133
					$request_headers = array();
1134
					$request_headers[] = 'Accept: application/json';
1135
					$request_headers[] = 'Authorization: Bearer ' . $bearertoken;
1136
					$request_headers[] = 'Content-Type: application/json';
1137
					curl_setopt($ch, CURLOPT_URL, $url);
1138
					curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
1139
					curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
1140
					curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
1141
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1142
					curl_setopt($ch, CURLOPT_HEADER, 1);
1143
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
1144
					break;
1145 b923a825 Tom Embt
				case 'linode':
1146
				case 'linode-v6':
1147
					$linode_api = "https://api.linode.com/v4";
1148
					$record_type = $this->_useIPv6 ? "AAAA" : "A";
1149
					$record_name = $this->_dnsHost == "@" ? "" : $this->_dnsHost;
1150
					$err_prefix = gettext("Dynamic DNS") . " {$this->_dnsService} ({$this->_FQDN}): (" . gettext("Error") . ")";
1151
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1152
					curl_setopt($ch, CURLOPT_HTTPHEADER, array(
1153
						'Accept: application/json',
1154
						'Content-Type: application/json',
1155
						'Authorization: Bearer ' . $this->_dnsPass
1156
					));
1157
1158
					// get domain id
1159 bd0a29ea Tom Embt
					curl_setopt($ch, CURLOPT_URL, "{$linode_api}/domains");
1160 b923a825 Tom Embt
					$domains_output = curl_exec($ch);
1161
					$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1162
					if ( $http_code == 401 && preg_match('/invalid oauth token/i', $domains_output) ) {
1163
						log_error("$err_prefix " . gettext("querying domains") . ": " . gettext("User Authentication Failed"));
1164
						return false;
1165
					} else if ( $http_code == 401 ) {
1166
						log_error("$err_prefix " . gettext("querying domains") . ": " . gettext("User Authorization Failed"));
1167
						return false;
1168
					} else if ( $http_code != 200 ) {
1169
						log_error("$err_prefix " . gettext("querying domains") . ": " .
1170 bd0a29ea Tom Embt
							( isset($domains_result["errors"][0]["reason"]) ? $domains_result["errors"][0]["reason"] : "HTTP {$http_code}" ) );
1171 b923a825 Tom Embt
						return false;
1172
					}
1173
1174
					$domains_result = json_decode($domains_output, TRUE);
1175
					foreach($domains_result["data"] as $domains_entry) {
1176
						if ($domains_entry["domain"] == $this->_dnsDomain) {
1177
							$domain_id = $domains_entry["id"];
1178
						}
1179
					}
1180
					if ( ! $domain_id ) {
1181 bd0a29ea Tom Embt
						log_error("{$err_prefix} " . gettext("no domain ID for domain") . ": '{$this->_dnsDomain}'");
1182 b923a825 Tom Embt
						return false;
1183
					}
1184
					if ($this->_dnsVerboseLog) {
1185
						log_error("_update(): " . sprintf(gettext("found domain id: %s"), $domain_id));
1186
					}
1187
1188
					// get existing record if present
1189 bd0a29ea Tom Embt
					curl_setopt($ch, CURLOPT_URL, "{$linode_api}/domains/{$domain_id}/records");
1190 b923a825 Tom Embt
					$records_output = curl_exec($ch);
1191
					$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1192
					if ( $http_code != 200 )
1193
					{
1194
						log_error("$err_prefix " . gettext("querying domains") . ": " .
1195 bd0a29ea Tom Embt
							( isset($domains_result["errors"][0]["reason"]) ? $domains_result["errors"][0]["reason"] : "HTTP {$http_code}" ) );
1196 b923a825 Tom Embt
						return false;
1197
					}
1198
1199
					$records_result = json_decode($records_output, TRUE);
1200
					foreach($records_result["data"] as $records_entry) {
1201
						if ( $records_entry["type"] == $record_type && $records_entry["name"] == $record_name ) {
1202
							// not adding support for pagination at this time, hope you have < 100 records!
1203
							$record = $records_entry;
1204
						}
1205
					}
1206
					if ($this->_dnsVerboseLog) {
1207
						log_error("_update(): " . ( $record ? sprintf(gettext("found existing record id: %s"), $record["id"]) : gettext("no matching record found") ));
1208
					}
1209
1210
					if (is_array($record)) {
1211
						// update existing record
1212
						$record["target"] = $this->_dnsIP;
1213
						$record["ttl_sec"] = (int) $this->_dnsTTL; // linode may round this up, 0 = zone default
1214
						curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($record));
1215
						curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
1216 bd0a29ea Tom Embt
						curl_setopt($ch, CURLOPT_URL, "{$linode_api}/domains/{$domain_id}/records/" . $record["id"]);
1217 b923a825 Tom Embt
					} else {
1218
						// create a new record
1219
						$record = array(
1220
							"type"    => $record_type,
1221
							"name"    => $record_name,
1222
							"target"  => $this->_dnsIP,
1223
							"ttl_sec" => (int) $this->_dnsTTL, // linode may round this up, 0 = zone default
1224
						);
1225
						curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($record));
1226
						curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
1227 bd0a29ea Tom Embt
						curl_setopt($ch, CURLOPT_URL, "{$linode_api}/domains/{$domain_id}/records");
1228 b923a825 Tom Embt
					}
1229 745d3779 Wagner Sartori Junior
1230 edfe22f8 Eric Vantillard
				break;
1231
			case 'gandi-livedns':
1232
				// NOTE: quite similar to digitalocean case but with json content like azure case
1233
				// Get record href
1234
				$server = 'https://dns.api.gandi.net/api/v5/domains/';
1235
				$url = $server . $this->_dnsDomain . '/records';
1236
				curl_setopt($ch, CURLOPT_HTTPHEADER, array("X-Api-Key: {$this->_dnsPass}"));
1237
				curl_setopt($ch, CURLOPT_URL, $url);
1238
				$output = json_decode(curl_exec($ch));
1239
				if (!is_array($output)) {
1240
					$output = array();
1241
				}
1242
				foreach($output as $dnsRecord) {
1243
					// NS records are named @ in DO's API, so check type as well
1244
					if ($this->_dnsHost == $dnsRecord->rrset_name && $dnsRecord->rrset_type == 'A') {
1245
						$recordHref = $dnsRecord->rrset_href;
1246
						break;
1247
					}
1248
				}
1249
				$request_headers = array();
1250
				//$request_headers[] = 'Accept: application/json';
1251
				$request_headers[] = 'X-Api-Key: ' .$this->_dnsPass;
1252
				$request_headers[] = 'Content-Type: application/json';
1253
				//create or update record
1254
				if ($recordHref == null) {
1255
					//create record
1256
					$url = $server . $this->_dnsDomain . '/records';
1257
					$body = '{"rrset_type": "A", "rrset_ttl": ' . $this->_dnsTTL . ', "rrset_name": "' . $this->_dnsHost . '", "rrset_values": ["' . $this->_dnsIP . '"]}';
1258
				} else {
1259
					//update record
1260
					$url = $recordHref;
1261
					$body = '{"rrset_ttl": ' . $this->_dnsTTL . ', "rrset_values": ["' . $this->_dnsIP . '"]}';
1262
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
1263
				}
1264
				curl_setopt($ch, CURLOPT_URL, $url);
1265
				curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
1266
				curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
1267 b923a825 Tom Embt
					break;
1268 ed5b58a7 Tom Embt
				default:
1269
					break;
1270 1fa2f630 Erik Kristensen
			}
1271 cc5adcaa Jason McCormick
			if ($this->_dnsService != 'ods') {
1272 15dcf132 PiBa-NL
				curl_setopt($ch, CURLOPT_HEADER, 1);
1273 0e0f580d Christoph Filnkößl
				$response = curl_exec($ch);
1274 0f2fbcd7 Jason McCormick
				$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
1275 0e0f580d Christoph Filnkößl
				$header = substr($response, 0, $header_size);
1276
				$data = substr($response, $header_size);
1277
				$this->_checkStatus($ch, $data, $header);
1278 425ba708 Ermal
				@curl_close($ch);
1279
			}
1280 1fa2f630 Erik Kristensen
		}
1281 c5e1ce90 robjarsen
1282 9a3ec9a5 frank
		/**
1283
		 * Private Function (added 23 Feb 17)
1284
		 *   Send Removal To Selected Service.
1285 c5e1ce90 robjarsen
		 *
1286 9a3ec9a5 frank
		 *   Some services do not perform an inplace upgrade.  If they do not then the solution
1287
		 *   is to remove the existing record and add a new record.
1288 c5e1ce90 robjarsen
		 *
1289 9a3ec9a5 frank
		 * @param unknown $existing_ip If required, an existing IP address for the record.
1290
		 */
1291
		function _remove($existing_ip = NULL) {
1292 f2e702b1 frank
			$remove_allowed = false;
1293 9a3ec9a5 frank
			if ($this->_dnsVerboseLog) {
1294
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _remove() starting.'), $this->_dnsService, $this->_FQDN));
1295
			}
1296 c5e1ce90 robjarsen
1297 9a3ec9a5 frank
			if (strstr($this->_dnsRequestIf, "_vip")) {
1298
				$parentif = get_configured_vip_interface($this->_dnsRequestIf);
1299
				$realparentif = convert_friendly_interface_to_real_interface_name($parentif);
1300
			} else {
1301
				$realparentif = $this->_dnsRequestIf;
1302
			}
1303 c5e1ce90 robjarsen
1304 9a3ec9a5 frank
			$ch = curl_init();
1305 c5e1ce90 robjarsen
1306 9a3ec9a5 frank
			if ($this->_useIPv6 == false) {
1307
				curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
1308
			}
1309 c5e1ce90 robjarsen
1310 f2e702b1 frank
			curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
1311
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
1312
			curl_setopt($ch, CURLOPT_INTERFACE, 'if!' . $realparentif);
1313
			curl_setopt($ch, CURLOPT_TIMEOUT, 120); // Completely empirical
1314 c5e1ce90 robjarsen
1315 9a3ec9a5 frank
			switch ($this->_dnsService) {
1316 e350558a frank
			case 'dreamhost':
1317
			case 'dreamhost-v6':
1318
				$server = 'https://api.dreamhost.com/';
1319
				$post_data['key'] = $this->_dnsPass;
1320
				$post_data['unique_id'] = uniqid($this->_dnsHost);
1321
				$post_data['cmd'] = 'dns-remove_record';
1322
				$post_data['format'] = 'json';
1323
				$post_data['value'] = $existing_ip;
1324
				$post_data['record'] = $this->_dnsHost;
1325
				$isv6 = ($this->_dnsService === 'dreamhost-v6');
1326
				$post_data['type'] = $isv6 ? 'AAAA' : 'A';
1327
				$port = "";
1328
				if ($this->_dnsServer) {
1329
					$server = $this->_dnsServer;
1330 9a3ec9a5 frank
				}
1331 e350558a frank
				if ($this->_dnsPort) {
1332
					$port = ":" . $this->_dnsPort;
1333 9a3ec9a5 frank
				}
1334 e350558a frank
				curl_setopt($ch, CURLOPT_URL, $server . $port);
1335
				curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1336 f2e702b1 frank
				$remove_allowed = true;
1337 e350558a frank
				break;
1338
			default:
1339
				break;
1340
			}
1341 f2e702b1 frank
			if ($remove_allowed) {
1342 e350558a frank
				curl_setopt($ch, CURLOPT_HEADER, 1);
1343
				$response = curl_exec($ch);
1344
				$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
1345
				$header = substr($response, 0, $header_size);
1346
				$data = substr($response, $header_size);
1347
				$this->_checkStatus($ch, $data, $header);
1348
				@curl_close($ch);
1349 9a3ec9a5 frank
			}
1350 e350558a frank
		}
1351 c5e1ce90 robjarsen
1352 9a3ec9a5 frank
		/**
1353
		 * Private Function (added 23 Feb 17)
1354 f2e702b1 frank
		 * Retrieves current DNS records from an external API source.
1355 c5e1ce90 robjarsen
		 *
1356
		 * Some services cannot perform new operations without the caller
1357
		 * providing existing record information.
1358 9a3ec9a5 frank
		 */
1359
		function _lookup_current() {
1360 f2e702b1 frank
			$lookup_allowed = false;
1361 9a3ec9a5 frank
			if ($this->_dnsVerboseLog) {
1362
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _listCurrent() starting.'), $this->_dnsService, $this->_FQDN));
1363
			}
1364 c5e1ce90 robjarsen
1365 9a3ec9a5 frank
			if (strstr($this->_dnsRequestIf, "_vip")) {
1366
				$parentif = get_configured_vip_interface($this->_dnsRequestIf);
1367
				$realparentif = convert_friendly_interface_to_real_interface_name($parentif);
1368
			} else {
1369
				$realparentif = $this->_dnsRequestIf;
1370
			}
1371 c5e1ce90 robjarsen
1372 9a3ec9a5 frank
			$ch = curl_init();
1373 c5e1ce90 robjarsen
1374 9a3ec9a5 frank
			if ($this->_useIPv6 == false) {
1375
				curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
1376
			}
1377 c5e1ce90 robjarsen
1378 f2e702b1 frank
			curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
1379
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
1380
			curl_setopt($ch, CURLOPT_INTERFACE, 'if!' . $realparentif);
1381
			curl_setopt($ch, CURLOPT_TIMEOUT, 120); // Completely empirical
1382 c5e1ce90 robjarsen
1383 9a3ec9a5 frank
			switch ($this->_dnsService) {
1384 e350558a frank
			case 'dreamhost':
1385
			case 'dreamhost-v6':
1386
				$server = 'https://api.dreamhost.com/';
1387
				$post_data['key'] = $this->_dnsPass;
1388
				$post_data['unique_id'] = uniqid($this->_dnsHost);
1389
				$post_data['cmd'] = 'dns-list_records';
1390
				$post_data['format'] = 'json';
1391
				$port = "";
1392
				if ($this->_dnsServer) {
1393
					$server = $this->_dnsServer;
1394
				}
1395
				if ($this->_dnsPort) {
1396
					$port = ":" . $this->_dnsPort;
1397
				}
1398
				curl_setopt($ch, CURLOPT_URL, $server . $port);
1399
				curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1400 f2e702b1 frank
				$lookup_allowed = true;
1401 e350558a frank
				break;
1402
			default:
1403
				break;
1404 9a3ec9a5 frank
			}
1405 f2e702b1 frank
			if ($lookup_allowed) {
1406 9a3ec9a5 frank
				curl_setopt($ch, CURLOPT_HEADER, 1);
1407
				$response = curl_exec($ch);
1408
				$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
1409
				$header = substr($response, 0, $header_size);
1410
				$data = substr($response, $header_size);
1411
				$this->_checkLookupStatus($ch, $data, $header);
1412
				@curl_close($ch);
1413
			}
1414
		}
1415
1416
		/*
1417 c5e1ce90 robjarsen
		 * Private Function (added 23 Feb 17)
1418 f2e702b1 frank
		 *   Retrieve Lookup Status from the provided data and/or header
1419 9a3ec9a5 frank
		 */
1420
		function _checkLookupStatus($ch, $data, $header) {
1421
			if ($this->_dnsVerboseLog) {
1422
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkLookupStatus() starting.'), $this->_dnsService, $this->_FQDN));
1423
			}
1424
			$success_str = "(" . gettext("Success") . ") ";
1425
			$error_str = "(" . gettext("Error") . ") ";
1426
			$status_intro = "phpDynDNS ({$this->_dnsHost}): ";
1427
1428
			if ($this->_dnsService != 'ods' && @curl_error($ch)) {
1429
				$status = gettext("Curl error occurred:") . " " . curl_error($ch);
1430
				log_error($status);
1431
				$this->status = $status;
1432
				return;
1433
			}
1434
			switch ($this->_dnsService) {
1435 e350558a frank
			case 'dreamhost':
1436
			case 'dreamhost-v6':
1437
				$result = json_decode($data,true);
1438
				if($result["result"] != "success") {
1439
					log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
1440
					$this->_debug($data);
1441
					return;
1442
				} else {
1443
					foreach($result["data"] as $key => $row) {
1444 c5e1ce90 robjarsen
						if($row["record"] == $this->_dnsHost &&
1445 e350558a frank
								(($row["type"] == "A" && !$this->_useIPv6)
1446
										|| ($row["type"] == "AAAA" && $this->_useIPv6)
1447
								)) {
1448
							if($row["editable"] == 0) {
1449
								log_error($status_intro . "host " . $this->_dnsHost . " is not editable.");
1450
								continue;
1451 9a3ec9a5 frank
							}
1452 e350558a frank
							$this->_existingRecords[]=array("record"=>$row["type"], "type"=>$row["type"], "existing_val"=>$row["value"]);
1453 9a3ec9a5 frank
						}
1454
					}
1455 e350558a frank
				}
1456
				if (!is_array($this->_existingRecords)){
1457
					if ($this->_dnsVerboseLog) {
1458
						log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkLookupStatus() ending.  No matching records found.'), $this->_dnsService, $this->_FQDN));
1459 9a3ec9a5 frank
					}
1460 e350558a frank
				}
1461
				break;
1462
			default:
1463
				break;
1464 9a3ec9a5 frank
			}
1465
		}
1466 1fa2f630 Erik Kristensen
1467
		/*
1468
		 * Private Function (added 12 July 2005) [beta]
1469
		 *   Retrieve Update Status
1470
		 */
1471 15dcf132 PiBa-NL
		function _checkStatus($ch, $data, $header) {
1472 87b91672 Phil Davis
			if ($this->_dnsVerboseLog) {
1473 9557ca30 Phil Davis
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkStatus() starting.'), $this->_dnsService, $this->_FQDN));
1474 87b91672 Phil Davis
			}
1475 4a6bb2ff Scott Ullrich
			$successful_update = false;
1476 9557ca30 Phil Davis
			$success_str = "(" . gettext("Success") . ") ";
1477
			$error_str = "(" . gettext("Error") . ") ";
1478
			$status_intro = "phpDynDNS ({$this->_dnsHost}): ";
1479
1480 cc5adcaa Jason McCormick
			if ($this->_dnsService != 'ods' && @curl_error($ch)) {
1481 9557ca30 Phil Davis
				$status = gettext("Curl error occurred:") . " " . curl_error($ch);
1482 425ba708 Ermal
				log_error($status);
1483
				$this->status = $status;
1484
				return;
1485
			}
1486 1fa2f630 Erik Kristensen
			switch ($this->_dnsService) {
1487 197cf433 McB
				case 'glesys':
1488 9557ca30 Phil Davis
					$status_intro = "GleSYS ({$this->_dnsHost}): ";
1489 197cf433 McB
					if (preg_match('/Record updated/i', $data)) {
1490 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1491 197cf433 McB
						$successful_update = true;
1492
					} else {
1493 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1494
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
1495 197cf433 McB
						$this->_debug($data);
1496
					}
1497
					break;
1498 52e6fdfd Scott Dale
				case 'dnsomatic':
1499 9557ca30 Phil Davis
					$status_intro = "DNS-O-Matic ({$this->_dnsHost}): ";
1500 52e6fdfd Scott Dale
					if (preg_match('/badauth/i', $data)) {
1501 9557ca30 Phil Davis
						$status = $status_intro . gettext("The DNS-O-Matic username or password specified are incorrect. No updates will be distributed to services until this is resolved.");
1502 52e6fdfd Scott Dale
					} else if (preg_match('/notfqdn /i', $data)) {
1503 9557ca30 Phil Davis
						$status = $status_intro . gettext("The hostname specified is not a fully-qualified domain name. If no hostnames included, notfqdn will be returned once.");
1504 52e6fdfd Scott Dale
					} else if (preg_match('/nohost/i', $data)) {
1505 9557ca30 Phil Davis
						$status = $status_intro . gettext("The hostname passed could not be matched to any services configured. The service field will be blank in the return code.");
1506 52e6fdfd Scott Dale
					} else if (preg_match('/numhost/i', $data)) {
1507 530e4707 NOYB
						$status = $status_intro . gettext("Up to 20 hosts my be updated. numhost is returned if attempting to update more than 20 or update a round-robin.");
1508 52e6fdfd Scott Dale
					} else if (preg_match('/abuse/i', $data)) {
1509 9557ca30 Phil Davis
						$status = $status_intro . gettext("The hostname is blocked for update abuse.");
1510 52e6fdfd Scott Dale
					} else if (preg_match('/good/i', $data)) {
1511 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1512 52e6fdfd Scott Dale
						$successful_update = true;
1513
					} else if (preg_match('/dnserr/i', $data)) {
1514 9557ca30 Phil Davis
						$status = $status_intro . gettext("DNS error encountered. Stop updating for 30 minutes.");
1515 52e6fdfd Scott Dale
					} else {
1516 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1517
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
1518 52e6fdfd Scott Dale
						$this->_debug($data);
1519
					}
1520
					break;
1521 2206f1b9 Mathias Andersson
				case 'citynetwork':
1522
					if (preg_match('/notfqdn/i', $data)) {
1523 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
1524 2206f1b9 Mathias Andersson
					} else if (preg_match('/nohost/i', $data)) {
1525 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("No such host");
1526 2206f1b9 Mathias Andersson
					} else if (preg_match('/nochg/i', $data)) {
1527 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1528 2206f1b9 Mathias Andersson
						$successful_update = true;
1529
					} else if (preg_match('/good/i', $data)) {
1530 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1531 2206f1b9 Mathias Andersson
						$successful_update = true;
1532
					} else if (preg_match('/badauth/i', $data)) {
1533 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1534 2206f1b9 Mathias Andersson
					} else {
1535 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1536
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
1537 2206f1b9 Mathias Andersson
						$this->_debug($data);
1538
					}
1539
					break;
1540 a4a56eb0 Stéphane
				case 'ovh-dynhost':
1541 1fa2f630 Erik Kristensen
				case 'dyndns':
1542
					if (preg_match('/notfqdn/i', $data)) {
1543 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
1544 1fa2f630 Erik Kristensen
					} else if (preg_match('/nochg/i', $data)) {
1545 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1546 0ede1bf7 Scott Ullrich
						$successful_update = true;
1547 1fa2f630 Erik Kristensen
					} else if (preg_match('/good/i', $data)) {
1548 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1549 4a6bb2ff Scott Ullrich
						$successful_update = true;
1550 1fa2f630 Erik Kristensen
					} else if (preg_match('/noauth/i', $data)) {
1551 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1552 1fa2f630 Erik Kristensen
					} else {
1553 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1554
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
1555 1fa2f630 Erik Kristensen
						$this->_debug($data);
1556
					}
1557
					break;
1558
				case 'dyndns-static':
1559
					if (preg_match('/notfqdn/i', $data)) {
1560 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
1561 1fa2f630 Erik Kristensen
					} else if (preg_match('/nochg/i', $data)) {
1562 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1563 9b8dc821 Scott Ullrich
						$successful_update = true;
1564 1fa2f630 Erik Kristensen
					} else if (preg_match('/good/i', $data)) {
1565 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
1566 4a6bb2ff Scott Ullrich
						$successful_update = true;
1567 1fa2f630 Erik Kristensen
					} else if (preg_match('/noauth/i', $data)) {
1568 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1569 1fa2f630 Erik Kristensen
					} else {
1570 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1571
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
1572 1fa2f630 Erik Kristensen
						$this->_debug($data);
1573
					}
1574
					break;
1575
				case 'dyndns-custom':
1576
					if (preg_match('/notfqdn/i', $data)) {
1577 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
1578 1fa2f630 Erik Kristensen
					} else if (preg_match('/nochg/i', $data)) {
1579 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1580 9b8dc821 Scott Ullrich
						$successful_update = true;
1581 1fa2f630 Erik Kristensen
					} else if (preg_match('/good/i', $data)) {
1582 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
1583 4a6bb2ff Scott Ullrich
						$successful_update = true;
1584 1fa2f630 Erik Kristensen
					} else if (preg_match('/noauth/i', $data)) {
1585 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1586 1fa2f630 Erik Kristensen
					} else {
1587 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1588
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
1589 1fa2f630 Erik Kristensen
						$this->_debug($data);
1590
					}
1591
					break;
1592
				case 'dhs':
1593
					break;
1594
				case 'noip':
1595 0333f968 Phil Davis
				case 'noip-free':
1596 086cf944 Phil Davis
					list($ip, $code) = explode(":", $data);
1597 1fa2f630 Erik Kristensen
					switch ($code) {
1598
						case 0:
1599 9557ca30 Phil Davis
							$status = $status_intro . $success_str . gettext("IP address is current, no update performed.");
1600 4a6bb2ff Scott Ullrich
							$successful_update = true;
1601 1fa2f630 Erik Kristensen
							break;
1602
						case 1:
1603 9557ca30 Phil Davis
							$status = $status_intro . $success_str . gettext("DNS hostname update successful.");
1604 4a6bb2ff Scott Ullrich
							$successful_update = true;
1605 1fa2f630 Erik Kristensen
							break;
1606
						case 2:
1607 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Hostname supplied does not exist.");
1608 1fa2f630 Erik Kristensen
							break;
1609
						case 3:
1610 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Invalid Username.");
1611 1fa2f630 Erik Kristensen
							break;
1612
						case 4:
1613 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Invalid Password.");
1614 1fa2f630 Erik Kristensen
							break;
1615
						case 5:
1616 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Too many updates sent.");
1617 1fa2f630 Erik Kristensen
							break;
1618
						case 6:
1619 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Account disabled due to violation of No-IP terms of service.");
1620 1fa2f630 Erik Kristensen
							break;
1621
						case 7:
1622 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Invalid IP. IP Address submitted is improperly formatted or is a private IP address or is on a blacklist.");
1623 1fa2f630 Erik Kristensen
							break;
1624
						case 8:
1625 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Disabled / Locked Hostname.");
1626 1fa2f630 Erik Kristensen
							break;
1627
						case 9:
1628 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Host updated is configured as a web redirect and no update was performed.");
1629 1fa2f630 Erik Kristensen
							break;
1630
						case 10:
1631 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Group supplied does not exist.");
1632 1fa2f630 Erik Kristensen
							break;
1633
						case 11:
1634 9557ca30 Phil Davis
							$status = $status_intro . $success_str . gettext("DNS group update is successful.");
1635 4a6bb2ff Scott Ullrich
							$successful_update = true;
1636 1fa2f630 Erik Kristensen
							break;
1637
						case 12:
1638 9557ca30 Phil Davis
							$status = $status_intro . $success_str . gettext("DNS group is current, no update performed.");
1639 4a6bb2ff Scott Ullrich
							$successful_update = true;
1640 1fa2f630 Erik Kristensen
							break;
1641
						case 13:
1642 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Update client support not available for supplied hostname or group.");
1643 1fa2f630 Erik Kristensen
							break;
1644
						case 14:
1645 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Hostname supplied does not have offline settings configured.");
1646 1fa2f630 Erik Kristensen
							break;
1647
						case 99:
1648 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Client disabled. Client should exit and not perform any more updates without user intervention.");
1649 1fa2f630 Erik Kristensen
							break;
1650
						case 100:
1651 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Client disabled. Client should exit and not perform any more updates without user intervention.");
1652 1fa2f630 Erik Kristensen
							break;
1653
						default:
1654 9557ca30 Phil Davis
							$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1655
							$this->_debug(gettext("Unknown Response:") . " " . $data);
1656 1fa2f630 Erik Kristensen
							break;
1657
					}
1658
					break;
1659
				case 'easydns':
1660
					if (preg_match('/NOACCESS/i', $data)) {
1661 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Authentication Failed: Username and/or Password was Incorrect.");
1662 1fa2f630 Erik Kristensen
					} else if (preg_match('/NOSERVICE/i', $data)) {
1663 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("No Service: Dynamic DNS Service has been disabled for this domain.");
1664 1fa2f630 Erik Kristensen
					} else if (preg_match('/ILLEGAL INPUT/i', $data)) {
1665 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Illegal Input: Self-Explanatory");
1666 1fa2f630 Erik Kristensen
					} else if (preg_match('/TOOSOON/i', $data)) {
1667 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Too Soon: Not Enough Time Has Elapsed Since Last Update");
1668 1fa2f630 Erik Kristensen
					} else if (preg_match('/NOERROR/i', $data)) {
1669 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Updated Successfully!");
1670 4a6bb2ff Scott Ullrich
						$successful_update = true;
1671 1fa2f630 Erik Kristensen
					} else {
1672 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1673
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1674 1fa2f630 Erik Kristensen
						$this->_debug($data);
1675
					}
1676
					break;
1677
				case 'hn':
1678 9b8dc821 Scott Ullrich
					/* FIXME: add checks */
1679 1fa2f630 Erik Kristensen
					break;
1680
				case 'zoneedit':
1681 9b9e5f09 Scott Ullrich
					if (preg_match('/799/i', $data)) {
1682 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Error 799") . ") " . gettext("Update Failed!");
1683 332a3e59 Scott Ullrich
					} else if (preg_match('/700/i', $data)) {
1684 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Error 700") . ") " . gettext("Update Failed!");
1685 9b9e5f09 Scott Ullrich
					} else if (preg_match('/200/i', $data)) {
1686 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1687 4a6bb2ff Scott Ullrich
						$successful_update = true;
1688 9b9e5f09 Scott Ullrich
					} else if (preg_match('/201/i', $data)) {
1689 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1690 1e0b1727 Phil Davis
						$successful_update = true;
1691 1fa2f630 Erik Kristensen
					} else {
1692 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1693
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1694 1fa2f630 Erik Kristensen
						$this->_debug($data);
1695
					}
1696
					break;
1697
				case 'dyns':
1698
					if (preg_match("/400/i", $data)) {
1699 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - The URL was malformed. Required parameters were not provided.");
1700 1fa2f630 Erik Kristensen
					} else if (preg_match('/402/i', $data)) {
1701 530e4707 NOYB
						$status = $status_intro . $error_str . gettext("Update Too Soon - Attempted to update too quickly since last change.");
1702 1fa2f630 Erik Kristensen
					} else if (preg_match('/403/i', $data)) {
1703 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Database Error - There was a server-sided database error.");
1704 1fa2f630 Erik Kristensen
					} else if (preg_match('/405/i', $data)) {
1705 1579e70f Phil Davis
						$status = $status_intro . $error_str . sprintf(gettext('Hostname Error - The hostname (%1$s) doesn\'t belong to user (%2$s).'), $this->_dnsHost, $this->_dnsUser);
1706 1fa2f630 Erik Kristensen
					} else if (preg_match('/200/i', $data)) {
1707 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1708 4a6bb2ff Scott Ullrich
						$successful_update = true;
1709 1fa2f630 Erik Kristensen
					} else {
1710 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1711
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1712 1fa2f630 Erik Kristensen
						$this->_debug($data);
1713
					}
1714
					break;
1715
				case 'ods':
1716
					if (preg_match("/299/i", $data)) {
1717 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1718 4a6bb2ff Scott Ullrich
						$successful_update = true;
1719 1fa2f630 Erik Kristensen
					} else {
1720 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1721
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1722 1fa2f630 Erik Kristensen
						$this->_debug($data);
1723
					}
1724
					break;
1725 9b8dc821 Scott Ullrich
				case 'freedns':
1726 ac16181a TechSmurf
				case 'freedns-v6':
1727 9b8dc821 Scott Ullrich
					if (preg_match("/has not changed./i", $data)) {
1728 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1729 9b8dc821 Scott Ullrich
						$successful_update = true;
1730
					} else if (preg_match("/Updated/i", $data)) {
1731 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
1732 9b8dc821 Scott Ullrich
						$successful_update = true;
1733
					} else {
1734 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1735
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1736 9b8dc821 Scott Ullrich
						$this->_debug($data);
1737 1e0b1727 Phil Davis
					}
1738 9b8dc821 Scott Ullrich
					break;
1739 0a1b0183 Ermal Luçi
				case 'dnsexit':
1740
					if (preg_match("/is the same/i", $data)) {
1741 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1742 0a1b0183 Ermal Luçi
						$successful_update = true;
1743
					} else if (preg_match("/Success/i", $data)) {
1744 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
1745 0a1b0183 Ermal Luçi
						$successful_update = true;
1746
					} else {
1747 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1748
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1749 87b91672 Phil Davis
						$this->_debug($data);
1750 0a1b0183 Ermal Luçi
					}
1751
					break;
1752 9b8dc821 Scott Ullrich
				case 'loopia':
1753
					if (preg_match("/nochg/i", $data)) {
1754 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1755 9b8dc821 Scott Ullrich
						$successful_update = true;
1756
					} else if (preg_match("/good/i", $data)) {
1757 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
1758 9b8dc821 Scott Ullrich
						$successful_update = true;
1759
					} else if (preg_match('/badauth/i', $data)) {
1760 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1761 9b8dc821 Scott Ullrich
					} else {
1762 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1763
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1764 9b8dc821 Scott Ullrich
						$this->_debug($data);
1765
					}
1766
					break;
1767 2d78b166 Ermal Luçi
				case 'opendns':
1768
					if (preg_match('/badauth/i', $data)) {
1769 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not a valid username or password!");
1770 2d78b166 Ermal Luçi
					} else if (preg_match('/nohost/i', $data)) {
1771 530e4707 NOYB
						$status = $status_intro . $error_str . gettext("Hostname specified does not exist.");
1772 2d78b166 Ermal Luçi
						$successful_update = true;
1773
					} else if (preg_match('/good/i', $data)) {
1774 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1775 2d78b166 Ermal Luçi
						$successful_update = true;
1776
					} else if (preg_match('/yours/i', $data)) {
1777 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Hostname specified exists, but not under the username specified.");
1778 2d78b166 Ermal Luçi
					} else if (preg_match('/abuse/i', $data)) {
1779 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Updating too frequently, considered abuse.");
1780 2d78b166 Ermal Luçi
					} else {
1781 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1782
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1783 2d78b166 Ermal Luçi
						$this->_debug($data);
1784
					}
1785
					break;
1786 37f3e704 Matt Corallo
				case 'staticcling':
1787 d74b5b8b sullrich
					if (preg_match("/invalid ip/i", $data)) {
1788 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - The IP provided was invalid.");
1789 d74b5b8b sullrich
					} else if (preg_match('/required info missing/i', $data)) {
1790 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - Required parameters were not provided.");
1791 d74b5b8b sullrich
					} else if (preg_match('/invalid characters/i', $data)) {
1792 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - Illegal characters in either the username or the password.");
1793 d74b5b8b sullrich
					} else if (preg_match('/bad password/i', $data)) {
1794 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Invalid password.");
1795 d74b5b8b sullrich
					} else if (preg_match('/account locked/i', $data)) {
1796 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("This account has been administratively locked.");
1797 d74b5b8b sullrich
					} else if (preg_match('/update too frequent/i', $data)) {
1798 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Updating too frequently.");
1799 d74b5b8b sullrich
					} else if (preg_match('/DB error/i', $data)) {
1800 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Server side error.");
1801 d74b5b8b sullrich
					} else if (preg_match('/success/i', $data)) {
1802 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1803 0c7bb880 Phil Davis
						$successful_update = true;
1804 d74b5b8b sullrich
					} else {
1805 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1806
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1807 0c7bb880 Phil Davis
						$this->_debug($data);
1808 d74b5b8b sullrich
					}
1809
					break;
1810 61c30081 jim-p
				case 'namecheap':
1811 18f15f68 jim-p
					$tmp = str_replace("^M", "", $data);
1812
					$ncresponse = @xml2array($tmp);
1813 61c30081 jim-p
					if (preg_match("/internal server error/i", $data)) {
1814 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Server side error.");
1815 3dc3b15b jim-p
					} else if (preg_match("/request is badly formed/i", $data)) {
1816 530e4707 NOYB
						$status = $status_intro . $error_str . gettext("Badly Formed Request (check the settings).");
1817 18f15f68 jim-p
					} else if ($ncresponse['interface-response']['ErrCount'] === "0") {
1818 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1819 c305abd5 jim-p
						$successful_update = true;
1820 18f15f68 jim-p
					} else if (is_numeric($ncresponse['interface-response']['ErrCount']) && ($ncresponse['interface-response']['ErrCount'] > 0)) {
1821 9557ca30 Phil Davis
						$status = $status_intro . $error_str . implode(", ", $ncresponse["interface-response"]["errors"]);
1822 c305abd5 jim-p
						$successful_update = true;
1823 61c30081 jim-p
					} else {
1824 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1825
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1826 61c30081 jim-p
						$this->_debug($data);
1827
					}
1828
					break;
1829 19b7263e Ionut
				case 'duiadns':
1830
				case 'duiadns-v6':
1831
					if (preg_match("/error/i", $data)) {
1832
						$status = $status_intro . $error_str . gettext("Server side error.");
1833
					} else if (preg_match('/nohost/i', $data)) {
1834
						$status = $status_intro . $error_str . gettext("Bad Request - A hostname was not provided.");
1835
					} else if (preg_match('/badauth/i', $data)) {
1836
						$status = $status_intro . $error_str . gettext("Invalid username or password.");
1837
					} else if (preg_match('/good/i', $data)) {
1838
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1839
						$successful_update = true;
1840
					} else if (preg_match('/nochg/i', $data)) {
1841
						$status = $status_intro . $success_str . gettext("No Change In IP Address.");
1842
						$successful_update = true;
1843
					} else {
1844
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1845
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1846
						$this->_debug($data);
1847
					}
1848
					break;
1849 8ea77433 Chris Wells
				case 'he-net':
1850 b4025ccd Daniel Becker
				case 'he-net-v6':
1851 8ea77433 Chris Wells
					if (preg_match("/badip/i", $data)) {
1852 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - The IP provided was invalid.");
1853 8ea77433 Chris Wells
					} else if (preg_match('/nohost/i', $data)) {
1854 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - A hostname was not provided.");
1855 8ea77433 Chris Wells
					} else if (preg_match('/badauth/i', $data)) {
1856 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Invalid username or password.");
1857 8ea77433 Chris Wells
					} else if (preg_match('/good/i', $data)) {
1858 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1859 0c7bb880 Phil Davis
						$successful_update = true;
1860 8ea77433 Chris Wells
					} else if (preg_match('/nochg/i', $data)) {
1861 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address.");
1862 0c7bb880 Phil Davis
						$successful_update = true;
1863 8ea77433 Chris Wells
					} else {
1864 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1865
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1866 0c7bb880 Phil Davis
						$this->_debug($data);
1867 8ea77433 Chris Wells
					}
1868
					break;
1869 38a481ad jim-p
				case 'he-net-tunnelbroker':
1870
					/*
1871
					-ERROR: Missing parameter(s).
1872
					-ERROR: Invalid API key or password
1873
					-ERROR: Tunnel not found
1874
					-ERROR: Another tunnel exists for this IP.
1875
					-ERROR: This tunnel is already associated with this IP address
1876
					+OK: Tunnel endpoint updated to: x.x.x.x
1877
					*/
1878
					if (preg_match("/Missing parameter/i", $data)) {
1879 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - Missing/Invalid Parameters.");
1880 38a481ad jim-p
					} else if (preg_match('/Tunnel not found/i', $data)) {
1881 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - Invalid Tunnel ID.");
1882 38a481ad jim-p
					} else if (preg_match('/Invalid API key or password/i', $data)) {
1883 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Invalid username or password.");
1884 38a481ad jim-p
					} else if (preg_match('/OK:/i', $data)) {
1885 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1886 0c7bb880 Phil Davis
						$successful_update = true;
1887 38a481ad jim-p
					} else if (preg_match('/This tunnel is already associated with this IP address/i', $data)) {
1888 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address.");
1889 0c7bb880 Phil Davis
						$successful_update = true;
1890 38a481ad jim-p
					} else {
1891 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1892
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1893 0c7bb880 Phil Davis
						$this->_debug($data);
1894 38a481ad jim-p
					}
1895
					break;
1896 fb403496 Gerald Raaf
				case 'selfhost':
1897
					if (preg_match('/notfqdn/i', $data)) {
1898 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
1899 fb403496 Gerald Raaf
					} else if (preg_match('/nochg/i', $data)) {
1900 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address.");
1901 fb403496 Gerald Raaf
						$successful_update = true;
1902
					} else if (preg_match('/good/i', $data)) {
1903 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1904 fb403496 Gerald Raaf
						$successful_update = true;
1905
					} else if (preg_match('/noauth/i', $data)) {
1906 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1907 fb403496 Gerald Raaf
					} else {
1908 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1909
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1910 fb403496 Gerald Raaf
						$this->_debug($data);
1911
					}
1912
					break;
1913 0c7bb880 Phil Davis
				case 'route53':
1914 44c64da1 Matthew Fine
				case 'route53-v6':
1915 cc5adcaa Jason McCormick
					if(preg_match('/ErrorResponse/', $data)){
1916
						$status = $status_intro . $error_str . gettext("Route53 API call failed");
1917
						log_error(sprintf("error message: %s", $data));
1918
						$status_update = false;
1919
					} else {
1920 166f4a4c Jason McCormick
						$status = $status_intro . $success_str . gettext("IP address changed successfully");
1921 cc5adcaa Jason McCormick
						$successful_update = true;
1922
					}
1923 0c7bb880 Phil Davis
					break;
1924 37f3e704 Matt Corallo
				case 'custom':
1925 da40615d Daniel Becker
				case 'custom-v6':
1926 37f3e704 Matt Corallo
					$successful_update = false;
1927
					if ($this->_dnsResultMatch == "") {
1928
						$successful_update = true;
1929 1e0b1727 Phil Davis
					} else {
1930 37f3e704 Matt Corallo
						$this->_dnsResultMatch = str_replace("%IP%", $this->_dnsIP, $this->_dnsResultMatch);
1931
						$matches = preg_split("/(?<!\\\\)\\|/", $this->_dnsResultMatch);
1932 1e0b1727 Phil Davis
						foreach ($matches as $match) {
1933 37f3e704 Matt Corallo
							$match= str_replace("\\|", "|", $match);
1934 1e0b1727 Phil Davis
							if (strcmp($match, trim($data, "\t\n\r")) == 0) {
1935 37f3e704 Matt Corallo
								$successful_update = true;
1936 1e0b1727 Phil Davis
							}
1937 37f3e704 Matt Corallo
						}
1938
						unset ($matches);
1939
					}
1940 1e0b1727 Phil Davis
					if ($successful_update == true) {
1941 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1942 1e0b1727 Phil Davis
					} else {
1943 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Result did not match.") . " [" . $data . "]";
1944 1e0b1727 Phil Davis
					}
1945 37f3e704 Matt Corallo
					break;
1946 3a05e4c3 Austin Seipp
				case 'cloudflare-v6':
1947 e26e1f76 Andrew Senetar
				case 'cloudflare':
1948 22d95a68 doktornotor
					$output = json_decode($data);
1949 4e322e2c Phil Davis
					if ($output->result->content === $this->_dnsIP) {
1950 9557ca30 Phil Davis
						$status = $status_intro . $success_str . sprintf(gettext('%1$s updated to %2$s'), $this->_dnsHost, $this->_dnsIP);
1951 22d95a68 doktornotor
						$successful_update = true;
1952 4e322e2c Phil Davis
					} elseif ($output->errors[0]->code === 9103) {
1953 07a84ece robjarsen
						$status = $status_intro . $error_str . gettext("Invalid Credentials! Don't forget to use API Key for password field with Cloudflare.");
1954 4e322e2c Phil Davis
					} elseif (($output->success) && (!$output->result[0]->id)) {
1955 530e4707 NOYB
						$status = $status_intro . $error_str . gettext("Zone or Host ID was not found, check the hostname.");
1956 4e322e2c Phil Davis
					} else {
1957 9557ca30 Phil Davis
						$status = $status_intro . gettext("UNKNOWN ERROR") . " - " . $output->errors[0]->message;
1958
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1959 ffa1acdc Andrew Senetar
					}
1960
					break;
1961 ec66caa6 John Byron
				case 'eurodns':
1962
					if (preg_match('/notfqdn/i', $data)) {
1963 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
1964 ec66caa6 John Byron
					} else if (preg_match('/nochg/i', $data)) {
1965 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1966 ec66caa6 John Byron
						$successful_update = true;
1967
					} else if (preg_match('/good/i', $data)) {
1968 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1969 ec66caa6 John Byron
						$successful_update = true;
1970
					} else if (preg_match('/badauth/i', $data)) {
1971 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1972 ec66caa6 John Byron
					} else {
1973 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1974
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1975 ec66caa6 John Byron
						$this->_debug($data);
1976
					}
1977
					break;
1978 5458bc59 Scavy
				case 'gratisdns':
1979
					if (preg_match('/Forkerte værdier/i', $data)) {
1980 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Wrong values - Update could not be completed.");
1981 5458bc59 Scavy
					} else if (preg_match('/Bruger login: Bruger eksistere ikke/i', $data)) {
1982 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Unknown username - User does not exist.");
1983 5458bc59 Scavy
					} else if (preg_match('/Bruger login: 1Fejl i kodeord/i', $data)) {
1984 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Wrong password - Remember password is case sensitive.");
1985 5458bc59 Scavy
					} else if (preg_match('/Domæne kan IKKE administreres af bruger/i', $data)) {
1986 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User unable to administer the selected domain.");
1987 5458bc59 Scavy
					} else if (preg_match('/OK/i', $data)) {
1988 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1989 1e0b1727 Phil Davis
						$successful_update = true;
1990 5458bc59 Scavy
					} else {
1991 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1992
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1993 1e0b1727 Phil Davis
						$this->_debug($data);
1994 5458bc59 Scavy
					}
1995
					break;
1996 544674ad Grant Sheehan
				case 'digitalocean':
1997 0c43f825 Matthew Fine
				case 'digitalocean-v6':
1998 5878d529 Grant Sheehan
					// Creating new records returns an HTTP 201, updating existing records get 200
1999
					// https://redmine.pfsense.org/issues/9171
2000
					if (preg_match("/HTTP\/2\s20[0,1]/i", $header)) {
2001 544674ad Grant Sheehan
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2002
						$successful_update = true;
2003
					} else {
2004
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2005
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2006
						$this->_debug($data);
2007
					}
2008
					break;
2009 916d683e surrural
				case 'dnsimple':
2010
					/* Responds with HTTP 200 on success.
2011
					   Responds with HTTP 4xx on error.
2012
					   Returns JSON data as body */
2013 0e0f580d Christoph Filnkößl
;
2014 6c7d0571 Paul Sadauskas
                                        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
2015
					
2016
					if ($code == "200") {
2017 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2018 916d683e surrural
						$successful_update = true;
2019 6c7d0571 Paul Sadauskas
					} else if (preg_match("/4\d\d/i", $code)) {
2020 0e0f580d Christoph Filnkößl
						$arrbody = json_decode($data, true);
2021 916d683e surrural
						$message = $arrbody['message'] . ".";
2022
						if (isset($arrbody['errors']['content'])) {
2023 1e0b1727 Phil Davis
							foreach ($arrbody['errors']['content'] as $key => $content) {
2024 916d683e surrural
								$message .= " " . $content . ".";
2025
							}
2026
						}
2027 9557ca30 Phil Davis
						$status = $status_intro . $error_str . $message;
2028 916d683e surrural
					} else {
2029 6c7d0571 Paul Sadauskas
						$status = $status_intro . "(" . gettext("Unknown Response") . ": " . $code .")";
2030 0e0f580d Christoph Filnkößl
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2031
						$this->_debug($data);
2032 916d683e surrural
					}
2033
					break;
2034 456ba14f Sam Neely
				case 'godaddy':
2035
				case 'godaddy-v6':
2036
					/* Responds with HTTP 200 on success.
2037
					   Responds with HTTP 4xx or  on error.
2038
					   Returns JSON data as body */
2039
;
2040
					if (preg_match("/\s200\sOK/i", $header)) {
2041
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2042
						$successful_update = true;
2043
					} else if (preg_match("/\s4\d\d\s/i", $header)) {
2044
						$arrbody = json_decode($data, true);
2045
						$message = $arrbody['message'] . ".";
2046
						if (isset($arrbody['fields'])) {
2047
							foreach ($arrbody['fields'] as $error) {
2048
								$message .= " " . $error['path'] . ": " . $error['message'] . ".";
2049
							}
2050
						}
2051
						$status = $status_intro . $error_str . $message;
2052
					} else {
2053
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2054
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2055
						$this->_debug($data);
2056
					}
2057
					break;
2058 c5ecdc25 Jose Luis Duran
				case 'googledomains':
2059 6c92b378 Christopher Fazendin
					if (preg_match('/notfqdn/i', $data)) {
2060 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN");
2061 6c92b378 Christopher Fazendin
					} else if (preg_match('/nochg/i', $data)) {
2062 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2063 6c92b378 Christopher Fazendin
						$successful_update = true;
2064
					} else if (preg_match('/good/i', $data)) {
2065 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2066 6c92b378 Christopher Fazendin
						$successful_update = true;
2067
					} else if (preg_match('/badauth/i', $data)) {
2068 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2069 c5ecdc25 Jose Luis Duran
					} else if (preg_match('/nohost/i', $data)) {
2070 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Hostname does not exist or DynDNS not enabled");
2071 c5ecdc25 Jose Luis Duran
					} else if (preg_match('/badagent/i', $data)) {
2072 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad request");
2073 c5ecdc25 Jose Luis Duran
					} else if (preg_match('/abuse/i', $data)) {
2074 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Dynamic DNS access has been blocked!");
2075 c5ecdc25 Jose Luis Duran
					} else if (preg_match('/911/i', $data)) {
2076 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Error on Google's end, retry in 5 minutes");
2077 6c92b378 Christopher Fazendin
					} else {
2078 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2079
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2080 6c92b378 Christopher Fazendin
						$this->_debug($data);
2081
					}
2082
					break;
2083 c5ecdc25 Jose Luis Duran
				case 'dnsmadeeasy':
2084
					switch ($data) {
2085
						case 'success':
2086 9557ca30 Phil Davis
							$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2087 c5ecdc25 Jose Luis Duran
							$successful_update = true;
2088
							break;
2089
						case 'error-auth':
2090 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Invalid username or password");
2091 c5ecdc25 Jose Luis Duran
							break;
2092
						case 'error-auth-suspend':
2093 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Account suspended");
2094 c5ecdc25 Jose Luis Duran
							break;
2095
						case 'error-auth-voided':
2096 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Account revoked");
2097 c5ecdc25 Jose Luis Duran
							break;
2098
						case 'error-record-invalid':
2099 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Record does not exist in the system. Unable to update record");
2100 c5ecdc25 Jose Luis Duran
							break;
2101
						case 'error-record-auth':
2102 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("User does not have access to this record");
2103 c5ecdc25 Jose Luis Duran
							break;
2104
						case 'error-record-ip-same':
2105 9557ca30 Phil Davis
							$status = $status_intro . $success_str . gettext("No Change In IP Address");
2106 c5ecdc25 Jose Luis Duran
							$successful_update = true;
2107
							break;
2108
						case 'error-system':
2109 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("General system error recognized by the system");
2110 c5ecdc25 Jose Luis Duran
							break;
2111
						case 'error':
2112 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("General system error unrecognized by the system");
2113 c5ecdc25 Jose Luis Duran
							break;
2114
						default:
2115 9557ca30 Phil Davis
							$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2116
							log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2117 c5ecdc25 Jose Luis Duran
							$this->_debug($data);
2118
							break;
2119
					}
2120
					break;
2121 1c2c08bd exii1988
				case 'spdyn':
2122
				case 'spdyn-v6':
2123 f3ee8545 Rene Schuster
					if (preg_match('/notfqdn/i', $data)) {
2124 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
2125 f3ee8545 Rene Schuster
					} else if (preg_match('/nohost/i', $data)) {
2126 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("No such host");
2127 f3ee8545 Rene Schuster
					} else if (preg_match('/nochg/i', $data)) {
2128 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2129
						$successful_update = true;
2130 f3ee8545 Rene Schuster
					} else if (preg_match('/good/i', $data)) {
2131 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2132
						$successful_update = true;
2133 f3ee8545 Rene Schuster
					} else if (preg_match('/badauth/i', $data)) {
2134 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2135 f3ee8545 Rene Schuster
					} else {
2136 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2137
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2138
						$this->_debug($data);
2139 f3ee8545 Rene Schuster
					}
2140
					break;
2141 575b1dcf Christoph Filnkößl
				case 'all-inkl':
2142
 					if (preg_match('/good\s'.$this->_dnsIP.'/i', $data)) {
2143
							$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2144
 							$successful_update = true;
2145
 					} else if (preg_match('/good/i', $data)) {
2146
						$status = $status_intro . $error_str . gettext("Result did not match.");
2147
					} else if (preg_match("/\s401\sUnauthorized/i", $header)) {
2148
						$status = $status_intro . $error_str . gettext("Invalid username or password");
2149 c5e1ce90 robjarsen
					}
2150 575b1dcf Christoph Filnkößl
					else {
2151
							$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2152
							log_error($status_intro . gettext("PAYLOAD:") . " " . $header.$data);
2153
 							$this->_debug($data);
2154
 							$this->_debug($header);
2155
 					}
2156
 					break;
2157 74533d41 xygrec
				case 'hover':
2158
					if (preg_match('/succeeded":true/i', $data)) {
2159
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2160
						$successful_update = true;
2161
					} else {
2162
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2163
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2164
						$this->_debug($data);
2165
					}
2166
					break;
2167 745d3779 Wagner Sartori Junior
				case 'cloudns':
2168
					$result = json_decode($data, true);
2169
					if ($result['status'] == 'Success') {
2170
						$successful_update = true;
2171
					} else {
2172
						log_error($result['status'] . "(" . $result['statusDescription'] . ")");
2173
					}
2174
					break;
2175 9a3ec9a5 frank
				case 'dreamhost':
2176
				case 'dreamhost-v6':
2177
					$result = json_decode($data,true);
2178
					if ($this->_dnsVerboseLog) {
2179
						log_error(sprintf(gettext('_checkStatus() results: %1$s'), $data));
2180
					}
2181
					switch ($result['data']) {
2182 e350558a frank
					case 'success':
2183
					case 'record_added':
2184
					case 'record_removed':
2185
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2186
						$successful_update = true;
2187
						break;
2188
					case 'no_record':
2189
					case 'no_such_record ':
2190
						$status = $status_intro . $error_str . gettext("No record exists.");
2191
						break;
2192 598c1d97 frank
					case 'no_type':
2193 e350558a frank
					case 'no_such_type ':
2194
						$status = $status_intro . $error_str . gettext("No type exists.");
2195
						break;
2196 598c1d97 frank
					case 'no_value':
2197 e350558a frank
					case 'no_such_value ':
2198
						$status = $status_intro . $error_str . gettext("No value exists.");
2199
						break;
2200
					case 'no_such_zone':
2201
						$status = $status_intro . $error_str . gettext("No such zone exists.");
2202
						break;
2203
					case 'invalid_record':
2204
						$status = $status_intro . $error_str . gettext("The specified record is invalid.");
2205
						break;
2206
					case 'invalid_type':
2207
						$status = $status_intro . $error_str . gettext("The specified type is invalid.");
2208
						break;
2209
					case 'invalid_value':
2210
						$status = $status_intro . $error_str . gettext("The specified value is invalid.");
2211
						break;
2212
					case 'not_editable ':
2213
						$status = $status_intro . $error_str . gettext("Record is not editable.");
2214
						break;
2215
					case 'record_already_exists_not_editable':
2216
						$status = $status_intro . $error_str . gettext("Record exists but is not editable.");
2217
						break;
2218
					case 'record_already_exists_remove_first':
2219
						$status = $status_intro . $error_str . gettext("Record exists and must be removed before adding.");
2220
						break;
2221
					case 'internal_error_updating_zone':
2222
						$status = $status_intro . $error_str . gettext("A remote server error occurred updating the zone.");
2223
						break;
2224
					case 'internal_error_could_not_load_zone':
2225
						$status = $status_intro . $error_str . gettext("A remote server error occurred loading the zone.");
2226
						break;
2227
					case 'internal_error_could_not_update_zone':
2228
						$status = $status_intro . $error_str . gettext("A remote server error occurred updating the zone.");
2229
						break;
2230
					case 'internal_error_could_not_add_record':
2231
						$status = $status_intro . $error_str . gettext("A remote server error occurred adding a new record.");
2232
						break;
2233
					case 'internal_error_could_not_destroy_record ':
2234
						$status = $status_intro . $error_str . gettext("A remote server error occurred removing an existing record.");
2235
						break;
2236
					default:
2237
						break;
2238 9a3ec9a5 frank
					}
2239 1ac3c88a martgras
				case 'azure':
2240
				case 'azurev6':
2241
					$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
2242
					if ($http_code == 401) {
2243
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2244
					} else if ($http_code == 201) {
2245
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2246
						$successful_update = true;
2247
					} else if ($http_code == 200) {
2248
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2249
						$successful_update = true;
2250
					} else {
2251
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2252
						log_error($status_intro . gettext("PAYLOAD:") . " " . $http_code);
2253
						$this->_debug($data);
2254
					}
2255 493e4284 robjarsen
					break;
2256 b923a825 Tom Embt
				case 'linode':
2257
				case 'linode-v6':
2258
					$status_intro = gettext("Dynamic DNS") . " {$this->_dnsService} ({$this->_FQDN}): ";
2259
					$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
2260
					$result = json_decode($data,true);
2261
					if ($this->_dnsVerboseLog) {
2262
						log_error(sprintf(gettext('_checkStatus() results: %1$s'), $data));
2263
					}
2264
					if ($http_code == 200 && isset($result["id"]) && ! isset($result["errors"])) {
2265
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2266
						$successful_update = true;
2267
					} else if ( $http_code == 401 && preg_match('/not authorized to use/i', $data) ) {
2268
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2269
					} else {
2270
						$status = $status_intro . $error_str .
2271 bd0a29ea Tom Embt
							( isset($domains_result["errors"][0]["reason"]) ? $domains_result["errors"][0]["reason"] : "HTTP {$http_code}" );
2272 b923a825 Tom Embt
					}
2273
					break;
2274 edfe22f8 Eric Vantillard
				case 'gandi-livedns':
2275
					// NOTE: same as azure
2276
					// Creating new records returns an HTTP 201, updating existing records get 200
2277
					$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
2278
					if ($http_code == 401) {
2279
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2280
					} else if ($http_code == 201) {
2281
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2282
						$successful_update = true;
2283
					} else if ($http_code == 200) {
2284
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2285
						$successful_update = true;
2286
					} else {
2287
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2288
						log_error($status_intro . gettext("PAYLOAD:") . " " . $http_code);
2289
						$this->_debug($data);
2290
					}
2291
					break;
2292 9a3ec9a5 frank
				default:
2293
					break;
2294 1fa2f630 Erik Kristensen
			}
2295 916d683e surrural
2296 1e0b1727 Phil Davis
			if ($successful_update == true) {
2297 4a6bb2ff Scott Ullrich
				/* Write WAN IP to cache file */
2298 22de7804 Bill Marquette
				$wan_ip = $this->_checkIP();
2299 d7e6f573 Daniel Becker
				if ($this->_useIPv6 == false && $wan_ip > 0) {
2300 53842a6c jim-p
					$currentTime = time();
2301 9557ca30 Phil Davis
					notify_all_remote(sprintf(gettext('DynDNS updated IP Address on %1$s (%2$s) to %3$s'), convert_real_interface_to_friendly_descr($this->_if), $this->_if, $wan_ip));
2302
					log_error(sprintf(gettext('phpDynDNS: updating cache file %1$s: %2$s'), $this->_cacheFile, $wan_ip));
2303 d51cdd48 Renato Botelho
					@file_put_contents($this->_cacheFile, "{$wan_ip}|{$currentTime}");
2304 1e0b1727 Phil Davis
				} else {
2305 dd575ea4 Ermal
					@unlink($this->_cacheFile);
2306 1e0b1727 Phil Davis
				}
2307 d7e6f573 Daniel Becker
				if ($this->_useIPv6 == true && $wan_ip > 0) {
2308 b4025ccd Daniel Becker
					$currentTime = time();
2309 1579e70f Phil Davis
					notify_all_remote(sprintf(gettext('DynDNS updated IPv6 Address on %1$s (%2$s) to %3$s'), convert_real_interface_to_friendly_descr($this->_if), $this->_if, $wan_ip));
2310 9557ca30 Phil Davis
					log_error(sprintf(gettext('phpDynDNS: updating cache file %1$s: %2$s'), $this->_cacheFile_v6, $wan_ip));
2311 b4319c50 Daniel Becker
					@file_put_contents($this->_cacheFile_v6, "{$wan_ip}|{$currentTime}");
2312 1e0b1727 Phil Davis
				} else {
2313 d7e6f573 Daniel Becker
					@unlink($this->_cacheFile_v6);
2314 1e0b1727 Phil Davis
				}
2315 4a6bb2ff Scott Ullrich
			}
2316 1fa2f630 Erik Kristensen
			$this->status = $status;
2317
			log_error($status);
2318
		}
2319
2320
		/*
2321
		 * Private Function (added 12 July 05) [beta]
2322
		 *   Return Error, Set Last Error, and Die.
2323
		 */
2324
		function _error($errorNumber = '1') {
2325 9557ca30 Phil Davis
			$err_str = 'phpDynDNS: (' . gettext('ERROR!') . ') ';
2326
			$err_str_r53 = 'Route 53: (' . gettext('Error') . ') ';
2327 1fa2f630 Erik Kristensen
			switch ($errorNumber) {
2328
				case 0:
2329
					break;
2330
				case 2:
2331 9557ca30 Phil Davis
					$error = $err_str . gettext('No Dynamic DNS Service provider was selected.');
2332 1fa2f630 Erik Kristensen
					break;
2333
				case 3:
2334 9557ca30 Phil Davis
					$error = $err_str . gettext('No Username Provided.');
2335 1fa2f630 Erik Kristensen
					break;
2336
				case 4:
2337 9557ca30 Phil Davis
					$error = $err_str . gettext('No Password Provided.');
2338 1fa2f630 Erik Kristensen
					break;
2339
				case 5:
2340 9557ca30 Phil Davis
					$error = $err_str . gettext('No Hostname Provided.');
2341 1fa2f630 Erik Kristensen
					break;
2342
				case 6:
2343 9557ca30 Phil Davis
					$error = $err_str . gettext('The Dynamic DNS Service provided is not yet supported.');
2344 1fa2f630 Erik Kristensen
					break;
2345 9b8dc821 Scott Ullrich
				case 7:
2346 9557ca30 Phil Davis
					$error = $err_str . gettext('No Update URL Provided.');
2347 9b8dc821 Scott Ullrich
					break;
2348 0c7bb880 Phil Davis
				case 8:
2349 9557ca30 Phil Davis
					$status = $err_str_r53 . gettext("Invalid ZoneID");
2350 cd132e86 Edson Brandi
					break;
2351 0c7bb880 Phil Davis
				case 9:
2352 9557ca30 Phil Davis
					$status = $err_str_r53 . gettext("Invalid TTL");
2353 1e0b1727 Phil Davis
					break;
2354 1fa2f630 Erik Kristensen
				case 10:
2355 9557ca30 Phil Davis
					$error = "phpDynDNS ({$this->_FQDN}): " . sprintf(gettext("No change in my IP address and/or %s days has not passed. Not updating dynamic DNS entry."), $this->_dnsMaxCacheAgeDays);
2356 1fa2f630 Erik Kristensen
					break;
2357
				default:
2358 9557ca30 Phil Davis
					$error = $err_str . gettext('Unknown Response.');
2359 9b8dc821 Scott Ullrich
					/* FIXME: $data isn't in scope here */
2360
					/* $this->_debug($data); */
2361 1fa2f630 Erik Kristensen
					break;
2362
			}
2363
			$this->lastError = $error;
2364
			log_error($error);
2365
		}
2366
2367
		/*
2368
		 * Private Function (added 12 July 05) [beta]
2369
		 *   - Detect whether or not IP needs to be updated.
2370 5775f324 Chris Buechler
		 *      | Written Specifically for pfSense (https://www.pfsense.org) may
2371 1fa2f630 Erik Kristensen
		 *      | work with other systems. pfSense base is FreeBSD.
2372
		 */
2373
		function _detectChange() {
2374 dceff62e Ermal
			global $debug;
2375
2376 1e0b1727 Phil Davis
			if ($debug) {
2377 9557ca30 Phil Davis
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _detectChange() starting.'), $this->_dnsService, $this->_FQDN));
2378 1e0b1727 Phil Davis
			}
2379
2380 1fa2f630 Erik Kristensen
			$currentTime = time();
2381
2382 22de7804 Bill Marquette
			$wan_ip = $this->_checkIP();
2383 dd575ea4 Ermal
			if ($wan_ip == 0) {
2384 9557ca30 Phil Davis
				log_error(sprintf(gettext("Dynamic Dns (%s): Current WAN IP could not be determined, skipping update process."), $this->_FQDN));
2385 193ee786 Ermal
				return false;
2386 dd575ea4 Ermal
			}
2387 9557ca30 Phil Davis
			$log_error = sprintf(gettext('Dynamic Dns (%1$s): Current WAN IP: %2$s'), $this->_FQDN, $wan_ip) . " ";
2388 1fa2f630 Erik Kristensen
2389 d7e6f573 Daniel Becker
			if ($this->_useIPv6 == true) {
2390
				if (file_exists($this->_cacheFile_v6)) {
2391
					$contents = file_get_contents($this->_cacheFile_v6);
2392 086cf944 Phil Davis
					list($cacheIP, $cacheTime) = explode('|', $contents);
2393 d7e6f573 Daniel Becker
					$this->_debug($cacheIP.'/'.$cacheTime);
2394
					$initial = false;
2395 9557ca30 Phil Davis
					$log_error .= sprintf(gettext("Cached IPv6: %s"), $cacheIP);
2396 d7e6f573 Daniel Becker
				} else {
2397
					$cacheIP = '::';
2398 b4319c50 Daniel Becker
					@file_put_contents($this->_cacheFile, "::|{$currentTime}");
2399 d7e6f573 Daniel Becker
					$cacheTime = $currentTime;
2400
					$initial = true;
2401 9557ca30 Phil Davis
					$log_error .= gettext("No Cached IPv6 found.");
2402 d7e6f573 Daniel Becker
				}
2403 1fa2f630 Erik Kristensen
			} else {
2404 d7e6f573 Daniel Becker
				if (file_exists($this->_cacheFile)) {
2405
					$contents = file_get_contents($this->_cacheFile);
2406 d51cdd48 Renato Botelho
					list($cacheIP, $cacheTime) = explode('|', $contents);
2407 d7e6f573 Daniel Becker
					$this->_debug($cacheIP.'/'.$cacheTime);
2408
					$initial = false;
2409 9557ca30 Phil Davis
					$log_error .= sprintf(gettext("Cached IP: %s"), $cacheIP);
2410 d7e6f573 Daniel Becker
				} else {
2411
					$cacheIP = '0.0.0.0';
2412 d51cdd48 Renato Botelho
					@file_put_contents($this->_cacheFile, "0.0.0.0|{$currentTime}");
2413 d7e6f573 Daniel Becker
					$cacheTime = $currentTime;
2414
					$initial = true;
2415 9557ca30 Phil Davis
					$log_error .= gettext("No Cached IP found.");
2416 d7e6f573 Daniel Becker
				}
2417 1fa2f630 Erik Kristensen
			}
2418 1e0b1727 Phil Davis
			if ($this->_dnsVerboseLog) {
2419 87b91672 Phil Davis
				log_error($log_error);
2420 1e0b1727 Phil Davis
			}
2421 1fa2f630 Erik Kristensen
2422 f5e293e6 Phil Davis
			// Convert seconds = days * hr/day * min/hr * sec/min
2423
			$maxCacheAgeSecs = $this->_dnsMaxCacheAgeDays * 24 * 60 * 60;
2424 1fa2f630 Erik Kristensen
2425 e24b26e9 Scott Ullrich
			$needs_updating = FALSE;
2426 4494cf6a Chris Buechler
			/* lets determine if the item needs updating */
2427 a255e1f7 Scott Ullrich
			if ($cacheIP != $wan_ip) {
2428 eb346556 Ermal Lu?i
				$needs_updating = true;
2429 9557ca30 Phil Davis
				$update_reason = gettext("Dynamic Dns: cacheIP != wan_ip. Updating.") . " ";
2430
				$update_reason .= sprintf(gettext('Cached IP: %1$s WAN IP: %2$s'), $cacheIP, $wan_ip) . " ";
2431 a255e1f7 Scott Ullrich
			}
2432 f5e293e6 Phil Davis
			if (($currentTime - $cacheTime) > $maxCacheAgeSecs) {
2433 c3c3e03b Ermal
				$needs_updating = true;
2434 0333f968 Phil Davis
				$this->_forceUpdateNeeded = true;
2435 9557ca30 Phil Davis
				$update_reason = sprintf(gettext("Dynamic Dns: More than %s days. Updating."), $this->_dnsMaxCacheAgeDays);
2436
				$update_reason .= " {$currentTime} - {$cacheTime} > {$maxCacheAgeSecs} ";
2437 a255e1f7 Scott Ullrich
			}
2438 eb346556 Ermal Lu?i
			if ($initial == true) {
2439
				$needs_updating = true;
2440 9557ca30 Phil Davis
				$update_reason .= gettext("Initial update.");
2441 a255e1f7 Scott Ullrich
			}
2442 eb346556 Ermal Lu?i
2443 a255e1f7 Scott Ullrich
			/*   finally if we need updating then store the
2444
			 *   new cache value and return true
2445 0c7bb880 Phil Davis
			 */
2446 eb346556 Ermal Lu?i
			if ($needs_updating == true) {
2447 086cf944 Phil Davis
				if ($this->_dnsVerboseLog) {
2448 6635aa0f jim-p
					log_error("DynDns ({$this->_FQDN}): {$update_reason}");
2449 086cf944 Phil Davis
				}
2450 eb346556 Ermal Lu?i
				return true;
2451 1fa2f630 Erik Kristensen
			}
2452 eb346556 Ermal Lu?i
2453 1e0b1727 Phil Davis
			return false;
2454 1fa2f630 Erik Kristensen
		}
2455
2456
		/*
2457 0c7bb880 Phil Davis
		 * Private Function (added 16 July 05) [beta]
2458 1fa2f630 Erik Kristensen
		 *   - Writes debug information to a file.
2459
		 *   - This function is only called when a unknown response
2460
		 *   - status is returned from a DynDNS service provider.
2461
		 */
2462 6a45171d Ermal
		function _debug($data) {
2463
			global $g;
2464
2465 1e0b1727 Phil Davis
			if (!$g['debug']) {
2466 6a45171d Ermal
				return;
2467 1e0b1727 Phil Davis
			}
2468 bb9ccd63 bcyrill
			$string = date('m-d-y h:i:s').' - ('.$this->_debugID.') - ['.$this->_dnsService.'] - '.$data."\n";
2469 1fa2f630 Erik Kristensen
			$file = fopen($this->_debugFile, 'a');
2470
			fwrite($file, $string);
2471
			fclose($file);
2472
		}
2473 22de7804 Bill Marquette
		function _checkIP() {
2474 dceff62e Ermal
			global $debug;
2475 22de7804 Bill Marquette
2476 1e0b1727 Phil Davis
			if ($debug) {
2477 9557ca30 Phil Davis
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkIP() starting.'), $this->_dnsService, $this->_FQDN));
2478 1e0b1727 Phil Davis
			}
2479 22de7804 Bill Marquette
2480 d7e6f573 Daniel Becker
			if ($this->_useIPv6 == true) {
2481 d20a3d08 Chris Buechler
				$ip_address = get_interface_ipv6($this->_if);
2482 1e0b1727 Phil Davis
				if (!is_ipaddrv6($ip_address)) {
2483 d7e6f573 Daniel Becker
					return 0;
2484 1e0b1727 Phil Davis
				}
2485 d7e6f573 Daniel Becker
			} else {
2486 be060079 jim-p
				$ip_address = dyndnsCheckIP($this->_if);
2487 1e0b1727 Phil Davis
				if (!is_ipaddr($ip_address)) {
2488 d7e6f573 Daniel Becker
					return 0;
2489 1e0b1727 Phil Davis
				}
2490 d7e6f573 Daniel Becker
			}
2491 be060079 jim-p
			if ($this->_useIPv6 == false && is_private_ip(get_interface_ip($this->_if))) {
2492 87b91672 Phil Davis
				if (is_ipaddr($ip_address)) {
2493 1e0b1727 Phil Davis
					if ($this->_dnsVerboseLog) {
2494 be060079 jim-p
						log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): %3$s extracted from Check IP Service'), $this->_dnsService, $this->_FQDN, $ip_address));
2495 1e0b1727 Phil Davis
					}
2496 87b91672 Phil Davis
				} else {
2497 be060079 jim-p
					log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): IP address could not be extracted from Check IP Service'), $this->_dnsService, $this->_FQDN));
2498 c749ef62 Ermal
					return 0;
2499
				}
2500 87b91672 Phil Davis
			} else {
2501 1e0b1727 Phil Davis
				if ($this->_dnsVerboseLog) {
2502 9557ca30 Phil Davis
					log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): %3$s extracted from local system.'), $this->_dnsService, $this->_FQDN, $ip_address));
2503 1e0b1727 Phil Davis
				}
2504 87b91672 Phil Davis
			}
2505 fffbfef0 Matt Corallo
			$this->_dnsIP = $ip_address;
2506
2507 22de7804 Bill Marquette
			return $ip_address;
2508
		}
2509 1fa2f630 Erik Kristensen
2510
	}
2511
2512 aa7c49b9 Ermal
?>