Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ PWD := $(shell pwd)
DOCKER_RUN_BASE := docker run -e UID=$(UID) -e GID=$(GID) -v $(PWD):/home/build/NanoKVM --rm

# Build commands
GO_BUILD_CMD := cd /home/build/NanoKVM/server && go mod tidy && CGO_ENABLED=1 GOOS=linux GOARCH=riscv64 CC=riscv64-unknown-linux-musl-gcc CGO_CFLAGS="-mcpu=c906fdv -march=rv64imafdcv0p7xthead -mcmodel=medany -mabi=lp64d" go build
GO_BUILD_CMD := cd /home/build/NanoKVM/server && go mod tidy && CGO_ENABLED=1 GOOS=linux GOARCH=riscv64 CC=riscv64-unknown-linux-musl-gcc CGO_CFLAGS="-mcpu=c906fdv -march=rv64imafdcv0p7xthead -mcmodel=medany -mabi=lp64d" CGO_LDFLAGS="-Wl,-rpath,\$$ORIGIN/dl_lib" go build
SUPPORT_BUILD_CMD := . ./home/build/MaixCDK/bin/activate && cd /home/build/NanoKVM/support/sg2002 && ./build kvm_system && ./build kvm_system add_to_kvmapp

.PHONY: help check-root builder-image rebuild-image check-image shell app support all clean
Expand Down
130 changes: 124 additions & 6 deletions kvmapp/system/init.d/S30eth
Original file line number Diff line number Diff line change
@@ -1,11 +1,125 @@
#!/bin/sh

RESERVE_INET="192.168.90.1/22"
ETH_MODE_FILE="/etc/kvm/eth.mode"
ETH_PASS_FILE="/etc/kvm/eth.pass"
ETH_IDENTITY_FILE="/etc/kvm/eth.identity"
ETH_EAP_FILE="/etc/kvm/eth.eap"
ETH_PHASE2_FILE="/etc/kvm/eth.phase2"
ETH_ANON_IDENTITY_FILE="/etc/kvm/eth.anonymous_identity"
ETH_CA_CERT_FILE="/etc/kvm/eth.ca_cert"
ETH_CLIENT_CERT_FILE="/etc/kvm/eth.client_cert"
ETH_PRIVATE_KEY_FILE="/etc/kvm/eth.private_key"
ETH_PRIVATE_KEY_PASSWD_FILE="/etc/kvm/eth.private_key_passwd"
ETH_DOMAIN_SUFFIX_MATCH_FILE="/etc/kvm/eth.domain_suffix_match"
ETH_WPA_CONF="/etc/wpa_supplicant-wired.conf"
ETH_WPA_PID="/run/wpa_supplicant.eth0.pid"
ETH_DHCP_PID="/run/udhcpc.eth0.pid"
ETH_WPA_BIN="/usr/sbin/wpa_supplicant-wired"

clean_line() {
echo "$1" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/\r//g'
}

read_file_trimmed() {
file="$1"
[ -e "$file" ] || return 0
tr -d '\r' <"$file" | sed 's/[[:space:]]*$//'
}

append_quoted_value() {
key="$1"
value="$2"
[ -n "$value" ] || return 0
escaped=$(printf '%s' "$value" | sed 's/\\/\\\\/g; s/"/\\"/g')
printf ' %s="%s"\n' "$key" "$escaped"
}

supports_wired_driver() {
if [ -x "$ETH_WPA_BIN" ]; then
return 0
fi
wpa_supplicant -h 2>&1 | grep -q "wired = Wired Ethernet driver"
}

get_wpa_bin() {
if [ -x "$ETH_WPA_BIN" ]; then
echo "$ETH_WPA_BIN"
return 0
fi
command -v wpa_supplicant
}

gen_wired_enterprise_conf() {
pass="$1"
identity="$2"
eap="$3"
phase2="$4"
anonymous_identity="$5"
ca_cert="$6"
domain_suffix_match="$7"
client_cert="$8"
private_key="$9"
private_key_passwd="${10}"

echo "ctrl_interface=/var/run/wpa_supplicant"
echo "ap_scan=0"
echo "fast_reauth=1"
echo
echo "network={"
echo " key_mgmt=IEEE8021X"
[ -n "$eap" ] && echo " eap=$eap"
append_quoted_value "identity" "$identity"
append_quoted_value "password" "$pass"
append_quoted_value "phase2" "$phase2"
append_quoted_value "anonymous_identity" "$anonymous_identity"
append_quoted_value "ca_cert" "$ca_cert"
append_quoted_value "domain_suffix_match" "$domain_suffix_match"
append_quoted_value "client_cert" "$client_cert"
append_quoted_value "private_key" "$private_key"
append_quoted_value "private_key_passwd" "$private_key_passwd"
echo "}"
}

