DDNS: Fix API call for the "Dynu" DDNS service
[people/teissler/ipfire-2.x.git] / src / scripts / setddns.pl
1 #!/usr/bin/perl
2 #
3 # SmoothWall CGIs
4 #
5 # This code is distributed under the terms of the GPL
6 #
7 # (c) The SmoothWall Team
8 #
9 # $Id: setddns.pl,v 1.4.2.32 2006/02/07 01:29:47 franck78 Exp $
10 #
11
12 #close(STDIN);
13 #close(STDOUT);
14 #close(STDERR);
15
16 use strict;
17 use IO::Socket;
18 use Net::SSLeay;
19
20 require '/var/ipfire/general-functions.pl';
21
22 #Prototypes functions
23 sub encode_base64 ($;$);
24
25 my %settings;
26 my $filename = "${General::swroot}/ddns/config";
27 my $cachefile = "${General::swroot}/ddns/ipcache";
28 my $ipcache = 0;
29 my @current = ();
30
31 if (open(FILE, "$filename")) {
32 @current = <FILE>;
33 close(FILE);
34 unless(@current) {
35 exit 0;
36 }
37 } else {
38 &General::log('Dynamic DNS failure : unable to open config file.');
39 exit 0;
40 }
41
42 &General::readhash("${General::swroot}/ddns/settings", \%settings);
43
44 # ignore monthly update if not in minimize update mode
45 exit 0 if (($settings{'MINIMIZEUPDATES'} ne 'on') && ($ARGV[1] eq '-m'));
46
47 my $ip = &General::GetDyndnsRedIP();
48
49 if ($ip eq "unavailable") {
50 &General::log("Dynamic DNS error: RED/Public IP is unavailable");
51 exit(0);
52 }
53
54 #&General::log("Dynamic DNS public router IP is: $ip");
55
56 if ($ARGV[0] eq '-f') {
57 unlink ($cachefile); # next regular calls will try again if this force update fails.
58 } else {
59 open(IPCACHE, "$cachefile");
60 $ipcache = <IPCACHE>;
61 close(IPCACHE);
62 chomp $ipcache;
63 }
64
65 if ($ip ne $ipcache) {
66 my $id = 0;
67 my $success = 0;
68 my $line;
69 my $lines = @current;
70
71 foreach $line (@current) {
72 $id++;
73 chomp($line);
74 my @temp = split(/\,/,$line);
75 unless ($temp[7] ne "on") {
76 $settings{'SERVICE'} = $temp[0];
77 $settings{'HOSTNAME'} = $temp[1];
78 $settings{'DOMAIN'} = $temp[2];
79 $settings{'PROXY'} = $temp[3];
80 $settings{'WILDCARDS'} = $temp[4];
81 $settings{'LOGIN'} = $temp[5];
82 $settings{'PASSWORD'} = $temp[6];
83 $settings{'ENABLED'} = $temp[7];
84
85 #Some connection are very stable (more than 40 days). Finally force
86 #one update / month to avoid account lost
87 #cron call once/week with -f & once/month with -f -m options
88 #minimize update ?
89 if ( ($settings{'MINIMIZEUPDATES'} eq 'on') && ($ARGV[1] ne '-m') ) {
90 if (General::DyndnsServiceSync($ip, $settings{'HOSTNAME'},$settings{'DOMAIN'})) {
91 &General::log ("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} is uptodate [$ip]");
92 $success++;
93 next; # do not update, go to test next service
94 }
95 }
96 if ($settings{'SERVICE'} ne "dns.lightningwirelabs.com") {
97 my @service = split(/\./, "$settings{'SERVICE'}");
98 $settings{'SERVICE'} = "$service[0]";
99 }
100 if ($settings{'SERVICE'} eq 'no-ip') {
101 open(F, ">${General::swroot}/ddns/noipsettings");
102 flock F, 2;
103 print F "PROXY=" . ($settings{'PROXY'} eq 'on' ? "Y\n" : "N\n");
104 print F "PASSWORD=$settings{'PASSWORD'}\n";
105 print F "NAT=N\n";
106 print F "LOGIN=$settings{'LOGIN'}\n";
107 print F "INTERVAL=1\n";
108 if ($settings{'HOSTNAME'} !~ s/$General::noipprefix//) {
109 print F "HOSTNAME=$settings{'HOSTNAME'}\n";
110 print F "GROUP=\n";
111 } else {
112 print F "HOSTNAME=\n";
113 print F "GROUP=$settings{'HOSTNAME'}\n";
114 }
115 print F "DOMAIN=$settings{'DOMAIN'}\n";
116 print F "DEVICE=\n";
117 print F "DAEMON=N\n";
118 close(F);
119
120 my @ddnscommand = ('/usr/bin/noip','-c',"${General::swroot}/ddns/noipsettings",'-i',"$ip");
121
122 my $result = system(@ddnscommand);
123 if ( $result != 0) {
124 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure");
125 } else {
126 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
127 $success++;
128 }
129 }
130
131 elsif ($settings{'SERVICE'} eq 'all-inkl') {
132 my %proxysettings;
133 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
134 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
135 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
136 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
137 }
138
139 my ($out, $response) = Net::SSLeay::get_https("dyndns.kasserver.com", 443, "/", Net::SSLeay::make_headers(
140 'User-Agent' => 'IPFire', 'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")
141 ));
142
143 # Valid response are 'ok' 'nochange'
144 if ($response =~ m%HTTP/1\.. 200 OK%) {
145 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
146 $success++;
147 } else {
148 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server, check your credentials)");
149 }
150 }
151
152 elsif ($settings{'SERVICE'} eq 'cjb') {
153 # use proxy ?
154 my %proxysettings;
155 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
156 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
157 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
158 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
159 }
160
161 my ($out, $response) = Net::SSLeay::get_http( 'www.cjb.net',
162 80,
163 "/cgi-bin/dynip.cgi?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&ip=$ip",
164 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
165 );
166
167 if ($response =~ m%HTTP/1\.. 200 OK%) {
168 if ( $out !~ m/has been updated to point to/ ) {
169 &General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : failure (bad password or login)");
170 } else {
171 &General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : success");
172 $success++;
173 }
174 } else {
175 &General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : failure (could not connect to server)");
176 }
177 }
178 elsif ($settings{'SERVICE'} eq 'selfhost') {
179 # use proxy ?
180 my %proxysettings;
181 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
182 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
183 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
184 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
185 }
186
187 my ($out, $response) = Net::SSLeay::get_https( 'carol.selfhost.de',
188 443,
189 "/update?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&textmodi=1",
190 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
191 );
192
193 if ($response =~ m%HTTP/1\.. 200 OK%) {
194 if ( $out !~ m/status=(200|204)/ ) {
195 $out =~ s/\n/ /g;
196 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out)");
197 } else {
198 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
199 $success++;
200 }
201 } else {
202 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
203 }
204 }
205 elsif ($settings{'SERVICE'} eq 'dnspark') {
206 # use proxy ?
207 my %proxysettings;
208 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
209 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
210 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
211 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
212 }
213
214 if ($settings{'HOSTNAME'} eq '') {
215 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
216 } else {
217 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
218 }
219
220 my ($out, $response) = Net::SSLeay::get_https( "www.dnspark.net",
221 443,
222 "/api/dynamic/update.php?hostname=$settings{'HOSTDOMAIN'}&ip=$ip",
223 Net::SSLeay::make_headers('User-Agent' => 'IPFire',
224 'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")
225 )
226 );
227 # Valid response are 'ok' 'nochange'
228 if ($response =~ m%HTTP/1\.. 200 OK%) {
229 if ( $out !~ m/^(ok|nochange)/ ) {
230 $out =~ s/\n/ /g;
231 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
232 } else {
233 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
234 $success++;
235 }
236 } else {
237 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials)");
238 }
239 }
240 elsif ($settings{'SERVICE'} eq 'dns.lightningwirelabs.com') {
241 # use proxy ?
242 my %proxysettings;
243 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
244 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
245 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
246 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
247 }
248
249 if ($settings{'HOSTNAME'} eq '') {
250 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
251 } else {
252 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
253 }
254
255 my $authstring;
256 if ($settings{'LOGIN'} eq "token") {
257 $authstring = "token=$settings{'PASSWORD'}";
258 } else {
259 $authstring = "username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}";
260 }
261
262 my $user_agent = &General::MakeUserAgent();
263 my ($out, $response) = Net::SSLeay::get_https("dns.lightningwirelabs.com", 443,
264 "/update?hostname=$settings{'HOSTDOMAIN'}&address4=$ip&$authstring",
265 Net::SSLeay::make_headers('User-Agent' => $user_agent)
266 );
267
268 # Valid response are 'ok' 'nochange'
269 if ($response =~ m%HTTP/1\.. 200 OK%) {
270 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
271 $success++;
272 } else {
273 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials)");
274 }
275 }
276 elsif ($settings{'SERVICE'} eq 'enom') {
277 # use proxy ?
278 my %proxysettings;
279 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
280 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
281 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
282 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
283 }
284 if ($settings{'HOSTNAME'} eq '') {
285 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
286 } else {
287 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
288 }
289
290 my ($out, $response) = Net::SSLeay::get_http( 'dynamic.name-services.com',
291 80,
292 "/interface.asp?Command=SetDNSHost&Zone=$settings{'DOMAIN'}&DomainPassword=$settings{'PASSWORD'}&Address=$ip",
293 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
294 );
295
296 if ($response =~ m%HTTP/1\.. 200 OK%) {
297 #Valid responses from update => ErrCount=0
298 if ( $out !~ m/ErrCount=0/ ) {
299 $out =~ s/(\n|\x0D)/ /g;
300 $out =~ /Err1=([\w ]+) /;
301 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($1)");
302 } else {
303 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
304 $success++;
305 }
306 } else {
307 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
308 }
309 }
310 elsif ($settings{'SERVICE'} eq 'nsupdate') {
311 # Fetch UI configurable values and assemble the host name.
312
313 my $hostName="$settings{'DOMAIN'}";
314 if ($settings{'HOSTNAME'} ne "") {
315 $hostName="$settings{'HOSTNAME'}.$hostName";
316 }
317 my $keyName=$settings{'LOGIN'};
318 my $keySecret=$settings{'PASSWORD'};
319
320 # Use a relatively long TTL value to reduce load on DNS.
321 # Some public Dynamic DNS servers use values around 4 hours,
322 # some use values as low as 60 seconds.
323 # XXX Maybe we could fetch the master value from the server
324 # (not the timed-down version supplied by DNS cache)
325
326 my $timeToLive="3600";
327
328 # Internal setting that can be used to override the DNS server
329 # where the update is applied. It can be of use when testing
330 # against a private DNS server.
331
332 my $masterServer="";
333
334 # Prepare the nsupdate command script to remove and re-add the
335 # updated A record for the domain.
336
337 my $cmdFile="/tmp/nsupdate-$hostName-commands";
338 my $logFile="/tmp/nsupdate-$hostName-result";
339 open(TF, ">$cmdFile");
340 if ($masterServer ne "") {
341 print TF "server $masterServer\n";
342 }
343 if ($keyName ne "" && $keySecret ne "") {
344 print TF "key $keyName $keySecret\n";
345 }
346 print TF "update delete $hostName A\n";
347 print TF "update add $hostName $timeToLive A $ip\n";
348 print TF "send\n";
349 close(TF);
350
351 # Run nsupdate with -v to use TCP instead of UDP because we're
352 # issuing multiple cmds and potentially long keys, and -d to
353 # get diagnostic result output.
354
355 my $result = system("/usr/bin/nsupdate -v -d $cmdFile 2>$logFile");
356 if ($result != 0) {
357 &General::log("Dynamic DNS ip-update for $hostName : failure");
358 open(NSLOG, "$logFile");
359 my @nsLog = <NSLOG>;
360 close(NSLOG);
361 my $logLine;
362 foreach $logLine (@nsLog) {
363 chomp($logLine);
364 if ($logLine ne "") {
365 &General::log("... $logLine");
366 }
367 }
368 } else {
369 &General::log("Dynamic DNS ip-update for $hostName : success");
370 $success++;
371 }
372 unlink $cmdFile, $logFile;
373 }
374 elsif ($settings{'SERVICE'} eq 'freedns') {
375 # use proxy ?
376 my %proxysettings;
377 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
378 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
379 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
380 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
381 }
382
383 my ($out, $response) = Net::SSLeay::get_https( 'freedns.afraid.org',
384 443,
385 "/dynamic/update.php?$settings{'LOGIN'}",
386 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
387 );
388 #Valid responses from service are:
389 #Updated n host(s) <domain>
390 #ERROR: <ip> has not changed.
391 if ($response =~ m%HTTP/1\.. 200 OK%) {
392 #Valid responses from update => ErrCount=0
393 if ( $out !~ m/(^Updated|Address .* has not changed)/ig ) {
394 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out)");
395 } else {
396 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
397 $success++;
398 }
399 } else {
400 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
401 }
402 }
403 elsif ($settings{'SERVICE'} eq 'spdns.de') {
404 # use proxy ?
405 my %proxysettings;
406 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
407 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
408 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
409 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
410 }
411
412 if ($settings{'HOSTNAME'} eq '') {
413 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
414 } else {
415 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
416 }
417
418 my ($out, $response) = Net::SSLeay::get_https( 'update.spdns.de', 443,
419 "/nic/update?&hostname=$settings{'HOSTDOMAIN'}&myip=$ip",
420 Net::SSLeay::make_headers('User-Agent' => 'IPFire' ,
421 'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}"))
422 );
423
424 #Valid responses from service are:
425 # good xxx.xxx.xxx.xxx
426 # nochg xxx.xxx.xxx.xxx
427 if ($response =~ m%HTTP/1\.. 200 OK%) {
428 if ($out !~ m/good |nochg /ig) {
429 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
430 } else {
431 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
432 $success++;
433 }
434 } else {
435 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");
436 }
437 }
438 elsif ($settings{'SERVICE'} eq 'strato') {
439 # use proxy ?
440 my %proxysettings;
441 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
442 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
443 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
444 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
445 }
446
447 if ($settings{'HOSTNAME'} eq '') {
448 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
449 } else {
450 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
451 }
452
453 my ($out, $response) = Net::SSLeay::get_https( 'dyndns.strato.com',
454 443,
455 "/nic/update?hostname=$settings{'HOSTDOMAIN'}&myip=$ip",
456 Net::SSLeay::make_headers('User-Agent' => 'IPFire',
457 'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}") )
458 );
459
460 if ($response =~ m%HTTP/1\.. 200 OK%) {
461 #Valid responses from update => ErrCount=0
462 if ( $out =~ m/good |nochg /ig) {
463 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
464 $success++;
465 } else {
466 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure1 ($out)");
467 $success++;
468 }
469 } elsif ( $out =~ m/<title>(.*)<\/title>/ig ) {
470 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure2 ($1)");
471 } else {
472 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure3 ($response)");
473 }
474 }
475 elsif ($settings{'SERVICE'} eq 'regfish') {
476 # use proxy ?
477 my %proxysettings;
478 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
479 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
480 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
481 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
482 }
483 my ($out, $response) = Net::SSLeay::get_https( 'dyndns.regfish.de',
484 443,
485 "/?fqdn=$settings{'DOMAIN'}&ipv4=$ip&forcehost=1&authtype=secure&token=$settings{'LOGIN'}",
486 Net::SSLeay::make_headers('User-Agent' => 'Ipfire' )
487 );
488 #Valid responses from service are:
489 #success|100|update succeeded!
490 #success|101|no update needed at this time..
491 if ($response =~ m%HTTP/1\.. 200 OK%) {
492 if ( $out !~ m/(success\|(100|101)\|)/ig ) {
493 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure ($out)");
494 } else {
495 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : success");
496 $success++;
497 }
498 } else {
499 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure (could not connect to server)");
500 }
501 }
502 elsif ($settings{'SERVICE'} eq 'ovh') {
503 my %proxysettings;
504 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
505
506 my $peer = 'www.ovh.com';
507 my $peerport = 80;
508
509 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
510 ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
511 }
512
513 my $sock;
514 unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
515 &General::log("Dynamic DNS failure : could not connect to $peer:$peerport: $@");
516 next;
517 }
518
519 if ($settings{'HOSTNAME'} eq '') {
520 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
521 } else {
522 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
523 }
524
525 my ($GET_CMD, $code64);
526 $GET_CMD = "GET http://www.ovh.com/nic/update?system=dyndns&hostname=$settings{'HOSTDOMAIN'}&myip=$ip HTTP/1.1\r\n";
527 $GET_CMD .= "Host: www.ovh.com\r\n";
528 chomp($code64 = encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}"));
529 $GET_CMD .= "Authorization: Basic $code64\r\n";
530 $GET_CMD .= "User-Agent: ipfire\r\n";
531 #$GET_CMD .= "Content-Type: application/x-www-form-urlencoded\r\n";
532 $GET_CMD .= "\r\n";
533 print $sock "$GET_CMD";
534
535 my $out = '';
536 while(<$sock>) {
537 $out .= $_;
538 }
539 close($sock);
540
541 #HTTP response => error (in Title tag) else text response
542 #Valid responses from service:good,nochg (ez-ipupdate like)
543 #Should use ez-ipdate but "system=dyndns" is not present
544 if ( $out =~ m/<Title>(.*)<\/Title>/ig ) {
545 &General::log("Dynamic DNS ovh.com : failure ($1)");
546 }
547 elsif ($out !~ m/good |nochg /ig) {
548 $out =~ s/.+?\015?\012\015?\012//s; # header HTTP
549 my @out = split("\r", $out);
550 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure ($out[1])");
551 } else {
552 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : success");
553 $success++;
554 }
555 }
556 elsif ($settings{'SERVICE'} eq 'dtdns') {
557 # use proxy ?
558 my %proxysettings;
559 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
560 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
561 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
562 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
563 }
564
565 if ($settings{'HOSTNAME'} eq '') {
566 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
567 } else {
568 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
569 }
570
571 my ($out, $response) = Net::SSLeay::get_http( 'www.dtdns.com',
572 80,
573 "/api/autodns.cfm?id=$settings{'HOSTDOMAIN'}&pw=$settings{'PASSWORD'}",
574 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
575 );
576 #Valid responses from service are:
577 # now points to
578 #
579 if ($response =~ m%HTTP/1\.. 200 OK%) {
580 if ( $out !~ m/Host .* now points to/ig ) {
581 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
582 } else {
583 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
584 $success++;
585 }
586 } else {
587 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");
588 }
589 }
590 #namecheap test
591 elsif ($settings{'SERVICE'} eq 'namecheap') {
592 # use proxy ?
593 my %proxysettings;
594 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
595 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
596 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
597 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
598 }
599
600 my ($out, $response) = Net::SSLeay::get_https( 'dynamicdns.park-your-domain.com',
601 443,
602 "/update?host=$settings{'HOSTNAME'}&domain=$settings{'DOMAIN'}&password=$settings{'PASSWORD'}&ip=$ip",
603 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
604 );
605 #Valid responses from service are:
606 # wait confirmation!!
607 if ($response =~ m%HTTP/1\.. 200 OK%) {
608 if ( $out !~ m/<ErrCount>0<\/ErrCount>/ ) {
609 $out =~ m/<Err1>(.*)<\/Err1>/;
610 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($1)");
611 } else {
612 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
613 $success++;
614 }
615 } else {
616 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
617 }
618 }
619 #end namecheap test
620 elsif ($settings{'SERVICE'} eq 'dynu') {
621 # use proxy ?
622 my %proxysettings;
623 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
624 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
625 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
626 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
627 }
628
629 if ($settings{'HOSTNAME'} eq '') {
630 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
631 } else {
632 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
633 }
634
635 my ($out, $response) = Net::SSLeay::get_https( 'api.dynu.com',
636 443,
637 "/nic/update?hostname=$settings{'HOSTDOMAIN'}&myip=$ip&username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}",
638 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
639 );
640 # Valid responses are 'good xxx.xxx.xxx.xxx', 'nochg'
641 # see http://www.dynu.com/Default.aspx?page=dnsapi for further details
642 if ($response =~ m%HTTP/1\.. 200 OK%) {
643 if ( $out !~ m/^(good|nochg)/ ) {
644 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
645 } else {
646 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success ($out)");
647 $success++;
648 }
649 } else {
650 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server---$out-$response)");
651 }
652 }
653 elsif ($settings{'SERVICE'} eq 'udmedia') {
654 # use proxy ?
655 my %proxysettings;
656 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
657 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
658 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
659 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
660 }
661
662 if ($settings{'HOSTNAME'} eq '') {
663 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
664 } else {
665 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
666 }
667
668 my ($out, $response) = Net::SSLeay::get_https( 'www.udmedia.de',
669 443,
670 "/nic/update?myip=$ip&username=$settings{'HOSTDOMAIN'}&password=$settings{'PASSWORD'}",
671 Net::SSLeay::make_headers('User-Agent' => 'IPFire',
672 'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")) );
673
674 # Valid response are 'ok' 'nochange'
675 if ($response =~ m%HTTP/1\.. 200 OK%) {
676 if ( $out !~ m/^(ok|nochg)/ ) {
677 $out =~ s/\n/ /g;
678 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
679 } else {
680 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
681 $success++;
682 }
683 } else {
684 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials---$out-$response--)");
685 }
686 }
687 elsif ($settings{'SERVICE'} eq 'twodns') {
688 # use proxy ?
689 my %proxysettings;
690 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
691 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
692 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
693 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
694 }
695
696 if ($settings{'HOSTNAME'} eq '') {
697 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
698 } else {
699 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
700 }
701
702 my ($out, $response) = Net::SSLeay::get_https( 'update.twodns.de',
703 443,
704 "/update?hostname=$settings{'HOSTDOMAIN'}&ip=$ip",
705 Net::SSLeay::make_headers('User-Agent' => 'IPFire',
706 'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")) );
707
708 # Valid response are 'ok' 'nochange'
709 if ($response =~ m%HTTP/1\.. 200 OK%) {
710 if ( $out !~ m/^(good|nochg)/ ) {
711 $out =~ s/\n/ /g;
712 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
713 } else {
714 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
715 $success++;
716 }
717 } else {
718 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials---$out-$response--)");
719 }
720 }
721 elsif ($settings{'SERVICE'} eq 'variomedia') {
722 # use proxy ?
723 my %proxysettings;
724 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
725 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
726 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
727 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
728 }
729
730 if ($settings{'HOSTNAME'} eq '') {
731 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
732 } else {
733 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
734 }
735
736 my ($out, $response) = Net::SSLeay::get_https( 'dyndns.variomedia.de',
737 443,
738 "/nic/update?hostname=$settings{'HOSTDOMAIN'}&myip=$ip",
739 Net::SSLeay::make_headers('User-Agent' => 'IPFire',
740 'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")) );
741
742 # Valid response is 'good $ip'
743 if ($response =~ m%HTTP/1\.. 200 OK%) {
744 if ( $out !~ m/^good $ip/ ) {
745 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} ($ip) : failure ($out)");
746 } else {
747 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} ($ip) : success");
748 $success++;
749 }
750 } else {
751 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials---$out-$response--)");
752 }
753 }
754 else {
755 if ($settings{'WILDCARDS'} eq 'on') {
756 $settings{'WILDCARDS'} = '-w';
757 } else {
758 $settings{'WILDCARDS'} = '';
759 }
760
761 if (($settings{'SERVICE'} eq 'dyndns-custom' ||
762 $settings{'SERVICE'} eq 'easydns' ||
763 $settings{'SERVICE'} eq 'zoneedit') && $settings{'HOSTNAME'} eq '') {
764 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
765 } else {
766 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
767 }
768
769 my @ddnscommand = ('/usr/bin/ez-ipupdate', '-a', "$ip", '-S', "$settings{'SERVICE'}", '-u', "$settings{'LOGIN'}:$settings{'PASSWORD'}", '-h', "$settings{'HOSTDOMAIN'}", "$settings{'WILDCARDS'}", '-q');
770
771 my $result = system(@ddnscommand);
772 if ( $result != 0) {
773 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: failure");
774 } else {
775 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: success");
776 $success++;
777 }
778 }
779 } else {
780 # If a line is disabled, then we should discount it
781 $lines--;
782 }
783 }
784
785 if ($lines == $success) {
786 open(IPCACHE, ">$cachefile");
787 flock IPCACHE, 2;
788 print IPCACHE $ip;
789 close(IPCACHE);
790 exit 1;
791 }
792
793 }
794 exit 0;
795
796 # Extracted from Base64.pm
797 sub encode_base64 ($;$) {
798 my $res = "";
799 my $eol = $_[1];
800 $eol = "\n" unless defined $eol;
801 pos($_[0]) = 0; # ensure start at the beginning
802 while ($_[0] =~ /(.{1,45})/gs) {
803 $res .= substr(pack('u', $1), 1);
804 chop($res);
805 }
806 $res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs
807 # fix padding at the end
808 my $padding = (3 - length($_[0]) % 3) % 3;
809 $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
810 # break encoded string into lines of no more than 76 characters each
811 if (length $eol) {
812 $res =~ s/(.{1,76})/$1$eol/g;
813 }
814 $res;
815 }
816
817
818
819 __END__
820 old code for selfhost.de
821
822 my %proxysettings;
823 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
824
825 my $peer = 'carol.selfhost.de';
826 my $peerport = 80;
827
828 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
829 ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
830 }
831
832 my $sock;
833 unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
834 die "Could not connect to $peer:$peerport: $@";
835 return 1;
836 }
837
838 my $GET_CMD;
839 $GET_CMD = "GET https://carol.selfhost.de/update?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&myip=$ip&textmodi=1 HTTP/1.1\r\n";
840 $GET_CMD .= "Host: carol.selfhost.de\r\n";
841 $GET_CMD .= "User-Agent: ipfire\r\n";
842 $GET_CMD .= "Connection: close\r\n\r\n";
843 print $sock "$GET_CMD";
844
845 my $out = '';
846 while(<$sock>) {
847 $out .= $_;
848 }
849 close($sock);
850
851 if ( $out !~ m/status=(200|204)/ ) {
852 #cleanup http response...
853 $out =~ s/.+?\015?\012\015?\012//s; # header HTTP
854 my @out = split("\r", $out);
855 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out[1])");
856 } else {
857 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
858 $success++;
859 }
860
861
862