jump to navigation

Wireless installer for the masses… March 25, 2009

Posted by bigmaconcampus in Mac Tech.
16 comments

~~~~~ 8/27/09 ATTENTION! ~~~~~
The information on this version of the installer is outdated. There is a newer version of this installer available. However, the info on this page does provide a detailed description of what is being accomplished and should not necessarily be ignored, but at least reviewed before reading the updated version.

We now join you local broadcast, already in progress…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

After wrestling and much trial-and-error (a years worth of tinkering, on-and-off), I finally ended up with a version (only took 3 tries) of a wireless installer I can be somewhat proud of. 

The background info:
I had need of an automated wireless installer for various reason.

  1. Needed to setup hundreds of student Macs for start of semesters and such.
  2. Needed an easy tool for faculty and staff to use
  3. We were changing our wireless network and needed to deploy/change networks somewhat rapidly and smoothly
  4. There were known issues with people not setting up the network correctly even with a guide

Although, I’d found several methods for doing this on Mac OS X 10.4, none would work with Mac OS X 10.5. This installer will setup a connection for an Enterprise WPA network and remove previous settings (usually botched). It will also remove any legacy networks you might want to get rid of on the client’s computer. You will need to edit these scripts to do your bidding. I attempted to make it fairly easy to edit, but YMMV.

I have posted a flat-file .pkg on a website at our University for students/employees to download and run themselves. I decided to deploy this batch of scripts via a Packaged installer, making it dump a payload of scripts into a /tmp folder and then engage via postscript. It is comprised of shell, applescript and python (one-line). I confess it might not be pretty code, but it gets the job done. It accomplishes most tasks by editing the appropriate plist files and uses applescript to make modifications to the keychain items. There is one step that relies on GUI scripting to click a single button at the end of the installation to allow the eapolclient access to the keychain item. I’d developed another method but it relied on more GUI scripting and I preferred to keep that to a minimum due to flackiness of GUI scripting. The applescript parts that prompt for the Mac password, and wireless username and password, test the validity of the authentication credentials. The wireless credentials are tested by smb mounting a server on our internal network. Remove if not necessary.

I had also ran into a last minute issue with turning on Assistive devices. When I would create the invisible file at /var/db/.accessibilityAPIEnabled, it wouldn’t recognize later while the script was running on brand new machines, fresh out of the box (fix seems to be restarting the Finder). I left a step in where I just copy the file into the correct location rather than touch it to create it. Figured it should work either way.

The real beauty of this script is that it doesn’t harm any existing wireless settings, except for the ones you want it to touch. More of a scalpel instead of a hand-grenade approach when dealing with computers that you don’t own.

Please feel free to use, modify, test these at your location as I have found many pieces from various forums, primarily http://www.macscripter.net and macosxhints.com. If there are others out there I got help from and failed to acknowledge, let me know.

My installation package installs all the certificates and applescripts to a /tmp/wireless directory. The installer runs as the local user (due to needing to access the proper login.keychain) and runs certain steps as sudo when necessary. It also installs the PlistBuddy to /tmp/wireless, although you could possibly have it search the local computer for a copy since Apple uses that for their upgrades. I also installed a copy of .accessibilityAPIEnabled into the /tmp/wireless folder to copy to /var/db in the script, but you could just touch /var/db/.accessibilityAPIEnabled instead.

The Main Shell Script:


#!/bin/sh
PATH=/bin:/usr/bin:/sbin:/usr/sbin export PATH
#################################################
# Wireless Setup Script #
# Created by Bryan S. Lee 2009 #
#################################################

###################################################
### VARIABLES THAT MUST BE SET BEFORE RUNNING!!!!!#
###################################################

### Temp folder location for installation files
TEMP="/private/tmp/wireless"

### Location of PlistBuddy
PLISTBUDDY="$TEMP/PlistBuddy"

### New Wireless Network to be setup and legacy networks to remove
WIRELESSNETWORKNAME="nameofwirelessnetwork"
LEGACYNETWORK1="nameofoldwirelessnetwork"
LEGACYNETWORK2="nameofoldopenwirelessnetwork"

##########################################################
### Initial state variables that probably don't change ###
##########################################################


### Variable that tests whether a previous setup is detected later in the script
PREV_WIRELESS_EXISTS=""

### Variable that tests if a legacy network is present. To be used later in the script
PREV_LEGACY1_EXISTS=""

### Variable that tests if a second legacy network is present. To be used later in the script
PREV_LEGACY2_EXISTS=""

### Set other variables
LOCALUSER=`whoami`
HOME=`dscl . -read /Users/$LOCALUSER home | sed -e 's|dsAttrTypeNative:home: ||g'`
LOG=$HOME/Library/Logs/Wireless_Setup.log
OSVERSION=`system_profiler -detailLevel mini | grep "System Version:" | cut -c 32-35`

### Setup Error log for later use in case of errors. Duh!
ERRORLOG="$TEMP/error.log"
ERROR=""
rm -rf $TEMP/error.log
touch $TEMP/error.log

# Check hardware to see if computer is a MacBookAir, if so, change Wireless Interface variable to en0
# instead of en1 to accomodate hardware difference (no ethernet at en0 on MacBookAir, airport is en0 instead)
# Also, set variable MBAirPresent to pass to get_wireless_pass.scpt, to bypass network test if applicable.
WIRELESSINTERFACE="en1"
CHECKFORAIR=`system_profiler -detailLevel mini | grep MacBookAir`
if [ "$CHECKFORAIR" != "" ]; then
echo "MacBookAir detected, changing Wireless Interface to en0..." >> $LOG
WIRELESSINTERFACE="en0"
MBAirPresent="true"
else
MBAirPresent="false"
fi

