From 5e075681008174839a47cae698ae459c0ea3a30a Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Wed, 12 May 2021 19:59:01 +0200 Subject: [PATCH 01/16] Fix argsparse string for listing token providers. Signed-off-by: Stefan Schantl --- ddns.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ddns.in b/ddns.in index 538e4b0..20edd28 100755 --- a/ddns.in +++ b/ddns.in @@ -49,8 +49,8 @@ def main(): p_list_providers = subparsers.add_parser("list-providers", help=_("List all available providers")) - # list-token-provider - p_list_token_provider = subparsers.add_parser("list-token-provider", + # list-token-providers + p_list_token_provider = subparsers.add_parser("list-token-providers", help=_("List all providers which supports authentication via token")) # update -- 2.39.2 From a026b2734b73ef177686ab36c66743ae58bdef56 Mon Sep 17 00:00:00 2001 From: Jhon Crowley Date: Sun, 11 Jul 2021 11:36:37 +0200 Subject: [PATCH 02/16] Add support for he.net Signed-off-by: Jhon Crowley Signed-off-by: Stefan Schantl --- src/ddns/providers.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/ddns/providers.py b/src/ddns/providers.py index 56e6620..2f1804b 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -1218,6 +1218,22 @@ class DDNSProviderFreeDNSAfraidOrg(DDNSProvider): raise DDNSUpdateError +class DDNSProviderHENet(DDNSProtocolDynDNS2, DDNSProvider): + handle = "he.net" + name = "he.net" + website = "https://he.net" + protocols = ("ipv6", "ipv4",) + + # Detailed information about the update api can be found here. + # http://dns.he.net/docs.html + + url = "https://dyn.dns.he.net/nic/update" + @property + def username(self): + return self.get("hostname") + + + class DDNSProviderItsdns(DDNSProtocolDynDNS2, DDNSProvider): handle = "inwx.com" name = "INWX" -- 2.39.2 From e00128d37b22d4eae3823ca21bdbcbb8485fdac2 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 11 Jul 2021 23:47:32 +0200 Subject: [PATCH 03/16] noip.com: Use HTTPS to send requests Fixes #12658. Signed-off-by: Stefan Schantl --- src/ddns/providers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ddns/providers.py b/src/ddns/providers.py index 2f1804b..149eb65 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -1460,7 +1460,7 @@ class DDNSProviderNOIP(DDNSProtocolDynDNS2, DDNSProvider): # here: http://www.noip.com/integrate/request and # here: http://www.noip.com/integrate/response - url = "http://dynupdate.noip.com/nic/update" + url = "https://dynupdate.noip.com/nic/update" def prepare_request_data(self, proto): assert proto == "ipv4" -- 2.39.2 From 86aff9eac096c5c78c8274eca28df31b69880972 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Mon, 12 Jul 2021 12:33:09 +0200 Subject: [PATCH 04/16] All-inkl.com: Send request via HTTPS Signed-off-by: Stefan Schantl --- src/ddns/providers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ddns/providers.py b/src/ddns/providers.py index 149eb65..6a34759 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -446,7 +446,7 @@ class DDNSProviderAllInkl(DDNSProvider): # from the net. # http://all-inkl.goetze.it/v01/ddns-mit-einfachen-mitteln/ - url = "http://dyndns.kasserver.com" + url = "https://dyndns.kasserver.com" can_remove_records = False supports_token_auth = False -- 2.39.2 From aae1decec8243e8d97a927e3a3ac1d9cc1ff0351 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Mon, 12 Jul 2021 12:34:54 +0200 Subject: [PATCH 05/16] ddnss.de: Send request via HTTPS Signed-off-by: Stefan Schantl --- src/ddns/providers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ddns/providers.py b/src/ddns/providers.py index 6a34759..79db20a 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -626,7 +626,7 @@ class DDNSProviderDDNSS(DDNSProvider): # http://www.ddnss.de/info.php # http://www.megacomputing.de/2014/08/dyndns-service-response-time/#more-919 - url = "http://www.ddnss.de/upd.php" + url = "https://www.ddnss.de/upd.php" can_remove_records = False supports_token_auth = False -- 2.39.2 From d156590bb6668759d6511b315bf5604e84ae48e0 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Mon, 12 Jul 2021 12:35:51 +0200 Subject: [PATCH 06/16] dhs.org: Send request via HTTPS The provider only supports TLS 1.0 and TLS 1.1 but IMHO this is even better than sending the auth details as plain text. Signed-off-by: Stefan Schantl --- src/ddns/providers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ddns/providers.py b/src/ddns/providers.py index 79db20a..2a4c492 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -689,7 +689,8 @@ class DDNSProviderDHS(DDNSProvider): # No information about the used update api provided on webpage, # grabed from source code of ez-ipudate. - url = "http://members.dhs.org/nic/hosts" + # Provider currently does not support TLS 1.2. + url = "https://members.dhs.org/nic/hosts" can_remove_records = False supports_token_auth = False -- 2.39.2 From c0886a42d8839a8a32eb8e469a2bb1d8f0896ef3 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Mon, 12 Jul 2021 12:37:11 +0200 Subject: [PATCH 07/16] easydns.com: Send request via HTTPS Signed-off-by: Stefan Schantl --- src/ddns/providers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ddns/providers.py b/src/ddns/providers.py index 2a4c492..ca6792a 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -996,7 +996,7 @@ class DDNSProviderEasyDNS(DDNSProvider): # (API 1.3) are available on the providers webpage. # https://fusion.easydns.com/index.php?/Knowledgebase/Article/View/102/7/dynamic-dns - url = "http://api.cp.easydns.com/dyn/tomato.php" + url = "https://api.cp.easydns.com/dyn/tomato.php" supports_token_auth = False -- 2.39.2 From 7211a5cf0a264cc10377ea818088e6e765917aed Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Mon, 12 Jul 2021 12:38:07 +0200 Subject: [PATCH 08/16] domopoli.de: Send request via HTTPS The provider only supports TLS 1.0 and TLS 1.1 but IMHO this is even better than sending the auth details as plain text. Signed-off-by: Stefan Schantl --- src/ddns/providers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ddns/providers.py b/src/ddns/providers.py index ca6792a..82eb604 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -1044,7 +1044,8 @@ class DDNSProviderDomopoli(DDNSProtocolDynDNS2, DDNSProvider): # https://www.domopoli.de/?page=howto#DynDns_start - url = "http://dyndns.domopoli.de/nic/update" + # This provider does not support TLS 1.2. + url = "https://dyndns.domopoli.de/nic/update" class DDNSProviderDynsNet(DDNSProvider): -- 2.39.2 From c395275d5319ab6b5916381d09aeed39ca45ecf7 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Mon, 12 Jul 2021 12:38:45 +0200 Subject: [PATCH 09/16] dyns.net: Send request via HTTPS Signed-off-by: Stefan Schantl --- src/ddns/providers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ddns/providers.py b/src/ddns/providers.py index 82eb604..83e933b 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -1060,7 +1060,7 @@ class DDNSProviderDynsNet(DDNSProvider): # the possible response codes. (Currently we are using the v1.1 proto) # http://www.dyns.net/documentation/technical/protocol/ - url = "http://www.dyns.net/postscript011.php" + url = "https://www.dyns.net/postscript011.php" def update_protocol(self, proto): data = { -- 2.39.2 From aaa846b0fddae4b4e91eef55dcf12f6ea904d1ff Mon Sep 17 00:00:00 2001 From: Kashif Iftikhar Date: Mon, 12 Jul 2021 17:21:39 +0200 Subject: [PATCH 10/16] freedns.afraid.org: Update to new provider API Signed-off-by: Kashif Iftikhar Signed-off-by: Stefan Schantl --- src/ddns/providers.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/ddns/providers.py b/src/ddns/providers.py index 83e933b..4f27af9 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -1188,26 +1188,23 @@ class DDNSProviderFreeDNSAfraidOrg(DDNSProvider): # No information about the request or response could be found on the vendor # page. All used values have been collected by testing. - url = "https://freedns.afraid.org/dynamic/update.php" + url = "https://sync.afraid.org/u/" can_remove_records = False supports_token_auth = True def update_protocol(self, proto): - data = { - "address" : self.get_address(proto), - } # Add auth token to the update url. - url = "%s?%s" % (self.url, self.token) + url = "%s%s/" % (self.url, self.token) # Send update to the server. - response = self.send_request(url, data=data) + response = self.send_request(url) # Get the full response message. output = response.read().decode() # Handle success messages. - if output.startswith("Updated") or "has not changed" in output: + if output.startswith("Updated") or output.startswith("No IP changed detected"): return # Handle error codes. -- 2.39.2 From 99e683f4d469f6b499e9e9077920d73325dead74 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Mon, 12 Jul 2021 17:29:29 +0200 Subject: [PATCH 11/16] Bump version to 014. Signed-off-by: Stefan Schantl --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index dad12b7..eac7527 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ AC_PREREQ([2.64]) AC_INIT([ddns], - [013], + [014], [info@ipfire.org], [ddns], [http://git.ipfire.org/?p=oddments/ddns.git;a=summary]) -- 2.39.2 From 3a162595b9b44a4cbf08a3db14a4d2ebfeeb5583 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sat, 23 Oct 2021 21:11:27 +0200 Subject: [PATCH 12/16] FreeDNSAfraid.org: Fix typo in checking if the IP has been changed. Signed-off-by: Stefan Schantl --- src/ddns/providers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ddns/providers.py b/src/ddns/providers.py index 4f27af9..5b2a82d 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -1204,7 +1204,7 @@ class DDNSProviderFreeDNSAfraidOrg(DDNSProvider): output = response.read().decode() # Handle success messages. - if output.startswith("Updated") or output.startswith("No IP changed detected"): + if output.startswith("Updated") or output.startswith("No IP change detected"): return # Handle error codes. -- 2.39.2 From de57b2caf44bf10de72e42a20abf690eca50d512 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Mon, 4 Apr 2022 10:33:46 +0100 Subject: [PATCH 13/16] system: Catch exception when host is not dual-stacked This problem seems to have been introduced with an upgrade to Python 3.10. Reported-by: Adrian Zaugg Signed-off-by: Michael Tremer --- src/ddns/system.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ddns/system.py b/src/ddns/system.py index 73a27a5..48c9a8f 100644 --- a/src/ddns/system.py +++ b/src/ddns/system.py @@ -226,8 +226,12 @@ class DDNSSystem(object): if e.reason.errno == -2: raise DDNSResolveError + # Cannot assign requested address + elif e.reason.errno == 99: + raise DDNSNetworkUnreachableError + # Network Unreachable (e.g. no IPv6 access) - if e.reason.errno == 101: + elif e.reason.errno == 101: raise DDNSNetworkUnreachableError # Connection Refused -- 2.39.2 From 8b1e720fb75faff79c23085d2d3b4b98f79a1236 Mon Sep 17 00:00:00 2001 From: Costas Tyfoxylos Date: Sun, 12 Mar 2023 14:05:31 +0100 Subject: [PATCH 14/16] Add support for godaddy and fix typos. Signed-off-by: Costas Tyfoxylos Signed-off-by: Stefan Schantl --- README | 3 ++- ddns.conf.sample | 6 +++++ src/ddns/providers.py | 52 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/README b/README index b6decb3..f0df1ff 100644 --- a/README +++ b/README @@ -27,7 +27,7 @@ LICENSE: INSTALLATION: REQUIREMENTS: ddns is written in Python and does not require any third-party - modules. The minumum version of Python that has been tested + modules. The minimum version of Python that has been tested is Python 2.7. Building the program from source code requires: @@ -69,6 +69,7 @@ SUPPORTED PROVIDERS: enom.com entrydns.net freedns.afraid.org + godaddy.com inwx.com|de|at|ch|es itsdns.de joker.com diff --git a/ddns.conf.sample b/ddns.conf.sample index 61a608a..f93c738 100644 --- a/ddns.conf.sample +++ b/ddns.conf.sample @@ -100,6 +100,12 @@ # username = user # password = pass +# [test.godaddy.com] +# provider = godaddy.com +# username = key +# password = secret + + # [test.google.com] # provider = domains.google.com # username = user diff --git a/src/ddns/providers.py b/src/ddns/providers.py index 5b2a82d..8025720 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -21,6 +21,7 @@ import datetime import logging +import json import os import subprocess import urllib.request @@ -442,7 +443,7 @@ class DDNSProviderAllInkl(DDNSProvider): protocols = ("ipv4",) # There are only information provided by the vendor how to - # perform an update on a FRITZ Box. Grab requried informations + # perform an update on a FRITZ Box. Grab required information # from the net. # http://all-inkl.goetze.it/v01/ddns-mit-einfachen-mitteln/ @@ -1217,6 +1218,55 @@ class DDNSProviderFreeDNSAfraidOrg(DDNSProvider): raise DDNSUpdateError +class DDNSProviderGodaddy(DDNSProvider): + handle = "godaddy.com" + name = "godaddy.com" + website = "https://godaddy.com/" + protocols = ("ipv4",) + + # Information about the format of the HTTP request is to be found + # here: https://developer.godaddy.com/doc/endpoint/domains#/v1/recordReplaceTypeName + url = "https://api.godaddy.com/v1/domains/" + can_remove_records = False + + def update_protocol(self, proto): + # retrieve ip + ip_address = self.get_address(proto) + + # set target url + url = f"{self.url}/{self.hostname}/records/A/@" + + # prepare data + data = json.dumps([{"data": ip_address, "ttl": 600, "name": self.hostname, "type": "A"}]).encode("utf-8") + + # Method requires authentication by special headers. + request = urllib.request.Request(url=url, + data=data, + headers={"Authorization": f"sso-key {self.username}:{self.password}", + "Content-Type": "application/json"}, + method="PUT") + result = urllib.request.urlopen(request) + + # handle success + if result.code == 200: + return + + # handle errors + if result.code == 400: + raise DDNSRequestError(_("Malformed request received.")) + if result.code in (401, 403): + raise DDNSAuthenticationError + if result.code == 404: + raise DDNSRequestError(_("Resource not found.")) + if result.code == 422: + raise DDNSRequestError(_("Record does not fulfill the schema.")) + if result.code == 429: + raise DDNSRequestError(_("API Rate limiting.")) + + # If we got here, some other update error happened. + raise DDNSUpdateError + + class DDNSProviderHENet(DDNSProtocolDynDNS2, DDNSProvider): handle = "he.net" name = "he.net" -- 2.39.2 From 3844b74468ed8cca8f37c01fd0a6c377658b1eb2 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Wed, 15 Mar 2023 12:55:10 +0100 Subject: [PATCH 15/16] Bump version to 015. Signed-off-by: Stefan Schantl --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index eac7527..512f5ff 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ AC_PREREQ([2.64]) AC_INIT([ddns], - [014], + [015], [info@ipfire.org], [ddns], [http://git.ipfire.org/?p=oddments/ddns.git;a=summary]) -- 2.39.2 From e928b37b8f5509af195d1c56ecf89c3dbfdb0072 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rouven=20Sch=C3=BCrch?= Date: Sun, 21 Apr 2024 13:11:52 +0200 Subject: [PATCH 16/16] chore: add provider and sample configuration for infomaniak.ch MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Rouven Schürch Signed-off-by: Michael Tremer --- ddns.conf.sample | 6 +++++- src/ddns/providers.py | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ddns.conf.sample b/ddns.conf.sample index f93c738..f1adf5d 100644 --- a/ddns.conf.sample +++ b/ddns.conf.sample @@ -105,12 +105,16 @@ # username = key # password = secret - # [test.google.com] # provider = domains.google.com # username = user # password = pass +# [test.infomaniak.ch] +# provider = infomaniak.ch +# username = user +# password = pass + # [test.loopia.se] # provider = loopia.se # username = user diff --git a/src/ddns/providers.py b/src/ddns/providers.py index 8025720..59f9665 100644 --- a/src/ddns/providers.py +++ b/src/ddns/providers.py @@ -2005,3 +2005,15 @@ class DDNSProviderZZZZ(DDNSProvider): # If we got here, some other update error happened. raise DDNSUpdateError + +class DDNSProviderInfomaniak(DDNSProtocolDynDNS2, DDNSProvider): + handle = "infomaniak.ch" + name = "infomaniak" + website = "https://www.infomaniak.ch" + protocols = ("ipv4",) + + # Detailed information about how to send the update request and possible response + # codes can be obtained from here. + # https://www.infomaniak.com/de/support/faq/2376/dyndns-aktualisieren-eines-dynamischen-dns-uber-die-api + + url = "https://infomaniak.com/nic/update" -- 2.39.2