]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/scripts/setddns.pl
Merge branch 'master' of git://git.ipfire.org/ipfire-2.x
[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 my @service = split(/\./, "$settings{'SERVICE'}");
119 $settings{'SERVICE'} = "$service[0]";
120 if ($settings{'SERVICE'} eq 'no-ip') {
121 open(F, ">${General::swroot}/ddns/noipsettings");
122 flock F, 2;
123 print F "PROXY=" . ($settings{'PROXY'} eq 'on' ? "Y\n" : "N\n");
124 print F "PASSWORD=$settings{'PASSWORD'}\n";
125 print F "NAT=N\n";
126 print F "LOGIN=$settings{'LOGIN'}\n";
127 print F "INTERVAL=1\n";
128 if ($settings{'HOSTNAME'} !~ s/$General::noipprefix//) {
129 print F "HOSTNAME=$settings{'HOSTNAME'}\n";
130 print F "GROUP=\n";
131 } else {
132 print F "HOSTNAME=\n";
133 print F "GROUP=$settings{'HOSTNAME'}\n";
134 }
135 print F "DOMAIN=$settings{'DOMAIN'}\n";
136 print F "DEVICE=\n";
137 print F "DAEMON=N\n";
138 close(F);
139
140 my @ddnscommand = ('/usr/bin/noip','-c',"${General::swroot}/ddns/noipsettings",'-i',"$ip");
141
142 my $result = system(@ddnscommand);
143 if ( $result != 0) {
144 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure");
145 } else {
146 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
147 $success++;
148 }
149 }
150
151 elsif ($settings{'SERVICE'} eq 'cjb') {
152 # use proxy ?
153 my %proxysettings;
154 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
155 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
156 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
157 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
158 }
159
160 my ($out, $response) = Net::SSLeay::get_http( 'www.cjb.net',
161 80,
162 "/cgi-bin/dynip.cgi?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&ip=$ip",
163 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
164 );
165
166 if ($response =~ m%HTTP/1\.. 200 OK%) {
167 if ( $out !~ m/has been updated to point to/ ) {
168 &General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : failure (bad password or login)");
169 } else {
170 &General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : success");
171 $success++;
172 }
173 } else {
174 &General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : failure (could not connect to server)");
175 }
176 }
177 elsif ($settings{'SERVICE'} eq 'mydyn') {
178 # use proxy ?
179 my %proxysettings;
180 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
181 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
182 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
183 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
184 }
185
186 my ($out, $response) = Net::SSLeay::get_http( 'www.mydyn.de',
187 80,
188 "/cgi-bin/update.pl?$settings{'LOGIN'}-$settings{'PASSWORD'}",
189 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
190 );
191
192 if ($response =~ m%HTTP/1\.. 200 OK%) {
193 if ( $out !~ m/The IP address of the subdomain/ ) {
194 &General::log("Dynamic DNS ip-update for mydyn.de ($settings{'LOGIN'}) : failure (bad password or login)");
195 } else {
196 &General::log("Dynamic DNS ip-update for mydyn.de ($settings{'LOGIN'}) : success");
197 $success++;
198 }
199 } else {
200 &General::log("Dynamic DNS ip-update for mydyn.de ($settings{'LOGIN'}) : failure (could not connect to server)");
201 }
202
203 }
204 elsif ($settings{'SERVICE'} eq 'selfhost') {
205 # use proxy ?
206 my %proxysettings;
207 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
208 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
209 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
210 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
211 }
212
213 my ($out, $response) = Net::SSLeay::get_https( 'carol.selfhost.de',
214 443,
215 "/update?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&textmodi=1",
216 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
217 );
218
219 if ($response =~ m%HTTP/1\.. 200 OK%) {
220 if ( $out !~ m/status=(200|204)/ ) {
221 $out =~ s/\n/ /g;
222 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out)");
223 } else {
224 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
225 $success++;
226 }
227 } else {
228 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
229 }
230 }
231 elsif ($settings{'SERVICE'} eq 'dnspark') {
232 # use proxy ?
233 my %proxysettings;
234 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
235 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
236 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
237 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
238 }
239
240 if ($settings{'HOSTNAME'} eq '') {
241 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
242 } else {
243 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
244 }
245
246 my ($out, $response) = Net::SSLeay::get_https( "www.dnspark.net",
247 443,
248 "/api/dynamic/update.php?hostname=$settings{'HOSTDOMAIN'}&ip=$ip",
249 Net::SSLeay::make_headers('User-Agent' => 'IPFire',
250 'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")
251 )
252 );
253 # Valid response are 'ok' 'nochange'
254 if ($response =~ m%HTTP/1\.. 200 OK%) {
255 if ( $out !~ m/^(ok|nochange)/ ) {
256 $out =~ s/\n/ /g;
257 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
258 } else {
259 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
260 $success++;
261 }
262 } else {
263 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials)");
264 }
265 }
266 elsif ($settings{'SERVICE'} eq 'enom') {
267 # use proxy ?
268 my %proxysettings;
269 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
270 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
271 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
272 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
273 }
274 if ($settings{'HOSTNAME'} eq '') {
275 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
276 } else {
277 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
278 }
279
280 my ($out, $response) = Net::SSLeay::get_http( 'dynamic.name-services.com',
281 80,
282 "/interface.asp?Command=SetDNSHost&Zone=$settings{'DOMAIN'}&DomainPassword=$settings{'PASSWORD'}&Address=$ip",
283 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
284 );
285
286 if ($response =~ m%HTTP/1\.. 200 OK%) {
287 #Valid responses from update => ErrCount=0
288 if ( $out !~ m/ErrCount=0/ ) {
289 $out =~ s/(\n|\x0D)/ /g;
290 $out =~ /Err1=([\w ]+) /;
291 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($1)");
292 } else {
293 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
294 $success++;
295 }
296 } else {
297 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
298 }
299 }
300 elsif ($settings{'SERVICE'} eq 'nsupdate') {
301 # Fetch UI configurable values and assemble the host name.
302
303 my $hostName="$settings{'DOMAIN'}";
304 if ($settings{'HOSTNAME'} ne "") {
305 $hostName="$settings{'HOSTNAME'}.$hostName";
306 }
307 my $keyName=$settings{'LOGIN'};
308 my $keySecret=$settings{'PASSWORD'};
309
310 # Use a relatively long TTL value to reduce load on DNS.
311 # Some public Dynamic DNS servers use values around 4 hours,
312 # some use values as low as 60 seconds.
313 # XXX Maybe we could fetch the master value from the server
314 # (not the timed-down version supplied by DNS cache)
315
316 my $timeToLive="3600";
317
318 # Internal setting that can be used to override the DNS server
319 # where the update is applied. It can be of use when testing
320 # against a private DNS server.
321
322 my $masterServer="";
323
324 # Prepare the nsupdate command script to remove and re-add the
325 # updated A record for the domain.
326
327 my $cmdFile="/tmp/nsupdate-$hostName-commands";
328 my $logFile="/tmp/nsupdate-$hostName-result";
329 open(TF, ">$cmdFile");
330 if ($masterServer ne "") {
331 print TF "server $masterServer\n";
332 }
333 if ($keyName ne "" && $keySecret ne "") {
334 print TF "key $keyName $keySecret\n";
335 }
336 print TF "update delete $hostName A\n";
337 print TF "update add $hostName $timeToLive A $ip\n";
338 print TF "send\n";
339 close(TF);
340
341 # Run nsupdate with -v to use TCP instead of UDP because we're
342 # issuing multiple cmds and potentially long keys, and -d to
343 # get diagnostic result output.
344
345 my $result = system("/usr/bin/nsupdate -v -d $cmdFile 2>$logFile");
346 if ($result != 0) {
347 &General::log("Dynamic DNS ip-update for $hostName : failure");
348 open(NSLOG, "$logFile");
349 my @nsLog = <NSLOG>;
350 close(NSLOG);
351 my $logLine;
352 foreach $logLine (@nsLog) {
353 chomp($logLine);
354 if ($logLine ne "") {
355 &General::log("... $logLine");
356 }
357 }
358 } else {
359 &General::log("Dynamic DNS ip-update for $hostName : success");
360 $success++;
361 }
362 unlink $cmdFile, $logFile;
363 }
364 elsif ($settings{'SERVICE'} eq 'freedns') {
365 # use proxy ?
366 my %proxysettings;
367 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
368 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
369 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
370 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
371 }
372
373 my ($out, $response) = Net::SSLeay::get_https( 'freedns.afraid.org',
374 443,
375 "/dynamic/update.php?$settings{'LOGIN'}",
376 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
377 );
378 #Valid responses from service are:
379 #Updated n host(s) <domain>
380 #ERROR: <ip> has not changed.
381 if ($response =~ m%HTTP/1\.. 200 OK%) {
382 #Valid responses from update => ErrCount=0
383 if ( $out !~ m/(^Updated|Address .* has not changed)/ig ) {
384 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out)");
385 } else {
386 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
387 $success++;
388 }
389 } else {
390 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
391 }
392 }
393 elsif ($settings{'SERVICE'} eq 'regfish') {
394 # use proxy ?
395 my %proxysettings;
396 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
397 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
398 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
399 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
400 }
401
402
403 my ($out, $response) = Net::SSLeay::get_https( 'www.regfish.com',
404 443,
405 "/dyndns/2/?fqdn=$settings{'DOMAIN'}&ipv4=$ip&forcehost=1&authtype=secure&token=$settings{'LOGIN'}",
406 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
407 );
408 #Valid responses from service are:
409 #success|100|update succeeded!
410 #success|101|no update needed at this time..
411 if ($response =~ m%HTTP/1\.. 200 OK%) {
412 if ( $out !~ m/(success\|(100|101)\|)/ig ) {
413 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure ($out)");
414 } else {
415 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : success");
416 $success++;
417 }
418 } else {
419 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure (could not connect to server)");
420 }
421 }
422 elsif ($settings{'SERVICE'} eq 'ovh') {
423 my %proxysettings;
424 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
425
426 my $peer = 'www.ovh.com';
427 my $peerport = 80;
428
429 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
430 ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
431 }
432
433 my $sock;
434 unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
435 &General::log("Dynamic DNS failure : could not connect to $peer:$peerport: $@");
436 next;
437 }
438
439 if ($settings{'HOSTNAME'} eq '') {
440 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
441 } else {
442 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
443 }
444
445 my ($GET_CMD, $code64);
446 $GET_CMD = "GET http://www.ovh.com/nic/update?system=dyndns&hostname=$settings{'HOSTDOMAIN'}&myip=$ip HTTP/1.1\r\n";
447 $GET_CMD .= "Host: www.ovh.com\r\n";
448 chomp($code64 = encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}"));
449 $GET_CMD .= "Authorization: Basic $code64\r\n";
450 $GET_CMD .= "User-Agent: ipfire\r\n";
451 #$GET_CMD .= "Content-Type: application/x-www-form-urlencoded\r\n";
452 $GET_CMD .= "\r\n";
453 print $sock "$GET_CMD";
454
455 my $out = '';
456 while(<$sock>) {
457 $out .= $_;
458 }
459 close($sock);
460
461 #HTTP response => error (in Title tag) else text response
462 #Valid responses from service:good,nochg (ez-ipupdate like)
463 #Should use ez-ipdate but "system=dyndns" is not present
464 if ( $out =~ m/<Title>(.*)<\/Title>/ig ) {
465 &General::log("Dynamic DNS ovh.com : failure ($1)");
466 }
467 elsif ($out !~ m/good |nochg /ig) {
468 $out =~ s/.+?\015?\012\015?\012//s; # header HTTP
469 my @out = split("\r", $out);
470 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure ($out[1])");
471 } else {
472 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : success");
473 $success++;
474 }
475 }
476 elsif ($settings{'SERVICE'} eq 'dtdns') {
477 # use proxy ?
478 my %proxysettings;
479 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
480 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
481 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
482 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
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 ($out, $response) = Net::SSLeay::get_http( 'www.dtdns.com',
492 80,
493 "/api/autodns.cfm?id=$settings{'HOSTDOMAIN'}&pw=$settings{'PASSWORD'}",
494 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
495 );
496 #Valid responses from service are:
497 # now points to
498 #
499 if ($response =~ m%HTTP/1\.. 200 OK%) {
500 if ( $out !~ m/Host .* now points to/ig ) {
501 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
502 } else {
503 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
504 $success++;
505 }
506 } else {
507 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");
508 }
509 }
510 elsif ($settings{'SERVICE'} eq 'dynu') {
511 # use proxy ?
512 my %proxysettings;
513 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
514 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
515 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
516 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
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 ($out, $response) = Net::SSLeay::get_http( 'dynserv.ca',
526 80,
527 "/dyn/dynengine.cgi?func=set&name=$settings{'LOGIN'}&pass=$settings{'PASSWORD'}&ip=$ip&domain=$settings{'DOMAIN'}",
528 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
529 );
530 #Valid responses from service are:
531 # 02 == Domain already exists, refreshing data for ... => xxx.xxx.xxx.xxx
532 #
533 if ($response =~ m%HTTP/1\.. 200 OK%) {
534 if ( $out !~ m/Domain already exists, refreshing data for/ig ) {
535 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
536 } else {
537 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
538 $success++;
539 }
540 } else {
541 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");
542 }
543 } else {
544 if ($settings{'WILDCARDS'} eq 'on') {
545 $settings{'WILDCARDS'} = '-w';
546 } else {
547 $settings{'WILDCARDS'} = '';
548 }
549
550 if (($settings{'SERVICE'} eq 'dyndns-custom' ||
551 $settings{'SERVICE'} eq 'easydns' ||
552 $settings{'SERVICE'} eq 'zoneedit') && $settings{'HOSTNAME'} eq '') {
553 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
554 } else {
555 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
556 }
557
558 my @ddnscommand = ('/usr/bin/ez-ipupdate', '-a', "$ip", '-S', "$settings{'SERVICE'}", '-u', "$settings{'LOGIN'}:$settings{'PASSWORD'}", '-h', "$settings{'HOSTDOMAIN'}", "$settings{'WILDCARDS'}", '-q');
559
560 my $result = system(@ddnscommand);
561 if ( $result != 0) {
562 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: failure");
563 } else {
564 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: success");
565 $success++;
566 }
567 }
568 } else {
569 # If a line is disabled, then we should discount it
570 $lines--;
571 }
572 }
573
574 if ($lines == $success) {
575 open(IPCACHE, ">$cachefile");
576 flock IPCACHE, 2;
577 print IPCACHE $ip;
578 close(IPCACHE);
579 exit 1;
580 }
581
582 }
583 exit 0;
584
585 # Extracted from Base64.pm
586 sub encode_base64 ($;$) {
587 my $res = "";
588 my $eol = $_[1];
589 $eol = "\n" unless defined $eol;
590 pos($_[0]) = 0; # ensure start at the beginning
591 while ($_[0] =~ /(.{1,45})/gs) {
592 $res .= substr(pack('u', $1), 1);
593 chop($res);
594 }
595 $res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs
596 # fix padding at the end
597 my $padding = (3 - length($_[0]) % 3) % 3;
598 $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
599 # break encoded string into lines of no more than 76 characters each
600 if (length $eol) {
601 $res =~ s/(.{1,76})/$1$eol/g;
602 }
603 $res;
604 }
605
606
607
608 __END__
609 old code for selfhost.de
610
611 my %proxysettings;
612 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
613
614 my $peer = 'carol.selfhost.de';
615 my $peerport = 80;
616
617 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
618 ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
619 }
620
621 my $sock;
622 unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
623 die "Could not connect to $peer:$peerport: $@";
624 return 1;
625 }
626
627 my $GET_CMD;
628 $GET_CMD = "GET https://carol.selfhost.de/update?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&myip=$ip&textmodi=1 HTTP/1.1\r\n";
629 $GET_CMD .= "Host: carol.selfhost.de\r\n";
630 $GET_CMD .= "User-Agent: ipfire\r\n";
631 $GET_CMD .= "Connection: close\r\n\r\n";
632 print $sock "$GET_CMD";
633
634 my $out = '';
635 while(<$sock>) {
636 $out .= $_;
637 }
638 close($sock);
639
640 if ( $out !~ m/status=(200|204)/ ) {
641 #cleanup http response...
642 $out =~ s/.+?\015?\012\015?\012//s; # header HTTP
643 my @out = split("\r", $out);
644 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out[1])");
645 } else {
646 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
647 $success++;
648 }
649
650
651