Tor hidden service fixes

- will send the correct combination of hostname and port
- if proxyhostname is a hostname and an IP address, it will now allow
  multiple parallel connections for hidden service
This commit is contained in:
Peter Šurda 2016-06-10 10:44:42 +02:00
parent 4b559bbe66
commit f242d409fd
Signed by untrusted user: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
3 changed files with 24 additions and 6 deletions

View File

@ -605,14 +605,15 @@ class receiveDataThread(threading.Thread):
sentOwn = False sentOwn = False
for i in range(500): for i in range(500):
# if current connection is over a proxy, sent our own onion address at a random position # if current connection is over a proxy, sent our own onion address at a random position
if ownPosition == i and ".onion" in shared.config.get("bitmessagesettings", "onionhostname") and self.sock.getproxytype() != 0 and not sentOwn: if ownPosition == i and ".onion" in shared.config.get("bitmessagesettings", "onionhostname") and \
hasattr(self.sock, "getproxytype") and self.sock.getproxytype() != "none" and not sentOwn:
peer = shared.Peer(shared.config.get("bitmessagesettings", "onionhostname"), shared.config.getint("bitmessagesettings", "onionport")) peer = shared.Peer(shared.config.get("bitmessagesettings", "onionhostname"), shared.config.getint("bitmessagesettings", "onionport"))
else: else:
# still may contain own onion address, but we don't change it # still may contain own onion address, but we don't change it
peer, = random.sample(shared.knownNodes[self.streamNumber], 1) peer, = random.sample(shared.knownNodes[self.streamNumber], 1)
if isHostInPrivateIPRange(peer.host): if isHostInPrivateIPRange(peer.host):
continue continue
if shared.config.get("bitmessagesettings", "onionhostname") == peer.host: if peer.host == shared.config.get("bitmessagesettings", "onionhostname") and peer.port == shared.config.getint("bitmessagesettings", "onionport") :
sentOwn = True sentOwn = True
addrsInMyStream[peer] = shared.knownNodes[ addrsInMyStream[peer] = shared.knownNodes[
self.streamNumber][peer] self.streamNumber][peer]

View File

@ -123,8 +123,7 @@ class singleListener(threading.Thread, StoppableThread):
# share the same external IP. This is here to prevent # share the same external IP. This is here to prevent
# connection flooding. # connection flooding.
# permit repeated connections from Tor # permit repeated connections from Tor
# FIXME: sockshostname may be a hostname rather than IP, in such a case this will break if HOST in shared.connectedHostsList and (".onion" not in shared.config.get('bitmessagesettings', 'onionhostname') or shared.checkSocksIP(HOST)):
if HOST in shared.connectedHostsList and (".onion" not in shared.config.get('bitmessagesettings', 'onionhostname') or HOST != shared.config.get('bitmessagesettings', 'sockshostname')):
socketObject.close() socketObject.close()
logger.info('We are already connected to ' + str(HOST) + '. Ignoring connection.') logger.info('We are already connected to ' + str(HOST) + '. Ignoring connection.')
else: else:

View File

@ -123,6 +123,9 @@ trustedPeer = None
# For UPnP # For UPnP
extPort = None extPort = None
# for Tor hidden service
socksIP = None
#Compiled struct for packing/unpacking headers #Compiled struct for packing/unpacking headers
#New code should use CreatePacket instead of Header.pack #New code should use CreatePacket instead of Header.pack
Header = Struct('!L12sL4s') Header = Struct('!L12sL4s')
@ -244,6 +247,14 @@ def haveSSL(server = False):
return True return True
return False return False
def checkSocksIP(host):
try:
if socksIP is None or not socksIP:
socksIP = socket.gethostbyname(config.get("bitmessagesettings", "sockshostname"))
except NameError:
socksIP = socket.gethostbyname(config.get("bitmessagesettings", "sockshostname"))
return socksIP == host
def assembleVersionMessage(remoteHost, remotePort, myStreamNumber, server = False): def assembleVersionMessage(remoteHost, remotePort, myStreamNumber, server = False):
payload = '' payload = ''
payload += pack('>L', 3) # protocol version. payload += pack('>L', 3) # protocol version.
@ -258,9 +269,16 @@ def assembleVersionMessage(remoteHost, remotePort, myStreamNumber, server = Fals
payload += pack('>q', 1) # bitflags of the services I offer. payload += pack('>q', 1) # bitflags of the services I offer.
payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + pack( payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + pack(
'>L', 2130706433) # = 127.0.0.1. This will be ignored by the remote host. The actual remote connected IP will be used. '>L', 2130706433) # = 127.0.0.1. This will be ignored by the remote host. The actual remote connected IP will be used.
if safeConfigGetBoolean('bitmessagesettings', 'upnp') and extPort: # we have a separate extPort and
# incoming over clearnet or
# outgoing through clearnet
if safeConfigGetBoolean('bitmessagesettings', 'upnp') and extPort \
and ((server and not checkSocksIP(remoteHost)) or \
(config.get("bitmessagesettings", "socksproxytype") == "none" and not server)):
payload += pack('>H', extPort) payload += pack('>H', extPort)
else: elif checkSocksIP(remoteHost) and server: # incoming connection over Tor
payload += pack('>H', shared.config.getint('bitmessagesettings', 'onionport'))
else: # no extPort and not incoming over Tor
payload += pack('>H', shared.config.getint('bitmessagesettings', 'port')) payload += pack('>H', shared.config.getint('bitmessagesettings', 'port'))
random.seed() random.seed()