mirror of
https://github.com/onionshare/onionshare.git
synced 2024-12-27 08:19:41 -05:00
Add support for stealth onion services in CLI version
This commit is contained in:
parent
fd41eac48d
commit
eff0d3729a
@ -33,6 +33,14 @@ class NoTor(Exception):
|
||||
"""
|
||||
pass
|
||||
|
||||
class TorTooOld(Exception):
|
||||
"""
|
||||
This exception is raised if onionshare needs to use a feature of Tor or stem
|
||||
(like stealth ephemeral onion services) but the version you have installed
|
||||
is too old.
|
||||
"""
|
||||
pass
|
||||
|
||||
class Onion(object):
|
||||
"""
|
||||
Onion is an abstraction layer for connecting to the Tor control port and
|
||||
@ -48,8 +56,9 @@ class Onion(object):
|
||||
onion services are supported. If not, it falls back to modifying the
|
||||
Tor configuration.
|
||||
"""
|
||||
def __init__(self, transparent_torification=False):
|
||||
def __init__(self, transparent_torification=False, stealth=False):
|
||||
self.transparent_torification = transparent_torification
|
||||
self.stealth = stealth
|
||||
|
||||
# files and dirs to delete on shutdown
|
||||
self.cleanup_filenames = []
|
||||
@ -89,17 +98,42 @@ class Onion(object):
|
||||
list_ephemeral_hidden_services = getattr(self.c, "list_ephemeral_hidden_services", None)
|
||||
self.supports_ephemeral = callable(list_ephemeral_hidden_services) and tor_version >= '0.2.7.1'
|
||||
|
||||
# do the versions of stem and tor that I'm using support stealth onion services?
|
||||
try:
|
||||
res = self.c.create_ephemeral_hidden_service({1:1}, basic_auth={'onionshare':None}, await_publication=False)
|
||||
tmp_service_id = res.content()[0][2].split('=')[1]
|
||||
self.c.remove_ephemeral_hidden_service(tmp_service_id)
|
||||
self.supports_stealth = True
|
||||
except TypeError:
|
||||
# ephemeral stealth onion services are not supported
|
||||
self.supports_stealth = False
|
||||
|
||||
def start(self, port):
|
||||
"""
|
||||
Start a onion service on port 80, pointing to the given port, and
|
||||
return the onion hostname.
|
||||
"""
|
||||
print(strings._("connecting_ctrlport").format(int(port)))
|
||||
self.auth_string = None
|
||||
if self.stealth and not self.supports_stealth:
|
||||
raise TorTooOld(strings._('error_stealth_not_supported'))
|
||||
|
||||
print(strings._("config_onion_service").format(int(port)))
|
||||
if self.supports_ephemeral:
|
||||
print(strings._('using_ephemeral'))
|
||||
res = self.c.create_ephemeral_hidden_service({ 80: port }, await_publication = True)
|
||||
|
||||
if self.stealth:
|
||||
basic_auth = {'onionshare':None}
|
||||
else:
|
||||
basic_auth = None
|
||||
|
||||
res = self.c.create_ephemeral_hidden_service({ 80: port }, await_publication=True, basic_auth=basic_auth)
|
||||
self.service_id = res.content()[0][2].split('=')[1]
|
||||
onion_host = self.service_id + '.onion'
|
||||
|
||||
if self.stealth:
|
||||
auth_cookie = res.content()[2][2].split('=')[1].split(':')[1]
|
||||
self.auth_string = 'HidServAuth {} {}'.format(onion_host, auth_cookie)
|
||||
|
||||
return onion_host
|
||||
|
||||
else:
|
||||
|
@ -27,7 +27,7 @@ class OnionShare(object):
|
||||
OnionShare is the main application class. Pass in options and run
|
||||
start_onion_service and it will do the magic.
|
||||
"""
|
||||
def __init__(self, debug=False, local_only=False, stay_open=False, transparent_torification=False):
|
||||
def __init__(self, debug=False, local_only=False, stay_open=False, transparent_torification=False, stealth=False):
|
||||
self.port = None
|
||||
self.onion = None
|
||||
self.hidserv_dir = None
|
||||
@ -49,6 +49,9 @@ class OnionShare(object):
|
||||
# traffic automatically goes through Tor
|
||||
self.transparent_torification = transparent_torification
|
||||
|
||||
# use stealth onion service
|
||||
self.stealth = stealth
|
||||
|
||||
def choose_port(self):
|
||||
"""
|
||||
Pick an un-used port in the range 17600-17650 to bind to.
|
||||
@ -76,10 +79,13 @@ class OnionShare(object):
|
||||
return
|
||||
|
||||
if not self.onion:
|
||||
self.onion = onion.Onion(self.transparent_torification)
|
||||
self.onion = onion.Onion(self.transparent_torification, self.stealth)
|
||||
|
||||
self.onion_host = self.onion.start(self.port)
|
||||
|
||||
if self.stealth:
|
||||
self.auth_string = self.onion.auth_string
|
||||
|
||||
def cleanup(self):
|
||||
"""
|
||||
Shut everything down and clean up temporary files, etc.
|
||||
@ -115,6 +121,7 @@ def main(cwd=None):
|
||||
parser.add_argument('--local-only', action='store_true', dest='local_only', help=strings._("help_local_only"))
|
||||
parser.add_argument('--stay-open', action='store_true', dest='stay_open', help=strings._("help_stay_open"))
|
||||
parser.add_argument('--transparent', action='store_true', dest='transparent_torification', help=strings._("help_transparent_torification"))
|
||||
parser.add_argument('--stealth', action='store_true', dest='stealth', help=strings._("help_stealth"))
|
||||
parser.add_argument('--debug', action='store_true', dest='debug', help=strings._("help_debug"))
|
||||
parser.add_argument('filename', metavar='filename', nargs='+', help=strings._('help_filename'))
|
||||
args = parser.parse_args()
|
||||
@ -127,6 +134,7 @@ def main(cwd=None):
|
||||
debug = bool(args.debug)
|
||||
stay_open = bool(args.stay_open)
|
||||
transparent_torification = bool(args.transparent_torification)
|
||||
stealth = bool(args.stealth)
|
||||
|
||||
# validation
|
||||
valid = True
|
||||
@ -139,11 +147,13 @@ def main(cwd=None):
|
||||
|
||||
# start the onionshare app
|
||||
try:
|
||||
app = OnionShare(debug, local_only, stay_open, transparent_torification)
|
||||
app = OnionShare(debug, local_only, stay_open, transparent_torification, stealth)
|
||||
app.choose_port()
|
||||
app.start_onion_service()
|
||||
except onion.NoTor as e:
|
||||
sys.exit(e.args[0])
|
||||
except onion.TorTooOld as e:
|
||||
sys.exit(e.args[0])
|
||||
|
||||
# prepare files to share
|
||||
print(strings._("preparing_files"))
|
||||
@ -171,8 +181,13 @@ def main(cwd=None):
|
||||
# Wait for web.generate_slug() to finish running
|
||||
time.sleep(0.2)
|
||||
|
||||
print(strings._("give_this_url"))
|
||||
print('http://{0:s}/{1:s}'.format(app.onion_host, web.slug))
|
||||
if(stealth):
|
||||
print(strings._("give_this_url_stealth"))
|
||||
print('http://{0:s}/{1:s}'.format(app.onion_host, web.slug))
|
||||
print(app.auth_string)
|
||||
else:
|
||||
print(strings._("give_this_url"))
|
||||
print('http://{0:s}/{1:s}'.format(app.onion_host, web.slug))
|
||||
print('')
|
||||
print(strings._("ctrlc_to_stop"))
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"connecting_ctrlport": "Connecting to Tor control port to set up onion service on port {0:d}.",
|
||||
"config_onion_service": "Configuring onion service on port {0:d}.",
|
||||
"cant_connect_ctrlport": "Can't connect to Tor control port on port {0:s}. OnionShare requires Tor Browser to be running in the background to work. If you don't have it you can get it from https://www.torproject.org/.",
|
||||
"cant_connect_socksport": "Can't connect to Tor SOCKS5 server on port {0:s}. OnionShare requires Tor Browser to be running in the background to work. If you don't have it you can get it from https://www.torproject.org/.",
|
||||
"ctrlport_missing_password": "Connected to Tor control port on port {0:s}, but you require a password. You must have the TOR_AUTHENTICATION_PASSWORD environment variable set. Or just open Tor Browser in the background.",
|
||||
@ -10,6 +10,7 @@
|
||||
"wait_for_hs_nope": "Not ready yet.",
|
||||
"wait_for_hs_yup": "Ready!",
|
||||
"give_this_url": "Give this URL to the person you're sending the file to:",
|
||||
"give_this_url_stealth": "Give this URL and HidServAuth line to the person you're sending the file to:",
|
||||
"ctrlc_to_stop": "Press Ctrl-C to stop server",
|
||||
"not_a_file": "{0:s} is not a file.",
|
||||
"download_page_loaded": "Download page loaded",
|
||||
@ -19,10 +20,10 @@
|
||||
"large_filesize": "Warning: Sending large files could take hours",
|
||||
"error_tails_invalid_port": "Invalid value, port must be an integer",
|
||||
"error_tails_unknown_root": "Unknown error with Tails root process",
|
||||
"help_tails_port": "Tails only: port for opening firewall, starting onion service",
|
||||
"help_local_only": "Do not attempt to use tor: for development only",
|
||||
"help_stay_open": "Keep onion service running after download has finished",
|
||||
"help_transparent_torification": "My system is transparently torified",
|
||||
"help_stealth": "Create stealth onion service (advanced)",
|
||||
"help_debug": "Log errors to disk",
|
||||
"help_filename": "List of files or folders to share",
|
||||
"gui_drag_and_drop": "Drag and drop\nfiles here",
|
||||
@ -52,5 +53,6 @@
|
||||
"gui_quit_warning_quit": "Quit",
|
||||
"gui_quit_warning_dont_quit": "Don't Quit",
|
||||
"error_rate_limit": "An attacker might be trying to guess your URL. To prevent this, OnionShare has automatically stopped the server. To share the files you must start it again and share the new URL.",
|
||||
"zip_progress_bar_format": "Crunching files: %p%"
|
||||
"zip_progress_bar_format": "Crunching files: %p%",
|
||||
"error_stealth_not_supported": "Your versions of tor or stem are too old. You need to upgrade them to create stealth onion services."
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user