Project

General

Profile

Download (70 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * dyndns.class
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7
 * All rights reserved.
8
 *
9
 * Licensed under the Apache License, Version 2.0 (the "License");
10
 * you may not use this file except in compliance with the License.
11
 * You may obtain a copy of the License at
12
 *
13
 * http://www.apache.org/licenses/LICENSE-2.0
14
 *
15
 * Unless required by applicable law or agreed to in writing, software
16
 * distributed under the License is distributed on an "AS IS" BASIS,
17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
 * See the License for the specific language governing permissions and
19
 * limitations under the License.
20
 */
21

    
22
	/*
23
	 * PHP.updateDNS (pfSense version)
24
	 *
25
	 * +====================================================+
26
	 *  Services Supported:
27
	 *    - DynDns (dyndns.org) [dynamic, static, custom]
28
	 *    - No-IP (no-ip.com)
29
	 *    - EasyDNS (easydns.com)
30
	 *    - DHS (www.dhs.org)
31
	 *    - HN (hn.org) -- incomplete checking!
32
	 *    - DynS (dyns.org)
33
	 *    - ZoneEdit (zoneedit.com)
34
	 *    - FreeDNS (freedns.afraid.org)
35
	 *    - FreeDNS IPv6 (freedns.afraid.org)
36
	 *    - Loopia (loopia.se)
37
	 *    - StaticCling (staticcling.org)
38
	 *    - DNSexit (dnsexit.com)
39
	 *    - OpenDNS (opendns.com)
40
	 *    - Namecheap (namecheap.com)
41
	 *    - HE.net (dns.he.net)
42
	 *    - HE.net IPv6 (dns.he.net)
43
	 *    - HE.net Tunnelbroker IP update (ipv4.tunnelbroker.net)
44
	 *    - SelfHost (selfhost.de)
45
	 *    - Amazon Route 53 (aws.amazon.com)
46
	 *    - DNS-O-Matic (dnsomatic.com)
47
	 *    - Custom DDNS (any URL)
48
	 *    - Custom DDNS IPv6 (any URL)
49
	 *    - CloudFlare (www.cloudflare.com)
50
	 *    - CloudFlare IPv6 (www.cloudflare.com)
51
	 *    - Eurodns (eurodns.com)
52
	 *    - GratisDNS (gratisdns.dk)
53
	 *    - City Network (citynetwork.se)
54
	 *    - GleSYS (glesys.com)
55
	 *    - DNSimple (dnsimple.com)
56
	 *    - Google Domains (domains.google.com)
57
	 *    - DNS Made Easy (www.dnsmadeeasy.com)
58
	 *    - SPDYN (spdyn.de)
59
	 *    - SPDYN IPv6 (spdyn.de)
60
	 *    - All-Inkl (all-inkl.com)
61
	 *    - DuiaDNS (www.duiadns.net)
62
	 *    - DuiaDNS IPv6 (www.duiadns.net)
63
	 * +----------------------------------------------------+
64
	 *  Requirements:
65
	 *    - PHP version 4.0.2 or higher with the CURL Library and the PCRE Library
66
	 * +----------------------------------------------------+
67
	 *  Public Functions
68
	 *    - updatedns()
69
	 *
70
	 *  Private Functions
71
	 *    - _update()
72
	 *    - _checkStatus()
73
	 *    - _error()
74
	 *    - _detectChange()
75
	 *    - _debug()
76
	 *    - _checkIP()
77
	 * +----------------------------------------------------+
78
	 *  DynDNS Dynamic  - Last Tested: 12 July 2005
79
	 *  DynDNS Static   - Last Tested: NEVER
80
	 *  DynDNS Custom   - Last Tested: NEVER
81
	 *  No-IP           - Last Tested: 20 July 2008
82
	 *  HN.org          - Last Tested: 12 July 2005
83
	 *  EasyDNS         - Last Tested: 20 July 2008
84
	 *  DHS             - Last Tested: 12 July 2005
85
	 *  ZoneEdit        - Last Tested: NEVER
86
	 *  Dyns            - Last Tested: NEVER
87
	 *  ODS             - Last Tested: 02 August 2005
88
	 *  FreeDNS         - Last Tested: 01 May 2016
89
	 *  FreeDNS IPv6    - Last Tested: 01 May 2016
90
	 *  Loopia          - Last Tested: NEVER
91
	 *  StaticCling     - Last Tested: 27 April 2006
92
	 *  DNSexit         - Last Tested: 20 July 2008
93
	 *  OpenDNS         - Last Tested: 4 August 2008
94
	 *  Namecheap       - Last Tested: 31 August 2010
95
	 *  HE.net          - Last Tested: 7 July 2013
96
	 *  HE.net IPv6     - Last Tested: 7 July 2013
97
	 *  HE.net Tunnel   - Last Tested: 28 June 2011
98
	 *  SelfHost        - Last Tested: 26 December 2011
99
	 *  Amazon Route 53 - Last Tested: 30 August 2016 
100
	 *  DNS-O-Matic     - Last Tested: 9 September 2010
101
	 *  CloudFlare      - Last Tested: 05 September 2016
102
	 *  CloudFlare IPv6 - Last Tested: 17 July 2016
103
	 *  Eurodns         - Last Tested: 27 June 2013
104
	 *  GratisDNS       - Last Tested: 15 August 2012
105
	 *  OVH DynHOST     - Last Tested: NEVER
106
	 *  City Network    - Last Tested: 13 November 2013
107
	 *  GleSYS          - Last Tested: 3 February 2015
108
	 *  DNSimple        - Last Tested: 09 February 2015
109
	 *  Google Domains  - Last Tested: 27 April 2015
110
	 *  DNS Made Easy   - Last Tested: 27 April 2015
111
	 *  SPDYN           - Last Tested: 02 July 2016
112
	 *  SPDYN IPv6      - Last Tested: 02 July 2016
113
	 *  All-Inkl        - Last Tested: 12 November 2016
114
	 *  DuiaDNS         - Last Tested: 25 November 2016
115
	 *  DuiaDNS IPv6    - Last Tested: 25 November 2016
116
	 * +====================================================+
117
	 *
118
	 * @author 	E.Kristensen
119
	 * @link    	http://www.idylldesigns.com/projects/phpdns/
120
	 * @version 	0.8
121
	 * @updated	13 October 05 at 21:02:42 GMT
122
	 *
123
	 * DNSexit/OpenDNS support and multiwan extension for pfSense by Ermal Luçi
124
	 * Custom DNS support by Matt Corallo
125
	 *
126
	 */
127

    
128
	class updatedns {
129
		var $_cacheFile;
130
		var $_cacheFile_v6;
131
		var $_debugFile;
132
		var $_UserAgent = 'phpDynDNS/0.7';
133
		var $_errorVerbosity = 0;
134
		var $_dnsService;
135
		var $_dnsUser;
136
		var $_dnsPass;
137
		var $_dnsHost;
138
		var $_dnsDomain;
139
		var $_FQDN;
140
		var $_dnsIP;
141
		var $_dnsWildcard;
142
		var $_dnsProxied;
143
		var $_dnsMX;
144
		var $_dnsBackMX;
145
		var $_dnsServer;
146
		var $_dnsPort;
147
		var $_dnsUpdateURL;
148
		var $_dnsZoneID;
149
		var $_dnsTTL;
150
		var $status;
151
		var $_debugID;
152
		var $_if;
153
		var $_dnsResultMatch;
154
		var $_dnsRequestIf;
155
		var $_dnsRequestIfIP;
156
		var $_dnsVerboseLog;
157
		var $_curlIpresolveV4;
158
		var $_curlSslVerifypeer;
159
		var $_dnsMaxCacheAgeDays;
160
		var $_dnsDummyUpdateDone;
161
		var $_forceUpdateNeeded;
162
		var $_useIPv6;
163

    
164
		/*
165
		 * Public Constructor Function (added 12 July 05) [beta]
166
		 *   - Gets the dice rolling for the update.
167
		 *   - $dnsResultMatch should only be used with $dnsService = 'custom'
168
		 *   -  $dnsResultMatch is parsed for '%IP%', which is the IP the provider was updated to,
169
		 *   -  it is otherwise expected to be exactly identical to what is returned by the Provider.
170
		 *   - $dnsUser, and $dnsPass indicate HTTP Auth for custom DNS, if they are needed in the URL (GET Variables), include them in $dnsUpdateURL.
171
		 *   - $For custom requests, $dnsUpdateURL is parsed for '%IP%', which is replaced with the new IP.
172
		 */
173
		function updatedns ($dnsService = '', $dnsHost = '', $dnsDomain = '', $dnsUser = '', $dnsPass = '',
174
					$dnsWildcard = 'OFF', $dnsProxied = false, $dnsMX = '', $dnsIf = '', $dnsBackMX = '',
175
					$dnsServer = '', $dnsPort = '', $dnsUpdateURL = '', $forceUpdate = false,
176
					$dnsZoneID ='', $dnsTTL='', $dnsResultMatch = '', $dnsRequestIf = '',
177
					$dnsID = '', $dnsVerboseLog = false, $curlIpresolveV4 = false, $curlSslVerifypeer = true) {
178

    
179
			global $config, $g, $dyndns_split_domain_types;
180
			if (in_array($dnsService, $dyndns_split_domain_types)) {
181
				$this->_FQDN = $dnsHost . "." . $dnsDomain;
182
			} else {
183
				$this->_FQDN = $dnsHost;
184
			}
185

    
186
			$this->_cacheFile = "{$g['conf_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($this->_FQDN) . "{$dnsID}.cache";
187
			$this->_cacheFile_v6 = "{$g['conf_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($this->_FQDN) . "{$dnsID}_v6.cache";
188
			$this->_debugFile = "{$g['varetc_path']}/dyndns_{$dnsIf}{$dnsService}" . escapeshellarg($this->_FQDN) . "{$dnsID}.debug";
189

    
190
			$this->_curlIpresolveV4 = $curlIpresolveV4;
191
			$this->_curlSslVerifypeer = $curlSslVerifypeer;
192
			$this->_dnsVerboseLog = $dnsVerboseLog;
193
			if ($this->_dnsVerboseLog) {
194
				log_error(gettext("Dynamic DNS: updatedns() starting"));
195
			}
196

    
197
			$dyndnslck = lock("DDNS".$dnsID, LOCK_EX);
198

    
199
			if (!$dnsService) $this->_error(2);
200
			switch ($dnsService) {
201
			case 'freedns':
202
			case 'freedns-v6':
203
				if (!$dnsHost) $this->_error(5);
204
				break;
205
			case "namecheap":
206
				if (!$dnsPass) $this->_error(4);
207
				if (!$dnsHost) $this->_error(5);
208
				if (!$dnsDomain) $this->_error(5);
209
				break;
210
			case "cloudflare-v6":
211
			case "cloudflare":
212
			case "gratisdns":
213
				if (!$dnsUser) $this->_error(3);
214
				if (!$dnsPass) $this->_error(4);
215
				if (!$dnsHost) $this->_error(5);
216
				if (!$dnsDomain) $this->_error(5);
217
				break;
218
			case 'route53':
219
				if (!$dnsZoneID) $this->_error(8);
220
				if (!$dnsTTL) $this->_error(9);
221
				break;
222
			case 'custom':
223
				if (!$dnsUpdateURL) $this->_error(7);
224
				break;
225
			default:
226
				if (!$dnsUser) $this->_error(3);
227
				if (!$dnsPass) $this->_error(4);
228
				if (!$dnsHost) $this->_error(5);
229
			}
230

    
231
			switch ($dnsService) {
232
				case 'he-net-v6':
233
				case 'custom-v6':
234
				case 'spdyn-v6':
235
				case 'duiadns-v6':
236
				case 'freedns-v6':
237
				case 'cloudflare-v6':
238
					$this->_useIPv6 = true;
239
					break;
240
				default:
241
					$this->_useIPv6 = false;
242
			}
243
			$this->_dnsService = strtolower($dnsService);
244
			$this->_dnsUser = $dnsUser;
245
			$this->_dnsPass = base64_decode($dnsPass);
246
			$this->_dnsHost = $dnsHost;
247
			$this->_dnsDomain = $dnsDomain;
248
			$this->_dnsServer = $dnsServer;
249
			$this->_dnsPort = $dnsPort;
250
			$this->_dnsWildcard = $dnsWildcard;
251
			$this->_dnsProxied = $dnsProxied;
252
			$this->_dnsMX = $dnsMX;
253
			$this->_dnsZoneID = $dnsZoneID;
254
			$this->_dnsTTL = $dnsTTL;
255
			$this->_if = get_failover_interface($dnsIf);
256
			$this->_checkIP();
257
			$this->_dnsUpdateURL = $dnsUpdateURL;
258
			$this->_dnsResultMatch = $dnsResultMatch;
259
			$this->_dnsRequestIf = get_failover_interface($dnsRequestIf);
260
			if ($this->_dnsVerboseLog) {
261
				log_error(sprintf(gettext('Dynamic DNS (%1$s): running get_failover_interface for %2$s. found %3$s'), $this->_FQDN, $dnsRequestIf, $this->_dnsRequestIf));
262
			}
263
			$this->_dnsRequestIfIP = get_interface_ip($dnsRequestIf);
264
			$this->_dnsMaxCacheAgeDays = 25;
265
			$this->_dnsDummyUpdateDone = false;
266
			$this->_forceUpdateNeeded = $forceUpdate;
267

    
268
			// Ensure that we were able to lookup the IP
269
			if (!is_ipaddr($this->_dnsIP)) {
270
				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));
271
				unlock($dyndnslck);
272
				return;
273
			}
274

    
275
			$this->_debugID = rand(1000000, 9999999);
276

    
277
			if ($forceUpdate == false && $this->_detectChange() == false) {
278
				$this->_error(10);
279
			} else {
280
				switch ($this->_dnsService) {
281
					case 'glesys':
282
					case 'dnsomatic':
283
					case 'dyndns':
284
					case 'dyndns-static':
285
					case 'dyndns-custom':
286
					case 'dhs':
287
					case 'noip':
288
					case 'noip-free':
289
					case 'easydns':
290
					case 'hn':
291
					case 'zoneedit':
292
					case 'dyns':
293
					case 'ods':
294
					case 'freedns':
295
					case 'freedns-v6':
296
					case 'loopia':
297
					case 'staticcling':
298
					case 'dnsexit':
299
					case 'custom':
300
					case 'custom-v6':
301
					case 'opendns':
302
					case 'namecheap':
303
					case 'he-net':
304
					case 'he-net-v6':
305
					case 'duiadns':
306
					case 'duiadns-v6':
307
					case 'selfhost':
308
					case 'he-net-tunnelbroker':
309
					case 'route53':
310
					case 'cloudflare':
311
					case 'cloudflare-v6':
312
					case 'eurodns':
313
					case 'gratisdns':
314
					case 'ovh-dynhost':
315
					case 'citynetwork':
316
					case 'dnsimple':
317
					case 'googledomains':
318
					case 'dnsmadeeasy':
319
					case 'spdyn':
320
					case 'spdyn-v6':
321
					case 'all-inkl':
322
						$this->_update();
323
						if ($this->_dnsDummyUpdateDone == true) {
324
							// If a dummy update was needed, then sleep a while and do the update again to put the proper address back.
325
							// Some providers (e.g. No-IP free accounts) need to have at least 1 address change every month.
326
							// If the address has not changed recently, or the user did "Force Update", then the code does
327
							// a dummy address change for providers like this.
328
							sleep(10);
329
							$this->_update();
330
						}
331
						break;
332
					default:
333
						$this->_error(6);
334
						break;
335
				}
336
			}
337

    
338
			unlock($dyndnslck);
339
		}
