Skip to content

Instantly share code, notes, and snippets.

@joshua-d-miller
Last active December 17, 2020 16:17
Show Gist options
  • Save joshua-d-miller/2ba2804be41cf60ae961805447961152 to your computer and use it in GitHub Desktop.
Save joshua-d-miller/2ba2804be41cf60ae961805447961152 to your computer and use it in GitHub Desktop.
This will read all Ethernet interfaces on a system and determine based on what you call your 802.1x Profile if it is present on all Ethernet interfaces and report it into jamf as a string. You can then create a SMART group that looks for the word false so if any are false you can then use a policy to make the profile apply to all interfaces
#!/usr/bin/python
# pylint: disable=E0611, E1101, E0602, C0103
''''Fix 802.1x When Using Config Profiles and PEAP-MSCHAPV2 or EAP-TLS'''
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# This script will find the system profile and determine whether it is attached
# to each interface and report that information. This is formated to be used
# with jamf as an Extension attribute. Expected output would be as follows:
# || en3 - True || en4 - False || en5 - False ||
#
# Joshua D. Miller - josh@psu.edu - The Pennsylvania State University
# Last Updated Friday March 21, 2017
#
# References
# https://gist.github.com/pudquick/8ad859f30438f3be149fe9751391d037
# https://gist.github.com/pudquick/4cf32c2b403bf0be23b268d6dd3cf803
# https://github.com/mosen/moobjc-framework-Security/blob/
# master/metadata/Security.fwinfo
# https://github.com/mosen/meap/blob/master/meap/eap8021x/_metadata.py
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# I'd like to give a very special thanks to Mosen who was so influencial
# in making this script a reality. Thank you so much for asssting with
# this project and it is my hope that this truly solves our 802.1x issue
# on the Mac side and allows us to move forward with the project. We
# decided to switch from EAP-TLS to PEAP-MSCHAPV2 because the user
# will still need a domain bound computer which can only be done by our
# IT Staff and will need the cert from our CA. This script does work with both
# protocols though
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
from __future__ import print_function
from Foundation import NSBundle
from SystemConfiguration import (
SCNetworkServiceCopyAll, SCNetworkInterfaceGetBSDName,
SCNetworkInterfaceGetInterfaceType, SCNetworkServiceGetInterface,
SCPreferencesCreate)
import objc
def ethernet_services(services):
'''function will pull any en(x) device that is truly an ethernet
Special Thanks to @mosen for this little function that gets
the job done'''
for service in services:
interface = SCNetworkServiceGetInterface(service)
if SCNetworkInterfaceGetInterfaceType(interface) == 'Ethernet':
yield interface
def main():
'''This function is very similar to our fix but instead of performing
any systematic changes will read the information and report it to
jamf as an extension attribute.'''
eap8021x_bundle = NSBundle.bundleWithPath_(
'/System/Library/PrivateFrameworks/EAP8021X.framework')
# EAP Functions from @mosen's meap project (See above for link)
eapol_functions = [
('EAPOLClientConfigurationGetTypeID', 'Q'),
('EAPOLClientProfileGetTypeID', 'Q'),
('EAPOLClientItemIDGetTypeID', 'Q'),
('EAPOLClientConfigurationCreate',
'^{EAPOLClientConfigurationRef=}^{__CFAllocator=}'),
('EAPOLClientProfileGetUserDefinedName',
'@^{EAPOLClientProfileRef=}'),
('EAPOLClientConfigurationGetSystemProfile',
'^{EAPOLClientProfileRef=}'
'^{EAPOLClientConfigurationRef=}@'),
('EAPOLClientConfigurationSetSystemProfile',
'Z^{EAPOLClientConfigurationRef=}@'
'^{EAPOLClientProfileRef=}'),
('EAPOLClientConfigurationSave',
'Z^{EAPOLClientConfigurationRef=}')]
objc.loadBundleFunctions(eap8021x_bundle, globals(), eapol_functions)
# CF Types to be loaded also from @mosen's meap project
cf_types = [
('EAPOLClientConfigurationRef',
'^{EAPOLClientConfigurationRef=}',
EAPOLClientConfigurationGetTypeID()),
('EAPOLClientProfileRef',
'^{EAPOLClientProfileRef=}',
EAPOLClientProfileGetTypeID()),
('EAPOLClientItemIDRef',
'^{EAPOLClientItemIDRef=}',
EAPOLClientItemIDGetTypeID()), ]
for item in cf_types:
objc.registerCFSignature(*item)
# Define blank lists to be used to gather EAPOL information on
# Ethernet interfaces
interface_list = []
result = []
prefs = SCPreferencesCreate(None, "python", None)
services = SCNetworkServiceCopyAll(prefs)
# Poll through the interfaces and make a list of the true Ethernet
# adapters on the system
for interface in ethernet_services(services):
interface_list.append(SCNetworkInterfaceGetBSDName(interface))
# For loop to iterate through our Ethernet adapters and determine if they
# have the system profile we are looking for applied to them. False if not
# present. Change "Ethernet(COE)" to whatever your 802.1x profile is
# called in Network Preferences. Default in jamf is sadly "Network"
for ethernet in interface_list:
cfg = EAPOLClientConfigurationCreate(None)
look_for_cfg = EAPOLClientConfigurationGetSystemProfile(cfg, ethernet)
if look_for_cfg is not None:
if EAPOLClientProfileGetUserDefinedName(
look_for_cfg) == 'Ethernet(COE)':
eth_string = '| {0:} - True |'.format(ethernet)
result.append(eth_string)
else:
eth_string = '| {0:} - False |'.format(ethernet)
result.append(eth_string)
else:
eth_string = '| {0:} - False |'.format(ethernet)
result.append(eth_string)
result = ''.join(result)
print('<result>|{0:}|</result>'.format(result))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment