From bb9c6ea62207dd9d41a08ca59c7a1f5d6fa07189 Mon Sep 17 00:00:00 2001
From: Sam <30577766+Samasaur1@users.noreply.github.com>
Date: Tue, 24 Dec 2024 17:04:24 -0800
Subject: [PATCH] Convert script to Swift Package Manager library (#5)
* Convert to Swift Package Manager module
* Update Makefile to use SPM build
This also avoids the incredibly cursed SDK parsing
* Switch from a Swift version check to a module import check
The check for the Swift 6.0 compiler was trying to do the same thing
(ensure that the 15.0 SDK or newer was in use before compiling code that
would error on earlier SDKs), but there were niche situations where it
would not work.
Thanks to , I have
found a framework (CoreHID) that only exists in the 15.0 SDK or newer,
so I have switched to checking if that module can be imported.
* Use Swift's ability to create a universal binary
* Restore legacy build in Makefile
* fix makefile
---------
Co-authored-by: Logicer
---
.gitignore | 1 +
Makefile | 25 +++++++++----------
Package.swift | 22 ++++++++++++++++
.../pam-watchid/pam_watchid.swift | 2 +-
4 files changed, 36 insertions(+), 14 deletions(-)
create mode 100644 Package.swift
rename watchid-pam-extension.swift => Sources/pam-watchid/pam_watchid.swift (98%)
diff --git a/.gitignore b/.gitignore
index 0f5ab48..53521f4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@
*.swp
*.swo
._*
+/.build
diff --git a/Makefile b/Makefile
index 5abb85c..dd59755 100644
--- a/Makefile
+++ b/Makefile
@@ -2,25 +2,24 @@ VERSION = $(shell cat VERSION)
LIBRARY_PREFIX = pam_watchid
LIBRARY_NAME = $(LIBRARY_PREFIX).so
DESTINATION = /usr/local/lib/pam
-TARGET = apple-darwin$(shell uname -r)
+TARGET = apple-macosx10.15
PAM_FILE_BASE = /etc/pam.d/sudo
PAM_TEXT = auth sufficient $(LIBRARY_NAME)
PAM_TID_TEXT = auth sufficient pam_tid.so
-# Determine if the macOS Sequoia SDK or later is available.
-DEFINES =
-# Due to the different ways in which the CLT and Xcode structure their SDK paths, one of the following will always be an empty string depending on what is configured by xcode-select.
-CLT_SDK_MAJOR_VER = $(shell xcrun --sdk macosx --show-sdk-path | xargs readlink -f | xargs basename | sed 's/MacOSX//' | cut -d. -f1)
-XCODE_SDK_MAJOR_VER = $(shell xcrun --sdk macosx --show-sdk-path | xargs basename | sed 's/MacOSX//' | cut -d. -f1)
-SDK_REQUIRED_MAJOR_VER = 15
-ifeq "$(SDK_REQUIRED_MAJOR_VER)" "$(word 1, $(sort $(SDK_REQUIRED_MAJOR_VER) $(XCODE_SDK_MAJOR_VER) $(CLT_SDK_MAJOR_VER)))"
- DEFINES += -DSEQUOIASDK
-endif
-
all:
- swiftc watchid-pam-extension.swift $(DEFINES) -o $(LIBRARY_PREFIX)_x86_64.so -target x86_64-$(TARGET) -emit-library
- swiftc watchid-pam-extension.swift $(DEFINES) -o $(LIBRARY_PREFIX)_arm64.so -target arm64-$(TARGET) -emit-library
+ifeq ($(shell [[ '$(shell xcode-select -p)' == '/Library/Developer/CommandLineTools' ]] && echo true),true)
+# Legacy build
+# For CLT due to poor support for building swift packages.
+# Swift packages do work in macOS Sonoma and later with the CLT, but are an order of magnitude slower than Xcode.
+ swiftc Sources/pam-watchid/pam_watchid.swift -o $(LIBRARY_PREFIX)_x86_64.so -target x86_64-$(TARGET) -emit-library
+ swiftc Sources/pam-watchid/pam_watchid.swift -o $(LIBRARY_PREFIX)_arm64.so -target arm64-$(TARGET) -emit-library
lipo -create $(LIBRARY_PREFIX)_arm64.so $(LIBRARY_PREFIX)_x86_64.so -output $(LIBRARY_NAME)
+else
+# Swift Package Manager build
+ swift build -c release --arch x86_64 --arch arm64
+ mv .build/apple/Products/Release/libpam-watchid.dylib $(LIBRARY_NAME)
+endif
install: all
sudo mkdir -p $(DESTINATION)
diff --git a/Package.swift b/Package.swift
new file mode 100644
index 0000000..6082f3d
--- /dev/null
+++ b/Package.swift
@@ -0,0 +1,22 @@
+// swift-tools-version:5.1
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "pam-watchid",
+ platforms: [.macOS(.v10_15)],
+ products: [
+ // Products define the executables and libraries a package produces, making them visible to other packages.
+ .library(
+ name: "pam-watchid",
+ type: .dynamic,
+ targets: ["pam-watchid"]),
+ ],
+ targets: [
+ // Targets are the basic building blocks of a package, defining a module or a test suite.
+ // Targets can depend on other targets in this package and products from dependencies.
+ .target(
+ name: "pam-watchid"),
+ ]
+)
diff --git a/watchid-pam-extension.swift b/Sources/pam-watchid/pam_watchid.swift
similarity index 98%
rename from watchid-pam-extension.swift
rename to Sources/pam-watchid/pam_watchid.swift
index 2a46d79..30ff587 100644
--- a/watchid-pam-extension.swift
+++ b/Sources/pam-watchid/pam_watchid.swift
@@ -80,7 +80,7 @@ private func parseArguments(argc: Int, argv: vchar) -> [String: String] {
private extension LAPolicy {
static var deviceOwnerAuthenticationIgnoringUserID: LAPolicy {
-#if SEQUOIASDK
+#if canImport(CoreHID) // Check for the 15.0 SDK
if #available(macOS 15, *) {
return .deviceOwnerAuthenticationWithBiometricsOrCompanion
} else {