]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - html/cgi-bin/ddns.cgi
aliases.cgi: Use new system methods
[people/pmueller/ipfire-2.x.git] / html / cgi-bin / ddns.cgi
index 7be9a50f073bd64560560204efb749014ef386fb..7e4ddb5b78e9891e44530265ab794ae3a31a4a21 100644 (file)
@@ -20,6 +20,7 @@
 ###############################################################################
 
 use strict;
+use experimental 'smartmatch';
 
 # enable only the following on debugging purpose
 #use warnings;
@@ -36,7 +37,7 @@ undef (@dummy);
 my %color = ();
 my %mainsettings = ();
 &General::readhash("${General::swroot}/main/settings", \%mainsettings);
-&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
+&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color);
 
 # Config file for basic configuration.
 my $settingsfile = "${General::swroot}/ddns/settings";
@@ -44,10 +45,8 @@ my $settingsfile = "${General::swroot}/ddns/settings";
 # Config file to store the configured ddns providers.
 my $datafile = "${General::swroot}/ddns/config";
 
-# Dynamic ddns programm call.
-my @ddnsprog = ("/usr/bin/ddns", "--config",
-               "/var/ipfire/ddns/ddns.conf",
-               "update-all");
+# Call the ddnsctrl helper binary to perform the update.
+my @ddnsprog = ("/usr/local/bin/ddnsctrl", "update-all");
 
 my %settings=();
 my $errormessage = '';
@@ -60,14 +59,18 @@ $settings{'HOSTNAME'} = '';
 $settings{'DOMAIN'} = '';
 $settings{'LOGIN'} = '';
 $settings{'PASSWORD'} = '';
+$settings{'TOKEN'} = '';
 $settings{'ENABLED'} = '';
 $settings{'PROXY'} = '';
 $settings{'SERVICE'} = '';
 
 $settings{'ACTION'} = '';
 
