Early support for ClientAuth with v3 onions

This commit is contained in:
Miguel Jacq 2021-05-04 10:02:02 +10:00
parent ad93056a17
commit 4aa6d6f3ec
11 changed files with 455 additions and 156 deletions

View file

@ -25,11 +25,14 @@
"gui_receive_flatpak_data_dir": "Because you installed OnionShare using Flatpak, you must save files to a folder in ~/OnionShare.",
"gui_copy_url": "Copy Address",
"gui_copy_hidservauth": "Copy HidServAuth",
"gui_copy_client_auth_v3": "Copy ClientAuth",
"gui_canceled": "Canceled",
"gui_copied_url_title": "Copied OnionShare Address",
"gui_copied_url": "OnionShare address copied to clipboard",
"gui_copied_hidservauth_title": "Copied HidServAuth",
"gui_copied_hidservauth": "HidServAuth line copied to clipboard",
"gui_copied_client_auth_v3_title": "Copied ClientAuth",
"gui_copied_client_auth_v3": "ClientAuth private key copied to clipboard",
"gui_show_url_qr_code": "Show QR Code",
"gui_qr_code_dialog_title": "OnionShare QR Code",
"gui_waiting_to_start": "Scheduled to start in {}. Click to cancel.",
@ -68,7 +71,7 @@
"gui_settings_button_save": "Save",
"gui_settings_button_cancel": "Cancel",
"gui_settings_button_help": "Help",
"settings_test_success": "Connected to the Tor controller.\n\nTor version: {}\nSupports ephemeral onion services: {}.\nSupports client authentication: {}.\nSupports next-gen .onion addresses: {}.",
"settings_test_success": "Connected to the Tor controller.\n\nTor version: {}\nSupports ephemeral onion services: {}.\nSupports legacy .onion addresses: {}.\nSupports v2 client authentication: {}.\nSupports next-gen .onion addresses: {}.\nSupports next-gen client authentication: {}.",
"connecting_to_tor": "Connecting to the Tor network",
"update_available": "New OnionShare out. <a href='{}'>Click here</a> to get it.<br><br>You are using {} and the latest is {}.",
"update_error_invalid_latest_version": "Could not check for new version: The OnionShare website is saying the latest version is the unrecognizable '{}'…",
@ -194,4 +197,4 @@
"gui_rendezvous_cleanup": "Waiting for Tor circuits to close to be sure your files have successfully transferred.\n\nThis might take a few minutes.",
"gui_rendezvous_cleanup_quit_early": "Quit Early",
"error_port_not_available": "OnionShare port not available"
}
}

View file

@ -695,8 +695,10 @@ class SettingsDialog(QtWidgets.QDialog):
strings._("settings_test_success").format(
onion.tor_version,
onion.supports_ephemeral,
onion.supports_v2_onions,
onion.supports_stealth,
onion.supports_v3_onions,
onion.supports_stealth_v3,
),
)

View file