340

    
341
		/*
342
		 * Private Function (added 12 July 05) [beta]
343
		 *   Send Update To Selected Service.
344
		 */
345
		function _update() {
346

    
347
			if ($this->_dnsVerboseLog) {
348
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _update() starting.'), $this->_dnsService, $this->_FQDN));
349
			}
350

    
351
			if (strstr($this->_dnsRequestIf, "_vip")) {
352
				$parentif = get_configured_vip_interface($this->_dnsRequestIf);
353
				$realparentif = convert_friendly_interface_to_real_interface_name($parentif);
354
			} else {
355
				$realparentif = $this->_dnsRequestIf;
356
			}
357

    
358
			$ch = curl_init();
359

    
360
			if ($this->_useIPv6 == false) {
361
				curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
362
			}
363

    
364
			if ($this->_dnsService != 'ods') {
365
				curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
366
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
367
				curl_setopt($ch, CURLOPT_INTERFACE, 'if!' . $realparentif);
368
				curl_setopt($ch, CURLOPT_TIMEOUT, 120); // Completely empirical
369
			}
370

    
371
			switch ($this->_dnsService) {
372
				case 'glesys':
373
					$needsIP = TRUE;
374
					$server = 'https://api.glesys.com/domain/updaterecord/format/json';
375
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
376
					$post_data['recordid'] = $this->_FQDN;
377
					$post_data['data'] = $this->_dnsIP;
378
					curl_setopt($ch, CURLOPT_URL, $server);
379
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
380
					break;
381
				case 'dyndns':
382
				case 'dyndns-static':
383
				case 'dyndns-custom':
384
					$needsIP = FALSE;
385
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") {
386
						$this->_dnsWildcard = "ON";
387
					}
388
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
389
					$server = "https://members.dyndns.org/nic/update";
390
					$port = "";
391
					if ($this->_dnsServer) {
392
						$server = $this->_dnsServer;
393
					}
394
					if ($this->_dnsPort) {
395
						$port = ":" . $this->_dnsPort;
396
					}
397
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?system=dyndns&hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard='.$this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NO');
398
					break;
399
				case 'dhs':
400
					// DHS is disabled in the GUI because the following doesn't work.
401
					$needsIP = TRUE;
402
					$post_data['hostscmd'] = 'edit';
403
					$post_data['hostscmdstage'] = '2';
404
					$post_data['type'] = '4';
405
					$post_data['updatetype'] = 'Online';
406
					$post_data['mx'] = $this->_dnsMX;
407
					$post_data['mx2'] = '';
408
					$post_data['txt'] = '';
409
					$post_data['offline_url'] = '';
410
					$post_data['cloak'] = 'Y';
411
					$post_data['cloak_title'] = '';
412
					$post_data['ip'] = $this->_dnsIP;
413
					$post_data['domain'] = 'dyn.dhs.org';
414
					$post_data['hostname'] = $this->_dnsHost;
415
					$post_data['submit'] = 'Update';
416
					$server = "https://members.dhs.org/nic/hosts";
417
					$port = "";
418
					if ($this->_dnsServer) {
419
						$server = $this->_dnsServer;
420
					}
421
					if ($this->_dnsPort) {
422
						$port = ":" . $this->_dnsPort;
423
					}
