117 lines
3.0 KiB
C#
117 lines
3.0 KiB
C#
using System.Globalization;
|
|
|
|
namespace LibNftables.Tests;
|
|
|
|
internal static class NativeTestSupport
|
|
{
|
|
private const string PrivilegedTestsEnvironmentVariable = "LIBNFTABLES_RUN_PRIVILEGED_TESTS";
|
|
|
|
internal static bool IsRunningAsRoot()
|
|
{
|
|
if (!OperatingSystem.IsLinux())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
foreach (var line in File.ReadLines("/proc/self/status"))
|
|
{
|
|
if (!line.StartsWith("Uid:", StringComparison.Ordinal))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var parts = line["Uid:".Length..]
|
|
.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
|
|
|
return parts.Length > 0 && parts[0] == "0";
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// If uid probing fails, keep tests conservative.
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
internal static bool PrivilegedTestsRequested()
|
|
{
|
|
var value = Environment.GetEnvironmentVariable(PrivilegedTestsEnvironmentVariable);
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return value.Equals("1", StringComparison.Ordinal)
|
|
|| value.Equals("true", StringComparison.OrdinalIgnoreCase)
|
|
|| value.Equals("yes", StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
internal static bool ShouldRunPrivilegedTests()
|
|
{
|
|
return PrivilegedTestsRequested()
|
|
&& IsRunningAsRoot()
|
|
&& HasCapNetAdmin();
|
|
}
|
|
|
|
internal static bool HasCapNetAdmin()
|
|
{
|
|
const int capNetAdminBit = 12;
|
|
const ulong mask = 1UL << capNetAdminBit;
|
|
|
|
try
|
|
{
|
|
foreach (var line in File.ReadLines("/proc/self/status"))
|
|
{
|
|
if (!line.StartsWith("CapEff:", StringComparison.Ordinal))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var hex = line["CapEff:".Length..].Trim();
|
|
if (ulong.TryParse(hex, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out var value))
|
|
{
|
|
return (value & mask) != 0;
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// If capability probing fails, keep tests conservative.
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
internal static bool TryCreateContext(out NftContext context)
|
|
{
|
|
try
|
|
{
|
|
context = new NftContext();
|
|
return true;
|
|
}
|
|
catch (DllNotFoundException)
|
|
{
|
|
context = null!;
|
|
return false;
|
|
}
|
|
catch (TypeInitializationException ex) when (ex.InnerException is DllNotFoundException)
|
|
{
|
|
context = null!;
|
|
return false;
|
|
}
|
|
catch (BadImageFormatException)
|
|
{
|
|
context = null!;
|
|
return false;
|
|
}
|
|
catch (EntryPointNotFoundException)
|
|
{
|
|
context = null!;
|
|
return false;
|
|
}
|
|
}
|
|
}
|