From e2c3f9dd04de8490551379df930f93dbfa2e0f59 Mon Sep 17 00:00:00 2001 From: John Crisp Date: Thu, 2 Jul 2020 15:18:12 +0200 Subject: [PATCH] Add support for dinahosting Fixes #203 --- ChangeLog.md | 1 + README.md | 1 + ddclient.conf.in | 8 +++++ ddclient.in | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 5a5ad5f..c4d1f56 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -9,6 +9,7 @@ repository history](https://github.com/ddclient/ddclient/commits/master). * Added support for OVH DynHost. * Added support for ClouDNS. + * Added support for dinahosting. * Added a build system to make it easier for distributions to package ddclient: diff --git a/README.md b/README.md index f640252..c97e8c0 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Dynamic DNS services currently supported include: NearlyFreeSpeech.net - See https://www.nearlyfreespeech.net/services/dns for details OVH - See https://www.ovh.com for details ClouDNS - See https://www.cloudns.net + dinahosting - See https://dinahosting.com DDclient now supports many of cable/dsl broadband routers. diff --git a/ddclient.conf.in b/ddclient.conf.in index d1ef2a1..7c4e6cd 100644 --- a/ddclient.conf.in +++ b/ddclient.conf.in @@ -283,3 +283,11 @@ ssl=yes # use ssl-support. Works with # protocol=cloudns, \ # dynurl=https://ipv4.cloudns.net/api/dynamicURL/?q=Njc1OTE2OjY3Njk0NDM6YTk2, \ # myhost.example.com + +## +## dinahosting (https://dinahosting.com) +## +# protocol=dinahosting, \ +# login=myusername, \ +# password=mypassword \ +# myhost.mydomain.com diff --git a/ddclient.in b/ddclient.in index c2a25da..51bde20 100755 --- a/ddclient.in +++ b/ddclient.in @@ -466,6 +466,17 @@ my %services = ( 'password' => setv(T_STRING, 0, 0, 'unused', undef), }, }, + 'dinahosting' => { + 'updateable' => undef, + 'update' => \&nic_dinahosting_update, + 'examples' => \&nic_dinahosting_examples, + 'variables' => { + %{$variables{'service-common-defaults'}}, + 'min-error-interval' => setv(T_DELAY, 0, 0, interval('8m'), 0), + 'script' => setv(T_STRING, 0, 1, '/special/api.php', undef), + 'server' => setv(T_FQDNP, 1, 0, 'dinahosting.com', undef), + }, + }, 'dnsmadeeasy' => { 'updateable' => undef, 'update' => \&nic_dnsmadeeasy_update, @@ -5051,6 +5062,73 @@ sub nic_cloudns_update { } } +###################################################################### +## nic_dinahosting_examples +###################################################################### +sub nic_dinahosting_examples { + return <<"EoEXAMPLE"; +o 'dinahosting' + +The 'dinahosting' protocol is used by dinahosting (https://dinahosting.com). +Details about the API can be found at https://dinahosting.com/api. + +Available configuration variables and their defaults: + * login (required) is your username. + * password (required) is your password. + * server=dinahosting.com is the hostname part of the dinahosting API URL. + * script=/special/api.php is the path part of the dinahosting API URL. + +Example ${program}.conf file entry: + protocol=dinahosting, \\ + login=myusername, \\ + password=mypassword \\ + myhost.mydomain.com +EoEXAMPLE +} + +###################################################################### +## nic_dinahosting_update +###################################################################### +sub nic_dinahosting_update { + debug("\nnic_dinahosting_update -------------------"); + for my $h (@_) { + my $ip = delete $config{$h}{'wantip'}; + info("setting IP address to %s for %s", $ip, $h); + verbose("UPDATE:", "updating %s", $h); + my ($hostname, $domain) = split(/\./, $h, 2); + my $url = "https://$config{$h}{'server'}$config{$h}{'script'}"; + $url .= "?hostname=$hostname"; + $url .= "&domain=$domain"; + $url .= "&command=Domain_Zone_UpdateType" . is_ipv6($ip) ? 'AAAA' : 'A'; + $url .= "&ip=$ip"; + my $reply = geturl({ + proxy => opt('proxy'), + login => $config{$h}{'login'}, + password => $config{$h}{'password'}, + url => $url, + }); + $config{$h}{'status'} = 'failed'; # assume failure until otherwise determined + if (!$reply) { + failed("updating %s: failed to visit URL %s", $h, $url); + next; + } + next if !header_ok($h, $reply); + $reply =~ s/^.*?\n\n//s; # Strip the headers. + if ($reply !~ /Success/i) { + $reply =~ /^responseCode = (\d+)$/m; + my $code = $1 // ''; + $reply =~ /^errors_0_message = '(.*)'$/m; + my $message = $1 // ''; + failed("updating %s: error %d: %s", $code, $message); + next; + } + $config{$h}{'ip'} = $ip; + $config{$h}{'mtime'} = $now; + $config{$h}{'status'} = 'good'; + success("updating %s: IP address set to %s", $h, $ip); + } +} + # Execute main() if this file is run as a script or run via PAR (https://metacpan.org/pod/PAR), # otherwise do nothing. This "modulino" pattern makes it possible to import this file as a module # and test its functions directly; there's no need for test-only command-line arguments or stdout