2015-09-19 14:14:54 +00:00
|
|
|
from __future__ import print_function
|
|
|
|
import bottle as b
|
|
|
|
import base64
|
|
|
|
import ssl
|
|
|
|
import threading
|
|
|
|
import zlib
|
|
|
|
import sys
|
|
|
|
import functools
|
|
|
|
from Crypto.Cipher import AES
|
|
|
|
|
|
|
|
# fill with your values
|
|
|
|
# number of bytes; if less than or equals to zero then unlimited
|
|
|
|
MAXSIZE = 104857600 # max 100MB
|
|
|
|
PRODUCTION_HOST = '188.226.169.172'
|
|
|
|
PRODUCTION_PORT = 80
|
|
|
|
DEV_HOST = 'localhost'
|
|
|
|
DEV_PORT = 8080
|
|
|
|
URL_PREFIX = 'x'
|
|
|
|
# AES encryption stuff
|
|
|
|
# fill with your values
|
|
|
|
AES_MODE = AES.MODE_CFB
|
|
|
|
AES_IV = r'A123B890JKL @%#$'
|
|
|
|
AES_KEY = r')(*+AKIM 313 321kjah.;klk@sfsd%$'
|
|
|
|
|
2015-09-20 06:10:07 +00:00
|
|
|
debug = False
|
|
|
|
|
2015-09-19 14:14:54 +00:00
|
|
|
py3k = sys.version_info >= (3, 0, 0)
|
|
|
|
if py3k:
|
|
|
|
import urllib.request as urlreq
|
|
|
|
import urllib.parse as urlpar
|
|
|
|
|
|
|
|
stdout_write = sys.stdout.buffer.write
|
2015-09-20 06:10:07 +00:00
|
|
|
|
2015-09-19 14:14:54 +00:00
|
|
|
def get_content_length(r):
|
|
|
|
foo = r.getheader('Content-Length')
|
|
|
|
if foo:
|
|
|
|
return int(foo)
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
else:
|
|
|
|
import urllib2 as urlreq
|
|
|
|
import urllib as urlpar
|
|
|
|
|
|
|
|
stdout_write = sys.stdout.write
|
2015-09-20 06:10:07 +00:00
|
|
|
|
2015-09-19 14:14:54 +00:00
|
|
|
def get_content_length(r):
|
|
|
|
foo = r.info().getheaders('Content-Length')
|
|
|
|
if foo and len(foo) >= 1:
|
|
|
|
return int(foo[0])
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
|
|
|
urlunquote = urlpar.unquote
|
|
|
|
|
|
|
|
if hasattr(ssl, 'create_default_context'):
|
|
|
|
SSL_NO_VERIFY_CTX = ssl.create_default_context()
|
|
|
|
SSL_NO_VERIFY_CTX.check_hostname = False
|
|
|
|
SSL_NO_VERIFY_CTX.verify_mode = ssl.CERT_NONE
|
|
|
|
urlopen = functools.partial(urlreq.urlopen, context=SSL_NO_VERIFY_CTX)
|
|
|
|
else:
|
|
|
|
urlopen = urlreq.urlopen
|
|
|
|
|
|
|
|
|
|
|
|
lock = threading.Lock()
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: implement key rotation or something similar
|
|
|
|
def aes_key():
|
|
|
|
return AES_KEY
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: implement IV rotation or something similar
|
|
|
|
def aes_iv():
|
|
|
|
return AES_IV
|
|
|
|
|
|
|
|
|
|
|
|
def aes_new():
|
|
|
|
return AES.new(aes_key(), AES_MODE, aes_iv())
|
|
|
|
|
|
|
|
|
|
|
|
@b.route('/')
|
|
|
|
def x():
|
|
|
|
return "/" + URL_PREFIX + "/TARGET"
|
|
|
|
|
|
|
|
|
|
|
|
@b.route('/' + URL_PREFIX + '/<url:re:.+>')
|
|
|
|
def x(url):
|
|
|
|
global debug
|
|
|
|
# allow only one request at a time
|
|
|
|
with lock:
|
|
|
|
durl = str.encode(url)
|
2015-10-13 08:09:05 +00:00
|
|
|
durl = base64.urlsafe_b64decode(durl)
|
2015-09-19 14:14:54 +00:00
|
|
|
durl = zlib.decompress(durl)
|
|
|
|
aes = aes_new()
|
|
|
|
durl = aes.decrypt(durl)
|
|
|
|
durl = urlunquote(durl.decode())
|
|
|
|
if debug:
|
|
|
|
print('fetching {}'.format(durl))
|
|
|
|
foo = urlopen(durl)
|
|
|
|
content_length = get_content_length(foo)
|
|
|
|
if debug:
|
|
|
|
print('content-length: {}'.format(content_length))
|
|
|
|
if content_length is None:
|
|
|
|
x = str.encode('No Content-Length\n')
|
|
|
|
elif MAXSIZE > 0 and content_length > MAXSIZE:
|
|
|
|
x = str.encode('Too big\n')
|
|
|
|
else:
|
|
|
|
x = foo.read()
|
|
|
|
b.response.set_header('Content-Type', "text/plain")
|
|
|
|
b.response.set_header('Content-Disposition',
|
|
|
|
"attachment; filename=DATA.txt")
|
|
|
|
aes = aes_new()
|
|
|
|
return base64.b64encode(zlib.compress(aes.encrypt(x)))
|
|
|
|
|
2015-09-20 06:10:07 +00:00
|
|
|
if __name__ == "__main__":
|
|
|
|
argc = len(sys.argv)
|
|
|
|
if argc > 1:
|
|
|
|
aes = aes_new()
|
|
|
|
if sys.argv[1] == '-h':
|
|
|
|
print("usage: {0} -h print help".format(sys.argv[0]))
|
|
|
|
print("usage: {0} c TARGET encode TARGET".format(sys.argv[0]))
|
|
|
|
print("usage: {0} d decode stdin".format(sys.argv[0]))
|
|
|
|
print("usage: {0} ANY run server in debug mode on"
|
|
|
|
"8080".format(sys.argv[0]))
|
|
|
|
print("usage: {0} run server on 80".format(sys.argv[0]))
|
|
|
|
sys.exit(0)
|
|
|
|
elif sys.argv[1] == 'c':
|
|
|
|
if argc < 3:
|
|
|
|
print("missing target")
|
|
|
|
sys.exit(1)
|
|
|
|
else:
|
|
|
|
# encode target url
|
|
|
|
if sys.argv[1] == 'c':
|
|
|
|
foo = str.encode(sys.argv[2])
|
|
|
|
foo = aes.encrypt(foo)
|
|
|
|
foo = zlib.compress(foo)
|
2015-10-13 08:09:05 +00:00
|
|
|
foo = base64.urlsafe_b64encode(foo)
|
2015-09-20 06:10:07 +00:00
|
|
|
stdout_write(foo)
|
|
|
|
print()
|
|
|
|
sys.exit(0)
|
|
|
|
# decode data from stdin
|
|
|
|
elif sys.argv[1] == 'd':
|
|
|
|
foo = str.encode(sys.stdin.read())
|
|
|
|
foo = base64.b64decode(foo)
|
|
|
|
foo = zlib.decompress(foo)
|
|
|
|
foo = aes.decrypt(foo)
|
|
|
|
stdout_write(foo)
|
|
|
|
sys.exit(0)
|
2015-09-19 14:14:54 +00:00
|
|
|
else:
|
2015-09-20 06:10:07 +00:00
|
|
|
# run dev server
|
|
|
|
host = DEV_HOST
|
|
|
|
port = DEV_PORT
|
|
|
|
debug = True
|
2015-09-19 14:14:54 +00:00
|
|
|
else:
|
2015-09-20 06:10:07 +00:00
|
|
|
# run production server
|
|
|
|
host = PRODUCTION_HOST
|
|
|
|
port = PRODUCTION_PORT
|
|
|
|
debug = False
|
2015-09-19 14:14:54 +00:00
|
|
|
|
2015-09-20 06:10:07 +00:00
|
|
|
b.run(host=host, port=port, debug=debug, reloader=True)
|