Error in getting 802.1x status

Hey, I want to retrieve the 802.1x status when a user starts 802.1x authentication so that I'll know when the user gets successfully authenticated via 802.1x. I refered the eapolclient code on apple opensource and wrote the below code but it's failing to retrieve the state.

#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <iostream>

#ifndef kSCEntNetEAPOL
#define kSCEntNetEAPOL CFSTR("EAPOL")
#endif /* kSCEntNetEAPOL */

class MyService {
public:
    static void handleEAPOLStatusChange(
        SCDynamicStoreRef store,
        CFArrayRef changedKeys,
        void *context) {
        MyService *serviceInstance = static_cast<MyService *>(context);
        serviceInstance->handleEAPOLStatus(store);
    }

    void handleEAPOLStatus(SCDynamicStoreRef store) {
        // Function to handle EAPOL status change events
        CFStringRef key = createEAPOLControlAnyInterfaceKey();
        CFPropertyListRef eapolStatusValue = SCDynamicStoreCopyValue(store, key);
        CFShow(eapolStatusValue);
        CFRelease(key);

        if (eapolStatusValue) {
            if (CFGetTypeID(eapolStatusValue) == CFDictionaryGetTypeID()) {
                CFDictionaryRef eapolStatusDict = static_cast<CFDictionaryRef>(eapolStatusValue);
                std::cout << "EAPOL Status Dictionary: " << std::endl;
                CFShow(eapolStatusDict);
                CFRelease(eapolStatusDict);
            } else {
                std::cerr << "Error: The retrieved value is not a dictionary." << std::endl;
            }
            CFRelease(eapolStatusValue);
        } else {
            std::cerr << "Error: Failed to get EAPOL status." << std::endl;
        }
    }

    void setupDynamicStore() {
        CFStringRef key;
        CFArrayRef patterns;
        CFRunLoopSourceRef rls;
        SCDynamicStoreContext context;

        bzero(&context, sizeof(context));
        context.info = this;
        store_ = SCDynamicStoreCreate(NULL, CFSTR("eapolclient"), &MyService::handleEAPOLStatusChange, &context);
        if (store_ == NULL) {
            std::cerr << "SCDynamicStoreCreate() failed." << std::endl;
            return;
        }

        key = createEAPOLControlAnyInterfaceKey();
        patterns = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks);
        CFRelease(key);

        SCDynamicStoreSetNotificationKeys(store_, NULL, patterns);
        CFRelease(patterns);

        rls = SCDynamicStoreCreateRunLoopSource(NULL, store_, 0);
        CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
        CFRelease(rls);
    }

private:
    SCDynamicStoreRef store_;

    CFStringRef createEAPOLControlAnyInterfaceKey() {
        return SCDynamicStoreKeyCreateNetworkInterfaceEntity(
            NULL,
            kSCDynamicStoreDomainState,
            kSCCompAnyRegex,
            kSCEntNetEAPOL);
    }
};

int main() {
    MyService myService;
    myService.setupDynamicStore();
    CFRunLoopRun();
    return 0;
}

In situations like this I recommend that you prototype your approach using scutil. Have you tried that? What did you see?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Error in getting 802.1x status
 
 
Q