|
IntroductionDevelopers sometimes need to uniquely identify a particular Macintosh computer. Applications that require this typically fall into two categories:
In general, the only consistent serial number on a Macintosh computer is on the bar code label attached to the machine's case. On current versions of Mac OS X, the About This Mac window and the System Profiler utility display this serial number. At first glance this appears to be what developers would want to use in their products, but there are caveats that this technote will discuss. Note: Beyond general advice such as provided in this technote, DTS does not support developing digital rights management products because of the significant compatibility issues involved that can affect customers. DTS does not maintain expertise in DRM techniques. Serious DRM is much more complicated than this technote describes. Asset Tracking and Remote System ManagementAsset tracking applications allow system administrators to keep an inventory of the computers they manage for accounting purposes. Remote system management applications allow administrators to manage systems remotely, such as to install new software, reset passwords, view attached devices, and so on. These applications often allow the administrator to access information about a particular computer using its serial number. This is a logical attribute to use: it's a human-readable attribute that is unique and readable even if the machine is nonfunctional. Accessing the system serial number programmaticallyDevelopers of these applications often ask how to retrieve the system serial number that appears in the About This Mac window or in System Profiler. Prior to Mac OS X 10.3 "Panther", the only supported means of retrieving the serial number is to use AppleScript or Apple events to request this information from the System Profiler utility. However, starting with Panther, the serial number is presented in the property Listing 1: Reading the IOPlatformSerialNumber property #include <CoreFoundation/CoreFoundation.h> #include <IOKit/IOKitLib.h> // Returns the serial number as a CFString. // It is the caller's responsibility to release the returned CFString when done with it. void CopySerialNumber(CFStringRef *serialNumber) { if (serialNumber != NULL) { *serialNumber = NULL; io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")); if (platformExpert) { CFTypeRef serialNumberAsCFString = IORegistryEntryCreateCFProperty(platformExpert, CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0); if (serialNumberAsCFString) { *serialNumber = serialNumberAsCFString; } IOObjectRelease(platformExpert); } } } Caveats for using the serial numberIt is possible for a system to lose its serial number so that it will no longer appear either in System Profiler or the I/O Registry. Repairing a system by swapping hardware components is one reason this can happen. Apple does not document the specific details of how a machine can lose its serial number. Once the serial number has been lost there is no means to restore it to the machine. Apple does not guarantee that all future systems will have a software-readable serial number. Both of these cases illustrate why asset tracking software should always provide a way for a serial number to be entered manually. IMPORTANT: Developers should not make any assumptions about the format of the serial number such as its length or what characters it may contain. Digital Rights Management (DRM)Digital rights management products seek to limit access to software or other digital content to licensed users of that content. DRM solutions have more stringent requirements for a system identifier:
The Ethernet MAC (media access control) address for the primary built-in Ethernet interface is the closest fit to these requirements available on Macintosh computers. The IEEE 802 networking standards specify universal addresses because a station with such an address can be attached to any LAN in the world with an assurance that the address will be unique. All systems that can run Mac OS X include at least one built-in Ethernet port, so the presence of a MAC address is assured. On systems with more than one Ethernet port, one port is designated the primary port and is assigned the interface name Accessing the built-in MAC address programmaticallyThe primary MAC address can be read from the I/O Registry as shown in the sample Sample Code Project 'GetPrimaryMACAddress'. Caveats for using the primary MAC addressThe primary MAC address is associated with a particular system main logic board. So while the address is stable, it will change should the system's main logic board need to be replaced. Or, a customer may simply want to transfer their licensed content to a newly-purchased computer. DRM solutions relying on the primary MAC address should provide a means for users to re-register their licensed content to a different MAC address. Netbooting introduces a wrinkle with systems with multiple built-in Ethernet ports. The primary Ethernet port on these systems is the one that is connected to the NetBoot server. This means that a search for the primary port may return either of the built-in MAC addresses depending on which port was used for netbooting. Note that "built-in" does not include Ethernet ports that reside on an expansion card. There are other means for reading a MAC address programmatically besides the I/O Registry technique employed by the GetPrimaryMACAddress sample. One is to use the function Neither the Finally, it is possible for the built-in MAC address (or any I/O Registry property for that matter) to be spoofed by knowledgeable persons. If a more robust level of security is required, such as in cases where the licensed assets have a high monetary value, developers may want to investigate the numerous hardware security tokens that are available. Network RegistrationRather than identifying a unique Macintosh computer, you may decide that you want to prevent multiple copies of the same application running on a network. The method some developers use is to register a service on the network using Bonjour with the name being a hash of the single serial number of the license. (Of course, you still need a way of generating and distributing that serial number.) Attempts to register the same service and serial number will return an error that the application uses to deny the use of the program. Some resources you can refer to to learn more about Bonjour are: Caveats for using network registrationWhen using Bonjour in this way, pass in zero for the port number when registering your service. This will prevent these services from showing up when browsing. Be sure to register a hash of the serial number, not the actual serial number, since it would be easy to use a packet sniffer to capture the raw serial number. If the user has admin privileges, they can always disable the Bonjour daemon ConclusionsThe schemes described here are simple ways to help uniquely identify a computer. Each approach is best suited for particular situations. If you are serious about digital rights management, you should probably be contacting one of the many companies which specialize in DRM solutions, rather than writing a solution yourself. Both hardware solutions (such as USB dongles) and software solutions (such as licensing software) are widely available from third parties. ReferencesDocument Revision History
Posted: 2006-04-25 |
|