Skip to content

Commit bea4cba

Browse files
committed
Removed dependence on deprecated AddressBook framework. SSYIOKit now uses machine serial number as fallback instead of user's email address.
1 parent 9bc23db commit bea4cba

File tree

2 files changed

+72
-18
lines changed

2 files changed

+72
-18
lines changed

SSYIOKit.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
@interface SSYIOKit : NSObject
55

6-
+ (NSData*)primaryMACAddressData;
6+
+ (NSData*)primaryMACAddressOrMachineSerialNumberData;
77
+ (NSData*)hashedMACAddress;
88
+ (NSData*)hashedMACAddressAndShortUserName;
99

SSYIOKit.m

+71-17
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ Change History (most recent first):
2121
*/
2222

2323
#import "SSYIOKit.h"
24-
#import <AddressBook/ABAddressBook.h>
25-
#import <AddressBook/ABMultiValue.h>
2624
#include <IOKit/network/IOEthernetInterface.h>
2725
#include <IOKit/network/IONetworkInterface.h>
2826
#include <IOKit/network/IOEthernetController.h>
@@ -162,7 +160,7 @@ CFDataRef CreateMACAddress(io_iterator_t intfIterator)
162160

163161
@implementation SSYIOKit
164162

165-
+ (NSData*)primaryMACAddressData {
163+
+ (NSData*)primaryMACAddressOrMachineSerialNumberData {
166164
kern_return_t kernResult = KERN_SUCCESS; // on PowerPC this is an int (4 bytes)
167165
/*
168166
* error number layout as follows (see mach/error.h and IOKit/IOReturn.h):
@@ -177,7 +175,7 @@ + (NSData*)primaryMACAddressData {
177175
CFDataRef MACAddressData = NULL ;
178176

179177
if (KERN_SUCCESS != kernResult) {
180-
NSLog(@"+[SSYIOKit primaryMACAddressData]: FindEthernetInterfaces returned error, 0x%08lx", (long)kernResult) ;
178+
NSLog(@"+[SSYIOKit primaryMACAddressOrMachineSerialNumberData]: FindEthernetInterfaces returned error, 0x%08lx", (long)kernResult) ;
181179
}
182180
else {
183181
MACAddressData = CreateMACAddress(intfIterator);
@@ -186,30 +184,86 @@ + (NSData*)primaryMACAddressData {
186184
(void) IOObjectRelease(intfIterator); // Release the iterator.
187185

188186
if (MACAddressData == nil) {
189-
// May be a Hackintosh. Use email instead.
190-
// Starting with macOS 10.8, -[ABAddressBook me] will produce an ugly warning
191-
// asking if it's OK for your app to access Contacts, and will block until
192-
// user dismisses the dialog. But I figure that if someone
193-
// is using a Hackintosh, they should expect stuff like that.
194-
ABPerson* me = [[ABAddressBook sharedAddressBook] me] ;
195-
ABMultiValue *emails = [me valueForProperty:kABEmailProperty];
196-
NSString* email = [emails valueAtIndex:[emails indexForIdentifier:[emails primaryIdentifier]]];
197-
if ((email != nil) && ([email length] > 7)) {
198-
MACAddressData = (CFDataRef)[[email dataUsingEncoding:NSUTF8StringEncoding] retain] ;
199-
}
187+
/* May be a Hackintosh. Use email instead. Until 2020-Apr-17 I used
188+
the email address of the primary user:
189+
ABPerson* me = [[ABAddressBook sharedAddressBook] me] ;
190+
ABMultiValue *emails = [me valueForProperty:kABEmailProperty];
191+
NSString* email = [emails valueAtIndex:[emails indexForIdentifier:[emails primaryIdentifier]]];
192+
if ((email != nil) && ([email length] > 7)) {
193+
MACAddressData = (CFDataRef)[[email dataUsingEncoding:NSUTF8StringEncoding] retain] ;
194+
}
195+
But then I started to get depracation warnings on AddressBook … use
196+
Contacts instead. But after 15 minutes of research I cannot find
197+
any equivalent method in Contacts which would get the Contacts record
198+
of the logged-in user. And even if there was such a method, I am sure
199+
it would be protected by a bunch of security hoops and/or roadblocks.
200+
201+
So I decided to do this instead – get the machine serial number. I
202+
remember reading somewhere that this was not a good idea for some
203+
reason – maybe if the motherboard is replaced. But as a fallback
204+
in extreme edge cases, I think it is good enough.
205+
206+
Instead of using two NSTasks as below, the following code could read
207+
in the whole ioRegTask output and filter for the desired line using
208+
Cocoa methods. I tried that, and [task launch] hung. This is
209+
probably too much data got put into the pipe (the output of ioReg -l
210+
is maybe thousnds of lines), and the pipe plugged up and stalled – I
211+
forget what the exact terminology is. There is probably a way to deal
212+
with it, as I recall doing in Chromessenger, but it makes the
213+
following two-task method simpler: */
214+
NSTask* ioRegTask = [[NSTask alloc] init];
215+
NSTask* grepTask = [[NSTask alloc] init];
216+
217+
[ioRegTask setLaunchPath: @"/usr/sbin/ioreg"];
218+
[grepTask setLaunchPath: @"/usr/bin/grep"];
219+
220+
[ioRegTask setArguments: [NSArray arrayWithObjects: @"-l", nil]];
221+
[grepTask setArguments: [NSArray arrayWithObjects: @"IOPlatformSerialNumber", nil]];
222+
223+
/* Connect the pipes */
224+
NSPipe *pipeBetween = [NSPipe pipe];
225+
[ioRegTask setStandardOutput: pipeBetween];
226+
[grepTask setStandardInput: pipeBetween];
227+
NSPipe *pipeToMe = [NSPipe pipe];
228+
[grepTask setStandardOutput: pipeToMe];
229+
230+
NSFileHandle *grepOutput = [pipeToMe fileHandleForReading];
231+
232+
[ioRegTask launch];
233+
[grepTask launch];
234+
[grepTask waitUntilExit];
235+
236+
NSData *data = [grepOutput readDataToEndOfFile];
237+
[ioRegTask release];
238+
[grepTask release];
239+
NSString* targetLine = [[NSString alloc] initWithData:data
240+
encoding:NSUTF8StringEncoding];
241+
if (targetLine.length > 0) {
242+
NSScanner* scanner = [[NSScanner alloc] initWithString:targetLine];
243+
NSString* serialString = nil;
244+
[scanner scanUpToString:@"=" intoString:NULL];
245+
[scanner scanUpToString:@"\"" intoString:NULL];
246+
scanner.scanLocation = scanner.scanLocation + 1;
247+
[scanner scanUpToString:@"\"" intoString:&serialString];
248+
[scanner release];
249+
NSData* data = [serialString dataUsingEncoding:NSUTF8StringEncoding];
250+
[data retain];
251+
MACAddressData = (CFDataRef)data;
252+
}
253+
[targetLine release];
200254
}
201255

202256
return [(NSData*)MACAddressData autorelease] ;
203257
}
204258

205259
+ (NSData*)hashedMACAddress {
206-
NSData* macAddress = [SSYIOKit primaryMACAddressData] ;
260+
NSData* macAddress = [SSYIOKit primaryMACAddressOrMachineSerialNumberData] ;
207261
NSData* hashedMACAddress = [macAddress sha1Digest] ;
208262
return hashedMACAddress ;
209263
}
210264

211265
+ (NSData*)hashedMACAddressAndShortUserName {
212-
NSData* macAddress = [SSYIOKit primaryMACAddressData];
266+
NSData* macAddress = [SSYIOKit primaryMACAddressOrMachineSerialNumberData];
213267
NSData* userNameData = [NSUserName() dataUsingEncoding:NSUTF8StringEncoding];
214268
NSMutableData* data = [macAddress mutableCopy];
215269
[data appendData:userNameData];

0 commit comments

Comments
 (0)