Compare commits

...
Sign in to create a new pull request.

7 commits
master ... beta

Author SHA1 Message Date
kkb
1591618c2c optimization update, web scheduler test-integration 2023-12-14 11:09:03 +01:00
kkb
3c9ccaafeb testing remote stuff 2023-11-17 17:12:41 +01:00
Kevin Kai Berthold
1e05d4576d syntax updates 2023-09-22 22:16:56 +02:00
Kevin Kai Berthold
283fa1abc2 web-proxy rewrite 2023-09-21 23:44:05 +02:00
Kevin Kai Berthold
26c741ad03 update packages 2023-09-21 22:32:40 +02:00
Kevin Kai Berthold
450a6f2796 refactor (networking) 2023-09-21 22:10:55 +02:00
Kevin Kai Berthold
febc4d9488 fixed chatservice 2023-09-21 20:45:37 +02:00
593 changed files with 27102 additions and 15610 deletions

View file

@ -1,8 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
</Project>

View file

@ -31,11 +31,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Server", "src\Serve
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Updater", "src\Updater\Insight.Updater\Insight.Updater.csproj", "{4875D70F-A96B-4EBA-99BE-218886D29BEB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Web.Assets", "src\Web\Insight.Web.Assets\Insight.Web.Assets.csproj", "{EBB8A2A8-453B-4867-A8E2-072530391DD0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Agent", "src\Agent\Insight.Agent\Insight.Agent.csproj", "{2A391CA2-F96B-4DB7-80AA-0668A5141640}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Agent.Assets", "src\Agent\Insight.Agent.Assets\Insight.Agent.Assets.csproj", "{4C2B66EA-4EE1-47BF-BAEE-DDBAF6FCB324}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Remote", "Remote", "{D4D7BF4A-B2E3-470A-A14C-FC658FF7461D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Remote.Shared", "src\Remote\Insight.Remote.Shared\Insight.Remote.Shared.csproj", "{5C4697BD-BC97-484F-9DB1-CA87E2BEAA4B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Remote.Windows", "src\Remote\Insight.Remote.Windows\Insight.Remote.Windows.csproj", "{AF313B47-3079-407F-91D1-9989C1E1AF2A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -71,18 +73,18 @@ Global
{4875D70F-A96B-4EBA-99BE-218886D29BEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4875D70F-A96B-4EBA-99BE-218886D29BEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4875D70F-A96B-4EBA-99BE-218886D29BEB}.Release|Any CPU.Build.0 = Release|Any CPU
{EBB8A2A8-453B-4867-A8E2-072530391DD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EBB8A2A8-453B-4867-A8E2-072530391DD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EBB8A2A8-453B-4867-A8E2-072530391DD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EBB8A2A8-453B-4867-A8E2-072530391DD0}.Release|Any CPU.Build.0 = Release|Any CPU
{2A391CA2-F96B-4DB7-80AA-0668A5141640}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A391CA2-F96B-4DB7-80AA-0668A5141640}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A391CA2-F96B-4DB7-80AA-0668A5141640}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A391CA2-F96B-4DB7-80AA-0668A5141640}.Release|Any CPU.Build.0 = Release|Any CPU
{4C2B66EA-4EE1-47BF-BAEE-DDBAF6FCB324}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4C2B66EA-4EE1-47BF-BAEE-DDBAF6FCB324}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C2B66EA-4EE1-47BF-BAEE-DDBAF6FCB324}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C2B66EA-4EE1-47BF-BAEE-DDBAF6FCB324}.Release|Any CPU.Build.0 = Release|Any CPU
{5C4697BD-BC97-484F-9DB1-CA87E2BEAA4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5C4697BD-BC97-484F-9DB1-CA87E2BEAA4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C4697BD-BC97-484F-9DB1-CA87E2BEAA4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C4697BD-BC97-484F-9DB1-CA87E2BEAA4B}.Release|Any CPU.Build.0 = Release|Any CPU
{AF313B47-3079-407F-91D1-9989C1E1AF2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF313B47-3079-407F-91D1-9989C1E1AF2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF313B47-3079-407F-91D1-9989C1E1AF2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF313B47-3079-407F-91D1-9989C1E1AF2A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -95,9 +97,9 @@ Global
{EF3188D7-338D-43DA-BF6B-D26E5BDAC3A6} = {35BA5DCB-BECC-4F51-8DD0-694C555D205A}
{1E75F7E9-E6AA-44E7-A2F3-DB4CA85E0118} = {038C3821-E554-496D-B585-A3BC193B7913}
{4875D70F-A96B-4EBA-99BE-218886D29BEB} = {F2D241DB-7692-46DB-8A6A-958B365DAAF8}
{EBB8A2A8-453B-4867-A8E2-072530391DD0} = {3F000016-069D-477E-ACA3-F643880B57E8}
{2A391CA2-F96B-4DB7-80AA-0668A5141640} = {140F73DD-29D3-4C44-809B-5B470880AA0D}
{4C2B66EA-4EE1-47BF-BAEE-DDBAF6FCB324} = {140F73DD-29D3-4C44-809B-5B470880AA0D}
{5C4697BD-BC97-484F-9DB1-CA87E2BEAA4B} = {D4D7BF4A-B2E3-470A-A14C-FC658FF7461D}
{AF313B47-3079-407F-91D1-9989C1E1AF2A} = {D4D7BF4A-B2E3-470A-A14C-FC658FF7461D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F376A326-7590-4E7E-AB9B-76CED8527AB0}

View file

@ -1,14 +0,0 @@
namespace Insight.Agent.Enums
{
public enum CategoryEnum
{
Network = 1,
System = 2,
Application = 3,
Security = 4,
Monitoring = 5,
Task = 6,
Printer = 7,
RDP = 8
}
}

View file

@ -1,9 +0,0 @@
namespace Insight.Agent.Enums
{
public enum DispatchEnum
{
Pending = 1,
Failure = 2,
Success = 3,
}
}

View file

@ -1,9 +0,0 @@
namespace Insight.Agent.Enums
{
public enum StatusEnum
{
Information = 1,
Warning = 2,
Error = 3
}
}

View file

@ -1,30 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>true</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>Insight.Agent.Assets</AssemblyName>
<RootNamespace>Insight.Agent</RootNamespace>
<Product>Insight</Product>
<AssemblyVersion>2023.9.14.0</AssemblyVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>none</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>none</DebugType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Vaitr.Network" Version="2023.9.13" />
<PackageReference Include="Vaitr.Snmp" Version="2023.3.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Core\Insight.Domain\Insight.Domain.csproj" />
</ItemGroup>
</Project>

View file

@ -1,9 +0,0 @@
using Insight.Agent.Messages;
namespace Insight.Agent.Interfaces
{
public partial interface IAgentMessageHandler<TSender>
{
ValueTask HandleAsync<TMessage>(TSender sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage;
}
}

View file

@ -1,41 +0,0 @@
using MemoryPack;
using System.Runtime.InteropServices;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(120, typeof(Application))]
[MemoryPackUnion(121, typeof(ApplicationList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Application : IAgentMessage
{
[MemoryPackOrder(0)]
public string? Name { get; set; }
[MemoryPackOrder(1)]
public string? Publisher { get; set; }
[MemoryPackOrder(2)]
public string? Version { get; set; }
[MemoryPackOrder(3)]
public string? Location { get; set; }
[MemoryPackOrder(4)]
public string? Source { get; set; }
[MemoryPackOrder(5)]
public string? Uninstall { get; set; }
[MemoryPackOrder(6)]
public DateTime? InstallDate { get; set; }
[MemoryPackOrder(7)]
public Architecture? Architecture { get; set; }
}
[MemoryPackable(GenerateType.Collection)]
public partial class ApplicationList : List<Application>, IAgentMessage { }
}

View file

@ -1,34 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(1, typeof(Authentication))]
[MemoryPackUnion(2, typeof(AuthenticationRequest))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Authentication : IAgentMessage
{
[MemoryPackOrder(0)]
public PlatformType? Platform { get; set; }
[MemoryPackOrder(1)]
public Guid Serial { get; set; }
[MemoryPackOrder(2)]
public Version? Version { get; set; }
[MemoryPackOrder(3)]
public string? Hostname { get; set; }
public enum PlatformType
{
Unknown = 0,
Windows = 1,
Unix = 2
}
}
[MemoryPackable]
public partial class AuthenticationRequest : IAgentMessage { }
}

View file

@ -1,10 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(2000, typeof(GetInventory))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class GetInventory : IAgentMessage { }
}

View file

@ -1,49 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(1000, typeof(ConsoleQuery))]
[MemoryPackUnion(1001, typeof(ConsoleQueryRequest))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class ConsoleQuery : IAgentMessage
{
[MemoryPackOrder(0)]
public string? Id { get; set; }
[MemoryPackOrder(1)]
public string? HostId { get; set; }
[MemoryPackOrder(2)]
public string? Query { get; set; }
[MemoryPackOrder(3)]
public string? Data { get; set; }
[MemoryPackOrder(4)]
public string? Errors { get; set; }
[MemoryPackOrder(5)]
public bool IsString { get; set; }
[MemoryPackOrder(6)]
public bool IsArray { get; set; }
[MemoryPackOrder(7)]
public bool HadErrors { get; set; }
}
[MemoryPackable]
public partial class ConsoleQueryRequest : IAgentMessage
{
[MemoryPackOrder(0)]
public string? Id { get; set; }
[MemoryPackOrder(1)]
public string? HostId { get; set; }
[MemoryPackOrder(2)]
public string? Query { get; set; }
}
}

View file

@ -1,103 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(50, typeof(Drive))]
[MemoryPackUnion(51, typeof(DriveList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Drive : IAgentMessage
{
[MemoryPackOrder(0)]
public uint? Index { get; set; }
[MemoryPackOrder(1)]
public string? Id { get; set; }
[MemoryPackOrder(2)]
public string? Name { get; set; }
[MemoryPackOrder(3)]
public string? Manufacturer { get; set; }
[MemoryPackOrder(4)]
public string? SerialNumber { get; set; }
[MemoryPackOrder(5)]
public ulong? Size { get; set; }
[MemoryPackOrder(6)]
public string? Status { get; set; }
[MemoryPackOrder(7)]
public string? InterfaceType { get; set; }
[MemoryPackOrder(8)]
public string? FirmwareRevision { get; set; }
[MemoryPackOrder(9)]
public string? PNPDeviceID { get; set; }
[MemoryPackOrder(10)]
public List<Volume>? Volumes { get; set; }
}
[MemoryPackable(GenerateType.Collection)]
public partial class DriveList : List<Drive>, IAgentMessage { }
[MemoryPackable]
public partial class Volume : IAgentMessage
{
[MemoryPackOrder(0)]
public uint? Index { get; set; }
[MemoryPackOrder(1)]
public string? Id { get; set; }
[MemoryPackOrder(2)]
public string? Name { get; set; }
[MemoryPackOrder(3)]
public string? SerialNumber { get; set; }
[MemoryPackOrder(4)]
public ulong? Size { get; set; }
[MemoryPackOrder(5)]
public ulong? FreeSpace { get; set; }
[MemoryPackOrder(6)]
public string? Type { get; set; }
[MemoryPackOrder(7)]
public string? FileSystem { get; set; }
[MemoryPackOrder(8)]
public bool? Compressed { get; set; }
[MemoryPackOrder(9)]
public bool? Bootable { get; set; }
[MemoryPackOrder(10)]
public bool? PrimaryPartition { get; set; }
[MemoryPackOrder(11)]
public bool? BootPartition { get; set; }
[MemoryPackOrder(12)]
public ulong? BlockSize { get; set; }
[MemoryPackOrder(13)]
public ulong? NumberOfBlocks { get; set; }
[MemoryPackOrder(14)]
public ulong? StartingOffset { get; set; }
[MemoryPackOrder(15)]
public DriveType? DriveType { get; set; }
[MemoryPackOrder(16)]
public string? ProviderName { get; set; }
}
}

View file

@ -1,41 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(10, typeof(Event))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Event : IAgentMessage
{
[MemoryPackOrder(0)]
public DateTime? Timestamp { get; set; }
[MemoryPackOrder(1)]
public StatusType? Status { get; set; }
[MemoryPackOrder(2)]
public string? Source { get; set; }
[MemoryPackOrder(3)]
public string? Category { get; set; }
[MemoryPackOrder(4)]
public int? EventId { get; set; }
[MemoryPackOrder(5)]
public string? Task { get; set; }
[MemoryPackOrder(6)]
public string? Message { get; set; }
public enum StatusType
{
Unknown = 0,
Information = 1,
Warning = 2,
Error = 3,
Critical = 4
}
}
}

View file

@ -1,7 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackable]
public partial interface IAgentMessage { }
}

View file

@ -1,195 +0,0 @@
using MemoryPack;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(70, typeof(Interface))]
[MemoryPackUnion(71, typeof(InterfaceList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Interface : IAgentMessage
{
[MemoryPackOrder(0)]
public uint? Index { get; set; }
[MemoryPackOrder(1)]
public Guid? Guid { get; set; }
[MemoryPackOrder(2)]
public string? Mac { get; set; }
[MemoryPackOrder(3)]
public string? Name { get; set; }
[MemoryPackOrder(4)]
public string? Description { get; set; }
[MemoryPackOrder(5)]
public string? Manufacturer { get; set; }
[MemoryPackOrder(6)]
public string? Suffix { get; set; }
[MemoryPackOrder(7)]
public bool? Physical { get; set; }
[MemoryPackOrder(8)]
public NetworkInterfaceType? Type { get; set; }
[MemoryPackOrder(9)]
public OperationalStatus? Status { get; set; }
[MemoryPackOrder(10)]
public long? Speed { get; set; }
[MemoryPackOrder(11)]
public long? Ipv4Mtu { get; set; }
[MemoryPackOrder(12)]
public bool? Ipv4Dhcp { get; set; }
[MemoryPackOrder(13)]
public bool? Ipv4Forwarding { get; set; }
[MemoryPackOrder(14)]
public long? Ipv6Mtu { get; set; }
[MemoryPackOrder(15)]
public long? Sent { get; set; }
[MemoryPackOrder(16)]
public long? Received { get; set; }
[MemoryPackOrder(17)]
public long? IncomingPacketsDiscarded { get; set; }
[MemoryPackOrder(18)]
public long? IncomingPacketsWithErrors { get; set; }
[MemoryPackOrder(19)]
public long? IncomingUnknownProtocolPackets { get; set; }
[MemoryPackOrder(20)]
public long? OutgoingPacketsDiscarded { get; set; }
[MemoryPackOrder(21)]
public long? OutgoingPacketsWithErrors { get; set; }
[MemoryPackOrder(22)]
public List<Unicast>? Addresses { get; set; }
[MemoryPackOrder(23)]
public List<IPAddress2>? Gateways { get; set; }
[MemoryPackOrder(24)]
public List<IPAddress2>? Dns { get; set; }
[MemoryPackOrder(25)]
public List<IPAddress2>? Dhcp { get; set; }
[MemoryPackOrder(26)]
public List<Route>? Routes { get; set; }
}
[MemoryPackable(GenerateType.Collection)]
public partial class InterfaceList : List<Interface>, IAgentMessage { }
[MemoryPackable]
public partial class Unicast : IAgentMessage
{
[MemoryPackOrder(0)]
public IPAddress2? IpAddress { get; set; }
[MemoryPackOrder(1)]
public IPAddress2? Ipv4Mask { get; set; }
[MemoryPackOrder(2)]
public long? AddressPreferredLifetime { get; set; }
[MemoryPackOrder(3)]
public long? AddressValidLifetime { get; set; }
[MemoryPackOrder(4)]
public long? DhcpLeaseLifetime { get; set; }
[MemoryPackOrder(5)]
public DuplicateAddressDetectionState? DuplicateAddressDetectionState { get; set; }
[MemoryPackOrder(6)]
public int? PrefixLength { get; set; }
[MemoryPackOrder(7)]
public PrefixOrigin? PrefixOrigin { get; set; }
[MemoryPackOrder(8)]
public SuffixOrigin? SuffixOrigin { get; set; }
}
[MemoryPackable]
public partial class Route : IAgentMessage
{
[MemoryPackOrder(0)]
public uint? InterfaceIndex { get; set; }
[MemoryPackOrder(1)]
public IPAddress2? Destination { get; set; }
[MemoryPackOrder(2)]
public IPAddress2? Gateway { get; set; }
[MemoryPackOrder(3)]
public string? Mask { get; set; }
[MemoryPackOrder(4)]
public int? Metric { get; set; }
}
[MemoryPackable]
public partial class IPAddress2 : IAgentMessage
{
[MemoryPackOrder(0)]
public AddressFamily? AddressFamily { get; set; }
[MemoryPackOrder(1)]
public string? Address { get; set; }
[MemoryPackOrder(2)]
public bool? IsIPv6Teredo { get; set; }
[MemoryPackOrder(3)]
public bool? IsIPv6SiteLocal { get; set; }
[MemoryPackOrder(4)]
public bool? IsIPv6Multicast { get; set; }
[MemoryPackOrder(5)]
public bool? IsIPv6LinkLocal { get; set; }
[MemoryPackOrder(6)]
public bool? IsIPv4MappedToIPv6 { get; set; }
[MemoryPackOrder(7)]
public bool? IsIPv6UniqueLocal { get; set; }
[MemoryPackConstructor]
public IPAddress2()
{
}
public IPAddress2(IPAddress address)
{
AddressFamily = address.AddressFamily;
Address = address.ToString();
IsIPv4MappedToIPv6 = address.IsIPv4MappedToIPv6;
IsIPv6LinkLocal = address.IsIPv6LinkLocal;
IsIPv6Multicast = address.IsIPv6Multicast;
IsIPv6SiteLocal = address.IsIPv6SiteLocal;
IsIPv6Teredo = address.IsIPv6Teredo;
IsIPv6UniqueLocal = address.IsIPv6UniqueLocal;
}
}
}

View file

@ -1,10 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(0, typeof(Keepalive))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Keepalive : IAgentMessage { }
}

View file

@ -1,29 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(20, typeof(Mainboard))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Mainboard : IAgentMessage
{
[MemoryPackOrder(0)]
public string? Manufacturer { get; set; }
[MemoryPackOrder(1)]
public string? Model { get; set; }
[MemoryPackOrder(2)]
public string? Serial { get; set; }
[MemoryPackOrder(3)]
public string? BiosManufacturer { get; set; }
[MemoryPackOrder(4)]
public string? BiosVersion { get; set; }
[MemoryPackOrder(5)]
public DateTime? BiosDate { get; set; }
}
}

View file

@ -1,67 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(40, typeof(Memory))]
[MemoryPackUnion(41, typeof(MemoryList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Memory : IAgentMessage
{
[MemoryPackOrder(0)]
public uint? Index { get; set; }
[MemoryPackOrder(1)]
public string? Tag { get; set; }
[MemoryPackOrder(2)]
public string? Location { get; set; }
[MemoryPackOrder(3)]
public string? Manufacturer { get; set; }
[MemoryPackOrder(4)]
public string? Model { get; set; }
[MemoryPackOrder(5)]
public string? Serial { get; set; }
[MemoryPackOrder(6)]
public ulong? Capacity { get; set; }
[MemoryPackOrder(7)]
public uint? Speed { get; set; }
[MemoryPackOrder(8)]
public uint? Voltage { get; set; }
[MemoryPackOrder(9)]
public uint? ConfiguredSpeed { get; set; }
[MemoryPackOrder(10)]
public uint? ConfiguredVoltage { get; set; }
}
[MemoryPackable(GenerateType.Collection)]
public partial class MemoryList : List<Memory>, IAgentMessage { }
[MemoryPackable]
public partial class MemoryMetric : IAgentMessage
{
[MemoryPackOrder(0)]
public DateTime? Timestamp { get; set; }
[MemoryPackOrder(1)]
public float? MemoryAvailable { get; set; }
[MemoryPackOrder(2)]
public float? MemoryAvailablePercentage { get; set; }
[MemoryPackOrder(3)]
public float? MemoryUsed { get; set; }
[MemoryPackOrder(4)]
public float? MemoryUsagePercentage { get; set; }
}
}

View file

@ -1,30 +0,0 @@
using MemoryPack;
using System.Runtime.InteropServices;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(90, typeof(OperationSystem))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class OperationSystem : IAgentMessage
{
[MemoryPackOrder(0)]
public string? Name { get; set; }
[MemoryPackOrder(1)]
public string? Version { get; set; }
[MemoryPackOrder(2)]
public string? SerialNumber { get; set; }
[MemoryPackOrder(3)]
public Architecture? Architecture { get; set; }
[MemoryPackOrder(4)]
public bool? Virtual { get; set; }
[MemoryPackOrder(5)]
public DateTime? InstallDate { get; set; }
}
}

View file

@ -1,30 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(140, typeof(Printer))]
[MemoryPackUnion(141, typeof(PrinterList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Printer : IAgentMessage
{
[MemoryPackOrder(0)]
public string? Name { get; set; }
[MemoryPackOrder(1)]
public string? Driver { get; set; }
[MemoryPackOrder(2)]
public string? Port { get; set; }
[MemoryPackOrder(3)]
public string? Location { get; set; }
[MemoryPackOrder(4)]
public string? Comment { get; set; }
}
[MemoryPackable(GenerateType.Collection)]
public partial class PrinterList : List<Printer>, IAgentMessage { }
}

View file

@ -1,70 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(30, typeof(Processor))]
[MemoryPackUnion(31, typeof(ProcessorList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Processor : IAgentMessage
{
[MemoryPackOrder(0)]
public uint? Index { get; set; }
[MemoryPackOrder(1)]
public string? Name { get; set; }
[MemoryPackOrder(2)]
public string? Manufacturer { get; set; }
[MemoryPackOrder(3)]
public string? SerialNumber { get; set; }
[MemoryPackOrder(4)]
public string? Socket { get; set; }
[MemoryPackOrder(5)]
public string? Version { get; set; }
[MemoryPackOrder(6)]
public string? DeviceId { get; set; }
[MemoryPackOrder(7)]
public uint? Cores { get; set; }
[MemoryPackOrder(8)]
public uint? LogicalCores { get; set; }
[MemoryPackOrder(9)]
public uint? CurrentSpeed { get; set; }
[MemoryPackOrder(10)]
public uint? MaxSpeed { get; set; }
[MemoryPackOrder(11)]
public uint? L1Size { get; set; }
[MemoryPackOrder(12)]
public uint? L2Size { get; set; }
[MemoryPackOrder(13)]
public uint? L3Size { get; set; }
[MemoryPackOrder(14)]
public bool? Virtualization { get; set; }
}
[MemoryPackable(GenerateType.Collection)]
public partial class ProcessorList : List<Processor>, IAgentMessage { }
[MemoryPackable]
public partial class ProcessorMetric : IAgentMessage
{
[MemoryPackOrder(0)]
public DateTime? Timestamp { get; set; }
[MemoryPackOrder(1)]
public float? ProcessorUsagePercentage { get; set; }
}
}

View file

@ -1,64 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(130, typeof(Service))]
[MemoryPackUnion(131, typeof(ServiceList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Service : IAgentMessage
{
[MemoryPackOrder(0)]
public uint? ProcessId { get; set; }
[MemoryPackOrder(1)]
public string? Name { get; set; }
[MemoryPackOrder(2)]
public string? Display { get; set; }
[MemoryPackOrder(3)]
public string? Description { get; set; }
[MemoryPackOrder(4)]
public string? PathName { get; set; }
[MemoryPackOrder(5)]
public string? Account { get; set; }
[MemoryPackOrder(6)]
public bool? Delay { get; set; }
[MemoryPackOrder(7)]
public ServiceStatus? Status { get; set; }
[MemoryPackOrder(8)]
public ServiceMode? StartMode { get; set; }
public enum ServiceStatus
{
Unknown = -1,
Stopped = 1,
StartPending = 2,
StopPending = 3,
Running = 4,
ContinuePending = 5,
PausePending = 6,
Paused = 7
}
public enum ServiceMode
{
Unknown = -1,
Boot = 0,
System = 1,
Automatic = 2,
Manual = 3,
Disabled = 4
}
}
[MemoryPackable(GenerateType.Collection)]
public partial class ServiceList : List<Service>, IAgentMessage { }
}

View file

@ -1,30 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(110, typeof(Session))]
[MemoryPackUnion(111, typeof(SessionList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Session : IAgentMessage
{
[MemoryPackOrder(0)]
public string? Sid { get; set; }
[MemoryPackOrder(1)]
public string? User { get; set; }
[MemoryPackOrder(2)]
public string? Type { get; set; }
[MemoryPackOrder(3)]
public string? Status { get; set; }
[MemoryPackOrder(4)]
public string? Remote { get; set; }
}
[MemoryPackable(GenerateType.Collection)]
public partial class SessionList : List<Session>, IAgentMessage { }
}

View file

@ -1,17 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(3, typeof(Status))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Status : IAgentMessage
{
[MemoryPackOrder(0)]
public DateTime Timestamp { get; } = DateTime.Now;
[MemoryPackOrder(1)]
public TimeSpan Uptime { get; set; }
}
}

View file

@ -1,302 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(160, typeof(StoragePool))]
[MemoryPackUnion(161, typeof(StoragePoolList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class StoragePool : IAgentMessage
{
[MemoryPackOrder(0)]
public string? UniqueId { get; set; }
[MemoryPackOrder(1)]
public string? Name { get; set; }
[MemoryPackOrder(2)]
public string? FriendlyName { get; set; }
[MemoryPackOrder(3)]
public List<OperationalState>? States { get; set; }
[MemoryPackOrder(4)]
public HealthState? Health { get; set; }
[MemoryPackOrder(5)]
public RetireMissingPhysicalDisksEnum? RetireMissingPhysicalDisks { get; set; }
[MemoryPackOrder(6)]
public string? Resiliency { get; set; }
[MemoryPackOrder(7)]
public bool? IsPrimordial { get; set; }
[MemoryPackOrder(8)]
public bool? IsReadOnly { get; set; }
[MemoryPackOrder(9)]
public bool? IsClustered { get; set; }
[MemoryPackOrder(10)]
public ulong? Size { get; set; }
[MemoryPackOrder(11)]
public ulong? AllocatedSize { get; set; }
[MemoryPackOrder(12)]
public ulong? SectorSize { get; set; }
[MemoryPackOrder(13)]
public List<PhysicalDisk>? PhysicalDisks { get; set; }
[MemoryPackOrder(14)]
public List<VirtualDisk>? VirtualDisks { get; set; }
public enum OperationalState
{
Unknown = 0,
Other = 1,
OK = 2,
Degraded = 3,
Stressed = 4,
Predictive_Failure = 5,
Error = 6,
Non_Recoverable_Error = 7,
Starting = 8,
Stopping = 9,
Stopped = 10,
In_Service = 11,
No_Contact = 12,
Lost_Communication = 13,
Aborted = 14,
Dormant = 15,
Supporting_Entity_In_Error = 16,
Completed = 17,
Power_Mode = 18,
Relocating = 19
}
public enum HealthState
{
Healthy = 0,
Warning = 1,
Unhealthy = 2,
Unknown = 3
}
public enum RetireMissingPhysicalDisksEnum
{
Auto = 1,
Always = 2,
Never = 3
}
}
[MemoryPackable(GenerateType.Collection)]
public partial class StoragePoolList : List<StoragePool>, IAgentMessage { }
[MemoryPackable]
public partial class PhysicalDisk : IAgentMessage
{
[MemoryPackOrder(0)]
public string? UniqueId { get; set; }
[MemoryPackOrder(1)]
public string? DeviceId { get; set; }
[MemoryPackOrder(2)]
public string? FriendlyName { get; set; }
[MemoryPackOrder(3)]
public string? Manufacturer { get; set; }
[MemoryPackOrder(4)]
public string? Model { get; set; }
[MemoryPackOrder(5)]
public ushort? MediaType { get; set; }
[MemoryPackOrder(6)]
public ushort? BusType { get; set; }
[MemoryPackOrder(7)]
public List<OperationalState>? States { get; set; }
[MemoryPackOrder(8)]
public HealthState? Health { get; set; }
[MemoryPackOrder(9)]
public List<SupportedUsagesEnum>? SupportedUsages { get; set; }
[MemoryPackOrder(10)]
public ushort? Usage { get; set; }
[MemoryPackOrder(11)]
public string? PhysicalLocation { get; set; }
[MemoryPackOrder(12)]
public string? SerialNumber { get; set; }
[MemoryPackOrder(13)]
public string? FirmwareVersion { get; set; }
[MemoryPackOrder(14)]
public ulong? Size { get; set; }
[MemoryPackOrder(15)]
public ulong? AllocatedSize { get; set; }
[MemoryPackOrder(16)]
public ulong? LogicalSectorSize { get; set; }
[MemoryPackOrder(17)]
public ulong? PhysicalSectorSize { get; set; }
[MemoryPackOrder(18)]
public ulong? VirtualDiskFootprint { get; set; }
public enum OperationalState
{
Unknown = 0,
Other = 1,
OK = 2,
Degraded = 3,
Stressed = 4,
Predictive_Failure = 5,
Error = 6,
Non_Recoverable_Error = 7,
Starting = 8,
Stopping = 9,
Stopped = 10,
In_Service = 11,
No_Contact = 12,
Lost_Communication = 13,
Aborted = 14,
Dormant = 15,
Supporting_Entity_In_Error = 16,
Completed = 17,
Power_Mode = 18,
Relocating = 19
}
public enum HealthState
{
Healthy = 0,
Warning = 1,
Unhealthy = 2,
Unknown = 3
}
public enum SupportedUsagesEnum
{
Unknown = 0,
Auto_Select = 1,
Manual_Select = 2,
Hot_Spare = 3,
Retired = 4,
Journal = 5
}
}
[MemoryPackable]
public partial class VirtualDisk : IAgentMessage
{
[MemoryPackOrder(0)]
public string? UniqueId { get; set; }
[MemoryPackOrder(1)]
public string? Name { get; set; }
[MemoryPackOrder(2)]
public string? FriendlyName { get; set; }
[MemoryPackOrder(3)]
public List<OperationalState>? States { get; set; }
[MemoryPackOrder(4)]
public HealthState? Health { get; set; }
[MemoryPackOrder(5)]
public AccessTypeEnum? AccessType { get; set; }
[MemoryPackOrder(6)]
public ProvisioningTypeEnum? ProvisioningType { get; set; }
[MemoryPackOrder(7)]
public ushort? PhysicalDiskRedundancy { get; set; }
[MemoryPackOrder(8)]
public string? ResiliencySettingName { get; set; }
[MemoryPackOrder(9)]
public bool? Deduplication { get; set; }
[MemoryPackOrder(10)]
public bool? IsSnapshot { get; set; }
[MemoryPackOrder(11)]
public ulong? Size { get; set; }
[MemoryPackOrder(12)]
public ulong? AllocatedSize { get; set; }
[MemoryPackOrder(13)]
public ulong? FootprintOnPool { get; set; }
[MemoryPackOrder(14)]
public ulong? ReadCacheSize { get; set; }
[MemoryPackOrder(15)]
public ulong? WriteCacheSize { get; set; }
public enum OperationalState
{
Unknown = 0,
Other = 1,
OK = 2,
Degraded = 3,
Stressed = 4,
Predictive_Failure = 5,
Error = 6,
Non_Recoverable_Error = 7,
Starting = 8,
Stopping = 9,
Stopped = 10,
In_Service = 11,
No_Contact = 12,
Lost_Communication = 13,
Aborted = 14,
Dormant = 15,
Supporting_Entity_In_Error = 16,
Completed = 17,
Power_Mode = 18,
Relocating = 19
}
public enum HealthState
{
Healthy = 0,
Warning = 1,
Unhealthy = 2,
Unknown = 3
}
public enum AccessTypeEnum
{
Unknown = 0,
Readable = 1,
Writeable = 2,
Read_Write = 3,
Write_Once = 4
}
public enum ProvisioningTypeEnum
{
Unknown = 0,
Thin = 1,
Fixed = 2
}
}
}

View file

@ -1,23 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(80, typeof(SystemInfo))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class SystemInfo : IAgentMessage
{
[MemoryPackOrder(0)]
public DateTime? LastBootUpTime { get; set; }
[MemoryPackOrder(1)]
public DateTime? LocalDateTime { get; set; }
[MemoryPackOrder(2)]
public uint? Processes { get; set; }
[MemoryPackOrder(3)]
public string? License { get; set; }
}
}

View file

@ -1,29 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(11, typeof(Trap))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Trap : IAgentMessage
{
[MemoryPackOrder(0)]
public DateTime? Timestamp { get; set; }
[MemoryPackOrder(1)]
public string? Endpoint { get; set; }
[MemoryPackOrder(2)]
public string? Hostname { get; set; }
[MemoryPackOrder(3)]
public string? Version { get; set; }
[MemoryPackOrder(4)]
public string? Community { get; set; }
[MemoryPackOrder(5)]
public List<KeyValuePair<string, string?>>? Data { get; set; }
}
}

View file

@ -1,83 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(100, typeof(Update))]
[MemoryPackUnion(101, typeof(UpdateList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Update : IAgentMessage
{
[MemoryPackOrder(0)]
public string? Id { get; set; }
[MemoryPackOrder(1)]
public DateTime? Date { get; set; }
[MemoryPackOrder(2)]
public string? Name { get; set; }
[MemoryPackOrder(3)]
public string? Description { get; set; }
[MemoryPackOrder(4)]
public string? SupportUrl { get; set; }
[MemoryPackOrder(5)]
public string? Hotfix { get; set; }
// if installed
[MemoryPackOrder(6)]
public OsUpdateResultCodeEnum? Result { get; set; }
// if pending
[MemoryPackOrder(7)]
public OsUpdateTypeEnum? Type { get; set; }
[MemoryPackOrder(8)]
public decimal? Size { get; set; }
[MemoryPackOrder(9)]
public bool? IsDownloaded { get; set; }
[MemoryPackOrder(10)]
public bool? CanRequestUserInput { get; set; }
[MemoryPackOrder(11)]
public OsUpdateRebootBehaviorEnum? RebootBehavior { get; set; }
public enum OsUpdateRebootBehaviorEnum
{
NeverReboots = 1,
AlwaysRequiresReboot = 2,
CanRequestReboot = 3
}
public enum OsUpdateResultCodeEnum
{
NotStarted = 1,
InProgress = 2,
Succeeded = 3,
SucceededWithErrors = 4,
Failed = 5,
Aborted = 6
}
public enum OsUpdateTypeEnum
{
Software = 1,
Driver = 2
}
}
[MemoryPackable]
public partial class UpdateList : IAgentMessage
{
[MemoryPackOrder(0)]
public List<Update>? Installed { get; set; }
[MemoryPackOrder(1)]
public List<Update>? Pending { get; set; }
}
}

View file

@ -1,73 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(150, typeof(User))]
[MemoryPackUnion(151, typeof(UserList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class User : IAgentMessage
{
[MemoryPackOrder(0)]
public string? Sid { get; set; }
[MemoryPackOrder(1)]
public string? Domain { get; set; }
[MemoryPackOrder(2)]
public string? Name { get; set; }
[MemoryPackOrder(3)]
public string? FullName { get; set; }
[MemoryPackOrder(4)]
public string? Description { get; set; }
[MemoryPackOrder(5)]
public string? Status { get; set; }
[MemoryPackOrder(6)]
public bool? LocalAccount { get; set; }
[MemoryPackOrder(7)]
public bool? Disabled { get; set; }
[MemoryPackOrder(8)]
public bool? Lockout { get; set; }
[MemoryPackOrder(9)]
public bool? PasswordChangeable { get; set; }
[MemoryPackOrder(10)]
public bool? PasswordExpires { get; set; }
[MemoryPackOrder(11)]
public bool? PasswordRequired { get; set; }
[MemoryPackOrder(12)]
public List<Group>? Groups { get; set; }
}
[MemoryPackable(GenerateType.Collection)]
public partial class UserList : List<User>, IAgentMessage { }
[MemoryPackable]
public partial class Group : IAgentMessage
{
[MemoryPackOrder(0)]
public string? Sid { get; set; }
[MemoryPackOrder(1)]
public string? Domain { get; set; }
[MemoryPackOrder(2)]
public string? Name { get; set; }
[MemoryPackOrder(3)]
public string? Description { get; set; }
[MemoryPackOrder(4)]
public bool? LocalAccount { get; set; }
}
}

View file

@ -1,30 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(60, typeof(Videocard))]
[MemoryPackUnion(61, typeof(VideocardList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class Videocard : IAgentMessage
{
[MemoryPackOrder(0)]
public string? DeviceId { get; set; }
[MemoryPackOrder(1)]
public string? Model { get; set; }
[MemoryPackOrder(2)]
public ulong Memory { get; set; }
[MemoryPackOrder(3)]
public DateTime DriverDate { get; set; }
[MemoryPackOrder(4)]
public string? DriverVersion { get; set; }
}
[MemoryPackable(GenerateType.Collection)]
public partial class VideocardList : List<Videocard>, IAgentMessage { }
}

View file

@ -1,265 +0,0 @@
using MemoryPack;
namespace Insight.Agent.Messages
{
[MemoryPackUnion(170, typeof(VirtualMaschine))]
[MemoryPackUnion(171, typeof(VirtualMaschineList))]
public partial interface IAgentMessage { }
[MemoryPackable]
public partial class VirtualMaschine : IAgentMessage
{
[MemoryPackOrder(0)]
public Guid? Id { get; set; }
[MemoryPackOrder(1)]
public uint? ProcessId { get; set; }
[MemoryPackOrder(2)]
public string? Caption { get; set; }
[MemoryPackOrder(3)]
public string? Name { get; set; }
[MemoryPackOrder(4)]
public string? Notes { get; set; }
[MemoryPackOrder(5)]
public EnabledEnum? Enabled { get; set; }
[MemoryPackOrder(6)]
public EnabledDefaultEnum? EnabledDefault { get; set; }
[MemoryPackOrder(7)]
public HealthStatusEnum? HealthState { get; set; }
[MemoryPackOrder(8)]
public string? Status { get; set; }
[MemoryPackOrder(9)]
public ulong? OnTime { get; set; }
[MemoryPackOrder(10)]
public uint? ReplicationMode { get; set; }
[MemoryPackOrder(11)]
public ReplicationStateEnum? ReplicationState { get; set; }
[MemoryPackOrder(12)]
public ReplicationHealthEnum? ReplicationHealth { get; set; }
[MemoryPackOrder(13)]
public string? ConfigurationVersion { get; set; }
[MemoryPackOrder(14)]
public IntegrationServicesVersionStateEnum? IntegrationServicesVersionState { get; set; }
[MemoryPackOrder(15)]
public uint? NumberOfProcessors { get; set; }
[MemoryPackOrder(16)]
public uint? ProcessorLoad { get; set; }
[MemoryPackOrder(17)]
public int? MemoryAvailable { get; set; }
[MemoryPackOrder(18)]
public ulong? MemoryUsage { get; set; }
[MemoryPackOrder(19)]
public DateTime? InstallDate { get; set; }
[MemoryPackOrder(20)]
public DateTime? TimeOfLastConfigurationChange { get; set; }
[MemoryPackOrder(21)]
public DateTime? TimeOfLastStateChange { get; set; }
[MemoryPackOrder(22)]
public DateTime? LastReplicationTime { get; set; }
[MemoryPackOrder(23)]
public string? GuestOperatingSystem { get; set; }
[MemoryPackOrder(24)]
public List<VirtualMaschineConfiguration>? Configurations { get; set; }
public enum EnabledEnum
{
Unbekannt = 0,
Andere = 1,
Aktiviert = 2,
Deaktiviert = 3,
Herunterfahren = 4,
Nicht_Verfügbar = 5,
Aktiviert_Offline = 6,
In_Test = 7,
Latent = 8,
Eingeschränkt = 9,
Wird_gestartet = 10
}
public enum EnabledDefaultEnum
{
Aktiviert = 2,
Deaktiviert = 3,
Aktiviert_Offline = 6
}
public enum HealthStatusEnum
{
OK = 5,
Hauptfehler = 20,
Kritischer_Fehler = 25
}
public enum ReplicationStateEnum
{
Deaktiviert = 0,
Bereit = 1,
Warten_auf_Erstreplikation = 2,
Replikat = 3,
Synchronisierte_Replication_abgeschlossen = 4,
Wiederhergestellt = 5,
Commit = 6,
Angehalten = 7,
Kritisch = 8,
Warten_auf_die_Neusynchronisierung = 9,
Resynchronisierung = 10,
Resynchronisierung_angehalten = 11,
Failover_in_Bearbeitung = 12,
Failback_in_Fortschritt = 13,
Failback_abgeschlossen = 14,
Datenträgerupdate_in_Bearbeitung = 15,
Datenträgeraktualisierung_kritisch = 16,
Unbekannt = 17,
Repurpose_Replikation_in_Bearbeitung = 18,
Vorbereitet_für_die_Synchronisierungsreplikation = 19,
Vorbereitet_für_die_Umgekehrte_Replikation_der_Gruppe = 20,
Failover_in_Fortschritt = 21
}
public enum ReplicationHealthEnum
{
OK = 1,
Warnung = 2,
Kritisch = 3
}
public enum IntegrationServicesVersionStateEnum
{
Unknown = 0,
UpToDate = 1,
Mismatch = 2
}
}
[MemoryPackable(GenerateType.Collection)]
public partial class VirtualMaschineList : List<VirtualMaschine>, IAgentMessage { }
[MemoryPackable]
public partial class VirtualMaschineConfiguration : IAgentMessage
{
[MemoryPackOrder(0)]
public string? Id { get; set; }
[MemoryPackOrder(1)]
public string? ParentId { get; set; }
[MemoryPackOrder(2)]
public string? Type { get; set; }
[MemoryPackOrder(3)]
public string? Name { get; set; }
[MemoryPackOrder(4)]
public DateTime? CreationTime { get; set; }
[MemoryPackOrder(5)]
public string? Generation { get; set; }
[MemoryPackOrder(6)]
public string? Architecture { get; set; }
[MemoryPackOrder(7)]
public AutomaticStartupActionEnum? AutomaticStartupAction { get; set; }
//public DateTime? AutomaticStartupActionDelay { get; set; }
[MemoryPackOrder(8)]
public AutomaticShutdownActionEnum? AutomaticShutdownAction { get; set; }
[MemoryPackOrder(9)]
public AutomaticRecoveryActionEnum? AutomaticRecoveryAction { get; set; }
[MemoryPackOrder(10)]
public bool? AutomaticSnapshotsEnabled { get; set; }
[MemoryPackOrder(11)]
public string? BaseBoardSerialNumber { get; set; }
[MemoryPackOrder(12)]
public string? BIOSGUID { get; set; }
[MemoryPackOrder(13)]
public string? BIOSSerialNumber { get; set; }
[MemoryPackOrder(14)]
public ushort[]? BootOrder { get; set; }
[MemoryPackOrder(15)]
public string? ConfigurationDataRoot { get; set; }
[MemoryPackOrder(16)]
public string? ConfigurationFile { get; set; }
[MemoryPackOrder(17)]
public string? GuestStateDataRoot { get; set; }
[MemoryPackOrder(18)]
public string? GuestStateFile { get; set; }
[MemoryPackOrder(19)]
public string? SnapshotDataRoot { get; set; }
[MemoryPackOrder(20)]
public string? SuspendDataRoot { get; set; }
[MemoryPackOrder(21)]
public string? SwapFileDataRoot { get; set; }
[MemoryPackOrder(22)]
public bool? SecureBootEnabled { get; set; }
[MemoryPackOrder(23)]
public bool? IsAutomaticSnapshot { get; set; }
[MemoryPackOrder(24)]
public string[]? Notes { get; set; }
[MemoryPackOrder(25)]
public List<VirtualMaschineConfiguration>? Childs { get; set; }
//public string[]? HostResource { get; set; }
public enum AutomaticStartupActionEnum
{
Nothing = 2,
RestartIfLastStateActive = 3,
Alway = 4
}
public enum AutomaticShutdownActionEnum
{
Ausschalten = 2,
Speichern = 3,
Herunterfahren = 4
}
public enum AutomaticRecoveryActionEnum
{
Keine = 2,
Neustart = 3,
Rollback = 4
}
}
}

View file

@ -1,7 +0,0 @@
namespace Insight.Agent.Models
{
public class Config
{
public Guid? Serial { get; set; }
}
}

View file

@ -1,10 +1,9 @@
namespace Insight.Agent
namespace Insight.Agent;
public static class Appsettings
{
public static class Appsettings
{
public const string Api = "api";
public const string ServerHost = "server.host";
public const string ServerPort = "server.port";
public const string TrapPort = "trap.port";
}
public const string Api = "api";
public const string ServerHost = "server.host";
public const string ServerPort = "server.port";
public const string TrapPort = "trap.port";
}

View file

@ -1,21 +1,20 @@
namespace Insight.Agent.Constants
namespace Insight.Agent.Constants;
public static class Deploy
{
public static class Deploy
public static class Updater
{
public static class Updater
{
public const string Name = "Updater";
public const string ServiceName = "insight_updater";
public const string Description = "Insight Updater";
}
public static DirectoryInfo GetAppDirectory(string appName)
=> new($"{Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)}/Webmatic/Insight/{appName}");
public static FileInfo GetAppExecutable(string appName)
=> new($"{GetAppDirectory(appName).FullName}/{appName.ToLower()}.exe");
public static Uri GetUpdateHref(Uri api, string appName)
=> new($"{api.AbsoluteUri}/update/{appName.ToLower()}/windows");
public const string Name = "Updater";
public const string ServiceName = "insight_updater";
public const string Description = "Insight Updater";
}
public static DirectoryInfo GetAppDirectory(string appName)
=> new($"{Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)}/Webmatic/Insight/{appName}");
public static FileInfo GetAppExecutable(string appName)
=> new($"{GetAppDirectory(appName).FullName}/{appName.ToLower()}.exe");
public static Uri GetUpdateHref(Uri api, string appName)
=> new($"{api.AbsoluteUri}/update/{appName.ToLower()}/windows");
}

View file

@ -1,14 +1,13 @@
using Microsoft.Extensions.Configuration;
namespace Insight.Agent.Extensions
namespace Insight.Agent.Extensions;
public static class ConfigurationExtensions
{
public static class ConfigurationExtensions
public static IConfigurationBuilder Defaults(this IConfigurationBuilder configuration)
{
public static IConfigurationBuilder Defaults(this IConfigurationBuilder configuration)
{
configuration.Sources.Clear();
configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
return configuration.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true);
}
configuration.Sources.Clear();
configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
return configuration.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true);
}
}

View file

@ -1,32 +1,31 @@
using System.Diagnostics;
using System.Runtime.Versioning;
namespace Insight.Agent.Extensions
namespace Insight.Agent.Extensions;
public static class Linux
{
public static class Linux
[SupportedOSPlatform("linux")]
public static string Bash(this string cmd)
{
[SupportedOSPlatform("linux")]
public static string Bash(this string cmd)
var escaped = cmd.Replace("\"", "\\\"");
using var proc = new Process()
{
var escaped = cmd.Replace("\"", "\\\"");
using var proc = new Process()
StartInfo = new ProcessStartInfo
{
StartInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = $"-c \"{escaped}\"",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
}
};
FileName = "/bin/bash",
Arguments = $"-c \"{escaped}\"",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
}
};
proc.Start();
var result = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
proc.Start();
var result = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
return result;
}
return result;
}
}

View file

@ -6,7 +6,7 @@
<RootNamespace>Insight.Agent</RootNamespace>
<Product>Insight</Product>
<AssemblyName>agent</AssemblyName>
<AssemblyVersion>2023.9.14.0</AssemblyVersion>
<AssemblyVersion>2023.12.14.0</AssemblyVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
@ -23,14 +23,15 @@
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.1" />
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.3.10" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
<PackageReference Include="System.Management" Version="7.0.2" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="7.0.1" />
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.3.7" />
<PackageReference Include="Vaitr.Snmp" Version="2023.3.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Insight.Agent.Assets\Insight.Agent.Assets.csproj" />
<ProjectReference Include="..\..\Core\Insight.Domain\Insight.Domain.csproj" />
</ItemGroup>
<ItemGroup>

View file

@ -1,69 +1,68 @@
using System.Management;
using System.Runtime.Versioning;
namespace Insight.Agent
namespace Insight.Agent;
public static class ManagmentExtensions
{
public static class ManagmentExtensions
[SupportedOSPlatform("windows")]
public static HashSet<string> GetPropertyHashes(this ManagementBaseObject @object)
{
[SupportedOSPlatform("windows")]
public static HashSet<string> GetPropertyHashes(this ManagementBaseObject @object)
var properties = new HashSet<string>();
foreach (var property in @object.Properties)
{
var properties = new HashSet<string>();
foreach (var property in @object.Properties)
{
properties.Add(property.Name);
}
return properties;
properties.Add(property.Name);
}
[SupportedOSPlatform("windows")]
internal static bool TryGet(this ManagementObjectSearcher searcher, out ManagementObjectCollection collection)
return properties;
}
[SupportedOSPlatform("windows")]
internal static bool TryGet(this ManagementObjectSearcher searcher, out ManagementObjectCollection collection)
{
collection = searcher.Get();
try
{
collection = searcher.Get();
try
{
_ = collection.Count;
return true;
}
catch (ManagementException)
{
collection.Dispose();
return false;
}
}
[SupportedOSPlatform("windows")]
internal static T? GetValue<T>(this ManagementObject @object, HashSet<string> properties, string key)
{
if (@object is null || properties is null || key is null) return default;
if (properties.Contains(key, StringComparer.OrdinalIgnoreCase) is false) return default;
if (@object[key] is not T obj)
{
return default;
}
return obj;
}
[SupportedOSPlatform("windows")]
internal static bool TryGetValue<T>(this ManagementBaseObject @object, HashSet<string> properties, string key, out T? value)
{
value = default;
if (@object is null || properties is null || key is null) return default;
if (properties.Contains(key, StringComparer.OrdinalIgnoreCase) is false) return false;
if (@object[key] is not T obj)
{
return false;
}
value = obj;
_ = collection.Count;
return true;
}
catch (ManagementException)
{
collection.Dispose();
return false;
}
}
[SupportedOSPlatform("windows")]
internal static T? GetValue<T>(this ManagementObject @object, HashSet<string> properties, string key)
{
if (@object is null || properties is null || key is null) return default;
if (properties.Contains(key, StringComparer.OrdinalIgnoreCase) is false) return default;
if (@object[key] is not T obj)
{
return default;
}
return obj;
}
[SupportedOSPlatform("windows")]
internal static bool TryGetValue<T>(this ManagementBaseObject @object, HashSet<string> properties, string key, out T? value)
{
value = default;
if (@object is null || properties is null || key is null) return default;
if (properties.Contains(key, StringComparer.OrdinalIgnoreCase) is false) return false;
if (@object[key] is not T obj)
{
return false;
}
value = obj;
return true;
}
}

View file

@ -2,43 +2,42 @@
using System.ServiceProcess;
using System.Text;
namespace Insight.Agent
namespace Insight.Agent;
internal class Helpers
{
internal class Helpers
internal static string? EscapeWql(string text)
{
internal static string? EscapeWql(string text)
{
if (text == null) return null;
if (text == null) return null;
var sb = new StringBuilder(text.Length);
foreach (var c in text)
var sb = new StringBuilder(text.Length);
foreach (var c in text)
{
if (c == '\\' || c == '\'' || c == '"')
{
if (c == '\\' || c == '\'' || c == '"')
{
sb.Append('\\');
}
sb.Append(c);
sb.Append('\\');
}
return sb.ToString();
sb.Append(c);
}
return sb.ToString();
}
[SupportedOSPlatform("windows")]
internal static bool ForceWinRmStart()
{
var winRm = ServiceController
.GetServices()
.First(x => x.ServiceName
.ToLower()
.Equals("winrm", StringComparison.Ordinal));
if (winRm.Status is not ServiceControllerStatus.Running)
{
winRm.Start();
winRm.WaitForStatus(ServiceControllerStatus.Running);
}
[SupportedOSPlatform("windows")]
internal static bool ForceWinRmStart()
{
var winRm = ServiceController
.GetServices()
.First(x => x.ServiceName
.ToLower()
.Equals("winrm", StringComparison.Ordinal));
if (winRm.Status is not ServiceControllerStatus.Running)
{
winRm.Start();
winRm.WaitForStatus(ServiceControllerStatus.Running);
}
if (winRm.Status != ServiceControllerStatus.Running) return false;
return true;
}
if (winRm.Status != ServiceControllerStatus.Running) return false;
return true;
}
}

View file

@ -0,0 +1,6 @@
namespace Insight.Agent.Models;
public class Config
{
public Guid? Serial { get; set; }
}

View file

@ -1,57 +1,56 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Microsoft.Extensions.Logging;
using Vaitr.Network;
namespace Insight.Agent.Network
namespace Insight.Agent.Network;
public class AgentSession : TcpSession<IMessage>
{
public class AgentSession : TcpSession<IAgentMessage>
private readonly IEnumerable<IMessageHandler<AgentSession>> _handlers;
public AgentSession(IEnumerable<IMessageHandler<AgentSession>> handlers, ISerializer<IMessage> serializer, ILogger<AgentSession> logger) : base(serializer, logger)
{
private readonly IEnumerable<IAgentMessageHandler<AgentSession>> _handlers;
_handlers = handlers;
}
public AgentSession(IEnumerable<IAgentMessageHandler<AgentSession>> handlers, ISerializer<IAgentMessage> serializer, ILogger<AgentSession> logger) : base(serializer, logger)
protected override ValueTask OnConnectedAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Agent ({ep?}) connected", RemoteEndPoint);
return default;
}
protected override ValueTask OnDisconnectedAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Agent ({ep?}) disconnected", RemoteEndPoint);
return default;
}
protected override ValueTask OnSentAsync(IPacketContext<IMessage> context, CancellationToken cancellationToken)
{
return base.OnSentAsync(context, cancellationToken);
}
protected override async ValueTask OnReceivedAsync(IPacketContext<IMessage> context, CancellationToken cancellationToken)
{
await base.OnReceivedAsync(context, cancellationToken);
foreach (var handler in _handlers)
{
_handlers = handlers;
}
protected override ValueTask OnConnectedAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Agent ({ep?}) connected", RemoteEndPoint);
return default;
}
protected override ValueTask OnDisconnectedAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Agent ({ep?}) disconnected", RemoteEndPoint);
return default;
}
protected override ValueTask OnSentAsync(IPacketContext<IAgentMessage> context, CancellationToken cancellationToken)
{
return base.OnSentAsync(context, cancellationToken);
}
protected override async ValueTask OnReceivedAsync(IPacketContext<IAgentMessage> context, CancellationToken cancellationToken)
{
await base.OnReceivedAsync(context, cancellationToken);
foreach (var handler in _handlers)
try
{
try
{
await handler.HandleAsync(this, context.Packet, cancellationToken);
}
catch (Exception ex)
{
_logger.LogWarning("Agent ({ep?}) {ex}", RemoteEndPoint, ex.ToString());
}
await handler.HandleAsync(this, context.Packet, cancellationToken);
}
catch (Exception ex)
{
_logger.LogWarning("Agent ({ep?}) {ex}", RemoteEndPoint, ex.ToString());
}
}
}
protected override ValueTask OnHeartbeatAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Agent ({ep?}) Heartbeat", RemoteEndPoint);
return default;
}
protected override ValueTask OnHeartbeatAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Agent ({ep?}) Heartbeat", RemoteEndPoint);
return default;
}
}

