Files
tbd-station-14/Content.Server/Administration/Commands/ImportNetsetCommand.cs
Moony b13e672393 Adds a tool for importing .netset files into the ban DB. (#9016)
* Adds a tool for importing .netset files into the ban DB.

* Adds a static variable so it's clear what the GUID is.
2022-06-25 10:52:05 -07:00

117 lines
3.7 KiB
C#

using System.Net;
using Content.Server.Database;
using Content.Shared.Administration;
using Robust.Shared.Console;
using Robust.Shared.ContentPack;
using Robust.Shared.Network;
using Robust.Shared.Utility;
namespace Content.Server.Administration.Commands;
[AdminCommand(AdminFlags.Host)]
public sealed class ImportNetsetCommand : IConsoleCommand
{
[Dependency] private readonly IResourceManager _resourceManager = default!;
[Dependency] private readonly IServerDbManager _serverDbManager = default!;
public static NetUserId AutomationBanningUser = new(new Guid("a17aa146-807c-48bb-8573-65e3cb05119d"));
public string Command => "importnetset";
public string Description => "Import a .netset file into the ban database.";
public string Help => "importnetset <filepath in vfs> \"<ban reason>\"";
public async void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 2)
{
shell.WriteError(Loc.GetString("shell-wrong-arguments-number"));
return;
}
var stream = _resourceManager.ContentFileReadText(new ResourcePath(args[0]).ToRootedPath());
var bansToAdd = new List<ServerBanDef>();
var line = await stream.ReadLineAsync();
while (line != null)
{
if (line.StartsWith("#")) // That's a comment, skip it.
{
line = await stream.ReadLineAsync();
continue;
}
if (bansToAdd.Count % 100 == 0)
shell.WriteLine($"Got {bansToAdd.Count} bans so far...");
var ipMaskSplit = line.Split("/");
if (ipMaskSplit.Length > 2)
{
shell.WriteError($"Failed to import address {line}");
return;
}
if (!IPAddress.TryParse(ipMaskSplit[0], out var ip))
{
shell.WriteError($"Failed to import address {line}");
return;
}
var cidr = 32;
if (ipMaskSplit.Length == 2)
{
if ( !int.TryParse(ipMaskSplit[1], out cidr))
{
shell.WriteError($"Failed to import address {line}");
return;
}
}
var possibleCollisions = await _serverDbManager.GetServerBansAsync(ip, null, null, false);
var collides = false;
foreach (var ban in possibleCollisions)
{
if (ban.UserId != null || ban.ExpirationTime != null || ban.HWId == null)
continue;
if (ban.Address == null) // no clue how we'd get here but best be safe.
continue;
if (ban.Address.Value.cidrMask > cidr)
continue;
collides = true;
shell.WriteError($"The imported address {ip}/{cidr} collides with {ban.Address.Value.address}/{ban.Address.Value.cidrMask}, ban {ban.Id}. Add it manually.");
}
if (collides)
{
line = await stream.ReadLineAsync();
continue; // not gonna add a ban that collides.
}
var def = new ServerBanDef(
null,
null,
(ip, cidr),
null,
DateTimeOffset.UnixEpoch,
null,
args[1],
AutomationBanningUser,
null);
bansToAdd.Add(def);
line = await stream.ReadLineAsync();
}
shell.WriteLine($"Importing {bansToAdd.Count} bans");
foreach (var ban in bansToAdd)
{
await _serverDbManager.AddServerBanAsync(ban);
}
shell.WriteLine("Import complete!");
}
}