Skip to content

Commit 579f3ef

Browse files
removed NetTools dependency, rewrote patches, so patched libraries are no dependencies
1 parent 8a736f0 commit 579f3ef

File tree

16 files changed

+260
-264
lines changed

16 files changed

+260
-264
lines changed

Aikido.Zen.Core/Agent.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
using Aikido.Zen.Core.Models.Events;
1515
using Microsoft.Extensions.Logging;
1616
using Microsoft.Extensions.Logging.Abstractions;
17-
using NetTools;
1817

1918
[assembly: InternalsVisibleTo("Aikido.Zen.Tests")]
2019
namespace Aikido.Zen.Core

Aikido.Zen.Core/Aikido.Zen.Core.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,10 @@
3535
</Target>-->
3636

3737
<ItemGroup>
38-
<PackageReference Include="IPAddressRange" Version="6.1.0" />
3938
<PackageReference Include="Lib.Harmony" Version="2.3.3" />
4039
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
4140
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
4241
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
43-
<PackageReference Include="System.Text.Json" Version="9.0.0" />
42+
<PackageReference Include="System.Text.Json" Version="8.0.1" />
4443
</ItemGroup>
4544
</Project>

Aikido.Zen.Core/Helpers/IPHelper.cs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.Net;
22
using System.Linq;
3-
using NetTools;
43
using System.Collections.Generic;
54
using System;
65

@@ -28,30 +27,6 @@ public static bool IsValidIp(string ip)
2827
return IPAddress.TryParse(ip, out _);
2928
}
3029

31-
/// <summary>
32-
/// Check if an IP address is in a subnet
33-
/// Example:
34-
/// Mask: 192.168.1.0/24
35-
/// Address: 192.168.1.1
36-
/// </summary>
37-
/// <param name="address"></param>
38-
/// <param name="subnet"></param>
39-
/// <returns></returns>
40-
public static bool IsInSubnet(IPAddress address, IPAddressRange subnet)
41-
{
42-
return subnet.Contains(address);
43-
}
44-
45-
/// <summary>
46-
/// Checks if a given ip string is a subnet
47-
/// </summary>
48-
/// <param name="ip"></param>
49-
/// <returns></returns>
50-
public static bool IsSubnet(string ip)
51-
{
52-
return ip.Contains("/") && IPAddressRange.TryParse(ip, out _);
53-
}
54-
5530
/// <summary>
5631
/// Converts an IP address range to a list of CIDR strings.
5732
/// </summary>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Reflection;
6+
using System.Text;
7+
8+
namespace Aikido.Zen.Core.Helpers
9+
{
10+
/// <summary>
11+
/// Helper class for reflection-related operations.
12+
/// </summary>
13+
public static class ReflectionHelper
14+
{
15+
private static IDictionary<string, Type> _types;
16+
private static IDictionary<string, Assembly> _assemblies;
17+
18+
static ReflectionHelper()
19+
{
20+
_types = new Dictionary<string, Type>();
21+
_assemblies = new Dictionary<string, Assembly>();
22+
}
23+
24+
/// <summary>
25+
/// Attempts to load an assembly, get a type from the loaded assembly, and then get a method from the type.
26+
/// </summary>
27+
/// <param name="assemblyName">The name of the assembly to load.</param>
28+
/// <param name="typeName">The name of the type to get from the assembly.</param>
29+
/// <param name="methodName">The name of the method to get from the type.</param>
30+
/// <param name="parameterTypeNames">The names of the parameter types for the method.</param>
31+
/// <returns>The MethodInfo of the specified method, or null if not found.</returns>
32+
public static MethodInfo GetMethodFromAssembly(string assemblyName, string typeName, string methodName, params string[] parameterTypeNames)
33+
{
34+
// Attempt to load the assembly
35+
// Attempt to get the assembly from the cache, if not found, load it
36+
if (!_assemblies.TryGetValue(assemblyName, out var assembly))
37+
{
38+
assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == assemblyName);
39+
// If the assembly is not loaded, and the assembly path exists, load it
40+
if (File.Exists($"{assemblyName}.dll") && assembly == null)
41+
{
42+
assembly = Assembly.LoadFrom($"{assemblyName}.dll");
43+
}
44+
if (assembly == null) return null;
45+
_assemblies[assemblyName] = assembly;
46+
}
47+
48+
// Attempt to get the type from the cache, if not found, get it from the loaded assembly
49+
var typeKey = $"{assemblyName}.{typeName}";
50+
if (!_types.TryGetValue(typeKey, out var type))
51+
{
52+
type = assembly.ExportedTypes.FirstOrDefault(t => t.Name == typeName);
53+
if (type == null) return null;
54+
_types[typeKey] = type;
55+
}
56+
57+
// Use reflection to get the method
58+
var method = type.GetMethods().FirstOrDefault(m => m.Name == methodName && m.GetParameters().All(p => parameterTypeNames.Any(ptn => ptn == p.ParameterType.FullName)));
59+
return method;
60+
}
61+
62+
public static void ClearCache()
63+
{
64+
_types.Clear();
65+
_assemblies.Clear();
66+
}
67+
}
68+
}

