fix wifi settings

This commit is contained in:
Tobias Hopp 2024-03-29 03:45:47 +01:00
parent 8eb2d69e13
commit 9831046592
5 changed files with 128 additions and 121 deletions

8
scripts/addWifi.sh Normal file → Executable file
View File

@ -31,15 +31,21 @@ update_config=1
fi fi
# Validate arguments # Validate arguments
if [ -z "$ssid" ] || [ -z "$psk" ]; then if [ -z "$ssid" ]; then
echo "invalid-args" echo "invalid-args"
exit 1 exit 1
fi fi
key="WPA-PSK"
if [ -z "$psk" ]; then
key="NONE"
fi
echo " echo "
network={ network={
ssid=\"$ssid\" ssid=\"$ssid\"
psk=\"$psk\" psk=\"$psk\"
key_mgmt=\"$key\"
} }
" | sudo tee -a "$file" >/dev/null " | sudo tee -a "$file" >/dev/null

83
scripts/connectToWifi.sh Normal file → Executable file
View File

@ -3,92 +3,17 @@
iface=$(iw dev | awk '$1=="Interface"{print $2}' | grep '^wlan') iface=$(iw dev | awk '$1=="Interface"{print $2}' | grep '^wlan')
file="/etc/wpa_supplicant/wpa_supplicant-monopoly.conf" file="/etc/wpa_supplicant/wpa_supplicant-monopoly.conf"
ssid="no_args_given" sleep 5
echo "!!ok"
# Parse arguments
while getopts ":s:p:" opt; do
case ${opt} in
s )
ssid="$OPTARG"
;;
: )
echo "Invalid option: $OPTARG" 1>&2
exit 1
;;
esac
done
shift $((OPTIND -1))
# Remove all disabled
sudo sed -i '/disabled=1/d' "$file"
# Temporary file to store modified content
temp_file=$(mktemp)
# Use awk to add disabled=1 within each network block
awk '
BEGIN { RS="\n\n"; FS="\n"; OFS="\n" }
{
found=0
for(i=1; i<=NF; i++) {
if ($i ~ /^network=/) {
for(j=i+1; j<=NF && $j !~ /^}/; j++) {
if ($j ~ /^disabled=1/) {
found=1
break
}
}
if (!found) {
$i = $i "\n disabled=1"
}
}
}
print $0 "\n"
}' "$file" > "$temp_file"
# Overwrite the original file with the modified content
sudo mv -f "$temp_file" "$file"
temp_file=$(mktemp)
while IFS= read -r line
do
if [[ "$line" == *"$ssid"* ]]; then
echo $line $ssid
remove_line=1
echo "remove_line=1"
fi
if [[ "$remove_line" -eq 1 && "$line" == *"disabled=1"* ]]; then
echo "skipped disabled line"
continue
fi
if [[ "$line" == *"}"* ]]; then
in_block=0
remove_line=0
fi
echo "$line" >> "$temp_file"
done < "$file"
# Overwrite the original file with the modified content
sudo mv -f "$temp_file" "$file"
cat $file
exit 0 exit 0
sudo ip addr flush dev $iface sudo ip addr flush dev $iface
sudo killall wpa_supplicant sudo killall wpa_supplicant
sudo truncate -s 0 /tmp/wifi_connection_status.txt sudo truncate -s 0 /tmp/wifi_connection_status.txt
sudo wpa_supplicant -B -i $iface -f /tmp/wifi_connection_status.txt -c $file sudo wpa_supplicant -B -i $iface -f /tmp/wifi_connection_status.txt -c $file
declare -i i=0 declare -i i=0
declare -i timeout=5 declare -i timeout=8
while [ $i -le $timeout ]; do while [ $i -le $timeout ]; do
if grep -iq 'CTRL-EVENT-CONNECTED' /tmp/wifi_connection_status.txt; then if grep -iq 'CTRL-EVENT-CONNECTED' /tmp/wifi_connection_status.txt; then
sudo dhclient wlan0 sudo dhclient wlan0
@ -100,5 +25,5 @@ while [ $i -le $timeout ]; do
(( i++ )) (( i++ ))
sleep 1 sleep 1
done done
echo "!!ok"
exit 0 exit 0

