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