Skip to content
Snippets Groups Projects
hostapd.sh 15.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
    . /lib/functions/network.sh
    
    hostapd_add_rate() {
    	local var="$1"
    	local val="$(($2 / 100))"
    	append $var "$val" " "
    }
    
    hostapd_append_wep_key() {
    	local var="$1"
    
    	wep_keyidx=0
    	set_default key 1
    	case "$key" in
    		[1234])
    			for idx in 1 2 3 4; do
    				local zidx
    				zidx=$(($idx - 1))
    				json_get_var ckey "key${idx}"
    				[ -n "$ckey" ] && \
    					append $var "wep_key${zidx}=$(prepare_key_wep "$ckey")" "$N$T"
    			done
    			wep_keyidx=$((key - 1))
    		;;
    		*)
    			append $var "wep_key0=$(prepare_key_wep "$key")" "$N$T"
    		;;
    	esac
    }
    
    hostapd_append_wpa_key_mgmt() {
    	local auth_type="$(echo $auth_type | tr 'a-z' 'A-Z')"
    
    	append wpa_key_mgmt "WPA-$auth_type"
    	[ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-${auth_type}"
    	[ "${ieee80211w:-0}" -gt 0 ] && append wpa_key_mgmt "WPA-${auth_type}-SHA256"
    }
    
    hostapd_add_log_config() {
    	config_add_boolean \
    		log_80211 \
    		log_8021x \
    		log_radius \
    		log_wpa \
    		log_driver \
    		log_iapp \
    		log_mlme
    
    	config_add_int log_level
    }
    
    hostapd_common_add_device_config() {
    	config_add_array basic_rate
    	config_add_array supported_rates
    
    	config_add_string country
    	config_add_boolean country_ie doth
    	config_add_string require_mode
    	config_add_boolean legacy_rates
    
    	config_add_string acs_chan_bias
    	config_add_array hostapd_options
    
    	hostapd_add_log_config
    }
    
    hostapd_prepare_device_config() {
    	local config="$1"
    	local driver="$2"
    
    	local base="${config%%.conf}"
    	local base_cfg=
    
    	json_get_vars country country_ie beacon_int:100 doth require_mode legacy_rates acs_chan_bias
    
    	hostapd_set_log_options base_cfg
    
    	set_default country_ie 1
    	set_default doth 1
    	set_default legacy_rates 1
    
    	[ "$hwmode" = "b" ] && legacy_rates=1
    
    	[ -n "$country" ] && {
    		append base_cfg "country_code=$country" "$N"
    
    		[ "$country_ie" -gt 0 ] && append base_cfg "ieee80211d=1" "$N"
    		[ "$hwmode" = "a" -a "$doth" -gt 0 ] && append base_cfg "ieee80211h=1" "$N"
    	}
    
    	[ -n "$acs_chan_bias" ] && append base_cfg "acs_chan_bias=$acs_chan_bias" "$N"
    
    	local brlist= br
    	json_get_values basic_rate_list basic_rate
    	local rlist= r
    	json_get_values rate_list supported_rates
    
    	[ -n "$hwmode" ] && append base_cfg "hw_mode=$hwmode" "$N"
    	[ "$legacy_rates" -eq 0 ] && set_default require_mode g
    
    	[ "$hwmode" = "g" ] && {
    		[ "$legacy_rates" -eq 0 ] && set_default rate_list "6000 9000 12000 18000 24000 36000 48000 54000"
    		[ -n "$require_mode" ] && set_default basic_rate_list "6000 12000 24000"
    	}
    
    	case "$require_mode" in
    		n) append base_cfg "require_ht=1" "$N";;
    		ac) append base_cfg "require_vht=1" "$N";;
    	esac
    
    	for r in $rate_list; do
    		hostapd_add_rate rlist "$r"
    	done
    
    	for br in $basic_rate_list; do
    		hostapd_add_rate brlist "$br"
    	done
    
    	[ -n "$rlist" ] && append base_cfg "supported_rates=$rlist" "$N"
    	[ -n "$brlist" ] && append base_cfg "basic_rates=$brlist" "$N"
    	append base_cfg "beacon_int=$beacon_int" "$N"
    
    	json_get_values opts hostapd_options
    	for val in $opts; do
    		append base_cfg "$val" "$N"
    	done
    
    	cat > "$config" <<EOF
    driver=$driver
    $base_cfg
    EOF
    }
    
    hostapd_common_add_bss_config() {
    	config_add_string 'bssid:macaddr' 'ssid:string'
    	config_add_boolean wds wmm uapsd hidden
    
    	config_add_int maxassoc max_inactivity
    	config_add_boolean disassoc_low_ack isolate short_preamble
    
    	config_add_int \
    		wep_rekey eap_reauth_period \
    		wpa_group_rekey wpa_pair_rekey wpa_master_rekey
    	config_add_boolean wpa_disable_eapol_key_retries
    
    	config_add_boolean rsn_preauth auth_cache
    	config_add_int ieee80211w
    	config_add_int eapol_version
    
    	config_add_string 'auth_server:host' 'server:host'
    	config_add_string auth_secret
    	config_add_int 'auth_port:port' 'port:port'
    
    	config_add_string acct_server
    	config_add_string acct_secret
    	config_add_int acct_port
    	config_add_int acct_interval
    
    	config_add_string dae_client
    	config_add_string dae_secret
    	config_add_int dae_port
    
    	config_add_string nasid
    	config_add_string ownip
    	config_add_string iapp_interface
    	config_add_string eap_type ca_cert client_cert identity anonymous_identity auth priv_key priv_key_pwd
    
    	config_add_int dynamic_vlan vlan_naming
    	config_add_string vlan_tagged_interface vlan_bridge
    	config_add_string vlan_file
    
    	config_add_string 'key1:wepkey' 'key2:wepkey' 'key3:wepkey' 'key4:wepkey' 'password:wpakey'
    
    	config_add_string wpa_psk_file
    
    	config_add_boolean wps_pushbutton wps_label ext_registrar wps_pbc_in_m1
    	config_add_int wps_ap_setup_locked wps_independent
    	config_add_string wps_device_type wps_device_name wps_manufacturer wps_pin
    
    	config_add_boolean ieee80211r pmk_r1_push ft_psk_generate_local ft_over_ds
    	config_add_int r0_key_lifetime reassociation_deadline
    	config_add_string mobility_domain r1_key_holder
    	config_add_array r0kh r1kh
    
    	config_add_int ieee80211w_max_timeout ieee80211w_retry_timeout
    
    	config_add_string macfilter 'macfile:file'
    	config_add_array 'maclist:list(macaddr)'
    
    	config_add_array bssid_blacklist
    	config_add_array bssid_whitelist
    
    	config_add_int mcast_rate
    	config_add_array basic_rate
    	config_add_array supported_rates
    }
    
    hostapd_set_bss_options() {
    	local var="$1"
    	local phy="$2"
    	local vif="$3"
    
    	wireless_vif_parse_encryption
    
    	local bss_conf
    	local wep_rekey wpa_group_rekey wpa_pair_rekey wpa_master_rekey wpa_key_mgmt
    
    	json_get_vars \
    		wep_rekey wpa_group_rekey wpa_pair_rekey wpa_master_rekey \
    		wpa_disable_eapol_key_retries \
    		maxassoc max_inactivity disassoc_low_ack isolate auth_cache \
    		wps_pushbutton wps_label ext_registrar wps_pbc_in_m1 wps_ap_setup_locked \
    		wps_independent wps_device_type wps_device_name wps_manufacturer wps_pin \
    		macfilter ssid wmm uapsd hidden short_preamble rsn_preauth \
    		iapp_interface eapol_version dynamic_vlan ieee80211w nasid \
    		acct_server acct_secret acct_port acct_interval
    
    	set_default isolate 0
    	set_default maxassoc 0
    	set_default max_inactivity 0
    	set_default short_preamble 1
    	set_default disassoc_low_ack 1
    	set_default hidden 0
    	set_default wmm 1
    	set_default uapsd 1
    	set_default wpa_disable_eapol_key_retries 0
    	set_default eapol_version 0
    	set_default acct_port 1813
    
    	append bss_conf "ctrl_interface=/var/run/hostapd"
    	if [ "$isolate" -gt 0 ]; then
    		append bss_conf "ap_isolate=$isolate" "$N"
    	fi
    	if [ "$maxassoc" -gt 0 ]; then
    		append bss_conf "max_num_sta=$maxassoc" "$N"
    	fi
    	if [ "$max_inactivity" -gt 0 ]; then
    		append bss_conf "ap_max_inactivity=$max_inactivity" "$N"
    	fi
    
    	append bss_conf "disassoc_low_ack=$disassoc_low_ack" "$N"
    	append bss_conf "preamble=$short_preamble" "$N"
    	append bss_conf "wmm_enabled=$wmm" "$N"
    	append bss_conf "ignore_broadcast_ssid=$hidden" "$N"
    	append bss_conf "uapsd_advertisement_enabled=$uapsd" "$N"
    
    	[ "$wpa" -gt 0 ] && {
    		[ -n "$wpa_group_rekey"  ] && append bss_conf "wpa_group_rekey=$wpa_group_rekey" "$N"
    		[ -n "$wpa_pair_rekey"   ] && append bss_conf "wpa_ptk_rekey=$wpa_pair_rekey"    "$N"
    		[ -n "$wpa_master_rekey" ] && append bss_conf "wpa_gmk_rekey=$wpa_master_rekey"  "$N"
    	}
    
    	[ -n "$nasid" ] && append bss_conf "nas_identifier=$nasid" "$N"
    	[ -n "$acct_server" ] && {
    		append bss_conf "acct_server_addr=$acct_server" "$N"
    		append bss_conf "acct_server_port=$acct_port" "$N"
    		[ -n "$acct_secret" ] && \
    			append bss_conf "acct_server_shared_secret=$acct_secret" "$N"
    		[ -n "$acct_interval" ] && \
    			append bss_conf "radius_acct_interim_interval=$acct_interval" "$N"
    	}
    
    	local vlan_possible=""
    
    	case "$auth_type" in
    		none)
    			wps_possible=1
    			# Here we make the assumption that if we're in open mode
    			# with WPS enabled, we got to be in unconfigured state.
    			wps_not_configured=1
    		;;
    		psk)
    			json_get_vars key wpa_psk_file
    			if [ ${#key} -lt 8 ]; then
    				wireless_setup_vif_failed INVALID_WPA_PSK
    				return 1
    			elif [ ${#key} -eq 64 ]; then
    				append bss_conf "wpa_psk=$key" "$N"
    			else
    				append bss_conf "wpa_passphrase=$key" "$N"
    			fi
    			[ -n "$wpa_psk_file" ] && {
    				[ -e "$wpa_psk_file" ] || touch "$wpa_psk_file"
    				append bss_conf "wpa_psk_file=$wpa_psk_file" "$N"
    			}
    			[ "$eapol_version" -ge "1" -a "$eapol_version" -le "2" ] && append bss_conf "eapol_version=$eapol_version" "$N"
    
    			wps_possible=1
    		;;
    		eap)
    			json_get_vars \
    				auth_server auth_secret auth_port \
    				dae_client dae_secret dae_port \
    				ownip \
    				eap_reauth_period
    
    			# radius can provide VLAN ID for clients
    			vlan_possible=1
    
    			# legacy compatibility
    			[ -n "$auth_server" ] || json_get_var auth_server server
    			[ -n "$auth_port" ] || json_get_var auth_port port
    			[ -n "$auth_secret" ] || json_get_var auth_secret key
    
    			set_default auth_port 1812
    			set_default dae_port 3799
    
    
    			append bss_conf "auth_server_addr=$auth_server" "$N"
    			append bss_conf "auth_server_port=$auth_port" "$N"
    			append bss_conf "auth_server_shared_secret=$auth_secret" "$N"
    
    			[ -n "$eap_reauth_period" ] && append bss_conf "eap_reauth_period=$eap_reauth_period" "$N"
    
    			[ -n "$dae_client" -a -n "$dae_secret" ] && {
    				append bss_conf "radius_das_port=$dae_port" "$N"
    				append bss_conf "radius_das_client=$dae_client $dae_secret" "$N"
    			}
    
    			[ -n "$ownip" ] && append bss_conf "own_ip_addr=$ownip" "$N"
    			append bss_conf "eapol_key_index_workaround=1" "$N"
    			append bss_conf "ieee8021x=1" "$N"
    
    			[ "$eapol_version" -ge "1" -a "$eapol_version" -le "2" ] && append bss_conf "eapol_version=$eapol_version" "$N"
    		;;
    		wep)
    			local wep_keyidx=0
    			json_get_vars key
    			hostapd_append_wep_key bss_conf
    			append bss_conf "wep_default_key=$wep_keyidx" "$N"
    			[ -n "$wep_rekey" ] && append bss_conf "wep_rekey_period=$wep_rekey" "$N"
    		;;
    	esac
    
    	local auth_algs=$((($auth_mode_shared << 1) | $auth_mode_open))
    	append bss_conf "auth_algs=${auth_algs:-1}" "$N"
    	append bss_conf "wpa=$wpa" "$N"
    	[ -n "$wpa_pairwise" ] && append bss_conf "wpa_pairwise=$wpa_pairwise" "$N"
    
    	set_default wps_pushbutton 0
    	set_default wps_label 0
    	set_default wps_pbc_in_m1 0
    
    	config_methods=
    	[ "$wps_pushbutton" -gt 0 ] && append config_methods push_button
    	[ "$wps_label" -gt 0 ] && append config_methods label
    
    	[ -n "$wps_possible" -a -n "$config_methods" ] && {
    		set_default ext_registrar 0
    		set_default wps_device_type "6-0050F204-1"
    		set_default wps_device_name "Lede AP"
    		set_default wps_manufacturer "www.lede-project.org"
    		set_default wps_independent 1
    
    		wps_state=2
    		[ -n "$wps_configured" ] && wps_state=1
    
    		[ "$ext_registrar" -gt 0 -a -n "$network_bridge" ] && append bss_conf "upnp_iface=$network_bridge" "$N"
    
    		append bss_conf "eap_server=1" "$N"
    		[ -n "$wps_pin" ] && append bss_conf "ap_pin=$wps_pin" "$N"
    		append bss_conf "wps_state=$wps_state" "$N"
    		append bss_conf "device_type=$wps_device_type" "$N"
    		append bss_conf "device_name=$wps_device_name" "$N"
    		append bss_conf "manufacturer=$wps_manufacturer" "$N"
    		append bss_conf "config_methods=$config_methods" "$N"
    		append bss_conf "wps_independent=$wps_independent" "$N"
    		[ -n "$wps_ap_setup_locked" ] && append bss_conf "ap_setup_locked=$wps_ap_setup_locked" "$N"
    		[ "$wps_pbc_in_m1" -gt 0 ] && append bss_conf "pbc_in_m1=$wps_pbc_in_m1" "$N"
    	}
    
    	append bss_conf "ssid=$ssid" "$N"
    	[ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge" "$N"
    	[ -n "$iapp_interface" ] && {
    		local ifname
    		network_get_device ifname "$iapp_interface" || ifname="$iapp_interface"
    		append bss_conf "iapp_interface=$ifname" "$N"
    	}
    
    	if [ "$wpa" -ge "1" ]; then
    		json_get_vars ieee80211r
    		set_default ieee80211r 0
    
    		if [ "$ieee80211r" -gt "0" ]; then
    			json_get_vars mobility_domain r0_key_lifetime r1_key_holder \
    				reassociation_deadline pmk_r1_push ft_psk_generate_local ft_over_ds
    			json_get_values r0kh r0kh
    			json_get_values r1kh r1kh
    
    			set_default mobility_domain "4f57"
    			set_default r0_key_lifetime 10000
    			set_default reassociation_deadline 1000
    			set_default pmk_r1_push 0
    			set_default ft_psk_generate_local 0
    			set_default ft_over_ds 1
    
    			append bss_conf "mobility_domain=$mobility_domain" "$N"
    			append bss_conf "r0_key_lifetime=$r0_key_lifetime" "$N"
    			[ -n "$r1_key_holder" ] && append bss_conf "r1_key_holder=$r1_key_holder" "$N"
    			append bss_conf "reassociation_deadline=$reassociation_deadline" "$N"
    			append bss_conf "pmk_r1_push=$pmk_r1_push" "$N"
    			append bss_conf "ft_psk_generate_local=$ft_psk_generate_local" "$N"
    			append bss_conf "ft_over_ds=$ft_over_ds" "$N"
    
    			for kh in $r0kh; do
    				append bss_conf "r0kh=${kh//,/ }" "$N"
    			done
    			for kh in $r1kh; do
    				append bss_conf "r1kh=${kh//,/ }" "$N"
    			done
    		fi
    
    		append bss_conf "wpa_disable_eapol_key_retries=$wpa_disable_eapol_key_retries" "$N"
    
    		hostapd_append_wpa_key_mgmt
    		[ -n "$wpa_key_mgmt" ] && append bss_conf "wpa_key_mgmt=$wpa_key_mgmt" "$N"
    	fi
    
    	if [ "$wpa" -ge "2" ]; then
    		if [ -n "$network_bridge" -a "$rsn_preauth" = 1 ]; then
    			set_default auth_cache 1
    			append bss_conf "rsn_preauth=1" "$N"
    			append bss_conf "rsn_preauth_interfaces=$network_bridge" "$N"
    		else
    			set_default auth_cache 0
    		fi
    
    		append bss_conf "okc=$auth_cache" "$N"
    		[ "$auth_cache" = 0 ] && append bss_conf "disable_pmksa_caching=1" "$N"
    
    		# RSN -> allow management frame protection
    		case "$ieee80211w" in
    			[012])
    				json_get_vars ieee80211w_max_timeout ieee80211w_retry_timeout
    				append bss_conf "ieee80211w=$ieee80211w" "$N"
    				[ "$ieee80211w" -gt "0" ] && {
    					[ -n "$ieee80211w_max_timeout" ] && \
    						append bss_conf "assoc_sa_query_max_timeout=$ieee80211w_max_timeout" "$N"
    					[ -n "$ieee80211w_retry_timeout" ] && \
    						append bss_conf "assoc_sa_query_retry_timeout=$ieee80211w_retry_timeout" "$N"
    				}
    			;;
    		esac
    	fi
    
    	_macfile="/var/run/hostapd-$ifname.maclist"
    	case "$macfilter" in
    		allow)
    			append bss_conf "macaddr_acl=1" "$N"
    			append bss_conf "accept_mac_file=$_macfile" "$N"
    			# accept_mac_file can be used to set MAC to VLAN ID mapping
    			vlan_possible=1
    		;;
    		deny)
    			append bss_conf "macaddr_acl=0" "$N"
    			append bss_conf "deny_mac_file=$_macfile" "$N"
    		;;
    		*)
    			_macfile=""
    		;;
    	esac
    
    	[ -n "$_macfile" ] && {
    		json_get_vars macfile
    		json_get_values maclist maclist
    
    		rm -f "$_macfile"
    		(
    			for mac in $maclist; do
    				echo "$mac"
    			done
    			[ -n "$macfile" -a -f "$macfile" ] && cat "$macfile"
    		) > "$_macfile"
    	}
    
    	[ -n "$vlan_possible" -a -n "$dynamic_vlan" ] && {
    		json_get_vars vlan_naming vlan_tagged_interface vlan_bridge vlan_file
    		set_default vlan_naming 1
    		append bss_conf "dynamic_vlan=$dynamic_vlan" "$N"
    		append bss_conf "vlan_naming=$vlan_naming" "$N"
    		[ -n "$vlan_bridge" ] && \
    			append bss_conf "vlan_bridge=$vlan_bridge" "$N"
    		[ -n "$vlan_tagged_interface" ] && \
    			append bss_conf "vlan_tagged_interface=$vlan_tagged_interface" "$N"
    		[ -n "$vlan_file" ] && {
    			[ -e "$vlan_file" ] || touch "$vlan_file"
    			append bss_conf "vlan_file=$vlan_file" "$N"
    		}
    	}
    
    	append "$var" "$bss_conf" "$N"
    	return 0
    }
    
    hostapd_set_log_options() {
    	local var="$1"
    
    	local log_level log_80211 log_8021x log_radius log_wpa log_driver log_iapp log_mlme
    	json_get_vars log_level log_80211 log_8021x log_radius log_wpa log_driver log_iapp log_mlme
    
    	set_default log_level 2
    	set_default log_80211  1
    	set_default log_8021x  1
    	set_default log_radius 1
    	set_default log_wpa    1
    	set_default log_driver 1
    	set_default log_iapp   1
    	set_default log_mlme   1
    
    	local log_mask=$(( \
    		($log_80211  << 0) | \
    		($log_8021x  << 1) | \
    		($log_radius << 2) | \
    		($log_wpa    << 3) | \
    		($log_driver << 4) | \
    		($log_iapp   << 5) | \
    		($log_mlme   << 6)   \
    	))
    
    	append "$var" "logger_syslog=$log_mask" "$N"
    	append "$var" "logger_syslog_level=$log_level" "$N"
    	append "$var" "logger_stdout=$log_mask" "$N"
    	append "$var" "logger_stdout_level=$log_level" "$N"
    
    	return 0
    }
    
    hostapd_common_cleanup() {
    	killall hostapd
    }