1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#!/usr/bin/env python3
# File: outbound.py
# Location: https://bgstack15.ddns.net/cgit/outbound/
# Author: bgstack15
# Startdate: 2022-11-28-2 16:34
# SPDX-License-Identifier: GPL-3.0
# Title: Outbound flask web app
# Project: outbound
# Purpose: allow web server to log outbound links, by using a link underneath this webapp entry point
# History:
# Usage: See README
# References:
# fuss.py, coupons.py
# https://werkzeug.palletsprojects.com/en/2.2.x/serving/#werkzeug.serving.run_simple
# Improve:
# ensure it works under an arbitrary top-level path like "/outbound/"
# add domain and port globbing in WHITELIST
# Dependencies:
# python3-flask
# Documentation: See README
from flask import Flask, request, redirect, abort
from urllib.parse import urlparse
import sys, os, re
# Load app from same directory as this file.py
#sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from urllib import parse
app = Flask(__name__)
try:
app.config.from_pyfile(os.environ["OUTBOUND_CONF"], silent=False)
except:
try:
app.config.from_pyfile("/etc/outbound.conf")
except:
try:
# from working directory
app.config.from_pyfile("outbound.conf")
except:
try:
# from same directory
app.config.from_pyfile(os.path.join(os.path.dirname(os.path.realpath(__file__)),"outbound.conf"))
except:
# defaults
print(f"WARNING: Using default configs because could not find OUTBOUND_CONF, or /etc/outbound.conf, or ./outbound.conf!")
app.config.update(
WHITELIST = ["localhost"],
DEBUG = False,
ALLOW_DEBUG = False
)
if "WSGI_LOGGING" in app.config:
dictConfig(app.config["WSGI_LOGGING"])
# satisfies mod_wsgi:
application = app
@app.route("/<path:url>", methods=["GET"])
def root(url = ""):
referer = None
allow_debug = app.config["ALLOW_DEBUG"]
_debug = app.config["DEBUG"]
try:
#print(dict(request.headers))
for item in dict(request.headers):
#print(f"Item: {item}, {request.headers.get('item')}")
#print(f"Evaluating item {item}")
if item.lower() in ["debug"]:
#print(f"DEBUG header: {request.headers.get(item).lower()}")
if request.headers.get(item).lower() in ["true","yes","on","1"]:
#print(f"{item}: {request.headers.get(item)}")
if allow_debug:
_debug = True
except:
pass
bad_referer = False
try:
referer = request.referrer
domain = urlparse(referer).netloc
if _debug:
print(f"Referer: {referer}, domain {domain}")
# TODO: allow wildcard/globbing
if domain in app.config["WHITELIST"]:
# Main logic to redirect to/print url.
# need to fix the webserver->flask collapse of the parameter string http:// down to http:/
new_url = re.sub("(((ht|f)tps?|gemini):)\/+","\\1//",url)
if _debug and allow_debug:
return f"redirect to {new_url}\n",307
else:
return redirect(new_url, 307)
else:
#print("Bad referer 1")
bad_referer = True
except:
#print("Bad referer 2")
bad_referer = True
if bad_referer:
if _debug and allow_debug:
return f"<html>Invalid referer: {referer}</html>\n",404
else:
abort(404)
return "OK", 200
if __name__ == "__main__":
app.run()
|