Aikido.Zen.Core/Models/AgentContext.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using Aikido.Zen.Core.Helpers;
22
using Aikido.Zen.Core.Models.Ip;
33
using Microsoft.AspNetCore.Http;
4-
using NetTools;
54
using System;
65
using System.Collections.Generic;
76
using System.Linq;

Aikido.Zen.Core/Models/Ip/Blocklist.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.Net;
55
using System.Threading;
66
using Aikido.Zen.Core.Helpers;
7-
using NetTools;
87

98
namespace Aikido.Zen.Core.Models.Ip
109
{

Aikido.Zen.Core/Patches/HttpClientPatches.cs

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,47 +9,49 @@ namespace Aikido.Zen.Core.Patches
99
{
1010
internal static class HttpClientPatches
1111
{
12+
/// <summary>
13+
/// Applies patches to HttpClient methods using Harmony and reflection.
14+
/// </summary>
15+
/// <param name="harmony">The Harmony instance used for patching.</param>
1216
public static void ApplyPatches(Harmony harmony)
1317
{
14-
var asyncMethod = AccessTools.Method(typeof(HttpClient), "SendAsync", new[] {
15-
typeof(HttpRequestMessage),
16-
typeof(HttpCompletionOption),
17-
typeof(CancellationToken)
18-
});
19-
var syncMethod = AccessTools.Method(typeof(HttpClient), "Send", new[] {
20-
typeof(HttpRequestMessage),
21-
typeof(CancellationToken)
22-
});
23-
try
24-
{
25-
if (asyncMethod != null && !asyncMethod.IsAbstract)
26-
{
27-
var patchMethod = new HarmonyMethod(typeof(HttpClientPatches).GetMethod(nameof(CaptureRequest), BindingFlags.Static | BindingFlags.NonPublic));
28-
harmony.Patch(asyncMethod, patchMethod);
29-
}
18+
// Use reflection to get the methods dynamically
19+
PatchMethod(harmony, "System.Net.Http", "HttpClient", "SendAsync", "System.Net.Http.HttpRequestMessage", "System.Net.Http.HttpCompletionOption", "System.Threading.CancellationToken");
20+
PatchMethod(harmony, "System.Net.Http", "HttpClient", "Send", "System.Net.Http.HttpRequestMessage", "System.Threading.CancellationToken");
21+
}
3022

31-
if (syncMethod != null && !syncMethod.IsAbstract)
32-
{
33-
harmony.Patch(syncMethod, new HarmonyMethod(typeof(HttpClientPatches).GetMethod(nameof(CaptureRequest), BindingFlags.Static | BindingFlags.NonPublic)));
34-
}
35-
}
36-
catch (Exception)
23+
/// <summary>
24+
/// Patches a method using Harmony by dynamically retrieving it via reflection.
25+
/// </summary>
26+
/// <param name="harmony">The Harmony instance used for patching.</param>
27+
/// <param name="assemblyName">The name of the assembly containing the type.</param>
28+
/// <param name="typeName">The name of the type containing the method.</param>
29+
/// <param name="methodName">The name of the method to patch.</param>
30+
/// <param name="parameterTypeNames">The names of the parameter types for the method.</param>
31+
private static void PatchMethod(Harmony harmony, string assemblyName, string typeName, string methodName, params string[] parameterTypeNames)
32+
{
33+
var method = ReflectionHelper.GetMethodFromAssembly(assemblyName, typeName, methodName, parameterTypeNames);
34+
if (method != null && !method.IsAbstract)
3735
{
38-
// continue
36+
var patchMethod = new HarmonyMethod(typeof(HttpClientPatches).GetMethod(nameof(CaptureRequest), BindingFlags.Static | BindingFlags.NonPublic));
37+
harmony.Patch(method, patchMethod);
3938
}
40-
4139
}
4240

43-
internal static bool CaptureRequest(
44-
HttpRequestMessage request,
45-
HttpClient __instance)
41+
/// <summary>
42+
/// Callback method executed before the original HttpClient method is executed.
43+
/// </summary>
44+
/// <param name="request">The HttpRequestMessage being sent.</param>
45+
/// <param name="__instance">The instance of HttpClient being used.</param>
46+
/// <returns>True if the original method should continue execution; otherwise, false.</returns>
47+
internal static bool CaptureRequest(HttpRequestMessage request, HttpClient __instance)
4648
{
4749
var uri = __instance.BaseAddress == null
4850
? request.RequestUri
4951
: request.RequestUri == null
5052
? __instance.BaseAddress
5153
: new Uri(__instance.BaseAddress, request.RequestUri);
52-
54+
5355
var (hostname, port) = UriHelper.ExtractHost(uri);
5456
if (hostname.EndsWith("aikido.dev"))
5557
return true;

Aikido.Zen.DotNetCore/Aikido.Zen.DotNetCore.csproj

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
<PropertyGroup>
44
<TargetFrameworks>net6.0;net7.0;net8.0;</TargetFrameworks>
55
<ImplicitUsings>enable</ImplicitUsings>
6-
<Nullable>disable</Nullable>
6+
<Nullable>disable</Nullable>
77
<PackageOutputPath>..\nupkgs</PackageOutputPath>
8-
<AssemblyVersion></AssemblyVersion>
9-
<FileVersion></FileVersion>
8+
<AssemblyVersion>0.0.1</AssemblyVersion>
9+
<FileVersion>0.0.1</FileVersion>
1010
<UserSecretsId>97bd5157-97c6-4825-833a-933ce895cbc0</UserSecretsId>
1111
</PropertyGroup>
1212

@@ -16,20 +16,12 @@
1616
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
1717
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="2.2.2" />
1818
<PackageReference Include="Microsoft.AspNetCore.Routing.Abstractions" Version="2.2.0" />
19-
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
20-
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="6.0.0" Condition="'$(TargetFramework)' == 'net6.0'" />
21-
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="7.0.0" Condition="'$(TargetFramework)' == 'net7.0'" />
22-
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="8.0.0" Condition="'$(TargetFramework)' == 'net8.0'" />
2319
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" Condition="'$(TargetFramework)' == 'net6.0'" />
2420
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" Condition="'$(TargetFramework)' == 'net7.0'" />
2521
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" Condition="'$(TargetFramework)' == 'net8.0'" />
2622
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" Condition="'$(TargetFramework)' == 'net6.0'" />
2723
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" Condition="'$(TargetFramework)' == 'net7.0'" />
2824
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.0" Condition="'$(TargetFramework)' == 'net8.0'" />
29-
<PackageReference Include="MySql.Data" Version="9.1.0" />
30-
<PackageReference Include="MySqlConnector" Version="2.4.0" />
31-
<PackageReference Include="Npgsql" Version="9.0.2" />
32-
<PackageReference Include="System.Data.SqlClient" Version="4.9.0" />
3325
</ItemGroup>
3426

3527
<ItemGroup>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<package >
3+
<metadata>
4+
<id>Aikido.Zen.DotNetCore</id>
5+
<version>0.0.1-alpha4</version>
6+
<title>$title$</title>
7+
<authors>Aikido Security</authors>
8+
<owners>Aikido Security</owners>
9+
<description>Aikido Security Zen .NET Core Firewall</description>
10+
<frameworkReferences>
11+
<group targetFramework="net8.0">
12+
<frameworkReference name="Microsoft.AspNetCore.App" />
13+
</group>
14+
<group targetFramework="net7.0">
15+
<frameworkReference name="Microsoft.AspNetCore.App" />
16+
</group>
17+
<group targetFramework="net6.0">
18+
<frameworkReference name="Microsoft.AspNetCore.App" />
19+
</group>
20+
</frameworkReferences>
21+
<dependencies>
22+
<group targetFramework="net8.0">
23+
<dependency id="Lib.Harmony" version="2.3.3" />
24+
<dependency id="Microsoft.AspNetCore.Hosting.Abstractions" version="2.2.0" />
25+
<dependency id="Microsoft.AspNetCore.Http" version="2.2.2" />
26+
<dependency id="Microsoft.AspNetCore.Routing" version="2.2.2" />
27+
<dependency id="Microsoft.AspNetCore.Routing.Abstractions" version="2.2.0" />
28+
<dependency id="Microsoft.AspNetCore.Http.Abstractions" version="2.2.0" />
29+
<dependency id="Microsoft.AspNetCore.WebUtilities" version="2.2.0" />
30+
<dependency id="Microsoft.Extensions.Logging.Abstractions" version="8.0.2" />
31+
<dependency id="System.Text.Json" version="8.0.0" />
32+
</group>
33+
<group targetFramework="net7.0">
34+
<dependency id="Lib.Harmony" version="2.3.3" />
35+
<dependency id="Microsoft.AspNetCore.Hosting.Abstractions" version="2.2.0" />
36+
<dependency id="Microsoft.AspNetCore.Http" version="2.2.2" />
37+
<dependency id="Microsoft.AspNetCore.Routing" version="2.2.2" />
38+
<dependency id="Microsoft.AspNetCore.Routing.Abstractions" version="2.2.0" />
39+
<dependency id="Microsoft.AspNetCore.Http.Abstractions" version="2.2.0" />
40+
<dependency id="Microsoft.AspNetCore.WebUtilities" version="2.2.0" />
41+
<dependency id="Microsoft.Extensions.Logging.Abstractions" version="7.0.2" />
42+
<dependency id="System.Text.Json" version="7.0.0" />
43+
</group>
44+
<group targetFramework="net6.0">
45+
<dependency id="Lib.Harmony" version="2.3.3" />
46+
<dependency id="Microsoft.AspNetCore.Hosting.Abstractions" version="2.2.0" />
47+
<dependency id="Microsoft.AspNetCore.Http" version="2.2.2" />
48+
<dependency id="Microsoft.AspNetCore.Routing" version="2.2.2" />
49+
<dependency id="Microsoft.AspNetCore.Routing.Abstractions" version="2.2.0" />
50+
<dependency id="Microsoft.AspNetCore.Http.Abstractions" version="2.2.0" />
51+
<dependency id="Microsoft.AspNetCore.WebUtilities" version="2.2.0" />
52+
<dependency id="Microsoft.Extensions.Logging.Abstractions" version="6.0.2" />
53+
<dependency id="System.Text.Json" version="6.0.0" />
54+
</group>
55+
</dependencies>
56+
</metadata>
57+
<files>
58+
<file src="bin\Release\net8.0\Aikido.Zen.Core.dll" target="lib\net8.0" />
59+
<file src="bin\Release\net7.0\Aikido.Zen.Core.dll" target="lib\net7.0" />
60+
<file src="bin\Release\net6.0\Aikido.Zen.Core.dll" target="lib\net6.0" />
61+
<file src="bin\Release\net8.0\Aikido.Zen.DotNetCore.dll" target="lib\net8.0" />
62+
<file src="bin\Release\net7.0\Aikido.Zen.DotNetCore.dll" target="lib\net7.0" />
63+
<file src="bin\Release\net6.0\Aikido.Zen.DotNetCore.dll" target="lib\net6.0" />
64+
</files>
65+
</package>

0 commit comments

Comments
 (0)