diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | README.debian | 12 | ||||
-rwxr-xr-x | fhost.py | 203 | ||||
-rw-r--r-- | front.html.in | 146 | ||||
-rw-r--r-- | hex-zero.conf.example | 39 |
5 files changed, 238 insertions, 164 deletions
@@ -3,3 +3,5 @@ __pycache__/ db.sqlite up/ *.pyc +.*.swp +*.conf diff --git a/README.debian b/README.debian new file mode 100644 index 0000000..a0104b2 --- /dev/null +++ b/README.debian @@ -0,0 +1,12 @@ +apt-get install uwsgi uwsgi-plugin-python3 python3-flask python3-alembic python3-click python3-decorator python3-flask-migrate python3-flask-script python3-flask-sqlalchemy python3-humanize python3-itsdangerous python3-jinja2 python3-mako python3-markupsafe python3-editor python3-magic python3-requests python3-six python3-validators python3-werkzeug +# need to find short-url (1.2.2) +sudo su hex-zero -c 'pip3 --user install short_url' + +# apache +a2enmod proxy +a2enmod rewrite +a2enmod proxy_http + +# to run: +cd /var/www/0x0 +ps -o user=,pid=,command:80= -u hex-zero | awk '/runserver/{print $2}' | xargs sudo kill ; sudo su hex-zero -c './fhost.py runserver' @@ -1,5 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# https://stackoverflow.com/a/34831345/3569534 """ Copyright © 2020 Mia Herkt @@ -21,7 +22,7 @@ from flask import Flask, abort, escape, make_response, redirect, request, send_from_directory, url_for, Response from flask_sqlalchemy import SQLAlchemy -from flask_script import Manager +from flask_script import Manager, Server from flask_migrate import Migrate, MigrateCommand from hashlib import sha256 from humanize import naturalsize @@ -68,6 +69,13 @@ app.config["FHOST_UPLOAD_BLACKLIST"] = "tornodes.txt" app.config["NSFW_DETECT"] = False app.config["NSFW_THRESHOLD"] = 0.608 +# read config file +app.config.from_pyfile("hex-zero.conf", silent=True) + +# read html template file +with open(app.config["FHOST_FRONTPAGE"], "r") as j: + frontpagestring = j.read() + if app.config["NSFW_DETECT"]: from nsfw_detect import NSFWDetector nsfw = NSFWDetector() @@ -124,11 +132,13 @@ class File(db.Model): def geturl(self): n = self.getname() + o = n if self.nsfw_score and self.nsfw_score > app.config["NSFW_THRESHOLD"]: - return url_for("get", path=n, _external=True, _anchor="nsfw") + "\n" + o = url_for("get", path=n, _external=True, _anchor="nsfw") + "\n" else: - return url_for("get", path=n, _external=True) + "\n" + o = url_for("get", path=n, _external=True) + "\n" + return o.replace("http://" + app.config["APP_HOST_LISTEN"] + ":" + str(app.config["APP_PORT"]),app.config["APP_URL"]) def pprint(self): print("url: {}".format(self.getname())) @@ -142,6 +152,7 @@ def getpath(fn): return os.path.join(app.config["FHOST_STORAGE_PATH"], fn) def fhost_url(scheme=None): + return app.config["APP_URL"] if not scheme: return url_for(".fhost", _external=True).rstrip("/") else: @@ -328,6 +339,19 @@ def get(path): abort(404) +@app.route("/dump_files/") +@app.route("/dump_files/<int:start>") +def dump_files(start=0): + meta = "#FORMAT: BEACON\n#PREFIX: {}/\n\n".format(fhost_url("https")) + + def gen(): + yield meta + + for file in File.query.order_by(File.id.asc()).offset(start): + yield file.getname() + "|" + str(file.id) + "\n" + + return Response(gen(), mimetype="text/plain") + @app.route("/dump_urls/") @app.route("/dump_urls/<int:start>") def dump_urls(start=0): @@ -352,7 +376,11 @@ def fhost(): out = None if "file" in request.files: - out = store_file(request.files["file"], request.remote_addr) + if app.config["USE_HTTP_X_FORWARDED_FOR"]: + stored_ip_address = request.environ["HTTP_X_FORWARDED_FOR"] + else: + stored_ip_address = request.remote_addr + out = store_file(request.files["file"], stored_ip_address) elif "url" in request.form: out = store_url(request.form["url"], request.remote_addr) elif "shorten" in request.form: @@ -375,153 +403,12 @@ def fhost(): if maxsizehalf.is_integer(): maxsizehalf = int(maxsizehalf) - return """<!DOCTYPE html> -<html lang="en"> - <head> - <title>{6}</title> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - <meta name="description" content="envs.sh | Null Pointer" /> - <link rel="stylesheet" href="https://envs.net/css/css_style.css" /> - </head> - <body id="body" class="dark-mode"> - <div class="clear" style="min-width: 1150px;"> - - <div id="main"> -<div class="block"> -<h1><em>envs.sh | THE NULL POINTER</em></h1> -<h2><em>file hosting and URL shortening service.</em></h2> -<br /> -</div> - -<h2>USAGE</h2> -<pre> -HTTP POST files here: - <code>curl -F'file=@yourfile.png' {0}</code> -post your text directly: - <code>echo "text here" | curl -F'file=@-;' {0}</code> -you can also POST remote URLs: - <code>curl -F'url=https://example.com/image.jpg' {0}</code> -or you can shorten URLs: - <code>curl -F'shorten=http://example.com/some/long/url' {0}</code> - -file URLs are valid for at least 30 days and up to a year (see below). -shortened URLs do not expire. -not allowed: {5} -maximum file size: {1} -</pre> -<br /> - -<h2>ACCEPTABLE USE POLICY</h2> -<pre> -please do not post any informations that -may violate law (login/password lists, email lists, personal information). - -envs.sh is NOT a platform for: -</pre> -<br /> -<ul> - <li>child pornography</li> - <li>malware, including “potentially unwanted applications”</li> - <li>botnet command and control schemes involving this service</li> - <li>anything even remotely related to crypto currencies</li> - <li>hosting your backups</li> - <li>spamming the service with CI build artifacts</li> - <li>piracy</li> - <li>alt-right shitposting</li> -</ul> -<br /> -<h2>REQUIREMENTS</h2> -<pre> -there is only one thing you need to use this service - curl. -curl is available on most platforms, including Windows, Mac OS X and Linux. - -if you run a server and like this site, clone it! centralization is bad. -<small><a href="https://github.com/envs-net/0x0" target="_blank">https://github.com/envs-net/0x0</a></small> -you can also support it financially via liberapay. -<a href="https://en.liberapay.com/envs.net/donate" target="_blank" style="border-bottom-color: transparent;"><img src="https://img.shields.io/liberapay/receives/envs.net.svg?logo=liberapay" alt="img_shield_receives_via_liberapay"></a> -</pre> -<br /> - -<h2>ALIAS</h2> -<pre> -to make your life easier, you can add aliases to your <code>.bash_aliases</code> on Linux -and <code>.bash_profile</code> on Mac OS X. just remember to reset your terminal session after that. -<code>0file() { curl -F"file=@$1" {0} ; } -0pb() { curl -F"file=@-;" {0} ; } -0url() { curl -F"url=$1" {0} ; } -0short() { curl -F"shorten=$1" {0} ; }</code> - -now you can use: -<code>0file "yourfile.png" -# or -echo "text here" | 0pb</code> - -<em>if you want a nice wrapper, try <a href="https://git.envs.net/envs/pb">~tomasino's pb</a></em> -</pre> -<br /> - -<h2>FILE RETENTION PERIOD</h2> -<pre> -retention = min_age + (-max_age + min_age) * pow((file_size / max_size - 1), 3) - - days - 365 | \\ - | \\ - | \\ - | \\ - | \\ - | \\ - | .. - | \\ - 197.5 | ----------..------------------------------------------- - | .. - | \\ - | .. - | ... - | .. - | ... - | .... - | ...... - 30 | .................... - 0{2}{3} - {4} -</pre> -<br /> - -<h2>ABUSE</h2> -<pre> -if you would like to request permanent deletion, please -send an email to <a href="mailto:hostmaster@envs.net?subject=Abuse%200x0%20-%20envs.sh" target="_blank">hostmaster@envs.net</a>. - -please allow up to 24 hours for a response. -</pre> - </div> - -<!-- UPLOAD --> - - <div id="sidebar"> -<div class="block"> -<h2>UPLOAD DIRECTLY</h2> -<br /> -<form action="{0}" method="POST" enctype="multipart/form-data"> -<label>File:</label><br /> -<input class="form-control" type="file" name="file" style="width:250px;"><br /> -<input class="form-control" type="submit" value="Submit"> -</form> -</div> - </div> - - <footer><pre class="clean">a <a href="https://envs.net/">envs.net</a> service | by <a href="https://envs.net/~creme/">~creme</a> | <a href="https://envs.net/impressum/">impressum</a></pre></footer> - - </div> - - </body> -</html> - -""".format(fhost_url(), + # python-interpreted variables + return frontpagestring.format(fhost_url(), maxsize, str(maxsizehalf).rjust(27), str(maxsizenum).rjust(27), maxsizeunit.rjust(54), - ", ".join(app.config["FHOST_MIME_BLACKLIST"]),fhost_url().split("/",2)[2]) + ", ".join(app.config["FHOST_MIME_BLACKLIST"]),fhost_url().split("/",2)[2], + app.config["APP_URL"], app.config["ADMIN_EMAIL"]) @app.route("/robots.txt") def robots(): @@ -541,21 +428,7 @@ def segfault(e): @app.errorhandler(404) def notfound(e): - return u"""<pre>Process {0} stopped -* thread #1: tid = {0}, {1:#018x}, name = '{2}' - frame #0: -Process {0} stopped -* thread #8: tid = {0}, {3:#018x} fhost`get(path='{4}') + 27 at fhost.c:139, name = 'fhost/responder', stop reason = invalid address (fault address: 0x30) - frame #0: {3:#018x} fhost`get(path='{4}') + 27 at fhost.c:139 - 136 get(SrvContext *ctx, const char *path) - 137 {{ - 138 StoredObj *obj = ctx->store->query(shurl_debase(path)); --> 139 switch (obj->type) {{ - 140 case ObjTypeFile: - 141 ctx->serve_file_id(obj->id); - 142 break; -(lldb) q</pre> -""".format(os.getpid(), id(app), "fhost", id(get), escape(request.path)), e.code + return make_response("404 File not found: {0}/{1}".format(fhost_url(),request.path.lstrip("/")),404) @manager.command def debug(): @@ -667,4 +540,6 @@ def querybl(nsfw=False, removed=False): f.pprint() if __name__ == "__main__": + # allow port adjustment + manager.add_command('runserver', Server(host=app.config["APP_HOST_LISTEN"], port=app.config["APP_PORT"])) manager.run() diff --git a/front.html.in b/front.html.in new file mode 100644 index 0000000..fcd2afa --- /dev/null +++ b/front.html.in @@ -0,0 +1,146 @@ +<!DOCTYPE html> +<!-- + python-interpreted variables that are available: + 0) {0} + 1) {1} + 2) {2} + 3) {3} + 4) {4} + 5) {5} + 6) {6} + 7) {7} + 8) {8} +--> +<html lang="en"> + <head> + <title>{6}</title> + <meta http-equiv="content-type" content="text/html; charset=utf-8" /> + <meta name="description" content="Hex Zero" /> + </head> + <body id="body" class="dark-mode"> + <div class="clear" style="min-width: 1150px;"> + + <div id="main"> +<div class="block"> +<h1>THE NULL POINTER</h1> +<h2>file hosting and URL shortening service.</h2> +</div> +<h2>USAGE</h2> +<pre> +HTTP POST files here: + <code>curl -F'file=@yourfile.png' {0}</code> +post your text directly: + <code>echo "text here" | curl -F'file=@-;' {0}</code> +you can also POST remote URLs: + <code>curl -F'url=https://example.com/image.jpg' {0}</code> +or you can shorten URLs: + <code>curl -F'shorten=http://example.com/some/long/url' {0}</code> + +file URLs are valid for at least 30 days and up to a year (see below). +shortened URLs do not expire. +not allowed: {5} +maximum file size: {1} +</pre> + +<h2>ACCEPTABLE USE POLICY</h2> +<pre> +please do not post any informations that +may violate law (login/password lists, email lists, personal information). + +{0} is NOT a platform for: +</pre> +<ul> + <li>child pornography</li> + <li>malware, including potentially unwanted applications</li> + <li>botnet command and control schemes involving this service</li> + <li>anything even remotely related to crypto currencies</li> + <li>hosting your backups</li> + <li>spamming the service with CI build artifacts</li> + <li>piracy</li> + <li>alt-right shitposting</li> +</ul> +<h2>REQUIREMENTS</h2> +<pre> +there is only one thing you need to use this service - curl. +curl is available on most platforms, including Windows, Mac OS X and Linux. + +if you run a server and like this site, clone it! centralization is bad. +<small><a href="https://github.com/envs-net/0x0" target="_blank">https://github.com/envs-net/0x0</a></small> +you can also support it financially via liberapay. +<a href="https://en.liberapay.com/envs.net/donate" target="_blank" style="border-bottom-color: transparent;"><img src="https://img.shields.io/liberapay/receives/envs.net.svg?logo=liberapay" alt="img_shield_receives_via_liberapay"></a> +</pre> + +<h2>ALIAS</h2> +<pre> +to make your life easier, you can add aliases to your <code>.bash_aliases</code> on Linux +and <code>.bash_profile</code> on Mac OS X. just remember to reset your terminal session after that. +<code>0file() { curl -F"file=@$1" {0} ; } +0pb() { curl -F"file=@-;" {0} ; } +0url() { curl -F"url=$1" {0} ; } +0short() { curl -F"shorten=$1" {0} ; }</code> + +now you can use: +<code>0file "yourfile.png" +# or +echo "text here" | 0pb</code> + +<em>if you want a nice wrapper, try <a href="https://git.envs.net/envs/pb">~tomasino's pb</a></em> +</pre> + +<h2>FILE RETENTION PERIOD</h2> +<pre> +retention = min_age + (-max_age + min_age) * pow((file_size / max_size - 1), 3) + + days + 365 | \\ + | \\ + | \\ + | \\ + | \\ + | \\ + | .. + | \\ + 197.5 | ----------..------------------------------------------- + | .. + | \\ + | .. + | ... + | .. + | ... + | .... + | ...... + 30 | .................... + 0{2}{3} + {4} +</pre> + +<h2>ABUSE</h2> +<pre> +if you would like to request permanent deletion, please +send an email to <a href="mailto:{8}?subject=Abuse%200x0%20-%20hex-zero" target="_blank">{8}</a>. + +please allow up to 24 hours for a response. +</pre> + </div> + +<!-- UPLOAD --> + + <div id="sidebar"> +<div class="block"> +<h2>UPLOAD DIRECTLY</h2> +<form action="{0}" method="POST" enctype="multipart/form-data"> +<label>File:</label> +<input class="form-control" type="file" name="file" style="width:250px;"><br /> +<input class="form-control" type="submit" value="Submit"> +</form> +</div> + </div> + <footer><pre class="clean">Adapted from <a href="https://github.com/envs-net/0x0">envs.net 0x0 app</a></footer> + <!-- +which itself is a fork of https://github.com/mia-0/0x0 and includes patches from +https://github.com/mia-0/0x0/pull/21 +https://github.com/iomintz/0x0/commit/51d51d4c00d9a5b66276a670b59308b5351a5e82 +--> + </div> + </body> +</html> diff --git a/hex-zero.conf.example b/hex-zero.conf.example new file mode 100644 index 0000000..19e6300 --- /dev/null +++ b/hex-zero.conf.example @@ -0,0 +1,39 @@ +# vim: syntax=python +FHOST_STORAGE_PATH = "/var/www/0x0/up" +FHOST_USE_X_ACCEL_REDIRECT = False # use True for nginx +USE_X_SENDFILE = False # supposed to use True when using anything other than nginx, but True fails in my apache2 setup +MAX_CONTENT_LENGTH = 512 * 1024 * 1024 +MAX_URL_LENGTH = 4096 +FHOST_EXT_OVERRIDE = { + "audio/flac" : ".flac", + "image/gif" : ".gif", + "image/jpeg" : ".jpg", + "image/png" : ".png", + "image/svg+xml" : ".svg", + "video/webm" : ".webm", + "video/x-matroska" : ".mkv", + "application/octet-stream" : ".bin", + "text/plain" : ".log", + "text/plain" : ".txt", + "text/x-diff" : ".diff", +} + +# default blacklist to avoid AV mafia extortion +FHOST_MIME_BLACKLIST = [ + "application/x-dosexec", + "application/java-archive", + "application/java-vm" +] + +# template for front page of app +FHOST_FRONTPAGE = "/var/www/0x0/front.html.in" + +ADMIN_EMAIL = "webmaster@example.com" +# with this, as well as use this for printing the base url of the app +APP_URL = "http://0x0.example.com/hex-zero" +# use the forwarded IP address header instead of the requester IP address +USE_HTTP_X_FORWARDED_FOR = True +# If you want to expose this app directly on 0.0.0.0 that is dangerous, but up to you. +APP_HOST_LISTEN = "localhost" +# this must match the apache proxy destination port number +APP_PORT = 3031 |