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 {