@ -139,7 +139,7 @@ class ModeSettingsWidget(QtWidgets.QWidget):
else:
self.legacy_checkbox.setCheckState(QtCore.Qt.Unchecked)
# Client auth
# Client auth (v2)
self.client_auth_checkbox = QtWidgets.QCheckBox()
self.client_auth_checkbox.clicked.connect(self.client_auth_checkbox_clicked)
self.client_auth_checkbox.clicked.connect(self.update_ui)
@ -151,6 +151,18 @@ class ModeSettingsWidget(QtWidgets.QWidget):
else:
self.client_auth_checkbox.setCheckState(QtCore.Qt.Unchecked)
# Client auth (v3)
self.client_auth_v3_checkbox = QtWidgets.QCheckBox()
self.client_auth_v3_checkbox.clicked.connect(self.client_auth_v3_checkbox_clicked)
self.client_auth_v3_checkbox.clicked.connect(self.update_ui)
self.client_auth_v3_checkbox.setText(
strings._("mode_settings_client_auth_checkbox")
)
if self.settings.get("general", "client_auth_v3"):
self.client_auth_v3_checkbox.setCheckState(QtCore.Qt.Checked)
else:
self.client_auth_v3_checkbox.setCheckState(QtCore.Qt.Unchecked)
# Toggle advanced settings
self.toggle_advanced_button = QtWidgets.QPushButton()
self.toggle_advanced_button.clicked.connect(self.toggle_advanced_clicked)
@ -167,6 +179,7 @@ class ModeSettingsWidget(QtWidgets.QWidget):
advanced_layout.addLayout(autostop_timer_layout)
advanced_layout.addWidget(self.legacy_checkbox)
advanced_layout.addWidget(self.client_auth_checkbox)
advanced_layout.addWidget(self.client_auth_v3_checkbox)
self.advanced_widget = QtWidgets.QWidget()
self.advanced_widget.setLayout(advanced_layout)
self.advanced_widget.hide()
@ -192,16 +205,19 @@ class ModeSettingsWidget(QtWidgets.QWidget):
strings._("mode_settings_advanced_toggle_show")
)
# Client auth is only a legacy option
# v2 client auth is only a legacy option
if self.client_auth_checkbox.isChecked():
self.legacy_checkbox.setChecked(True)
self.legacy_checkbox.setEnabled(False)
self.client_auth_v3_checkbox.hide()
else:
self.legacy_checkbox.setEnabled(True)
if self.legacy_checkbox.isChecked():
self.client_auth_checkbox.show()
self.client_auth_v3_checkbox.hide()
else:
self.client_auth_checkbox.hide()
self.client_auth_v3_checkbox.show()
# If the server has been started in the past, prevent changing legacy option
if self.settings.get("onion", "private_key"):
@ -209,10 +225,12 @@ class ModeSettingsWidget(QtWidgets.QWidget):
# If using legacy, disable legacy and client auth options
self.legacy_checkbox.setEnabled(False)
self.client_auth_checkbox.setEnabled(False)
self.client_auth_v3_checkbox.hide()
else:
# If using v3, hide legacy and client auth options
# If using v3, hide legacy and client auth options, show v3 client auth option
self.legacy_checkbox.hide()
self.client_auth_checkbox.hide()
self.client_auth_v3_checkbox.show()
def title_editing_finished(self):
if self.title_lineedit.text().strip() == "":
@ -283,6 +301,11 @@ class ModeSettingsWidget(QtWidgets.QWidget):
"general", "client_auth", self.client_auth_checkbox.isChecked()
)
def client_auth_v3_checkbox_clicked(self):
self.settings.set(
"general", "client_auth_v3", self.client_auth_v3_checkbox.isChecked()
)
def toggle_advanced_clicked(self):
if self.advanced_widget.isVisible():
self.advanced_widget.hide()

View file

