mirror of
https://github.com/onionshare/onionshare.git
synced 2025-01-13 16:29:31 -05:00
Onion now connects to the Tor controller using the settings in Settings (except automatic still needs some work), and the settings dialog handles error when testing settings
This commit is contained in:
parent
943e23658e
commit
19d020f245
@ -27,6 +27,38 @@ from . import socks
|
||||
from . import helpers, strings
|
||||
from .settings import Settings
|
||||
|
||||
class TorErrorInvalidSetting(Exception):
|
||||
"""
|
||||
This exception is raised if the settings just don't make sense.
|
||||
"""
|
||||
pass
|
||||
|
||||
class TorErrorSocketPort(Exception):
|
||||
"""
|
||||
OnionShare can't connect to the Tor controller using the supplied address and port.
|
||||
"""
|
||||
pass
|
||||
|
||||
class TorErrorSocketFile(Exception):
|
||||
"""
|
||||
OnionShare can't connect to the Tor controller using the supplied socket file.
|
||||
"""
|
||||
pass
|
||||
|
||||
class TorErrorMissingPassword(Exception):
|
||||
"""
|
||||
OnionShare connected to the Tor controller, but it requires a password.
|
||||
"""
|
||||
pass
|
||||
|
||||
class TorErrorUnreadableCookieFile(Exception):
|
||||
"""
|
||||
OnionShare connected to the Tor controller, but your user does not have permission
|
||||
to access the cookie file.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class NoTor(Exception):
|
||||
"""
|
||||
This exception is raised if onionshare can't find a Tor control port
|
||||
@ -72,34 +104,69 @@ class Onion(object):
|
||||
self.cleanup_filenames = []
|
||||
self.service_id = None
|
||||
|
||||
# if the TOR_CONTROL_PORT environment variable is set, use that
|
||||
# otherwise, default to Tor Browser, Tor Messenger, and system tor ports
|
||||
env_port = os.environ.get('TOR_CONTROL_PORT')
|
||||
if env_port:
|
||||
ports = [int(env_port)]
|
||||
else:
|
||||
ports = [9151, 9153, 9051]
|
||||
|
||||
# if the TOR_AUTHENTICATION_PASSWORD is set, use that to authenticate
|
||||
password = os.environ.get('TOR_AUTHENTICATION_PASSWORD')
|
||||
|
||||
# connect to the tor controlport
|
||||
found_tor = False
|
||||
# Try to connect to Tor
|
||||
self.c = None
|
||||
for port in ports:
|
||||
|
||||
if self.settings.get('connection_type') == 'automatic':
|
||||
# Automatically try to guess the right way to connect to Tor Browser
|
||||
|
||||
# if the TOR_CONTROL_PORT environment variable is set, use that
|
||||
# otherwise, default to Tor Browser, Tor Messenger, and system tor ports
|
||||
env_port = os.environ.get('TOR_CONTROL_PORT')
|
||||
if env_port:
|
||||
ports = [int(env_port)]
|
||||
else:
|
||||
ports = [9151, 9153, 9051]
|
||||
|
||||
# connect to the tor controlport
|
||||
found_tor = False
|
||||
for port in ports:
|
||||
try:
|
||||
self.c = Controller.from_port(port=port)
|
||||
self.c.authenticate()
|
||||
found_tor = True
|
||||
break
|
||||
except SocketError:
|
||||
pass
|
||||
except MissingPassword:
|
||||
raise NoTor(strings._("ctrlport_missing_password").format(str(ports)))
|
||||
except UnreadableCookieFile:
|
||||
raise NoTor(strings._("ctrlport_unreadable_cookie").format(str(ports)))
|
||||
if not found_tor:
|
||||
raise NoTor(strings._("cant_connect_ctrlport").format(str(ports)))
|
||||
|
||||
else:
|
||||
# Use specific settings to connect to tor
|
||||
|
||||
# Try connecting
|
||||
try:
|
||||
self.c = Controller.from_port(port=port)
|
||||
self.c.authenticate(password)
|
||||
found_tor = True
|
||||
break
|
||||
if self.settings.get('connection_type') == 'control_port':
|
||||
self.c = Controller.from_port(address=self.settings.get('control_port_address'), port=self.settings.get('control_port_port'))
|
||||
elif self.settings.get('connection_type') == 'socket_file':
|
||||
self.c = Controller.from_socket_file(path=self.settings.get('socket_file_path'))
|
||||
else:
|
||||
raise TorErrorInvalidSetting(strings._("settings_error_unknown"))
|
||||
|
||||
except SocketError:
|
||||
pass
|
||||
if self.settings.get('connection_type') == 'control_port':
|
||||
raise TorErrorSocketPort(strings._("settings_error_socket_port").format(self.settings.get('control_port_address'), self.settings.get('control_port_port')))
|
||||
else:
|
||||
raise TorErrorSocketFile(strings._("settings_error_socket_file").format(self.settings.get('socket_file_path')))
|
||||
|
||||
# Try authenticating
|
||||
try:
|
||||
if self.settings.get('auth_type') == 'no_auth':
|
||||
self.c.authenticate()
|
||||
elif self.settings.get('auth_type') == 'password':
|
||||
self.c.authenticate(self.settings.get('auth_password'))
|
||||
else:
|
||||
raise TorErrorInvalidSetting(strings._("settings_error_unknown"))
|
||||
|
||||
except MissingPassword:
|
||||
raise NoTor(strings._("ctrlport_missing_password").format(str(ports)))
|
||||
raise TorErrorMissingPassword(strings._('settings_error_missing_password'))
|
||||
except UnreadableCookieFile:
|
||||
raise NoTor(strings._("ctrlport_unreadable_cookie").format(str(ports)))
|
||||
if not found_tor:
|
||||
raise NoTor(strings._("cant_connect_ctrlport").format(str(ports)))
|
||||
raise TorErrorUnreadableCookieFile(strings._('settings_error_unreadable_cookie_file'))
|
||||
|
||||
|
||||
# do the versions of stem and tor that I'm using support ephemeral onion services?
|
||||
tor_version = self.c.get_version().version_str
|
||||
@ -107,8 +174,7 @@ class Onion(object):
|
||||
self.supports_ephemeral = callable(list_ephemeral_hidden_services) and tor_version >= '0.2.7.1'
|
||||
|
||||
# do the versions of stem and tor that I'm using support stealth onion services?
|
||||
if self.stealth:
|
||||
self.check_for_stealth_support()
|
||||
self.check_for_stealth_support()
|
||||
|
||||
def check_for_stealth_support(self):
|
||||
try:
|
||||
|
@ -37,11 +37,10 @@ class Settings(object):
|
||||
'version': helpers.get_version(),
|
||||
'connection_type': 'automatic',
|
||||
'control_port_address': '127.0.0.1',
|
||||
'control_port_port': '9051',
|
||||
'control_port_port': 9051,
|
||||
'socket_file_path': '/var/run/tor/control',
|
||||
'auth_type': 'no_auth',
|
||||
'auth_password': '',
|
||||
'auth_cookie_path': '/var/run/tor/control.authcookie'
|
||||
'auth_password': ''
|
||||
}
|
||||
|
||||
def build_filename(self):
|
||||
|
@ -21,7 +21,9 @@ from PyQt5 import QtCore, QtWidgets, QtGui
|
||||
|
||||
from onionshare import strings
|
||||
from onionshare.settings import Settings
|
||||
from onionshare.onion import Onion
|
||||
from onionshare.onion import Onion, TorErrorInvalidSetting, TorErrorSocketPort, TorErrorSocketFile, TorErrorMissingPassword, TorErrorUnreadableCookieFile
|
||||
|
||||
from .alert import Alert
|
||||
|
||||
class SettingsDialog(QtWidgets.QDialog):
|
||||
"""
|
||||
@ -100,27 +102,11 @@ class SettingsDialog(QtWidgets.QDialog):
|
||||
self.authenticate_password_extras.setLayout(authenticate_password_extras_layout)
|
||||
self.authenticate_password_extras.hide()
|
||||
|
||||
# Cookie
|
||||
self.authenticate_cookie_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_cookie_option', True))
|
||||
self.authenticate_cookie_radio.toggled.connect(self.authenticate_cookie_toggled)
|
||||
|
||||
authenticate_cookie_extras_label = QtWidgets.QLabel(strings._('gui_settings_cookie_label', True))
|
||||
self.authenticate_cookie_extras_cookie_path = QtWidgets.QLineEdit()
|
||||
authenticate_cookie_extras_layout = QtWidgets.QHBoxLayout()
|
||||
authenticate_cookie_extras_layout.addWidget(authenticate_cookie_extras_label)
|
||||
authenticate_cookie_extras_layout.addWidget(self.authenticate_cookie_extras_cookie_path)
|
||||
|
||||
self.authenticate_cookie_extras = QtWidgets.QWidget()
|
||||
self.authenticate_cookie_extras.setLayout(authenticate_cookie_extras_layout)
|
||||
self.authenticate_cookie_extras.hide()
|
||||
|
||||
# Authentication options layout
|
||||
authenticate_group_layout = QtWidgets.QVBoxLayout()
|
||||
authenticate_group_layout.addWidget(self.authenticate_no_auth_radio)
|
||||
authenticate_group_layout.addWidget(self.authenticate_password_radio)
|
||||
authenticate_group_layout.addWidget(self.authenticate_cookie_radio)
|
||||
authenticate_group_layout.addWidget(self.authenticate_password_extras)
|
||||
authenticate_group_layout.addWidget(self.authenticate_cookie_extras)
|
||||
self.authenticate_group = QtWidgets.QGroupBox(strings._("gui_settings_authenticate_label", True))
|
||||
self.authenticate_group.setLayout(authenticate_group_layout)
|
||||
|
||||
@ -158,17 +144,14 @@ class SettingsDialog(QtWidgets.QDialog):
|
||||
elif connection_type == 'socket_file':
|
||||
self.connection_type_socket_file_radio.setChecked(True)
|
||||
self.connection_type_control_port_extras_address.setText(settings.get('control_port_address'))
|
||||
self.connection_type_control_port_extras_port.setText(settings.get('control_port_port'))
|
||||
self.connection_type_control_port_extras_port.setText(str(settings.get('control_port_port')))
|
||||
self.connection_type_socket_file_extras_path.setText(settings.get('socket_file_path'))
|
||||
auth_type = settings.get('auth_type')
|
||||
if auth_type == 'no_auth':
|
||||
self.authenticate_no_auth_radio.setChecked(True)
|
||||
elif auth_type == 'password':
|
||||
self.authenticate_password_radio.setChecked(True)
|
||||
elif auth_type == 'cookie':
|
||||
self.authenticate_cookie_radio.setChecked(True)
|
||||
self.authenticate_password_extras_password.setText(settings.get('auth_password'))
|
||||
self.authenticate_cookie_extras_cookie_path.setText(settings.get('auth_cookie_path'))
|
||||
|
||||
# Show the dialog
|
||||
self.exec_()
|
||||
@ -220,24 +203,20 @@ class SettingsDialog(QtWidgets.QDialog):
|
||||
else:
|
||||
self.authenticate_password_extras.hide()
|
||||
|
||||
def authenticate_cookie_toggled(self, checked):
|
||||
"""
|
||||
Authentication option cookie was toggled. If checked, show extra fields
|
||||
for cookie auth. If unchecked, hide those extra fields.
|
||||
"""
|
||||
if checked:
|
||||
self.authenticate_cookie_extras.show()
|
||||
else:
|
||||
self.authenticate_cookie_extras.hide()
|
||||
|
||||
def test_clicked(self):
|
||||
"""
|
||||
Test Settings button clicked. With the given settings, see if we can
|
||||
successfully connect and authenticate to Tor.
|
||||
"""
|
||||
print("Testing settings")
|
||||
settings = self.settings_from_fields()
|
||||
onion = Onion(settings=settings)
|
||||
|
||||
try:
|
||||
onion = Onion(settings=settings)
|
||||
|
||||
# If an exception hasn't been raised yet, the Tor settings work
|
||||
|
||||
except (TorErrorInvalidSetting, TorErrorSocketPort, TorErrorSocketFile, TorErrorMissingPassword, TorErrorUnreadableCookieFile) as e:
|
||||
Alert(e.args[0])
|
||||
|
||||
def save_clicked(self):
|
||||
"""
|
||||
@ -267,17 +246,14 @@ class SettingsDialog(QtWidgets.QDialog):
|
||||
settings.set('connection_type', 'socket_file')
|
||||
|
||||
settings.set('control_port_address', self.connection_type_control_port_extras_address.text())
|
||||
settings.set('control_port_port', self.connection_type_control_port_extras_port.text())
|
||||
settings.set('control_port_port', int(self.connection_type_control_port_extras_port.text()))
|
||||
settings.set('socket_file_path', self.connection_type_socket_file_extras_path.text())
|
||||
|
||||
if self.authenticate_no_auth_radio.isChecked():
|
||||
settings.set('auth_type', 'no_auth')
|
||||
if self.authenticate_password_radio.isChecked():
|
||||
settings.set('auth_type', 'password')
|
||||
if self.authenticate_cookie_radio.isChecked():
|
||||
settings.set('auth_type', 'cookie')
|
||||
|
||||
settings.set('auth_password', self.authenticate_password_extras_password.text())
|
||||
settings.set('auth_cookie_path', self.authenticate_cookie_extras_cookie_path.text())
|
||||
|
||||
return settings
|
||||
|
@ -70,7 +70,7 @@
|
||||
"gui_settings_control_port_label": "Control port",
|
||||
"gui_settings_socket_file_label": "Socket file",
|
||||
"gui_settings_authenticate_label": "Tor authentication options",
|
||||
"gui_settings_authenticate_no_auth_option": "No authentication",
|
||||
"gui_settings_authenticate_no_auth_option": "No authentication, or cookie authentication",
|
||||
"gui_settings_authenticate_password_option": "Password",
|
||||
"gui_settings_authenticate_cookie_option": "Cookie",
|
||||
"gui_settings_password_label": "Password",
|
||||
@ -78,5 +78,10 @@
|
||||
"gui_settings_button_test": "Test Settings",
|
||||
"gui_settings_button_save": "Save",
|
||||
"gui_settings_button_cancel": "Cancel",
|
||||
"settings_saved": "Settings saved to {}"
|
||||
"settings_saved": "Settings saved to {}",
|
||||
"settings_error_unknown": "Can't connect to Tor controller because the settings don't make sense.",
|
||||
"settings_error_socket_port": "Can't connect to Tor controller on address {} with port {}.",
|
||||
"settings_error_socket_file": "Can't connect to Tor controller using socket file {}.",
|
||||
"settings_error_missing_password": "Connected to Tor controller, but it requires a password to authenticate.",
|
||||
"settings_error_unreadable_cookie_file": "Connected to Tor controller, but can't authenticate because your password may be wrong, and your user doesn't have permission to read the cookie file."
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user