onionshare_cli 2.3__py3-none-any.whl

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.
Files changed (45) hide show
  1. onionshare_cli/__init__.py +522 -0
  2. onionshare_cli/common.py +296 -0
  3. onionshare_cli/mode_settings.py +146 -0
  4. onionshare_cli/onion.py +845 -0
  5. onionshare_cli/onionshare.py +110 -0
  6. onionshare_cli/resources/static/css/style.css +393 -0
  7. onionshare_cli/resources/static/img/ajax.gif +0 -0
  8. onionshare_cli/resources/static/img/favicon.ico +0 -0
  9. onionshare_cli/resources/static/img/logo.png +0 -0
  10. onionshare_cli/resources/static/img/logo_large.png +0 -0
  11. onionshare_cli/resources/static/img/web_file.png +0 -0
  12. onionshare_cli/resources/static/img/web_folder.png +0 -0
  13. onionshare_cli/resources/static/js/chat.js +173 -0
  14. onionshare_cli/resources/static/js/jquery-3.5.1.min.js +2 -0
  15. onionshare_cli/resources/static/js/receive.js +130 -0
  16. onionshare_cli/resources/static/js/send.js +75 -0
  17. onionshare_cli/resources/static/js/socket.io.min.js +3 -0
  18. onionshare_cli/resources/templates/401.html +21 -0
  19. onionshare_cli/resources/templates/403.html +21 -0
  20. onionshare_cli/resources/templates/404.html +21 -0
  21. onionshare_cli/resources/templates/405.html +21 -0
  22. onionshare_cli/resources/templates/chat.html +46 -0
  23. onionshare_cli/resources/templates/denied.html +14 -0
  24. onionshare_cli/resources/templates/listing.html +59 -0
  25. onionshare_cli/resources/templates/receive.html +46 -0
  26. onionshare_cli/resources/templates/send.html +69 -0
  27. onionshare_cli/resources/templates/thankyou.html +27 -0
  28. onionshare_cli/resources/torrc_template +8 -0
  29. onionshare_cli/resources/torrc_template-meek_lite_amazon +2 -0
  30. onionshare_cli/resources/torrc_template-meek_lite_azure +2 -0
  31. onionshare_cli/resources/torrc_template-obfs4 +27 -0
  32. onionshare_cli/resources/version.txt +1 -0
  33. onionshare_cli/resources/wordlist.txt +7776 -0
  34. onionshare_cli/settings.py +201 -0
  35. onionshare_cli/web/__init__.py +21 -0
  36. onionshare_cli/web/chat_mode.py +169 -0
  37. onionshare_cli/web/receive_mode.py +488 -0
  38. onionshare_cli/web/send_base_mode.py +338 -0
  39. onionshare_cli/web/share_mode.py +406 -0
  40. onionshare_cli/web/web.py +424 -0
  41. onionshare_cli/web/website_mode.py +123 -0
  42. onionshare_cli-2.3.dist-info/METADATA +34 -0
  43. onionshare_cli-2.3.dist-info/RECORD +45 -0
  44. onionshare_cli-2.3.dist-info/WHEEL +4 -0
  45. onionshare_cli-2.3.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,424 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ OnionShare | https://onionshare.org/