View file

@ -1,38 +1,43 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Agent.Models;
using Insight.Agent.Models;
using Insight.Agent.Services;
using Insight.Domain.Constants;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
public class AuthenticationHandler : IMessageHandler<AgentSession>
{
public class AuthenticationHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is AuthenticationRequest)
{
Config? config = null;
try
case AuthenticationRequest:
{
config = await Configurator.ReadAsync<Config>(Configuration.DefaultConfig, cancellationToken).ConfigureAwait(false);
Config? config = null;
try
{
config = await Configurator.ReadAsync<Config>(Configuration.DefaultConfig, cancellationToken).ConfigureAwait(false);
}
catch (Exception) { }
if (config is null)
{
config = new Config { Serial = Guid.NewGuid() };
await Configurator.WriteAsync(config, Configuration.DefaultConfig, cancellationToken).ConfigureAwait(false);
}
await sender.SendAsync(new AuthenticationResponse
{
Serial = config.Serial ?? throw new InvalidDataException(nameof(config.Serial)),
Version = Configuration.Version,
Hostname = Configuration.Hostname
}, cancellationToken);
break;
}
catch (Exception) { }
if (config is null)
{
config = new Config { Serial = Guid.NewGuid() };
await Configurator.WriteAsync(config, Configuration.DefaultConfig, cancellationToken).ConfigureAwait(false);
}
await sender.SendAsync(new Authentication
{
Serial = config.Serial ?? throw new InvalidDataException(nameof(config.Serial)),
Version = Configuration.Version,
Hostname = Configuration.Hostname
}, cancellationToken);
}
}
}
}

View file

@ -0,0 +1,40 @@
using Insight.Agent.Services;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using Microsoft.Extensions.Logging;
namespace Insight.Agent.Network.Handlers;
public class CustomHandler : IMessageHandler<AgentSession>
{
private readonly ScriptService _scriptService;
private readonly ILogger<CustomHandler> _logger;
public CustomHandler(ScriptService scriptService, ILogger<CustomHandler> logger)
{
_scriptService = scriptService;
_logger = logger;
}
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
switch (message)
{
case Request request:
await OnRequestAsync(sender, request, cancellationToken);
break;
}
}
private async ValueTask OnRequestAsync(AgentSession sender, Request request, CancellationToken cancellationToken)
{
var result = await _scriptService.QueryAsync(request.RequestData);
await sender.SendAsync(new Response(request)
{
ResponseData = result.HadErrors ? result.Errors : result.Data,
ResponseError = result.HadErrors
}, cancellationToken);
}
}

View file

@ -1,178 +1,182 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Management;
using System.Runtime.Versioning;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class DriveHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class DriveHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
var result = new DriveList();
result.AddRange(GetDrives());
await sender.SendAsync(result, cancellationToken);
}
}
private static List<Drive> GetDrives()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select index, name, caption, model, manufacturer, serialNumber, size, status, interfacetype, firmwarerevision, deviceid, pnpdeviceid from win32_diskdrive")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_diskdrive");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var drives = new List<Drive>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
case InventoryRequest:
{
var drive = new Drive();
var result = new Collection<Drive>();
result.AddRange(GetDrives());
var properties = @object.GetPropertyHashes();
drive.Index = @object.GetValue<uint>(properties, "index");
drive.Id = @object.GetValue<string>(properties, "deviceid")?.Trim();
drive.Name = @object.GetValue<string>(properties, "model")?.Trim();
drive.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
drive.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
drive.Size = @object.GetValue<ulong>(properties, "size");
drive.Status = @object.GetValue<string>(properties, "status")?.Trim();
drive.InterfaceType = @object.GetValue<string>(properties, "interfacetype")?.Trim();
drive.FirmwareRevision = @object.GetValue<string>(properties, "firmwarerevision")?.Trim();
drive.PNPDeviceID = @object.GetValue<string>(properties, "pnpdeviceid")?.Trim();
drive.Volumes = new List<Volume>();
var diskpartition = @object.GetRelated("win32_diskpartition");
using (diskpartition)
{
foreach (ManagementObject dp in diskpartition.Cast<ManagementObject>())
{
var volume = new Volume();
var dpProperties = dp.GetPropertyHashes();
volume.NumberOfBlocks = dp.GetValue<ulong>(dpProperties, "numberofblocks");
volume.BootPartition = dp.GetValue<bool>(dpProperties, "bootpartition");
volume.PrimaryPartition = dp.GetValue<bool>(dpProperties, "primarypartition");
volume.Size = dp.GetValue<ulong>(dpProperties, "size");
volume.Index = dp.GetValue<uint>(dpProperties, "index");
volume.Type = dp.GetValue<string>(dpProperties, "type")?.Trim();
volume.Bootable = dp.GetValue<bool>(dpProperties, "bootable");
volume.BlockSize = dp.GetValue<ulong>(dpProperties, "blocksize");
volume.StartingOffset = dp.GetValue<ulong>(dpProperties, "startingoffset");
var logicaldisk = dp.GetRelated("win32_logicaldisk");
using (logicaldisk)
{
foreach (ManagementObject ld in logicaldisk.Cast<ManagementObject>())
{
var ldProperties = ld.GetPropertyHashes();
volume.Id = ld.GetValue<string>(ldProperties, "deviceid")?.Trim();
volume.Name = ld.GetValue<string>(ldProperties, "volumename")?.Trim();
volume.SerialNumber = ld.GetValue<string>(ldProperties, "volumeserialnumber")?.Trim();
volume.DriveType = (DriveType)ld.GetValue<uint>(ldProperties, "drivetype");
volume.FileSystem = ld.GetValue<string>(ldProperties, "filesystem")?.Trim();
volume.Compressed = ld.GetValue<bool>(ldProperties, "compressed");
volume.Size = ld.GetValue<ulong>(ldProperties, "size");
volume.FreeSpace = ld.GetValue<ulong>(ldProperties, "freespace");
volume.ProviderName = ld.GetValue<string>(ldProperties, "providername")?.Trim();
}
}
drive.Volumes.Add(volume);
}
}
drives.Add(drive);
await sender.SendAsync(result, cancellationToken);
break;
}
}
return drives;
}
private static List<Volume> GetVolumes()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select deviceid, volumename, volumeserialnumber, drivetype, filesystem, compressed, size, freeSpace, providername from win32_logicaldisk")
};
// per device query
// "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + driveDeviceId + "'} WHERE AssocClass=Win32_DiskDriveToDiskPartition"
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_logicaldisk");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var volumes = new List<Volume>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var volume = new Volume();
var properties = @object.GetPropertyHashes();
//volume.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
//volume.VolumeName = @object.GetValue<string>(properties, "volumename")?.Trim();
//volume.VolumeSerialNumber = @object.GetValue<string>(properties, "volumeserialnumber")?.Trim();
volume.DriveType = (DriveType)@object.GetValue<uint>(properties, "drivetype");
volume.FileSystem = @object.GetValue<string>(properties, "filesystem")?.Trim();
volume.Compressed = @object.GetValue<bool>(properties, "compressed");
volume.Size = @object.GetValue<ulong>(properties, "size");
volume.FreeSpace = @object.GetValue<ulong>(properties, "freespace");
volume.ProviderName = @object.GetValue<string>(properties, "providername")?.Trim();
if (volume.Id is not null)
{
searcher.Query = new ObjectQuery("associators of {win32_logicaldisk.deviceid='" + volume.Id + "'} where assocclass=win32_logicaldisktopartition");
if (searcher.TryGet(out var collection2))
{
using (collection2)
{
foreach (ManagementObject @object2 in collection2)
{
var properties2 = @object2.GetPropertyHashes();
volume.Index = @object2.GetValue<uint>(properties2, "index");
//volume.DiskIndex = @object2.GetValue<uint>(properties2, "diskindex");
volume.Type = @object2.GetValue<string>(properties2, "type")?.Trim();
volume.Bootable = @object2.GetValue<bool>(properties2, "bootable");
volume.PrimaryPartition = @object2.GetValue<bool>(properties2, "primarypartition");
volume.BootPartition = @object2.GetValue<bool>(properties2, "bootpartition");
volume.BlockSize = @object2.GetValue<ulong>(properties2, "blocksize");
volume.NumberOfBlocks = @object2.GetValue<ulong>(properties2, "numberofblocks");
volume.StartingOffset = @object2.GetValue<ulong>(properties2, "startingoffset");
}
}
}
}
volumes.Add(volume);
}
}
return volumes;
}
}
private static List<Drive> GetDrives()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select index, name, caption, model, manufacturer, serialNumber, size, status, interfacetype, firmwarerevision, deviceid, pnpdeviceid from win32_diskdrive")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_diskdrive");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var drives = new List<Drive>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var drive = new Drive();
var properties = @object.GetPropertyHashes();
drive.Index = @object.GetValue<uint>(properties, "index");
drive.Id = @object.GetValue<string>(properties, "deviceid")?.Trim();
drive.Name = @object.GetValue<string>(properties, "model")?.Trim();
drive.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
drive.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
drive.Size = @object.GetValue<ulong>(properties, "size");
drive.Status = @object.GetValue<string>(properties, "status")?.Trim();
drive.InterfaceType = @object.GetValue<string>(properties, "interfacetype")?.Trim();
drive.FirmwareRevision = @object.GetValue<string>(properties, "firmwarerevision")?.Trim();
drive.PNPDeviceID = @object.GetValue<string>(properties, "pnpdeviceid")?.Trim();
drive.Volumes = new List<Volume>();
var diskpartition = @object.GetRelated("win32_diskpartition");
using (diskpartition)
{
foreach (ManagementObject dp in diskpartition.Cast<ManagementObject>())
{
var volume = new Volume();
var dpProperties = dp.GetPropertyHashes();
volume.NumberOfBlocks = dp.GetValue<ulong>(dpProperties, "numberofblocks");
volume.BootPartition = dp.GetValue<bool>(dpProperties, "bootpartition");
volume.PrimaryPartition = dp.GetValue<bool>(dpProperties, "primarypartition");
volume.Size = dp.GetValue<ulong>(dpProperties, "size");
volume.Index = dp.GetValue<uint>(dpProperties, "index");
volume.Type = dp.GetValue<string>(dpProperties, "type")?.Trim();
volume.Bootable = dp.GetValue<bool>(dpProperties, "bootable");
volume.BlockSize = dp.GetValue<ulong>(dpProperties, "blocksize");
volume.StartingOffset = dp.GetValue<ulong>(dpProperties, "startingoffset");
var logicaldisk = dp.GetRelated("win32_logicaldisk");
using (logicaldisk)
{
foreach (ManagementObject ld in logicaldisk.Cast<ManagementObject>())
{
var ldProperties = ld.GetPropertyHashes();
volume.Id = ld.GetValue<string>(ldProperties, "deviceid")?.Trim();
volume.Name = ld.GetValue<string>(ldProperties, "volumename")?.Trim();
volume.SerialNumber = ld.GetValue<string>(ldProperties, "volumeserialnumber")?.Trim();
volume.DriveType = (DriveType)ld.GetValue<uint>(ldProperties, "drivetype");
volume.FileSystem = ld.GetValue<string>(ldProperties, "filesystem")?.Trim();
volume.Compressed = ld.GetValue<bool>(ldProperties, "compressed");
volume.Size = ld.GetValue<ulong>(ldProperties, "size");
volume.FreeSpace = ld.GetValue<ulong>(ldProperties, "freespace");
volume.ProviderName = ld.GetValue<string>(ldProperties, "providername")?.Trim();
}
}
drive.Volumes.Add(volume);
}
}
drives.Add(drive);
}
}
return drives;
}
private static List<Volume> GetVolumes()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select deviceid, volumename, volumeserialnumber, drivetype, filesystem, compressed, size, freeSpace, providername from win32_logicaldisk")
};
// per device query
// "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + driveDeviceId + "'} WHERE AssocClass=Win32_DiskDriveToDiskPartition"
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_logicaldisk");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var volumes = new List<Volume>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var volume = new Volume();
var properties = @object.GetPropertyHashes();
//volume.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
//volume.VolumeName = @object.GetValue<string>(properties, "volumename")?.Trim();
//volume.VolumeSerialNumber = @object.GetValue<string>(properties, "volumeserialnumber")?.Trim();
volume.DriveType = (DriveType)@object.GetValue<uint>(properties, "drivetype");
volume.FileSystem = @object.GetValue<string>(properties, "filesystem")?.Trim();
volume.Compressed = @object.GetValue<bool>(properties, "compressed");
volume.Size = @object.GetValue<ulong>(properties, "size");
volume.FreeSpace = @object.GetValue<ulong>(properties, "freespace");
volume.ProviderName = @object.GetValue<string>(properties, "providername")?.Trim();
if (volume.Id is not null)
{
searcher.Query = new ObjectQuery("associators of {win32_logicaldisk.deviceid='" + volume.Id + "'} where assocclass=win32_logicaldisktopartition");
if (searcher.TryGet(out var collection2))
{
using (collection2)
{
foreach (ManagementObject @object2 in collection2)
{
var properties2 = @object2.GetPropertyHashes();
volume.Index = @object2.GetValue<uint>(properties2, "index");
//volume.DiskIndex = @object2.GetValue<uint>(properties2, "diskindex");
volume.Type = @object2.GetValue<string>(properties2, "type")?.Trim();
volume.Bootable = @object2.GetValue<bool>(properties2, "bootable");
volume.PrimaryPartition = @object2.GetValue<bool>(properties2, "primarypartition");
volume.BootPartition = @object2.GetValue<bool>(properties2, "bootpartition");
volume.BlockSize = @object2.GetValue<ulong>(properties2, "blocksize");
volume.NumberOfBlocks = @object2.GetValue<ulong>(properties2, "numberofblocks");
volume.StartingOffset = @object2.GetValue<ulong>(properties2, "startingoffset");
}
}
}
}
volumes.Add(volume);
}
}
return volumes;
}
}

View file

@ -1,274 +1,277 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Management;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Route = Insight.Agent.Messages.Route;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class InterfaceHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class InterfaceHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
var result = new InterfaceList();
result.AddRange(GetInterfaces());
await sender.SendAsync(result, cancellationToken);
}
}
private static List<Interface> GetInterfaces()
{
if (NetworkInterface.GetIsNetworkAvailable() is false) return null;
if (NetworkInterface.GetAllNetworkInterfaces().Any() is false) return null;
var interfaces = new List<Interface>();
foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
{
var ipProperties = ni.GetIPProperties();
var ipStatistics = ni.GetIPStatistics();
var @interface = new Interface
case InventoryRequest:
{
Mac = ni.GetPhysicalAddress().ToString(),
Name = ni.Name,
Description = ni.Description,
Type = ni.NetworkInterfaceType,
Speed = ni.Speed,
Status = ni.OperationalStatus,
Suffix = ipProperties.DnsSuffix,
Sent = ipStatistics.BytesSent,
Received = ipStatistics.BytesReceived,
IncomingPacketsDiscarded = ipStatistics.IncomingPacketsDiscarded,
IncomingPacketsWithErrors = ipStatistics.IncomingPacketsWithErrors,
IncomingUnknownProtocolPackets = ipStatistics.IncomingUnknownProtocolPackets,
OutgoingPacketsDiscarded = ipStatistics.OutgoingPacketsDiscarded,
OutgoingPacketsWithErrors = ipStatistics.OutgoingPacketsWithErrors
};
var result = new Collection<Interface>();
result.AddRange(GetInterfaces());
try
{
var propertiesV4 = ipProperties.GetIPv4Properties();
@interface.Index = uint.Parse(propertiesV4.Index.ToString());
@interface.Ipv4Mtu = propertiesV4.Mtu;
@interface.Ipv4Dhcp = propertiesV4.IsDhcpEnabled;
@interface.Ipv4Forwarding = propertiesV4.IsForwardingEnabled;
await sender.SendAsync(result, cancellationToken);
break;
}
catch (Exception) { }
try
{
var propertiesV6 = ipProperties.GetIPv6Properties();
@interface.Index = uint.Parse(propertiesV6.Index.ToString());
@interface.Ipv6Mtu = propertiesV6.Mtu;
}
catch (Exception) { }
@interface.Gateways = GetAddresses(ipProperties.GatewayAddresses);
@interface.Addresses = GetAddresses(ipProperties.UnicastAddresses);
@interface.Dns = GetAddresses(ipProperties.DnsAddresses);
@interface.Dhcp = GetAddresses(ipProperties.DhcpServerAddresses);
if (@interface.Index.HasValue)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery($"select interfaceindex, guid, physicaladapter, manufacturer from win32_networkadapter where interfaceindex = {@interface.Index}")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery($"select * from win32_networkadapter where interfaceindex = {@interface.Index}");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
using (collection)
{
foreach (ManagementObject @object in collection)
{
var properties = @object.GetPropertyHashes();
@interface.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
@interface.Guid = @object.GetValue<Guid>(properties, "guid");
@interface.Physical = @object.GetValue<bool>(properties, "physicaladapter");
break;
}
}
@interface.Routes = QueryInterfaceRoutes(@interface.Index.Value);
}
}
interfaces.Add(@interface);
}
return interfaces;
}
private static List<Route> QueryInterfaceRoutes(uint interfaceIndex)
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\standardcimv2"),
Query = new ObjectQuery($"select addressFamily, state, interfaceindex, routemetric, nexthop, destinationprefix from msft_netroute where interfaceindex = {interfaceIndex}")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery($"select * from msft_netroute where interfaceindex = {interfaceIndex}");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var routes = new List<Route>();
using (collection)
{
foreach (var @object in collection)
{
var route = new Route
{
InterfaceIndex = interfaceIndex
};
var properties = @object.GetPropertyHashes();
if (@object.TryGetValue<object>(properties, "routemetric", out var routemetric))
{
if (int.TryParse(routemetric?.ToString(), out var metric)) route.Metric = metric;
}
if (@object.TryGetValue<object>(properties, "nexthop", out var nexthop))
{
if (IPAddress.TryParse(nexthop?.ToString(), out var gateway)) route.Gateway = new IPAddress2(gateway);
}
if (@object.TryGetValue<object>(properties, "destinationprefix", out var destinationprefix))
{
var split = destinationprefix?.ToString()?.Split('/');
var cidrData = split?[1];
if (IPAddress.TryParse(split?[0], out var destination))
route.Destination = new IPAddress2(destination);
if (int.TryParse(cidrData, out var cidr))
{
var mask = ConvertCidr(cidr);
route.Mask = mask;
}
}
routes.Add(route);
}
}
return routes;
}
private static List<Unicast> GetAddresses(UnicastIPAddressInformationCollection unicastCollection)
{
var addresses = new List<Unicast>();
if (unicastCollection.Any() is false) return addresses;
foreach (var unicast in unicastCollection)
{
addresses.Add(new Unicast
{
IpAddress = new IPAddress2(unicast.Address),
AddressPreferredLifetime = unicast.AddressPreferredLifetime,
AddressValidLifetime = unicast.AddressValidLifetime,
DuplicateAddressDetectionState = unicast.DuplicateAddressDetectionState,
Ipv4Mask = new IPAddress2(unicast.IPv4Mask),
PrefixLength = unicast.PrefixLength,
PrefixOrigin = unicast.PrefixOrigin,
SuffixOrigin = unicast.SuffixOrigin,
DhcpLeaseLifetime = unicast.DhcpLeaseLifetime,
});
}
return addresses;
}
private static List<IPAddress2> GetAddresses(IPAddressCollection addressCollection)
{
var addresses = new List<IPAddress2>();
if (addressCollection.Any() is false) return addresses;
foreach (var address in addressCollection)
{
addresses.Add(new IPAddress2(address));
}
return addresses;
}
private static List<IPAddress2> GetAddresses(GatewayIPAddressInformationCollection addressCollection)
{
var addresses = new List<IPAddress2>();
if (addressCollection.Any() is false) return addresses;
foreach (var address in addressCollection)
{
addresses.Add(new IPAddress2(address.Address));
}
return addresses;
}
private static string? ConvertCidr(int cidr)
{
return cidr switch
{
0 => "0.0.0.0",
1 => "128.0.0.0",
2 => "192.0.0.0",
3 => "224.0.0.0",
4 => "240.0.0.0",
5 => "248.0.0.0",
6 => "252.0.0.0",
7 => "254.0.0.0",
8 => "255.0.0.0",
9 => "255.128.0.0",
10 => "255.192.0.0",
11 => "255.224.0.0",
12 => "255.240.0.0",
13 => "255.248.0.0",
14 => "255.252.0.0",
15 => "255.254.0.0",
16 => "255.255.0.0",
17 => "255.255.128.0",
18 => "255.255.192.0",
19 => "255.255.224.0",
20 => "255.255.240.0",
21 => "255.255.248.0",
22 => "255.255.252.0",
23 => "255.255.254.0",
24 => "255.255.255.0",
25 => "255.255.255.128",
26 => "255.255.255.192",
27 => "255.255.255.224",
28 => "255.255.255.240",
29 => "255.255.255.248",
30 => "255.255.255.252",
31 => "255.255.255.254",
32 => "255.255.255.255",
_ => null,
};
}
}
private static List<Interface> GetInterfaces()
{
if (NetworkInterface.GetIsNetworkAvailable() is false) return null;
if (NetworkInterface.GetAllNetworkInterfaces().Any() is false) return null;
var interfaces = new List<Interface>();
foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
{
var ipProperties = ni.GetIPProperties();
var ipStatistics = ni.GetIPStatistics();
var @interface = new Interface
{
Mac = ni.GetPhysicalAddress().ToString(),
Name = ni.Name,
Description = ni.Description,
Type = ni.NetworkInterfaceType,
Speed = ni.Speed,
Status = ni.OperationalStatus,
Suffix = ipProperties.DnsSuffix,
Sent = ipStatistics.BytesSent,
Received = ipStatistics.BytesReceived,
IncomingPacketsDiscarded = ipStatistics.IncomingPacketsDiscarded,
IncomingPacketsWithErrors = ipStatistics.IncomingPacketsWithErrors,
IncomingUnknownProtocolPackets = ipStatistics.IncomingUnknownProtocolPackets,
OutgoingPacketsDiscarded = ipStatistics.OutgoingPacketsDiscarded,
OutgoingPacketsWithErrors = ipStatistics.OutgoingPacketsWithErrors
};
try
{
var propertiesV4 = ipProperties.GetIPv4Properties();
@interface.Index = uint.Parse(propertiesV4.Index.ToString());
@interface.Ipv4Mtu = propertiesV4.Mtu;
@interface.Ipv4Dhcp = propertiesV4.IsDhcpEnabled;
@interface.Ipv4Forwarding = propertiesV4.IsForwardingEnabled;
}
catch (Exception) { }
try
{
var propertiesV6 = ipProperties.GetIPv6Properties();
@interface.Index = uint.Parse(propertiesV6.Index.ToString());
@interface.Ipv6Mtu = propertiesV6.Mtu;
}
catch (Exception) { }
@interface.Gateways = GetAddresses(ipProperties.GatewayAddresses);
@interface.Addresses = GetAddresses(ipProperties.UnicastAddresses);
@interface.Dns = GetAddresses(ipProperties.DnsAddresses);
@interface.Dhcp = GetAddresses(ipProperties.DhcpServerAddresses);
if (@interface.Index.HasValue)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery($"select interfaceindex, guid, physicaladapter, manufacturer from win32_networkadapter where interfaceindex = {@interface.Index}")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery($"select * from win32_networkadapter where interfaceindex = {@interface.Index}");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
using (collection)
{
foreach (ManagementObject @object in collection)
{
var properties = @object.GetPropertyHashes();
@interface.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
@interface.Guid = @object.GetValue<Guid>(properties, "guid");
@interface.Physical = @object.GetValue<bool>(properties, "physicaladapter");
break;
}
}
@interface.Routes = QueryInterfaceRoutes(@interface.Index.Value);
}
}
interfaces.Add(@interface);
}
return interfaces;
}
private static List<Route> QueryInterfaceRoutes(uint interfaceIndex)
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\standardcimv2"),
Query = new ObjectQuery($"select addressFamily, state, interfaceindex, routemetric, nexthop, destinationprefix from msft_netroute where interfaceindex = {interfaceIndex}")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery($"select * from msft_netroute where interfaceindex = {interfaceIndex}");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var routes = new List<Route>();
using (collection)
{
foreach (var @object in collection)
{
var route = new Route
{
InterfaceIndex = interfaceIndex
};
var properties = @object.GetPropertyHashes();
if (@object.TryGetValue<object>(properties, "routemetric", out var routemetric))
{
if (int.TryParse(routemetric?.ToString(), out var metric)) route.Metric = metric;
}
if (@object.TryGetValue<object>(properties, "nexthop", out var nexthop))
{
if (IPAddress.TryParse(nexthop?.ToString(), out var gateway)) route.Gateway = new IPAddress2(gateway);
}
if (@object.TryGetValue<object>(properties, "destinationprefix", out var destinationprefix))
{
var split = destinationprefix?.ToString()?.Split('/');
var cidrData = split?[1];
if (IPAddress.TryParse(split?[0], out var destination))
route.Destination = new IPAddress2(destination);
if (int.TryParse(cidrData, out var cidr))
{
var mask = ConvertCidr(cidr);
route.Mask = mask;
}
}
routes.Add(route);
}
}
return routes;
}
private static List<Unicast> GetAddresses(UnicastIPAddressInformationCollection unicastCollection)
{
var addresses = new List<Unicast>();
if (unicastCollection.Any() is false) return addresses;
foreach (var unicast in unicastCollection)
{
addresses.Add(new Unicast
{
IpAddress = new IPAddress2(unicast.Address),
AddressPreferredLifetime = unicast.AddressPreferredLifetime,
AddressValidLifetime = unicast.AddressValidLifetime,
DuplicateAddressDetectionState = unicast.DuplicateAddressDetectionState,
Ipv4Mask = new IPAddress2(unicast.IPv4Mask),
PrefixLength = unicast.PrefixLength,
PrefixOrigin = unicast.PrefixOrigin,
SuffixOrigin = unicast.SuffixOrigin,
DhcpLeaseLifetime = unicast.DhcpLeaseLifetime,
});
}
return addresses;
}
private static List<IPAddress2> GetAddresses(IPAddressCollection addressCollection)
{
var addresses = new List<IPAddress2>();
if (addressCollection.Any() is false) return addresses;
foreach (var address in addressCollection)
{
addresses.Add(new IPAddress2(address));
}
return addresses;
}
private static List<IPAddress2> GetAddresses(GatewayIPAddressInformationCollection addressCollection)
{
var addresses = new List<IPAddress2>();
if (addressCollection.Any() is false) return addresses;
foreach (var address in addressCollection)
{
addresses.Add(new IPAddress2(address.Address));
}
return addresses;
}
private static string? ConvertCidr(int cidr)
{
return cidr switch
{
0 => "0.0.0.0",
1 => "128.0.0.0",
2 => "192.0.0.0",
3 => "224.0.0.0",
4 => "240.0.0.0",
5 => "248.0.0.0",
6 => "252.0.0.0",
7 => "254.0.0.0",
8 => "255.0.0.0",
9 => "255.128.0.0",
10 => "255.192.0.0",
11 => "255.224.0.0",
12 => "255.240.0.0",
13 => "255.248.0.0",
14 => "255.252.0.0",
15 => "255.254.0.0",
16 => "255.255.0.0",
17 => "255.255.128.0",
18 => "255.255.192.0",
19 => "255.255.224.0",
20 => "255.255.240.0",
21 => "255.255.248.0",
22 => "255.255.252.0",
23 => "255.255.254.0",
24 => "255.255.255.0",
25 => "255.255.255.128",
26 => "255.255.255.192",
27 => "255.255.255.224",
28 => "255.255.255.240",
29 => "255.255.255.248",
30 => "255.255.255.252",
31 => "255.255.255.254",
32 => "255.255.255.255",
_ => null,
};
}
}

