@@ -35,7 +35,7 @@ import SSH
35
35
36
36
37
37
final class SSHDefaultAgent {
38
- public static var instance : SSHAgent {
38
+ public static var instance : SSHAgent ? {
39
39
if let agent = Self . _instance {
40
40
return agent
41
41
} else {
@@ -44,6 +44,7 @@ final class SSHDefaultAgent {
44
44
}
45
45
private static var _instance : SSHAgent ? = nil
46
46
private init ( ) { }
47
+ // The pool is responsible for the location of Agents.
47
48
private static let defaultAgentFile : URL = BlinkPaths . blinkAgentSettingsURL ( ) . appendingPathComponent ( " default " )
48
49
49
50
enum Error : Swift . Error , LocalizedError {
@@ -57,30 +58,41 @@ final class SSHDefaultAgent {
57
58
}
58
59
}
59
60
60
- private static func load( ) -> SSHAgent {
61
- let instance = SSHAgent ( )
62
- Self . _instance = instance
63
- // If the Settings are not available, the agent is initialized with the default configuration.
64
- // If there is a problem with the location, it is safe to assume that it will persist.
65
- if let settings = try ? getSettings ( ) {
66
- try ? applySettings ( settings)
67
- } else {
68
- try ? setSettings ( BKAgentSettings ( prompt: . Confirm, keys: [ ] ) )
61
+ // Load the (default) agent in the pool. If the Agent cannot be loaded, it will be unavailable (nil).
62
+ // If the agent doesn't exist, it will be initialized (default only).
63
+ private static func load( ) -> SSHAgent ? {
64
+ do {
65
+ if let settings = try getSettings ( ) {
66
+ try setAgentInstance ( with: settings)
67
+ } else {
68
+ try setSettings ( BKAgentSettings ( ) )
69
+ }
70
+ } catch {
71
+ return nil
69
72
}
70
- return instance
73
+
74
+ return Self . _instance
71
75
}
72
76
77
+ // Create the settings for the agent and load it in the pool.
78
+ // NOTE: For non-default agents, this would be the main initialization method.
73
79
static func setSettings( _ settings: BKAgentSettings ) throws {
74
80
try BKAgentSettings . save ( settings: settings, to: defaultAgentFile)
75
- try applySettings ( settings)
81
+ try setAgentInstance ( with : settings)
76
82
}
77
83
78
- private static func applySettings( _ settings: BKAgentSettings ) throws {
79
- let agent = Self . instance
80
- agent. clear ( )
81
-
84
+ private static func setAgentInstance( with settings: BKAgentSettings ) throws {
82
85
let bkConfig = try BKConfig ( )
83
86
87
+ let agent : SSHAgent
88
+ if let _instance = Self . _instance {
89
+ agent = _instance
90
+ agent. clear ( )
91
+ } else {
92
+ agent = SSHAgent ( )
93
+ Self . _instance = agent
94
+ }
95
+
84
96
settings. keys. forEach { key in
85
97
if let ( signer, name) = bkConfig. signer ( forIdentity: key) {
86
98
if let constraints = settings. constraints ( ) {
@@ -90,18 +102,21 @@ final class SSHDefaultAgent {
90
102
}
91
103
}
92
104
93
- static func getSettings( ) throws -> BKAgentSettings {
94
- try BKAgentSettings . load ( from: defaultAgentFile)
105
+ static func getSettings( ) throws -> BKAgentSettings ? {
106
+ try BKAgentSettings . read ( from: defaultAgentFile)
95
107
}
96
108
97
109
// Applying settings clears the agent first. Adding a key doesn't modify or reset previous constraints.
98
110
static func addKey( named keyName: String ) throws {
99
- let settings = try getSettings ( )
111
+ guard let agent = Self . instance,
112
+ let settings = try getSettings ( ) else {
113
+ return
114
+ }
115
+
100
116
if settings. keys. contains ( keyName) {
101
117
return
102
118
}
103
119
104
- let agent = Self . instance
105
120
let bkConfig = try BKConfig ( )
106
121
107
122
if let ( signer, name) = bkConfig. signer ( forIdentity: keyName) {
@@ -124,16 +139,17 @@ final class SSHDefaultAgent {
124
139
125
140
static func removeKey( named keyName: String ) throws -> Signer ? {
126
141
// Remove from settings and apply
127
- let settings = try getSettings ( )
128
- guard settings. keys. contains ( keyName) else {
142
+ guard let agent = Self . instance,
143
+ let settings = try getSettings ( ) ,
144
+ settings. keys. contains ( keyName) else {
129
145
return nil
130
146
}
131
147
132
148
var keys = settings. keys
133
149
keys. removeAll ( where: { $0 == keyName } )
134
150
try BKAgentSettings . save ( settings: BKAgentSettings ( prompt: settings. prompt, keys: keys) , to: defaultAgentFile)
135
151
136
- return Self . instance . removeKey ( keyName)
152
+ return agent . removeKey ( keyName)
137
153
}
138
154
}
139
155
@@ -151,17 +167,22 @@ struct BKAgentSettings: Codable, Equatable {
151
167
let prompt : BKAgentSettingsPrompt
152
168
let keys : [ String ]
153
169
154
- // init(prompt: BKAgentSettingsPrompt, keys: [String]) {
155
- // self.prompt = prompt
156
- // self.keys = keys
157
- // }
170
+ init ( prompt: BKAgentSettingsPrompt , keys: [ String ] ) {
171
+ self . prompt = prompt
172
+ self . keys = keys
173
+ }
174
+
175
+ init ( ) { self = Self ( prompt: . Confirm, keys: [ ] ) }
158
176
159
177
static func save( settings: BKAgentSettings , to file: URL ) throws {
160
178
let data = try JSONEncoder ( ) . encode ( settings)
161
179
try data. write ( to: file)
162
180
}
163
181
164
- static func load( from file: URL ) throws -> BKAgentSettings {
182
+ fileprivate static func read( from file: URL ) throws -> BKAgentSettings ? {
183
+ guard FileManager . default. fileExists ( atPath: file. path) else {
184
+ return nil
185
+ }
165
186
let data = try Data ( contentsOf: file)
166
187
return try JSONDecoder ( ) . decode ( BKAgentSettings . self, from: data)
167
188
}
0 commit comments