424
					curl_setopt($ch, CURLOPT_URL, $server . $port);
425
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
426
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
427
					break;
428
				case 'noip':
429
				case 'noip-free':
430
					$needsIP = TRUE;
431
					$server = "https://dynupdate.no-ip.com/ducupdate.php";
432
					$port = "";
433
					if ($this->_dnsServer) {
434
						$server = $this->_dnsServer;
435
					}
436
					if ($this->_dnsPort) {
437
						$port = ":" . $this->_dnsPort;
438
					}
439
					if (($this->_dnsService == "noip-free") &&
440
					    ($this->_forceUpdateNeeded == true) &&
441
					    ($this->_dnsDummyUpdateDone == false)) {
442
						// Update the IP to a dummy value to force No-IP free accounts to see a change.
443
						$iptoset = "192.168.1.1";
444
						$this->_dnsDummyUpdateDone = true;
445
						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));
446
					} else {
447
						$iptoset = $this->_dnsIP;
448
					}
449
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?username=' . urlencode($this->_dnsUser) . '&pass=' . urlencode($this->_dnsPass) . '&h[]=' . $this->_dnsHost.'&ip=' . $iptoset);
450
					break;
451
				case 'easydns':
452
					$needsIP = TRUE;
453
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
454
					$server = "https://members.easydns.com/dyn/dyndns.php";
455
					$port = "";
456
					if ($this->_dnsServer) {
457
						$server = $this->_dnsServer;
458
					}
459
					if ($this->_dnsPort) {
460
						$port = ":" . $this->_dnsPort;
461
					}
462
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard=' . $this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=' . $this->_dnsBackMX);
463
					break;
464
				case 'hn':
465
					$needsIP = TRUE;
466
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
467
					$server = "http://dup.hn.org/vanity/update";
468
					$port = "";
469
					if ($this->_dnsServer) {
470
						$server = $this->_dnsServer;
471
					}
472
					if ($this->_dnsPort) {
473
						$port = ":" . $this->_dnsPort;
474
					}
475
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?ver=1&IP=' . $this->_dnsIP);
476
					break;
477
				case 'zoneedit':
478
					$needsIP = FALSE;
479
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
480

    
481
					$server = "https://dynamic.zoneedit.com/auth/dynamic.html";
482
					$port = "";
483
					if ($this->_dnsServer) {
484
						$server = $this->_dnsServer;
485
					}
486
					if ($this->_dnsPort) {
487
						$port = ":" . $this->_dnsPort;
488
					}
489
					curl_setopt($ch, CURLOPT_URL, "{$server}{$port}?host=" . $this->_dnsHost . '&dnsto=' . $this->_dnsIP);
490
					break;
491
				case 'dyns':
492
					$needsIP = FALSE;
493
					$server = "http://www.dyns.net/postscript011.php";
494
					$port = "";
495
					if ($this->_dnsServer) {
496
						$server = $this->_dnsServer;
497
					}
498
					if ($this->_dnsPort) {
499
						$port = ":" . $this->_dnsPort;
500
					}
501
					curl_setopt($ch, CURLOPT_URL, $server . $port . '?username=' . urlencode($this->_dnsUser) . '&password=' . $this->_dnsPass . '&host=' . $this->_dnsHost);
502
					break;
503
				case 'ods':
504
					$needsIP = FALSE;
505
					$misc_errno = 0;
506
					$misc_error = "";
507
					$server = "ods.org";
508
					$port = "";
509
					if ($this->_dnsServer) {
510
						$server = $this->_dnsServer;
511
					}
512
					if ($this->_dnsPort) {
513
						$port = ":" . $this->_dnsPort;
514
					}
515
					$this->con['socket'] = fsockopen("{$server}{$port}", "7070", $misc_errno, $misc_error, 30);
516
					/* Check that we have connected */
517
					if (!$this->con['socket']) {
518
						print "error! could not connect.";
519
						break;
520
					}
521
					/* Here is the loop. Read the incoming data (from the socket connection) */
522
					while (!feof($this->con['socket'])) {
523
						$this->con['buffer']['all'] = trim(fgets($this->con['socket'], 4096));
524
						$code = substr($this->con['buffer']['all'], 0, 3);
525
						sleep(1);
526
						switch ($code) {
527
							case 100:
528
								fputs($this->con['socket'], "LOGIN ".$this->_dnsUser." ".$this->_dnsPass."\n");
529
								break;
530
							case 225:
531
								fputs($this->con['socket'], "DELRR ".$this->_dnsHost." A\n");
532
								break;
533
							case 901:
534
								fputs($this->con['socket'], "ADDRR ".$this->_dnsHost." A ".$this->_dnsIP."\n");
535
								break;
536
							case 795:
537
								fputs($this->con['socket'], "QUIT\n");
538
								break;
539
						}
540
					}
541
					$this->_checkStatus(0, $code);
542
					break;
543
				case 'freedns':
544
				case 'freedns-v6':
545
					$needIP = FALSE;
546
					curl_setopt($ch, CURLOPT_URL, 'https://freedns.afraid.org/dynamic/update.php?' . $this->_dnsPass);
547
					break;
548
				case 'dnsexit':
549
					$needsIP = TRUE;
550
					curl_setopt($ch, CURLOPT_URL, 'https://www.dnsexit.com/RemoteUpdate.sv?login='.$this->_dnsUser. '&password='.$this->_dnsPass.'&host='.$this->_dnsHost.'&myip='.$this->_dnsIP);
551
					break;
552
				case 'loopia':
553
					$needsIP = TRUE;
554
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
555
					curl_setopt($ch, CURLOPT_URL, 'https://dns.loopia.se/XDynDNSServer/XDynDNS.php?hostname='.$this->_dnsHost.'&myip='.$this->_dnsIP);
556
					break;
557
				case 'opendns':
558
					$needsIP = FALSE;
559
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") $this->_dnsWildcard = "ON";
560
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
561
					$server = "https://updates.opendns.com/nic/update?hostname=". $this->_dnsHost;
562
					$port = "";
563
					if ($this->_dnsServer) {
564
						$server = $this->_dnsServer;
565
					}
566
					if ($this->_dnsPort) {
567
						$port = ":" . $this->_dnsPort;
568
					}
569
					curl_setopt($ch, CURLOPT_URL, $server .$port);
570
					break;
571

    
572
				case 'staticcling':
573
					$needsIP = FALSE;
574
					curl_setopt($ch, CURLOPT_URL, 'https://www.staticcling.org/update.html?login='.$this->_dnsUser.'&pass='.$this->_dnsPass);
575
					break;
576
				case 'dnsomatic':
577
					/* Example syntax
578
						https://username:password@updates.dnsomatic.com/nic/update?hostname=yourhostname&myip=ipaddress&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG
579
					*/
580
					$needsIP = FALSE;
581
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") {
582
						$this->_dnsWildcard = "ON";
583
					}
584
					/*
585
					Reference: https://www.dnsomatic.com/wiki/api
586
						DNS-O-Matic usernames are 3-25 characters.
587
						DNS-O-Matic passwords are 6-20 characters.
588
						All ASCII letters and numbers accepted.
589
						Dots, dashes, and underscores allowed, but not at the beginning or end of the string.
590
					Required: "rawurlencode" http://www.php.net/manual/en/function.rawurlencode.php
591
						Encodes the given string according to RFC 3986.
592
					*/
593
					$server = "https://" . rawurlencode($this->_dnsUser) . ":" . rawurlencode($this->_dnsPass) . "@updates.dnsomatic.com/nic/update?hostname=";
594
					if ($this->_dnsServer) {
595
						$server = $this->_dnsServer;
596
					}
597
					if ($this->_dnsPort) {
598
						$port = ":" . $this->_dnsPort;
599
					}
600
					curl_setopt($ch, CURLOPT_URL, $server . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard='.$this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NOCHG');
601
					break;
602
				case 'namecheap':
603
					/* Example:
604
						https://dynamicdns.park-your-domain.com/update?host=[host_name]&domain=[domain.com]&password=[domain_password]&ip=[your_ip]
605
					*/
606
					$needsIP = FALSE;
607
					$dnspass = trim($this->_dnsPass);
608
					$server = "https://dynamicdns.park-your-domain.com/update?host={$this->_dnsHost}&domain={$this->_dnsDomain}&password={$dnspass}&ip={$this->_dnsIP}";
609
					curl_setopt($ch, CURLOPT_URL, $server);
610
					break;
611
				case 'duiadns':
612
				case 'duiadns-v6':
613
					$needsIP = FALSE;
614
					$server = "https://ipv4.duiadns.net/dyndns.duia?";
615
					curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
616
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
617
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
618
					curl_setopt($ch, CURLOPT_URL, $server . 'hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
619
					break;
620
				case 'he-net':
621
				case 'he-net-v6':
622
					$needsIP = FALSE;
623
					$server = "https://dyn.dns.he.net/nic/update?";
624
					curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
625
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
626
					curl_setopt($ch, CURLOPT_URL, $server . 'hostname=' . $this->_dnsHost . '&password=' . $this->_dnsPass . '&myip=' . $this->_dnsIP);
627
					break;
628
				case 'he-net-tunnelbroker':
629
					$needsIP = FALSE;
630
					$server = "https://ipv4.tunnelbroker.net/ipv4_end.php?";
631
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser . ':' . $this->_dnsPass);
632
					curl_setopt($ch, CURLOPT_URL, $server . 'tid=' . $this->_dnsHost);
633
					break;
