Last active
September 24, 2018 19:58
-
-
Save haircut/b5d5bea915a58c9b61160c857e7a08a2 to your computer and use it in GitHub Desktop.
Forget all saved SSIDs with whitelisting
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: utf-8 -*- | |
''' | |
Forget saved SSIDs with whitelisting | |
This script removes ALL saved SSIDs on a Mac except for those configured in a | |
whitelist – see SSID_WHITELIST variable below. | |
Thanks to @sepiemoini for suggestion of "MERGE_CURRENT_SSID" behavior | |
author: Matthew Warren | |
@haircut on #macadmins slack | |
created: 2018-04-20 | |
modified: 2018-09-24 | |
''' | |
import objc | |
import subprocess | |
from SystemConfiguration import SCNetworkInterfaceGetLocalizedDisplayName, \ | |
SCNetworkInterfaceGetBSDName, \ | |
SCNetworkInterfaceGetHardwareAddressString, \ | |
SCNetworkInterfaceCopyAll | |
# SSIDs to skip and NOT remove | |
# NOTE: If you configure Wi-Fi via Configuration Profile you must exclude those | |
# configured SSIDs here. The `networksetup` binary does not care about | |
# your profiles! | |
SSID_WHITELIST = ['DoNotRemove', 'CorpWifi', 'onboarding'] | |
# Merge currently-connected SSID into whitelist? | |
# If `True`, the SSID to which the device is currently connected will be merged | |
# into the whitelist and not removed from the preferred SSID list. This is | |
# is provided as an option in case you DO want to remove a particular SSID even | |
# if the device is currently connected. Set to `False` if you prefer the latter | |
# behavior. | |
MERGE_CURRENT_SSID = True | |
# Completion message | |
# This message is displayed in a dialog after non-whitelisted SSIDs are removed | |
COMPLETE_MSG = """ | |
All non-institutional networks have been forgotten. You may need to reconnect | |
to your home network and re-enter its password. | |
""" | |
# Managed Mac? | |
# If False, the completion dialog will simply appear on screen | |
# If 'jamf', the Self Service application will come to the foreground and | |
# display the completion dialog | |
# If 'munki', the Managed Software Center application will come to the | |
# foreground and display the completion dialog | |
# examples: | |
# MANAGED = False | |
# MANAGED = 'jamf' | |
# MANAGED = 'munki' | |
MANAGED = 'jamf' | |
def getwifiinterface(): | |
'''Returns the name of the wifi interface''' | |
network_interfaces = SCNetworkInterfaceCopyAll() | |
interfaces = {} | |
for interface in network_interfaces: | |
interfaces[SCNetworkInterfaceGetLocalizedDisplayName(interface)] = ( | |
SCNetworkInterfaceGetBSDName(interface), | |
SCNetworkInterfaceGetHardwareAddressString(interface) | |
) | |
wifi_interface = None | |
try: | |
wifi_interface = interfaces['Wi-Fi'][0] | |
except KeyError: | |
pass | |
return wifi_interface | |
def get_current_ssid(): | |
'''returns the current SSID''' | |
wifi_ssid = None | |
objc.loadBundle('CoreWLAN', | |
bundle_path='/System/Library/Frameworks/CoreWLAN.framework', | |
module_globals=globals()) | |
wifi = CWInterface.interfaceNames() | |
if wifi: | |
for iname in wifi: | |
interface = CWInterface.interfaceWithName_(iname) | |
if interface: | |
try: | |
wifi_ssid = interface.ssid() | |
except AttributeError: | |
pass | |
return wifi_ssid | |
def getssids(interface): | |
'''Returns a list of saved SSIDs for the provided interface''' | |
cmd = ['networksetup', '-listpreferredwirelessnetworks', interface] | |
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
output, _ = proc.communicate() | |
return [item.strip() for item in output.splitlines()[1:]] | |
def removessid(ssid, interface): | |
''' | |
Removes the passed ssid from the preferred SSID list on the passed | |
interface | |
''' | |
cmd = ['networksetup', '-removepreferredwirelessnetwork', interface, ssid] | |
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
output, _ = proc.communicate() | |
return True if proc.returncode == 0 else False | |
def osascript(osastring): | |
'''Wrapper to run AppleScript commands''' | |
cmd = ['/usr/bin/osascript', '-e', osastring] | |
proc = subprocess.Popen(cmd, shell=False, bufsize=1, | |
stdin=subprocess.PIPE, | |
stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
(out, err) = proc.communicate() | |
if proc.returncode != 0: | |
print >> sys.stderr, 'Error: ', err | |
if out: | |
return str(out).decode('UTF-8').rstrip('\n') | |
def alertcomplete(): | |
'''Alerts user process is complete''' | |
# determine which management app should display the completion dialog | |
if MANAGED == 'jamf': | |
mgmtapp = 'Self Service' | |
elif MANAGED == 'munki': | |
mgmtapp = 'Managed Software Center' | |
else: | |
mgmtapp = 'System Events' | |
# bring management app to foreground | |
osascript('tell application "%s" to activate' % mgmtapp) | |
# show dialog | |
cmd = ('tell application "%s" to display dialog "%s" buttons {"Okay"} ' | |
'with icon note giving up after 120' % (mgmtapp, COMPLETE_MSG)) | |
prompt = osascript(cmd) | |
def main(): | |
'''Main''' | |
interface = getwifiinterface() | |
ssids = getssids(interface) | |
if MERGE_CURRENT_SSID: | |
current_ssid = get_current_ssid() | |
if current_ssid is not None: | |
if current_ssid not in SSID_WHITELIST: | |
SSID_WHITELIST.append(current_ssid) | |
for ssid in ssids: | |
if ssid not in SSID_WHITELIST: | |
if removessid(ssid, interface): | |
print "Removed SSID", ssid | |
else: | |
print "Unable to remove SSID", ssid | |
alertcomplete() | |
if __name__ == '__main__': | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment