Project

General

Profile

Download (129 KB) Statistics
| Branch: | Tag: | Revision:
1 d237be68 Scott Ullrich
<?php
2 ac24dc24 Renato Botelho
/*
3
 * dyndns.class
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6 38809d47 Renato Botelho do Couto
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8 8f2f85c3 Luiz Otavio O Souza
 * Copyright (c) 2014-2022 Rubicon Communications, LLC (Netgate)
9 ac24dc24 Renato Botelho
 * All rights reserved.
10
 *
11 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
12
 * you may not use this file except in compliance with the License.
13
 * You may obtain a copy of the License at
14 ac24dc24 Renato Botelho
 *
15 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
16 ac24dc24 Renato Botelho
 *
17 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
18
 * distributed under the License is distributed on an "AS IS" BASIS,
19
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
 * See the License for the specific language governing permissions and
21
 * limitations under the License.
22 ac24dc24 Renato Botelho
 */
23
24 1fa2f630 Erik Kristensen
	/*
25
	 * PHP.updateDNS (pfSense version)
26
	 *
27
	 * +====================================================+
28
	 *  Services Supported:
29 f56efb0d Jaakko Kantojärvi
	 *    - All-Inkl (all-inkl.com)
30
	 *    - Amazon Route 53 (aws.amazon.com)
31
	 *    - Azure DNS (azure.microsoft.com)
32
	 *    - City Network (citynetwork.se)
33
	 *    - Cloudflare (www.cloudflare.com)
34
	 *    - Cloudflare IPv6 (www.cloudflare.com)
35 691d0458 Jaakko Kantojärvi
	 *    - ClouDNS (www.cloudns.net)
36 f56efb0d Jaakko Kantojärvi
	 *    - Custom DDNS (any URL)
37
	 *    - Custom DDNS IPv6 (any URL)
38 9e8300cb Inperpetuammemoriam
	 *    - deSEC (desec.io)
39 f56efb0d Jaakko Kantojärvi
	 *    - DHS (www.dhs.org)
40
	 *    - DNS Made Easy (www.dnsmadeeasy.com)
41
	 *    - DNS-O-Matic (dnsomatic.com)
42
	 *    - DNSexit (dnsexit.com)
43
	 *    - DNSimple (dnsimple.com)
44
	 *    - DreamHost DNS (www.dreamhost.com)
45
	 *    - DuiaDNS (www.duiadns.net)
46
	 *    - DuiaDNS IPv6 (www.duiadns.net)
47 230ac725 Jaakko Kantojärvi
	 *    - DY.fi (dy.fi)
48 9b8dc821 Scott Ullrich
	 *    - DynDns (dyndns.org) [dynamic, static, custom]
49 f56efb0d Jaakko Kantojärvi
	 *    - DynS (dyns.org)
50
	 *    - Dynv6 (www.dynv6.com)
51 1fa2f630 Erik Kristensen
	 *    - EasyDNS (easydns.com)
52 00105b36 wurzelpanzer
	 *    - EasyDNS IPv6 (easydns.com)
53 f56efb0d Jaakko Kantojärvi
	 *    - Eurodns (eurodns.com)
54 49d54787 Ricky Burgin
	 *    - FreeDNS API v1 (freedns.afraid.org)
55
	 *    - FreeDNS API v2 (freedns.afraid.org)
56 f56efb0d Jaakko Kantojärvi
	 *    - FreeDNS IPv6 API v1 (freedns.afraid.org)
57 49d54787 Ricky Burgin
	 *    - FreeDNS IPv6 API v2 (freedns.afraid.org)
58 edfe22f8 Eric Vantillard
	 *    - Gandi LiveDNS (www.gandi.net)
59 e0a4147b surrural
	 *    - GleSYS (glesys.com)
60 f56efb0d Jaakko Kantojärvi
	 *    - GoDaddy (www.godaddy.com)
61 6c92b378 Christopher Fazendin
	 *    - Google Domains (domains.google.com)
62 f56efb0d Jaakko Kantojärvi
	 *    - GratisDNS (gratisdns.dk)
63
	 *    - HE.net (dns.he.net)
64
	 *    - HE.net IPv6 (dns.he.net)
65
	 *    - HE.net Tunnelbroker IP update (ipv4.tunnelbroker.net)
66
	 *    - HN (hn.org) -- incomplete checking!
67
	 *    - Hover (www.hover.com)
68
	 *    - Loopia (loopia.se)
69 6a9fe85f olehfb
	 *    - Name.com (name.com)
70
	 *    - Name.com IPv6 (name.com)
71 f56efb0d Jaakko Kantojärvi
	 *    - Namecheap (namecheap.com)
72
	 *    - No-IP (no-ip.com)
73
	 *    - OpenDNS (opendns.com)
74 691d0458 Jaakko Kantojärvi
	 *    - SelfHost (selfhost.de)
75 1c2c08bd exii1988
	 *    - SPDYN (spdyn.de)
76
	 *    - SPDYN IPv6 (spdyn.de)
77 f56efb0d Jaakko Kantojärvi
	 *    - StaticCling (staticcling.org)
78 dc6eb05f Dennis Neuhaeuser
	 *    - Strato (www.strato.de)
79 f56efb0d Jaakko Kantojärvi
	 *    - ZoneEdit (zoneedit.com)
80 1fa2f630 Erik Kristensen
	 * +----------------------------------------------------+
81
	 *  Requirements:
82 37f3e704 Matt Corallo
	 *    - PHP version 4.0.2 or higher with the CURL Library and the PCRE Library
83 1fa2f630 Erik Kristensen
	 * +----------------------------------------------------+
84
	 *  Public Functions
85
	 *    - updatedns()
86
	 *
87
	 *  Private Functions
88
	 *    - _update()
89
	 *    - _checkStatus()
90
	 *    - _error()
91
	 *    - _detectChange()
92
	 *    - _debug()
93 22de7804 Bill Marquette
	 *    - _checkIP()
94 1fa2f630 Erik Kristensen
	 * +----------------------------------------------------+
95 f56efb0d Jaakko Kantojärvi
	 *  All-Inkl        - Last Tested: 12 November 2016
96
	 *  Amazon Route 53 - Last Tested: 04 February 2017
97
	 *  Azure DNS       - Last Tested: 08 March 2018
98
	 *  City Network    - Last Tested: 13 November 2013
99
	 *  Cloudflare      - Last Tested: 05 September 2016
100
	 *  Cloudflare IPv6 - Last Tested: 17 July 2016
101 691d0458 Jaakko Kantojärvi
	 *  ClouDNS         - Last Tested: 22 August 2017
102 9e8300cb Inperpetuammemoriam
	 *  deSEC           - Last Tested: NEVER
103
	 *  deSEC IPv6      - Last Tested: NEVER
104 f56efb0d Jaakko Kantojärvi
	 *  DHS             - Last Tested: 12 July 2005
105 691d0458 Jaakko Kantojärvi
	 *  DigitalOcean    - Not Yet Tested
106 f56efb0d Jaakko Kantojärvi
	 *  DNS Made Easy   - Last Tested: 27 April 2015
107
	 *  DNS-O-Matic     - Last Tested: 9 September 2010
108 17f81cb6 Koen Zomers
	 *  DNSexit         - Last Tested: 27 June 2022
109 f56efb0d Jaakko Kantojärvi
	 *  DNSimple        - Last Tested: 09 February 2015
110
	 *  DreamHost       - Last Tested: 30 April 2017
111
	 *  DreamHost IPv6  - Not Yet Tested
112
	 *  DuiaDNS         - Last Tested: 25 November 2016
113
	 *  DuiaDNS IPv6    - Last Tested: 25 November 2016
114 230ac725 Jaakko Kantojärvi
	 *  DY.fi           - Last Tested: 22 April 2021
115 f56efb0d Jaakko Kantojärvi
	 *  DynDNS Custom   - Last Tested: NEVER
116 01c155f2 Phil Davis
	 *  DynDNS Dynamic  - Last Tested: 12 July 2005
117
	 *  DynDNS Static   - Last Tested: NEVER
118
	 *  Dyns            - Last Tested: NEVER
119 f56efb0d Jaakko Kantojärvi
	 *  EasyDNS         - Last Tested: 20 July 2008
120
	 *  Eurodns         - Last Tested: 27 June 2013
121 ac16181a TechSmurf
	 *  FreeDNS         - Last Tested: 01 May 2016
122
	 *  FreeDNS IPv6    - Last Tested: 01 May 2016
123 49d54787 Ricky Burgin
	 *  FreeDNS IPv6 v2 - Last Tested: 01 June 2020
124 f56efb0d Jaakko Kantojärvi
	 *  FreeDNS v2      - Last Tested: 01 June 2020
125
	 *  Gandi LiveDNS   - Not Yet Tested
126
	 *  GleSYS          - Last Tested: 3 February 2015
127
	 *  GoDaddy         - Last Tested: 22 November 2017
128
	 *  GoDaddy IPv6    - Last Tested: 22 November 2017
129
	 *  Google Domains  - Last Tested: 27 April 2015
130
	 *  GratisDNS       - Last Tested: 15 August 2012
131 01c155f2 Phil Davis
	 *  HE.net          - Last Tested: 7 July 2013
132
	 *  HE.net IPv6     - Last Tested: 7 July 2013
133
	 *  HE.net Tunnel   - Last Tested: 28 June 2011
134 f56efb0d Jaakko Kantojärvi
	 *  HN.org          - Last Tested: 12 July 2005
135
	 *  Hover           - Last Tested: 15 February 2017
136
	 *  Loopia          - Last Tested: 21 August 2019
137 6a9fe85f olehfb
	 *  Name.com        - Last Tested: 5 Dec 2021
138
	 *  Name.com IPv6   - Last Tested: 5 Dec 2021
139 f56efb0d Jaakko Kantojärvi
	 *  Namecheap       - Last Tested: 31 August 2010
140
	 *  No-IP           - Last Tested: 20 July 2008
141
	 *  ODS             - Last Tested: 02 August 2005
142
	 *  OpenDNS         - Last Tested: 4 August 2008
143 691d0458 Jaakko Kantojärvi
	 *  OVH DynHOST     - Last Tested: NEVER
144
	 *  SelfHost        - Last Tested: 26 December 2011
145 1c2c08bd exii1988
	 *  SPDYN           - Last Tested: 02 July 2016
146
	 *  SPDYN IPv6      - Last Tested: 02 July 2016
147 f56efb0d Jaakko Kantojärvi
	 *  StaticCling     - Last Tested: 27 April 2006
148 dc6eb05f Dennis Neuhaeuser
	 *  Strato          - Last Tested: 29 May 2021
149 f56efb0d Jaakko Kantojärvi
	 *  ZoneEdit        - Last Tested: NEVER
150 1fa2f630 Erik Kristensen
	 * +====================================================+
151
	 *
152 e24b26e9 Scott Ullrich
	 * @author 	E.Kristensen
153 1fa2f630 Erik Kristensen
	 * @link    	http://www.idylldesigns.com/projects/phpdns/
154 0da417be Erik Kristensen
	 * @version 	0.8
155 e24b26e9 Scott Ullrich
	 * @updated	13 October 05 at 21:02:42 GMT
156 1fa2f630 Erik Kristensen
	 *
157 17f81cb6 Koen Zomers
	 * DNSexit/OpenDNS support and multiwan extension for pfSense by Ermal Luçi and Koen Zomers
158 37f3e704 Matt Corallo
	 * Custom DNS support by Matt Corallo
159 0a1b0183 Ermal Luçi
	 *
160 1fa2f630 Erik Kristensen
	 */
161
162
	class updatedns {
163 67ee1ec5 Ermal Luçi
		var $_cacheFile;
164 d7e6f573 Daniel Becker
		var $_cacheFile_v6;
165 67ee1ec5 Ermal Luçi
		var $_debugFile;
166 ce9a9572 Philip Soeberg
		var $_UserAgent = 'phpDynDNS/0.7';
167 1fa2f630 Erik Kristensen
		var $_errorVerbosity = 0;
168
		var $_dnsService;
169
		var $_dnsUser;
170
		var $_dnsPass;
171
		var $_dnsHost;
172 6635aa0f jim-p
		var $_dnsDomain;
173
		var $_FQDN;
174 1fa2f630 Erik Kristensen
		var $_dnsIP;
175
		var $_dnsWildcard;
176 e10d25b4 CarlGill
		var $_dnsProxied;
177 1fa2f630 Erik Kristensen
		var $_dnsMX;
178
		var $_dnsBackMX;
179 9b8dc821 Scott Ullrich
		var $_dnsServer;
180
		var $_dnsPort;
181
		var $_dnsUpdateURL;
182 cd132e86 Edson Brandi
		var $_dnsZoneID;
183
		var $_dnsTTL;
184 1fa2f630 Erik Kristensen
		var $status;
185
		var $_debugID;
186 67ee1ec5 Ermal Luçi
		var $_if;
187 37f3e704 Matt Corallo
		var $_dnsResultMatch;
188
		var $_dnsRequestIf;
189
		var $_dnsRequestIfIP;
190 87b91672 Phil Davis
		var $_dnsVerboseLog;
191 aa79f351 Sebastian Chrostek
		var $_curlIpresolveV4;
192
		var $_curlSslVerifypeer;
193 f5e293e6 Phil Davis
		var $_dnsMaxCacheAgeDays;
194 0333f968 Phil Davis
		var $_dnsDummyUpdateDone;
195
		var $_forceUpdateNeeded;
196 b4025ccd Daniel Becker
		var $_useIPv6;
197 9a3ec9a5 frank
		var $_existingRecords;
198 fd331bdc Viktor G
		var $_curlProxy;
199 1e0b1727 Phil Davis
200
		/*
201 1fa2f630 Erik Kristensen
		 * Public Constructor Function (added 12 July 05) [beta]
202 1e0b1727 Phil Davis
		 *   - Gets the dice rolling for the update.
203 37f3e704 Matt Corallo
		 *   - $dnsResultMatch should only be used with $dnsService = 'custom'
204 1e0b1727 Phil Davis
		 *   -  $dnsResultMatch is parsed for '%IP%', which is the IP the provider was updated to,
205 1bf52c67 Phil Davis
		 *   -  it is otherwise expected to be exactly identical to what is returned by the Provider.
206 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.
207
		 *   - $For custom requests, $dnsUpdateURL is parsed for '%IP%', which is replaced with the new IP.
208 1fa2f630 Erik Kristensen
		 */
209 d43154fe Renato Botelho do Couto
		function __construct($dnsService = '', $dnsHost = '', $dnsDomain = '', $dnsUser = '', $dnsPass = '',
210 e10d25b4 CarlGill
					$dnsWildcard = 'OFF', $dnsProxied = false, $dnsMX = '', $dnsIf = '', $dnsBackMX = '',
211 1e0b1727 Phil Davis
					$dnsServer = '', $dnsPort = '', $dnsUpdateURL = '', $forceUpdate = false,
212 82caf945 Jaakko Kantojärvi
					$dnsZoneID ='', $dnsTTL='', $dnsResultMatch = '', $dnsRequestIf = '', $dnsMaxCacheAge = '',
213 fd331bdc Viktor G
					$dnsID = '', $dnsVerboseLog = false, $curlIpresolveV4 = false, $curlSslVerifypeer = true,
214
					$curlProxy = false) {
215 1e0b1727 Phil Davis
216 2446fffa jim-p
			global $config, $g, $dyndns_split_domain_types;
217
			if (in_array($dnsService, $dyndns_split_domain_types)) {
218 6635aa0f jim-p
				$this->_FQDN = $dnsHost . "." . $dnsDomain;
219
			} else {
220
				$this->_FQDN = $dnsHost;
221
			}
222
223
			$this->_cacheFile = "{$g['conf_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($this->_FQDN) . "{$dnsID}.cache";
224
			$this->_cacheFile_v6 = "{$g['conf_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($this->_FQDN) . "{$dnsID}_v6.cache";
225
			$this->_debugFile = "{$g['varetc_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($this->_FQDN) . "{$dnsID}.debug";
226 67ee1ec5 Ermal Luçi
227 aa79f351 Sebastian Chrostek
			$this->_curlIpresolveV4 = $curlIpresolveV4;
228
			$this->_curlSslVerifypeer = $curlSslVerifypeer;
229 fd331bdc Viktor G
			$this->_curlProxy = $curlProxy;
230 87b91672 Phil Davis
			$this->_dnsVerboseLog = $dnsVerboseLog;
231 1e0b1727 Phil Davis
			if ($this->_dnsVerboseLog) {
232 9557ca30 Phil Davis
				log_error(gettext("Dynamic DNS: updatedns() starting"));
233 1e0b1727 Phil Davis
			}
234 71070cc5 Ermal
235 f9734a1a Balázs Váradi
			$dyndnslck = lock("DDNS" . $dnsID, LOCK_EX);
236 71070cc5 Ermal
237 1fa2f630 Erik Kristensen
			if (!$dnsService) $this->_error(2);
238 ce6d1106 jim-p
			switch ($dnsService) {
239 f56efb0d Jaakko Kantojärvi
			case 'custom':
240
			case 'custom-v6':
241
				if (!$dnsUpdateURL) $this->_error(7);
242 2446fffa jim-p
				break;
243 f56efb0d Jaakko Kantojärvi
			// providers in an alphabetical order (based on the first provider in a group of cases)
244
			case 'azure':
245
			case 'azurev6':
246
				if (!$dnsUser) $this->_error(3);
247 88d878f2 Chris Pick
				if (!$dnsPass) $this->_error(4);
248
				if (!$dnsHost) $this->_error(5);
249 f56efb0d Jaakko Kantojärvi
				if (!$dnsZoneID) $this->_error(8);
250
				if (!$dnsTTL) $this->_error(9);
251 88d878f2 Chris Pick
				break;
252 f56efb0d Jaakko Kantojärvi
			case 'cloudflare':
253
			case 'cloudflare-v6':
254 9b8dc821 Scott Ullrich
				if (!$dnsPass) $this->_error(4);
255
				if (!$dnsHost) $this->_error(5);
256 6635aa0f jim-p
				if (!$dnsDomain) $this->_error(5);
257 ce6d1106 jim-p
				break;
258 745d3779 Wagner Sartori Junior
			case 'cloudns':
259 f56efb0d Jaakko Kantojärvi
			case 'godaddy':
260
			case 'godaddy-v6':
261 745d3779 Wagner Sartori Junior
				if (!$dnsUser) $this->_error(3);
262
				if (!$dnsPass) $this->_error(4);
263
				if (!$dnsHost) $this->_error(5);
264
				if (!$dnsDomain) $this->_error(5);
265
				if (!$dnsTTL) $this->_error(9);
266
				break;
267 9e8300cb Inperpetuammemoriam
			case 'desec':
268
			case 'desec-v6':
269
				if (!$dnsPass) $this->_error(4);
270
				if (!$dnsHost) $this->_error(5);
271
				break;
272 544674ad Grant Sheehan
			case 'digitalocean':
273 0c43f825 Matthew Fine
			case 'digitalocean-v6':
274 f56efb0d Jaakko Kantojärvi
			case 'gandi-livedns':
275
			case 'gandi-livedns-v6':
276 b923a825 Tom Embt
			case 'linode':
277
			case 'linode-v6':
278 4e820dc1 Viktor G
			case 'onecom':
279
			case 'onecom-v6':
280
			case 'yandex':
281
			case 'yandex-v6':
282 544674ad Grant Sheehan
				if (!$dnsPass) $this->_error(4);
283
				if (!$dnsHost) $this->_error(5);
284
				if (!$dnsDomain) $this->_error(5);
285 32cb54c3 Grant Sheehan
				if (!$dnsTTL) $this->_error(9);
286
				break;
287 f56efb0d Jaakko Kantojärvi
			case 'freedns':
288
			case 'freedns-v6':
289
			case 'freedns2':
290
			case 'freedns2-v6':
291
				if (!$dnsHost) $this->_error(5);
292
				break;
293
			case 'gratisdns':
294
			case 'hover':
295 6a9fe85f olehfb
			case 'name.com':
296
			case 'name.com-v6':
297 1ac3c88a martgras
				if (!$dnsUser) $this->_error(3);
298
				if (!$dnsPass) $this->_error(4);
299
				if (!$dnsHost) $this->_error(5);
300 f56efb0d Jaakko Kantojärvi
				if (!$dnsDomain) $this->_error(5);
301
				break;
302
			case 'namecheap':
303
				if (!$dnsPass) $this->_error(4);
304
				if (!$dnsHost) $this->_error(5);
305
				if (!$dnsDomain) $this->_error(5);
306
				break;
307
			case 'route53':
308
			case 'route53-v6':
309 1ac3c88a martgras
				if (!$dnsZoneID) $this->_error(8);
310
				if (!$dnsTTL) $this->_error(9);
311 544674ad Grant Sheehan
				break;
312 ce6d1106 jim-p
			default:
313
				if (!$dnsUser) $this->_error(3);
314
				if (!$dnsPass) $this->_error(4);
315 99295d7b Scott Ullrich
				if (!$dnsHost) $this->_error(5);
316 9b8dc821 Scott Ullrich
			}
317 1e0b1727 Phil Davis
318 b4025ccd Daniel Becker
			switch ($dnsService) {
319 f56efb0d Jaakko Kantojärvi
				case 'azurev6':
320
				case 'cloudflare-v6':
321
				case 'custom-v6':
322 9e8300cb Inperpetuammemoriam
				case 'desec-v6':
323 0c43f825 Matthew Fine
				case 'digitalocean-v6':
324 77a0eb0d Zac West
				case 'dnsimple-v6':
325 4d6cc223 Viktor G
				case 'domeneshop-v6':
326 f56efb0d Jaakko Kantojärvi
				case 'dreamhost-v6':
327 19b7263e Ionut
				case 'duiadns-v6':
328 f56efb0d Jaakko Kantojärvi
				case 'dynv6-v6':
329
				case 'easydns-v6':
330 ac16181a TechSmurf
				case 'freedns-v6':
331 c7df496c Ricky Burgin
				case 'freedns2-v6':
332 f56efb0d Jaakko Kantojärvi
				case 'gandi-livedns-v6':
333 456ba14f Sam Neely
				case 'godaddy-v6':
334 f56efb0d Jaakko Kantojärvi
				case 'he-net-v6':
335 b923a825 Tom Embt
				case 'linode-v6':
336 fe6b1252 Viktor G
				case 'mythicbeasts-v6':
337 6a9fe85f olehfb
				case 'name.com-v6':
338 91aa6dfd Csoban Kesmarki
				case 'noip-free-v6':
339 f56efb0d Jaakko Kantojärvi
				case 'noip-v6':
340
				case 'route53-v6':
341
				case 'spdyn-v6':
342 4e820dc1 Viktor G
				case 'yandex-v6':
343 1e0b1727 Phil Davis
					$this->_useIPv6 = true;
344
					break;
345
				default:
346
					$this->_useIPv6 = false;
347 b4025ccd Daniel Becker
			}
348 1fa2f630 Erik Kristensen
			$this->_dnsService = strtolower($dnsService);
349
			$this->_dnsUser = $dnsUser;
350 86584ded jim-p
			$this->_dnsPass = base64_decode($dnsPass);
351 1fa2f630 Erik Kristensen
			$this->_dnsHost = $dnsHost;
352 6635aa0f jim-p
			$this->_dnsDomain = $dnsDomain;
353 9b8dc821 Scott Ullrich
			$this->_dnsServer = $dnsServer;
354
			$this->_dnsPort = $dnsPort;
355
			$this->_dnsWildcard = $dnsWildcard;
356 e10d25b4 CarlGill
			$this->_dnsProxied = $dnsProxied;
357 9b8dc821 Scott Ullrich
			$this->_dnsMX = $dnsMX;
358 0c7bb880 Phil Davis
			$this->_dnsZoneID = $dnsZoneID;
359
			$this->_dnsTTL = $dnsTTL;
360 bf001dec smos
			$this->_if = get_failover_interface($dnsIf);
361 fffbfef0 Matt Corallo
			$this->_checkIP();
362 37f3e704 Matt Corallo
			$this->_dnsUpdateURL = $dnsUpdateURL;
363
			$this->_dnsResultMatch = $dnsResultMatch;
364 c3474eef Viktor G
			if (($this->_dnsService == 'custom') || ($this->_dnsService == 'custom-v6')) {
365
				$this->_dnsRequestIf = get_failover_interface($dnsRequestIf);
366
			} else {
367
				$this->_dnsRequestIf = $this->_if;
368
			}
369 2c393b55 jim-p
			if (($dnsMaxCacheAge !== null) && ($dnsMaxCacheAge !== "")) {
370 82caf945 Jaakko Kantojärvi
				$this->_dnsMaxCacheAgeDays = (int)$dnsMaxCacheAge;
371
			} else {
372 230ac725 Jaakko Kantojärvi
				switch ($dnsService) {
373
					// exceptions to _dnsMaxCacheAgeDays in an alphabetical order
374
					case 'dyfi':
375
						$this->_dnsMaxCacheAgeDays = 6;
376
						break;
377
					default:
378
						$this->_dnsMaxCacheAgeDays = 25;
379
				}
380 82caf945 Jaakko Kantojärvi
			}
381 1e0b1727 Phil Davis
			if ($this->_dnsVerboseLog) {
382 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));
383 1e0b1727 Phil Davis
			}
