Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ Since this is a library build in native go, the files are mostly organized follo
## Code Style

- Follow Go's idiomatic style defined in
- #fetch https://google.github.io/styleguide/go/guide
- #fetch https://google.github.io/styleguide/go/decisions
- #fetch https://google.github.io/styleguide/go/best-practices
- #fetch https://golang.org/doc/effective_go.html
- <https://google.github.io/styleguide/go/guide>
- <https://google.github.io/styleguide/go/decisions>
- <https://google.github.io/styleguide/go/best-practices>
- <https://golang.org/doc/effective_go.html>
- Use meaningful names for variables, functions, and packages.
- Keep functions small and focused on a single task.
- Use comments to explain complex logic or decisions.
Expand Down
186 changes: 0 additions & 186 deletions .github/workflows/main.yml

This file was deleted.

1 change: 1 addition & 0 deletions CLAUDE.md
34 changes: 30 additions & 4 deletions darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ var (
ioregSerialRe = regexp.MustCompile(`"IOPlatformSerialNumber"\s*=\s*"([^"]+)"`)
)

// nullUUID is the all-zero UUID that some firmware implementations return
// when no real hardware UUID is programmed. It must be rejected so it
// cannot contribute to the machine ID.
const nullUUID = "00000000-0000-0000-0000-000000000000"

// spHardwareDataType represents the JSON output of `system_profiler SPHardwareDataType -json`.
type spHardwareDataType struct {
SPHardwareDataType []spHardwareEntry `json:"SPHardwareDataType"`
Expand Down Expand Up @@ -90,17 +95,22 @@ func collectIdentifiers(ctx context.Context, p *Provider, diag *DiagnosticInfo)
}

// macOSHardwareUUID retrieves hardware UUID using system_profiler with JSON parsing.
// Null UUIDs (all zeros) are rejected so the fallback path is triggered.
func macOSHardwareUUID(ctx context.Context, executor CommandExecutor, logger *slog.Logger) (string, error) {
output, err := executeCommand(ctx, executor, logger, "system_profiler", "SPHardwareDataType", "-json")
if err == nil {
uuid, parseErr := extractHardwareField(output, func(e spHardwareEntry) string {
return e.PlatformUUID
})
if parseErr == nil {
return uuid, nil
}

if logger != nil {
if uuid == nullUUID {
if logger != nil {
logger.Debug("system_profiler returned null UUID, falling back")
}
} else {
return uuid, nil
}
} else if logger != nil {
logger.Debug("system_profiler UUID parsing failed", "error", parseErr)
}
}
Expand All @@ -114,6 +124,7 @@ func macOSHardwareUUID(ctx context.Context, executor CommandExecutor, logger *sl
}

// macOSHardwareUUIDViaIOReg retrieves hardware UUID using ioreg as fallback.
// Null UUIDs (all zeros) are rejected with ErrNotFound.
func macOSHardwareUUIDViaIOReg(ctx context.Context, executor CommandExecutor, logger *slog.Logger) (string, error) {
output, err := executeCommand(ctx, executor, logger, "ioreg", "-d2", "-c", "IOPlatformExpertDevice")
if err != nil {
Expand All @@ -122,6 +133,14 @@ func macOSHardwareUUIDViaIOReg(ctx context.Context, executor CommandExecutor, lo

match := ioregUUIDRe.FindStringSubmatch(output)
if len(match) > 1 {
if match[1] == nullUUID {
if logger != nil {
logger.Debug("ioreg returned null UUID")
}

return "", &ParseError{Source: "ioreg output", Err: ErrNotFound}
}

return match[1], nil
}

Expand Down Expand Up @@ -182,6 +201,13 @@ func macOSSerialNumberViaIOReg(ctx context.Context, executor CommandExecutor, lo
// producing "ChipType:" — this trailing colon is preserved for backward
// compatibility with existing license activations.
// Falls back to system_profiler chip_type only if sysctl fails entirely.
//
// Known quirk: if machdep.cpu.brand_string succeeds but machdep.cpu.features
// errors (e.g. transient syscall failure under sandboxing), the result
// degrades to just cpuBrand instead of "cpuBrand:features". This produces a
// different hash for the same machine across calls. The divergence is
// preserved intentionally — changing it would invalidate every existing
// license activation generated under the current behavior.
func macOSCPUInfo(ctx context.Context, executor CommandExecutor, logger *slog.Logger) (string, error) {
// Primary: sysctl (backward compatible)
output, err := executeCommand(ctx, executor, logger, "sysctl", "-n", "machdep.cpu.brand_string")
Expand Down
Loading
Loading