#!/bin/sh ## ## Shell script to perform U of C wireless authentication without ## a web browser. Yee haw. ## ## $Id: wgauth,v 1.7 2007/02/15 21:24:54 dgc Exp $ ## PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/ucb:/usr/bsd OS=`uname -s` HOST=`hostname | cut -d. -f1` A0=`basename $0` q='"' nl=' ' log=false ## Find the hostname of my gateway, so we can assume it's the wireless ## gateway we're going to authenticate to. This function should return ## the gateway and the interface as $1 and $2, resp. get_ifgw_Darwin () { netstat -nr | awk '$1 == "default" { print $2, $6; }' } get_ifgw_OpenBSD () { netstat -nr | awk '$1 == "default" { print $2, $7; }' } get_ifgw_SunOS () { netstat -nr | awk '$1 == "default" { print $2; }' netstat -nr | awk '$2 ~ /'$HOST'(\..*)?$/ && $5 > 0 {print $6;}' | head -1 } get_ifgw_Linux () { netstat -nr | awk '$1 == "0.0.0.0" { print $2, $8; }' } ## Given an interface name, get the corresponding IP addr. get_ifaddr_Darwin () { ifconfig $1 | awk '$1 == "inet" {print $2}' } get_ifaddr_OpenBSD () { ifconfig $1 | awk '$1 == "inet" {print $2}' } get_ifaddr_SunOS () { ifconfig $1 | awk '$1 == "inet" {print $2}' } get_ifaddr_Linux () { ifconfig $1 | awk '$1 == "inet" {print $2}' } ## Read a password getpass () { printf >/dev/tty "$@" _tty_state=`stty -g` # if stty -g doesn't work # _tty_state="sane" trap "stty $_tty_state /dev/tty echo $_pass } ## Format an HTTP request for authn fmtreq () { formdata="username=$user&password=$pass&reqFrom=perfigo_simple_login.jsp&cm=ws32vklm&userip=$addr&os=MAC_OSX&index=0&provider=RADIUS-PROD&login_submit=Authenticate" len=`expr "$formdata" : '.*'` echo "POST /auth/perfigo_cm_validate.jsp HTTP/1.0" #echo "Host: $gateway" #echo "Connection: close" #echo "Referer: https://$gateway/login.html" #echo "Accept: */*" echo "Content-Type: application/x-www-form-urlencoded" echo "Content-Length: $len" echo echo $formdata } ## Issue auth query, return Location: response sendauth () { httpreq=`fmtreq` if $log; then : > $LOG chmod 600 $LOG : > $LOG ( echo "Request:"; echo "$httpreq" ) > $LOG ( echo; echo "Response:" ) > $LOG fi echo "$httpreq" \ | openssl s_client -host $gateway -port 443 -quiet 2>/dev/null \ | tee -a $LOG } ## Try to authenticate tryauth () { moreinfo= html=`sendauth` if echo "$html" | grep 'You have been successfully' >/dev/null; then logon=`echo "$html" | sed -n -e '/Time Logged/{;s/<[^>]*>//g;p;}'` session=`echo "$html" | sed -n -e '/User Session/{;s/<[^>]*>//g;p;}'` # Abuse the shell to strip out unwanted whitespace: moreinfo=`echo $logon; echo $session` # success rc=0 elif echo "$html" | grep 'Invalid username or password' >/dev/null; then # failure to authenticate echo "failed (bad credentials?)" rc=6 else # unknown if $log; then echo "Undefined error. HTTP result is in $LOG" else echo "Undefined error. Use $q$A0 -l$q to log authentication." fi rc=5 fi } # Usage usage () { echo "usage: $A0 [-g server] [-i interface] [username [password]]" } ## Options ## ## Use -h to specify the gateway name (if using the IP doesn't work) ## Use -i if autodiscovery of the default route's interface doesn't work. ## errors= while getopts hg:i:l c; do case "$c" in h) usage; exit 2;; g) gateway=$OPTARG; shift 2;; i) interface=$OPTARG; shift 2;; l) log=true; shift;; *) errors=1 ;; esac done ## Set logfile if $log; then LOG=${TMPDIR-/tmp}/$A0-$user.log else LOG=/dev/null fi ## If no gateway specified, try interface if [ -z "$gateway" -a -n "$interface" ]; then myip=`get_ifaddr_$OS $interface` set -- `echo $myip | tr . " "` -- "$@" gateway=$1.$2.$3.1 while [ ! "$1" = "--" ]; do shift done shift fi ## If still have no gateway, then try to gather it from default route if [ -z "$gateway" ]; then set -- `get_ifgw_$OS` -- "$@" gateway=$1 interface=$2 while [ ! "$1" = "--" ]; do shift done shift fi # Override gw. This was needed during Perfigo rollout, but no longer. #gateway=wg-south.uchicago.edu ## Check gateway if [ -z "$gateway" ]; then echo "There is no default route. Wireless networking does not appear to be active." exit 4 fi if [ -n "$errors" -o -z "$gateway" ]; then usage exit 2 fi user=${1-`whoami`} pass=${2} ## Read a password if [ -z "$pass" ]; then pass=`getpass "Password for $user@$gateway: "` fi addr=`get_ifaddr_$OS $interface` printf "Authenticating... " tryauth if [ $rc -ne 0 ]; then exit $rc fi echo "address is $addr" echo "$moreinfo"; echo