summaryrefslogtreecommitdiff
path: root/onionshare
diff options
context:
space:
mode:
authorMicah Lee <micah@micahflee.com>2019-11-02 15:37:21 -0700
committerMicah Lee <micah@micahflee.com>2019-11-02 15:37:21 -0700
commit9f0e031c8bec382953cf97eec0beeadec49458ed (patch)
tree4f5d51b1b8ea7b74dc34c6d0343d786e881fc0ae /onionshare
parentb8f12994962a402555fcd153f56e1c23d71c5d57 (diff)
downloadonionshare-9f0e031c8bec382953cf97eec0beeadec49458ed.tar.gz
onionshare-9f0e031c8bec382953cf97eec0beeadec49458ed.zip
Refactor onionshare CLI to accept and use all mode settings
Diffstat (limited to 'onionshare')
-rw-r--r--onionshare/__init__.py164
-rw-r--r--onionshare/onionshare.py7
-rw-r--r--onionshare/web/send_base_mode.py3
-rw-r--r--onionshare/web/share_mode.py19
-rw-r--r--onionshare/web/web.py10
5 files changed, 129 insertions, 74 deletions
diff --git a/onionshare/__init__.py b/onionshare/__init__.py
index a85de871..e7c7158c 100644
--- a/onionshare/__init__.py
+++ b/onionshare/__init__.py
@@ -29,9 +29,9 @@ from .onionshare import OnionShare
from .mode_settings import ModeSettings
-def build_url(common, app, web):
+def build_url(mode_settings, app, web):
# Build the URL
- if common.settings.get("public_mode"):
+ if mode_settings.get("general", "public"):
return f"http://{app.onion_host}"
else:
return f"http://onionshare:{web.password}@{app.onion_host}"
@@ -56,63 +56,101 @@ def main(cwd=None):
parser = argparse.ArgumentParser(
formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=28)
)
+ # Select modes
+ parser.add_argument(
+ "--receive", action="store_true", dest="receive", help="Receive files"
+ )
+ parser.add_argument(
+ "--website", action="store_true", dest="website", help="Publish website"
+ )
+ # Tor connection-related args
parser.add_argument(
"--local-only",
action="store_true",
dest="local_only",
+ default=False,
help="Don't use Tor (only for development)",
)
parser.add_argument(
- "--stay-open",
+ "--connect-timeout",
+ metavar="<int>",
+ dest="connect_timeout",
+ default=120,
+ help="Give up connecting to Tor after a given amount of seconds (default: 120)",
+ )
+ parser.add_argument(
+ "--config",
+ metavar="config",
+ default=None,
+ help="Filename of custom global settings",
+ )
+ # Persistent file
+ parser.add_argument(
+ "--persistent",
+ metavar="persistent",
+ default=None,
+ help="Filename of persistent session",
+ )
+ # General args
+ parser.add_argument(
+ "--public",
action="store_true",
- dest="stay_open",
- help="Continue sharing after files have been sent",
+ dest="public",
+ default=False,
+ help="Don't use a password",
)
parser.add_argument(
"--auto-start-timer",
metavar="<int>",
dest="autostart_timer",
default=0,
- help="Schedule this share to start N seconds from now",
+ help="Start onion service at scheduled time (N seconds from now)",
)
parser.add_argument(
"--auto-stop-timer",
metavar="<int>",
dest="autostop_timer",
default=0,
- help="Stop sharing after a given amount of seconds",
+ help="Stop onion service at schedule time (N seconds from now)",
)
parser.add_argument(
- "--connect-timeout",
- metavar="<int>",
- dest="connect_timeout",
- default=120,
- help="Give up connecting to Tor after a given amount of seconds (default: 120)",
+ "--legacy",
+ action="store_true",
+ dest="legacy",
+ default=False,
+ help="Use legacy address (v2 onion service, not recommended)",
)
parser.add_argument(
- "--stealth",
+ "--client-auth",
action="store_true",
- dest="stealth",
- help="Use client authorization (advanced)",
+ dest="client_auth",
+ default=False,
+ help="Use client authorization (requires --legacy)",
)
+ # Share args
parser.add_argument(
- "--receive",
+ "--autostop-sharing",
action="store_true",
- dest="receive",
- help="Receive shares instead of sending them",
+ dest="autostop_sharing",
+ default=True,
+ help="Share files: Stop sharing after files have been sent",
)
+ # Receive args
parser.add_argument(
- "--website",
- action="store_true",
- dest="website",
- help="Publish a static website",
+ "--data-dir",
+ metavar="data_dir",
+ default=None,
+ help="Receive files: Save files received to this directory",
)
+ # Website args
parser.add_argument(
- "--config",
- metavar="config",
+ "--disable_csp",
+ action="store_true",
+ dest="disable_csp",
default=False,
- help="Custom JSON config file location (optional)",
+ help="Publish website: Disable Content Security Policy header (allows your website to use third-party resources)",
)
+ # Other
parser.add_argument(
"-v",
"--verbose",
@@ -132,16 +170,21 @@ def main(cwd=None):
for i in range(len(filenames)):
filenames[i] = os.path.abspath(filenames[i])
- local_only = bool(args.local_only)
- verbose = bool(args.verbose)
- stay_open = bool(args.stay_open)
- autostart_timer = int(args.autostart_timer)
- autostop_timer = int(args.autostop_timer)
- connect_timeout = int(args.connect_timeout)
- stealth = bool(args.stealth)
receive = bool(args.receive)
website = bool(args.website)
+ local_only = bool(args.local_only)
+ connect_timeout = int(args.connect_timeout)
config = args.config
+ persistent = args.persistent
+ public = bool(args.public)
+ autostart_timer = int(args.autostart_timer)
+ autostop_timer = int(args.autostop_timer)
+ legacy = bool(args.legacy)
+ client_auth = bool(args.client_auth)
+ autostop_sharing = bool(args.autostop_sharing)
+ data_dir = args.data_dir
+ disable_csp = bool(args.disable_csp)
+ verbose = bool(args.verbose)
if receive:
mode = "receive"
@@ -169,6 +212,13 @@ def main(cwd=None):
if not valid:
sys.exit()
+ # client_auth can only be set if legacy is also set
+ if client_auth and not legacy:
+ print(
+ "Client authentication (--client-auth) is only supported with with legacy onion services (--legacy)"
+ )
+ sys.exit()
+
# Re-load settings, if a custom config was passed in
if config:
common.load_settings(config)
@@ -180,6 +230,20 @@ def main(cwd=None):
# Mode settings
mode_settings = ModeSettings(common)
+ mode_settings.set("general", "public", public)
+ mode_settings.set("general", "autostart_timer", autostart_timer)
+ mode_settings.set("general", "autostop_timer", autostop_timer)
+ mode_settings.set("general", "legacy", legacy)
+ mode_settings.set("general", "client_auth", client_auth)
+ if mode == "share":
+ mode_settings.set("share", "autostop_sharing", autostop_sharing)
+ if mode == "receive":
+ if data_dir:
+ mode_settings.set("receive", "data_dir", data_dir)
+ if mode == "website":
+ mode_settings.set("website", "disable_csp", disable_csp)
+
+ # TODO: handle persistent
# Create the Web object
web = Web(common, False, mode_settings, mode)
@@ -202,36 +266,35 @@ def main(cwd=None):
# Start the onionshare app
try:
common.settings.load()
- if not common.settings.get("public_mode"):
- web.generate_password(common.settings.get("password"))
+ if not mode_settings.get("general", "public"):
+ web.generate_password(mode_settings.get("persistent", "password"))
else:
web.password = None
app = OnionShare(common, onion, local_only, autostop_timer)
- app.set_stealth(stealth)
app.choose_port()
# Delay the startup if a startup timer was set
if autostart_timer > 0:
# Can't set a schedule that is later than the auto-stop timer
- if app.autostop_timer > 0 and app.autostop_timer < autostart_timer:
+ if autostop_timer > 0 and autostop_timer < autostart_timer:
print(
"The auto-stop time can't be the same or earlier than the auto-start time. Please update it to start sharing."
)
sys.exit()
app.start_onion_service(False, True)
- url = build_url(common, app, web)
+ url = build_url(mode_settings, app, web)
schedule = datetime.now() + timedelta(seconds=autostart_timer)
if mode == "receive":
print(
- f"Files sent to you appear in this folder: {common.settings.get('data_dir')}"
+ f"Files sent to you appear in this folder: {mode_settings.get('receive', 'data_dir')}"
)
print("")
print(
"Warning: Receive mode lets people upload files to your computer. Some files can potentially take control of your computer if you open them. Only open things from people you trust, or if you know what you are doing."
)
print("")
- if stealth:
+ if mode_settings.get("general", "client_auth"):
print(
f"Give this address and HidServAuth lineto your sender, and tell them it won't be accessible until: {schedule.strftime('%I:%M:%S%p, %b %d, %y')}"
)
@@ -241,7 +304,7 @@ def main(cwd=None):
f"Give this address to your sender, and tell them it won't be accessible until: {schedule.strftime('%I:%M:%S%p, %b %d, %y')}"
)
else:
- if stealth:
+ if mode_settings.get("general", "client_auth"):
print(
f"Give this address and HidServAuth line to your recipient, and tell them it won't be accessible until: {schedule.strftime('%I:%M:%S%p, %b %d, %y')}"
)
@@ -291,10 +354,7 @@ def main(cwd=None):
print("")
# Start OnionShare http service in new thread
- t = threading.Thread(
- target=web.start,
- args=(app.port, stay_open, common.settings.get("public_mode"), web.password),
- )
+ t = threading.Thread(target=web.start, args=(app.port,))
t.daemon = True
t.start()
@@ -307,13 +367,13 @@ def main(cwd=None):
app.autostop_timer_thread.start()
# Save the web password if we are using a persistent private key
- if common.settings.get("save_private_key"):
- if not common.settings.get("password"):
- common.settings.set("password", web.password)
- common.settings.save()
+ if mode_settings.get("persistent", "enabled"):
+ if not mode_settings.get("persistent", "password"):
+ mode_settings.set("persistent", "password", web.password)
+ # mode_settings.save()
# Build the URL
- url = build_url(common, app, web)
+ url = build_url(mode_settings, app, web)
print("")
if autostart_timer > 0:
@@ -321,7 +381,7 @@ def main(cwd=None):
else:
if mode == "receive":
print(
- f"Files sent to you appear in this folder: {common.settings.get('data_dir')}"
+ f"Files sent to you appear in this folder: {mode_settings.get('receive', 'data_dir')}"
)
print("")
print(
@@ -329,7 +389,7 @@ def main(cwd=None):
)
print("")
- if stealth:
+ if mode_settings.get("general", "client_auth"):
print("Give this address and HidServAuth to the sender:")
print(url)
print(app.auth_string)
@@ -337,7 +397,7 @@ def main(cwd=None):
print("Give this address to the sender:")
print(url)
else:
- if stealth:
+ if mode_settings.get("general", "client_auth"):
print("Give this address and HidServAuth line to the recipient:")
print(url)
print(app.auth_string)
diff --git a/onionshare/onionshare.py b/onionshare/onionshare.py
index 955f813d..a5c03ea3 100644
--- a/onionshare/onionshare.py
+++ b/onionshare/onionshare.py
@@ -42,7 +42,6 @@ class OnionShare(object):
self.hidserv_dir = None
self.onion_host = None
self.port = None
- self.stealth = None
# files and dirs to delete on shutdown
self.cleanup_filenames = []
@@ -55,12 +54,6 @@ class OnionShare(object):
# init auto-stop timer thread
self.autostop_timer_thread = None
- def set_stealth(self, stealth):
- self.common.log("OnionShare", f"set_stealth", "stealth={stealth}")
-
- self.stealth = stealth
- self.onion.stealth = stealth
-
def choose_port(self):
"""
Choose a random port.
diff --git a/onionshare/web/send_base_mode.py b/onionshare/web/send_base_mode.py
index c2086f15..020b65e0 100644
--- a/onionshare/web/send_base_mode.py
+++ b/onionshare/web/send_base_mode.py
@@ -26,8 +26,7 @@ class SendBaseModeWeb:
self.gzip_filesize = None
self.zip_writer = None
- # If "Stop After First Download" is checked (stay_open == False), only allow
- # one download at a time.
+ # If autostop_sharing, only allow one download at a time
self.download_in_progress = False
# This tracks the history id
diff --git a/onionshare/web/share_mode.py b/onionshare/web/share_mode.py
index 7e4f1672..60c8eca0 100644
--- a/onionshare/web/share_mode.py
+++ b/onionshare/web/share_mode.py
@@ -37,7 +37,10 @@ class ShareModeWeb(SendBaseModeWeb):
# Deny new downloads if "Stop sharing after files have been sent" is checked and there is
# currently a download
- deny_download = not self.web.stay_open and self.download_in_progress
+ deny_download = (
+ not self.web.settings.get("share", "autostop_sharing")
+ and self.download_in_progress
+ )
if deny_download:
r = make_response(
render_template("denied.html"),
@@ -60,7 +63,10 @@ class ShareModeWeb(SendBaseModeWeb):
"""
# Deny new downloads if "Stop After First Download" is checked and there is
# currently a download
- deny_download = not self.web.stay_open and self.download_in_progress
+ deny_download = (
+ not self.web.settings.get("share", "autostop_sharing")
+ and self.download_in_progress
+ )
if deny_download:
r = make_response(
render_template(
@@ -96,7 +102,7 @@ class ShareModeWeb(SendBaseModeWeb):
def generate():
# Starting a new download
- if not self.web.stay_open:
+ if not self.web.settings.get("share", "autostop_sharing"):
self.download_in_progress = True
chunk_size = 102400 # 100kb
@@ -161,11 +167,14 @@ class ShareModeWeb(SendBaseModeWeb):
sys.stdout.write("\n")
# Download is finished
- if not self.web.stay_open:
+ if not self.web.settings.get("share", "autostop_sharing"):
self.download_in_progress = False
# Close the server, if necessary
- if not self.web.stay_open and not canceled:
+ if (
+ not self.web.settings.get("share", "autostop_sharing")
+ and not canceled
+ ):
print("Stopped because transfer is complete")
self.web.running = False
try:
diff --git a/onionshare/web/web.py b/onionshare/web/web.py
index 07fa5b6b..a143a22f 100644
--- a/onionshare/web/web.py
+++ b/onionshare/web/web.py
@@ -352,17 +352,11 @@ class Web:
pass
self.running = False
- def start(self, port, stay_open=False, public_mode=False, password=None):
+ def start(self, port):
"""
Start the flask web server.
"""
- self.common.log(
- "Web",
- "start",
- f"port={port}, stay_open={stay_open}, public_mode={public_mode}, password={password}",
- )
-
- self.stay_open = stay_open
+ self.common.log("Web", "start", f"port={port}")
# Make sure the stop_q is empty when starting a new server
while not self.stop_q.empty():