634
				case 'selfhost':
635
					$needsIP = FALSE;
636
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") {
637
						$this->_dnsWildcard = "ON";
638
					}
639
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
640
					$server = "https://carol.selfhost.de/nic/update";
641
					$port = "";
642
					if ($this->_dnsServer) {
643
						$server = $this->_dnsServer;
644
					}
645
					if ($this->_dnsPort) {
646
						$port = ":" . $this->_dnsPort;
647
					}
648
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?system=dyndns&hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard='.$this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NO');
649
					break;
650
				case 'route53':		
651
					require_once("r53.class");
652
					$r53 = new Route53($this->_dnsUser, $this->_dnsPass);
653
					$apiurl = $r53->getApiUrl($this->_dnsZoneID);
654
					$xmlreq = $r53->getRequestBody($this->_dnsHost, $this->_dnsIP, $this->_dnsTTL);
655
					$httphead = $r53->getHttpPostHeaders(strlen($xmlreq));
656
					curl_setopt($ch, CURLOPT_HTTPHEADER, $httphead);
657
					if($this->_dnsVerboseLog){
658
						log_error(sprintf("Sending reuquest to: %s", $apiurl));
659
						foreach($httphead as $hv){
660
							log_error(sprintf("Header: %s", $hv));
661
						}
662
						log_error(sprintf("XMLPOST: %s", $xmlreq));
663
					}
664
					curl_setopt($ch, CURLOPT_URL, $apiurl);
665
					curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlreq);
666
					break;
667
				case 'custom':
668
				case 'custom-v6':
669
					if (strstr($this->dnsUpdateURL, "%IP%")) {$needsIP = TRUE;} else {$needsIP = FALSE;}
670
					if ($this->_dnsUser != '') {
671
						if ($this->_curlIpresolveV4) {
672
							curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
673
						}
674
						if ($this->_curlSslVerifypeer) {
675
							curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
676
						} else {
677
							curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
678
						}
679
						curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
680
						curl_setopt($ch, CURLOPT_USERPWD, "{$this->_dnsUser}:{$this->_dnsPass}");
681
					}
682
					$server = str_replace("%IP%", $this->_dnsIP, $this->_dnsUpdateURL);
683
					if ($this->_dnsVerboseLog) {
684
						log_error(sprintf(gettext("Sending request to: %s"), $server));
685
					}
686
					curl_setopt($ch, CURLOPT_URL, $server);
687
					break;
688
				case 'cloudflare-v6':
689
				case 'cloudflare':
690
					$isv6 = ($this->_dnsService === 'cloudflare-v6');
691
					$recordType = $isv6 ? "AAAA" : "A";
692
					$needsIP = TRUE;
693
					$dnsServer ='api.cloudflare.com';
694
					$dnsHost = str_replace(' ', '', $this->_dnsHost);
695

    
696
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
697
					curl_setopt($ch, CURLOPT_HTTPHEADER, array(
698
						'X-Auth-Email: '.$this->_dnsUser.'',
699
						'X-Auth-Key: '.$this->_dnsPass.'',
700
						'Content-Type: application/json'
701
					));
702

    
703
					// Get zone ID
704
					$getZoneId = "https://{$dnsServer}/client/v4/zones/?name={$this->_dnsDomain}";
705
					curl_setopt($ch, CURLOPT_URL, $getZoneId);
706
					$output = json_decode(curl_exec($ch));
707
					$zone = $output->result[0]->id;
708
					if ($zone) { // If zone ID was found get host ID
709
						$getHostId = "https://{$dnsServer}/client/v4/zones/{$zone}/dns_records?name={$this->_FQDN}&type={$recordType}";
710
						curl_setopt($ch, CURLOPT_URL, $getHostId);
711
						$output = json_decode(curl_exec($ch));
712
						$host = $output->result[0]->id;
713
						if ($host) { // If host ID was found update host
714
							$hostData = array(
715
								"content" => "{$this->_dnsIP}",
716
								"type" => "{$recordType}",
717
								"proxied" => $this->_dnsProxied,
718
								"name" => "{$this->_dnsHost}"
719
							);
720
							$data_json = json_encode($hostData);
721
							$updateHostId = "https://{$dnsServer}/client/v4/zones/{$zone}/dns_records/{$host}";
722
							curl_setopt($ch, CURLOPT_URL, $updateHostId);
723
							curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
724
							curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
725
						}
726
					}
727
					break;
728
				case 'eurodns':
729
					$needsIP = TRUE;
730
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
731
					$server = "https://update.eurodyndns.org/update/";
732
					$port = "";
733
					if ($this->_dnsPort) {
734
						$port = ":" . $this->_dnsPort;
735
					}
736
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
737
					break;
738
				case 'gratisdns':
739
					$needsIP = TRUE;
740
					$server = "https://ssl.gratisdns.dk/ddns.phtml";
741
					curl_setopt($ch, CURLOPT_URL, $server . '?u=' . $this->_dnsUser . '&p=' . $this->_dnsPass . '&h=' . $this->_dnsHost . '&d=' . $this->_dnsDomain . '&i=' . $this->_dnsIP);
742
					break;
743
				case 'ovh-dynhost':
744
					$needsIP = FALSE;
745
					if (isset($this->_dnsWildcard) && $this->_dnsWildcard != "OFF") $this->_dnsWildcard = "ON";
746
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
747
					$server = "https://www.ovh.com/nic/update";
748
					$port = "";
749
					if ($this->_dnsServer) {
750
						$server = $this->_dnsServer;
751
					}
752
					if ($this->_dnsPort) {
753
						$port = ":" . $this->_dnsPort;
754
					}
755
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?system=dyndns&hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP . '&wildcard='.$this->_dnsWildcard . '&mx=' . $this->_dnsMX . '&backmx=NO');
756
					break;
757
				case 'citynetwork':
758
					$needsIP = TRUE;
759
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
760
					$server = 'https://dyndns.citynetwork.se/nic/update';
761
					$port = "";
762
					if ($this->_dnsServer) {
763
						$server = $this->_dnsServer;
764
					}
765
					if ($this->_dnsPort) {
766
						$port = ":" . $this->_dnsPort;
767
					}
768
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
769
					break;
770
				case 'dnsimple':
771
					/* Uses DNSimple's REST API
772
					   Requires username and Account API token passed in header
773
					   Piggybacks on Route 53's ZoneID field for DNSimple record ID
774
					   Data sent as JSON */
775
					$needsIP = TRUE;
776
					$server = 'https://api.dnsimple.com/v1/domains/';
777
					$token = $this->_dnsUser . ':' . $this->_dnsPass;
778
					$jsondata = '{"record":{"content":"' . $this->_dnsIP . '","ttl":"' . $this->_dnsTTL . '"}}';
779
					curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
780
					curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-Type: application/json', 'X-DNSimple-Token: ' . $token));
781
					curl_setopt($ch, CURLOPT_URL, $server . $this->_dnsHost . '/records/' . $this->_dnsZoneID);
782
					curl_setopt($ch, CURLOPT_POSTFIELDS, $jsondata);
783
					break;
784
				case 'googledomains':
785
					$needsIP = FALSE;
786
					$post_data['username:password'] = $this->_dnsUser . ':' . $this->_dnsPass;
787
					$post_data['hostname'] = $this->_dnsHost;
788
					$post_data['myip'] = $this->_dnsIP;
789
					$post_data['offline'] = 'no';
790
					$server = "https://domains.google.com/nic/update";
791
					$port = "";
792
					curl_setopt($ch, CURLOPT_URL, 'https://domains.google.com/nic/update');
793
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
794
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
795
					break;
796
				case 'dnsmadeeasy':
797
					$needsIP = TRUE;
798
					$server = "https://cp.dnsmadeeasy.com/servlet/updateip";
799
					curl_setopt($ch, CURLOPT_URL, $server . '?username=' . $this->_dnsUser . '&password=' . $this->_dnsPass . '&id=' . $this->_dnsHost . '&ip=' . $this->_dnsIP);
800
					break;
801
				case 'spdyn':
802
				case 'spdyn-v6':
803
					$needsIP = FALSE;
804
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
805
					$server = "https://update.spdyn.de/nic/update";
806
					$port = "";
807
					if ($this->_dnsServer) {
808
						$server = $this->_dnsServer;
809
					}
810
					if ($this->_dnsPort) {
811
						$port = ":" . $this->_dnsPort;
812
					}
813
					curl_setopt($ch, CURLOPT_URL, $server .$port . '?hostname=' . $this->_dnsHost . '&myip=' . $this->_dnsIP);
814
					break;
815
				case 'all-inkl':
816
					$needsIP = FALSE;
817
					$server = 'https://dyndns.kasserver.com/';
818
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
819
					curl_setopt($ch, CURLOPT_URL, $server . 'myip=' . $this->_dnsIP);
820
					break;
821
				default:
822
					break;
823
			}
824
			if ($this->_dnsService != 'ods') {
825
				curl_setopt($ch, CURLOPT_HEADER, 1);
826
				$response = curl_exec($ch);
827
				$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
828
				$header = substr($response, 0, $header_size);
829
				$data = substr($response, $header_size);
830
				$this->_checkStatus($ch, $data, $header);
831
				@curl_close($ch);
832
			}
833
		}
834

    
835
		/*
836
		 * Private Function (added 12 July 2005) [beta]
837
		 *   Retrieve Update Status
838
		 */
