Skip to content

Commit

Permalink
Teach osx-randmac to randomize everyday.
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] committed Mar 11, 2016
1 parent 233001d commit 8f8f380
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 79 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ to launchd control.::
osx-ipfw.sh Enable ipfw(8) with a default set of secure rules
osx-noatime.sh Enable noatime mounts on all disks
osx-ramfs.sh Put /tmp and /var/run under a RAMFS
osx-randmac.sh Randomize your MAC address at every boot. Designed to auto-detect your wifi
interface and use it with that.
osx-randmac.sh Randomize your MAC address every day. Designed to auto-detect your wifi
interface. Run it without any args to see usage.
osx-tuntap.sh Make your tun-tap driver persistent.


Expand Down
166 changes: 89 additions & 77 deletions osx-randmac.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

#
# Setup OS X with a random mac address for WiFi or a specific
# interface.
# interface. The MAC address on the specified iface is randomized
# every day (24 hours). This script uses a systemwide LaunchAgent to
# trigger the periodic MAC refresh.
#
# Author: Sudhi Herle <sudhi-at-herle-net>
# (c) Sudhi Herle 2013-2016
# License: GPLv2
#
# Order of doing things
# - disassociate from any network
Expand All @@ -16,10 +22,38 @@ airport=/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport
net=/usr/sbin/networksetup
ipconfig=/usr/sbin/ipconfig
Z=`basename $0`
DATE=/bin/date
STAT=/usr/bin/stat
TOUCH=/usr/bin/touch
PROG=$0
Me=`id -u`

# Debug hook
#e=echo

Installdir=/Library/LaunchDaemons
Bindir=/usr/sbin

PATH=/sbin:/usr/sbin:/bin:/usr/bin:$PATH
export PATH


function die {
echo "$Z: $@" 1>&2
exit 1
}


if [ $Me -ne 0 ]; then
echo "$Z: Need root privilege to install system-wide; switching to dry-run mode .."
Installdir=/tmp/LaunchAgents
Bindir=/tmp/bin
e=echo

mkdir -p $Installdir $Bindir
fi


#set -x

# First dump existing config to stderr
Expand All @@ -29,15 +63,15 @@ function usage {
cat 1>&2 <<EOF1
$Z - Randomize MAC address of OS X WiFi (or any given interface).
Usage: $Z start|update|stop|restartinstall [IFACE]
Usage: $Z start|update|stop|restart|install [IFACE]
If no interface is specified, the script automatically detects and
uses the WiFi interface. Description of actions:
start, update: Update MAC Address
stop: No Op
restart: No op
install: Creates a system startup file in /System/Library/LaunchDaemons/$FNAME.plist
install: Creates a launchd file in /Library/LaunchDaemons
EOF1

exit 1
Expand All @@ -47,50 +81,25 @@ uname=`uname`
case $uname in
Darwin);;

*) echo "$0: This script is meant for Mac OS X only." 1>&2
exit 1
*) die "This script is meant for Mac OS X only."
;;
esac

action=$1
if [ -z "$action" ]; then
usage
exit 1
fi
test -n "$action" || usage
shift

# Ideally, this should be installed at the system wide level.
# If you install it on a per-user basis, make sure you tie it to laptop lid-wake events.
# sleepwatcher is your friend.
systemwide=1

if [ -n "$systemwide" ]; then
installdir=/System/Library/LaunchDaemons
bindir=/usr/sbin
else
installdir=/Library/LaunchDaemons
bindir=/etc
fi



me=`id -u`
if [ $me -ne 0 ]; then
echo "$Z: Need root privilege to run; switching to dry-run mode .."
e=echo
fi
function writelog {
$e logger -p "daemon.info" -t "${FNAME}" "$@"
}

#set -x