384 37f3e704 Matt Corallo
			$this->_dnsRequestIfIP = get_interface_ip($dnsRequestIf);
385 0333f968 Phil Davis
			$this->_dnsDummyUpdateDone = false;
386
			$this->_forceUpdateNeeded = $forceUpdate;
387 1e0b1727 Phil Davis
388 0c7bb880 Phil Davis
			// Ensure that we were able to lookup the IP
389 1e0b1727 Phil Davis
			if (!is_ipaddr($this->_dnsIP)) {
390 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));
391 fffbfef0 Matt Corallo
				unlock($dyndnslck);
392
				return;
393
			}
394 07a3b40b sullrich
395 1fa2f630 Erik Kristensen
			$this->_debugID = rand(1000000, 9999999);
396 1e0b1727 Phil Davis
397 d7e6f573 Daniel Becker
			if ($forceUpdate == false && $this->_detectChange() == false) {
398 1fa2f630 Erik Kristensen
				$this->_error(10);
399
			} else {
400 9d96a475 Ermal Lu?i
				switch ($this->_dnsService) {
401 f56efb0d Jaakko Kantojärvi
					case 'all-inkl':
402
					case 'azure':
403
					case 'azurev6':
404
					case 'citynetwork':
405
					case 'cloudflare':
406
					case 'cloudflare-v6':
407
					case 'cloudns':
408
					case 'custom':
409
					case 'custom-v6':
410 9e8300cb Inperpetuammemoriam
					case 'desec':
411
					case 'desec-v6':
412 f56efb0d Jaakko Kantojärvi
					case 'dhs':
413
					case 'digitalocean':
414
					case 'digitalocean-v6':
415
					case 'dnsexit':
416
					case 'dnsimple':
417 77a0eb0d Zac West
					case 'dnsimple-v6':
418 f56efb0d Jaakko Kantojärvi
					case 'dnsmadeeasy':
419 1e0b1727 Phil Davis
					case 'dnsomatic':
420 4d6cc223 Viktor G
					case 'domeneshop':
421
					case 'domeneshop-v6':
422 f56efb0d Jaakko Kantojärvi
					case 'duiadns':
423
					case 'duiadns-v6':
424 230ac725 Jaakko Kantojärvi
					case 'dyfi':
425 1e0b1727 Phil Davis
					case 'dyndns':
426
					case 'dyndns-custom':
427 f56efb0d Jaakko Kantojärvi
					case 'dyndns-static':
428
					case 'dyns':
429
					case 'dynv6':
430
					case 'dynv6-v6':
431 1e0b1727 Phil Davis
					case 'easydns':
432 00105b36 wurzelpanzer
					case 'easydns-v6':
433 f56efb0d Jaakko Kantojärvi
					case 'eurodns':
434 1e0b1727 Phil Davis
					case 'freedns':
435 ac16181a TechSmurf
					case 'freedns-v6':
436 c7df496c Ricky Burgin
					case 'freedns2':
437
					case 'freedns2-v6':
438 f56efb0d Jaakko Kantojärvi
					case 'gandi-livedns':
439
					case 'gandi-livedns-v6':
440
					case 'glesys':
441
					case 'godaddy':
442
					case 'godaddy-v6':
443
					case 'googledomains':
444
					case 'gratisdns':
445
					case 'he-net':
446
					case 'he-net-tunnelbroker':
447
					case 'he-net-v6':
448
					case 'hn':
449
					case 'hover':
450
					case 'linode':
451
					case 'linode-v6':
452 1e0b1727 Phil Davis
					case 'loopia':
453 f56efb0d Jaakko Kantojärvi
					case 'mythicbeasts':
454
					case 'mythicbeasts-v6':
455 6a9fe85f olehfb
					case 'name.com':
456
					case 'name.com-v6':
457 1e0b1727 Phil Davis
					case 'namecheap':
458 4e820dc1 Viktor G
					case 'nicru':
459
					case 'nicru-v6':
460 f56efb0d Jaakko Kantojärvi
					case 'noip':
461
					case 'noip-free':
462
					case 'noip-free-v6':
463
					case 'noip-v6':
464
					case 'ods':
465
					case 'opendns':
466
					case 'ovh-dynhost':
467 1e0b1727 Phil Davis
					case 'route53':
468 44c64da1 Matthew Fine
					case 'route53-v6':
469 f56efb0d Jaakko Kantojärvi
					case 'selfhost':
470 1c2c08bd exii1988
					case 'spdyn':
471
					case 'spdyn-v6':
472 f56efb0d Jaakko Kantojärvi
					case 'staticcling':
473 dc6eb05f Dennis Neuhaeuser
					case 'strato':
474 e7de40d5 Viktor G
					case 'onecom':
475
					case 'onecom-v6':
476 4e820dc1 Viktor G
					case 'yandex':
477
					case 'yandex-v6':
478 f56efb0d Jaakko Kantojärvi
					case 'zoneedit':
479 0333f968 Phil Davis
						$this->_update();
480 1e0b1727 Phil Davis
						if ($this->_dnsDummyUpdateDone == true) {
481
							// If a dummy update was needed, then sleep a while and do the update again to put the proper address back.
482
							// Some providers (e.g. No-IP free accounts) need to have at least 1 address change every month.
483
							// If the address has not changed recently, or the user did "Force Update", then the code does
484
							// a dummy address change for providers like this.
485
							sleep(10);
486
							$this->_update();
487
						}
488
						break;
489 9a3ec9a5 frank
					case 'dreamhost':
490
					case 'dreamhost-v6':
491
						$this->_lookup_current();
492
						if (isset($this->status)) {
493
							return;
494
						}
495
						foreach ($this->_existingRecords as $record) {
496
							$this->_remove($record['existing_val']);
497
							$this->_update();
498
						}
499
						break;
500 1e0b1727 Phil Davis
					default:
501
						$this->_error(6);
502
						break;
503 1fa2f630 Erik Kristensen
				}
504 9d96a475 Ermal Lu?i
			}
505 71070cc5 Ermal
506
			unlock($dyndnslck);
507 1fa2f630 Erik Kristensen
		}
508 1e0b1727 Phil Davis
509 1fa2f630 Erik Kristensen
		/*
510
		 * Private Function (added 12 July 05) [beta]
511
		 *   Send Update To Selected Service.
512
		 */
513
		function _update() {
514 1e0b1727 Phil Davis
515
			if ($this->_dnsVerboseLog) {
516 9557ca30 Phil Davis
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _update() starting.'), $this->_dnsService, $this->_FQDN));
517 1e0b1727 Phil Davis
			}
518 b37b4034 Phil Davis
519 f1d3adf1 Chris Buechler
			if (strstr($this->_dnsRequestIf, "_vip")) {
520 ac5c0cfe Chris Buechler
				$parentif = get_configured_vip_interface($this->_dnsRequestIf);
521 f1d3adf1 Chris Buechler
				$realparentif = convert_friendly_interface_to_real_interface_name($parentif);
522
			} else {
523
				$realparentif = $this->_dnsRequestIf;
524
			}
525 1e0b1727 Phil Davis
526 0ec4b3b4 Chris Buechler
			$ch = curl_init();
527
528 becd6caa Chris Buechler
			if ($this->_useIPv6 == false) {
529 4e322e2c Phil Davis
				curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
530 becd6caa Chris Buechler
			}
531
532 15dcf132 PiBa-NL
			if ($this->_dnsService != 'ods') {
533 1fa2f630 Erik Kristensen
				curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
534
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
535 f1d3adf1 Chris Buechler
				curl_setopt($ch, CURLOPT_INTERFACE, 'if!' . $realparentif);
536 93b8df2a Ermal
				curl_setopt($ch, CURLOPT_TIMEOUT, 120); // Completely empirical
537 1fa2f630 Erik Kristensen
			}
538
539
			switch ($this->_dnsService) {
540 f56efb0d Jaakko Kantojärvi
				// The special custom provider
541
				case 'custom':
542
				case 'custom-v6':
543
					if (strstr($this->dnsUpdateURL, "%IP%")) {$needsIP = TRUE;} else {$needsIP = FALSE;}
544
					if ($this->_dnsUser != '') {
545
						if ($this->_curlIpresolveV4) {
546
							curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
547
						}
548
						if ($this->_curlSslVerifypeer) {
549 7054b63f Viktor G
							/* required for a local CA
550
							 * see https://redmine.pfsense.org/issues/12589 */
551
							curl_setopt($ch, CURLOPT_CAPATH, "/etc/ssl/certs/");
552 f56efb0d Jaakko Kantojärvi
							curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
553
						} else {
554
							curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
555
						}
556
						curl_setopt($ch, CURLOPT_USERPWD, "{$this->_dnsUser}:{$this->_dnsPass}");
557
					}
558
					$server = str_replace("%IP%", $this->_dnsIP, $this->_dnsUpdateURL);
559
					if ($this->_dnsVerboseLog) {
560
						log_error(sprintf(gettext("Sending request to: %s"), $server));
561
					}
562
					curl_setopt($ch, CURLOPT_URL, $server);
563
					break;
564
				// Providers in an alphabetical order. Add code for new providers below in a correct position.
565 230ac725 Jaakko Kantojärvi
				case 'dyfi':
566
					// see specification at https://www.dy.fi/page/specification
567
					$needsIP = FALSE;
568
					$server = 'https://www.dy.fi/nic/update';
569
					curl_setopt($ch, CURLOPT_USERPWD, "{$this->_dnsUser}:{$this->_dnsPass}");
570
					curl_setopt($ch, CURLOPT_URL, "{$server}?hostname={$this->_dnsHost}");
571
					break;
572 197cf433 McB
				case 'glesys':
573
					$needsIP = TRUE;
574
					$server = 'https://api.glesys.com/domain/updaterecord/format/json';
575 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
576 6635aa0f jim-p
					$post_data['recordid'] = $this->_FQDN;
577 197cf433 McB
					$post_data['data'] = $this->_dnsIP;
578
					curl_setopt($ch, CURLOPT_URL, $server);
579
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
580
					break;
581 f56efb0d Jaakko Kantojärvi
				//
582
				// Not yet ordered providers.
583
				// TODO: When editing a provider, move it above in a correct position.
584
				//
585 1fa2f630 Erik Kristensen
				case 'dyndns':
586
				case 'dyndns-static':
587 52e95286 Ermal
				case 'dyndns-custom':
588 1fa2f630 Erik Kristensen
					$needsIP = FALSE;
589 1e0b1727 Phil Davis
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") {
590
						$this->_dnsWildcard = "ON";
591
					}
592 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
593 9b8dc821 Scott Ullrich
					$server = "https://members.dyndns.org/nic/update";
594
					$port = "";
595 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
596 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
597 1e0b1727 Phil Davis
					}
598
					if ($this->_dnsPort) {
599 9b8dc821 Scott Ullrich
						$port = ":" . $this->_dnsPort;
600 1e0b1727 Phil Davis
					}
601 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?system=dyndns&hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard=' . $this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NO');
602 1fa2f630 Erik Kristensen
					break;
603
				case 'dhs':
604 34c9962b Chris Buechler
					// DHS is disabled in the GUI because the following doesn't work.
605 1fa2f630 Erik Kristensen
					$needsIP = TRUE;
606 a255e1f7 Scott Ullrich
					$post_data['hostscmd'] = 'edit';
607
					$post_data['hostscmdstage'] = '2';
608
					$post_data['type'] = '4';
609
					$post_data['updatetype'] = 'Online';
610
					$post_data['mx'] = $this->_dnsMX;
611
					$post_data['mx2'] = '';
612
					$post_data['txt'] = '';
613
					$post_data['offline_url'] = '';
614
					$post_data['cloak'] = 'Y';
615
					$post_data['cloak_title'] = '';
616
					$post_data['ip'] = $this->_dnsIP;
617
					$post_data['domain'] = 'dyn.dhs.org';
618
					$post_data['hostname'] = $this->_dnsHost;
619
					$post_data['submit'] = 'Update';
620 9b8dc821 Scott Ullrich
					$server = "https://members.dhs.org/nic/hosts";
621
					$port = "";
622 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
623 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
624 1e0b1727 Phil Davis
					}
625
					if ($this->_dnsPort) {
626
						$port = ":" . $this->_dnsPort;
627
					}
628 34c9962b Chris Buechler
					curl_setopt($ch, CURLOPT_URL, $server . $port);
629 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
630 1fa2f630 Erik Kristensen
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
631
					break;
632 91aa6dfd Csoban Kesmarki
				case 'noip-v6':
633
				case 'noip-free-v6':
634
					$needsIP = TRUE;
635 3501e0c4 Viktor G
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
636
					$server = "https://dynupdate.no-ip.com/nic/update";
637 91aa6dfd Csoban Kesmarki
					$port = "";
638
					if ($this->_dnsServer) {
639
						$server = $this->_dnsServer;
640
					}
641
					if ($this->_dnsPort) {
642
						$port = ":" . $this->_dnsPort;
643
					}
644
					if (($this->_dnsService == "noip-free-v6") &&
645
					    ($this->_forceUpdateNeeded == true) &&
646
					    ($this->_dnsDummyUpdateDone == false)) {
647
						// Update the IP to a dummy value to force No-IP free accounts to see a change.
648
						$iptoset = "fd00:d::1";
649
						$this->_dnsDummyUpdateDone = true;
650 1c67c475 Csoban Kesmarki
						$log_message = 'Dynamic DNS %1$s (%2$s): ';
651
						$log_message .= 'Processing dummy update on No-IP free account. ';
652
						$log_message .= 'IP temporarily set to %3$s';
653
						log_error(sprintf(gettext($log_message), $this->_dnsService, $this->_dnsHost, $iptoset));
654 91aa6dfd Csoban Kesmarki
					} else {
655
						$iptoset = $this->_dnsIP;
656
					}
657 1c67c475 Csoban Kesmarki
					curl_setopt($ch, CURLOPT_URL, $url_data);
658 3501e0c4 Viktor G
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?hostname=' . $this->_dnsHost . '&myipv6=' . $iptoset);
659 91aa6dfd Csoban Kesmarki
					break;
660 1fa2f630 Erik Kristensen
				case 'noip':
661 0333f968 Phil Davis
				case 'noip-free':
662 1fa2f630 Erik Kristensen
					$needsIP = TRUE;
663 4aab19d4 Viktor G
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
664 3501e0c4 Viktor G
					$server = "https://dynupdate.no-ip.com/nic/update";
665 9b8dc821 Scott Ullrich
					$port = "";
666 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
667 472da675 Phil Davis
						$server = $this->_dnsServer;
668 1e0b1727 Phil Davis
					}
669
					if ($this->_dnsPort) {
670 9b8dc821 Scott Ullrich
						$port = ":" . $this->_dnsPort;
671 1e0b1727 Phil Davis
					}
672
					if (($this->_dnsService == "noip-free") &&
673 ae52d165 Renato Botelho
					    ($this->_forceUpdateNeeded == true) &&
674
					    ($this->_dnsDummyUpdateDone == false)) {
675 0333f968 Phil Davis
						// Update the IP to a dummy value to force No-IP free accounts to see a change.
676
						$iptoset = "192.168.1.1";
677
						$this->_dnsDummyUpdateDone = true;
678 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));
679 0333f968 Phil Davis
					} else {
680
						$iptoset = $this->_dnsIP;
681
					}
682 3501e0c4 Viktor G
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?hostname=' . $this->_dnsHost . '&myip=' . $iptoset);
683 1fa2f630 Erik Kristensen
					break;
684
				case 'easydns':
685
					$needsIP = TRUE;
686 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
687 64746cf6 Chris Buechler
					$server = "https://members.easydns.com/dyn/dyndns.php";
688 9b8dc821 Scott Ullrich
					$port = "";
689 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
690 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
691 1e0b1727 Phil Davis
					}
692
					if ($this->_dnsPort) {
693 9b8dc821 Scott Ullrich
						$port = ":" . $this->_dnsPort;
694 1e0b1727 Phil Davis
					}
695 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);
696 1fa2f630 Erik Kristensen
					break;
697 00105b36 wurzelpanzer
				case 'easydns-v6':
698
					$needsIP = TRUE;
699
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
700
					$server = "https://members.easydns.com/dyn/dyndns.php";
701
					$port = "";
702
					if ($this->_dnsServer) {
703
						$server = $this->_dnsServer;
704
					}
705
					if ($this->_dnsPort) {
706
						$port = ":" . $this->_dnsPort;
707
					}
708
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard=' . $this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=' . $this->_dnsBackMX);
709
					break;
710 1fa2f630 Erik Kristensen
				case 'hn':
711
					$needsIP = TRUE;
712 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
713 9b8dc821 Scott Ullrich
					$server = "http://dup.hn.org/vanity/update";
714
					$port = "";
715 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
716 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
717 1e0b1727 Phil Davis
					}
718
					if ($this->_dnsPort) {
719 9b8dc821 Scott Ullrich
						$port = ":" . $this->_dnsPort;
720 1e0b1727 Phil Davis
					}
721 cd8f5ccd Scott Ullrich
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?ver=1&IP=' . $this->_dnsIP);
722 1fa2f630 Erik Kristensen
					break;
723
				case 'zoneedit':
724
					$needsIP = FALSE;
725 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
726 89a75ca9 Bill Marquette
727 9b8dc821 Scott Ullrich
					$server = "https://dynamic.zoneedit.com/auth/dynamic.html";
728
					$port = "";
729 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
730 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
731 1e0b1727 Phil Davis
					}
732
					if ($this->_dnsPort) {
733 9b8dc821 Scott Ullrich
						$port = ":" . $this->_dnsPort;
734 1e0b1727 Phil Davis
					}
735 176d24e1 Phil Davis
					curl_setopt($ch, CURLOPT_URL, "{$server}{$port}?host=" . $this->_dnsHost . '&dnsto=' . $this->_dnsIP);
736 1fa2f630 Erik Kristensen
					break;
737
				case 'dyns':
738
					$needsIP = FALSE;
739 ea46d833 Chris Buechler
					$server = "http://www.dyns.net/postscript011.php";
740 9b8dc821 Scott Ullrich
					$port = "";
741 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
742 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
743 1e0b1727 Phil Davis
					}
744
					if ($this->_dnsPort) {
745
						$port = ":" . $this->_dnsPort;
746
					}
747 fdcaa527 Ermal Luçi
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?username=' . urlencode($this->_dnsUser) . '&password=' . $this->_dnsPass . '&host=' . $this->_dnsHost);
748 1fa2f630 Erik Kristensen
					break;
749
				case 'ods':
750
					$needsIP = FALSE;
751 9b8dc821 Scott Ullrich
					$misc_errno = 0;
752
					$misc_error = "";
753
					$server = "ods.org";
754
					$port = "";
755 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
756 9b8dc821 Scott Ullrich
						$server = $this->_dnsServer;
757 1e0b1727 Phil Davis
					}
758
					if ($this->_dnsPort) {
759
						$port = ":" . $this->_dnsPort;
760
					}
