Don't do idna conversion for local network addresses

merge-requests/30/head
Bob Mottram 2021-01-25 11:38:12 +00:00
parent 7feb38e382
commit 192498859a
2 changed files with 29 additions and 12 deletions

View File

@ -17,7 +17,6 @@ from socket import error as SocketError
import errno import errno
from functools import partial from functools import partial
import pyqrcode import pyqrcode
import idna
# for saving images # for saving images
from hashlib import sha256 from hashlib import sha256
from hashlib import sha1 from hashlib import sha1
@ -184,6 +183,7 @@ from shares import addShare
from shares import removeShare from shares import removeShare
from shares import expireShares from shares import expireShares
from categories import setHashtagCategory from categories import setHashtagCategory
from utils import decodedHost
from utils import isPublicPost from utils import isPublicPost
from utils import getLockedAccount from utils import getLockedAccount
from utils import hasUsersPath from utils import hasUsersPath
@ -9876,11 +9876,7 @@ class PubServer(BaseHTTPRequestHandler):
def do_GET(self): def do_GET(self):
callingDomain = self.server.domainFull callingDomain = self.server.domainFull
if self.headers.get('Host'): if self.headers.get('Host'):
# IDNA decoding is an idempotent operation so this callingDomain = decodedHost(self.headers['Host'])
# 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'])
if self.server.onionDomain: if self.server.onionDomain:
if callingDomain != self.server.domain and \ if callingDomain != self.server.domain and \
callingDomain != self.server.domainFull and \ callingDomain != self.server.domainFull and \
@ -12039,9 +12035,7 @@ class PubServer(BaseHTTPRequestHandler):
def do_HEAD(self): def do_HEAD(self):
callingDomain = self.server.domainFull callingDomain = self.server.domainFull
if self.headers.get('Host'): if self.headers.get('Host'):
# As in the GET handler this should be idempotent but callingDomain = decodedHost(self.headers['Host'])
# for security maybe make configurable.
callingDomain = idna.decode(self.headers['Host'])
if self.server.onionDomain: if self.server.onionDomain:
if callingDomain != self.server.domain and \ if callingDomain != self.server.domain and \
callingDomain != self.server.domainFull and \ callingDomain != self.server.domainFull and \
@ -12992,9 +12986,7 @@ class PubServer(BaseHTTPRequestHandler):
callingDomain = self.server.domainFull callingDomain = self.server.domainFull
if self.headers.get('Host'): if self.headers.get('Host'):
# As notes in the GET handler, this should be idempotent callingDomain = decodedHost(self.headers['Host'])
# but should be configurable just in case
callingDomain = idna.decode(self.headers['Host'])
if self.server.onionDomain: if self.server.onionDomain:
if callingDomain != self.server.domain and \ if callingDomain != self.server.domain and \
callingDomain != self.server.domainFull and \ callingDomain != self.server.domainFull and \

View File

@ -14,11 +14,36 @@ import json
from socket import error as SocketError from socket import error as SocketError
import errno import errno
import urllib.request import urllib.request
import idna
from pprint import pprint from pprint import pprint
from calendar import monthrange from calendar import monthrange
from followingCalendar import addPersonToCalendar 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: def getLockedAccount(actorJson: {}) -> bool:
"""Returns whether the given account requires follower approval """Returns whether the given account requires follower approval
""" """