function grok_wifi_darwin {
typeset iface=$1

if [ -n "$iface" ]; then
n=$(ifconfig $iface 2>/dev/null | wc -l)
if [ $n -eq 0 ]; then
echo "$Z: $iface is not a network interface?" 1>&2
exit 2
fi
test $n -gt 0 || die "$iface is not a network interface?"
else
# grok the wifi interface

Expand All @@ -99,25 +108,17 @@ function grok_wifi_darwin {

if [ -z "$xx" ]; then
echo list | scutil 1>&2
echo "$Z: Whoa. Can't find any WiFi interface!" 1>&2
exit 1
die "Whoa. Can't find any WiFi interface!"
fi

typeset dx=`dirname $xx`
iface=`basename $dx`

if [ -z "$iface" ]; then
echo "$Z: Can't grok WiFi Interface. Are you connected via WiFi?" 1>&2
exit 1
fi
test -n "$iface" || die "Can't grok WiFi Interface. Are you connected via WiFi?"
fi

# Now, lets make sure this is really a wireless interface
xx=`$net -getairportnetwork $iface`
if [ $? -ne 0 ]; then
echo "$Z: $iface doesn't look like a WiFi interface.." 1>&2
exit 1
fi
test $? -eq 0 || die "$iface doesn't look like a WiFi interface.."

echo $iface
}
Expand Down Expand Up @@ -151,18 +152,14 @@ function wait_wifi_darwin {

# Now, lets make sure this is really a wireless interface
xx=`$net -getairportnetwork $iface`
if [ $? -ne 0 ]; then
echo "$Z: $iface doesn't look like a WiFi interface.." 1>&2
exit 1
fi
test $? -eq 0 || die "$iface doesn't look like a WiFi interface.."

echo $iface
return 0

done

echo "$Z: Can't grok WiFi interface after 10 tries!" 1>&2
exit 1
die "Can't grok WiFi interface after 10 tries!"
}


Expand All @@ -171,10 +168,7 @@ function verify_wifi_Darwin {
typeset iface=$1
typeset x=`echo list | scutil | grep "State:/Network/Interface/$iface/AirPort"`

if [ -z "$x" ]; then
echo "$Z: $iface is not a WiFi interface" 1>&2
return 1
fi
test -n "$x" || die "$iface is not a WiFi interface"
$e ifconfig $iface down
return 0
}
Expand Down Expand Up @@ -205,6 +199,7 @@ function _randmac {
echo "$pref:$a1:$a2:$a3"
}


function update_mac {
typeset iface=$1
typeset mac=$(_randmac)
Expand All @@ -225,28 +220,28 @@ function update_mac {

$e $net -detectnewhardware

$e writelog "$iface: MAC updated to $mac"

return 0
}


# Installs a startup service
function install_service {
typeset iface=$1
typeset fname=${2}.$iface
typeset bn=`basename $Z`
typeset prog=$bindir/$bn
typeset prog=$Bindir/$bn

if [ $me -ne 0 ]; then
installdir=/tmp
fi

typeset file=$installdir/${FNAME}.plist
typeset file=$Installdir/${fname}.plist

cat > $file <<EOF2
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>$FNAME</string>
<string>$fname</string>
<key>Disabled</key>
<false/>
Expand All @@ -260,55 +255,72 @@ function install_service {
<key>KeepAlive</key>
<false/>
<key>Debug</key>
<false/>
<key>RunAtLoad</key>
<true/>
<key>AbandonProcessGroup</key>
<true/>
<!-- Randomize the MAC at 0600 every day -->
<key>StartCalendarInterval</key>
<dict>
<key>Minute</key>
<integer>0</integer>
<key>Hour</key>
<integer>6</integer>
</dict>
<key>ProgramArguments</key>
<array>
<string>$prog</string>
<string>start</string>
<string>update</string>
<string>$iface</string>
</array>
</dict>
</plist>
EOF2

$e cp $0 $prog
test -d $Bindir || $e mkdir -p $Bindir
$e cp $PROG $prog
$e chmod a+rx,og-w $prog

$e launchctl load $file
$e launchctl enable system/$fname

echo "Installed to $file and $prog .."

return 0
}

# -- start of main() --

iface=$1
if [ -z "$iface" ]; then
iface=`wait_wifi_darwin`

if [ -z "$iface" ]; then
echo "$Z: Can't figure out the WiFi interface. Aborting..." 1>&2
exit 1
fi
test -n "$iface" || die "Can't figure out the WiFi interface. Aborting..."
else
verify_wifi_Darwin $iface
if [ $? -ne 0 ]; then
exit 1
fi
test $? -eq 0 || exit 1
fi
FNAME=${FNAME}.$iface

$e ifconfig $iface down

case $action in
start|update)
#echo "Setting MAC Address for $iface .."
if [ $Me -ne 0 ]; then
die "Need root privileges to set/update MAC address"
fi

$e ifconfig $iface down
update_mac $iface
;;

install)
install_service
install_service ${iface} ${FNAME}
;;

stop|restart)
Expand Down

0 comments on commit 8f8f380

Please sign in to comment.