Mercurial > servermonitor
comparison ServerMonitor/Objects/ServerMonitor.cs @ 5:b6fe203af9d5
Private key passwords and validation
author | Brad Greco <brad@bgreco.net> |
---|---|
date | Thu, 28 Feb 2019 21:19:32 -0500 |
parents | 3142e52cbe69 |
children | c1dffaac66fa |
comparison
equal
deleted
inserted
replaced
4:3142e52cbe69 | 5:b6fe203af9d5 |
---|---|
1 using ServerMonitorApp.Properties; | 1 using Renci.SshNet; |
2 using Renci.SshNet.Common; | |
3 using ServerMonitorApp.Properties; | |
2 using System; | 4 using System; |
3 using System.Collections.Generic; | 5 using System.Collections.Generic; |
4 using System.Diagnostics; | 6 using System.Diagnostics; |
5 using System.IO; | 7 using System.IO; |
6 using System.Linq; | 8 using System.Linq; |
16 public class ServerMonitor | 18 public class ServerMonitor |
17 { | 19 { |
18 private readonly string configFileDir; | 20 private readonly string configFileDir; |
19 private readonly Logger logger; | 21 private readonly Logger logger; |
20 private readonly Dictionary<int, CancellationTokenSource> tokens = new Dictionary<int, CancellationTokenSource>(); | 22 private readonly Dictionary<int, CancellationTokenSource> tokens = new Dictionary<int, CancellationTokenSource>(); |
23 private readonly Dictionary<string, PrivateKeyFile> privateKeys = new Dictionary<string, PrivateKeyFile>(); | |
21 private readonly List<int> pausedChecks = new List<int>(); | 24 private readonly List<int> pausedChecks = new List<int>(); |
22 private bool running, networkAvailable; | 25 private bool running, networkAvailable; |
23 private Dictionary<Task<CheckResult>, int> tasks; | 26 private Dictionary<Task<CheckResult>, int> tasks; |
24 private ServerSummaryForm mainForm; | 27 private ServerSummaryForm mainForm; |
25 | 28 |
30 public List<Server> Servers { get; private set; } = new List<Server>(); | 33 public List<Server> Servers { get; private set; } = new List<Server>(); |
31 | 34 |
32 public IEnumerable<Check> Checks => Servers.SelectMany(s => s.Checks); | 35 public IEnumerable<Check> Checks => Servers.SelectMany(s => s.Checks); |
33 | 36 |
34 public string ConfigFile { get; private set; } | 37 public string ConfigFile { get; private set; } |
38 | |
39 public IEnumerable<string> LockedKeys { get { return privateKeys.Where(kvp => kvp.Value == null).Select(kvp => kvp.Key); } } | |
35 | 40 |
36 public ServerMonitor(ServerSummaryForm mainForm) | 41 public ServerMonitor(ServerSummaryForm mainForm) |
37 { | 42 { |
38 this.mainForm = mainForm; | 43 this.mainForm = mainForm; |
39 configFileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ServerMonitor"); | 44 configFileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ServerMonitor"); |
65 // Update the Checks so they know what Server they belong to. | 70 // Update the Checks so they know what Server they belong to. |
66 // Would rather do this in the Server object on deserialization, but | 71 // Would rather do this in the Server object on deserialization, but |
67 // that doesn't work when using the XML serializer for some reason. | 72 // that doesn't work when using the XML serializer for some reason. |
68 foreach (Server server in Servers) | 73 foreach (Server server in Servers) |
69 { | 74 { |
75 if (server.LoginType == LoginType.PrivateKey) | |
76 OpenPrivateKey(server.KeyFile); | |
70 foreach (Check check in server.Checks) | 77 foreach (Check check in server.Checks) |
71 { | 78 { |
72 check.Server = server; | 79 check.Server = server; |
73 if (check.Status == CheckStatus.Running) | 80 if (check.Status == CheckStatus.Running) |
74 check.Status = check.LastRunStatus; | 81 check.Status = check.LastRunStatus; |
234 } | 241 } |
235 | 242 |
236 private void CancelCheck(Check check) | 243 private void CancelCheck(Check check) |
237 { | 244 { |
238 Task<CheckResult> task = tasks.FirstOrDefault(kvp => kvp.Value == check.Id).Key; | 245 Task<CheckResult> task = tasks.FirstOrDefault(kvp => kvp.Value == check.Id).Key; |
239 tasks.Remove(task); | 246 if (task != null) |
247 tasks.Remove(task); | |
240 pausedChecks.RemoveAll(id => id == check.Id); | 248 pausedChecks.RemoveAll(id => id == check.Id); |
241 if (tokens.TryGetValue(check.Id, out CancellationTokenSource cts)) | 249 if (tokens.TryGetValue(check.Id, out CancellationTokenSource cts)) |
242 cts.Cancel(); | 250 cts.Cancel(); |
243 } | 251 } |
244 | 252 |
267 networkAvailable = Helpers.IsNetworkAvailable(); | 275 networkAvailable = Helpers.IsNetworkAvailable(); |
268 if (networkAvailable) | 276 if (networkAvailable) |
269 mainForm.Invoke((MethodInvoker)(() => Run())); | 277 mainForm.Invoke((MethodInvoker)(() => Run())); |
270 } | 278 } |
271 | 279 |
280 public KeyStatus OpenPrivateKey(string path, string password = null) | |
281 { | |
282 KeyStatus keyStatus; | |
283 if (path == null) | |
284 return KeyStatus.NotAccessible; | |
285 if (privateKeys.TryGetValue(path, out PrivateKeyFile key) && key != null) | |
286 return KeyStatus.Open; | |
287 try | |
288 { | |
289 key = new PrivateKeyFile(path, password); | |
290 keyStatus = KeyStatus.Open; | |
291 } | |
292 catch (Exception e) when (e is SshPassPhraseNullOrEmptyException || e is InvalidOperationException) | |
293 { | |
294 keyStatus = KeyStatus.NeedPassword; | |
295 } | |
296 catch (Exception) | |
297 { | |
298 keyStatus = KeyStatus.NotAccessible; | |
299 } | |
300 foreach (Server server in Servers) | |
301 { | |
302 if (server.KeyFile == path) | |
303 { | |
304 server.PrivateKeyFile = key; | |
305 server.KeyStatus = keyStatus; | |
306 } | |
307 } | |
308 privateKeys[path] = key; | |
309 return keyStatus; | |
310 } | |
311 | |
272 private void GenerateIds() | 312 private void GenerateIds() |
273 { | 313 { |
274 if (Servers.Any()) | 314 if (Servers.Any()) |
275 { | 315 { |
276 int id = Servers.Max(s => s.Id); | 316 int id = Servers.Max(s => s.Id); |