-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.swift
102 lines (88 loc) · 3.57 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
95
96
97
98
99
100
101
102
/*
Copyright NetFoundry Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import Foundation
import CZiti
func usage() {
let nm = URL(fileURLWithPath: args[0]).lastPathComponent
print("Usage: \(nm) file.jwt out.zid [--trustca]")
}
// CommandLine
let args = CommandLine.arguments
guard CommandLine.argc >= 3 else {
usage()
exit(-1)
}
if CommandLine.argc == 4 && args[3] != "--trustca" {
usage()
exit(-1)
}
let jwtFile = args[1]
let outFile = args[2]
let trustCa = (CommandLine.argc == 4)
// Enroll
Ziti.enroll(jwtFile) { zid, zErr in
guard let zid = zid else {
fputs("Invalid enrollment response, \(String(describing: zErr))\n", stderr)
exit(-1)
}
guard zid.save(outFile) else {
fputs("Unable to save to file \(outFile)\n", stderr)
exit(-1)
}
print("Successfully enrolled id \"\(zid.id)\" with controller \"\(zid.ztAPI)\"")
// Add the optional CA to keychain if not already trusted
if trustCa, let ca = zid.ca {
let zkc = ZitiKeychain(tag: zid.id)
let certs = zkc.extractCerts(ca)
// evalTrustForCertificates requires same DispatchQueue as caller, so force that to happen.
// need to process the queue, block until done
let dispQueue = DispatchQueue.main
let dispGroup = DispatchGroup()
dispGroup.enter()
dispQueue.async {
print("Evaluating trust for CA")
let status = zkc.evalTrustForCertificates(certs, dispQueue) { secTrust, isTrusted, err in
defer { dispGroup.leave() }
print("CA already trusted? \(isTrusted)")
// if not trusted, prompt to addTrustForCertificate
if !isTrusted {
guard zkc.addCaPool(ca) else {
fputs("Unable to add CA pool to kechain\n", stderr)
return
}
print("Added CA pool to Keychain")
// Might be configured still to not trust rootCA. Give user
// the change to mark as "Always Trust" (UI dialog will prompt for creds)
if let rootCA = zkc.extractRootCa(ca) {
let status = zkc.addTrustForCertificate(rootCA)
if status != errSecSuccess {
let errStr = SecCopyErrorMessageString(status, nil) as String? ?? "\(status)"
fputs("Unable to add trust for CA: \(errStr)\n", stderr)
} else {
print("User has allowed trust of CA")
}
}
}
}
guard status == errSecSuccess else {
let errStr = SecCopyErrorMessageString(status, nil) as String? ?? "\(status)"
fputs("Unable to evaluate trust for ca, err: \(status), \(errStr)\n", stderr)
exit(status)
}
}
dispGroup.notify(queue: dispQueue) {
exit(0)
}
dispatchMain()
}
}