summary refs log tree commit diff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xbin/clear-notification11
-rwxr-xr-xbin/connmenu220
2 files changed, 231 insertions, 0 deletions
diff --git a/bin/clear-notification b/bin/clear-notification
new file mode 100755
index 0000000..e58ddb2
--- /dev/null
+++ b/bin/clear-notification
@@ -0,0 +1,11 @@
+#!/bin/sh
+set -eu
+if [ -z "$1" ]; then
+	printf "error: missing notification id\n" >&2
+	exit 1
+fi
+exec gdbus call --session \
+	--dest org.freedesktop.Notifications \
+	--object-path /org/freedesktop/Notifications \
+	--method org.freedesktop.Notifications.CloseNotification \
+	"$1" >/dev/null
diff --git a/bin/connmenu b/bin/connmenu
new file mode 100755
index 0000000..cc584e4
--- /dev/null
+++ b/bin/connmenu
@@ -0,0 +1,220 @@
+#!/bin/bash
+# This is a modified version of:
+# https://github.com/march-linux/connman_dmenu
+#
+# changes:
+# * include DEBUG=1 env var switch
+# * use menu (my bemenu wrapper)
+# * replace dmenu_notify with notify-send
+# * include icons in menu prompts
+
+set -e
+[ -n "$DEBUG" ] && set -x
+export UNSAFE=1
+
+readonly SCAN_RESULT=/tmp/connman.scan
+readonly STORAGE_PATH=/var/lib/connman
+readonly VPN_STORAGE_PATH=/var/lib/connman-vpn
+
+dmenu() {
+	menu "$@"
+}
+notifysend() {
+	[ -z "$notifyicon" ] && notifyicon=wifi
+	local msg=$1
+	shift 1
+	notification_id=$(notify-send "connman" "$msg" -i "$(iconez -sn "$notifyicon")" --print-id "$@")
+}
+
+get_services() {
+	if [[ -f $SCAN_RESULT ]]; then
+		notifysend 'another connman_dmenu is running'
+		exit 1
+	fi
+
+	local notification_id
+	local notifyicon=wifi-sync
+	notifysend "scanning for wifi services..." --expire-time=0
+
+	trap "rm -f $SCAN_RESULT" EXIT
+	connmanctl enable wifi &>/dev/null
+	connmanctl scan wifi &>/dev/null
+	clear-notification "$notification_id"
+
+	connmanctl services |
+		awk -F ' +' '{ service_id=$NF; $NF=""; $1=""; name=substr($0, 2, length-2); gsub(/[^a-zA-Z0-9-]/, "_", name) }
+	name { print name, service_id }' >$SCAN_RESULT
+}
+
+# $1 = index
+index_to_name() {
+	[[ -f $SCAN_RESULT ]] || exit 1
+	awk -v line="$1" 'NR == line { print $1 }' $SCAN_RESULT
+}
+
+# $1 = index
+index_to_service() {
+	[[ -f $SCAN_RESULT ]] || exit 1
+	awk -v line="$1" 'NR == line { print $2 }' $SCAN_RESULT
+}
+
+# $1 = service id
+get_service_security() {
+	cut -d _ -f 5 <<<"$1"
+}
+
+# $1 = service id
+get_service_signal() {
+	connmanctl services "$1" | awk '$1 == "Strength" { print $3 }'
+}
+
+# $1 = service id
+get_service_state() {
+	connmanctl services "$1" | awk '$1 == "State" { print $3 }'
+}
+
+create_dmenu() {
+	[[ -f $SCAN_RESULT ]] || exit 1
+	echo 'setup vpn pptp'
+	local order=1
+	local name
+	local service_id
+	local security
+	local signal
+	local disconnect
+	while read -r name service_id; do
+		security=''
+		signal=''
+		disconnect=''
+		[[ ! "$(get_service_state "$service_id")" =~ ^(idle|failure)$ ]] && disconnect='(disconnect)'
+		case "$service_id" in
+		wifi_*)
+			security="$(get_service_security "$service_id")"
+			signal="$(get_service_signal "$service_id")"
+			;;
+		vpn_*)
+			security=vpn
+			;;
+		esac
+		printf '%2s  %-40s%9s %-3s %s\n' "$order" "$name" "$security" "$signal" "$disconnect"
+		((order++))
+	done <$SCAN_RESULT
+}
+
+# $1 = question
+# $2 = var name
+dmenu_ask() {
+	IFS= read -r "$2" < <(: | dmenu -p "󱛆 $1")
+	if [[ ! "${!2}" ]]; then
+		(
+			notifyicon=wifi-alert
+			notifysend "invalid $2"
+		)
+		exit 1
+	fi
+}
+
+get_services
+index="$(create_dmenu | dmenu -l 10 -i -p '󱛆 select wifi service' | sed 's/^ *//g' | cut -d ' ' -f 1)"
+
+if [[ "$index" == setup ]]; then
+	# create vpn mode
+	dmenu_ask 'name this PPTP VPN' name
+	name="${name// /_}"
+	dmenu_ask 'please provide VPN domain' domain
+	dmenu_ask 'please provide identity' identity
+	dmenu_ask 'please provide password' password
+	cat >"$VPN_STORAGE_PATH/$name.config" <<-EOF
+		[provider_$name]
+		Type = PPTP
+		Name = $name
+		Host = $(dig +short A "$domain" | sort -n | head -n1)
+		Domain = $domain
+		PPTP.User = $identity
+		PPTP.Password = $password
+	EOF
+	notifysend "VPN $name is created"
+	exit 0
+fi
+
+service_id="$(index_to_service "$index")"
+[[ "$service_id" ]] || exit 1
+
+name="$(index_to_name "$index")"
+echo "$name { $service_id }"
+
+if [[ ! "$(get_service_state "$service_id")" =~ ^(idle|failure)$ ]]; then
+	connmanctl disconnect "$service_id"
+	(
+		notifyicon=wifi-remove
+		notifysend "$name disconnected"
+	)
+	exit 0
+fi
+
+security="$(get_service_security "$service_id")"
+
+# create service file for encryption
+if [[ "$security" =~ ^(ieee8021x|psk|wep)$ ]]; then
+	config_file="$STORAGE_PATH/$name-$security.config"
+	if [[ -f "$config_file" && no != "$(echo -e 'yes\nno' | dmenu -p '󱛆 use previous profile?')" ]]; then
+		echo "use old profile: $config_file"
+	else
+		dmenu_ask 'please provide password' password
+		case "$security" in
+		ieee8021x)
+			dmenu_ask 'please provide identity' identity
+			case "$(echo -e 'PEAP/MSCHAPV2\nTTLS/PAP' | dmenu -p '󱛆 please specify EAP type')" in
+			PEAP/MSCHAPV2)
+				eap=peap
+				phase2=MSCHAPV2
+				;;
+			TTLS/PAP)
+				eap=ttls
+				phase2=PAP
+				;;
+			*)
+				(
+					notifyicon=wifi-alert
+					notifysend 'invalid EAP'
+				)
+				exit 1
+				;;
+			esac
+			cat >"$config_file" <<-EOF
+				[service_$service_id]
+				Type = wifi
+				Name = $name
+				EAP = $eap
+				Phase2 = $phase2
+				Identity = $identity
+				Passphrase = $password
+			EOF
+			;;
+		psk | wep)
+			cat >"$config_file" <<-EOF
+				[service_$service_id]
+				Type = wifi
+				Name = $name
+				Passphrase = $password
+			EOF
+			;;
+		esac
+		chmod 600 "$config_file"
+	fi
+fi
+
+connman_msg="$(timeout 10 connmanctl connect "$service_id" 2>&1 | head -n 1)"
+if [[ "$connman_msg" == Connected* ]]; then
+	(
+		notifyicon=wifi-check
+		notifysend "connected to $name"
+	)
+else
+	error_msg='automatic timeout for connman_dmenu'
+	[[ "$connman_msg" ]] && error_msg="$(cut -d ' ' -f 3- <<<"$connman_msg")"
+	(
+		notifyicon=wifi-cancel
+		notifysend "cannot connect to $name ($error_msg)"
+	)
+fi