stop_wired_auth() {
if [ -e "$ETH_WPA_PID" ]; then
kill "$(cat "$ETH_WPA_PID")" 2>/dev/null || true
rm -f "$ETH_WPA_PID"
fi
}

start_wired_auth() {
mode=$(read_file_trimmed "$ETH_MODE_FILE")
case "$mode" in
enterprise|8021x|wpa-eap)
if ! supports_wired_driver; then
echo "S30eth: wired 802.1X driver is unavailable; skipping wpa_supplicant startup" >&2
return 0
fi
pass=$(read_file_trimmed "$ETH_PASS_FILE")
identity=$(read_file_trimmed "$ETH_IDENTITY_FILE")
eap=$(read_file_trimmed "$ETH_EAP_FILE")
phase2=$(read_file_trimmed "$ETH_PHASE2_FILE")
anonymous_identity=$(read_file_trimmed "$ETH_ANON_IDENTITY_FILE")
ca_cert=$(read_file_trimmed "$ETH_CA_CERT_FILE")
domain_suffix_match=$(read_file_trimmed "$ETH_DOMAIN_SUFFIX_MATCH_FILE")
client_cert=$(read_file_trimmed "$ETH_CLIENT_CERT_FILE")
private_key=$(read_file_trimmed "$ETH_PRIVATE_KEY_FILE")
private_key_passwd=$(read_file_trimmed "$ETH_PRIVATE_KEY_PASSWD_FILE")

[ -n "$eap" ] || eap="PEAP"

gen_wired_enterprise_conf "$pass" "$identity" "$eap" "$phase2" \
"$anonymous_identity" "$ca_cert" "$domain_suffix_match" \
"$client_cert" "$private_key" "$private_key_passwd" >"$ETH_WPA_CONF"
chmod 600 "$ETH_WPA_CONF"
ip link set eth0 up
stop_wired_auth
"$(get_wpa_bin)" -B -D wired -i eth0 -c "$ETH_WPA_CONF" -P "$ETH_WPA_PID"
;;
esac
}

calc_gw() {
addr="$1"
netid="$2"
Expand All @@ -23,7 +137,9 @@ EOF
}