761 9b8dc821 Scott Ullrich
					$this->con['socket'] = fsockopen("{$server}{$port}", "7070", $misc_errno, $misc_error, 30);
762 1fa2f630 Erik Kristensen
					/* Check that we have connected */
763
					if (!$this->con['socket']) {
764
						print "error! could not connect.";
765
						break;
766
					}
767
					/* Here is the loop. Read the incoming data (from the socket connection) */
768
					while (!feof($this->con['socket'])) {
769
						$this->con['buffer']['all'] = trim(fgets($this->con['socket'], 4096));
770
						$code = substr($this->con['buffer']['all'], 0, 3);
771
						sleep(1);
772 1e0b1727 Phil Davis
						switch ($code) {
773 1fa2f630 Erik Kristensen
							case 100:
774 f9734a1a Balázs Váradi
								fputs($this->con['socket'], "LOGIN " . $this->_dnsUser . " " . $this->_dnsPass . "\n");
775 1fa2f630 Erik Kristensen
								break;
776
							case 225:
777 f9734a1a Balázs Váradi
								fputs($this->con['socket'], "DELRR " . $this->_dnsHost . " A\n");
778 1fa2f630 Erik Kristensen
								break;
779
							case 901:
780 f9734a1a Balázs Váradi
								fputs($this->con['socket'], "ADDRR " . $this->_dnsHost . " A " . $this->_dnsIP . "\n");
781 1fa2f630 Erik Kristensen
								break;
782
							case 795:
783
								fputs($this->con['socket'], "QUIT\n");
784
								break;
785
						}
786
					}
787 bdffb77d jim-p
					$this->_checkStatus(null, null, $code, null);
788 1fa2f630 Erik Kristensen
					break;
789 9b8dc821 Scott Ullrich
				case 'freedns':
790 ac16181a TechSmurf
				case 'freedns-v6':
791 44857365 9Lukas5
					$needIP = TRUE;
792
					curl_setopt($ch, CURLOPT_URL, 'https://freedns.afraid.org/dynamic/update.php?' . $this->_dnsPass . '&address=' . $this->_dnsIP);
793 9b8dc821 Scott Ullrich
					break;
794 c7df496c Ricky Burgin
				case 'freedns2':
795 49d54787 Ricky Burgin
					$needIP = TRUE;
796
					curl_setopt($ch, CURLOPT_URL, 'https://sync.afraid.org/u/' . $this->_dnsPass . '/?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
797
					break;
798 c7df496c Ricky Burgin
				case 'freedns2-v6':
799 49d54787 Ricky Burgin
					$needIP = TRUE;
800
					curl_setopt($ch, CURLOPT_URL, 'https://v6.sync.afraid.org/u/' . $this->_dnsPass . '/?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
801
					break;
802 0a1b0183 Ermal Luçi
				case 'dnsexit':
803
					$needsIP = TRUE;
804 17f81cb6 Koen Zomers
					curl_setopt($ch, CURLOPT_URL, 'https://api.dnsexit.com/dns/ud/?apikey=' . $this->_dnsPass . '&host=' . $this->_dnsHost . '&ip=' . $this->_dnsIP);
805 0a1b0183 Ermal Luçi
					break;
806 9b8dc821 Scott Ullrich
				case 'loopia':
807
					$needsIP = TRUE;
808 cedc8184 kristoffer-ekenstam
					if(isset($this->_dnsWildcard) && $this->_dnsWildcard == TRUE) {
809
						$this->_dnsWildcard = "ON";
810
					} else {
811
						$this->_dnsWildcard = "OFF";
812
					}
813
					curl_setopt($ch, CURLOPT_USERPWD, "{$this->_dnsUser}:{$this->_dnsPass}");
814
					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");
815 9b8dc821 Scott Ullrich
					break;
816 2d78b166 Ermal Luçi
				case 'opendns':
817
					$needsIP = FALSE;
818
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") $this->_dnsWildcard = "ON";
819 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
820
					$server = "https://updates.opendns.com/nic/update?hostname=" . $this->_dnsHost;
821 2d78b166 Ermal Luçi
					$port = "";
822 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
823 2d78b166 Ermal Luçi
						$server = $this->_dnsServer;
824 1e0b1727 Phil Davis
					}
825
					if ($this->_dnsPort) {
826 2d78b166 Ermal Luçi
						$port = ":" . $this->_dnsPort;
827 1e0b1727 Phil Davis
					}
828 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_URL, $server . $port);
829 2d78b166 Ermal Luçi
					break;
830
831 d74b5b8b sullrich
				case 'staticcling':
832
					$needsIP = FALSE;
833 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_URL, 'https://www.staticcling.org/update.html?login=' . $this->_dnsUser . '&pass=' . $this->_dnsPass);
834 1e0b1727 Phil Davis
					break;
835 52e6fdfd Scott Dale
				case 'dnsomatic':
836 1e0b1727 Phil Davis
					/* Example syntax
837 52e6fdfd Scott Dale
						https://username:password@updates.dnsomatic.com/nic/update?hostname=yourhostname&myip=ipaddress&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG
838
					*/
839
					$needsIP = FALSE;
840 1e0b1727 Phil Davis
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") {
841
						$this->_dnsWildcard = "ON";
842
					}
843 99438649 swatspyder
					/*
844 8fa5038b Marcos Mendoza
					Reference: https://www.dnsomatic.com/docs/api
845 99438649 swatspyder
						DNS-O-Matic usernames are 3-25 characters.
846
						DNS-O-Matic passwords are 6-20 characters.
847
						All ASCII letters and numbers accepted.
848
						Dots, dashes, and underscores allowed, but not at the beginning or end of the string.
849 8fa5038b Marcos Mendoza
					Required: "rawurlencode" https://www.php.net/manual/en/function.rawurlencode.php
850 99438649 swatspyder
						Encodes the given string according to RFC 3986.
851
					*/
852
					$server = "https://" . rawurlencode($this->_dnsUser) . ":" . rawurlencode($this->_dnsPass) . "@updates.dnsomatic.com/nic/update?hostname=";
853 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
854 52e6fdfd Scott Dale
						$server = $this->_dnsServer;
855 1e0b1727 Phil Davis
					}
856
					if ($this->_dnsPort) {
857 52e6fdfd Scott Dale
						$port = ":" . $this->_dnsPort;
858 1e0b1727 Phil Davis
					}
859 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_URL, $server . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard=' . $this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NOCHG');
860 52e6fdfd Scott Dale
					break;
861 4d6cc223 Viktor G
				case 'domeneshop':
862
				case 'domeneshop-v6':
863
					/* Example:
864
						https://{token}:{secret}@api.domeneshop.no/v0/dyndns/update?hostname=example.com&myip=127.0.0.1
865
					*/
866
					$needsIP = FALSE;
867
					$server = "https://{$this->_dnsUser}:{$this->_dnsPass}@api.domeneshop.no/v0/dyndns/update?hostname={$this->_dnsHost}&myip={$this->_dnsIP}";
868
					curl_setopt($ch, CURLOPT_URL, $server);
869
					break;
870 fe6b1252 Viktor G
				case 'mythicbeasts':
871
				case 'mythicbeasts-v6':
872
					/* Example:
873
						https://{login}:{password}@https://api.mythic-beasts.com/dns/v2/zones/example.com/records/test1/A -d data=1.2.3.4
874
					*/
875
					$needsIP = FALSE;
876
					if ($this->_useIPv6) {
877 f6f1d1c6 Jaakko Kantojärvi
						$record = "AAAA";
878 fe6b1252 Viktor G
					} else {
879 f6f1d1c6 Jaakko Kantojärvi
						$record = "A";
880 fe6b1252 Viktor G
					}
881
					$post_data['data'] = $this->_dnsIP;
882
					$server = "https://api.mythic-beasts.com/dns/v2/zones/{$this->_dnsDomain}/records/{$this->_dnsHost}/{$record}";
883
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
884
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
885
					curl_setopt($ch, CURLOPT_URL, $server);
886
					break;
887 6a9fe85f olehfb
				case 'name.com':
888
				case 'name.com-v6':
889 8fa5038b Marcos Mendoza
					// API documentation: https://www.name.com/api-docs/ & https://www.name.com/api-docs/dns
890 6a9fe85f olehfb
					$namedotcom_api = "https://api.name.com/v4/domains/{$this->_dnsDomain}/records";
891
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
892
					$record_type = $this->_useIPv6 ? "AAAA" : "A";
893
					// Check if a record already exists for this host.
894
					curl_setopt($ch, CURLOPT_URL, "{$namedotcom_api}?perPage=1000");
895 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
896 6a9fe85f olehfb
					$response = json_decode(curl_exec($ch), true);
897
					$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
898
					if ($http_code != "200") {
899
						log_error(gettext("Error message: ") . $response);
900
						return false;
901
					}
902
					if (!is_array($response["records"])) {
903
						log_error(gettext("Unexpected response: ") . $response);
904
						return false;
905
					}
906
					foreach($response["records"] as $record) {
907
						if (($record["domainName"] == $this->_dnsDomain) &&
908
							($record["host"] == $this->_dnsHost) &&
909
							($record["type"] == $record_type)) {
910
								$record_id = $record["id"];
911
								$existing_ttl = $record["ttl"];
912
								break;
913
						}
914
					}
915
					if (!$record_id && $response["nextPage"])
916
					{
917
						log_error(gettext("Too many (>1000) Name.com DNS records. Paging not supported."));
918
						return false;
919
					}
920
					// Either update an existing record or create a new one.
921
					$post_data['host'] = $this->_dnsHost;
922
					$post_data['type'] = $record_type;
923
					$post_data['answer'] = $this->_dnsIP;
924
					$post_data['ttl'] = max($this->_dnsTTL ?: $existing_ttl, 300);
925
					curl_setopt($ch, CURLOPT_URL, "{$namedotcom_api}/{$record_id}");
926
					curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
927
					curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
928
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $record_id ? "PUT" : "POST");
929
					break;
930 61c30081 jim-p
				case 'namecheap':
931
					/* Example:
932
						https://dynamicdns.park-your-domain.com/update?host=[host_name]&domain=[domain.com]&password=[domain_password]&ip=[your_ip]
933
					*/
934
					$needsIP = FALSE;
935 4178d033 jim-p
					$dnspass = trim($this->_dnsPass);
936 6635aa0f jim-p
					$server = "https://dynamicdns.park-your-domain.com/update?host={$this->_dnsHost}&domain={$this->_dnsDomain}&password={$dnspass}&ip={$this->_dnsIP}";
937 61c30081 jim-p
					curl_setopt($ch, CURLOPT_URL, $server);
938 8ea77433 Chris Wells
					break;
939 4e820dc1 Viktor G
				case 'nicru':
940
				case 'nicru-v6':
941
					/* see https://www.nic.ru/help/dynamic-dns-for-developers_5810.html */
942
					$needsIP = FALSE;
943
					if (is_ipaddrv6($this->_dnsIP)) {
944
						$iptype = "ipv6";
945
					} else {
946
						$iptype = "myip";
947
					}
948
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
949
					$server = "https://api.nic.ru/dyndns/update?hostname={$this->_dnsHost}&{$iptype}={$this->_dnsIP}";
950
					curl_setopt($ch, CURLOPT_URL, $server);
951
					break;
952
				case 'yandex':
953
				case 'yandex-v6':
954
					// https://yandex.com/dev/connect/directory/api/concepts/domains/dns-records-via-pdd.html
955
956
					if (is_ipaddrv4($this->_dnsIP)) {
957
						$type = 'A';
958
					} else {
959
						$type = 'AAAA';
960
					}
961
962
					// get record_id
963
					curl_setopt($ch, CURLOPT_URL, "https://pddimp.yandex.ru/api2/admin/dns/list?domain={$this->_dnsDomain}");
964 f7e2e6e1 Viktor G
					curl_setopt($ch, CURLOPT_HTTPHEADER, array('PddToken: ' . $this->_dnsPass));
965 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
966 4e820dc1 Viktor G
					$output = json_decode(curl_exec($ch), true);
967
					if (is_array($output["records"])) {
968
						foreach($output["records"] as $record) {
969
							if (($record["domain"] == $this->_dnsDomain) &&
970
							    ($record["subdomain"] == $this->_dnsHost) &&
971
							    ($record["type"] == $type)) {
972
								$record_id = $record["record_id"];
973
							}
974
						}
975
					}
976
977
					if ($record_id) {
978
						$action = 'edit';
979
						$post_data['record_id'] = $record_id;
980
					} else {
981
						$action = 'add';
982
					}
983
984
					$post_data['domain'] = $this->_dnsDomain;
985
					$post_data['subdomain'] = $this->_dnsHost;
986
					$post_data['content'] = $this->_dnsIP;
987
					$post_data['type'] = $type;
988
					if ($this->_dnsTTL) {
989
						$post_data['ttl'] = $this->_dnsTTL;
990
					}
991 f6f1d1c6 Jaakko Kantojärvi
992 4e820dc1 Viktor G
					curl_setopt($ch, CURLOPT_URL, 'https://pddimp.yandex.ru/api2/admin/dns/' . $action);
993 f7e2e6e1 Viktor G
					curl_setopt($ch, CURLOPT_HTTPHEADER, array('PddToken: ' . $this->_dnsPass));
994 4e820dc1 Viktor G
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
995
					break;
996 19b7263e Ionut
				case 'duiadns':
997
				case 'duiadns-v6':
998
					$needsIP = FALSE;
999
					$server = "https://ipv4.duiadns.net/dyndns.duia?";
1000
					curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
1001
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
1002
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
1003
					curl_setopt($ch, CURLOPT_URL, $server . 'hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
1004
					break;
1005 8ea77433 Chris Wells
				case 'he-net':
1006 d7e6f573 Daniel Becker
				case 'he-net-v6':
1007 8ea77433 Chris Wells
					$needsIP = FALSE;
1008
					$server = "https://dyn.dns.he.net/nic/update?";
1009 086cf944 Phil Davis
					curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
1010 393dac91 Chris Buechler
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
1011 16fea0ce Cedric Ohle
					curl_setopt($ch, CURLOPT_URL, $server . 'hostname=' . $this->_dnsHost . '&password=' . $this->_dnsPass . '&myip=' . $this->_dnsIP);
1012 8ea77433 Chris Wells
					break;
1013 38a481ad jim-p
				case 'he-net-tunnelbroker':
1014
					$needsIP = FALSE;
1015 cc0618e2 Michael Smith
					$server = "https://ipv4.tunnelbroker.net/nic/update?";
1016 38a481ad jim-p
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
1017 cc0618e2 Michael Smith
					curl_setopt($ch, CURLOPT_URL, $server . 'hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
1018 38a481ad jim-p
					break;
1019 fb403496 Gerald Raaf
				case 'selfhost':
1020
					$needsIP = FALSE;
1021 1e0b1727 Phil Davis
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") {
1022
						$this->_dnsWildcard = "ON";
1023
					}
1024 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
1025 fb403496 Gerald Raaf
					$server = "https://carol.selfhost.de/nic/update";
1026
					$port = "";
1027 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
1028 fb403496 Gerald Raaf
						$server = $this->_dnsServer;
1029 1e0b1727 Phil Davis
					}
1030
					if ($this->_dnsPort) {
1031 fb403496 Gerald Raaf
						$port = ":" . $this->_dnsPort;
1032 1e0b1727 Phil Davis
					}
1033 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?system=dyndns&hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard=' . $this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NO');
1034 fb403496 Gerald Raaf
					break;
1035 dc6eb05f Dennis Neuhaeuser
				case 'strato':
1036
					$needsIP = FALSE;
1037
					$server = 'https://dyndns.strato.com/nic/update';
1038
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
1039
					curl_setopt($ch, CURLOPT_URL, $server . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
1040
					break;
1041 c5e1ce90 robjarsen
				case 'route53':
1042 16b16366 Jason McCormick
					require_once("r53.class");
1043
					$r53 = new Route53($this->_dnsUser, $this->_dnsPass);
1044 b2cb7364 Jason D. McCormick
					$apiurl = $r53->getApiUrl($this->_dnsZoneID);
1045 16b16366 Jason McCormick
					$xmlreq = $r53->getRequestBody($this->_dnsHost, $this->_dnsIP, $this->_dnsTTL);
1046 56632443 Jason D. McCormick
					$httphead = $r53->getHttpPostHeaders($this->_dnsZoneID, "us-east-1", hash("sha256",$xmlreq));
1047 cc5adcaa Jason McCormick
					curl_setopt($ch, CURLOPT_HTTPHEADER, $httphead);
1048
					if($this->_dnsVerboseLog){
1049 19e87bb3 Bryan Stenson
						log_error(sprintf("Sending request to: %s", $apiurl));
1050 cc5adcaa Jason McCormick
						foreach($httphead as $hv){
1051
							log_error(sprintf("Header: %s", $hv));
1052 0c7bb880 Phil Davis
						}
1053 16b16366 Jason McCormick
						log_error(sprintf("XMLPOST: %s", $xmlreq));
1054 0c7bb880 Phil Davis
					}
1055 cc5adcaa Jason McCormick
					curl_setopt($ch, CURLOPT_URL, $apiurl);
1056
					curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlreq);
1057 0c7bb880 Phil Davis
					break;
1058 c5e1ce90 robjarsen
				case 'route53-v6':
1059 44c64da1 Matthew Fine
					require_once("r53.class");
1060
					$r53 = new Route53($this->_dnsUser, $this->_dnsPass);
1061
					$apiurl = $r53->getApiUrl($this->_dnsZoneID);
1062
					$xmlreq = $r53->getRequestBodyV6($this->_dnsHost, $this->_dnsIP, $this->_dnsTTL);
1063
					$httphead = $r53->getHttpPostHeaders($this->_dnsZoneID, "us-east-1", hash("sha256",$xmlreq));
1064
					curl_setopt($ch, CURLOPT_HTTPHEADER, $httphead);
1065
					if($this->_dnsVerboseLog){
1066 19e87bb3 Bryan Stenson
						log_error(sprintf("Sending request to: %s", $apiurl));
1067 44c64da1 Matthew Fine
						foreach($httphead as $hv){
1068
							log_error(sprintf("Header: %s", $hv));
1069
						}
1070
						log_error(sprintf("XMLPOST: %s", $xmlreq));
1071
					}
1072
					curl_setopt($ch, CURLOPT_URL, $apiurl);
1073
					curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlreq);
1074
					break;
1075 3a05e4c3 Austin Seipp
				case 'cloudflare-v6':
1076 e26e1f76 Andrew Senetar
				case 'cloudflare':
1077 6534026b jim-p
					$this->_FQDN = ltrim($this->_FQDN, '@.');
1078 3a05e4c3 Austin Seipp
					$isv6 = ($this->_dnsService === 'cloudflare-v6');
1079
					$recordType = $isv6 ? "AAAA" : "A";
1080 e26e1f76 Andrew Senetar
					$needsIP = TRUE;
1081 22d95a68 doktornotor
					$dnsServer ='api.cloudflare.com';
1082 4e322e2c Phil Davis
					$dnsHost = str_replace(' ', '', $this->_dnsHost);
1083 22d95a68 doktornotor
1084
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1085
1086 88d878f2 Chris Pick
					if ((!$this->_dnsUser) || (strpos($this->_dnsUser, '@') !== false)) {
1087
						if (strpos($this->_dnsUser, '@') !== false) {
1088
							curl_setopt($ch, CURLOPT_HTTPHEADER, array(
1089
										'X-Auth-Email: ' . $this->_dnsUser,
1090
										'X-Auth-Key: ' . $this->_dnsPass,
1091
										'Content-Type: application/json'
1092
										));
1093
						} else {
1094
							curl_setopt($ch, CURLOPT_HTTPHEADER, array(
1095
										'Authorization: Bearer ' . $this->_dnsPass,
1096
										'Content-Type: application/json'
1097
										));
1098
						}
1099 e67f13c6 Balázs Váradi
1100
						// Get zone ID
1101
						$getZoneId = "https://{$dnsServer}/client/v4/zones/?name={$this->_dnsDomain}";
1102
						curl_setopt($ch, CURLOPT_URL, $getZoneId);
1103 02d6ca03 jim-p
						curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1104 e67f13c6 Balázs Váradi
						$output = json_decode(curl_exec($ch));
1105
						$zone = $output->result[0]->id;
1106
					} else {
1107
						curl_setopt($ch, CURLOPT_HTTPHEADER, array(
1108 f9734a1a Balázs Váradi
							'Authorization: Bearer ' . $this->_dnsPass,
1109 e67f13c6 Balázs Váradi
							'Content-Type: application/json'
1110
						));
1111
1112
						$zone = $this->_dnsUser;
1113
					}
1114
1115 4e322e2c Phil Davis
					if ($zone) { // If zone ID was found get host ID
1116 2446fffa jim-p
						$getHostId = "https://{$dnsServer}/client/v4/zones/{$zone}/dns_records?name={$this->_FQDN}&type={$recordType}";
1117 b37b4034 Phil Davis
						curl_setopt($ch, CURLOPT_URL, $getHostId);
1118 02d6ca03 jim-p
						curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1119 22d95a68 doktornotor
						$output = json_decode(curl_exec($ch));
1120
						$host = $output->result[0]->id;
1121 4e322e2c Phil Davis
						if ($host) { // If host ID was found update host
1122 22d95a68 doktornotor
							$hostData = array(
1123
								"content" => "{$this->_dnsIP}",
1124 3a05e4c3 Austin Seipp
								"type" => "{$recordType}",
1125 e10d25b4 CarlGill
								"proxied" => $this->_dnsProxied,
1126 9404b54a jim-p
								"name" => "{$this->_dnsHost}",
1127 e9869c5a jim-p
								"ttl" => empty($this->_dnsTTL) ? 1 : (int) $this->_dnsTTL
1128 22d95a68 doktornotor
							);
1129
							$data_json = json_encode($hostData);
1130
							$updateHostId = "https://{$dnsServer}/client/v4/zones/{$zone}/dns_records/{$host}";
1131 b37b4034 Phil Davis
							curl_setopt($ch, CURLOPT_URL, $updateHostId);
1132 22d95a68 doktornotor
							curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
1133 4e322e2c Phil Davis
							curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
1134 22d95a68 doktornotor
						}
1135
					}
