From b2c310f2e01ba192b9c78f51313c33bbc0002579 Mon Sep 17 00:00:00 2001 From: irykoon Date: Thu, 15 Feb 2018 23:19:53 +0000 Subject: [PATCH 1/7] Support meek_lite Pluggable Transport Currently, meek/meek_lite is one of the few, if not only, mature pluggable transport that works in some heavily cenosored areas, for example, China. Therefore, this can be a nice feature to have. --- install/onionshare.nsi | 4 ++ install/pyinstaller.spec | 2 + onionshare/onion.py | 18 +++++++- onionshare/settings.py | 2 + onionshare_gui/settings_dialog.py | 61 +++++++++++++++++++++++++++ share/locale/en.json | 4 ++ share/torrc_template-meek_lite_amazon | 2 + share/torrc_template-meek_lite_azure | 2 + test/test_onionshare_settings.py | 4 ++ 9 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 share/torrc_template-meek_lite_amazon create mode 100644 share/torrc_template-meek_lite_azure diff --git a/install/onionshare.nsi b/install/onionshare.nsi index 9c15de47..2bb89e57 100644 --- a/install/onionshare.nsi +++ b/install/onionshare.nsi @@ -192,6 +192,8 @@ Section "install" File "${BINPATH}\share\torrc_template" File "${BINPATH}\share\torrc_template-windows" File "${BINPATH}\share\torrc_template-obfs4" + File "${BINPATH}\share\torrc_template-meek_lite_amazon" + File "${BINPATH}\share\torrc_template-meek_lite_azure" File "${BINPATH}\share\version.txt" File "${BINPATH}\share\wordlist.txt" @@ -404,6 +406,8 @@ FunctionEnd Delete "$INSTDIR\share\torrc_template" Delete "$INSTDIR\share\torrc_template-windows" Delete "$INSTDIR\share\torrc_template-obfs4" + Delete "$INSTDIR\share\torrc_template-meek_lite_amazon" + Delete "$INSTDIR\share\torrc_template-meek_lite_azure" Delete "$INSTDIR\share\version.txt" Delete "$INSTDIR\share\wordlist.txt" Delete "$INSTDIR\sip.pyd" diff --git a/install/pyinstaller.spec b/install/pyinstaller.spec index a38aaf6e..6ca2fdbe 100644 --- a/install/pyinstaller.spec +++ b/install/pyinstaller.spec @@ -15,6 +15,8 @@ a = Analysis( ('../share/wordlist.txt', 'share'), ('../share/torrc_template', 'share'), ('../share/torrc_template-obfs4', 'share'), + ('../share/torrc_template-meek_lite_amazon', 'share'), + ('../share/torrc_template-meek_lite_azure', 'share'), ('../share/torrc_template-windows', 'share'), ('../share/images/*', 'share/images'), ('../share/locale/*', 'share/locale'), diff --git a/onionshare/onion.py b/onionshare/onion.py index 6e48d3da..887650c9 100644 --- a/onionshare/onion.py +++ b/onionshare/onion.py @@ -211,9 +211,22 @@ class Onion(object): with open(common.get_resource_path('torrc_template-obfs4')) as o: for line in o: f.write(line) + elif self.settings.get('tor_bridges_use_meek_lite_amazon'): + f.write('ClientTransportPlugin meek_lite exec {}\n'.format(self.obfs4proxy_file_path)) + with open(common.get_resource_path('torrc_template-meek_lite_amazon')) as o: + for line in o: + f.write(line) + elif self.settings.get('tor_bridges_use_meek_lite_azure'): + f.write('ClientTransportPlugin meek_lite exec {}\n'.format(self.obfs4proxy_file_path)) + with open(common.get_resource_path('torrc_template-meek_lite_azure')) as o: + for line in o: + f.write(line) + if self.settings.get('tor_bridges_use_custom_bridges'): if 'obfs4' in self.settings.get('tor_bridges_use_custom_bridges'): f.write('ClientTransportPlugin obfs4 exec {}\n'.format(self.obfs4proxy_file_path)) + elif 'meek_lite' in self.settings.get('tor_bridges_use_custom_bridges'): + f.write('ClientTransportPlugin meek_lite exec {}\n'.format(self.obfs4proxy_file_path)) f.write(self.settings.get('tor_bridges_use_custom_bridges')) f.write('\nUseBridges 1') @@ -267,7 +280,10 @@ class Onion(object): time.sleep(0.2) # If using bridges, it might take a bit longer to connect to Tor - if self.settings.get('tor_bridges_use_custom_bridges') or self.settings.get('tor_bridges_use_obfs4'): + if self.settings.get('tor_bridges_use_custom_bridges') or \ + self.settings.get('tor_bridges_use_obfs4') or \ + self.settings.get('tor_bridges_use_meek_lite_amazon') or \ + self.settings.get('tor_bridges_use_meek_lite_azure'): connect_timeout = 150 else: # Timeout after 120 seconds diff --git a/onionshare/settings.py b/onionshare/settings.py index 94b5dde5..cf3728cc 100644 --- a/onionshare/settings.py +++ b/onionshare/settings.py @@ -63,6 +63,8 @@ class Settings(object): 'autoupdate_timestamp': None, 'no_bridges': True, 'tor_bridges_use_obfs4': False, + 'tor_bridges_use_meek_lite_amazon': False, + 'tor_bridges_use_meek_lite_azure': False, 'tor_bridges_use_custom_bridges': '', 'save_private_key': False, 'private_key': '', diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index dae3b6c5..de03a3da 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -156,6 +156,26 @@ class SettingsDialog(QtWidgets.QDialog): self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_obfs4_radio_option', True)) self.tor_bridges_use_obfs4_radio.toggled.connect(self.tor_bridges_use_obfs4_radio_toggled) + # meek_lite-amazon option radio + # if the obfs4proxy binary is missing, we can't use meek_lite-amazon transports + (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = common.get_tor_paths() + if not os.path.isfile(self.obfs4proxy_file_path): + self.tor_bridges_use_meek_lite_amazon_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_amazon_radio_option_no_obfs4proxy', True)) + self.tor_bridges_use_meel_lite_amazon_radio.setEnabled(False) + else: + self.tor_bridges_use_meek_lite_amazon_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_amazon_radio_option', True)) + self.tor_bridges_use_meek_lite_amazon_radio.toggled.connect(self.tor_bridges_use_meek_lite_amazon_radio_toggled) + + # meek_lite-azure option radio + # if the obfs4proxy binary is missing, we can't use meek_lite-azure transports + (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = common.get_tor_paths() + if not os.path.isfile(self.obfs4proxy_file_path): + self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_azure_radio_option_no_obfs4proxy', True)) + self.tor_bridges_use_meel_lite_azure_radio.setEnabled(False) + else: + self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_azure_radio_option', True)) + self.tor_bridges_use_meek_lite_azure_radio.toggled.connect(self.tor_bridges_use_meek_lite_azure_radio_toggled) + # Custom bridges radio and textbox self.tor_bridges_use_custom_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_custom_radio_option', True)) self.tor_bridges_use_custom_radio.toggled.connect(self.tor_bridges_use_custom_radio_toggled) @@ -179,6 +199,8 @@ class SettingsDialog(QtWidgets.QDialog): bridges_layout = QtWidgets.QVBoxLayout() bridges_layout.addWidget(self.tor_bridges_no_bridges_radio) bridges_layout.addWidget(self.tor_bridges_use_obfs4_radio) + bridges_layout.addWidget(self.tor_bridges_use_meek_lite_amazon_radio) + bridges_layout.addWidget(self.tor_bridges_use_meek_lite_azure_radio) bridges_layout.addWidget(self.tor_bridges_use_custom_radio) bridges_layout.addWidget(self.tor_bridges_use_custom_textbox_options) @@ -401,10 +423,15 @@ class SettingsDialog(QtWidgets.QDialog): if self.old_settings.get('no_bridges'): self.tor_bridges_no_bridges_radio.setChecked(True) self.tor_bridges_use_obfs4_radio.setChecked(False) + self.tor_bridges_use_meek_lite_amazon_radio.setChecked(False) + self.tor_bridges_use_meek_lite_azure_radio.setChecked(False) self.tor_bridges_use_custom_radio.setChecked(False) else: self.tor_bridges_no_bridges_radio.setChecked(False) self.tor_bridges_use_obfs4_radio.setChecked(self.old_settings.get('tor_bridges_use_obfs4')) + self.tor_bridges_use_meek_lite_amazon_radio.setChecked(self.old_settings.get('tor_bridges_use_meek_lite_amazon')) + self.tor_bridges_use_meek_lite_azure_radio.setChecked(self.old_settings.get('tor_bridges_use_meek_lite_azure')) + if self.old_settings.get('tor_bridges_use_custom_bridges'): self.tor_bridges_use_custom_radio.setChecked(True) # Remove the 'Bridge' lines at the start of each bridge. @@ -441,6 +468,20 @@ class SettingsDialog(QtWidgets.QDialog): if checked: self.tor_bridges_use_custom_textbox_options.hide() + def tor_bridges_use_meek_lite_amazon_radio_toggled(self, checked): + """ + meek_lite-amazon bridges option was toggled. If checked, disable custom bridge options. + """ + if checked: + self.tor_bridges_use_custom_textbox_options.hide() + + def tor_bridges_use_meek_lite_azure_radio_toggled(self, checked): + """ + meel_lite_azure bridges option was toggled. If checked, disable custom bridge options. + """ + if checked: + self.tor_bridges_use_custom_textbox_options.hide() + def tor_bridges_use_custom_radio_toggled(self, checked): """ Custom bridges option was toggled. If checked, show custom bridge options. @@ -624,6 +665,7 @@ class SettingsDialog(QtWidgets.QDialog): 'control_port_port', 'socks_address', 'socks_port', 'socket_file_path', 'auth_type', 'auth_password', 'no_bridges', 'tor_bridges_use_obfs4', + 'tor_bridges_use_meek_lite_amazon', 'tor_bridges_use_meek_lite_azure', 'tor_bridges_use_custom_bridges']): reboot_onion = True @@ -729,14 +771,33 @@ class SettingsDialog(QtWidgets.QDialog): if self.tor_bridges_no_bridges_radio.isChecked(): settings.set('no_bridges', True) settings.set('tor_bridges_use_obfs4', False) + settings.set('tor_bridges_use_meek_lite_amazon', False) + settings.set('tor_bridges_use_meek_lite_azure', False) settings.set('tor_bridges_use_custom_bridges', '') if self.tor_bridges_use_obfs4_radio.isChecked(): settings.set('no_bridges', False) settings.set('tor_bridges_use_obfs4', True) + settings.set('tor_bridges_use_meek_lite_amazon', False) + settings.set('tor_bridges_use_meek_lite_azure', False) + settings.set('tor_bridges_use_custom_bridges', '') + if self.tor_bridges_use_meek_lite_amazon_radio.isChecked(): + settings.set('no_bridges', False) + settings.set('tor_bridges_use_obfs4', False) + settings.set('tor_bridges_use_meek_lite_amazon', True) + settings.set('tor_bridges_use_meek_lite_azure', False) + settings.set('tor_bridges_use_custom_bridges', '') + if self.tor_bridges_use_meek_lite_azure_radio.isChecked(): + settings.set('no_bridges', False) + settings.set('tor_bridges_use_obfs4', False) + settings.set('tor_bridges_use_meek_lite_amazon', False) + settings.set('tor_bridges_use_meek_lite_azure', True) settings.set('tor_bridges_use_custom_bridges', '') if self.tor_bridges_use_custom_radio.isChecked(): settings.set('no_bridges', False) settings.set('tor_bridges_use_obfs4', False) + settings.set('tor_bridges_use_meek_lite_amazon', False) + settings.set('tor_bridges_use_meek_lite_azure', False) + # Insert a 'Bridge' line at the start of each bridge. # This makes it easier to copy/paste a set of bridges # provided from https://bridges.torproject.org diff --git a/share/locale/en.json b/share/locale/en.json index eff0cae4..9739448f 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -95,6 +95,10 @@ "gui_settings_tor_bridges_no_bridges_radio_option": "Don't use bridges", "gui_settings_tor_bridges_obfs4_radio_option": "Use built-in obfs4 pluggable transports", "gui_settings_tor_bridges_obfs4_radio_option_no_obfs4proxy": "Use built-in obfs4 pluggable transports (requires obfs4proxy)", + "gui_settings_tor_bridges_meek_lite_amazon_radio_option": "Use built-in meek_lite_amazon pluggable transports", + "gui_settings_tor_bridges_meek_lite_amazon_radio_option_no_meek_lite_obfs4proxy": "Use built-in meek_lite_amazon pluggable transports (requires obfs4proxy)", + "gui_settings_tor_bridges_meek_lite_azure_radio_option": "Use built-in meek_lite_azure pluggable transports", + "gui_settings_tor_bridges_meek_lite_azure_radio_option_no_obfs4proxy": "Use built-in meek_lite_azure pluggable transports (requires obfs4proxy)", "gui_settings_tor_bridges_custom_radio_option": "Use custom bridges", "gui_settings_tor_bridges_custom_label": "You can get bridges from https://bridges.torproject.org", "gui_settings_tor_bridges_invalid": "None of the bridges you supplied seem to be valid, so they've been ignored.\nPlease try again with valid bridges.", diff --git a/share/torrc_template-meek_lite_amazon b/share/torrc_template-meek_lite_amazon new file mode 100644 index 00000000..606ae889 --- /dev/null +++ b/share/torrc_template-meek_lite_amazon @@ -0,0 +1,2 @@ +Bridge meek_lite 0.0.2.0:2 B9E7141C594AF25699E0079C1F0146F409495296 url=https://d2cly7j4zqgua7.cloudfront.net/ front=a0.awsstatic.com +UseBridges 1 \ No newline at end of file diff --git a/share/torrc_template-meek_lite_azure b/share/torrc_template-meek_lite_azure new file mode 100644 index 00000000..a9b374ba --- /dev/null +++ b/share/torrc_template-meek_lite_azure @@ -0,0 +1,2 @@ +Bridge meek_lite 0.0.2.0:3 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com +UseBridges 1 \ No newline at end of file diff --git a/test/test_onionshare_settings.py b/test/test_onionshare_settings.py index b17ce30a..24c46042 100644 --- a/test/test_onionshare_settings.py +++ b/test/test_onionshare_settings.py @@ -60,6 +60,8 @@ class TestSettings: 'autoupdate_timestamp': None, 'no_bridges': True, 'tor_bridges_use_obfs4': False, + 'tor_bridges_use_meek_lite_amazon': False, + 'tor_bridges_use_meek_lite_azure': False, 'tor_bridges_use_custom_bridges': '', 'save_private_key': False, 'private_key': '', @@ -125,6 +127,8 @@ class TestSettings: assert settings_obj.get('autoupdate_timestamp') is None assert settings_obj.get('no_bridges') is True assert settings_obj.get('tor_bridges_use_obfs4') is False + assert settings_obj.get('tor_bridges_use_meek_lite_amazon') is False + assert settings_obj.get('tor_bridges_use_meek_lite_azure') is False assert settings_obj.get('tor_bridges_use_custom_bridges') == '' From 85afd855876c979ccba9f896d9b7c373b5514ab6 Mon Sep 17 00:00:00 2001 From: irykoon Date: Mon, 19 Feb 2018 07:34:09 +0000 Subject: [PATCH 2/7] Adopt more user-friendly wording Thank you @mig5 for the great suggestion. --- share/locale/en.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/share/locale/en.json b/share/locale/en.json index 9739448f..7f82c9bf 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -95,10 +95,10 @@ "gui_settings_tor_bridges_no_bridges_radio_option": "Don't use bridges", "gui_settings_tor_bridges_obfs4_radio_option": "Use built-in obfs4 pluggable transports", "gui_settings_tor_bridges_obfs4_radio_option_no_obfs4proxy": "Use built-in obfs4 pluggable transports (requires obfs4proxy)", - "gui_settings_tor_bridges_meek_lite_amazon_radio_option": "Use built-in meek_lite_amazon pluggable transports", - "gui_settings_tor_bridges_meek_lite_amazon_radio_option_no_meek_lite_obfs4proxy": "Use built-in meek_lite_amazon pluggable transports (requires obfs4proxy)", - "gui_settings_tor_bridges_meek_lite_azure_radio_option": "Use built-in meek_lite_azure pluggable transports", - "gui_settings_tor_bridges_meek_lite_azure_radio_option_no_obfs4proxy": "Use built-in meek_lite_azure pluggable transports (requires obfs4proxy)", + "gui_settings_tor_bridges_meek_lite_amazon_radio_option": "Use built-in meek_lite (Amazon) pluggable transports", + "gui_settings_tor_bridges_meek_lite_amazon_radio_option_no_meek_lite_obfs4proxy": "Use built-in meek_lite (Amazon) pluggable transports (requires obfs4proxy)", + "gui_settings_tor_bridges_meek_lite_azure_radio_option": "Use built-in meek_lite (Azure) pluggable transports", + "gui_settings_tor_bridges_meek_lite_azure_radio_option_no_obfs4proxy": "Use built-in meek_lite (Azure) pluggable transports (requires obfs4proxy)", "gui_settings_tor_bridges_custom_radio_option": "Use custom bridges", "gui_settings_tor_bridges_custom_label": "You can get bridges from https://bridges.torproject.org", "gui_settings_tor_bridges_invalid": "None of the bridges you supplied seem to be valid, so they've been ignored.\nPlease try again with valid bridges.", From 02c16ce179c2aca282a7aca562aa919b85619a1c Mon Sep 17 00:00:00 2001 From: irykoon Date: Tue, 20 Feb 2018 01:24:44 +0000 Subject: [PATCH 3/7] Add meek_lite support for custom bridges --- onionshare_gui/settings_dialog.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index de03a3da..4dafdd9e 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -809,7 +809,10 @@ class SettingsDialog(QtWidgets.QDialog): # Check the syntax of the custom bridge to make sure it looks legitimate ipv4_pattern = re.compile("(obfs4\s)?(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9]+\s[A-Z0-9]+(.+)?$") ipv6_pattern = re.compile("(obfs4\s)?\[(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\]:[0-9]+\s[A-Z0-9]+(.+)?$") - if ipv4_pattern.match(bridge) or ipv6_pattern.match(bridge): + meek_lite_pattern = re.compile("(meek_lite)(\s)+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)(\s)+([0-9A-Z]+)(\s)+url=(.+)(\s)+front=(.+)") + if ipv4_pattern.match(bridge) or \ + ipv6_pattern.match(bridge) or \ + meek_lite_pattern.match(bridge): new_bridges.append(''.join(['Bridge ', bridge, '\n'])) bridges_valid = True if bridges_valid: From 2cdfcea2417dcb4877f87b3dd81d3e92d407ad2c Mon Sep 17 00:00:00 2001 From: irykoon Date: Tue, 20 Feb 2018 01:26:02 +0000 Subject: [PATCH 4/7] Adopt a more robust RE for custom obfs4 bridges --- onionshare_gui/settings_dialog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index 4dafdd9e..67dfcff3 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -807,7 +807,7 @@ class SettingsDialog(QtWidgets.QDialog): for bridge in bridges: if bridge != '': # Check the syntax of the custom bridge to make sure it looks legitimate - ipv4_pattern = re.compile("(obfs4\s)?(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9]+\s[A-Z0-9]+(.+)?$") + ipv4_pattern = re.compile("(obfs4)(\s)+(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):([0-9]+)(\s+)([A-Z0-9]+)(\s+)cert=(.+)$") ipv6_pattern = re.compile("(obfs4\s)?\[(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\]:[0-9]+\s[A-Z0-9]+(.+)?$") meek_lite_pattern = re.compile("(meek_lite)(\s)+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)(\s)+([0-9A-Z]+)(\s)+url=(.+)(\s)+front=(.+)") if ipv4_pattern.match(bridge) or \ From d03ad0ab30509294af52d8c5abc53e7b429474a3 Mon Sep 17 00:00:00 2001 From: irykoon Date: Tue, 20 Feb 2018 01:33:58 +0000 Subject: [PATCH 5/7] Adopt a more robust RE for custom obfs4 IPV6 bridges --- onionshare_gui/settings_dialog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index 67dfcff3..3b91709e 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -808,7 +808,7 @@ class SettingsDialog(QtWidgets.QDialog): if bridge != '': # Check the syntax of the custom bridge to make sure it looks legitimate ipv4_pattern = re.compile("(obfs4)(\s)+(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):([0-9]+)(\s+)([A-Z0-9]+)(\s+)cert=(.+)$") - ipv6_pattern = re.compile("(obfs4\s)?\[(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\]:[0-9]+\s[A-Z0-9]+(.+)?$") + ipv6_pattern = re.compile("(obfs4)(\s+)\[(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\]:[0-9]+(\s+)[A-Z0-9]+(\s+)cert=(.+)$") meek_lite_pattern = re.compile("(meek_lite)(\s)+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)(\s)+([0-9A-Z]+)(\s)+url=(.+)(\s)+front=(.+)") if ipv4_pattern.match(bridge) or \ ipv6_pattern.match(bridge) or \ From 53510bf43e8ded97acf8e67c1c6e105d3441a935 Mon Sep 17 00:00:00 2001 From: irykoon Date: Tue, 20 Feb 2018 03:25:43 +0000 Subject: [PATCH 6/7] Take care of custom vanilla bridges Thank you @mig5 for pointing this out. --- onionshare_gui/settings_dialog.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index 3b91709e..424f2589 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -807,8 +807,8 @@ class SettingsDialog(QtWidgets.QDialog): for bridge in bridges: if bridge != '': # Check the syntax of the custom bridge to make sure it looks legitimate - ipv4_pattern = re.compile("(obfs4)(\s)+(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):([0-9]+)(\s+)([A-Z0-9]+)(\s+)cert=(.+)$") - ipv6_pattern = re.compile("(obfs4)(\s+)\[(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\]:[0-9]+(\s+)[A-Z0-9]+(\s+)cert=(.+)$") + ipv4_pattern = re.compile("(obfs4\s+)?(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):([0-9]+)(\s+)([A-Z0-9]+)(.+)$") + ipv6_pattern = re.compile("(obfs4\s+)?\[(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\]:[0-9]+\s+[A-Z0-9]+(.+)$") meek_lite_pattern = re.compile("(meek_lite)(\s)+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)(\s)+([0-9A-Z]+)(\s)+url=(.+)(\s)+front=(.+)") if ipv4_pattern.match(bridge) or \ ipv6_pattern.match(bridge) or \ From 61384e67686e800c317b9c664dc157cacdabbbc7 Mon Sep 17 00:00:00 2001 From: irykoon Date: Tue, 20 Feb 2018 05:45:15 +0000 Subject: [PATCH 7/7] Fix typo Again, many thanks to the careful review by @mig5 ! --- share/locale/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/locale/en.json b/share/locale/en.json index 7f82c9bf..5bc2dc8d 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -96,7 +96,7 @@ "gui_settings_tor_bridges_obfs4_radio_option": "Use built-in obfs4 pluggable transports", "gui_settings_tor_bridges_obfs4_radio_option_no_obfs4proxy": "Use built-in obfs4 pluggable transports (requires obfs4proxy)", "gui_settings_tor_bridges_meek_lite_amazon_radio_option": "Use built-in meek_lite (Amazon) pluggable transports", - "gui_settings_tor_bridges_meek_lite_amazon_radio_option_no_meek_lite_obfs4proxy": "Use built-in meek_lite (Amazon) pluggable transports (requires obfs4proxy)", + "gui_settings_tor_bridges_meek_lite_amazon_radio_option_no_obfs4proxy": "Use built-in meek_lite (Amazon) pluggable transports (requires obfs4proxy)", "gui_settings_tor_bridges_meek_lite_azure_radio_option": "Use built-in meek_lite (Azure) pluggable transports", "gui_settings_tor_bridges_meek_lite_azure_radio_option_no_obfs4proxy": "Use built-in meek_lite (Azure) pluggable transports (requires obfs4proxy)", "gui_settings_tor_bridges_custom_radio_option": "Use custom bridges",