KasperskyLab-TinyCheck/server/backend/app/classes/config.py

170 lines
6.1 KiB
Python
Raw Permalink Normal View History

2020-11-24 19:45:03 +01:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import yaml
import sys
import io
import os
import re
import hashlib
from functools import reduce
from flask import send_file
class Config(object):
def __init__(self):
self.dir = "/".join(sys.path[0].split("/")[:-2])
return None
def read_config(self, path):
"""
Read a single value from the configuration
:return: value (it can be any type)
"""
config = yaml.load(
open(os.path.join(self.dir, "config.yaml"), "r"), Loader=yaml.SafeLoader)
return reduce(dict.get, path, config)
def export_config(self):
"""
Export the configuration
:return: dict (configuration content)
"""
config = yaml.load(
open(os.path.join(self.dir, "config.yaml"), "r"), Loader=yaml.SafeLoader)
2021-01-22 14:09:03 +01:00
config["ifaces_in"] = self.get_ifaces_in()
config["ifaces_out"] = self.get_ifaces_out()
2020-11-24 19:45:03 +01:00
return config
def write_config(self, cat, key, value):
"""
Write a new value in the configuration
:return: bool, operation status
"""
2020-11-24 19:45:03 +01:00
config = yaml.load(
open(os.path.join(self.dir, "config.yaml"), "r"), Loader=yaml.SafeLoader)
# Some checks prior configuration changes.
if cat not in config:
return {"status": False,
"message": "Wrong category specified"}
if key not in config[cat]:
return {"status": False,
"message": "Wrong key specified"}
# Changes for network interfaces.
if cat == "network" and key in ["in", "out"]:
2021-01-22 14:09:03 +01:00
if re.match("^(wlan[0-9]|wl[a-z0-9]{20})$", value):
if key == "in":
self.edit_configuration_files(value)
2021-01-22 14:09:03 +01:00
config[cat][key] = value
if key == "out":
config[cat][key] = value
elif re.match("^(eth[0-9]|en[a-z0-9]{20})$", value) and key == "out":
config[cat][key] = value
else:
return {"status": False,
"message": "Wrong value specified"}
# Changes for network SSIDs.
elif cat == "network" and key == "ssids":
ssids = list(set(value.split("|"))) if "|" in value else [value]
if len(ssids):
config[cat][key] = ssids
# Changes for watchers.
elif cat == "watchers" and key in ["iocs", "whitelists"]:
urls = []
values = list(set(value.split("|"))) if "|" in value else [value]
for value in values: # Preventing SSRF based on watchers URLs.
if "https://raw.githubusercontent.com" in value[0:33]:
urls.append(value)
if len(urls):
config[cat][key] = urls
# Changes for backend password.
elif cat == "backend" and key == "password":
config[cat][key] = self.make_password(value)
# Changes for anything not specified.
# Warning: can break your config if you play with it (eg. arrays, ints & bools).
else:
2021-01-04 11:18:29 +01:00
if isinstance(value, bool):
config[cat][key] = value
elif len(value):
config[cat][key] = value
2020-11-24 19:45:03 +01:00
with open(os.path.join(self.dir, "config.yaml"), "w") as yaml_file:
yaml_file.write(yaml.dump(config, default_flow_style=False))
return {"status": True,
"message": "Configuration updated"}
2020-11-24 19:45:03 +01:00
def make_password(self, clear_text):
"""
Make a simple password hash (without salt)
"""
return hashlib.sha256(clear_text.encode()).hexdigest()
def export_db(self):
"""
Export the database.
:return: send_file (the database)
"""
with open(os.path.join(self.dir, "tinycheck.sqlite3"), "rb") as f:
return send_file(
io.BytesIO(f.read()),
mimetype="application/octet-stream",
as_attachment=True,
attachment_filename='tinycheck-export-db.sqlite')
2021-01-22 14:09:03 +01:00
def get_ifaces_in(self):
2020-11-24 19:45:03 +01:00
"""
2021-01-22 14:09:03 +01:00
List the Wireless interfaces on the box
which can be used as Access Points.
2020-11-24 19:45:03 +01:00
:return: list of the interfaces
"""
try:
2021-01-22 14:09:03 +01:00
return [i for i in os.listdir("/sys/class/net/") if i.startswith("wl")]
2020-11-24 19:45:03 +01:00
except:
2021-01-22 14:09:03 +01:00
return ["No wireless interface"]
def get_ifaces_out(self):
"""
List the network interfaces on the box
which can be used to access to Internet.
:return: list of the interfaces
"""
try:
return [i for i in os.listdir("/sys/class/net/") if i.startswith(("wl", "et"))]
except:
return ["No network interfaces"]
2020-11-24 19:45:03 +01:00
def edit_configuration_files(self, iface):
"""
Edit the DNSMasq and DHCPCD configuration files
:return: nothing.
"""
try:
if re.match("^(wlan[0-9]|wlx[a-f0-9]{12})$", iface):
2020-11-24 19:45:03 +01:00
# Edit of DHCPD.conf
with open("/etc/dhcpcd.conf", 'r') as file:
content = file.readlines()
for i, line in enumerate(content):
if line.startswith("interface"):
content[i] = "interface {}\n".format(iface)
with open("/etc/dhcpcd.conf", 'w') as file:
file.writelines(content)
2020-11-24 19:45:03 +01:00
# Edit of DNSMASQ.conf
with open("/etc/dnsmasq.conf", 'r') as file:
content = file.readlines()
for i, line in enumerate(content):
if line.startswith("interface"):
content[i] = "interface={}\n".format(iface)
with open("/etc/dnsmasq.conf", 'w') as file:
file.writelines(content)
except:
pass