1136 e26e1f76 Andrew Senetar
					break;
1137 1e0b1727 Phil Davis
				case 'eurodns':
1138 ec66caa6 John Byron
					$needsIP = TRUE;
1139 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
1140 874599b9 johnbyronent
					$server = "https://update.eurodyndns.org/update/";
1141 ec66caa6 John Byron
					$port = "";
1142 1e0b1727 Phil Davis
					if ($this->_dnsPort) {
1143 ec66caa6 John Byron
						$port = ":" . $this->_dnsPort;
1144 1e0b1727 Phil Davis
					}
1145 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
1146 5458bc59 Scavy
					break;
1147
				case 'gratisdns':
1148 3e31a7f8 mortencombat
					$needsIP = TRUE;
1149 5458bc59 Scavy
					$server = "https://ssl.gratisdns.dk/ddns.phtml";
1150 2446fffa jim-p
					curl_setopt($ch, CURLOPT_URL, $server . '?u=' . $this->_dnsUser . '&p=' . $this->_dnsPass . '&h=' . $this->_dnsHost . '&d=' . $this->_dnsDomain . '&i=' . $this->_dnsIP);
1151 5458bc59 Scavy
					break;
1152 a4a56eb0 Stéphane
				case 'ovh-dynhost':
1153
					$needsIP = FALSE;
1154
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") $this->_dnsWildcard = "ON";
1155 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
1156 a4a56eb0 Stéphane
					$server = "https://www.ovh.com/nic/update";
1157
					$port = "";
1158 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
1159 a4a56eb0 Stéphane
						$server = $this->_dnsServer;
1160 1e0b1727 Phil Davis
					}
1161
					if ($this->_dnsPort) {
1162 a4a56eb0 Stéphane
						$port = ":" . $this->_dnsPort;
1163 1e0b1727 Phil Davis
					}
1164 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?system=dyndns&hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard=' . $this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NO');
1165 a4a56eb0 Stéphane
					break;
1166 2206f1b9 Mathias Andersson
				case 'citynetwork':
1167
					$needsIP = TRUE;
1168 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
1169 2206f1b9 Mathias Andersson
					$server = 'https://dyndns.citynetwork.se/nic/update';
1170
					$port = "";
1171 1e0b1727 Phil Davis
					if ($this->_dnsServer) {
1172 2206f1b9 Mathias Andersson
						$server = $this->_dnsServer;
1173 1e0b1727 Phil Davis
					}
1174
					if ($this->_dnsPort) {
1175 2206f1b9 Mathias Andersson
						$port = ":" . $this->_dnsPort;
1176 1e0b1727 Phil Davis
					}
1177 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
1178 2206f1b9 Mathias Andersson
					break;
1179 916d683e surrural
				case 'dnsimple':
1180 77a0eb0d Zac West
				case 'dnsimple-v6':
1181 9e69907e Aaron Kalin
					/* Uses DNSimple's v2 REST API
1182
					   Requires the Account ID as the username (found in the URL when pull up the domain)
1183
					   And an API Token for the password (generated in the User Settings -> API tokens area of the website)
1184
					   Piggybacks on Route 53's ZoneID field for the DNSimple record ID to update
1185
					   The DNS record MUST exist before it can update since it performs a PATCH operation
1186
					   Data sent as JSON over HTTPS */
1187 916d683e surrural
					$needsIP = TRUE;
1188 d2cad3b5 Aaron Kalin
					$server = 'https://api.dnsimple.com/v2/';
1189
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
1190
					curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-Type: application/json', 'Authorization: Bearer ' . $this->_dnsPass));
1191
					curl_setopt($ch, CURLOPT_URL, $server . $this->_dnsUser . '/zones/' . $this->_dnsHost . '/records/' . $this->_dnsZoneID);
1192
					curl_setopt($ch, CURLOPT_POSTFIELDS, '{"content":"' . $this->_dnsIP . '","ttl":"' . $this->_dnsTTL . '"}');
1193 916d683e surrural
					break;
1194 456ba14f Sam Neely
				case 'godaddy':
1195
				case 'godaddy-v6':
1196
					/* Uses GoDaddy's REST API
1197
					   Requires username and Account API sso-key passed in header
1198
					   Data sent as JSON */
1199
					$needsIP = TRUE;
1200
					$server = 'https://api.godaddy.com/v1/domains/';
1201
					$recordType = $this->_useIPv6 ? "AAAA" : "A";
1202 f9734a1a Balázs Váradi
					$url = $server . $this->_dnsDomain . '/records/' . $recordType . '/' . $this->_dnsHost;
1203 456ba14f Sam Neely
					$jsondata = '[{"data":"' . $this->_dnsIP . '","ttl":' . $this->_dnsTTL . '}]';
1204
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
1205
					curl_setopt($ch, CURLOPT_HTTPHEADER, array(
1206
						'Accept: application/json',
1207
						'Content-Type: application/json',
1208
						'Authorization: sso-key ' . $this->_dnsUser . ':' . $this->_dnsPass
1209
					));
1210
					curl_setopt($ch, CURLOPT_URL, $url);
1211
					curl_setopt($ch, CURLOPT_POSTFIELDS, $jsondata);
1212
					break;
1213 c5ecdc25 Jose Luis Duran
				case 'googledomains':
1214 6c92b378 Christopher Fazendin
					$needsIP = FALSE;
1215
					$post_data['username:password'] = $this->_dnsUser . ':' . $this->_dnsPass;
1216
					$post_data['hostname'] = $this->_dnsHost;
1217
					$post_data['myip'] = $this->_dnsIP;
1218
					$post_data['offline'] = 'no';
1219 404ff523 Christopher Fazendin
					$server = "https://domains.google.com/nic/update";
1220 6c92b378 Christopher Fazendin
					$port = "";
1221
					curl_setopt($ch, CURLOPT_URL, 'https://domains.google.com/nic/update');
1222 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
1223 b5360f49 Viktor G
					curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
1224
					curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
1225
					curl_setopt($ch, CURLOPT_POST, 1);
1226 6c92b378 Christopher Fazendin
					break;
1227 c5ecdc25 Jose Luis Duran
				case 'dnsmadeeasy':
1228
					$needsIP = TRUE;
1229
					$server = "https://cp.dnsmadeeasy.com/servlet/updateip";
1230 3900634b Viktor G
					$username = empty($this->_dnsUser) ? "" : "&username={$this->dnsUser}";
1231
					curl_setopt($ch, CURLOPT_URL, $server . '?password=' . $this->_dnsPass . '&id=' . $this->_dnsHost . '&ip=' . $this->_dnsIP . $username);
1232 c5ecdc25 Jose Luis Duran
					break;
1233 1c2c08bd exii1988
				case 'spdyn':
1234
				case 'spdyn-v6':
1235 f3ee8545 Rene Schuster
					$needsIP = FALSE;
1236 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
1237 1c2c08bd exii1988
					$server = "https://update.spdyn.de/nic/update";
1238 f3ee8545 Rene Schuster
					$port = "";
1239 4e322e2c Phil Davis
					if ($this->_dnsServer) {
1240 f3ee8545 Rene Schuster
						$server = $this->_dnsServer;
1241 4e322e2c Phil Davis
					}
1242
					if ($this->_dnsPort) {
1243 f3ee8545 Rene Schuster
						$port = ":" . $this->_dnsPort;
1244 4e322e2c Phil Davis
					}
1245 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
1246 f3ee8545 Rene Schuster
					break;
1247 575b1dcf Christoph Filnkößl
				case 'all-inkl':
1248
					$needsIP = FALSE;
1249
					$server = 'https://dyndns.kasserver.com/';
1250 f9734a1a Balázs Váradi
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
1251 575b1dcf Christoph Filnkößl
					curl_setopt($ch, CURLOPT_URL, $server . 'myip=' . $this->_dnsIP);
1252
					break;
1253 74533d41 xygrec
				case 'hover':
1254
					$needsIP = FALSE;
1255
					$port = "";
1256
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1257 61c813f9 xygrec
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
1258 74533d41 xygrec
1259
					//step 1: login to API
1260
					$post_data['username'] = $this->_dnsUser;
1261
					$post_data['password'] = $this->_dnsPass;
1262
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1263
					curl_setopt($ch, CURLOPT_URL, "https://www.hover.com/api/login");
1264
					curl_setopt($ch, CURLOPT_HEADER, 1); //return the full headers to extract the cookies
1265 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1266 74533d41 xygrec
					$output = curl_exec($ch);
1267
1268
					//extract the cookies
1269
					preg_match_all("/^Set-cookie: (.*?);/ism", $output, $cookies);
1270
					if( count($cookies[1]) > 0 ){
1271
						$cookie_data = implode("; ",$cookies[1]);
1272
					}
1273
1274
					//step 2: find the id of the A record
1275
					$post_data = null;
1276
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1277
					curl_setopt($ch, CURLOPT_COOKIE, $cookie_data);
1278
					curl_setopt($ch, CURLOPT_HEADER, 0);
1279
					curl_setopt($ch, CURLOPT_URL, "https://www.hover.com/api/dns");
1280
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
1281 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1282 74533d41 xygrec
					$output = curl_exec($ch);
1283 e9015d70 zeroxx1986
					$pregHost = preg_quote($this->_dnsHost);
1284
					$pregDomain = preg_quote($this->_dnsDomain);
1285
					preg_match("/^{\"succeeded\":true.*?domain_name\":\"{$pregDomain}.*?entries.*?{\"id\":\"([^\"]*?)\",\"name\":\"{$pregHost}\",\"type\":\"A\".*?\$/", $output, $hostID);
1286 74533d41 xygrec
					$hostID = $hostID[1];
1287 e9015d70 zeroxx1986
					preg_match("/^{\"succeeded\":true.*?domain_name\":\"{$pregDomain}.*?entries.*?{[^\}]*?\"name\":\"{$pregHost}\",\"type\":\"A\".*?content\":\"([^\"]*?)\".*?\$/", $output, $hostIP);
1288 74533d41 xygrec
					$hostIP = $hostIP[1];
1289 e9015d70 zeroxx1986
					unset($pregHost);
1290
					unset($pregDomain);
1291 74533d41 xygrec
1292
					//step 3: update the IP
1293
					if ($hostID) {
1294
						curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1295 61c813f9 xygrec
						curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
1296 74533d41 xygrec
						curl_setopt($ch, CURLOPT_COOKIE, $cookie_data);
1297
						$post_data['content'] = $this->_dnsIP;
1298
						curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1299
						curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
1300
						curl_setopt($ch, CURLOPT_URL, "https://www.hover.com/api/dns/{$hostID}");
1301
						log_error("HostID:{$hostID}, OldIP:{$hostIP}");
1302
					}
1303
					break;
1304 4e820dc1 Viktor G
				case 'onecom':
1305
				case 'onecom-v6':
1306 e7de40d5 Viktor G
					/* see https://redmine.pfsense.org/issues/11293
1307
					 * and https://redmine.pfsense.org/issues/12352 */
1308
1309
					curl_setopt($ch, CURLOPT_URL, "https://www.one.com/admin/");
1310
					curl_setopt($ch, CURLOPT_HEADER, 1); //return the full headers to extract the cookies
1311
					curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
1312
					curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
1313 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1314 e7de40d5 Viktor G
					$output = curl_exec($ch);
1315
					$last_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
1316
1317
					// extract the cookies
1318
					preg_match_all("/^Set-cookie: (.*?);/ism", $output, $cookies);
1319
					if (count($cookies[1]) > 0) {
1320
						$cookie_data = implode("; ", $cookies[1]);
1321
					}
1322 4e820dc1 Viktor G
1323
					// login in
1324
					$post_data['username'] = $this->_dnsUser;
1325 e7de40d5 Viktor G
					$post_data['password'] = $this->_dnsPass;
1326
					$post_data['credentialId'] = '';
1327 4e820dc1 Viktor G
1328
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1329 e7de40d5 Viktor G
					curl_setopt($ch, CURLOPT_URL, $last_url);
1330
					curl_setopt($ch, CURLOPT_COOKIE, $cookie_data);
1331 4e820dc1 Viktor G
					curl_setopt($ch, CURLOPT_HEADER, 1); //return the full headers to extract the cookies
1332 e7de40d5 Viktor G
					curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
1333 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1334 4e820dc1 Viktor G
					$output = curl_exec($ch);
1335
1336
					// extract the cookies
1337
					preg_match_all("/^Set-cookie: (.*?);/ism", $output, $cookies);
1338 e7de40d5 Viktor G
					if (count($cookies[1]) > 0) {
1339
						$cookie_data = implode("; ", $cookies[1]);
1340 4e820dc1 Viktor G
					}
1341
1342
					// gets all DNS records of the domain.
1343
					$post_data = null;
1344
					$url = "https://www.one.com/admin/api/domains/" . $this->_dnsDomain + "/dns/custom_records";
1345
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1346
					curl_setopt($ch, CURLOPT_COOKIE, $cookie_data);
1347
					curl_setopt($ch, CURLOPT_HEADER, 0);
1348
					curl_setopt($ch, CURLOPT_URL, $url);
1349
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
1350 e7de40d5 Viktor G
					curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
1351 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1352 4e820dc1 Viktor G
					$output = curl_exec($ch);
1353
					$result = json_decode($output, true);
1354
					$records = $result['result']['data'];
1355
1356
					// finds the record id of a record from it's subdomain
1357
					foreach ($records as $rec) {
1358
						if ($rec['attributes']['prefix'] == $this->_dnsHostname) {
1359
							$id = $rec['id'];
1360
							break;
1361
						}
1362
					}
1363
					if (!$id) {
1364
						log_error("Could not find one.com hostname record id");
1365
						return false;
1366
					}
1367
1368
					// changes the IP Address of a TYPE A record. Default TTL=3800
1369
					$tosend = array();
1370
					$tosend['type'] = 'dns_service_records';
1371
					$tosend['id'] = $id;
1372
					if (is_ipaddrv4($this->_dnsIP)) {
1373
						$rectype = 'A';
1374
					} else {
1375
						$rectype = 'AAAA';
1376
					}
1377
					$tosend['attributes'] = array(
1378
						'type' => $rectype,
1379
						'prefix' => $this->_dnsHostname,
1380
						'content' => $this->_dnsIP,
1381
						'ttl' => $this->_dnsTTL
1382
					);
1383
					$url = "https://www.one.com/admin/api/domains/" . $this->_dnsDomain .
1384
						 "/dns/custom_records/" . $id;
1385
					curl_setopt($ch, CURLOPT_URL, $url);
1386
					curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
1387
					curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($tosend));
1388
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
1389 e7de40d5 Viktor G
					curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
1390 4e820dc1 Viktor G
					break;
1391 9a3ec9a5 frank
				case 'dreamhost':
1392
				case 'dreamhost-v6':
1393
					$needsIP = TRUE;
1394
					$isv6 = ($this->_dnsService === 'dreamhost-v6');
1395
					$server = 'https://api.dreamhost.com/';
1396 a71deb5a frank
					$post_data['key'] = $this->_dnsPass;
1397 9a3ec9a5 frank
					$post_data['unique_id'] = uniqid($this->_dnsHost);
1398
					$post_data['cmd'] = 'dns-add_record';
1399
					$post_data['format'] = 'json';
1400
					$post_data['value'] = $this->_dnsIP;
1401
					$post_data['record'] = $this->_dnsHost;
1402
					$post_data['type'] = $isv6 ? 'AAAA' : 'A';
1403 f9734a1a Balázs Váradi
					$post_data['comment'] = "Updated by pfSense:$this->_dnsUser on " . date('c');
1404 9a3ec9a5 frank
					$port = "";
1405
					if ($this->_dnsServer) {
1406
						$server = $this->_dnsServer;
1407
					}
1408
					if ($this->_dnsPort) {
1409
						$port = ":" . $this->_dnsPort;
1410
					}
1411
					curl_setopt($ch, CURLOPT_URL, $server . $port);
1412
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1413
					break;
1414 544674ad Grant Sheehan
				case 'digitalocean':
1415 0c43f825 Matthew Fine
				case 'digitalocean-v6':
1416 544674ad Grant Sheehan
					// Get record ID
1417
					$server = 'https://api.digitalocean.com/v2/domains/';
1418 0c43f825 Matthew Fine
					$isv6 = ($this->_dnsService === 'digitalocean-v6');
1419 544674ad Grant Sheehan
					$url = $server . $this->_dnsDomain . '/records';
1420 32cb54c3 Grant Sheehan
					curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: Bearer {$this->_dnsPass}"));
1421 544674ad Grant Sheehan
					curl_setopt($ch, CURLOPT_URL, $url);
1422 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1423 544674ad Grant Sheehan
					$output = json_decode(curl_exec($ch));
1424 7c957a56 Stephen Jones
					if (!is_array($output->domain_records)) {
1425
						$output->domain_records = array();
1426
					}
1427 fb477a9d csobankesmarki
1428 d5e1cbd6 csobankesmarki
					// DO's API lists 20 NS records per page, so additional pages needs to be downloaded
1429 fb477a9d csobankesmarki
					// https://redmine.pfsense.org/issues/10952
1430 d5e1cbd6 csobankesmarki
					$_domain_records = $output->domain_records;
1431
					$_count = count($_domain_records);
1432
					$_total = 0;
1433
					if (property_exists($output, 'meta')) {
1434 fb477a9d csobankesmarki
						$meta = $output->meta;
1435
						if (property_exists($meta, 'total')) {
1436
							$_total = $meta->total;
1437
						}
1438 d5e1cbd6 csobankesmarki
					}
1439
					$_next = '...';
1440
					$_last = '';
1441
					while ($_next != $_last) {
1442 fb477a9d csobankesmarki
						$_next = '';
1443
						if (property_exists($output, 'links')) {
1444
							$_links = $output->links;
1445
							if (property_exists($_links, 'pages')) {
1446
								$_pages = $_links->pages;
1447
								if (property_exists($_pages, 'next')) {
1448
									$_next = $_pages->next;
1449
								}
1450
								if (property_exists($_pages, 'last')) {
1451
									$_last = $_pages->last;
1452
								}
1453
								if ($_next != '') {
1454
									echo "getting $_next\n";
1455
									curl_setopt($ch, CURLOPT_URL, $_next);
1456 02d6ca03 jim-p
									curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1457 fb477a9d csobankesmarki
									$output = json_decode(curl_exec($ch));
1458
									if (!is_array($output->domain_records)) {
1459
										$output->domain_records = array();
1460 d5e1cbd6 csobankesmarki
									}
1461 fb477a9d csobankesmarki
									$_domain_records = array_merge($_domain_records,$output->domain_records);
1462
								}
1463 d5e1cbd6 csobankesmarki
							}
1464 fb477a9d csobankesmarki
						}
1465 d5e1cbd6 csobankesmarki
					}
1466
					$_count = count($_domain_records);
1467 fb477a9d csobankesmarki
1468 d5e1cbd6 csobankesmarki
					foreach($_domain_records as $dnsRecord) {
1469 f6f1d1c6 Jaakko Kantojärvi
						// NS records are named @ in DO's API, so check type as well
1470 5878d529 Grant Sheehan
						// https://redmine.pfsense.org/issues/9171
1471 08939cfb csobankesmarki
						if ($this->_dnsHost == $dnsRecord->name && $dnsRecord->type == ($isv6 ? 'AAAA' : 'A')) {
1472 32cb54c3 Grant Sheehan
							$recordID = $dnsRecord->id;
1473 544674ad Grant Sheehan
							break;
1474
						}
1475
					}
1476
1477 32cb54c3 Grant Sheehan
					// Create/update record
1478
					if ($recordID == null) {
1479
						$url = $server . $this->_dnsDomain . '/records';
1480
					} else {
1481
						$url = $server . $this->_dnsDomain . '/records/' . $recordID;
1482
						curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
1483
					}
1484 0c43f825 Matthew Fine
					$post_data['type'] = $isv6 ? 'AAAA' : 'A';
1485 32cb54c3 Grant Sheehan
					$post_data['ttl'] = $this->_dnsTTL;
1486 544674ad Grant Sheehan
					$post_data['name'] = $this->_dnsHost;
1487
					$post_data['data'] = $this->_dnsIP;
1488
					curl_setopt($ch, CURLOPT_URL, $url);
1489
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1490
					break;
1491 745d3779 Wagner Sartori Junior
				case 'cloudns':
1492
					/* Uses ClouDNS REST API
1493
					   Requires auth-id or sub-auth-id or sub-auth-user */
1494
					// Step 1: Find the Record ID
1495
					$url = 'https://api.cloudns.net/dns/records.json';
1496
					$post_data['auth-id'] = $this->_dnsUser;
1497
					$post_data['auth-password'] = $this->_dnsPass;
1498
					$post_data['domain-name'] = $this->_dnsDomain;
1499
					$post_data['host'] = $this->_dnsHost;
1500
					$post_data['type'] = 'a';
1501
					curl_setopt($ch, CURLOPT_URL, $url);
1502
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1503 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1504 745d3779 Wagner Sartori Junior
					$output = json_decode(curl_exec($ch));
1505
					$recordID = key(get_object_vars($output));
1506
1507
					// Step 2: Set the record
1508
					$needsIP = TRUE;
1509
					$url = 'https://api.cloudns.net/dns/mod-record.json';
1510
					$post_data = array();
1511
					$post_data['auth-id'] = $this->_dnsUser;
1512
					$post_data['auth-password'] = $this->_dnsPass;
1513
					$post_data['domain-name'] = $this->_dnsDomain;
1514
					$post_data['record-id'] = $recordID;
1515
					$post_data['host'] = $this->_dnsHost;
1516
					$post_data['record'] = $this->_dnsIP;
1517
					$post_data['ttl'] = $this->_dnsTTL;
1518
					curl_setopt($ch, CURLOPT_URL, $url);
1519
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1520
					break;
1521 ed5b58a7 Tom Embt
				case 'azurev6':
1522
				case 'azure':
1523
					$hostname = "{$this->_dnsHost}";
1524
					$resourceid = trim($this->_dnsZoneID);