-# Get supported ddns providers.
-my @providers = &GetProviders();
+# Get all supported ddns providers.
+my @providers = &GetProviders("all");
+
+# Get provider which support a token based authentication mechanism.
+my @token_provider = &GetProviders("token-providers");
 
 # Hook to regenerate the configuration files, if cgi got called from command line.
 if ($ENV{"REMOTE_ADDR"} eq "") {
@@ -89,7 +92,6 @@ close (FILE);
 # Save General Settings.
 #
 if ($settings{'ACTION'} eq $Lang::tr{'save'}) {
-
        # Open /var/ipfire/ddns/settings for writing.
        open(FILE, ">$settingsfile") or die "Unable to open $settingsfile.";
 
@@ -104,9 +106,6 @@ if ($settings{'ACTION'} eq $Lang::tr{'save'}) {
        # Close file after writing.
        close(FILE);
 
-       # Unset given CGI parmas.
-       undef %settings;
-
        # Update ddns config file.
        &GenerateDDNSConfigFile();
 }
@@ -115,7 +114,6 @@ if ($settings{'ACTION'} eq $Lang::tr{'save'}) {
 # Toggle enable/disable field.  Field is in second position
 #
 if ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
-
        # Open /var/ipfire/ddns/config for writing.
        open(FILE, ">$datafile") or die "Unable to open $datafile.";
 
@@ -127,23 +125,19 @@ if ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
 
        # Read file line by line.
        foreach my $line (@current) {
-
                # Remove newlines.
                chomp($line);
 
                if ($settings{'ID'} eq $id) {
-
                        # Splitt lines (splitting element is a single ",") and save values into temp array.
                        @temp = split(/\,/,$line);
 
                        # Check if we want to toggle ENABLED or WILDCARDS.
                        if ($settings{'ENABLED'} ne '') {
-
                                # Update ENABLED.
                                print FILE "$temp[0],$temp[1],$temp[2],$temp[3],$temp[4],$temp[5],$temp[6],$settings{'ENABLED'}\n";
                        }
                } else {
-
                        # Print unmodified line.
                        print FILE "$line\n";
                }
@@ -151,13 +145,11 @@ if ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
                # Increase $id.
                $id++;
        }
+       undef $settings{'ID'};
 
        # Close file after writing.
        close(FILE);
 
-       # Unset given CGI params.
-       undef %settings;
-
        # Write out logging notice.
        &General::log($Lang::tr{'ddns hostname modified'});
 
@@ -169,7 +161,6 @@ if ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
 # Add new accounts, or edit existing ones.
 #
 if (($settings{'ACTION'} eq $Lang::tr{'add'}) || ($settings{'ACTION'} eq $Lang::tr{'update'})) {
-
        # Check if a hostname has been given.
        if ($settings{'HOSTNAME'} eq '') {
                $errormessage = $Lang::tr{'hostname not set'};
@@ -187,19 +178,38 @@ if (($settings{'ACTION'} eq $Lang::tr{'add'}) || ($settings{'ACTION'} eq $Lang::
 
        # Check if a password has been typed in.
        # freedns.afraid.org does not require this field.
-       if (($settings{'PASSWORD'} eq '') && ($settings{'SERVICE'} ne 'freedns.afraid.org')) {
+       if (($settings{'PASSWORD'} eq '') && ($settings{'SERVICE'} ne 'freedns.afraid.org') && ($settings{'SERVICE'} ne 'regfish.com')) {
                $errormessage = $Lang::tr{'password not set'};
        }
 
-       # Go furter if there was no error.
-       if ( ! $errormessage) {
+       # Check if a token has been given for provider which support tokens.
+       if (($settings{'SERVICE'} ~~ @token_provider) && ($settings{'TOKEN'} eq '')) {
+               $errormessage = $Lang::tr{'token not set'};
+       }
 
+       # Go furter if there was no error.
+       if (!$errormessage) {
                # Splitt hostname field into 2 parts for storrage.
                my($hostname, $domain) = split(/\./, $settings{'HOSTNAME'}, 2);
 
+               # Handle enabled checkbox. When the checkbox is selected a "on" will be returned,
+               # if the checkbox is not checked nothing is returned in this case we set the value to "off".
+               if ($settings{'ENABLED'} ne 'on') {
+                       $settings{'ENABLED'} = 'off';
+               }
+
+               # Handle token provider.
+               if($settings{'SERVICE'} ~~ @token_provider) {
+                       # Clear username and password if they contain values.
+                       undef($settings{'LOGIN'});
+                       undef($settings{'PASSWORD'});
+
+                       # Assign the token as a password for saving.
+                       $settings{'PASSWORD'} = $settings{'TOKEN'};
+               }
+
                # Handle adding new accounts.
                if ($settings{'ACTION'} eq $Lang::tr{'add'}) {
-
                        # Open /var/ipfire/ddns/config for writing.
                        open(FILE, ">>$datafile") or die "Unable to open $datafile.";
 
@@ -215,11 +225,8 @@ if (($settings{'ACTION'} eq $Lang::tr{'add'}) || ($settings{'ACTION'} eq $Lang::
                        # Write out notice to logfile.
                        &General::log($Lang::tr{'ddns hostname added'});
 
-                       # Update ddns config file.
-
                # Handle account edditing.
                } elsif ($settings{'ACTION'} eq $Lang::tr{'update'}) {
-
                        # Open /var/ipfire/ddns/config for writing.
                        open(FILE, ">$datafile") or die "Unable to open $datafile.";
 
@@ -230,7 +237,6 @@ if (($settings{'ACTION'} eq $Lang::tr{'add'}) || ($settings{'ACTION'} eq $Lang::
 
                        # Read file line by line.
                        foreach my $line (@current) {
-
                                if ($settings{'ID'} eq $id) {
                                        print FILE "$settings{'SERVICE'},$hostname,$domain,$settings{'PROXY'},$settings{'WILDCARDS'},$settings{'LOGIN'},$settings{'PASSWORD'},$settings{'ENABLED'}\n";
                                } else {
@@ -247,9 +253,8 @@ if (($settings{'ACTION'} eq $Lang::tr{'add'}) || ($settings{'ACTION'} eq $Lang::
                        # Write out notice to logfile.
                        &General::log($Lang::tr{'ddns hostname modified'});
                }
-
-               # Unset given CGI params.
-               undef %settings;
+               # Clear settings hash.
+               %settings = '';
 
                # Update ddns config file.
                &GenerateDDNSConfigFile();
@@ -260,7 +265,6 @@ if (($settings{'ACTION'} eq $Lang::tr{'add'}) || ($settings{'ACTION'} eq $Lang::
 # Remove existing accounts.
 #
 if ($settings{'ACTION'} eq $Lang::tr{'remove'}) {
-
        # Open /var/ipfire/ddns/config for writing.
        open(FILE, ">$datafile") or die "Unable to open $datafile.";
 
@@ -271,7 +275,6 @@ if ($settings{'ACTION'} eq $Lang::tr{'remove'}) {
 
        # Read file line by line.
        foreach my $line (@current) {
-
                # Write back every line, except the one we want to drop
                # (identified by the ID)
                unless ($settings{'ID'} eq $id) {
@@ -281,13 +284,11 @@ if ($settings{'ACTION'} eq $Lang::tr{'remove'}) {
                # Increase id.
                $id++;
        }
+       undef $settings{'ID'};
 
        # Close file after writing.
        close(FILE);
 
-       # Unset given CGI params.
-       undef %settings;
-
        # Write out notice to logfile.
        &General::log($Lang::tr{'ddns hostname removed'});
 
@@ -299,33 +300,42 @@ if ($settings{'ACTION'} eq $Lang::tr{'remove'}) {
 # Read items for editing.
 #
 if ($settings{'ACTION'} eq $Lang::tr{'edit'}) {
-
        my $id = 0;
        my @temp;
 
        # Read file line by line.
        foreach my $line (@current) {
-
                if ($settings{'ID'} eq $id) {
-
                        # Remove newlines.
                        chomp($line);
 
                        # Splitt lines (splitting element is a single ",") and save values into temp array.
                        @temp = split(/\,/,$line);
 
+                       # Handle hostname details. Only connect the values with a dott if both are available.
+                       my $hostname;
+
+                       if (($temp[1]) && ($temp[2])) {
+                               $hostname = "$temp[1].$temp[2]";
+                       } else {
+                               $hostname = "$temp[1]";
+                       }
+
                        $settings{'SERVICE'} = $temp[0];
-                       $settings{'HOSTNAME'} = "$temp[1].$temp[2]";
+                       $settings{'HOSTNAME'} = $hostname;
                        $settings{'PROXY'} = $temp[3];
                        $settings{'WILDCARDS'} = $temp[4];
                        $settings{'LOGIN'} = $temp[5];
                        $settings{'PASSWORD'} = $temp[6];
+                       $settings{'TOKEN'} = $temp[6];
                        $settings{'ENABLED'} = $temp[7];
                }
-       # Increase $id.
-       $id++;
 
+               # Increase $id.
+               $id++;
        }
+
+       &GenerateDDNSConfigFile();
 }
 
 #
@@ -338,12 +348,65 @@ if ($settings{'ACTION'} eq $Lang::tr{'instant update'}) {
 #
 # Set default values.
 #
-if (! $settings{'ACTION'}) {
+if (!$settings{'ACTION'}) {
        $settings{'SERVICE'} = 'dyndns.org';
        $settings{'ENABLED'} = 'on';
+       $settings{'ID'} = '';
 }
 
 &Header::openpage($Lang::tr{'dynamic dns'}, 1, '');
+
+### Java Script ###
+print"<script>\n";
+
+# Generate Java Script Array which contains the provider that support token.
+my $line = "";
+$line = join("', '", @token_provider);
+
+print "\t// Array which contains the providers that support token.\n";
+print "\ttoken_provider = ['$line']\;\n\n";
+
+print <<END
+       // Java Script function to swap the text input fields for
+       // username and password or token.
+       var update_auth = function() {
+               if(inArray(\$('#SERVICE').val(), token_provider)) {
+                       \$('.username').hide();
+                       \$('.password').hide();
+                       \$('.token').show();
+               } else {
+                       \$('.username').show();
+                       \$('.password').show();
+                       \$('.token').hide();
+               }
+       };
+
+       // Java Script function to check if a given value is part of
+       // an array.
+       function inArray(value,array) {
+               var count=array.length;
+
+               for(var i=0;i<count;i++) {
+                       if(array[i]===value){
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
+       // JQuery function to call corresponding function when
+       // the service provider is changed or the page is loaded for showing/hiding
+       // the username/password or token area.
+       \$(document).ready(function() {
+               \$('#SERVICE').change(update_auth);
+                       update_auth();
+       });
+
+</script>
+END
+;
+
 &Header::openbigbox('100%', 'left', '', $errormessage);
 
 # Read file for general ddns settings.
@@ -354,7 +417,9 @@ $checked{'BEHINDROUTER'}{'RED_IP'} = '';
 $checked{'BEHINDROUTER'}{'FETCH_IP'} = '';
 $checked{'BEHINDROUTER'}{$settings{'BEHINDROUTER'}} = "checked='checked'";
 
-$checked{'ENABLED'}{'on'} = ($settings{'ENABLED'} eq '' ) ? '' : "checked='checked'";
+$checked{'ENABLED'}{'on'} = '';
+$checked{'ENABLED'}{'off'} = '';
+$checked{'ENABLED'}{$settings{'ENABLED'}} = "checked='checked'";
 
 # Show box for errormessages..
 if ($errormessage) {
@@ -404,18 +469,15 @@ my $buttontext = $Lang::tr{'add'};
 
 # Change buttontext and headline if we edit an account.
 if ($settings{'ACTION'} eq $Lang::tr{'edit'}) {
-
        # Rename button and print headline for updating.
        $buttontext = $Lang::tr{'update'};
        &Header::openbox('100%', 'left', $Lang::tr{'edit an existing host'});
 } else {
-
        # Otherwise use default button text and show headline for adding a new account.
        &Header::openbox('100%', 'left', $Lang::tr{'add a host'});
 }
 
 print <<END
-
 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
 <input type='hidden' name='ID' value='$settings{'ID'}' />
 <table width='100%'>
@@ -425,13 +487,12 @@ print <<END
 END
 ;
                # Generate dropdown menu for service selection.
-               print"<select size='1' name='SERVICE'>\n";
+               print"<select size='1' name='SERVICE' id='SERVICE'>\n";
 
                my $selected;
 
                # Loop to print the providerlist.
                foreach my $provider (@providers) {
-
                        # Check if the current provider needs to be selected.
                        if ($provider eq $settings{'SERVICE'}) {
                                $selected = 'selected';
@@ -451,12 +512,16 @@ print <<END
 
        <tr>
                <td class='base'>$Lang::tr{'enabled'}</td>
-               <td><input type='checkbox' name='ENABLED' value='on' $checked{'ENABLED'}{'on'} /></td>
-               <td class='base'>$Lang::tr{'username'}</td>
-               <td><input type='text' name='LOGIN' value='$settings{'LOGIN'}' /></td>
+               <td><input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>
+
+               <td class='username'>$Lang::tr{'username'}</td>
+               <td class='username'><input type='text' name='LOGIN' value='$settings{'LOGIN'}' /></td>
+
+               <td class='token' style='display:none'>$Lang::tr{'token'}</td>
+               <td class='token' style='display:none'><input type='text' name='TOKEN' value='$settings{'TOKEN'}' /></td>
        </tr>
 
-       <tr>
+       <tr class='password'>
                <td class='base'></td>
                <td></td>
                <td class='base'>$Lang::tr{'password'}</td>
@@ -507,17 +572,32 @@ END
                chomp(@current);
                my @temp = split(/\,/,$line);
 
+               # Handle hostname details. Only connect the values with a dott if both are available.
+               my $hostname="";
+
+               if (($temp[1]) && ($temp[2])) {
+                       $hostname="$temp[1].$temp[2]";
+               } else {
+                       $hostname="$temp[1]";
+               }
+
                # Generate value for enable/disable checkbox.
-               my $sync = "<font color='blue'>";
+               my $sync = '';
                my $gif = '';
                my $gdesc = '';
 
                if ($temp[7] eq "on") {
                        $gif = 'on.gif';
                        $gdesc = $Lang::tr{'click to disable'};
-                       $sync = (&General::DyndnsServiceSync ($ip,$temp[1], $temp[2]) ? "<font color='green'>": "<font color='red'>") ;
+
+                       # Check if the given hostname is a FQDN before doing a nslookup.
+                       if (&General::validfqdn($hostname)) {
+                               $sync = (&General::DyndnsServiceSync ($ip,$temp[1], $temp[2]) ? "<font color='green'>": "<font color='red'>") ;
+                       }
+
                        $toggle_enabled = 'off';
                } else {
+                       $sync = "<font color='blue'>";
                        $gif = 'off.gif';
                        $gdesc = $Lang::tr{'click to enable'};
                        $toggle_enabled = 'on';
@@ -536,11 +616,20 @@ END
                        $col="bgcolor='$color{'color22'}'";
                }
 
+               # Handle hostname details. Only connect the values with a dott if both are available.
+               my $hostname="";
+
+               if (($temp[1]) && ($temp[2])) {
+                       $hostname="$temp[1].$temp[2]";
+               } else {
+                       $hostname="$temp[1]";
+               }
+
                # The following HTML Code still is part of the loop.
                print <<END;
 <tr>
        <td align='center' $col><a href='http://$temp[0]'>$temp[0]</a></td>
-       <td align='center' $col>$sync$temp[1].$sync$temp[2]</td>
+       <td align='center' $col>$sync$hostname</td>
 
        <td align='center' $col><form method='post' action='$ENV{'SCRIPT_NAME'}'>
                <input type='hidden' name='ID' value='$id'>
@@ -630,6 +719,7 @@ sub GenerateDDNSConfigFile {
 
        while (<SETTINGS>) {
                my $line = $_;
+               chomp($line);
 
                # Generate array based on the line content (seperator is a single or multiple space's)
                my @settings = split(/,/, $line);
@@ -639,19 +729,26 @@ sub GenerateDDNSConfigFile {
                next unless ($provider ~~ @providers);
 
                # Skip disabled entries.
-               next if ($enabled eq "off");
+               next unless ($enabled eq "on");
+
+               # Handle hostname details. Only connect the values with a dott if both are available.
+               if (($hostname) && ($domain)) {
+                       print FILE "[$hostname.$domain]\n";
+               } else {
+                       print FILE "[$hostname]\n";
+               }
 
-               print FILE "[$hostname.$domain]\n";
                print FILE "provider = $provider\n";
 
                my $use_token = 0;
 
                # Handle token based auth for various providers.
-               if ($provider ~~ ["dns.lightningwirelabs.com", "entrydns.net", "regfish.com"] && $username eq "token") {
+               if ($provider ~~ @token_provider) {
                        $use_token = 1;
+               }
 
-               # Handle token auth for freedns.afraid.org.
-               } elsif ($provider eq "freedns.afraid.org" && $password eq "") {
+               # Handle token auth for freedns.afraid.org and regfish.com.
+               if ($provider ~~ ["freedns.afraid.org", "regfish.com"] && $password eq "") {
                        $use_token = 1;
                        $password = $username;
 
@@ -679,11 +776,6 @@ sub GenerateDDNSConfigFile {
                        print FILE "password = $password\n";
                }
 
-               # These providers need to be set to only use IPv4.
-               if ($provider ~~ ["freedns.afraid.org", "nsupdate.info", "opendns.com", "variomedia.de", "zoneedit.com"]) {
-                       print FILE "proto = ipv4\n";
-               }
-
                print FILE "\n";
        }
 
@@ -692,9 +784,20 @@ sub GenerateDDNSConfigFile {
 }
 
 # Function which generates an array (@providers) which contains the supported providers.
-sub GetProviders {
-       # Get supported providers.
-       open(PROVIDERS, "/usr/bin/ddns list-providers |");
+sub GetProviders ($) {
+       my ($type) = @_;
+
+       # Set default type to get all providers
+       $type = $type ? $type : "all";
+
+       # Check if the requested type is "token-providers".
+       if ($type eq "token-providers") {
+               # Call ddns util to only get providers which supports token based auth.
+               open(PROVIDERS, "/usr/bin/ddns list-token-providers |");
+       } else {
+               # Get all supported providers.
+               open(PROVIDERS, "/usr/bin/ddns list-providers |");
+       }
 
        # Create new array to store the providers.
        my @providers = ();