mirror of
https://github.com/onionshare/onionshare.git
synced 2024-12-28 00:39:37 -05:00
commit for pull
This commit is contained in:
parent
14276dd9ac
commit
3bb0f1c53c
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
.idea
|
||||||
|
|
||||||
# C extensions
|
# C extensions
|
||||||
*.so
|
*.so
|
||||||
|
@ -1,238 +0,0 @@
|
|||||||
import os, sys, subprocess, time, hashlib, platform, json, locale, socket, argparse, Queue, inspect
|
|
||||||
from random import randint
|
|
||||||
from functools import wraps
|
|
||||||
|
|
||||||
from stem.control import Controller
|
|
||||||
from stem import SocketError
|
|
||||||
|
|
||||||
from flask import Flask, Markup, Response, request, make_response, send_from_directory, render_template_string
|
|
||||||
|
|
||||||
class NoTor(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
|
|
||||||
strings = {}
|
|
||||||
onionshare_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
|
||||||
slug = os.urandom(16).encode('hex')
|
|
||||||
|
|
||||||
# information about the file
|
|
||||||
filename = filesize = filehash = None
|
|
||||||
def set_file_info(new_filename, new_filehash, new_filesize):
|
|
||||||
global filename, filehash, filesize
|
|
||||||
filename = new_filename
|
|
||||||
filehash = new_filehash
|
|
||||||
filesize = new_filesize
|
|
||||||
|
|
||||||
REQUEST_LOAD = 0
|
|
||||||
REQUEST_DOWNLOAD = 1
|
|
||||||
REQUEST_PROGRESS = 2
|
|
||||||
REQUEST_OTHER = 3
|
|
||||||
q = Queue.Queue()
|
|
||||||
|
|
||||||
download_count = 0
|
|
||||||
|
|
||||||
def add_request(type, path, data=None):
|
|
||||||
global q
|
|
||||||
q.put({
|
|
||||||
'type': type,
|
|
||||||
'path': path,
|
|
||||||
'data': data
|
|
||||||
})
|
|
||||||
|
|
||||||
@app.route("/{0}".format(slug))
|
|
||||||
def index():
|
|
||||||
global filename, filesize, filehash, slug, strings, REQUEST_LOAD
|
|
||||||
add_request(REQUEST_LOAD, request.path)
|
|
||||||
return render_template_string(open('{0}/index.html'.format(onionshare_dir)).read(),
|
|
||||||
slug=slug, filename=os.path.basename(filename), filehash=filehash, filesize=filesize, strings=strings)
|
|
||||||
|
|
||||||
@app.route("/{0}/download".format(slug))
|
|
||||||
def download():
|
|
||||||
global filename, filesize, q, download_count
|
|
||||||
global REQUEST_DOWNLOAD, REQUEST_PROGRESS
|
|
||||||
|
|
||||||
# each download has a unique id
|
|
||||||
download_id = download_count
|
|
||||||
download_count += 1
|
|
||||||
|
|
||||||
# tell GUI the download started
|
|
||||||
path = request.path
|
|
||||||
add_request(REQUEST_DOWNLOAD, path, { 'id':download_id })
|
|
||||||
|
|
||||||
dirname = os.path.dirname(filename)
|
|
||||||
basename = os.path.basename(filename)
|
|
||||||
|
|
||||||
def generate():
|
|
||||||
chunk_size = 102400 # 100kb
|
|
||||||
|
|
||||||
fp = open(filename, 'rb')
|
|
||||||
done = False
|
|
||||||
while not done:
|
|
||||||
chunk = fp.read(102400)
|
|
||||||
if chunk == '':
|
|
||||||
done = True
|
|
||||||
else:
|
|
||||||
yield chunk
|
|
||||||
|
|
||||||
# tell GUI the progress
|
|
||||||
add_request(REQUEST_PROGRESS, path, { 'id':download_id, 'bytes':fp.tell() })
|
|
||||||
fp.close()
|
|
||||||
|
|
||||||
r = Response(generate())
|
|
||||||
r.headers.add('Content-Length', filesize)
|
|
||||||
r.headers.add('Content-Disposition', 'attachment', filename=basename)
|
|
||||||
return r
|
|
||||||
|
|
||||||
@app.errorhandler(404)
|
|
||||||
def page_not_found(e):
|
|
||||||
global REQUEST_OTHER
|
|
||||||
add_request(REQUEST_OTHER, request.path)
|
|
||||||
return render_template_string(open('{0}/404.html'.format(onionshare_dir)).read())
|
|
||||||
|
|
||||||
def get_platform():
|
|
||||||
p = platform.system()
|
|
||||||
if p == 'Linux' and platform.uname()[0:2] == ('Linux', 'amnesia'):
|
|
||||||
p = 'Tails'
|
|
||||||
return p
|
|
||||||
|
|
||||||
def is_root():
|
|
||||||
return os.geteuid() == 0
|
|
||||||
|
|
||||||
def tails_open_port(port):
|
|
||||||
if get_platform() == 'Tails':
|
|
||||||
print strings["punching_a_hole"]
|
|
||||||
subprocess.call(['/sbin/iptables', '-I', 'OUTPUT', '-o', 'lo', '-p', 'tcp', '--dport', str(port), '-j', 'ACCEPT'])
|
|
||||||
|
|
||||||
def tails_close_port(port):
|
|
||||||
if get_platform() == 'Tails':
|
|
||||||
print strings["closing_hole"]
|
|
||||||
subprocess.call(['/sbin/iptables', '-I', 'OUTPUT', '-o', 'lo', '-p', 'tcp', '--dport', str(port), '-j', 'REJECT'])
|
|
||||||
|
|
||||||
def load_strings(default="en"):
|
|
||||||
global strings
|
|
||||||
try:
|
|
||||||
translated = json.loads(open('{0}/strings.json'.format(os.getcwd())).read())
|
|
||||||
except IOError:
|
|
||||||
translated = json.loads(open('{0}/strings.json'.format(onionshare_dir)).read())
|
|
||||||
strings = translated[default]
|
|
||||||
lc, enc = locale.getdefaultlocale()
|
|
||||||
if lc:
|
|
||||||
lang = lc[:2]
|
|
||||||
if lang in translated:
|
|
||||||
# if a string doesn't exist, fallback to English
|
|
||||||
for key in translated[default]:
|
|
||||||
if key in translated[lang]:
|
|
||||||
strings[key] = translated[lang][key]
|
|
||||||
return strings
|
|
||||||
|
|
||||||
def file_crunching(filename):
|
|
||||||
# calculate filehash, file size
|
|
||||||
BLOCKSIZE = 65536
|
|
||||||
hasher = hashlib.sha1()
|
|
||||||
with open(filename, 'rb') as f:
|
|
||||||
buf = f.read(BLOCKSIZE)
|
|
||||||
while len(buf) > 0:
|
|
||||||
hasher.update(buf)
|
|
||||||
buf = f.read(BLOCKSIZE)
|
|
||||||
filehash = hasher.hexdigest()
|
|
||||||
filesize = os.path.getsize(filename)
|
|
||||||
return filehash, filesize
|
|
||||||
|
|
||||||
def choose_port():
|
|
||||||
# let the OS choose a port
|
|
||||||
tmpsock = socket.socket()
|
|
||||||
tmpsock.bind(("127.0.0.1", 0))
|
|
||||||
port = tmpsock.getsockname()[1]
|
|
||||||
tmpsock.close()
|
|
||||||
return port
|
|
||||||
|
|
||||||
def start_hidden_service(port):
|
|
||||||
# come up with a hidden service directory name
|
|
||||||
hidserv_dir_rand = os.urandom(8).encode('hex')
|
|
||||||
if get_platform() == "Windows":
|
|
||||||
if 'Temp' in os.environ:
|
|
||||||
temp = os.environ['Temp'].replace('\\', '/')
|
|
||||||
else:
|
|
||||||
temp = 'C:/tmp'
|
|
||||||
hidserv_dir = "{0}/onionshare_{1}".format(temp, hidserv_dir_rand)
|
|
||||||
else:
|
|
||||||
hidserv_dir = "/tmp/onionshare_{0}".format(hidserv_dir_rand)
|
|
||||||
|
|
||||||
# connect to the tor controlport
|
|
||||||
controlports = [9051, 9151]
|
|
||||||
controller = False
|
|
||||||
for controlport in controlports:
|
|
||||||
try:
|
|
||||||
controller = Controller.from_port(port=controlport)
|
|
||||||
except SocketError:
|
|
||||||
pass
|
|
||||||
if not controller:
|
|
||||||
raise NoTor(strings["cant_connect_ctrlport"].format(controlports))
|
|
||||||
controller.authenticate()
|
|
||||||
|
|
||||||
# set up hidden service
|
|
||||||
controller.set_options([
|
|
||||||
('HiddenServiceDir', hidserv_dir),
|
|
||||||
('HiddenServicePort', '80 127.0.0.1:{0}'.format(port))
|
|
||||||
])
|
|
||||||
|
|
||||||
# figure out the .onion hostname
|
|
||||||
hostname_file = '{0}/hostname'.format(hidserv_dir)
|
|
||||||
onion_host = open(hostname_file, 'r').read().strip()
|
|
||||||
|
|
||||||
return onion_host
|
|
||||||
|
|
||||||
def main():
|
|
||||||
load_strings()
|
|
||||||
|
|
||||||
# check for root in Tails
|
|
||||||
if get_platform() == 'Tails' and not is_root():
|
|
||||||
sys.exit(strings["tails_requires_root"])
|
|
||||||
|
|
||||||
# parse arguments
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('--local-only', action='store_true', dest='local_only', help='Do not attempt to use tor: for development only')
|
|
||||||
parser.add_argument('filename', nargs=1)
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
filename = os.path.abspath(args.filename[0])
|
|
||||||
local_only = args.local_only
|
|
||||||
|
|
||||||
if not (filename and os.path.isfile(filename)):
|
|
||||||
sys.exit(strings["not_a_file"].format(filename))
|
|
||||||
filename = os.path.abspath(filename)
|
|
||||||
|
|
||||||
port = choose_port()
|
|
||||||
local_host = "127.0.0.1:{0}".format(port)
|
|
||||||
|
|
||||||
if not local_only:
|
|
||||||
# try starting hidden service
|
|
||||||
print strings["connecting_ctrlport"].format(port)
|
|
||||||
try:
|
|
||||||
onion_host = start_hidden_service(port)
|
|
||||||
except NoTor as e:
|
|
||||||
sys.exit(e.args[0])
|
|
||||||
|
|
||||||
# startup
|
|
||||||
print strings["calculating_sha1"]
|
|
||||||
filehash, filesize = file_crunching(filename)
|
|
||||||
set_file_info(filename, filehash, filesize)
|
|
||||||
tails_open_port(port)
|
|
||||||
print '\n' + strings["give_this_url"]
|
|
||||||
if local_only:
|
|
||||||
print 'http://{0}/{1}'.format(local_host, slug)
|
|
||||||
else:
|
|
||||||
print 'http://{0}/{1}'.format(onion_host, slug)
|
|
||||||
print ''
|
|
||||||
print strings["ctrlc_to_stop"]
|
|
||||||
|
|
||||||
# start the web server
|
|
||||||
app.run(port=port)
|
|
||||||
print '\n'
|
|
||||||
|
|
||||||
# shutdown
|
|
||||||
tails_close_port(port)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -3,8 +3,6 @@ from PyQt4.QtCore import *
|
|||||||
from PyQt4.QtGui import *
|
from PyQt4.QtGui import *
|
||||||
from PyQt4.QtWebKit import *
|
from PyQt4.QtWebKit import *
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
onionshare_gui_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
onionshare_gui_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -14,7 +12,6 @@ except ImportError:
|
|||||||
import onionshare
|
import onionshare
|
||||||
|
|
||||||
import webapp
|
import webapp
|
||||||
>>>>>>> 272092f877ade0ada63fc1b7b43f7837e73adede
|
|
||||||
|
|
||||||
window_icon = None
|
window_icon = None
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user