#####################
### FUNCTIONS ###
#####################

# Function for checking error log file for any possible errors coming from Applescript portions
CHECK_FOR_ERRORS ()
{
ERROR=`grep exit $ERRORLOG | cut -c 1-7`
if [ "$ERROR" != "" ]; then
$REPORTER
rm -rf /tmp/wireless
$ERROR
fi
}

# Fuction that will report back the position counts in plist files to the Log
PLISTCOUNTER ()
{
((PLISTITEMCOUNT=$PLISTITEMCOUNT+1))
echo "Entries start at 0, and current number of entries is " $PLISTITEMCOUNT >> $LOG
echo "Next entry number position will be " $PLISTITEMCOUNT >> $LOG
}

# Function that toggles the airport between on and off. Expects on or off as variables of the function
TOGGLEAIRPORT ()
{
echo "Turning $1 Airport wireless..." >> $LOG
if [ "$OSVERSION" = "10.5" ]; then
networksetup -setairportpower $1
else
if [ "$OSVERSION" = "10.6" ]; then
networksetup -setairportpower $WIRELESSINTERFACE $1
else
osascript -e "tell application \"Finder\" to activate"
osascript -e "tell application \"Finder\" to display dialog \"An error occurred while attempting to turn the wireless on or off. Please try the installer again or contact whoever for help.\" buttons {\"OK\"} with icon caution"
osascript -e "tell application \"Installer\" to activate"
echo "exit 20 Error occurred while changing airport power due to unknown operating system version." >> $LOG
echo "exit 20 Error occurred while changing airport power due to unknown operating system version." > $ERRORLOG
fi
fi
echo "Airport wireless turned $1" >> $LOG
}

######################
### Starting Setup ###
######################

# Setup the log so we know what's going on later...
echo "------------------------------------------------------------------" >> $LOG
echo "Wireless Setup started at `date`" >> $LOG
echo "Starting Wireless Setup..." >> $LOG
echo "------------------------------------------------------------------" >> $LOG
echo "" >> $LOG

system_profiler -detailLevel mini | grep "System Version:" | cut -c 7-50 >> $LOG

# Turn on Airport to test if Wireless network to join is present
TOGGLEAIRPORT on

CHECK_FOR_ERRORS

### Check to see if Wireless Network is within range (only works with broadcast SSID)
echo "Checking to see if wireless network, $WIRELESSNETWORKNAME, is within range for setup to continue..." >> $LOG
WIRELESSINRANGE=`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport --scan=$WIRELESSNETWORKNAME`
if [ "$WIRELESSINRANGE" = "No networks found" ]; then
echo "$WIRELESSNETWORKNAME not within range, installation will quit" >> $LOG
osascript -e "tell application \"Finder\" to activate"
osascript -e "tell application \"Finder\" to display dialog \"The wireless network, $WIRELESSNETWORKNAME, is not within range.\" & return & return & \"The installer will now quit. Please move to within range of the wireless signal and try again.\" buttons {\"OK\"} with icon caution"
osascript -e "tell application \"Installer\" to activate"
echo "exit 10 Wireless Network not within range" >> $LOG
echo "exit 10 Wireless Network not within range" > $ERRORLOG
fi

CHECK_FOR_ERRORS

echo "Wireless network, $WIRELESSNETWORKNAME, is within range. Setup will continue..." >> $LOG

### Prompt for Mac Admin Password, Wireless Username and Wireless Password
### Applescripts perform tests for validity and return variables
echo "Prompting user for Mac Admin password..." >> $LOG
MACPASS=`osascript "$TEMP/get_mac_pass.scpt" $LOG $ERRORLOG`

CHECK_FOR_ERRORS

echo "Mac Admin Password authenticated successfully..." >> $LOG

echo "Prompting user for Wireless username and password..." >> $LOG
WIRELESSPASS=`osascript "$TEMP/get_wireless_pass.scpt" $MACPASS $LOG $ERRORLOG $MBAirPresent`
WIRELESSUSER=`ls $TEMP | grep WirelessUserNameIs | cut -c 19-30`

### Clean up clutter from getting WirelessUserName
echo $MACPASS | sudo -S rm -rf $TEMP/WirelessUserNameIs*

CHECK_FOR_ERRORS

### Update Log
echo "User to configure: $WIRELESSUSER" >> $LOG
if [ "$CHECKFORAIR" != "" ]; then
echo "Network Password not tested due to presence of MacBookAir hardware..." >> $LOG
else
echo "Wireless Password authenticated successfully..." >> $LOG
fi

# Get MAC Addresses
hwAddress=`ifconfig en0 | awk '/ether/ { gsub(":", ""); print $2 }'`
hwAddresswithColons=`ifconfig en0 | awk '/ether/ { gsub(":", "\\\\:"); print $2 }'`
echo "Computer Hardware address: $hwAddress" >> $LOG

AirAddress=`ifconfig $WIRELESSINTERFACE | awk '/ether/ { gsub(":", ""); print $2 }'`
AirAddresswithColons=`ifconfig $WIRELESSINTERFACE | awk '/ether/ { gsub(":", "\\\\:"); print $2 }'`
AirAddresswithColons2=`ifconfig $WIRELESSINTERFACE | awk '/ether/ { gsub(":", "\\:"); print $2 }'`
echo "Computer Airport address: $AirAddress" >> $LOG

