Project

General

Profile

Download (18.5 KB) Statistics
| Branch: | Tag: | Revision:
1
<?
2
	/*
3
	 * PHP.updateDNS (pfSense version)
4
	 *
5
	 * +====================================================+
6
	 *  Services Supported:
7
	 *    - DynDns (dyndns.org) [dynamic, static, custom)
8
	 *    - DHSDns (dhs.org)
9
	 *    - No-IP (no-ip.com)
10
	 *    - EasyDNS (easydns.com)
11
	 *    - DHS (www.dhs.org)
12
	 *    - HN (hn.org)
13
	 *    - DynS (dyns.org)
14
	 *    - ZoneEdit (zoneedit.com)
15
	 * +----------------------------------------------------+
16
	 *  Requirements:
17
	 *    - PHP version 4.0.2 or higher with CURL Library
18
	 * +----------------------------------------------------+
19
	 *  Public Functions
20
	 *    - updatedns()
21
	 *
22
	 *  Private Functions
23
	 *    - _update()
24
	 *    - _checkStatus()
25
	 *    - _error()
26
	 *    - _detectChange()
27
	 *    - _debug()
28
	 * +----------------------------------------------------+
29
	 *  DynDNS Dynamic - Last Tested: 12 July 2005
30
	 *  DynDNS Static  - Last Tested: NEVER
31
	 *  DynDNS Custom  - Last Tested: NEVER
32
	 *  No-IP          - Last Tested: 12 July 2005
33
	 *  HN.org         - Last Tested: 12 July 2005
34
	 *  EasyDNS        - Last Tested: NEVER
35
	 *  DHS            - Last Tested: 12 July 2005
36
	 *  ZoneEdit       - Last Tested: NEVER
37
	 *  Dyns           - Last Tested: NEVER
38
	 * +====================================================+
39
	 *
40
	 * @author 		E.Kristensen
41
	 * @link    	http://www.idylldesigns.com/projects/phpdns/
42
	 * @version 	0.7
43
	 * @updated		1 August 05 at 21:02:42 GMT
44
	 *
45
	 */
