onionshare_cli 2.6.1__tar.gz → 2.6.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/PKG-INFO +9 -10
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/__init__.py +12 -1
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/censorship.py +17 -15
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/common.py +9 -8
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/meek.py +2 -2
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/mode_settings.py +16 -3
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/onion.py +4 -2
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/receive.html +1 -1
- onionshare_cli-2.6.3/onionshare_cli/resources/torrc_template-meek_lite_azure +2 -0
- onionshare_cli-2.6.3/onionshare_cli/resources/torrc_template-snowflake +3 -0
- onionshare_cli-2.6.3/onionshare_cli/resources/version.txt +1 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/settings.py +4 -3
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/web/chat_mode.py +70 -23
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/web/receive_mode.py +5 -2
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/web/send_base_mode.py +28 -12
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/web/share_mode.py +12 -4
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/web/web.py +10 -4
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/pyproject.toml +8 -8
- onionshare_cli-2.6.1/onionshare_cli/resources/torrc_template-meek_lite_azure +0 -2
- onionshare_cli-2.6.1/onionshare_cli/resources/torrc_template-snowflake +0 -3
- onionshare_cli-2.6.1/onionshare_cli/resources/version.txt +0 -1
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/onionshare.py +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/css/style.css +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/img/ajax.gif +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/img/favicon.ico +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/img/logo.png +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/img/logo_large.png +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/img/web_file.png +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/img/web_folder.png +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/js/chat.js +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/js/jquery-3.5.1.min.js +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/js/receive.js +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/js/send.js +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/js/socket.io.js +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/js/socket.io.min.js +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/403.html +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/404.html +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/405.html +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/500.html +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/chat.html +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/denied.html +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/listing.html +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/send.html +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/thankyou.html +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/torrc_template +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/torrc_template-obfs4 +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/wordlist.txt +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/web/__init__.py +0 -0
- {onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/web/website_mode.py +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: onionshare_cli
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.3
|
|
4
4
|
Summary: OnionShare lets you securely and anonymously send and receive files. It works by starting a web server, making it accessible as a Tor onion service, and generating an unguessable web address so others can download files from you, or upload files to you. It does _not_ require setting up a separate server or using a third party file-sharing service.
|
|
5
5
|
License: GPLv3+
|
|
6
6
|
Author: Micah Lee
|
|
7
7
|
Author-email: micah@micahflee.com
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.10,<3.13
|
|
9
9
|
Classifier: Environment :: Web Environment
|
|
10
10
|
Classifier: Framework :: Flask
|
|
11
11
|
Classifier: Intended Audience :: End Users/Desktop
|
|
@@ -13,10 +13,9 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (G
|
|
|
13
13
|
Classifier: License :: Other/Proprietary License
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
19
|
Classifier: Topic :: Communications :: File Sharing
|
|
21
20
|
Classifier: Topic :: Security :: Cryptography
|
|
22
21
|
Requires-Dist: cffi (>=1.15.1,<2.0.0)
|
|
@@ -29,16 +28,16 @@ Requires-Dist: flask-compress (>=1.13,<2.0)
|
|
|
29
28
|
Requires-Dist: flask-socketio (==5.3.4)
|
|
30
29
|
Requires-Dist: gevent (>=23.9.1,<24.0.0)
|
|
31
30
|
Requires-Dist: gevent-websocket
|
|
32
|
-
Requires-Dist: packaging (>=
|
|
31
|
+
Requires-Dist: packaging (>=24)
|
|
33
32
|
Requires-Dist: psutil
|
|
34
33
|
Requires-Dist: pynacl
|
|
35
34
|
Requires-Dist: pysocks
|
|
36
35
|
Requires-Dist: qrcode (>=7.4.2,<8.0.0)
|
|
37
36
|
Requires-Dist: requests[socks]
|
|
38
|
-
Requires-Dist: setuptools
|
|
37
|
+
Requires-Dist: setuptools (>=70.0.0)
|
|
39
38
|
Requires-Dist: stem (==1.8.1)
|
|
40
39
|
Requires-Dist: unidecode
|
|
41
|
-
Requires-Dist: urllib3
|
|
42
|
-
Requires-Dist: waitress (>=
|
|
43
|
-
Requires-Dist: werkzeug (
|
|
40
|
+
Requires-Dist: urllib3 (>=2.2.2,<3.0.0)
|
|
41
|
+
Requires-Dist: waitress (>=3.0.1,<4.0.0)
|
|
42
|
+
Requires-Dist: werkzeug (==3.0.6)
|
|
44
43
|
Requires-Dist: wheel (>=0.41.2,<0.42.0)
|
|
@@ -119,6 +119,13 @@ def main(cwd=None):
|
|
|
119
119
|
default=False,
|
|
120
120
|
help="Share files: Continue sharing after files have been sent (default is to stop sharing)",
|
|
121
121
|
)
|
|
122
|
+
parser.add_argument(
|
|
123
|
+
"--log-filenames",
|
|
124
|
+
action="store_true",
|
|
125
|
+
dest="log_filenames",
|
|
126
|
+
default=False,
|
|
127
|
+
help="Log file download activity to stdout"
|
|
128
|
+
)
|
|
122
129
|
parser.add_argument(
|
|
123
130
|
"--qr",
|
|
124
131
|
action="store_true",
|
|
@@ -204,6 +211,7 @@ def main(cwd=None):
|
|
|
204
211
|
disable_files = args.disable_files
|
|
205
212
|
disable_csp = bool(args.disable_csp)
|
|
206
213
|
custom_csp = args.custom_csp
|
|
214
|
+
log_filenames = bool(args.log_filenames)
|
|
207
215
|
verbose = bool(args.verbose)
|
|
208
216
|
|
|
209
217
|
# Verbose mode?
|
|
@@ -242,6 +250,7 @@ def main(cwd=None):
|
|
|
242
250
|
mode_settings.set("persistent", "mode", mode)
|
|
243
251
|
if mode == "share":
|
|
244
252
|
mode_settings.set("share", "autostop_sharing", autostop_sharing)
|
|
253
|
+
mode_settings.set("share", "log_filenames", log_filenames)
|
|
245
254
|
if mode == "receive":
|
|
246
255
|
if data_dir:
|
|
247
256
|
mode_settings.set("receive", "data_dir", data_dir)
|
|
@@ -259,6 +268,7 @@ def main(cwd=None):
|
|
|
259
268
|
if custom_csp:
|
|
260
269
|
mode_settings.set("website", "custom_csp", custom_csp)
|
|
261
270
|
mode_settings.set("website", "disable_csp", False)
|
|
271
|
+
mode_settings.set("website", "log_filenames", log_filenames)
|
|
262
272
|
else:
|
|
263
273
|
# See what the persistent mode was
|
|
264
274
|
mode = mode_settings.get("persistent", "mode")
|
|
@@ -505,7 +515,7 @@ def main(cwd=None):
|
|
|
505
515
|
if not app.autostop_timer_thread.is_alive():
|
|
506
516
|
if mode == "share":
|
|
507
517
|
# If there were no attempts to download the share, or all downloads are done, we can stop
|
|
508
|
-
if web.share_mode.cur_history_id == 0 or web.done:
|
|
518
|
+
if not web.share_mode.download_in_progress or web.share_mode.cur_history_id == 0 or web.done:
|
|
509
519
|
print("Stopped because auto-stop timer ran out")
|
|
510
520
|
web.stop(app.port)
|
|
511
521
|
break
|
|
@@ -531,6 +541,7 @@ def main(cwd=None):
|
|
|
531
541
|
finally:
|
|
532
542
|
# Shutdown
|
|
533
543
|
web.cleanup()
|
|
544
|
+
t.join()
|
|
534
545
|
onion.cleanup()
|
|
535
546
|
|
|
536
547
|
|
|
@@ -238,21 +238,23 @@ class CensorshipCircumvention(object):
|
|
|
238
238
|
bridges_ok = False
|
|
239
239
|
self.settings = settings
|
|
240
240
|
|
|
241
|
-
#
|
|
242
|
-
#
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
241
|
+
# We iterate over each group of bridges returned in settings.
|
|
242
|
+
# The first set of valid bridges are the ones we use.
|
|
243
|
+
if bridge_settings.get("settings", False):
|
|
244
|
+
for returned_bridge_settings in bridge_settings["settings"]:
|
|
245
|
+
if returned_bridge_settings.get("bridges", False):
|
|
246
|
+
bridges = returned_bridge_settings["bridges"]
|
|
247
|
+
bridge_strings = bridges["bridge_strings"]
|
|
248
|
+
|
|
249
|
+
self.settings.set("bridges_type", "custom")
|
|
250
|
+
|
|
251
|
+
# Sanity check the bridges provided from the Tor API before saving
|
|
252
|
+
bridges_checked = self.common.check_bridges_valid(bridge_strings)
|
|
253
|
+
|
|
254
|
+
if bridges_checked:
|
|
255
|
+
self.settings.set("bridges_custom", "\n".join(bridges_checked))
|
|
256
|
+
bridges_ok = True
|
|
257
|
+
break
|
|
256
258
|
|
|
257
259
|
# If we got any good bridges, save them to settings and return.
|
|
258
260
|
if bridges_ok:
|
|
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
19
19
|
"""
|
|
20
20
|
import base64
|
|
21
21
|
import hashlib
|
|
22
|
+
import importlib.resources as importlib_resources
|
|
22
23
|
import os
|
|
23
24
|
import platform
|
|
24
25
|
import random
|
|
@@ -29,7 +30,6 @@ import threading
|
|
|
29
30
|
import time
|
|
30
31
|
import shutil
|
|
31
32
|
import re
|
|
32
|
-
from pkg_resources import resource_filename
|
|
33
33
|
|
|
34
34
|
import colorama
|
|
35
35
|
from colorama import Fore, Back, Style
|
|
@@ -313,9 +313,10 @@ class Common:
|
|
|
313
313
|
"""
|
|
314
314
|
Returns the absolute path of a resource
|
|
315
315
|
"""
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
316
|
+
ref = importlib_resources.files("onionshare_cli.resources") / filename
|
|
317
|
+
with importlib_resources.as_file(ref) as path:
|
|
318
|
+
self.log("Common", "get_resource_path", f"filename={filename}, path={str(path)}")
|
|
319
|
+
return str(path)
|
|
319
320
|
|
|
320
321
|
def get_tor_paths(self):
|
|
321
322
|
if self.platform == "Linux":
|
|
@@ -484,16 +485,16 @@ class Common:
|
|
|
484
485
|
if bridge != "":
|
|
485
486
|
# Check the syntax of the custom bridge to make sure it looks legitimate
|
|
486
487
|
ipv4_pattern = re.compile(
|
|
487
|
-
"(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]+)(.+)$"
|
|
488
|
+
r"(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]+)(.+)$"
|
|
488
489
|
)
|
|
489
490
|
ipv6_pattern = re.compile(
|
|
490
|
-
"(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]+(.+)$"
|
|
491
|
+
r"(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]+(.+)$"
|
|
491
492
|
)
|
|
492
493
|
meek_lite_pattern = re.compile(
|
|
493
|
-
"(meek_lite)(\s)+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)(\s)+([0-9A-Z]+)(\s)+url=(.+)(\s)+front=(.+)"
|
|
494
|
+
r"(meek_lite)(\s)+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)(\s)+([0-9A-Z]+)(\s)+url=(.+)(\s)+front=(.+)"
|
|
494
495
|
)
|
|
495
496
|
snowflake_pattern = re.compile(
|
|
496
|
-
"(snowflake)(\s)+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)(\s)+([0-9A-Z]+)"
|
|
497
|
+
r"(snowflake)(\s)+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)(\s)+([0-9A-Z]+)"
|
|
497
498
|
)
|
|
498
499
|
if (
|
|
499
500
|
ipv4_pattern.match(bridge)
|
|
@@ -51,8 +51,8 @@ class Meek(object):
|
|
|
51
51
|
) = get_tor_paths()
|
|
52
52
|
|
|
53
53
|
self.meek_proxies = {}
|
|
54
|
-
self.meek_url = "https://
|
|
55
|
-
self.meek_front = "
|
|
54
|
+
self.meek_url = "https://1723079976.rsc.cdn77.org/"
|
|
55
|
+
self.meek_front = "www.phpmyadmin.net"
|
|
56
56
|
self.meek_env = {
|
|
57
57
|
"TOR_PT_MANAGED_TRANSPORT_VER": "1",
|
|
58
58
|
"TOR_PT_CLIENT_TRANSPORTS": "meek",
|
|
@@ -40,7 +40,11 @@ class ModeSettings:
|
|
|
40
40
|
"client_auth_priv_key": None,
|
|
41
41
|
"client_auth_pub_key": None,
|
|
42
42
|
},
|
|
43
|
-
"persistent": {
|
|
43
|
+
"persistent": {
|
|
44
|
+
"mode": None,
|
|
45
|
+
"enabled": False,
|
|
46
|
+
"autostart_on_launch": False
|
|
47
|
+
},
|
|
44
48
|
"general": {
|
|
45
49
|
"title": None,
|
|
46
50
|
"public": False,
|
|
@@ -48,14 +52,23 @@ class ModeSettings:
|
|
|
48
52
|
"autostop_timer": False,
|
|
49
53
|
"service_id": None,
|
|
50
54
|
},
|
|
51
|
-
"share": {
|
|
55
|
+
"share": {
|
|
56
|
+
"autostop_sharing": True,
|
|
57
|
+
"filenames": [],
|
|
58
|
+
"log_filenames": False,
|
|
59
|
+
},
|
|
52
60
|
"receive": {
|
|
53
61
|
"data_dir": self.build_default_receive_data_dir(),
|
|
54
62
|
"webhook_url": None,
|
|
55
63
|
"disable_text": False,
|
|
56
64
|
"disable_files": False,
|
|
57
65
|
},
|
|
58
|
-
"website": {
|
|
66
|
+
"website": {
|
|
67
|
+
"disable_csp": False,
|
|
68
|
+
"custom_csp": None,
|
|
69
|
+
"log_filenames": False,
|
|
70
|
+
"filenames": []
|
|
71
|
+
},
|
|
59
72
|
"chat": {},
|
|
60
73
|
}
|
|
61
74
|
self._settings = {}
|
|
@@ -27,13 +27,14 @@ import base64
|
|
|
27
27
|
import nacl.public
|
|
28
28
|
import os
|
|
29
29
|
import psutil
|
|
30
|
+
import re
|
|
30
31
|
import shlex
|
|
31
32
|
import subprocess
|
|
32
33
|
import tempfile
|
|
33
34
|
import time
|
|
34
35
|
import traceback
|
|
35
36
|
|
|
36
|
-
from
|
|
37
|
+
from packaging.version import Version
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
class TorErrorAutomatic(Exception):
|
|
@@ -658,7 +659,8 @@ class Onion(object):
|
|
|
658
659
|
# Does this version of Tor support next-gen ('v3') onions?
|
|
659
660
|
# Note, this is the version of Tor where this bug was fixed:
|
|
660
661
|
# https://trac.torproject.org/projects/tor/ticket/28619
|
|
661
|
-
|
|
662
|
+
cleaned_tor_version = re.sub(r"\s*\(.*\)", "", self.tor_version)
|
|
663
|
+
self.supports_v3_onions = Version(cleaned_tor_version) >= Version("0.3.5.7")
|
|
662
664
|
|
|
663
665
|
# Now that we are connected to Tor, if we are using built-in bridges,
|
|
664
666
|
# update them with the latest copy available from the Tor API
|
{onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/receive.html
RENAMED
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
<p><input type="file" id="file-select" name="file[]" multiple /></p>
|
|
54
54
|
{% endif %}
|
|
55
55
|
{% if not disable_text %}
|
|
56
|
-
<p><textarea id="text" name="text" placeholder="Write a message"></textarea></p>
|
|
56
|
+
<p><textarea id="text" name="text" placeholder="Write a message (max length 524288 characters)" maxlength="524288"></textarea></p>
|
|
57
57
|
{% endif %}
|
|
58
58
|
<p><button type="submit" id="send-button" class="button">Submit</button></p>
|
|
59
59
|
</form>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Enable built-in snowflake bridge
|
|
2
|
+
Bridge snowflake 192.0.2.3:80 2B280B23E1107BB62ABFC40DDCC8824814F80A72 fingerprint=2B280B23E1107BB62ABFC40DDCC8824814F80A72 url=https://1098762253.rsc.cdn77.org/ fronts=www.cdn77.com,www.phpmyadmin.net ice=stun:stun.antisip.com:3478,stun:stun.epygi.com:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.mixvoip.com:3478,stun:stun.nextcloud.com:3478,stun:stun.bethesda.net:3478,stun:stun.nextcloud.com:443 utls-imitate=hellorandomizedalpn
|
|
3
|
+
Bridge snowflake 192.0.2.4:80 8838024498816A039FCBBAB14E6F40A0843051FA fingerprint=8838024498816A039FCBBAB14E6F40A0843051FA url=https://1098762253.rsc.cdn77.org/ fronts=www.cdn77.com,www.phpmyadmin.net ice=stun:stun.antisip.com:3478,stun:stun.epygi.com:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.mixvoip.com:3478,stun:stun.nextcloud.com:3478,stun:stun.bethesda.net:3478,stun:stun.nextcloud.com:443 utls-imitate=hellorandomizedalpn
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.6.3
|
|
@@ -66,7 +66,7 @@ class Settings(object):
|
|
|
66
66
|
"zh_Hans": "中文 (简体)", # Simplified Chinese
|
|
67
67
|
"hr": "Hrvatski", # Croatian
|
|
68
68
|
"cs": "čeština", # Czech
|
|
69
|
-
|
|
69
|
+
"da": "Dansk", # Danish
|
|
70
70
|
# "nl": "Nederlands", # Dutch
|
|
71
71
|
"en": "English", # English
|
|
72
72
|
"fi": "Suomi", # Finnish
|
|
@@ -76,7 +76,7 @@ class Settings(object):
|
|
|
76
76
|
"el": "Ελληνικά", # Greek
|
|
77
77
|
"is": "Íslenska", # Icelandic
|
|
78
78
|
# "id": "Bahasa Indonesia", # Indonesian
|
|
79
|
-
|
|
79
|
+
"ga": "Gaeilge", # Irish
|
|
80
80
|
"it": "Italiano", # Italian
|
|
81
81
|
"ja": "日本語", # Japanese
|
|
82
82
|
"km": "ខ្មែរ", # Khmer(Central)
|
|
@@ -91,10 +91,11 @@ class Settings(object):
|
|
|
91
91
|
"ru": "Русский", # Russian
|
|
92
92
|
"sn": "chiShona", # Shona
|
|
93
93
|
# "sr_Latn": "Srpska (latinica)", # Serbian (latin)
|
|
94
|
-
|
|
94
|
+
"sk": "Slovenčina", # Slovak
|
|
95
95
|
"es": "Español", # Spanish
|
|
96
96
|
"sw": "Kiswahili", # Swahili
|
|
97
97
|
"sv": "Svenska", # Swedish
|
|
98
|
+
"ta": "Tamil", # Tamil
|
|
98
99
|
# "te": "తెలుగు", # Telugu
|
|
99
100
|
"tr": "Türkçe", # Turkish
|
|
100
101
|
"uk": "Українська", # Ukrainian
|
|
@@ -17,6 +17,7 @@ GNU General Public License for more details.
|
|
|
17
17
|
You should have received a copy of the GNU General Public License
|
|
18
18
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
19
19
|
"""
|
|
20
|
+
import unicodedata
|
|
20
21
|
|
|
21
22
|
from flask import request, render_template, make_response, jsonify, session
|
|
22
23
|
from flask_socketio import emit, ConnectionRefusedError
|
|
@@ -47,15 +48,45 @@ class ChatModeWeb:
|
|
|
47
48
|
|
|
48
49
|
self.define_routes()
|
|
49
50
|
|
|
50
|
-
def
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
and
|
|
51
|
+
def remove_unallowed_characters(self, text):
|
|
52
|
+
"""
|
|
53
|
+
Sanitize username to remove unwanted characters.
|
|
54
|
+
Allowed characters right now are:
|
|
55
|
+
- all ASCII numbers
|
|
56
|
+
- all ASCII letters
|
|
57
|
+
- dash, underscore and single space
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
def allowed_character(ch):
|
|
61
|
+
allowed_unicode_categories = [
|
|
62
|
+
'L', # All letters
|
|
63
|
+
'N', # All numbers
|
|
64
|
+
]
|
|
65
|
+
allowed_special_characters = [
|
|
66
|
+
'-', # dash
|
|
67
|
+
'_', # underscore
|
|
68
|
+
' ', # single space
|
|
69
|
+
]
|
|
70
|
+
return (
|
|
71
|
+
unicodedata.category(ch)[0] in allowed_unicode_categories and ord(ch) < 128
|
|
72
|
+
) or ch in allowed_special_characters
|
|
73
|
+
|
|
74
|
+
return "".join(
|
|
75
|
+
ch for ch in text if allowed_character(ch)
|
|
57
76
|
)
|
|
58
77
|
|
|
78
|
+
def validate_username(self, username):
|
|
79
|
+
try:
|
|
80
|
+
username = self.remove_unallowed_characters(username.strip())
|
|
81
|
+
return (
|
|
82
|
+
username
|
|
83
|
+
and username not in self.connected_users
|
|
84
|
+
and len(username) < 128
|
|
85
|
+
)
|
|
86
|
+
except Exception as e:
|
|
87
|
+
self.common.log("ChatModeWeb", "validate_username", e)
|
|
88
|
+
return False
|
|
89
|
+
|
|
59
90
|
def define_routes(self):
|
|
60
91
|
"""
|
|
61
92
|
The web app routes for chatting
|
|
@@ -77,13 +108,17 @@ class ChatModeWeb:
|
|
|
77
108
|
|
|
78
109
|
self.web.add_request(self.web.REQUEST_LOAD, request.path)
|
|
79
110
|
return render_template(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
111
|
+
"chat.html",
|
|
112
|
+
static_url_path=self.web.static_url_path,
|
|
113
|
+
username=session.get("name"),
|
|
114
|
+
title=self.web.settings.get("general", "title"),
|
|
84
115
|
)
|
|
85
116
|
|
|
86
|
-
@self.web.app.route(
|
|
117
|
+
@self.web.app.route(
|
|
118
|
+
"/update-session-username",
|
|
119
|
+
methods=["POST"],
|
|
120
|
+
provide_automatic_options=False,
|
|
121
|
+
)
|
|
87
122
|
def update_session_username():
|
|
88
123
|
history_id = self.cur_history_id
|
|
89
124
|
data = request.get_json()
|
|
@@ -122,6 +157,8 @@ class ChatModeWeb:
|
|
|
122
157
|
A status message is broadcast to all people in the room."""
|
|
123
158
|
if self.validate_username(session.get("name")):
|
|
124
159
|
self.connected_users.append(session.get("name"))
|
|
160
|
+
# Store the session id for the user
|
|
161
|
+
session["socketio_session_id"] = request.sid
|
|
125
162
|
emit(
|
|
126
163
|
"status",
|
|
127
164
|
{
|
|
@@ -133,7 +170,7 @@ class ChatModeWeb:
|
|
|
133
170
|
broadcast=True,
|
|
134
171
|
)
|
|
135
172
|
else:
|
|
136
|
-
raise ConnectionRefusedError('
|
|
173
|
+
raise ConnectionRefusedError('Invalid session')
|
|
137
174
|
|
|
138
175
|
@self.web.socketio.on("text", namespace="/chat")
|
|
139
176
|
def text(message):
|
|
@@ -153,9 +190,9 @@ class ChatModeWeb:
|
|
|
153
190
|
new_name = message.get("username", "").strip()
|
|
154
191
|
if self.validate_username(new_name):
|
|
155
192
|
session["name"] = new_name
|
|
156
|
-
self.connected_users[
|
|
157
|
-
|
|
158
|
-
|
|
193
|
+
self.connected_users[self.connected_users.index(current_name)] = (
|
|
194
|
+
session.get("name")
|
|
195
|
+
)
|
|
159
196
|
emit(
|
|
160
197
|
"status",
|
|
161
198
|
{
|
|
@@ -178,13 +215,23 @@ class ChatModeWeb:
|
|
|
178
215
|
def disconnect():
|
|
179
216
|
"""Sent by clients when they disconnect.
|
|
180
217
|
A status message is broadcast to all people in the server."""
|
|
218
|
+
user_already_disconnected = False
|
|
181
219
|
if session.get("name") in self.connected_users:
|
|
182
220
|
self.connected_users.remove(session.get("name"))
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
broadcast=True,
|
|
221
|
+
else:
|
|
222
|
+
user_already_disconnected = True
|
|
223
|
+
|
|
224
|
+
# Forcefully disconnect the user
|
|
225
|
+
self.web.socketio.server.disconnect(
|
|
226
|
+
sid=session.get("socketio_session_id"), namespace="/chat"
|
|
190
227
|
)
|
|
228
|
+
|
|
229
|
+
if not user_already_disconnected:
|
|
230
|
+
emit(
|
|
231
|
+
"status",
|
|
232
|
+
{
|
|
233
|
+
"msg": "{} has left the room.".format(session.get("name")),
|
|
234
|
+
"connected_users": self.connected_users,
|
|
235
|
+
},
|
|
236
|
+
broadcast=True,
|
|
237
|
+
)
|
|
@@ -194,7 +194,10 @@ class ReceiveModeWeb:
|
|
|
194
194
|
if files_received > 0:
|
|
195
195
|
msg = f"Uploaded {files_msg}"
|
|
196
196
|
else:
|
|
197
|
-
|
|
197
|
+
if not self.web.settings.get("receive", "disable_text"):
|
|
198
|
+
msg = "Nothing submitted or message was too long (> 524288 characters)"
|
|
199
|
+
else:
|
|
200
|
+
msg = "Nothing submitted"
|
|
198
201
|
|
|
199
202
|
if ajax:
|
|
200
203
|
info_flashes.append(msg)
|
|
@@ -462,7 +465,7 @@ class ReceiveModeRequest(Request):
|
|
|
462
465
|
self.includes_message = False
|
|
463
466
|
if not self.web.settings.get("receive", "disable_text"):
|
|
464
467
|
text_message = self.form.get("text")
|
|
465
|
-
if text_message:
|
|
468
|
+
if text_message and len(text_message) <= 524288:
|
|
466
469
|
if text_message.strip() != "":
|
|
467
470
|
self.includes_message = True
|
|
468
471
|
|
|
@@ -25,7 +25,7 @@ import mimetypes
|
|
|
25
25
|
import gzip
|
|
26
26
|
from flask import Response, request
|
|
27
27
|
from unidecode import unidecode
|
|
28
|
-
from urllib.parse import quote
|
|
28
|
+
from urllib.parse import quote, unquote
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
class SendBaseModeWeb:
|
|
@@ -132,6 +132,9 @@ class SendBaseModeWeb:
|
|
|
132
132
|
self.set_file_info_custom(filenames, processed_size_callback)
|
|
133
133
|
|
|
134
134
|
def directory_listing(self, filenames, path="", filesystem_path=None, add_trailing_slash=False):
|
|
135
|
+
"""
|
|
136
|
+
Display the front page of a share or index.html-less website, listing the files/directories.
|
|
137
|
+
"""
|
|
135
138
|
# Tell the GUI about the directory listing
|
|
136
139
|
history_id = self.cur_history_id
|
|
137
140
|
self.cur_history_id += 1
|
|
@@ -151,6 +154,11 @@ class SendBaseModeWeb:
|
|
|
151
154
|
|
|
152
155
|
# If filesystem_path is None, this is the root directory listing
|
|
153
156
|
files, dirs = self.build_directory_listing(path, filenames, filesystem_path, add_trailing_slash)
|
|
157
|
+
|
|
158
|
+
# Mark the request as done so we know we can close the share if in auto-stop mode.
|
|
159
|
+
self.web.done = True
|
|
160
|
+
|
|
161
|
+
# Render and return the response.
|
|
154
162
|
return self.directory_listing_template(
|
|
155
163
|
path, files, dirs, breadcrumbs, breadcrumbs_leaf
|
|
156
164
|
)
|
|
@@ -170,18 +178,18 @@ class SendBaseModeWeb:
|
|
|
170
178
|
if is_dir:
|
|
171
179
|
if add_trailing_slash:
|
|
172
180
|
dirs.append(
|
|
173
|
-
{"link": os.path.join(f"/{path}", filename, ""), "basename": filename}
|
|
181
|
+
{"link": os.path.join(f"/{path}", quote(filename), ""), "basename": filename}
|
|
174
182
|
)
|
|
175
183
|
else:
|
|
176
184
|
dirs.append(
|
|
177
|
-
{"link": os.path.join(f"/{path}", filename), "basename": filename}
|
|
185
|
+
{"link": os.path.join(f"/{path}", quote(filename)), "basename": filename}
|
|
178
186
|
)
|
|
179
187
|
else:
|
|
180
188
|
size = os.path.getsize(this_filesystem_path)
|
|
181
189
|
size_human = self.common.human_readable_filesize(size)
|
|
182
190
|
files.append(
|
|
183
191
|
{
|
|
184
|
-
"link": os.path.join(f"/{path}", filename),
|
|
192
|
+
"link": os.path.join(f"/{path}", quote(filename)),
|
|
185
193
|
"basename": filename,
|
|
186
194
|
"size_human": size_human,
|
|
187
195
|
}
|
|
@@ -228,11 +236,11 @@ class SendBaseModeWeb:
|
|
|
228
236
|
chunk_size = 102400 # 100kb
|
|
229
237
|
|
|
230
238
|
fp = open(file_to_download, "rb")
|
|
231
|
-
done = False
|
|
232
|
-
while not done:
|
|
239
|
+
self.web.done = False
|
|
240
|
+
while not self.web.done:
|
|
233
241
|
chunk = fp.read(chunk_size)
|
|
234
242
|
if chunk == b"":
|
|
235
|
-
done = True
|
|
243
|
+
self.web.done = True
|
|
236
244
|
else:
|
|
237
245
|
try:
|
|
238
246
|
yield chunk
|
|
@@ -245,8 +253,17 @@ class SendBaseModeWeb:
|
|
|
245
253
|
or self.common.platform == "Linux"
|
|
246
254
|
or self.common.platform == "BSD"
|
|
247
255
|
):
|
|
256
|
+
if self.web.settings.get(self.web.mode, "log_filenames"):
|
|
257
|
+
# Decode and sanitize the path to remove newlines
|
|
258
|
+
decoded_path = unquote(path)
|
|
259
|
+
decoded_path = decoded_path.replace("\r", "").replace("\n", "")
|
|
260
|
+
filename_str = f"{decoded_path} - "
|
|
261
|
+
else:
|
|
262
|
+
filename_str = ""
|
|
263
|
+
|
|
248
264
|
sys.stdout.write(
|
|
249
|
-
"\r{0:s}, {
|
|
265
|
+
"\r{0}{1:s}, {2:.2f}% ".format(
|
|
266
|
+
filename_str,
|
|
250
267
|
self.common.human_readable_filesize(
|
|
251
268
|
downloaded_bytes
|
|
252
269
|
),
|
|
@@ -264,10 +281,10 @@ class SendBaseModeWeb:
|
|
|
264
281
|
"filesize": filesize,
|
|
265
282
|
},
|
|
266
283
|
)
|
|
267
|
-
done = False
|
|
284
|
+
self.web.done = False
|
|
268
285
|
except Exception:
|
|
269
286
|
# Looks like the download was canceled
|
|
270
|
-
done = True
|
|
287
|
+
self.web.done = True
|
|
271
288
|
|
|
272
289
|
# Tell the GUI the individual file was canceled
|
|
273
290
|
self.web.add_request(
|
|
@@ -278,8 +295,7 @@ class SendBaseModeWeb:
|
|
|
278
295
|
|
|
279
296
|
fp.close()
|
|
280
297
|
|
|
281
|
-
|
|
282
|
-
sys.stdout.write("\n")
|
|
298
|
+
sys.stdout.write("\n")
|
|
283
299
|
|
|
284
300
|
basename = os.path.basename(filesystem_path)
|
|
285
301
|
|
|
@@ -29,7 +29,7 @@ from datetime import datetime, timezone
|
|
|
29
29
|
from flask import Response, request, render_template, make_response, abort
|
|
30
30
|
from unidecode import unidecode
|
|
31
31
|
from werkzeug.http import parse_date, http_date
|
|
32
|
-
from urllib.parse import quote
|
|
32
|
+
from urllib.parse import quote, unquote
|
|
33
33
|
|
|
34
34
|
from .send_base_mode import SendBaseModeWeb
|
|
35
35
|
|
|
@@ -346,8 +346,17 @@ class ShareModeWeb(SendBaseModeWeb):
|
|
|
346
346
|
or self.common.platform == "Linux"
|
|
347
347
|
or self.common.platform == "BSD"
|
|
348
348
|
):
|
|
349
|
+
if self.web.settings.get("share", "log_filenames"):
|
|
350
|
+
# Decode and sanitize the path to remove newlines
|
|
351
|
+
decoded_path = unquote(path)
|
|
352
|
+
decoded_path = decoded_path.replace("\r", "").replace("\n", "")
|
|
353
|
+
filename_str = f"{decoded_path} - "
|
|
354
|
+
else:
|
|
355
|
+
filename_str = ""
|
|
356
|
+
|
|
349
357
|
sys.stdout.write(
|
|
350
|
-
"\r{0:s}, {
|
|
358
|
+
"\r{0}{1:s}, {2:.2f}% ".format(
|
|
359
|
+
filename_str,
|
|
351
360
|
self.common.human_readable_filesize(downloaded_bytes),
|
|
352
361
|
percent,
|
|
353
362
|
)
|
|
@@ -376,8 +385,7 @@ class ShareModeWeb(SendBaseModeWeb):
|
|
|
376
385
|
|
|
377
386
|
fp.close()
|
|
378
387
|
|
|
379
|
-
|
|
380
|
-
sys.stdout.write("\n")
|
|
388
|
+
sys.stdout.write("\n")
|
|
381
389
|
|
|
382
390
|
# Download is finished
|
|
383
391
|
if self.web.settings.get("share", "autostop_sharing"):
|
|
@@ -176,11 +176,17 @@ class Web:
|
|
|
176
176
|
self.website_mode = WebsiteModeWeb(self.common, self)
|
|
177
177
|
elif self.mode == "chat":
|
|
178
178
|
if self.common.verbose:
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
179
|
+
try:
|
|
180
|
+
self.socketio = SocketIO(
|
|
181
|
+
async_mode="gevent", logger=True, engineio_logger=True
|
|
182
|
+
)
|
|
183
|
+
except ValueError:
|
|
184
|
+
self.socketio = SocketIO(logger=True, engineio_logger=True)
|
|
182
185
|
else:
|
|
183
|
-
|
|
186
|
+
try:
|
|
187
|
+
self.socketio = SocketIO(async_mode="gevent")
|
|
188
|
+
except ValueError:
|
|
189
|
+
self.socketio = SocketIO()
|
|
184
190
|
self.socketio.init_app(self.app)
|
|
185
191
|
self.chat_mode = ChatModeWeb(self.common, self)
|
|
186
192
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "onionshare_cli"
|
|
3
|
-
version = "2.6.
|
|
3
|
+
version = "2.6.3"
|
|
4
4
|
description = "OnionShare lets you securely and anonymously send and receive files. It works by starting a web server, making it accessible as a Tor onion service, and generating an unguessable web address so others can download files from you, or upload files to you. It does _not_ require setting up a separate server or using a third party file-sharing service."
|
|
5
5
|
authors = ["Micah Lee <micah@micahflee.com>"]
|
|
6
6
|
license = "GPLv3+"
|
|
@@ -16,7 +16,7 @@ classifiers = [
|
|
|
16
16
|
]
|
|
17
17
|
|
|
18
18
|
[tool.poetry.dependencies]
|
|
19
|
-
python = ">=3.
|
|
19
|
+
python = ">=3.10,<3.13"
|
|
20
20
|
click = "*"
|
|
21
21
|
flask = "2.3.2"
|
|
22
22
|
flask-compress = "^1.13"
|
|
@@ -25,23 +25,23 @@ psutil = "*"
|
|
|
25
25
|
pysocks = "*"
|
|
26
26
|
requests = {extras = ["socks"], version = "*"}
|
|
27
27
|
unidecode = "*"
|
|
28
|
-
urllib3 = "
|
|
28
|
+
urllib3 = "^2.2.2"
|
|
29
29
|
eventlet = "*"
|
|
30
|
-
setuptools = "
|
|
30
|
+
setuptools = ">=70.0.0"
|
|
31
31
|
pynacl = "*"
|
|
32
32
|
colorama = "*"
|
|
33
33
|
gevent-websocket = "*"
|
|
34
34
|
stem = "1.8.1"
|
|
35
|
-
waitress = "^
|
|
36
|
-
werkzeug = "
|
|
37
|
-
packaging = "
|
|
35
|
+
waitress = "^3.0.1"
|
|
36
|
+
werkzeug = "3.0.6"
|
|
37
|
+
packaging = ">=24"
|
|
38
38
|
gevent = "^23.9.1"
|
|
39
39
|
wheel = "^0.41.2"
|
|
40
40
|
cffi = "^1.15.1"
|
|
41
41
|
cython = "^3.0.2"
|
|
42
42
|
qrcode = "^7.4.2"
|
|
43
43
|
|
|
44
|
-
[tool.poetry.dev
|
|
44
|
+
[tool.poetry.group.dev.dependencies]
|
|
45
45
|
pytest = ">=7.2.0"
|
|
46
46
|
|
|
47
47
|
[tool.poetry.scripts]
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
# Enable built-in snowflake bridge
|
|
2
|
-
Bridge snowflake 192.0.2.3:80 2B280B23E1107BB62ABFC40DDCC8824814F80A72 fingerprint=2B280B23E1107BB62ABFC40DDCC8824814F80A72 url=https://snowflake-broker.torproject.net.global.prod.fastly.net/ front=foursquare.com ice=stun:stun.l.google.com:19302,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.com:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478 utls-imitate=hellorandomizedalpn
|
|
3
|
-
Bridge snowflake 192.0.2.4:80 8838024498816A039FCBBAB14E6F40A0843051FA fingerprint=8838024498816A039FCBBAB14E6F40A0843051FA url=https://snowflake-broker.torproject.net.global.prod.fastly.net/ front=foursquare.com ice=stun:stun.l.google.com:19302,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.net:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478 utls-imitate=hellorandomizedalpn
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2.6.1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/img/favicon.ico
RENAMED
|
File without changes
|
|
File without changes
|
{onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/img/logo_large.png
RENAMED
|
File without changes
|
{onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/img/web_file.png
RENAMED
|
File without changes
|
{onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/img/web_folder.png
RENAMED
|
File without changes
|
|
File without changes
|
{onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/js/jquery-3.5.1.min.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/js/socket.io.js
RENAMED
|
File without changes
|
{onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/static/js/socket.io.min.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/denied.html
RENAMED
|
File without changes
|
{onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/listing.html
RENAMED
|
File without changes
|
|
File without changes
|
{onionshare_cli-2.6.1 → onionshare_cli-2.6.3}/onionshare_cli/resources/templates/thankyou.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|