# Get some Unique Identifiers to use in the plists...
uuid=`uuidgen`
netuuid=`uuidgen`
OLD_UUID=""

# DYNAMICALLY SET THE LEOPARD UUID FOR THE BYHOST FILE NAMING
if [[ `ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c27-50` == "00000000-0000-1000-8000-" ]]; then
LEOUUID=`ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c51-62 | awk {'print tolower()'}`
elif [[ `ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c27-50` != "00000000-0000-1000-8000-" ]]; then
LEOUUID=`ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c27-62`
fi

# Define the 4 plist files that will be changed...
PREFSPATH="/Library/Preferences/SystemConfiguration/preferences.plist"
AirportPref="/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist"
EAPProfiles="$HOME/Library/Preferences/com.apple.eap.profiles.plist"
EAPBindings="$HOME/Library/Preferences/ByHost/com.apple.eap.bindings.$LEOUUID.plist"

# Turn off Airport
TOGGLEAIRPORT off

CHECK_FOR_ERRORS

# Turn on Assistive Devices and set variable to possibly turn off later
if [ -e /private/var/db/.AccessibilityAPIEnabled ]; then
echo "Assistive Devices already turned on..." >> $LOG
ASSISTDEVOFF="false"
else
echo "Assistive Devices is off..." >> $LOG
ASSISTDEVOFF="true"
echo "Turning on Assistive Devices Setting..." >> $LOG
echo $MACPASS | sudo -S cp /private/tmp/wireless/AccessibilityAPIEnabled /private/var/db/.AccessibilityAPIEnabled
echo $MACPASS | sudo -S chmod 444 /private/var/db/.AccessibilityAPIEnabled
fi

##############################
##### Cleanup Section ########
##############################

###
### Search preferences.plist for matching previous wireless networks and remove if found
###

echo "Determining if previous tigernet installation exists..." >> $LOG
echo "Starting Cleanup of any previously detected legacy networks..." >> $LOG

# Create a backup copy of com.apple.preferences.plist, JUST IN CASE
echo "Backing up Preferences plist file" >> $LOG
echo $MACPASS | sudo -S cp $PREFSPATH "/Library/Preferences/SystemConfiguration/preferences.plist.old"

# Search all entries in com.apple.preferences.plist to find and delete previously set connections.
# If more than 100 wireless networks present, number may
# need to be increased in COUNTER (hopefully, no one has more than 100 wireless network connections)

# Search to figure out the UUID for the SETS entry in the preferences.plist
SETUUID=`grep "/Sets/" $PREFSPATH | cut -c 16-51`

# Loop through the com.apple.preferences.plist file looking for matches of wireless networks to remove and then removing them.
for ((COUNTER=0; COUNTER <= 100 ; COUNTER=COUNTER+1))
do
TESTFORNETWORK=`"$PLISTBUDDY" -c "Print :Sets:$SETUUID:Network:Interface:$WIRELESSINTERFACE:AirPort:PreferredNetworks:$COUNTER" $PREFSPATH | grep "$WIRELESSNETWORKNAME"`
if [ "$TESTFORNETWORK" != "" ]; then
echo "Previous $WIRELESSNETWORKNAME connection found and deleted" >> $LOG
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Delete :Sets:$SETUUID:Network:Interface:$WIRELESSINTERFACE:AirPort:PreferredNetworks:$COUNTER" $PREFSPATH
((COUNTER=COUNTER-1))
fi
TESTFORNETWORK=`"$PLISTBUDDY" -c "Print :Sets:$SETUUID:Network:Interface:$WIRELESSINTERFACE:AirPort:PreferredNetworks:$COUNTER" $PREFSPATH | grep "$LEGACYNETWORK1"`
if [ "$TESTFORNETWORK" != "" ]; then
echo "Previous $LEGACYNETWORK1 connection found and deleted" >> $LOG
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Delete :Sets:$SETUUID:Network:Interface:$WIRELESSINTERFACE:AirPort:PreferredNetworks:$COUNTER" $PREFSPATH
((COUNTER=COUNTER-1))
fi
TESTFORNETWORK=`"$PLISTBUDDY" -c "Print :Sets:$SETUUID:Network:Interface:$WIRELESSINTERFACE:AirPort:PreferredNetworks:$COUNTER" $PREFSPATH | grep "$LEGACYNETWORK2"`
if [ "$TESTFORNETWORK" != "" ]; then
echo "Previous $LEGACYNETWORK2 connection found and deleted" >> $LOG
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Delete :Sets:$SETUUID:Network:Interface:$WIRELESSINTERFACE:AirPort:PreferredNetworks:$COUNTER" $PREFSPATH
((COUNTER=COUNTER-1))
fi
done

###
### Delete com.apple.airport.preferences.plist file to clear previously cached settings for ALL networks (no harm done)
###

echo $MACPASS | sudo -S rm -rf $AirportPref

###
### Search EAP Profile plist to cleanup if necessary
###

# Search all entries to find and delete previously set connections. If more than 20 Enterprise
# wireless networks present, number may
# need to be increased in COUNTER (hopefully, no one has more than 20 enterprise network connections)
for ((COUNTER=0; COUNTER <= 20 ; COUNTER=COUNTER+1))
do
TESTFORNETWORK=`"$PLISTBUDDY" -c "Print :Profiles:$COUNTER" $EAPProfiles | grep "$WIRELESSNETWORKNAME"`
if [ "$TESTFORNETWORK" != "" ]; then
echo "Previous $WIRELESSNETWORKNAME found and deleted in EAP Profile" >> $LOG
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Delete :Profiles:$COUNTER" $EAPProfiles
((COUNTER=COUNTER-1))
fi
done

