Skip to content

Instantly share code, notes, and snippets.

@rudyrichter
Last active August 27, 2020 16:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rudyrichter/c0d1a685b378e6d9e96cdaf3d2f2c21f to your computer and use it in GitHub Desktop.
Save rudyrichter/c0d1a685b378e6d9e96cdaf3d2f2c21f to your computer and use it in GitHub Desktop.
In doing receipt validation for Mac App Store, there are certain rules that should be followed in getting the MAC address of the machine. This is what AppStore.app uses for its validation.
io_service_t io_service(const char *name, BOOL wantBuiltIn) {
io_iterator_t iterator = IO_OBJECT_NULL;
mach_port_t master_port = IO_OBJECT_NULL;
io_service_t service = IO_OBJECT_NULL;
if (KERN_SUCCESS != IOMasterPort(MACH_PORT_NULL, &master_port)) {
return IO_OBJECT_NULL;
}
CFMutableDictionaryRef matchingDict = IOBSDNameMatching(master_port, 0, name);
if (matchingDict == NULL) {
return IO_OBJECT_NULL;
}
if (KERN_SUCCESS != IOServiceGetMatchingServices(master_port, matchingDict, &iterator)) {
return IO_OBJECT_NULL;
}
if (iterator != IO_OBJECT_NULL) {
io_service_t candidate = IOIteratorNext(iterator);
while (candidate != IO_OBJECT_NULL) {
CFTypeRef isBuiltIn = IORegistryEntryCreateCFProperty(candidate, CFSTR(kIOBuiltin), kCFAllocatorDefault, 0);
if (isBuiltIn != NULL && CFGetTypeID(isBuiltIn) == CFBooleanGetTypeID()) {
if (wantBuiltIn == CFBooleanGetValue(isBuiltIn)) {
service = candidate;
break;
}
}
IOObjectRelease(candidate);
candidate = IOIteratorNext(iterator);
}
IOObjectRelease(iterator);
}
return service;
}
// Returns a CFData object, containing the machine's GUID.
static CFDataRef copyMACAddress(void) {
CFDataRef macAddress = NULL;
io_service_t service = io_service("en0", true);
if (service == IO_OBJECT_NULL) {
service = io_service("en1", true);
}
if (service == IO_OBJECT_NULL) {
service = io_service("en0", false);
}
if (service != IO_OBJECT_NULL) {
io_iterator_t iterator = IO_OBJECT_NULL;
if (KERN_SUCCESS != IORegistryEntryGetParentIterator(service, kIOServicePlane, &iterator)) {
return NULL;
}
if (iterator != IO_OBJECT_NULL) {
io_service_t parent = IOIteratorNext(iterator);
while (parent != IO_OBJECT_NULL) {
CFTypeRef property = IORegistryEntryCreateCFProperty(parent, CFSTR(kIOMACAddress), kCFAllocatorDefault, 0);
if (property != NULL && CFGetTypeID(property) == CFDataGetTypeID()) {
macAddress = property;
IOObjectRelease(parent);
break;
}
else {
CFRelease(property);
}
IOObjectRelease(parent);
parent = IOIteratorNext(parent);
}
IOObjectRelease(iterator);
}
IOObjectRelease(service);
}
return macAddress;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment