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.
This commit is contained in:
116
Content.Server/Administration/Commands/ImportNetsetCommand.cs
Normal file
116
Content.Server/Administration/Commands/ImportNetsetCommand.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
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!");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user