###
### Search EAP Bindings plist to cleanup if necessary
###

# Search all entries to find and delete previously set connections. If more than 20 Enterprise
# wireless networks present, number may
# need to be increased in COUNTER (hopefully, no one has more than 20 enterprise network connections)
for ((COUNTER=0; COUNTER <= 20 ; COUNTER=COUNTER+1))
do
TESTFORNETWORK=`"$PLISTBUDDY" -c "Print :$AirAddresswithColons:$COUNTER" $EAPBindings | grep "$WIRELESSNETWORKNAME"`
if [ "$TESTFORNETWORK" != "" ]; then
echo "Previous $WIRELESSNETWORKNAME found and deleted in EAP Bindings" >> $LOG
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Delete :$AirAddresswithColons:$COUNTER" $EAPBindings
((COUNTER=COUNTER-1))
fi
done

##########################################
### Add entries to PLIST files section ###
##########################################

###
### Scan preferences.plist file to figure out how many entries exist under Preferred Networks
###

PLISTITEMCOUNT=-1
for ((COUNTER=0; COUNTER <= 100 ; COUNTER=COUNTER+1))
do
TESTFORNETWORK=`"$PLISTBUDDY" -c "Print :Sets:$SETUUID:Network:Interface:$WIRELESSINTERFACE:AirPort:PreferredNetworks:$COUNTER" $PREFSPATH | grep SSID_STR`
if [ "$TESTFORNETWORK" != "" ]; then
((PLISTITEMCOUNT=$PLISTITEMCOUNT+1))
fi
done

PLISTCOUNTER

###
### Add new entry for wireless network into com.apple.preferences.plist
###

echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :Sets:$SETUUID:Network:Interface:$WIRELESSINTERFACE:AirPort:PreferredNetworks array" $PREFSPATH
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :Sets:$SETUUID:Network:Interface:$WIRELESSINTERFACE:AirPort:PreferredNetworks:$PLISTITEMCOUNT dict" $PREFSPATH
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :Sets:$SETUUID:Network:Interface:$WIRELESSINTERFACE:AirPort:PreferredNetworks:$PLISTITEMCOUNT:SSID_STR string $WIRELESSNETWORKNAME" $PREFSPATH
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :Sets:$SETUUID:Network:Interface:$WIRELESSINTERFACE:AirPort:PreferredNetworks:$PLISTITEMCOUNT:SecurityType string WPA2\ Enterprise" $PREFSPATH
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :Sets:$SETUUID:Network:Interface:$WIRELESSINTERFACE:AirPort:PreferredNetworks:$PLISTITEMCOUNT:Unique\ Network\ ID string $uuid" $PREFSPATH

###
### Add new entry for wireless network into com.apple.airport.preferences.plist
###

echo "Adding $WIRELESSNETWORKNAME to Airport Preferences..." >> $LOG
# "$PLISTBUDDY" -c "Delete :KnownNetworks" $AirportPref ;# Remove any previous entry.

echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :KnownNetworks dict" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :KnownNetworks:$uuid dict" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :KnownNetworks:$uuid:Remembered\ Channels array" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :KnownNetworks:$uuid:Remembered\ Channels:0 integer 11" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :KnownNetworks:$uuid:Remembered\ Channels:1 integer 6" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :KnownNetworks:$uuid:Remembered\ Channels:2 integer 1" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :KnownNetworks:$uuid:SCAN_DIRECTED bool Yes" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :KnownNetworks:$uuid:SSID_STR string $WIRELESSNETWORKNAME" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :KnownNetworks:$uuid:SecurityType string WPA2\ Enterprise" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :KnownNetworks:$uuid:_timeStamp date 1995-06-21T14\:00\:00Z" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :Version integer 6" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :$WIRELESSINTERFACE dict" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :$WIRELESSINTERFACE:RecentNetworks array" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :$WIRELESSINTERFACE:RecentNetworks:0 dict" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :$WIRELESSINTERFACE:RecentNetworks:0:SSID_STR string $WIRELESSNETWORKNAME" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :$WIRELESSINTERFACE:RecentNetworks:0:SecurityType string WPA2\ Enterprise" $AirportPref
echo $MACPASS | sudo -S "$PLISTBUDDY" -c "Add :$WIRELESSINTERFACE:RecentNetworks:0:Unique\ Network\ ID string $uuid" $AirportPref

###
### Rebuild new entries for com.apple.eap.profiles.plist
###

echo "Building the User's EAPProfiles setting at $EAPProfiles..." >> $LOG

###
### Scan EAP Profile plist file to figure out how many entries exist
###

PLISTITEMCOUNT=-1
for ((COUNTER=0; COUNTER <= 20 ; COUNTER=COUNTER+1))
do
TESTFORNETWORK=`"$PLISTBUDDY" -c "Print :Profiles:$COUNTER" $EAPProfiles | grep EAP`
if [ "$TESTFORNETWORK" != "" ]; then
((PLISTITEMCOUNT=$PLISTITEMCOUNT+1))
fi
done

PLISTCOUNTER