View file

@ -1,86 +1,88 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Management;
using System.Runtime.Versioning;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class MainboardHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class MainboardHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
case InventoryRequest:
await sender.SendAsync(GetMainboard(), cancellationToken);
}
}
private static Mainboard GetMainboard()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select manufacturer, product, serialnumber from win32_baseboard")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_baseboard");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var mainboard = new Mainboard();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var properties = @object.GetPropertyHashes();
mainboard.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
mainboard.Model = @object.GetValue<string>(properties, "product")?.Trim();
mainboard.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
break;
}
}
searcher.Query = new ObjectQuery("select manufacturer, serialnumber, smbiosbiosversion, releasedate from win32_bios");
if (searcher.TryGet(out var collection2) is false)
{
searcher.Query = new ObjectQuery("select * from win32_bios");
if (searcher.TryGet(out collection2) is false) return null;
}
using (collection2)
{
foreach (ManagementObject @object in collection2.Cast<ManagementObject>())
{
var properties = @object.GetPropertyHashes();
mainboard.BiosManufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
mainboard.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
mainboard.BiosVersion = @object.GetValue<string>(properties, "smbiosbiosversion")?.Trim();
if (@object.TryGetValue<object>(properties, "releasedate", out var releasedate))
{
mainboard.BiosDate = ManagementDateTimeConverter.ToDateTime(releasedate?.ToString());
}
break;
}
}
//Logger.LogWarning(JsonSerializer.Serialize(mainboard, new JsonSerializerOptions
//{
// WriteIndented= true
//}));
return mainboard;
break;
}
}
private static Mainboard GetMainboard()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select manufacturer, product, serialnumber from win32_baseboard")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_baseboard");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var mainboard = new Mainboard();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var properties = @object.GetPropertyHashes();
mainboard.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
mainboard.Model = @object.GetValue<string>(properties, "product")?.Trim();
mainboard.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
break;
}
}
searcher.Query = new ObjectQuery("select manufacturer, serialnumber, smbiosbiosversion, releasedate from win32_bios");
if (searcher.TryGet(out var collection2) is false)
{
searcher.Query = new ObjectQuery("select * from win32_bios");
if (searcher.TryGet(out collection2) is false) return null;
}
using (collection2)
{
foreach (ManagementObject @object in collection2.Cast<ManagementObject>())
{
var properties = @object.GetPropertyHashes();
mainboard.BiosManufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
mainboard.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
mainboard.BiosVersion = @object.GetValue<string>(properties, "smbiosbiosversion")?.Trim();
if (@object.TryGetValue<object>(properties, "releasedate", out var releasedate))
{
mainboard.BiosDate = ManagementDateTimeConverter.ToDateTime(releasedate?.ToString());
}
break;
}
}
//Logger.LogWarning(JsonSerializer.Serialize(mainboard, new JsonSerializerOptions
//{
// WriteIndented= true
//}));
return mainboard;
}
}

View file

@ -1,123 +1,127 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Management;
using System.Runtime.Versioning;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class MemoryHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class MemoryHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
var result = new MemoryList();
result.AddRange(GetMemory());
await sender.SendAsync(result, cancellationToken);
}
}
private static List<Memory> GetMemory()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select tag, devicelocator, manufacturer, partnumber, serialnumber, capacity, speed, maxvoltage, configuredclockspeed, configuredvoltage from win32_physicalmemory")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_physicalmemory");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var memorysticks = new List<Memory>();
using (collection)
{
uint index = 0;
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
case InventoryRequest:
{
var @memory = new Memory();
var result = new Collection<Memory>();
result.AddRange(GetMemory());
var properties = @object.GetPropertyHashes();
@memory.Index = index;
@memory.Tag = @object.GetValue<string>(properties, "tag")?.Trim();
@memory.Location = @object.GetValue<string>(properties, "devicelocator")?.Trim();
@memory.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
@memory.Model = @object.GetValue<string>(properties, "partnumber")?.Trim();
@memory.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
@memory.Capacity = @object.GetValue<ulong>(properties, "capacity");
@memory.Speed = @object.GetValue<uint>(properties, "speed");
@memory.Voltage = @object.GetValue<uint>(properties, "maxvoltage");
@memory.ConfiguredSpeed = @object.GetValue<uint>(properties, "configuredclockspeed");
@memory.ConfiguredVoltage = @object.GetValue<uint>(properties, "configuredvoltage");
memorysticks.Add(@memory);
index++;
await sender.SendAsync(result, cancellationToken);
break;
}
}
}
}
return memorysticks;
private static List<Memory> GetMemory()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select tag, devicelocator, manufacturer, partnumber, serialnumber, capacity, speed, maxvoltage, configuredclockspeed, configuredvoltage from win32_physicalmemory")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_physicalmemory");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
//private async ValueTask<Memory.Metric> GetMemoryMetricAsync(CancellationToken cancellationToken)
//{
// var metric = new Memory.Metric();
var memorysticks = new List<Memory>();
// using var searcher = new ManagementObjectSearcher
// {
// Scope = new ManagementScope(@"root\cimv2"),
// Query = new ObjectQuery("select totalphysicalmemory from win32_computersystem")
// };
using (collection)
{
uint index = 0;
// if (searcher.TryGet(out var collection) is false)
// {
// searcher.Query = new ObjectQuery("select * from win32_computersystem");
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var @memory = new Memory();
// if (searcher.TryGet(out collection) is false) return metric;
// }
var properties = @object.GetPropertyHashes();
// ulong capacity = 0;
@memory.Index = index;
@memory.Tag = @object.GetValue<string>(properties, "tag")?.Trim();
@memory.Location = @object.GetValue<string>(properties, "devicelocator")?.Trim();
@memory.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
@memory.Model = @object.GetValue<string>(properties, "partnumber")?.Trim();
@memory.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
@memory.Capacity = @object.GetValue<ulong>(properties, "capacity");
@memory.Speed = @object.GetValue<uint>(properties, "speed");
@memory.Voltage = @object.GetValue<uint>(properties, "maxvoltage");
@memory.ConfiguredSpeed = @object.GetValue<uint>(properties, "configuredclockspeed");
@memory.ConfiguredVoltage = @object.GetValue<uint>(properties, "configuredvoltage");
// using (collection)
// {
// foreach (var @object in collection)
// {
// var properties = @object.GetPropertyHashes();
memorysticks.Add(@memory);
index++;
}
}
// if (@object.TryGetValue(properties, "totalphysicalmemory", out capacity))
// {
// capacity = capacity / 1024 / 1024;
// }
// break;
// }
// }
// if (MemoryAvailableCounter is null)
// {
// MemoryAvailableCounter = new PerformanceCounter
// {
// CategoryName = "Memory",
// CounterName = "Available MBytes"
// };
// metric.MemoryAvailable = MemoryAvailableCounter.NextValue();
// await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
// }
// metric.Timestamp = DateTime.Now;
// metric.MemoryAvailable = MemoryAvailableCounter.NextValue();
// metric.MemoryUsed = capacity - metric.MemoryAvailable;
// metric.MemoryUsagePercentage = metric.MemoryUsed / capacity * 100;
// metric.MemoryAvailablePercentage = 100 - metric.MemoryUsagePercentage;
// return metric;
//}
return memorysticks;
}
//private async ValueTask<Memory.Metric> GetMemoryMetricAsync(CancellationToken cancellationToken)
//{
// var metric = new Memory.Metric();
// using var searcher = new ManagementObjectSearcher
// {
// Scope = new ManagementScope(@"root\cimv2"),
// Query = new ObjectQuery("select totalphysicalmemory from win32_computersystem")
// };
// if (searcher.TryGet(out var collection) is false)
// {
// searcher.Query = new ObjectQuery("select * from win32_computersystem");
// if (searcher.TryGet(out collection) is false) return metric;
// }
// ulong capacity = 0;
// using (collection)
// {
// foreach (var @object in collection)
// {
// var properties = @object.GetPropertyHashes();
// if (@object.TryGetValue(properties, "totalphysicalmemory", out capacity))
// {
// capacity = capacity / 1024 / 1024;
// }
// break;
// }
// }
// if (MemoryAvailableCounter is null)
// {
// MemoryAvailableCounter = new PerformanceCounter
// {
// CategoryName = "Memory",
// CounterName = "Available MBytes"
// };
// metric.MemoryAvailable = MemoryAvailableCounter.NextValue();
// await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
// }
// metric.Timestamp = DateTime.Now;
// metric.MemoryAvailable = MemoryAvailableCounter.NextValue();
// metric.MemoryUsed = capacity - metric.MemoryAvailable;
// metric.MemoryUsagePercentage = metric.MemoryUsed / capacity * 100;
// metric.MemoryAvailablePercentage = 100 - metric.MemoryUsagePercentage;
// return metric;
//}
}

View file

@ -1,91 +1,93 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using Microsoft.Win32;
using System.Management;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.AccessControl;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class OperationSystemHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class OperationSystemHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
case InventoryRequest:
await sender.SendAsync(GetOperatingSystem(), cancellationToken);
}
}
private static OperationSystem GetOperatingSystem()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select caption, version, serialnumber, osarchitecture, installdate from win32_operatingsystem")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_operatingsystem");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var os = new OperationSystem();
using (collection)
{
foreach (ManagementObject @object in collection)
{
var properties = @object.GetPropertyHashes();
os.Name = @object.GetValue<string>(properties, "caption")?.Trim();
os.Version = @object.GetValue<string>(properties, "version")?.Trim();
os.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
if (@object.TryGetValue<string>(properties, "osarchitecture", out var architecture))
{
if (architecture is not null && architecture.ToLower().Contains("64")) os.Architecture = Architecture.X64;
}
else
{
os.Architecture = Architecture.X86;
}
if (@object.TryGetValue<object>(properties, "installdate", out var installdate))
{
os.InstallDate = ManagementDateTimeConverter.ToDateTime(installdate?.ToString());
}
break;
}
}
using var registry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);
using var key = registry.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey);
if (key is not null && key?.GetValue("UBR")?.ToString() is string buildNumber)
{
os.Version = $"{os.Version}.{buildNumber}";
}
searcher.Query = new ObjectQuery("select * from win32_portconnector");
if (searcher.TryGet(out var collection2) is false)
{
os.Virtual = true;
}
else
{
os.Virtual = false;
}
collection2.Dispose();
return os;
break;
}
}
private static OperationSystem GetOperatingSystem()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select caption, version, serialnumber, osarchitecture, installdate from win32_operatingsystem")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_operatingsystem");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var os = new OperationSystem();
using (collection)
{
foreach (ManagementObject @object in collection)
{
var properties = @object.GetPropertyHashes();
os.Name = @object.GetValue<string>(properties, "caption")?.Trim();
os.Version = @object.GetValue<string>(properties, "version")?.Trim();
os.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
if (@object.TryGetValue<string>(properties, "osarchitecture", out var architecture))
{
if (architecture is not null && architecture.ToLower().Contains("64")) os.Architecture = Architecture.X64;
}
else
{
os.Architecture = Architecture.X86;
}
if (@object.TryGetValue<object>(properties, "installdate", out var installdate))
{
os.InstallDate = ManagementDateTimeConverter.ToDateTime(installdate?.ToString());
}
break;
}
}
using var registry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);
using var key = registry.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey);
if (key is not null && key?.GetValue("UBR")?.ToString() is string buildNumber)
{
os.Version = $"{os.Version}.{buildNumber}";
}
searcher.Query = new ObjectQuery("select * from win32_portconnector");
if (searcher.TryGet(out var collection2) is false)
{
os.Virtual = true;
}
else
{
os.Virtual = false;
}
collection2.Dispose();
return os;
}
}

View file

@ -1,60 +1,64 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Management;
using System.Runtime.Versioning;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class PrinterHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class PrinterHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
var result = new PrinterList();
result.AddRange(GetPrinters());
await sender.SendAsync(result, cancellationToken);
}
}
private static List<Printer> GetPrinters()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select drivername, name, portname, location, comment from win32_printer")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_printer");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var printers = new List<Printer>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
case InventoryRequest:
{
var printer = new Printer();
var result = new Collection<Printer>();
result.AddRange(GetPrinters());
var properties = @object.GetPropertyHashes();
printer.Driver = @object.GetValue<string>(properties, "drivername")?.Trim();
printer.Name = @object.GetValue<string>(properties, "name")?.Trim();
printer.Port = @object.GetValue<string>(properties, "portname")?.Trim();
printer.Location = @object.GetValue<string>(properties, "location")?.Trim();
printer.Comment = @object.GetValue<string>(properties, "comment")?.Trim();
printers.Add(printer);
await sender.SendAsync(result, cancellationToken);
break;
}
}
return printers;
}
}
private static List<Printer> GetPrinters()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select drivername, name, portname, location, comment from win32_printer")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_printer");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var printers = new List<Printer>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var printer = new Printer();
var properties = @object.GetPropertyHashes();
printer.Driver = @object.GetValue<string>(properties, "drivername")?.Trim();
printer.Name = @object.GetValue<string>(properties, "name")?.Trim();
printer.Port = @object.GetValue<string>(properties, "portname")?.Trim();
printer.Location = @object.GetValue<string>(properties, "location")?.Trim();
printer.Comment = @object.GetValue<string>(properties, "comment")?.Trim();
printers.Add(printer);
}
}
return printers;
}
}

View file

@ -1,143 +1,147 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Management;
using System.Runtime.Versioning;
namespace Insight.Agent.Network.Handlers
{
[SupportedOSPlatform("windows")]
public class ProcessorHandler : IAgentMessageHandler<AgentSession>
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
{
if (message is GetInventory)
{
var result = new ProcessorList();
result.AddRange(GetProcessors());
namespace Insight.Agent.Network.Handlers;
await sender.SendAsync(result, cancellationToken);
}
[SupportedOSPlatform("windows")]
public class ProcessorHandler : IMessageHandler<AgentSession>
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
switch (message)
{
case InventoryRequest:
{
var result = new Collection<Processor>();
result.AddRange(GetProcessors());
await sender.SendAsync(result, cancellationToken);
break;
}
}
}
private static List<Processor> GetProcessors()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select deviceid, name, manufacturer, socketdesignation, version, processorid, l2cachesize, l3cachesize, currentclockspeed, maxclockspeed, numberofcores, numberoflogicalprocessors, virtualizationfirmwareenabled from win32_processor")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_processor");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
private static List<Processor> GetProcessors()
var processors = new List<Processor>();
using (collection)
{
using var searcher = new ManagementObjectSearcher
uint index = 0;
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select deviceid, name, manufacturer, socketdesignation, version, processorid, l2cachesize, l3cachesize, currentclockspeed, maxclockspeed, numberofcores, numberoflogicalprocessors, virtualizationfirmwareenabled from win32_processor")
};
var processor = new Processor();
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_processor");
var properties = @object.GetPropertyHashes();
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
processor.Index = index;
processor.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
processor.Name = @object.GetValue<string>(properties, "name")?.Trim();
processor.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
processor.Socket = @object.GetValue<string>(properties, "socketdesignation")?.Trim();
processor.Version = @object.GetValue<string>(properties, "version")?.Trim();
processor.SerialNumber = @object.GetValue<string>(properties, "processorid")?.Trim();
processor.CurrentSpeed = @object.GetValue<uint>(properties, "currentclockspeed");
processor.MaxSpeed = @object.GetValue<uint>(properties, "maxclockspeed");
processor.Cores = @object.GetValue<uint>(properties, "numberofcores");
processor.LogicalCores = @object.GetValue<uint>(properties, "numberoflogicalprocessors");
processor.Virtualization = @object.GetValue<bool>(properties, "virtualizationfirmwareenabled");
var processors = new List<Processor>();
searcher.Query = new ObjectQuery("select level, maxcachesize from win32_cachememory");
using (collection)
{
uint index = 0;
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
if (searcher.TryGet(out var collection2) is false)
{
var processor = new Processor();
searcher.Query = new ObjectQuery("select * from win32_cachememory");
var properties = @object.GetPropertyHashes();
if (searcher.TryGet(out collection2) is false) throw new InvalidOperationException("WMI Collection NULL");
}
processor.Index = index;
processor.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
processor.Name = @object.GetValue<string>(properties, "name")?.Trim();
processor.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
processor.Socket = @object.GetValue<string>(properties, "socketdesignation")?.Trim();
processor.Version = @object.GetValue<string>(properties, "version")?.Trim();
processor.SerialNumber = @object.GetValue<string>(properties, "processorid")?.Trim();
processor.CurrentSpeed = @object.GetValue<uint>(properties, "currentclockspeed");
processor.MaxSpeed = @object.GetValue<uint>(properties, "maxclockspeed");
processor.Cores = @object.GetValue<uint>(properties, "numberofcores");
processor.LogicalCores = @object.GetValue<uint>(properties, "numberoflogicalprocessors");
processor.Virtualization = @object.GetValue<bool>(properties, "virtualizationfirmwareenabled");
searcher.Query = new ObjectQuery("select level, maxcachesize from win32_cachememory");
if (searcher.TryGet(out var collection2) is false)
using (collection2)
{
foreach (ManagementObject @object2 in collection2.Cast<ManagementObject>())
{
searcher.Query = new ObjectQuery("select * from win32_cachememory");
var properties2 = @object2.GetPropertyHashes();
if (searcher.TryGet(out collection2) is false) throw new InvalidOperationException("WMI Collection NULL");
}
ProcessorCacheLevelEnum? cacheLevel = null;
using (collection2)
{
foreach (ManagementObject @object2 in collection2.Cast<ManagementObject>())
cacheLevel = (ProcessorCacheLevelEnum?)@object2.GetValue<ushort>(properties2, "level");
if (cacheLevel is null) continue;
var installedSize = @object2.GetValue<uint>(properties2, "maxcachesize");
switch (cacheLevel)
{
var properties2 = @object2.GetPropertyHashes();
ProcessorCacheLevelEnum? cacheLevel = null;
cacheLevel = (ProcessorCacheLevelEnum?)@object2.GetValue<ushort>(properties2, "level");
if (cacheLevel is null) continue;
var installedSize = @object2.GetValue<uint>(properties2, "maxcachesize");
switch (cacheLevel)
{
case ProcessorCacheLevelEnum.L1:
{
processor.L1Size = installedSize;
break;
}
case ProcessorCacheLevelEnum.L2:
{
processor.L2Size = installedSize;
break;
}
case ProcessorCacheLevelEnum.L3:
{
processor.L3Size = installedSize;
break;
}
}
case ProcessorCacheLevelEnum.L1:
{
processor.L1Size = installedSize;
break;
}
case ProcessorCacheLevelEnum.L2:
{
processor.L2Size = installedSize;
break;
}
case ProcessorCacheLevelEnum.L3:
{
processor.L3Size = installedSize;
break;
}
}
}
processors.Add(processor);
index++;
}
processors.Add(processor);
index++;
}
return processors;
}
private enum ProcessorCacheLevelEnum
{
L1 = 3,
L2 = 4,
L3 = 5,
}
//private async ValueTask<Processor.Metric?> GetProcessorMetricAsync(CancellationToken cancellationToken)
//{
// var metric = new Processor.Metric();
// if (ProcessorTimeCounter is null)
// {
// ProcessorTimeCounter = new PerformanceCounter
// {
// CategoryName = "Processor",
// CounterName = "% Processor Time",
// InstanceName = "_Total"
// };
// metric.ProcessorUsagePercentage = ProcessorTimeCounter.NextValue();
// await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
// }
// metric.Timestamp = DateTime.Now;
// metric.ProcessorUsagePercentage = ProcessorTimeCounter?.NextValue();
// return metric;
//}
return processors;
}
private enum ProcessorCacheLevelEnum
{
L1 = 3,
L2 = 4,
L3 = 5,
}
//private async ValueTask<Processor.Metric?> GetProcessorMetricAsync(CancellationToken cancellationToken)
//{
// var metric = new Processor.Metric();
// if (ProcessorTimeCounter is null)
// {
// ProcessorTimeCounter = new PerformanceCounter
// {
// CategoryName = "Processor",
// CounterName = "% Processor Time",
// InstanceName = "_Total"
// };
// metric.ProcessorUsagePercentage = ProcessorTimeCounter.NextValue();
// await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
// }
// metric.Timestamp = DateTime.Now;
// metric.ProcessorUsagePercentage = ProcessorTimeCounter?.NextValue();
// return metric;
//}
}

View file

@ -0,0 +1,44 @@
using Insight.Agent.Services;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using Microsoft.Extensions.Logging;
namespace Insight.Agent.Network.Handlers;
public class ProxyHandler : IMessageHandler<AgentSession>
{
private readonly ScriptService _scriptService;
private readonly ILogger<ProxyHandler> _logger;
public ProxyHandler(ScriptService scriptService, ILogger<ProxyHandler> logger)
{
_scriptService = scriptService;
_logger = logger;
}
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
switch (message)
{
case Proxy<Request> proxyRequest:
await OnProxyRequestAsync(sender, proxyRequest, cancellationToken);
break;
}
}
private async ValueTask OnProxyRequestAsync(AgentSession sender, Proxy<Request> proxyRequest, CancellationToken cancellationToken)
{
var result = await _scriptService.QueryAsync(proxyRequest.Message.RequestData);
await sender.SendAsync(new Proxy<Response>()
{
ProxyId = proxyRequest.ProxyId,
Message = new Response(proxyRequest.Message)
{
ResponseData = result.HadErrors ? result.Errors : result.Data,
ResponseError = result.HadErrors
}
}, cancellationToken);
}
}

View file

@ -1,118 +1,122 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Management;
using System.Runtime.Versioning;
using System.ServiceProcess;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class ServiceHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class ServiceHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
var result = new ServiceList();
result.AddRange(GetServices());
await sender.SendAsync(result, cancellationToken);
}
}
private static List<Service> GetServices()
{
var services = new List<Service>();
var serviceControllers = ServiceController.GetServices()?.OrderBy(s => s.DisplayName)?.ToList();
if (serviceControllers is null || serviceControllers.Any() is false) throw new InvalidOperationException("SERVICE Collection NULL");
foreach (var sc in serviceControllers)
{
var status = sc.Status switch
case InventoryRequest:
{
ServiceControllerStatus.Stopped => Service.ServiceStatus.Stopped,
ServiceControllerStatus.StartPending => Service.ServiceStatus.StartPending,
ServiceControllerStatus.StopPending => Service.ServiceStatus.StopPending,
ServiceControllerStatus.Running => Service.ServiceStatus.Running,
ServiceControllerStatus.ContinuePending => Service.ServiceStatus.ContinuePending,
ServiceControllerStatus.PausePending => Service.ServiceStatus.PausePending,
ServiceControllerStatus.Paused => Service.ServiceStatus.Paused,
_ => Service.ServiceStatus.Unknown
};
var result = new Collection<Service>();
result.AddRange(GetServices());
var mode = sc.StartType switch
{
ServiceStartMode.Boot => Service.ServiceMode.Boot,
ServiceStartMode.System => Service.ServiceMode.System,
ServiceStartMode.Automatic => Service.ServiceMode.Automatic,
ServiceStartMode.Manual => Service.ServiceMode.Manual,
ServiceStartMode.Disabled => Service.ServiceMode.Disabled,
_ => Service.ServiceMode.Unknown,
};
var service = new Service
{
Name = sc.ServiceName?.Trim(),
Display = sc.DisplayName?.Trim(),
Status = status,
StartMode = mode
};
services.Add(service);
}
// additional infos
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("SELECT processid, name, description, pathname, startname, delayedautostart from win32_service")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_service");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var services2 = new List<Service>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var service2 = new Service();
var properties = @object.GetPropertyHashes();
service2.Name = @object.GetValue<string>(properties, "name")?.Trim();
service2.ProcessId = @object.GetValue<uint>(properties, "processid");
service2.Description = @object.GetValue<string>(properties, "description")?.Trim();
service2.PathName = @object.GetValue<string>(properties, "pathname")?.Trim();
service2.Account = @object.GetValue<string>(properties, "startname")?.Trim();
service2.Delay = @object.GetValue<bool>(properties, "delayedautostart");
services2.Add(service2);
await sender.SendAsync(result, cancellationToken);
break;
}
}
if (services2.Any() is false) return services;
foreach (var svc in services)
{
var map = services2.Where(p => p.Name == svc.Name).FirstOrDefault();
if (map is null) continue;
svc.ProcessId = map.ProcessId;
svc.Description = map.Description;
svc.PathName = map.PathName;
svc.Account = map.Account;
svc.Delay = map.Delay;
}
return services.OrderBy(x => x.Name).ToList();
}
}
private static List<Service> GetServices()
{
var services = new List<Service>();
var serviceControllers = ServiceController.GetServices()?.OrderBy(s => s.DisplayName)?.ToList();
if (serviceControllers is null || serviceControllers.Any() is false) throw new InvalidOperationException("SERVICE Collection NULL");
foreach (var sc in serviceControllers)
{
var status = sc.Status switch
{
ServiceControllerStatus.Stopped => Service.ServiceStatus.Stopped,
ServiceControllerStatus.StartPending => Service.ServiceStatus.StartPending,
ServiceControllerStatus.StopPending => Service.ServiceStatus.StopPending,
ServiceControllerStatus.Running => Service.ServiceStatus.Running,
ServiceControllerStatus.ContinuePending => Service.ServiceStatus.ContinuePending,
ServiceControllerStatus.PausePending => Service.ServiceStatus.PausePending,
ServiceControllerStatus.Paused => Service.ServiceStatus.Paused,
_ => Service.ServiceStatus.Unknown
};
var mode = sc.StartType switch
{
ServiceStartMode.Boot => Service.ServiceMode.Boot,
ServiceStartMode.System => Service.ServiceMode.System,
ServiceStartMode.Automatic => Service.ServiceMode.Automatic,
ServiceStartMode.Manual => Service.ServiceMode.Manual,
ServiceStartMode.Disabled => Service.ServiceMode.Disabled,
_ => Service.ServiceMode.Unknown,
};
var service = new Service
{
Name = sc.ServiceName?.Trim(),
Display = sc.DisplayName?.Trim(),
Status = status,
StartMode = mode
};
services.Add(service);
}
// additional infos
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("SELECT processid, name, description, pathname, startname, delayedautostart from win32_service")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_service");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var services2 = new List<Service>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var service2 = new Service();
var properties = @object.GetPropertyHashes();
service2.Name = @object.GetValue<string>(properties, "name")?.Trim();
service2.ProcessId = @object.GetValue<uint>(properties, "processid");
service2.Description = @object.GetValue<string>(properties, "description")?.Trim();
service2.PathName = @object.GetValue<string>(properties, "pathname")?.Trim();
service2.Account = @object.GetValue<string>(properties, "startname")?.Trim();
service2.Delay = @object.GetValue<bool>(properties, "delayedautostart");
services2.Add(service2);
}
}
if (services2.Any() is false) return services;
foreach (var svc in services)
{
var map = services2.Where(p => p.Name == svc.Name).FirstOrDefault();
if (map is null) continue;
svc.ProcessId = map.ProcessId;
svc.Description = map.Description;
svc.PathName = map.PathName;
svc.Account = map.Account;
svc.Delay = map.Delay;
}
return services.OrderBy(x => x.Name).ToList();
}
}

View file