1525
					$app_id = $this->_dnsUser;
1526
					$client_secret = $this->_dnsPass;
1527
					$newip = $this->_dnsIP;
1528
					$newttl = $this->_dnsTTL;
1529
						// ensure resourceid starts with / and has no trailing /
1530
					$resourceid = '/' . trim($resourceid, '/');
1531
						// extract subscription id from resource id
1532
					preg_match('/\\/subscriptions\\/(?<sid>[^\\/]*)/', $resourceid, $result);
1533
					$subscriptionid = isset($result['sid']) ? $result['sid'] : '';
1534
					if (isset($result['sid'])) {
1535
						$subscriptionid = $result['sid'];
1536
					} else {
1537
						log_error("Azure subscription id not found in resource id");
1538
						return false;
1539
					}
1540
						// find tenant id from subscription id
1541
					curl_setopt($ch, CURLOPT_URL, "https://management.azure.com/subscriptions/" . $subscriptionid . "?api-version=2016-09-01");
1542
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1543
					curl_setopt($ch, CURLOPT_HEADER, 1);
1544
					curl_setopt($ch, CURLOPT_NOBODY, 1);
1545 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1546 ed5b58a7 Tom Embt
					$output = curl_exec($ch);
1547
					$pattern = '/Bearer authorization_uri="https:\\/\\/login.windows.net\\/(?<tid>[^"]*)/i';
1548
					preg_match($pattern, $output, $result);
1549
					if (isset($result['tid'])) {
1550
						$tenantid = $result['tid'];
1551
					} else {
1552
						log_error("Tenant ID not found");
1553
						return false;
1554
					}
1555
						// get an bearer token
1556
					curl_setopt($ch, CURLOPT_URL, "https://login.microsoftonline.com/" . $tenantid . "/oauth2/token");
1557
					curl_setopt($ch, CURLOPT_POST, 1);
1558
					$body = "resource=" . urlencode("https://management.core.windows.net/") . "&grant_type=client_credentials&client_id=" . $app_id . "&client_secret=" . urlencode($client_secret);
1559
					curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
1560
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1561 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1562 ed5b58a7 Tom Embt
					$server_output = curl_exec($ch);
1563
					$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1564
					preg_match("/\"access_token\":\"(?<tok>[^\"]*)\"/", $server_output, $result);
1565
					if (isset($result['tok'])) {
1566
						$bearertoken = $result['tok'];
1567
					} else {
1568
						log_error("no valid bearer token");
1569
						return false;
1570
					}
1571
						// Update the DNS record
1572
					if ($this->_useIPv6) {
1573
						$url = "https://management.azure.com" . $resourceid . "/AAAA/" . $hostname . "?api-version=2017-09-01";
1574
						$body = '{"properties":{"TTL":"' . $newttl . '", "AAAARecords":[{"ipv6Address":"' . $newip . '"}]}}';
1575
					} else {
1576
						$url = "https://management.azure.com" . $resourceid . "/A/" . $hostname . "?api-version=2017-09-01";
1577
						$body = '{"properties":{"TTL":"' . $newttl . '", "ARecords":[{"ipv4Address":"' . $newip . '"}]}}';
1578
					}
1579
					$request_headers = array();
1580
					$request_headers[] = 'Accept: application/json';
1581
					$request_headers[] = 'Authorization: Bearer ' . $bearertoken;
1582
					$request_headers[] = 'Content-Type: application/json';
1583
					curl_setopt($ch, CURLOPT_URL, $url);
1584
					curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
1585
					curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
1586
					curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
1587
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1588
					curl_setopt($ch, CURLOPT_HEADER, 1);
1589
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
1590
					break;
1591 b923a825 Tom Embt
				case 'linode':
1592
				case 'linode-v6':
1593
					$linode_api = "https://api.linode.com/v4";
1594
					$record_type = $this->_useIPv6 ? "AAAA" : "A";
1595
					$record_name = $this->_dnsHost == "@" ? "" : $this->_dnsHost;
1596
					$err_prefix = gettext("Dynamic DNS") . " {$this->_dnsService} ({$this->_FQDN}): (" . gettext("Error") . ")";
1597
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1598
					curl_setopt($ch, CURLOPT_HTTPHEADER, array(
1599
						'Accept: application/json',
1600
						'Content-Type: application/json',
1601
						'Authorization: Bearer ' . $this->_dnsPass
1602
					));
1603
1604
					// get domain id
1605 bd0a29ea Tom Embt
					curl_setopt($ch, CURLOPT_URL, "{$linode_api}/domains");
1606 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1607 b923a825 Tom Embt
					$domains_output = curl_exec($ch);
1608
					$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1609
					if ( $http_code == 401 && preg_match('/invalid oauth token/i', $domains_output) ) {
1610
						log_error("$err_prefix " . gettext("querying domains") . ": " . gettext("User Authentication Failed"));
1611
						return false;
1612
					} else if ( $http_code == 401 ) {
1613
						log_error("$err_prefix " . gettext("querying domains") . ": " . gettext("User Authorization Failed"));
1614
						return false;
1615
					} else if ( $http_code != 200 ) {
1616
						log_error("$err_prefix " . gettext("querying domains") . ": " .
1617 bd0a29ea Tom Embt
							( isset($domains_result["errors"][0]["reason"]) ? $domains_result["errors"][0]["reason"] : "HTTP {$http_code}" ) );
1618 b923a825 Tom Embt
						return false;
1619
					}
1620
1621
					$domains_result = json_decode($domains_output, TRUE);
1622
					foreach($domains_result["data"] as $domains_entry) {
1623
						if ($domains_entry["domain"] == $this->_dnsDomain) {
1624
							$domain_id = $domains_entry["id"];
1625
						}
1626
					}
1627
					if ( ! $domain_id ) {
1628 bd0a29ea Tom Embt
						log_error("{$err_prefix} " . gettext("no domain ID for domain") . ": '{$this->_dnsDomain}'");
1629 b923a825 Tom Embt
						return false;
1630
					}
1631
					if ($this->_dnsVerboseLog) {
1632
						log_error("_update(): " . sprintf(gettext("found domain id: %s"), $domain_id));
1633
					}
1634
1635
					// get existing record if present
1636 bd0a29ea Tom Embt
					curl_setopt($ch, CURLOPT_URL, "{$linode_api}/domains/{$domain_id}/records");
1637 02d6ca03 jim-p
					curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1638 b923a825 Tom Embt
					$records_output = curl_exec($ch);
1639
					$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1640
					if ( $http_code != 200 )
1641
					{
1642
						log_error("$err_prefix " . gettext("querying domains") . ": " .
1643 bd0a29ea Tom Embt
							( isset($domains_result["errors"][0]["reason"]) ? $domains_result["errors"][0]["reason"] : "HTTP {$http_code}" ) );
1644 b923a825 Tom Embt
						return false;
1645
					}
1646
1647
					$records_result = json_decode($records_output, TRUE);
1648
					foreach($records_result["data"] as $records_entry) {
1649
						if ( $records_entry["type"] == $record_type && $records_entry["name"] == $record_name ) {
1650
							// not adding support for pagination at this time, hope you have < 100 records!
1651
							$record = $records_entry;
1652
						}
1653
					}
1654
					if ($this->_dnsVerboseLog) {
1655
						log_error("_update(): " . ( $record ? sprintf(gettext("found existing record id: %s"), $record["id"]) : gettext("no matching record found") ));
1656
					}
1657
1658
					if (is_array($record)) {
1659
						// update existing record
1660
						$record["target"] = $this->_dnsIP;
1661
						$record["ttl_sec"] = (int) $this->_dnsTTL; // linode may round this up, 0 = zone default
1662
						curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($record));
1663
						curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
1664 bd0a29ea Tom Embt
						curl_setopt($ch, CURLOPT_URL, "{$linode_api}/domains/{$domain_id}/records/" . $record["id"]);
1665 b923a825 Tom Embt
					} else {
1666
						// create a new record
1667
						$record = array(
1668
							"type"    => $record_type,
1669
							"name"    => $record_name,
1670
							"target"  => $this->_dnsIP,
1671
							"ttl_sec" => (int) $this->_dnsTTL, // linode may round this up, 0 = zone default
1672
						);
1673
						curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($record));
1674
						curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
1675 bd0a29ea Tom Embt
						curl_setopt($ch, CURLOPT_URL, "{$linode_api}/domains/{$domain_id}/records");
1676 b923a825 Tom Embt
					}
1677 96b2a66a Viktor G
					break;
1678
				case 'dynv6':
1679
					$needIP = TRUE;
1680
					curl_setopt($ch, CURLOPT_URL, 'https://dynv6.com/api/update?ipv4=' . $this->_dnsIP . '&hostname=' . $this->_dnsHost . '&token=' . $this->_dnsPass);
1681
					break;
1682
				case 'dynv6-v6':
1683
					$needIP = TRUE;
1684
					curl_setopt($ch, CURLOPT_URL, 'https://dynv6.com/api/update?ipv6=' . $this->_dnsIP . '&hostname=' . $this->_dnsHost . '&token=' . $this->_dnsPass);
1685
					break;
1686 2efdd601 bitscher
				case 'gandi-livedns':
1687
				case 'gandi-livedns-v6':
1688
					// https://api.gandi.net/docs/livedns/#v5-livedns-domains-fqdn-records-rrset_name-rrset_type
1689
					// PUT overrides the existing record or creates if none exists
1690
					$gandi_api = 'https://api.gandi.net/v5/livedns/domains/';
1691
					$record_type = $this->_useIPv6 ? "AAAA" : "A";
1692
					$url = "{$gandi_api}{$this->_dnsDomain}/records/{$this->_dnsHost}/{$record_type}";
1693
1694
					$headers = array(
1695
						'Authorization: Apikey ' . $this->_dnsPass,
1696
						'Content-Type: application/json'
1697
					);
1698
					$body = array(
1699
						"rrset_ttl"  => $this->_dnsTTL,
1700
						"rrset_values" => array($this->_dnsIP),
1701
					);
1702
1703
					curl_setopt($ch, CURLOPT_URL, $url);
1704 edfe22f8 Eric Vantillard
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
1705 2efdd601 bitscher
					curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
1706
					curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
1707 b923a825 Tom Embt
					break;
1708 9e8300cb Inperpetuammemoriam
				case 'desec':
1709
					curl_setopt($ch, CURLOPT_URL, 'https://update.dedyn.io/?hostname=' . $this->_dnsHost);
1710
					curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Token ' . $this->_dnsPass));
1711
					break;
1712
				case 'desec-v6':
1713
					curl_setopt($ch, CURLOPT_URL, 'https://update6.dedyn.io/?hostname=' . $this->_dnsHost);
1714
					curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Token ' . $this->_dnsPass));
1715
					break;
1716 ed5b58a7 Tom Embt
				default:
1717
					break;
1718 1fa2f630 Erik Kristensen
			}
1719 cc5adcaa Jason McCormick
			if ($this->_dnsService != 'ods') {
1720 15dcf132 PiBa-NL
				curl_setopt($ch, CURLOPT_HEADER, 1);
1721 fd331bdc Viktor G
				if ($this->_curlProxy == true) {
1722
					set_curlproxy($ch);
1723
				}
1724 02d6ca03 jim-p
				curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1725 0e0f580d Christoph Filnkößl
				$response = curl_exec($ch);
1726 0f2fbcd7 Jason McCormick
				$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
1727 0e0f580d Christoph Filnkößl
				$header = substr($response, 0, $header_size);
1728
				$data = substr($response, $header_size);
1729 11360468 Ben Tyger
				if ($this->_dnsVerboseLog) {
1730
					foreach (explode(PHP_EOL, $header) as $hv) {
1731 30c7b89b Ben Tyger
						log_error(sprintf("Response Header: %s", rtrim($hv)));
1732 02d6ca03 jim-p
					}
1733 0bdae0b4 Ben Tyger
					log_error(sprintf("Response Data: %s", $data));
1734 30c7b89b Ben Tyger
				}
1735 bdffb77d jim-p
				$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1736
				$curl_error = @curl_error($ch);
1737
				$this->_checkStatus($http_code, $curl_error, $data, $header);
1738 425ba708 Ermal
			}
1739 02d6ca03 jim-p
			if ($this->_dnsVerboseLog) {
1740
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _update() ending.'), $this->_dnsService, $this->_FQDN));
1741
			}
1742 1fa2f630 Erik Kristensen
		}
1743 c5e1ce90 robjarsen
1744 9a3ec9a5 frank
		/**
1745
		 * Private Function (added 23 Feb 17)
1746
		 *   Send Removal To Selected Service.
1747 c5e1ce90 robjarsen
		 *
1748 9a3ec9a5 frank
		 *   Some services do not perform an inplace upgrade.  If they do not then the solution
1749
		 *   is to remove the existing record and add a new record.
1750 c5e1ce90 robjarsen
		 *
1751 9a3ec9a5 frank
		 * @param unknown $existing_ip If required, an existing IP address for the record.
1752
		 */
1753
		function _remove($existing_ip = NULL) {
1754 f2e702b1 frank
			$remove_allowed = false;
1755 9a3ec9a5 frank
			if ($this->_dnsVerboseLog) {
1756
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _remove() starting.'), $this->_dnsService, $this->_FQDN));
1757
			}
1758 c5e1ce90 robjarsen
1759 9a3ec9a5 frank
			if (strstr($this->_dnsRequestIf, "_vip")) {
1760
				$parentif = get_configured_vip_interface($this->_dnsRequestIf);
1761
				$realparentif = convert_friendly_interface_to_real_interface_name($parentif);
1762
			} else {
1763
				$realparentif = $this->_dnsRequestIf;
1764
			}
1765 c5e1ce90 robjarsen
1766 9a3ec9a5 frank
			$ch = curl_init();
1767 c5e1ce90 robjarsen
1768 9a3ec9a5 frank
			if ($this->_useIPv6 == false) {
1769
				curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
1770
			}
1771 c5e1ce90 robjarsen
1772 f2e702b1 frank
			curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
1773
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
1774
			curl_setopt($ch, CURLOPT_INTERFACE, 'if!' . $realparentif);
1775
			curl_setopt($ch, CURLOPT_TIMEOUT, 120); // Completely empirical
1776 c5e1ce90 robjarsen
1777 9a3ec9a5 frank
			switch ($this->_dnsService) {
1778 e350558a frank
			case 'dreamhost':
1779
			case 'dreamhost-v6':
1780
				$server = 'https://api.dreamhost.com/';
1781
				$post_data['key'] = $this->_dnsPass;
1782
				$post_data['unique_id'] = uniqid($this->_dnsHost);
1783
				$post_data['cmd'] = 'dns-remove_record';
1784
				$post_data['format'] = 'json';
1785
				$post_data['value'] = $existing_ip;
1786
				$post_data['record'] = $this->_dnsHost;
1787
				$isv6 = ($this->_dnsService === 'dreamhost-v6');
1788
				$post_data['type'] = $isv6 ? 'AAAA' : 'A';
1789
				$port = "";
1790
				if ($this->_dnsServer) {
1791
					$server = $this->_dnsServer;
1792 9a3ec9a5 frank
				}
1793 e350558a frank
				if ($this->_dnsPort) {
1794
					$port = ":" . $this->_dnsPort;
1795 9a3ec9a5 frank
				}
1796 e350558a frank
				curl_setopt($ch, CURLOPT_URL, $server . $port);
1797
				curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1798 f2e702b1 frank
				$remove_allowed = true;
1799 e350558a frank
				break;
1800
			default:
1801
				break;
1802
			}
1803 f2e702b1 frank
			if ($remove_allowed) {
1804 e350558a frank
				curl_setopt($ch, CURLOPT_HEADER, 1);
1805 02d6ca03 jim-p
				curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1806 e350558a frank
				$response = curl_exec($ch);
1807
				$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
1808
				$header = substr($response, 0, $header_size);
1809
				$data = substr($response, $header_size);
1810 bdffb77d jim-p
				$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1811
				$curl_error = @curl_error($ch);
1812
				$this->_checkStatus($http_code, $curl_error, $data, $header);
1813 9a3ec9a5 frank
			}
1814 e350558a frank
		}
1815 c5e1ce90 robjarsen
1816 9a3ec9a5 frank
		/**
1817
		 * Private Function (added 23 Feb 17)
1818 f2e702b1 frank
		 * Retrieves current DNS records from an external API source.
1819 c5e1ce90 robjarsen
		 *
1820
		 * Some services cannot perform new operations without the caller
1821
		 * providing existing record information.
1822 9a3ec9a5 frank
		 */
1823
		function _lookup_current() {
1824 f2e702b1 frank
			$lookup_allowed = false;
1825 9a3ec9a5 frank
			if ($this->_dnsVerboseLog) {
1826
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _listCurrent() starting.'), $this->_dnsService, $this->_FQDN));
1827
			}
1828 c5e1ce90 robjarsen
1829 9a3ec9a5 frank
			if (strstr($this->_dnsRequestIf, "_vip")) {
1830
				$parentif = get_configured_vip_interface($this->_dnsRequestIf);
1831
				$realparentif = convert_friendly_interface_to_real_interface_name($parentif);
1832
			} else {
1833
				$realparentif = $this->_dnsRequestIf;
1834
			}
1835 c5e1ce90 robjarsen
1836 9a3ec9a5 frank
			$ch = curl_init();
1837 c5e1ce90 robjarsen
1838 9a3ec9a5 frank
			if ($this->_useIPv6 == false) {
1839
				curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
1840
			}
1841 c5e1ce90 robjarsen
1842 f2e702b1 frank
			curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
1843
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
1844
			curl_setopt($ch, CURLOPT_INTERFACE, 'if!' . $realparentif);
1845
			curl_setopt($ch, CURLOPT_TIMEOUT, 120); // Completely empirical
1846 c5e1ce90 robjarsen
1847 9a3ec9a5 frank
			switch ($this->_dnsService) {
1848 e350558a frank
			case 'dreamhost':
1849
			case 'dreamhost-v6':
1850
				$server = 'https://api.dreamhost.com/';
1851
				$post_data['key'] = $this->_dnsPass;
1852
				$post_data['unique_id'] = uniqid($this->_dnsHost);
1853
				$post_data['cmd'] = 'dns-list_records';
1854
				$post_data['format'] = 'json';
1855
				$port = "";
1856
				if ($this->_dnsServer) {
1857
					$server = $this->_dnsServer;
1858
				}
1859
				if ($this->_dnsPort) {
1860
					$port = ":" . $this->_dnsPort;
1861
				}
1862
				curl_setopt($ch, CURLOPT_URL, $server . $port);
1863
				curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
1864 f2e702b1 frank
				$lookup_allowed = true;
1865 e350558a frank
				break;
1866
			default:
1867
				break;
1868 9a3ec9a5 frank
			}
1869 f2e702b1 frank
			if ($lookup_allowed) {
1870 9a3ec9a5 frank
				curl_setopt($ch, CURLOPT_HEADER, 1);
1871 02d6ca03 jim-p
				curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
1872 9a3ec9a5 frank
				$response = curl_exec($ch);
1873
				$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
1874
				$header = substr($response, 0, $header_size);
1875
				$data = substr($response, $header_size);
1876 02d6ca03 jim-p
				$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1877
				$curl_error = @curl_error($ch);
1878
				$this->_checkLookupStatus($curl_error, $data, $header);
1879 9a3ec9a5 frank
			}
1880
		}
1881
1882
		/*
1883 c5e1ce90 robjarsen
		 * Private Function (added 23 Feb 17)
1884 f2e702b1 frank
		 *   Retrieve Lookup Status from the provided data and/or header
1885 9a3ec9a5 frank
		 */
1886 02d6ca03 jim-p
		function _checkLookupStatus($curl_error, $data, $header) {
1887 9a3ec9a5 frank
			if ($this->_dnsVerboseLog) {
1888
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkLookupStatus() starting.'), $this->_dnsService, $this->_FQDN));
1889
			}
1890
			$success_str = "(" . gettext("Success") . ") ";
1891
			$error_str = "(" . gettext("Error") . ") ";
1892
			$status_intro = "phpDynDNS ({$this->_dnsHost}): ";
1893
1894 02d6ca03 jim-p
			if ($this->_dnsService != 'ods' && !empty($curl_error)) {
1895
				$status = gettext("Curl error occurred:") . " {$curl_error}";
1896 9a3ec9a5 frank
				log_error($status);
1897
				$this->status = $status;
1898
				return;
1899
			}
1900
			switch ($this->_dnsService) {
1901 e350558a frank
			case 'dreamhost':
1902
			case 'dreamhost-v6':
1903
				$result = json_decode($data,true);
1904
				if($result["result"] != "success") {
1905
					log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
1906
					$this->_debug($data);
1907
					return;
1908
				} else {
1909
					foreach($result["data"] as $key => $row) {
1910 c5e1ce90 robjarsen
						if($row["record"] == $this->_dnsHost &&
1911 e350558a frank
								(($row["type"] == "A" && !$this->_useIPv6)
1912
										|| ($row["type"] == "AAAA" && $this->_useIPv6)
1913
								)) {
1914
							if($row["editable"] == 0) {
1915
								log_error($status_intro . "host " . $this->_dnsHost . " is not editable.");
1916
								continue;
1917 9a3ec9a5 frank
							}
1918 e350558a frank
							$this->_existingRecords[]=array("record"=>$row["type"], "type"=>$row["type"], "existing_val"=>$row["value"]);
1919 9a3ec9a5 frank
						}
1920
					}
1921 e350558a frank
				}
1922
				if (!is_array($this->_existingRecords)){
1923
					if ($this->_dnsVerboseLog) {
1924
						log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkLookupStatus() ending.  No matching records found.'), $this->_dnsService, $this->_FQDN));
1925 9a3ec9a5 frank
					}
1926 e350558a frank
				}
1927
				break;
1928
			default:
1929
				break;
1930 9a3ec9a5 frank
			}
1931
		}
1932 1fa2f630 Erik Kristensen
1933
		/*
1934
		 * Private Function (added 12 July 2005) [beta]
1935
		 *   Retrieve Update Status
1936
		 */