"$PLISTBUDDY" -c "Add :Profiles array" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT dict" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:ConnectByDefault bool Yes" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:EAPClientConfiguration dict" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:EAPClientConfiguration:AcceptEAPTypes array" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:EAPClientConfiguration:AcceptEAPTypes:0 integer 25" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:EAPClientConfiguration:Description string Automatic" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:EAPClientConfiguration:EAPFASTProvisionPAC bool Yes" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:EAPClientConfiguration:EAPFASTProvisionPACAnonymously bool No" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:EAPClientConfiguration:EAPFASTUsePAC bool Yes" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:EAPClientConfiguration:OuterIdentity string " $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:EAPClientConfiguration:TLSVerifyServerCertificate bool Yes" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:EAPClientConfiguration:TTLSInnerAuthentication string MSCHAPv2" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:EAPClientConfiguration:UserName string $WIRELESSUSER" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:EAPClientConfiguration:UserPasswordKeychainItemID string $uuid" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:UniqueIdentifier string $uuid" $EAPProfiles
"$PLISTBUDDY" -c "Add :Profiles:$PLISTITEMCOUNT:UserDefinedName string WPA:\ $WIRELESSNETWORKNAME" $EAPProfiles

###
### Rebuild new entries for com.apple.eap.bindings.X.plist
###

echo "Building the User's EAPBindings settings at $EAPBindings..." >> $LOG

###
### Scan EAP Bindings plist file to figure out how many entries exist
###

PLISTITEMCOUNT=-1
for ((COUNTER=0; COUNTER <= 20 ; COUNTER=COUNTER+1))
do
TESTFORNETWORK=`"$PLISTBUDDY" -c "Print :$AirAddresswithColons:$COUNTER" $EAPBindings | grep UniqueIdentifier`
if [ "$TESTFORNETWORK" != "" ]; then
((PLISTITEMCOUNT=$PLISTITEMCOUNT+1))
fi
done

PLISTCOUNTER

"$PLISTBUDDY" -c "Add :$AirAddresswithColons array" $EAPBindings
"$PLISTBUDDY" -c "Add :$AirAddresswithColons:$PLISTITEMCOUNT dict" $EAPBindings
# "$PLISTBUDDY" -c "Add :$AirAddresswithColons:0:Hardware\ Address string $AirAddresswithColons2" $EAPBindings
"$PLISTBUDDY" -c "Add :$AirAddresswithColons:$PLISTITEMCOUNT:UniqueIdentifier string $uuid" $EAPBindings
"$PLISTBUDDY" -c "Add :$AirAddresswithColons:$PLISTITEMCOUNT:Wireless\ Network string $WIRELESSNETWORKNAME" $EAPBindings

###############################
### Security Setup Section ####
###############################

### A vast section of the security setup must be accomplished in applescript due to
### technical limitations of bash shell access to the keychain.
### A single step (clicking the 'Allow Always' button of the SecurityAgent) must be
### accomplished using GUI scripting via Applescript

# Add certificate to System Keychain for all users
echo "Adding Certificate to System Keychain..." >> $LOG
echo $MACPASS | sudo -S security add-trusted-cert -d -r trustAsRoot -k /Library/Keychains/System.keychain $TEMP/name.of.certificate.pem
echo "Certificate added successfully..." >> $LOG

# Add generic password item to login.keychain for network settings to attach to
echo "Checking login.keychain for previous keychain passwords to remove and adding new keychain item..." >> $LOG
osascript /tmp/cu_wireless/setup_wireless_keychain.scpt $MACPASS $WIRELESSNETWORKNAME $uuid $WIRELESSUSER $WIRELESSPASS $LOG $ERRORLOG

CHECK_FOR_ERRORS

# Report Password item added successfully to log
echo "Password Item added successfully..." >> $LOG

### Turn on Wireless
TOGGLEAIRPORT on

CHECK_FOR_ERRORS

### Attaching to wireless network
# echo $MACPASS | sudo -S /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport --associate=$WIRELESSNETWORKNAME

### Applescript step that relies on GUI scripting
echo "Setting ACL of keychain item to allow eapolclient..." >> $LOG
osascript "/tmp/cu_wireless/allow_keychain_acl.scpt" $MACPASS $LOG $ERRORLOG

CHECK_FOR_ERRORS

# Report no error setting ACL of keychain to log
echo "ACL of keychain item set..." >> $LOG

# Turn off Assistive Devices if originally off
if [ $ASSISTDEVOFF = "true" ]; then
echo "Turning off Assistive Devices Setting..." >> $LOG
echo $MACPASS | sudo -S rm -rf /private/var/db/.AccessibilityAPIEnabled
echo "Assistive Devices turned off successfully..." >> $LOG
fi

CHECK_FOR_ERRORS

echo "Wireless Setup completed successfully" >> $LOG

# Remove all setup files when finished
echo $MACPASS | sudo -S rm -rf /tmp/wireless

exit 0

 

AppleScript portions referred to in the above Shell script:

get_mac_pass.scpt


-- Script created
-- by Bryan S. Lee 2009

-- This script will prompt user for the Admin Mac Password and test the password for validity
-- This script expects to receive all logs locations from the parent script

on run argv
set LOGS to item 1 of argv
set ERRORLOG to item 2 of argv
set theUser to (do shell script "echo $USER")
set myMacPass to ""
set myMacPassTest to ""

