From 825107a2105fe090a3d595558ca98a7ef306594d Mon Sep 17 00:00:00 2001 From: Tim Wilkinson Date: Sun, 17 Nov 2024 17:05:05 -0800 Subject: [PATCH] Provide proxy and redirect for problematic services (#1699) * Add http proxy for easier access to problematic services * Redirect-or --- files/app/main/httpproxy.ut | 72 +++++++++++++++++++++++ files/app/main/redirect.ut | 61 +++++++++++++++++++ files/app/main/status/e/local-services.ut | 7 ++- 3 files changed, 138 insertions(+), 2 deletions(-) create mode 100755 files/app/main/httpproxy.ut create mode 100755 files/app/main/redirect.ut diff --git a/files/app/main/httpproxy.ut b/files/app/main/httpproxy.ut new file mode 100755 index 00000000..270850b2 --- /dev/null +++ b/files/app/main/httpproxy.ut @@ -0,0 +1,72 @@ +{% +/* + * Part of AREDN® -- Used for creating Amateur Radio Emergency Data Networks + * Copyright (C) 2024 Tim Wilkinson + * See Contributors file for additional contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Additional Terms: + * + * Additional use restrictions exist on the AREDN® trademark and logo. + * See AREDNLicense.txt for more info. + * + * Attributions to the AREDN® Project must be retained in the source code. + * If importing this code into a new or existing project attribution + * to the AREDN® project must be added to the source code. + * + * You must not misrepresent the origin of the material contained within. + * + * Modified versions must be modified to attribute to the original source + * and be marked in reasonable ways as differentiate it from the original + * version + */ +%} +{% +const url = request.env.QUERY_STRING; +const m = match(url, /^https?:\/\/(.+@)?([^/]+)\//); +let valid = false; +if (m) { + const host = replace(m[2], ".local.mesh", ""); + const s = fs.open("/etc/hosts"); + if (s) { + const k = lc(`\t${host}`); + for (let line = s.read("line"); length(line); line = s.read("line")) { + if (index(lc(line), k) !== -1) { + valid = true; + break; + } + } + s.close(); + } +} + +response.override = true; +if (valid) { + uhttpd.send("Status: 200 OK\r\nCache-Control: no-store\r\n\r\n"); + const s = fs.popen(`/usr/bin/wget -O - ${url}`); + if (s) { + for (;;) { + const d = s.read(10240); + if (!length(d)) { + break; + } + uhttpd.send(d); + } + s.close(); + } +} +else { + uhttpd.send("Status: 404 Not Found\r\nCache-Control: no-store\r\n\r\n"); +} +%} diff --git a/files/app/main/redirect.ut b/files/app/main/redirect.ut new file mode 100755 index 00000000..09bfd107 --- /dev/null +++ b/files/app/main/redirect.ut @@ -0,0 +1,61 @@ +{% +/* + * Part of AREDN® -- Used for creating Amateur Radio Emergency Data Networks + * Copyright (C) 2024 Tim Wilkinson + * See Contributors file for additional contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Additional Terms: + * + * Additional use restrictions exist on the AREDN® trademark and logo. + * See AREDNLicense.txt for more info. + * + * Attributions to the AREDN® Project must be retained in the source code. + * If importing this code into a new or existing project attribution + * to the AREDN® project must be added to the source code. + * + * You must not misrepresent the origin of the material contained within. + * + * Modified versions must be modified to attribute to the original source + * and be marked in reasonable ways as differentiate it from the original + * version + */ +%} +{% +const url = request.env.QUERY_STRING; +const m = match(url, /^https?:\/\/(.+@)?([^/]+)\//); +let valid = false; +if (m) { + const host = replace(m[2], ".local.mesh", ""); + const s = fs.open("/etc/hosts"); + if (s) { + const k = lc(`\t${host}`); + for (let line = s.read("line"); length(line); line = s.read("line")) { + if (index(lc(line), k) !== -1) { + valid = true; + break; + } + } + s.close(); + } +} + +response.override = true; +if (valid) { + uhttpd.send(`Status: 307 Temporary Redirect\r\nLocation: ${url}\r\nCache-Control: no-store\r\n\r\n`); +} +else { + uhttpd.send("Status: 404 Not Found\r\nCache-Control: no-store\r\n\r\n"); +} +%} diff --git a/files/app/main/status/e/local-services.ut b/files/app/main/status/e/local-services.ut index 5f3ca75f..fac5c2ad 100755 --- a/files/app/main/status/e/local-services.ut +++ b/files/app/main/status/e/local-services.ut @@ -97,6 +97,7 @@ const templates = [ { name: "Axis camera", type: "camera", protocol: "http", port: 80, path: "jpg/image.jpg" }, { name: "Sunba Lite camera", type: "camera", protocol: "http", port: 80, path: "webcapture.jpg?command=snap&channel=1&user=USERNAME&password=PASSWORD" }, { name: "Sunba Performance camera", type: "camera", protocol: "http", port: 80, path: "images/snapshot.jpg" }, + { name: "Sunba Performance camera (redirect)", type: "camera", protocol: "http", port: 80, path: "a/redirect?http://USERNAME:PASSWORD@CAMERANAME/images/snapshot.jpg" }, { name: "Sunba Smart camera", type: "camera", protocol: "http", port: 80, path: "ISAPI/Custom/snapshot?authInfo=USERNAME:PASSWORD" }, { name: "NTP Server", type: "time", protocol: "ntp", port: 123 }, { name: "Streaming video", type: "video", protocol: "rtsp", port: 554 }, @@ -108,6 +109,8 @@ const templates = [ { name: "Proxmox Server", type: "server", protocol: "https", port: 8006 }, { name: "Generic HTTP", protocol: "http", port: 80 }, { name: "Generic HTTPS", protocol: "https", port: 443 }, + { name: "HTTP Proxy", protocol: "http", port: 80, path: "a/httpproxy?URL" }, + { name: "Redirect", protocol: "http", port: 80, path: "a/redirect?URL" }, ]; const services = []; const dhcp = configuration.getDHCP(); @@ -254,7 +257,7 @@ if (f) { %} : - / + / {% } %} @@ -519,7 +522,7 @@ if (f) { :// : - / + /