@ -1,252 +1,254 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace Insight.Agent.Network.Handlers
{
[SupportedOSPlatform("windows")]
public class SessionHandler : IAgentMessageHandler<AgentSession>
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
{
if (message is GetInventory)
{
var result = new SessionList();
result.AddRange(GetSessions());
namespace Insight.Agent.Network.Handlers;
await sender.SendAsync(result, cancellationToken);
}
[SupportedOSPlatform("windows")]
public class SessionHandler : IMessageHandler<AgentSession>
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
switch (message)
{
case InventoryRequest:
{
var result = new Collection<Session>();
result.AddRange(GetSessions());
await sender.SendAsync(result, cancellationToken);
break;
}
}
}
private static List<Session> GetSessions()
{
var sessions = new List<Session>();
foreach (var s in NativeMethods.GetSessions())
{
sessions.Add(new Session
{
Sid = s.SessionId.ToString(),
User = s.Username,
Type = s.Workstation,
Status = s.State.ToString(),
Remote = s.IPAddress
});
}
private static List<Session> GetSessions()
return sessions;
}
private static partial class NativeMethods
{
//public const int WTS_CURRENT_SESSION = -1;
[DllImport("wtsapi32.dll")]
static extern int WTSEnumerateSessions(
nint pServer,
[MarshalAs(UnmanagedType.U4)] int iReserved,
[MarshalAs(UnmanagedType.U4)] int iVersion,
ref nint pSessionInfo,
[MarshalAs(UnmanagedType.U4)] ref int iCount);
[DllImport("Wtsapi32.dll")]
private static extern bool WTSQuerySessionInformation(
nint pServer,
int iSessionID,
WTS_INFO_CLASS oInfoClass,
out nint pBuffer,
out uint iBytesReturned);
[DllImport("wtsapi32.dll")]
static extern void WTSFreeMemory(
nint pMemory);
[StructLayout(LayoutKind.Sequential)]
private struct WTS_CLIENT_ADDRESS
{
var query = NativeMethods.GetSessions();
public int iAddressFamily;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] bAddress;
}
var sessions = new List<Session>();
[StructLayout(LayoutKind.Sequential)]
private struct WTS_SESSION_INFO
{
public int iSessionID;
[MarshalAs(UnmanagedType.LPStr)]
public string sWinsWorkstationName;
public WTS_CONNECTSTATE_CLASS oState;
}
foreach (var s in NativeMethods.GetSessions())
[StructLayout(LayoutKind.Sequential)]
private struct WTS_CLIENT_DISPLAY
{
public int iHorizontalResolution;
public int iVerticalResolution;
//1 = The display uses 4 bits per pixel for a maximum of 16 colors.
//2 = The display uses 8 bits per pixel for a maximum of 256 colors.
//4 = The display uses 16 bits per pixel for a maximum of 2^16 colors.
//8 = The display uses 3-byte RGB values for a maximum of 2^24 colors.
//16 = The display uses 15 bits per pixel for a maximum of 2^15 colors.
public int iColorDepth;
}
public enum WTS_CONNECTSTATE_CLASS
{
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
}
public enum WTS_INFO_CLASS
{
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType,
WTSIdleTime,
WTSLogonTime,
WTSIncomingBytes,
WTSOutgoingBytes,
WTSIncomingFrames,
WTSOutgoingFrames,
WTSClientInfo,
WTSSessionInfo,
WTSConfigInfo,
WTSValidationInfo,
WTSSessionAddressV4,
WTSIsRemoteSession
}
public class WTSSession
{
public int SessionId { get; set; }
public WTS_CONNECTSTATE_CLASS State { get; set; }
public string? Workstation { get; set; }
public string? IPAddress { get; set; }
public string? Username { get; set; }
public int HorizontalResolution { get; set; }
public int VerticalResolution { get; set; }
public int ColorDepth { get; set; }
public string? ClientApplicationDirectory { get; set; }
}
public static IEnumerable<WTSSession> GetSessions()
{
var sessions = new List<WTSSession>();
var pServer = nint.Zero;
var pSessionInfo = nint.Zero;
try
{
sessions.Add(new Session
var count = 0;
var sessionCount = WTSEnumerateSessions(pServer, 0, 1, ref pSessionInfo, ref count);
var dataSize = (long)Marshal.SizeOf(typeof(WTS_SESSION_INFO));
var current = (long)pSessionInfo;
if (sessionCount <= 0)
return sessions;
for (int i = 0; i < count; i++)
{
Sid = s.SessionId.ToString(),
User = s.Username,
Type = s.Workstation,
Status = s.State.ToString(),
Remote = s.IPAddress
});
if (Marshal.PtrToStructure((nint)current, typeof(WTS_SESSION_INFO)) is not object sessionStructure)
continue;
var sessionInfo = (WTS_SESSION_INFO)sessionStructure;
current += dataSize;
var session = new WTSSession
{
SessionId = sessionInfo.iSessionID,
State = sessionInfo.oState,
Workstation = sessionInfo.sWinsWorkstationName,
};
var returned = (uint)0;
// get terminal user address
var address = nint.Zero;
var clientAddress = new WTS_CLIENT_ADDRESS();
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientAddress, out address, out returned) == true)
{
if (Marshal.PtrToStructure(address, clientAddress.GetType()) is not object addressStructure)
break;
clientAddress = (WTS_CLIENT_ADDRESS)addressStructure;
session.IPAddress = clientAddress.bAddress[2] + "." + clientAddress.bAddress[3] + "." + clientAddress.bAddress[4] + "." + clientAddress.bAddress[5];
}
// get terminal user name
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSUserName, out address, out returned) == true)
{
session.Username = Marshal.PtrToStringAnsi(address);
}
// get terminal user domain name
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSDomainName, out address, out returned) == true)
{
session.Username = Marshal.PtrToStringAnsi(address) + @"\" + session.Username;
}
// get terminal user display informations
var clientDisplay = new WTS_CLIENT_DISPLAY();
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientDisplay, out address, out returned) == true)
{
if (Marshal.PtrToStructure(address, clientDisplay.GetType()) is not object displayStructure)
break;
clientDisplay = (WTS_CLIENT_DISPLAY)displayStructure;
session.HorizontalResolution = clientDisplay.iHorizontalResolution;
session.VerticalResolution = clientDisplay.iVerticalResolution;
session.ColorDepth = clientDisplay.iColorDepth;
}
// get terminal user application directory
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientDirectory, out address, out returned) == true)
{
session.ClientApplicationDirectory = Marshal.PtrToStringAnsi(address);
}
sessions.Add(session);
}
}
catch (Exception)
{
throw;
}
finally
{
WTSFreeMemory(pSessionInfo);
}
return sessions;
}
private static partial class NativeMethods
{
//public const int WTS_CURRENT_SESSION = -1;
[DllImport("wtsapi32.dll")]
static extern int WTSEnumerateSessions(
nint pServer,
[MarshalAs(UnmanagedType.U4)] int iReserved,
[MarshalAs(UnmanagedType.U4)] int iVersion,
ref nint pSessionInfo,
[MarshalAs(UnmanagedType.U4)] ref int iCount);
[DllImport("Wtsapi32.dll")]
private static extern bool WTSQuerySessionInformation(
nint pServer,
int iSessionID,
WTS_INFO_CLASS oInfoClass,
out nint pBuffer,
out uint iBytesReturned);
[DllImport("wtsapi32.dll")]
static extern void WTSFreeMemory(
nint pMemory);
[StructLayout(LayoutKind.Sequential)]
private struct WTS_CLIENT_ADDRESS
{
public int iAddressFamily;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] bAddress;
}
[StructLayout(LayoutKind.Sequential)]
private struct WTS_SESSION_INFO
{
public int iSessionID;
[MarshalAs(UnmanagedType.LPStr)]
public string sWinsWorkstationName;
public WTS_CONNECTSTATE_CLASS oState;
}
[StructLayout(LayoutKind.Sequential)]
private struct WTS_CLIENT_DISPLAY
{
public int iHorizontalResolution;
public int iVerticalResolution;
//1 = The display uses 4 bits per pixel for a maximum of 16 colors.
//2 = The display uses 8 bits per pixel for a maximum of 256 colors.
//4 = The display uses 16 bits per pixel for a maximum of 2^16 colors.
//8 = The display uses 3-byte RGB values for a maximum of 2^24 colors.
//16 = The display uses 15 bits per pixel for a maximum of 2^15 colors.
public int iColorDepth;
}
public enum WTS_CONNECTSTATE_CLASS
{
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
}
public enum WTS_INFO_CLASS
{
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType,
WTSIdleTime,
WTSLogonTime,
WTSIncomingBytes,
WTSOutgoingBytes,
WTSIncomingFrames,
WTSOutgoingFrames,
WTSClientInfo,
WTSSessionInfo,
WTSConfigInfo,
WTSValidationInfo,
WTSSessionAddressV4,
WTSIsRemoteSession
}
public class WTSSession
{
public int SessionId { get; set; }
public WTS_CONNECTSTATE_CLASS State { get; set; }
public string? Workstation { get; set; }
public string? IPAddress { get; set; }
public string? Username { get; set; }
public int HorizontalResolution { get; set; }
public int VerticalResolution { get; set; }
public int ColorDepth { get; set; }
public string? ClientApplicationDirectory { get; set; }
}
public static IEnumerable<WTSSession> GetSessions()
{
var sessions = new List<WTSSession>();
var pServer = nint.Zero;
var pSessionInfo = nint.Zero;
try
{
var count = 0;
var sessionCount = WTSEnumerateSessions(pServer, 0, 1, ref pSessionInfo, ref count);
var dataSize = (long)Marshal.SizeOf(typeof(WTS_SESSION_INFO));
var current = (long)pSessionInfo;
if (sessionCount <= 0)
return sessions;
for (int i = 0; i < count; i++)
{
if (Marshal.PtrToStructure((nint)current, typeof(WTS_SESSION_INFO)) is not object sessionStructure)
continue;
var sessionInfo = (WTS_SESSION_INFO)sessionStructure;
current += dataSize;
var session = new WTSSession
{
SessionId = sessionInfo.iSessionID,
State = sessionInfo.oState,
Workstation = sessionInfo.sWinsWorkstationName,
};
var returned = (uint)0;
// get terminal user address
var address = nint.Zero;
var clientAddress = new WTS_CLIENT_ADDRESS();
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientAddress, out address, out returned) == true)
{
if (Marshal.PtrToStructure(address, clientAddress.GetType()) is not object addressStructure)
break;
clientAddress = (WTS_CLIENT_ADDRESS)addressStructure;
session.IPAddress = clientAddress.bAddress[2] + "." + clientAddress.bAddress[3] + "." + clientAddress.bAddress[4] + "." + clientAddress.bAddress[5];
}
// get terminal user name
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSUserName, out address, out returned) == true)
{
session.Username = Marshal.PtrToStringAnsi(address);
}
// get terminal user domain name
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSDomainName, out address, out returned) == true)
{
session.Username = Marshal.PtrToStringAnsi(address) + @"\" + session.Username;
}
// get terminal user display informations
var clientDisplay = new WTS_CLIENT_DISPLAY();
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientDisplay, out address, out returned) == true)
{
if (Marshal.PtrToStructure(address, clientDisplay.GetType()) is not object displayStructure)
break;
clientDisplay = (WTS_CLIENT_DISPLAY)displayStructure;
session.HorizontalResolution = clientDisplay.iHorizontalResolution;
session.VerticalResolution = clientDisplay.iVerticalResolution;
session.ColorDepth = clientDisplay.iColorDepth;
}
// get terminal user application directory
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientDirectory, out address, out returned) == true)
{
session.ClientApplicationDirectory = Marshal.PtrToStringAnsi(address);
}
sessions.Add(session);
}
}
catch (Exception)
{
throw;
}
finally
{
WTSFreeMemory(pSessionInfo);
}
return sessions;
}
}
}
}

View file

@ -1,119 +1,123 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using Microsoft.Win32;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.AccessControl;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
internal class SoftwareHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
internal class SoftwareHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
var x64 = Task.Run(() => ApplicationRegistryQuery(RegistryView.Registry64), cancellationToken);
var x86 = Task.Run(() => ApplicationRegistryQuery(RegistryView.Registry32), cancellationToken);
await Task.WhenAll(x64, x86).ConfigureAwait(false);
var result = new ApplicationList();
result.AddRange(x64.Result);
result.AddRange(x86.Result.Where(p => result.All(app => p.Name != app.Name && p.Version != app.Version)));
await sender.SendAsync(result, cancellationToken);
}
}
private static IEnumerable<Application> ApplicationRegistryQuery(RegistryView registryView)
{
using var registry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView);
using var key = registry.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\", RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey);
if (key is null) throw new NullReferenceException(nameof(key));
var apps = new List<Application>();
var architecture = registryView switch
{
RegistryView.Registry32 => Architecture.X86,
_ => Architecture.X64
};
foreach (string name in key.GetSubKeyNames())
{
using var query = key.OpenSubKey(name);
if (query is null) continue;
var app = new Application
case InventoryRequest:
{
Architecture = architecture
};
var x64 = Task.Run(() => ApplicationRegistryQuery(RegistryView.Registry64), cancellationToken);
var x86 = Task.Run(() => ApplicationRegistryQuery(RegistryView.Registry32), cancellationToken);
if (query.GetValue("DisplayName")?.ToString()?.Trim() is string displayName && string.IsNullOrWhiteSpace(displayName) is false)
{
app.Name = displayName;
await Task.WhenAll(x64, x86).ConfigureAwait(false);
var result = new Collection<Application>();
result.AddRange(x64.Result);
result.AddRange(x86.Result.Where(p => result.All(app => p.Name != app.Name && p.Version != app.Version)));
await sender.SendAsync(result, cancellationToken);
break;
}
if (query.GetValue("Publisher")?.ToString()?.Trim() is string publisher && string.IsNullOrWhiteSpace(publisher) is false)
{
app.Publisher = publisher;
}
if (query.GetValue("DisplayVersion")?.ToString()?.Trim() is string version && string.IsNullOrWhiteSpace(version) is false)
{
app.Version = version;
}
if (query.GetValue("InstallLocation")?.ToString()?.Trim() is string location && string.IsNullOrWhiteSpace(location) is false)
{
app.Location = location;
}
if (query.GetValue("InstallSource")?.ToString()?.Trim() is string source && string.IsNullOrWhiteSpace(source) is false)
{
app.Source = source;
}
if (query.GetValue("UninstallString")?.ToString()?.Trim() is string uninstall && string.IsNullOrWhiteSpace(uninstall) is false)
{
app.Uninstall = uninstall;
}
if (app.Uninstall is null)
{
if (query.GetValue("UninstallString_Hidden")?.ToString()?.Trim() is string uninstall2 && string.IsNullOrWhiteSpace(uninstall2) is false)
{
app.Uninstall = uninstall2;
}
}
if (query.GetValue("InstallDate")?.ToString()?.Trim() is string installDate)
{
if (DateTime.TryParseExact(installDate, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime valid))
{
app.InstallDate = valid;
}
if (app.InstallDate is null)
{
if (DateTime.TryParseExact(installDate, "dd.MM.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime valid2))
{
app.InstallDate = valid2;
}
}
}
if (app.Name is not null)
{
apps.Add(app);
}
}
return apps;
}
}
private static IEnumerable<Application> ApplicationRegistryQuery(RegistryView registryView)
{
using var registry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView);
using var key = registry.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\", RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey);
if (key is null) throw new NullReferenceException(nameof(key));
var apps = new List<Application>();
var architecture = registryView switch
{
RegistryView.Registry32 => Architecture.X86,
_ => Architecture.X64
};
foreach (string name in key.GetSubKeyNames())
{
using var query = key.OpenSubKey(name);
if (query is null) continue;
var app = new Application
{
Architecture = architecture
};
if (query.GetValue("DisplayName")?.ToString()?.Trim() is string displayName && string.IsNullOrWhiteSpace(displayName) is false)
{
app.Name = displayName;
}
if (query.GetValue("Publisher")?.ToString()?.Trim() is string publisher && string.IsNullOrWhiteSpace(publisher) is false)
{
app.Publisher = publisher;
}
if (query.GetValue("DisplayVersion")?.ToString()?.Trim() is string version && string.IsNullOrWhiteSpace(version) is false)
{
app.Version = version;
}
if (query.GetValue("InstallLocation")?.ToString()?.Trim() is string location && string.IsNullOrWhiteSpace(location) is false)
{
app.Location = location;
}
if (query.GetValue("InstallSource")?.ToString()?.Trim() is string source && string.IsNullOrWhiteSpace(source) is false)
{
app.Source = source;
}
if (query.GetValue("UninstallString")?.ToString()?.Trim() is string uninstall && string.IsNullOrWhiteSpace(uninstall) is false)
{
app.Uninstall = uninstall;
}
if (app.Uninstall is null)
{
if (query.GetValue("UninstallString_Hidden")?.ToString()?.Trim() is string uninstall2 && string.IsNullOrWhiteSpace(uninstall2) is false)
{
app.Uninstall = uninstall2;
}
}
if (query.GetValue("InstallDate")?.ToString()?.Trim() is string installDate)
{
if (DateTime.TryParseExact(installDate, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime valid))
{
app.InstallDate = valid;
}
if (app.InstallDate is null)
{
if (DateTime.TryParseExact(installDate, "dd.MM.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime valid2))
{
app.InstallDate = valid2;
}
}
}
if (app.Name is not null)
{
apps.Add(app);
}
}
return apps;
}
}

View file

@ -1,308 +1,312 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Management;
using System.Runtime.Versioning;
using static Insight.Agent.Messages.PhysicalDisk;
using static Insight.Agent.Messages.StoragePool;
using static Insight.Agent.Messages.VirtualDisk;
using static Insight.Domain.Network.Agent.Messages.PhysicalDisk;
using static Insight.Domain.Network.Agent.Messages.StoragePool;
using static Insight.Domain.Network.Agent.Messages.VirtualDisk;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class StoragePoolHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class StoragePoolHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
var result = new StoragePoolList();
result.AddRange(GetStoragePool());
await sender.SendAsync(result, cancellationToken);
}
}
private static List<StoragePool> GetStoragePool()
{
if (Environment.OSVersion.Version.Major < 6 || Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor < 2)
{
throw new PlatformNotSupportedException();
}
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname, resiliencysettingnamedefault, isprimordial, isreadonly, isclustered, size, allocatedsize, logicalsectorsize, operationalstatus, healthstatus from msft_storagepool")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from msft_storagepool");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var pools = new List<StoragePool>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
case InventoryRequest:
{
var pool = new StoragePool();
var result = new Collection<StoragePool>();
result.AddRange(GetStoragePool());
var properties = @object.GetPropertyHashes();
pool.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
pool.Name = @object.GetValue<string>(properties, "name")?.Trim();
pool.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
{
pool.States = operationals.Select(p => (StoragePool.OperationalState)p).ToList();
}
pool.Health = (StoragePool.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
pool.RetireMissingPhysicalDisks = (RetireMissingPhysicalDisksEnum)@object.GetValue<ushort>(properties, "retiremissingphysicaldisks");
pool.Resiliency = @object.GetValue<string>(properties, "resiliencysettingnamedefault")?.Trim();
pool.IsPrimordial = @object.GetValue<bool>(properties, "isprimordial");
pool.IsReadOnly = @object.GetValue<bool>(properties, "isreadonly");
pool.IsClustered = @object.GetValue<bool>(properties, "isclustered");
pool.Size = @object.GetValue<ulong>(properties, "size");
pool.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
pool.SectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
if (@object.GetValue<string>(properties, "objectid") is string objectId)
{
pool.PhysicalDisks = QueryPhysicalDisksByStoragePool(objectId);
pool.VirtualDisks = QueryVirtualDisksByStoragePool(objectId);
}
pools.Add(pool);
await sender.SendAsync(result, cancellationToken);
break;
}
}
return pools;
}
private static List<PhysicalDisk> GetPhysicalDisks()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname from msft_physicaldisk")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from msft_physicaldisk");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var disks = new List<PhysicalDisk>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var disk = new PhysicalDisk();
var properties = @object.GetPropertyHashes();
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
disk.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
disk.Model = @object.GetValue<string>(properties, "model")?.Trim();
disk.MediaType = @object.GetValue<ushort>(properties, "mediatype");
disk.BusType = @object.GetValue<ushort>(properties, "bustype");
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
{
disk.States = operationals.Select(p => (PhysicalDisk.OperationalState)p).ToList();
}
disk.Health = (PhysicalDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
if (@object.TryGetValue<ushort[]>(properties, "supportedusages", out var supportedusages) && supportedusages is not null)
{
disk.SupportedUsages = supportedusages.Select(p => (SupportedUsagesEnum)p).ToList();
}
disk.Usage = @object.GetValue<ushort>(properties, "usage");
disk.PhysicalLocation = @object.GetValue<string>(properties, "physicallocation")?.Trim();
disk.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
disk.FirmwareVersion = @object.GetValue<string>(properties, "firmwareversion")?.Trim();
disk.Size = @object.GetValue<ulong>(properties, "size");
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
disk.LogicalSectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
disk.PhysicalSectorSize = @object.GetValue<ulong>(properties, "physicalsectorsize");
disk.VirtualDiskFootprint = @object.GetValue<ulong>(properties, "virtualdiskfootprint");
disks.Add(disk);
}
}
return disks;
}
private static List<VirtualDisk> GetVirtualDisks()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname, access, provisioningtype, physicaldiskredundancy, resiliencysettingname, isdeduplicationenabled, issnapshot, operationalstatus, healthstatus, size, allocatedsize, footprintonpool, readcachesize, writecachesize from msft_virtualdisk")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from msft_virtualdisk");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var disks = new List<VirtualDisk>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var disk = new VirtualDisk();
var properties = @object.GetPropertyHashes();
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
disk.Name = @object.GetValue<string>(properties, "name")?.Trim();
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
disk.AccessType = (AccessTypeEnum)@object.GetValue<ushort>(properties, "access");
disk.ProvisioningType = (ProvisioningTypeEnum)@object.GetValue<ushort>(properties, "provisioningtype");
disk.PhysicalDiskRedundancy = @object.GetValue<ushort>(properties, "physicaldiskredundancy");
disk.ResiliencySettingName = @object.GetValue<string>(properties, "resiliencysettingname")?.Trim();
disk.Deduplication = @object.GetValue<bool>(properties, "isdeduplicationenabled");
disk.IsSnapshot = @object.GetValue<bool>(properties, "issnapshot");
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
{
disk.States = operationals.Select(p => (VirtualDisk.OperationalState)p).ToList();
}
disk.Health = (VirtualDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
disk.Size = @object.GetValue<ulong>(properties, "size");
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
disk.FootprintOnPool = @object.GetValue<ulong>(properties, "footprintonpool");
disk.ReadCacheSize = @object.GetValue<ulong>(properties, "readcachesize");
disk.WriteCacheSize = @object.GetValue<ulong>(properties, "writecachesize");
disks.Add(disk);
}
}
return disks;
}
private static List<PhysicalDisk> QueryPhysicalDisksByStoragePool(string storagePoolObjectId)
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
Query = new ObjectQuery("ASSOCIATORS OF {MSFT_StoragePool.ObjectId=\"" + Helpers.EscapeWql(storagePoolObjectId) + "\"} WHERE AssocClass = MSFT_StoragePoolToPhysicalDisk")
};
if (searcher.TryGet(out var collection) is false) throw new InvalidOperationException("WMI Collection NULL");
var disks = new List<PhysicalDisk>();
using (collection)
{
foreach (ManagementObject @object in collection)
{
var disk = new PhysicalDisk();
var properties = @object.GetPropertyHashes();
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
disk.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
disk.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
disk.Model = @object.GetValue<string>(properties, "model")?.Trim();
disk.MediaType = @object.GetValue<ushort>(properties, "mediatype");
disk.BusType = @object.GetValue<ushort>(properties, "bustype");
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
{
disk.States = operationals.Select(p => (PhysicalDisk.OperationalState)p).ToList();
}
disk.Health = (PhysicalDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
if (@object.TryGetValue<ushort[]>(properties, "supportedusages", out var supportedusages) && supportedusages is not null)
{
disk.SupportedUsages = supportedusages.Select(p => (SupportedUsagesEnum)p).ToList();
}
disk.Usage = @object.GetValue<ushort>(properties, "usage");
disk.PhysicalLocation = @object.GetValue<string>(properties, "physicallocation")?.Trim();
disk.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
disk.FirmwareVersion = @object.GetValue<string>(properties, "firmwareversion")?.Trim();
disk.Size = @object.GetValue<ulong>(properties, "size");
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
disk.LogicalSectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
disk.PhysicalSectorSize = @object.GetValue<ulong>(properties, "physicalsectorsize");
disk.VirtualDiskFootprint = @object.GetValue<ulong>(properties, "virtualdiskfootprint");
disks.Add(disk);
}
}
return disks;
}
private static List<VirtualDisk> QueryVirtualDisksByStoragePool(string storagePoolObjectId)
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
Query = new ObjectQuery("ASSOCIATORS OF {MSFT_StoragePool.ObjectId=\"" + Helpers.EscapeWql(storagePoolObjectId) + "\"} WHERE AssocClass = MSFT_StoragePoolToVirtualDisk")
};
if (searcher.TryGet(out var collection) is false) throw new InvalidOperationException("WMI Collection NULL");
var disks = new List<VirtualDisk>();
using (collection)
{
foreach (ManagementObject @object in collection)
{
var disk = new VirtualDisk();
var properties = @object.GetPropertyHashes();
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
disk.Name = @object.GetValue<string>(properties, "name")?.Trim();
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
disk.AccessType = (AccessTypeEnum)@object.GetValue<ushort>(properties, "access");
disk.ProvisioningType = (ProvisioningTypeEnum)@object.GetValue<ushort>(properties, "provisioningtype");
disk.PhysicalDiskRedundancy = @object.GetValue<ushort>(properties, "physicaldiskredundancy");
disk.ResiliencySettingName = @object.GetValue<string>(properties, "resiliencysettingname")?.Trim();
disk.Deduplication = @object.GetValue<bool>(properties, "isdeduplicationenabled");
disk.IsSnapshot = @object.GetValue<bool>(properties, "issnapshot");
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
{
disk.States = operationals.Select(p => (VirtualDisk.OperationalState)p).ToList();
}
disk.Health = (VirtualDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
disk.Size = @object.GetValue<ulong>(properties, "size");
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
disk.FootprintOnPool = @object.GetValue<ulong>(properties, "footprintonpool");
disk.ReadCacheSize = @object.GetValue<ulong>(properties, "readcachesize");
disk.WriteCacheSize = @object.GetValue<ulong>(properties, "writecachesize");
disks.Add(disk);
}
}
return disks;
}
}
private static List<StoragePool> GetStoragePool()
{
if (Environment.OSVersion.Version.Major < 6 || Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor < 2)
{
throw new PlatformNotSupportedException();
}
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname, resiliencysettingnamedefault, isprimordial, isreadonly, isclustered, size, allocatedsize, logicalsectorsize, operationalstatus, healthstatus from msft_storagepool")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from msft_storagepool");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var pools = new List<StoragePool>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var pool = new StoragePool();
var properties = @object.GetPropertyHashes();
pool.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
pool.Name = @object.GetValue<string>(properties, "name")?.Trim();
pool.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
{
pool.States = operationals.Select(p => (StoragePool.OperationalState)p).ToList();
}
pool.Health = (StoragePool.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
pool.RetireMissingPhysicalDisks = (RetireMissingPhysicalDisksEnum)@object.GetValue<ushort>(properties, "retiremissingphysicaldisks");
pool.Resiliency = @object.GetValue<string>(properties, "resiliencysettingnamedefault")?.Trim();
pool.IsPrimordial = @object.GetValue<bool>(properties, "isprimordial");
pool.IsReadOnly = @object.GetValue<bool>(properties, "isreadonly");
pool.IsClustered = @object.GetValue<bool>(properties, "isclustered");
pool.Size = @object.GetValue<ulong>(properties, "size");
pool.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
pool.SectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
if (@object.GetValue<string>(properties, "objectid") is string objectId)
{
pool.PhysicalDisks = QueryPhysicalDisksByStoragePool(objectId);
pool.VirtualDisks = QueryVirtualDisksByStoragePool(objectId);
}
pools.Add(pool);
}
}
return pools;
}
private static List<PhysicalDisk> GetPhysicalDisks()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname from msft_physicaldisk")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from msft_physicaldisk");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var disks = new List<PhysicalDisk>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var disk = new PhysicalDisk();
var properties = @object.GetPropertyHashes();
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
disk.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
disk.Model = @object.GetValue<string>(properties, "model")?.Trim();
disk.MediaType = @object.GetValue<ushort>(properties, "mediatype");
disk.BusType = @object.GetValue<ushort>(properties, "bustype");
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
{
disk.States = operationals.Select(p => (PhysicalDisk.OperationalState)p).ToList();
}
disk.Health = (PhysicalDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
if (@object.TryGetValue<ushort[]>(properties, "supportedusages", out var supportedusages) && supportedusages is not null)
{
disk.SupportedUsages = supportedusages.Select(p => (SupportedUsagesEnum)p).ToList();
}
disk.Usage = @object.GetValue<ushort>(properties, "usage");
disk.PhysicalLocation = @object.GetValue<string>(properties, "physicallocation")?.Trim();
disk.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
disk.FirmwareVersion = @object.GetValue<string>(properties, "firmwareversion")?.Trim();
disk.Size = @object.GetValue<ulong>(properties, "size");
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
disk.LogicalSectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
disk.PhysicalSectorSize = @object.GetValue<ulong>(properties, "physicalsectorsize");
disk.VirtualDiskFootprint = @object.GetValue<ulong>(properties, "virtualdiskfootprint");
disks.Add(disk);
}
}
return disks;
}
private static List<VirtualDisk> GetVirtualDisks()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname, access, provisioningtype, physicaldiskredundancy, resiliencysettingname, isdeduplicationenabled, issnapshot, operationalstatus, healthstatus, size, allocatedsize, footprintonpool, readcachesize, writecachesize from msft_virtualdisk")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from msft_virtualdisk");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var disks = new List<VirtualDisk>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var disk = new VirtualDisk();
var properties = @object.GetPropertyHashes();
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
disk.Name = @object.GetValue<string>(properties, "name")?.Trim();
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
disk.AccessType = (AccessTypeEnum)@object.GetValue<ushort>(properties, "access");
disk.ProvisioningType = (ProvisioningTypeEnum)@object.GetValue<ushort>(properties, "provisioningtype");
disk.PhysicalDiskRedundancy = @object.GetValue<ushort>(properties, "physicaldiskredundancy");
disk.ResiliencySettingName = @object.GetValue<string>(properties, "resiliencysettingname")?.Trim();
disk.Deduplication = @object.GetValue<bool>(properties, "isdeduplicationenabled");
disk.IsSnapshot = @object.GetValue<bool>(properties, "issnapshot");
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
{
disk.States = operationals.Select(p => (VirtualDisk.OperationalState)p).ToList();
}
disk.Health = (VirtualDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
disk.Size = @object.GetValue<ulong>(properties, "size");
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
disk.FootprintOnPool = @object.GetValue<ulong>(properties, "footprintonpool");
disk.ReadCacheSize = @object.GetValue<ulong>(properties, "readcachesize");
disk.WriteCacheSize = @object.GetValue<ulong>(properties, "writecachesize");
disks.Add(disk);
}
}
return disks;
}
private static List<PhysicalDisk> QueryPhysicalDisksByStoragePool(string storagePoolObjectId)
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
Query = new ObjectQuery("ASSOCIATORS OF {MSFT_StoragePool.ObjectId=\"" + Helpers.EscapeWql(storagePoolObjectId) + "\"} WHERE AssocClass = MSFT_StoragePoolToPhysicalDisk")
};
if (searcher.TryGet(out var collection) is false) throw new InvalidOperationException("WMI Collection NULL");
var disks = new List<PhysicalDisk>();
using (collection)
{
foreach (ManagementObject @object in collection)
{
var disk = new PhysicalDisk();
var properties = @object.GetPropertyHashes();
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
disk.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
disk.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
disk.Model = @object.GetValue<string>(properties, "model")?.Trim();
disk.MediaType = @object.GetValue<ushort>(properties, "mediatype");
disk.BusType = @object.GetValue<ushort>(properties, "bustype");
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
{
disk.States = operationals.Select(p => (PhysicalDisk.OperationalState)p).ToList();
}
disk.Health = (PhysicalDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
if (@object.TryGetValue<ushort[]>(properties, "supportedusages", out var supportedusages) && supportedusages is not null)
{
disk.SupportedUsages = supportedusages.Select(p => (SupportedUsagesEnum)p).ToList();
}
disk.Usage = @object.GetValue<ushort>(properties, "usage");
disk.PhysicalLocation = @object.GetValue<string>(properties, "physicallocation")?.Trim();
disk.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
disk.FirmwareVersion = @object.GetValue<string>(properties, "firmwareversion")?.Trim();
disk.Size = @object.GetValue<ulong>(properties, "size");
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
disk.LogicalSectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
disk.PhysicalSectorSize = @object.GetValue<ulong>(properties, "physicalsectorsize");
disk.VirtualDiskFootprint = @object.GetValue<ulong>(properties, "virtualdiskfootprint");
disks.Add(disk);
}
}
return disks;
}
private static List<VirtualDisk> QueryVirtualDisksByStoragePool(string storagePoolObjectId)
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
Query = new ObjectQuery("ASSOCIATORS OF {MSFT_StoragePool.ObjectId=\"" + Helpers.EscapeWql(storagePoolObjectId) + "\"} WHERE AssocClass = MSFT_StoragePoolToVirtualDisk")
};
if (searcher.TryGet(out var collection) is false) throw new InvalidOperationException("WMI Collection NULL");
var disks = new List<VirtualDisk>();
using (collection)
{
foreach (ManagementObject @object in collection)
{
var disk = new VirtualDisk();
var properties = @object.GetPropertyHashes();
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
disk.Name = @object.GetValue<string>(properties, "name")?.Trim();
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
disk.AccessType = (AccessTypeEnum)@object.GetValue<ushort>(properties, "access");
disk.ProvisioningType = (ProvisioningTypeEnum)@object.GetValue<ushort>(properties, "provisioningtype");
disk.PhysicalDiskRedundancy = @object.GetValue<ushort>(properties, "physicaldiskredundancy");
disk.ResiliencySettingName = @object.GetValue<string>(properties, "resiliencysettingname")?.Trim();
disk.Deduplication = @object.GetValue<bool>(properties, "isdeduplicationenabled");
disk.IsSnapshot = @object.GetValue<bool>(properties, "issnapshot");
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
{
disk.States = operationals.Select(p => (VirtualDisk.OperationalState)p).ToList();
}
disk.Health = (VirtualDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
disk.Size = @object.GetValue<ulong>(properties, "size");
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
disk.FootprintOnPool = @object.GetValue<ulong>(properties, "footprintonpool");
disk.ReadCacheSize = @object.GetValue<ulong>(properties, "readcachesize");
disk.WriteCacheSize = @object.GetValue<ulong>(properties, "writecachesize");
disks.Add(disk);
}
}
return disks;
}
}

View file

@ -1,175 +1,177 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using Microsoft.Win32;
using System.Collections;
using System.Management;
using System.Runtime.Versioning;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class SystemInfoHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class SystemInfoHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
case InventoryRequest:
await sender.SendAsync(GetSystem(), cancellationToken);
}
}
private static SystemInfo GetSystem()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select lastbootuptime, localdatetime, numberofprocesses from win32_operatingsystem")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_operatingsystem");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var system = new SystemInfo();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var properties = @object.GetPropertyHashes();
if (@object.TryGetValue<object>(properties, "lastbootuptime", out var lastbootuptime))
{
system.LastBootUpTime = ManagementDateTimeConverter.ToDateTime(lastbootuptime?.ToString());
}
if (@object.TryGetValue<object>(properties, "localdatetime", out var localdatetime))
{
system.LocalDateTime = ManagementDateTimeConverter.ToDateTime(localdatetime?.ToString());
}
system.Processes = @object.GetValue<uint>(properties, "numberofprocesses");
break;
}
}
system.License = GetWindowsProductKeyFromRegistry();
return system;
}
private static string GetWindowsProductKeyFromRegistry()
{
var localKey =
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem
? RegistryView.Registry64
: RegistryView.Registry32);
var registryKeyValue = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion")?.GetValue("DigitalProductId");
if (registryKeyValue == null)
return "Failed to get DigitalProductId from registry";
var digitalProductId = (byte[])registryKeyValue;
localKey.Close();
var isWin8OrUp =
Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 2
||
Environment.OSVersion.Version.Major > 6;
return GetWindowsProductKeyFromDigitalProductId(digitalProductId,
isWin8OrUp ? DigitalProductIdVersion.Windows8AndUp : DigitalProductIdVersion.UpToWindows7);
}
private static string GetWindowsProductKeyFromDigitalProductId(byte[] digitalProductId, DigitalProductIdVersion digitalProductIdVersion)
{
var productKey = digitalProductIdVersion == DigitalProductIdVersion.Windows8AndUp
? DecodeProductKeyWin8AndUp(digitalProductId)
: DecodeProductKey(digitalProductId);
return productKey;
}
private static string DecodeProductKey(byte[] digitalProductId)
{
const int keyStartIndex = 52;
const int keyEndIndex = keyStartIndex + 15;
var digits = new[]
{
'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R',
'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9',
};
const int decodeLength = 29;
const int decodeStringLength = 15;
var decodedChars = new char[decodeLength];
var hexPid = new ArrayList();
for (var i = keyStartIndex; i <= keyEndIndex; i++)
{
hexPid.Add(digitalProductId[i]);
}
for (var i = decodeLength - 1; i >= 0; i--)
{
// Every sixth char is a separator.
if ((i + 1) % 6 == 0)
{
decodedChars[i] = '-';
}
else
{
// Do the actual decoding.
var digitMapIndex = 0;
for (var j = decodeStringLength - 1; j >= 0; j--)
{
var byteValue = digitMapIndex << 8 | (byte)hexPid[j];
hexPid[j] = (byte)(byteValue / 24);
digitMapIndex = byteValue % 24;
decodedChars[i] = digits[digitMapIndex];
}
}
}
return new string(decodedChars);
}
private static string DecodeProductKeyWin8AndUp(byte[] digitalProductId)
{
var key = string.Empty;
const int keyOffset = 52;
var isWin8 = (byte)(digitalProductId[66] / 6 & 1);
digitalProductId[66] = (byte)(digitalProductId[66] & 0xf7 | (isWin8 & 2) * 4);
const string digits = "BCDFGHJKMPQRTVWXY2346789";
var last = 0;
for (var i = 24; i >= 0; i--)
{
var current = 0;
for (var j = 14; j >= 0; j--)
{
current = current * 256;
current = digitalProductId[j + keyOffset] + current;
digitalProductId[j + keyOffset] = (byte)(current / 24);
current = current % 24;
last = current;
}
key = digits[current] + key;
}
var keypart1 = key.Substring(1, last);
var keypart2 = key.Substring(last + 1, key.Length - (last + 1));
key = keypart1 + "N" + keypart2;
for (var i = 5; i < key.Length; i += 6)
{
key = key.Insert(i, "-");
}
return key;
}
private enum DigitalProductIdVersion
{
UpToWindows7,
Windows8AndUp
break;
}
}
private static SystemInfo GetSystem()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select lastbootuptime, localdatetime, numberofprocesses from win32_operatingsystem")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_operatingsystem");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var system = new SystemInfo();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var properties = @object.GetPropertyHashes();
if (@object.TryGetValue<object>(properties, "lastbootuptime", out var lastbootuptime))
{
system.LastBootUpTime = ManagementDateTimeConverter.ToDateTime(lastbootuptime?.ToString());
}
if (@object.TryGetValue<object>(properties, "localdatetime", out var localdatetime))
{
system.LocalDateTime = ManagementDateTimeConverter.ToDateTime(localdatetime?.ToString());
}
system.Processes = @object.GetValue<uint>(properties, "numberofprocesses");
break;
}
}
system.License = GetWindowsProductKeyFromRegistry();
return system;
}
private static string GetWindowsProductKeyFromRegistry()
{
var localKey =
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem
? RegistryView.Registry64
: RegistryView.Registry32);
var registryKeyValue = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion")?.GetValue("DigitalProductId");
if (registryKeyValue == null)
return "Failed to get DigitalProductId from registry";
var digitalProductId = (byte[])registryKeyValue;
localKey.Close();
var isWin8OrUp =
Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 2
||
Environment.OSVersion.Version.Major > 6;
return GetWindowsProductKeyFromDigitalProductId(digitalProductId,
isWin8OrUp ? DigitalProductIdVersion.Windows8AndUp : DigitalProductIdVersion.UpToWindows7);
}
private static string GetWindowsProductKeyFromDigitalProductId(byte[] digitalProductId, DigitalProductIdVersion digitalProductIdVersion)
{
var productKey = digitalProductIdVersion == DigitalProductIdVersion.Windows8AndUp
? DecodeProductKeyWin8AndUp(digitalProductId)
: DecodeProductKey(digitalProductId);
return productKey;
}
private static string DecodeProductKey(byte[] digitalProductId)
{
const int keyStartIndex = 52;
const int keyEndIndex = keyStartIndex + 15;
var digits = new[]
{
'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R',
'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9',
};
const int decodeLength = 29;
const int decodeStringLength = 15;
var decodedChars = new char[decodeLength];
var hexPid = new ArrayList();
for (var i = keyStartIndex; i <= keyEndIndex; i++)
{
hexPid.Add(digitalProductId[i]);
}
for (var i = decodeLength - 1; i >= 0; i--)
{
// Every sixth char is a separator.
if ((i + 1) % 6 == 0)
{
decodedChars[i] = '-';
}
else
{
// Do the actual decoding.
var digitMapIndex = 0;
for (var j = decodeStringLength - 1; j >= 0; j--)
{
var byteValue = digitMapIndex << 8 | (byte)hexPid[j];
hexPid[j] = (byte)(byteValue / 24);
digitMapIndex = byteValue % 24;
decodedChars[i] = digits[digitMapIndex];
}
}
}
return new string(decodedChars);
}
private static string DecodeProductKeyWin8AndUp(byte[] digitalProductId)
{
var key = string.Empty;
const int keyOffset = 52;
var isWin8 = (byte)(digitalProductId[66] / 6 & 1);
digitalProductId[66] = (byte)(digitalProductId[66] & 0xf7 | (isWin8 & 2) * 4);
const string digits = "BCDFGHJKMPQRTVWXY2346789";
var last = 0;
for (var i = 24; i >= 0; i--)
{
var current = 0;
for (var j = 14; j >= 0; j--)
{
current = current * 256;
current = digitalProductId[j + keyOffset] + current;
digitalProductId[j + keyOffset] = (byte)(current / 24);
current = current % 24;
last = current;
}
key = digits[current] + key;
}
var keypart1 = key.Substring(1, last);
var keypart2 = key.Substring(last + 1, key.Length - (last + 1));
key = keypart1 + "N" + keypart2;
for (var i = 5; i < key.Length; i += 6)
{
key = key.Insert(i, "-");
}
return key;
}
private enum DigitalProductIdVersion
{
UpToWindows7,
Windows8AndUp
}
}