839
		function _checkStatus($ch, $data, $header) {
840
			if ($this->_dnsVerboseLog) {
841
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkStatus() starting.'), $this->_dnsService, $this->_FQDN));
842
			}
843
			$successful_update = false;
844
			$success_str = "(" . gettext("Success") . ") ";
845
			$error_str = "(" . gettext("Error") . ") ";
846
			$status_intro = "phpDynDNS ({$this->_dnsHost}): ";
847

    
848
			if ($this->_dnsService != 'ods' && @curl_error($ch)) {
849
				$status = gettext("Curl error occurred:") . " " . curl_error($ch);
850
				log_error($status);
851
				$this->status = $status;
852
				return;
853
			}
854
			switch ($this->_dnsService) {
855
				case 'glesys':
856
					$status_intro = "GleSYS ({$this->_dnsHost}): ";
857
					if (preg_match('/Record updated/i', $data)) {
858
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
859
						$successful_update = true;
860
					} else {
861
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
862
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
863
						$this->_debug($data);
864
					}
865
					break;
866
				case 'dnsomatic':
867
					$status_intro = "DNS-O-Matic ({$this->_dnsHost}): ";
868
					if (preg_match('/badauth/i', $data)) {
869
						$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.");
870
					} else if (preg_match('/notfqdn /i', $data)) {
871
						$status = $status_intro . gettext("The hostname specified is not a fully-qualified domain name. If no hostnames included, notfqdn will be returned once.");
872
					} else if (preg_match('/nohost/i', $data)) {
873
						$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.");
874
					} else if (preg_match('/numhost/i', $data)) {
875
						$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.");
876
					} else if (preg_match('/abuse/i', $data)) {
877
						$status = $status_intro . gettext("The hostname is blocked for update abuse.");
878
					} else if (preg_match('/good/i', $data)) {
879
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
880
						$successful_update = true;
881
					} else if (preg_match('/dnserr/i', $data)) {
882
						$status = $status_intro . gettext("DNS error encountered. Stop updating for 30 minutes.");
883
					} else {
884
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
885
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
886
						$this->_debug($data);
887
					}
888
					break;
889
				case 'citynetwork':
890
					if (preg_match('/notfqdn/i', $data)) {
891
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
892
					} else if (preg_match('/nohost/i', $data)) {
893
						$status = $status_intro . $error_str . gettext("No such host");
894
					} else if (preg_match('/nochg/i', $data)) {
895
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
896
						$successful_update = true;
897
					} else if (preg_match('/good/i', $data)) {
898
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
899
						$successful_update = true;
900
					} else if (preg_match('/badauth/i', $data)) {
901
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
902
					} else {
903
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
904
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
905
						$this->_debug($data);
906
					}
907
					break;
908
				case 'ovh-dynhost':
909
				case 'dyndns':
910
					if (preg_match('/notfqdn/i', $data)) {
911
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
912
					} else if (preg_match('/nochg/i', $data)) {
913
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
914
						$successful_update = true;
915
					} else if (preg_match('/good/i', $data)) {
916
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
917
						$successful_update = true;
918
					} else if (preg_match('/noauth/i', $data)) {
919
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
920
					} else {
921
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
922
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
923
						$this->_debug($data);
924
					}
925
					break;
926
				case 'dyndns-static':
927
					if (preg_match('/notfqdn/i', $data)) {
928
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
929
					} else if (preg_match('/nochg/i', $data)) {
930
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
931
						$successful_update = true;
932
					} else if (preg_match('/good/i', $data)) {
933
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
934
						$successful_update = true;
935
					} else if (preg_match('/noauth/i', $data)) {
936
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
937
					} else {
938
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
939
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
940
						$this->_debug($data);
941
					}
942
					break;
943
				case 'dyndns-custom':
944
					if (preg_match('/notfqdn/i', $data)) {
945
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
946
					} else if (preg_match('/nochg/i', $data)) {
947
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
948
						$successful_update = true;
949
					} else if (preg_match('/good/i', $data)) {
950
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
951
						$successful_update = true;
952
					} else if (preg_match('/noauth/i', $data)) {
953
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
954
					} else {
955
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
956
						log_error($status_intro . gettext("PAYLOAD:") . " {$data}");
957
						$this->_debug($data);
958
					}
959
					break;
960
				case 'dhs':
961
					break;
962
				case 'noip':
963
				case 'noip-free':
964
					list($ip, $code) = explode(":", $data);
965
					switch ($code) {
966
						case 0:
967
							$status = $status_intro . $success_str . gettext("IP address is current, no update performed.");
968
							$successful_update = true;
969
							break;
970
						case 1:
971
							$status = $status_intro . $success_str . gettext("DNS hostname update successful.");
972
							$successful_update = true;
973
							break;
974
						case 2:
975
							$status = $status_intro . $error_str . gettext("Hostname supplied does not exist.");
976
							break;
977
						case 3:
978
							$status = $status_intro . $error_str . gettext("Invalid Username.");
979
							break;
980
						case 4:
981
							$status = $status_intro . $error_str . gettext("Invalid Password.");
982
							break;
983
						case 5:
984
							$status = $status_intro . $error_str . gettext("Too many updates sent.");
985
							break;
986
						case 6:
987
							$status = $status_intro . $error_str . gettext("Account disabled due to violation of No-IP terms of service.");
988
							break;
989
						case 7:
990
							$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.");
991
							break;
992
						case 8:
993
							$status = $status_intro . $error_str . gettext("Disabled / Locked Hostname.");
994
							break;
995
						case 9:
996
							$status = $status_intro . $error_str . gettext("Host updated is configured as a web redirect and no update was performed.");
997
							break;
998
						case 10:
999
							$status = $status_intro . $error_str . gettext("Group supplied does not exist.");
1000
							break;
1001
						case 11:
1002
							$status = $status_intro . $success_str . gettext("DNS group update is successful.");
1003
							$successful_update = true;
1004
							break;
1005
						case 12:
1006
							$status = $status_intro . $success_str . gettext("DNS group is current, no update performed.");
1007
							$successful_update = true;
1008
							break;
1009
						case 13:
1010
							$status = $status_intro . $error_str . gettext("Update client support not available for supplied hostname or group.");
1011
							break;
1012
						case 14:
1013
							$status = $status_intro . $error_str . gettext("Hostname supplied does not have offline settings configured.");
1014
							break;
1015
						case 99:
1016
							$status = $status_intro . $error_str . gettext("Client disabled. Client should exit and not perform any more updates without user intervention.");
1017
							break;
1018
						case 100:
1019
							$status = $status_intro . $error_str . gettext("Client disabled. Client should exit and not perform any more updates without user intervention.");
1020
							break;
1021
						default:
1022
							$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1023
							$this->_debug(gettext("Unknown Response:") . " " . $data);
1024
							break;
1025
					}
1026
					break;
1027
				case 'easydns':
1028
					if (preg_match('/NOACCESS/i', $data)) {
1029
						$status = $status_intro . $error_str . gettext("Authentication Failed: Username and/or Password was Incorrect.");
1030
					} else if (preg_match('/NOSERVICE/i', $data)) {
1031
						$status = $status_intro . $error_str . gettext("No Service: Dynamic DNS Service has been disabled for this domain.");
1032
					} else if (preg_match('/ILLEGAL INPUT/i', $data)) {
1033
						$status = $status_intro . $error_str . gettext("Illegal Input: Self-Explanatory");
1034
					} else if (preg_match('/TOOSOON/i', $data)) {
1035
						$status = $status_intro . $error_str . gettext("Too Soon: Not Enough Time Has Elapsed Since Last Update");
1036
					} else if (preg_match('/NOERROR/i', $data)) {
1037
						$status = $status_intro . $success_str . gettext("IP Updated Successfully!");
1038
						$successful_update = true;
1039
					} else {
1040
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1041
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1042
						$this->_debug($data);
1043
					}
1044
					break;
1045
				case 'hn':
1046
					/* FIXME: add checks */
1047
					break;
1048
				case 'zoneedit':
1049
					if (preg_match('/799/i', $data)) {
1050
						$status = $status_intro . "(" . gettext("Error 799") . ") " . gettext("Update Failed!");
1051
					} else if (preg_match('/700/i', $data)) {
1052
						$status = $status_intro . "(" . gettext("Error 700") . ") " . gettext("Update Failed!");
1053
					} else if (preg_match('/200/i', $data)) {
1054
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1055
						$successful_update = true;
1056
					} else if (preg_match('/201/i', $data)) {
1057
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1058
						$successful_update = true;
1059
					} else {
1060
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1061
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1062
						$this->_debug($data);
1063
					}
1064
					break;
1065
				case 'dyns':
1066
					if (preg_match("/400/i", $data)) {
1067
						$status = $status_intro . $error_str . gettext("Bad Request - The URL was malformed. Required parameters were not provided.");
1068
					} else if (preg_match('/402/i', $data)) {
1069
						$status = $status_intro . $error_str . gettext("Update Too Soon - Attempted to update too quickly since last change.");
1070
					} else if (preg_match('/403/i', $data)) {
1071
						$status = $status_intro . $error_str . gettext("Database Error - There was a server-sided database error.");
1072
					} else if (preg_match('/405/i', $data)) {
1073
						$status = $status_intro . $error_str . sprintf(gettext("Hostname Error - The hostname (%s) doesn't belong to user (%s)."), $this->_dnsHost, $this->_dnsUser);
1074
					} else if (preg_match('/200/i', $data)) {
1075
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1076
						$successful_update = true;
1077
					} else {
1078
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1079
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1080
						$this->_debug($data);
1081
					}
1082
					break;
1083
				case 'ods':
1084
					if (preg_match("/299/i", $data)) {
1085
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1086
						$successful_update = true;
1087
					} else {
1088
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1089
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1090
						$this->_debug($data);
1091
					}
1092
					break;
1093
				case 'freedns':
1094
				case 'freedns-v6':
1095
					if (preg_match("/has not changed./i", $data)) {
1096
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1097
						$successful_update = true;
1098
					} else if (preg_match("/Updated/i", $data)) {
1099
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
1100
						$successful_update = true;
1101
					} else {
1102
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1103
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1104
						$this->_debug($data);
1105
					}
1106
					break;
1107
				case 'dnsexit':
1108
					if (preg_match("/is the same/i", $data)) {
1109
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1110
						$successful_update = true;
1111
					} else if (preg_match("/Success/i", $data)) {
1112
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
1113
						$successful_update = true;
1114
					} else {
1115
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1116
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1117
						$this->_debug($data);
1118
					}
1119
					break;
1120
				case 'loopia':
1121
					if (preg_match("/nochg/i", $data)) {
1122
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1123
						$successful_update = true;
1124
					} else if (preg_match("/good/i", $data)) {
1125
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
1126
						$successful_update = true;
1127
					} else if (preg_match('/badauth/i', $data)) {
1128
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1129
					} else {
1130
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1131
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1132
						$this->_debug($data);
1133
					}
1134
					break;
1135
				case 'opendns':
1136
					if (preg_match('/badauth/i', $data)) {
1137
						$status = $status_intro . $error_str . gettext("Not a valid username or password!");
1138
					} else if (preg_match('/nohost/i', $data)) {
1139
						$status = $status_intro . $error_str . gettext("Hostname specified does not exist.");
1140
						$successful_update = true;
1141
					} else if (preg_match('/good/i', $data)) {
1142
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1143
						$successful_update = true;
1144
					} else if (preg_match('/yours/i', $data)) {
1145
						$status = $status_intro . $error_str . gettext("Hostname specified exists, but not under the username specified.");
1146
					} else if (preg_match('/abuse/i', $data)) {
1147
						$status = $status_intro . $error_str . gettext("Updating too frequently, considered abuse.");
1148
					} else {
1149
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1150
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1151
						$this->_debug($data);
1152
					}
1153
					break;
1154
				case 'staticcling':
1155
					if (preg_match("/invalid ip/i", $data)) {
1156
						$status = $status_intro . $error_str . gettext("Bad Request - The IP provided was invalid.");
1157
					} else if (preg_match('/required info missing/i', $data)) {
1158
						$status = $status_intro . $error_str . gettext("Bad Request - Required parameters were not provided.");
1159
					} else if (preg_match('/invalid characters/i', $data)) {
1160
						$status = $status_intro . $error_str . gettext("Bad Request - Illegal characters in either the username or the password.");
1161
					} else if (preg_match('/bad password/i', $data)) {
1162
						$status = $status_intro . $error_str . gettext("Invalid password.");
1163
					} else if (preg_match('/account locked/i', $data)) {
1164
						$status = $status_intro . $error_str . gettext("This account has been administratively locked.");
1165
					} else if (preg_match('/update too frequent/i', $data)) {
1166
						$status = $status_intro . $error_str . gettext("Updating too frequently.");
1167
					} else if (preg_match('/DB error/i', $data)) {
1168
						$status = $status_intro . $error_str . gettext("Server side error.");
1169
					} else if (preg_match('/success/i', $data)) {
1170
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1171
						$successful_update = true;
1172
					} else {
1173
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1174
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1175
						$this->_debug($data);
1176
					}
1177
					break;
1178
				case 'namecheap':
1179
					$tmp = str_replace("^M", "", $data);
1180
					$ncresponse = @xml2array($tmp);
1181
					if (preg_match("/internal server error/i", $data)) {
1182
						$status = $status_intro . $error_str . gettext("Server side error.");
1183
					} else if (preg_match("/request is badly formed/i", $data)) {
1184
						$status = $status_intro . $error_str . gettext("Badly Formed Request (check the settings).");
1185
					} else if ($ncresponse['interface-response']['ErrCount'] === "0") {
1186
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1187
						$successful_update = true;
1188
					} else if (is_numeric($ncresponse['interface-response']['ErrCount']) && ($ncresponse['interface-response']['ErrCount'] > 0)) {
1189
						$status = $status_intro . $error_str . implode(", ", $ncresponse["interface-response"]["errors"]);
1190
						$successful_update = true;
1191
					} else {
1192
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1193
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1194
						$this->_debug($data);
1195
					}
1196
					break;
1197
				case 'duiadns':
1198
				case 'duiadns-v6':
1199
					if (preg_match("/error/i", $data)) {
1200
						$status = $status_intro . $error_str . gettext("Server side error.");
1201
					} else if (preg_match('/nohost/i', $data)) {
1202
						$status = $status_intro . $error_str . gettext("Bad Request - A hostname was not provided.");
1203
					} else if (preg_match('/badauth/i', $data)) {
1204
						$status = $status_intro . $error_str . gettext("Invalid username or password.");
1205
					} else if (preg_match('/good/i', $data)) {
1206
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1207
						$successful_update = true;
1208
					} else if (preg_match('/nochg/i', $data)) {
1209
						$status = $status_intro . $success_str . gettext("No Change In IP Address.");
1210
						$successful_update = true;
1211
					} else {
1212
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1213
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1214
						$this->_debug($data);
1215
					}
1216
					break;
1217
				case 'he-net':
1218
				case 'he-net-v6':
1219
					if (preg_match("/badip/i", $data)) {
1220
						$status = $status_intro . $error_str . gettext("Bad Request - The IP provided was invalid.");
1221
					} else if (preg_match('/nohost/i', $data)) {
1222
						$status = $status_intro . $error_str . gettext("Bad Request - A hostname was not provided.");
1223
					} else if (preg_match('/badauth/i', $data)) {
1224
						$status = $status_intro . $error_str . gettext("Invalid username or password.");
1225
					} else if (preg_match('/good/i', $data)) {
1226
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1227
						$successful_update = true;
1228
					} else if (preg_match('/nochg/i', $data)) {
1229
						$status = $status_intro . $success_str . gettext("No Change In IP Address.");
1230
						$successful_update = true;
1231
					} else {
1232
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1233
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1234
						$this->_debug($data);
1235
					}
1236
					break;
1237
				case 'he-net-tunnelbroker':
1238
					/*
1239
					-ERROR: Missing parameter(s).
1240
					-ERROR: Invalid API key or password
1241
					-ERROR: Tunnel not found
1242
					-ERROR: Another tunnel exists for this IP.
1243
					-ERROR: This tunnel is already associated with this IP address
1244
					+OK: Tunnel endpoint updated to: x.x.x.x
1245
					*/
1246
					if (preg_match("/Missing parameter/i", $data)) {
1247
						$status = $status_intro . $error_str . gettext("Bad Request - Missing/Invalid Parameters.");
1248
					} else if (preg_match('/Tunnel not found/i', $data)) {
1249
						$status = $status_intro . $error_str . gettext("Bad Request - Invalid Tunnel ID.");
1250
					} else if (preg_match('/Invalid API key or password/i', $data)) {
1251
						$status = $status_intro . $error_str . gettext("Invalid username or password.");
1252
					} else if (preg_match('/OK:/i', $data)) {
1253
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1254
						$successful_update = true;
1255
					} else if (preg_match('/This tunnel is already associated with this IP address/i', $data)) {
1256
						$status = $status_intro . $success_str . gettext("No Change In IP Address.");
1257
						$successful_update = true;
1258
					} else {
1259
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1260
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1261
						$this->_debug($data);
1262
					}
1263
					break;
1264
				case 'selfhost':
1265
					if (preg_match('/notfqdn/i', $data)) {
1266
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
1267
					} else if (preg_match('/nochg/i', $data)) {
1268
						$status = $status_intro . $success_str . gettext("No Change In IP Address.");
1269
						$successful_update = true;
1270
					} else if (preg_match('/good/i', $data)) {
1271
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1272
						$successful_update = true;
1273
					} else if (preg_match('/noauth/i', $data)) {
1274
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1275
					} else {
1276
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1277
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1278
						$this->_debug($data);
1279
					}
1280
					break;
1281
				case 'route53':
1282
					if(preg_match('/ErrorResponse/', $data)){
1283
						$status = $status_intro . $error_str . gettext("Route53 API call failed");
1284
						log_error(sprintf("error message: %s", $data));
1285
						$status_update = false;
1286
					} else {
1287
						$status = $status_intro . $success_str . gettext("IP address changed successfully");
1288
						$successful_update = true;
1289
					}
1290
					break;
1291
				case 'custom':
1292
				case 'custom-v6':
1293
					$successful_update = false;
1294
					if ($this->_dnsResultMatch == "") {
1295
						$successful_update = true;
1296
					} else {
1297
						$this->_dnsResultMatch = str_replace("%IP%", $this->_dnsIP, $this->_dnsResultMatch);
1298
						$matches = preg_split("/(?<!\\\\)\\|/", $this->_dnsResultMatch);
1299
						foreach ($matches as $match) {
1300
							$match= str_replace("\\|", "|", $match);
1301
							if (strcmp($match, trim($data, "\t\n\r")) == 0) {
1302
								$successful_update = true;
1303
							}
1304
						}
1305
						unset ($matches);
1306
					}
1307
					if ($successful_update == true) {
1308
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1309
					} else {
1310
						$status = $status_intro . $error_str . gettext("Result did not match.") . " [" . $data . "]";
1311
					}
1312
					break;
1313
				case 'cloudflare-v6':
1314
				case 'cloudflare':
1315
					$output = json_decode($data);
1316
					if ($output->result->content === $this->_dnsIP) {
1317
						$status = $status_intro . $success_str . sprintf(gettext('%1$s updated to %2$s'), $this->_dnsHost, $this->_dnsIP);
1318
						$successful_update = true;
1319
					} elseif ($output->errors[0]->code === 9103) {
1320
						$status = $status_intro . $error_str . gettext("Invalid Credentials! Don't forget to use API Key for password field with CloudFlare.");
1321
					} elseif (($output->success) && (!$output->result[0]->id)) {
1322
						$status = $status_intro . $error_str . gettext("Zone or Host ID was not found, check the hostname.");
1323
					} else {
1324
						$status = $status_intro . gettext("UNKNOWN ERROR") . " - " . $output->errors[0]->message;
1325
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1326
					}
1327
					break;
1328
				case 'eurodns':
1329
					if (preg_match('/notfqdn/i', $data)) {
1330
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
1331
					} else if (preg_match('/nochg/i', $data)) {
1332
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1333
						$successful_update = true;
1334
					} else if (preg_match('/good/i', $data)) {
1335
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1336
						$successful_update = true;
1337
					} else if (preg_match('/badauth/i', $data)) {
1338
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1339
					} else {
1340
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1341
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1342
						$this->_debug($data);
1343
					}
1344
					break;
1345
				case 'gratisdns':
1346
					if (preg_match('/Forkerte værdier/i', $data)) {
1347
						$status = $status_intro . $error_str . gettext("Wrong values - Update could not be completed.");
1348
					} else if (preg_match('/Bruger login: Bruger eksistere ikke/i', $data)) {
1349
						$status = $status_intro . $error_str . gettext("Unknown username - User does not exist.");
1350
					} else if (preg_match('/Bruger login: 1Fejl i kodeord/i', $data)) {
1351
						$status = $status_intro . $error_str . gettext("Wrong password - Remember password is case sensitive.");
1352
					} else if (preg_match('/Domæne kan IKKE administreres af bruger/i', $data)) {
1353
						$status = $status_intro . $error_str . gettext("User unable to administer the selected domain.");
1354
					} else if (preg_match('/OK/i', $data)) {
1355
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1356
						$successful_update = true;
1357
					} else {
1358
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1359
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1360
						$this->_debug($data);
1361
					}
1362
					break;
1363
				case 'dnsimple':
1364
					/* Responds with HTTP 200 on success.
1365
					   Responds with HTTP 4xx on error.
1366
					   Returns JSON data as body */
1367
;
1368
					if (preg_match("/\s200\sOK/i", $header)) {
1369
						$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!");
1370
						$successful_update = true;
1371
					} else if (preg_match("/\s4\d\d\s/i", $header)) {
1372
						$arrbody = json_decode($data, true);
1373
						$message = $arrbody['message'] . ".";
1374
						if (isset($arrbody['errors']['content'])) {
1375
							foreach ($arrbody['errors']['content'] as $key => $content) {
1376
								$message .= " " . $content . ".";
1377
							}
1378
						}
1379
						$status = $status_intro . $error_str . $message;
1380
					} else {
1381
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1382
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1383
						$this->_debug($data);
1384
					}
1385
					break;
1386
				case 'googledomains':
1387
					if (preg_match('/notfqdn/i', $data)) {
1388
						$status = $status_intro . $error_str . gettext("Not A FQDN");
1389
					} else if (preg_match('/nochg/i', $data)) {
1390
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1391
						$successful_update = true;
1392
					} else if (preg_match('/good/i', $data)) {
1393
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1394
						$successful_update = true;
1395
					} else if (preg_match('/badauth/i', $data)) {
1396
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1397
					} else if (preg_match('/nohost/i', $data)) {
1398
						$status = $status_intro . $error_str . gettext("Hostname does not exist or DynDNS not enabled");
1399
					} else if (preg_match('/badagent/i', $data)) {
1400
						$status = $status_intro . $error_str . gettext("Bad request");
1401
					} else if (preg_match('/abuse/i', $data)) {
1402
						$status = $status_intro . $error_str . gettext("Dynamic DNS access has been blocked!");
1403
					} else if (preg_match('/911/i', $data)) {
1404
						$status = $status_intro . $error_str . gettext("Error on Google's end, retry in 5 minutes");
1405
					} else {
1406
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1407
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1408
						$this->_debug($data);
1409
					}
1410
					break;
1411
				case 'dnsmadeeasy':
1412
					switch ($data) {
1413
						case 'success':
1414
							$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1415
							$successful_update = true;
1416
							break;
1417
						case 'error-auth':
1418
							$status = $status_intro . $error_str . gettext("Invalid username or password");
1419
							break;
1420
						case 'error-auth-suspend':
1421
							$status = $status_intro . $error_str . gettext("Account suspended");
1422
							break;
1423
						case 'error-auth-voided':
1424
							$status = $status_intro . $error_str . gettext("Account revoked");
1425
							break;
1426
						case 'error-record-invalid':
1427
							$status = $status_intro . $error_str . gettext("Record does not exist in the system. Unable to update record");
1428
							break;
1429
						case 'error-record-auth':
1430
							$status = $status_intro . $error_str . gettext("User does not have access to this record");
1431
							break;
1432
						case 'error-record-ip-same':
1433
							$status = $status_intro . $success_str . gettext("No Change In IP Address");
1434
							$successful_update = true;
1435
							break;
1436
						case 'error-system':
1437
							$status = $status_intro . $error_str . gettext("General system error recognized by the system");
1438
							break;
1439
						case 'error':
1440
							$status = $status_intro . $error_str . gettext("General system error unrecognized by the system");
1441
							break;
1442
						default:
1443
							$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1444
							log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1445
							$this->_debug($data);
1446
							break;
1447
					}
1448
					break;
1449
				case 'spdyn':
1450
				case 'spdyn-v6':
1451
					if (preg_match('/notfqdn/i', $data)) {
1452
						$status = $status_intro . $error_str . gettext("Not A FQDN!");
1453
					} else if (preg_match('/nohost/i', $data)) {
1454
						$status = $status_intro . $error_str . gettext("No such host");
1455
					} else if (preg_match('/nochg/i', $data)) {
1456
						$status = $status_intro . $success_str . gettext("No Change In IP Address");
1457
						$successful_update = true;
1458
					} else if (preg_match('/good/i', $data)) {
1459
						$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1460
						$successful_update = true;
1461
					} else if (preg_match('/badauth/i', $data)) {
1462
						$status = $status_intro . $error_str . gettext("User Authorization Failed");
1463
					} else {
1464
						$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1465
						log_error($status_intro . gettext("PAYLOAD:") . " " . $data);
1466
						$this->_debug($data);
1467
					}
1468
					break;
1469
				case 'all-inkl':
1470
 					if (preg_match('/good\s'.$this->_dnsIP.'/i', $data)) {
1471
							$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!") . " (" . $this->_dnsIP . ")";
1472
 							$successful_update = true;
1473
 					} else if (preg_match('/good/i', $data)) {
1474
						$status = $status_intro . $error_str . gettext("Result did not match.");
1475
					} else if (preg_match("/\s401\sUnauthorized/i", $header)) {
1476
						$status = $status_intro . $error_str . gettext("Invalid username or password");
1477
					} 
1478
					else {
1479
							$status = $status_intro . "(" . gettext("Unknown Response") . ")";
1480
							log_error($status_intro . gettext("PAYLOAD:") . " " . $header.$data);
1481
 							$this->_debug($data);
1482
 							$this->_debug($header);
1483
 					}
1484
 					break;
1485
			}
1486

    
1487
			if ($successful_update == true) {
1488
				/* Write WAN IP to cache file */
1489
				$wan_ip = $this->_checkIP();
1490
				if ($this->_useIPv6 == false && $wan_ip > 0) {
1491
					$currentTime = time();
1492
					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));
1493
					log_error(sprintf(gettext('phpDynDNS: updating cache file %1$s: %2$s'), $this->_cacheFile, $wan_ip));
1494
					@file_put_contents($this->_cacheFile, "{$wan_ip}:{$currentTime}");
1495
				} else {
1496
					@unlink($this->_cacheFile);
1497
				}
