-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.swift
94 lines (81 loc) · 3.07 KB
/
main.swift
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// pinentry-tem - A barebones pinentry for macOS using Touch ID and Keychain.
// Author: Alexander Pushkov <alexander@notpushk.in>
// SPDX-License-Identifier: ISC
import Foundation
import LocalAuthentication
import Darwin.C
let keychainServiceName = "sh.ale.PinentryTem.password"
let policy = LAPolicy.deviceOwnerAuthenticationWithBiometrics
let reason = "validate your Tem Shop purchase"
// Save the passphrase into Keychain.
func setPassword(password: String) -> Bool {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: keychainServiceName,
kSecValueData as String: password
]
let status = SecItemAdd(query as CFDictionary, nil)
return status == errSecSuccess
}
// Get the passphrase from Keychain.
func getPassword() -> String? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: keychainServiceName,
kSecMatchLimit as String: kSecMatchLimitOne,
kSecReturnData as String: true
]
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)
guard status == errSecSuccess,
let passwordData = item as? Data,
let password = String(data: passwordData, encoding: String.Encoding.utf8)
else { return nil }
return password
}
func interact() {
let context = LAContext()
context.touchIDAuthenticationAllowableReuseDuration = 0
var error: NSError?
guard context.canEvaluatePolicy(policy, error: &error) else {
print("ERR 83886179 Your Mac doesn't support deviceOwnerAuthenticationWithBiometrics")
exit(EXIT_FAILURE)
}
print("OK hOI! welcom to... da TEM SHOP!!!")
while let input = readLine() {
if input.lowercased().hasPrefix("setpass") {
// TODO: use a CLI option
guard setPassword(password: "SUPERSECURE") else {
print("ERR 83886179 ??????")
continue
}
print("OK tem set password to 'SUPERSECURE'!!! (change it using Keychain Access)")
continue
}
switch input.lowercased() {
case "getpin":
context.evaluatePolicy(policy, localizedReason: reason) { success, error in
if success && error == nil {
guard let password = getPassword() else {
print("ERR 83886179 you don hav da passwords,")
return
}
print("D \(password)")
print("OK thanks PURCHASE!")
} else {
let errorDescription = error?.localizedDescription ?? "Unknown error"
print("ERR 83886179 \(errorDescription)")
}
}
case "bye":
print("OK bOI")
exit(EXIT_SUCCESS)
default:
print("OK fdshfg")
}
}
// on EOF, continue running until ^C
dispatchMain()
}
setbuf(__stdoutp, nil)
interact()