@ -39,6 +39,7 @@ class ServerStatus(QtWidgets.QWidget):
button_clicked = QtCore.Signal()
url_copied = QtCore.Signal()
hidservauth_copied = QtCore.Signal()
client_auth_v3_copied = QtCore.Signal()
STATUS_STOPPED = 0
STATUS_WORKING = 1
@ -98,6 +99,9 @@ class ServerStatus(QtWidgets.QWidget):
self.copy_hidservauth_button = QtWidgets.QPushButton(
strings._("gui_copy_hidservauth")
)
self.copy_client_auth_v3_button = QtWidgets.QPushButton(
strings._("gui_copy_client_auth_v3")
)
self.show_url_qr_code_button = QtWidgets.QPushButton(
strings._("gui_show_url_qr_code")
)
@ -113,10 +117,15 @@ class ServerStatus(QtWidgets.QWidget):
self.common.gui.css["server_status_url_buttons"]
)
self.copy_hidservauth_button.clicked.connect(self.copy_hidservauth)
self.copy_client_auth_v3_button.setStyleSheet(
self.common.gui.css["server_status_url_buttons"]
)
self.copy_client_auth_v3_button.clicked.connect(self.copy_client_auth_v3)
url_buttons_layout = QtWidgets.QHBoxLayout()
url_buttons_layout.addWidget(self.copy_url_button)
url_buttons_layout.addWidget(self.show_url_qr_code_button)
url_buttons_layout.addWidget(self.copy_hidservauth_button)
url_buttons_layout.addWidget(self.copy_client_auth_v3_button)
url_buttons_layout.addStretch()
url_layout = QtWidgets.QVBoxLayout()
@ -218,6 +227,11 @@ class ServerStatus(QtWidgets.QWidget):
else:
self.copy_hidservauth_button.hide()
if self.settings.get("general", "client_auth_v3"):
self.copy_client_auth_v3_button.show()
else:
self.copy_client_auth_v3_button.hide()
def update(self):
"""
Update the GUI elements based on the current state.
@ -247,6 +261,7 @@ class ServerStatus(QtWidgets.QWidget):
self.url.hide()
self.copy_url_button.hide()
self.copy_hidservauth_button.hide()
self.copy_client_auth_v3_button.hide()
self.show_url_qr_code_button.hide()
self.mode_settings_widget.update_ui()
@ -454,6 +469,15 @@ class ServerStatus(QtWidgets.QWidget):
self.hidservauth_copied.emit()
def copy_client_auth_v3(self):
"""
Copy the ClientAuth v3 private key line to the clipboard.
"""
clipboard = self.qtapp.clipboard()
clipboard.setText(self.app.auth_string_v3)
self.client_auth_v3_copied.emit()
def get_url(self):
"""
Returns the OnionShare URL.

View file

@ -276,6 +276,7 @@ class Tab(QtWidgets.QWidget):
self.share_mode.server_status.button_clicked.connect(self.clear_message)
self.share_mode.server_status.url_copied.connect(self.copy_url)
self.share_mode.server_status.hidservauth_copied.connect(self.copy_hidservauth)
self.share_mode.server_status.client_auth_v3_copied.connect(self.copy_client_auth_v3)
self.change_title.emit(self.tab_id, strings._("gui_tab_name_share"))
@ -313,6 +314,9 @@ class Tab(QtWidgets.QWidget):
self.receive_mode.server_status.hidservauth_copied.connect(
self.copy_hidservauth
)
self.receive_mode.server_status.client_auth_v3_copied.connect(
self.copy_client_auth_v3
)
self.change_title.emit(self.tab_id, strings._("gui_tab_name_receive"))
@ -350,6 +354,9 @@ class Tab(QtWidgets.QWidget):
self.website_mode.server_status.hidservauth_copied.connect(
self.copy_hidservauth
)
self.website_mode.server_status.client_auth_v3_copied.connect(
self.copy_client_auth_v3
)
self.change_title.emit(self.tab_id, strings._("gui_tab_name_website"))
@ -383,6 +390,7 @@ class Tab(QtWidgets.QWidget):
self.chat_mode.server_status.button_clicked.connect(self.clear_message)
self.chat_mode.server_status.url_copied.connect(self.copy_url)
self.chat_mode.server_status.hidservauth_copied.connect(self.copy_hidservauth)
self.chat_mode.server_status.client_auth_v3_copied.connect(self.copy_client_auth_v3)
self.change_title.emit(self.tab_id, strings._("gui_tab_name_chat"))
@ -604,6 +612,16 @@ class Tab(QtWidgets.QWidget):
strings._("gui_copied_hidservauth"),
)
def copy_client_auth_v3(self):
"""
When the v3 onion service ClientAuth private key gets copied to the clipboard, display this in the status bar.
"""
self.common.log("Tab", "copy_client_auth_v3")
self.system_tray.showMessage(
strings._("gui_copied_client_auth_v3_title"),
strings._("gui_copied_client_auth_v3"),
)
def clear_message(self):
"""
Clear messages from the status bar.