1#
2# Copyright (c) 2014, The Linux Foundation. All rights reserved.
3#
4#  Permission to use, copy, modify, and/or distribute this software for any
5#  purpose with or without fee is hereby granted, provided that the above
6#  copyright notice and this permission notice appear in all copies.
7#
8#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15#
16
17wpa_supplicant_setup_vif() {
18	local vif="$1"
19	local driver="$2"
20	local key="$key"
21	local options="$3"
22	local freq="" crypto=""
23	[ -n "$4" ] && freq="frequency=$4"
24
25	# make sure we have the encryption type and the psk
26	[ -n "$enc" ] || {
27		config_get enc "$vif" encryption
28	}
29
30	enc_list=`echo "$enc" | sed "s/+/ /g"`
31
32	for enc_var in $enc_list; do
33		case "$enc_var" in
34			*tkip)
35				crypto="TKIP $crypto"
36				;;
37			*aes)
38				crypto="CCMP $crypto"
39				;;
40			*ccmp)
41				crypto="CCMP $crypto"
42				;;
43			*ccmp-256)
44				crypto="CCMP-256 $crypto"
45				;;
46			*gcmp)
47				crypto="GCMP $crypto"
48				;;
49			*gcmp-256)
50				crypto="GCMP-256 $crypto"
51		esac
52	done
53
54	[ -n "$key" ] || {
55		config_get key "$vif" key
56	}
57
58	local net_cfg bridge
59	config_get bridge "$vif" bridge
60	[ -z "$bridge" ] && {
61		net_cfg="$(find_net_config "$vif")"
62		[ -z "$net_cfg" ] || bridge="$(bridge_interface "$net_cfg")"
63		config_set "$vif" bridge "$bridge"
64	}
65
66	local mode ifname wds modestr=""
67	config_get mode "$vif" mode
68	config_get ifname "$vif" ifname
69	config_get_bool wds "$vif" wds 0
70	config_get_bool extap "$vif" extap 0
71
72	config_get device "$vif" device
73	config_get_bool qwrap_enable "$device" qwrap_enable 0
74
75	[ -z "$bridge" ] || [ "$mode" = ap ] || [ "$mode" = sta -a $wds -eq 1 ] || \
76	[ "$mode" = sta -a $extap -eq 1 ] || [ $qwrap_enable -ne 0 ] || {
77		echo "wpa_supplicant_setup_vif($ifname): Refusing to bridge $mode mode interface"
78		return 1
79	}
80	[ "$mode" = "adhoc" ] && modestr="mode=1"
81
82	key_mgmt='NONE'
83	case "$enc" in
84		*none*) ;;
85		*wep*)
86			config_get key "$vif" key
87			key="${key:-1}"
88			case "$key" in
89				[1234])
90					for idx in 1 2 3 4; do
91						local zidx
92						zidx=$(($idx - 1))
93						config_get ckey "$vif" "key${idx}"
94						[ -n "$ckey" ] && \
95							append "wep_key${zidx}" "wep_key${zidx}=$(prepare_key_wep "$ckey")"
96					done
97					wep_tx_keyidx="wep_tx_keyidx=$((key - 1))"
98				;;
99				*)
100					wep_key0="wep_key0=$(prepare_key_wep "$key")"
101					wep_tx_keyidx="wep_tx_keyidx=0"
102				;;
103			esac
104			case "$enc" in
105				*mixed*)
106					wep_auth_alg='auth_alg=OPEN SHARED'
107				;;
108				*shared*)
109					wep_auth_alg='auth_alg=SHARED'
110				;;
111				*open*)
112					wep_auth_alg='auth_alg=OPEN'
113				;;
114			esac
115		;;
116		*psk*)
117			key_mgmt='WPA-PSK'
118			# if you want to use PSK with a non-nl80211 driver you
119			# have to use WPA-NONE and wext driver for wpa_s
120			[ "$mode" = "adhoc" -a "$driver" != "nl80211" ] && {
121				key_mgmt='WPA-NONE'
122				driver='wext'
123			}
124			if [ ${#key} -eq 64 ]; then
125				passphrase="psk=${key}"
126			else
127				passphrase="psk=\"${key}\""
128			fi
129
130			[ -n "$crypto" ] || crypto="CCMP"
131			pairwise="pairwise=$crypto"
132
133			case "$enc" in
134				*mixed*)
135					proto='proto=RSN WPA'
136				;;
137				*psk2*)
138					proto='proto=RSN'
139					config_get ieee80211w "$vif" ieee80211w
140				;;
141				*psk*)
142					proto='proto=WPA'
143				;;
144			esac
145		;;
146		*wpa*|*8021x*)
147			proto='proto=WPA2'
148			key_mgmt='WPA-EAP'
149			config_get ieee80211w "$vif" ieee80211w
150			config_get ca_cert "$vif" ca_cert
151			config_get eap_type "$vif" eap_type
152			ca_cert=${ca_cert:+"ca_cert=\"$ca_cert\""}
153
154			[ -n "$crypto" ] || crypto="CCMP"
155			pairwise="pairwise=$crypto"
156
157			case "$eap_type" in
158				tls)
159					config_get identity "$vif" identity
160					config_get client_cert "$vif" client_cert
161					config_get priv_key "$vif" priv_key
162					config_get priv_key_pwd "$vif" priv_key_pwd
163					identity="identity=\"$identity\""
164					client_cert="client_cert=\"$client_cert\""
165					priv_key="private_key=\"$priv_key\""
166					priv_key_pwd="private_key_passwd=\"$priv_key_pwd\""
167				;;
168				peap|ttls)
169					config_get auth "$vif" auth
170					config_get identity "$vif" identity
171					config_get password "$vif" password
172					phase2="phase2=\"auth=${auth:-MSCHAPV2}\""
173					identity="identity=\"$identity\""
174					password="password=\"$password\""
175				;;
176			esac
177			eap_type="eap=$(echo $eap_type | tr 'a-z' 'A-Z')"
178		;;
179	esac
180
181	keymgmt='NONE'
182
183	# Allow SHA256
184	case "$enc" in
185		*wpa*|*8021x*) keymgmt=EAP;;
186		*psk*) keymgmt=PSK;;
187	esac
188
189	case "$ieee80211w" in
190		0)
191			key_mgmt="WPA-${keymgmt}"
192		;;
193		1)
194			key_mgmt="WPA-${keymgmt} WPA-${keymgmt}-SHA256"
195		;;
196		2)
197			key_mgmt="WPA-${keymgmt}-SHA256"
198		;;
199	esac
200
201	[ -n "$ieee80211w" ] && ieee80211w="ieee80211w=$ieee80211w"
202	case "$pairwise" in
203		*CCMP-256*) group="group=CCMP-256 GCMP-256 GCMP CCMP TKIP";;
204		*GCMP-256*) group="group=GCMP-256 GCMP CCMP TKIP";;
205		*GCMP*) group="group=GCMP CCMP TKIP";;
206		*CCMP*) group="group=CCMP TKIP";;
207		*TKIP*) group="group=TKIP";;
208	esac
209
210	config_get ifname "$vif" ifname
211	config_get bridge "$vif" bridge
212	config_get ssid "$vif" ssid
213	config_get bssid "$vif" bssid
214	bssid=${bssid:+"bssid=$bssid"}
215
216	config_get_bool wps_pbc "$vif" wps_pbc 0
217
218	config_get config_methods "$vif" wps_config
219	[ "$wps_pbc" -gt 0 ] && append config_methods push_button
220
221	[ -n "$config_methods" ] && {
222		wps_cred="wps_cred_processing=2"
223		wps_config_methods="config_methods=$config_methods"
224		update_config="update_config=1"
225		# fix the overlap session of WPS PBC for two STA vifs
226		macaddr=$(cat /sys/class/net/${bridge}/address)
227		uuid=$(echo "$macaddr" | sed 's/://g')
228		[ -n "$uuid" ] && {
229			uuid_config="uuid=87654321-9abc-def0-1234-$uuid"
230		}
231	}
232
233	local ctrl_interface wait_for_wrap=""
234
235	if [ $qwrap_enable -ne 0 ]; then
236		ctrl_interface="/var/run/wpa_supplicant"
237		echo -e "/var/run/wpa_supplicant-$ifname.conf \c\h" >> /tmp/qwrap_conf_filename
238		wait_for_wrap="-W"
239	fi
240
241	ctrl_interface="/var/run/wpa_supplicant-$ifname"
242
243	rm -rf $ctrl_interface
244	cat > /var/run/wpa_supplicant-$ifname.conf <<EOF
245ctrl_interface=$ctrl_interface
246$wps_config_methods
247$wps_cred
248$update_config
249$uuid_config
250network={
251	$modestr
252	scan_ssid=1
253	ssid="$ssid"
254	$bssid
255	key_mgmt=$key_mgmt
256	$proto
257	$freq
258	$ieee80211w
259	$passphrase
260	$pairwise
261	$group
262	$eap_type
263	$ca_cert
264	$client_cert
265	$priv_key
266	$priv_key_pwd
267	$phase2
268	$identity
269	$password
270	$wep_key0
271	$wep_key1
272	$wep_key2
273	$wep_key3
274	$wep_tx_keyidx
275	$wep_auth_alg
276}
277EOF
278	[ -z "$proto" -a "$key_mgmt" != "NONE" ] || \
279		wpa_supplicant ${bridge:+ -b $bridge} -B $wait_for_wrap -P "/var/run/wifi-${ifname}.pid" -D ${driver:-wext} -i "$ifname" -c /var/run/wpa_supplicant-$ifname.conf $options
280}
281