From e362086ffe1b9f20a34bedea96fab8e573119c5f Mon Sep 17 00:00:00 2001 From: SiloDS Date: Fri, 30 Jul 2021 12:38:38 +0100 Subject: [PATCH] New Version --- app/__init__.py | 2 +- app/network_utils.py | 157 +++++++++++++++++++++++++++++++++++++++ app/routes2.py | 71 ++++++++++++++++++ app/templates/index.html | 20 ++--- 4 files changed, 240 insertions(+), 10 deletions(-) create mode 100644 app/network_utils.py create mode 100644 app/routes2.py diff --git a/app/__init__.py b/app/__init__.py index e8b0dcf..39161d3 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -11,4 +11,4 @@ migrate = Migrate(app, db) login = LoginManager(app) login.login_view = "login" -from app import routes, models +from app import routes2, models diff --git a/app/network_utils.py b/app/network_utils.py new file mode 100644 index 0000000..79195e8 --- /dev/null +++ b/app/network_utils.py @@ -0,0 +1,157 @@ +import re +import subprocess + +from config import ClientInterface + +wpafile_wpa = """country=GB # Your 2-digit country code +ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev + +network={{ + ssid="{}" + psk="{}" + key_mgmt=WPA-PSK +}} +""" + +wpafile_nowpa = """country=GB # Your 2-digit country code +ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev + +network={{ +ssid="{}" +key_mgmt=NONE +}} +""" + +wpafile_none = """country=GB # Your 2-digit country code +ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev +""" + + +def run_subprocess(cmd, check=True): + cmd_split = cmd.split(" ") + return subprocess.run(cmd_split, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=check).stdout.decode("utf-8") + + +def run_subprocess_interface(cmd, check=True): + return run_subprocess(cmd.format(ClientInterface), check) + + +def parse_iwlist(iwlist_output, current_sid): + """Parses iwlist scan output + + Args: + iwlist_output (string): iwlist scan output + current (string): Current Connected Sidd + + Returns: + [dictionary]: Dictionary containing relavent data + """ + data = [] + cell = [] + for line in iwlist_output.splitlines(): + if line.find(" Cell ") != -1 and cell != []: + data.append(cell) + cell = [] + elif line.find("Scan completed :") > 0: + pass + else: + cell.append(line) + + try: + del data[0][0] + except: + pass + + cells = [] + + try: + for item in data: + cell = {} + for line in item: + line = line.strip() + if line.find("ESSID:") != -1: + if line.partition("ESSID:")[2].strip('"') != "": + cell["SSID"] = line.partition("ESSID:")[2].strip('"') + if cell["SSID"] == current_sid: + cell["Connected"] = "Yes" + else: + cell["Connected"] = "" + if line.partition("Signal level=")[2].split("/")[0] != "" != -1: + cell["Signal"] = line.partition("Signal level=")[2].split("/")[0] + if line.find("Encryption key:") != -1: + if line.find(":on") != -1: + cell["WPA"] = "WPA2" + else: + cell["WPA"] = "None" + + cells.append(cell) + except: + cells = [] + + return cells + + +def scan_networks(): + """Scans for Networks""" + output = run_subprocess("sudo iwgetid", check=False) + + current = output.partition("ESSID:")[2].strip().strip('"') + + output = run_subprocess("sudo iwlist {} scan".format(ClientInterface)) + + scan = parse_iwlist(output, current) + + return scan + + +def connect_network(ssid, security, password): + with open("/etc/network/interfaces", "r") as source: + lines = source.readlines() + with open("/etc/network/interfaces", "w") as source: + for line in lines: + source.write( + re.sub(r"^iface {} inet manual".format(ClientInterface), "iface {} inet dhcp".format(ClientInterface), line) + ) + + run_subprocess_interface("sudo /usr/sbin/ifdown {}") + + run_subprocess("sudo /usr/bin/systemctl stop wpa_supplicant") + + with open("/etc/wpa_supplicant/wpa_supplicant.conf", "wt") as f: + if security == "WPA2": + f.write(wpafile_wpa.format(ssid, password)) + else: + f.write(wpafile_nowpa) + + try: + run_subprocess("sudo /usr/bin/systemctl start wpa_supplicant") + run_subprocess_interface("sudo /usr/sbin/ifup {}") + except: + return False + + return True + + +def disconnect_network(ssid): + run_subprocess_interface("sudo /usr/sbin/ifdown {}") + + with open("/etc/wpa_supplicant/wpa_supplicant.conf", "wt") as f: + f.write(wpafile_none) + + run_subprocess("sudo /usr/bin/systemctl stop wpa_supplicant") + + with open("/etc/network/interfaces", "r") as sources: + lines = sources.readlines() + with open("/etc/network/interfaces", "w") as sources: + for line in lines: + sources.write( + re.sub(r"^iface {} inet dhcp".format(ClientInterface), "iface {} inet manual".format(ClientInterface), line) + ) + + try: + run_subprocess("sudo /usr/bin/systemctl start wpa_supplicant") + run_subprocess_interface("sudo /usr/sbin/ifup {}") + except: + return False + + return True diff --git a/app/routes2.py b/app/routes2.py new file mode 100644 index 0000000..580adb7 --- /dev/null +++ b/app/routes2.py @@ -0,0 +1,71 @@ +from flask import flash, redirect, render_template, url_for +from flask_login import current_user, login_required, login_user, logout_user + +from app import app +from app.forms import LoginForm, WPAForm +from app.models import Passwords, User +from app.network_utils import scan_networks, connect_network, disconnect_network + + +@app.route("/") +@app.route("/index") +@login_required +def index(): + return render_template("index.html", networks=scan_networks()) + + +@app.route("/login", methods=["GET", "POST"]) +def login(): + if current_user.is_authenticated: + return redirect(url_for("index")) + form = LoginForm() + if form.validate_on_submit(): + user = User.query.filter_by(username=form.username.data).first() + if user is None or not user.check_password(form.password.data): + flash("Invalid username or password") + return redirect(url_for("login")) + login_user(user) + return redirect(url_for("index")) + return render_template("login.html", title="Sign In", form=form) + + +@app.route("/logout") +def logout(): + logout_user() + return redirect(url_for("index")) + + +@app.route("/connect/&", methods=["GET", "POST"]) +@login_required +def connect(ssid, security): + if security == "WPA2": + return redirect(url_for("connectwpa", ssid=ssid)) + + result = connect_network(ssid, security, "") + if result: + return render_template("message.html", message="Successfully connected to {}".format(ssid)) + + return render_template("message.html", message="Failt to connected to {}".format(ssid)) + + +@app.route("/wpa/", methods=["GET", "POST"]) +@login_required +def connectwpa(ssid): + form = WPAForm() + if form.validate_on_submit(): + result = connect_network(ssid, "WPA2", form.password.data) + if result: + return render_template("message.html", message="Successfully connected to {}".format(ssid)) + + return render_template("message.html", message="Failt to connected to {}".format(ssid)) + + return render_template("wpa.html", title="WPA Password", form=form) + + +@app.route("/disconnect/", methods=["GET", "POST"]) +@login_required +def disconnect(ssid): + if disconnect_network(ssid): + return render_template("message.html", message="Sucessfully disconnected from {}".format(ssid)) + + return render_template("message.html", message="Failt to disconnect from {}".format(ssid)) diff --git a/app/templates/index.html b/app/templates/index.html index cce7d44..483ff4e 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -11,18 +11,20 @@ Security Action - {%- for row in index_table %} + {%- for row in networks %} - {{row[0]}} - {{row[1]}} - {{row[2]}} - {{row[3]}} - {% if row[2] == "Yes" %} - {{ "User is logged in" if loggedin else "User is not logged in" }} - Disconnect + {{ row['SSID'] }} + {{ row['Signal'] }} + {{ row['Connected'] }} + {{ row['WPA'] }} + + {% if row["Connected"] == "Yes" %} + + Disconnect {% else %} - Connect + Connect {% endif %} + {%- endfor %}