forked from tailscale/tailscale
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserialnumber_macos.go
74 lines (67 loc) · 2.14 KB
/
serialnumber_macos.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:build cgo && darwin && !ios
package posture
// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit
// #include <CoreFoundation/CoreFoundation.h>
// #include <IOKit/IOKitLib.h>
//
// #if __MAC_OS_X_VERSION_MIN_REQUIRED < 120000
// #define kIOMainPortDefault kIOMasterPortDefault
// #endif
//
// const char *
// getSerialNumber()
// {
// CFMutableDictionaryRef matching = IOServiceMatching("IOPlatformExpertDevice");
// if (!matching) {
// return "err: failed to create dictionary to match IOServices";
// }
//
// io_service_t service = IOServiceGetMatchingService(kIOMainPortDefault, matching);
// if (!service) {
// return "err: failed to look up registered IOService objects that match a matching dictionary";
// }
//
// CFStringRef serialNumberRef = IORegistryEntryCreateCFProperty(
// service,
// CFSTR("IOPlatformSerialNumber"),
// kCFAllocatorDefault,
// 0
// );
// if (!serialNumberRef) {
// return "err: failed to look up serial number in IORegistry";
// }
//
// CFIndex length = CFStringGetLength(serialNumberRef);
// CFIndex max_size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
// char *serialNumberBuf = (char *)malloc(max_size);
//
// bool result = CFStringGetCString(serialNumberRef, serialNumberBuf, max_size, kCFStringEncodingUTF8);
//
// CFRelease(serialNumberRef);
// IOObjectRelease(service);
//
// if (!result) {
// free(serialNumberBuf);
//
// return "err: failed to convert serial number reference to string";
// }
//
// return serialNumberBuf;
// }
import "C"
import (
"fmt"
"strings"
"tailscale.com/types/logger"
)
// GetSerialNumber returns the platform serial sumber as reported by IOKit.
func GetSerialNumbers(_ logger.Logf) ([]string, error) {
csn := C.getSerialNumber()
serialNumber := C.GoString(csn)
if err, ok := strings.CutPrefix(serialNumber, "err: "); ok {
return nil, fmt.Errorf("failed to get serial number from IOKit: %s", err)
}
return []string{serialNumber}, nil
}