From 5cf5e098d995d3f9c3255f166c438c6cc5beb4a3 Mon Sep 17 00:00:00 2001 From: Andreas Venizelou Date: Wed, 26 Jun 2024 17:12:20 +0300 Subject: [PATCH] Fetch SNMP, back-end --- Protest/Front/deviceview.js | 45 ++++++++++++++++++++++++-- Protest/Front/fetch.js | 4 +-- Protest/Front/userview.js | 2 +- Protest/Protocols/Kerberos.cs | 2 +- Protest/Tasks/Fetch.cs | 59 ++++++++++++++++++++++------------- 5 files changed, 83 insertions(+), 29 deletions(-) diff --git a/Protest/Front/deviceview.js b/Protest/Front/deviceview.js index 8bf641f0..10ab56c0 100644 --- a/Protest/Front/deviceview.js +++ b/Protest/Front/deviceview.js @@ -32,7 +32,7 @@ class DeviceView extends View { "owner", "owner name", "location", ["mono/directory.svg", "Domain information"], - "guid", "distinguished name", "dns hostname", "created on dc", "fqdn", + "object guid", "distinguished name", "dns hostname", "created on dc", "fqdn", ["mono/credential.svg", "credentials"], "domain", "username", "password", "ssh username", "ssh password", "anydesk id", "anydesk password" @@ -2658,8 +2658,6 @@ class DeviceView extends View { snmpInput.disabled = true; grid.appendChild(snmpInput); - //TODO: implement SNMP - const wmiToggle = this.CreateToggle("WMI", true, grid); wmiToggle.label.style.gridArea = "3 / 2"; @@ -2690,6 +2688,31 @@ class DeviceView extends View { extendedOption.text = "Extended (1-8191)"; portScanInput.appendChild(extendedOption); + setTimeout(async ()=>{ + const snmpProfiles = await this.GetSnmpProfiles(); + if (snmpProfiles === null || snmpProfiles.length === 0) return; + + snmpToggle.checkbox.disabled = false; + + for (let i = 0; i < snmpProfiles.length; i++) { + const option = document.createElement("option"); + option.value = snmpProfiles[i].guid; + option.text = snmpProfiles[i].name; + snmpInput.appendChild(option); + } + + if (this.link && "snmp profile" in this.link) { + snmpToggle.checkbox.checked = true; + snmpInput.disabled = false; + snmpInput.value = this.link["snmp profile"].v; + } + else if (this.link && ".snmp profile" in this.link) { + snmpToggle.checkbox.checked = true; + snmpInput.disabled = false; + snmpInput.value = this.link[".snmp profile"].v; + } + }, 0); + snmpToggle.checkbox.onchange = ()=> { snmpInput.disabled = !snmpToggle.checkbox.checked; }; @@ -2808,6 +2831,22 @@ class DeviceView extends View { dialog.okButton.focus(); } + async GetSnmpProfiles() { + try { + const response = await fetch("config/snmpprofiles/list"); + + if (response.status !== 200) return null; + + const json = await response.json(); + if (json.error) throw(json.error); + + return json; + } + catch (ex) { + return null; + } + } + Copy() { //overrides new DeviceView({copy: this.args.file}); } diff --git a/Protest/Front/fetch.js b/Protest/Front/fetch.js index 78dea10c..3f41a43e 100644 --- a/Protest/Front/fetch.js +++ b/Protest/Front/fetch.js @@ -1101,7 +1101,7 @@ class Fetch extends Tabs { const guidOption = document.createElement("option"); guidOption.text = "Same GUID"; - guidOption.value = "guid"; + guidOption.value = "object guid"; conflictConditionInput.appendChild(guidOption); conflictConditionInput.value = "ip"; @@ -1113,7 +1113,7 @@ class Fetch extends Tabs { conflictConditionInput.appendChild(usernameOption); const guidOption = document.createElement("option"); guidOption.text = "Same GUID"; - guidOption.value = "guid"; + guidOption.value = "object guid"; conflictConditionInput.appendChild(guidOption); conflictConditionInput.value = "username"; diff --git a/Protest/Front/userview.js b/Protest/Front/userview.js index 27f47b69..669798a1 100644 --- a/Protest/Front/userview.js +++ b/Protest/Front/userview.js @@ -12,7 +12,7 @@ class UserView extends View { "e-mail", "secondary e-mail", "telephone number", "office number", "mobile number", "internal extension", "mobile extension", "fax", ["mono/directory.svg", "Domain information"], - "guid", "distinguished name", + "object guid", "distinguished name", ["mono/sim.svg", "sim information"], "sim", "puk", "voicemail" diff --git a/Protest/Protocols/Kerberos.cs b/Protest/Protocols/Kerberos.cs index 8228d5f9..4f1302a9 100644 --- a/Protest/Protocols/Kerberos.cs +++ b/Protest/Protocols/Kerberos.cs @@ -308,7 +308,7 @@ public static Dictionary AdFetch(SearchResult result) { ContentBuilderAddValue(result, "facsimiletelephonenumber", "fax", data, null); - data.Add("guid", new Guid((byte[])result.Properties["objectGuid"][0]).ToString()); + data.Add("object guid", new Guid((byte[])result.Properties["objectGuid"][0]).ToString()); return data; } diff --git a/Protest/Tasks/Fetch.cs b/Protest/Tasks/Fetch.cs index 950a73ff..8a818605 100644 --- a/Protest/Tasks/Fetch.cs +++ b/Protest/Tasks/Fetch.cs @@ -19,9 +19,9 @@ namespace Protest.Tasks; internal static class Fetch { enum Type : byte { - none = 0, + none = 0, devices = 1, - users = 2, + users = 2, } struct Result { @@ -48,15 +48,36 @@ public static byte[] SingleDeviceSerialize(Dictionary parameters parameters.TryGetValue("target", out string target); parameters.TryGetValue("wmi", out string wmi); parameters.TryGetValue("kerberos", out string kerberos); - parameters.TryGetValue("snmp2", out string snmp2); - parameters.TryGetValue("snmp3", out string snmp3); + parameters.TryGetValue("snmp", out string snmp); parameters.TryGetValue("portscan", out string portScan); if (target is null) { return Data.CODE_INVALID_ARGUMENT.Array; } - ConcurrentDictionary data = SingleDevice(target, true, wmi == "true", kerberos == "true", snmp2=="true", null, snmp3=="true", null, portScan, asynchronous, CancellationToken.None); + SnmpProfiles.Profile snmpProfile = null; + if (snmp is not null && Guid.TryParse(snmp, out Guid guid)) { + SnmpProfiles.Profile[] profiles = SnmpProfiles.Load(); + for (int i = 0; i< profiles.Length; i++) { + if (profiles[i].guid == guid) { + snmpProfile = profiles[i]; + break; + } + } + } + + SnmpProfiles.Profile[] snmpProfiles = snmpProfile is null ? null : new SnmpProfiles.Profile[] { snmpProfile }; + + ConcurrentDictionary data = SingleDevice( + target, + true, + wmi=="true", + kerberos=="true", + snmpProfiles, + portScan, + asynchronous, + CancellationToken.None + ); if (data is null || data.IsEmpty) { return "{\"error\":\"Failed to fetch data.\"}"u8.ToArray(); @@ -64,7 +85,7 @@ public static byte[] SingleDeviceSerialize(Dictionary parameters return JsonSerializer.SerializeToUtf8Bytes(data, fetchSerializerOptions); } - public static async Task> SingleDeviceAsync(string target, bool useDns, bool useWmi, bool useKerberos, bool snmp2, string[] snmp2Profiles, bool snmp3, string[] snmp3Profiles, string argPortScan, bool asynchronous, CancellationToken cancellationToken) { + public static async Task> SingleDeviceAsync(string target, bool useDns, bool useWmi, bool useKerberos, SnmpProfiles.Profile[] snmpProfiles, string argPortScan, bool asynchronous, CancellationToken cancellationToken) { PingReply reply = null; try { using Ping ping = new Ping(); @@ -76,13 +97,13 @@ public static async Task> SingleDeviceAsy catch { } if (reply?.Status == IPStatus.Success) { - ConcurrentDictionary data = SingleDevice(target, useDns, useWmi, useKerberos, snmp2, snmp2Profiles, snmp3, snmp3Profiles, argPortScan, asynchronous, cancellationToken); + ConcurrentDictionary data = SingleDevice(target, useDns, useWmi, useKerberos, snmpProfiles , argPortScan, asynchronous, cancellationToken); return data; } return null; } - public static ConcurrentDictionary SingleDevice(string target, bool useDns, bool useWmi, bool useKerberos, bool snmp2, string[] snmp2Profiles, bool snmp3, string[] snmp3Profiles, string argPortScan, bool asynchronous, CancellationToken cancellationToken) { + public static ConcurrentDictionary SingleDevice(string target, bool useDns, bool useWmi, bool useKerberos, SnmpProfiles.Profile[] snmpProfiles, string argPortScan, bool asynchronous, CancellationToken cancellationToken) { if (target.Contains(';')) { target = target.Split(';')[0].Trim(); } @@ -186,7 +207,7 @@ public static ConcurrentDictionary SingleDevice(string target, if (value.Length > 0) ad.Add("CHANGED ON DC", value); }*/ - ad.Add("guid", new Guid((byte[])result.Properties["objectGuid"][0]).ToString()); + ad.Add("object guid", new Guid((byte[])result.Properties["objectGuid"][0]).ToString()); }); } @@ -247,7 +268,6 @@ public static ConcurrentDictionary SingleDevice(string target, foreach (KeyValuePair o in ad) { string key = o.Key; - if (key == "operating system") { //os not found in ad, use wmi if (!wmi.ContainsKey("operating system")) { data.TryAdd(key, new string[] { o.Value, "Kerberos", string.Empty }); @@ -362,7 +382,7 @@ public static ConcurrentDictionary SingleDevice(string target, return null; } - if (snmp2) { + if (snmpProfiles is not null) { if (data.TryGetValue("type", out string[] type)) { switch (type[0]) { case "fax": @@ -392,10 +412,6 @@ public static ConcurrentDictionary SingleDevice(string target, //TODO: generic OID } - if (snmp3) { - //TODO: - } - if (cancellationToken.IsCancellationRequested) { return null; } @@ -454,9 +470,11 @@ public static byte[] DevicesTask(HttpListenerContext ctx, Dictionary>> tasks = new List>>(); for (int i = 0; i < size; i++) { - tasks.Add(SingleDeviceAsync(queue[i], dns, wmi, kerberos, snmp2, snmp2Profiles, snmp3, snmp3Profiles, portscan, false, task.cancellationToken)); + tasks.Add(SingleDeviceAsync(queue[i], dns, wmi, kerberos, snmpProfiles, portscan, false, task.cancellationToken)); } ConcurrentDictionary[] result = await Task.WhenAll(tasks);