-#!/usr/bin/python
+#!/usr/bin/python3
###############################################################################
# #
# ddns - A dynamic DNS client for IPFire #
import re
import ssl
import socket
-import urllib
-import urllib2
+import urllib.request
+import urllib.parse
+import urllib.error
-from __version__ import CLIENT_VERSION
+from .__version__ import CLIENT_VERSION
from .errors import *
-from i18n import _
+from .i18n import _
# Initialize the logger.
import logging
return proxy
def get_local_ip_address(self, proto):
+ ip_address = self._get_local_ip_address(proto)
+
+ # Check if the IP address is usable and only return it then
+ if self._is_usable_ip_address(proto, ip_address):
+ return ip_address
+
+ def _get_local_ip_address(self, proto):
# Legacy code for IPFire 2.
if self.distro == "ipfire-2" and proto == "ipv4":
try:
with open("/var/ipfire/red/local-ipaddress") as f:
return f.readline()
- except IOError, e:
+ except IOError as e:
# File not found
if e.errno == 2:
return
if not response.code == 200:
return
- match = re.search(r"^Your IP address is: (.*)$", response.read())
+ match = re.search(b"^Your IP address is: (.*)$", response.read())
if match is None:
return
- return match.group(1)
+ return match.group(1).decode()
def guess_external_ip_address(self, family, **kwargs):
if family == "ipv6":
- url = "http://checkip6.dns.lightningwirelabs.com"
+ url = "https://checkip6.dns.lightningwirelabs.com"
elif family == "ipv4":
- url = "http://checkip4.dns.lightningwirelabs.com"
+ url = "https://checkip4.dns.lightningwirelabs.com"
else:
raise ValueError("unknown address family")
if data:
logger.debug(" data: %s" % data)
- req = urllib2.Request(url, data=data)
+ req = urllib.request.Request(url, data=data)
if username and password:
basic_auth_header = self._make_basic_auth_header(username, password)
- req.add_header("Authorization", "Basic %s" % basic_auth_header)
+ req.add_header("Authorization", "Basic %s" % basic_auth_header.decode())
# Set the user agent.
req.add_header("User-Agent", self.USER_AGENT)
logger.debug(" %s: %s" % (k, v))
try:
- resp = urllib2.urlopen(req, timeout=timeout)
+ resp = urllib.request.urlopen(req, timeout=timeout)
# Log response header.
logger.debug(_("Response header (Status Code %s):") % resp.code)
# Return the entire response object.
return resp
- except urllib2.HTTPError, e:
+ except urllib.error.HTTPError as e:
# Log response header.
logger.debug(_("Response header (Status Code %s):") % e.code)
for k, v in e.hdrs.items():
elif e.code == 404:
raise DDNSNotFound(e.reason)
+ # 429 - Too Many Requests
+ elif e.code == 429:
+ raise DDNSTooManyRequests(e.reason)
+
# 500 - Internal Server Error
elif e.code == 500:
raise DDNSInternalServerError(e.reason)
# Raise all other unhandled exceptions.
raise
- except urllib2.URLError, e:
+ except urllib.error.URLError as e:
if e.reason:
# Handle SSL errors
if isinstance(e.reason, ssl.SSLError):
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
# Raise all other unhandled exceptions.
raise
- except socket.timeout, e:
+ except socket.timeout as e:
logger.debug(_("Connection timeout"))
raise DDNSConnectionTimeoutError
args = []
for k, v in data.items():
- arg = "%s=%s" % (k, urllib.quote(v))
+ arg = "%s=%s" % (k, urllib.parse.quote(v))
args.append(arg)
return "&".join(args)
authstring = "%s:%s" % (username, password)
# Encode authorization data in base64.
- authstring = base64.encodestring(authstring)
-
- # Remove any newline characters.
- authstring = authstring.replace("\n", "")
+ authstring = base64.b64encode(authstring.encode())
return authstring
guess_ip = self.core.settings.get("guess_external_ip", "true")
guess_ip = guess_ip in ("true", "yes", "1")
- # If the external IP address should be used, we just do that.
- if guess_ip:
- return self.guess_external_ip_address(proto)
-
# Get the local IP address.
- local_ip_address = self.get_local_ip_address(proto)
+ local_ip_address = None
+
+ if not guess_ip:
+ try:
+ local_ip_address = self.get_local_ip_address(proto)
+ except NotImplementedError:
+ logger.warning(_("Falling back to check the IP address with help of a public server"))
- # If the local IP address is not usable, we must guess
- # the correct IP address...
- if not self._is_usable_ip_address(proto, local_ip_address):
+ # If no local IP address could be determined, we will fall back to the guess
+ # it with help of an external server...
+ if not local_ip_address:
local_ip_address = self.guess_external_ip_address(proto)
return local_ip_address
# Resolve the host address.
try:
response = socket.getaddrinfo(hostname, None, family)
- except socket.gaierror, e:
+ except socket.gaierror as e:
# Name or service not known
if e.errno == -2:
return []
continue
# Add to repsonse list if not already in there.
- if not address in addresses:
+ if address not in addresses:
addresses.append(address)
return addresses
"""
try:
f = open("/etc/os-release", "r")
- except IOError, e:
+ except IOError as e:
# File not found
if e.errno == 2:
return
"""
try:
f = open("/etc/system-release", "r")
- except IOError, e:
+ except IOError as e:
# File not found
if e.errno == 2:
return