Old version of my Stateless temp link downloader script. This version uses cgi.

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))

Published

Category

snippets

Tags