start() {
stop_wired_auth
ip addr flush dev eth0
start_wired_auth
if [ -e /boot/eth.nodhcp ]; then
while IFS= read -r line || [ -n "$line" ]; do
line=$(clean_line "$line")
Expand Down Expand Up @@ -57,22 +173,24 @@ start() {
done < /boot/eth.nodhcp

ip a show dev eth0 | grep inet > /dev/null || {
udhcpc -i eth0 -t 3 -T 1 -A 5 -b -p /run/udhcpc.eth0.pid &>/dev/null
udhcpc -i eth0 -t 3 -T 1 -A 5 -b -p "$ETH_DHCP_PID" &>/dev/null
ip a show dev eth0 | grep inet > /dev/null
} || {
inet=$RESERVE_INET
addr=${inet%/*}
ip a add "$inet" brd + dev eth0
} || exit 1
else
udhcpc -i eth0 -t 10 -T 1 -A 5 -b -p /run/udhcpc.eth0.pid &
udhcpc -i eth0 -t 10 -T 1 -A 5 -b -p "$ETH_DHCP_PID" &
fi
}

stop() {
[ ! -e "/run/udhcpc.eth0.pid" ] && exit 1
kill "$(cat /run/udhcpc.eth0.pid)"
rm /run/udhcpc.eth0.pid
if [ -e "$ETH_DHCP_PID" ]; then
kill "$(cat "$ETH_DHCP_PID")" 2>/dev/null || true
rm -f "$ETH_DHCP_PID"
fi
stop_wired_auth
}

case "$1" in
Expand All @@ -83,4 +201,4 @@ case "$1" in
$0 start
;;
*) exit 1 ;;
esac
esac
181 changes: 176 additions & 5 deletions kvmapp/system/init.d/S30wifi
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,87 @@
. /etc/profile

APFLAG_FILE=/tmp/wifiap
WIFI_STATIC_CONFIG=/boot/wifi.nodhcp

escape_wpa_value() {
printf "%s" "$1" | tr -d '\r\n' | sed 's/\\/\\\\/g; s/"/\\"/g'
}

sanitize_wpa_token() {
printf "%s" "$1" | tr -cd 'A-Za-z0-9_-'
}

clean_line() {
echo "$1" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/\r//g'
}

append_wpa_field() {
key="${1}"
value="${2}"
if [ -n "$value" ]; then
printf ' %s="%s"\n' "$key" "$(escape_wpa_value "$value")"
fi
}

calc_gw() {
addr="$1"
netid="$2"
IFS=. read a b c d <<EOF
$addr
EOF
ipnum=$(( (a<<24) + (b<<16) + (c<<8) + d ))
mask=$(( 0xFFFFFFFF << (32-netid) & 0xFFFFFFFF ))
gwnum=$(( (ipnum & mask) | 1 ))
if [ $gwnum -eq $ipnum ]; then
broadcast=$(( (ipnum & mask) | (0xFFFFFFFF & ~mask) ))
gwnum=$(( broadcast - 1 ))
fi
echo "$(( (gwnum>>24)&255 )).$(( (gwnum>>16)&255 )).$(( (gwnum>>8)&255 )).$(( gwnum&255 ))"
}

gen_wpa_enterprise_conf() {
ssid="${1}"
pass="${2}"
identity="${3}"
eap="${4:-PEAP}"
phase2="${5}"
anonymous_identity="${6}"
ca_cert="${7}"
domain_suffix_match="${8}"
client_cert="${9}"
private_key="${10}"
private_key_passwd="${11}"
eap=$(sanitize_wpa_token "$eap")
case "$eap" in
PEAP | TTLS)
if [ -z "$phase2" ]; then
phase2="auth=MSCHAPV2"
fi
;;
*)
phase2=""
;;
esac

echo "ctrl_interface=/var/run/wpa_supplicant"
echo "ap_scan=1"
echo "fast_reauth=1"
echo ""
echo "network={"
append_wpa_field "ssid" "$ssid"
echo " key_mgmt=WPA-EAP"
echo " eap=${eap}"
append_wpa_field "identity" "$identity"
append_wpa_field "password" "$pass"
append_wpa_field "phase2" "$phase2"
append_wpa_field "anonymous_identity" "$anonymous_identity"
append_wpa_field "ca_cert" "$ca_cert"
append_wpa_field "client_cert" "$client_cert"
append_wpa_field "private_key" "$private_key"
append_wpa_field "private_key_passwd" "$private_key_passwd"
append_wpa_field "domain_suffix_match" "$domain_suffix_match"
echo "}"
}

gen_hostapd_conf() {
ssid="${1}"
Expand Down Expand Up @@ -52,27 +133,117 @@ start() {
echo "wifi mode: sta"
ssid=""
pass=""
mode="psk"
identity=""
eap="PEAP"
phase2="auth=MSCHAPV2"
anonymous_identity=""
ca_cert=""
client_cert=""
private_key=""
private_key_passwd=""
domain_suffix_match=""
if [ -e /boot/wifi.ssid ] && [ -e /boot/wifi.pass ]; then
echo "Updating WiFi credentials from /boot to /etc/kvm/"

rm -f /etc/kvm/wifi.ssid /etc/kvm/wifi.pass
rm -f /etc/kvm/wifi.ssid /etc/kvm/wifi.pass /etc/kvm/wifi.mode

mv /boot/wifi.ssid /etc/kvm/wifi.ssid
mv /boot/wifi.pass /etc/kvm/wifi.pass

chown root:root /etc/kvm/wifi.ssid /etc/kvm/wifi.pass
chmod 644 /etc/kvm/wifi.ssid /etc/kvm/wifi.pass
chmod 644 /etc/kvm/wifi.ssid
chmod 600 /etc/kvm/wifi.pass
fi
if [ -e /etc/kvm/wifi.ssid ]; then
ssid=$(cat /etc/kvm/wifi.ssid)
fi
if [ -e /etc/kvm/wifi.pass ]; then
pass=$(cat /etc/kvm/wifi.pass)
fi
echo "ctrl_interface=/var/run/wpa_supplicant" >/etc/wpa_supplicant.conf
wpa_passphrase "$ssid" "$pass" >>/etc/wpa_supplicant.conf
if [ -e /etc/kvm/wifi.mode ]; then
mode=$(cat /etc/kvm/wifi.mode)
fi
if [ -e /etc/kvm/wifi.identity ]; then
identity=$(cat /etc/kvm/wifi.identity)
fi
if [ -e /etc/kvm/wifi.eap ]; then
eap=$(cat /etc/kvm/wifi.eap)
fi
if [ -e /etc/kvm/wifi.phase2 ]; then
phase2=$(cat /etc/kvm/wifi.phase2)
fi
if [ -e /etc/kvm/wifi.anonymous_identity ]; then
anonymous_identity=$(cat /etc/kvm/wifi.anonymous_identity)
fi
if [ -e /etc/kvm/wifi.ca_cert ]; then
ca_cert=$(cat /etc/kvm/wifi.ca_cert)
fi
if [ -e /etc/kvm/wifi.client_cert ]; then
client_cert=$(cat /etc/kvm/wifi.client_cert)
fi
if [ -e /etc/kvm/wifi.private_key ]; then
private_key=$(cat /etc/kvm/wifi.private_key)
fi
if [ -e /etc/kvm/wifi.private_key_passwd ]; then
private_key_passwd=$(cat /etc/kvm/wifi.private_key_passwd)
fi
if [ -e /etc/kvm/wifi.domain_suffix_match ]; then
domain_suffix_match=$(cat /etc/kvm/wifi.domain_suffix_match)
fi

case "$mode" in
enterprise | 8021x | wpa-eap)
gen_wpa_enterprise_conf "$ssid" "$pass" "$identity" "$eap" "$phase2" "$anonymous_identity" "$ca_cert" "$domain_suffix_match" "$client_cert" "$private_key" "$private_key_passwd" >/etc/wpa_supplicant.conf
;;
*)
echo "ctrl_interface=/var/run/wpa_supplicant" >/etc/wpa_supplicant.conf
wpa_passphrase "$ssid" "$pass" >>/etc/wpa_supplicant.conf
;;
esac
chmod 600 /etc/wpa_supplicant.conf
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf
if [ ! -e /boot/wifi.nodhcp ]; then
ifconfig wlan0 up
ip route del default || true
ip addr flush dev wlan0
if [ -e "$WIFI_STATIC_CONFIG" ]; then
while IFS= read -r line || [ -n "$line" ]; do
line=$(clean_line "$line")
[ -z "$line" ] && continue
set -- $line
inet="$1"
gw="$2"
[ -z "$inet" ] && continue
case "$inet" in
*/*)
netid_check=${inet#*/}
if ! echo "$netid_check" | grep -qE '^[0-9]+$' || [ $netid_check -lt 1 ] 2>/dev/null || [ $netid_check -gt 32 ] 2>/dev/null; then
inet="${inet%/*}/16"
fi
;;
*)
inet="$inet/16"
;;
esac
addr=${inet%/*}
netid=${inet#*/}
[ -z "$gw" ] && gw=$(calc_gw "$addr" "$netid")
arping -Dqc2 -Iwlan0 "$addr" || continue
ip a add "$inet" brd + dev wlan0
ip r add default via "$gw" dev wlan0
echo -e "nameserver $gw" >> /etc/resolv.conf
break
done < "$WIFI_STATIC_CONFIG"

ip a show dev wlan0 | grep inet > /dev/null || {
udhcpc -i wlan0 -t 3 -T 1 -A 5 -b -p /run/udhcpc.wlan0.pid &>/dev/null
ip a show dev wlan0 | grep inet > /dev/null
} || {
inet=192.168.90.1/22
addr=${inet%/*}
ip a add "$inet" brd + dev wlan0
} || exit 1
else
(udhcpc -i wlan0 -t 10 -T 1 -A 5 -b -p /run/udhcpc.wlan0.pid) &
fi
}
Expand Down
Loading