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;
}

Replies

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"

  • @eskimo I tried using the scutil but the particular key that I'm using doesn't seem to be present and I'm also not able to find any other useful key in scutil which will helpful to achieve my task.

Add a Comment