-- Prompt user for Mac Password
tell application "Finder"
activate
repeat until myMacPassTest is not ""
set myMacPassDialog to display dialog "Please enter your Mac password." & return & "(This is the password you created while registering your Mac)" default answer "" buttons {"Quit", "OK"} default button 2 with title "Wireless Setup" with hidden answer
set myMacPass to the text returned of myMacPassDialog
if button returned of myMacPassDialog is "Quit" then
tell me
do shell script "echo \"exit 99 User cancelled installation.\" 2>&1 > " & ERRORLOG
do shell script "echo \"exit 99 User cancelled installation.\" 2>&1 >> " & LOGS
tell application "Installer" to activate
return
end tell
end if
-- Test to see if Mac Password is correct
tell me
try
do shell script "sudo touch /private/tmp/mac_password_test" user name theUser password myMacPass with administrator privileges
if myMacPass is "" then
tell application "Finder"
activate
tell me
do shell script "echo \"exit 98 Cancelled installation due to blank Mac password.\" 2>&1 > " & ERRORLOG
do shell script "echo \"exit 98 Cancelled installation due to blank Mac password.\" 2>&1 >> " & LOGS
end tell
set dialogReply to display dialog "It is HIGHLY recommended that your Mac Password not be blank due to security concerns." & return & return & "You MUST create a Mac password to continue using this installer." & return & return & "Please create a Mac Password by clicking the 'Create Mac Password' button below. Then click the 'Change Password' button that appears in the next window." & return & return & "This installer will now exit with an error. Please run it again after creating a Mac Password." with title "Wireless Setup" buttons {"Quit", "Create Mac Password"} default button 2 with icon caution
tell application "Installer" to activate
set myMacPassTest to ""
if button returned of dialogReply is "Create Mac Password" then
tell application "System Preferences"
activate
reveal anchor "passwordPref" of pane "Accounts"
activate pane id "com.apple.preferences.users"
end tell
end if
return
end tell
end if
set myMacPassTest to "true"
on error
tell application "Finder"
activate
set dialogReply to display dialog "Mac Password entered was incorrect, please try again." with title "Wireless Setup" buttons {"Quit", "OK"} default button 2 with icon caution
set myMacPassTest to ""
if button returned of dialogReply is "Quit" then
tell me
do shell script "echo \"exit 99 User cancelled installation.\" 2>&1 > " & ERRORLOG
do shell script "echo \"exit 99 User cancelled installation.\" 2>&1 >> " & LOGS
tell application "Installer" to activate
return
end tell
end if
end tell
end try
end tell
end repeat
end tell

-- cleanup password test file
do shell script "sudo rm -rf /private/tmp/mac_password_test" user name theUser password myMacPass with administrator privileges

-- Bring Installer.app to frontmost
tell application "Installer" to activate

return myMacPass
end run

get_wireless_pass.scpt


-- Script created
-- by Bryan S. Lee 2009

-- Prompt for Network username and password. Write username to a file and return the password to the main script
-- This script expects to receive the Mac Admin password, Logs locations and MBAirPresent variable from the parent script as arguments
-- Ex. osascript /path/to/this/script $MACPASS $LOG $ERRORLOG $MBAirPresent

on run argv
set myMacPass to item 1 of argv
set LOGS to item 2 of argv
set ERRORLOG to item 3 of argv
set MBAirPresent to item 4 of argv
set theUser to (do shell script "echo $USER")
set myPass to ""
set counter to 1

tell application "Finder"
activate
repeat until myPass is not ""
if counter < 6 then
set acctBox to display dialog "Please enter your wireless USERNAME" & return & "(Ex. USERNAME@somedomain.edu)" default answer "" buttons {"Quit", "OK"} default button 2 with title "Wireless Setup"
set myAcct to the text returned of acctBox
if button returned of acctBox is "Quit" then
tell me
do shell script "echo \"exit 99 User cancelled installation.\" 2>&1 > " & ERRORLOG
do shell script "echo \"exit 99 User cancelled installation.\" 2>&1 >> " & LOGS
end tell
tell application "Installer" to activate
return
end if
if button returned of acctBox is "OK" then
if myAcct is not "" then

-- Remove any trailing @mydomain.com information from network name
if myAcct contains "@" then
set myAcct to text 1 through ((offset of "@" in myAcct) - 1) of myAcct
end if

-- Test to see if Network password is correct
set myPassBox to display dialog "Please enter your wireless password:" & return & return & "Be careful to enter it correctly!" & return & "This password is case-sensitive!" default answer "" buttons {"Quit", "OK"} default button 2 with title "Wireless Setup" with hidden answer
if button returned of myPassBox is "Quit" then
tell me
do shell script "echo \"exit 99 User cancelled installation.\" 2>&1 > " & ERRORLOG
do shell script "echo \"exit 99 User cancelled installation.\" 2>&1 >> " & LOGS
end tell
tell application "Installer" to activate
return
end if
set myPass to the text returned of myPassBox

-- test to see if network password is blank
if myPass is not "" then

-- Convert any illegal symbols in password to hexadecimal to function correctly in URL of Volume mount test
try
tell me
set fixedPassword to do shell script "python -c 'import sys, urllib; print urllib.quote(sys.argv[1])' " & quoted form of myPass
end tell
on error
tell me
do shell script "echo \"exit 90 Password possibly contains unsupported characters, such as backslash or double quotes. Please reset password and try again.\" 2>&1 > " & ERRORLOG
do shell script "echo \"exit 90 Password possibly contains unsupported characters, such as backslash or double quotes. Please reset password and try again.\" 2>&1 >> " & LOGS
end tell
tell application "Finder"
set dialogReply to display dialog "Password possibly contains unsupported characters, such as backslash or double quotes. Please reset password and try again." buttons {"Reset Password", "Quit"} default button 1 with icon caution
if button returned of dialogReply is "Reset Password" then
open location "https://reset.password.webpage.edu"
else
return
end if
end tell
tell application "Installer"
activate
end tell
return
end try

