Closes #1538. Refactors 'onionservicesonly' to 'onlynet=onion', prevents bootstrapping from non-onion nodes when true, and prevents bootstrapping from any node but the trusted peer (when set) #1694
|
@ -358,6 +358,11 @@ class SettingsDialog(QtGui.QDialog):
|
||||||
if proxytype_index > 2: # last literal proxytype in ui
|
if proxytype_index > 2: # last literal proxytype in ui
|
||||||
start_proxyconfig()
|
start_proxyconfig()
|
||||||
|
|
||||||
|
onionOnly_deprecated = BMConfigParser().safeGetBoolean(
|
||||||
|
"bitmessagesettings", "onionservicesonly")
|
||||||
|
onionOnly = BMConfigParser().safeGet(
|
||||||
|
"bitmessagesettings", "onlynet") == "onion"
|
||||||
|
onionOnly = onionOnly or onionOnly_deprecated
|
||||||
self.config.set('bitmessagesettings', 'socksauthentication', str(
|
self.config.set('bitmessagesettings', 'socksauthentication', str(
|
||||||
self.checkBoxAuthentication.isChecked()))
|
self.checkBoxAuthentication.isChecked()))
|
||||||
self.config.set('bitmessagesettings', 'sockshostname', str(
|
self.config.set('bitmessagesettings', 'sockshostname', str(
|
||||||
|
@ -371,10 +376,20 @@ class SettingsDialog(QtGui.QDialog):
|
||||||
self.config.set('bitmessagesettings', 'sockslisten', str(
|
self.config.set('bitmessagesettings', 'sockslisten', str(
|
||||||
self.checkBoxSocksListen.isChecked()))
|
self.checkBoxSocksListen.isChecked()))
|
||||||
if self.checkBoxOnionOnly.isChecked() \
|
if self.checkBoxOnionOnly.isChecked() \
|
||||||
and not self.config.safeGetBoolean('bitmessagesettings', 'onionservicesonly'):
|
and not onionOnly:
|
||||||
self.net_restart_needed = True
|
self.net_restart_needed = True
|
||||||
self.config.set('bitmessagesettings', 'onionservicesonly', str(
|
if self.checkBoxOnionOnly.isChecked():
|
||||||
self.checkBoxOnionOnly.isChecked()))
|
self.config.set('bitmessagesettings', 'onlynet', 'onion')
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
return self.config.remove_option('bitmessagesettings', 'onlynet')
|
||||||
|
except ConfigParser.NoOptionError:
|
||||||
|
pass
|
||||||
|
# Remove deprecated onionservicesonly option if it exists:
|
||||||
|
try:
|
||||||
|
return self.config.remove_option('bitmessagesettings', 'onionservicesonly')
|
||||||
|
except ConfigParser.NoOptionError:
|
||||||
|
pass
|
||||||
try:
|
try:
|
||||||
# Rounding to integers just for aesthetics
|
# Rounding to integers just for aesthetics
|
||||||
self.config.set('bitmessagesettings', 'maxdownloadrate', str(
|
self.config.set('bitmessagesettings', 'maxdownloadrate', str(
|
||||||
|
|
|
@ -31,8 +31,11 @@ def chooseConnection(stream):
|
||||||
"""Returns an appropriate connection"""
|
"""Returns an appropriate connection"""
|
||||||
haveOnion = BMConfigParser().safeGet(
|
haveOnion = BMConfigParser().safeGet(
|
||||||
"bitmessagesettings", "socksproxytype")[0:5] == 'SOCKS'
|
"bitmessagesettings", "socksproxytype")[0:5] == 'SOCKS'
|
||||||
onionOnly = BMConfigParser().safeGetBoolean(
|
onionOnly_deprecated = BMConfigParser().safeGetBoolean(
|
||||||
"bitmessagesettings", "onionservicesonly")
|
"bitmessagesettings", "onionservicesonly")
|
||||||
|
onionOnly = BMConfigParser().safeGet(
|
||||||
|
"bitmessagesettings", "onlynet") == "onion"
|
||||||
|
onionOnly = onionOnly or onionOnly_deprecated
|
||||||
try:
|
try:
|
||||||
retval = portCheckerQueue.get(False)
|
retval = portCheckerQueue.get(False)
|
||||||
portCheckerQueue.task_done()
|
portCheckerQueue.task_done()
|
||||||
|
|
|
@ -51,6 +51,12 @@ class BMConnectionPool(object):
|
||||||
BMConfigParser().safeGetInt(
|
BMConfigParser().safeGetInt(
|
||||||
"bitmessagesettings", "maxuploadrate")
|
"bitmessagesettings", "maxuploadrate")
|
||||||
)
|
)
|
||||||
|
onionOnly_deprecated = BMConfigParser().safeGetBoolean(
|
||||||
|
"bitmessagesettings", "onionservicesonly")
|
||||||
|
onionOnly = BMConfigParser().safeGet(
|
||||||
|
"bitmessagesettings", "onlynet") == "onion"
|
||||||
|
|
||||||
|
self.onionOnly = onionOnly or onionOnly_deprecated
|
||||||
self.outboundConnections = {}
|
self.outboundConnections = {}
|
||||||
self.inboundConnections = {}
|
self.inboundConnections = {}
|
||||||
self.listeningSockets = {}
|
self.listeningSockets = {}
|
||||||
|
@ -205,17 +211,17 @@ class BMConnectionPool(object):
|
||||||
|
|
||||||
def startBootstrappers(self):
|
def startBootstrappers(self):
|
||||||
"""Run the process of resolving bootstrap hostnames"""
|
"""Run the process of resolving bootstrap hostnames"""
|
||||||
|
onion_seed = 'quzwelsuziwqgpt2.onion' # FIXME onion bootstrap server is down
|
||||||
proxy_type = BMConfigParser().safeGet(
|
proxy_type = BMConfigParser().safeGet(
|
||||||
'bitmessagesettings', 'socksproxytype')
|
'bitmessagesettings', 'socksproxytype')
|
||||||
# A plugins may be added here
|
# A plugins may be added here
|
||||||
hostname = None
|
hostname = None
|
||||||
|
port = 8444
|
||||||
|
|
||||||
if not proxy_type or proxy_type == 'none':
|
if not proxy_type or proxy_type == 'none':
|
||||||
connection_base = TCPConnection
|
connection_base = TCPConnection
|
||||||
elif proxy_type == 'SOCKS5':
|
elif proxy_type == 'SOCKS5':
|
||||||
connection_base = Socks5BMConnection
|
connection_base = Socks5BMConnection
|
||||||
hostname = helper_random.randomchoice([
|
|
||||||
'quzwelsuziwqgpt2.onion', None
|
|
||||||
])
|
|
||||||
elif proxy_type == 'SOCKS4a':
|
elif proxy_type == 'SOCKS4a':
|
||||||
connection_base = Socks4aBMConnection # FIXME: I cannot test
|
connection_base = Socks4aBMConnection # FIXME: I cannot test
|
||||||
else:
|
else:
|
||||||
|
@ -223,12 +229,21 @@ class BMConnectionPool(object):
|
||||||
# is handled in bitmessagemain before starting the connectionpool
|
# is handled in bitmessagemain before starting the connectionpool
|
||||||
return
|
return
|
||||||
|
|
||||||
bootstrapper = bootstrap(connection_base)
|
if self.trustedPeer is not None:
|
||||||
if not hostname:
|
hostname = self.trustedPeer.host
|
||||||
|
port = self.trustedPeer.port
|
||||||
|
elif proxy_type == "SOCKS5" or self.onionOnly:
|
||||||
|
if self.onionOnly:
|
||||||
|
hostname = onion_seed
|
||||||
|
else:
|
||||||
|
hostname = helper_random.randomchoice([
|
||||||
|
onion_seed, None])
|
||||||
|
|
||||||
|
if hostname is None:
|
||||||
port = helper_random.randomchoice([8080, 8444])
|
port = helper_random.randomchoice([8080, 8444])
|
||||||
hostname = 'bootstrap%s.bitmessage.org' % port
|
hostname = 'bootstrap%s.bitmessage.org' % port
|
||||||
else:
|
|
||||||
port = 8444
|
bootstrapper = bootstrap(connection_base)
|
||||||
self.addConnection(bootstrapper(hostname, port))
|
self.addConnection(bootstrapper(hostname, port))
|
||||||
|
|
||||||
def loop(self): # pylint: disable=too-many-branches,too-many-statements
|
def loop(self): # pylint: disable=too-many-branches,too-many-statements
|
||||||
|
|
|
@ -194,14 +194,7 @@ class TestCore(unittest.TestCase):
|
||||||
start_proxyconfig()
|
start_proxyconfig()
|
||||||
self._check_bootstrap()
|
self._check_bootstrap()
|
||||||
|
|
||||||
@unittest.skipUnless(stem_version, 'No stem, skipping tor dependent test')
|
def _check_exclusively_onion_networking(self):
|
||||||
def test_onionservicesonly(self): # this should start after bootstrap
|
|
||||||
"""
|
|
||||||
set onionservicesonly, wait for 3 connections and check them all
|
|
||||||
are onions
|
|
||||||
"""
|
|
||||||
BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'SOCKS5')
|
|
||||||
BMConfigParser().set('bitmessagesettings', 'onionservicesonly', 'true')
|
|
||||||
self._initiate_bootstrap()
|
self._initiate_bootstrap()
|
||||||
BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')
|
BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')
|
||||||
for _ in range(360):
|
for _ in range(360):
|
||||||
|
@ -218,6 +211,25 @@ class TestCore(unittest.TestCase):
|
||||||
% peer.host)
|
% peer.host)
|
||||||
self.fail('Failed to connect to at least 3 nodes within 360 sec')
|
self.fail('Failed to connect to at least 3 nodes within 360 sec')
|
||||||
|
|
||||||
|
@unittest.skipUnless(stem_version, 'No stem, skipping tor dependent test')
|
||||||
|
def test_onionservicesonly(self): # this should start after bootstrap
|
||||||
|
"""
|
||||||
|
set onionservicesonly (deprecated), wait for 3 connections and check
|
||||||
|
that all are onions
|
||||||
|
"""
|
||||||
|
BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'SOCKS5')
|
||||||
|
BMConfigParser().set('bitmessagesettings', 'onionservicesonly', 'true')
|
||||||
|
self._check_exclusively_onion_networking()
|
||||||
|
|
||||||
|
@unittest.skipUnless(stem_version, 'No stem, skipping tor dependent test')
|
||||||
|
def test_onlynetonion(self): # this should start after bootstrap
|
||||||
|
"""
|
||||||
|
set onlynet=onion, wait for 3 connections and check that all are onions
|
||||||
|
"""
|
||||||
|
BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'SOCKS5')
|
||||||
|
BMConfigParser().set('bitmessagesettings', 'onlynet', 'onion')
|
||||||
|
self._check_exclusively_onion_networking()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _decode_msg(data, pattern):
|
def _decode_msg(data, pattern):
|
||||||
proto = BMProto()
|
proto = BMProto()
|
||||||
|
|
Reference in New Issue
Block a user