mirror of
https://github.com/onionshare/onionshare.git
synced 2024-10-01 01:35:40 -04:00
Merge branch 'develop' into 929_download_errors
This commit is contained in:
commit
3c6cbd04a7
@ -22,7 +22,14 @@ from stem.control import Controller
|
||||
from stem import ProtocolError, SocketClosed
|
||||
from stem.connection import MissingPassword, UnreadableCookieFile, AuthenticationFailure
|
||||
from Crypto.PublicKey import RSA
|
||||
import base64, os, sys, tempfile, shutil, urllib, platform, subprocess, time, shlex
|
||||
import base64
|
||||
import os
|
||||
import tempfile
|
||||
import subprocess
|
||||
import time
|
||||
import shlex
|
||||
import getpass
|
||||
import psutil
|
||||
|
||||
from distutils.version import LooseVersion as Version
|
||||
from . import common
|
||||
@ -109,13 +116,6 @@ class TorTooOld(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class BundledTorNotSupported(Exception):
|
||||
"""
|
||||
This exception is raised if onionshare is set to use the bundled Tor binary,
|
||||
but it's not supported on that platform, or in dev mode.
|
||||
"""
|
||||
|
||||
|
||||
class BundledTorTimeout(Exception):
|
||||
"""
|
||||
This exception is raised if onionshare is set to use the bundled Tor binary,
|
||||
@ -158,14 +158,6 @@ class Onion(object):
|
||||
|
||||
self.use_tmp_dir = use_tmp_dir
|
||||
|
||||
# Is bundled tor supported?
|
||||
if (
|
||||
self.common.platform == "Windows" or self.common.platform == "Darwin"
|
||||
) and getattr(sys, "onionshare_dev_mode", False):
|
||||
self.bundle_tor_supported = False
|
||||
else:
|
||||
self.bundle_tor_supported = True
|
||||
|
||||
# Set the path of the tor binary, for bundled tor
|
||||
if not get_tor_paths:
|
||||
get_tor_paths = self.common.get_tor_paths
|
||||
@ -221,12 +213,6 @@ class Onion(object):
|
||||
self.c = None
|
||||
|
||||
if self.settings.get("connection_type") == "bundled":
|
||||
if not self.bundle_tor_supported:
|
||||
raise BundledTorNotSupported(
|
||||
# strings._("settings_error_bundled_tor_not_supported")
|
||||
"Using the Tor version that comes with OnionShare does not work in developer mode on Windows or macOS."
|
||||
)
|
||||
|
||||
# Create a torrc for this session
|
||||
if self.use_tmp_dir:
|
||||
self.tor_data_directory = tempfile.TemporaryDirectory(
|
||||
@ -253,6 +239,26 @@ class Onion(object):
|
||||
raise OSError("OnionShare port not available")
|
||||
self.tor_torrc = os.path.join(self.tor_data_directory_name, "torrc")
|
||||
|
||||
# If there is an existing OnionShare tor process, kill it
|
||||
for proc in psutil.process_iter(["pid", "name", "username"]):
|
||||
try:
|
||||
cmdline = proc.cmdline()
|
||||
if (
|
||||
cmdline[0] == self.tor_path
|
||||
and cmdline[1] == "-f"
|
||||
and cmdline[2] == self.tor_torrc
|
||||
):
|
||||
self.common.log(
|
||||
"Onion",
|
||||
"connect",
|
||||
"found a stale tor process, killing it",
|
||||
)
|
||||
proc.terminate()
|
||||
proc.wait()
|
||||
break
|
||||
except:
|
||||
pass
|
||||
|
||||
if self.common.platform == "Windows" or self.common.platform == "Darwin":
|
||||
# Windows doesn't support unix sockets, so it must use a network port.
|
||||
# macOS can't use unix sockets either because socket filenames are limited to
|
||||
|
@ -1,55 +1,59 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OnionShare</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon" />
|
||||
<link href="{{ static_url_path }}/css/style.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="clearfix">
|
||||
<img class="logo" src="{{ static_url_path }}/img/logo.png" title="OnionShare">
|
||||
<h1>OnionShare</h1>
|
||||
</header>
|
||||
<head>
|
||||
<title>OnionShare</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon" />
|
||||
<link href="{{ static_url_path }}/css/style.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
|
||||
{% if breadcrumbs %}
|
||||
<ul class="breadcrumbs">
|
||||
{% for breadcrumb in breadcrumbs %}<li><a href="{{ breadcrumb[1] }}">{{ breadcrumb[0] }}</a> <span class="sep">‣</span></li>{% endfor %}<li>{{ breadcrumbs_leaf }}</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
<body>
|
||||
|
||||
<table class="file-list" id="file-list">
|
||||
<tr>
|
||||
<th id="filename-header">Filename</th>
|
||||
<th id="size-header">Size</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<header class="clearfix">
|
||||
<img class="logo" src="{{ static_url_path }}/img/logo.png" title="OnionShare">
|
||||
<h1>OnionShare</h1>
|
||||
</header>
|
||||
|
||||
{% for info in dirs %}
|
||||
<tr>
|
||||
<td>
|
||||
<img width="30" height="30" title="" alt="" src="{{ static_url_path }}/img/web_folder.png" />
|
||||
<a href="{{ info.basename }}">
|
||||
{{ info.basename }}
|
||||
</a>
|
||||
</td>
|
||||
<td>—</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if breadcrumbs %}
|
||||
<ul class="breadcrumbs">
|
||||
{% for breadcrumb in breadcrumbs %}<li><a href="{{ breadcrumb[1] }}">{{ breadcrumb[0] }}</a> <span
|
||||
class="sep">‣</span></li>{% endfor %}<li>{{ breadcrumbs_leaf }}</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% for info in files %}
|
||||
<tr>
|
||||
<td>
|
||||
<img width="30" height="30" title="" alt="" src="{{ static_url_path }}/img/web_file.png" />
|
||||
<a href="{{ info.basename }}">
|
||||
{{ info.basename }}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ info.size_human }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
<table class="file-list" id="file-list">
|
||||
<tr>
|
||||
<th id="filename-header">Filename</th>
|
||||
<th id="size-header">Size</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
{% for info in dirs %}
|
||||
<tr>
|
||||
<td>
|
||||
<img width="30" height="30" title="" alt="" src="{{ static_url_path }}/img/web_folder.png" />
|
||||
<a href="{{ info.link }}">
|
||||
{{ info.basename }}
|
||||
</a>
|
||||
</td>
|
||||
<td>—</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
{% for info in files %}
|
||||
<tr>
|
||||
<td>
|
||||
<img width="30" height="30" title="" alt="" src="{{ static_url_path }}/img/web_file.png" />
|
||||
<a href="{{ info.link }}">
|
||||
{{ info.basename }}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ info.size_human }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -85,7 +85,7 @@ class SendBaseModeWeb:
|
||||
|
||||
# If it's a directory, add it recursively
|
||||
elif os.path.isdir(filename):
|
||||
self.root_files[basename + "/"] = filename
|
||||
self.root_files[basename] = filename
|
||||
|
||||
for root, _, nested_filenames in os.walk(filename):
|
||||
# Normalize the root path. So if the directory name is "/home/user/Documents/some_folder",
|
||||
@ -96,7 +96,7 @@ class SendBaseModeWeb:
|
||||
).rstrip("/")
|
||||
|
||||
# Add the dir itself
|
||||
self.files[normalized_root + "/"] = root
|
||||
self.files[normalized_root] = root
|
||||
|
||||
# Add the files in this dir
|
||||
for nested_filename in nested_filenames:
|
||||
@ -117,19 +117,21 @@ class SendBaseModeWeb:
|
||||
)
|
||||
|
||||
breadcrumbs = [("☗", "/")]
|
||||
parts = path.split("/")[:-1]
|
||||
parts = path.split("/")
|
||||
if parts[-1] == "":
|
||||
parts = parts[:-1]
|
||||
for i in range(len(parts)):
|
||||
breadcrumbs.append((parts[i], f"/{'/'.join(parts[0 : i + 1])}/"))
|
||||
breadcrumbs.append((parts[i], f"/{'/'.join(parts[0 : i + 1])}"))
|
||||
breadcrumbs_leaf = breadcrumbs.pop()[0]
|
||||
|
||||
# If filesystem_path is None, this is the root directory listing
|
||||
files, dirs = self.build_directory_listing(filenames, filesystem_path)
|
||||
files, dirs = self.build_directory_listing(path, filenames, filesystem_path)
|
||||
r = self.directory_listing_template(
|
||||
path, files, dirs, breadcrumbs, breadcrumbs_leaf
|
||||
)
|
||||
return self.web.add_security_headers(r)
|
||||
|
||||
def build_directory_listing(self, filenames, filesystem_path):
|
||||
def build_directory_listing(self, path, filenames, filesystem_path):
|
||||
files = []
|
||||
dirs = []
|
||||
|
||||
@ -142,11 +144,20 @@ class SendBaseModeWeb:
|
||||
is_dir = os.path.isdir(this_filesystem_path)
|
||||
|
||||
if is_dir:
|
||||
dirs.append({"basename": filename})
|
||||
dirs.append(
|
||||
{"link": os.path.join(f"/{path}", filename), "basename": filename}
|
||||
)
|
||||
else:
|
||||
size = os.path.getsize(this_filesystem_path)
|
||||
size_human = self.common.human_readable_filesize(size)
|
||||
files.append({"basename": filename, "size_human": size_human})
|
||||
files.append(
|
||||
{
|
||||
"link": os.path.join(f"/{path}", filename),
|
||||
"basename": filename,
|
||||
"size_human": size_human,
|
||||
}
|
||||
)
|
||||
|
||||
return files, dirs
|
||||
|
||||
def stream_individual_file(self, filesystem_path):
|
||||
|
@ -71,6 +71,9 @@ class WebsiteModeWeb(SendBaseModeWeb):
|
||||
self.web.cancel_compression = True
|
||||
|
||||
def render_logic(self, path=""):
|
||||
# Strip trailing slash
|
||||
path = path.rstrip("/")
|
||||
|
||||
if path in self.files:
|
||||
filesystem_path = self.files[path]
|
||||
|
||||
@ -86,10 +89,7 @@ class WebsiteModeWeb(SendBaseModeWeb):
|
||||
# Otherwise, render directory listing
|
||||
filenames = []
|
||||
for filename in os.listdir(filesystem_path):
|
||||
if os.path.isdir(os.path.join(filesystem_path, filename)):
|
||||
filenames.append(filename + "/")
|
||||
else:
|
||||
filenames.append(filename)
|
||||
filenames.append(filename)
|
||||
filenames.sort()
|
||||
return self.directory_listing(filenames, path, filesystem_path)
|
||||
|
||||
|
46
cli/poetry.lock
generated
46
cli/poetry.lock
generated
@ -98,7 +98,7 @@ dotenv = ["python-dotenv"]
|
||||
|
||||
[[package]]
|
||||
name = "flask-httpauth"
|
||||
version = "4.1.0"
|
||||
version = "4.2.0"
|
||||
description = "Basic and Digest HTTP authentication for Flask routes"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -214,6 +214,17 @@ importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
|
||||
[[package]]
|
||||
name = "psutil"
|
||||
version = "5.7.3"
|
||||
description = "Cross-platform lib for process and system monitoring in Python."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[package.extras]
|
||||
test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"]
|
||||
|
||||
[[package]]
|
||||
name = "py"
|
||||
version = "1.9.0"
|
||||
@ -302,7 +313,7 @@ client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.24.0"
|
||||
version = "2.25.0"
|
||||
description = "Python HTTP for Humans."
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -312,7 +323,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
certifi = ">=2017.4.17"
|
||||
chardet = ">=3.0.2,<4"
|
||||
idna = ">=2.5,<3"
|
||||
urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26"
|
||||
urllib3 = ">=1.21.1,<1.27"
|
||||
|
||||
[package.extras]
|
||||
security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
|
||||
@ -344,7 +355,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "1.25.11"
|
||||
version = "1.26.2"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -382,7 +393,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.6"
|
||||
content-hash = "3947b230139f4b699f40c97e0b90d8c8ab6d3d7ef9093d16d2acb507131e14da"
|
||||
content-hash = "38f69a7cfa72b1da17d995e8c33dcceb0568ebfb065439927a5a007f3c8bd873"
|
||||
|
||||
[metadata.files]
|
||||
atomicwrites = [
|
||||
@ -422,8 +433,8 @@ flask = [
|
||||
{file = "Flask-1.1.2.tar.gz", hash = "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060"},
|
||||
]
|
||||
flask-httpauth = [
|
||||
{file = "Flask-HTTPAuth-4.1.0.tar.gz", hash = "sha256:9e028e4375039a49031eb9ecc40be4761f0540476040f6eff329a31dabd4d000"},
|
||||
{file = "Flask_HTTPAuth-4.1.0-py2.py3-none-any.whl", hash = "sha256:29e0288869a213c7387f0323b6bf2c7191584fb1da8aa024d9af118e5cd70de7"},
|
||||
{file = "Flask-HTTPAuth-4.2.0.tar.gz", hash = "sha256:8c7e49e53ce7dc14e66fe39b9334e4b7ceb8d0b99a6ba1c3562bb528ef9da84a"},
|
||||
{file = "Flask_HTTPAuth-4.2.0-py2.py3-none-any.whl", hash = "sha256:3fcedb99a03985915335a38c35bfee6765cbd66d7f46440fa3b42ae94a90fac7"},
|
||||
]
|
||||
flask-socketio = [
|
||||
{file = "Flask-SocketIO-4.3.1.tar.gz", hash = "sha256:36c1d5765010d1f4e4f05b4cc9c20c289d9dc70698c88d1addd0afcfedc5b062"},
|
||||
@ -512,6 +523,19 @@ pluggy = [
|
||||
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
|
||||
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
|
||||
]
|
||||
psutil = [
|
||||
{file = "psutil-5.7.3-cp27-none-win32.whl", hash = "sha256:1cd6a0c9fb35ece2ccf2d1dd733c1e165b342604c67454fd56a4c12e0a106787"},
|
||||
{file = "psutil-5.7.3-cp27-none-win_amd64.whl", hash = "sha256:e02c31b2990dcd2431f4524b93491941df39f99619b0d312dfe1d4d530b08b4b"},
|
||||
{file = "psutil-5.7.3-cp35-cp35m-win32.whl", hash = "sha256:56c85120fa173a5d2ad1d15a0c6e0ae62b388bfb956bb036ac231fbdaf9e4c22"},
|
||||
{file = "psutil-5.7.3-cp35-cp35m-win_amd64.whl", hash = "sha256:fa38ac15dbf161ab1e941ff4ce39abd64b53fec5ddf60c23290daed2bc7d1157"},
|
||||
{file = "psutil-5.7.3-cp36-cp36m-win32.whl", hash = "sha256:01bc82813fbc3ea304914581954979e637bcc7084e59ac904d870d6eb8bb2bc7"},
|
||||
{file = "psutil-5.7.3-cp36-cp36m-win_amd64.whl", hash = "sha256:6a3e1fd2800ca45083d976b5478a2402dd62afdfb719b30ca46cd28bb25a2eb4"},
|
||||
{file = "psutil-5.7.3-cp37-cp37m-win32.whl", hash = "sha256:fbcac492cb082fa38d88587d75feb90785d05d7e12d4565cbf1ecc727aff71b7"},
|
||||
{file = "psutil-5.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:5d9106ff5ec2712e2f659ebbd112967f44e7d33f40ba40530c485cc5904360b8"},
|
||||
{file = "psutil-5.7.3-cp38-cp38-win32.whl", hash = "sha256:ade6af32eb80a536eff162d799e31b7ef92ddcda707c27bbd077238065018df4"},
|
||||
{file = "psutil-5.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:2cb55ef9591b03ef0104bedf67cc4edb38a3edf015cf8cf24007b99cb8497542"},
|
||||
{file = "psutil-5.7.3.tar.gz", hash = "sha256:af73f7bcebdc538eda9cc81d19db1db7bf26f103f91081d780bbacfcb620dee2"},
|
||||
]
|
||||
py = [
|
||||
{file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"},
|
||||
{file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"},
|
||||
@ -575,8 +599,8 @@ python-socketio = [
|
||||
{file = "python_socketio-4.6.0-py2.py3-none-any.whl", hash = "sha256:d437f797c44b6efba2f201867cf02b8c96b97dff26d4e4281ac08b45817cd522"},
|
||||
]
|
||||
requests = [
|
||||
{file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"},
|
||||
{file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"},
|
||||
{file = "requests-2.25.0-py2.py3-none-any.whl", hash = "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998"},
|
||||
{file = "requests-2.25.0.tar.gz", hash = "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8"},
|
||||
]
|
||||
six = [
|
||||
{file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
|
||||
@ -590,8 +614,8 @@ toml = [
|
||||
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
||||
]
|
||||
urllib3 = [
|
||||
{file = "urllib3-1.25.11-py2.py3-none-any.whl", hash = "sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e"},
|
||||
{file = "urllib3-1.25.11.tar.gz", hash = "sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2"},
|
||||
{file = "urllib3-1.26.2-py2.py3-none-any.whl", hash = "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"},
|
||||
{file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"},
|
||||
]
|
||||
werkzeug = [
|
||||
{file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"},
|
||||
|
@ -21,6 +21,7 @@ click = "*"
|
||||
flask = "*"
|
||||
flask-httpauth = "*"
|
||||
flask-socketio = "*"
|
||||
psutil = "*"
|
||||
pycryptodome = "*"
|
||||
pysocks = "*"
|
||||
requests = "*"
|
||||
|
@ -14,7 +14,6 @@ icon = "src/onionshare/resources/onionshare"
|
||||
sources = ['src/onionshare']
|
||||
requires = [
|
||||
"./onionshare_cli-2.3.dev2-py3-none-any.whl",
|
||||
"psutil",
|
||||
"pyside2==5.15.1",
|
||||
"qrcode"
|
||||
]
|
||||
|
@ -128,7 +128,15 @@ class GuiCommon:
|
||||
""",
|
||||
"server_status_url_buttons": """
|
||||
QPushButton {
|
||||
color: #3f7fcf;
|
||||
border: 1px solid #d3d3d3;
|
||||
border-radius: 4px;
|
||||
background-color: #ffffff;
|
||||
padding: 8px 16px;
|
||||
text-align: center;
|
||||
color: #4e0d4e;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(239, 239, 240, 255))
|
||||
}
|
||||
""",
|
||||
"server_status_button_stopped": """
|
||||
|
Loading…
Reference in New Issue
Block a user