1937 bdffb77d jim-p
		function _checkStatus($http_code, $curl_error, $data, $header) {
1938 87b91672 Phil Davis
			if ($this->_dnsVerboseLog) {
1939 9557ca30 Phil Davis
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkStatus() starting.'), $this->_dnsService, $this->_FQDN));
1940 87b91672 Phil Davis
			}
1941 4a6bb2ff Scott Ullrich
			$successful_update = false;
1942 9557ca30 Phil Davis
			$success_str = "(" . gettext("Success") . ") ";
1943
			$error_str = "(" . gettext("Error") . ") ";
1944
			$status_intro = "phpDynDNS ({$this->_dnsHost}): ";
1945
1946 bdffb77d jim-p
			if ($this->_dnsService != 'ods' && !empty($curl_error)) {
1947
				$status = gettext("Curl error occurred:") . " {$curl_error}";
1948 425ba708 Ermal
				log_error($status);
1949
				$this->status = $status;
1950
				return;
1951
			}
1952 1fa2f630 Erik Kristensen
			switch ($this->_dnsService) {
1953 f56efb0d Jaakko Kantojärvi
				// The special custom provider
1954
				case 'custom':
1955
				case 'custom-v6':
1956
					$successful_update = false;
1957
					if ($this->_dnsResultMatch == "") {
1958
						$successful_update = true;
1959
					} else {
1960
						$this->_dnsResultMatch = str_replace("%IP%", $this->_dnsIP, $this->_dnsResultMatch);
1961
						$matches = preg_split("/(?<!\\\\)\\|/", $this->_dnsResultMatch);
1962
						foreach ($matches as $match) {
1963
							$match= str_replace("\\|", "|", $match);
1964
							if (strcmp($match, trim($data, "\t\n\r")) == 0) {
1965
								$successful_update = true;
1966
							}
1967
						}
1968
						unset ($matches);
1969
					}
1970
					if ($successful_update == true) {
1971
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1972
					} else {
1973
						$status = $status_intro . $error_str . gettext("Result did not match.") . " [" . $data . "]";
1974
					}
1975
					break;
1976
				// Providers in an alphabetical order. Add code for new providers below in a correct position.
1977 230ac725 Jaakko Kantojärvi
				case 'dyfi':
1978
					// see specification at https://www.dy.fi/page/specification
1979
					if (preg_match('/badauth/i', $data)) {
1980
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1981
					} else if (preg_match('/nohost/i', $data)) {
1982
						$status = $status_intro . $error_str . gettext("No such host");
1983
					} else if (preg_match('/notfqdn/i', $data)) {
1984
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
1985
					} else if (preg_match('/badip/i', $data)) {
1986
						$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.");
1987
					} else if (preg_match('/nochg/i', $data)) {
1988
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1989
						$successful_update = true;
1990
					} else if (preg_match('/good/i', $data)) {
1991
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1992
						$successful_update = true;
1993
					} else if (preg_match('/dnserr/i', $data)) {
1994
						$status = $status_intro . $error_str . gettext("Server side error.");
1995
					} else if (preg_match('/abuse/i', $data)) {
1996
						$status = $status_intro . $error_str . gettext("Updating too frequently, considered abuse.");
1997
					} else {
1998
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1999
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
2000
						$this->_debug($data);
2001
					}
2002
					break;
2003 197cf433 McB
				case 'glesys':
2004 9557ca30 Phil Davis
					$status_intro = "GleSYS ({$this->_dnsHost}): ";
2005 ae9e5dde Viktor G
					if (preg_match("/OK/i", $data)) {
2006 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2007 197cf433 McB
						$successful_update = true;
2008
					} else {
2009 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2010
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
2011 197cf433 McB
						$this->_debug($data);
2012
					}
2013
					break;
2014 f56efb0d Jaakko Kantojärvi
				//
2015
				// Not yet ordered providers.
2016
				// TODO: When editing a provider, move it above in a correct position.
2017
				//
2018 52e6fdfd Scott Dale
				case 'dnsomatic':
2019 9557ca30 Phil Davis
					$status_intro = "DNS-O-Matic ({$this->_dnsHost}): ";
2020 52e6fdfd Scott Dale
					if (preg_match('/badauth/i', $data)) {
2021 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.");
2022 52e6fdfd Scott Dale
					} else if (preg_match('/notfqdn /i', $data)) {
2023 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.");
2024 52e6fdfd Scott Dale
					} else if (preg_match('/nohost/i', $data)) {
2025 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.");
2026 52e6fdfd Scott Dale
					} else if (preg_match('/numhost/i', $data)) {
2027 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.");
2028 52e6fdfd Scott Dale
					} else if (preg_match('/abuse/i', $data)) {
2029 9557ca30 Phil Davis
						$status = $status_intro . gettext("The hostname is blocked for update abuse.");
2030 52e6fdfd Scott Dale
					} else if (preg_match('/good/i', $data)) {
2031 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2032 52e6fdfd Scott Dale
						$successful_update = true;
2033
					} else if (preg_match('/dnserr/i', $data)) {
2034 9557ca30 Phil Davis
						$status = $status_intro . gettext("DNS error encountered. Stop updating for 30 minutes.");
2035 52e6fdfd Scott Dale
					} else {
2036 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2037
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
2038 52e6fdfd Scott Dale
						$this->_debug($data);
2039
					}
2040
					break;
2041 f2b03cda Viktor G
				case 'domeneshop':
2042
				case 'domeneshop-v6':
2043
					/* Responds with HTTP 204 on success.
2044
					 * see https://api.domeneshop.no/docs/index.html#tag/ddns/paths/~1dyndns~1update/get */
2045
2046 bdffb77d jim-p
					if ($http_code == "204") {
2047 f2b03cda Viktor G
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2048
						$successful_update = true;
2049
					} else {
2050 bdffb77d jim-p
						$status = $status_intro . "(" . gettext("Unknown Response") . ": " . $http_code . ")";
2051 f2b03cda Viktor G
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2052
						$this->_debug($data);
2053
					}
2054
					break;
2055 4e820dc1 Viktor G
				case 'onecom':
2056
				case 'onecom-v6':
2057 f6f1d1c6 Jaakko Kantojärvi
2058 bdffb77d jim-p
					if (($http_code == "200") || ($http_code == "204")) {
2059 4e820dc1 Viktor G
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2060
						$successful_update = true;
2061
					} else {
2062 bdffb77d jim-p
						$status = $status_intro . "(" . gettext("Unknown Response") . ": " . $http_code . ")";
2063 4e820dc1 Viktor G
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2064
						$this->_debug($data);
2065
					}
2066
					break;
2067 2206f1b9 Mathias Andersson
				case 'citynetwork':
2068
					if (preg_match('/notfqdn/i', $data)) {
2069 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
2070 2206f1b9 Mathias Andersson
					} else if (preg_match('/nohost/i', $data)) {
2071 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("No such host");
2072 2206f1b9 Mathias Andersson
					} else if (preg_match('/nochg/i', $data)) {
2073 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2074 2206f1b9 Mathias Andersson
						$successful_update = true;
2075
					} else if (preg_match('/good/i', $data)) {
2076 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2077 2206f1b9 Mathias Andersson
						$successful_update = true;
2078
					} else if (preg_match('/badauth/i', $data)) {
2079 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2080 2206f1b9 Mathias Andersson
					} else {
2081 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2082
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
2083 2206f1b9 Mathias Andersson
						$this->_debug($data);
2084
					}
2085
					break;
2086 a4a56eb0 Stéphane
				case 'ovh-dynhost':
2087 1fa2f630 Erik Kristensen
				case 'dyndns':
2088
					if (preg_match('/notfqdn/i', $data)) {
2089 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
2090 1fa2f630 Erik Kristensen
					} else if (preg_match('/nochg/i', $data)) {
2091 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2092 0ede1bf7 Scott Ullrich
						$successful_update = true;
2093 1fa2f630 Erik Kristensen
					} else if (preg_match('/good/i', $data)) {
2094 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2095 4a6bb2ff Scott Ullrich
						$successful_update = true;
2096 1fa2f630 Erik Kristensen
					} else if (preg_match('/noauth/i', $data)) {
2097 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2098 1fa2f630 Erik Kristensen
					} else {
2099 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2100
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
2101 1fa2f630 Erik Kristensen
						$this->_debug($data);
2102
					}
2103
					break;
2104
				case 'dyndns-static':
2105
					if (preg_match('/notfqdn/i', $data)) {
2106 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
2107 1fa2f630 Erik Kristensen
					} else if (preg_match('/nochg/i', $data)) {
2108 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2109 9b8dc821 Scott Ullrich
						$successful_update = true;
2110 1fa2f630 Erik Kristensen
					} else if (preg_match('/good/i', $data)) {
2111 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2112 4a6bb2ff Scott Ullrich
						$successful_update = true;
2113 1fa2f630 Erik Kristensen
					} else if (preg_match('/noauth/i', $data)) {
2114 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2115 1fa2f630 Erik Kristensen
					} else {
2116 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2117
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
2118 1fa2f630 Erik Kristensen
						$this->_debug($data);
2119
					}
2120
					break;
2121
				case 'dyndns-custom':
2122
					if (preg_match('/notfqdn/i', $data)) {
2123 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
2124 1fa2f630 Erik Kristensen
					} else if (preg_match('/nochg/i', $data)) {
2125 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2126 9b8dc821 Scott Ullrich
						$successful_update = true;
2127 1fa2f630 Erik Kristensen
					} else if (preg_match('/good/i', $data)) {
2128 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2129 4a6bb2ff Scott Ullrich
						$successful_update = true;
2130 1fa2f630 Erik Kristensen
					} else if (preg_match('/noauth/i', $data)) {
2131 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2132 1fa2f630 Erik Kristensen
					} else {
2133 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2134
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
2135 1fa2f630 Erik Kristensen
						$this->_debug($data);
2136
					}
2137
					break;
2138
				case 'dhs':
2139
					break;
2140
				case 'noip':
2141 0333f968 Phil Davis
				case 'noip-free':
2142 8ec7864a Viktor G
					if (preg_match('/good/i', $data)) {
2143
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2144
						$successful_update = true;
2145
					} else if (preg_match('/nochg/i', $data)) {
2146
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2147
						$successful_update = true;
2148
					} else if (preg_match('/nohost/i', $data)) {
2149
						$status = $status_intro . $error_str . gettext("Hostname supplied does not exist under specified account");
2150
					} else if (preg_match('/badauth/i', $data)) {
2151
						$status = $status_intro . $error_str . gettext("Invalid username password combination");
2152
					} else if (preg_match('/badagent/i', $data)) {
2153
						$status = $status_intro . $error_str . gettext("Client disabled");
2154
					} else if (preg_match('/\!donator/i', $data)) {
2155
						$status = $status_intro . $error_str . gettext("Feature is not available");
2156
					} else if (preg_match('/abuse/i', $data)) {
2157
						$status = $status_intro . $error_str . gettext("Username is blocked due to abuse");
2158
					} else if (preg_match('/911/i', $data)) {
2159
						$status = $status_intro . $error_str . gettext("Fatal error");
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
				case 'noip-v6':
2167 91aa6dfd Csoban Kesmarki
				case 'noip-free-v6':
2168 086cf944 Phil Davis
					list($ip, $code) = explode(":", $data);
2169 1fa2f630 Erik Kristensen
					switch ($code) {
2170
						case 0:
2171 9557ca30 Phil Davis
							$status = $status_intro . $success_str . gettext("IP address is current, no update performed.");
2172 4a6bb2ff Scott Ullrich
							$successful_update = true;
2173 1fa2f630 Erik Kristensen
							break;
2174
						case 1:
2175 9557ca30 Phil Davis
							$status = $status_intro . $success_str . gettext("DNS hostname update successful.");
2176 4a6bb2ff Scott Ullrich
							$successful_update = true;
2177 1fa2f630 Erik Kristensen
							break;
2178
						case 2:
2179 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Hostname supplied does not exist.");
2180 1fa2f630 Erik Kristensen
							break;
2181
						case 3:
2182 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Invalid Username.");
2183 1fa2f630 Erik Kristensen
							break;
2184
						case 4:
2185 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Invalid Password.");
2186 1fa2f630 Erik Kristensen
							break;
2187
						case 5:
2188 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Too many updates sent.");
2189 1fa2f630 Erik Kristensen
							break;
2190
						case 6:
2191 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Account disabled due to violation of No-IP terms of service.");
2192 1fa2f630 Erik Kristensen
							break;
2193
						case 7:
2194 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.");
2195 1fa2f630 Erik Kristensen
							break;
2196
						case 8:
2197 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Disabled / Locked Hostname.");
2198 1fa2f630 Erik Kristensen
							break;
2199
						case 9:
2200 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Host updated is configured as a web redirect and no update was performed.");
2201 1fa2f630 Erik Kristensen
							break;
2202
						case 10:
2203 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Group supplied does not exist.");
2204 1fa2f630 Erik Kristensen
							break;
2205
						case 11:
2206 9557ca30 Phil Davis
							$status = $status_intro . $success_str . gettext("DNS group update is successful.");
2207 4a6bb2ff Scott Ullrich
							$successful_update = true;
2208 1fa2f630 Erik Kristensen
							break;
2209
						case 12:
2210 9557ca30 Phil Davis
							$status = $status_intro . $success_str . gettext("DNS group is current, no update performed.");
2211 4a6bb2ff Scott Ullrich
							$successful_update = true;
2212 1fa2f630 Erik Kristensen
							break;
2213
						case 13:
2214 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Update client support not available for supplied hostname or group.");
2215 1fa2f630 Erik Kristensen
							break;
2216
						case 14:
2217 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Hostname supplied does not have offline settings configured.");
2218 1fa2f630 Erik Kristensen
							break;
2219
						case 99:
2220 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Client disabled. Client should exit and not perform any more updates without user intervention.");
2221 1fa2f630 Erik Kristensen
							break;
2222
						case 100:
2223 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Client disabled. Client should exit and not perform any more updates without user intervention.");
2224 1fa2f630 Erik Kristensen
							break;
2225
						default:
2226 9557ca30 Phil Davis
							$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2227
							$this->_debug(gettext("Unknown Response:") . " " . $data);
2228 1fa2f630 Erik Kristensen
							break;
2229
					}
2230
					break;
2231
				case 'easydns':
2232
					if (preg_match('/NOACCESS/i', $data)) {
2233 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Authentication Failed: Username and/or Password was Incorrect.");
2234 1fa2f630 Erik Kristensen
					} else if (preg_match('/NOSERVICE/i', $data)) {
2235 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("No Service: Dynamic DNS Service has been disabled for this domain.");
2236 00105b36 wurzelpanzer
					} else if (preg_match('/ILLEGAL INPUT/i', $data)) {
2237
						$status = $status_intro . $error_str . gettext("Illegal Input: Self-Explanatory");
2238
					} else if (preg_match('/TOOSOON/i', $data)) {
2239
						$status = $status_intro . $error_str . gettext("Too Soon: Not Enough Time Has Elapsed Since Last Update");
2240
					} else if (preg_match('/NOERROR/i', $data)) {
2241
						$status = $status_intro . $success_str . gettext("IP Updated Successfully!");
2242
						$successful_update = true;
2243
					} else {
2244
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2245
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2246
						$this->_debug($data);
2247
					}
2248
					break;
2249
				case 'easydns-v6':
2250
					if (preg_match('/NOACCESS/i', $data)) {
2251
						$status = $status_intro . $error_str . gettext("Authentication Failed: Username and/or Password was Incorrect.");
2252
					} else if (preg_match('/NOSERVICE/i', $data)) {
2253
						$status = $status_intro . $error_str . gettext("No Service: Dynamic DNS Service has been disabled for this domain.");
2254 1fa2f630 Erik Kristensen
					} else if (preg_match('/ILLEGAL INPUT/i', $data)) {
2255 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Illegal Input: Self-Explanatory");
2256 1fa2f630 Erik Kristensen
					} else if (preg_match('/TOOSOON/i', $data)) {
2257 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Too Soon: Not Enough Time Has Elapsed Since Last Update");
2258 1fa2f630 Erik Kristensen
					} else if (preg_match('/NOERROR/i', $data)) {
2259 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Updated Successfully!");
2260 4a6bb2ff Scott Ullrich
						$successful_update = true;
2261 1fa2f630 Erik Kristensen
					} else {
2262 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2263
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2264 1fa2f630 Erik Kristensen
						$this->_debug($data);
2265
					}
2266
					break;
2267
				case 'hn':
2268 9b8dc821 Scott Ullrich
					/* FIXME: add checks */
2269 1fa2f630 Erik Kristensen
					break;
2270
				case 'zoneedit':
2271 9b9e5f09 Scott Ullrich
					if (preg_match('/799/i', $data)) {
2272 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Error 799") . ") " . gettext("Update Failed!");
2273 332a3e59 Scott Ullrich
					} else if (preg_match('/700/i', $data)) {
2274 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Error 700") . ") " . gettext("Update Failed!");
2275 9b9e5f09 Scott Ullrich
					} else if (preg_match('/200/i', $data)) {
2276 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2277 4a6bb2ff Scott Ullrich
						$successful_update = true;
2278 9b9e5f09 Scott Ullrich
					} else if (preg_match('/201/i', $data)) {
2279 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2280 1e0b1727 Phil Davis
						$successful_update = true;
2281 1fa2f630 Erik Kristensen
					} else {
2282 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2283
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2284 1fa2f630 Erik Kristensen
						$this->_debug($data);
2285
					}
2286
					break;
2287
				case 'dyns':
2288
					if (preg_match("/400/i", $data)) {
2289 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - The URL was malformed. Required parameters were not provided.");
2290 1fa2f630 Erik Kristensen
					} else if (preg_match('/402/i', $data)) {
2291 530e4707 NOYB
						$status = $status_intro . $error_str . gettext("Update Too Soon - Attempted to update too quickly since last change.");
2292 1fa2f630 Erik Kristensen
					} else if (preg_match('/403/i', $data)) {
2293 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Database Error - There was a server-sided database error.");
2294 1fa2f630 Erik Kristensen
					} else if (preg_match('/405/i', $data)) {
2295 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);
2296 1fa2f630 Erik Kristensen
					} else if (preg_match('/200/i', $data)) {
2297 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2298 4a6bb2ff Scott Ullrich
						$successful_update = true;
2299 1fa2f630 Erik Kristensen
					} else {
2300 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2301
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2302 1fa2f630 Erik Kristensen
						$this->_debug($data);
2303
					}
2304
					break;
2305
				case 'ods':
2306
					if (preg_match("/299/i", $data)) {
2307 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2308 4a6bb2ff Scott Ullrich
						$successful_update = true;
2309 1fa2f630 Erik Kristensen
					} else {
2310 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2311
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2312 1fa2f630 Erik Kristensen
						$this->_debug($data);
2313
					}
2314
					break;
2315 9b8dc821 Scott Ullrich
				case 'freedns':
2316 ac16181a TechSmurf
				case 'freedns-v6':
2317 9b8dc821 Scott Ullrich
					if (preg_match("/has not changed./i", $data)) {
2318 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2319 9b8dc821 Scott Ullrich
						$successful_update = true;
2320
					} else if (preg_match("/Updated/i", $data)) {
2321 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2322 9b8dc821 Scott Ullrich
						$successful_update = true;
2323
					} else {
2324 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2325 49d54787 Ricky Burgin
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2326
						$this->_debug($data);
2327
					}
2328
					break;
2329 c7df496c Ricky Burgin
				case 'freedns2':
2330
				case 'freedns2-v6':
2331 49d54787 Ricky Burgin
					if (preg_match("/No IP change detected/i", $data)) {
2332
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2333
						$successful_update = true;
2334
					} else if (preg_match("/Updated/i", $data)) {
2335
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2336
						$successful_update = true;
2337
					} else {
2338
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2339 9557ca30 Phil Davis
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2340 9b8dc821 Scott Ullrich
						$this->_debug($data);
2341 1e0b1727 Phil Davis
					}
2342 9b8dc821 Scott Ullrich
					break;
2343 0a1b0183 Ermal Luçi
				case 'dnsexit':
2344 17f81cb6 Koen Zomers
					if (preg_match("/IP not changed/i", $data)) {
2345 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2346 0a1b0183 Ermal Luçi
						$successful_update = true;
2347
					} else if (preg_match("/Success/i", $data)) {
2348 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2349 0a1b0183 Ermal Luçi
						$successful_update = true;
2350
					} else {
2351 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2352
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2353 87b91672 Phil Davis
						$this->_debug($data);
2354 0a1b0183 Ermal Luçi
					}
2355
					break;
2356 9b8dc821 Scott Ullrich
				case 'loopia':
2357
					if (preg_match("/nochg/i", $data)) {
2358 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2359 9b8dc821 Scott Ullrich
						$successful_update = true;
2360
					} else if (preg_match("/good/i", $data)) {
2361 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2362 9b8dc821 Scott Ullrich
						$successful_update = true;
2363
					} else if (preg_match('/badauth/i', $data)) {
2364 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2365 9b8dc821 Scott Ullrich
					} else {
2366 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2367
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2368 9b8dc821 Scott Ullrich
						$this->_debug($data);
2369
					}
2370
					break;
2371 2d78b166 Ermal Luçi
				case 'opendns':
2372
					if (preg_match('/badauth/i', $data)) {
2373 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not a valid username or password!");
2374 2d78b166 Ermal Luçi
					} else if (preg_match('/nohost/i', $data)) {
2375 530e4707 NOYB
						$status = $status_intro . $error_str . gettext("Hostname specified does not exist.");
2376 2d78b166 Ermal Luçi
						$successful_update = true;
2377
					} else if (preg_match('/good/i', $data)) {
2378 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2379 2d78b166 Ermal Luçi
						$successful_update = true;
2380
					} else if (preg_match('/yours/i', $data)) {
2381 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Hostname specified exists, but not under the username specified.");
2382 2d78b166 Ermal Luçi
					} else if (preg_match('/abuse/i', $data)) {
2383 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Updating too frequently, considered abuse.");
2384 2d78b166 Ermal Luçi
					} else {
2385 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2386
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2387 2d78b166 Ermal Luçi
						$this->_debug($data);
2388
					}