View file

@ -1,130 +1,128 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using WUApiLib;
using static Insight.Agent.Messages.Update;
using static Insight.Domain.Network.Agent.Messages.Update;
using UpdateCollection = Insight.Domain.Network.Agent.Messages.UpdateCollection;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class UpdateHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class UpdateHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
await sender.SendAsync(GetUpdates(), cancellationToken);
}
}
private static UpdateList GetUpdates()
{
return new UpdateList
{
Installed = QueryInstalledUpdates(),
Pending = QueryPendingUpdates()
};
}
private static List<Update> QueryInstalledUpdates()
{
var updates = new List<Update>();
var session = new UpdateSessionClass();
var searcher = session.CreateUpdateSearcher();
searcher.Online = false;
var count = searcher.GetTotalHistoryCount();
var result = searcher.QueryHistory(0, count);
foreach (IUpdateHistoryEntry wupdate in result)
{
var update = new Update
case InventoryRequest:
await sender.SendAsync(new UpdateCollection
{
Id = wupdate.UpdateIdentity.UpdateID,
Date = wupdate.Date,
Name = wupdate.Title,
Description = wupdate.Description,
Result = wupdate.ResultCode switch
{
OperationResultCode.orcNotStarted => OsUpdateResultCodeEnum.NotStarted,
OperationResultCode.orcInProgress => OsUpdateResultCodeEnum.InProgress,
OperationResultCode.orcSucceeded => OsUpdateResultCodeEnum.Succeeded,
OperationResultCode.orcSucceededWithErrors => OsUpdateResultCodeEnum.SucceededWithErrors,
OperationResultCode.orcFailed => OsUpdateResultCodeEnum.Failed,
OperationResultCode.orcAborted => OsUpdateResultCodeEnum.Aborted,
_ => null
},
SupportUrl = wupdate.SupportUrl,
};
try
{
var rx = new Regex(@"KB(\d+)");
update.Hotfix = rx.Match(wupdate.Title).Value;
}
catch (Exception)
{
}
updates.Add(update);
}
return updates;
}
private static List<Update> QueryPendingUpdates()
{
var updates = new List<Update>();
var session = new UpdateSessionClass();
var searcher = session.CreateUpdateSearcher();
searcher.Online = true;
var result = searcher.Search("IsInstalled=0");
foreach (IUpdate wupdate in result.Updates)
{
var update = new Update
{
Id = wupdate.Identity.UpdateID,
Type = wupdate.Type switch
{
UpdateType.utSoftware => OsUpdateTypeEnum.Software,
UpdateType.utDriver => OsUpdateTypeEnum.Driver,
_ => null
},
Date = wupdate.LastDeploymentChangeTime,
Name = wupdate.Title,
Description = wupdate.Description,
SupportUrl = wupdate.SupportUrl,
Size = wupdate.MaxDownloadSize,
IsDownloaded = wupdate.IsDownloaded,
CanRequestUserInput = wupdate.InstallationBehavior.CanRequestUserInput,
RebootBehavior = wupdate.InstallationBehavior.RebootBehavior switch
{
InstallationRebootBehavior.irbNeverReboots => OsUpdateRebootBehaviorEnum.NeverReboots,
InstallationRebootBehavior.irbAlwaysRequiresReboot => OsUpdateRebootBehaviorEnum.AlwaysRequiresReboot,
InstallationRebootBehavior.irbCanRequestReboot => OsUpdateRebootBehaviorEnum.CanRequestReboot,
_ => null
},
};
if (wupdate.KBArticleIDs.Count > 0)
{
foreach (var id in wupdate.KBArticleIDs)
{
update.Hotfix = $"KB{id}";
break;
}
}
updates.Add(update);
}
return updates;
Installed = QueryInstalledUpdates(),
Pending = QueryPendingUpdates()
}, cancellationToken);
break;
}
}
private static List<Update> QueryInstalledUpdates()
{
var updates = new List<Update>();
var session = new UpdateSessionClass();
var searcher = session.CreateUpdateSearcher();
searcher.Online = false;
var count = searcher.GetTotalHistoryCount();
var result = searcher.QueryHistory(0, count);
foreach (IUpdateHistoryEntry wupdate in result)
{
var update = new Update
{
Id = wupdate.UpdateIdentity.UpdateID,
Date = wupdate.Date,
Name = wupdate.Title,
Description = wupdate.Description,
Result = wupdate.ResultCode switch
{
OperationResultCode.orcNotStarted => OsUpdateResultCodeEnum.NotStarted,
OperationResultCode.orcInProgress => OsUpdateResultCodeEnum.InProgress,
OperationResultCode.orcSucceeded => OsUpdateResultCodeEnum.Succeeded,
OperationResultCode.orcSucceededWithErrors => OsUpdateResultCodeEnum.SucceededWithErrors,
OperationResultCode.orcFailed => OsUpdateResultCodeEnum.Failed,
OperationResultCode.orcAborted => OsUpdateResultCodeEnum.Aborted,
_ => null
},
SupportUrl = wupdate.SupportUrl,
};
try
{
var rx = new Regex(@"KB(\d+)");
update.Hotfix = rx.Match(wupdate.Title).Value;
}
catch (Exception)
{
}
updates.Add(update);
}
return updates;
}
private static List<Update> QueryPendingUpdates()
{
var updates = new List<Update>();
var session = new UpdateSessionClass();
var searcher = session.CreateUpdateSearcher();
searcher.Online = true;
var result = searcher.Search("IsInstalled=0");
foreach (IUpdate wupdate in result.Updates)
{
var update = new Update
{
Id = wupdate.Identity.UpdateID,
Type = wupdate.Type switch
{
UpdateType.utSoftware => OsUpdateTypeEnum.Software,
UpdateType.utDriver => OsUpdateTypeEnum.Driver,
_ => null
},
Date = wupdate.LastDeploymentChangeTime,
Name = wupdate.Title,
Description = wupdate.Description,
SupportUrl = wupdate.SupportUrl,
Size = wupdate.MaxDownloadSize,
IsDownloaded = wupdate.IsDownloaded,
CanRequestUserInput = wupdate.InstallationBehavior.CanRequestUserInput,
RebootBehavior = wupdate.InstallationBehavior.RebootBehavior switch
{
InstallationRebootBehavior.irbNeverReboots => OsUpdateRebootBehaviorEnum.NeverReboots,
InstallationRebootBehavior.irbAlwaysRequiresReboot => OsUpdateRebootBehaviorEnum.AlwaysRequiresReboot,
InstallationRebootBehavior.irbCanRequestReboot => OsUpdateRebootBehaviorEnum.CanRequestReboot,
_ => null
},
};
if (wupdate.KBArticleIDs.Count > 0)
{
foreach (var id in wupdate.KBArticleIDs)
{
update.Hotfix = $"KB{id}";
break;
}
}
updates.Add(update);
}
return updates;
}
}

View file

@ -1,188 +1,192 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Management;
using System.Runtime.Versioning;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class UserHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class UserHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
var result = new UserList();
result.AddRange(GetUsers());
await sender.SendAsync(result, cancellationToken);
}
}
private static List<User> GetUsers()
{
var users = QueryUsers();
var groups = GetGroups();
var usergrouping = QueryUserGroupMaps();
foreach (var u in users)
{
u.Groups = new List<Group>();
foreach (var ug in usergrouping.Where(ug => ug.UserDomain == u.Domain && ug.UserName == u.Name))
case InventoryRequest:
{
var grps = groups.Where(g => g.Domain == ug.GroupDomain && g.Name == ug.GroupName);
var result = new Collection<User>();
result.AddRange(GetUsers());
if (grps is not null)
{
u.Groups.AddRange(grps);
}
await sender.SendAsync(result, cancellationToken);
break;
}
}
return users;
}
private static List<Group> GetGroups()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select sid, domain, name, description, localaccount from win32_group")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_group");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var groups = new List<Group>();
using (collection)
{
foreach (ManagementObject @object in collection)
{
var group = new Group();
var properties = @object.GetPropertyHashes();
group.Sid = @object.GetValue<string>(properties, "sid")?.Trim();
group.Domain = @object.GetValue<string>(properties, "domain")?.Trim();
group.Name = @object.GetValue<string>(properties, "name")?.Trim();
group.Description = @object.GetValue<string>(properties, "description")?.Trim();
group.LocalAccount = @object.GetValue<bool>(properties, "localaccount");
groups.Add(group);
}
}
return groups.OrderBy(x => x.Name)?.ToList();
}
private static List<User> QueryUsers()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select sid, name, fullname, description, domain, localaccount, disabled, lockout, status, passwordchangeable, passwordexpires, passwordrequired from win32_useraccount")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_useraccount");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var users = new List<User>();
using (collection)
{
foreach (ManagementObject @object in collection)
{
var user = new User();
var properties = @object.GetPropertyHashes();
user.Sid = @object.GetValue<string>(properties, "sid")?.Trim();
user.Name = @object.GetValue<string>(properties, "name")?.Trim();
user.FullName = @object.GetValue<string>(properties, "fullname")?.Trim();
user.Description = @object.GetValue<string>(properties, "description")?.Trim();
user.Domain = @object.GetValue<string>(properties, "domain")?.Trim();
user.LocalAccount = @object.GetValue<bool>(properties, "localaccount");
user.Disabled = @object.GetValue<bool>(properties, "disabled");
user.Lockout = @object.GetValue<bool>(properties, "lockout");
user.Status = @object.GetValue<string>(properties, "status")?.Trim();
user.PasswordChangeable = @object.GetValue<bool>(properties, "passwordchangeable");
user.PasswordExpires = @object.GetValue<bool>(properties, "passwordexpires");
user.PasswordRequired = @object.GetValue<bool>(properties, "passwordrequired");
users.Add(user);
}
}
return users;
}
private static List<UserGroupMap> QueryUserGroupMaps()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select groupcomponent, partcomponent from win32_groupuser")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_groupuser");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var usergroups = new List<UserGroupMap>();
using (collection)
{
foreach (ManagementObject @object in collection)
{
var usergroup = new UserGroupMap();
var properties = @object.GetPropertyHashes();
var raw = @object.GetValue<string>(properties, "groupcomponent");
var split = raw?.Split(".Domain=")[1]?.Split(",Name=");
if (split is not null && split.Length > 1)
{
usergroup.GroupDomain = split[0].TrimStart('"').TrimEnd('"');
usergroup.GroupName = split[1].TrimStart('"').TrimEnd('"');
}
raw = @object.GetValue<string>(properties, "partcomponent");
split = raw?.Split(".Domain=")[1]?.Split(",Name=");
if (split is not null && split.Length > 1)
{
usergroup.UserDomain = split[0].TrimStart('"').TrimEnd('"');
usergroup.UserName = split[1].TrimStart('"').TrimEnd('"');
}
usergroups.Add(usergroup);
}
}
return usergroups;
}
private class UserGroupMap
{
public string? GroupDomain { get; set; }
public string? GroupName { get; set; }
public string? UserDomain { get; set; }
public string? UserName { get; set; }
}
}
private static List<User> GetUsers()
{
var users = QueryUsers();
var groups = GetGroups();
var usergrouping = QueryUserGroupMaps();
foreach (var u in users)
{
u.Groups = new List<Group>();
foreach (var ug in usergrouping.Where(ug => ug.UserDomain == u.Domain && ug.UserName == u.Name))
{
var grps = groups.Where(g => g.Domain == ug.GroupDomain && g.Name == ug.GroupName);
if (grps is not null)
{
u.Groups.AddRange(grps);
}
}
}
return users;
}
private static List<Group> GetGroups()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select sid, domain, name, description, localaccount from win32_group")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_group");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var groups = new List<Group>();
using (collection)
{
foreach (ManagementObject @object in collection)
{
var group = new Group();
var properties = @object.GetPropertyHashes();
group.Sid = @object.GetValue<string>(properties, "sid")?.Trim();
group.Domain = @object.GetValue<string>(properties, "domain")?.Trim();
group.Name = @object.GetValue<string>(properties, "name")?.Trim();
group.Description = @object.GetValue<string>(properties, "description")?.Trim();
group.LocalAccount = @object.GetValue<bool>(properties, "localaccount");
groups.Add(group);
}
}
return groups.OrderBy(x => x.Name)?.ToList();
}
private static List<User> QueryUsers()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select sid, name, fullname, description, domain, localaccount, disabled, lockout, status, passwordchangeable, passwordexpires, passwordrequired from win32_useraccount")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_useraccount");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var users = new List<User>();
using (collection)
{
foreach (ManagementObject @object in collection)
{
var user = new User();
var properties = @object.GetPropertyHashes();
user.Sid = @object.GetValue<string>(properties, "sid")?.Trim();
user.Name = @object.GetValue<string>(properties, "name")?.Trim();
user.FullName = @object.GetValue<string>(properties, "fullname")?.Trim();
user.Description = @object.GetValue<string>(properties, "description")?.Trim();
user.Domain = @object.GetValue<string>(properties, "domain")?.Trim();
user.LocalAccount = @object.GetValue<bool>(properties, "localaccount");
user.Disabled = @object.GetValue<bool>(properties, "disabled");
user.Lockout = @object.GetValue<bool>(properties, "lockout");
user.Status = @object.GetValue<string>(properties, "status")?.Trim();
user.PasswordChangeable = @object.GetValue<bool>(properties, "passwordchangeable");
user.PasswordExpires = @object.GetValue<bool>(properties, "passwordexpires");
user.PasswordRequired = @object.GetValue<bool>(properties, "passwordrequired");
users.Add(user);
}
}
return users;
}
private static List<UserGroupMap> QueryUserGroupMaps()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select groupcomponent, partcomponent from win32_groupuser")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_groupuser");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var usergroups = new List<UserGroupMap>();
using (collection)
{
foreach (ManagementObject @object in collection)
{
var usergroup = new UserGroupMap();
var properties = @object.GetPropertyHashes();
var raw = @object.GetValue<string>(properties, "groupcomponent");
var split = raw?.Split(".Domain=")[1]?.Split(",Name=");
if (split is not null && split.Length > 1)
{
usergroup.GroupDomain = split[0].TrimStart('"').TrimEnd('"');
usergroup.GroupName = split[1].TrimStart('"').TrimEnd('"');
}
raw = @object.GetValue<string>(properties, "partcomponent");
split = raw?.Split(".Domain=")[1]?.Split(",Name=");
if (split is not null && split.Length > 1)
{
usergroup.UserDomain = split[0].TrimStart('"').TrimEnd('"');
usergroup.UserName = split[1].TrimStart('"').TrimEnd('"');
}
usergroups.Add(usergroup);
}
}
return usergroups;
}
private class UserGroupMap
{
public string? GroupDomain { get; set; }
public string? GroupName { get; set; }
public string? UserDomain { get; set; }
public string? UserName { get; set; }
}
}

View file

@ -1,64 +1,68 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Management;
using System.Runtime.Versioning;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class VideocardHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class VideocardHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
var result = new VideocardList();
result.AddRange(GetVideocards());
await sender.SendAsync(result, cancellationToken);
}
}
private static List<Videocard> GetVideocards()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select deviceid, name, adapterram, driverdate, driverversion from win32_videocontroller")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_videocontroller");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var videocards = new List<Videocard>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
case InventoryRequest:
{
var videocard = new Videocard();
var result = new Collection<Videocard>();
result.AddRange(GetVideocards());
var properties = @object.GetPropertyHashes();
videocard.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
videocard.Model = @object.GetValue<string>(properties, "name")?.Trim();
if (@object.TryGetValue<object>(properties, "driverdate", out var driverdate))
{
videocard.DriverDate = ManagementDateTimeConverter.ToDateTime(driverdate?.ToString());
}
videocard.DriverVersion = @object.GetValue<string>(properties, "driverversion")?.Trim();
videocards.Add(videocard);
await sender.SendAsync(result, cancellationToken);
break;
}
}
return videocards;
}
}
private static List<Videocard> GetVideocards()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("select deviceid, name, adapterram, driverdate, driverversion from win32_videocontroller")
};
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_videocontroller");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var videocards = new List<Videocard>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
{
var videocard = new Videocard();
var properties = @object.GetPropertyHashes();
videocard.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
videocard.Model = @object.GetValue<string>(properties, "name")?.Trim();
if (@object.TryGetValue<object>(properties, "driverdate", out var driverdate))
{
videocard.DriverDate = ManagementDateTimeConverter.ToDateTime(driverdate?.ToString());
}
videocard.DriverVersion = @object.GetValue<string>(properties, "driverversion")?.Trim();
videocards.Add(videocard);
}
}
return videocards;
}
}

View file

