TODO

download.cgi
#!/usr/bin/env python3.4
# -*- coding: UTF-8 -*-
from Crypto.Cipher import AES
import hashlib
DOWNLOAD_TIMEOUT_S = 30
DOWNLOAD_DIR = "~/downloads/"
PASSWORD = "SWORDFISH".encode("utf-8")
import cgi
#import cgitb; cgitb.enable() # for troubleshooting
import os
import sys
import time
import urllib
from string import Template
from Crypto import Random
import binascii
class AESCipher(object):
key = hashlib.sha256(PASSWORD).digest()
bs = AES.block_size
def encrypt(self, number):
string = str(number).zfill(len(str(number)) + self.bs - len(str(number)) % self.bs).encode("latin1")
iv = Random.new().read(AES.block_size)
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return binascii.hexlify(iv + cipher.encrypt(string))
def decrypt(self, enc):
string = binascii.unhexlify(enc)
iv = string[:AES.block_size]
enc = string[AES.block_size:]
cipher = AES.new(self.key, AES.MODE_CBC, iv)
string = cipher.decrypt(enc)
return int(string)
test = ""
with open("./template/index.html", "rb") as file:
template = file.read()
def read_tokken(url_tokken):
try:
aes = AESCipher()
tokken_time = aes.decrypt(url_tokken)
except Exception:
return False
now = int(time.time())
return tokken_time > now - DOWNLOAD_TIMEOUT_S
def gen_new_tokken():
aes = AESCipher()
return aes.encrypt(int(time.time())).decode("utf-8")
class file_desc:
tokken = gen_new_tokken()#one tokken per side load
row_template = Template("<tr><td><a href=\"?tokken=$tokken&file=$file\">$filename</td></tr>\n")
def __init__(self, filepath, filename, description):
self.filename = filename
self.filepath = filepath
#self.description = description
def __str__(self):
return self.row_template.substitute(tokken=urllib.parse.quote_plus(self.tokken), file=urllib.parse.quote_plus(self.filename), filename=self.filename)
class header:
def __str__(self):
return "<table>"
class fotter:
def __str__(self):
return "</table>\n"
def send_file(filename):
filepath = os.path.join(DOWNLOAD_DIR, filename)
size = os.path.getsize(filepath)
sys.stdout.buffer.write(b'Cache-Control: no-cache, must-revalidate\n')
sys.stdout.buffer.write(b'Pragma: no-cache\n')
sys.stdout.buffer.write(b'Content-Length: ' + str(size).encode("ascii") + b'\n')
sys.stdout.buffer.write(b'Content-Disposition: attachment; filename=' + filename.encode("ascii") + b'\n')
sys.stdout.buffer.write(b'Content-Transfer-Encoding: binary\n')
sys.stdout.buffer.write(b'Content-Type: application/octet-stream\n\n')
with open(filepath , "rb" ) as download_file:
while True:
chunk = download_file.read(8192)
if not chunk:
break
sys.stdout.buffer.write(chunk)
def display_page(message_list):
global test
sys.stdout.buffer.write(b"Content-type: text/html; charset=utf-8\n\n")
tmp = ["<table>"]
tmp.extend([str(obj) for obj in message_list])
tmp.append("</table>")
tmp.append(test)
sys.stdout.buffer.write(template.replace(b"%%%youshouldnotseethis%%%", " ".join(tmp).encode("utf-8")))
def extract_params():
global test
form = cgi.FieldStorage(encoding="utf8")
tokken = form.getvalue("tokken", "")
file = form.getvalue("file", "")
if file == "" or tokken == "":
return False
file = urllib.parse.unquote_plus(file)
path = os.path.join(DOWNLOAD_DIR, file)
if not os.path.exists(path):
return False
tokken = urllib.parse.unquote_plus(tokken)
if read_tokken(tokken):
return file
else:
return False
def directory_to_objlist(directory):
files = os.listdir(directory)
objlist = []
for file in files:
objlist.append(file_desc(file, file, " "))
return objlist
file = extract_params()
if file:
send_file(file)
else:
display_page(directory_to_objlist(DOWNLOAD_DIR))