1498
				if ($this->_useIPv6 == true && $wan_ip > 0) {
1499
					$currentTime = time();
1500
					notify_all_remote(sprintf(gettext("DynDNS updated IPv6 Address on %s (%s) to %s"), convert_real_interface_to_friendly_descr($this->_if), $this->_if, $wan_ip));
1501
					log_error(sprintf(gettext('phpDynDNS: updating cache file %1$s: %2$s'), $this->_cacheFile_v6, $wan_ip));
1502
					@file_put_contents($this->_cacheFile_v6, "{$wan_ip}|{$currentTime}");
1503
				} else {
1504
					@unlink($this->_cacheFile_v6);
1505
				}
1506
			}
1507
			$this->status = $status;
1508
			log_error($status);
1509
		}
1510

    
1511
		/*
1512
		 * Private Function (added 12 July 05) [beta]
1513
		 *   Return Error, Set Last Error, and Die.
1514
		 */
1515
		function _error($errorNumber = '1') {
1516
			$err_str = 'phpDynDNS: (' . gettext('ERROR!') . ') ';
1517
			$err_str_r53 = 'Route 53: (' . gettext('Error') . ') ';
1518
			switch ($errorNumber) {
1519
				case 0:
1520
					break;
1521
				case 2:
1522
					$error = $err_str . gettext('No Dynamic DNS Service provider was selected.');
1523
					break;
1524
				case 3:
1525
					$error = $err_str . gettext('No Username Provided.');
1526
					break;
1527
				case 4:
1528
					$error = $err_str . gettext('No Password Provided.');
1529
					break;
1530
				case 5:
1531
					$error = $err_str . gettext('No Hostname Provided.');
1532
					break;
1533
				case 6:
1534
					$error = $err_str . gettext('The Dynamic DNS Service provided is not yet supported.');
1535
					break;
1536
				case 7:
1537
					$error = $err_str . gettext('No Update URL Provided.');
1538
					break;
1539
				case 8:
1540
					$status = $err_str_r53 . gettext("Invalid ZoneID");
1541
					break;
1542
				case 9:
1543
					$status = $err_str_r53 . gettext("Invalid TTL");
1544
					break;
1545
				case 10:
1546
					$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);
1547
					break;
1548
				default:
1549
					$error = $err_str . gettext('Unknown Response.');
1550
					/* FIXME: $data isn't in scope here */
1551
					/* $this->_debug($data); */
1552
					break;
1553
			}