@ -1,359 +1,363 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Management;
using System.Runtime.Versioning;
using static Insight.Agent.Messages.VirtualMaschine;
using static Insight.Agent.Messages.VirtualMaschineConfiguration;
using static Insight.Domain.Network.Agent.Messages.VirtualMaschine;
using static Insight.Domain.Network.Agent.Messages.VirtualMaschineConfiguration;
namespace Insight.Agent.Network.Handlers
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class VirtualMaschineHandler : IMessageHandler<AgentSession>
{
[SupportedOSPlatform("windows")]
public class VirtualMaschineHandler : IAgentMessageHandler<AgentSession>
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
switch (message)
{
if (message is GetInventory)
{
var result = new VirtualMaschineList();
result.AddRange(GetVirtualMaschines());
await sender.SendAsync(result, cancellationToken);
}
}
private static List<VirtualMaschine> GetVirtualMaschines()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\virtualization\v2"),
Query = new ObjectQuery("select * msvm_computersystem")
};
if (searcher.TryGet(out var computersystems) is false)
{
searcher.Query = new ObjectQuery("select * from msvm_computersystem");
if (searcher.TryGet(out computersystems) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var vms = new List<VirtualMaschine>();
using (computersystems)
{
foreach (ManagementObject cs in computersystems.Cast<ManagementObject>())
case InventoryRequest:
{
var vm = new VirtualMaschine();
var result = new Collection<VirtualMaschine>();
result.AddRange(GetVirtualMaschines());
var csProperties = cs.GetPropertyHashes();
var vmId = cs.GetValue<string>(csProperties, "name")?.Trim();
if (Guid.TryParse(vmId, out var vmGuid) is false) continue;
vm.Id = vmGuid;
vm.ProcessId = cs.GetValue<uint>(csProperties, "processid");
vm.Caption = cs.GetValue<string>(csProperties, "caption")?.Trim();
vm.Name = cs.GetValue<string>(csProperties, "elementname")?.Trim();
vm.Enabled = (EnabledEnum)cs.GetValue<ushort>(csProperties, "enabledstate");
vm.EnabledDefault = (EnabledDefaultEnum)cs.GetValue<ushort>(csProperties, "enableddefault");
vm.HealthState = (HealthStatusEnum)cs.GetValue<ushort>(csProperties, "healthstate");
vm.Status = cs.GetValue<string>(csProperties, "status")?.Trim();
vm.OnTime = cs.GetValue<ulong>(csProperties, "ontimeinmilliseconds");
vm.ReplicationMode = cs.GetValue<ushort>(csProperties, "replicationmode");
vm.ReplicationState = (ReplicationStateEnum)cs.GetValue<ushort>(csProperties, "replicationstate");
vm.ReplicationHealth = (ReplicationHealthEnum)cs.GetValue<ushort>(csProperties, "replicationhealth");
if (cs.TryGetValue<object>(csProperties, "installdate", out var installdate))
{
vm.InstallDate = ManagementDateTimeConverter.ToDateTime(installdate?.ToString());
}
if (cs.TryGetValue<object>(csProperties, "timeoflastconfigurationchange", out var timeoflastconfigurationchange))
{
vm.TimeOfLastConfigurationChange = ManagementDateTimeConverter.ToDateTime(timeoflastconfigurationchange?.ToString());
}
if (cs.TryGetValue<object>(csProperties, "timeoflaststatechange", out var timeoflaststatechange))
{
vm.TimeOfLastStateChange = ManagementDateTimeConverter.ToDateTime(timeoflaststatechange?.ToString());
}
if (cs.TryGetValue<object>(csProperties, "lastreplicationtime", out var lastreplicationtime))
{
vm.LastReplicationTime = ManagementDateTimeConverter.ToDateTime(lastreplicationtime?.ToString());
}
var summaryinformation = cs.GetRelated("msvm_summaryinformation");
using (summaryinformation)
{
foreach (ManagementObject si in summaryinformation.Cast<ManagementObject>())
{
var siProperties = si.GetPropertyHashes();
vm.Notes = si.GetValue<string>(siProperties, "Notes");
vm.ConfigurationVersion = si.GetValue<string>(siProperties, "Version");
vm.IntegrationServicesVersionState = (IntegrationServicesVersionStateEnum)si.GetValue<ushort>(siProperties, "IntegrationServicesVersionState");
vm.GuestOperatingSystem = si.GetValue<string>(siProperties, "GuestOperatingSystem");
vm.NumberOfProcessors = si.GetValue<ushort>(siProperties, "NumberOfProcessors");
vm.ProcessorLoad = si.GetValue<ushort>(siProperties, "ProcessorLoad");
vm.MemoryAvailable = si.GetValue<int>(siProperties, "MemoryAvailable");
vm.MemoryUsage = si.GetValue<ulong>(siProperties, "MemoryUsage");
}
}
var virtualSystemSettingData = cs.GetRelated("Msvm_VirtualSystemSettingData");
using (virtualSystemSettingData)
{
var configs = new List<VirtualMaschineConfiguration>();
foreach (ManagementObject vssd in virtualSystemSettingData.Cast<ManagementObject>())
{
var vmc = new VirtualMaschineConfiguration();
var vssdProperties = vssd.GetPropertyHashes();
var vmcId = vssd.GetValue<string>(vssdProperties, "ConfigurationID")?.Trim();
if (Guid.TryParse(vmcId, out var vmcGuid) is false) continue;
vmc.Id = vmcGuid.ToString();
vmc.Type = vssd.GetValue<string>(vssdProperties, "VirtualSystemType");
vmc.Name = vssd.GetValue<string>(vssdProperties, "ElementName");
if (vssd.TryGetValue<object>(vssdProperties, "CreationTime", out var creationtime))
{
vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(creationtime?.ToString());
}
vmc.Generation = vssd.GetValue<string>(vssdProperties, "VirtualSystemSubType");
vmc.Architecture = vssd.GetValue<string>(vssdProperties, "Architecture");
vmc.AutomaticStartupAction = (AutomaticStartupActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticStartupAction");
vmc.AutomaticShutdownAction = (AutomaticShutdownActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticShutdownAction");
vmc.AutomaticRecoveryAction = (AutomaticRecoveryActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticRecoveryAction");
vmc.AutomaticSnapshotsEnabled = vssd.GetValue<bool>(vssdProperties, "AutomaticSnapshotsEnabled");
//if (vssd.TryGetValue<object>(vssdProperties, "AutomaticStartupActionDelay", out var automaticstartupactiondelay))
//{
// vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(automaticstartupactiondelay?.ToString());
//}
vmc.BaseBoardSerialNumber = vssd.GetValue<string>(vssdProperties, "BaseBoardSerialNumber");
vmc.BIOSGUID = vssd.GetValue<string>(vssdProperties, "BIOSGUID");
vmc.BIOSSerialNumber = vssd.GetValue<string>(vssdProperties, "BIOSSerialNumber");
vmc.BootOrder = vssd.GetValue<ushort[]>(vssdProperties, "BootOrder");
vmc.ConfigurationDataRoot = vssd.GetValue<string>(vssdProperties, "ConfigurationDataRoot");
vmc.ConfigurationFile = vssd.GetValue<string>(vssdProperties, "ConfigurationFile");
vmc.GuestStateDataRoot = vssd.GetValue<string>(vssdProperties, "GuestStateDataRoot");
vmc.GuestStateFile = vssd.GetValue<string>(vssdProperties, "GuestStateFile");
vmc.SnapshotDataRoot = vssd.GetValue<string>(vssdProperties, "SnapshotDataRoot");
vmc.SuspendDataRoot = vssd.GetValue<string>(vssdProperties, "SuspendDataRoot");
vmc.SwapFileDataRoot = vssd.GetValue<string>(vssdProperties, "SwapFileDataRoot");
vmc.SecureBootEnabled = vssd.GetValue<bool>(vssdProperties, "SecureBootEnabled");
vmc.IsAutomaticSnapshot = vssd.GetValue<bool>(vssdProperties, "IsAutomaticSnapshot");
vmc.Notes = vssd.GetValue<string[]>(vssdProperties, "Notes");
if (vssd.GetValue<string>(vssdProperties, "Parent") is string parent)
{
using var vmcp = new ManagementObject(parent);
vmcp.Get();
if (Guid.TryParse(vmcp["ConfigurationID"]?.ToString(), out var parentGuid) is false) continue;
vmc.ParentId = parentGuid.ToString();
}
//var storageallocationsettingdata = cs.GetRelated("Msvm_StorageAllocationSettingData");
//using (storageallocationsettingdata)
//{
//}
configs.Add(vmc);
}
vm.Configurations = configs.GroupBy(p => p.Id).Select(p => p.First()).ToList();
}
vms.Add(vm);
await sender.SendAsync(result, cancellationToken);
break;
}
}
return vms;
}
private static List<VirtualMaschine> QueryVirtualMaschines0()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\virtualization\v2"),
Query = new ObjectQuery("select * msvm_computersystem")
};
if (searcher.TryGet(out var computersystems) is false)
{
searcher.Query = new ObjectQuery("select * from msvm_computersystem");
if (searcher.TryGet(out computersystems) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var vms = new List<VirtualMaschine>();
using (computersystems)
{
foreach (ManagementObject cs in computersystems.Cast<ManagementObject>())
{
var vm = new VirtualMaschine();
var csProperties = cs.GetPropertyHashes();
var vmId = cs.GetValue<string>(csProperties, "name")?.Trim();
if (Guid.TryParse(vmId, out var vmGuid) is false) continue;
vm.Id = vmGuid;
vm.ProcessId = cs.GetValue<uint>(csProperties, "processid");
vm.Caption = cs.GetValue<string>(csProperties, "caption")?.Trim();
vm.Name = cs.GetValue<string>(csProperties, "elementname")?.Trim();
vm.Enabled = (EnabledEnum)cs.GetValue<ushort>(csProperties, "enabledstate");
vm.EnabledDefault = (EnabledDefaultEnum)cs.GetValue<ushort>(csProperties, "enableddefault");
vm.HealthState = (HealthStatusEnum)cs.GetValue<ushort>(csProperties, "healthstate");
vm.Status = cs.GetValue<string>(csProperties, "status")?.Trim();
vm.OnTime = cs.GetValue<ulong>(csProperties, "ontimeinmilliseconds");
vm.ReplicationMode = cs.GetValue<ushort>(csProperties, "replicationmode");
vm.ReplicationState = (ReplicationStateEnum)cs.GetValue<ushort>(csProperties, "replicationstate");
vm.ReplicationHealth = (ReplicationHealthEnum)cs.GetValue<ushort>(csProperties, "replicationhealth");
if (cs.TryGetValue<object>(csProperties, "installdate", out var installdate))
{
vm.InstallDate = ManagementDateTimeConverter.ToDateTime(installdate?.ToString());
}
if (cs.TryGetValue<object>(csProperties, "timeoflastconfigurationchange", out var timeoflastconfigurationchange))
{
vm.TimeOfLastConfigurationChange = ManagementDateTimeConverter.ToDateTime(timeoflastconfigurationchange?.ToString());
}
if (cs.TryGetValue<object>(csProperties, "timeoflaststatechange", out var timeoflaststatechange))
{
vm.TimeOfLastStateChange = ManagementDateTimeConverter.ToDateTime(timeoflaststatechange?.ToString());
}
if (cs.TryGetValue<object>(csProperties, "lastreplicationtime", out var lastreplicationtime))
{
vm.LastReplicationTime = ManagementDateTimeConverter.ToDateTime(lastreplicationtime?.ToString());
}
var summaryinformation = cs.GetRelated("msvm_summaryinformation");
using (summaryinformation)
{
foreach (ManagementObject si in summaryinformation.Cast<ManagementObject>())
{
var siProperties = si.GetPropertyHashes();
vm.Notes = si.GetValue<string>(siProperties, "Notes");
vm.ConfigurationVersion = si.GetValue<string>(siProperties, "Version");
vm.IntegrationServicesVersionState = (IntegrationServicesVersionStateEnum)si.GetValue<ushort>(siProperties, "IntegrationServicesVersionState");
vm.GuestOperatingSystem = si.GetValue<string>(siProperties, "GuestOperatingSystem");
vm.NumberOfProcessors = si.GetValue<ushort>(siProperties, "NumberOfProcessors");
vm.ProcessorLoad = si.GetValue<ushort>(siProperties, "ProcessorLoad");
vm.MemoryAvailable = si.GetValue<int>(siProperties, "MemoryAvailable");
vm.MemoryUsage = si.GetValue<ulong>(siProperties, "MemoryUsage");
}
}
var virtualSystemSettingData = cs.GetRelated("Msvm_VirtualSystemSettingData");
using (virtualSystemSettingData)
{
var configs = new List<VirtualMaschineConfiguration>();
foreach (ManagementObject vssd in virtualSystemSettingData.Cast<ManagementObject>())
{
var vmc = new VirtualMaschineConfiguration();
var vssdProperties = vssd.GetPropertyHashes();
var vmcId = vssd.GetValue<string>(vssdProperties, "ConfigurationID")?.Trim();
if (Guid.TryParse(vmcId, out var vmcGuid) is false) continue;
vmc.Id = vmcGuid.ToString();
vmc.Type = vssd.GetValue<string>(vssdProperties, "VirtualSystemType");
vmc.Name = vssd.GetValue<string>(vssdProperties, "ElementName");
if (vssd.TryGetValue<object>(vssdProperties, "CreationTime", out var creationtime))
{
vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(creationtime?.ToString());
}
vmc.Generation = vssd.GetValue<string>(vssdProperties, "VirtualSystemSubType");
vmc.Architecture = vssd.GetValue<string>(vssdProperties, "Architecture");
vmc.AutomaticStartupAction = (AutomaticStartupActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticStartupAction");
//if (vssd.TryGetValue<object>(vssdProperties, "AutomaticStartupActionDelay", out var automaticstartupactiondelay))
//{
// vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(automaticstartupactiondelay?.ToString());
//}
vmc.AutomaticShutdownAction = (AutomaticShutdownActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticShutdownAction");
vmc.AutomaticRecoveryAction = (AutomaticRecoveryActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticRecoveryAction");
vmc.AutomaticSnapshotsEnabled = vssd.GetValue<bool>(vssdProperties, "AutomaticSnapshotsEnabled");
vmc.BaseBoardSerialNumber = vssd.GetValue<string>(vssdProperties, "BaseBoardSerialNumber");
vmc.BIOSGUID = vssd.GetValue<string>(vssdProperties, "BIOSGUID");
vmc.BIOSSerialNumber = vssd.GetValue<string>(vssdProperties, "BIOSSerialNumber");
vmc.BootOrder = vssd.GetValue<ushort[]>(vssdProperties, "BootOrder");
vmc.ConfigurationDataRoot = vssd.GetValue<string>(vssdProperties, "ConfigurationDataRoot");
vmc.ConfigurationFile = vssd.GetValue<string>(vssdProperties, "ConfigurationFile");
vmc.GuestStateDataRoot = vssd.GetValue<string>(vssdProperties, "GuestStateDataRoot");
vmc.GuestStateFile = vssd.GetValue<string>(vssdProperties, "GuestStateFile");
vmc.SnapshotDataRoot = vssd.GetValue<string>(vssdProperties, "SnapshotDataRoot");
vmc.SuspendDataRoot = vssd.GetValue<string>(vssdProperties, "SuspendDataRoot");
vmc.SwapFileDataRoot = vssd.GetValue<string>(vssdProperties, "SwapFileDataRoot");
vmc.SecureBootEnabled = vssd.GetValue<bool>(vssdProperties, "SecureBootEnabled");
vmc.IsAutomaticSnapshot = vssd.GetValue<bool>(vssdProperties, "IsAutomaticSnapshot");
vmc.Notes = vssd.GetValue<string[]>(vssdProperties, "Notes");
vmc.ParentId = vssd.GetValue<string>(vssdProperties, "Parent");
var storageallocationsettingdata = cs.GetRelated("Msvm_StorageAllocationSettingData");
using (storageallocationsettingdata)
{
}
configs.Add(vmc);
}
configs = configs.GroupBy(p => p.Id).Select(p => p.First()).ToList();
if (configs.Any(p => p.ParentId is not null))
{
foreach (var conf in configs.Where(p => p.ParentId is not null))
{
using var parent = new ManagementObject(conf.ParentId);
parent.Get();
if (Guid.TryParse(parent["ConfigurationID"]?.ToString(), out var parentGuid) && configs.FirstOrDefault(p => p.Id == parentGuid.ToString()) is VirtualMaschineConfiguration parentConfig)
{
conf.ParentId = parentGuid.ToString();
parentConfig.Childs ??= new List<VirtualMaschineConfiguration>();
parentConfig.Childs.Add(conf);
}
else
{
conf.ParentId = null;
}
}
}
vm.Configurations = configs.Where(p => p.ParentId is null).ToList();
}
vms.Add(vm);
}
}
return vms;
}
}
private static List<VirtualMaschine> GetVirtualMaschines()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\virtualization\v2"),
Query = new ObjectQuery("select * msvm_computersystem")
};
if (searcher.TryGet(out var computersystems) is false)
{
searcher.Query = new ObjectQuery("select * from msvm_computersystem");
if (searcher.TryGet(out computersystems) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var vms = new List<VirtualMaschine>();
using (computersystems)
{
foreach (ManagementObject cs in computersystems.Cast<ManagementObject>())
{
var vm = new VirtualMaschine();
var csProperties = cs.GetPropertyHashes();
var vmId = cs.GetValue<string>(csProperties, "name")?.Trim();
if (Guid.TryParse(vmId, out var vmGuid) is false) continue;
vm.Id = vmGuid;
vm.ProcessId = cs.GetValue<uint>(csProperties, "processid");
vm.Caption = cs.GetValue<string>(csProperties, "caption")?.Trim();
vm.Name = cs.GetValue<string>(csProperties, "elementname")?.Trim();
vm.Enabled = (EnabledEnum)cs.GetValue<ushort>(csProperties, "enabledstate");
vm.EnabledDefault = (EnabledDefaultEnum)cs.GetValue<ushort>(csProperties, "enableddefault");
vm.HealthState = (HealthStatusEnum)cs.GetValue<ushort>(csProperties, "healthstate");
vm.Status = cs.GetValue<string>(csProperties, "status")?.Trim();
vm.OnTime = cs.GetValue<ulong>(csProperties, "ontimeinmilliseconds");
vm.ReplicationMode = cs.GetValue<ushort>(csProperties, "replicationmode");
vm.ReplicationState = (ReplicationStateEnum)cs.GetValue<ushort>(csProperties, "replicationstate");
vm.ReplicationHealth = (ReplicationHealthEnum)cs.GetValue<ushort>(csProperties, "replicationhealth");
if (cs.TryGetValue<object>(csProperties, "installdate", out var installdate))
{
vm.InstallDate = ManagementDateTimeConverter.ToDateTime(installdate?.ToString());
}
if (cs.TryGetValue<object>(csProperties, "timeoflastconfigurationchange", out var timeoflastconfigurationchange))
{
vm.TimeOfLastConfigurationChange = ManagementDateTimeConverter.ToDateTime(timeoflastconfigurationchange?.ToString());
}
if (cs.TryGetValue<object>(csProperties, "timeoflaststatechange", out var timeoflaststatechange))
{
vm.TimeOfLastStateChange = ManagementDateTimeConverter.ToDateTime(timeoflaststatechange?.ToString());
}
if (cs.TryGetValue<object>(csProperties, "lastreplicationtime", out var lastreplicationtime))
{
vm.LastReplicationTime = ManagementDateTimeConverter.ToDateTime(lastreplicationtime?.ToString());
}
var summaryinformation = cs.GetRelated("msvm_summaryinformation");
using (summaryinformation)
{
foreach (ManagementObject si in summaryinformation.Cast<ManagementObject>())
{
var siProperties = si.GetPropertyHashes();
vm.Notes = si.GetValue<string>(siProperties, "Notes");
vm.ConfigurationVersion = si.GetValue<string>(siProperties, "Version");
vm.IntegrationServicesVersionState = (IntegrationServicesVersionStateEnum)si.GetValue<ushort>(siProperties, "IntegrationServicesVersionState");
vm.GuestOperatingSystem = si.GetValue<string>(siProperties, "GuestOperatingSystem");
vm.NumberOfProcessors = si.GetValue<ushort>(siProperties, "NumberOfProcessors");
vm.ProcessorLoad = si.GetValue<ushort>(siProperties, "ProcessorLoad");
vm.MemoryAvailable = si.GetValue<int>(siProperties, "MemoryAvailable");
vm.MemoryUsage = si.GetValue<ulong>(siProperties, "MemoryUsage");
}
}
var virtualSystemSettingData = cs.GetRelated("Msvm_VirtualSystemSettingData");
using (virtualSystemSettingData)
{
var configs = new List<VirtualMaschineConfiguration>();
foreach (ManagementObject vssd in virtualSystemSettingData.Cast<ManagementObject>())
{
var vmc = new VirtualMaschineConfiguration();
var vssdProperties = vssd.GetPropertyHashes();
var vmcId = vssd.GetValue<string>(vssdProperties, "ConfigurationID")?.Trim();
if (Guid.TryParse(vmcId, out var vmcGuid) is false) continue;
vmc.Id = vmcGuid.ToString();
vmc.Type = vssd.GetValue<string>(vssdProperties, "VirtualSystemType");
vmc.Name = vssd.GetValue<string>(vssdProperties, "ElementName");
if (vssd.TryGetValue<object>(vssdProperties, "CreationTime", out var creationtime))
{
vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(creationtime?.ToString());
}
vmc.Generation = vssd.GetValue<string>(vssdProperties, "VirtualSystemSubType");
vmc.Architecture = vssd.GetValue<string>(vssdProperties, "Architecture");
vmc.AutomaticStartupAction = (AutomaticStartupActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticStartupAction");
vmc.AutomaticShutdownAction = (AutomaticShutdownActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticShutdownAction");
vmc.AutomaticRecoveryAction = (AutomaticRecoveryActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticRecoveryAction");
vmc.AutomaticSnapshotsEnabled = vssd.GetValue<bool>(vssdProperties, "AutomaticSnapshotsEnabled");
//if (vssd.TryGetValue<object>(vssdProperties, "AutomaticStartupActionDelay", out var automaticstartupactiondelay))
//{
// vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(automaticstartupactiondelay?.ToString());
//}
vmc.BaseBoardSerialNumber = vssd.GetValue<string>(vssdProperties, "BaseBoardSerialNumber");
vmc.BIOSGUID = vssd.GetValue<string>(vssdProperties, "BIOSGUID");
vmc.BIOSSerialNumber = vssd.GetValue<string>(vssdProperties, "BIOSSerialNumber");
vmc.BootOrder = vssd.GetValue<ushort[]>(vssdProperties, "BootOrder");
vmc.ConfigurationDataRoot = vssd.GetValue<string>(vssdProperties, "ConfigurationDataRoot");
vmc.ConfigurationFile = vssd.GetValue<string>(vssdProperties, "ConfigurationFile");
vmc.GuestStateDataRoot = vssd.GetValue<string>(vssdProperties, "GuestStateDataRoot");
vmc.GuestStateFile = vssd.GetValue<string>(vssdProperties, "GuestStateFile");
vmc.SnapshotDataRoot = vssd.GetValue<string>(vssdProperties, "SnapshotDataRoot");
vmc.SuspendDataRoot = vssd.GetValue<string>(vssdProperties, "SuspendDataRoot");
vmc.SwapFileDataRoot = vssd.GetValue<string>(vssdProperties, "SwapFileDataRoot");
vmc.SecureBootEnabled = vssd.GetValue<bool>(vssdProperties, "SecureBootEnabled");
vmc.IsAutomaticSnapshot = vssd.GetValue<bool>(vssdProperties, "IsAutomaticSnapshot");
vmc.Notes = vssd.GetValue<string[]>(vssdProperties, "Notes");
if (vssd.GetValue<string>(vssdProperties, "Parent") is string parent)
{
using var vmcp = new ManagementObject(parent);
vmcp.Get();
if (Guid.TryParse(vmcp["ConfigurationID"]?.ToString(), out var parentGuid) is false) continue;
vmc.ParentId = parentGuid.ToString();
}
//var storageallocationsettingdata = cs.GetRelated("Msvm_StorageAllocationSettingData");
//using (storageallocationsettingdata)
//{
//}
configs.Add(vmc);
}
vm.Configurations = configs.GroupBy(p => p.Id).Select(p => p.First()).ToList();
}
vms.Add(vm);
}
}
return vms;
}
private static List<VirtualMaschine> QueryVirtualMaschines0()
{
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\virtualization\v2"),
Query = new ObjectQuery("select * msvm_computersystem")
};
if (searcher.TryGet(out var computersystems) is false)
{
searcher.Query = new ObjectQuery("select * from msvm_computersystem");
if (searcher.TryGet(out computersystems) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var vms = new List<VirtualMaschine>();
using (computersystems)
{
foreach (ManagementObject cs in computersystems.Cast<ManagementObject>())
{
var vm = new VirtualMaschine();
var csProperties = cs.GetPropertyHashes();
var vmId = cs.GetValue<string>(csProperties, "name")?.Trim();
if (Guid.TryParse(vmId, out var vmGuid) is false) continue;
vm.Id = vmGuid;
vm.ProcessId = cs.GetValue<uint>(csProperties, "processid");
vm.Caption = cs.GetValue<string>(csProperties, "caption")?.Trim();
vm.Name = cs.GetValue<string>(csProperties, "elementname")?.Trim();
vm.Enabled = (EnabledEnum)cs.GetValue<ushort>(csProperties, "enabledstate");
vm.EnabledDefault = (EnabledDefaultEnum)cs.GetValue<ushort>(csProperties, "enableddefault");
vm.HealthState = (HealthStatusEnum)cs.GetValue<ushort>(csProperties, "healthstate");
vm.Status = cs.GetValue<string>(csProperties, "status")?.Trim();
vm.OnTime = cs.GetValue<ulong>(csProperties, "ontimeinmilliseconds");
vm.ReplicationMode = cs.GetValue<ushort>(csProperties, "replicationmode");
vm.ReplicationState = (ReplicationStateEnum)cs.GetValue<ushort>(csProperties, "replicationstate");
vm.ReplicationHealth = (ReplicationHealthEnum)cs.GetValue<ushort>(csProperties, "replicationhealth");
if (cs.TryGetValue<object>(csProperties, "installdate", out var installdate))
{
vm.InstallDate = ManagementDateTimeConverter.ToDateTime(installdate?.ToString());
}
if (cs.TryGetValue<object>(csProperties, "timeoflastconfigurationchange", out var timeoflastconfigurationchange))
{
vm.TimeOfLastConfigurationChange = ManagementDateTimeConverter.ToDateTime(timeoflastconfigurationchange?.ToString());
}
if (cs.TryGetValue<object>(csProperties, "timeoflaststatechange", out var timeoflaststatechange))
{
vm.TimeOfLastStateChange = ManagementDateTimeConverter.ToDateTime(timeoflaststatechange?.ToString());
}
if (cs.TryGetValue<object>(csProperties, "lastreplicationtime", out var lastreplicationtime))
{
vm.LastReplicationTime = ManagementDateTimeConverter.ToDateTime(lastreplicationtime?.ToString());
}
var summaryinformation = cs.GetRelated("msvm_summaryinformation");
using (summaryinformation)
{
foreach (ManagementObject si in summaryinformation.Cast<ManagementObject>())
{
var siProperties = si.GetPropertyHashes();
vm.Notes = si.GetValue<string>(siProperties, "Notes");
vm.ConfigurationVersion = si.GetValue<string>(siProperties, "Version");
vm.IntegrationServicesVersionState = (IntegrationServicesVersionStateEnum)si.GetValue<ushort>(siProperties, "IntegrationServicesVersionState");
vm.GuestOperatingSystem = si.GetValue<string>(siProperties, "GuestOperatingSystem");
vm.NumberOfProcessors = si.GetValue<ushort>(siProperties, "NumberOfProcessors");
vm.ProcessorLoad = si.GetValue<ushort>(siProperties, "ProcessorLoad");
vm.MemoryAvailable = si.GetValue<int>(siProperties, "MemoryAvailable");
vm.MemoryUsage = si.GetValue<ulong>(siProperties, "MemoryUsage");
}
}
var virtualSystemSettingData = cs.GetRelated("Msvm_VirtualSystemSettingData");
using (virtualSystemSettingData)
{
var configs = new List<VirtualMaschineConfiguration>();
foreach (ManagementObject vssd in virtualSystemSettingData.Cast<ManagementObject>())
{
var vmc = new VirtualMaschineConfiguration();
var vssdProperties = vssd.GetPropertyHashes();
var vmcId = vssd.GetValue<string>(vssdProperties, "ConfigurationID")?.Trim();
if (Guid.TryParse(vmcId, out var vmcGuid) is false) continue;
vmc.Id = vmcGuid.ToString();
vmc.Type = vssd.GetValue<string>(vssdProperties, "VirtualSystemType");
vmc.Name = vssd.GetValue<string>(vssdProperties, "ElementName");
if (vssd.TryGetValue<object>(vssdProperties, "CreationTime", out var creationtime))
{
vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(creationtime?.ToString());
}
vmc.Generation = vssd.GetValue<string>(vssdProperties, "VirtualSystemSubType");
vmc.Architecture = vssd.GetValue<string>(vssdProperties, "Architecture");
vmc.AutomaticStartupAction = (AutomaticStartupActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticStartupAction");
//if (vssd.TryGetValue<object>(vssdProperties, "AutomaticStartupActionDelay", out var automaticstartupactiondelay))
//{
// vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(automaticstartupactiondelay?.ToString());
//}
vmc.AutomaticShutdownAction = (AutomaticShutdownActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticShutdownAction");
vmc.AutomaticRecoveryAction = (AutomaticRecoveryActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticRecoveryAction");
vmc.AutomaticSnapshotsEnabled = vssd.GetValue<bool>(vssdProperties, "AutomaticSnapshotsEnabled");
vmc.BaseBoardSerialNumber = vssd.GetValue<string>(vssdProperties, "BaseBoardSerialNumber");
vmc.BIOSGUID = vssd.GetValue<string>(vssdProperties, "BIOSGUID");
vmc.BIOSSerialNumber = vssd.GetValue<string>(vssdProperties, "BIOSSerialNumber");
vmc.BootOrder = vssd.GetValue<ushort[]>(vssdProperties, "BootOrder");
vmc.ConfigurationDataRoot = vssd.GetValue<string>(vssdProperties, "ConfigurationDataRoot");
vmc.ConfigurationFile = vssd.GetValue<string>(vssdProperties, "ConfigurationFile");
vmc.GuestStateDataRoot = vssd.GetValue<string>(vssdProperties, "GuestStateDataRoot");
vmc.GuestStateFile = vssd.GetValue<string>(vssdProperties, "GuestStateFile");
vmc.SnapshotDataRoot = vssd.GetValue<string>(vssdProperties, "SnapshotDataRoot");
vmc.SuspendDataRoot = vssd.GetValue<string>(vssdProperties, "SuspendDataRoot");
vmc.SwapFileDataRoot = vssd.GetValue<string>(vssdProperties, "SwapFileDataRoot");
vmc.SecureBootEnabled = vssd.GetValue<bool>(vssdProperties, "SecureBootEnabled");
vmc.IsAutomaticSnapshot = vssd.GetValue<bool>(vssdProperties, "IsAutomaticSnapshot");
vmc.Notes = vssd.GetValue<string[]>(vssdProperties, "Notes");
vmc.ParentId = vssd.GetValue<string>(vssdProperties, "Parent");
var storageallocationsettingdata = cs.GetRelated("Msvm_StorageAllocationSettingData");
using (storageallocationsettingdata)
{
}
configs.Add(vmc);
}
configs = configs.GroupBy(p => p.Id).Select(p => p.First()).ToList();
if (configs.Any(p => p.ParentId is not null))
{
foreach (var conf in configs.Where(p => p.ParentId is not null))
{
using var parent = new ManagementObject(conf.ParentId);
parent.Get();
if (Guid.TryParse(parent["ConfigurationID"]?.ToString(), out var parentGuid) && configs.FirstOrDefault(p => p.Id == parentGuid.ToString()) is VirtualMaschineConfiguration parentConfig)
{
conf.ParentId = parentGuid.ToString();
parentConfig.Childs ??= new List<VirtualMaschineConfiguration>();
parentConfig.Childs.Add(conf);
}
else
{
conf.ParentId = null;
}
}
}
vm.Configurations = configs.Where(p => p.ParentId is null).ToList();
}
vms.Add(vm);
}
}
return vms;
}
}

View file

@ -1,10 +1,10 @@
using Insight.Agent.Extensions;
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Insight.Agent.Network;
using Insight.Agent.Network.Handlers;
using Insight.Agent.Services;
using Insight.Domain.Constants;
using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@ -12,86 +12,91 @@ using Microsoft.Extensions.Logging;
using Vaitr.Network;
using Vaitr.Network.Hosting;
namespace Insight.Agent.Windows
namespace Insight.Agent.Windows;
internal class Program
{
internal class Program
public static async Task Main(string[] args)
{
public static async Task Main(string[] args)
var builder = Host.CreateDefaultBuilder(args);
builder.UseWindowsService();
builder.UseSystemd();
builder.ConfigureAppConfiguration(config =>
{
var builder = Host.CreateDefaultBuilder(args);
builder.UseWindowsService();
builder.UseSystemd();
config.Defaults();
});
builder.ConfigureAppConfiguration(config =>
builder.ConfigureLogging(options =>
{
options.ClearProviders();
options.SetMinimumLevel(LogLevel.Trace);
options.AddSimpleConsole(options =>
{
config.Defaults();
options.IncludeScopes = true;
options.SingleLine = true;
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff ";
});
builder.ConfigureLogging(options =>
options.AddFile($"{Configuration.AppDirectory?.FullName}/" + "logs/agent_{Date}.log", LogLevel.Trace, fileSizeLimitBytes: 104857600, retainedFileCountLimit: 10, outputTemplate: "{Timestamp:o} [{Level:u3}] {Message} {NewLine}{Exception}");
});
builder.ConfigureServices((host, services) =>
{
// HOST-SERVICES
services.AddHostedService<UpdateService>();
services.AddHostedService<TrapService>();
// SERVICES (WINDOWS)
if (OperatingSystem.IsWindows()) services.AddHostedService<EventService>();
if (OperatingSystem.IsWindows()) services.AddSingleton<ScriptService>();
// AGENT NETWORKING
services.UseHostedClient<AgentSession, IMessage>(options =>
{
options.ClearProviders();
options.SetMinimumLevel(LogLevel.Trace);
options.Host = host.Configuration.GetValue<string?>(Appsettings.ServerHost) ?? throw new Exception($"{Appsettings.ServerHost} value not set (appsettings)");
options.Port = host.Configuration.GetValue<int?>(Appsettings.ServerPort) ?? throw new Exception($"{Appsettings.ServerPort} value not set (appsettings)");
options.Keepalive = 10000;
options.Timeout = 30000;
options.AddSimpleConsole(options =>
{
options.IncludeScopes = true;
options.SingleLine = true;
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff ";
});
options.Compression = true;
options.Encryption = Encryption.Tls12;
options.AddFile($"{Configuration.AppDirectory?.FullName}/" + "logs/agent_{Date}.log", LogLevel.Trace, fileSizeLimitBytes: 104857600, retainedFileCountLimit: 10, outputTemplate: "{Timestamp:o} [{Level:u3}] {Message} {NewLine}{Exception}");
options.UseSerializer<AgentSession, IMessage, MemPackSerializer<IMessage>>();
});
builder.ConfigureServices((host, services) =>
services.AddSingleton<IMessageHandler<AgentSession>, CustomHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, ProxyHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, AuthenticationHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, DriveHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, InterfaceHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, MainboardHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, MemoryHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, OperationSystemHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, PrinterHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, ProcessorHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, ServiceHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, SessionHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, SoftwareHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, StoragePoolHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, SystemInfoHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, UpdateHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, UserHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, VideocardHandler>();
services.AddSingleton<IMessageHandler<AgentSession>, VirtualMaschineHandler>();
// GLOBAL DEPENDENCIES
//services.AddSingleton<Bus>();
services.AddTransient(provider => new HttpClient(new HttpClientHandler
{
// SERVICES
services.AddHostedService<UpdateService>();
services.AddHostedService<TrapService>();
ClientCertificateOptions = ClientCertificateOption.Manual,
ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true
}));
});
// SERVICES (WINDOWS)
if (OperatingSystem.IsWindows()) services.AddHostedService<EventService>();
// AGENT NETWORKING
services.UseHostedClient<AgentSession, IAgentMessage>(options =>
{
options.Host = host.Configuration.GetValue<string?>(Appsettings.ServerHost) ?? throw new Exception($"{Appsettings.ServerHost} value not set (appsettings)");
options.Port = host.Configuration.GetValue<int?>(Appsettings.ServerPort) ?? throw new Exception($"{Appsettings.ServerPort} value not set (appsettings)");
options.Keepalive = 10000;
options.Timeout = 30000;
options.Encryption = Encryption.Tls12;
options.UseSerializer<MemPackSerializer<IAgentMessage>, IAgentMessage>();
});
services.AddSingleton<IAgentMessageHandler<AgentSession>, AuthenticationHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, DriveHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, InterfaceHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, MainboardHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, MemoryHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, OperationSystemHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, PrinterHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, ProcessorHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, ServiceHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, SessionHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, SoftwareHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, StoragePoolHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, SystemInfoHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, UpdateHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, UserHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, VideocardHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, VirtualMaschineHandler>();
services.AddSingleton<IAgentMessageHandler<AgentSession>, ConsoleHandler>();
// GLOBAL DEPENDENCIES
services.AddTransient(provider => new HttpClient(new HttpClientHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual,
ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true
}));
});
var host = builder.Build();
await host.RunAsync().ConfigureAwait(false);
}
var host = builder.Build();
await host.RunAsync().ConfigureAwait(false);
}
}

View file

@ -2,16 +2,15 @@
using Microsoft.Extensions.Logging.Abstractions;
using System.Runtime.Versioning;
namespace Insight.Agent.Services
{
[SupportedOSPlatform("linux")]
public partial class CollectorService
{
public ILogger<CollectorService> Logger { get; }
namespace Insight.Agent.Services;
public CollectorService(ILogger<CollectorService>? logger = null)
{
Logger = logger ?? NullLogger<CollectorService>.Instance;
}
[SupportedOSPlatform("linux")]
public partial class CollectorService
{
public ILogger<CollectorService> Logger { get; }
public CollectorService(ILogger<CollectorService>? logger = null)
{
Logger = logger ?? NullLogger<CollectorService>.Instance;
}
}

View file

@ -1,97 +1,96 @@
using System.Text.Json;
namespace Insight.Agent.Services
namespace Insight.Agent.Services;
public static class Configurator
{
public static class Configurator
public static async ValueTask<TConfig> ReadAsync<TConfig>(string file, CancellationToken cancellationToken = default)
where TConfig : class
{
public static async ValueTask<TConfig> ReadAsync<TConfig>(string file, CancellationToken cancellationToken = default)
where TConfig : class
var json = await File.ReadAllTextAsync(file, cancellationToken);
if (JsonSerializer.Deserialize<TConfig>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true, WriteIndented = true }) is not TConfig config)
{
var json = await File.ReadAllTextAsync(file, cancellationToken);
if (JsonSerializer.Deserialize<TConfig>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true, WriteIndented = true }) is not TConfig config)
{
throw new InvalidDataException($"Failed to deserialize ({file})");
}
return config;
}
public static async ValueTask<JsonDocument> ReadJsonAsync(string file, CancellationToken cancellationToken = default)
{
var json = await File.ReadAllTextAsync(file, cancellationToken);
if (JsonDocument.Parse(json) is not JsonDocument doc)
{
throw new InvalidDataException($"Failed to deserialize ({file})");
}
return doc;
}
public static async ValueTask<IDictionary<string, object>> ReadDictionaryAsync(string file, CancellationToken cancellationToken = default)
{
var json = await File.ReadAllTextAsync(file, cancellationToken);
if (JsonSerializer.Deserialize<IDictionary<string, object>>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true, WriteIndented = true }) is not IDictionary<string, object> config)
{
throw new InvalidDataException($"Failed to deserialize ({file})");
}
return config;
throw new InvalidDataException($"Failed to deserialize ({file})");
}
public static async ValueTask WriteAsync<TConfig>(TConfig config, string file, CancellationToken cancellationToken) where TConfig : class
return config;
}
public static async ValueTask<JsonDocument> ReadJsonAsync(string file, CancellationToken cancellationToken = default)
{
var json = await File.ReadAllTextAsync(file, cancellationToken);
if (JsonDocument.Parse(json) is not JsonDocument doc)
{
await WriteToFileAsync(config, file, cancellationToken);
}
public static async ValueTask WriteAsync(JsonDocument config, string file, CancellationToken cancellationToken)
{
await WriteToFileAsync(config, file, cancellationToken);
}
public static async ValueTask WriteAsync(IDictionary<string, object?> config, string file, CancellationToken cancellationToken)
{
await WriteToFileAsync(config, file, cancellationToken);
throw new InvalidDataException($"Failed to deserialize ({file})");
}
public static async ValueTask AddOrUpdateAsync(KeyValuePair<string, object> data, string file, CancellationToken cancellationToken)
return doc;
}
public static async ValueTask<IDictionary<string, object>> ReadDictionaryAsync(string file, CancellationToken cancellationToken = default)
{
var json = await File.ReadAllTextAsync(file, cancellationToken);
if (JsonSerializer.Deserialize<IDictionary<string, object>>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true, WriteIndented = true }) is not IDictionary<string, object> config)
{
var readData = await ReadDictionaryAsync(file, cancellationToken);
var key = readData.Keys.FirstOrDefault(dic => string.Compare(dic, data.Key, StringComparison.OrdinalIgnoreCase) == 0);
if (key is null)
{
readData.Add(data.Key, data.Value);
}
else
{
readData[key] = data.Value;
}
await WriteToFileAsync(readData, file, cancellationToken);
}
public static async ValueTask RemoveAsync(string data, string file, CancellationToken cancellationToken)
{
var readData = await ReadDictionaryAsync(file, cancellationToken);
var key = readData.Keys.FirstOrDefault(dic => string.Compare(dic, data, StringComparison.OrdinalIgnoreCase) == 0);
if (key is null)
{
return;
}
else
{
readData.Remove(key);
}
await WriteToFileAsync(readData, file, cancellationToken);
throw new InvalidDataException($"Failed to deserialize ({file})");
}
private static async ValueTask WriteToFileAsync<TData>(TData data, string file, CancellationToken cancellationToken)
{
var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true });
return config;
}
await File.WriteAllTextAsync(file, json, cancellationToken);
public static async ValueTask WriteAsync<TConfig>(TConfig config, string file, CancellationToken cancellationToken) where TConfig : class
{
await WriteToFileAsync(config, file, cancellationToken);
}
public static async ValueTask WriteAsync(JsonDocument config, string file, CancellationToken cancellationToken)
{
await WriteToFileAsync(config, file, cancellationToken);
}
public static async ValueTask WriteAsync(IDictionary<string, object?> config, string file, CancellationToken cancellationToken)
{
await WriteToFileAsync(config, file, cancellationToken);
}
public static async ValueTask AddOrUpdateAsync(KeyValuePair<string, object> data, string file, CancellationToken cancellationToken)
{
var readData = await ReadDictionaryAsync(file, cancellationToken);
var key = readData.Keys.FirstOrDefault(dic => string.Compare(dic, data.Key, StringComparison.OrdinalIgnoreCase) == 0);
if (key is null)
{
readData.Add(data.Key, data.Value);
}
else
{
readData[key] = data.Value;
}
await WriteToFileAsync(readData, file, cancellationToken);
}
public static async ValueTask RemoveAsync(string data, string file, CancellationToken cancellationToken)
{
var readData = await ReadDictionaryAsync(file, cancellationToken);
var key = readData.Keys.FirstOrDefault(dic => string.Compare(dic, data, StringComparison.OrdinalIgnoreCase) == 0);
if (key is null)
{
return;
}
else
{
readData.Remove(key);
}
await WriteToFileAsync(readData, file, cancellationToken);
}
private static async ValueTask WriteToFileAsync<TData>(TData data, string file, CancellationToken cancellationToken)
{
var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true });
await File.WriteAllTextAsync(file, json, cancellationToken);
}
}

View file

@ -1,170 +1,170 @@
using Insight.Agent.Messages;
using Insight.Agent.Network;
using Insight.Agent.Network;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Diagnostics.Eventing.Reader;
using System.Runtime.Versioning;
using System.Threading.Channels;
using Vaitr.Network;
using static Insight.Agent.Messages.Event;
using static Insight.Domain.Network.Agent.Messages.Event;
using EventLevel = System.Diagnostics.Tracing.EventLevel;
namespace Insight.Agent.Services
namespace Insight.Agent.Services;
[SupportedOSPlatform("windows")]
internal class EventService : BackgroundService
{
[SupportedOSPlatform("windows")]
internal class EventService : BackgroundService
private readonly Channel<Event> _queue;
private readonly ISessionPool<AgentSession, IMessage> _pool;
private readonly ILogger<EventService> _logger;
public EventService(ISessionPool<AgentSession, IMessage> pool, ILogger<EventService> logger)
{
private readonly Channel<Event> _queue;
private readonly ISessionPool<AgentSession, IAgentMessage> _pool;
private readonly ILogger<EventService> _logger;
_pool = pool;
_logger = logger;
public EventService(ISessionPool<AgentSession, IAgentMessage> pool, ILogger<EventService> logger)
_queue = Channel.CreateBounded<Event>(new BoundedChannelOptions(1000)
{
_pool = pool;
_logger = logger;
SingleReader = true,
SingleWriter = true,
AllowSynchronousContinuations = false,
FullMode = BoundedChannelFullMode.DropOldest
});
}
_queue = Channel.CreateBounded<Event>(new BoundedChannelOptions(1000)
{
SingleReader = true,
SingleWriter = true,
AllowSynchronousContinuations = false,
FullMode = BoundedChannelFullMode.DropOldest
});
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
_logger.LogTrace("ExecuteAsync");
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
while (cancellationToken.IsCancellationRequested is false)
{
_logger.LogTrace("ExecuteAsync");
while (cancellationToken.IsCancellationRequested is false)
{
try
{
var tasks = new List<Task>
{
HandleQueueAsync(cancellationToken),
WatchAsync("Application", "*", cancellationToken),
WatchAsync("Security", "*", cancellationToken),
WatchAsync("System", "*", cancellationToken),
WatchAsync("Microsoft-Windows-PrintService/Admin", "*", cancellationToken),
WatchAsync("Microsoft-Windows-TaskScheduler/Operational", "*", cancellationToken),
WatchAsync("Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational", "*", cancellationToken),
WatchAsync("Microsoft-Windows-TerminalServices-LocalSessionManager/Operational", "*", cancellationToken),
WatchAsync("Microsoft-Windows-TerminalServices-RDPClient/Operational", "*", cancellationToken),
WatchAsync("Microsoft-Windows-SmbClient/Connectivity", "*", cancellationToken),
WatchAsync("Microsoft-Windows-SmbClient/Security", "*", cancellationToken),
WatchAsync("Microsoft-Windows-SMBServer/Security", "*", cancellationToken),
WatchAsync("Microsoft-Windows-StorageSpaces-Driver/Operational", "*", cancellationToken),
WatchAsync("Microsoft-Windows-Diagnostics-Performance/Operational", "*", cancellationToken)
};
await Task.WhenAll(tasks);
}
catch (OperationCanceledException) { }
catch (Exception ex)
{
_logger.LogError("{ex}", ex);
}
}
}
private async Task WatchAsync(string path, string query, CancellationToken cancellationToken)
{
var config = new EventLogConfiguration(path);
if (config is null) return;
if (config.IsEnabled is false)
{
config.IsEnabled = true;
config.SaveChanges();
}
var watcher = new EventLogWatcher(new EventLogQuery(path, PathType.LogName, query)
{
TolerateQueryErrors = true,
Session = EventLogSession.GlobalSession
});
try
{
watcher.EventRecordWritten += new EventHandler<EventRecordWrittenEventArgs>(OnEvent);
watcher.Enabled = true;
using var semaphore = new SemaphoreSlim(0, 1);
await semaphore.WaitAsync(cancellationToken);
}
catch (Exception) { }
finally
{
watcher.EventRecordWritten -= new EventHandler<EventRecordWrittenEventArgs>(OnEvent);
watcher.Enabled = false;
watcher?.Dispose();
}
}
private async Task HandleQueueAsync(CancellationToken cancellationToken)
{
while (await _queue.Reader.WaitToReadAsync(cancellationToken))
{
var session = _pool.FirstOrDefault();
if (session.Value is null)
var tasks = new List<Task>
{
await Task.Delay(10000, cancellationToken);
continue;
}
if (_queue.Reader.TryRead(out var item) is false)
{
await Task.Delay(1000, cancellationToken);
continue;
}
try
{
await session.Value.SendAsync(item, cancellationToken);
}
catch (OperationCanceledException) { }
catch (Exception ex)
{
_logger.LogError("{ex}", ex);
await Task.Delay(10000, cancellationToken);
}
}
}
private void OnEvent(object? sender, EventRecordWrittenEventArgs e)
{
if (e is null || e.EventRecord is null) return;
try
{
var @event = new Event
{
Timestamp = e?.EventRecord?.TimeCreated,
EventId = e?.EventRecord?.Id,
Source = e?.EventRecord?.ProviderName,
Category = e?.EventRecord?.LogName,
Task = e?.EventRecord?.TaskDisplayName,
Message = e?.EventRecord?.FormatDescription(),
HandleQueueAsync(cancellationToken),
WatchAsync("Application", "*", cancellationToken),
WatchAsync("Security", "*", cancellationToken),
WatchAsync("System", "*", cancellationToken),
WatchAsync("Microsoft-Windows-PrintService/Admin", "*", cancellationToken),
WatchAsync("Microsoft-Windows-TaskScheduler/Operational", "*", cancellationToken),
WatchAsync("Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational", "*", cancellationToken),
WatchAsync("Microsoft-Windows-TerminalServices-LocalSessionManager/Operational", "*", cancellationToken),
WatchAsync("Microsoft-Windows-TerminalServices-RDPClient/Operational", "*", cancellationToken),
WatchAsync("Microsoft-Windows-SmbClient/Connectivity", "*", cancellationToken),
WatchAsync("Microsoft-Windows-SmbClient/Security", "*", cancellationToken),
WatchAsync("Microsoft-Windows-SMBServer/Security", "*", cancellationToken),
WatchAsync("Microsoft-Windows-StorageSpaces-Driver/Operational", "*", cancellationToken),
WatchAsync("Microsoft-Windows-Diagnostics-Performance/Operational", "*", cancellationToken)
};
if (e?.EventRecord?.Level is not null)
{
@event.Status = (EventLevel)Convert.ToInt32(e?.EventRecord?.Level) switch
{
EventLevel.Informational => StatusType.Information,
EventLevel.Warning => StatusType.Warning,
EventLevel.Error => StatusType.Error,
EventLevel.Critical => StatusType.Critical,
_ => StatusType.Information,
};
}
_queue.Writer.WriteAsync(@event, default);
await Task.WhenAll(tasks);
}
catch (OperationCanceledException) { }
catch (Exception ex)
{
_logger.LogError("{ex}", ex);
}
catch (Exception) { } // app crash
}
}
private async Task WatchAsync(string path, string query, CancellationToken cancellationToken)
{
var config = new EventLogConfiguration(path);
if (config is null) return;
if (config.IsEnabled is false)
{
config.IsEnabled = true;
config.SaveChanges();
}
var watcher = new EventLogWatcher(new EventLogQuery(path, PathType.LogName, query)
{
TolerateQueryErrors = true,
Session = EventLogSession.GlobalSession
});
try
{
watcher.EventRecordWritten += new EventHandler<EventRecordWrittenEventArgs>(OnEvent);
watcher.Enabled = true;
using var semaphore = new SemaphoreSlim(0, 1);
await semaphore.WaitAsync(cancellationToken);
}
catch (Exception) { }
finally
{
watcher.EventRecordWritten -= new EventHandler<EventRecordWrittenEventArgs>(OnEvent);
watcher.Enabled = false;
watcher?.Dispose();
}
}
private async Task HandleQueueAsync(CancellationToken cancellationToken)
{
while (await _queue.Reader.WaitToReadAsync(cancellationToken))
{
var session = _pool.FirstOrDefault();
if (session.Value is null)
{
await Task.Delay(10000, cancellationToken);
continue;
}
if (_queue.Reader.TryRead(out var item) is false)
{
await Task.Delay(1000, cancellationToken);
continue;
}
try
{
await session.Value.SendAsync(item, cancellationToken);
}
catch (OperationCanceledException) { }
catch (Exception ex)
{
_logger.LogError("{ex}", ex);
await Task.Delay(10000, cancellationToken);
}
}
}
private void OnEvent(object? sender, EventRecordWrittenEventArgs e)
{
if (e is null || e.EventRecord is null) return;
try
{
var @event = new Event
{
Timestamp = e?.EventRecord?.TimeCreated,
EventId = e?.EventRecord?.Id,
Source = e?.EventRecord?.ProviderName,
Category = e?.EventRecord?.LogName,
Task = e?.EventRecord?.TaskDisplayName,
Message = e?.EventRecord?.FormatDescription(),
};
if (e?.EventRecord?.Level is not null)
{
@event.Status = (EventLevel)Convert.ToInt32(e?.EventRecord?.Level) switch
{
EventLevel.Informational => StatusType.Information,
EventLevel.Warning => StatusType.Warning,
EventLevel.Error => StatusType.Error,
EventLevel.Critical => StatusType.Critical,
_ => StatusType.Information,
};
}
_queue.Writer.WriteAsync(@event, default);
}
catch (Exception) { } // app crash
}
}

View file

@ -1,36 +1,19 @@
using Insight.Agent.Interfaces;
using Insight.Agent.Messages;
using Microsoft.Extensions.Logging;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
namespace Insight.Agent.Network.Handlers;
namespace Insight.Agent.Services;
public class ConsoleHandler : IAgentMessageHandler<AgentSession>
public class ScriptService
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
private readonly ILogger<ScriptService> _logger;
public ScriptService(ILogger<ScriptService> logger)
{
if (message is ConsoleQueryRequest consoleQueryRequest)
{
await OnConsoleQueryRequestAsync(sender, consoleQueryRequest, cancellationToken);
}
_logger = logger;
}
private async ValueTask OnConsoleQueryRequestAsync(AgentSession sender, ConsoleQueryRequest consoleQueryRequest, CancellationToken cancellationToken)
{
var result = await QueryScriptAsync(consoleQueryRequest.Query);
await sender.SendAsync(new ConsoleQuery
{
Id = consoleQueryRequest.Id,
HostId = consoleQueryRequest.HostId,
Query = consoleQueryRequest.Query,
Data = result.Data,
Errors = result.Errors,
HadErrors = result.HadErrors
}, cancellationToken);
}
private static async Task<QueryResult> QueryScriptAsync(string query)
public async Task<QueryResult> QueryAsync(string query)
{
var result = new QueryResult();
var errors = new List<string>();
@ -44,7 +27,7 @@ public class ConsoleHandler : IAgentMessageHandler<AgentSession>
using var ps = PowerShell.Create(runspace);
ps.AddScript("Set-ExecutionPolicy unrestricted -Scope Process");
ps.AddScript(query);
ps.AddCommand("ConvertTo-Json"); // -Depth 10
//ps.AddCommand("ConvertTo-Json"); // -Depth 10
result.Query = query;
@ -57,7 +40,15 @@ public class ConsoleHandler : IAgentMessageHandler<AgentSession>
}
else
{
result.Data = queryResult[0].ToString();
var newLine = false;
foreach (var data in queryResult)
{
if (newLine) result.Data += "\n";
else newLine = true;
result.Data += data.ToString();
}
//if (string.IsNullOrWhiteSpace(jsonString)) return result;
@ -100,12 +91,12 @@ public class ConsoleHandler : IAgentMessageHandler<AgentSession>
result.Errors = string.Join("\n", errors);
return result;
}
}
public class QueryResult
{
public bool HadErrors { get; set; }
public string? Query { get; set; }
public string? Data { get; set; }
public string? Errors { get; set; }
public class QueryResult
{
public bool HadErrors { get; set; }
public string? Query { get; set; }
public string? Data { get; set; }
public string? Errors { get; set; }
}
}

View file

