diff options
Diffstat (limited to '')
-rw-r--r-- | web/TMP/tools.html | 273 | ||||
-rwxr-xr-x | web/TMP/tools.py | 269 | ||||
-rw-r--r-- | web/TMP/tools/api/index.html | 11 | ||||
-rwxr-xr-x | web/TMP/tools/api/v0/dns/a/index.py | 93 | ||||
-rwxr-xr-x | web/TMP/tools/api/v0/ip/address/index.py | 70 | ||||
-rwxr-xr-x | web/TMP/tools/api/v0/ipv4/address/index.py | 62 | ||||
-rwxr-xr-x | web/TMP/tools/api/v0/ipv6/address/index.py | 62 |
7 files changed, 840 insertions, 0 deletions
diff --git a/web/TMP/tools.html b/web/TMP/tools.html new file mode 100644 index 0000000..6b8d23a --- /dev/null +++ b/web/TMP/tools.html @@ -0,0 +1,273 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta name="author" content="system-administration@open-infrastructure.net"> + <meta name="description" content="Open Infrastructure"> + <meta name="generator" content="open-infrastructure.net"> + <title>{hostname}</title> + + <link rel="canonical" href="https://open-infrastructure.net"> + <link rel="icon" href="/favicon.svg" type="image/svg+xml"> + + <!-- Bootstrap core CSS --> + <link href="/_static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> + + <!-- Custom styles for this template --> + <link href="/_static/bootstrap-icons/bootstrap-icons.css" rel="stylesheet"> + <link href="/_static/dejavu-fonts/dejavu-fonts.css" rel="stylesheet"> + + <link href="/_static/local/font.css" rel="stylesheet"> + <link href="/_static/local/icon.css" rel="stylesheet"> + </head> + + <body> + <nav class="navbar navbar-expand-md navbar-dark fixed-top" style="background: #a40000"> + <div class="container-fluid"> + <a class="navbar-brand" href="/"><b>{hostname}</b></a> + <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + <div style="width: 4em"></div> + <div class="collapse navbar-collapse" id="navbarCollapse"> + <ul class="navbar-nav me-auto mb-2 mb-md-0"> + <li class="nav-item"> + <a class="nav-link active" aria-current="page" href="/systems">Systems</a> + </li> + <li><div style="width: 1em"></div></li> + <li class="nav-item"> + <a class="nav-link active" aria-current="page" href="/tools">Tools</a> + </li> + <li><div style="width: 1em"></div></li> + <li class="nav-item"> + <a class="nav-link active" aria-current="page" href="/ttyd">ttyd</a> + </li> + <li><div style="width: 1em"></div></li> + <li class="nav-item"> + <a class="nav-link active" aria-current="page" href="/netdata">netdata</a> + </li> + </ul> + </div> + </div> + </nav> + + <div class="container"> + <main> + <!-- Begin content --> + + <main role="main" class="container"> + + <div class="content"> + +<a name="top"></a> +<h1><i class="fa-fw far fa-tools"></i> Tools <small>(<a href="/tools/api">API</a>)</small></h1> +<div style="height: 2em"></div> + +<script src="/_static/jquery/jquery.min.js"></script> + +<script> + $(document).ready(function(){ + $("[type=button]").click(function() { + var command = $(this).data("command"); + var protocol = $("input[name='protocol']:checked").val(); + var target = document.getElementById("target").value; + var cgi = command + "&protocol=" + protocol + "&target=" + target; + $.ajax({url: cgi, success: function(result){ + $("#output").text(result); + document.getElementById('output-hidden').style.display = 'block'; + $(document).scrollTop( $("#output").offset().top -125); + }}); + }); + + $("[type=reset]").click(function() { + $("#dual-stack").click(); + $('.btn-group').find('reset').removeClass('active') + .end().find('[type="reset"]').prop('checked', false); + document.getElementById('output-hidden').style.display = 'none'; + $("#target").focus(); + $("#target").prop('autofocus'); + }); + }); +</script> + +<style type="text/css"> + label, [type="button"], [type="reset"], [type="text"] { + margin-top: 0.5em; + } +</style> + +<form id="form"> + <div class="form-group"> + <div class="row"> + <div class="col-md-6"> + <b>Target</b> + <input id="target" placeholder="IP address/subnet, FQDN, ASN, Internet resources..." style="width: 100%;" type="text" autofocus /> + + <div style="height: 1em"></div> + </div> + + <div class="col-md-6"> + <b>Settings</b><br /> + <input class="btn btn-light btn-sm" type="reset" value="Reset" /> + + <div class="btn-group btn-group-toggle" data-toggle="buttons"> + <label class="btn btn-light btn-sm active"> + <input type="radio" name="protocol" id="dual-stack" value="dual-stack" checked> Dual-stack + </label> + <label class="btn btn-light btn-sm"> + <input type="radio" name="protocol" id="ipv4-only" value="ipv4-only"> IPv4-only + </label> + <label class="btn btn-light btn-sm"> + <input type="radio" name="protocol" id="ipv6-only" value="ipv6-only"> IPv6-only + </label> + </div> + + <div style="height: 1em"></div> + </div> + </div> + </div> +</form> + +<hr /> + +<div class="row"> + <div class="col-md-6"> + <b>Network</b><br /> + <button type="button" class="btn btn-success" data-command="/tools.py?command=ping">ping</button> + <button type="button" class="btn btn-success" data-command="/tools.py?command=traceroute">traceroute</button> + <button type="button" class="btn btn-success" data-command="/tools.py?command=tcptraceroute">tcptraceroute</button> + <button type="button" class="btn btn-success" data-command="/tools.py?command=whois">whois</button> + + <div style="height: 1em"></div> + + <b>Security</b><br /> + <button type="button" class="btn btn-warning" data-command="/tools.py?command=nmap">nmap</button> + <button type="button" class="btn btn-warning" data-command="/tools.py?command=ssh-audit">ssh-audit</button> + <button type="button" class="btn btn-warning" data-command="/tools.py?command=testssl">testssl</button> + + <div style="height: 1em"></div> + + <b>other</b><br /> + <button type="button" class="btn btn-info" data-command="/tools.py?command=my-ip&target=none">My IP</button> + <button type="button" class="btn btn-info" data-command="/tools.py?command=my-browser&target=none">My browser</button> + + <div style="height: 1em"></div> + </div> + + <div class="col-md-6"> + <b>DNS</b><br /> + <small><b>Address-related records</b></small><br /> + <button type="button" class="btn btn-primary" data-command="/tools.py?command=kdig&query=ANY">ANY</button> + <button type="button" class="btn btn-primary" data-command="/tools.py?command=kdig&query=A">A</button> + <button type="button" class="btn btn-primary" data-command="/tools.py?command=kdig&query=AAAA">AAAA</button> + <button type="button" class="btn btn-primary" data-command="/tools.py?command=kdig&query=CNAME">CNAME</button> + <button type="button" class="btn btn-primary" data-command="/tools.py?command=kdig&query=DNAME">DNAME</button> + <button type="button" class="btn btn-primary" data-command="/tools.py?command=kdig&query=PTR">PTR</button> + + <div style="height: 1em"></div> + + <small><b>Informational records</b></small><br /> + <button type="button" class="btn btn-info" data-command="/tools.py?command=kdig&query=APL">APL</button> + <button type="button" class="btn btn-info" data-command="/tools.py?command=kdig&query=HINFO">HINFO</button> + <button type="button" class="btn btn-info" data-command="/tools.py?command=kdig&query=LOC">LOC</button> + <button type="button" class="btn btn-info" data-command="/tools.py?command=kdig&query=RP">RP</button> + <button type="button" class="btn btn-info" data-command="/tools.py?command=kdig&query=SOA">SOA</button> + <button type="button" class="btn btn-info" data-command="/tools.py?command=kdig&query=SRV">SRV</button> + <button type="button" class="btn btn-info" data-command="/tools.py?command=kdig&query=TXT">TXT</button> + + <div style="height: 1em"></div> + + <small><b>DNSSEC records</b></small><br /> + <button type="button" class="btn btn-secondary" data-command="/tools.py?command=kdig&query=CDNSKEY">CDNSKEY</button> + <button type="button" class="btn btn-secondary" data-command="/tools.py?command=kdig&query=CDS">CDS</button> + <button type="button" class="btn btn-secondary" data-command="/tools.py?command=kdig&query=DNSKEY">DNSKEY</button> + <button type="button" class="btn btn-secondary" data-command="/tools.py?command=kdig&query=DS">DS</button> + <button type="button" class="btn btn-secondary" data-command="/tools.py?command=kdig&query=RRSIG">RRSIG</button> + + <div style="height: 1em"></div> + + <small><b>Security-related records</b></small><br /> + <button type="button" class="btn btn-warning" data-command="/tools.py?command=kdig&query=CAA">CAA</button> + <button type="button" class="btn btn-warning" data-command="/tools.py?command=kdig&query=NSEC3">NSEC3</button> + <button type="button" class="btn btn-warning" data-command="/tools.py?command=kdig&query=NSEC3PARAM">NSEC3PARAM</button> + <button type="button" class="btn btn-warning" data-command="/tools.py?command=kdig&query=SSHFP">SSHFP</button> + <button type="button" class="btn btn-warning" data-command="/tools.py?command=kdig&query=TLSA">TLSA</button> + + <div style="height: 1em"></div> + + <small><b>other records and types</b></small><br /> + <button type="button" class="btn btn-success" data-command="/tools.py?command=kdig&query=AXFR">AXFR*</button> + <button type="button" class="btn btn-success" data-command="/tools.py?command=kdig&query=MX">MX</button> + <button type="button" class="btn btn-success" data-command="/tools.py?command=kdig&query=NS">NS</button> + + <div style="height: 1em"></div> + + <small><b>Legacy records</b></small><br /> + <button type="button" class="btn btn-danger" data-command="/tools.py?command=kdig&query=NSEC">NSEC</button> + <button type="button" class="btn btn-danger" data-command="/tools.py?command=kdig&query=SPF">SPF</button> + + <div style="height: 1em"></div> + </div> +</div> + +<div class="row"> + <div class="col-md-6"> + <small><b>Notes:</b> + <ul> + <li>testssl can take up to 5min (with currently no output until the end)</li> + </ul></small> + + <div style="height: 1em"></div> + </div> + + <div class="col-md-6"> + <small><b>*</b> only available for BFH authoritative zones</small> + + <div style="height: 1em"></div> + </div> +</div> + +<hr /> + +<div id="output-hidden" style="display: none;"> +<a name="output"></a> +<a href="#top"><button type="button" class="btn btn-light btn-sm float-right">↑</button></a><br /> +<b>Output</b><br /> +<pre> +<textarea id="output" readonly rows="25" style="background: #f1f1f1; width: 100%;"></textarea> +</pre> +</div> + +<div style="height: 1em"></div> + + + </div> + + </main><!-- /.container --> + + + + + <!-- End content --> + </main> + + <div style="height: 4em"></div> + + <footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top"> + <p class="col-md-4 mb-0 text-muted">© 2022</p> + + <ul class="nav col-md-4 justify-content-end"> + <li class="nav-item"><a href="https://open-infrastructure.net/contact" class="nav-link px-2 text-muted">Contact</a></li> + <li class="nav-item"><a href="https://open-infrastructure.net/legal" class="nav-link px-2 text-muted">Legal</a></li> + </ul> + </footer> + </div> + + <!-- Bootstrap core JS --> + <script src="/_static/popperjs/popper.min.js"></script> + <script src="/_static/bootstrap/js/bootstrap.min.js"></script> + + <!-- Custom scripts for this template --> + </body> +</html> diff --git a/web/TMP/tools.py b/web/TMP/tools.py new file mode 100755 index 0000000..c8dab03 --- /dev/null +++ b/web/TMP/tools.py @@ -0,0 +1,269 @@ +#!/usr/bin/python3 + +# Copyright (C) 2013-2021 Daniel Baumann <daniel@debian.org> +# +# SPDX-License-Identifier: GPL-3.0+ +# +# 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, either version 3 of the License, or +# (at your option) any later version. +# +# 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 <http://www.gnu.org/licenses/>. + +# Dependencies: +# sudo apt install iputils-ping traceroute whois nmap ssh-audit testssl.sh geoip-bin geoip-database knot-dnsutils +# sudo apt install python3-pygments + +from cgi import FieldStorage +from datetime import datetime +import ipaddress +from os import getenv +from subprocess import Popen, PIPE +from sys import exit + +def filter_nameservers(servers, protocol): + nameservers= [] + + for server in servers: + name = server.rstrip().rstrip('.') + + if protocol == 'ipv6-only': + command = 'kdig -6' + options = ' -t AAAA +short -q ' + elif protocol == 'ipv4-only': + command = 'kdig -4' + options = ' -t A +short -q ' + else: + command = 'kdig' + options = ' +short -q ' + + command_line = (command + options + name).split() + kdig = Popen(command_line, stdout=PIPE) + address = kdig.stdout.readline() + + if address: + nameservers.append(name) + + return nameservers + +def get_nameserver(name, protocol): + nameservers = [] + + if protocol == 'ipv6-only': + command = 'kdig -6' + elif protocol == 'ipv4-only': + command = 'kdig -4' + else: + command = 'kdig' + + options = ' -t NS +short -q ' + + command_line = (command + options + name).split() + kdig = Popen(command_line, stdout=PIPE) + servers = kdig.stdout.readlines() + + count = 0 + while not servers and count < 10: + name = name.split('.') + del name[0] + name = '.'.join(name) + + command_line = (command + options + name).split() + kdig = Popen(command_line, stdout=PIPE) + servers = kdig.stdout.readlines() + + count += 1 + + names = [] + for server in servers: + name = server.rstrip().decode('utf-8').rstrip('.') + names.append(name) + + nameservers = filter_nameservers(names, protocol) + return nameservers + +def run_command(command): + process = Popen(command, stdout=PIPE) + empty_lines = 0 + while True: + line = process.stdout.readline().rstrip() + if not line: + empty_lines = empty_lines + 1 + if empty_lines > 2: + break + else: + print() + else: + empty_lines = 0 + yield line.decode('utf-8') + +def main(): + form = FieldStorage() + + if form.getvalue("command"): + Command = form.getvalue("command").split()[0] + + if "target" in form: + Target = form.getvalue("target").split()[0] + + if "protocol" in form: + Protocol = form.getvalue("protocol").split()[0] + + if "query" in form: + Query = form.getvalue("query").split()[0] + + if Command and Protocol and Target: + print('Content-Type: text/html\n') + + Date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + if Command == 'kdig': + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + + if Query == 'PTR': + arpa = ipaddress.ip_address(Target).reverse_pointer + + nameserver = get_nameserver(arpa, Protocol) + + protocol_passed = False + + for server in nameserver: + check_options = options + ' @' + server + ' -t ' + Query + ' -q ' + + command_line = (Command + ' +short' + check_options + arpa).split() + kdig = Popen(command_line, stdout=PIPE) + protocol_check = kdig.stdout.readline() + + if protocol_check: + protocol_passed = True + break + + if not protocol_passed: + print('IPv6-only query but no IPv6 enabled nameserver available for ' + Target + '\n\n') + print('--') + print('Run: ' + str(command_line)) + print('Date: ' + Date) + + exit(0) + + options = options + ' @' + server + ' -x ' + else: + nameserver = get_nameserver(Target, Protocol) + + protocol_passed = False + + for server in nameserver: + check_options = options + ' @' + server + ' -t ' + Query + ' -q ' + + command_line = (Command + ' +short' + check_options + Target).split() + kdig = Popen(command_line, stdout=PIPE) + protocol_check = kdig.stdout.readline() + + if protocol_check: + protocol_passed = True + break + + if not protocol_passed: + print('IPv6-only query but no IPv6 enabled nameserver available for ' + Target + '\n\n') + print('--') + print('Run: ' + str(command_line)) + print('Date: ' + Date) + + exit(0) + + options = options + ' @' + server + ' -t ' + Query + ' -q ' + elif Command == 'ping': + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + options = options + ' -c3 ' + elif Command == 'traceroute': + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + options = options + ' ' + elif Command == 'tcptraceroute': + Command = 'traceroute' + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + options = options + ' -T ' + elif Command == 'nmap': + if Protocol == 'ipv6-only': + options = ' -6' + else: + options = ' ' + #-O -T5 + elif Command == 'ssh-audit': + if Protocol == 'ipv6-only': + options = ' -6' + elif Protocol == 'ipv4-only': + options = ' -4' + else: + options = '' + options = options + ' --no-colors ' + elif Command == 'testssl': + options = ' --color 0 ' + elif Command == 'whois': + options = ' -H ' + else: + options = ' ' + + if Command == 'my-ip': + command_line = '' + + ip_address = getenv('REMOTE_ADDR') + print('IP address: ' + ip_address) + + # TODO: show reverse DNS + + if ':' in ip_address: + print('IP version: IPv6') + process = Popen(['geoiplookup6', ip_address], stdout=PIPE) + else: + print('IP version: IPv4') + process = Popen(['geoiplookup', ip_address], stdout=PIPE) + + geoiplookup = process.stdout.readline().rstrip() + country = geoiplookup.decode('utf-8').split(':')[1] + print('Country:' + country + '\n\n') + elif Command == 'my-browser': + command_line = '' + print('User-Agent: ' + getenv('HTTP_USER_AGENT', 'n/a') + '\n\n') + else: + command_line = Command + options + Target + + for path in run_command(command_line.split()): + print(path) + + print('--') + print('Date: ' + Date) + + if command_line: + print('Run: ' + command_line) + + exit(0) + +if __name__ == '__main__': + main() diff --git a/web/TMP/tools/api/index.html b/web/TMP/tools/api/index.html new file mode 100644 index 0000000..a5f22f2 --- /dev/null +++ b/web/TMP/tools/api/index.html @@ -0,0 +1,11 @@ +<html> + <h1>tools.bfh.info</h1> + + <h2>API</h2> + + <ul> + <li><a href="/tools/api/v0/ip/address">/tools/api/v0/ip/address</a></li> + <li><a href="/tools/api/v0/ipv4/address">/tools/api/v0/ipv4/address</a></li> + <li><a href="/tools/api/v0/ipv6/address">/tools/api/v0/ipv6/address</a></li> + </ul> +</html> diff --git a/web/TMP/tools/api/v0/dns/a/index.py b/web/TMP/tools/api/v0/dns/a/index.py new file mode 100755 index 0000000..88b1b03 --- /dev/null +++ b/web/TMP/tools/api/v0/dns/a/index.py @@ -0,0 +1,93 @@ +#!/usr/bin/python3 + +# Copyright (C) 2013-2021 Daniel Baumann <daniel@debian.org> +# +# SPDX-License-Identifier: GPL-3.0+ +# +# 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, either version 3 of the License, or +# (at your option) any later version. +# +# 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 <https://www.gnu.org/licenses/>. + +from ipaddress import ip_address +from json import dumps +from os import getenv +from subprocess import Popen, PIPE +from sys import exit + +from pygments import highlight +from pygments.lexers import JsonLexer +from pygments.formatters import TerminalFormatter + +def run_command(command): + process = Popen(command, stdout=PIPE) + empty_lines = 0 + while True: + line = process.stdout.readline().rstrip() + if not line: + empty_lines = empty_lines + 1 + if empty_lines > 2: + break + else: + print() + else: + empty_lines = 0 + yield line.decode('utf-8') + +def v0_dns_a(): + a = 'google.com' + cgi = getenv('GATEWAY_INTERFACE') + + #command_line = 'kdig +json A ' + a + ' | jq -r -M \'.answer | .[] | .rdata\'' + command_line = 'kdig +json A ' + a + + kdig = Popen(command_line.split(), stdout=PIPE) + +# try: +# ip = str(ip_address(address)) +# if ip_address(address).version == 4: +# ip_version = 'ipv4' +# elif ip_address(address).version == 6: +# ip_version = 'ipv6' +# else: +# ip_version = None +# message = 'valid IP address' +# status = True +# except ValueError: +# ip = None +# ip_version = None +# message = 'invalid IP address' +# status = False + + status = True + message = 'valid DNS record' + + json = \ + { + 'data': { + 'record': a, + }, + 'meta': { + 'status': status, + 'message': message, + }, + } + + if cgi: + print('Content-Type: application/json\n') + print(dumps(json)) + else: + print(highlight(dumps(json, indent=4), JsonLexer(), TerminalFormatter())) + + exit(0) + +if __name__ == '__main__': + v0_dns_a() diff --git a/web/TMP/tools/api/v0/ip/address/index.py b/web/TMP/tools/api/v0/ip/address/index.py new file mode 100755 index 0000000..49e4971 --- /dev/null +++ b/web/TMP/tools/api/v0/ip/address/index.py @@ -0,0 +1,70 @@ +#!/usr/bin/python3 + +# Copyright (C) 2013-2021 Daniel Baumann <daniel@debian.org> +# +# SPDX-License-Identifier: GPL-3.0+ +# +# 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, either version 3 of the License, or +# (at your option) any later version. +# +# 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 <https://www.gnu.org/licenses/>. + +from ipaddress import ip_address +from json import dumps +from os import getenv +from sys import exit + +from pygments import highlight +from pygments.lexers import JsonLexer +from pygments.formatters import TerminalFormatter + +def v0_ip_address(): + address = getenv('REMOTE_ADDR') + cgi = getenv('GATEWAY_INTERFACE') + + try: + ip = str(ip_address(address)) + if ip_address(address).version == 4: + ip_version = 'ipv4' + elif ip_address(address).version == 6: + ip_version = 'ipv6' + else: + ip_version = None + message = 'valid IP address' + status = True + except ValueError: + ip = None + ip_version = None + message = 'invalid IP address' + status = False + + json = \ + { + 'data': { + 'ip_address': ip, + 'ip_version': ip_version, + }, + 'meta': { + 'status': status, + 'message': message, + }, + } + + if cgi: + print('Content-Type: application/json\n') + print(dumps(json)) + else: + print(highlight(dumps(json, indent=4), JsonLexer(), TerminalFormatter())) + + exit(0) + +if __name__ == '__main__': + v0_ip_address() diff --git a/web/TMP/tools/api/v0/ipv4/address/index.py b/web/TMP/tools/api/v0/ipv4/address/index.py new file mode 100755 index 0000000..7a08c34 --- /dev/null +++ b/web/TMP/tools/api/v0/ipv4/address/index.py @@ -0,0 +1,62 @@ +#!/usr/bin/python3 + +# Copyright (C) 2013-2021 Daniel Baumann <daniel@debian.org> +# +# SPDX-License-Identifier: GPL-3.0+ +# +# 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, either version 3 of the License, or +# (at your option) any later version. +# +# 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 <https://www.gnu.org/licenses/>. + +from ipaddress import IPv4Address +from json import dumps +from os import getenv +from sys import exit + +from pygments import highlight +from pygments.lexers import JsonLexer +from pygments.formatters import TerminalFormatter + +def v0_ipv4_address(): + address = getenv('REMOTE_ADDR') + cgi = getenv('GATEWAY_INTERFACE') + + try: + ip = str(IPv4Address(address)) + message = 'valid IPv4 address' + status = True + except ValueError: + ip = None + message = 'invalid IPv4 address' + status = False + + json = \ + { + 'data': { + 'ipv4_address': ip, + }, + 'meta': { + 'status': status, + 'message': message, + }, + } + + if cgi: + print('Content-Type: application/json\n') + print(dumps(json)) + else: + print(highlight(dumps(json, indent=4), JsonLexer(), TerminalFormatter())) + + exit(0) + +if __name__ == '__main__': + v0_ipv4_address() diff --git a/web/TMP/tools/api/v0/ipv6/address/index.py b/web/TMP/tools/api/v0/ipv6/address/index.py new file mode 100755 index 0000000..0746a83 --- /dev/null +++ b/web/TMP/tools/api/v0/ipv6/address/index.py @@ -0,0 +1,62 @@ +#!/usr/bin/python3 + +# Copyright (C) 2013-2021 Daniel Baumann <daniel@debian.org> +# +# SPDX-License-Identifier: GPL-3.0+ +# +# 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, either version 3 of the License, or +# (at your option) any later version. +# +# 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 <https://www.gnu.org/licenses/>. + +from ipaddress import IPv6Address +from json import dumps +from os import getenv +from sys import exit + +from pygments import highlight +from pygments.lexers import JsonLexer +from pygments.formatters import TerminalFormatter + +def v0_ipv6_address(): + address = getenv('REMOTE_ADDR') + cgi = getenv('GATEWAY_INTERFACE') + + try: + ip = str(IPv6Address(address)) + message = 'valid IPv6 address' + status = True + except ValueError: + ip = None + message = 'invalid IPv6 address' + status = False + + json = \ + { + 'data': { + 'ipv6_address': ip, + }, + 'meta': { + 'status': status, + 'message': message, + }, + } + + if cgi: + print('Content-Type: application/json\n') + print(dumps(json)) + else: + print(highlight(dumps(json, indent=4), JsonLexer(), TerminalFormatter())) + + exit(0) + +if __name__ == '__main__': + v0_ipv6_address() |