View File

@ -3,11 +3,18 @@ import {spawn, exec} from 'node:child_process';
import * as dns from "dns"; import * as dns from "dns";
import * as process from "process"; import * as process from "process";
import * as path from "path"; import * as path from "path";
import * as fs from "fs";
const wifiScan = require("node-wifi-scanner"); const wifiScan = require("node-wifi-scanner");
export default class OSHandler { export default class OSHandler {
static scriptPath = path.resolve(process.cwd(), "scripts");
static async enableAllWifis() {
return this.overwriteWifis(await this.getKnownWifis());
}
static getKnownWifis(): Promise<WiFiNetwork[]> { static getKnownWifis(): Promise<WiFiNetwork[]> {
return new Promise<WiFiNetwork[]>((resolve, reject) => { return new Promise<WiFiNetwork[]>((resolve, reject) => {
exec("sudo touch /etc/wpa_supplicant/wpa_supplicant-monopoly.conf && sudo cat /etc/wpa_supplicant/wpa_supplicant-monopoly.conf", (err, stdout) => { exec("sudo touch /etc/wpa_supplicant/wpa_supplicant-monopoly.conf && sudo cat /etc/wpa_supplicant/wpa_supplicant-monopoly.conf", (err, stdout) => {
@ -20,16 +27,15 @@ export default class OSHandler {
let inBlock = false; let inBlock = false;
let currentNetwork: WiFiNetwork = {ssid: "", psk: "", isSecured: false}; let currentNetwork: WiFiNetwork = {ssid: "", psk: "", isSecured: false};
for(let line of lines) for (let line of lines) {
{
if (line.includes("network={")) if (line.includes("network={"))
inBlock = true; inBlock = true;
if (line.includes("}")) { if (line.includes("}")) {
inBlock = false; inBlock = false;
currentNetwork.isSecured = !!currentNetwork.psk; //currentNetwork.isSecured = !!currentNetwork.psk;
if (currentNetwork.ssid) if (currentNetwork.ssid)
wifis.push(currentNetwork); wifis.push({...currentNetwork});
currentNetwork.ssid = ""; currentNetwork.ssid = "";
currentNetwork.psk = ""; currentNetwork.psk = "";
currentNetwork.isSecured = false; currentNetwork.isSecured = false;
@ -39,6 +45,8 @@ export default class OSHandler {
currentNetwork.ssid = line.substring(line.indexOf('"') + 1, line.lastIndexOf('"')); currentNetwork.ssid = line.substring(line.indexOf('"') + 1, line.lastIndexOf('"'));
if (inBlock && line.includes("psk")) if (inBlock && line.includes("psk"))
currentNetwork.psk = line.substring(line.indexOf('"') + 1, line.lastIndexOf('"')); currentNetwork.psk = line.substring(line.indexOf('"') + 1, line.lastIndexOf('"'));
if (inBlock && line.includes("key_mgmt"))
currentNetwork.isSecured = line.includes("WPA-PSK");
} }
resolve(wifis); resolve(wifis);
@ -46,32 +54,91 @@ export default class OSHandler {
}); });
} }
static addWifi(wifi: string, passkey: string | null) { /**
* Adds a new wifi to the known networks
* @param ssid
* @param passkey
*/
static addWifi(ssid: string, passkey: string) {
return new Promise<void>(async (resolve, reject) => {
try {
let knownWifis = await this.getKnownWifis();
let found = false;
for (let wifi of knownWifis) {
if (wifi.ssid == wifi.ssid) {
// We know this wifi! - Refresh it!
found = true;
wifi.psk = passkey;
wifi.isSecured = !!passkey;
}
}
if (!found) {
knownWifis.push({ssid: ssid, psk: passkey, isSecured: !!passkey});
}
await this.overwriteWifis(knownWifis);
return resolve();
} catch (e) {
return reject(e);
}
});
}
/**
* Overwrites the custom wpa_supplicant file
* @param wifis
* @param ssid
*/
static overwriteWifis(wifis: WiFiNetwork[], ssid = "") {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
let p = path.resolve(process.cwd(), "/scripts/addWifi.sh"); let wifi_str = `ctrl_interface=/run/wpa_supplicant \nupdate_config=0\n\n`;
exec(p + ` -s "${wifi}" -p "${passkey}"`, (err, stdout) => { for (let wifi of wifis) {
wifi_str += "network={\n";
wifi_str += ` ssid="${wifi.ssid}"\n`
wifi_str += ` key_mgmt="${wifi.isSecured ? "WPA-PSK" : "NONE"}"\n`
if (ssid && ssid != wifi.ssid)
wifi_str += ` disabled=1\n`
if (wifi.psk)
wifi_str += ` psk="${wifi.psk}"\n`
wifi_str += `}\n\n`
}
fs.writeFileSync("/tmp/wpa_supplicant.conf", wifi_str);
exec("sudo mv -f /tmp/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant-monopoly.conf", (err, stdout) => {
if (err) if (err)
return reject(err); return reject(err);
if(stdout == "ok")
resolve(); resolve();
else });
reject("no-return");
}) })
});
} }
static connectToWifi(ssid: string) /**
{ * Connects to a specific wifi
* @param ssid
*/
static connectToWifi(ssid: string) {
return new Promise<boolean>((resolve, reject) => { return new Promise<boolean>((resolve, reject) => {
this.getKnownWifis().then((wifis) => {
let p = path.resolve(process.cwd(), "/scripts/connectToWifi.sh"); this.overwriteWifis(wifis, ssid).then(() => {
exec(p + ``) let p = path.resolve(this.scriptPath, "connectToWifi.sh");
exec(p, (error, stdout, stderr) => {
if (!error)
return resolve(stdout.includes("!!ok"));
reject(error);
});
}).catch(reject);
}).catch(reject);
}); });
} }
static disableAllWifis() { static removeWifi(ssid: string) {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
this.getKnownWifis().then(wifis => {
wifis.filter((ele) => {
return ele.ssid != ssid;
});
this.overwriteWifis(wifis).then(resolve).catch(reject);
}).catch(reject);
}); });
} }
@ -113,7 +180,6 @@ export default class OSHandler {
return -1; return -1;
}); });
console.log(networks);
networks = networks.filter((ele, index) => { networks = networks.filter((ele, index) => {
// If empty ssid // If empty ssid

View File

@ -12,7 +12,7 @@ const wifiScan = require("node-wifi-scanner");
export default class SmartMonopoly { export default class SmartMonopoly {
static run() { static run() {
this.setupIPCEvents(); this.setupIPCEvents();
OSHandler.getKnownWifis().then(console.log); OSHandler.enableAllWifis().then().catch(console.error);
} }
static setupIPCEvents() { static setupIPCEvents() {
@ -30,11 +30,15 @@ export default class SmartMonopoly {
}); });
IPCHandler("WIFI_CONNECT", async (e, request, args) => { IPCHandler("WIFI_CONNECT", async (e, request, args) => {
let data = request.data as {wifi: string, password: string} let data = request.data as {ssid: string, psk: string}
await OSHandler.addWifi(data.wifi, data.password); try {
await OSHandler.addWifi(data.ssid, data.psk);
let status = await OSHandler.connectToWifi(data.ssid);
return {status: status};
} catch(e)
{
return {status: false} return {status: false}
}
}); });
IPCHandler("WIFI_SCAN", async (e, request, args) => { IPCHandler("WIFI_SCAN", async (e, request, args) => {

View File

@ -26,7 +26,8 @@ interface WiFiState {
selectedSecured: boolean, selectedSecured: boolean,
foundWiFis: WiFiNetwork[], foundWiFis: WiFiNetwork[],
scanning: boolean, scanning: boolean,
status: status status: status,
password: string,
} }
type status = "NONE" | "SELECTION_FAILURE" | "CONNECTING" | "PASSWORD_NEEDED" | "FAILURE" | "CONNECTED" | 'SCAN_FAILURE'; type status = "NONE" | "SELECTION_FAILURE" | "CONNECTING" | "PASSWORD_NEEDED" | "FAILURE" | "CONNECTED" | 'SCAN_FAILURE';
@ -41,6 +42,7 @@ export default class WiFi extends Component<{}, WiFiState> {
foundWiFis: [], foundWiFis: [],
scanning: false, scanning: false,
status: "NONE", status: "NONE",
password: "",
}; };
} }
@ -100,7 +102,7 @@ export default class WiFi extends Component<{}, WiFiState> {
...prevState, ...prevState,
status: "CONNECTING" status: "CONNECTING"
})); }));
window.api.request('WIFI_CONNECT', {data: this.state.currentSelection}).then((answer: IPCAnswer) => { window.api.request('WIFI_CONNECT', {data: {ssid: this.state.currentSelection, psk: this.state.password}}).then((answer: IPCAnswer) => {
this.setState((prevState) => ({ this.setState((prevState) => ({
...prevState, ...prevState,
status: answer.status ? "CONNECTED" : "FAILURE" status: answer.status ? "CONNECTED" : "FAILURE"
@ -149,9 +151,10 @@ export default class WiFi extends Component<{}, WiFiState> {
</Typography> </Typography>
<Typography id="transition-modal-description" sx={{mt: 2}}> <Typography id="transition-modal-description" sx={{mt: 2}}>
<Alert variant={this.state.status == "FAILURE" ? "filled" : "standard"} <Alert variant={this.state.status == "FAILURE" ? "filled" : "standard"}
severity={this.state.status.includes("FAILURE") ? "error" : "info"}> severity={this.state.status.includes("FAILURE") ? "error" : (this.state.status == "CONNECTED" ? "success" : "info")}>
{this.state.status == "NONE" && "Bitte wählen Sie eins der folgenden Netzwerke aus"} {this.state.status == "NONE" && "Bitte wählen Sie eins der folgenden Netzwerke aus"}
{this.state.status == "CONNECTING" && "Verbinden..." } {this.state.status == "CONNECTING" && "Verbinden..." }
{this.state.status == "CONNECTED" && "Verbunden!" }
{this.state.status == "SCAN_FAILURE" && "Das Scannen ist fehlgeschlagen. - Möglicherweise fehlen Berechtigungen, um Netzwerke zu scannen, oder es befindet sich kein WLAN-Interface auf diesem Gerät." } {this.state.status == "SCAN_FAILURE" && "Das Scannen ist fehlgeschlagen. - Möglicherweise fehlen Berechtigungen, um Netzwerke zu scannen, oder es befindet sich kein WLAN-Interface auf diesem Gerät." }
{this.state.status == "FAILURE" && "Verbindungsfehler!" } {this.state.status == "FAILURE" && "Verbindungsfehler!" }
{this.state.status == "SELECTION_FAILURE" && "Bitte zunächst ein Netzwerk auswählen!" } {this.state.status == "SELECTION_FAILURE" && "Bitte zunächst ein Netzwerk auswählen!" }
@ -193,7 +196,10 @@ export default class WiFi extends Component<{}, WiFiState> {
</FormControl> </FormControl>
<FormControl sx={{m: 1, minWidth: '70%'}}> <FormControl sx={{m: 1, minWidth: '70%'}}>
<TextField id="password" label="Passwort" disabled={this.state.scanning || !this.state.selectedSecured} variant="outlined" /> <TextField id="password" value={this.state.password} onChange={evt => this.setState(prev => ({
...prev,
password: evt.target.value
}))} label="Passwort" disabled={this.state.scanning || !this.state.selectedSecured} variant="outlined" />
</FormControl> </FormControl>
@ -219,7 +225,7 @@ export default class WiFi extends Component<{}, WiFiState> {
<FormControl sx={{ml: 2, minWidth: '20%'}}> <FormControl sx={{ml: 2, minWidth: '20%'}}>
<Button variant="contained" disabled={this.state.status == "CONNECTING"} <Button variant="contained" disabled={this.state.status == "CONNECTING"}
onClick={() => this.handleClose()} onClick={() => this.handleClose()}
color="error">Abbrechen</Button> color="secondary">Schließen</Button>
</FormControl> </FormControl>
</Typography> </Typography>
</Box> </Box>