Add dnsexit support (based on #52) (#311)

* Patch in dnsexit support

Based on patch from here https://sourceforge.net/p/ddclient/discussion/399428/thread/04e23ee6/ hacked back in.

* dnsexit: check for valid responses that mean 'failure' (from @truesalo)

Co-authored-by: sreknob <sreknob@hotmail.com>
This commit is contained in:
Reuben Thomas 2021-05-12 20:45:28 +01:00 committed by GitHub
parent b84f2334e4
commit f0270e4940
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 133 additions and 0 deletions

View file

@ -32,6 +32,7 @@ Dynamic DNS services currently supported include:
ClouDNS - See https://www.cloudns.net
dinahosting - See https://dinahosting.com
Gandi - See https://gandi.net
dnsexit - See https://dnsexit.com/ for details
DDclient now supports many of cable/dsl broadband routers.

View file

@ -302,3 +302,10 @@ ssl=yes # use ssl-support. Works with
# login=myusername, \
# password=mypassword \
# myhost.mydomain.com
## dnsexit (www.dnsexit.com)
##
#protocol=dnsexit, \
#login=myusername, \
#password=mypassword, \
#subdomain-1.domain.com,subdomain-2.domain.com

View file

@ -523,6 +523,12 @@ my %variables = (
'static' => setv(T_BOOL, 0, 1, 0, undef),
'wildcard' => setv(T_BOOL, 0, 1, 0, undef),
},
'dnsexit-common-defaults' => {
'ssl' => setv(T_BOOL, 0, 0, 0, undef),
'server' => setv(T_FQDNP, 1, 0, 'update.dnsexit.com', undef),
'script' => setv(T_STRING, 0, 1, '/RemoteUpdate.sv', undef),
'min-error-interval' => setv(T_DELAY, 0, 0, interval('8m'), 0),
},
);
my %services = (
'changeip' => {
@ -820,6 +826,15 @@ my %services = (
'zone' => setv(T_OFQDN, 0, 0, undef, undef),
},
},
'dnsexit' => {
'updateable' => undef,
'update' => \&nic_dnsexit_update,
'examples' => \&nic_dnsexit_examples,
'variables' => merge(
$variables{'dnsexit-common-defaults'},
$variables{'service-common-defaults'},
),
},
);
$variables{'merged'} = {
map({ %{$services{$_}{'variables'}} } keys(%services)),
@ -4040,7 +4055,117 @@ sub nic_dyndns2_update {
}
}
######################################################################
## nic_dnsexit_examples
######################################################################
sub nic_dnsexit_examples {
return <<"EoEXAMPLE";
o 'dnsexit'
The 'dnsexit' protocol is the protocol used by the dynamic hostname services
of the 'DnsExit' dns services. This is currently used by the free
dynamic DNS service offered by www.dnsexit.com.
Configuration variables applicable to the 'dnsexit' protocol are:
ssl=no ## turn off ssl
protocol=dnsexit ##
server=update.dnsexit.com ## defaults to update.dnsexit.com
use=web ## defaults to web
web=update.dnsexit.com ## defaults to update.dnsexit.com
script=/RemoteUpdate.sv ## defaults to /RemoteUpdate.sv
login=service-userid ## userid registered with the service
password=service-password ## password registered with the service
fully.qualified.host ## the host registered with the service.
Example ${program}.conf file entries:
## single host update
protocol=dnsexit \\
login=service-userid \\
password=service-password \\
fully.qualified.host
EoEXAMPLE
}
######################################################################
## nic_dnsexit_update
##
## written by Gonzalo Pérez de Olaguer Córdoba <salo@gpoc.es>
##
## based on https://www.dnsexit.com/Direct.sv?cmd=ipClients
## fetches this URL to update:
## https://update.dnsexit.com/RemoteUpdate.sv?login=yourlogin&password=yourpassword&
## host=yourhost.yourdomain.com&myip=xxx.xx.xx.xxx
##
######################################################################
sub nic_dnsexit_update {
debug("\nnic_dnsexit_update -------------------");
my %status = (
'0' => [ 'good', 'Success' ],
'1' => [ 'nochg', 'IP is the same as the IP on the system' ],
'2' => [ 'badauth', 'Invalid password' ],
'3' => [ 'badauth', 'User not found' ],
'4' => [ 'nochg', 'IP not changed. To save our system resources, please don\'t post updates unless the IP got changed.' ],
'10' => [ 'error', 'Hostname is not specified' ],
'11' => [ 'nohost', 'fail to find the domain' ],
'13' => [ 'error', 'parameter validation error' ],
);
## update each configured host
foreach my $h (@_) {
my $ip = delete $config{$h}{'wantip'};
info("setting IP address to %s for %s", $ip, $h);
verbose("UPDATE:","updating %s", $h);
# Set the URL that we're going to update
my $url;
$url = "https://$config{$h}{'server'}$config{$h}{'script'}";
$url .= "?login=$config{$h}{'login'}";
$url .= "&password=$config{$h}{'password'}";
$url .= "&host=$h";
$url .= "&myip=";
$url .= $ip if $ip;
# Try to get URL
my $reply = geturl(
proxy => opt('proxy'),
url => $url
);
# No response, declare as failed
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'});
last;
}
last if !header_ok($h, $reply);
# Response found
if ($reply =~ /(\d+)=(.+)/) {
my ($statuscode, $statusmsg) = ($1, $2);
if (exists $status{$statuscode}) {
my ($status, $message) = @{ $status{$statuscode} };
if ($status =~ m'^(good|nochg)$') {
$config{$h}{'ip'} = $ip;
$config{$h}{'mtime'} = $now;
}
$config{$h}{'status'} = $status;
if ($status eq 'good') {
success("updating %s: good: IP address set to %s", $h, $ip);
} else {
warning("updating %s: %s: %s", $h, $status, $message);
}
} else {
$config{$h}{'status'} = 'failed';
failed("updating %s: failed: unrecognized status code (%s)", $h, $statuscode);
}
} else {
$config{$h}{'status'} = 'failed';
warning("SENT: %s", $url) unless opt('verbose');
warning("REPLIED: %s", $reply);
failed("updating %s: unrecognized reply.", $h);
}
}
}
######################################################################
## nic_noip_update
## Note: uses same features as nic_dyndns2_update, less return codes