mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-16 12:30:29 +00:00
Add a TXM value for external devices
This commit is contained in:
parent
4e4cb2b782
commit
1ce0c91282
3 changed files with 114 additions and 24 deletions
|
|
@ -15,6 +15,53 @@ struct DeviceProfileEntry: Identifiable, Codable, Equatable {
|
|||
var pairingFilename: String
|
||||
var dateAdded: Date
|
||||
var lastUpdated: Date
|
||||
var isTXM: Bool
|
||||
|
||||
init(id: UUID,
|
||||
name: String,
|
||||
ipAddress: String,
|
||||
pairingRelativePath: String,
|
||||
pairingFilename: String,
|
||||
dateAdded: Date,
|
||||
lastUpdated: Date,
|
||||
isTXM: Bool = false) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.ipAddress = ipAddress
|
||||
self.pairingRelativePath = pairingRelativePath
|
||||
self.pairingFilename = pairingFilename
|
||||
self.dateAdded = dateAdded
|
||||
self.lastUpdated = lastUpdated
|
||||
self.isTXM = isTXM
|
||||
}
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id, name, ipAddress, pairingRelativePath, pairingFilename, dateAdded, lastUpdated, isTXM
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
id = try container.decode(UUID.self, forKey: .id)
|
||||
name = try container.decode(String.self, forKey: .name)
|
||||
ipAddress = try container.decode(String.self, forKey: .ipAddress)
|
||||
pairingRelativePath = try container.decode(String.self, forKey: .pairingRelativePath)
|
||||
pairingFilename = try container.decode(String.self, forKey: .pairingFilename)
|
||||
dateAdded = try container.decode(Date.self, forKey: .dateAdded)
|
||||
lastUpdated = try container.decode(Date.self, forKey: .lastUpdated)
|
||||
isTXM = try container.decodeIfPresent(Bool.self, forKey: .isTXM) ?? false
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(id, forKey: .id)
|
||||
try container.encode(name, forKey: .name)
|
||||
try container.encode(ipAddress, forKey: .ipAddress)
|
||||
try container.encode(pairingRelativePath, forKey: .pairingRelativePath)
|
||||
try container.encode(pairingFilename, forKey: .pairingFilename)
|
||||
try container.encode(dateAdded, forKey: .dateAdded)
|
||||
try container.encode(lastUpdated, forKey: .lastUpdated)
|
||||
try container.encode(isTXM, forKey: .isTXM)
|
||||
}
|
||||
}
|
||||
|
||||
enum DeviceLibraryError: LocalizedError {
|
||||
|
|
@ -95,7 +142,11 @@ final class DeviceLibraryStore: ObservableObject {
|
|||
loadFromDisk()
|
||||
}
|
||||
|
||||
func addDevice(name: String, ipAddress: String, pairingData: Data?, originalFilename: String?) throws {
|
||||
func addDevice(name: String,
|
||||
ipAddress: String,
|
||||
pairingData: Data?,
|
||||
originalFilename: String?,
|
||||
isTXM: Bool) throws {
|
||||
guard let pairingData else {
|
||||
throw DeviceLibraryError.missingPairingData
|
||||
}
|
||||
|
|
@ -110,7 +161,8 @@ final class DeviceLibraryStore: ObservableObject {
|
|||
pairingRelativePath: relativePath,
|
||||
pairingFilename: originalFilename ?? "pairingFile.plist",
|
||||
dateAdded: now,
|
||||
lastUpdated: now
|
||||
lastUpdated: now,
|
||||
isTXM: isTXM
|
||||
)
|
||||
devices.append(entry)
|
||||
persistDevices()
|
||||
|
|
@ -120,7 +172,8 @@ final class DeviceLibraryStore: ObservableObject {
|
|||
name: String,
|
||||
ipAddress: String,
|
||||
pairingData: Data?,
|
||||
originalFilename: String?) throws {
|
||||
originalFilename: String?,
|
||||
isTXM: Bool) throws {
|
||||
guard !isDefaultDevice(device) else { return }
|
||||
guard let index = devices.firstIndex(where: { $0.id == device.id }) else {
|
||||
throw DeviceLibraryError.deviceNotFound
|
||||
|
|
@ -129,6 +182,7 @@ final class DeviceLibraryStore: ObservableObject {
|
|||
devices[index].name = name.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
devices[index].ipAddress = ipAddress.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
devices[index].lastUpdated = Date()
|
||||
devices[index].isTXM = isTXM
|
||||
if activeDeviceID == device.id {
|
||||
UserDefaults.standard.set(devices[index].ipAddress, forKey: "TunnelDeviceIP")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,14 +140,19 @@ struct DeviceLibraryView: View {
|
|||
private func handleSave(mode: DeviceEditorMode, input: DeviceEditorInput) throws {
|
||||
switch mode {
|
||||
case .add:
|
||||
try store.addDevice(name: input.name, ipAddress: input.ipAddress, pairingData: input.pairingData, originalFilename: input.pairingFilename)
|
||||
try store.addDevice(name: input.name,
|
||||
ipAddress: input.ipAddress,
|
||||
pairingData: input.pairingData,
|
||||
originalFilename: input.pairingFilename,
|
||||
isTXM: input.isTXM)
|
||||
alert = DeviceAlert(title: "Device Saved", message: "\(input.name) was added to your library.", isError: false)
|
||||
case .edit(let device):
|
||||
try store.update(device: device,
|
||||
name: input.name,
|
||||
ipAddress: input.ipAddress,
|
||||
pairingData: input.pairingData,
|
||||
originalFilename: input.pairingFilename ?? device.pairingFilename)
|
||||
originalFilename: input.pairingFilename ?? device.pairingFilename,
|
||||
isTXM: input.isTXM)
|
||||
alert = DeviceAlert(title: "Device Updated", message: "\(input.name) has been updated.", isError: false)
|
||||
}
|
||||
}
|
||||
|
|
@ -304,6 +309,21 @@ private struct DeviceRow: View {
|
|||
Text("Pairing: \(device.pairingFilename)")
|
||||
.font(.footnote)
|
||||
.foregroundColor(.secondary)
|
||||
if device.isTXM {
|
||||
Label("TXM Capable", systemImage: "shield.checkerboard")
|
||||
.font(.caption2.weight(.semibold))
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, 2)
|
||||
.background(Color.green.opacity(0.15), in: Capsule())
|
||||
.foregroundColor(.green)
|
||||
} else {
|
||||
Label("Non-TXM", systemImage: "xmark.shield")
|
||||
.font(.caption2.weight(.semibold))
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, 2)
|
||||
.background(Color.secondary.opacity(0.15), in: Capsule())
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer()
|
||||
|
|
@ -349,6 +369,7 @@ private struct DeviceEditorInput {
|
|||
var ipAddress: String
|
||||
var pairingData: Data?
|
||||
var pairingFilename: String?
|
||||
var isTXM: Bool
|
||||
}
|
||||
|
||||
private struct DeviceEditorSheet: View {
|
||||
|
|
@ -366,6 +387,7 @@ private struct DeviceEditorSheet: View {
|
|||
@State private var selectedFilename: String?
|
||||
@State private var errorMessage: String?
|
||||
@State private var showImporter = false
|
||||
@State private var isTXMDevice: Bool
|
||||
|
||||
private var accentColor: Color { themeExpansion?.resolvedAccentColor(from: customAccentColorHex) ?? .blue }
|
||||
private var requiresPairing: Bool {
|
||||
|
|
@ -397,9 +419,11 @@ private struct DeviceEditorSheet: View {
|
|||
case .add:
|
||||
_name = State(initialValue: "")
|
||||
_ipAddress = State(initialValue: "10.7.0.1")
|
||||
_isTXMDevice = State(initialValue: false)
|
||||
case .edit(let device):
|
||||
_name = State(initialValue: device.name)
|
||||
_ipAddress = State(initialValue: device.ipAddress)
|
||||
_isTXMDevice = State(initialValue: device.isTXM)
|
||||
}
|
||||
_selectedFilename = State(initialValue: nil)
|
||||
_pairingData = State(initialValue: nil)
|
||||
|
|
@ -413,6 +437,13 @@ private struct DeviceEditorSheet: View {
|
|||
.textInputAutocapitalization(.words)
|
||||
TextField("Device IP", text: $ipAddress)
|
||||
.keyboardType(.numbersAndPunctuation)
|
||||
Toggle(isOn: $isTXMDevice) {
|
||||
Text("TXM Capable")
|
||||
}
|
||||
.tint(accentColor)
|
||||
Text("Enable if this device includes the Trusted Execution Monitor (TXM).")
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
Section(header: Text("Pairing File")) {
|
||||
|
|
@ -493,7 +524,8 @@ private struct DeviceEditorSheet: View {
|
|||
name: name,
|
||||
ipAddress: ipAddress,
|
||||
pairingData: pairingData,
|
||||
pairingFilename: selectedFilename ?? existingFilename
|
||||
pairingFilename: selectedFilename ?? existingFilename,
|
||||
isTXM: isTXMDevice
|
||||
))
|
||||
dismiss()
|
||||
} catch {
|
||||
|
|
|
|||
|
|
@ -2126,24 +2126,28 @@ struct HomeView: View {
|
|||
// MARK: - TXM detection
|
||||
|
||||
public extension ProcessInfo {
|
||||
var hasTXM: Bool {
|
||||
if isTXMOverridden {
|
||||
return true
|
||||
}
|
||||
|
||||
return {
|
||||
if let boot = FileManager.default.filePath(atPath: "/System/Volumes/Preboot", withLength: 36),
|
||||
let file = FileManager.default.filePath(atPath: "\(boot)/boot", withLength: 96) {
|
||||
return access("\(file)/usr/standalone/firmware/FUD/Ap,TrustedExecutionMonitor.img4", F_OK) == 0
|
||||
} else {
|
||||
return (FileManager.default.filePath(atPath: "/private/preboot", withLength: 96).map {
|
||||
access("\($0)/usr/standalone/firmware/FUD/Ap,TrustedExecutionMonitor.img4", F_OK) == 0
|
||||
}) ?? false
|
||||
}
|
||||
}()
|
||||
var hasTXM: Bool {
|
||||
if isTXMOverridden {
|
||||
return true
|
||||
}
|
||||
|
||||
var isTXMOverridden: Bool {
|
||||
UserDefaults.standard.bool(forKey: UserDefaults.Keys.txmOverride)
|
||||
if DeviceLibraryStore.shared.isUsingExternalDevice {
|
||||
return DeviceLibraryStore.shared.activeDevice?.isTXM ?? false
|
||||
}
|
||||
return ProcessInfo.detectLocalTXM()
|
||||
}
|
||||
|
||||
var isTXMOverridden: Bool {
|
||||
UserDefaults.standard.bool(forKey: UserDefaults.Keys.txmOverride)
|
||||
}
|
||||
|
||||
private static func detectLocalTXM() -> Bool {
|
||||
if let boot = FileManager.default.filePath(atPath: "/System/Volumes/Preboot", withLength: 36),
|
||||
let file = FileManager.default.filePath(atPath: "\(boot)/boot", withLength: 96) {
|
||||
return access("\(file)/usr/standalone/firmware/FUD/Ap,TrustedExecutionMonitor.img4", F_OK) == 0
|
||||
} else {
|
||||
return (FileManager.default.filePath(atPath: "/private/preboot", withLength: 96).map {
|
||||
access("\($0)/usr/standalone/firmware/FUD/Ap,TrustedExecutionMonitor.img4", F_OK) == 0
|
||||
}) ?? false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue