diff --git a/dns/ddclient/Makefile b/dns/ddclient/Makefile index 091f84cee..d2d3a3d02 100644 --- a/dns/ddclient/Makefile +++ b/dns/ddclient/Makefile @@ -1,6 +1,6 @@ PLUGIN_NAME= ddclient -PLUGIN_VERSION= 1.13 -PLUGIN_REVISION= 2 +PLUGIN_VERSION= 1.14 +#PLUGIN_REVISION= 1 PLUGIN_DEPENDS= ddclient-devel PLUGIN_COMMENT= Dynamic DNS client PLUGIN_MAINTAINER= ad@opnsense.org diff --git a/dns/ddclient/src/opnsense/mvc/app/controllers/OPNsense/DynDNS/forms/dialogAccount.xml b/dns/ddclient/src/opnsense/mvc/app/controllers/OPNsense/DynDNS/forms/dialogAccount.xml index c0aac07e9..7afd4b9c4 100644 --- a/dns/ddclient/src/opnsense/mvc/app/controllers/OPNsense/DynDNS/forms/dialogAccount.xml +++ b/dns/ddclient/src/opnsense/mvc/app/controllers/OPNsense/DynDNS/forms/dialogAccount.xml @@ -27,7 +27,10 @@ account.server text - DynDNS Server + DynDNS Server hostname or uri to use (depending on the protocol). + When a URI is provided, the tag __MYIP__ will be replaced with the current detected address for this service + and __HOSTNAME__ will contain the (comma separated) list of hostnames provided. + diff --git a/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.php b/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.php index 00726445e..969d52691 100644 --- a/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.php +++ b/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.php @@ -1,7 +1,7 @@ getFlatNodes() as $key => $node) { + $tagName = $node->getInternalXMLTagName(); + $parentNode = $node->getParentNode(); + if ($validateFullModel || $node->isFieldChanged()) { + if ($parentNode->getInternalXMLTagName() === 'account' && in_array($tagName, ['protocol', 'server'])) { + $parentKey = $parentNode->__reference; + $validate_servers[$parentKey] = $parentNode; + } + } + } + foreach ($validate_servers as $key => $node) { + if ((string)$node->service != 'custom') { + continue; + } + $srv = (string)$node->server; + if ((string)$node->protocol == 'post') { + if (empty($srv) || filter_var($srv, FILTER_VALIDATE_URL) === false) { + $messages->appendMessage( + new Message( + gettext("A valid URI is required."), + $key . ".server" + ) + ); + } + } else { + if (empty($srv) || filter_var($srv, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) === false) { + $messages->appendMessage( + new Message( + gettext("A valid domain is required."), + $key . ".server" + ) + ); + } + } + } + return $messages; + } } diff --git a/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.xml b/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.xml index a04ca3794..1bc908dec 100644 --- a/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.xml +++ b/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.xml @@ -93,11 +93,11 @@ DynDns1 DynDns2 + custom POST - + N - N N @@ -105,7 +105,7 @@ The username contains invalid characters. - Y + N /^[^\n]*$/ diff --git a/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/__init__.py b/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/__init__.py index b74f08c3c..e143cc28b 100755 --- a/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/__init__.py +++ b/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/__init__.py @@ -120,6 +120,7 @@ class BaseAccount: interface = self.settings['interface'] if self.settings.get('interface' ,'').strip() != '' else None ) + if self._current_address != '' and ( self._state.get('ip') is None or self._current_address != self._state.get('ip') or diff --git a/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/azure.py b/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/azure.py index 11fd3c637..64a635ab0 100755 --- a/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/azure.py +++ b/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/azure.py @@ -84,6 +84,7 @@ class Azure(BaseAccount): def known_services(): return Azure._services + @staticmethod def match(account): return account.get('service') in Azure._services diff --git a/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/cloudflare.py b/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/cloudflare.py index 388c2b147..1fd15ada8 100755 --- a/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/cloudflare.py +++ b/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/cloudflare.py @@ -44,6 +44,7 @@ class Cloudflare(BaseAccount): def known_services(): return Cloudflare._services.keys() + @staticmethod def match(account): return account.get('service') in Cloudflare._services diff --git a/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/dyndns2.py b/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/dyndns2.py index e53b14c83..aef23eb43 100755 --- a/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/dyndns2.py +++ b/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/dyndns2.py @@ -55,35 +55,46 @@ class DynDNS2(BaseAccount): def known_services(): return list(DynDNS2._services.keys()) + ['custom'] + @staticmethod def match(account): - if account.get('service') in DynDNS2._services or ( - account.get('server') is not None and account.get('protocol') in ['dyndns2', 'dyndns1'] - ): + if account.get('service') in DynDNS2.known_services(): return True else: return False def execute(self): if super().execute(): - proto = 'https' if self.settings.get('force_ssl', False) else 'http' - if self.settings.get('service') in self._services: - url = "%s://%s/nic/update" % (proto, self._services[self.settings.get('service')]) + protocol = self.settings.get('protocol', None) + if protocol == 'post': + url = self.settings.get('server') + url = url.replace('__MYIP__', self.current_address) + url = url.replace('__HOSTNAME__', self.settings.get('hostnames')) + req = requests.post( + url=url, + headers={'User-Agent': 'OPNsense-dyndns'}, + auth=HTTPBasicAuth(self.settings.get('username'), self.settings.get('password')) + ) else: - url = "%s://%s/nic/update" % (proto, self.settings.get('server')) + uri_proto = 'https' if self.settings.get('force_ssl', False) else 'http' + if self.settings.get('service') in self._services: + url = "%s://%s/nic/update" % (uri_proto, self._services[self.settings.get('service')]) + else: + url = "%s://%s/nic/update" % (uri_proto, self.settings.get('server')) - req_opts = { - 'url': url, - 'params': { - 'hostname': self.settings.get('hostnames'), - 'myip': self.current_address, - 'wildcard': 'ON' if self.settings.get('wildcard', False) else 'NOCHG' - }, - 'auth': HTTPBasicAuth(self.settings.get('username'), self.settings.get('password')), - 'headers': { - 'User-Agent': 'OPNsense-dyndns' + req_opts = { + 'url': url, + 'params': { + 'hostname': self.settings.get('hostnames'), + 'myip': self.current_address, + 'wildcard': 'ON' if self.settings.get('wildcard', False) else 'NOCHG' + }, + 'auth': HTTPBasicAuth(self.settings.get('username'), self.settings.get('password')), + 'headers': { + 'User-Agent': 'OPNsense-dyndns' + } } - } - req = requests.get(**req_opts) + req = requests.get(**req_opts) + if req.status_code == 200: if self.is_verbose: syslog.syslog(