-- Test to see if Network Password is correct
if MBAirPresent is "false" then
tell me
try
do shell script "sudo mkdir '/Volumes/Share'" user name theUser password myMacPass with administrator privileges
do shell script "sudo mount_smbfs '//" & myAcct & ":" & fixedPassword & "@share.server.edu/Share' /Volumes/Share/" user name theUser password myMacPass with administrator privileges
on error
do shell script "sudo rmdir /Volumes/Share/" user name theUser password myMacPass with administrator privileges
set myPass to ""
if counter < 5 then
tell application "Finder"
display dialog "Password entered was incorrect or network cable was disconnected. Please check cable and try again." with title "Wireless Setup" buttons {"OK"} default button 1 with icon caution
end tell
do shell script "echo \"Network password entered incorrectly or wired connection failure, asking user to re-enter and trying again...\" 2>&1 >> " & LOGS
end if
end try
end tell
end if
else
display dialog "Password cannot be blank!" buttons {"OK"} default button 1 with icon caution
end if
else
display dialog "Username cannot be blank!" buttons {"OK"} default button 1 with icon caution
end if
end if
else
tell me
do shell script "echo \"exit 2 Password not accepted by network.\" 2>&1 > " & ERRORLOG
do shell script "echo \"exit 2 Password not accepted by network.\" 2>&1 >> " & LOGS
end tell
tell application "Finder"
set dialogReply to display dialog "Password is not accepted. Possibly due to a case-sensitivity difference. Please reset your password and try again." buttons {"Reset Password", "Quit"} default button 1 with icon caution
if button returned of dialogReply is "Reset Password" then
open location "https://change.password.webpage.edu"
end if
set myPass to "exit loop"
end tell
tell application "Installer"
activate
end tell
return
end if
set counter to counter + 1
end repeat
end tell
delay 0.5
if MBAirPresent is "false" then
try
do shell script "sudo umount /Volumes/Share/" user name theUser password myMacPass with administrator privileges
on error
do shell script "echo \"exit 3 Could not unmount network test drive.\" 2>&1 > " & ERRORLOG
do shell script "echo \"exit 3 Could not unmount network test drive.\" 2>&1 >> " & LOGS
tell application "Finder"
display dialog "Could not disconnect network drive during network password test" buttons {"OK"} default button 1 with icon caution
end tell
tell application "Installer"
activate
end tell
return
end try
end if

-- Write username to file for parent script to pickup
tell me
do shell script "touch /private/tmp/wireless/WirelessUserNameIs" & myAcct user name theUser password myMacPass with administrator privileges
end tell

tell application "Installer"
activate
end tell

-- Send wireless password to parent script
return myPass

end run

 

setup_wireless_keychain.scpt


-- Script created
-- by Bryan S. Lee 2009

-- This script will remove all necessary keychain items.
-- This includes previous keychain entry and legacy network keychain items.
-- Then it will add the new keychain item
-- Removal Section of script should be edited with the names of the keychains you wish to be removed

-- IMPORTANT INFO!!!
-- This script expects to receive the following as arguments directly following the command:
-- Mac Administrative password
-- Name of the wireless
-- UUID (Unique ID number)
-- Wireless Network Username
-- Wireless Network password

-- Like the sample below
-- osascript path_to_this_script.scpt MacPassword WirelessName UUID WirelessUsername WirelessPassword

on run argv
-- set incoming variables
set MacPassword to item 1 of argv
set WirelessName to item 2 of argv
set UUID to item 3 of argv
set USER to item 4 of argv
set pass to item 5 of argv
set LOGS to item 6 of argv
set ERRORLOG to item 7 of argv

-- Set other variables
set KeychainName to "WPA: " & WirelessName

-- Removal Section (PLEASE EDIT AS NECESSARY)
try
tell application "Keychain Access"
quit
end tell
tell application "Keychain Scripting"
tell keychain "login.keychain"
unlock with password MacPassword
repeat 5 times -- to catch possible, multiple keychain items with same name
repeat with this_key in (get keys)
if (get name of this_key) = KeychainName then
do shell script "echo \"Keychain item, wireless_name, found...\" 2>&1 >> " & LOGS
delete this_key
do shell script "echo \"Keychain item, wireless_name, deleted...\" 2>&1 >> " & LOGS
exit repeat
end if
end repeat
repeat with this_key in (get keys)
if (get name of this_key) = "Network password for wireless_name Profile" then
do shell script "echo \"Keychain item, Network password for wireless_name Profile, found...\" 2>&1 >> " & LOGS
delete this_key
do shell script "echo \"Keychain item, Network password for wireless_name Profile, deleted...\" 2>&1 >> " & LOGS
exit repeat
end if
end repeat
repeat with this_key in (get keys)
if (get name of this_key) = "wireless_name2" then
do shell script "echo \"Keychain item, wireless_name2, found...\" 2>&1 >> " & LOGS
delete this_key
do shell script "echo \"Keychain item, wireless_name2, deleted...\" 2>&1 >> " & LOGS
exit repeat
end if
end repeat
end repeat
end tell
end tell
on error
do shell script "echo \"exit 4 Error attempting to remove previous wireless keychain items. Probably due to a corrupt login.keychain. Please remove and try again.\" 2>&1 > " & ERRORLOG
do shell script "echo \"exit 4 Error attempting to remove previous wireless keychain items. Probably due to a corrupt login.keychain. Please remove and try again.\" 2>&1 >> " & LOGS
tell application "Finder"
activate
display dialog "Error attempting to remove previous wireless keychain items. Probably due to a corrupt login.keychain. Please remove and try again." buttons {"OK"} default button 1 with icon caution
end tell
tell application "Installer"
activate
end tell
return
end try

