slitaz-boot-scripts diff etc/init.d/network.sh @ rev 393

network.sh: better handle WEP connections, handle EAP, store Wi-Fi neworks by default; network.conf: migrate to extended format to support EAP arguments, and few more.
author Aleksej Bobylev <al.bobylev@gmail.com>
date Mon Mar 23 02:01:21 2015 +0200 (2015-03-23)
parents aea6cf6b8a5b
children 7acd64a8f538
line diff
     1.1 --- a/etc/init.d/network.sh	Fri May 02 13:40:34 2014 +0200
     1.2 +++ b/etc/init.d/network.sh	Mon Mar 23 02:01:21 2015 +0200
     1.3 @@ -1,24 +1,33 @@
     1.4  #!/bin/sh
     1.5  #
     1.6  # /etc/init.d/network.sh : Network initialization boot script
     1.7 -# Configuration file     : /etc/network.conf
     1.8 -#
     1.9 +# /etc/network.conf      : Main SliTaz network configuration file
    1.10 +# /etc/wpa/wpa.conf      : Wi-Fi networks configuration file
    1.11 +
    1.12  . /etc/init.d/rc.functions
    1.13  
    1.14 -if [ -z "$2" ]; then
    1.15 -	. /etc/network.conf
    1.16 -else
    1.17 -	. $2
    1.18 -fi
    1.19 +CONF="${2:-/etc/network.conf}"
    1.20 +echo "Loading network settings from $CONF"
    1.21 +. "$CONF"
    1.22 +
    1.23 +WPA_CONF='/etc/wpa/wpa.conf'
    1.24 +
    1.25 +
    1.26 +# Migrate existing settings to a new format file
    1.27 +
    1.28 +. /usr/share/slitaz/network.conf_migration
    1.29 +
    1.30 +
    1.31 +# Actions executing on boot time (running network.sh without parameters)
    1.32  
    1.33  boot() {
    1.34 -	# Set hostname.
    1.35 +	# Set hostname
    1.36  	echo -n "Setting hostname to: $(cat /etc/hostname)"
    1.37  	/bin/hostname -F /etc/hostname
    1.38  	status
    1.39  
    1.40 -	# Configure loopback interface.
    1.41 -	echo -n "Configuring loopback..."
    1.42 +	# Configure loopback interface
    1.43 +	echo -n 'Configuring loopback...'
    1.44  	/sbin/ifconfig lo 127.0.0.1 up
    1.45  	/sbin/route add -net 127.0.0.0 netmask 255.0.0.0 dev lo
    1.46  	status
    1.47 @@ -26,225 +35,288 @@
    1.48  	[ -s /etc/sysctl.conf ] && sysctl -p /etc/sysctl.conf
    1.49  }
    1.50  
    1.51 +
    1.52  # Use ethernet
    1.53 +
    1.54  eth() {
    1.55 -	ifconfig $INTERFACE up
    1.56 +	[ "$WIFI" != 'yes' ] && ifconfig $INTERFACE up
    1.57  }
    1.58  
    1.59 -# For wifi. Users just have to enable it through yes and usually
    1.60 -# essid any will work and the interface is autodetected.
    1.61 +
    1.62 +# Start wpa_supplicant with prepared settings in wpa.conf
    1.63 +
    1.64 +start_wpa_supplicant() {
    1.65 +	echo "Starting wpa_supplicant for $1..."
    1.66 +	wpa_supplicant -B -W -c$WPA_CONF -D$WIFI_WPA_DRIVER -i$WIFI_INTERFACE
    1.67 +}
    1.68 +
    1.69 +
    1.70 +# Reconnect to the given network
    1.71 +
    1.72 +reconnect_wifi_network() {
    1.73 +	if [ "$WIFI" == 'yes' ]; then
    1.74 +		# Wpa_supplicant will auto-connect to the first network
    1.75 +		# notwithstanding to priority when scan_ssid=1
    1.76 +		current_ssid="$(wpa_cli list_networks 2>/dev/null | fgrep '[CURRENT]' | cut -f2)"
    1.77 +		if [ "$current_ssid" != "$WIFI_ESSID" ]; then
    1.78 +			echo "Connecting to $WIFI_ESSID..."
    1.79 +			for i in $(seq 20); do
    1.80 +				index=$(wpa_cli list_networks 2>/dev/null | \
    1.81 +					grep -m1 -F $'\t'$WIFI_ESSID$'\t' | head -n1 | cut -f1)
    1.82 +				[ -z "$index" ] && echo -n '.' && sleep 1
    1.83 +			done
    1.84 +			wpa_cli select_network $index >/dev/null; status
    1.85 +		fi
    1.86 +	fi
    1.87 +}
    1.88 +
    1.89 +
    1.90 +# For Wi-Fi. Users just have to enable it through WIFI="yes" and usually
    1.91 +# ESSID="any" will work and the interface is autodetected.
    1.92 +
    1.93  wifi() {
    1.94 -	if [ "$WIFI" == "yes" ]; then
    1.95 +	if [ "$WIFI" == 'yes' ]; then
    1.96  		ifconfig $INTERFACE down
    1.97  
    1.98 -		# Confirm if $WIFI_INTERFACE is the wifi interface
    1.99 +		# Confirm if $WIFI_INTERFACE is the Wi-Fi interface
   1.100  		if [ ! -d /sys/class/net/$WIFI_INTERFACE/wireless ]; then
   1.101 -			echo "$WIFI_INTERFACE is not a wifi interface, changing it."
   1.102 -			WIFI_INTERFACE=$(fgrep : /proc/net/dev | cut -d: -f1 | \
   1.103 -				while read dev; do iwconfig $dev 2>&1 | \
   1.104 -					fgrep -iq "essid" && { echo $dev ; break; }; \
   1.105 -				done)
   1.106 +			echo "$WIFI_INTERFACE is not a Wi-Fi interface, changing it."
   1.107 +			WIFI_INTERFACE=$(iwconfig 2>/dev/null | awk 'NR==1{print $1}')
   1.108  			[ -n "$WIFI_INTERFACE" ] && sed -i \
   1.109 -				"s/^WIFI_INTERFACE=.*/WIFI_INTERFACE=\"$WIFI_INTERFACE\"/" \
   1.110 +				"s|^WIFI_INTERFACE=.*|WIFI_INTERFACE=\"$WIFI_INTERFACE\"|" \
   1.111  				/etc/network.conf
   1.112  		fi
   1.113  
   1.114 -		echo -n "Configuring $WIFI_INTERFACE..."
   1.115 +		echo -n "Configuring Wi-Fi interface $WIFI_INTERFACE..."
   1.116  		ifconfig $WIFI_INTERFACE up 2>/dev/null
   1.117 -		if iwconfig $WIFI_INTERFACE | fgrep -q "Tx-Power"; then
   1.118 +		if iwconfig $WIFI_INTERFACE | fgrep -q 'Tx-Power'; then
   1.119  			iwconfig $WIFI_INTERFACE txpower on
   1.120  		fi
   1.121  		status
   1.122  
   1.123 -		IWCONFIG_ARGS=""
   1.124 -		[ -n "$WPA_DRIVER" ] || WPA_DRIVER="wext"
   1.125 -		[ -n "$WIFI_MODE" ] && IWCONFIG_ARGS="$IWCONFIG_ARGS mode $WIFI_MODE"
   1.126 +		IWCONFIG_ARGS=''
   1.127 +		[ -n "$WIFI_WPA_DRIVER" ] || WIFI_WPA_DRIVER='wext'
   1.128 +		[ -n "$WIFI_MODE" ]    && IWCONFIG_ARGS="$IWCONFIG_ARGS mode $WIFI_MODE"
   1.129  		[ -n "$WIFI_CHANNEL" ] && IWCONFIG_ARGS="$IWCONFIG_ARGS channel $WIFI_CHANNEL"
   1.130 -		[ -n "$WIFI_AP" ] && IWCONFIG_ARGS="$IWCONFIG_ARGS ap $WIFI_AP"
   1.131 -		
   1.132 -		# Unencrypted network
   1.133 -		if [ "$WIFI_KEY" == "" -o "$WIFI_KEY_TYPE" == "" ]; then
   1.134 -			iwconfig $WIFI_INTERFACE essid "$WIFI_ESSID" $IWCONFIG_ARGS
   1.135 +		[ -n "$WIFI_AP" ]      && IWCONFIG_ARGS="$IWCONFIG_ARGS ap $WIFI_AP"
   1.136 +
   1.137 +		# Clean all / add / change stored networks settings
   1.138 +		if [ "$WIFI_BLANK_NETWORKS" == 'yes' ]; then
   1.139 +			echo "Creating new $WPA_CONF"
   1.140 +			cat /etc/wpa/wpa_empty.conf > $WPA_CONF
   1.141 +		else
   1.142 +			if fgrep -q ssid=\"$WIFI_ESSID\" $WPA_CONF; then
   1.143 +				echo "Change network settings in $WPA_CONF"
   1.144 +				# Remove given existing network (it to be appended later)
   1.145 +				mv -f $WPA_CONF $WPA_CONF.old
   1.146 +				cat $WPA_CONF.old | tr '\n' '\a' | sed 's|[^#]\(network={\)|\n\1|g' | \
   1.147 +				fgrep -v "ssid=\"$WIFI_ESSID\"" | tr '\a' '\n' > $WPA_CONF
   1.148 +			else
   1.149 +				echo "Append existing $WPA_CONF"
   1.150 +			fi
   1.151  		fi
   1.152 -		
   1.153 -		# Encrypted network
   1.154 -		[ -n "$WIFI_KEY" ] && case "$WIFI_KEY_TYPE" in
   1.155 -			wep|WEP)
   1.156 -				# wpa_supplicant can also deal with wep encryption
   1.157 -				# Tip: Use unquoted strings for hexadecimal key in wep_key0
   1.158 -				echo "Creating: /etc/wpa/wpa.conf"
   1.159 -				cat /etc/wpa/wpa_empty.conf > /etc/wpa/wpa.conf
   1.160 -				cat >> /etc/wpa/wpa.conf << EOT
   1.161 +
   1.162 +		# Each new network has a higher priority than the existing
   1.163 +		MAX_PRIORITY=$(sed -n 's|[\t ]*priority=\([0-9]*\)|\1|p' $WPA_CONF | sort -g | tail -n1)
   1.164 +		PRIORITY=$(( ${MAX_PRIORITY:-0} + 1 ))
   1.165 +
   1.166 +		# Begin network description
   1.167 +		cat >> $WPA_CONF <<EOT
   1.168  network={
   1.169  	ssid="$WIFI_ESSID"
   1.170 +EOT
   1.171 +
   1.172 +		# For networks with hidden SSID: write its BSSID and allow probe requests
   1.173 +		[ -n "$WIFI_BSSID" ] && cat >> $WPA_CONF <<EOT
   1.174 +	bssid=$WIFI_BSSID
   1.175  	scan_ssid=1
   1.176 +EOT
   1.177 +
   1.178 +		case x$(echo -n $WIFI_KEY_TYPE | tr a-z A-Z) in
   1.179 +			x|xNONE) # Open network
   1.180 +				cat >> $WPA_CONF <<EOT
   1.181  	key_mgmt=NONE
   1.182 -	wep_key0=$WIFI_KEY
   1.183 -	wep_tx_keyidx=0
   1.184 -	priority=5
   1.185 +	priority=$PRIORITY
   1.186  }
   1.187  EOT
   1.188 -				echo "Starting wpa_supplicant for NONE/WEP..."
   1.189 -				wpa_supplicant -B -W -c/etc/wpa/wpa.conf -D$WPA_DRIVER \
   1.190 -					-i$WIFI_INTERFACE ;;
   1.191 -			
   1.192 -			wpa|WPA)
   1.193 -				# load pre-configured multiple profiles
   1.194 -				echo "Creating: /etc/wpa/wpa.conf"
   1.195 -				cat /etc/wpa/wpa_empty.conf > /etc/wpa/wpa.conf
   1.196 -				if [ "$WIFI_IDENTITY" ]; then
   1.197 -					cat >> /etc/wpa/wpa.conf << EOT
   1.198 -network={
   1.199 -	ssid="$WIFI_ESSID"
   1.200 -	key_mgmt=WPA-EAP
   1.201 -	scan_ssid=1
   1.202 -	identity="$WIFI_IDENTITY"
   1.203 -	password="$WIFI_PASSWORD"
   1.204 +				# start_wpa_supplicant NONE
   1.205 +				iwconfig $WIFI_INTERFACE essid "$WIFI_ESSID" $IWCONFIG_ARGS
   1.206 +				;;
   1.207 +
   1.208 +			xWEP) # WEP security
   1.209 +				# Encryption key length:  64 bit  (5 ASCII or 10 HEX)
   1.210 +				# Encryption key length: 128 bit (13 ASCII or 26 HEX)
   1.211 +				# ASCII key in "quotes", HEX key without quotes
   1.212 +				case "${#WIFI_KEY}" in
   1.213 +					10|26) Q=''  ;;
   1.214 +					*)     Q='"' ;;
   1.215 +				esac
   1.216 +				cat >> $WPA_CONF <<EOT
   1.217 +	key_mgmt=NONE
   1.218 +	auth_alg=OPEN SHARED
   1.219 +	wep_key0=$Q$WIFI_KEY$Q
   1.220 +	priority=$PRIORITY
   1.221  }
   1.222  EOT
   1.223 -				else
   1.224 -					cat >> /etc/wpa/wpa.conf << EOT
   1.225 -network={
   1.226 -	ssid="$WIFI_ESSID"
   1.227 -	scan_ssid=1
   1.228 -	proto=WPA RSN
   1.229 -	key_mgmt=WPA-PSK WPA-EAP
   1.230 +				start_wpa_supplicant WEP ;;
   1.231 +
   1.232 +			xWPA) # WPA/WPA2-PSK security
   1.233 +				cat >> $WPA_CONF <<EOT
   1.234  	psk="$WIFI_KEY"
   1.235 -	priority=5
   1.236 +	key_mgmt=WPA-PSK
   1.237 +	priority=$PRIORITY
   1.238  }
   1.239  EOT
   1.240 -				fi
   1.241 -				echo "Starting wpa_supplicant for WPA-PSK..."
   1.242 -				wpa_supplicant -B -W -c/etc/wpa/wpa.conf \
   1.243 -					-D$WPA_DRIVER -i$WIFI_INTERFACE ;;
   1.244 -			
   1.245 -			any|ANY)
   1.246 -				echo "Creating: /etc/wpa/wpa.conf"
   1.247 -				cat /etc/wpa/wpa_empty.conf > /etc/wpa/wpa.conf
   1.248 -				cat >> /etc/wpa/wpa.conf << EOT
   1.249 -network={
   1.250 -	ssid="$WIFI_ESSID"
   1.251 -	scan_ssid=1
   1.252 +				start_wpa_supplicant WPA/WPA2-PSK ;;
   1.253 +
   1.254 +			xEAP) # 802.1x EAP security
   1.255 +				{
   1.256 +					cat <<EOT
   1.257 +	key_mgmt=WPA-EAP IEEE8021X
   1.258 +	eap=$WIFI_EAP_METHOD
   1.259 +EOT
   1.260 +					if [ "$WIFI_EAP_METHOD" == 'PWD' ]; then
   1.261 +						WIFI_PHASE2=''; WIFI_CA_CERT=''; WIFI_USER_CERT=''; WIFI_ANONYMOUS_IDENTITY=''
   1.262 +					fi
   1.263 +					[ -n "$WIFI_CA_CERT" ] && echo -e "\tca_cert=\"$WIFI_CA_CERT\""
   1.264 +					[ -n "$WIFI_CLIENT_CERT" ] && echo -e "\tclient_cert=\"$WIFI_CLIENT_CERT\""
   1.265 +					[ -n "$WIFI_IDENTITY" ] && echo -e "\tidentity=\"$WIFI_IDENTITY\""
   1.266 +					[ -n "$WIFI_ANONYMOUS_IDENTITY" ] && echo -e "\tanonymous_identity=\"$WIFI_ANONYMOUS_IDENTITY\""
   1.267 +					[ -n "$WIFI_KEY" ] && echo -e "\tpassword=\"$WIFI-KEY\""
   1.268 +					[ -n "$WIFI_PHASE2" ] && echo -e "\tphase2=\"auth=$WIFI_PHASE2\""
   1.269 +				} >> $WPA_CONF
   1.270 +				start_wpa_supplicant '802.1x EAP' ;;
   1.271 +
   1.272 +			xANY)
   1.273 +				cat >> $WPA_CONF <<EOT
   1.274  	key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE
   1.275  	group=CCMP TKIP WEP104 WEP40
   1.276  	pairwise=CCMP TKIP
   1.277  	psk="$WIFI_KEY"
   1.278 -	priority=5
   1.279 +	password="$WIFI_KEY"
   1.280 +	priority=$PRIORITY
   1.281  }
   1.282  EOT
   1.283 -				echo "Starting wpa_supplicant for any key type..."
   1.284 -				wpa_supplicant -B -W -c/etc/wpa/wpa.conf \
   1.285 -					-D$WPA_DRIVER -i$WIFI_INTERFACE ;;
   1.286 +				start_wpa_supplicant 'any key type' ;;
   1.287 +
   1.288  		esac
   1.289  		INTERFACE=$WIFI_INTERFACE
   1.290  	fi
   1.291  }
   1.292  
   1.293 +
   1.294  # WPA DHCP script
   1.295 +
   1.296  wpa() {
   1.297  	wpa_cli -a"/etc/init.d/wpa_action.sh" -B
   1.298  }
   1.299  
   1.300 -# For a dynamic IP with DHCP.
   1.301 +
   1.302 +# For a dynamic IP with DHCP
   1.303 +
   1.304  dhcp() {
   1.305 -	if [ "$DHCP" = "yes" ]  ; then
   1.306 +	if [ "$DHCP" == 'yes' ]; then
   1.307  		echo "Starting udhcpc client on: $INTERFACE..."
   1.308 -		# Is wpa wireless && wpa_ctrl_open interface up ?
   1.309 -		if [ -d /var/run/wpa_supplicant ] && [ "$WIFI" = "yes" ]; then
   1.310 +		# Is wpa wireless && wpa_ctrl_open interface up?
   1.311 +		if [ -d /var/run/wpa_supplicant ] && [ "$WIFI" == 'yes' ]; then
   1.312  			wpa
   1.313 -		else # fallback on udhcpc: wep, eth
   1.314 +		else
   1.315 +			# fallback on udhcpc: wep, eth
   1.316  			/sbin/udhcpc -b -T 1 -A 12 -i $INTERFACE -p \
   1.317 -			/var/run/udhcpc.$INTERFACE.pid
   1.318 +				/var/run/udhcpc.$INTERFACE.pid
   1.319  		fi
   1.320  	fi
   1.321  }
   1.322  
   1.323 -# For a static IP.
   1.324 +
   1.325 +# For a static IP
   1.326 +
   1.327  static_ip() {
   1.328 -	if [ "$STATIC" = "yes" ] ; then
   1.329 +	if [ "$STATIC" == 'yes' ]; then
   1.330  		echo "Configuring static IP on $INTERFACE: $IP..."
   1.331  		if [ -n "$BROADCAST" ]; then
   1.332  			/sbin/ifconfig $INTERFACE $IP netmask $NETMASK broadcast $BROADCAST up
   1.333  		else
   1.334  			/sbin/ifconfig $INTERFACE $IP netmask $NETMASK up
   1.335  		fi
   1.336 -		
   1.337 +
   1.338  		# Use ip to set gateways if iproute.conf exists
   1.339  		if [ -f /etc/iproute.conf ]; then
   1.340 -		    while read line
   1.341 -			do
   1.342 +			while read line; do
   1.343  				ip route add $line
   1.344  			done < /etc/iproute.conf
   1.345  		else
   1.346  			/sbin/route add default gateway $GATEWAY
   1.347  		fi
   1.348 -		
   1.349 +
   1.350  		# wpa_supplicant waits for wpa_cli
   1.351  		[ -d /var/run/wpa_supplicant ] && wpa_cli -B
   1.352 -		
   1.353 -		# Multi-DNS server in $DNS_SERVER.
   1.354 +
   1.355 +		# Multi-DNS server in $DNS_SERVER
   1.356  		/bin/mv /etc/resolv.conf /tmp/resolv.conf.$$
   1.357 -		for NS in $DNS_SERVER
   1.358 -		do
   1.359 -			echo "nameserver $NS" >> /etc/resolv.conf
   1.360 -		done
   1.361 -		if [ ! -z $DOMAIN ];then
   1.362 -		    echo "search $DOMAIN" >> /etc/resolv.conf
   1.363 -		fi
   1.364 +		{
   1.365 +			printf 'nameserver %s\n' $DNS_SERVER			# Multiple allowed
   1.366 +			[ -n "$DOMAIN" ] && echo "search $DOMAIN"
   1.367 +		} >> /etc/resolv.conf
   1.368  		for HELPER in /etc/ipup.d/*; do
   1.369  			[ -x $HELPER ] && $HELPER $INTERFACE $DNS_SERVER
   1.370  		done
   1.371  	fi
   1.372  }
   1.373  
   1.374 -# stopping everything
   1.375 +
   1.376 +# Stopping everything
   1.377 +
   1.378  stop() {
   1.379 -	echo "stopping all interfaces"
   1.380 +	echo 'Stopping all interfaces'
   1.381  	ifconfig $INTERFACE down
   1.382  	ifconfig $WIFI_INTERFACE down
   1.383  
   1.384 -	echo "Killing all daemons"
   1.385 +	echo 'Killing all daemons'
   1.386  	killall udhcpc
   1.387  	killall wpa_supplicant 2>/dev/null
   1.388  
   1.389 -	if iwconfig $WIFI_INTERFACE | fgrep -q "Tx-Power"; then
   1.390 -		echo "Shutting down wifi card"
   1.391 +	if iwconfig $WIFI_INTERFACE | fgrep -q 'Tx-Power'; then
   1.392 +		echo 'Shutting down Wi-Fi card'
   1.393  		iwconfig $WIFI_INTERFACE txpower off
   1.394  	fi
   1.395  }
   1.396  
   1.397 +
   1.398  start() {
   1.399  	eth
   1.400  	wifi
   1.401  	dhcp
   1.402  	static_ip
   1.403 -	# change default lxpanel panel iface
   1.404 +	reconnect_wifi_network
   1.405 +
   1.406 +	# change default LXPanel panel iface
   1.407  	if [ -f /etc/lxpanel/default/panels/panel ]; then
   1.408 -		sed -i "s/iface=.*/iface=$INTERFACE/" \
   1.409 -			/etc/lxpanel/default/panels/panel
   1.410 +		sed -i "s/iface=.*/iface=$INTERFACE/" /etc/lxpanel/default/panels/panel
   1.411  	fi
   1.412  }
   1.413  
   1.414 -# looking for arguments:
   1.415 -if [ -z "$1" ]; then
   1.416 -	boot
   1.417 -	start
   1.418 -else
   1.419 -	case $1 in
   1.420 -		start)
   1.421 -			start ;;
   1.422 -		stop)
   1.423 -			stop ;;
   1.424 -		restart)
   1.425 -			stop
   1.426 -			start ;;
   1.427 -		*)
   1.428 -			echo ""
   1.429 -			echo -e "\033[1mUsage:\033[0m /etc/init.d/`basename $0` [start|stop|restart]"
   1.430 -			echo ""
   1.431 -			echo -e "	Default configuration file is \033[1m/etc/network.conf\033[0m"
   1.432 -			echo -e "	You can specify another configuration file in the second argument:"
   1.433 -			echo -e "	\033[1mUsage:\033[0m /etc/init.d/`basename $0` [start|stop|restart] file.conf"
   1.434 -			echo "" ;;
   1.435 -	esac
   1.436 -fi
   1.437 +
   1.438 +# Looking for arguments:
   1.439 +
   1.440 +case "$1" in
   1.441 +	'')
   1.442 +		boot; start ;;
   1.443 +	start)
   1.444 +		start ;;
   1.445 +	stop)
   1.446 +		stop ;;
   1.447 +	restart)
   1.448 +		stop; sleep 2; start ;;
   1.449 +	*)
   1.450 +		cat <<EOT
   1.451 +
   1.452 +$(boldify 'Usage:') /etc/init.d/$(basename $0) [start|stop|restart]
   1.453 +
   1.454 +Default configuration file is $(boldify '/etc/network.conf')
   1.455 +You can specify another configuration file in the second argument:
   1.456 +/etc/init.d/$(basename $0) [start|stop|restart] file.conf
   1.457 +
   1.458 +EOT
   1.459 +		;;
   1.460 +esac