diff --git a/daemon.py b/daemon.py index 81b664b01..03c9300f2 100644 --- a/daemon.py +++ b/daemon.py @@ -17,7 +17,6 @@ from socket import error as SocketError import errno from functools import partial import pyqrcode -import idna # for saving images from hashlib import sha256 from hashlib import sha1 @@ -184,6 +183,7 @@ from shares import addShare from shares import removeShare from shares import expireShares from categories import setHashtagCategory +from utils import decodedHost from utils import isPublicPost from utils import getLockedAccount from utils import hasUsersPath @@ -9876,11 +9876,7 @@ class PubServer(BaseHTTPRequestHandler): def do_GET(self): callingDomain = self.server.domainFull if self.headers.get('Host'): - # IDNA decoding is an idempotent operation so this - # should not break 'normal' domains. - # For non-IDNA domains perhaps this behaviour should - # be disabled: TODO add config option? - callingDomain = idna.decode(self.headers['Host']) + callingDomain = decodedHost(self.headers['Host']) if self.server.onionDomain: if callingDomain != self.server.domain and \ callingDomain != self.server.domainFull and \ @@ -12039,9 +12035,7 @@ class PubServer(BaseHTTPRequestHandler): def do_HEAD(self): callingDomain = self.server.domainFull if self.headers.get('Host'): - # As in the GET handler this should be idempotent but - # for security maybe make configurable. - callingDomain = idna.decode(self.headers['Host']) + callingDomain = decodedHost(self.headers['Host']) if self.server.onionDomain: if callingDomain != self.server.domain and \ callingDomain != self.server.domainFull and \ @@ -12992,9 +12986,7 @@ class PubServer(BaseHTTPRequestHandler): callingDomain = self.server.domainFull if self.headers.get('Host'): - # As notes in the GET handler, this should be idempotent - # but should be configurable just in case - callingDomain = idna.decode(self.headers['Host']) + callingDomain = decodedHost(self.headers['Host']) if self.server.onionDomain: if callingDomain != self.server.domain and \ callingDomain != self.server.domainFull and \ diff --git a/utils.py b/utils.py index fe2deda4c..35d68de22 100644 --- a/utils.py +++ b/utils.py @@ -14,11 +14,36 @@ import json from socket import error as SocketError import errno import urllib.request +import idna from pprint import pprint from calendar import monthrange from followingCalendar import addPersonToCalendar +def _localNetworkHost(host: str) -> bool: + """Returns true if the given host is on the local network + """ + if host.startswith('192.') or \ + host.startswith('127.') or \ + host.startswith('10.'): + return True + return False + + +def decodedHost(host: str) -> str: + """Convert hostname to internationalized domain + https://en.wikipedia.org/wiki/Internationalized_domain_name + """ + if ':' not in host: + if not _localNetworkHost(host): + if not host.endswith('.onion'): + if not host.endswith('.i2p'): + # For domains on ports numbers don't use idna + # eg. mydomain:8000 + return idna.decode(host) + return host + + def getLockedAccount(actorJson: {}) -> bool: """Returns whether the given account requires follower approval """