-- This section will add the keychain item to the login.keychain and create all necessary settings except setting ACL for eapolclient

tell application "Keychain Scripting"
tell keychain "login.keychain"
unlock with password MacPassword
set namename to KeychainName
set servicename to UUID
set accountname to USER
set commentname to " Wireless Installer created by Bryan S. Lee and maintained by Your_name "
set passwordname to pass
try
make new generic key with properties {name:namename, kind:"application password", account:accountname, service:servicename, comment:commentname, password:passwordname}
on error
do shell script "echo \"exit 5 Error attempting to create wireless keychain item.\" 2>&1 > " & ERRORLOG
do shell script "echo \"exit 5 Error attempting to create wireless keychain item.\" 2>&1 >> " & LOGS
tell application "Finder"
activate
display dialog "Error attempting to create wireless keychain item." buttons {"OK"} default button 1 with icon caution
end tell
tell application "Installer"
activate
end tell
return
end try
end tell
end tell
end run

 

allow_keychain_acl.scpt


-- Script created
-- by Bryan S. Lee 2009
-- This script will wait for the until the Security Agent prompts the user
-- to Alway Allow, Deny or Allow the eapolclient to access the keychain item
-- then it will select Always Allow

-- This script expects to receive the Logs location and Error Logs location from the parent script as arguments
-- Ex. osascript /path/to/this/script $LOG $ERRORLOG

on run argv

set theUser to (do shell script "echo $USER")
set myMacPass to item 1 of argv
set LOGS to item 2 of argv
set ERRORLOG to item 3 of argv
set counter to 0

-- Leaving Sys Prefs open can cause a conflict
tell application "System Preferences" to quit

 

try
-- restart the Finder to make sure it notices that Assistive Devices is turned on
tell application "System Events"
repeat until (name of every process) does not contain "Finder"
tell application "Finder" to quit
delay 1
end repeat
end tell
tell application "Finder" to launch
tell application "System Events"
repeat until exists process "Finder"
delay 1
end repeat
end tell
delay 1
tell application "Installer" to activate
tell application "System Events"
tell application process "SecurityAgent"
repeat until (exists window 1)
delay 0.1
if counter > 900 then
do shell script "echo \"exit 6 Setting ACL of keychain timed out.\" 2>&1 > " & ERRORLOG
do shell script "echo \"exit 6 Setting ACL of keychain timed out.\" 2>&1 >> " & LOGS
tell application "Finder"
activate
display dialog "Setting ACL of keychain timed out, possibly due to weak wireless signal." & return & return & "If a dialog appears later asking to allow the EAPOLCLIENT access to your password, click 'ALWAYS ALLOW', or try the installer again within range of the wireless signal." buttons {"OK"} default button 1 with icon caution
end tell
tell application "Installer"
activate
end tell
return
end if
set counter to counter + 1
end repeat
click button "Always Allow" of group 1 of window 1
end tell
end tell
on error
do shell script "echo \"exit 7 Encountered an error attempting to set ACL of keychain. Possibly due to Assistive Devices being off.\" 2>&1 > " & ERRORLOG
do shell script "echo \"exit 7 Encountered an error attempting to set ACL of keychain. Possibly due to Assistive Devices being off.\" 2>&1 >> " & LOGS
tell application "Finder"
activate
display dialog "An error occurred that requires a restart of your computer." & return & return & "Please restart your computer and try the wireless installer again." buttons {"OK"} default button 1 with icon caution
end tell
tell application "Installer"
activate
end tell
end try
end run

Rhinoism of the Day March 25, 2009

Posted by bigmaconcampus in Uncategorized.
add a comment

“BRITISH… are the original English…”

In response to my explanation of why British people don’t speak funny, it’s us (Americans) that speak funny.

Rhinoisms March 9, 2009

Posted by bigmaconcampus in Uncategorized.
add a comment

What will probably wind up being a semi-regular feature in this forum, are what I happily dubbed Rhinoisms. Child number 2, whose nickname is Rhino (due to the closeness of her name to the large creatures, not that she looks like a line-backer) comes up with the most thought-provoking comments from time to time and I can’t help but try to jot them down or save them for the Coke-out-the-nose experience I get from them sometimes.

Previous contenders for the Douglas Adams Deep Thought award go to:

  • “They’re not french, they’re people.”
  • “When I grow up, I want to be a zookeeper and an artist, because monkeys are interesting.”
  • “I didn’t get all these gifts for Christmas when I was a kid” said the Dad. “But Daddy, that’s because you were bad.” said the Rhino
  • “When I hum, it tastes like cheese.”
  • “Don’t worry, you’re going to live for the rest of your life.”

Today’s entry is:

  • “Why ARE pandas so fat?”

Day one and counting… March 9, 2009

Posted by bigmaconcampus in Uncategorized.
add a comment

Stay tuned for varied ramblings, musings, techno-babble and other assorted items with my own personal skewed views. Centers around the day-to-day oddities of raising 4 kids and finding time trying to keep up with techie life at a major University.