From 6692095f9d8e46d1e5067be7e1e060e218ef4eda Mon Sep 17 00:00:00 2001
From: David Bauer <mail@david-bauer.net>
Date: Sun, 16 Feb 2020 22:28:03 +0100
Subject: [PATCH] gluob-client-bridge: add support for OWE encryption

---
 package/gluon-client-bridge/check_site.lua    |  8 +-
 .../upgrade/320-gluon-client-bridge-wireless  | 90 +++++++++++++++++--
 2 files changed, 89 insertions(+), 9 deletions(-)

diff --git a/package/gluon-client-bridge/check_site.lua b/package/gluon-client-bridge/check_site.lua
index 7922fae50..b077f87bb 100644
--- a/package/gluon-client-bridge/check_site.lua
+++ b/package/gluon-client-bridge/check_site.lua
@@ -9,7 +9,13 @@ need_string_match(in_domain({'next_node', 'ip6'}), '^[%x:]+$', false)
 
 for _, config in ipairs({'wifi24', 'wifi5'}) do
 	if need_table({config, 'ap'}, nil, false) then
-		need_string_match(in_domain({config, 'ap', 'ssid'}), '^' .. ('.?'):rep(32) .. '$')
 		need_boolean({config, 'ap', 'disabled'}, false)
+		if need_boolean({config, 'ap', 'owe_transition_mode'}, false) then
+			need_string_match(in_domain({config, 'ap', 'ssid'}), '^' .. ('.?'):rep(32) .. '$')
+			need_string_match(in_domain({config, 'ap', 'owe_ssid'}), '^' .. ('.?'):rep(32) .. '$')
+		else
+			need_string_match(in_domain({config, 'ap', 'ssid'}), '^' .. ('.?'):rep(32) .. '$', false)
+			need_string_match(in_domain({config, 'ap', 'owe_ssid'}), '^' .. ('.?'):rep(32) .. '$', false)
+		end
 	end
 end
diff --git a/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/320-gluon-client-bridge-wireless b/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/320-gluon-client-bridge-wireless
index d9ac83f30..0aa257524 100755
--- a/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/320-gluon-client-bridge-wireless
+++ b/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/320-gluon-client-bridge-wireless
@@ -1,6 +1,7 @@
 #!/usr/bin/lua
 
 local util = require 'gluon.util'
+local platform = require 'gluon.platform'
 
 local uci = require('simple-uci').cursor()
 
@@ -13,9 +14,7 @@ local function is_disabled(config, name)
 	return config.disabled(false)
 end
 
-util.foreach_radio(uci, function(radio, index, config)
-	local radio_name = radio['.name']
-
+local function configure_ap(radio, index, config, radio_name)
 	local name = 'client_' .. radio_name
 	local suffix = radio_name:match('^radio(%d+)$')
 
@@ -24,12 +23,9 @@ util.foreach_radio(uci, function(radio, index, config)
 
 	uci:delete('wireless', name)
 
-	if not ap() then
-		return
-	end
-
 	local macaddr = util.get_wlan_mac(uci, radio, index, 1)
-	if not macaddr then
+
+	if not ap() or not ap.ssid() or not macaddr then
 		return
 	end
 
@@ -42,6 +38,84 @@ util.foreach_radio(uci, function(radio, index, config)
 		ifname = suffix and 'client' .. suffix,
 		disabled = disabled or false,
 	})
+end
+
+local function configure_owe(radio, index, config, radio_name)
+	local name = 'owe_' .. radio_name
+	local suffix = radio_name:match('^radio(%d+)$')
+
+	local ap = config.ap
+
+	local disabled = is_disabled(ap, 'client_' .. radio_name)
+
+	uci:delete('wireless', name)
+
+	-- Don't configure OWE in case our device
+	-- can't do MFP, as it's mandatory for OWE.
+	if not platform.device_supports_mfp(uci) then
+		return
+	end
+
+	local macaddr = util.get_wlan_mac(uci, radio, index, 3)
+
+	if not ap() or not ap.owe_ssid() or not macaddr then
+		return
+	end
+
+	uci:section('wireless', 'wifi-iface', name, {
+		device = radio_name,
+		network = 'client',
+		mode = 'ap',
+		ssid = ap.owe_ssid(),
+		macaddr = macaddr,
+		ifname = suffix and 'owe' .. suffix,
+		disabled = disabled or false,
+		encryption = 'owe',
+		ieee80211w = 2,
+	})
+end
+
+local function configure_owe_transition_mode(config, radio_name)
+	local ap = config.ap
+
+	-- Don't configure OWE in case our device
+	-- can't do MFP, as it's mandatory for OWE.
+	if not platform.device_supports_mfp(uci) then
+		return
+	end
+
+	if not ap() or not ap.owe_transition_mode() then
+		return
+	end
+
+	local name_client = 'client_' .. radio_name
+	local name_owe = 'owe_' .. radio_name
+
+	local ssid_client = uci:get('wireless', name_client, 'ssid')
+	local ssid_owe = uci:get('wireless', name_owe, 'ssid')
+
+	local macaddr_client = uci:get('wireless', name_client, 'macaddr')
+	local macaddr_owe = uci:get('wireless', name_owe, 'macaddr')
+
+	if not ssid_client or not ssid_owe or not macaddr_client or not macaddr_owe then
+		return
+	end
+
+	uci:set('wireless', name_client, 'owe_transition_ssid', ssid_owe)
+	uci:set('wireless', name_client, 'owe_transition_bssid', macaddr_owe)
+
+	uci:set('wireless', name_owe, 'owe_transition_ssid', ssid_client)
+	uci:set('wireless', name_owe, 'owe_transition_bssid', macaddr_client)
+	uci:set('wireless', name_owe, 'hidden', '1')
+end
+
+util.foreach_radio(uci, function(radio, index, config)
+	local radio_name = radio['.name']
+
+	configure_ap(radio, index, config, radio_name)
+
+	configure_owe(radio, index, config, radio_name)
+	configure_owe_transition_mode(config, radio_name)
 end)
 
 uci:save('wireless')
-- 
GitLab