-#!/usr/bin/perl\r
-#\r
-# SmoothWall CGIs\r
-#\r
-# This code is distributed under the terms of the GPL\r
-#\r
-# (c) The SmoothWall Team\r
-#\r
-# $Id: setddns.pl,v 1.4.2.32 2006/02/07 01:29:47 franck78 Exp $\r
-#\r
-\r
-#close(STDIN);\r
-#close(STDOUT);\r
-#close(STDERR);\r
-\r
-use strict;\r
-use IO::Socket;\r
-use Net::SSLeay;\r
-\r
-require '/var/ipcop/general-functions.pl';\r
-\r
-#Prototypes functions\r
-sub encode_base64 ($;$);\r
-\r
-my %settings;\r
-my $filename = "${General::swroot}/ddns/config";\r
-my $cachefile = "${General::swroot}/ddns/ipcache";\r
-my $ipcache = 0;\r
-my @current = ();\r
-\r
-if (open(FILE, "$filename")) {\r
- @current = <FILE>;\r
- close(FILE);\r
- unless(@current) { \r
- exit 0; \r
- }\r
-} else {\r
- &General::log('Dynamic DNS failure : unable to open config file.');\r
- exit 0;\r
-}\r
-\r
-&General::readhash("${General::swroot}/ddns/settings", \%settings);\r
-\r
-# ignore monthly update if not in minimize update mode\r
-exit 0 if (($settings{'MINIMIZEUPDATES'} ne 'on') && ($ARGV[1] eq '-m'));\r
-\r
-my $ip;\r
-if (open(IP, "${General::swroot}/red/local-ipaddress")) {\r
- $ip = <IP>;\r
- close(IP);\r
- chomp $ip;\r
-} else {\r
- &General::log('Dynamic DNS failure : unable to open local-ipaddress file.');\r
- exit 0;\r
-}\r
-\r
-#If IP is reserved network, we are behind a router. May we ask for our real public IP ?\r
-if ( &General::IpInSubnet ($ip,'10.0.0.0','255.0.0.0') ||\r
- &General::IpInSubnet ($ip,'172.16.0.0','255.240.0.0') ||\r
- &General::IpInSubnet ($ip,'192.168.0.0','255.255.0.0')) {\r
- # We can, but are we authorized by GUI ?\r
- if ($settings{'BEHINDROUTER'} eq 'FETCH_IP') {\r
- if ($ARGV[0] eq '-f'){\r
- $settings{'BEHINDROUTERWAITLOOP'} = -1; # When forced option, fectch PublicIP now\r
- }\r
-\r
- # Increment counter modulo 4. When it is zero, fetch ip else exit\r
- # This divides by 4 the requests to the dyndns server.\r
- $settings{'BEHINDROUTERWAITLOOP'} = ($settings{'BEHINDROUTERWAITLOOP'}+1) %4;\r
- &General::writehash("${General::swroot}/ddns/settings", \%settings);\r
- exit 0 if ( $settings{'BEHINDROUTERWAITLOOP'} ne 0 );\r
- my $RealIP = &General::FetchPublicIp;\r
- $ip = (&General::validip ($RealIP) ? $RealIP : 'unavailable');\r
- &General::log ("Dynamic DNS public router IP is:$ip");\r
- }\r
-}\r
-\r
-\r
-if ($ARGV[0] eq '-f') {\r
- unlink ($cachefile); # next regular calls will try again if this force update fails.\r
-} else {\r
- open(IPCACHE, "$cachefile");\r
- $ipcache = <IPCACHE>;\r
- close(IPCACHE);\r
- chomp $ipcache;\r
-}\r
-\r
-if ($ip ne $ipcache) {\r
- my $id = 0;\r
- my $success = 0;\r
- my $line;\r
- my $lines = @current;\r
-\r
- foreach $line (@current) {\r
- $id++;\r
- chomp($line);\r
- my @temp = split(/\,/,$line);\r
- unless ($temp[7] ne "on") {\r
- $settings{'SERVICE'} = $temp[0];\r
- $settings{'HOSTNAME'} = $temp[1];\r
- $settings{'DOMAIN'} = $temp[2];\r
- $settings{'PROXY'} = $temp[3];\r
- $settings{'WILDCARDS'} = $temp[4];\r
- $settings{'LOGIN'} = $temp[5];\r
- $settings{'PASSWORD'} = $temp[6];\r
- $settings{'ENABLED'} = $temp[7];\r
-\r
- #Some connection are very stable (more than 40 days). Finally force\r
- #one update / month to avoid account lost\r
- #cron call once/week with -f & once/month with -f -m options\r
- #minimize update ?\r
- if ( ($settings{'MINIMIZEUPDATES'} eq 'on') && ($ARGV[1] ne '-m') ) {\r
- if (General::DyndnsServiceSync($ip, $settings{'HOSTNAME'},$settings{'DOMAIN'})) {\r
- &General::log ("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} is uptodate [$ip]");\r
- $success++;\r
- next; # do not update, go to test next service\r
- }\r
- }\r
- my @service = split(/\./, "$settings{'SERVICE'}");\r
- $settings{'SERVICE'} = "$service[0]";\r
- if ($settings{'SERVICE'} eq 'no-ip') {\r
- open(F, ">${General::swroot}/ddns/noipsettings");\r
- flock F, 2;\r
- print F "PROXY=" . ($settings{'PROXY'} eq 'on' ? "Y\n" : "N\n");\r
- print F "PASSWORD=$settings{'PASSWORD'}\n";\r
- print F "NAT=N\n";\r
- print F "LOGIN=$settings{'LOGIN'}\n";\r
- print F "INTERVAL=1\n";\r
- if ($settings{'HOSTNAME'} !~ s/$General::noipprefix//) {\r
- print F "HOSTNAME=$settings{'HOSTNAME'}\n";\r
- print F "GROUP=\n";\r
- } else {\r
- print F "HOSTNAME=\n";\r
- print F "GROUP=$settings{'HOSTNAME'}\n";\r
- }\r
- print F "DOMAIN=$settings{'DOMAIN'}\n";\r
- print F "DEVICE=\n";\r
- print F "DAEMON=N\n";\r
- close(F);\r
-\r
- my @ddnscommand = ('/usr/bin/noip','-c',"${General::swroot}/ddns/noipsettings",'-i',"$ip");\r
-\r
- my $result = system(@ddnscommand);\r
- if ( $result != 0) { \r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure");\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");\r
- $success++;\r
- }\r
- }\r
-\r
- elsif ($settings{'SERVICE'} eq 'cjb') {\r
- # use proxy ?\r
- my %proxysettings;\r
- &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);\r
- if ($_=$proxysettings{'UPSTREAM_PROXY'}) {\r
- my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);\r
- Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );\r
- }\r
-\r
- my ($out, $response) = Net::SSLeay::get_http( 'www.cjb.net',\r
- 80,\r
- "/cgi-bin/dynip.cgi?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&ip=$ip",\r
- Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )\r
- );\r
-\r
- if ($response =~ m%HTTP/1\.. 200 OK%) {\r
- if ( $out !~ m/has been updated to point to/ ) {\r
- &General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : failure (bad password or login)");\r
- } else {\r
- &General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : success");\r
- $success++;\r
- }\r
- } else {\r
- &General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : failure (could not connect to server)");\r
- }\r
- }\r
- elsif ($settings{'SERVICE'} eq 'selfhost') {\r
- # use proxy ?\r
- my %proxysettings;\r
- &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);\r
- if ($_=$proxysettings{'UPSTREAM_PROXY'}) {\r
- my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);\r
- Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );\r
- }\r
-\r
- my ($out, $response) = Net::SSLeay::get_https( 'carol.selfhost.de',\r
- 443,\r
- "/update?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&textmodi=1",\r
- Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )\r
- );\r
-\r
- if ($response =~ m%HTTP/1\.. 200 OK%) {\r
- if ( $out !~ m/status=(200|204)/ ) {\r
- $out =~ s/\n/ /g;\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out)");\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");\r
- $success++;\r
- }\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");\r
- }\r
- }\r
- elsif ($settings{'SERVICE'} eq 'dnspark') {\r
- # use proxy ?\r
- my %proxysettings;\r
- &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);\r
- if ($_=$proxysettings{'UPSTREAM_PROXY'}) {\r
- my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);\r
- Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );\r
- }\r
-\r
- if ($settings{'HOSTNAME'} eq '') {\r
- $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};\r
- } else {\r
- $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";\r
- }\r
-\r
- my ($out, $response) = Net::SSLeay::get_https( "www.dnspark.net",\r
- 443,\r
- "/api/dynamic/update.php?hostname=$settings{'HOSTDOMAIN'}&ip=$ip",\r
- Net::SSLeay::make_headers('User-Agent' => 'Ipcop',\r
- 'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")\r
- )\r
- );\r
- # Valid response are 'ok' 'nochange'\r
- if ($response =~ m%HTTP/1\.. 200 OK%) {\r
- if ( $out !~ m/^(ok|nochange)/ ) {\r
- $out =~ s/\n/ /g;\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");\r
- $success++;\r
- }\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials)");\r
- }\r
- }\r
- elsif ($settings{'SERVICE'} eq 'enom') {\r
- # use proxy ?\r
- my %proxysettings;\r
- &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);\r
- if ($_=$proxysettings{'UPSTREAM_PROXY'}) {\r
- my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);\r
- Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );\r
- }\r
- if ($settings{'HOSTNAME'} eq '') {\r
- $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};\r
- } else {\r
- $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";\r
- }\r
-\r
- my ($out, $response) = Net::SSLeay::get_http( 'dynamic.name-services.com',\r
- 80,\r
- "/interface.asp?Command=SetDNSHost&Zone=$settings{'DOMAIN'}&DomainPassword=$settings{'PASSWORD'}&Address=$ip",\r
- Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )\r
- );\r
-\r
- if ($response =~ m%HTTP/1\.. 200 OK%) {\r
- #Valid responses from update => ErrCount=0\r
- if ( $out !~ m/ErrCount=0/ ) {\r
- $out =~ s/(\n|\x0D)/ /g;\r
- $out =~ /Err1=([\w ]+) /;\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($1)");\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");\r
- $success++;\r
- }\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");\r
- }\r
- }\r
- elsif ($settings{'SERVICE'} eq 'nsupdate') {\r
- # Fetch UI configurable values and assemble the host name.\r
-\r
- my $hostName="$settings{'DOMAIN'}";\r
- if ($settings{'HOSTNAME'} ne "") {\r
- $hostName="$settings{'HOSTNAME'}.$hostName";\r
- }\r
- my $keyName=$settings{'LOGIN'};\r
- my $keySecret=$settings{'PASSWORD'};\r
-\r
- # Use a relatively long TTL value to reduce load on DNS.\r
- # Some public Dynamic DNS servers use values around 4 hours,\r
- # some use values as low as 60 seconds.\r
- # XXX Maybe we could fetch the master value from the server\r
- # (not the timed-down version supplied by DNS cache)\r
-\r
- my $timeToLive="3600";\r
-\r
- # Internal setting that can be used to override the DNS server\r
- # where the update is applied. It can be of use when testing\r
- # against a private DNS server.\r
- \r
- my $masterServer="";\r
-\r
- # Prepare the nsupdate command script to remove and re-add the\r
- # updated A record for the domain.\r
-\r
- my $cmdFile="/tmp/nsupdate-$hostName-commands";\r
- my $logFile="/tmp/nsupdate-$hostName-result";\r
- open(TF, ">$cmdFile");\r
- if ($masterServer ne "") {\r
- print TF "server $masterServer\n";\r
- }\r
- if ($keyName ne "" && $keySecret ne "") {\r
- print TF "key $keyName $keySecret\n";\r
- }\r
- print TF "update delete $hostName A\n";\r
- print TF "update add $hostName $timeToLive A $ip\n";\r
- print TF "send\n";\r
- close(TF);\r
-\r
- # Run nsupdate with -v to use TCP instead of UDP because we're\r
- # issuing multiple cmds and potentially long keys, and -d to\r
- # get diagnostic result output.\r
-\r
- my $result = system("/usr/bin/nsupdate -v -d $cmdFile 2>$logFile");\r
- if ($result != 0) {\r
- &General::log("Dynamic DNS ip-update for $hostName : failure");\r
- open(NSLOG, "$logFile");\r
- my @nsLog = <NSLOG>;\r
- close(NSLOG);\r
- my $logLine;\r
- foreach $logLine (@nsLog) {\r
- chomp($logLine);\r
- if ($logLine ne "") {\r
- &General::log("... $logLine");\r
- }\r
- }\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $hostName : success");\r
- $success++;\r
- }\r
- unlink $cmdFile, $logFile;\r
- }\r
- elsif ($settings{'SERVICE'} eq 'freedns') {\r
- # use proxy ?\r
- my %proxysettings;\r
- &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);\r
- if ($_=$proxysettings{'UPSTREAM_PROXY'}) {\r
- my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);\r
- Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );\r
- }\r
-\r
- my ($out, $response) = Net::SSLeay::get_https( 'freedns.afraid.org',\r
- 443,\r
- "/dynamic/update.php?$settings{'LOGIN'}",\r
- Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )\r
- );\r
- #Valid responses from service are:\r
- #Updated n host(s) <domain>\r
- #ERROR: <ip> has not changed.\r
- if ($response =~ m%HTTP/1\.. 200 OK%) {\r
- #Valid responses from update => ErrCount=0\r
- if ( $out !~ m/(^Updated|Address .* has not changed)/ig ) {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out)");\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");\r
- $success++;\r
- }\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");\r
- }\r
- }\r
- elsif ($settings{'SERVICE'} eq 'regfish') {\r
- # use proxy ?\r
- my %proxysettings;\r
- &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);\r
- if ($_=$proxysettings{'UPSTREAM_PROXY'}) {\r
- my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);\r
- Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );\r
- }\r
-\r
-\r
- my ($out, $response) = Net::SSLeay::get_https( 'www.regfish.com',\r
- 443,\r
- "/dyndns/2/?fqdn=$settings{'DOMAIN'}&ipv4=$ip&forcehost=1&authtype=secure&token=$settings{'LOGIN'}",\r
- Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )\r
- );\r
- #Valid responses from service are:\r
- #success|100|update succeeded!\r
- #success|101|no update needed at this time..\r
- if ($response =~ m%HTTP/1\.. 200 OK%) {\r
- if ( $out !~ m/(success\|(100|101)\|)/ig ) {\r
- &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure ($out)");\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : success");\r
- $success++;\r
- }\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure (could not connect to server)");\r
- }\r
- }\r
- elsif ($settings{'SERVICE'} eq 'ovh') {\r
- my %proxysettings;\r
- &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);\r
-\r
- my $peer = 'www.ovh.com';\r
- my $peerport = 80;\r
-\r
- if ($_=$proxysettings{'UPSTREAM_PROXY'}) {\r
- ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);\r
- }\r
-\r
- my $sock;\r
- unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {\r
- &General::log("Dynamic DNS failure : could not connect to $peer:$peerport: $@");\r
- next;\r
- }\r
-\r
- if ($settings{'HOSTNAME'} eq '') {\r
- $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};\r
- } else {\r
- $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";\r
- }\r
-\r
- my ($GET_CMD, $code64);\r
- $GET_CMD = "GET http://www.ovh.com/nic/update?system=dyndns&hostname=$settings{'HOSTDOMAIN'}&myip=$ip HTTP/1.1\r\n";\r
- $GET_CMD .= "Host: www.ovh.com\r\n";\r
- chomp($code64 = encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}"));\r
- $GET_CMD .= "Authorization: Basic $code64\r\n";\r
- $GET_CMD .= "User-Agent: ipcop\r\n";\r
- #$GET_CMD .= "Content-Type: application/x-www-form-urlencoded\r\n";\r
- $GET_CMD .= "\r\n";\r
- print $sock "$GET_CMD";\r
- \r
- my $out = '';\r
- while(<$sock>) {\r
- $out .= $_;\r
- }\r
- close($sock);\r
-\r
- #HTTP response => error (in Title tag) else text response\r
- #Valid responses from service:good,nochg (ez-ipupdate like)\r
- #Should use ez-ipdate but "system=dyndns" is not present\r
- if ( $out =~ m/<Title>(.*)<\/Title>/ig ) {\r
- &General::log("Dynamic DNS ovh.com : failure ($1)");\r
- }\r
- elsif ($out !~ m/good |nochg /ig) {\r
- $out =~ s/.+?\015?\012\015?\012//s; # header HTTP\r
- my @out = split("\r", $out);\r
- &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure ($out[1])");\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : success");\r
- $success++;\r
- }\r
- }\r
- elsif ($settings{'SERVICE'} eq 'dtdns') {\r
- # use proxy ?\r
- my %proxysettings;\r
- &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);\r
- if ($_=$proxysettings{'UPSTREAM_PROXY'}) {\r
- my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);\r
- Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );\r
- }\r
-\r
- if ($settings{'HOSTNAME'} eq '') {\r
- $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};\r
- } else {\r
- $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";\r
- }\r
-\r
- my ($out, $response) = Net::SSLeay::get_http( 'www.dtdns.com',\r
- 80,\r
- "/api/autodns.cfm?id=$settings{'HOSTDOMAIN'}&pw=$settings{'PASSWORD'}",\r
- Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )\r
- );\r
- #Valid responses from service are:\r
- # now points to\r
- #\r
- if ($response =~ m%HTTP/1\.. 200 OK%) {\r
- if ( $out !~ m/Host .* now points to/ig ) {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");\r
- $success++;\r
- }\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");\r
- }\r
- }\r
- elsif ($settings{'SERVICE'} eq 'dynu') {\r
- # use proxy ?\r
- my %proxysettings;\r
- &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);\r
- if ($_=$proxysettings{'UPSTREAM_PROXY'}) {\r
- my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);\r
- Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );\r
- }\r
-\r
- if ($settings{'HOSTNAME'} eq '') {\r
- $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};\r
- } else {\r
- $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";\r
- }\r
-\r
- my ($out, $response) = Net::SSLeay::get_http( 'dynserv.ca',\r
- 80,\r
- "/dyn/dynengine.cgi?func=set&name=$settings{'LOGIN'}&pass=$settings{'PASSWORD'}&ip=$ip&domain=$settings{'DOMAIN'}",\r
- Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )\r
- );\r
- #Valid responses from service are:\r
- # 02 == Domain already exists, refreshing data for ... => xxx.xxx.xxx.xxx\r
- #\r
- if ($response =~ m%HTTP/1\.. 200 OK%) {\r
- if ( $out !~ m/Domain already exists, refreshing data for/ig ) {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");\r
- $success++;\r
- }\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");\r
- }\r
- } else {\r
- if ($settings{'WILDCARDS'} eq 'on') {\r
- $settings{'WILDCARDS'} = '-w';\r
- } else {\r
- $settings{'WILDCARDS'} = '';\r
- }\r
-\r
- if (($settings{'SERVICE'} eq 'dyndns-custom' ||\r
- $settings{'SERVICE'} eq 'easydns' || \r
- $settings{'SERVICE'} eq 'zoneedit') && $settings{'HOSTNAME'} eq '') {\r
- $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};\r
- } else {\r
- $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";\r
- }\r
-\r
- my @ddnscommand = ('/usr/bin/ez-ipupdate', '-a', "$ip", '-S', "$settings{'SERVICE'}", '-u', "$settings{'LOGIN'}:$settings{'PASSWORD'}", '-h', "$settings{'HOSTDOMAIN'}", "$settings{'WILDCARDS'}", '-q');\r
-\r
- my $result = system(@ddnscommand);\r
- if ( $result != 0) { \r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: failure");\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: success");\r
- $success++;\r
- }\r
- }\r
- } else {\r
- # If a line is disabled, then we should discount it\r
- $lines--;\r
- }\r
- }\r
-\r
- if ($lines == $success) {\r
- open(IPCACHE, ">$cachefile");\r
- flock IPCACHE, 2;\r
- print IPCACHE $ip;\r
- close(IPCACHE);\r
- exit 1;\r
- }\r
- \r
-}\r
-exit 0;\r
-\r
-# Extracted from Base64.pm\r
-sub encode_base64 ($;$) {\r
- my $res = "";\r
- my $eol = $_[1];\r
- $eol = "\n" unless defined $eol;\r
- pos($_[0]) = 0; # ensure start at the beginning\r
- while ($_[0] =~ /(.{1,45})/gs) {\r
- $res .= substr(pack('u', $1), 1);\r
- chop($res);\r
- }\r
- $res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs\r
- # fix padding at the end\r
- my $padding = (3 - length($_[0]) % 3) % 3;\r
- $res =~ s/.{$padding}$/'=' x $padding/e if $padding;\r
- # break encoded string into lines of no more than 76 characters each\r
- if (length $eol) {\r
- $res =~ s/(.{1,76})/$1$eol/g;\r
- }\r
- $res;\r
-}\r
-\r
-\r
-\r
-__END__\r
-old code for selfhost.de\r
-\r
- my %proxysettings;\r
- &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);\r
-\r
- my $peer = 'carol.selfhost.de';\r
- my $peerport = 80;\r
-\r
- if ($_=$proxysettings{'UPSTREAM_PROXY'}) {\r
- ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);\r
- }\r
-\r
- my $sock;\r
- unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {\r
- die "Could not connect to $peer:$peerport: $@";\r
- return 1;\r
- }\r
-\r
- my $GET_CMD;\r
- $GET_CMD = "GET https://carol.selfhost.de/update?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&myip=$ip&textmodi=1 HTTP/1.1\r\n";\r
- $GET_CMD .= "Host: carol.selfhost.de\r\n";\r
- $GET_CMD .= "User-Agent: ipcop\r\n";\r
- $GET_CMD .= "Connection: close\r\n\r\n";\r
- print $sock "$GET_CMD";\r
-\r
- my $out = '';\r
- while(<$sock>) {\r
- $out .= $_;\r
- }\r
- close($sock);\r
-\r
- if ( $out !~ m/status=(200|204)/ ) {\r
- #cleanup http response...\r
- $out =~ s/.+?\015?\012\015?\012//s; # header HTTP\r
- my @out = split("\r", $out);\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out[1])");\r
- } else {\r
- &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");\r
- $success++;\r
- }\r
-\r
-\r
- \r
+#!/usr/bin/perl
+#
+# SmoothWall CGIs
+#
+# This code is distributed under the terms of the GPL
+#
+# (c) The SmoothWall Team
+#
+# $Id: setddns.pl,v 1.4.2.32 2006/02/07 01:29:47 franck78 Exp $
+#
+
+#close(STDIN);
+#close(STDOUT);
+#close(STDERR);
+
+use strict;
+use IO::Socket;
+use Net::SSLeay;
+
+require '/var/ipfire/general-functions.pl';
+
+#Prototypes functions
+sub encode_base64 ($;$);
+
+my %settings;
+my $filename = "${General::swroot}/ddns/config";
+my $cachefile = "${General::swroot}/ddns/ipcache";
+my $ipcache = 0;
+my @current = ();
+
+if (open(FILE, "$filename")) {
+ @current = <FILE>;
+ close(FILE);
+ unless(@current) {
+ exit 0;
+ }
+} else {
+ &General::log('Dynamic DNS failure : unable to open config file.');
+ exit 0;
+}
+
+&General::readhash("${General::swroot}/ddns/settings", \%settings);
+
+# ignore monthly update if not in minimize update mode
+exit 0 if (($settings{'MINIMIZEUPDATES'} ne 'on') && ($ARGV[1] eq '-m'));
+
+my $ip;
+if (open(IP, "${General::swroot}/red/local-ipaddress")) {
+ $ip = <IP>;
+ close(IP);
+ chomp $ip;
+} else {
+ &General::log('Dynamic DNS failure : unable to open local-ipaddress file.');
+ exit 0;
+}
+
+#If IP is reserved network, we are behind a router. May we ask for our real public IP ?
+if ( &General::IpInSubnet ($ip,'10.0.0.0','255.0.0.0') ||
+ &General::IpInSubnet ($ip,'172.16.0.0','255.240.0.0') ||
+ &General::IpInSubnet ($ip,'192.168.0.0','255.255.0.0')) {
+ # We can, but are we authorized by GUI ?
+ if ($settings{'BEHINDROUTER'} eq 'FETCH_IP') {
+ if ($ARGV[0] eq '-f'){
+ $settings{'BEHINDROUTERWAITLOOP'} = -1; # When forced option, fectch PublicIP now
+ }
+
+ # Increment counter modulo 4. When it is zero, fetch ip else exit
+ # This divides by 4 the requests to the dyndns server.
+ $settings{'BEHINDROUTERWAITLOOP'} = ($settings{'BEHINDROUTERWAITLOOP'}+1) %4;
+ &General::writehash("${General::swroot}/ddns/settings", \%settings);
+ exit 0 if ( $settings{'BEHINDROUTERWAITLOOP'} ne 0 );
+ my $RealIP = &General::FetchPublicIp;
+ $ip = (&General::validip ($RealIP) ? $RealIP : 'unavailable');
+ &General::log ("Dynamic DNS public router IP is:$ip");
+ }
+}
+
+
+if ($ARGV[0] eq '-f') {
+ unlink ($cachefile); # next regular calls will try again if this force update fails.
+} else {
+ open(IPCACHE, "$cachefile");
+ $ipcache = <IPCACHE>;
+ close(IPCACHE);
+ chomp $ipcache;
+}
+
+if ($ip ne $ipcache) {
+ my $id = 0;
+ my $success = 0;
+ my $line;
+ my $lines = @current;
+
+ foreach $line (@current) {
+ $id++;
+ chomp($line);
+ my @temp = split(/\,/,$line);
+ unless ($temp[7] ne "on") {
+ $settings{'SERVICE'} = $temp[0];
+ $settings{'HOSTNAME'} = $temp[1];
+ $settings{'DOMAIN'} = $temp[2];
+ $settings{'PROXY'} = $temp[3];
+ $settings{'WILDCARDS'} = $temp[4];
+ $settings{'LOGIN'} = $temp[5];
+ $settings{'PASSWORD'} = $temp[6];
+ $settings{'ENABLED'} = $temp[7];
+
+ #Some connection are very stable (more than 40 days). Finally force
+ #one update / month to avoid account lost
+ #cron call once/week with -f & once/month with -f -m options
+ #minimize update ?
+ if ( ($settings{'MINIMIZEUPDATES'} eq 'on') && ($ARGV[1] ne '-m') ) {
+ if (General::DyndnsServiceSync($ip, $settings{'HOSTNAME'},$settings{'DOMAIN'})) {
+ &General::log ("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} is uptodate [$ip]");
+ $success++;
+ next; # do not update, go to test next service
+ }
+ }
+ my @service = split(/\./, "$settings{'SERVICE'}");
+ $settings{'SERVICE'} = "$service[0]";
+ if ($settings{'SERVICE'} eq 'no-ip') {
+ open(F, ">${General::swroot}/ddns/noipsettings");
+ flock F, 2;
+ print F "PROXY=" . ($settings{'PROXY'} eq 'on' ? "Y\n" : "N\n");
+ print F "PASSWORD=$settings{'PASSWORD'}\n";
+ print F "NAT=N\n";
+ print F "LOGIN=$settings{'LOGIN'}\n";
+ print F "INTERVAL=1\n";
+ if ($settings{'HOSTNAME'} !~ s/$General::noipprefix//) {
+ print F "HOSTNAME=$settings{'HOSTNAME'}\n";
+ print F "GROUP=\n";
+ } else {
+ print F "HOSTNAME=\n";
+ print F "GROUP=$settings{'HOSTNAME'}\n";
+ }
+ print F "DOMAIN=$settings{'DOMAIN'}\n";
+ print F "DEVICE=\n";
+ print F "DAEMON=N\n";
+ close(F);
+
+ my @ddnscommand = ('/usr/bin/noip','-c',"${General::swroot}/ddns/noipsettings",'-i',"$ip");
+
+ my $result = system(@ddnscommand);
+ if ( $result != 0) {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure");
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
+ $success++;
+ }
+ }
+
+ elsif ($settings{'SERVICE'} eq 'cjb') {
+ # use proxy ?
+ my %proxysettings;
+ &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
+ if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
+ my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
+ Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
+ }
+
+ my ($out, $response) = Net::SSLeay::get_http( 'www.cjb.net',
+ 80,
+ "/cgi-bin/dynip.cgi?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&ip=$ip",
+ Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )
+ );
+
+ if ($response =~ m%HTTP/1\.. 200 OK%) {
+ if ( $out !~ m/has been updated to point to/ ) {
+ &General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : failure (bad password or login)");
+ } else {
+ &General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : success");
+ $success++;
+ }
+ } else {
+ &General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : failure (could not connect to server)");
+ }
+ }
+ elsif ($settings{'SERVICE'} eq 'selfhost') {
+ # use proxy ?
+ my %proxysettings;
+ &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
+ if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
+ my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
+ Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
+ }
+
+ my ($out, $response) = Net::SSLeay::get_https( 'carol.selfhost.de',
+ 443,
+ "/update?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&textmodi=1",
+ Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )
+ );
+
+ if ($response =~ m%HTTP/1\.. 200 OK%) {
+ if ( $out !~ m/status=(200|204)/ ) {
+ $out =~ s/\n/ /g;
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out)");
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
+ $success++;
+ }
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
+ }
+ }
+ elsif ($settings{'SERVICE'} eq 'dnspark') {
+ # use proxy ?
+ my %proxysettings;
+ &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
+ if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
+ my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
+ Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
+ }
+
+ if ($settings{'HOSTNAME'} eq '') {
+ $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
+ } else {
+ $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
+ }
+
+ my ($out, $response) = Net::SSLeay::get_https( "www.dnspark.net",
+ 443,
+ "/api/dynamic/update.php?hostname=$settings{'HOSTDOMAIN'}&ip=$ip",
+ Net::SSLeay::make_headers('User-Agent' => 'Ipcop',
+ 'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")
+ )
+ );
+ # Valid response are 'ok' 'nochange'
+ if ($response =~ m%HTTP/1\.. 200 OK%) {
+ if ( $out !~ m/^(ok|nochange)/ ) {
+ $out =~ s/\n/ /g;
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
+ $success++;
+ }
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials)");
+ }
+ }
+ elsif ($settings{'SERVICE'} eq 'enom') {
+ # use proxy ?
+ my %proxysettings;
+ &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
+ if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
+ my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
+ Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
+ }
+ if ($settings{'HOSTNAME'} eq '') {
+ $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
+ } else {
+ $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
+ }
+
+ my ($out, $response) = Net::SSLeay::get_http( 'dynamic.name-services.com',
+ 80,
+ "/interface.asp?Command=SetDNSHost&Zone=$settings{'DOMAIN'}&DomainPassword=$settings{'PASSWORD'}&Address=$ip",
+ Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )
+ );
+
+ if ($response =~ m%HTTP/1\.. 200 OK%) {
+ #Valid responses from update => ErrCount=0
+ if ( $out !~ m/ErrCount=0/ ) {
+ $out =~ s/(\n|\x0D)/ /g;
+ $out =~ /Err1=([\w ]+) /;
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($1)");
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
+ $success++;
+ }
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
+ }
+ }
+ elsif ($settings{'SERVICE'} eq 'nsupdate') {
+ # Fetch UI configurable values and assemble the host name.
+
+ my $hostName="$settings{'DOMAIN'}";
+ if ($settings{'HOSTNAME'} ne "") {
+ $hostName="$settings{'HOSTNAME'}.$hostName";
+ }
+ my $keyName=$settings{'LOGIN'};
+ my $keySecret=$settings{'PASSWORD'};
+
+ # Use a relatively long TTL value to reduce load on DNS.
+ # Some public Dynamic DNS servers use values around 4 hours,
+ # some use values as low as 60 seconds.
+ # XXX Maybe we could fetch the master value from the server
+ # (not the timed-down version supplied by DNS cache)
+
+ my $timeToLive="3600";
+
+ # Internal setting that can be used to override the DNS server
+ # where the update is applied. It can be of use when testing
+ # against a private DNS server.
+
+ my $masterServer="";
+
+ # Prepare the nsupdate command script to remove and re-add the
+ # updated A record for the domain.
+
+ my $cmdFile="/tmp/nsupdate-$hostName-commands";
+ my $logFile="/tmp/nsupdate-$hostName-result";
+ open(TF, ">$cmdFile");
+ if ($masterServer ne "") {
+ print TF "server $masterServer\n";
+ }
+ if ($keyName ne "" && $keySecret ne "") {
+ print TF "key $keyName $keySecret\n";
+ }
+ print TF "update delete $hostName A\n";
+ print TF "update add $hostName $timeToLive A $ip\n";
+ print TF "send\n";
+ close(TF);
+
+ # Run nsupdate with -v to use TCP instead of UDP because we're
+ # issuing multiple cmds and potentially long keys, and -d to
+ # get diagnostic result output.
+
+ my $result = system("/usr/bin/nsupdate -v -d $cmdFile 2>$logFile");
+ if ($result != 0) {
+ &General::log("Dynamic DNS ip-update for $hostName : failure");
+ open(NSLOG, "$logFile");
+ my @nsLog = <NSLOG>;
+ close(NSLOG);
+ my $logLine;
+ foreach $logLine (@nsLog) {
+ chomp($logLine);
+ if ($logLine ne "") {
+ &General::log("... $logLine");
+ }
+ }
+ } else {
+ &General::log("Dynamic DNS ip-update for $hostName : success");
+ $success++;
+ }
+ unlink $cmdFile, $logFile;
+ }
+ elsif ($settings{'SERVICE'} eq 'freedns') {
+ # use proxy ?
+ my %proxysettings;
+ &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
+ if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
+ my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
+ Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
+ }
+
+ my ($out, $response) = Net::SSLeay::get_https( 'freedns.afraid.org',
+ 443,
+ "/dynamic/update.php?$settings{'LOGIN'}",
+ Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )
+ );
+ #Valid responses from service are:
+ #Updated n host(s) <domain>
+ #ERROR: <ip> has not changed.
+ if ($response =~ m%HTTP/1\.. 200 OK%) {
+ #Valid responses from update => ErrCount=0
+ if ( $out !~ m/(^Updated|Address .* has not changed)/ig ) {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out)");
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
+ $success++;
+ }
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
+ }
+ }
+ elsif ($settings{'SERVICE'} eq 'regfish') {
+ # use proxy ?
+ my %proxysettings;
+ &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
+ if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
+ my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
+ Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
+ }
+
+
+ my ($out, $response) = Net::SSLeay::get_https( 'www.regfish.com',
+ 443,
+ "/dyndns/2/?fqdn=$settings{'DOMAIN'}&ipv4=$ip&forcehost=1&authtype=secure&token=$settings{'LOGIN'}",
+ Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )
+ );
+ #Valid responses from service are:
+ #success|100|update succeeded!
+ #success|101|no update needed at this time..
+ if ($response =~ m%HTTP/1\.. 200 OK%) {
+ if ( $out !~ m/(success\|(100|101)\|)/ig ) {
+ &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure ($out)");
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : success");
+ $success++;
+ }
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure (could not connect to server)");
+ }
+ }
+ elsif ($settings{'SERVICE'} eq 'ovh') {
+ my %proxysettings;
+ &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
+
+ my $peer = 'www.ovh.com';
+ my $peerport = 80;
+
+ if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
+ ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
+ }
+
+ my $sock;
+ unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
+ &General::log("Dynamic DNS failure : could not connect to $peer:$peerport: $@");
+ next;
+ }
+
+ if ($settings{'HOSTNAME'} eq '') {
+ $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
+ } else {
+ $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
+ }
+
+ my ($GET_CMD, $code64);
+ $GET_CMD = "GET http://www.ovh.com/nic/update?system=dyndns&hostname=$settings{'HOSTDOMAIN'}&myip=$ip HTTP/1.1\r\n";
+ $GET_CMD .= "Host: www.ovh.com\r\n";
+ chomp($code64 = encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}"));
+ $GET_CMD .= "Authorization: Basic $code64\r\n";
+ $GET_CMD .= "User-Agent: ipcop\r\n";
+ #$GET_CMD .= "Content-Type: application/x-www-form-urlencoded\r\n";
+ $GET_CMD .= "\r\n";
+ print $sock "$GET_CMD";
+
+ my $out = '';
+ while(<$sock>) {
+ $out .= $_;
+ }
+ close($sock);
+
+ #HTTP response => error (in Title tag) else text response
+ #Valid responses from service:good,nochg (ez-ipupdate like)
+ #Should use ez-ipdate but "system=dyndns" is not present
+ if ( $out =~ m/<Title>(.*)<\/Title>/ig ) {
+ &General::log("Dynamic DNS ovh.com : failure ($1)");
+ }
+ elsif ($out !~ m/good |nochg /ig) {
+ $out =~ s/.+?\015?\012\015?\012//s; # header HTTP
+ my @out = split("\r", $out);
+ &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure ($out[1])");
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : success");
+ $success++;
+ }
+ }
+ elsif ($settings{'SERVICE'} eq 'dtdns') {
+ # use proxy ?
+ my %proxysettings;
+ &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
+ if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
+ my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
+ Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
+ }
+
+ if ($settings{'HOSTNAME'} eq '') {
+ $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
+ } else {
+ $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
+ }
+
+ my ($out, $response) = Net::SSLeay::get_http( 'www.dtdns.com',
+ 80,
+ "/api/autodns.cfm?id=$settings{'HOSTDOMAIN'}&pw=$settings{'PASSWORD'}",
+ Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )
+ );
+ #Valid responses from service are:
+ # now points to
+ #
+ if ($response =~ m%HTTP/1\.. 200 OK%) {
+ if ( $out !~ m/Host .* now points to/ig ) {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
+ $success++;
+ }
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");
+ }
+ }
+ elsif ($settings{'SERVICE'} eq 'dynu') {
+ # use proxy ?
+ my %proxysettings;
+ &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
+ if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
+ my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
+ Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
+ }
+
+ if ($settings{'HOSTNAME'} eq '') {
+ $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
+ } else {
+ $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
+ }
+
+ my ($out, $response) = Net::SSLeay::get_http( 'dynserv.ca',
+ 80,
+ "/dyn/dynengine.cgi?func=set&name=$settings{'LOGIN'}&pass=$settings{'PASSWORD'}&ip=$ip&domain=$settings{'DOMAIN'}",
+ Net::SSLeay::make_headers('User-Agent' => 'Ipcop' )
+ );
+ #Valid responses from service are:
+ # 02 == Domain already exists, refreshing data for ... => xxx.xxx.xxx.xxx
+ #
+ if ($response =~ m%HTTP/1\.. 200 OK%) {
+ if ( $out !~ m/Domain already exists, refreshing data for/ig ) {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
+ $success++;
+ }
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");
+ }
+ } else {
+ if ($settings{'WILDCARDS'} eq 'on') {
+ $settings{'WILDCARDS'} = '-w';
+ } else {
+ $settings{'WILDCARDS'} = '';
+ }
+
+ if (($settings{'SERVICE'} eq 'dyndns-custom' ||
+ $settings{'SERVICE'} eq 'easydns' ||
+ $settings{'SERVICE'} eq 'zoneedit') && $settings{'HOSTNAME'} eq '') {
+ $settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
+ } else {
+ $settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
+ }
+
+ my @ddnscommand = ('/usr/bin/ez-ipupdate', '-a', "$ip", '-S', "$settings{'SERVICE'}", '-u', "$settings{'LOGIN'}:$settings{'PASSWORD'}", '-h', "$settings{'HOSTDOMAIN'}", "$settings{'WILDCARDS'}", '-q');
+
+ my $result = system(@ddnscommand);
+ if ( $result != 0) {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: failure");
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: success");
+ $success++;
+ }
+ }
+ } else {
+ # If a line is disabled, then we should discount it
+ $lines--;
+ }
+ }
+
+ if ($lines == $success) {
+ open(IPCACHE, ">$cachefile");
+ flock IPCACHE, 2;
+ print IPCACHE $ip;
+ close(IPCACHE);
+ exit 1;
+ }
+
+}
+exit 0;
+
+# Extracted from Base64.pm
+sub encode_base64 ($;$) {
+ my $res = "";
+ my $eol = $_[1];
+ $eol = "\n" unless defined $eol;
+ pos($_[0]) = 0; # ensure start at the beginning
+ while ($_[0] =~ /(.{1,45})/gs) {
+ $res .= substr(pack('u', $1), 1);
+ chop($res);
+ }
+ $res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs
+ # fix padding at the end
+ my $padding = (3 - length($_[0]) % 3) % 3;
+ $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
+ # break encoded string into lines of no more than 76 characters each
+ if (length $eol) {
+ $res =~ s/(.{1,76})/$1$eol/g;
+ }
+ $res;
+}
+
+
+
+__END__
+old code for selfhost.de
+
+ my %proxysettings;
+ &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
+
+ my $peer = 'carol.selfhost.de';
+ my $peerport = 80;
+
+ if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
+ ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
+ }
+
+ my $sock;
+ unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
+ die "Could not connect to $peer:$peerport: $@";
+ return 1;
+ }
+
+ my $GET_CMD;
+ $GET_CMD = "GET https://carol.selfhost.de/update?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&myip=$ip&textmodi=1 HTTP/1.1\r\n";
+ $GET_CMD .= "Host: carol.selfhost.de\r\n";
+ $GET_CMD .= "User-Agent: ipcop\r\n";
+ $GET_CMD .= "Connection: close\r\n\r\n";
+ print $sock "$GET_CMD";
+
+ my $out = '';
+ while(<$sock>) {
+ $out .= $_;
+ }
+ close($sock);
+
+ if ( $out !~ m/status=(200|204)/ ) {
+ #cleanup http response...
+ $out =~ s/.+?\015?\012\015?\012//s; # header HTTP
+ my @out = split("\r", $out);
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out[1])");
+ } else {
+ &General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
+ $success++;
+ }
+
+
+