]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/scripts/setddns.pl
Update:
[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
79 if ($ARGV[0] eq '-f') {
80 unlink ($cachefile); # next regular calls will try again if this force update fails.
81 } else {
82 open(IPCACHE, "$cachefile");
83 $ipcache = <IPCACHE>;
84 close(IPCACHE);
85 chomp $ipcache;
86 }
87
88 if ($ip ne $ipcache) {
89 my $id = 0;
90 my $success = 0;
91 my $line;
92 my $lines = @current;
93
94 foreach $line (@current) {
95 $id++;
96 chomp($line);
97 my @temp = split(/\,/,$line);
98 unless ($temp[7] ne "on") {
99 $settings{'SERVICE'} = $temp[0];
100 $settings{'HOSTNAME'} = $temp[1];
101 $settings{'DOMAIN'} = $temp[2];
102 $settings{'PROXY'} = $temp[3];
103 $settings{'WILDCARDS'} = $temp[4];
104 $settings{'LOGIN'} = $temp[5];
105 $settings{'PASSWORD'} = $temp[6];
106 $settings{'ENABLED'} = $temp[7];
107
108 #Some connection are very stable (more than 40 days). Finally force
109 #one update / month to avoid account lost
110 #cron call once/week with -f & once/month with -f -m options
111 #minimize update ?
112 if ( ($settings{'MINIMIZEUPDATES'} eq 'on') && ($ARGV[1] ne '-m') ) {
113 if (General::DyndnsServiceSync($ip, $settings{'HOSTNAME'},$settings{'DOMAIN'})) {
114 &General::log ("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} is uptodate [$ip]");
115 $success++;
116 next; # do not update, go to test next service
117 }
118 }
119 my @service = split(/\./, "$settings{'SERVICE'}");
120 $settings{'SERVICE'} = "$service[0]";
121 if ($settings{'SERVICE'} eq 'no-ip') {
122 open(F, ">${General::swroot}/ddns/noipsettings");
123 flock F, 2;
124 print F "PROXY=" . ($settings{'PROXY'} eq 'on' ? "Y\n" : "N\n");
125 print F "PASSWORD=$settings{'PASSWORD'}\n";
126 print F "NAT=N\n";
127 print F "LOGIN=$settings{'LOGIN'}\n";
128 print F "INTERVAL=1\n";
129 if ($settings{'HOSTNAME'} !~ s/$General::noipprefix//) {
130 print F "HOSTNAME=$settings{'HOSTNAME'}\n";
131 print F "GROUP=\n";
132 } else {
133 print F "HOSTNAME=\n";
134 print F "GROUP=$settings{'HOSTNAME'}\n";
135 }
136 print F "DOMAIN=$settings{'DOMAIN'}\n";
137 print F "DEVICE=\n";
138 print F "DAEMON=N\n";
139 close(F);
140
141 my @ddnscommand = ('/usr/bin/noip','-c',"${General::swroot}/ddns/noipsettings",'-i',"$ip");
142
143 my $result = system(@ddnscommand);
144 if ( $result != 0) {
145 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure");
146 } else {
147 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
148 $success++;
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 'enom') {
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 if ($settings{'HOSTNAME'} eq '') {
249 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
250 } else {
251 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
252 }
253
254 my ($out, $response) = Net::SSLeay::get_http( 'dynamic.name-services.com',
255 80,
256 "/interface.asp?Command=SetDNSHost&Zone=$settings{'DOMAIN'}&DomainPassword=$settings{'PASSWORD'}&Address=$ip",
257 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
258 );
259
260 if ($response =~ m%HTTP/1\.. 200 OK%) {
261 #Valid responses from update => ErrCount=0
262 if ( $out !~ m/ErrCount=0/ ) {
263 $out =~ s/(\n|\x0D)/ /g;
264 $out =~ /Err1=([\w ]+) /;
265 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($1)");
266 } else {
267 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
268 $success++;
269 }
270 } else {
271 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
272 }
273 }
274 elsif ($settings{'SERVICE'} eq 'nsupdate') {
275 # Fetch UI configurable values and assemble the host name.
276
277 my $hostName="$settings{'DOMAIN'}";
278 if ($settings{'HOSTNAME'} ne "") {
279 $hostName="$settings{'HOSTNAME'}.$hostName";
280 }
281 my $keyName=$settings{'LOGIN'};
282 my $keySecret=$settings{'PASSWORD'};
283
284 # Use a relatively long TTL value to reduce load on DNS.
285 # Some public Dynamic DNS servers use values around 4 hours,
286 # some use values as low as 60 seconds.
287 # XXX Maybe we could fetch the master value from the server
288 # (not the timed-down version supplied by DNS cache)
289
290 my $timeToLive="3600";
291
292 # Internal setting that can be used to override the DNS server
293 # where the update is applied. It can be of use when testing
294 # against a private DNS server.
295
296 my $masterServer="";
297
298 # Prepare the nsupdate command script to remove and re-add the
299 # updated A record for the domain.
300
301 my $cmdFile="/tmp/nsupdate-$hostName-commands";
302 my $logFile="/tmp/nsupdate-$hostName-result";
303 open(TF, ">$cmdFile");
304 if ($masterServer ne "") {
305 print TF "server $masterServer\n";
306 }
307 if ($keyName ne "" && $keySecret ne "") {
308 print TF "key $keyName $keySecret\n";
309 }
310 print TF "update delete $hostName A\n";
311 print TF "update add $hostName $timeToLive A $ip\n";
312 print TF "send\n";
313 close(TF);
314
315 # Run nsupdate with -v to use TCP instead of UDP because we're
316 # issuing multiple cmds and potentially long keys, and -d to
317 # get diagnostic result output.
318
319 my $result = system("/usr/bin/nsupdate -v -d $cmdFile 2>$logFile");
320 if ($result != 0) {
321 &General::log("Dynamic DNS ip-update for $hostName : failure");
322 open(NSLOG, "$logFile");
323 my @nsLog = <NSLOG>;
324 close(NSLOG);
325 my $logLine;
326 foreach $logLine (@nsLog) {
327 chomp($logLine);
328 if ($logLine ne "") {
329 &General::log("... $logLine");
330 }
331 }
332 } else {
333 &General::log("Dynamic DNS ip-update for $hostName : success");
334 $success++;
335 }
336 unlink $cmdFile, $logFile;
337 }
338 elsif ($settings{'SERVICE'} eq 'freedns') {
339 # use proxy ?
340 my %proxysettings;
341 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
342 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
343 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
344 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
345 }
346
347 my ($out, $response) = Net::SSLeay::get_https( 'freedns.afraid.org',
348 443,
349 "/dynamic/update.php?$settings{'LOGIN'}",
350 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
351 );
352 #Valid responses from service are:
353 #Updated n host(s) <domain>
354 #ERROR: <ip> has not changed.
355 if ($response =~ m%HTTP/1\.. 200 OK%) {
356 #Valid responses from update => ErrCount=0
357 if ( $out !~ m/(^Updated|Address .* has not changed)/ig ) {
358 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out)");
359 } else {
360 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
361 $success++;
362 }
363 } else {
364 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
365 }
366 }
367 elsif ($settings{'SERVICE'} eq 'regfish') {
368 # use proxy ?
369 my %proxysettings;
370 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
371 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
372 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
373 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
374 }
375
376
377 my ($out, $response) = Net::SSLeay::get_https( 'www.regfish.com',
378 443,
379 "/dyndns/2/?fqdn=$settings{'DOMAIN'}&ipv4=$ip&forcehost=1&authtype=secure&token=$settings{'LOGIN'}",
380 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
381 );
382 #Valid responses from service are:
383 #success|100|update succeeded!
384 #success|101|no update needed at this time..
385 if ($response =~ m%HTTP/1\.. 200 OK%) {
386 if ( $out !~ m/(success\|(100|101)\|)/ig ) {
387 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure ($out)");
388 } else {
389 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : success");
390 $success++;
391 }
392 } else {
393 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure (could not connect to server)");
394 }
395 }
396 elsif ($settings{'SERVICE'} eq 'ovh') {
397 my %proxysettings;
398 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
399
400 my $peer = 'www.ovh.com';
401 my $peerport = 80;
402
403 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
404 ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
405 }
406
407 my $sock;
408 unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
409 &General::log("Dynamic DNS failure : could not connect to $peer:$peerport: $@");
410 next;
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 ($GET_CMD, $code64);
420 $GET_CMD = "GET http://www.ovh.com/nic/update?system=dyndns&hostname=$settings{'HOSTDOMAIN'}&myip=$ip HTTP/1.1\r\n";
421 $GET_CMD .= "Host: www.ovh.com\r\n";
422 chomp($code64 = encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}"));
423 $GET_CMD .= "Authorization: Basic $code64\r\n";
424 $GET_CMD .= "User-Agent: ipfire\r\n";
425 #$GET_CMD .= "Content-Type: application/x-www-form-urlencoded\r\n";
426 $GET_CMD .= "\r\n";
427 print $sock "$GET_CMD";
428
429 my $out = '';
430 while(<$sock>) {
431 $out .= $_;
432 }
433 close($sock);
434
435 #HTTP response => error (in Title tag) else text response
436 #Valid responses from service:good,nochg (ez-ipupdate like)
437 #Should use ez-ipdate but "system=dyndns" is not present
438 if ( $out =~ m/<Title>(.*)<\/Title>/ig ) {
439 &General::log("Dynamic DNS ovh.com : failure ($1)");
440 }
441 elsif ($out !~ m/good |nochg /ig) {
442 $out =~ s/.+?\015?\012\015?\012//s; # header HTTP
443 my @out = split("\r", $out);
444 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure ($out[1])");
445 } else {
446 &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : success");
447 $success++;
448 }
449 }
450 elsif ($settings{'SERVICE'} eq 'dtdns') {
451 # use proxy ?
452 my %proxysettings;
453 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
454 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
455 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
456 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
457 }
458
459 if ($settings{'HOSTNAME'} eq '') {
460 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
461 } else {
462 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
463 }
464
465 my ($out, $response) = Net::SSLeay::get_http( 'www.dtdns.com',
466 80,
467 "/api/autodns.cfm?id=$settings{'HOSTDOMAIN'}&pw=$settings{'PASSWORD'}",
468 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
469 );
470 #Valid responses from service are:
471 # now points to
472 #
473 if ($response =~ m%HTTP/1\.. 200 OK%) {
474 if ( $out !~ m/Host .* now points to/ig ) {
475 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
476 } else {
477 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
478 $success++;
479 }
480 } else {
481 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");
482 }
483 }
484 elsif ($settings{'SERVICE'} eq 'dynu') {
485 # use proxy ?
486 my %proxysettings;
487 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
488 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
489 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
490 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
491 }
492
493 if ($settings{'HOSTNAME'} eq '') {
494 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
495 } else {
496 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
497 }
498
499 my ($out, $response) = Net::SSLeay::get_http( 'dynserv.ca',
500 80,
501 "/dyn/dynengine.cgi?func=set&name=$settings{'LOGIN'}&pass=$settings{'PASSWORD'}&ip=$ip&domain=$settings{'DOMAIN'}",
502 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
503 );
504 #Valid responses from service are:
505 # 02 == Domain already exists, refreshing data for ... => xxx.xxx.xxx.xxx
506 #
507 if ($response =~ m%HTTP/1\.. 200 OK%) {
508 if ( $out !~ m/Domain already exists, refreshing data for/ig ) {
509 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
510 } else {
511 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
512 $success++;
513 }
514 } else {
515 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");
516 }
517 } else {
518 if ($settings{'WILDCARDS'} eq 'on') {
519 $settings{'WILDCARDS'} = '-w';
520 } else {
521 $settings{'WILDCARDS'} = '';
522 }
523
524 if (($settings{'SERVICE'} eq 'dyndns-custom' ||
525 $settings{'SERVICE'} eq 'easydns' ||
526 $settings{'SERVICE'} eq 'zoneedit') && $settings{'HOSTNAME'} eq '') {
527 $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
528 } else {
529 $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
530 }
531
532 my @ddnscommand = ('/usr/bin/ez-ipupdate', '-a', "$ip", '-S', "$settings{'SERVICE'}", '-u', "$settings{'LOGIN'}:$settings{'PASSWORD'}", '-h', "$settings{'HOSTDOMAIN'}", "$settings{'WILDCARDS'}", '-q');
533
534 my $result = system(@ddnscommand);
535 if ( $result != 0) {
536 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: failure");
537 } else {
538 &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: success");
539 $success++;
540 }
541 }
542 } else {
543 # If a line is disabled, then we should discount it
544 $lines--;
545 }
546 }
547
548 if ($lines == $success) {
549 open(IPCACHE, ">$cachefile");
550 flock IPCACHE, 2;
551 print IPCACHE $ip;
552 close(IPCACHE);
553 exit 1;
554 }
555
556 }
557 exit 0;
558
559 # Extracted from Base64.pm
560 sub encode_base64 ($;$) {
561 my $res = "";
562 my $eol = $_[1];
563 $eol = "\n" unless defined $eol;
564 pos($_[0]) = 0; # ensure start at the beginning
565 while ($_[0] =~ /(.{1,45})/gs) {
566 $res .= substr(pack('u', $1), 1);
567 chop($res);
568 }
569 $res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs
570 # fix padding at the end
571 my $padding = (3 - length($_[0]) % 3) % 3;
572 $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
573 # break encoded string into lines of no more than 76 characters each
574 if (length $eol) {
575 $res =~ s/(.{1,76})/$1$eol/g;
576 }
577 $res;
578 }
579
580
581
582 __END__
583 old code for selfhost.de
584
585 my %proxysettings;
586 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
587
588 my $peer = 'carol.selfhost.de';
589 my $peerport = 80;
590
591 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
592 ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
593 }
594
595 my $sock;
596 unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
597 die "Could not connect to $peer:$peerport: $@";
598 return 1;
599 }
600
601 my $GET_CMD;
602 $GET_CMD = "GET https://carol.selfhost.de/update?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&myip=$ip&textmodi=1 HTTP/1.1\r\n";
603 $GET_CMD .= "Host: carol.selfhost.de\r\n";
604 $GET_CMD .= "User-Agent: ipfire\r\n";
605 $GET_CMD .= "Connection: close\r\n\r\n";
606 print $sock "$GET_CMD";
607
608 my $out = '';
609 while(<$sock>) {
610 $out .= $_;
611 }
612 close($sock);
613
614 if ( $out !~ m/status=(200|204)/ ) {
615 #cleanup http response...
616 $out =~ s/.+?\015?\012\015?\012//s; # header HTTP
617 my @out = split("\r", $out);
618 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out[1])");
619 } else {
620 &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
621 $success++;
622 }
623
624
625