2389
					break;
2390 37f3e704 Matt Corallo
				case 'staticcling':
2391 d74b5b8b sullrich
					if (preg_match("/invalid ip/i", $data)) {
2392 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - The IP provided was invalid.");
2393 d74b5b8b sullrich
					} else if (preg_match('/required info missing/i', $data)) {
2394 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - Required parameters were not provided.");
2395 d74b5b8b sullrich
					} else if (preg_match('/invalid characters/i', $data)) {
2396 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - Illegal characters in either the username or the password.");
2397 d74b5b8b sullrich
					} else if (preg_match('/bad password/i', $data)) {
2398 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Invalid password.");
2399 d74b5b8b sullrich
					} else if (preg_match('/account locked/i', $data)) {
2400 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("This account has been administratively locked.");
2401 d74b5b8b sullrich
					} else if (preg_match('/update too frequent/i', $data)) {
2402 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Updating too frequently.");
2403 d74b5b8b sullrich
					} else if (preg_match('/DB error/i', $data)) {
2404 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Server side error.");
2405 d74b5b8b sullrich
					} else if (preg_match('/success/i', $data)) {
2406 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2407 0c7bb880 Phil Davis
						$successful_update = true;
2408 d74b5b8b sullrich
					} else {
2409 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2410
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2411 0c7bb880 Phil Davis
						$this->_debug($data);
2412 d74b5b8b sullrich
					}
2413
					break;
2414 fe6b1252 Viktor G
				case 'mythicbeasts':
2415
				case 'mythicbeasts-v6':
2416
					/* https://www.mythic-beasts.com/support/api/dnsv2/tutorial */
2417
					$result = json_decode($data, true);
2418
					if ($result['message'] == '1 records added') {
2419
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2420
						$successful_update = true;
2421
					} else {
2422
						log_error($status_intro . " ( " . gettext("Error message: ") . $result['error'] . " )");
2423
					}
2424
					break;
2425 6a9fe85f olehfb
				case 'name.com':
2426
				case 'name.com-v6':
2427
					if ($http_code == "200") {
2428
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2429
						$successful_update = true;
2430
					} else {
2431
						$status = $status_intro . "(" . gettext("Error, HTTP response code") . ": " . $http_code . ")";
2432
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2433
					}
2434
					break;
2435 61c30081 jim-p
				case 'namecheap':
2436 18f15f68 jim-p
					$tmp = str_replace("^M", "", $data);
2437
					$ncresponse = @xml2array($tmp);
2438 70db168b jim-p
					/* If XML parsing failed, it may be due to unsupported encoding on the response. */
2439 46127218 jim-p
					if (empty($ncresponse)) {
2440 70db168b jim-p
						mb_convert_encoding($tmp, 'UTF-8', 'UTF-16');
2441
						$tmp = str_ireplace('utf-16', 'utf-8', $tmp);
2442
						$ncresponse = @xml2array($tmp);
2443
					}
2444
					/* If it's still empty, try parsing without the XML definition */
2445
					if (empty($ncresponse)) {
2446
						$matches = [];
2447
						preg_match("/(<?xml.*?>)(.*)/", $tmp, $matches);
2448
						if (count($matches) == 3) {
2449
							$ncresponse = @xml2array($matches[2]);
2450
						}
2451 46127218 jim-p
					}
2452 61c30081 jim-p
					if (preg_match("/internal server error/i", $data)) {
2453 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Server side error.");
2454 3dc3b15b jim-p
					} else if (preg_match("/request is badly formed/i", $data)) {
2455 530e4707 NOYB
						$status = $status_intro . $error_str . gettext("Badly Formed Request (check the settings).");
2456 18f15f68 jim-p
					} else if ($ncresponse['interface-response']['ErrCount'] === "0") {
2457 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2458 c305abd5 jim-p
						$successful_update = true;
2459 18f15f68 jim-p
					} else if (is_numeric($ncresponse['interface-response']['ErrCount']) && ($ncresponse['interface-response']['ErrCount'] > 0)) {
2460 9557ca30 Phil Davis
						$status = $status_intro . $error_str . implode(", ", $ncresponse["interface-response"]["errors"]);
2461 61c30081 jim-p
					} else {
2462 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2463
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2464 61c30081 jim-p
						$this->_debug($data);
2465
					}
2466
					break;
2467 4e820dc1 Viktor G
				case 'nicru':
2468
				case 'nicru-v6':
2469
					$status_intro = "NIC.RU ({$this->_dnsHost}): ";
2470
					if (preg_match('/badauth/i', $data)) {
2471
						$status = $status_intro . gettext("The NIC.RU username or password specified are incorrect.");
2472
					} else if (preg_match('/notfqdn /i', $data)) {
2473
						$status = $status_intro . gettext("The hostname specified is not a fully-qualified domain name.");
2474
					} else if (preg_match('/nohost/i', $data)) {
2475
						$status = $status_intro . gettext("The hostname passed could not be matched to any records configured.");
2476
					} else if (preg_match('/good/i', $data)) {
2477
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2478
						$successful_update = true;
2479
					} else if (preg_match('/dnserr/i', $data)) {
2480
						$status = $status_intro . gettext("DNS error encountered. Stop updating for 30 minutes.");
2481
					} else {
2482
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2483
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
2484
						$this->_debug($data);
2485
					}
2486
					break;
2487 19b7263e Ionut
				case 'duiadns':
2488
				case 'duiadns-v6':
2489
					if (preg_match("/error/i", $data)) {
2490
						$status = $status_intro . $error_str . gettext("Server side error.");
2491
					} else if (preg_match('/nohost/i', $data)) {
2492
						$status = $status_intro . $error_str . gettext("Bad Request - A hostname was not provided.");
2493
					} else if (preg_match('/badauth/i', $data)) {
2494
						$status = $status_intro . $error_str . gettext("Invalid username or password.");
2495
					} else if (preg_match('/good/i', $data)) {
2496
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2497
						$successful_update = true;
2498
					} else if (preg_match('/nochg/i', $data)) {
2499
						$status = $status_intro . $success_str . gettext("No Change In IP Address.");
2500
						$successful_update = true;
2501
					} else {
2502
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2503
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2504
						$this->_debug($data);
2505
					}
2506
					break;
2507 8ea77433 Chris Wells
				case 'he-net':
2508 b4025ccd Daniel Becker
				case 'he-net-v6':
2509 cc0618e2 Michael Smith
				case 'he-net-tunnelbroker':
2510 8ea77433 Chris Wells
					if (preg_match("/badip/i", $data)) {
2511 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - The IP provided was invalid.");
2512 8ea77433 Chris Wells
					} else if (preg_match('/nohost/i', $data)) {
2513 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad Request - A hostname was not provided.");
2514 8ea77433 Chris Wells
					} else if (preg_match('/badauth/i', $data)) {
2515 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Invalid username or password.");
2516 8ea77433 Chris Wells
					} else if (preg_match('/good/i', $data)) {
2517 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2518 0c7bb880 Phil Davis
						$successful_update = true;
2519 8ea77433 Chris Wells
					} else if (preg_match('/nochg/i', $data)) {
2520 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address.");
2521 0c7bb880 Phil Davis
						$successful_update = true;
2522 38a481ad jim-p
					} else {
2523 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2524
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2525 0c7bb880 Phil Davis
						$this->_debug($data);
2526 38a481ad jim-p
					}
2527
					break;
2528 fb403496 Gerald Raaf
				case 'selfhost':
2529
					if (preg_match('/notfqdn/i', $data)) {
2530 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
2531 fb403496 Gerald Raaf
					} else if (preg_match('/nochg/i', $data)) {
2532 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address.");
2533 fb403496 Gerald Raaf
						$successful_update = true;
2534
					} else if (preg_match('/good/i', $data)) {
2535 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2536 fb403496 Gerald Raaf
						$successful_update = true;
2537
					} else if (preg_match('/noauth/i', $data)) {
2538 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2539 fb403496 Gerald Raaf
					} else {
2540 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2541
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2542 fb403496 Gerald Raaf
						$this->_debug($data);
2543
					}
2544
					break;
2545 dc6eb05f Dennis Neuhaeuser
				case 'strato':
2546
					if (preg_match('/good\s' . $this->_dnsIP . '/i', $data)) {
2547
						$status = $status_intro . $success_str . gettext("IP address updated successfully") . " (" . $this->_dnsIP . ")";
2548
						$successful_update = true;
2549
					} else if (preg_match('/good/i', $data)) {
2550
						$status = $status_intro . $error_str . gettext("IP result did not match");
2551
					} else if (preg_match('/nochg/i', $data)) {
2552
						$status = $status_intro . $success_str . gettext("IP was not changed");
2553
						$successful_update = true;
2554
					} else if (preg_match("/badauth/i", $data)) {
2555
						$status = $status_intro . $error_str . gettext("invalid username or password");
2556
					} else if (preg_match('/nohost/i', $data)) {
2557
						$status = $status_intro . $error_str . gettext("invalid hostname");
2558
					} else if (preg_match('/abuse/i', $data)) {
2559
						$status = $status_intro . $error_str . gettext("too many requests - please wait");
2560
					} else {
2561
						$status = $status_intro . "(" . gettext("unknown response") . ")";
2562
						log_error($status_intro . gettext("PAYLOAD:") . " " . $header . $data);
2563
						$this->_debug($data);
2564
						$this->_debug($header);
2565
					}
2566
					break;
2567 0c7bb880 Phil Davis
				case 'route53':
2568 44c64da1 Matthew Fine
				case 'route53-v6':
2569 cc5adcaa Jason McCormick
					if(preg_match('/ErrorResponse/', $data)){
2570
						$status = $status_intro . $error_str . gettext("Route53 API call failed");
2571
						log_error(sprintf("error message: %s", $data));
2572
						$status_update = false;
2573
					} else {
2574 166f4a4c Jason McCormick
						$status = $status_intro . $success_str . gettext("IP address changed successfully");
2575 cc5adcaa Jason McCormick
						$successful_update = true;
2576
					}
2577 0c7bb880 Phil Davis
					break;
2578 3a05e4c3 Austin Seipp
				case 'cloudflare-v6':
2579 e26e1f76 Andrew Senetar
				case 'cloudflare':
2580 22d95a68 doktornotor
					$output = json_decode($data);
2581 4e322e2c Phil Davis
					if ($output->result->content === $this->_dnsIP) {
2582 9557ca30 Phil Davis
						$status = $status_intro . $success_str . sprintf(gettext('%1$s updated to %2$s'), $this->_dnsHost, $this->_dnsIP);
2583 22d95a68 doktornotor
						$successful_update = true;
2584 4e322e2c Phil Davis
					} elseif ($output->errors[0]->code === 9103) {
2585 07a84ece robjarsen
						$status = $status_intro . $error_str . gettext("Invalid Credentials! Don't forget to use API Key for password field with Cloudflare.");
2586 4e322e2c Phil Davis
					} elseif (($output->success) && (!$output->result[0]->id)) {
2587 530e4707 NOYB
						$status = $status_intro . $error_str . gettext("Zone or Host ID was not found, check the hostname.");
2588 4e322e2c Phil Davis
					} else {
2589 9557ca30 Phil Davis
						$status = $status_intro . gettext("UNKNOWN ERROR") . " - " . $output->errors[0]->message;
2590
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2591 ffa1acdc Andrew Senetar
					}
2592
					break;
2593 4e820dc1 Viktor G
				case 'yandex-v6':
2594
				case 'yandex':
2595
					$result = json_decode($data, true);
2596
					if ($result['success'] == 'ok') {
2597
						$successful_update = true;
2598
					} elseif ($result['error'] == 'bad_domain') {
2599
						log_error($status_intro . $error_str .  gettext("The domain name was not specified or does not conform to the RFC"));
2600
					} elseif ($result['error'] == 'unknown') {
2601
						log_error($status_intro . $error_str .  gettext("A temporary failure or API error occurred"));
2602
					} elseif ($result['error'] == 'prohibited') {
2603
						log_error($status_intro . $error_str .  gettext("A forbidden domain name"));
2604
					} elseif ($result['error'] == 'bad_token') {
2605
						log_error($status_intro . $error_str .  gettext("Invalid PDD token"));
2606
					} elseif ($result['error'] == 'no_auth') {
2607
						log_error($status_intro . $error_str .  gettext("The PddToken header was omitted"));
2608
					} elseif ($result['error'] == 'not_allowed') {
2609
						log_error($status_intro . $error_str .  gettext("This operation is not allowed for this user"));
2610
					} elseif ($result['error'] == 'blocked') {
2611
						log_error($status_intro . $error_str .  gettext("Blocked domain"));
2612
					} elseif ($result['error'] == 'occupied') {
2613
						log_error($status_intro . $error_str .  gettext("The domain name is in use by another user"));
2614
					} elseif ($result['error'] == 'domain_limit_reached') {
2615
						log_error($status_intro . $error_str .  gettext("Exceeded the acceptable number of connected domains (50)"));
2616
					} elseif ($result['error'] == 'no_reply') {
2617
						log_error($status_intro . $error_str .  gettext("Yandex.Mail for Domain cannot connect to the server source for the import"));
2618
					} else {
2619
						log_error($status_intro . $error_str .  gettext("PAYLOAD:") . " " . $data);
2620
					}
2621
					break;
2622 ec66caa6 John Byron
				case 'eurodns':
2623
					if (preg_match('/notfqdn/i', $data)) {
2624 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
2625 ec66caa6 John Byron
					} else if (preg_match('/nochg/i', $data)) {
2626 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2627 ec66caa6 John Byron
						$successful_update = true;
2628
					} else if (preg_match('/good/i', $data)) {
2629 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2630 ec66caa6 John Byron
						$successful_update = true;
2631
					} else if (preg_match('/badauth/i', $data)) {
2632 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2633 ec66caa6 John Byron
					} else {
2634 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2635
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2636 ec66caa6 John Byron
						$this->_debug($data);
2637
					}
2638
					break;
2639 5458bc59 Scavy
				case 'gratisdns':
2640
					if (preg_match('/Forkerte værdier/i', $data)) {
2641 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Wrong values - Update could not be completed.");
2642 5458bc59 Scavy
					} else if (preg_match('/Bruger login: Bruger eksistere ikke/i', $data)) {
2643 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Unknown username - User does not exist.");
2644 5458bc59 Scavy
					} else if (preg_match('/Bruger login: 1Fejl i kodeord/i', $data)) {
2645 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Wrong password - Remember password is case sensitive.");
2646 5458bc59 Scavy
					} else if (preg_match('/Domæne kan IKKE administreres af bruger/i', $data)) {
2647 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User unable to administer the selected domain.");
2648 5458bc59 Scavy
					} else if (preg_match('/OK/i', $data)) {
2649 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2650 1e0b1727 Phil Davis
						$successful_update = true;
2651 5458bc59 Scavy
					} else {
2652 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2653
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2654 1e0b1727 Phil Davis
						$this->_debug($data);
2655 5458bc59 Scavy
					}
2656
					break;
2657 544674ad Grant Sheehan
				case 'digitalocean':
2658 0c43f825 Matthew Fine
				case 'digitalocean-v6':
2659 5878d529 Grant Sheehan
					// Creating new records returns an HTTP 201, updating existing records get 200
2660
					// https://redmine.pfsense.org/issues/9171
2661
					if (preg_match("/HTTP\/2\s20[0,1]/i", $header)) {
2662 544674ad Grant Sheehan
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2663
						$successful_update = true;
2664
					} else {
2665
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2666
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2667
						$this->_debug($data);
2668
					}
2669
					break;
2670 916d683e surrural
				case 'dnsimple':
2671 77a0eb0d Zac West
				case 'dnsimple-v6':
2672 916d683e surrural
					/* Responds with HTTP 200 on success.
2673
					   Responds with HTTP 4xx on error.
2674
					   Returns JSON data as body */
2675 0e0f580d Christoph Filnkößl
;
2676 bdffb77d jim-p
					if ($http_code == "200") {
2677 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2678 916d683e surrural
						$successful_update = true;
2679 bdffb77d jim-p
					} else if (preg_match("/4\d\d/i", $http_code)) {
2680 0e0f580d Christoph Filnkößl
						$arrbody = json_decode($data, true);
2681 916d683e surrural
						$message = $arrbody['message'] . ".";
2682
						if (isset($arrbody['errors']['content'])) {
2683 1e0b1727 Phil Davis
							foreach ($arrbody['errors']['content'] as $key => $content) {
2684 916d683e surrural
								$message .= " " . $content . ".";
2685
							}
2686
						}
2687 9557ca30 Phil Davis
						$status = $status_intro . $error_str . $message;
2688 916d683e surrural
					} else {
2689 bdffb77d jim-p
						$status = $status_intro . "(" . gettext("Unknown Response") . ": " . $http_code . ")";
2690 0e0f580d Christoph Filnkößl
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2691
						$this->_debug($data);
2692 916d683e surrural
					}
2693
					break;
2694 456ba14f Sam Neely
				case 'godaddy':
2695
				case 'godaddy-v6':
2696
					/* Responds with HTTP 200 on success.
2697
					   Responds with HTTP 4xx or  on error.
2698
					   Returns JSON data as body */
2699
;
2700
					if (preg_match("/\s200\sOK/i", $header)) {
2701
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
2702
						$successful_update = true;
2703
					} else if (preg_match("/\s4\d\d\s/i", $header)) {
2704
						$arrbody = json_decode($data, true);
2705
						$message = $arrbody['message'] . ".";
2706
						if (isset($arrbody['fields'])) {
2707
							foreach ($arrbody['fields'] as $error) {
2708
								$message .= " " . $error['path'] . ": " . $error['message'] . ".";
2709
							}
2710
						}
2711
						$status = $status_intro . $error_str . $message;
2712
					} else {
2713
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2714
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2715
						$this->_debug($data);
2716
					}
2717
					break;
2718 c5ecdc25 Jose Luis Duran
				case 'googledomains':
2719 6c92b378 Christopher Fazendin
					if (preg_match('/notfqdn/i', $data)) {
2720 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN");
2721 6c92b378 Christopher Fazendin
					} else if (preg_match('/nochg/i', $data)) {
2722 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2723 6c92b378 Christopher Fazendin
						$successful_update = true;
2724
					} else if (preg_match('/good/i', $data)) {
2725 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2726 6c92b378 Christopher Fazendin
						$successful_update = true;
2727
					} else if (preg_match('/badauth/i', $data)) {
2728 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2729 c5ecdc25 Jose Luis Duran
					} else if (preg_match('/nohost/i', $data)) {
2730 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Hostname does not exist or DynDNS not enabled");
2731 c5ecdc25 Jose Luis Duran
					} else if (preg_match('/badagent/i', $data)) {
2732 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Bad request");
2733 c5ecdc25 Jose Luis Duran
					} else if (preg_match('/abuse/i', $data)) {
2734 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Dynamic DNS access has been blocked!");
2735 c5ecdc25 Jose Luis Duran
					} else if (preg_match('/911/i', $data)) {
2736 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Error on Google's end, retry in 5 minutes");
2737 6c92b378 Christopher Fazendin
					} else {
2738 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2739
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2740 6c92b378 Christopher Fazendin
						$this->_debug($data);
2741
					}
2742
					break;
2743 c5ecdc25 Jose Luis Duran
				case 'dnsmadeeasy':
2744
					switch ($data) {
2745
						case 'success':
2746 9557ca30 Phil Davis
							$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2747 c5ecdc25 Jose Luis Duran
							$successful_update = true;
2748
							break;
2749
						case 'error-auth':
2750 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Invalid username or password");
2751 c5ecdc25 Jose Luis Duran
							break;
2752
						case 'error-auth-suspend':
2753 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Account suspended");
2754 c5ecdc25 Jose Luis Duran
							break;
2755
						case 'error-auth-voided':
2756 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Account revoked");
2757 c5ecdc25 Jose Luis Duran
							break;
2758
						case 'error-record-invalid':
2759 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("Record does not exist in the system. Unable to update record");
2760 c5ecdc25 Jose Luis Duran
							break;
2761
						case 'error-record-auth':
2762 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("User does not have access to this record");
2763 c5ecdc25 Jose Luis Duran
							break;
2764
						case 'error-record-ip-same':
2765 9557ca30 Phil Davis
							$status = $status_intro . $success_str . gettext("No Change In IP Address");
2766 c5ecdc25 Jose Luis Duran
							$successful_update = true;
2767
							break;
2768
						case 'error-system':
2769 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("General system error recognized by the system");
2770 c5ecdc25 Jose Luis Duran
							break;
2771
						case 'error':
2772 9557ca30 Phil Davis
							$status = $status_intro . $error_str . gettext("General system error unrecognized by the system");
2773 c5ecdc25 Jose Luis Duran
							break;
2774
						default:
2775 9557ca30 Phil Davis
							$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2776
							log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2777 c5ecdc25 Jose Luis Duran
							$this->_debug($data);
2778
							break;
2779
					}
2780
					break;
2781 1c2c08bd exii1988
				case 'spdyn':
2782
				case 'spdyn-v6':
2783 f3ee8545 Rene Schuster
					if (preg_match('/notfqdn/i', $data)) {
2784 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
2785 f3ee8545 Rene Schuster
					} else if (preg_match('/nohost/i', $data)) {
2786 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("No such host");
2787 f3ee8545 Rene Schuster
					} else if (preg_match('/nochg/i', $data)) {
2788 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
2789
						$successful_update = true;
2790 f3ee8545 Rene Schuster
					} else if (preg_match('/good/i', $data)) {
2791 9557ca30 Phil Davis
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2792
						$successful_update = true;
2793 f3ee8545 Rene Schuster
					} else if (preg_match('/badauth/i', $data)) {
2794 9557ca30 Phil Davis
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2795 f3ee8545 Rene Schuster
					} else {
2796 9557ca30 Phil Davis
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2797
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2798
						$this->_debug($data);
2799 f3ee8545 Rene Schuster
					}
2800
					break;
2801 575b1dcf Christoph Filnkößl
				case 'all-inkl':