4
+
5
+ Copyright (C) 2014-2020 Micah Lee, et al. <micah@micahflee.com>
6
+
7
+ This program is free software: you can redistribute it and/or modify
8
+ it under the terms of the GNU General Public License as published by
9
+ the Free Software Foundation, either version 3 of the License, or
10
+ (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License
18
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ """
20
+
21
+ import hmac
22
+ import logging
23
+ import os
24
+ import queue
25
+ import socket
26
+ import sys
27
+ import tempfile
28
+ import requests
29
+ from distutils.version import LooseVersion as Version
30
+ from urllib.request import urlopen
31
+
32
+ import flask
33
+ from flask import (
34
+ Flask,
35
+ request,
36
+ render_template,
37
+ abort,
38
+ make_response,
39
+ send_file,
40
+ __version__ as flask_version,
41
+ )
42
+ from flask_httpauth import HTTPBasicAuth
43
+ from flask_socketio import SocketIO
44
+
45
+ from .share_mode import ShareModeWeb
46
+ from .receive_mode import ReceiveModeWeb, ReceiveModeWSGIMiddleware, ReceiveModeRequest
47
+ from .website_mode import WebsiteModeWeb
48
+ from .chat_mode import ChatModeWeb
49
+
50
+ # Stub out flask's show_server_banner function, to avoiding showing warnings that
51
+ # are not applicable to OnionShare
52
+ def stubbed_show_server_banner(env, debug, app_import_path, eager_loading):
53
+ pass
54
+
55
+
56
+ try:
57
+ flask.cli.show_server_banner = stubbed_show_server_banner
58
+ except:
59
+ pass
60
+
61
+
62
+ class Web:
63
+ """
64
+ The Web object is the OnionShare web server, powered by flask
65
+ """
66
+
67
+ REQUEST_LOAD = 0
68
+ REQUEST_STARTED = 1
69
+ REQUEST_PROGRESS = 2
70
+ REQUEST_CANCELED = 3
71
+ REQUEST_RATE_LIMIT = 4
72
+ REQUEST_UPLOAD_FILE_RENAMED = 5
73
+ REQUEST_UPLOAD_SET_DIR = 6
74
+ REQUEST_UPLOAD_FINISHED = 7
75
+ REQUEST_UPLOAD_CANCELED = 8
76
+ REQUEST_INDIVIDUAL_FILE_STARTED = 9
77
+ REQUEST_INDIVIDUAL_FILE_PROGRESS = 10
78
+ REQUEST_INDIVIDUAL_FILE_CANCELED = 11
79
+ REQUEST_ERROR_DATA_DIR_CANNOT_CREATE = 12
80
+ REQUEST_OTHER = 13
81
+ REQUEST_INVALID_PASSWORD = 14
82
+
83
+ def __init__(self, common, is_gui, mode_settings, mode="share"):
84
+ self.common = common
85
+ self.common.log("Web", "__init__", f"is_gui={is_gui}, mode={mode}")
86
+
87
+ self.settings = mode_settings
88
+
89
+ # The flask app
90
+ self.app = Flask(
91
+ __name__,
92
+ static_folder=self.common.get_resource_path("static"),
93
+ static_url_path=f"/static_{self.common.random_string(16)}", # randomize static_url_path to avoid making /static unusable
94
+ template_folder=self.common.get_resource_path("templates"),
95
+ )
96
+ self.app.secret_key = self.common.random_string(8)
97
+ self.generate_static_url_path()
98
+ self.auth = HTTPBasicAuth()
99
+ self.auth.error_handler(self.error401)
100
+
101
+ # Verbose mode?
102
+ if self.common.verbose:
103
+ self.verbose_mode()
104
+
105
+ # Are we running in GUI mode?
106
+ self.is_gui = is_gui
107
+
108
+ # If the user stops the server while a transfer is in progress, it should
109
+ # immediately stop the transfer. In order to make it thread-safe, stop_q
110
+ # is a queue. If anything is in it, then the user stopped the server
111
+ self.stop_q = queue.Queue()
112
+
113
+ # Are we using receive mode?
114
+ self.mode = mode
115
+ if self.mode == "receive":
116
+ # Use custom WSGI middleware, to modify environ
117
+ self.app.wsgi_app = ReceiveModeWSGIMiddleware(self.app.wsgi_app, self)
118
+ # Use a custom Request class to track upload progress
119
+ self.app.request_class = ReceiveModeRequest
120
+
121
+ # Starting in Flask 0.11, render_template_string autoescapes template variables
122
+ # by default. To prevent content injection through template variables in
123
+ # earlier versions of Flask, we force autoescaping in the Jinja2 template
124
+ # engine if we detect a Flask version with insecure default behavior.
125
+ if Version(flask_version) < Version("0.11"):
126
+ # Monkey-patch in the fix from https://github.com/pallets/flask/commit/99c99c4c16b1327288fd76c44bc8635a1de452bc
127
+ Flask.select_jinja_autoescape = self._safe_select_jinja_autoescape
128
+
129
+ self.security_headers = [
130
+ ("X-Frame-Options", "DENY"),
131
+ ("X-Xss-Protection", "1; mode=block"),
132
+ ("X-Content-Type-Options", "nosniff"),
133
+ ("Referrer-Policy", "no-referrer"),
134
+ ("Server", "OnionShare"),
135
+ ]
136
+
137
+ self.q = queue.Queue()
138
+ self.password = None
139
+
140
+ self.reset_invalid_passwords()
141
+
142
+ self.done = False
143
+
144
+ # shutting down the server only works within the context of flask, so the easiest way to do it is over http
145
+ self.shutdown_password = self.common.random_string(16)
146
+
147
+ # Keep track if the server is running
148
+ self.running = False
149
+
150
+ # Define the web app routes
151
+ self.define_common_routes()
152
+
153
+ # Create the mode web object, which defines its own routes
154
+ self.share_mode = None
155
+ self.receive_mode = None
156
+ self.website_mode = None
157
+ self.chat_mode = None
158
+ if self.mode == "share":
159
+ self.share_mode = ShareModeWeb(self.common, self)
160
+ elif self.mode == "receive":
161
+ self.receive_mode = ReceiveModeWeb(self.common, self)
162
+ elif self.mode == "website":
163
+ self.website_mode = WebsiteModeWeb(self.common, self)
164
+ elif self.mode == "chat":
165
+ self.socketio = SocketIO()
166
+ self.socketio.init_app(self.app)
167
+ self.chat_mode = ChatModeWeb(self.common, self)
168
+
169
+ def get_mode(self):
170
+ if self.mode == "share":
171
+ return self.share_mode
172
+ elif self.mode == "receive":
173
+ return self.receive_mode
174
+ elif self.mode == "website":
175
+ return self.website_mode
176
+ elif self.mode == "chat":
177
+ return self.chat_mode
178
+ else:
179
+ return None
180
+
181
+ def generate_static_url_path(self):
182
+ # The static URL path has a 128-bit random number in it to avoid having name
183
+ # collisions with files that might be getting shared
184
+ self.static_url_path = f"/static_{self.common.random_string(16)}"
185
+ self.common.log(
186
+ "Web",
187
+ "generate_static_url_path",
188
+ f"new static_url_path is {self.static_url_path}",
189
+ )
190
+
191
+ # Update the flask route to handle the new static URL path
192
+ self.app.static_url_path = self.static_url_path
193
+ self.app.add_url_rule(
194
+ self.static_url_path + "/<path:filename>",
195
+ endpoint="static",
196
+ view_func=self.app.send_static_file,
197
+ )
198
+
199
+ def define_common_routes(self):
200
+ """
201
+ Common web app routes between all modes.
202
+ """
203
+
204
+ @self.auth.get_password
205
+ def get_pw(username):
206
+ if username == "onionshare":
207
+ return self.password
208
+ else:
209
+ return None
210
+
211
+ @self.app.before_request
212
+ def conditional_auth_check():
213
+ # Allow static files without basic authentication
214
+ if request.path.startswith(self.static_url_path + "/"):
215
+ return None
216
+
217
+ # If public mode is disabled, require authentication
218
+ if not self.settings.get("general", "public"):
219
+
220
+ @self.auth.login_required
221
+ def _check_login():
222
+ return None
223
+
224
+ return _check_login()
225
+
226
+ @self.app.errorhandler(404)
227
+ def not_found(e):
228
+ mode = self.get_mode()
229
+ history_id = mode.cur_history_id
230
+ mode.cur_history_id += 1
231
+ return self.error404(history_id)
232
+
233
+ @self.app.route("/<password_candidate>/shutdown")
234
+ def shutdown(password_candidate):
235
+ """
236
+ Stop the flask web server, from the context of an http request.
237
+ """
238
+ if password_candidate == self.shutdown_password:
239
+ self.force_shutdown()
240
+ return ""
241
+ abort(404)
242
+
243
+ if self.mode != "website":
244
+
245
+ @self.app.route("/favicon.ico")
246
+ def favicon():
247
+ return send_file(
248
+ f"{self.common.get_resource_path('static')}/img/favicon.ico"
249
+ )
250
+
251
+ def error401(self):
252
+ auth = request.authorization
253
+ if auth:
254
+ if (
255
+ auth["username"] == "onionshare"
256
+ and auth["password"] not in self.invalid_passwords
257
+ ):
258
+ print(f"Invalid password guess: {auth['password']}")
259
+ self.add_request(Web.REQUEST_INVALID_PASSWORD, data=auth["password"])
260
+
261
+ self.invalid_passwords.append(auth["password"])
262
+ self.invalid_passwords_count += 1
263
+
264
+ if self.invalid_passwords_count == 20:
265
+ self.add_request(Web.REQUEST_RATE_LIMIT)
266
+ self.force_shutdown()
267
+ print(
268
+ "Someone has made too many wrong attempts to guess your password, so OnionShare has stopped the server. Start sharing again and send the recipient a new address to share."
269
+ )
270
+
271
+ r = make_response(
272
+ render_template("401.html", static_url_path=self.static_url_path), 401
273
+ )
274
+ return self.add_security_headers(r)
275
+
276
+ def error403(self):
277
+ self.add_request(Web.REQUEST_OTHER, request.path)
278
+ r = make_response(
279
+ render_template("403.html", static_url_path=self.static_url_path), 403
280
+ )
281
+ return self.add_security_headers(r)
282
+
283
+ def error404(self, history_id):
284
+ self.add_request(
285
+ self.REQUEST_INDIVIDUAL_FILE_STARTED,
286
+ request.path,
287
+ {"id": history_id, "status_code": 404},
288
+ )
289
+
290
+ self.add_request(Web.REQUEST_OTHER, request.path)
291
+ r = make_response(
292
+ render_template("404.html", static_url_path=self.static_url_path), 404
293
+ )
294
+ return self.add_security_headers(r)
295
+
296
+ def error405(self, history_id):
297
+ self.add_request(
298
+ self.REQUEST_INDIVIDUAL_FILE_STARTED,
299
+ request.path,
300
+ {"id": history_id, "status_code": 405},
301
+ )
302
+
303
+ self.add_request(Web.REQUEST_OTHER, request.path)
304
+ r = make_response(
305
+ render_template("405.html", static_url_path=self.static_url_path), 405
306
+ )
307
+ return self.add_security_headers(r)
308
+
309
+ def add_security_headers(self, r):
310
+ """
311
+ Add security headers to a request
312
+ """
313
+ for header, value in self.security_headers:
314
+ r.headers.set(header, value)
315
+ # Set a CSP header unless in website mode and the user has disabled it
316
+ if not self.settings.get("website", "disable_csp") or self.mode != "website":
317
+ r.headers.set(
318
+ "Content-Security-Policy",
319
+ "default-src 'self'; style-src 'self'; script-src 'self'; img-src 'self' data:;",
320
+ )
321
+ return r
322
+
323
+ def _safe_select_jinja_autoescape(self, filename):
324
+ if filename is None:
325
+ return True
326
+ return filename.endswith((".html", ".htm", ".xml", ".xhtml"))
327
+
328
+ def add_request(self, request_type, path=None, data=None):
329
+ """
330
+ Add a request to the queue, to communicate with the GUI.
331
+ """
332
+ self.q.put({"type": request_type, "path": path, "data": data})
333
+
334
+ def generate_password(self, saved_password=None):
335
+ self.common.log("Web", "generate_password", f"saved_password={saved_password}")
336
+ if saved_password != None and saved_password != "":
337
+ self.password = saved_password
338
+ self.common.log(
339
+ "Web",
340
+ "generate_password",
341
+ f'saved_password sent, so password is: "{self.password}"',
342
+ )
343
+ else:
344
+ self.password = self.common.build_password()
345
+ self.common.log(
346
+ "Web", "generate_password", f'built random password: "{self.password}"'
347
+ )
348
+
349
+ def verbose_mode(self):
350
+ """
351
+ Turn on verbose mode, which will log flask errors to a file.
352
+ """
353
+ flask_log_filename = os.path.join(self.common.build_data_dir(), "flask.log")
354
+ log_handler = logging.FileHandler(flask_log_filename)
355
+ log_handler.setLevel(logging.WARNING)
356
+ self.app.logger.addHandler(log_handler)
357
+
358
+ def reset_invalid_passwords(self):
359
+ self.invalid_passwords_count = 0
360
+ self.invalid_passwords = []
361
+
362
+ def force_shutdown(self):
363
+ """
364
+ Stop the flask web server, from the context of the flask app.
365
+ """
366
+ # Shutdown the flask service
367
+ try:
368
+ func = request.environ.get("werkzeug.server.shutdown")
369
+ if func is None:
370
+ raise RuntimeError("Not running with the Werkzeug Server")
371
+ func()
372
+ except:
373
+ pass
374
+ self.running = False
375
+
376
+ def start(self, port):
377
+ """
378
+ Start the flask web server.
379
+ """
380
+ self.common.log("Web", "start", f"port={port}")
381
+
382
+ # Make sure the stop_q is empty when starting a new server
383
+ while not self.stop_q.empty():
384
+ try:
385
+ self.stop_q.get(block=False)
386
+ except queue.Empty:
387
+ pass
388
+
389
+ # In Whonix, listen on 0.0.0.0 instead of 127.0.0.1 (#220)
390
+ if os.path.exists("/usr/share/anon-ws-base-files/workstation"):
391
+ host = "0.0.0.0"
392
+ else:
393
+ host = "127.0.0.1"
394
+
395
+ self.running = True
396
+ if self.mode == "chat":
397
+ self.socketio.run(self.app, host=host, port=port)
398
+ else:
399
+ self.app.run(host=host, port=port, threaded=True)
400
+
401
+ def stop(self, port):
402
+ """
403
+ Stop the flask web server by loading /shutdown.
404
+ """
405
+ self.common.log("Web", "stop", "stopping server")
406
+
407
+ # Let the mode know that the user stopped the server
408
+ self.stop_q.put(True)
409
+
410
+ # To stop flask, load http://shutdown:[shutdown_password]@127.0.0.1/[shutdown_password]/shutdown
411
+ # (We're putting the shutdown_password in the path as well to make routing simpler)
412
+ if self.running:
413
+ if self.password:
414
+ requests.get(
415
+ f"http://127.0.0.1:{port}/{self.shutdown_password}/shutdown",
416
+ auth=requests.auth.HTTPBasicAuth("onionshare", self.password),
417
+ )
418
+ else:
419
+ requests.get(
420
+ f"http://127.0.0.1:{port}/{self.shutdown_password}/shutdown"
421
+ )
422
+
423
+ # Reset any password that was in use
424
+ self.password = None
@@ -0,0 +1,123 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ OnionShare | https://onionshare.org/
4
+
5
+ Copyright (C) 2014-2020 Micah Lee, et al. <micah@micahflee.com>
6
+
7
+ This program is free software: you can redistribute it and/or modify
8
+ it under the terms of the GNU General Public License as published by
9
+ the Free Software Foundation, either version 3 of the License, or
10
+ (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License
18
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ """
20
+
21
+ import os
22
+ import sys
23
+ import tempfile
24
+ import mimetypes
25
+ from flask import Response, request, render_template, make_response
26
+
27
+ from .send_base_mode import SendBaseModeWeb
28
+
29
+
30
+ class WebsiteModeWeb(SendBaseModeWeb):
31
+ """
32
+ All of the web logic for website mode
33
+ """
34
+
35
+ def init(self):
36
+ pass
37
+
38
+ def define_routes(self):
39
+ """
40
+ The web app routes for sharing a website
41
+ """
42
+
43
+ @self.web.app.route("/", defaults={"path": ""})
44
+ @self.web.app.route("/<path:path>")
45
+ def path_public(path):
46
+ return path_logic(path)
47
+
48
+ def path_logic(path=""):
49
+ """
50
+ Render the onionshare website.
51
+ """
52
+ return self.render_logic(path)
53
+
54
+ def directory_listing_template(
55
+ self, path, files, dirs, breadcrumbs, breadcrumbs_leaf
56
+ ):
57
+ return make_response(
58
+ render_template(
59
+ "listing.html",
60
+ path=path,
61
+ files=files,
62
+ dirs=dirs,
63
+ breadcrumbs=breadcrumbs,
64
+ breadcrumbs_leaf=breadcrumbs_leaf,
65
+ static_url_path=self.web.static_url_path,
66
+ )
67
+ )
68
+
69
+ def set_file_info_custom(self, filenames, processed_size_callback):
70
+ self.common.log("WebsiteModeWeb", "set_file_info_custom")
71
+ self.web.cancel_compression = True
72
+
73
+ def render_logic(self, path=""):
74
+ # Strip trailing slash
75
+ path = path.rstrip("/")
76
+
77
+ if path in self.files:
78
+ filesystem_path = self.files[path]
79
+
80
+ # If it's a directory
81
+ if os.path.isdir(filesystem_path):
82
+ # Is there an index.html?
83
+ index_path = os.path.join(path, "index.html")
84
+ if index_path in self.files:
85
+ # Render it
86
+ return self.stream_individual_file(self.files[index_path])
87
+
88
+ else:
89
+ # Otherwise, render directory listing
90
+ filenames = []
91
+ for filename in os.listdir(filesystem_path):
92
+ filenames.append(filename)
93
+ filenames.sort()
94
+ return self.directory_listing(filenames, path, filesystem_path)
95
+
96
+ # If it's a file
97
+ elif os.path.isfile(filesystem_path):
98
+ return self.stream_individual_file(filesystem_path)
99
+
100
+ # If it's not a directory or file, throw a 404
101
+ else:
102
+ history_id = self.cur_history_id
103
+ self.cur_history_id += 1
104
+ return self.web.error404(history_id)
105
+ else:
106
+ # Special case loading /
107
+
108
+ if path == "":
109
+ index_path = "index.html"
110
+ if index_path in self.files:
111
+ # Render it
112
+ return self.stream_individual_file(self.files[index_path])
113
+ else:
114
+ # Root directory listing
115
+ filenames = list(self.root_files)
116
+ filenames.sort()
117
+ return self.directory_listing(filenames, path)
118
+
119
+ else:
120
+ # If the path isn't found, throw a 404
121
+ history_id = self.cur_history_id
122
+ self.cur_history_id += 1
123
+ return self.web.error404(history_id)
@@ -0,0 +1,34 @@
1
+ Metadata-Version: 2.1
2
+ Name: onionshare-cli
3
+ Version: 2.3
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
+ License: GPLv3+
6
+ Author: Micah Lee
7
+ Author-email: micah@micahflee.com
8
+ Requires-Python: >=3.6,<4.0
9
+ Classifier: Environment :: Web Environment
10
+ Classifier: Framework :: Flask
11
+ Classifier: Intended Audience :: End Users/Desktop
12
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
13
+ Classifier: License :: Other/Proprietary License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.6
17
+ Classifier: Programming Language :: Python :: 3.7
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Topic :: Communications :: File Sharing
21
+ Classifier: Topic :: Security :: Cryptography
22
+ Requires-Dist: click
23
+ Requires-Dist: eventlet
24
+ Requires-Dist: flask
25
+ Requires-Dist: flask-httpauth
26
+ Requires-Dist: flask-socketio
27
+ Requires-Dist: psutil
28
+ Requires-Dist: pycryptodome
29
+ Requires-Dist: pysocks
30
+ Requires-Dist: requests
31
+ Requires-Dist: setuptools
32
+ Requires-Dist: stem
33
+ Requires-Dist: unidecode
34
+ Requires-Dist: urllib3
@@ -0,0 +1,45 @@
1
+ onionshare_cli/__init__.py,sha256=npQuu3Xxee-4ijr7zi1b66EYwTpyuMNiuefzjIkAWl4,18804
2
+ onionshare_cli/common.py,sha256=3e1Bg-0r8c_5u-JAbo9-lHKdLSU36kV_Qz-Nk48YhSM,10060
3
+ onionshare_cli/mode_settings.py,sha256=BvvxSULagqvXw5Oq7tS_FcDsya-u2A_o1vZdy2YxPao,5116
4
+ onionshare_cli/onion.py,sha256=lEMd-A1j8cAIWXWgbSMIpDomxWBYbaOb0ZQi-ONQ2SA,32727
5
+ onionshare_cli/onionshare.py,sha256=seCR03hDR7KqLN-6hoYAfgm8Hjuq125JL0-r2If4SQ8,3315
6
+ onionshare_cli/resources/static/css/style.css,sha256=Z44manZ4K00GW02pTzsLo_2dNdVEjUSF7n8y9SlYgDs,6088
7
+ onionshare_cli/resources/static/img/ajax.gif,sha256=Ha41spwCqc39DjUUk6Hq5TTRassrOGLVqzHPsjOzIGI,847
8
+ onionshare_cli/resources/static/img/favicon.ico,sha256=cAwV8YHCn_s0fcb8ouC5lx6VH2KJuw1kCR9xqB_rWTs,4286
9
+ onionshare_cli/resources/static/img/logo.png,sha256=O4s9U1wJZLPpAELaR2d4AxHJqGloQn86PXmLCEyy1Fw,3824
10
+ onionshare_cli/resources/static/img/logo_large.png,sha256=1peNnDBnxFy12It3htQ2J04a5LG8o_r_c6Ec4UntESg,9663
11
+ onionshare_cli/resources/static/img/web_file.png,sha256=5aW8bPAwB4OUlWPxYrSKnJm12T2AYar9Pa7bljyQT80,251
12
+ onionshare_cli/resources/static/img/web_folder.png,sha256=DCCm4ZCoz-6vruLkpH2sva9fQG2Ii8_wRDeCl7BrBu8,338
13
+ onionshare_cli/resources/static/js/chat.js,sha256=ZD7usLa7CCqqEcr4v9qEUgeFUy-7QyG8ln0WG6kI7XY,5268
14
+ onionshare_cli/resources/static/js/jquery-3.5.1.min.js,sha256=9_aliU8dGd2tb6OSsuzixeV4y_faTqgFtohetphbbj0,89476
15
+ onionshare_cli/resources/static/js/receive.js,sha256=C_ln2d6LbDhxpzpwcB0epsHe9QgujjcurI2RsxlD0E4,4288
16
+ onionshare_cli/resources/static/js/send.js,sha256=UWSMC0fMDCeTrimcKT6VWY0-wD8M6q-eXoG5QYr9YAk,2664
17
+ onionshare_cli/resources/static/js/socket.io.min.js,sha256=l7bJqGGRCT1WkgISTZPrdFddUwh8hFB7IBHngxng0L8,65070
18
+ onionshare_cli/resources/templates/401.html,sha256=51DfjrgIGCzw8hnLWWKVz-y5dgw6smCsN5437j4T1Gw,645
19
+ onionshare_cli/resources/templates/403.html,sha256=CnsDbx5EDpjq5Ddc1ilmhfRx5jknn5VtGiZRp9ehdcw,668
20
+ onionshare_cli/resources/templates/404.html,sha256=-0MM_80rlHpOelimpW-EF8Pw0XvWa9LHqn8K_3etczk,623
21
+ onionshare_cli/resources/templates/405.html,sha256=Pg8QOVGj-HHLed9q-ge44cSzA6T9Mms063F5Whj36Zk,641
22
+ onionshare_cli/resources/templates/chat.html,sha256=_LrnX5JHCdxjbzNVJ8N71B5HkCHGKjoYyc_GS-baitI,1304
23
+ onionshare_cli/resources/templates/denied.html,sha256=Y70lVlbafNsWfgfGebqjzAskFV4jikVsVY_gVe_Onec,230
24
+ onionshare_cli/resources/templates/listing.html,sha256=h2rgL10VULEI0GKzv3WX6HNCWkkzRPLIoOVA6T9m7os,1535
25
+ onionshare_cli/resources/templates/receive.html,sha256=-Mdic8baaqPj4fgaBfyHpiBOy0RQHd_vwCm_XZyMejc,1698
26
+ onionshare_cli/resources/templates/send.html,sha256=KFNDRwHyLQVi069ijW7srJDfr7mrVP0wu9XCsfVbdlk,2267
27
+ onionshare_cli/resources/templates/thankyou.html,sha256=u2m-FWbDTpMrbN8DdPs4x7gPGpO3Bvdawv35y7iT_us,852
28
+ onionshare_cli/resources/torrc_template,sha256=jx9N1CvSf9CcTo0O-ox9ZFLx4S_NLmfXBGFwd0enfxU,209
29
+ onionshare_cli/resources/torrc_template-meek_lite_amazon,sha256=8tV9kh1WY9plp8KwMyC8ScUIaYHB8ns5OSZdQnkpbYk,146
30
+ onionshare_cli/resources/torrc_template-meek_lite_azure,sha256=8lqaQdoAlzZDrkwW46q0PDB9bcxqQxEGFNvAt2dG40s,137
31
+ onionshare_cli/resources/torrc_template-obfs4,sha256=7RNprD5Cll7CpBIc8lmcwGra94r6nuzwBe5hi7mYgm4,4165
32
+ onionshare_cli/resources/version.txt,sha256=h3GmwEF0t_cZ697KXbhzBKcqEYpWKaXizp731iFYtyg,3
33
+ onionshare_cli/resources/wordlist.txt,sha256=bVV_BpOVj7XmULaLW-5YXrgs9NoyllUFx4npJHQ7xSI,62144
34
+ onionshare_cli/settings.py,sha256=j70KcNnSnMVnnh3xW1Fx1B1na-ZXnNngC1y2ckeM5p0,7284
35
+ onionshare_cli/web/__init__.py,sha256=5Ddm6klCmorvGir6AYMdzT6f5Ams-KFk4d4HOR4-ujE,769
36
+ onionshare_cli/web/chat_mode.py,sha256=5mWshE7qcjUWu8tRFn2IHM5UrOhwjOxq_QcL68O6OWg,5865
37
+ onionshare_cli/web/receive_mode.py,sha256=mf1B1hmp-RooyPERiXxW1ke8euWW4PpLlhJshY3rk9s,17150
38
+ onionshare_cli/web/send_base_mode.py,sha256=ur3tDU4pzqIznc7FK3Wb4g2IhLNIkOWNRAa2LGOygv0,12158
39
+ onionshare_cli/web/share_mode.py,sha256=OFockAvg6-GC3J1sM2u5bT8LAxb7rdMVd8rv9ppbXW8,15990
40
+ onionshare_cli/web/web.py,sha256=N1MXmWTaZpGxvb1U7jQgXq7DNDlxP3eJqV9O4wwoSHI,14861
41
+ onionshare_cli/web/website_mode.py,sha256=S6xjL-18hJfz7KVt3SZ0eRD26LE_0rbOCIbg8FUJY68,4071
42
+ onionshare_cli-2.3.dist-info/entry_points.txt,sha256=jqtxfoRDQXNWkup_DHJbmTimeFUz34p0m840rRqcu3I,54
43
+ onionshare_cli-2.3.dist-info/WHEEL,sha256=SrtnPGVTMeYWttls9xnWA01eUhCZ3ufFdJUYb1J3r-U,83
44
+ onionshare_cli-2.3.dist-info/METADATA,sha256=FJEkBq3LGkXz__l0E-tmmIj0NijZ8xQyia3Qr5ZBkoE,1482
45
+ onionshare_cli-2.3.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry 1.0.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ onionshare-cli=onionshare_cli:main
3
+