46

    
47
	class updatedns {
48
		var $_cacheFile = '/var/etc/dyndns.cache';
49
		var $_debugFile = '/var/etc/dyndns.debug';
50
		var $_UserAgent = 'User-Agent: phpDynDNS/0.7';
51
		var $_errorVerbosity = 0;
52
		var $_dnsService;
53
		var $_dnsUser;
54
		var $_dnsPass;
55
		var $_dnsHost;
56
		var $_dnsIP;
57
		var $_dnsWildcard;
58
		var $_dnsMX;
59
		var $_dnsBackMX;
60
		var $status;
61
		var $_debugID;
62

    
63
		/* 
64
		 * Public Constructor Function (added 12 July 05) [beta]
65
		 *   - Gets the dice rolling for the update. 
66
		 */
67
		function updatedns ($dnsService = '', $dnsHost = '', $dnsUser = '', $dnsPass = '', $dnsWildcard = 'OFF', $dnsMX = '', $dnsBackMX = '') {
68
			if (!$dnsService) $this->_error(2);
69
			if (!$dnsUser) $this->_error(3);
70
			if (!$dnsPass) $this->_error(4);
71
			if (!$dnsHost) $this->_error(5);
72

    
73
			$this->_dnsService = strtolower($dnsService);
74
			$this->_dnsUser = $dnsUser;
75
			$this->_dnsPass = $dnsPass;
76
			$this->_dnsHost = $dnsHost;
77
			$this->_dnsIP = $dnsIP;
78
			$this->_debugID = rand(1000000, 9999999);
79

    
80
			if ($this->_detectChange() == FALSE) {
81
				$this->_error(10);
82
			} else {
83
				if ($this->_dnsService == 'dyndns' ||
84
					$this->_dnsService == 'dyndns-static' ||
85
					$this->_dnsService == 'dyndns-custom' ||
86
					$this->_dnsService == 'dhs' ||
87
					$this->_dnsService == 'noip' ||
88
					$this->_dnsService == 'easydns' ||
89
					$this->_dnsService == 'hn' ||
90
					$this->_dnsService == 'zoneedit' ||
91
					$this->_dnsService == 'dyns' ||
92
					$this->_dnsService == 'ods')
93
				{
94
					$this->_update();
95
				} else {
96
					$this->_error(6);
97
				}
98
			}
99

    
100
		}
101

    
102

    
103
		/*
104
		 * Private Function (added 12 July 05) [beta]
105
		 *   Send Update To Selected Service.
106
		 */
107
		function _update() {
108
			if ($this->_dnsService != 'ods') {
109
				$ch = curl_init();
110
				curl_setopt($ch, CURLOPT_HEADER, 0);
111
				curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
112
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
113
			}
114

    
115
			switch ($this->_dnsService) {
116
				case 'dyndns':
117
					$needsIP = FALSE;
118
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
119
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
120
					curl_setopt($ch, CURLOPT_URL, 'https://members.dyndns.org/nic/update?hostname='.$this->_dnsHost.'&myip='.$this->_dnsIP.'&wildcard='.$this->_dnsWildcard.'&mx='.$this->_dnsMX.'&backmx=NO');
121
					$data = curl_exec($ch);
122
					curl_close($ch);
123
					$this->_checkStatus($data);
124
					break;
125
				case 'dyndns-static':
126
					$needsIP = FALSE;
127
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
128
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
129
					curl_setopt($ch, CURLOPT_URL, 'https://members.dyndns.org/nic/update?system=statdns&hostname='.$this->_dnsHost.'&myip='.$this->_dnsIP.'&wildcard='.$this->_dnsWildcard.'&mx='.$this->_dnsMX.'&backmx=NO');
130
					$data = curl_exec($ch);
131
					curl_close($ch);
132
					$this->_checkStatus($data);
133
					break;
134
				case 'dyndns-custom':
135
					$needsIP = FALSE;
136
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
137
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
138
					curl_setopt($ch, CURLOPT_URL, 'https://members.dyndns.org/nic/update?system=custom&hostname='.$this->_dnsHost.'&myip='.$this->_dnsIP.'&wildcard='.$this->_dnsWildcard.'&mx='.$this->_dnsMX.'&backmx=NO');
139
					$data = curl_exec($ch);
140
					curl_close($ch);
141
					$this->_checkStatus($data);
142
					break;
143
				case 'dhs':
144
					$needsIP = TRUE;
145
						$post_data['hostscmd'] = 'edit';
146
						$post_data['hostscmdstage'] = '2';
147
						$post_data['type'] = '4';
148
						$post_data['updatetype'] = 'Online';
149
						$post_data['mx'] = $this->_dnsMX;
150
						$post_data['mx2'] = '';
151
						$post_data['txt'] = '';
152
						$post_data['offline_url'] = '';
153
						$post_data['cloak'] = 'Y';
154
						$post_data['cloak_title'] = '';
155
						$post_data['ip'] = $this->_dnsIP;
156
						$post_data['domain'] = 'dyn.dhs.org';
157
						$post_data['hostname'] = $this->_dnsHost;
158
						$post_data['submit'] = 'Update';
159
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
160
					curl_setopt($ch, CURLOPT_URL, 'https://members.dhs.org/nic/hosts');
161
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
162
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
163
					$data = curl_exec($ch);
164
					curl_close($ch);
165
					$this->_checkStatus($data);
166
					break;
167
				case 'noip':
168
					$needsIP = TRUE;
169
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
170
					curl_setopt($ch, CURLOPT_URL, 'http://dynupdate.no-ip.com/dns?username='.$this->_dnsUser.'&password='.$this->_dnsPass.'&hostname='.$this->_dnsHost.'&ip='.$this->_dnsIP);
171
					$data = curl_exec($ch);
172
					curl_close($ch);
173
					$this->_checkStatus($data);
174
					break;
175
				case 'easydns':
176
					$needsIP = TRUE;
177
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
178
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
179
					curl_setopt($ch, CURLOPT_URL, 'http://members.easydns.com/dyn/dyndns.php?hostname='.$this->_dnsHost.'&myip='.$this->_dnsIP.'&wildcard='.$this->_dnsWildcard.'&mx='.$this->_dnsMX.'&backmx='.$this->_dnsBackMX);
180
					$data = curl_exec($ch);
181
					curl_close($ch);
182
					$this->_checkStatus($data);
183
					break;
184
				case 'hn':
185
					$needsIP = TRUE;
186
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
187
					curl_setopt($ch, CURLOPT_USERPWD, $this->_dnsUser.':'.$this->_dnsPass);
188
					curl_setopt($ch, CURLOPT_URL, 'http://dup.hn.org/vanity/update?ver=1&IP='.$this->_dnsIP);
189
					$data = curl_exec($ch);
190
					curl_close($ch);
191
					$this->_checkStatus($data);
192
					break;
193
				case 'zoneedit':
194
					$needsIP = FALSE;
195
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
196
					curl_setopt($ch, CURLOPT_URL, 'https://dynamic.zoneedit.com/auth/dynamic.html?host='.$this->_dnsHost.'&dnsto='.$this->_dnsIP);
197
					$data = curl_exec($ch);
198
					curl_close($ch);
199
					$this->_checkStatus($data);
200
					break;
201
				case 'dyns':
202
					$needsIP = FALSE;
203
					curl_setopt($ch, CURLOPT_URL, 'http://www.dyns.cx/postscript011.php?username='.$this->_dnsUser.'&password='.$this->_dnsPass.'&host='.$this->_dnsHost);
204
					$data = curl_exec($ch);
205
					curl_close($ch);
206
					$this->_checkStatus($data);
207
					break;
208
				case 'ods':
209
					$needsIP = FALSE;
210
					$this->con['socket'] = fsockopen("ods.org", "7070");
211
					/* Check that we have connected */
212
					if (!$this->con['socket']) {
213
						print "error! could not connect.";
214
						break;
215
					}
216
					/* Here is the loop. Read the incoming data (from the socket connection) */
217
					while (!feof($this->con['socket'])) {
218
						$this->con['buffer']['all'] = trim(fgets($this->con['socket'], 4096));
219
						$code = substr($this->con['buffer']['all'], 0, 3);
220
						sleep(1);
221
						switch($code) {
222
							case 100:
223
								fputs($this->con['socket'], "LOGIN ".$this->_dnsUser." ".$this->_dnsPass."\n");
224
								break;
225
							case 225:
226
								fputs($this->con['socket'], "DELRR ".$this->_dnsHost." A\n");
227
								break;
228
							case 901:
229
								fputs($this->con['socket'], "ADDRR ".$this->_dnsHost." A ".$this->_dnsIP."\n");
230
								break;
231
							case 795:
232
								fputs($this->con['socket'], "QUIT\n");
233
								break;
234
						}
235
					}
236
					$this->_checkStatus($code);
237
					break;
238
				default:
239
					break;
240
			}
241
		}
242

    
243

    
244
		/*
245
		 * Private Function (added 12 July 2005) [beta]
246
		 *   Retrieve Update Status
247
		 */
248
		function _checkStatus($data) {
249
			switch ($this->_dnsService) {
250
				case 'dyndns':
251
					if (preg_match('/notfqdn/i', $data)) {
252
						$status = "phpDynDNS: (Error) Not A FQDN!";
253
					} else if (preg_match('/nochg/i', $data)) {
254
						$status = "phpDynDNS: (Success) No Change In IP Address";
255
					} else if (preg_match('/good/i', $data)) {
256
						$status = "phpDynDNS: (Success) IP Address Changed Successfully! (".$this->_dnsIP.")";
257
					} else if (preg_match('/noauth/i', $data)) {
258
						$status = "phpDynDNS: (Error) User Authorization Failed";
259
					} else {
260
						$status = "phpDynDNS: (Unknown Response)";
261
						$this->_debug($data);
262
					}
263
					break;
264
				case 'dyndns-static':
265
					if (preg_match('/notfqdn/i', $data)) {
266
						$status = "phpDynDNS: (Error) Not A FQDN!";
267
					} else if (preg_match('/nochg/i', $data)) {
268
						$status = "phpDynDNS: (Success) No Change In IP Address";
269
					} else if (preg_match('/good/i', $data)) {
270
						$status = "phpDynDNS: (Success) IP Address Changed Successfully!";
271
					} else if (preg_match('/noauth/i', $data)) {
272
						$status = "phpDynDNS: (Error) User Authorization Failed";
273
					} else {
274
						$status = "phpDynDNS: (Unknown Response)";
275
						$this->_debug($data);
276
					}
277
					break;
278
				case 'dyndns-custom':
279
					if (preg_match('/notfqdn/i', $data)) {
280
						$status = "phpDynDNS: (Error) Not A FQDN!";
281
					} else if (preg_match('/nochg/i', $data)) {
282
						$status = "phpDynDNS: (Success) No Change In IP Address";
283
					} else if (preg_match('/good/i', $data)) {
284
						$status = "phpDynDNS: (Success) IP Address Changed Successfully!";
285
					} else if (preg_match('/noauth/i', $data)) {
286
						$status = "phpDynDNS: (Error) User Authorization Failed";
287
					} else {
288
						$status = "phpDynDNS: (Unknown Response)";
289
						$this->_debug($data);
290
					}
291
					break;
292
				case 'dhs':
293
					break;
294
				case 'noip':
295
					list($ip,$code) = split(":",$data);
296
					switch ($code) {
297
						case 0:
298
							$status = "phpDynDNS: (Success) IP address is current, no update performed.";
299
							break;
300
						case 1:
301
							$status = "phpDynDNS: (Success) DNS hostname update successful.";
302
							break;
303
						case 2:
304
							$status = "phpDynDNS: (Error) Hostname supplied does not exist.";
305
							break;
306
						case 3:
307
							$status = "phpDynDNS: (Error) Invalid Username.";
308
							break;
309
						case 4:
310
							$status = "phpDynDNS: (Error) Invalid Password.";
311
							break;
312
						case 5:
313
							$status = "phpDynDNS: (Error) To many updates sent.";
314
							break;
315
						case 6:
316
							$status = "phpDynDNS: (Error) Account disabled due to violation of No-IP terms of service.";
317
							break;
318
						case 7:
319
							$status = "phpDynDNS: (Error) Invalid IP. IP Address submitted is improperly formatted or is a private IP address or is on a blacklist.";
320
							break;
321
						case 8:
322
							$status = "phpDynDNS: (Error) Disabled / Locked Hostname.";
323
							break;
324
						case 9:
325
							$status = "phpDynDNS: (Error) Host updated is configured as a web redirect and no update was performed.";
326
							break;
327
						case 10:
328
							$status = "phpDynDNS: (Error) Group supplied does not exist.";
329
							break;
330
						case 11:
331
							$status = "phpDynDNS: (Success) DNS group update is successful.";
332
							break;
333
						case 12:
334
							$status = "phpDynDNS: (Success) DNS group is current, no update performed.";
335
							break;
336
						case 13:
337
							$status = "phpDynDNS: (Error) Update client support not available for supplied hostname or group.";
338
							break;
339
						case 14:
340
							$status = "phpDynDNS: (Error) Hostname supplied does not have offline settings configured.";
341
							break;
342
						case 99:
343
							$status = "phpDynDNS: (Error) Client disabled. Client should exit and not perform any more updates without user intervention.";
344
							break;
345
						case 100:
346
							$status = "phpDynDNS: (Error) Client disabled. Client should exit and not perform any more updates without user intervention.";
347
							break;
348
						default:
349
							$status = "phpDynDNS: (Unknown Response)";
350
							$this->_debug($data);
351
							break;
352
					}
353
					break;
354
				case 'easydns':
355
					if (preg_match('/NOACCESS/i', $data)) {
356
						$status = "phpDynDNS: (Error) Authentication Failed: Username and/or Password was Incorrect.";
357
					} else if (preg_match('/NOSERVICE/i', $data)) {
358
						$status = "phpDynDNS: (Error) No Service: Dynamic DNS Service has been disabled for this domain.";
359
					} else if (preg_match('/ILLEGAL INPUT/i', $data)) {
360
						$status = "phpDynDNS: (Error) Illegal Input: Self-Explantory";
361
					} else if (preg_match('/TOOSOON/i', $data)) {
362
						$status = "phpDynDNS: (Error) Too Soon: Not Enough Time Has Elapsed Since Last Update";
363
					} else if (preg_match('/NOERROR/i', $data)) {
364
						$status = "phpDynDNS: (Success) IP Updated Successfully!";					
365
					} else {
366
						$status = "phpDynDNS: (Unknown Response)";
367
						$this->_debug($data);
368
					}
369
					break;
370
				case 'hn':
371
					break;
372
				case 'zoneedit':
373
					if (preg_match('/{700,799}/i', $data)) {
374
						$status = "phpDynDNS: (Error) Update Failed!";
375
					} else if (preg_match('/{200,201}/i', $data)) {
376
						$status = "phpDynDNS: (Success) IP Address Updated Successfully!";
377
					} else {
378
						$status = "phpDynDNS: (Unknown Response)";
379
						$this->_debug($data);
380
					}
381
					break;
382
				case 'dyns':
383
					if (preg_match("/400/i", $data)) {
384
						$status = "phpDynDNS: (Error) Bad Request - The URL was malformed. Required parameters were not provided.";
385
					} else if (preg_match('/402/i', $data)) {
386
						$status = "phpDynDNS: (Error) Update Too Soon - You have tried updating to quickly since last change.";
387
					} else if (preg_match('/403/i', $data)) {
388
						$status = "phpDynDNS: (Error) Database Error - There was a server-sided database error.";
389
					} else if (preg_match('/405/i', $data)) {
390
						$status = "phpDynDNS: (Error) Hostname Error - The hostname (".$this->_dnsHost.") doesn't belong to you.";
391
					} else if (preg_match('/200/i', $data)) {
392
						$status = "phpDynDNS: (Success) IP Address Updated Successfully!";
393
					} else {
394
						$status = "phpDynDNS: (Unknown Response)";
395
						$this->_debug($data);
396
					}
397
					break;
398
				case 'ods':
399
					if (preg_match("/299/i", $data)) {
400
						$status = "phpDynDNS: (Success) IP Address Updated Successfully!";
401
					} else {
402
						$status = "phpDynDNS: (Unknown Response)";
403
						$this->_debug($data);
404
					}
405
					break;
406
			}
407
			$this->status = $status;
408
			log_error($status);
409
		}
410

    
411

    
412
		/*
413
		 * Private Function (added 12 July 05) [beta]
414
		 *   Return Error, Set Last Error, and Die.
415
		 */
416
		function _error($errorNumber = '1') {
417
			switch ($errorNumber) {
418
				case 0:
419
					break;
420
				case 2:
421
					$error = 'phpDynDNS: (ERROR!) No Dynamic DNS Service provider was selected.';
422
					break;
423
				case 3:
424
					$error = 'phpDynDNS: (ERROR!) No Username Provided.';
425
					break;
426
				case 4:
427
					$error = 'phpDynDNS: (ERROR!) No Password Provided.';
428
					break;
429
				case 5:
430
					$error = 'phpDynDNS: (ERROR!) No Hostname Provided.';
431
					break;
432
				case 6:
433
					$error = 'phpDynDNS: (ERROR!) The Dynamic DNS Service provided is not yet supported.';
434
					break;
435
				case 10:
436
					$error = 'phpDynDNS: No Change In My IP Address and/or 28 Days Has Not Past. Not Updating Dynamic DNS Entry.';
437
					break;
438
				default:
439
					$error = "phpDynDNS: (ERROR!) Unknown Response.";
440
					$this->_debug($data);
441
					break;
442
			}
443
			$this->lastError = $error;
444
			log_error($error);
445
		}
446

    
447

    
448
		/*
449
		 * Private Function (added 12 July 05) [beta]
450
		 *   - Detect whether or not IP needs to be updated.
451
		 *      | Written Specifically for pfSense (pfsense.com) may
452
		 *      | work with other systems. pfSense base is FreeBSD.
453
		 */
454
		function _detectChange() {
455
			$currentTime = time();
456

    
457
			#$wan_if = get_real_wan_interface();
458
			#$wan_ip = find_interface_ip($wan_if);
459
			$wan_ip = get_current_wan_address();
460
			$this->_dnsIP = $wan_ip;
461

    
462
			if (file_exists($this->_cacheFile)) {
463
				$file = fopen($this->_cacheFile, 'r');
464
				$contents = fread($file, filesize($this->_cacheFile));
465
				fclose($file);
466
				list($cacheIP,$cacheTime) = split(':', $contents);
467

    
468
				$this->_debug($cacheIP.'/'.$cacheTime);
469

    
470
				$initial = true;
471
			} else {
472
				$file = fopen($this->_cacheFile, 'w');
473
				fwrite($file, '0.0.0.0:'.$currentTime);
474
				fclose($file);
475
				$cacheIP = '0.0.0.0';
476
				$cacheTime = $currentTime;
477

    
478
				$initial = false;
479
			}
480

    
481
			switch ($this->_dnsService) {
482
				case 'dyndns':
483
					$time = '2419200';
484
					break;
485
				case 'dyndns-static':
486
					$time = '2419200';
487
					break;
488
				case 'dyndns-custom':
489
					$time = '2419200';
490
					break;
491
				case 'dhs':
492
					$time = '2419200';
493
					break;
494
				case 'easydns':
495
					$time = '2419200';
496
					break;
497
				case 'noip':
498
					$time = '2419200';
499
					break;
500
				case 'hn':
501
					$time = '2419200';
502
					break;
503
				case 'zoneedit':
504
					$time = '2419200';
505
					break;
506
				case 'dyns':
507
					$time = '2419200';
508
					break;
509
				case 'ods':
510
					$time = '2419200';
511
					break;
512
			}
513

    
514
			/* If IP addresses are different or 28 days have passed update record */
515
			if ( ($cacheIP != $wan_ip) || ( ($currentTime - $cacheTime) > $time ) || ($initial == true) ) {
516
				/* Write WAN IP to cache file */
517
				$file = fopen($this->_cacheFile, 'w');
518
				fwrite($file, $wan_ip.':'.$currentTime);
519
				fclose($file);
520

    
521
				return TRUE;
522
			} else {
523

    
524
				return FALSE;
525
			}
526
		}
527

    
528

    
529
		/*
530
		 * Private Funcation (added 16 July 05) [beta]
531
		 *   - Writes debug information to a file.
532
		 *   - This function is only called when a unknown response
533
		 *   - status is returned from a DynDNS service provider.
534
		 */
535
		function _debug ($data) {
536
			$string = date('m-d-y h:i:s').' - ('.$this->_debugID.') - ['.$this->_dnsService.'] - '.$data;
537
			$file = fopen($this->_debugFile, 'a');
538
			fwrite($file, $string);
539
			fclose($file);
540
		}
541

    
542
	}
543

    
544
?>
(4-4/23)