indonesian

auto-wifi.sh (OpenBSD)

Mar 7th, 2018
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 10.33 KB | None | 0 0
  1. #!/bin/ksh
  2. #
  3. # Copyright (c) 2012 Peter Ljung <[email protected]>
  4. #
  5. # Permission to use, copy, modify, and distribute this software for any
  6. # purpose with or without fee is hereby granted, provided that the above
  7. # copyright notice and this permission notice appear in all copies.
  8.  
  9. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. #
  17.  
  18. ## Script that allow a new wifi connection to be setup interactively
  19. #
  20. # Manual mode
  21. # 1. User select wifi interface to use
  22. # 2. Scan available networks (name, protection and signal strength)
  23. # 3. User select network to connect to
  24. # 4. User enter password for network (if not open)
  25. # 5. Connect to network (assuming dhcp)
  26. # 6. Optionally display a connect string to be appended to corresponding hostname.if file
  27. #
  28. # Automatic mode
  29. # 1. User select wifi interface to use
  30. # 2. Scan available networks (name, channel, security and signal strength)
  31. # 3. Merge available networks with known networks
  32. # 4. Automatically select then best known available network
  33. # 5. Connect to network (assuming dhcp)
  34. # 6. Optionally display a connect string to be appended to corresponding hostname.if file
  35. #
  36. # Other
  37. # - TODO: Add connect line to hostname.if (instead of just printing)
  38. # - TODO: Test with multiple known available networks
  39. # - TODO: Replace known file with regular hostname.if
  40. # - TODO: Handle spaces in password and nwid - DONE
  41. # - TODO: Automatically detect WEP/WPA security
  42. # - TODO: Improve security for known file
  43. #
  44.  
  45. # Default values
  46. AUTO="true"    # Setup automatically if possible
  47. INTERFACE=""   # E.g. "iwn0"
  48. NETWORK=""     # E.g. "astrid;6;208dB;54M;secure" i.e. name, chan, signal, speed, secure/open
  49. NAME=""        # E.g. "Astrid"
  50. CHAN=""        # E.g. "6"
  51. AUTHTYPE=""    # open, secure (i.e. wep or wpa), wep or wpa
  52. PREFIX=""      # optional "0x" prefix to PASSWORD
  53. PASSWORD=""    # "secret"
  54. IF_STATUS=""   # "active" or "no network"
  55. CONN_STR=""    # connect string for /etc/hostname.if
  56. HNAME_FILE=""  # hostname.if file
  57. KNOWN_FILE="/etc/known-wifi"
  58.  
  59. # Print input lines numbered from 1 .. n
  60. print_lines_numbered() {
  61.   awk '{print NR ". " $0}'
  62. }
  63.  
  64. # Print single line identified by $1 (1..n)
  65. print_line() {
  66.   awk 'NR=='"$1"' {print $0}'
  67. }
  68.  
  69. # Print the number of lines in file
  70. lines() {
  71.   wc -l $1 | awk '{ print $1 }'
  72. }
  73.  
  74. # Strip $1 from " from both ends (not used!)
  75. str_strip() {
  76.   temp=${1#\"}
  77.   echo "${temp%\"}"
  78. }
  79.  
  80. # Print column n (1..) in $1 from string in $2 with ; as separator
  81. col() {
  82.   echo "$2" | eval "awk -F'[;]' '{ print \$"$1" }'"  # eval expands $1
  83. }
  84.  
  85. # Get all interfaces (from dmesg output) as lines
  86. # TODO: Filter on WLAN interfaces (then unneccesary if selection with be removed)
  87. get_all_interfaces() {
  88.   dmesg | grep 'address' | awk '{ print $1 }' | cut -d : -f 1
  89. }
  90.  
  91. # Get network if from user
  92. get_interface() {
  93.   interfaces=$( get_all_interfaces )
  94.   if [[ -n $INTERFACE ]]; then
  95.     INTERFACE=$( print "$interfaces" | grep -i "^$INTERFACE" )
  96.   fi
  97.   if [[ -z $INTERFACE && -n $interfaces ]]; then
  98.     num_ifs=`echo "$interfaces" | wc -l | awk '{ print $1 }'`
  99.     if [[ $num_ifs -eq "1" ]]; then
  100.       INTERFACE=$( print "$interfaces" | print_line "1" )
  101.     elif [[ $num_ifs -gt "1" ]]; then
  102.       print "Select which interface to configure:"
  103.       print "$interfaces" | print_lines_numbered
  104.       print -n "Select interface: "; read n
  105.       INTERFACE=$( print "$interfaces" | print_line $n )
  106.     fi
  107.   fi
  108. }
  109.  
  110. # Print all wifi interfaces from INTERFACE scan. First argument is optional separator.
  111. # Columns: NAME;CHAN;signal;speed;AUTHTYPE
  112. #          astrid;6;212dB;54M;secure
  113. #          Time Capsule;4;242dB;54M;secure
  114. get_all_networks() {
  115.   ifconfig $INTERFACE scan | awk '/^\t+nwid/' | sed -E 's/^ +nwid /"/' | sed 's/ chan/" chan/' | sed 's/""/"/g' | {
  116.     while read l; do
  117.       eval set -A ary "$l"      # set -A handles " quoting. eval is used expand $l
  118.       SEC='open'
  119.       if echo ${ary[7]} | egrep -q 'privacy'; then
  120.         SEC='secure'
  121.       fi
  122.       echo "${ary[0]};${ary[2]};${ary[5]};${ary[6]};$SEC"
  123.     done
  124.   }
  125. }
  126.  
  127. # Let the user choose network based on interface scan. Set NAME, CHAN variables
  128. # TODO: Test case with no available networks
  129. get_network() {
  130.   networks=$( get_all_networks | sort -r -t';' -k3 )
  131.   if [[ -n $NAME ]]; then
  132.     NETWORK=$( print "$networks" | grep -i "^$NAME" )
  133.   fi
  134.   if [[ -z $NETWORK && -n $networks ]]; then
  135.     # TODO: Make network list more readable by e.g. removing ; with space
  136.     print "Select which network to connect to:"
  137.     print "$networks" | print_lines_numbered
  138.     print -n "Select network: "; read n
  139.     NETWORK=$( print "$networks" | print_line $n )
  140.   fi
  141.   NAME=`col 1 "$NETWORK"`
  142.   CHAN=`col 2 "$NETWORK"`
  143.   AUTHTYPE=`col 5 "$NETWORK"`
  144. }
  145.  
  146. # Get password from user. Set PASSWORD and AUTHTYPE if that can be determined from password type
  147. get_password() {
  148.   if [[ -z $PASSWORD ]]; then
  149.     print -n "Enter password: "; read pw
  150.     PASSWORD="$pw"
  151.   fi
  152. }
  153.  
  154. # Store current network as a known network. Replace network with same NAME
  155. # Format: NAME;AUTHTYPE;PASSWORD
  156. add_known_network() {
  157.   # Use ; as field separator
  158.   echo "$NAME;$AUTHTYPE;$PASSWORD" | cat $KNOWN_FILE - | sort -t';' -k1 -u > $TMP
  159.   cat $TMP > $KNOWN_FILE
  160. }
  161.  
  162. # Print known and available networks in signal strength order
  163. # Format: NAME;AUTHTYPE;PASSWORD;CHAN;signal
  164. known_available_networks() {
  165.   # Print the join between known files and avail networks in signal strength order
  166.   get_all_networks | sort -k1 > $TMP
  167.   if [[ $( lines $TMP ) -gt 0 && $( lines $KNOWN_FILE ) -gt 0 ]]; then
  168.     cat $KNOWN_FILE | sort -t';' -k1 | join -t';' - $TMP | sort -r -t';' -k6 | awk -F'[;]' '{ print $1";"$2";"$3";"$5";"$6 }'
  169.   fi
  170. }
  171.  
  172. # Set NAME, AUTHTYPE and PASSWORD to best (highest signal strength) available network
  173. best_known_network() {
  174.   BEST=$( known_available_networks | head -n 1 )
  175.   if [[ -n $BEST ]]; then
  176.     NAME=`col 1 "$BEST"`
  177.     AUTHTYPE=`col 2 "$BEST"`
  178.     PASSWORD=`col 3 "$BEST"`
  179.     CHAN=`col 5 "$BEST"`
  180.   fi
  181. }
  182.  
  183. # Setup connection to open network. Based on INTERFACE, NAME, CHANNEL and PASSWORD. Update AUTHTYPE.
  184. connect_open() {
  185.   ifconfig $INTERFACE chan $CHAN nwid "$NAME" -nwkey -wpakey up
  186.   sleep 5
  187. }
  188.  
  189. # Setup WEP connection. $1 is an optional prefix to password.
  190. connect_wep() {
  191.   AUTHTYPE="wep"; PREFIX=$1
  192.   ifconfig $INTERFACE chan $CHAN nwid "$NAME" -wpa -wpakey nwkey "$PREFIX$PASSWORD" up
  193.   sleep 5
  194. }
  195.  
  196. # Setup WPA connection. $1 is an optional prefix to password.
  197. connect_wpa() {
  198.   AUTHTYPE="wpa"; PREFIX=$1
  199.   ifconfig $INTERFACE chan $CHAN nwid "$NAME" -nwkey wpa wpakey "$PREFIX$PASSWORD" up
  200.   sleep 5
  201. }
  202.  
  203. # Set interface down.
  204. disconnect() {
  205.   ifconfig $INTERFACE -chan -nwid -nwkey -wpa -wpakey down
  206.   sleep 2
  207. }
  208.  
  209. # Setup connection using open, wpa, wep. Update AUTHTYPE, PASSWORD and IF_STATUS.
  210. connect() {
  211.   if [[ "$AUTHTYPE" == "open" ]]; then
  212.     connect_open
  213.   elif [[ "$AUTHTYPE" == "wep" ]]; then
  214.     connect_wep
  215.   elif [[ "$AUTHTYPE" == "wpa" ]]; then
  216.     connect_wpa
  217.   elif [[ "$AUTHTYPE" == "secure" ]]; then
  218.     # TODO: check that password is at least 8 characters (otherwise it is not wpa)
  219.     if [[ $(if_status) != "active" ]]; then
  220.       connect_wpa
  221.     fi
  222.     if [[ $(if_status) != "active" ]]; then
  223.       if [[ "$PASSWORD" = +([a-f]|[0-9]) ]]; then
  224.         connect_wpa "0x"
  225.       fi
  226.     fi
  227.     if [[ $(if_status) != "active" ]]; then
  228.       connect_wep
  229.     fi
  230.     if [[ $(if_status) != "active" ]]; then
  231.       if [[ "$PASSWORD" = +([a-f]|[0-9]) ]]; then
  232.         connect_wep "0x"
  233.       fi
  234.     fi
  235.   else
  236.       echo "Unknown authentication type: $AUTHTYPE"
  237.   fi
  238.   PASSWORD="$PREFIX$PASSWORD"
  239.   IF_STATUS=$(if_status)
  240. }
  241.  
  242. dhclient_request() {
  243.   dhclient $INTERFACE > /dev/null 2> /dev/null
  244. }
  245.  
  246. # Get interface status (using ifconfig). Output: "active" or "no network"
  247. if_status() {
  248.   ifconfig "$INTERFACE" | grep 'status:' | sed 's/^.*status: //'
  249. }
  250.  
  251. # Connect string to be written to hostname.if. Based on NAME, CHANNEL, PASSWORD and AUTHTYPE.
  252. connect_string() {
  253.   HNAME_FILE="/etc/hostname.$INTERFACE"
  254.     CONN_STR="dhcp chan $CHAN nwid \"$NAME\""
  255.   if [[ $AUTHTYPE == "wep" ]]; then
  256.       CONN_STR="$CONN_STR nwkey \"$PREFIX$PASSWORD\""
  257.   elif [[ $AUTHTYPE == "wpa" ]]; then
  258.       CONN_STR="$CONN_STR wpa wpakey \"$PREFIX$PASSWORD\""
  259.   fi
  260. }
  261.  
  262. initialize() {
  263.   TMP=`mktemp` || exit 1
  264.   touch $KNOWN_FILE
  265. }
  266.  
  267. finalize() {
  268.   rm "$TMP"
  269.   exit 0
  270. }
  271.  
  272. # Main ...
  273. while getopts "i:n:p:t:f:m" opt; do
  274.     case $opt in
  275.         i )    INTERFACE=$OPTARG ;;
  276.         n )    NAME=$OPTARG ;;
  277.         p )    PASSWORD=$OPTARG ;;
  278.         t )    AUTHTYPE=$OPTARG ;;
  279.         f )    KNOWN_FILE=$OPTARG ;;
  280.         m )    AUTO="false" ;;
  281.         \? )    print 'usage: sudo auto-wifi.sh [-i interface] [-n network_name] [-p password] [-t open/wep/wpa] [-f known_file] [-m(anual)]'
  282.                return 1 ;;
  283.     esac
  284. done
  285.  
  286. initialize
  287. get_interface; print
  288. if [[ -z $INTERFACE ]]; then
  289.   print "No interface available. Exit"; finalize
  290. fi
  291. if [[ $(if_status) == "active" ]]; then
  292.   print -n "Interface ($INTERFACE) is active. Disconnect? ([y]n): "; read ANS
  293.   if [[ $ANS == "n" ]]; then
  294.     print "You cant setup an active interface. Exit"; finalize
  295.   fi
  296.   print
  297. fi
  298. disconnect
  299. if [[ $AUTO == "true" ]]; then
  300.   best_known_network
  301. fi
  302. get_network; print
  303. if [[ -z $NAME ]]; then
  304.   print "No network available. Exit"; finalize
  305. fi
  306. if [[ "$AUTHTYPE" != "open" ]]; then
  307.   get_password; print
  308. fi
  309. connect
  310. dhclient_request
  311. if [[ $(if_status) == "active" ]]; then
  312.   add_known_network  # Ask user first?
  313.   connect_string
  314.   print "Interface ($INTERFACE) is active!"
  315.   print -n "Do you want to add connect string to $HNAME_FILE? (y[n]): "; read ans
  316.   if [[ $ans == "y" ]]; then
  317.     print "Add the following line to $HNAME_FILE:"  # Remove!
  318.     print "$CONN_STR"
  319.   fi
  320. else
  321.   print "Connection failed. Run script again to try again"
  322.   print "Known password my be outdated. Do manual setup (-m) to override known password"
  323. fi
  324. finalize
Advertisement
Add Comment
Please, Sign In to add comment