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