Home Forums Software InstaDMG Auto-configuring 802.1X for a user on first login

Viewing 12 posts - 1 through 12 (of 12 total)
  • Author
    Posts
  • #372523
    jdyck
    Participant

    Hello all,

    I have a bit of a dilemma here as I’m building an image for a large School District utilizing 802.1X authenticated WiFi access points. The users are mostly student Active Directory users who are managed via MCX OD Groups.

    In Leopard, to setup 802.1X you need to logon as the user, go into System Preferences –> Network, authenticate as an admin user, go into Airport, go to Advanced, go to the 802.1X tab and configure a user 802.1x configuration, enter the users AD credentials, go to the Airport tab, click the + button to add a new wireless, type in the name of the Wireless network, select 802.1x in the Security drop down menu, then select the user 802.1x config in the 802.1x configuration. From this point forward when the user logs in they will be auto-connected to the wireless network, and if their computer sleeps it will reconnect on wakeup.

    However, we’re talking about just under 3000 laptops scattered over a wide geographic area… I’m trying to find a way to create a login script that runs on first login, checks into a database server we have that contains the user id and passswords and auto-configures the network access. Or even something that gets everything configured and on first login asks for the username and password, but then configures things so it doesn’t need to be entered again.

    Without going through the process we’re having lots of problems – when you login you need to enter your credentials, but then if the computer goes to sleep when you wake it up it will show a connection but won’t be authenticated so you have no wireless access and need to power off Airport then power on and re-authenticate.

    I’ve browsed through the Leopard Command Line Admin guide but was unable to find anything referencing Airport config, let alone 802.1x and keychain passwords that are needed. Even figuring out how to get this all working by hand was a pain as the 802.1x area seems poorly documented.

    I had a script on Tiger that did a lot of this by building up several plist files by hand using plistbuddy, but Leopard has changed things quite a bit and those scripts don’t do anything for Leopard.

    Anyone out there more familiar with this than me? Any suggestions are greatly appreciated.

    Jeff

    #372596
    larkost
    Participant

    I hope this time it makes it though… My posts keep getting rejected as spam….

    I created a project for this, and got something that worked. Unfortunately that was before 802.1X was stable in 10.5, so I was mostly writing for 10.4. However, I would bet that with only minor tweaks that you could get it working for 10.5.

    I have the project up on Google’s Code hosting:

    http://code.google.com/p/macenterprise8021x/

    If you do take it up, I can add you to the project. I have moved to a new job since writing that code, so no longer have access to a 802.1X network to test it, so I can’t really develop it any further.

    But the project itself would make a great login-hook that could be used to keep the computers configured the way you want (without interfering with other uses).

    #372669
    jdyck
    Participant

    Hey larkost,

    Thanks for your reply, the tool you came up with looks pretty slick.

    I must confess to being pretty clueless about ‘real’ coding (I do some AppleScript Studio and bash stuff, but no C or Cocoa), so not sure that I’d be able to contribute terribly much to what you’ve already done. I did convert my certs into hex and tried inserting them into your code, but when I run the resulting compile I get a segmentation fault, so guess I’m missing something.

    I had pretty much traced the necessary steps to the following, which it seems your tool does…

    1) The certificate has to be imported into the System keychain, and trust configured to always allow EAP.

    2) Several preference files are configured, the ones I’ve traced are:
    – /Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist -> Correlates to known networks for auto-connect
    – ~/Library/Preferences/com.apple.eap.profiles.plist -> Sets EAP types, user name, user password keychain item and a UniqueIdentifer for the connection.
    – ~/Library/Preferences/ByHost/com.apple.eap.bindings.MACAddress.plist -> Seems to just match up the network name with the UniqueIdentifer.

    I’ve been able to use PListBuddy to recreate the preference files as part of a loginscript fired off by launchd, but I’m stumped on getting the trust settings for the cert.
    Both using security -add-trusted-cert command, and your tool, to adjust the trust settings you are required to enter an admin password. Problem is, if you use a startup script you don’t even get that opportunity.

    I’m just doing this manually after first boot, but would really love to have this automated. Starting to think that’s not going to be possible though.

    Now just need to test to see if the login script works ok when the certificate is in place.

    #372676
    Patrick Fergus
    Participant

    This may work:

    [code]/usr/bin/security add-trusted-cert -d -r trustRoot -k “/Library/Keychains/System.keychain” /private/tmp/mycert.pem[/code]

    However, I [i]don’t[/i] know if this is enough to get the certificate trusted for EAP. If it does work, you can point it at “$3″”/Library/Keychains/System.keychain”, adding it to a non-boot volume (part of a payload-free InstaDMG CustomPKG).

    – Patrick

    P.S. The above was stolen from post #2 here:

    [url]https://www.afp548.com/forum/viewtopic.php?showtopic=18460[/url]

    #372687
    jdyck
    Participant

    Hey, that’s perfect!!! I had played around with the security add-trusted-cert command but kept getting errors… I think because I was trying to do the -p eap part, which kept giving an error. This works though, which is fantastic. Thanks a bunch, now just need to revisit my scripts to auto-generate the 802.1x config to see if that works.

    #372724
    knowmad
    Participant

    when your all done, please post the working final routine for this

    #374069
    knowmad
    Participant

    Any chance you have done further work on this that you can share with us? I know of at least one other thread trying to figure this one out…..
    Any updates, even ones declaring ‘i tried this and this and then gave up” are very useful.

    [QUOTE][u]Quote by: jdyck[/u][p]Hey, that’s perfect!!! I had played around with the security add-trusted-cert command but kept getting errors… I think because I was trying to do the -p eap part, which kept giving an error. This works though, which is fantastic. Thanks a bunch, now just need to revisit my scripts to auto-generate the 802.1x config to see if that works.[/p][/QUOTE]

    can you post those scripts in whatever tested/untested form you have?

    Knowmad

    #374167
    jdyck
    Participant

    Hey, sorry for the delayed reply (to the email as well), have been working on a bunch of other stuff…

    Anyway, I kinda got things working to a pseudo-acceptable level – on the user level on first login the user gets an application that asks for their user-name and password. Once they enter this and click setup it pops up a message instructing them to connect to our network, after which the security dialog to give permissions for the wireless to access the keychain item pops up.

    It’s not as smooth as I wanted, and the backend is kinda scary, but here’s what I did…

    [b]1) Install 802.1X certificate into system keychain.[/b]

    I have a master launchd ‘startup-script’ that gets called on system startup. It runs and goes through a list of scripts in a hidden folder – one of these scripts installs the 802.1X cert for the Wireless network into the keychain, using the following command:
    [code]security add-trusted-cert -d -r trustRoot -k “/Library/Keychains/System.keychain” \
    “/path/to/Secure Certificate Authority.cer”[/code]
    [b]2) Directly configure plists to connect[/b]

    I have a second launchd ‘login-script’ which runs upon user login. It fires up an AppleScript Studio application I created which asks for the username and password. When you enter that info and click setup, it runs a shell script (see below) that adds the user info into a keychain item, then creates the plists OS X uses to configure 802.1x… it then pops up instructions for the user to select the wireless network (couldn’t figure out a way to automate this) which then pops up the authorization dialog to ask you if you want to allow the wireless config to use the keychain entry you created. The user then clicks “always allow” and dismisses the instructions dialog, at which point the program sends a stop airport then start airport command… As the Airport starts it sees its new plists and auto-connects.

    **Note: Because this configs some system level plists, if you now login as any other user the system will still try to connect to the 802.1x wireless, but because it won’t have the user level settings it’ll ask you for your user name and password. I’m working laptops assigned to individual students, so this hasn’t been a concern for me, but it may be for others.

    [b]SetupWifi.sh[/b] (called by SetupWiFi.sh username password /path/to/PListBuddy:
    [code]#!/bin/sh
    # SetupWiFi.sh

    # Set a few properties…
    # $1 = User’s short name, $2 = User’s password, $3 = Path to PListBuddy

    USER=$1
    PASS=$2
    Buddy=$3
    LocalUser=`whoami`
    HOME=`dscl . -read /Users/$LocalUser home | sed -e ‘s|dsAttrTypeNative:home: ||g’`
    LOG=$HOME/Library/Logs/CSF-NetworkSetup.log

    # Get MAC Addresses
    hwAddress=`ifconfig en0 | awk ‘/ether/ { gsub(“:”, “”); print $2 }’`
    hwAddresswithColons=`ifconfig en0 | awk ‘/ether/ { gsub(“:”, “\\\\:”); print $2 }’`

    AirAddress=`ifconfig en1 | awk ‘/ether/ { gsub(“:”, “”); print $2 }’`
    AirAddresswithColons=`ifconfig en1 | awk ‘/ether/ { gsub(“:”, “\\\\:”); print $2 }’`
    AirAddresswithColons2=`ifconfig en1 | awk ‘/ether/ { gsub(“:”, “\\:”); print $2 }’`

    # Get some Unique Identifiers to use in the plists…
    uuid=`uuidgen`
    netuuid=`uuidgen`

    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.$hwAddress.plist”

    # Setup the log so we know what’s going on later…
    echo “” >> $LOG
    echo “Creating some plist files to allow the Wireless to auto-connect…” >> $LOG
    echo “——————————————————————” >> $LOG
    echo “” >> $LOG
    echo “User to configure: $USER” >> $LOG
    echo “Computer Hardware address: $hwAddress” >> $LOG

    echo “First we need to build the System AirportPref…”
    “$Buddy” -c “Delete :KnownNetworks” $AirportPref ;# Remove any previous entry.

    “$Buddy” -c “Add :KnownNetworks dict” $AirportPref
    “$Buddy” -c “Add :KnownNetworks:$uuid dict” $AirportPref
    “$Buddy” -c “Add :KnownNetworks:$uuid:Remembered\ Channels array” $AirportPref
    “$Buddy” -c “Add :KnownNetworks:$uuid:Remembered\ Channels:0 integer 1” $AirportPref
    “$Buddy” -c “Add :KnownNetworks:$uuid:Remembered\ Channels:1 integer 8” $AirportPref
    “$Buddy” -c “Add :KnownNetworks:$uuid:SCAN_DIRECTED bool Yes” $AirportPref
    “$Buddy” -c “Add :KnownNetworks:$uuid:SecurityType string 802.1X\ WEP” $AirportPref
    “$Buddy” -c “Add :KnownNetworks:$uuid:SSID_STR string csf-secure” $AirportPref
    “$Buddy” -c “Add :Version integer 6” $AirportPref

    echo “Building the User’s EAPProfiles setting at $EAPProfiles…” >> $LOG
    “$Buddy” -c “Delete :Profiles” $EAPProfiles ;# Remove any previous entry.

    “$Buddy” -c “Add :Profiles array” $EAPProfiles >> $LOG
    “$Buddy” -c “Add :Profiles:0 dict” $EAPProfiles >> $LOG
    “$Buddy” -c “Add :Profiles:0:ConnectByDefault bool Yes” $EAPProfiles >> $LOG
    “$Buddy” -c “Add :Profiles:0:EAPClientConfiguration dict” $EAPProfiles >> $LOG
    “$Buddy” -c “Add :Profiles:0:EAPClientConfiguration:AcceptEAPTypes array” $EAPProfiles >> $LOG
    “$Buddy” -c “Add :Profiles:0:EAPClientConfiguration:AcceptEAPTypes:0 integer 21” $EAPProfiles >> $LOG
    “$Buddy” -c “Add :Profiles:0:EAPClientConfiguration:AcceptEAPTypes:1 integer 25” $EAPProfiles >> $LOG
    “$Buddy” -c “Add :Profiles:0:EAPClientConfiguration:UserName string $USER” $EAPProfiles >> $LOG
    “$Buddy” -c “Add :Profiles:0:EAPClientConfiguration:UserPasswordKeychainItemID string $uuid” $EAPProfiles >> $LOG
    “$Buddy” -c “Add :Profiles:0:UniqueIdentifier string $uuid” $EAPProfiles >> $LOG
    “$Buddy” -c “Add :Profiles:0:UserDefinedName string $USER” $EAPProfiles >> $LOG
    “$Buddy” -c “Add :Profiles:0:Wireless\ Network string csf-secure” $EAPProfiles >> $LOG
    “$Buddy” -c “Add :Profiles:0:userDefinedName string $USER-WPA” $EAPProfiles >> $LOG

    echo “Building the User’s EAPBindings settings at $EAPBindings…” >> $LOG
    “$Buddy” -c “Delete :$AirAddresswithColons” $EAPBindings ;# Remove any previous entry.

    “$Buddy” -c “Add :$AirAddresswithColons array” $EAPBindings >> $LOG
    “$Buddy” -c “Add :$AirAddresswithColons:0 dict” $EAPBindings >> $LOG
    “$Buddy” -c “Add :$AirAddresswithColons:0:Hardware\ Address string $AirAddresswithColons2” $EAPBindings >> $LOG
    “$Buddy” -c “Add :$AirAddresswithColons:0:UniqueIdentifier string $uuid” $EAPBindings >> $LOG
    “$Buddy” -c “Add :$AirAddresswithColons:0:Wireless\ Network string csf-secure” $EAPBindings >> $LOG

    # Now we need to add a password to the keychain with the uuid and allow eapservice to access…
    security add-generic-password -a $USER -s $uuid -p $PASS >> $LOG

    # Flag that this has been done so it won’t reload next login
    touch “$HOME/Library/Logs/.LoginScript-SetupWireless.sh-done”

    exit 0[/code]
    It then uses an applescript extension to turn off the wireless card then turn it back on, at which point OS X will fully authenticate to the wireless network.

    It’s obviously a pretty tedious workaround to something that should be much easier, and I am CERTAINLY open to a more elegant solution should anyone figure it out. However, it took far too long to track down all those entrees and get something that worked at all, so for now I’m content.

    #374168
    jdyck
    Participant

    If anyone is interested, I’ll try and pull a few of the proprietary private stuff from the AppleScript Studio app and post it.

    #374213
    jdyck
    Participant

    Hey all,

    I’ve done some re-writing of the solution I’m using to abstract it away from our network and to remove a bit of proprietary stuff and have a package I have just uploaded to AFP548.com. Probably be a few days before it shows up, but curious to hear feedback and perhaps get some more robust ideas on it…

    Just realized I didn’t include any kind of readme on it, basically two things are needed to make this work:

    1 – You have to have the 802.1X WAP certificate added to your client systems (command in this discussion).
    2 – Before you build the app, you need to go into the SetupWifi.applescript and change the referenced wifi network name to reflect your site.

    The GUI app is basically just collecting the user name and password and feeding it to a shell script, which you could also just call yourself (if you know the user’s name and password)… Format is:

    SetupWifi.sh -u username -p password -w wifinetworkname

    Cheers

    jeff

    #374235
    knowmad
    Participant

    as soon as I can download it, I am going to test the hell out of it. THANK YOU!
    Mind if I steal bits of your code to make some related scripts?
    I will post or email what I do andof course give you full credit.
    knowmad
    (ps, your email must have been spam-blocked, but the post here works just as well.)

    #374301
    jdyck
    Participant

    I don’t know how best to distribute this, but I just fixed a glitch in the setup script with newer hardware which uses the computer GUID rather than MAC address for ByHost prefs… My script only worked with older hardware that uses the MAC address as part of the plist name, corrected script fixes that.

    Perhaps I should setup a Google code repository or something? And then people that are interested in contributing can? Is this something anyone would be interested in?

    In the interim, you can edit the SetupWiFi.sh script – replace the # Defin the 3 plist files for easier reference section with the following (the code to figure out the proper UUID is by kevinberny from this discussion: [url]https://www.afp548.com/article.php?story=leopard_byhost_changes#comments[/url])
    [code]# 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 3 plist files for easier reference…
    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”[/code]

Viewing 12 posts - 1 through 12 (of 12 total)
  • You must be logged in to reply to this topic.

Comments are closed