@ -1,5 +1,6 @@
using Insight.Agent.Messages;
using Insight.Agent.Network;
using Insight.Agent.Network;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
@ -9,192 +10,190 @@ using System.Net.Sockets;
using System.Threading.Channels;
using Vaitr.Network;
namespace Insight.Agent.Services
namespace Insight.Agent.Services;
public class TrapService : BackgroundService
{
public class TrapService : BackgroundService
private static IPEndPoint EndpointCache { get; } = new(IPAddress.Any, 0);
private readonly Channel<Trap> _queue;
private readonly int _port;
private readonly ISessionPool<AgentSession, IMessage> _pool;
private readonly ILogger<TrapService> _logger;
public TrapService(ISessionPool<AgentSession, IMessage> pool, IConfiguration configuration, ILogger<TrapService> logger)
{
private static IPEndPoint EndpointCache { get; } = new(IPAddress.Any, 0);
private readonly Channel<Trap> _queue;
_port = configuration.GetValue<int?>(Appsettings.TrapPort) ?? throw new Exception($"{Appsettings.TrapPort} value not set (appsettings)");
_pool = pool;
_logger = logger;
private readonly int _port;
private readonly ISessionPool<AgentSession, IAgentMessage> _pool;
private readonly ILogger<TrapService> _logger;
public TrapService(ISessionPool<AgentSession, IAgentMessage> pool, IConfiguration configuration, ILogger<TrapService> logger)
_queue = Channel.CreateBounded<Trap>(new BoundedChannelOptions(100)
{
_port = configuration.GetValue<int?>(Appsettings.TrapPort) ?? throw new Exception($"{Appsettings.TrapPort} value not set (appsettings)");
_pool = pool;
_logger = logger;
SingleReader = false,
SingleWriter = true,
AllowSynchronousContinuations = false,
FullMode = BoundedChannelFullMode.DropOldest
});
}
_queue = Channel.CreateBounded<Trap>(new BoundedChannelOptions(100)
{
SingleReader = false,
SingleWriter = true,
AllowSynchronousContinuations = false,
FullMode = BoundedChannelFullMode.DropOldest
});
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
_logger.LogTrace("ExecuteAsync");
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
while (cancellationToken.IsCancellationRequested is false)
{
_logger.LogTrace("ExecuteAsync");
while (cancellationToken.IsCancellationRequested is false)
{
try
{
var tasks = new List<Task>
{
HandleQueueAsync(cancellationToken),
ListenAsync(cancellationToken)
};
await Task.WhenAll(tasks);
}
catch (OperationCanceledException) { }
catch (Exception ex)
{
_logger.LogError("{ex}", ex);
}
}
}
private async Task HandleQueueAsync(CancellationToken cancellationToken)
{
while (await _queue.Reader.WaitToReadAsync(cancellationToken))
{
var session = _pool.FirstOrDefault();
if (session.Value is null)
{
await Task.Delay(10000, cancellationToken);
continue;
}
if (_queue.Reader.TryRead(out var item) is false)
{
await Task.Delay(1000, cancellationToken);
continue;
}
try
{
await session.Value.SendAsync(item, cancellationToken);
}
catch (OperationCanceledException) { }
catch (Exception ex)
{
_logger.LogError("{ex}", ex);
await Task.Delay(10000, cancellationToken);
}
}
}
private async Task ListenAsync(CancellationToken cancellationToken)
{
using var udpSocket = new Socket(SocketType.Dgram, ProtocolType.Udp);
cancellationToken.Register(udpSocket.Dispose);
udpSocket.Bind(new IPEndPoint(IPAddress.Any, _port));
var buffer = GC.AllocateArray<byte>(length: 65527, pinned: true);
var bufferMem = buffer.AsMemory();
while (cancellationToken.IsCancellationRequested is false)
{
try
{
var result = await udpSocket.ReceiveFromAsync(bufferMem, SocketFlags.None, EndpointCache, cancellationToken);
if (result.ReceivedBytes == 0) continue;
var actualBytes = bufferMem[..result.ReceivedBytes].ToArray();
var ep = (IPEndPoint)result.RemoteEndPoint;
await ProcessAsync(ep, actualBytes, cancellationToken);
}
catch (SocketException) { continue; }
catch (IOException) { continue; }
catch (Exception) { continue; }
}
}
private async ValueTask ProcessAsync(IPEndPoint endpoint, byte[] buffer, CancellationToken cancellationToken)
{
var trap = new Trap
{
Timestamp = DateTime.Now,
Endpoint = endpoint.ToString(),
};
try
{
var protocol = (SnmpVersion)SnmpPacket.GetProtocolVersion(buffer, buffer.Length);
trap.Version = protocol.ToString();
trap.Hostname = Dns.GetHostEntry(endpoint.Address)?.HostName;
if (protocol == SnmpVersion.Ver1)
var tasks = new List<Task>
{
var packet = new SnmpV1TrapPacket();
packet.decode(buffer, buffer.Length);
HandleQueueAsync(cancellationToken),
ListenAsync(cancellationToken)
};
trap.Community = packet?.Community?.ToString();
if (packet?.Pdu?.VbList is not null)
{
trap.Data = ConvertVbs(packet.Pdu.VbList);
}
}
if (protocol == SnmpVersion.Ver2)
{
var packet = new SnmpV2Packet();
packet.decode(buffer, buffer.Length);
trap.Community = packet?.Community?.ToString();
if (packet?.Pdu?.VbList is not null)
{
trap.Data = ConvertVbs(packet.Pdu.VbList);
}
}
if (protocol == SnmpVersion.Ver3)
{
var packet = new SnmpV3Packet();
}
await Task.WhenAll(tasks);
}
catch (OperationCanceledException) { }
catch (Exception ex)
{
_logger.LogError("{ex}", ex);
}
await _queue.Writer.WriteAsync(trap, cancellationToken);
}
private List<KeyValuePair<string, string?>>? ConvertVbs(VbCollection vbs)
{
var data = new List<KeyValuePair<string, string?>>();
try
{
foreach (var item in vbs)
{
if (item.Oid is null) continue;
data.Add(new KeyValuePair<string, string?>(item.Oid.ToString(), item?.Value?.ToString()));
}
}
catch (Exception ex)
{
_logger.LogError("{ex}", ex);
}
return data;
}
}
private async Task HandleQueueAsync(CancellationToken cancellationToken)
{
while (await _queue.Reader.WaitToReadAsync(cancellationToken))
{
var session = _pool.FirstOrDefault();
if (session.Value is null)
{
await Task.Delay(10000, cancellationToken);
continue;
}
if (_queue.Reader.TryRead(out var item) is false)
{
await Task.Delay(1000, cancellationToken);
continue;
}
try
{
await session.Value.SendAsync(item, cancellationToken);
}
catch (OperationCanceledException) { }
catch (Exception ex)
{
_logger.LogError("{ex}", ex);
await Task.Delay(10000, cancellationToken);
}
}
}
private async Task ListenAsync(CancellationToken cancellationToken)
{
using var udpSocket = new Socket(SocketType.Dgram, ProtocolType.Udp);
cancellationToken.Register(udpSocket.Dispose);
udpSocket.Bind(new IPEndPoint(IPAddress.Any, _port));
var buffer = GC.AllocateArray<byte>(length: 65527, pinned: true);
var bufferMem = buffer.AsMemory();
while (cancellationToken.IsCancellationRequested is false)
{
try
{
var result = await udpSocket.ReceiveFromAsync(bufferMem, SocketFlags.None, EndpointCache, cancellationToken);
if (result.ReceivedBytes == 0) continue;
var actualBytes = bufferMem[..result.ReceivedBytes].ToArray();
var ep = (IPEndPoint)result.RemoteEndPoint;
await ProcessAsync(ep, actualBytes, cancellationToken);
}
catch (SocketException) { continue; }
catch (IOException) { continue; }
catch (Exception) { continue; }
}
}
private async ValueTask ProcessAsync(IPEndPoint endpoint, byte[] buffer, CancellationToken cancellationToken)
{
var trap = new Trap
{
Timestamp = DateTime.Now,
Endpoint = endpoint.ToString(),
};
try
{
var protocol = (SnmpVersion)SnmpPacket.GetProtocolVersion(buffer, buffer.Length);
trap.Version = protocol.ToString();
trap.Hostname = Dns.GetHostEntry(endpoint.Address)?.HostName;
if (protocol == SnmpVersion.Ver1)
{
var packet = new SnmpV1TrapPacket();
packet.decode(buffer, buffer.Length);
trap.Community = packet?.Community?.ToString();
if (packet?.Pdu?.VbList is not null)
{
trap.Data = ConvertVbs(packet.Pdu.VbList);
}
}
if (protocol == SnmpVersion.Ver2)
{
var packet = new SnmpV2Packet();
packet.decode(buffer, buffer.Length);
trap.Community = packet?.Community?.ToString();
if (packet?.Pdu?.VbList is not null)
{
trap.Data = ConvertVbs(packet.Pdu.VbList);
}
}
if (protocol == SnmpVersion.Ver3)
{
var packet = new SnmpV3Packet();
}
}
catch (Exception ex)
{
_logger.LogError("{ex}", ex);
}
await _queue.Writer.WriteAsync(trap, cancellationToken);
}
private List<KeyValuePair<string, string?>>? ConvertVbs(VbCollection vbs)
{
var data = new List<KeyValuePair<string, string?>>();
try
{
foreach (var item in vbs)
{
if (item.Oid is null) continue;
data.Add(new KeyValuePair<string, string?>(item.Oid.ToString(), item?.Value?.ToString()));
}
}
catch (Exception ex)
{
_logger.LogError("{ex}", ex);
}
return data;
}
}

View file

@ -10,351 +10,350 @@ using System.Runtime.Versioning;
using System.ServiceProcess;
using System.Text.Json;
namespace Insight.Agent.Services
namespace Insight.Agent.Services;
internal class UpdateService : BackgroundService
{
internal class UpdateService : BackgroundService
private readonly Uri _uri;
private readonly HttpClient _httpClient;
private readonly ILogger<UpdateService> _logger;
public UpdateService(HttpClient httpClient, IConfiguration configuration, ILogger<UpdateService> logger)
{
private readonly Uri _uri;
_httpClient = httpClient;
_uri = configuration.GetValue<Uri?>("api") ?? throw new Exception($"api value not set (appsettings)");
_logger = logger;
}
private readonly HttpClient _httpClient;
private readonly ILogger<UpdateService> _logger;
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
_logger.LogTrace("ExecuteAsync");
public UpdateService(HttpClient httpClient, IConfiguration configuration, ILogger<UpdateService> logger)
while (cancellationToken.IsCancellationRequested is false)
{
_httpClient = httpClient;
_uri = configuration.GetValue<Uri?>("api") ?? throw new Exception($"api value not set (appsettings)");
_logger = logger;
try
{
UpdateResult? result = null;
if (OperatingSystem.IsWindows()) result = await WindowsUpdateAsync(cancellationToken);
if (OperatingSystem.IsLinux()) result = await LinuxUpdateAsync(cancellationToken);
_logger.LogInformation("Update Result: {result}", result?.Success);
if (result?.UpdateErrors is not null)
{
_logger.LogError("Update Errors: {errors}", string.Concat(result?.UpdateErrors));
}
}
catch (OperationCanceledException) { }
catch (Exception ex) // may inform via client / api about errors
{
_logger.LogError("{ex}", ex.Message);
}
finally
{
await Task.Delay(TimeSpan.FromMinutes(1), cancellationToken);
}
}
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
[SupportedOSPlatform("windows")]
private async ValueTask<UpdateResult> WindowsUpdateAsync(CancellationToken cancellationToken)
{
return await Windows.Service.UpdateAsync(
_httpClient,
Deploy.GetUpdateHref(_uri, Deploy.Updater.Name),
Deploy.GetAppExecutable(Deploy.Updater.Name),
Deploy.Updater.ServiceName,
cancellationToken);
}
[SupportedOSPlatform("linux")]
private ValueTask<UpdateResult> LinuxUpdateAsync(CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
[SupportedOSPlatform("windows")]
private static class Windows
{
public static class Service
{
_logger.LogTrace("ExecuteAsync");
while (cancellationToken.IsCancellationRequested is false)
public static bool ServiceExistence(string serviceName)
{
try
{
UpdateResult? result = null;
if (ServiceController.GetServices().Any(s => s.ServiceName.Equals(serviceName, StringComparison.InvariantCultureIgnoreCase))) return true;
return false;
}
catch (Exception) { }
if (OperatingSystem.IsWindows()) result = await WindowsUpdateAsync(cancellationToken);
if (OperatingSystem.IsLinux()) result = await LinuxUpdateAsync(cancellationToken);
_logger.LogInformation("Update Result: {result}", result?.Success);
if (result?.UpdateErrors is not null)
{
_logger.LogError("Update Errors: {errors}", string.Concat(result?.UpdateErrors));
}
}
catch (OperationCanceledException) { }
catch (Exception ex) // may inform via client / api about errors
{
_logger.LogError("{ex}", ex.Message);
}
finally
{
await Task.Delay(TimeSpan.FromMinutes(1), cancellationToken);
}
return false;
}
}
[SupportedOSPlatform("windows")]
private async ValueTask<UpdateResult> WindowsUpdateAsync(CancellationToken cancellationToken)
{
return await Windows.Service.UpdateAsync(
_httpClient,
Deploy.GetUpdateHref(_uri, Deploy.Updater.Name),
Deploy.GetAppExecutable(Deploy.Updater.Name),
Deploy.Updater.ServiceName,
cancellationToken);
}
[SupportedOSPlatform("linux")]
private ValueTask<UpdateResult> LinuxUpdateAsync(CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
[SupportedOSPlatform("windows")]
private static class Windows
{
public static class Service
public static bool SetServiceState(string app, ServiceControllerStatus status, TimeSpan timeout)
{
public static bool ServiceExistence(string serviceName)
try
{
try
using var sc = ServiceController.GetServices().FirstOrDefault(s => s.ServiceName.Equals(app, StringComparison.InvariantCultureIgnoreCase));
if (sc is null) return false;
if (sc.Status != status)
{
if (ServiceController.GetServices().Any(s => s.ServiceName.Equals(serviceName, StringComparison.InvariantCultureIgnoreCase))) return true;
return false;
switch (status)
{
case ServiceControllerStatus.Running:
sc.Start();
break;
case ServiceControllerStatus.Stopped:
sc.Stop();
break;
}
sc.WaitForStatus(status, timeout);
}
catch (Exception) { }
return false;
return true;
}
catch (Exception) { }
public static bool SetServiceState(string app, ServiceControllerStatus status, TimeSpan timeout)
return false;
}
public static async ValueTask<UpdateResult> UpdateAsync(HttpClient httpClient, Uri api, FileInfo bin, string serviceName, CancellationToken cancellationToken)
{
var result = new UpdateResult
{
try
Api = api?.ToString(),
SourceDirectory = bin.Directory?.FullName,
App = bin.Name,
ServiceName = serviceName
};
try
{
// check if service exists
if (ServiceExistence(serviceName) is false)
{
using var sc = ServiceController.GetServices().FirstOrDefault(s => s.ServiceName.Equals(app, StringComparison.InvariantCultureIgnoreCase));
if (sc is null) return false;
if (sc.Status != status)
{
switch (status)
{
case ServiceControllerStatus.Running:
sc.Start();
break;
case ServiceControllerStatus.Stopped:
sc.Stop();
break;
}
sc.WaitForStatus(status, timeout);
}
return true;
result.UpdateErrors.Add("service not found");
return result;
}
catch (Exception) { }
return false;
}
public static async ValueTask<UpdateResult> UpdateAsync(HttpClient httpClient, Uri api, FileInfo bin, string serviceName, CancellationToken cancellationToken)
{
var result = new UpdateResult
// get service update details
var response = await httpClient.GetFromJsonAsync<UpdateResponse>(api, cancellationToken);
if (response is null)
{
Api = api?.ToString(),
SourceDirectory = bin.Directory?.FullName,
App = bin.Name,
ServiceName = serviceName
};
result.ApiErrors.Add("not available / response null");
return result;
}
try
result.ApiAvailable = true;
// check if local binary exists
if (bin is null)
{
// check if service exists
if (ServiceExistence(serviceName) is false)
{
result.UpdateErrors.Add("service not found");
return result;
}
result.UpdateErrors.Add("source binary not found");
return result;
}
// get service update details
var response = await httpClient.GetFromJsonAsync<UpdateResponse>(api, cancellationToken);
if (response is null)
{
result.ApiErrors.Add("not available / response null");
return result;
}
result.ApiAvailable = true;
// check if local binary exists
if (bin is null)
{
result.UpdateErrors.Add("source binary not found");
return result;
}
// get local file binary version
if (FileVersionInfo.GetVersionInfo(bin.FullName).FileVersion is not string binVersionString)
{
result.UpdateErrors.Add("source binary fileversion not valid");
return result;
}
// compare local against update version, skip lower or equal update version
var actualVersion = Version.Parse(binVersionString);
if (actualVersion >= response.Version)
{
result.Success = true;
return result;
}
else
{
result.UpdateAvailable = true;
}
// get update file (bytes) to memory
using var update = await httpClient.GetAsync(response.Uri, cancellationToken);
if (update is null)
{
result.ApiErrors.Add("update source not available");
return result;
}
// stop service
if (SetServiceState(serviceName, ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10)) is false)
{
result.UpdateErrors.Add("service control failed / failed to stop service");
return result;
}
// read update archive to temp (overwrite)
var temp = Directory.CreateTempSubdirectory();
var updateFile = new FileInfo($@"{temp.FullName}/{bin.Name}.zip");
await File.WriteAllBytesAsync(updateFile.FullName, await update.Content.ReadAsByteArrayAsync(cancellationToken), cancellationToken);
// extract update archive from temp to app dir (overwrite)
ZipFile.ExtractToDirectory(updateFile.FullName, bin.Directory?.FullName, true);
// delete temp folder
if (temp.Exists) temp.Delete(true);
// start updateds service
if (SetServiceState(serviceName, ServiceControllerStatus.Running, TimeSpan.FromSeconds(10)) is false)
{
result.UpdateErrors.Add("service control failed / failed to start service");
return result;
}
// get local file binary version
if (FileVersionInfo.GetVersionInfo(bin.FullName).FileVersion is not string binVersionString)
{
result.UpdateErrors.Add("source binary fileversion not valid");
return result;
}
// compare local against update version, skip lower or equal update version
var actualVersion = Version.Parse(binVersionString);
if (actualVersion >= response.Version)
{
result.Success = true;
return result;
}
catch (Exception ex)
else
{
result.UpdateErrors.Add(ex.Message);
result.UpdateAvailable = true;
}
return result;
// get update file (bytes) to memory
using var update = await httpClient.GetAsync(response.Uri, cancellationToken);
if (update is null)
{
result.ApiErrors.Add("update source not available");
return result;
}
// stop service
if (SetServiceState(serviceName, ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10)) is false)
{
result.UpdateErrors.Add("service control failed / failed to stop service");
return result;
}
// read update archive to temp (overwrite)
var temp = Directory.CreateTempSubdirectory();
var updateFile = new FileInfo($@"{temp.FullName}/{bin.Name}.zip");
await File.WriteAllBytesAsync(updateFile.FullName, await update.Content.ReadAsByteArrayAsync(cancellationToken), cancellationToken);
// extract update archive from temp to app dir (overwrite)
ZipFile.ExtractToDirectory(updateFile.FullName, bin.Directory?.FullName, true);
// delete temp folder
if (temp.Exists) temp.Delete(true);
// start updateds service
if (SetServiceState(serviceName, ServiceControllerStatus.Running, TimeSpan.FromSeconds(10)) is false)
{
result.UpdateErrors.Add("service control failed / failed to start service");
return result;
}
result.Success = true;
}
catch (Exception ex)
{
result.UpdateErrors.Add(ex.Message);
}
return result;
}
}
public static class Process
{
public static bool IsRunning(FileInfo bin)
{
if (bin.Exists is false) return false;
var matched = System.Diagnostics.Process.GetProcessesByName(bin.FullName);
if (matched is null || matched.Any() is false) return false;
if (matched.Any(p =>
p.MainModule is not null &&
p.MainModule.FileName is not null &&
p.MainModule.FileName.Equals(bin.FullName,
StringComparison.InvariantCultureIgnoreCase))) return true;
return false;
}
public static class Process
public static bool Start(FileInfo binary)
{
public static bool IsRunning(FileInfo bin)
try
{
if (bin.Exists is false) return false;
if (IsRunning(binary) is false) return false;
var matched = System.Diagnostics.Process.GetProcessesByName(bin.FullName);
if (matched is null || matched.Any() is false) return false;
if (matched.Any(p =>
p.MainModule is not null &&
p.MainModule.FileName is not null &&
p.MainModule.FileName.Equals(bin.FullName,
StringComparison.InvariantCultureIgnoreCase))) return true;
return false;
using var process = System.Diagnostics.Process.Start(binary.FullName);
return true;
}
catch (Exception) { }
public static bool Start(FileInfo binary)
{
try
{
if (IsRunning(binary) is false) return false;
return false;
}
using var process = System.Diagnostics.Process.Start(binary.FullName);
return true;
}
catch (Exception) { }
return false;
}
public static bool Stop(FileInfo bin, TimeSpan timeout)
{
try
{
if (IsRunning(bin) is false) return false;
var matched = System.Diagnostics.Process.GetProcessesByName(bin.FullName);
if (matched is null || matched.Any() is false) return true;
foreach (var procsInfo in matched.Where(p =>
p.MainModule is not null &&
p.MainModule.FileName is not null &&
p.MainModule.FileName.Equals(bin.FullName, StringComparison.InvariantCultureIgnoreCase)))
{
if (procsInfo.CloseMainWindow()) procsInfo.WaitForExit((int)timeout.TotalMilliseconds);
if (procsInfo.HasExited is false) procsInfo.Kill(true);
}
return true;
}
catch (Exception) { }
return false;
}
public static async ValueTask<bool> UpdateAsync(HttpClient httpClient, Uri api, FileInfo bin, CancellationToken cancellationToken)
public static bool Stop(FileInfo bin, TimeSpan timeout)
{
try
{
if (IsRunning(bin) is false) return false;
var response = await httpClient.GetFromJsonAsync<UpdateResponse>(api.AbsoluteUri, new JsonSerializerOptions
var matched = System.Diagnostics.Process.GetProcessesByName(bin.FullName);
if (matched is null || matched.Any() is false) return true;
foreach (var procsInfo in matched.Where(p =>
p.MainModule is not null &&
p.MainModule.FileName is not null &&
p.MainModule.FileName.Equals(bin.FullName, StringComparison.InvariantCultureIgnoreCase)))
{
IncludeFields = true
}, cancellationToken);
if (response is null) return false;
Version actualVersion;
if (FileVersionInfo.GetVersionInfo(bin.FullName).FileVersion is not string binVersionString) return false;
try
{
actualVersion = Version.Parse(binVersionString);
if (actualVersion >= response.Version) return false;
using var update = await httpClient.GetAsync(response.Uri, cancellationToken);
if (update is null) return false;
Stop(bin, TimeSpan.FromSeconds(60));
// read update archive to temp (overwrite)
var temp = Directory.CreateTempSubdirectory();
var updateFile = new FileInfo($@"{temp.FullName}/{bin.Name}.zip");
await File.WriteAllBytesAsync(updateFile.FullName, await update.Content.ReadAsByteArrayAsync(cancellationToken), cancellationToken);
// extract update archive from temp to app dir (overwrite)
ZipFile.ExtractToDirectory(updateFile.FullName, bin.Directory?.FullName, true);
// delete temp folder
if (temp.Exists) temp.Delete(true);
// rewrite with options to start user session process
//Start(app, directory, TimeSpan.FromSeconds(60));
return true;
if (procsInfo.CloseMainWindow()) procsInfo.WaitForExit((int)timeout.TotalMilliseconds);
if (procsInfo.HasExited is false) procsInfo.Kill(true);
}
catch (Exception) { }
return false;
return true;
}
catch (Exception) { }
public static bool Delete(FileInfo bin, TimeSpan timeout)
return false;
}
public static async ValueTask<bool> UpdateAsync(HttpClient httpClient, Uri api, FileInfo bin, CancellationToken cancellationToken)
{
if (IsRunning(bin) is false) return false;
var response = await httpClient.GetFromJsonAsync<UpdateResponse>(api.AbsoluteUri, new JsonSerializerOptions
{
try
{
Stop(bin, timeout);
bin.Delete();
IncludeFields = true
}, cancellationToken);
return true;
}
catch (Exception) { }
if (response is null) return false;
return false;
Version actualVersion;
if (FileVersionInfo.GetVersionInfo(bin.FullName).FileVersion is not string binVersionString) return false;
try
{
actualVersion = Version.Parse(binVersionString);
if (actualVersion >= response.Version) return false;
using var update = await httpClient.GetAsync(response.Uri, cancellationToken);
if (update is null) return false;
Stop(bin, TimeSpan.FromSeconds(60));
// read update archive to temp (overwrite)
var temp = Directory.CreateTempSubdirectory();
var updateFile = new FileInfo($@"{temp.FullName}/{bin.Name}.zip");
await File.WriteAllBytesAsync(updateFile.FullName, await update.Content.ReadAsByteArrayAsync(cancellationToken), cancellationToken);
// extract update archive from temp to app dir (overwrite)
ZipFile.ExtractToDirectory(updateFile.FullName, bin.Directory?.FullName, true);
// delete temp folder
if (temp.Exists) temp.Delete(true);
// rewrite with options to start user session process
//Start(app, directory, TimeSpan.FromSeconds(60));
return true;
}
catch (Exception) { }
return false;
}
public static bool Delete(FileInfo bin, TimeSpan timeout)
{
try
{
Stop(bin, timeout);
bin.Delete();
return true;
}
catch (Exception) { }
return false;
}
}
}
public class UpdateResult
{
public string? Api { get; set; }
public string? SourceDirectory { get; set; }
public string? App { get; set; }
public string? ServiceName { get; set; }
public class UpdateResult
{
public string? Api { get; set; }
public string? SourceDirectory { get; set; }
public string? App { get; set; }
public string? ServiceName { get; set; }
public bool ApiAvailable { get; set; } = false;
public bool UpdateAvailable { get; set; } = false;
public bool Success { get; set; } = false;
public List<string> ApiErrors { get; } = new();
public List<string> UpdateErrors { get; } = new();
}
public bool ApiAvailable { get; set; } = false;
public bool UpdateAvailable { get; set; } = false;
public bool Success { get; set; } = false;
public List<string> ApiErrors { get; } = new();
public List<string> UpdateErrors { get; } = new();
}
}

View file

