PageRenderTime 62ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/Winnebago/wifiutil.py

https://github.com/deanofmac/winnebago
Python | 1343 lines | 1287 code | 19 blank | 37 comment | 43 complexity | 8d696c84296d71e651027aee122d30d5 MD5 | raw file
Possible License(s): MPL-2.0
  1. #!/usr/bin/python
  2. __author__ = 'Zack Smith (@acidprime)'
  3. __version__ = '1.0'
  4. import os
  5. import getopt
  6. import uuid
  7. import plistlib
  8. import sys
  9. import shutil
  10. import subprocess
  11. import commands
  12. import re
  13. import time
  14. from Cocoa import NSData,NSString,NSDictionary,NSMutableDictionary,NSPropertyListSerialization,NSDate
  15. from Cocoa import NSUTF8StringEncoding,NSPropertyListImmutable
  16. # Commands used by this script
  17. airport = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport'
  18. eapolclient = '/System/Library/SystemConfiguration/EAPOLController.bundle/Contents/Resources/eapolclient'
  19. if not os.path.exists(eapolclient):
  20. # Leopard Location, used by security command for ACL
  21. eapolclient = '/System/Library/SystemConfiguration/EAPOLController.bundle/Resources/eapolclient'
  22. runDirectory = os.path.dirname(os.path.abspath(__file__))
  23. networksetup = '/usr/sbin/networksetup'
  24. profiles = '/usr/bin/profiles'
  25. plutil = '/usr/bin/plutil'
  26. sysctl = '/usr/sbin/sysctl'
  27. security = '/usr/bin/security'
  28. sudo = '/usr/bin/sudo'
  29. system_profiler = '/usr/sbin/system_profiler'
  30. who = '/usr/bin/who'
  31. # Added for 10.5 support
  32. kcutil = '%s/%s' % (runDirectory,'kcutil')
  33. def showUsage():
  34. print '''
  35. wifutil: A multi OS version wireless configuration tool
  36. Syntax:
  37. ## 802.1X PEAP Example (Username & Password are Required for non WPA2)
  38. wifiutil --username="zsmith" --password='d0gc4t' --plist="settings.plist"
  39. ## WPA2 Example
  40. wifiutil --plist="/Library/Preferences/com.318.wifi.plist"
  41. Options:
  42. -f | --plist= ## Path to a plist to read configuration information from
  43. This will override any other provided options!
  44. -u | --username= ## The username used to access the wireless
  45. -p | --password= ## The password used to access the wireless
  46. -d | --debug ## Echo commands (and passwords!) in clear text
  47. '''
  48. # Check scripts as root
  49. if not os.geteuid() == 0:
  50. showUsage()
  51. print '--> This script requires root access!'
  52. sys.exit(1)
  53. def createEAPProfile(path,uid,gid,networkDict):
  54. if os.path.exists(path):
  55. plist = NSMutableDictionary.dictionaryWithContentsOfFile_(path)
  56. else:
  57. plist = NSMutableDictionary.alloc().init()
  58. plist['Profiles'] = []
  59. # item entry
  60. _Profiles = {}
  61. # EAPClientConfiguration
  62. EAPClientConfiguration = {}
  63. AcceptEAPTypes = []
  64. _AcceptEAPTypes = networkDict['eapt']
  65. AcceptEAPTypes = [_AcceptEAPTypes]
  66. # Top Level EAPClientConfiguration keys
  67. EAPClientConfiguration['AcceptEAPTypes'] = AcceptEAPTypes
  68. EAPClientConfiguration['Description'] = 'Automatic'
  69. EAPClientConfiguration['EAPFASTProvisionPAC'] = True
  70. EAPClientConfiguration['EAPFASTUsePAC'] = True
  71. EAPClientConfiguration['TLSVerifyServerCertificate'] = False
  72. EAPClientConfiguration['TTLSInnerAuthentication'] = networkDict['iath']
  73. EAPClientConfiguration['UserName'] = networkDict['user']
  74. EAPClientConfiguration['UserPasswordKeychainItemID'] = networkDict['keyc']
  75. if not osVersion['minor'] == LEOP:
  76. EAPClientConfiguration['Wireless Security'] = networkDict['type']
  77. # Top Level item keys
  78. _Profiles['EAPClientConfiguration'] = EAPClientConfiguration
  79. _Profiles['UniqueIdentifier'] = networkDict['keyc']
  80. _Profiles['UserDefinedName'] = 'WPA: %s' % networkDict['ssid']
  81. if not osVersion['minor'] == LEOP:
  82. _Profiles['Wireless Security'] = networkDict['type']
  83. # Merge the data with current plist
  84. plist['Profiles'].append(_Profiles)
  85. exportFile = path
  86. plist.writeToFile_atomically_(exportFile,True)
  87. try:
  88. os.chown(path,uid,gid)
  89. except:
  90. print 'Path not found %s' % path
  91. def getAirportMac():
  92. # Script Created Entry
  93. port = getPlatformPortName()
  94. arguments = [networksetup,
  95. "-getmacaddress",
  96. port]
  97. execute = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  98. out, err = execute.communicate()
  99. parse = out.split()
  100. return parse[2]
  101. def createEAPBinding(path,uid,gid,networkDict):
  102. macAddress = getAirportMac()
  103. if os.path.exists(path):
  104. plist = NSMutableDictionary.dictionaryWithContentsOfFile_(path)
  105. else:
  106. plist = NSMutableDictionary.alloc().init()
  107. plist[macAddress] = []
  108. _item = {}
  109. _item['UniqueIdentifier'] = networkDict['keyc']
  110. _item['Wireless Network'] = networkDict['ssid']
  111. plist[macAddress].append(_item)
  112. exportFile = path
  113. plist.writeToFile_atomically_(exportFile,True)
  114. try:
  115. os.chown(path,uid,gid)
  116. except:
  117. print 'Path not found %s' % path
  118. def createRecentNetwork(networkDict):
  119. path = '/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist'
  120. # Set to root as the owner for good measure
  121. uid = 0
  122. gid = 80
  123. if os.path.exists(path):
  124. plist = NSMutableDictionary.dictionaryWithContentsOfFile_(path)
  125. else:
  126. plist = NSMutableDictionary.alloc().init()
  127. port = getPlatformPortName()
  128. # Check for non-existant keys
  129. if not port in plist.keys():
  130. plist[port] = {}
  131. # Make sure the Array is there
  132. if not 'RecentNetworks' in plist[port].keys():
  133. plist[port]['RecentNetworks'] = []
  134. _RecentNetworks = {}
  135. _RecentNetworks['SSID_STR'] = networkDict['ssid']
  136. _RecentNetworks['SecurityType'] = networkDict['sect']
  137. _RecentNetworks['Unique Network ID'] = networkDict['guid']
  138. _RecentNetworks['Unique Password ID'] = networkDict['keyc']
  139. plist[port]['RecentNetworks'].append(_RecentNetworks)
  140. exportFile = path
  141. plist.writeToFile_atomically_(exportFile,True)
  142. try:
  143. os.chown(path,uid,gid)
  144. except:
  145. print 'Path not found %s' % path
  146. def createKnownNetwork(networkDict):
  147. print 'Creating KnownNetworks entry'
  148. # There were some MacBook Airs that shipped with 10.5
  149. path = '/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist'
  150. # Set to root as the owner for good measure
  151. uid = 0
  152. gid = 80
  153. if os.path.exists(path):
  154. plist = NSMutableDictionary.dictionaryWithContentsOfFile_(path)
  155. else:
  156. plist = NSMutableDictionary.alloc().init()
  157. plist['KnownNetworks'] = {}
  158. guid = networkDict['guid']
  159. plist['KnownNetworks'][guid] = {}
  160. plist['KnownNetworks'][guid]['SSID_STR'] = networkDict['ssid']
  161. plist['KnownNetworks'][guid]['Remembered channels'] = [networkDict['chan'],]
  162. plist['KnownNetworks'][guid]['SecurityType'] = networkDict['sect']
  163. # If we are adding a non WPA2 Enterprise network add the keychain item
  164. if networkDict['type'] == 'WPA2':
  165. plist['KnownNetworks'][guid]['Unique Password ID'] = networkDict['keyc']
  166. plist['KnownNetworks'][guid]['_timeStamp'] = NSDate.date()
  167. exportFile = path
  168. plist.writeToFile_atomically_(exportFile,True)
  169. try:
  170. os.chown(path,uid,gid)
  171. except:
  172. print 'Path not found %s' % path
  173. def addKeychainPassword(arguments):
  174. # Script Created Entry
  175. print 'Adding password to keychain'
  176. if(debugEnabled):printCommand(arguments)
  177. execute = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  178. out, err = execute.communicate()
  179. print out
  180. def createLeopEAPkeychainEntry(networkDict):
  181. users = '/var/db/dslocal/nodes/Default/users'
  182. listing = os.listdir(users)
  183. for plist in listing:
  184. # Hardware test for Air
  185. excluded = re.compile("^((?!^_|root|daemon|nobody|com.apple.*).)*$")
  186. if excluded.match(plist):
  187. plistPath = '%s/%s' % (users,plist)
  188. print 'Processing: %s' % plistPath
  189. user = NSDictionary.dictionaryWithContentsOfFile_(plistPath)
  190. try:
  191. uid = int(user['uid'][0])
  192. gid = int(user['gid'][0])
  193. for home in user['home']:
  194. keychain = home + '/Library/Keychains/login.keychain'
  195. print 'Processing keychain: %s' % keychain
  196. if os.path.exists(keychain):
  197. if user['name'][0] == getConsoleUser():
  198. arguments = [security,
  199. "add-generic-password",
  200. '-a',
  201. networkDict['ssid'],
  202. '-l',
  203. '%s-%s' % (networkDict['ssid'],networkDict['user']),
  204. '-D',
  205. 'Internet Connect',
  206. '-s',
  207. networkDict['keyc'],
  208. '-w',
  209. networkDict['pass'],
  210. '-T',
  211. 'group://Aiport',
  212. '-T',
  213. '/System/Library/CoreServices/SystemUIServer.app',
  214. '-T',
  215. '/Applications/System Preferences.app',
  216. '-T',
  217. '/usr/libexec/airportd',
  218. '-T',
  219. eapolclient,
  220. keychain]
  221. addKeychainPassword(arguments)
  222. try:
  223. os.chown(keychain,uid,gid)
  224. except:
  225. print 'Path not found %s' % keychain
  226. else:
  227. print 'User will not be modified: %s' % user['name'][0]
  228. except:
  229. print 'Key Missing, Skipping'
  230. def createSnowEAPkeychainEntry(networkDict):
  231. users = '/var/db/dslocal/nodes/Default/users'
  232. listing = os.listdir(users)
  233. for plist in listing:
  234. # Hardware test for Air
  235. excluded = re.compile("^((?!^_|root|daemon|nobody|com.apple.*).)*$")
  236. if excluded.match(plist):
  237. plistPath = '%s/%s' % (users,plist)
  238. print 'Processing: %s' % plistPath
  239. user = NSDictionary.dictionaryWithContentsOfFile_(plistPath)
  240. try:
  241. uid = int(user['uid'][0])
  242. gid = int(user['gid'][0])
  243. for home in user['home']:
  244. keychain = home + '/Library/Keychains/login.keychain'
  245. print 'Processing keychain: %s' % keychain
  246. if os.path.exists(keychain):
  247. if user['name'][0] == getConsoleUser():
  248. arguments = [security,
  249. "add-generic-password",
  250. '-a',
  251. networkDict['user'],
  252. '-l',
  253. 'WPA: %s' % networkDict['ssid'],
  254. '-D',
  255. '802.1X Password',
  256. '-s',
  257. networkDict['keyc'],
  258. '-w',
  259. networkDict['pass'],
  260. '-T',
  261. 'group://Aiport',
  262. '-T',
  263. '/System/Library/CoreServices/SystemUIServer.app',
  264. '-T',
  265. '/Applications/System Preferences.app',
  266. '-T',
  267. eapolclient,
  268. keychain]
  269. addKeychainPassword(arguments)
  270. try:
  271. os.chown(keychain,uid,gid)
  272. except:
  273. print 'Path not found %s' % keychain
  274. except:
  275. print 'Key Missing, Skipping'
  276. def createLionEAPkeychainEntry(networkDict):
  277. users = '/var/db/dslocal/nodes/Default/users'
  278. listing = os.listdir(users)
  279. for plist in listing:
  280. # Hardware test for Air
  281. excluded = re.compile("^((?!^_|root|daemon|nobody|com.apple.*).)*$")
  282. if excluded.match(plist):
  283. plistPath = '%s/%s' % (users,plist)
  284. print 'Processing: %s' % plistPath
  285. user = NSDictionary.dictionaryWithContentsOfFile_(plistPath)
  286. try:
  287. uid = int(user['uid'][0])
  288. gid = int(user['gid'][0])
  289. for home in user['home']:
  290. keychain = home + '/Library/Keychains/login.keychain'
  291. print 'Processing keychain: %s' % keychain
  292. if os.path.exists(keychain):
  293. # Clear old value
  294. if user['name'][0] == getConsoleUser():
  295. arguments = [security,
  296. "delete-generic-password",
  297. '-D',
  298. '802.1X Password',
  299. '-l',
  300. networkDict['ssid'],
  301. '-a',
  302. networkDict['user'],
  303. keychain]
  304. deleteKeychainPassword(arguments)
  305. # Add New Value
  306. arguments = [security,
  307. "add-generic-password",
  308. '-a',
  309. networkDict['user'],
  310. '-l',
  311. networkDict['ssid'],
  312. '-D',
  313. '802.1X Password',
  314. '-s',
  315. 'com.apple.network.eap.user.item.wlan.ssid.%s' % networkDict['ssid'],
  316. '-w',
  317. networkDict['pass'],
  318. '-T',
  319. 'group://Aiport',
  320. '-T',
  321. '/System/Library/CoreServices/SystemUIServer.app',
  322. '-T',
  323. '/Applications/System Preferences.app',
  324. '-T',
  325. eapolclient,
  326. keychain]
  327. addKeychainPassword(arguments)
  328. try:
  329. os.chown(keychain,uid,gid)
  330. except:
  331. print 'Path not found %s' % keychain
  332. except:
  333. print 'Key Missing, Skipping'
  334. # Need to clean this up with defaults or a dict
  335. def genLionProfile(networkDict={}):
  336. plist = NSMutableDictionary.alloc().init()
  337. # EAPClientConfiguration
  338. AcceptEAPTypes = []
  339. _AcceptEAPTypes = networkDict['eapt']
  340. AcceptEAPTypes = [_AcceptEAPTypes]
  341. tlsTrustedServerNames = []
  342. EAPClientConfiguration = {}
  343. EAPClientConfiguration['AcceptEAPTypes'] = AcceptEAPTypes
  344. EAPClientConfiguration['TTLSInnerAuthentication'] = networkDict['iath']
  345. EAPClientConfiguration['UserName'] = networkDict['user']
  346. EAPClientConfiguration['UserPassword'] = networkDict['pass']
  347. EAPClientConfiguration['tlsTrustedServerNames'] = tlsTrustedServerNames
  348. # PayloadContent
  349. PayloadContent = []
  350. _PayloadContent = {}
  351. _PayloadContent['AuthenticationMethod'] = ''
  352. _PayloadContent['EAPClientConfiguration'] = EAPClientConfiguration
  353. _PayloadContent['EncryptionType'] = 'WPA'
  354. _PayloadContent['HIDDEN_NETWORK'] = False
  355. _PayloadContent['Interface'] = 'BuiltInWireless'
  356. _PayloadContent['PayloadDisplayName'] = '%s-%s' % (networkDict['ssid'],networkDict['user'])
  357. _PayloadContent['PayloadEnabled'] = True
  358. _PayloadContent['PayloadIdentifier'] = '%s.%s.alacarte.interfaces.%s' % (networkDict['mdmh'],networkDict['puid'],networkDict['suid'])
  359. _PayloadContent['PayloadType'] = 'com.apple.wifi.managed'
  360. _PayloadContent['PayloadUUID'] = networkDict['suid']
  361. _PayloadContent['PayloadVersion'] = 1
  362. _PayloadContent['SSID_STR'] = networkDict['ssid']
  363. PayloadContent = [_PayloadContent]
  364. plist['PayloadContent'] = PayloadContent
  365. plist['PayloadDisplayName'] = networkDict['orgn']
  366. plist['PayloadIdentifier'] = '%s.%s.alacarte' % (networkDict['mdmh'],networkDict['puid'])
  367. plist['PayloadOrganization'] = networkDict['orgn']
  368. plist['PayloadRemovalDisallowed'] = False
  369. plist['PayloadScope'] = networkDict['scop']
  370. plist['PayloadType'] = 'Configuration'
  371. plist['PayloadUUID'] = networkDict['puid']
  372. plist['PayloadVersion'] = 1
  373. # Show the plist on debug
  374. if(debugEnabled):print plist
  375. exportFile = '/tmp/.%s-%s.mobileconfig' % (networkDict['user'],networkDict['ssid'])
  376. plist.writeToFile_atomically_(exportFile,True)
  377. return exportFile
  378. def networksetupExecute(arguments):
  379. if(debugEnabled):printCommand(arguments)
  380. execute = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  381. out, err = execute.communicate()
  382. print out
  383. def profilesExecute(arguments):
  384. if(debugEnabled):printCommand(arguments)
  385. execute = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  386. out, err = execute.communicate()
  387. print out
  388. #-------------------------------------------------------------------------------
  389. # This is currently not used as writing the keys seemed best for auto connect
  390. def genSnowProfile(networkDict):
  391. # EAPClientConfiguration
  392. AcceptEAPTypes = []
  393. _AcceptEAPTypes = networkDict['eapt']
  394. AcceptEAPTypes = [_AcceptEAPTypes]
  395. EAPClientConfiguration = {}
  396. EAPClientConfiguration['AcceptEAPTypes'] = AcceptEAPTypes
  397. EAPClientConfiguration['UserName'] = networkDict['user']
  398. EAPClientConfiguration['UserPasswordKeychainItemID'] = networkDict['keyc']
  399. # UserProfiles
  400. UserProfiles = []
  401. _UserProfiles = {}
  402. _UserProfiles['ConnectByDefault'] = True
  403. _UserProfiles['EAPClientConfiguration'] = EAPClientConfiguration
  404. _UserProfiles['UniqueIdentifier'] = networkDict['keyc']
  405. _UserProfiles['UserDefinedName'] = '%s-%s' % (networkDict['ssid'],networkDict['user'])
  406. _UserProfiles['Wireless Network'] = networkDict['ssid']
  407. UserProfiles = [_UserProfiles]
  408. # 8021X
  409. plist = NSMutableDictionary.alloc().init()
  410. _8021X = {}
  411. _8021X['UserProfiles'] = UserProfiles
  412. plist['8021X'] = _8021X
  413. print plist
  414. exportFile = '/tmp/.importme.networkconnect'
  415. plist.writeToFile_atomically_(exportFile,True)
  416. return exportFile
  417. #-------------------------------------------------------------------------------
  418. # This is currently not used as writing the keys seemed best for auto connect
  419. def importSnowProfile(exportFile):
  420. arguments = [networksetup,
  421. "-import8021xProfiles",
  422. "Airport",
  423. exportFile]
  424. networksetupExecute(arguments)
  425. def addPreferredNetwork(networkDict):
  426. path = '/Library/Preferences/SystemConfiguration/preferences.plist'
  427. plist = NSMutableDictionary.dictionaryWithContentsOfFile_(path)
  428. for _Sets in plist['Sets'].keys():
  429. for Interface in plist['Sets'][_Sets]['Network']['Interface'].keys():
  430. if 'AirPort' in plist['Sets'][_Sets]['Network']['Interface'][Interface].keys():
  431. if not 'PreferredNetworks' in plist['Sets'][_Sets]['Network']['Interface'][Interface]['AirPort'].keys():
  432. plist['Sets'][_Sets]['Network']['Interface'][Interface]['AirPort']['PreferredNetworks'] = []
  433. _PreferredNetworks = {}
  434. _PreferredNetworks['SSID_STR'] = networkDict['ssid']
  435. _PreferredNetworks['SecurityType'] = networkDict['sect']
  436. _PreferredNetworks['Unique Network ID'] = networkDict['guid']
  437. # Add keychain item reference if not 802.1x or Open
  438. if networkDict['type'] == 'WPA2':
  439. _PreferredNetworks['Unique Password ID'] = networkDict['keyc']
  440. plist['Sets'][_Sets]['Network']['Interface'][Interface]['AirPort']['PreferredNetworks'].append(_PreferredNetworks)
  441. plist.writeToFile_atomically_(path,True)
  442. def getSystemVersion():
  443. # Our Operating System Constants
  444. global LEOP,SNOW,LION
  445. LEOP = 5
  446. SNOW = 6
  447. LION = 7
  448. systemVersionPath = '/System/Library/CoreServices/SystemVersion.plist'
  449. try:
  450. systemVersion = plistlib.Plist.fromFile(systemVersionPath)
  451. except:
  452. print 'Unable to parse file at path: %s' % systemVersion
  453. sys.exit(1)
  454. ProductVersion = systemVersion['ProductVersion'].split('.')
  455. returnDict = {}
  456. returnDict['major'] = int(ProductVersion[0])
  457. returnDict['minor'] = int(ProductVersion[1])
  458. returnDict['bugfx'] = int(ProductVersion[2])
  459. return returnDict
  460. def leopardAddWireless(networkDict={}):
  461. plistPath = '/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist'
  462. # Sanity check to make sure preferences are the there.
  463. if os.path.exists(plistPath):
  464. pl = NSMutableDictionary.dictionaryWithContentsOfFile_(plistPath)
  465. # Copy the dictionary for mutation during enumeration
  466. copy = NSMutableDictionary.dictionaryWithContentsOfFile_(plistPath)
  467. # 10.5 Style
  468. # Grab UUID if already in network list
  469. found = False
  470. print 'Checking for existing Keychain GUID in KnownNetworks'
  471. try:
  472. for key in copy['KnownNetworks'].keys():
  473. if copy['KnownNetworks'][key]['SSID_STR'] == networkDict['ssid']:
  474. networkDict['guid'] = copy['KnownNetworks'][key]['Unique Password ID']
  475. print 'Found existing reference to wireless password guid: %s' % networkDict['guid']
  476. found = True
  477. except:
  478. print 'Key KnownNetworks not found'
  479. # If this not an OPEN network then add keychain
  480. # Updated to not add blank keychain entry for Open networks
  481. if 'pass' in networkDict.keys() and not networkDict['type'] == "OPEN":
  482. """ Removing Keychain entries for system due to bug in 10.5 """
  483. #print 'Network has password generating keychain arguments...'
  484. #keychain = '/Library/Keychains/System.keychain'
  485. #arguments = [security,
  486. # "add-generic-password",
  487. # '-a',
  488. # networkDict['ssid'],
  489. # '-l',
  490. # networkDict['ssid'],
  491. # '-D',
  492. # 'AirPort network password',
  493. # '-s',
  494. # networkDict['guid'],
  495. # '-w',
  496. # networkDict['pass'],
  497. # '-T',
  498. # 'group://Aiport',
  499. # '-T',
  500. # '/System/Library/CoreServices/SystemUIServer.app',
  501. # '-T',
  502. # '/Applications/System Preferences.app',
  503. # '-T',
  504. # '/usr/libexec/airportd',
  505. # keychain]
  506. #addKeychainPassword(arguments)
  507. users = '/var/db/dslocal/nodes/Default/users'
  508. listing = os.listdir(users)
  509. for plist in listing:
  510. # Hardware test for Air
  511. excluded = re.compile("^((?!^_|root|daemon|nobody|com.apple.*).)*$")
  512. if excluded.match(plist):
  513. plistPath = '%s/%s' % (users,plist)
  514. print 'Processing: %s' % plistPath
  515. user = NSDictionary.dictionaryWithContentsOfFile_(plistPath)
  516. try:
  517. uid = int(user['uid'][0])
  518. gid = int(user['gid'][0])
  519. for home in user['home']:
  520. keychain = home + '/Library/Keychains/login.keychain'
  521. print 'Processing keychain: %s' % keychain
  522. if os.path.exists(keychain):
  523. # -U causing segmentation fault, removed sudo
  524. if user['name'][0] == getConsoleUser():
  525. arguments = [security,
  526. "add-generic-password",
  527. '-a',
  528. networkDict['ssid'],
  529. '-l',
  530. networkDict['ssid'],
  531. '-D',
  532. 'AirPort network password',
  533. '-s',
  534. 'AirPort Network',
  535. '-w',
  536. networkDict['pass'],
  537. '-T',
  538. 'group://Aiport',
  539. '-T',
  540. '/System/Library/CoreServices/SystemUIServer.app',
  541. '-T',
  542. '/Applications/System Preferences.app',
  543. keychain]
  544. addKeychainPassword(arguments)
  545. arguments = [kcutil,
  546. user['home'][0],
  547. user['name'][0],
  548. networkDict['pass'],
  549. configFile]
  550. addKeychainPassword(arguments)
  551. try:
  552. os.chown(keychain,uid,gid)
  553. except:
  554. print 'Path not found: %s' % keychain
  555. else:
  556. print 'Keychain file: %s does not exist' % keychain
  557. except:
  558. print 'User plist %s does not have a home key' % plistPath
  559. else:
  560. print 'No password is specified, skipping keychain actions'
  561. port = 'Airport'
  562. if networkDict['type'] == 'WPA2 Enterprise':
  563. createKnownNetwork(networkDict)
  564. createRecentNetwork(networkDict)
  565. addUsersEAPProfile(networkDict)
  566. createLeopEAPkeychainEntry(networkDict)
  567. addPreferredNetwork(networkDict)
  568. else:
  569. # We can automatically connect to WPA PSK type networks
  570. leopardRemoveWireless(networkDict['ssid'])
  571. connectToNewNetwork(port,networkDict)
  572. def leopardRemoveWireless(networkName):
  573. plistPath = '/Library/Preferences/SystemConfiguration/preferences.plist'
  574. # Sanity checks for the plist
  575. if os.path.exists(plistPath):
  576. try:
  577. pl = NSMutableDictionary.dictionaryWithContentsOfFile_(plistPath)
  578. except:
  579. print 'Unable to parse file at path: %s' % plistPath
  580. sys.exit(1)
  581. else:
  582. print 'File does not exist at path: %s' % plistPath
  583. sys.exit(1)
  584. print 'Processing preference file: %s' % plistPath
  585. # Create a copy of the dictionary due to emuration
  586. copy = NSMutableDictionary.dictionaryWithContentsOfFile_(plistPath)
  587. # Iterate through network sets
  588. for Set in copy['Sets']:
  589. UserDefinedName = copy['Sets'][Set]['UserDefinedName']
  590. print 'Processing location: %s' % UserDefinedName
  591. for enX in copy['Sets'][Set]['Network']['Interface']:
  592. print 'Processing interface: %s' % enX
  593. # I think this will always be a single key but this works either way
  594. for key in copy['Sets'][Set]['Network']['Interface'][enX]:
  595. print 'Processing Service: %s' % key
  596. # Try to grab the PreferredNetworks key if any
  597. try:
  598. # Iterate through preferred network sets
  599. index = 0
  600. for PreferredNetwork in copy['Sets'][Set]['Network']['Interface'][enX][key]['PreferredNetworks']:
  601. SSID_STR = PreferredNetwork['SSID_STR']
  602. print 'Processing SSID: %s' % SSID_STR
  603. # If the preferred network matches our removal SSID
  604. if SSID_STR == networkName:
  605. print 'Found SSID %s to remove' % SSID_STR
  606. # Delete our in ram copy
  607. print 'Processing Set: %s' % Set
  608. print 'Processing enX: %s' % enX
  609. print 'Processing key: %s' % key
  610. try:
  611. print 'Attempting delete of Set: %s for Interface:%s Named:%s Index:%d' % (Set,enX,key,index)
  612. del pl['Sets'][Set]['Network']['Interface'][enX][key]['PreferredNetworks'][index]
  613. print 'Deleted set: %s' % Set
  614. except IndexError:
  615. print 'Unable to remove Received Out of bounds error for index %d' % index
  616. index += 1
  617. except KeyError:
  618. print 'Skipping interface without PreferredNetworks'
  619. # Make a copy of plist
  620. shutil.copy(plistPath,plistPath + '.old')
  621. # Write the plist to a file
  622. writePlist(pl,plistPath)
  623. removeKnownNetwork(networkName)
  624. deleteUsersKeychainPassword(networkName)
  625. deleteUsersEAPProfile(networkName)
  626. #-------------------------------------------------------------------------------
  627. # Snow Leopard
  628. def snowLeopardRemoveWireless(networkName):
  629. port = 'Airport'
  630. arguments = [networksetup,
  631. "-removepreferredwirelessnetwork",
  632. port,
  633. networkName]
  634. if(debugEnabled):printCommand(arguments)
  635. networksetupExecute(arguments)
  636. # Remove from the Known Network list
  637. removeKnownNetwork(networkName)
  638. deleteUsersKeychainPassword(networkName)
  639. deleteSystemKeychainPassword(networkName)
  640. def snowLeopardAddWireless(networkDict={}):
  641. port = 'Airport'
  642. # Check if 802.1x profiles
  643. if networkDict['type'] == 'WPA2 Enterprise':
  644. addUsersEAPProfile(networkDict)
  645. createKnownNetwork(networkDict)
  646. createSnowEAPkeychainEntry(networkDict)
  647. #exportFile = genSnowProfile(networkDict)
  648. #importSnowProfile(exportFile)
  649. addPreferredNetwork(networkDict)
  650. else:
  651. if 'pass' in networkDict.keys():
  652. arguments = [networksetup,
  653. "-addpreferredwirelessnetworkatindex",
  654. port,
  655. networkDict['ssid'],
  656. '0',networkDict['type'],
  657. networkDict['pass']]
  658. else:
  659. arguments = [networksetup,
  660. "-addpreferredwirelessnetworkatindex",
  661. port,
  662. networkDict['ssid'],
  663. '0',networkDict['type']]
  664. networksetupExecute(arguments)
  665. connectToNewNetwork(port,networkDict)
  666. #-------------------------------------------------------------------------------
  667. # Lion
  668. #-------------------------------------------------------------------------------
  669. def lionRemoveWireless(networkName):
  670. port = getPlatformPortName()
  671. arguments = [networksetup,
  672. "-removepreferredwirelessnetwork",
  673. port,
  674. networkName]
  675. # Run the command
  676. networksetupExecute(arguments)
  677. # Remove from the Known Network list
  678. removeKnownNetwork(networkName)
  679. deleteUsersKeychainPassword(networkName)
  680. #-------------------------------------------------------------------------------
  681. def lionAddWireless(networkDict={}):
  682. # Set the bsd port name in Lion
  683. port = getPlatformPortName()
  684. print 'Removing any previous configurations for network %s' % networkDict['ssid']
  685. lionRemoveWireless(networkDict['ssid'])
  686. if networkDict['type'] == 'WPA2 Enterprise':
  687. # Generate the profile
  688. exportLionProfile = genLionProfile(networkDict)
  689. arguments = [profiles,
  690. "-I",
  691. "-v",
  692. "-f",
  693. '-F',
  694. exportLionProfile]
  695. profilesExecute(arguments)
  696. # Removing the temp profile
  697. os.remove(exportLionProfile)
  698. # Adding this as System profiles don't seem to do this
  699. arguments = [networksetup,
  700. "-addpreferredwirelessnetworkatindex",
  701. port,
  702. networkDict['ssid'],
  703. '0',
  704. networkDict['tkey']]
  705. networksetupExecute(arguments)
  706. createLionEAPkeychainEntry(networkDict)
  707. else:
  708. # Check for WPA2/OPEN network
  709. if 'pass' in networkDict.keys():
  710. arguments = [networksetup,
  711. "-addpreferredwirelessnetworkatindex",
  712. port,
  713. networkDict['ssid'],
  714. '0',
  715. networkDict['type'],
  716. networkDict['pass']]
  717. else:
  718. arguments = [networksetup,
  719. "-addpreferredwirelessnetworkatindex",
  720. port,
  721. networkDict['ssid'],
  722. '0',
  723. networkDict['type']]
  724. networksetupExecute(arguments)
  725. connectToNewNetwork(port,networkDict)
  726. #-------------------------------------------------------------------------------
  727. # Network Setup Sub Routine
  728. def networksetupExecute(arguments):
  729. if(debugEnabled):printCommand(arguments)
  730. execute = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  731. out, err = execute.communicate()
  732. print out
  733. #-------------------------------------------------------------------------------
  734. def removeKnownNetwork(networkName):
  735. plistPath = '/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist'
  736. # Sanity check to make sure preferences are the there.
  737. if os.path.exists(plistPath):
  738. pl = NSMutableDictionary.dictionaryWithContentsOfFile_(plistPath)
  739. else:
  740. return 1
  741. # Copy the dictionary for mutation during enumeration
  742. copy = NSMutableDictionary.dictionaryWithContentsOfFile_(plistPath)
  743. # 10.7 style
  744. try:
  745. index = 0
  746. for key in copy['RememberedNetworks']:
  747. name = pl['RememberedNetworks'][index]['SSIDString']
  748. if name == networkName:
  749. print 'Found %s at index %d' % (name,index)
  750. del pl['RememberedNetworks'][index]
  751. index += 1
  752. except:
  753. print 'Key RememberedNetworks not found'
  754. # 10.5 Style
  755. # Clean up KnownNetworks key
  756. try:
  757. for guid in copy['KnownNetworks'].keys():
  758. if copy['KnownNetworks'][guid]['SSID_STR'] == networkName:
  759. del pl['KnownNetworks'][guid]
  760. except:
  761. print 'Key KnownNetworks not found'
  762. # Clean up top level key
  763. port = getPlatformPortName()
  764. # There were some MacBook Airs that shipped with 10.5
  765. try:
  766. if port in copy.keys():
  767. index = 0
  768. try:
  769. for key in copy[port]['RecentNetworks']:
  770. if key['SSID_STR'] == networkName:
  771. del pl[port]['RecentNetworks'][index]
  772. index += 1
  773. except:
  774. print 'No key RecentNetworks'
  775. except:
  776. print 'Unable to cleanup %s' % port
  777. writePlist(pl,plistPath)
  778. #-------------------------------------------------------------------------------
  779. def writePlist(plist,filePath):
  780. # Make a copy of plist
  781. if os.path.exists(filePath):
  782. shutil.copy(filePath,filePath + '.old')
  783. # Write the new plist
  784. plist.writeToFile_atomically_(filePath,True)
  785. # Check the plist
  786. arguments = [plutil,filePath]
  787. execute = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  788. out, err = execute.communicate()
  789. print execute.returncode
  790. #-------------------------------------------------------------------------------
  791. def getAirportInfo():
  792. # Pull info from the Airport command
  793. arguments = [airport,"--getinfo"]
  794. execute = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  795. out, err = execute.communicate()
  796. dict = {}
  797. for line in out.split('\n'):
  798. parse = line.split(': ')
  799. try:
  800. key = parse[0].strip()
  801. value = parse[1]
  802. dict[key] = value
  803. except IndexError:
  804. None
  805. return dict
  806. #-------------------------------------------------------------------------------
  807. # Generic system_profiler parser
  808. def systemReport():
  809. spx = {}
  810. # This is our key value schema
  811. SPHardwareDataType = {
  812. 'platform_UUID': 'platform_UUID',
  813. }
  814. _dataTypes = {
  815. 'SPHardwareDataType': SPHardwareDataType,
  816. }
  817. dataTypes = _dataTypes.keys()
  818. # run the system_profiler command with data types
  819. arguments = [system_profiler,"-xml"] + dataTypes
  820. getspx = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  821. spxOut, err = getspx.communicate()
  822. # Someone give me an example of doing read from string via bridge and I will fix this
  823. #spxNSString = NSString.alloc().initWithString_(spxOut)
  824. #spxData = NSData.dataWithData_(spxNSString.dataUsingEncoding_(NSUTF8StringEncoding))
  825. #rootObject = NSPropertyListSerialization.propertyListFromData_mutabilityOption_format_errorDescription_(spxData,NSPropertyListImmutable,None,None)
  826. rootObject = plistlib.readPlistFromString(spxOut)
  827. # Parse datatype top level keys below
  828. for array in rootObject:
  829. for _dataType in _dataTypes:
  830. if array['_dataType'] == _dataType:
  831. _dataTypeSchema = _dataTypes[_dataType]
  832. for key in _dataTypeSchema:
  833. for item in array['_items']:
  834. # add a key to our dict per the schema
  835. spx[key] = item[_dataTypeSchema[key]]
  836. return spx
  837. #-------------------------------------------------------------------------------
  838. def getPlatformUUID():
  839. spx = systemReport()
  840. try:
  841. return spx['platform_UUID']
  842. except KeyError:
  843. return None
  844. def scanAvailableNetworks(networkName):
  845. # Create a directed SSID scan
  846. directed = "--scan=%s" % networkName
  847. arguments = [airport,"--xml",directed]
  848. if(debugEnabled):printCommand(arguments)
  849. execute = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  850. out, err = execute.communicate()
  851. try:
  852. avaiable = plistlib.readPlistFromString(out)
  853. except:
  854. # Might need to switch to Cocoa here
  855. print 'Unable to parse airport command output'
  856. print 'This error is not critical and can be ignored'
  857. return False
  858. print 'Search found following acess points available'
  859. found = False
  860. # Search the current list of APs
  861. for ap in avaiable:
  862. print 'SSID:\t%s BSSID:[%s]' % (ap['SSID_STR'],ap['BSSID'])
  863. # If we find the SSID then return True
  864. if networkName == ap['SSID_STR']:
  865. found = True
  866. return found
  867. def printCommand(arguments):
  868. print '\'%s\'' % '\' \''.join(arguments)
  869. def connectToNewNetwork(port,networkDict={}):
  870. toggleAirportPower('on')
  871. # If network is in range connect to it
  872. if osVersion['minor'] == LEOP:
  873. wireless = "-A%s" % networkDict['ssid']
  874. if 'pass' in networkDict.keys():
  875. password = "--password=%s" % networkDict['pass']
  876. else:
  877. password = ''
  878. arguments = [airport,wireless,password]
  879. if(debugEnabled):printCommand(arguments)
  880. execute = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  881. out, err = execute.communicate()
  882. print out
  883. if scanAvailableNetworks(networkDict['ssid']):
  884. print "Waiting for interface to come up..."
  885. time.sleep(10)
  886. if osVersion['minor'] >= SNOW:
  887. if 'pass' in networkDict.keys():
  888. arguments = [networksetup,"-setairportnetwork",port,networkDict['ssid'],networkDict['pass']]
  889. else:
  890. arguments = [networksetup,"-setairportnetwork",port,networkDict['ssid']]
  891. if osVersion['minor'] == LEOP:
  892. if 'pass' in networkDict.keys():
  893. arguments = [networksetup,"-setairportnetwork",networkDict['ssid'],networkDict['pass']]
  894. else:
  895. arguments = [networksetup,"-setairportnetwork",networkDict['ssid']]
  896. networksetupExecute(arguments)
  897. else:
  898. print 'Network %s not found' % networkDict['ssid']
  899. # Pull the current network from the airport command
  900. def checkCurrenNetwork(networkName):
  901. airportInfo = getAirportInfo()
  902. try:
  903. if airportInfo['SSID'] == networkName:
  904. print 'We are currently connected to %s' % airportInfo['SSID']
  905. except KeyError:
  906. print 'No current wireless network detected'
  907. # Hardware Test for MacbookAir,*
  908. def getPlatformPortName():
  909. # Hardware test for Air
  910. airTest = re.compile(".*(a|A)ir.*")
  911. hwmodel = commands.getoutput(sysctl + " hw.model").split(' ')
  912. if airTest.match(hwmodel[-1]):
  913. return 'en0'
  914. else:
  915. return 'en1'
  916. def getConsoleUser():
  917. arguments = [who]
  918. execute = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  919. out, err = execute.communicate()
  920. parse = out.split()
  921. console = re.compile(".*console.*")
  922. if console.match(out):
  923. return parse[0]
  924. else:
  925. return None
  926. def toggleAirportPower(value):
  927. # Returns the bsd style name of the port
  928. if osVersion['minor'] == LION:
  929. port = getPlatformPortName()
  930. else:
  931. port = 'Airport'
  932. if osVersion['minor'] >= SNOW:
  933. arguments = [networksetup,"-setairportpower",port,value]
  934. if osVersion['minor'] == LEOP:
  935. arguments = [networksetup,"-setairportpower",value]
  936. else:
  937. arguments = [networksetup,"-setairportpower",port,value]
  938. networksetupExecute(arguments)
  939. def deleteUsersKeychainPassword(networkName):
  940. users = '/var/db/dslocal/nodes/Default/users'
  941. listing = os.listdir(users)
  942. for plist in listing:
  943. # Hardware test for Air
  944. excluded = re.compile("^((?!^_|root|daemon|nobody|com.apple.*).)*$")
  945. if excluded.match(plist):
  946. plistPath = '%s/%s' % (users,plist)
  947. print 'Processing: %s' % plistPath
  948. user = NSDictionary.dictionaryWithContentsOfFile_(plistPath)
  949. try:
  950. uid = int(user['uid'][0])
  951. gid = int(user['gid'][0])
  952. for home in user['home']:
  953. keychain = home + '/Library/Keychains/login.keychain'
  954. print 'Processing keychain: %s' % keychain
  955. if os.path.exists(keychain):
  956. if user['name'][0] == getConsoleUser():
  957. # Snow Type 1
  958. arguments = [security,
  959. "delete-generic-password",
  960. '-D',
  961. 'AirPort network password',
  962. '-a',
  963. networkName,
  964. '-l',
  965. networkName,
  966. keychain]
  967. deleteKeychainPassword(arguments)
  968. # Snow Type 2
  969. arguments = [security,
  970. "delete-generic-password",
  971. '-D',
  972. 'AirPort network password',
  973. '-a',
  974. 'Airport',
  975. '-l',
  976. networkName,
  977. keychain]
  978. deleteKeychainPassword(arguments)
  979. # Snow 802.1X type 1
  980. # Updated to remove account type as local user name may mismatch
  981. arguments = [security,
  982. "delete-generic-password",
  983. '-D',
  984. '802.1X Password',
  985. '-l',
  986. 'WPA: %s' % networkName,
  987. keychain]
  988. deleteKeychainPassword(arguments)
  989. # Lion
  990. arguments = [security,
  991. "delete-generic-password",
  992. '-D',
  993. '802.1X Password',
  994. '-l',
  995. networkName,
  996. keychain]
  997. deleteKeychainPassword(arguments)
  998. try:
  999. os.chown(keychain,uid,gid)
  1000. except:
  1001. print 'Path not found %s' % keychain
  1002. else:
  1003. print 'Keychain file: %s does not exist' % keychain
  1004. except KeyError:
  1005. print 'User plist %s does not have a home key' % plistPath
  1006. def deleteUsersEAPProfile(networkName):
  1007. users = '/var/db/dslocal/nodes/Default/users'
  1008. listing = os.listdir(users)
  1009. for plist in listing:
  1010. # Hardware test for Air
  1011. excluded = re.compile("^((?!^_|root|daemon|nobody|com.apple.*).)*$")
  1012. if excluded.match(plist):
  1013. plistPath = '%s/%s' % (users,plist)
  1014. print 'Processing: %s' % plistPath
  1015. user = NSDictionary.dictionaryWithContentsOfFile_(plistPath)
  1016. try:
  1017. uid = int(user['uid'][0])
  1018. gid = int(user['gid'][0])
  1019. for home in user['home']:
  1020. profile = home + '/Library/Preferences/com.apple.eap.profiles.plist'
  1021. print 'Processing profile: %s' % profile
  1022. # Profile
  1023. if os.path.exists(profile):
  1024. profileFile = NSMutableDictionary.dictionaryWithContentsOfFile_(profile)
  1025. profileByHost = home + '/Library/Preferences/ByHost/com.apple.eap.bindings.%s.plist' % getPlatformUUID()
  1026. if os.path.exists(profileByHost):
  1027. print 'Updating File: %s' % profileByHost
  1028. profileByHostFile = NSMutableDictionary.dictionaryWithContentsOfFile_(profileByHost)
  1029. # Make a copy for enumeration
  1030. copy = NSDictionary.dictionaryWithDictionary_(profileByHostFile)
  1031. # Multiple MAC Addresses may exist
  1032. for mac in copy:
  1033. index = 0
  1034. for key in copy[mac]:
  1035. if key['Wireless Network'] == networkName:
  1036. UniqueIdentifier = key['UniqueIdentifier']
  1037. print 'Found Network with Identifier: %s' % UniqueIdentifier
  1038. # Delete the entry and update the file
  1039. del profileByHostFile[mac][index]
  1040. writePlist(profileByHostFile,profileByHost)
  1041. try:
  1042. os.chown(profileByHost,uid,gid)
  1043. except:
  1044. print 'Path not found: %s' % profileByHost
  1045. profileFileCopy = NSDictionary.dictionaryWithDictionary_(profileFile)
  1046. profileIndex = 0
  1047. print '-' * 80
  1048. for key in profileFileCopy['Profiles']:
  1049. if key['UniqueIdentifier'] == UniqueIdentifier:
  1050. print 'Found network: %s' % key['UserDefinedName']
  1051. # Delete the entry and update the file
  1052. del profileFile['Profiles'][index]
  1053. writePlist(profileFile,profile)
  1054. os.chown(profile,uid,gid)
  1055. profileIndex += 1
  1056. index += 1
  1057. else:
  1058. print 'File not found: %s' % profileByHost
  1059. else:
  1060. print 'Profile file: %s does not exist' % profile
  1061. except KeyError:
  1062. print 'User plist %s does not have a home key' % plistPath
  1063. def addUsersEAPProfile(networkDict):
  1064. users = '/var/db/dslocal/nodes/Default/users'
  1065. listing = os.listdir(users)
  1066. for plist in listing:
  1067. # Hardware test for Air
  1068. excluded = re.compile("^((?!^_|root|daemon|nobody|com.apple.*).)*$")
  1069. if excluded.match(plist):
  1070. plistPath = '%s/%s' % (users,plist)
  1071. print 'Processing: %s' % plistPath
  1072. user = NSDictionary.dictionaryWithContentsOfFile_(plistPath)
  1073. try:
  1074. uid = int(user['uid'][0])
  1075. gid = int(user['gid'][0])
  1076. for home in user['home']:
  1077. # Process the eap profile
  1078. profile = home + '/Library/Preferences/com.apple.eap.profiles.plist'
  1079. createEAPProfile(profile,uid,gid,networkDict)
  1080. # Process the eap binding
  1081. profileByHost = home + '/Library/Preferences/ByHost/com.apple.eap.bindings.%s.plist' % getPlatformUUID()
  1082. createEAPBinding(profileByHost,uid,gid,networkDict)
  1083. except KeyError:
  1084. print 'User plist %s does not have a home key' % plistPath
  1085. # Handle the system keychain as root
  1086. def deleteSystemKeychainPassword(networkName):
  1087. keychain = '/Library/Keychains/System.keychain'
  1088. arguments = [security,
  1089. "delete-generic-password",
  1090. '-D',
  1091. 'AirPort network password',
  1092. '-a',
  1093. 'Airport',
  1094. '-l',
  1095. networkName,
  1096. keychain]
  1097. deleteKeychainPassword(arguments)
  1098. arguments = [security,
  1099. "delete-generic-password",
  1100. '-D',
  1101. 'AirPort network password',
  1102. '-a',
  1103. networkName,
  1104. '-l',
  1105. networkName,
  1106. keychain]
  1107. deleteKeychainPassword(arguments)
  1108. def addKeychainPassword(arguments):
  1109. # Script Created Entry
  1110. if(debugEnabled):printCommand(arguments)
  1111. try:
  1112. execute = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  1113. out, err = execute.communicate()
  1114. print out
  1115. except:
  1116. print 'The command did not exit 0'
  1117. def deleteKeychainPassword(arguments):
  1118. # Script Created Entry
  1119. print 'Deleting keychain entries...'
  1120. if(debugEnabled):printCommand(arguments)
  1121. try:
  1122. execute = subprocess.Popen(arguments, stdout=subprocess.PIPE)
  1123. out, err = execute.communicate()
  1124. print out
  1125. except:
  1126. print 'Deletion of keychain password may have failed'
  1127. def removeWireless(osVersion,network):
  1128. print '-' * 80
  1129. print 'Removing SSID: %s' % network
  1130. print '-' * 80
  1131. # Leopard Code
  1132. if osVersion['minor'] == LEOP:
  1133. leopardRemoveWireless(network)
  1134. # Snow Leopard Code
  1135. if osVersion['minor'] == SNOW:
  1136. snowLeopardRemoveWireless(network)
  1137. # Lion code
  1138. if osVersion['minor'] == LION:
  1139. lionRemoveWireless(network)
  1140. def addWireless(osVersion,networkDict={}):
  1141. print '-' * 80
  1142. print 'Adding SSID: %s' % networkDict['ssid']
  1143. print '-' * 80
  1144. if networkDict['type'] == 'WPA2 Enterprise':
  1145. if networkDict['user'] == '' or networkDict['pass'] == '':
  1146. showUsage()
  1147. print '--> You must specify a username and password for WPA2 Enterprise'
  1148. return 1
  1149. # Leopard Code
  1150. if osVersion['minor'] == LEOP:
  1151. leopardAddWireless(networkDict)
  1152. # Snow Leopard Code
  1153. if osVersion['minor'] == SNOW:
  1154. snowLeopardAddWireless(networkDict)
  1155. # Lion code
  1156. if osVersion['minor'] == LION:
  1157. lionAddWireless(networkDict)
  1158. #-------------------------------------------------------------------------------
  1159. def main():
  1160. global debugEnabled
  1161. debugEnabled = False
  1162. # Check for envrionmental variables
  1163. try:
  1164. userName = os.environ['USER_NAME']
  1165. except KeyError:
  1166. userName = ''
  1167. try:
  1168. userPass = os.environ['PASS_WORD']
  1169. except KeyError:
  1170. userPass = ''
  1171. # Process Arguments
  1172. if(debugEnabled): print 'Processing Arguments: ', sys.argv[1:]
  1173. try:
  1174. options, remainder = getopt.getopt(sys.argv[1:], 'u:p:f:d', ['username=',
  1175. 'password=',
  1176. 'plist=',
  1177. 'debug'
  1178. ])
  1179. except getopt.GetoptError:
  1180. print "Syntax Error!"
  1181. return 1
  1182. for opt, arg in options:
  1183. if opt in ('-u', '--username'):
  1184. userName = arg
  1185. elif opt in ('-p', '--password'):
  1186. userPass = arg
  1187. elif opt in ('-f', '--plist'):
  1188. plistPath = arg
  1189. elif opt in ('-d', '--debug'):
  1190. debugEnabled = True
  1191. # Sanity Checks
  1192. if len(options) < 1:
  1193. showUsage()
  1194. print '--> Not enough options given'
  1195. return 1
  1196. # Check the current directory
  1197. if os.path.exists('wifiutil.settings.plist'):
  1198. plistPath = 'wifiutil.settings.plist'
  1199. try:
  1200. plistPath
  1201. except UnboundLocalError:
  1202. showUsage()
  1203. print '--> You must specify a plist path.'
  1204. return 1
  1205. if os.path.exists(plistPath):
  1206. plist = NSMutableDictionary.dictionaryWithContentsOfFile_(plistPath)
  1207. else:
  1208. print 'File does not exist: %s' % plistPath
  1209. return 1
  1210. global configFile
  1211. configFile = plistPath
  1212. # Get OS Version
  1213. global osVersion
  1214. osVersion = getSystemVersion()
  1215. # Disconnect from wireless
  1216. toggleAirportPower('off')
  1217. # Check for Networks to remove
  1218. if 'networkRemoveList' in plist.keys():
  1219. networkRemoveList = plist['networkRemoveList']
  1220. # Loop through our remove list
  1221. for network in networkRemoveList:
  1222. # Process os specific directives
  1223. removeWireless(osVersion,network)
  1224. else:
  1225. print 'No networks specified to remove'
  1226. # Check for Networks to Add
  1227. if 'networkAddList' in plist.keys():
  1228. networkAddList = plist['networkAddList']
  1229. # Loop through our add list
  1230. for networkDict in networkAddList:
  1231. # Add our username and password to the config
  1232. if 'user' not in networkDict.keys():
  1233. networkDict['user'] = userName
  1234. if 'pass' not in networkDict.keys():
  1235. networkDict['pass'] = userPass
  1236. # Remove the password for OPEN network
  1237. if networkDict['type'] == 'OPEN':
  1238. del networkDict['pass']
  1239. # Generate our wireless & keychain entry guids, not recommended
  1240. if not 'guid' in networkDict.keys():
  1241. networkDict['guid'] = str(uuid.uuid1()).upper()
  1242. if not 'keyc' in networkDict.keys():
  1243. networkDict['keyc'] = str(uuid.uuid1()).upper()
  1244. # Process os specific directives
  1245. addWireless(osVersion,networkDict)
  1246. else:
  1247. print 'No networks specified to add'
  1248. # Restore Airport Power
  1249. toggleAirportPower('on')
  1250. if __name__ == "__main__":
  1251. sys.exit(main())