1554
			$this->lastError = $error;
1555
			log_error($error);
1556
		}
1557

    
1558
		/*
1559
		 * Private Function (added 12 July 05) [beta]
1560
		 *   - Detect whether or not IP needs to be updated.
1561
		 *      | Written Specifically for pfSense (https://www.pfsense.org) may
1562
		 *      | work with other systems. pfSense base is FreeBSD.
1563
		 */
1564
		function _detectChange() {
1565
			global $debug;
1566

    
1567
			if ($debug) {
1568
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _detectChange() starting.'), $this->_dnsService, $this->_FQDN));
1569
			}
1570

    
1571
			$currentTime = time();
1572

    
1573
			$wan_ip = $this->_checkIP();
1574
			if ($wan_ip == 0) {
1575
				log_error(sprintf(gettext("Dynamic Dns (%s): Current WAN IP could not be determined, skipping update process."), $this->_FQDN));
1576
				return false;
1577
			}
1578
			$log_error = sprintf(gettext('Dynamic Dns (%1$s): Current WAN IP: %2$s'), $this->_FQDN, $wan_ip) . " ";
1579

    
1580
			if ($this->_useIPv6 == true) {
1581
				if (file_exists($this->_cacheFile_v6)) {
1582
					$contents = file_get_contents($this->_cacheFile_v6);
1583
					list($cacheIP, $cacheTime) = explode('|', $contents);
1584
					$this->_debug($cacheIP.'/'.$cacheTime);
1585
					$initial = false;
1586
					$log_error .= sprintf(gettext("Cached IPv6: %s"), $cacheIP);
1587
				} else {
1588
					$cacheIP = '::';
1589
					@file_put_contents($this->_cacheFile, "::|{$currentTime}");
1590
					$cacheTime = $currentTime;
1591
					$initial = true;
1592
					$log_error .= gettext("No Cached IPv6 found.");
1593
				}
1594
			} else {
1595
				if (file_exists($this->_cacheFile)) {
1596
					$contents = file_get_contents($this->_cacheFile);
1597
					list($cacheIP, $cacheTime) = explode(':', $contents);
1598
					$this->_debug($cacheIP.'/'.$cacheTime);
1599
					$initial = false;
1600
					$log_error .= sprintf(gettext("Cached IP: %s"), $cacheIP);
1601
				} else {
1602
					$cacheIP = '0.0.0.0';
1603
					@file_put_contents($this->_cacheFile, "0.0.0.0:{$currentTime}");
1604
					$cacheTime = $currentTime;
1605
					$initial = true;
1606
					$log_error .= gettext("No Cached IP found.");
1607
				}
1608
			}
1609
			if ($this->_dnsVerboseLog) {
1610
				log_error($log_error);
1611
			}
1612

    
1613
			// Convert seconds = days * hr/day * min/hr * sec/min
1614
			$maxCacheAgeSecs = $this->_dnsMaxCacheAgeDays * 24 * 60 * 60;
1615

    
1616
			$needs_updating = FALSE;
1617
			/* lets determine if the item needs updating */
1618
			if ($cacheIP != $wan_ip) {
1619
				$needs_updating = true;
1620
				$update_reason = gettext("Dynamic Dns: cacheIP != wan_ip. Updating.") . " ";
1621
				$update_reason .= sprintf(gettext('Cached IP: %1$s WAN IP: %2$s'), $cacheIP, $wan_ip) . " ";
1622
			}
1623
			if (($currentTime - $cacheTime) > $maxCacheAgeSecs) {
1624
				$needs_updating = true;
1625
				$this->_forceUpdateNeeded = true;
1626
				$update_reason = sprintf(gettext("Dynamic Dns: More than %s days. Updating."), $this->_dnsMaxCacheAgeDays);
1627
				$update_reason .= " {$currentTime} - {$cacheTime} > {$maxCacheAgeSecs} ";
1628
			}
1629
			if ($initial == true) {
1630
				$needs_updating = true;
1631
				$update_reason .= gettext("Initial update.");
1632
			}
1633

    
1634
			/*   finally if we need updating then store the
1635
			 *   new cache value and return true
1636
			 */
1637
			if ($needs_updating == true) {
1638
				if ($this->_dnsVerboseLog) {
1639
					log_error("DynDns ({$this->_FQDN}): {$update_reason}");
1640
				}
1641
				return true;
1642
			}
1643

    
1644
			return false;
1645
		}