@ -1,106 +1,105 @@
using Insight.Agent.Extensions;
using Insight.Agent.Messages;
using Insight.Domain.Network.Agent.Messages;
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace Insight.Agent.Services
namespace Insight.Agent.Services;
public partial class CollectorService
{
public partial class CollectorService
public OperationSystem? GetOperatingSystem()
{
public OperationSystem? GetOperatingSystem()
{
Logger.LogTrace("GetOperatingSystem");
Logger.LogTrace("GetOperatingSystem");
var os = new OperationSystem();
var os = new OperationSystem();
// get uptime
var output = string.Empty;
// get uptime
var output = string.Empty;
// read file
using var stream = File.OpenText(@"/proc/uptime");
output = stream.ReadToEnd();
// read file
using var stream = File.OpenText(@"/proc/uptime");
output = stream.ReadToEnd();
// clean output
var clean = Regex
.Replace(output
// clean output
var clean = Regex
.Replace(output
.Trim()
.Replace("\t", " "), @"[ ]{2,}", " ");
var elements = clean.Split(Array.Empty<char>(), StringSplitOptions.RemoveEmptyEntries);
// assign values
//os.Uptime = DateTime.Now - TimeSpan.FromSeconds(double.Parse(elements.ElementAt(0)));
// request data with process
output = "hostnamectl".Bash();
// linebreak list conversion
var lines = new List<string>(output
.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
.Select(l =>
{
return Regex
.Replace(l
.Trim()
.Replace("\t", " "), @"[ ]{2,}", " ");
})
.ToList();
var elements = clean.Split(Array.Empty<char>(), StringSplitOptions.RemoveEmptyEntries);
// assign values
os.Virtual = lines
.Any(l => l
.StartsWith("Virtualization:")) && !string.IsNullOrEmpty(lines
.Where(l => l
.StartsWith("Virtualization:"))
.First()
.Split("Virtualization:")[1]
.Trim());
// assign values
//os.Uptime = DateTime.Now - TimeSpan.FromSeconds(double.Parse(elements.ElementAt(0)));
// OS
// request data with process
output = "hostnamectl".Bash();
// request data with process
output = "hostnamectl".Bash();
// linebreak list conversion
lines = new List<string>(output
.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
.Select(l =>
{
return Regex
.Replace(l
.Trim()
.Replace("\t", " "), @"[ ]{2,}", " ");
})
.ToList();
// linebreak list conversion
var lines = new List<string>(output
.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
.Select(l =>
{
return Regex
.Replace(l
.Trim()
.Replace("\t", " "), @"[ ]{2,}", " ");
})
.ToList();
// assign values
os.Name = lines
.Any(l => l
.StartsWith("Operating System:")) ? lines
.Where(l => l
.StartsWith("Operating System:"))
.First()
.Split("Operating System:")[1]
.Trim() : string.Empty;
// assign values
os.Virtual = lines
.Any(l => l
.StartsWith("Virtualization:")) && !string.IsNullOrEmpty(lines
.Where(l => l
.StartsWith("Virtualization:"))
.First()
.Split("Virtualization:")[1]
.Trim());
os.Version = lines
.Any(l => l
.StartsWith("Kernel:")) ? lines
.Where(l => l
.StartsWith("Kernel:"))
.First()
.Split("Kernel:")[1]
.Trim() : string.Empty;
// OS
// request data with process
output = "hostnamectl".Bash();
var architecture = lines
.Any(l => l
.StartsWith("Architecture:")) ? lines
.Where(l => l
.StartsWith("Architecture:"))
.First()
.Split("Architecture:")[1]
.Trim() : string.Empty;
// linebreak list conversion
lines = new List<string>(output
.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
.Select(l =>
{
return Regex
.Replace(l
.Trim()
.Replace("\t", " "), @"[ ]{2,}", " ");
})
.ToList();
// assign values
os.Name = lines
.Any(l => l
.StartsWith("Operating System:")) ? lines
.Where(l => l
.StartsWith("Operating System:"))
.First()
.Split("Operating System:")[1]
.Trim() : string.Empty;
os.Version = lines
.Any(l => l
.StartsWith("Kernel:")) ? lines
.Where(l => l
.StartsWith("Kernel:"))
.First()
.Split("Kernel:")[1]
.Trim() : string.Empty;
var architecture = lines
.Any(l => l
.StartsWith("Architecture:")) ? lines
.Where(l => l
.StartsWith("Architecture:"))
.First()
.Split("Architecture:")[1]
.Trim() : string.Empty;
return os;
}
return os;
}
}

View file

@ -1,50 +1,49 @@
using Insight.Agent.Extensions;
using Insight.Agent.Messages;
using Insight.Domain.Network.Agent.Messages;
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace Insight.Agent.Services
namespace Insight.Agent.Services;
public partial class CollectorService
{
public partial class CollectorService
public List<Session>? GetSessions()
{
public List<Session>? GetSessions()
Logger.LogTrace("GetSessions");
var sessions = new List<Session>();
// request data with process
var output = "w".Bash();
// linebreak list conversion
var lines = output.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
lines = lines.Select(l =>
{
Logger.LogTrace("GetSessions");
return Regex.Replace(l.Trim().Replace("\t", " "), @"[ ]{2,}", " ");
}).ToList();
var sessions = new List<Session>();
// cleaning
lines.RemoveRange(0, 2);
// request data with process
var output = "w".Bash();
// process list elements
foreach (var l in lines)
{
// split into elements
var elements = l.Split(Array.Empty<char>(), StringSplitOptions.RemoveEmptyEntries);
// linebreak list conversion
var lines = output.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
lines = lines.Select(l =>
// add user, assign values
sessions.Add(new Session
{
return Regex.Replace(l.Trim().Replace("\t", " "), @"[ ]{2,}", " ");
}).ToList();
// cleaning
lines.RemoveRange(0, 2);
// process list elements
foreach (var l in lines)
{
// split into elements
var elements = l.Split(Array.Empty<char>(), StringSplitOptions.RemoveEmptyEntries);
// add user, assign values
sessions.Add(new Session
{
User = elements.ElementAt(0),
//Id = elements.ElementAt(1),
Remote = elements.ElementAt(2),
//Login = elements.ElementAt(3),
//Idle = elements.ElementAt(4)
});
}
return sessions;
User = elements.ElementAt(0),
//Id = elements.ElementAt(1),
Remote = elements.ElementAt(2),
//Login = elements.ElementAt(3),
//Idle = elements.ElementAt(4)
});
}
return sessions;
}
}

View file

@ -1,9 +1,8 @@
using Insight.Domain.Constants;
namespace Insight.Api
namespace Insight.Api;
public static class Locations
{
public static class Locations
{
public static DirectoryInfo UpdatesPath { get; } = new DirectoryInfo($"{Configuration.AppDirectory?.FullName}/files/updates");
}
public static DirectoryInfo UpdatesPath { get; } = new DirectoryInfo($"{Configuration.AppDirectory?.FullName}/files/updates");
}

View file

@ -4,73 +4,72 @@ using Insight.Infrastructure.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Insight.Api.Controllers
namespace Insight.Api.Controllers;
[ApiController, Route("api/accounts")]
public class AccountController : ControllerBase
{
[ApiController, Route("api/accounts")]
public class AccountController : ControllerBase
private readonly IdentityService _identityService;
private readonly AccountService _accountService;
private readonly ILogger<AccountController> _logger;
public AccountController(IdentityService identityService, AccountService accountService, ILogger<AccountController> logger)
{
private readonly IdentityService _identityService;
private readonly AccountService _accountService;
private readonly ILogger<AccountController> _logger;
_identityService = identityService;
_accountService = accountService;
_logger = logger;
}
public AccountController(IdentityService identityService, AccountService accountService, ILogger<AccountController> logger)
[HttpGet, Authorize]
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
{
try
{
_identityService = identityService;
_accountService = accountService;
_logger = logger;
var result = await _accountService.GetAsync(
offset: request.Offset,
limit: request.Limit,
request: Request,
response: Response,
cancellationToken: cancellationToken).ConfigureAwait(false);
return Ok(result);
}
[HttpGet, Authorize]
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
catch (UnauthorizedAccessException ex)
{
try
{
var result = await _accountService.GetAsync(
offset: request.Offset,
limit: request.Limit,
request: Request,
response: Response,
cancellationToken: cancellationToken).ConfigureAwait(false);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
return Unauthorized(ex.ToString());
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return Unauthorized(ex.ToString());
}
[HttpPost("register"), Authorize]
public async Task<ActionResult> Register([FromBody] RegistrationModel model)
catch (Exception ex)
{
if (string.IsNullOrWhiteSpace(model.Email)) return BadRequest("Email Required");
if (string.IsNullOrWhiteSpace(model.Password)) return BadRequest("Password Required");
if (string.IsNullOrWhiteSpace(model.ConfirmPassword)) return BadRequest("Password Confirmation Required");
if (model.Password != model.ConfirmPassword) return BadRequest("Passwords do not match");
try
{
var result = await _identityService.CreateUserAsync(model.Email, model.Password).ConfigureAwait(false);
if (result.Succeeded is false) return BadRequest(result.Errors);
}
catch (UnauthorizedAccessException ex)
{
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
//await _userManager.AddToRoleAsync(user, "Visitor");
return Ok(model.Email);
return BadRequest(ex.Message);
}
}
[HttpPost("register"), Authorize]
public async Task<ActionResult> Register([FromBody] RegistrationModel model)
{
if (string.IsNullOrWhiteSpace(model.Email)) return BadRequest("Email Required");
if (string.IsNullOrWhiteSpace(model.Password)) return BadRequest("Password Required");
if (string.IsNullOrWhiteSpace(model.ConfirmPassword)) return BadRequest("Password Confirmation Required");
if (model.Password != model.ConfirmPassword) return BadRequest("Passwords do not match");
try
{
var result = await _identityService.CreateUserAsync(model.Email, model.Password).ConfigureAwait(false);
if (result.Succeeded is false) return BadRequest(result.Errors);
}
catch (UnauthorizedAccessException ex)
{
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
//await _userManager.AddToRoleAsync(user, "Visitor");
return Ok(model.Email);
}
}

View file

@ -3,42 +3,41 @@ using Insight.Infrastructure.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Insight.Api.Controllers
namespace Insight.Api.Controllers;
[ApiController, Route("api/agents")]
public class AgentController : ControllerBase
{
[ApiController, Route("api/agents")]
public class AgentController : ControllerBase
private readonly AgentService _agentService;
private readonly ILogger<AgentController> _logger;
public AgentController(AgentService agentService, ILogger<AgentController> logger)
{
private readonly AgentService _agentService;
private readonly ILogger<AgentController> _logger;
_agentService = agentService;
_logger = logger;
}
public AgentController(AgentService agentService, ILogger<AgentController> logger)
[HttpGet, Authorize]
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
{
try
{
_agentService = agentService;
_logger = logger;
var result = await _agentService.GetAsync(
offset: request.Offset,
limit: request.Limit,
request: Request,
response: Response,
cancellationToken: cancellationToken).ConfigureAwait(false);
return Ok(result);
}
[HttpGet, Authorize]
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
catch (UnauthorizedAccessException ex)
{
try
{
var result = await _agentService.GetAsync(
offset: request.Offset,
limit: request.Limit,
request: Request,
response: Response,
cancellationToken: cancellationToken).ConfigureAwait(false);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
return Unauthorized(ex.ToString());
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return Unauthorized(ex.ToString());
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
}

View file

@ -3,42 +3,41 @@ using Insight.Infrastructure.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Insight.Api.Controllers
namespace Insight.Api.Controllers;
[ApiController, Route("api/customers")]
public class CustomerController : ControllerBase
{
[ApiController, Route("api/customers")]
public class CustomerController : ControllerBase
private readonly CustomerService _customerService;
private readonly ILogger<CustomerController> _logger;
public CustomerController(CustomerService customerService, ILogger<CustomerController> logger)
{
private readonly CustomerService _customerService;
private readonly ILogger<CustomerController> _logger;
_customerService = customerService;
_logger = logger;
}
public CustomerController(CustomerService customerService, ILogger<CustomerController> logger)
[HttpGet, Authorize]
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
{
try
{
_customerService = customerService;
_logger = logger;
var result = await _customerService.GetAsync(
offset: request.Offset,
limit: request.Limit,
request: Request,
response: Response,
cancellationToken: cancellationToken).ConfigureAwait(false);
return Ok(result);
}
[HttpGet, Authorize]
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
catch (UnauthorizedAccessException ex)
{
try
{
var result = await _customerService.GetAsync(
offset: request.Offset,
limit: request.Limit,
request: Request,
response: Response,
cancellationToken: cancellationToken).ConfigureAwait(false);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
return Unauthorized(ex.ToString());
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return Unauthorized(ex.ToString());
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
}

View file

@ -3,42 +3,41 @@ using Insight.Infrastructure.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Insight.Api.Controllers
namespace Insight.Api.Controllers;
[ApiController, Route("api/hosts")]
public class HostController : ControllerBase
{
[ApiController, Route("api/hosts")]
public class HostController : ControllerBase
private readonly HostService _hostService;
private readonly ILogger<HostController> _logger;
public HostController(HostService hostService, ILogger<HostController> logger)
{
private readonly HostService _hostService;
private readonly ILogger<HostController> _logger;
_hostService = hostService;
_logger = logger;
}
public HostController(HostService hostService, ILogger<HostController> logger)
[HttpGet, Authorize]
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
{
try
{
_hostService = hostService;
_logger = logger;
var result = await _hostService.GetAsync(
offset: request.Offset,
limit: request.Limit,
request: Request,
response: Response,
cancellationToken: cancellationToken).ConfigureAwait(false);
return Ok(result);
}
[HttpGet, Authorize]
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
catch (UnauthorizedAccessException ex)
{
try
{
var result = await _hostService.GetAsync(
offset: request.Offset,
limit: request.Limit,
request: Request,
response: Response,
cancellationToken: cancellationToken).ConfigureAwait(false);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
return Unauthorized(ex.ToString());
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return Unauthorized(ex.ToString());
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
}

View file

@ -8,66 +8,65 @@ using MongoDB.Driver;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
namespace Insight.Api.Controllers
namespace Insight.Api.Controllers;
[ApiController, Route("api/inventory")]
public class InventoryController : ControllerBase
{
[ApiController, Route("api/inventory")]
public class InventoryController : ControllerBase
private readonly InventoryService _inventoryService;
private readonly ILogger<InventoryController> _logger;
public InventoryController(InventoryService inventoryService, ILogger<InventoryController> logger)
{
private readonly InventoryService _inventoryService;
private readonly ILogger<InventoryController> _logger;
_inventoryService = inventoryService;
_logger = logger;
}
public InventoryController(InventoryService inventoryService, ILogger<InventoryController> logger)
[HttpGet, Authorize]
public async Task<IActionResult> Get([FromQuery] HostApplicationEntity request, [FromQuery] PagedDataRequest meta, CancellationToken cancellationToken)
{
try
{
_inventoryService = inventoryService;
_logger = logger;
var filter = Builders<HostApplicationEntity>.Filter.Empty;
if (request.Id is not null)
filter &= Builders<HostApplicationEntity>.Filter.Eq(p => p.Id, request.Id);
if (request.Host is not null)
filter &= Builders<HostApplicationEntity>.Filter.Eq(p => p.Host, request.Host);
if (request.Name is not null)
filter &= Builders<HostApplicationEntity>.Filter.Regex(p => p.Name, new BsonRegularExpression(new Regex(request.Name, RegexOptions.IgnoreCase)));
var result = await _inventoryService.GetAsync(
filter: filter,
offset: meta.Offset,
limit: meta.Limit,
request: Request,
response: Response,
cancellationToken: cancellationToken).ConfigureAwait(false);
return Ok(result);
}
[HttpGet, Authorize]
public async Task<IActionResult> Get([FromQuery] HostApplicationEntity request, [FromQuery] PagedDataRequest meta, CancellationToken cancellationToken)
catch (UnauthorizedAccessException ex)
{
try
{
var filter = Builders<HostApplicationEntity>.Filter.Empty;
if (request.Id is not null)
filter &= Builders<HostApplicationEntity>.Filter.Eq(p => p.Id, request.Id);
if (request.Host is not null)
filter &= Builders<HostApplicationEntity>.Filter.Eq(p => p.Host, request.Host);
if (request.Name is not null)
filter &= Builders<HostApplicationEntity>.Filter.Regex(p => p.Name, new BsonRegularExpression(new Regex(request.Name, RegexOptions.IgnoreCase)));
var result = await _inventoryService.GetAsync(
filter: filter,
offset: meta.Offset,
limit: meta.Limit,
request: Request,
response: Response,
cancellationToken: cancellationToken).ConfigureAwait(false);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
return Unauthorized(ex.ToString());
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return Unauthorized(ex.ToString());
}
public class ApplicationRequest
catch (Exception ex)
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("host")]
public string? Host { get; set; }
[JsonPropertyName("name")]
public string? Name { get; set; }
return BadRequest(ex.Message);
}
}
public class ApplicationRequest
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("host")]
public string? Host { get; set; }
[JsonPropertyName("name")]
public string? Name { get; set; }
}
}

View file

@ -1,30 +1,29 @@
using Microsoft.AspNetCore.Mvc;
namespace Insight.Server.Controllers
namespace Insight.Server.Controllers;
[ApiController, Route("api/setup")]
public class SetupController : ControllerBase
{
[ApiController, Route("api/setup")]
public class SetupController : ControllerBase
private readonly ILogger<SetupController> _logger;
public SetupController(ILogger<SetupController> logger)
{
private readonly ILogger<SetupController> _logger;
_logger = logger;
}
public SetupController(ILogger<SetupController> logger)
[HttpGet("windows")]
public async Task<IActionResult> GetAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("[{method}] {route} => {ep}", Request.Method, Request.HttpContext.Request.Path, Request.HttpContext.Connection.RemoteIpAddress);
var files = new DirectoryInfo($"{Domain.Constants.Configuration.AppDirectory?.FullName}/files/setup").GetFiles();
if (files.Length == 0)
{
_logger = logger;
return NotFound();
}
[HttpGet("windows")]
public async Task<IActionResult> GetAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("[{method}] {route} => {ep}", Request.Method, Request.HttpContext.Request.Path, Request.HttpContext.Connection.RemoteIpAddress);
var files = new DirectoryInfo($"{Domain.Constants.Configuration.AppDirectory?.FullName}/files/setup").GetFiles();
if (files.Length == 0)
{
return NotFound();
}
return File(await System.IO.File.ReadAllBytesAsync(files.OrderBy(p => p.LastWriteTime).First().FullName, cancellationToken), "application/zip", "setup-win64.zip");
}
return File(await System.IO.File.ReadAllBytesAsync(files.OrderBy(p => p.LastWriteTime).First().FullName, cancellationToken), "application/zip", "setup-win64.zip");
}
}

View file

@ -3,83 +3,82 @@ using Insight.Infrastructure.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Insight.Api.Controllers
namespace Insight.Api.Controllers;
[ApiController, Route("api/token", Order = 0)]
public class TokenController : ControllerBase
{
[ApiController, Route("api/token", Order = 0)]
public class TokenController : ControllerBase
private readonly TokenService _tokenService;
public TokenController(TokenService tokenService)
{
private readonly TokenService _tokenService;
_tokenService = tokenService;
}
public TokenController(TokenService tokenService)
/// <remarks>
/// Access Token Request
/// </remarks>
[HttpPost, AllowAnonymous]
public async Task<IActionResult> Authentication([FromBody] TokenRequest request)
{
try
{
_tokenService = tokenService;
var result = await _tokenService.GetAsync(request.Username, request.Password, request.Code, HttpContext.Connection.RemoteIpAddress).ConfigureAwait(false);
return Ok(result);
}
/// <remarks>
/// Access Token Request
/// </remarks>
[HttpPost, AllowAnonymous]
public async Task<IActionResult> Authentication([FromBody] TokenRequest request)
catch (UnauthorizedAccessException ex)
{
try
{
var result = await _tokenService.GetAsync(request.Username, request.Password, request.Code, HttpContext.Connection.RemoteIpAddress).ConfigureAwait(false);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return Unauthorized(ex.Message);
}
/// <remarks>
/// Refresh Token Request
/// </remarks>
[HttpPost("refresh"), AllowAnonymous]
public async Task<IActionResult> Refresh([FromBody] TokenRefreshRequest request)
catch (Exception ex)
{
if (string.IsNullOrWhiteSpace(request.Token)) return BadRequest("Refresh Token Required");
try
{
var result = await _tokenService.RefreshAsync(request.Token, HttpContext.Connection.RemoteIpAddress).ConfigureAwait(false);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return BadRequest(ex.Message);
}
}
/// <remarks>
/// Revoke Token Request
/// </remarks>
[HttpPost("revoke"), AllowAnonymous]
public async Task<IActionResult> Revoke([FromBody] TokenRevokeRequest request)
/// <remarks>
/// Refresh Token Request
/// </remarks>
[HttpPost("refresh"), AllowAnonymous]
public async Task<IActionResult> Refresh([FromBody] TokenRefreshRequest request)
{
if (string.IsNullOrWhiteSpace(request.Token)) return BadRequest("Refresh Token Required");
try
{
if (string.IsNullOrWhiteSpace(request.Token)) return BadRequest("Refresh Token Required");
var result = await _tokenService.RefreshAsync(request.Token, HttpContext.Connection.RemoteIpAddress).ConfigureAwait(false);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
try
{
await _tokenService.RevokeAsync(request.Token, request.Reason ?? "revoked by user", HttpContext.Connection.RemoteIpAddress).ConfigureAwait(false);
return Ok();
}
catch (UnauthorizedAccessException ex)
{
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
/// <remarks>
/// Revoke Token Request
/// </remarks>
[HttpPost("revoke"), AllowAnonymous]
public async Task<IActionResult> Revoke([FromBody] TokenRevokeRequest request)
{
if (string.IsNullOrWhiteSpace(request.Token)) return BadRequest("Refresh Token Required");
try
{
await _tokenService.RevokeAsync(request.Token, request.Reason ?? "revoked by user", HttpContext.Connection.RemoteIpAddress).ConfigureAwait(false);
return Ok();
}
catch (UnauthorizedAccessException ex)
{
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
}

View file

@ -2,92 +2,91 @@
using Insight.Domain.Models;
using Microsoft.AspNetCore.Mvc;
namespace Insight.Server.Controllers
namespace Insight.Server.Controllers;
[ApiController, Route("api/update")]
public class UpdateController : ControllerBase
{
[ApiController, Route("api/update")]
public class UpdateController : ControllerBase
private readonly ILogger<UpdateController> _logger;
public UpdateController(ILogger<UpdateController> logger)
{
private readonly ILogger<UpdateController> _logger;
_logger = logger;
}
public UpdateController(ILogger<UpdateController> logger)
[HttpGet("updater/windows")]
public IActionResult UpdaterWindows()
{
_logger.LogInformation("[{method}] {route} => {ep}", Request.Method, Request.HttpContext.Request.Path, Request.HttpContext.Connection.RemoteIpAddress);
var updateDir = new DirectoryInfo($"{Locations.UpdatesPath}/updater/windows");
if (updateDir.Exists is false)
{
_logger = logger;
return NotFound();
}
[HttpGet("updater/windows")]
public IActionResult UpdaterWindows()
var updateLock = new FileInfo($"{updateDir.FullName}/.lock");
if (updateLock.Exists)
{
_logger.LogInformation("[{method}] {route} => {ep}", Request.Method, Request.HttpContext.Request.Path, Request.HttpContext.Connection.RemoteIpAddress);
var updateDir = new DirectoryInfo($"{Locations.UpdatesPath}/updater/windows");
if (updateDir.Exists is false)
{
return NotFound();
}
var updateLock = new FileInfo($"{updateDir.FullName}/.lock");
if (updateLock.Exists)
{
return NotFound("locked");
}
var versions = updateDir.GetFiles("*.zip", SearchOption.TopDirectoryOnly);
if (versions is null || versions.Any() is false) return NotFound();
var latest = versions.OrderBy(x => x.Name).FirstOrDefault();
if (latest is null) return NotFound();
var relPath = $"{Path.GetRelativePath($"{Domain.Constants.Configuration.AppDirectory?.FullName}", latest.FullName)}";
if (Version.TryParse(Path.GetFileNameWithoutExtension(latest.Name), out var fileversion) is false) return NotFound();
return Ok(new UpdateResponse
{
Version = fileversion,
Uri = new Uri($"{Request.Scheme}://{Request.Host}/api/{relPath}")
});
return NotFound("locked");
}
[HttpGet("agent/windows")]
public IActionResult AgentWindows()
var versions = updateDir.GetFiles("*.zip", SearchOption.TopDirectoryOnly);
if (versions is null || versions.Any() is false) return NotFound();
var latest = versions.OrderBy(x => x.Name).FirstOrDefault();
if (latest is null) return NotFound();
var relPath = $"{Path.GetRelativePath($"{Domain.Constants.Configuration.AppDirectory?.FullName}", latest.FullName)}";
if (Version.TryParse(Path.GetFileNameWithoutExtension(latest.Name), out var fileversion) is false) return NotFound();
return Ok(new UpdateResponse
{
_logger.LogInformation("[{method}] {route} => {ep}", Request.Method, Request.HttpContext.Request.Path, Request.HttpContext.Connection.RemoteIpAddress);
Version = fileversion,
Uri = new Uri($"{Request.Scheme}://{Request.Host}/api/{relPath}")
});
}
var updateDir = new DirectoryInfo($"{Locations.UpdatesPath}/agent/windows");
[HttpGet("agent/windows")]
public IActionResult AgentWindows()
{
_logger.LogInformation("[{method}] {route} => {ep}", Request.Method, Request.HttpContext.Request.Path, Request.HttpContext.Connection.RemoteIpAddress);
if (updateDir.Exists is false)
{
return NotFound();
}
var updateDir = new DirectoryInfo($"{Locations.UpdatesPath}/agent/windows");
var updateLock = new FileInfo($"{updateDir.FullName}/.lock");
if (updateLock.Exists)
{
return NotFound("locked");
}
var versions = updateDir.GetFiles("*.zip", SearchOption.TopDirectoryOnly);
if (versions is null || versions.Any() is false) return NotFound();
var latest = versions.OrderBy(x => x.Name).FirstOrDefault();
if (latest is null) return NotFound();
var relPath = $"{Path.GetRelativePath($"{Domain.Constants.Configuration.AppDirectory?.FullName}", latest.FullName)}";
if (Version.TryParse(Path.GetFileNameWithoutExtension(latest.Name), out var fileversion) is false) return NotFound();
return Ok(new UpdateResponse
{
Version = fileversion,
Uri = new Uri($"{Request.Scheme}://{Request.Host}/api/{relPath}")
});
if (updateDir.Exists is false)
{
return NotFound();
}
var updateLock = new FileInfo($"{updateDir.FullName}/.lock");
if (updateLock.Exists)
{
return NotFound("locked");
}
var versions = updateDir.GetFiles("*.zip", SearchOption.TopDirectoryOnly);
if (versions is null || versions.Any() is false) return NotFound();
var latest = versions.OrderBy(x => x.Name).FirstOrDefault();
if (latest is null) return NotFound();
var relPath = $"{Path.GetRelativePath($"{Domain.Constants.Configuration.AppDirectory?.FullName}", latest.FullName)}";
if (Version.TryParse(Path.GetFileNameWithoutExtension(latest.Name), out var fileversion) is false) return NotFound();
return Ok(new UpdateResponse
{
Version = fileversion,
Uri = new Uri($"{Request.Scheme}://{Request.Host}/api/{relPath}")
});
}
}

View file

@ -2,58 +2,57 @@
using Microsoft.OpenApi.Models;
using System.Reflection;
namespace Insight.Api.Hosting
namespace Insight.Api.Hosting;
public static class ServiceExtensions
{
public static class ServiceExtensions
internal static IServiceCollection AddSwaggerServices(this IServiceCollection services, IConfiguration configuration)
{
internal static IServiceCollection AddSwaggerServices(this IServiceCollection services, IConfiguration configuration)
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options =>
{
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options =>
options.SwaggerDoc("v1", new OpenApiInfo
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Insight API",
Version = "v1"
});
options.AddSecurityDefinition(name: "Bearer", securityScheme: new OpenApiSecurityScheme
{
Name = "Authorization",
Description = "Enter the Bearer Authorization string as following: `Bearer Generated-JWT-Token`",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer",
BearerFormat = "JWT",
Reference = new OpenApiReference
{
Id = JwtBearerDefaults.AuthenticationScheme,
Type = ReferenceType.SecurityScheme
}
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Reference = new OpenApiReference
{
Id = "Bearer",
Type = ReferenceType.SecurityScheme
}
},
new List<string>()
}
});
var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
Title = "Insight API",
Version = "v1"
});
return services;
}
options.AddSecurityDefinition(name: "Bearer", securityScheme: new OpenApiSecurityScheme
{
Name = "Authorization",
Description = "Enter the Bearer Authorization string as following: `Bearer Generated-JWT-Token`",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer",
BearerFormat = "JWT",
Reference = new OpenApiReference
{
Id = JwtBearerDefaults.AuthenticationScheme,
Type = ReferenceType.SecurityScheme
}
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Reference = new OpenApiReference
{
Id = "Bearer",
Type = ReferenceType.SecurityScheme
}
},
new List<string>()
}
});
var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
});
return services;
}
}

View file

@ -4,7 +4,7 @@
<TargetFramework>net7.0</TargetFramework>
<Product>Insight</Product>
<AssemblyName>api</AssemblyName>
<AssemblyVersion>2023.8.23.1</AssemblyVersion>
<AssemblyVersion>2023.12.14.0</AssemblyVersion>
<RootNamespace>Insight.Api</RootNamespace>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
@ -30,17 +30,10 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.1" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.11" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.13" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
<!--Unix Serilog stuff-->
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
<PackageReference Include="System.Text.Encoding.Extensions" Version="4.3.0" />
<PackageReference Include="System.Runtime.Handles" Version="4.3.0" />
<PackageReference Include="System.IO" Version="4.3.0" />
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
<PackageReference Include="System.Threading" Version="4.3.0" />
<PackageReference Include="System.Threading.Tasks" Version="4.3.0" />
</ItemGroup>
<ItemGroup>

View file

@ -1,23 +1,22 @@
using System.ComponentModel.DataAnnotations;
namespace Insight.Api.Models
namespace Insight.Api.Models;
public class RegistrationModel
{
public class RegistrationModel
{
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
[Required(ErrorMessage = "Email is required")]
[EmailAddress]
public string? Email { get; set; }
[Required(ErrorMessage = "Email is required")]
[EmailAddress]
public string? Email { get; set; }
[Required(ErrorMessage = "Password is required")]
[DataType(DataType.Password)]
public string? Password { get; set; }
[Required(ErrorMessage = "Password is required")]
[DataType(DataType.Password)]
public string? Password { get; set; }
[Required(ErrorMessage = "Password is required")]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string? ConfirmPassword { get; set; }
}
[Required(ErrorMessage = "Password is required")]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string? ConfirmPassword { get; set; }
}

View file

@ -3,97 +3,96 @@ using Insight.Domain.Constants;
using Insight.Infrastructure;
using Microsoft.Extensions.FileProviders;
namespace Insight.Api
namespace Insight.Api;
internal class Program
{
public class Program
public static async Task Main(string[] args)
{
public static async Task Main(string[] args)
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseWindowsService();
builder.Host.UseSystemd();
// LOGGER
builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddFilter("Microsoft.AspNetCore", LogLevel.Warning);
builder.Logging.AddSimpleConsole(options =>
{
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseWindowsService();
builder.Host.UseSystemd();
options.IncludeScopes = true;
options.SingleLine = true;
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff ";
});
// LOGGER
builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddFilter("Microsoft.AspNetCore", LogLevel.Warning);
builder.Logging.AddFile($"{Configuration.AppDirectory?.FullName}/" + "logs/api_{Date}.log", LogLevel.Trace, fileSizeLimitBytes: 104857600, retainedFileCountLimit: 10, outputTemplate: "{Timestamp:o} [{Level:u3}] {Message} {NewLine}{Exception}");
builder.Logging.AddSimpleConsole(options =>
{
options.IncludeScopes = true;
options.SingleLine = true;
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff ";
});
// INFRASTRUCTURE
builder.Services.AddDatabase(builder.Configuration);
builder.Services.AddInfrastructureServices();
builder.Logging.AddFile($"{Configuration.AppDirectory?.FullName}/" + "logs/api_{Date}.log", LogLevel.Trace, fileSizeLimitBytes: 104857600, retainedFileCountLimit: 10, outputTemplate: "{Timestamp:o} [{Level:u3}] {Message} {NewLine}{Exception}");
// IDENTITY
builder.Services.AddIdentityServices(builder.Configuration);
builder.Services.AddBearerAuthentication(builder.Configuration);
builder.Services.AddTokenServices(builder.Configuration);
// INFRASTRUCTURE
builder.Services.AddDatabase(builder.Configuration);
builder.Services.AddInfrastructureServices();
// SECURITY
builder.Services.AddAuthorization();
// IDENTITY
builder.Services.AddIdentityServices(builder.Configuration);
builder.Services.AddBearerAuthentication(builder.Configuration);
builder.Services.AddTokenServices(builder.Configuration);
// WEBSERVICES
builder.Services.AddProxyServices(builder.Configuration);
builder.Services.AddRoutingServices(builder.Configuration);
builder.Services.AddControllers();
// SECURITY
builder.Services.AddAuthorization();
// SWAGGER
builder.Services.AddSwaggerServices(builder.Configuration);
// WEBSERVICES
builder.Services.AddProxyServices(builder.Configuration);
builder.Services.AddRoutingServices(builder.Configuration);
builder.Services.AddControllers();
//builder.Services.AddControllers();
//builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen();
// SWAGGER
builder.Services.AddSwaggerServices(builder.Configuration);
var app = builder.Build();
//builder.Services.AddControllers();
//builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen();
// Configure the HTTP request pipeline.
app.UseForwardedHeaders();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
// Configure the HTTP request pipeline.
app.UseForwardedHeaders();
if (app.Environment.IsDevelopment())
{
}
app.UseSwagger(options =>
{
options.RouteTemplate = "api/swagger/{documentName}/swagger.json";
});
app.UseSwaggerUI(options =>
{
options.DefaultModelsExpandDepth(-1);
options.SwaggerEndpoint("/api/swagger/v1/swagger.json", "v1");
options.RoutePrefix = "api/swagger";
});
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
app.UseAuthorization();
app.MapControllers();
// STATIC FILES (UPDATES)
var files = new DirectoryInfo($"{Domain.Constants.Configuration.AppDirectory?.FullName}/files");
files.Create();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(files.FullName),
RequestPath = "/api/files",
ServeUnknownFileTypes = true
});
await app.RunAsync();
}
app.UseSwagger(options =>
{
options.RouteTemplate = "api/swagger/{documentName}/swagger.json";
});
app.UseSwaggerUI(options =>
{
options.DefaultModelsExpandDepth(-1);
options.SwaggerEndpoint("/api/swagger/v1/swagger.json", "v1");
options.RoutePrefix = "api/swagger";
});
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
app.UseAuthorization();
app.MapControllers();
// STATIC FILES (UPDATES)
var files = new DirectoryInfo($"{Domain.Constants.Configuration.AppDirectory?.FullName}/files");
files.Create();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(files.FullName),
RequestPath = "/api/files",
ServeUnknownFileTypes = true
});
await app.RunAsync();
}
}

View file

@ -1,13 +1,12 @@
using System.Net;
using System.Reflection;
namespace Insight.Domain.Constants
namespace Insight.Domain.Constants;
public static class Configuration
{
public static class Configuration
{
public static string Hostname => Dns.GetHostEntry("localhost").HostName;
public static Version Version => Assembly.GetEntryAssembly()?.GetName().Version ?? throw new ArgumentNullException("Version");
public static DirectoryInfo? AppDirectory => string.IsNullOrWhiteSpace(Environment.ProcessPath) ? null : new DirectoryInfo(Environment.ProcessPath).Parent;
public static string DefaultConfig => Path.Combine(AppDirectory?.FullName ?? string.Empty, "config.json");
}
public static string Hostname => Dns.GetHostEntry("localhost").HostName;
public static Version Version => Assembly.GetEntryAssembly()?.GetName().Version ?? throw new ArgumentNullException("Version");
public static DirectoryInfo? AppDirectory => string.IsNullOrWhiteSpace(Environment.ProcessPath) ? null : new DirectoryInfo(Environment.ProcessPath).Parent;
public static string DefaultConfig => Path.Combine(AppDirectory?.FullName ?? string.Empty, "config.json");
}

View file

@ -0,0 +1,13 @@
namespace Insight.Domain.Enums;
public enum CategoryEnum
{
Network = 1,
System = 2,
Application = 3,
Security = 4,
Monitoring = 5,
Task = 6,
Printer = 7,
RDP = 8
}

View file

@ -0,0 +1,8 @@
namespace Insight.Domain.Enums;
public enum DispatchEnum
{
Pending = 1,
Failure = 2,
Success = 3,
}

View file

@ -0,0 +1,8 @@
namespace Insight.Domain.Enums;
public enum RemoteControlMode
{
Unknown,
Unattended,
Attended
}

View file

@ -0,0 +1,7 @@
namespace Insight.Domain.Enums;
public enum SessionEndReasons
{
Logoff = 1,
SystemShutdown = 2
}

View file

@ -0,0 +1,14 @@
namespace Insight.Domain.Enums;
public enum SessionSwitchReason
{
ConsoleConnect = 1,
ConsoleDisconnect = 2,
RemoteConnect = 3,
RemoteDisconnect = 4,
SessionLogon = 5,
SessionLogoff = 6,
SessionLock = 7,
SessionUnlock = 8,
SessionRemoteControl = 9
}

View file

@ -0,0 +1,8 @@
namespace Insight.Domain.Enums;
public enum StatusEnum
{
Information = 1,
Warning = 2,
Error = 3
}

View file

@ -6,9 +6,14 @@
<Nullable>enable</Nullable>
<RootNamespace>Insight.Domain</RootNamespace>
<Product>Insight</Product>
<AssemblyVersion>2023.7.3.0</AssemblyVersion>
<AssemblyVersion>2023.12.14.0</AssemblyVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Vaitr.Bus" Version="2023.12.13" />
<PackageReference Include="Vaitr.Network" Version="2023.12.14" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>none</DebugType>
</PropertyGroup>

View file

@ -0,0 +1,8 @@
using Insight.Domain.Network;
namespace Insight.Domain.Interfaces;
public partial interface IMessageHandler<TSender>
{
ValueTask HandleAsync<TMessage>(TSender sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage;
}

View file

@ -0,0 +1,148 @@
using MessagePack;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
namespace RemoteControl.Shared;
/// <summary>
/// Describes the success or failure of any kind of operation.
/// </summary>
[DataContract]
public class Result
{
/// <summary>
/// For serialization only.
/// </summary>
[SerializationConstructor]
[JsonConstructor]
public Result() { }
public Result(bool isSuccess, string reason = "", Exception? exception = null)
{
if (!isSuccess && exception is null && string.IsNullOrWhiteSpace(reason))
{
throw new ArgumentException("A reason or exception must be supplied for an unsuccessful result.");
}
IsSuccess = isSuccess;
Exception = exception;
Reason = reason;
}
[IgnoreDataMember]
public Exception? Exception { get; init; }
[IgnoreDataMember]
[MemberNotNullWhen(true, nameof(Exception))]
public bool HadException => Exception is not null;
[DataMember]
public bool IsSuccess { get; init; }
[DataMember]
public string Reason { get; init; } = string.Empty;
public static Result Fail(string reason)
{
return new Result(false, reason);
}
public static Result Fail(Exception ex)
{
return new Result(false, string.Empty, ex);
}
public static Result<T> Fail<T>(string reason)
{
return new Result<T>(reason);
}
public static Result<T> Fail<T>(Exception ex)
{
return new Result<T>(ex);
}
public static Result Ok()
{
return new Result(true);
}
public static Result<T> Ok<T>(T value)
{
return new Result<T>(value);
}
}
/// <summary>
/// Describes the success or failure of any kind of operation.
/// </summary>
[DataContract]
public class Result<T>
{
/// <summary>
/// Returns a successful result with the given value.
/// </summary>
/// <param name="value"></param>
public Result(T value)
{
IsSuccess = true;
Value = value;
}
/// <summary>
/// Returns an unsuccessful result with the given exception.
/// </summary>
/// <param name="exception"></param>
public Result(Exception exception)
{
IsSuccess = false;
Exception = exception;
Reason = exception.Message;
}
/// <summary>
/// Returns an unsuccessful result with the given reason.
/// </summary>
/// <param name="errorMessage"></param>
/// <exception cref="ArgumentException"></exception>
public Result(string reason)
{
IsSuccess = false;
Reason = reason;
}
/// <summary>
/// For serialization only.
/// </summary>
[SerializationConstructor]
[JsonConstructor]
public Result() { }
public Result(Exception? exception, bool isSuccess, string reason, T? value)
{
Exception = exception;
IsSuccess = isSuccess;
Reason = reason;
Value = value;
}
[IgnoreDataMember]
public Exception? Exception { get; init; }
[IgnoreDataMember]
[MemberNotNullWhen(true, nameof(Exception))]
public bool HadException => Exception is not null;
[DataMember]
[MemberNotNullWhen(true, nameof(Value))]
public bool IsSuccess { get; init; }
[DataMember]
public string Reason { get; init; } = string.Empty;
[DataMember]
public T? Value { get; init; }
}

View file

@ -1,55 +1,54 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace Insight.Domain.Models
namespace Insight.Domain.Models;
public class TokenRequest
{
public class TokenRequest
[JsonPropertyName("username"), EmailAddress, Required]
public string? Username { get; set; }
[JsonPropertyName("password"), DataType(DataType.Password), Required]
public string? Password { get; set; }
[JsonPropertyName("code"), DataType(DataType.Text)]
public string? Code { get; set; }
}
public class TokenResponse
{
[JsonPropertyName("access_token")]
public string? AccessToken { get; set; }
[JsonPropertyName("expires_in")]
public int ExpireInSeconds { get; set; }
[JsonPropertyName("refresh_token")]
public string? RefreshToken { get; set; }
}
public class TokenRevokeRequest
{
[JsonPropertyName("token"), Required]
public string? Token { get; set; }
[JsonPropertyName("reason")]
public string? Reason { get; set; }
public TokenRevokeRequest(string token, string? reason)
{
[JsonPropertyName("username"), EmailAddress, Required]
public string Username { get; set; }
[JsonPropertyName("password"), DataType(DataType.Password), Required]
public string Password { get; set; }
[JsonPropertyName("code"), DataType(DataType.Text)]
public string? Code { get; set; }
}
public class TokenResponse
{
[JsonPropertyName("access_token")]
public string AccessToken { get; set; }
[JsonPropertyName("expires_in")]
public int ExpireInSeconds { get; set; }
[JsonPropertyName("refresh_token")]
public string RefreshToken { get; set; }
}
public class TokenRevokeRequest
{
[JsonPropertyName("token"), Required]
public string Token { get; set; }
[JsonPropertyName("reason")]
public string? Reason { get; set; }
public TokenRevokeRequest(string token, string? reason)
{
Token = token;
Reason = reason;
}
}
public class TokenRefreshRequest
{
[JsonPropertyName("token"), Required]
public string Token { get; set; }
public TokenRefreshRequest(string token)
{
Token = token;
}
Token = token;
Reason = reason;
}
}
public class TokenRefreshRequest
{
[JsonPropertyName("token"), Required]
public string? Token { get; set; }
public TokenRefreshRequest(string token)
{
Token = token;
}
}

View file

@ -1,8 +1,7 @@
namespace Insight.Domain.Models
namespace Insight.Domain.Models;
public class UpdateResponse
{
public class UpdateResponse
{
public Version? Version { get; set; }
public Uri? Uri { get; set; }
}
public Version? Version { get; set; }
public Uri? Uri { get; set; }
}

View file

@ -0,0 +1,32 @@
using MemoryPack;
using System.Runtime.InteropServices;
namespace Insight.Domain.Network.Agent.Messages;
[MemoryPackable]
public partial class Application : IMessage
{
[MemoryPackOrder(0)]
public string? Name { get; set; }
[MemoryPackOrder(1)]
public string? Publisher { get; set; }
[MemoryPackOrder(2)]
public string? Version { get; set; }
[MemoryPackOrder(3)]
public string? Location { get; set; }
[MemoryPackOrder(4)]
public string? Source { get; set; }
[MemoryPackOrder(5)]
public string? Uninstall { get; set; }
[MemoryPackOrder(6)]
public DateTime? InstallDate { get; set; }
[MemoryPackOrder(7)]
public Architecture? Architecture { get; set; }
}

View file

@ -0,0 +1,29 @@
using MemoryPack;
namespace Insight.Domain.Network.Agent.Messages;
[MemoryPackable]
public partial class AuthenticationRequest : IMessage { }
[MemoryPackable]
public partial class AuthenticationResponse : IMessage
{
[MemoryPackOrder(0)]
public PlatformType? Platform { get; set; }
[MemoryPackOrder(1)]
public Guid Serial { get; set; }
[MemoryPackOrder(2)]
public Version? Version { get; set; }
[MemoryPackOrder(3)]
public string? Hostname { get; set; }
public enum PlatformType
{
Unknown = 0,
Windows = 1,
Unix = 2
}
}

View file

@ -0,0 +1,6 @@
using MemoryPack;
namespace Insight.Domain.Network.Agent.Messages;
[MemoryPackable]
public partial class InventoryRequest : IMessage { }

View file

@ -0,0 +1,95 @@
using MemoryPack;
namespace Insight.Domain.Network.Agent.Messages;
[MemoryPackable]
public partial class Drive : IMessage
{
[MemoryPackOrder(0)]
public uint? Index { get; set; }
[MemoryPackOrder(1)]
public string? Id { get; set; }
[MemoryPackOrder(2)]
public string? Name { get; set; }
[MemoryPackOrder(3)]
public string? Manufacturer { get; set; }
[MemoryPackOrder(4)]
public string? SerialNumber { get; set; }
[MemoryPackOrder(5)]
public ulong? Size { get; set; }
[MemoryPackOrder(6)]
public string? Status { get; set; }
[MemoryPackOrder(7)]
public string? InterfaceType { get; set; }
[MemoryPackOrder(8)]
public string? FirmwareRevision { get; set; }
[MemoryPackOrder(9)]
public string? PNPDeviceID { get; set; }
[MemoryPackOrder(10)]
public List<Volume>? Volumes { get; set; }
}
[MemoryPackable]
public partial class Volume : IMessage
{
[MemoryPackOrder(0)]
public uint? Index { get; set; }
[MemoryPackOrder(1)]
public string? Id { get; set; }
[MemoryPackOrder(2)]
public string? Name { get; set; }
[MemoryPackOrder(3)]
public string? SerialNumber { get; set; }
[MemoryPackOrder(4)]
public ulong? Size { get; set; }
[MemoryPackOrder(5)]
public ulong? FreeSpace { get; set; }
[MemoryPackOrder(6)]
public string? Type { get; set; }
[MemoryPackOrder(7)]
public string? FileSystem { get; set; }
[MemoryPackOrder(8)]
public bool? Compressed { get; set; }
[MemoryPackOrder(9)]
public bool? Bootable { get; set; }
[MemoryPackOrder(10)]
public bool? PrimaryPartition { get; set; }
[MemoryPackOrder(11)]
public bool? BootPartition { get; set; }
[MemoryPackOrder(12)]
public ulong? BlockSize { get; set; }
[MemoryPackOrder(13)]
public ulong? NumberOfBlocks { get; set; }
[MemoryPackOrder(14)]
public ulong? StartingOffset { get; set; }
[MemoryPackOrder(15)]
public DriveType? DriveType { get; set; }
[MemoryPackOrder(16)]
public string? ProviderName { get; set; }
}

View file

@ -0,0 +1,37 @@
using MemoryPack;
namespace Insight.Domain.Network.Agent.Messages;
[MemoryPackable]
public partial class Event : IMessage
{
[MemoryPackOrder(0)]
public DateTime? Timestamp { get; set; }
[MemoryPackOrder(1)]
public StatusType? Status { get; set; }
[MemoryPackOrder(2)]
public string? Source { get; set; }
[MemoryPackOrder(3)]
public string? Category { get; set; }
[MemoryPackOrder(4)]
public int? EventId { get; set; }
[MemoryPackOrder(5)]
public string? Task { get; set; }
[MemoryPackOrder(6)]
public string? Message { get; set; }
public enum StatusType
{
Unknown = 0,
Information = 1,
Warning = 2,
Error = 3,
Critical = 4
}
}

View file

@ -0,0 +1,187 @@
using MemoryPack;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
namespace Insight.Domain.Network.Agent.Messages;
[MemoryPackable]
public partial class Interface : IMessage
{
[MemoryPackOrder(0)]
public uint? Index { get; set; }
[MemoryPackOrder(1)]
public Guid? Guid { get; set; }
[MemoryPackOrder(2)]
public string? Mac { get; set; }
[MemoryPackOrder(3)]
public string? Name { get; set; }
[MemoryPackOrder(4)]
public string? Description { get; set; }
[MemoryPackOrder(5)]
public string? Manufacturer { get; set; }
[MemoryPackOrder(6)]
public string? Suffix { get; set; }
[MemoryPackOrder(7)]
public bool? Physical { get; set; }
[MemoryPackOrder(8)]
public NetworkInterfaceType? Type { get; set; }
[MemoryPackOrder(9)]
public OperationalStatus? Status { get; set; }
[MemoryPackOrder(10)]
public long? Speed { get; set; }
[MemoryPackOrder(11)]
public long? Ipv4Mtu { get; set; }
[MemoryPackOrder(12)]
public bool? Ipv4Dhcp { get; set; }
[MemoryPackOrder(13)]
public bool? Ipv4Forwarding { get; set; }
[MemoryPackOrder(14)]
public long? Ipv6Mtu { get; set; }
[MemoryPackOrder(15)]
public long? Sent { get; set; }
[MemoryPackOrder(16)]
public long? Received { get; set; }
[MemoryPackOrder(17)]
public long? IncomingPacketsDiscarded { get; set; }
[MemoryPackOrder(18)]
public long? IncomingPacketsWithErrors { get; set; }
[MemoryPackOrder(19)]
public long? IncomingUnknownProtocolPackets { get; set; }
[MemoryPackOrder(20)]
public long? OutgoingPacketsDiscarded { get; set; }
[MemoryPackOrder(21)]
public long? OutgoingPacketsWithErrors { get; set; }
[MemoryPackOrder(22)]
public List<Unicast>? Addresses { get; set; }
[MemoryPackOrder(23)]
public List<IPAddress2>? Gateways { get; set; }
[MemoryPackOrder(24)]
public List<IPAddress2>? Dns { get; set; }
[MemoryPackOrder(25)]
public List<IPAddress2>? Dhcp { get; set; }
[MemoryPackOrder(26)]
public List<Route>? Routes { get; set; }
}
[MemoryPackable]
public partial class Unicast : IMessage
{
[MemoryPackOrder(0)]
public IPAddress2? IpAddress { get; set; }
[MemoryPackOrder(1)]
public IPAddress2? Ipv4Mask { get; set; }
[MemoryPackOrder(2)]
public long? AddressPreferredLifetime { get; set; }
[MemoryPackOrder(3)]
public long? AddressValidLifetime { get; set; }
[MemoryPackOrder(4)]
public long? DhcpLeaseLifetime { get; set; }
[MemoryPackOrder(5)]
public DuplicateAddressDetectionState? DuplicateAddressDetectionState { get; set; }
[MemoryPackOrder(6)]
public int? PrefixLength { get; set; }
[MemoryPackOrder(7)]
public PrefixOrigin? PrefixOrigin { get; set; }
[MemoryPackOrder(8)]
public SuffixOrigin? SuffixOrigin { get; set; }
}
[MemoryPackable]
public partial class Route : IMessage
{
[MemoryPackOrder(0)]
public uint? InterfaceIndex { get; set; }
[MemoryPackOrder(1)]
public IPAddress2? Destination { get; set; }
[MemoryPackOrder(2)]
public IPAddress2? Gateway { get; set; }
[MemoryPackOrder(3)]
public string? Mask { get; set; }
[MemoryPackOrder(4)]
public int? Metric { get; set; }
}
[MemoryPackable]
public partial class IPAddress2 : IMessage
{
[MemoryPackOrder(0)]
public AddressFamily? AddressFamily { get; set; }
[MemoryPackOrder(1)]
public string? Address { get; set; }
[MemoryPackOrder(2)]
public bool? IsIPv6Teredo { get; set; }
[MemoryPackOrder(3)]
public bool? IsIPv6SiteLocal { get; set; }
[MemoryPackOrder(4)]
public bool? IsIPv6Multicast { get; set; }
[MemoryPackOrder(5)]
public bool? IsIPv6LinkLocal { get; set; }
[MemoryPackOrder(6)]
public bool? IsIPv4MappedToIPv6 { get; set; }
[MemoryPackOrder(7)]
public bool? IsIPv6UniqueLocal { get; set; }
[MemoryPackConstructor]
public IPAddress2()
{
}
public IPAddress2(IPAddress address)
{
AddressFamily = address.AddressFamily;
Address = address.ToString();
IsIPv4MappedToIPv6 = address.IsIPv4MappedToIPv6;
IsIPv6LinkLocal = address.IsIPv6LinkLocal;
IsIPv6Multicast = address.IsIPv6Multicast;
IsIPv6SiteLocal = address.IsIPv6SiteLocal;
IsIPv6Teredo = address.IsIPv6Teredo;
IsIPv6UniqueLocal = address.IsIPv6UniqueLocal;
}
}

Some files were not shown because too many files have changed in this diff Show more