2802 f9734a1a Balázs Váradi
 					if (preg_match('/good\s' . $this->_dnsIP . '/i', $data)) {
2803 575b1dcf Christoph Filnkößl
							$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2804
 							$successful_update = true;
2805
 					} else if (preg_match('/good/i', $data)) {
2806
						$status = $status_intro . $error_str . gettext("Result did not match.");
2807
					} else if (preg_match("/\s401\sUnauthorized/i", $header)) {
2808
						$status = $status_intro . $error_str . gettext("Invalid username or password");
2809 c5e1ce90 robjarsen
					}
2810 575b1dcf Christoph Filnkößl
					else {
2811
							$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2812 f9734a1a Balázs Váradi
							log_error($status_intro . gettext("PAYLOAD:") . " " . $header . $data);
2813 575b1dcf Christoph Filnkößl
 							$this->_debug($data);
2814
 							$this->_debug($header);
2815
 					}
2816
 					break;
2817 74533d41 xygrec
				case 'hover':
2818
					if (preg_match('/succeeded":true/i', $data)) {
2819
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2820
						$successful_update = true;
2821
					} else {
2822
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2823
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2824
						$this->_debug($data);
2825
					}
2826
					break;
2827 745d3779 Wagner Sartori Junior
				case 'cloudns':
2828
					$result = json_decode($data, true);
2829
					if ($result['status'] == 'Success') {
2830
						$successful_update = true;
2831
					} else {
2832
						log_error($result['status'] . "(" . $result['statusDescription'] . ")");
2833
					}
2834
					break;
2835 9a3ec9a5 frank
				case 'dreamhost':
2836
				case 'dreamhost-v6':
2837
					$result = json_decode($data,true);
2838
					if ($this->_dnsVerboseLog) {
2839
						log_error(sprintf(gettext('_checkStatus() results: %1$s'), $data));
2840
					}
2841
					switch ($result['data']) {
2842 e350558a frank
					case 'success':
2843
					case 'record_added':
2844
					case 'record_removed':
2845
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
2846
						$successful_update = true;
2847
						break;
2848
					case 'no_record':
2849
					case 'no_such_record ':
2850
						$status = $status_intro . $error_str . gettext("No record exists.");
2851
						break;
2852 598c1d97 frank
					case 'no_type':
2853 e350558a frank
					case 'no_such_type ':
2854
						$status = $status_intro . $error_str . gettext("No type exists.");
2855
						break;
2856 598c1d97 frank
					case 'no_value':
2857 e350558a frank
					case 'no_such_value ':
2858
						$status = $status_intro . $error_str . gettext("No value exists.");
2859
						break;
2860
					case 'no_such_zone':
2861
						$status = $status_intro . $error_str . gettext("No such zone exists.");
2862
						break;
2863
					case 'invalid_record':
2864
						$status = $status_intro . $error_str . gettext("The specified record is invalid.");
2865
						break;
2866
					case 'invalid_type':
2867
						$status = $status_intro . $error_str . gettext("The specified type is invalid.");
2868
						break;
2869
					case 'invalid_value':
2870
						$status = $status_intro . $error_str . gettext("The specified value is invalid.");
2871
						break;
2872
					case 'not_editable ':
2873
						$status = $status_intro . $error_str . gettext("Record is not editable.");
2874
						break;
2875
					case 'record_already_exists_not_editable':
2876
						$status = $status_intro . $error_str . gettext("Record exists but is not editable.");
2877
						break;
2878
					case 'record_already_exists_remove_first':
2879
						$status = $status_intro . $error_str . gettext("Record exists and must be removed before adding.");
2880
						break;
2881
					case 'internal_error_updating_zone':
2882
						$status = $status_intro . $error_str . gettext("A remote server error occurred updating the zone.");
2883
						break;
2884
					case 'internal_error_could_not_load_zone':
2885
						$status = $status_intro . $error_str . gettext("A remote server error occurred loading the zone.");
2886
						break;
2887
					case 'internal_error_could_not_update_zone':
2888
						$status = $status_intro . $error_str . gettext("A remote server error occurred updating the zone.");
2889
						break;
2890
					case 'internal_error_could_not_add_record':
2891
						$status = $status_intro . $error_str . gettext("A remote server error occurred adding a new record.");
2892
						break;
2893
					case 'internal_error_could_not_destroy_record ':
2894
						$status = $status_intro . $error_str . gettext("A remote server error occurred removing an existing record.");
2895
						break;
2896
					default:
2897
						break;
2898 9a3ec9a5 frank
					}
2899 1ac3c88a martgras
				case 'azure':
2900
				case 'azurev6':
2901
					if ($http_code == 401) {
2902
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2903
					} else if ($http_code == 201) {
2904
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2905
						$successful_update = true;
2906
					} else if ($http_code == 200) {
2907
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2908
						$successful_update = true;
2909
					} else {
2910
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2911
						log_error($status_intro . gettext("PAYLOAD:") . " " . $http_code);
2912
						$this->_debug($data);
2913
					}
2914 493e4284 robjarsen
					break;
2915 b923a825 Tom Embt
				case 'linode':
2916
				case 'linode-v6':
2917
					$status_intro = gettext("Dynamic DNS") . " {$this->_dnsService} ({$this->_FQDN}): ";
2918
					$result = json_decode($data,true);
2919
					if ($this->_dnsVerboseLog) {
2920
						log_error(sprintf(gettext('_checkStatus() results: %1$s'), $data));
2921
					}
2922
					if ($http_code == 200 && isset($result["id"]) && ! isset($result["errors"])) {
2923
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2924
						$successful_update = true;
2925
					} else if ( $http_code == 401 && preg_match('/not authorized to use/i', $data) ) {
2926
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2927
					} else {
2928
						$status = $status_intro . $error_str .
2929 bd0a29ea Tom Embt
							( isset($domains_result["errors"][0]["reason"]) ? $domains_result["errors"][0]["reason"] : "HTTP {$http_code}" );
2930 b923a825 Tom Embt
					}
2931
					break;
2932 edfe22f8 Eric Vantillard
				case 'gandi-livedns':
2933 2efdd601 bitscher
				case 'gandi-livedns-v6':
2934 edfe22f8 Eric Vantillard
					if ($http_code == 401) {
2935
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
2936 2efdd601 bitscher
					} else if ($http_code == 200 || $http_code == 201) {
2937 edfe22f8 Eric Vantillard
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2938
						$successful_update = true;
2939
					} else {
2940
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2941
						log_error($status_intro . gettext("PAYLOAD:") . " " . $http_code);
2942
						$this->_debug($data);
2943
					}
2944
					break;
2945 9e8300cb Inperpetuammemoriam
				case 'desec':
2946
				case 'desec-v6':
2947
					switch ($http_code) {
2948
						case '200':
2949
							$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2950 adfb1d2b Tiago d'Avila
							$successful_update = true;
2951
							break;
2952
						case '401':
2953
							$status = $status_intro . $error_str . gettext("User Authorization Failed");
2954
							break;
2955
						default:
2956
							$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2957
							log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2958
							$this->_debug($data);
2959
							break;
2960
					}
2961
					break;
2962
				case 'dynv6':
2963
					switch ($http_code) {
2964
						case '200':
2965
							$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
2966 9e8300cb Inperpetuammemoriam
							$successful_update = true;
2967
							break;
2968
						case '401':
2969
							$status = $status_intro . $error_str . gettext("User Authorization Failed");
2970
							break;
2971
						default:
2972
							$status = $status_intro . "(" . gettext("Unknown Response") . ")";
2973
							log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
2974
							$this->_debug($data);
2975
							break;
2976
					}
2977
					break;
2978 9a3ec9a5 frank
				default:
2979
					break;
2980 1fa2f630 Erik Kristensen
			}
2981 916d683e surrural
2982 1e0b1727 Phil Davis
			if ($successful_update == true) {
2983 4a6bb2ff Scott Ullrich
				/* Write WAN IP to cache file */
2984 22de7804 Bill Marquette
				$wan_ip = $this->_checkIP();
2985 d7e6f573 Daniel Becker
				if ($this->_useIPv6 == false && $wan_ip > 0) {
2986 53842a6c jim-p
					$currentTime = time();
2987 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));
2988
					log_error(sprintf(gettext('phpDynDNS: updating cache file %1$s: %2$s'), $this->_cacheFile, $wan_ip));
2989 d51cdd48 Renato Botelho
					@file_put_contents($this->_cacheFile, "{$wan_ip}|{$currentTime}");
2990 1e0b1727 Phil Davis
				} else {
2991 dd575ea4 Ermal
					@unlink($this->_cacheFile);
2992 1e0b1727 Phil Davis
				}
2993 d7e6f573 Daniel Becker
				if ($this->_useIPv6 == true && $wan_ip > 0) {
2994 b4025ccd Daniel Becker
					$currentTime = time();
2995 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));
2996 9557ca30 Phil Davis
					log_error(sprintf(gettext('phpDynDNS: updating cache file %1$s: %2$s'), $this->_cacheFile_v6, $wan_ip));
2997 b4319c50 Daniel Becker
					@file_put_contents($this->_cacheFile_v6, "{$wan_ip}|{$currentTime}");
2998 1e0b1727 Phil Davis
				} else {
2999 d7e6f573 Daniel Becker
					@unlink($this->_cacheFile_v6);
3000 1e0b1727 Phil Davis
				}
3001 4a6bb2ff Scott Ullrich
			}
3002 1fa2f630 Erik Kristensen
			$this->status = $status;
3003
			log_error($status);
3004 02d6ca03 jim-p
			if ($this->_dnsVerboseLog) {
3005
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkStatus() ending.'), $this->_dnsService, $this->_FQDN));
3006
			}
3007 1fa2f630 Erik Kristensen
		}
3008
3009
		/*
3010
		 * Private Function (added 12 July 05) [beta]
3011
		 *   Return Error, Set Last Error, and Die.
3012
		 */
3013
		function _error($errorNumber = '1') {
3014 9557ca30 Phil Davis
			$err_str = 'phpDynDNS: (' . gettext('ERROR!') . ') ';
3015
			$err_str_r53 = 'Route 53: (' . gettext('Error') . ') ';
3016 1fa2f630 Erik Kristensen
			switch ($errorNumber) {
3017
				case 0:
3018
					break;
3019
				case 2:
3020 9557ca30 Phil Davis
					$error = $err_str . gettext('No Dynamic DNS Service provider was selected.');
3021 1fa2f630 Erik Kristensen
					break;
3022
				case 3:
3023 9557ca30 Phil Davis
					$error = $err_str . gettext('No Username Provided.');
3024 1fa2f630 Erik Kristensen
					break;
3025
				case 4:
3026 9557ca30 Phil Davis
					$error = $err_str . gettext('No Password Provided.');
3027 1fa2f630 Erik Kristensen
					break;
3028
				case 5:
3029 9557ca30 Phil Davis
					$error = $err_str . gettext('No Hostname Provided.');
3030 1fa2f630 Erik Kristensen
					break;
3031
				case 6:
3032 9557ca30 Phil Davis
					$error = $err_str . gettext('The Dynamic DNS Service provided is not yet supported.');
3033 1fa2f630 Erik Kristensen
					break;
3034 9b8dc821 Scott Ullrich
				case 7:
3035 9557ca30 Phil Davis
					$error = $err_str . gettext('No Update URL Provided.');
3036 9b8dc821 Scott Ullrich
					break;
3037 0c7bb880 Phil Davis
				case 8:
3038 9557ca30 Phil Davis
					$status = $err_str_r53 . gettext("Invalid ZoneID");
3039 cd132e86 Edson Brandi
					break;
3040 0c7bb880 Phil Davis
				case 9:
3041 9557ca30 Phil Davis
					$status = $err_str_r53 . gettext("Invalid TTL");
3042 1e0b1727 Phil Davis
					break;
3043 1fa2f630 Erik Kristensen
				case 10:
3044 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);
3045 1fa2f630 Erik Kristensen
					break;
3046
				default:
3047 9557ca30 Phil Davis
					$error = $err_str . gettext('Unknown Response.');
3048 9b8dc821 Scott Ullrich
					/* FIXME: $data isn't in scope here */
3049
					/* $this->_debug($data); */
3050 1fa2f630 Erik Kristensen
					break;
3051
			}
3052
			$this->lastError = $error;
3053
			log_error($error);
3054
		}
3055
3056
		/*
3057
		 * Private Function (added 12 July 05) [beta]
3058
		 *   - Detect whether or not IP needs to be updated.
3059 5775f324 Chris Buechler
		 *      | Written Specifically for pfSense (https://www.pfsense.org) may
3060 1fa2f630 Erik Kristensen
		 *      | work with other systems. pfSense base is FreeBSD.
3061
		 */
3062
		function _detectChange() {
3063 bdffb77d jim-p
			if ($this->_dnsVerboseLog) {
3064 9557ca30 Phil Davis
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _detectChange() starting.'), $this->_dnsService, $this->_FQDN));
3065 1e0b1727 Phil Davis
			}
3066
3067 1fa2f630 Erik Kristensen
			$currentTime = time();
3068
3069 22de7804 Bill Marquette
			$wan_ip = $this->_checkIP();
3070 dd575ea4 Ermal
			if ($wan_ip == 0) {
3071 9557ca30 Phil Davis
				log_error(sprintf(gettext("Dynamic Dns (%s): Current WAN IP could not be determined, skipping update process."), $this->_FQDN));
3072 193ee786 Ermal
				return false;
3073 dd575ea4 Ermal
			}
3074 9557ca30 Phil Davis
			$log_error = sprintf(gettext('Dynamic Dns (%1$s): Current WAN IP: %2$s'), $this->_FQDN, $wan_ip) . " ";
3075 1fa2f630 Erik Kristensen
3076 d7e6f573 Daniel Becker
			if ($this->_useIPv6 == true) {
3077
				if (file_exists($this->_cacheFile_v6)) {
3078
					$contents = file_get_contents($this->_cacheFile_v6);
3079 086cf944 Phil Davis
					list($cacheIP, $cacheTime) = explode('|', $contents);
3080 f9734a1a Balázs Váradi
					$this->_debug($cacheIP . '/' . $cacheTime);
3081 d7e6f573 Daniel Becker
					$initial = false;
3082 9557ca30 Phil Davis
					$log_error .= sprintf(gettext("Cached IPv6: %s"), $cacheIP);
3083 d7e6f573 Daniel Becker
				} else {
3084
					$cacheIP = '::';
3085 b4319c50 Daniel Becker
					@file_put_contents($this->_cacheFile, "::|{$currentTime}");
3086 d7e6f573 Daniel Becker
					$cacheTime = $currentTime;
3087
					$initial = true;
3088 9557ca30 Phil Davis
					$log_error .= gettext("No Cached IPv6 found.");
3089 d7e6f573 Daniel Becker
				}
3090 1fa2f630 Erik Kristensen
			} else {
3091 d7e6f573 Daniel Becker
				if (file_exists($this->_cacheFile)) {
3092
					$contents = file_get_contents($this->_cacheFile);
3093 d51cdd48 Renato Botelho
					list($cacheIP, $cacheTime) = explode('|', $contents);
3094 f9734a1a Balázs Váradi
					$this->_debug($cacheIP . '/' . $cacheTime);
3095 d7e6f573 Daniel Becker
					$initial = false;
3096 9557ca30 Phil Davis
					$log_error .= sprintf(gettext("Cached IP: %s"), $cacheIP);
3097 d7e6f573 Daniel Becker
				} else {
3098
					$cacheIP = '0.0.0.0';
3099 d51cdd48 Renato Botelho
					@file_put_contents($this->_cacheFile, "0.0.0.0|{$currentTime}");
3100 d7e6f573 Daniel Becker
					$cacheTime = $currentTime;
3101
					$initial = true;
3102 9557ca30 Phil Davis
					$log_error .= gettext("No Cached IP found.");
3103 d7e6f573 Daniel Becker
				}
3104 1fa2f630 Erik Kristensen
			}
3105 1e0b1727 Phil Davis
			if ($this->_dnsVerboseLog) {
3106 87b91672 Phil Davis
				log_error($log_error);
3107 1e0b1727 Phil Davis
			}
3108 1fa2f630 Erik Kristensen
3109 f5e293e6 Phil Davis
			// Convert seconds = days * hr/day * min/hr * sec/min
3110 79b9e082 Jaakko Kantojärvi
			// We subtract 1 hour, so that when this code is executed few seconds
3111
			// before _dnsMaxCacheAgeDays has passed, then we still consider that
3112
			// a required number of days has passed.
3113
			$maxCacheAgeSecs = $this->_dnsMaxCacheAgeDays * 24 * 60 * 60 - 60 * 60;
3114 1fa2f630 Erik Kristensen
3115 e24b26e9 Scott Ullrich
			$needs_updating = FALSE;
3116 4494cf6a Chris Buechler
			/* lets determine if the item needs updating */
3117 a255e1f7 Scott Ullrich
			if ($cacheIP != $wan_ip) {
3118 eb346556 Ermal Lu?i
				$needs_updating = true;
3119 9557ca30 Phil Davis
				$update_reason = gettext("Dynamic Dns: cacheIP != wan_ip. Updating.") . " ";
3120
				$update_reason .= sprintf(gettext('Cached IP: %1$s WAN IP: %2$s'), $cacheIP, $wan_ip) . " ";
3121 a255e1f7 Scott Ullrich
			}
3122 f5e293e6 Phil Davis
			if (($currentTime - $cacheTime) > $maxCacheAgeSecs) {
3123 c3c3e03b Ermal
				$needs_updating = true;
3124 0333f968 Phil Davis
				$this->_forceUpdateNeeded = true;
3125 9557ca30 Phil Davis
				$update_reason = sprintf(gettext("Dynamic Dns: More than %s days. Updating."), $this->_dnsMaxCacheAgeDays);
3126
				$update_reason .= " {$currentTime} - {$cacheTime} > {$maxCacheAgeSecs} ";
3127 a255e1f7 Scott Ullrich
			}
3128 eb346556 Ermal Lu?i
			if ($initial == true) {
3129
				$needs_updating = true;
3130 9557ca30 Phil Davis
				$update_reason .= gettext("Initial update.");
3131 a255e1f7 Scott Ullrich
			}
3132 eb346556 Ermal Lu?i
3133 a255e1f7 Scott Ullrich
			/*   finally if we need updating then store the
3134
			 *   new cache value and return true
3135 0c7bb880 Phil Davis
			 */
3136 eb346556 Ermal Lu?i
			if ($needs_updating == true) {
3137 086cf944 Phil Davis
				if ($this->_dnsVerboseLog) {
3138 6635aa0f jim-p
					log_error("DynDns ({$this->_FQDN}): {$update_reason}");
3139 086cf944 Phil Davis
				}
3140 eb346556 Ermal Lu?i
				return true;
3141 1fa2f630 Erik Kristensen
			}
3142 eb346556 Ermal Lu?i
3143 1e0b1727 Phil Davis
			return false;
3144 1fa2f630 Erik Kristensen
		}
3145
3146
		/*
3147 0c7bb880 Phil Davis
		 * Private Function (added 16 July 05) [beta]
3148 1fa2f630 Erik Kristensen
		 *   - Writes debug information to a file.
3149
		 *   - This function is only called when a unknown response
3150
		 *   - status is returned from a DynDNS service provider.
3151
		 */
3152 6a45171d Ermal
		function _debug($data) {
3153
			global $g;
3154
3155 1e0b1727 Phil Davis
			if (!$g['debug']) {
3156 6a45171d Ermal
				return;
3157 1e0b1727 Phil Davis
			}
3158 f9734a1a Balázs Váradi
			$string = date('m-d-y h:i:s') . ' - (' . $this->_debugID . ') - [' . $this->_dnsService . '] - ' . $data . "\n";
3159 1fa2f630 Erik Kristensen
			$file = fopen($this->_debugFile, 'a');
3160
			fwrite($file, $string);
3161
			fclose($file);
3162
		}
3163 22de7804 Bill Marquette
		function _checkIP() {
3164 bdffb77d jim-p
			if ($this->_dnsVerboseLog) {
3165 9557ca30 Phil Davis
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkIP() starting.'), $this->_dnsService, $this->_FQDN));
3166 1e0b1727 Phil Davis
			}
3167 22de7804 Bill Marquette
3168 d7e6f573 Daniel Becker
			if ($this->_useIPv6 == true) {
3169 d20a3d08 Chris Buechler
				$ip_address = get_interface_ipv6($this->_if);
3170 1e0b1727 Phil Davis
				if (!is_ipaddrv6($ip_address)) {
3171 d7e6f573 Daniel Becker
					return 0;
3172 1e0b1727 Phil Davis
				}
3173 d7e6f573 Daniel Becker
			} else {
3174 be060079 jim-p
				$ip_address = dyndnsCheckIP($this->_if);
3175 1e0b1727 Phil Davis
				if (!is_ipaddr($ip_address)) {
3176 1fa4c473 Viktor G
					log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): IP address could not be extracted from Check IP Service'), $this->_dnsService, $this->_FQDN));
3177
					return 0;
3178
				} elseif (is_private_ip($ip_address)) {
3179
					log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): Public IP address could not be extracted from Check IP Service'), $this->_dnsService, $this->_FQDN));
3180 d7e6f573 Daniel Becker
					return 0;
3181 1e0b1727 Phil Davis
				}
3182 d7e6f573 Daniel Becker
			}
3183 be060079 jim-p
			if ($this->_useIPv6 == false && is_private_ip(get_interface_ip($this->_if))) {
3184 1fa4c473 Viktor G
				if ($this->_dnsVerboseLog) {
3185
					log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): %3$s extracted from Check IP Service'), $this->_dnsService, $this->_FQDN, $ip_address));
3186 c749ef62 Ermal
				}
3187 87b91672 Phil Davis
			} else {
3188 1e0b1727 Phil Davis
				if ($this->_dnsVerboseLog) {
3189 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));
3190 1e0b1727 Phil Davis
				}
3191 87b91672 Phil Davis
			}
3192 fffbfef0 Matt Corallo
			$this->_dnsIP = $ip_address;
3193
3194 22de7804 Bill Marquette
			return $ip_address;
3195
		}
3196 1fa2f630 Erik Kristensen
3197
	}
3198
3199 aa7c49b9 Ermal
?>