1646

    
1647
		/*
1648
		 * Private Function (added 16 July 05) [beta]
1649
		 *   - Writes debug information to a file.
1650
		 *   - This function is only called when a unknown response
1651
		 *   - status is returned from a DynDNS service provider.
1652
		 */
1653
		function _debug($data) {
1654
			global $g;
1655

    
1656
			if (!$g['debug']) {
1657
				return;
1658
			}
1659
			$string = date('m-d-y h:i:s').' - ('.$this->_debugID.') - ['.$this->_dnsService.'] - '.$data."\n";
1660
			$file = fopen($this->_debugFile, 'a');
1661
			fwrite($file, $string);
1662
			fclose($file);
1663
		}
1664
		function _checkIP() {
1665
			global $debug;
1666

    
1667
			if ($debug) {
1668
				log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkIP() starting.'), $this->_dnsService, $this->_FQDN));
1669
			}
1670

    
1671
			if ($this->_useIPv6 == true) {
1672
				$ip_address = get_interface_ipv6($this->_if);
1673
				if (!is_ipaddrv6($ip_address)) {
1674
					return 0;
1675
				}
1676
			} else {
1677
				$ip_address = get_interface_ip($this->_if);
1678
				if (!is_ipaddr($ip_address)) {
1679
					return 0;
1680
				}
1681
			}
1682
			if ($this->_useIPv6 == false && is_private_ip($ip_address)) {
1683
				$hosttocheck = "checkip.dyndns.org";
1684
				$try = 0;
1685
				while ($try < 3) {
1686
					$checkip = gethostbyname($hosttocheck);
1687
					if (is_ipaddr($checkip)) {
1688
						break;
1689
					}
1690
					$try++;
1691
				}
1692
				if ($try >= 3) {
1693
					log_error(sprintf(gettext('Dynamic DNS %1$s debug information (%2$s): Could not resolve %3$s to IP using interface IP %4$s.'), $this->_dnsService, $this->_FQDN, $hosttocheck, $ip_address));
1694
					return 0;
1695
				}
1696
				$ip_ch = curl_init("http://{$checkip}");
1697
				curl_setopt($ip_ch, CURLOPT_RETURNTRANSFER, 1);
1698
				curl_setopt($ip_ch, CURLOPT_SSL_VERIFYPEER, FALSE);
1699
				curl_setopt($ip_ch, CURLOPT_INTERFACE, 'host!' . $ip_address);
1700
				curl_setopt($ip_ch, CURLOPT_CONNECTTIMEOUT, '30');
1701
				curl_setopt($ip_ch, CURLOPT_TIMEOUT, 120);
1702
				if ($this->_useIPv6 == false) {
1703
					curl_setopt($ip_ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
1704
				}
1705
				$ip_result_page = curl_exec($ip_ch);
1706
				curl_close($ip_ch);
1707
				$ip_result_decoded = urldecode($ip_result_page);
1708
				preg_match('/Current IP Address: (.*)<\/body>/', $ip_result_decoded, $matches);
1709
				$ip_address = trim($matches[1]);
1710
				if (is_ipaddr($ip_address)) {
1711
					if ($this->_dnsVerboseLog) {
1712
						log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): %3$s extracted from %4$s'), $this->_dnsService, $this->_FQDN, $ip_address, $hosttocheck));
1713
					}
1714
				} else {
1715
					log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): IP address could not be extracted from %3$s'), $this->_dnsService, $this->_FQDN, $hosttocheck));
1716
					return 0;
1717
				}
1718
			} else {
1719
				if ($this->_dnsVerboseLog) {
1720
					log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): %3$s extracted from local system.'), $this->_dnsService, $this->_FQDN, $ip_address));
1721
				}
1722
			}
1723
			$this->_dnsIP = $ip_address;
1724

    
1725
			return $ip_address;
1726
		}
1727

    
1728
	}
1729

    
1730
?>
(10-10/51)