Skip to content
This repository has been archived by the owner on Nov 1, 2024. It is now read-only.

VPN try 2 #377

Merged
merged 1 commit into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<controls:PanicBunkerTab
<controls:PanicBunkerTab
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.Administration.UI.Tabs.PanicBunkerTab"
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
Expand Down Expand Up @@ -37,6 +37,11 @@
<Label Text="{Loc admin-ui-panic-bunker-min-overall-minutes}" MinWidth="175" />
<LineEdit Name="MinOverallMinutes" MinWidth="50" Margin="0 0 5 0" />
<Label Text="{Loc generic-minutes}" />
<!-- Corvax-VPNGuard-Start -->
<BoxContainer Orientation="Horizontal" Margin="2" Visible="True" Name="VPNContainer">
<CheckBox Name="DenyVPN" Text="{Loc admin-ui-panic-bunker-deny-vpn}" />
</BoxContainer>
<!-- Corvax-VPNGuard-End -->
</BoxContainer>
</BoxContainer>
</BoxContainer>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Shared.Administration.Events;
using Content.Corvax.Interfaces.Shared;
using Content.Shared.Administration.Events;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.XAML;
Expand Down Expand Up @@ -28,6 +29,16 @@ public PanicBunkerTab()
MinOverallMinutes.OnTextEntered += args => SendMinOverallMinutes(args.Text);
MinOverallMinutes.OnFocusExit += args => SendMinOverallMinutes(args.Text);
_minOverallMinutes = MinOverallMinutes.Text;

// Corvax-VPNGuard-Start
var haveSecrets = IoCManager.Instance!.TryResolveType<ISharedSponsorsManager>(out _); // TODO: Probably need better way to detect Secrets module
if (haveSecrets)
{
VPNContainer.Visible = true;
DenyVPN.OnPressed += _ => SendDenyVpn(DenyVPN.Pressed);
}
// Corvax-VPNGuard-End

}

private void SendMinAccountAge(string text)
Expand All @@ -54,6 +65,13 @@ private void SendMinOverallMinutes(string text)
_console.ExecuteCommand($"panicbunker_min_overall_minutes {minutes}");
}

// Corvax-VPNGuard-Start
private void SendDenyVpn(bool deny)
{
_console.ExecuteCommand($"panicbunker_deny_vpn {deny}");
}
// Corvax-VPNGuard-End

public void UpdateStatus(PanicBunkerStatus status)
{
EnabledButton.Pressed = status.Enabled;
Expand All @@ -73,5 +91,6 @@ public void UpdateStatus(PanicBunkerStatus status)

MinOverallMinutes.Text = status.MinOverallMinutes.ToString();
_minOverallMinutes = MinOverallMinutes.Text;
DenyVPN.Pressed = status.DenyVpn; // Corvax-VPNGuard
}
}
6 changes: 3 additions & 3 deletions Content.Server/Administration/Commands/PanicBunkerCommand.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Content.Shared.Administration;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
Expand Down Expand Up @@ -144,7 +144,7 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)

if (args.Length > 1)
{
shell.WriteError(Loc.GetString("shell-need-between-arguments",("lower", 0), ("upper", 1)));
shell.WriteError(Loc.GetString("shell-need-between-arguments", ("lower", 0), ("upper", 1)));
return;
}

Expand Down Expand Up @@ -176,7 +176,7 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)

if (args.Length > 1)
{
shell.WriteError(Loc.GetString("shell-need-between-arguments",("lower", 0), ("upper", 1)));
shell.WriteError(Loc.GetString("shell-need-between-arguments", ("lower", 0), ("upper", 1)));
return;
}

Expand Down
10 changes: 10 additions & 0 deletions Content.Server/Administration/Systems/AdminSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Content.Shared.Bank.Components;
using Content.Shared.Bank.Events;
using Content.Shared.CCVar;
using Content.Shared.Corvax.CCCVars;
using Content.Shared.GameTicking;
using Content.Shared.Hands.Components;
using Content.Shared.IdentityManagement;
Expand Down Expand Up @@ -82,6 +83,7 @@ public override void Initialize()
Subs.CVar(_config, CCVars.PanicBunkerShowReason, OnPanicBunkerShowReasonChanged, true);
Subs.CVar(_config, CCVars.PanicBunkerMinAccountAge, OnPanicBunkerMinAccountAgeChanged, true);
Subs.CVar(_config, CCVars.PanicBunkerMinOverallMinutes, OnPanicBunkerMinOverallMinutesChanged, true);
Subs.CVar(_config, CCCVars.PanicBunkerDenyVPN, OnPanicBunkerDenyVpnChanged, true); // Corvax-VPNGuard

/*
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
Expand Down Expand Up @@ -347,6 +349,14 @@ private void OnBabyJailMaxOverallMinutesChanged(int minutes)
SendBabyJailStatusAll();
}

// Corvax-VPNGuard-Start
private void OnPanicBunkerDenyVpnChanged(bool deny)
{
PanicBunker.DenyVpn = deny;
SendPanicBunkerStatusAll();
}
// Corvax-VPNGuard-End

private void UpdatePanicBunker()
{
var admins = PanicBunker.CountDeadminnedAdmins
Expand Down
81 changes: 70 additions & 11 deletions Content.Server/Connection/ConnectionManager.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
using System.Collections.Immutable;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using Content.Server._NF.Auth;
using Content.Server.Administration;
using Content.Server.Database;
using Content.Corvax.Interfaces.Server;
using Content.Corvax.Interfaces.Shared;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
using Content.Server.Preferences.Managers;
using Content.Shared.CCVar;
using Content.Shared.Corvax.CCCVars;
using Content.Shared.GameTicking;
using Content.Shared.Players.PlayTimeTracking;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Enums;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Timing;


Expand Down Expand Up @@ -52,21 +58,23 @@ public sealed class ConnectionManager : IConnectionManager
[Dependency] private readonly ServerDbEntryManager _serverDbEntry = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IChatManager _chatManager = default!;

private IServerSponsorsManager? _sponsorsMgr; //
//frontier
[Dependency] private readonly MiniAuthManager _authManager = default!;

private IServerVPNGuardManager? _vpnGuardMgr; // Corvax-VPNGuard

private readonly Dictionary<NetUserId, TimeSpan> _temporaryBypasses = [];
private ISawmill _sawmill = default!;

public void Initialize()
{
_sawmill = _logManager.GetSawmill("connections");

IoCManager.Instance!.TryResolveType(out _sponsorsMgr); // Corvax-Sponsors
_netMgr.Connecting += NetMgrOnConnecting;
_netMgr.AssignUserIdCallback = AssignUserIdCallback;
_plyMgr.PlayerStatusChanged += PlayerStatusChanged;
// Approval-based IP bans disabled because they don't play well with Happy Eyeballs.
// _netMgr.HandleApprovalCallback = HandleApproval;
}
Expand Down Expand Up @@ -135,6 +143,42 @@ private async Task NetMgrOnConnecting(NetConnectingArgs e)
}
}

private async void PlayerStatusChanged(object? sender, SessionStatusEventArgs args)
{
if (args.NewStatus == SessionStatus.Connected)
{
AdminAlertIfSharedConnection(args.Session);
}
}

private void AdminAlertIfSharedConnection(ICommonSession newSession)
{
var playerThreshold = _cfg.GetCVar(CCVars.AdminAlertMinPlayersSharingConnection);
if (playerThreshold < 0)
return;

var addr = newSession.Channel.RemoteEndPoint.Address;

var otherConnectionsFromAddress = _plyMgr.Sessions.Where(session =>
session.Status is SessionStatus.Connected or SessionStatus.InGame
&& session.Channel.RemoteEndPoint.Address.Equals(addr)
&& session.UserId != newSession.UserId)
.ToList();

var otherConnectionCount = otherConnectionsFromAddress.Count;
if (otherConnectionCount + 1 < playerThreshold) // Add one for the total, not just others, using the address
return;

var username = newSession.Name;
var otherUsernames = string.Join(", ",
otherConnectionsFromAddress.Select(session => session.Name));

_chatManager.SendAdminAlert(Loc.GetString("admin-alert-shared-connection",
("player", username),
("otherCount", otherConnectionCount),
("otherList", otherUsernames)));
}

private async Task<(ConnectionDenyReason, string, List<ServerBanDef>? bansHit)?> ShouldDeny(
NetConnectingArgs e)
{
Expand Down Expand Up @@ -197,8 +241,8 @@ private async Task NetMgrOnConnecting(NetConnectingArgs e)
}

var minOverallMinutes = _cfg.GetCVar(CCVars.PanicBunkerMinOverallMinutes);
var overallTime = ( await _db.GetPlayTimes(e.UserId)).Find(p => p.Tracker == PlayTimeTrackingShared.TrackerOverall);
var haveMinOverallTime = overallTime != null && overallTime.TimeSpent.TotalHours > minOverallMinutes;
var overallTime = (await _db.GetPlayTimes(e.UserId)).Find(p => p.Tracker == PlayTimeTrackingShared.TrackerOverall);
var haveMinOverallTime = overallTime != null && overallTime.TimeSpent.TotalMinutes > minOverallMinutes;

// Use the custom reason if it exists & they don't have the minimum time
if (customReason != string.Empty && !haveMinOverallTime && !bypassAllowed)
Expand All @@ -210,10 +254,27 @@ private async Task NetMgrOnConnecting(NetConnectingArgs e)
{
return (ConnectionDenyReason.Panic,
Loc.GetString("panic-bunker-account-denied-reason",
("reason", Loc.GetString("panic-bunker-account-reason-overall", ("hours", minOverallMinutes)))), null);
("reason", Loc.GetString("panic-bunker-account-reason-overall", ("minutes", minOverallMinutes)))), null);
}

// Corvax-VPNGuard-Start
if (_vpnGuardMgr == null) // "lazyload" because of problems with dependency resolve order
IoCManager.Instance!.TryResolveType(out _vpnGuardMgr);

var denyVpn = false;
if (_cfg.GetCVar(CCCVars.PanicBunkerDenyVPN) && _vpnGuardMgr != null)
{
denyVpn = await _vpnGuardMgr.IsConnectionVpn(e.IP.Address);
if (denyVpn)
{
return (ConnectionDenyReason.Panic,
Loc.GetString("panic-bunker-account-denied-reason",
("reason", Loc.GetString("panic-bunker-account-reason-vpn"))), null);
}
}
// Corvax-VPNGuard-End

if (!validAccountAge || !haveMinOverallTime && !bypassAllowed)
if ((!validAccountAge || !haveMinOverallTime || denyVpn) && !bypassAllowed) // Corvax-VPNGuard
{
return (ConnectionDenyReason.Panic, Loc.GetString("panic-bunker-account-denied"), null);
}
Expand All @@ -231,8 +292,8 @@ private async Task NetMgrOnConnecting(NetConnectingArgs e)
var adminBypass = _cfg.GetCVar(CCVars.AdminBypassMaxPlayers) && adminData != null;
// Corvax-Queue-Start
var isQueueEnabled = IoCManager.Instance!.TryResolveType<IServerJoinQueueManager>(out var mgr) && mgr.IsEnabled;
if (_plyMgr.PlayerCount >= _cfg.GetCVar(CCVars.SoftMaxPlayers) && !isPrivileged && !isQueueEnabled)
// Corvax-Queue-End
if ((_plyMgr.PlayerCount >= _cfg.GetCVar(CCVars.SoftMaxPlayers) && !adminBypass) && !wasInGame && !isQueueEnabled)
// Corvax-Queue-End
{
return (ConnectionDenyReason.Full, Loc.GetString("soft-player-cap-full"), null);
}
Expand Down Expand Up @@ -349,13 +410,11 @@ private bool HasTemporaryBypass(NetUserId user)
// Corvax-Queue-Start: Make these conditions in one place, for checks in the connection and in the queue
public async Task<bool> HavePrivilegedJoin(NetUserId userId)
{
var adminBypass = await _dbManager.GetAdminDataForAsync(userId) != null;
var havePriorityJoin = _sponsorsMgr != null && _sponsorsMgr.HavePriorityJoin(userId); // Corvax-Sponsors
var adminBypass = _cfg.GetCVar(CCVars.AdminBypassMaxPlayers) && await _dbManager.GetAdminDataForAsync(userId) != null;
var wasInGame = EntitySystem.TryGet<GameTicker>(out var ticker) &&
ticker.PlayerGameStatuses.TryGetValue(userId, out var status) &&
status == PlayerGameStatus.JoinedGame;
return adminBypass ||
havePriorityJoin || // Corvax-Sponsors
wasInGame;
}
// Corvax-Queue-End
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.Corvax.CCCVars;
using Robust.Shared.Configuration;
using Robust.Shared.Console;

namespace Content.Server.Corvax.Administration.Commands;

[AdminCommand(AdminFlags.Server)]
public sealed class PanicBunkerDenyVpnCommand : LocalizedCommands
{
[Dependency] private readonly IConfigurationManager _cfg = default!;

public override string Command => "panicbunker_deny_vpn";

public override void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 1)
{
shell.WriteError(Loc.GetString("shell-need-exactly-one-argument"));
return;
}

if (!bool.TryParse(args[0], out var deny))
{
shell.WriteError(Loc.GetString("shell-argument-must-be-boolean"));
return;
}

_cfg.SetCVar(CCCVars.PanicBunkerDenyVPN, deny);
shell.WriteLine(Loc.GetString(deny ? "panicbunker-command-deny-vpn-enabled" : "panicbunker-command-deny-vpn-disabled"));
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Robust.Shared.Serialization;
using Robust.Shared.Serialization;

namespace Content.Shared.Administration.Events;

Expand All @@ -12,6 +12,7 @@ public sealed class PanicBunkerStatus
public bool ShowReason;
public int MinAccountAgeMinutes;
public int MinOverallMinutes;
public bool DenyVpn; // Corvax-VPNGuard
}

[Serializable, NetSerializable]
Expand Down
9 changes: 9 additions & 0 deletions Content.Shared/CCVar/CCVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,15 @@ public static readonly CVarDef<bool>
public static readonly CVarDef<bool> ServerBanErasePlayer =
CVarDef.Create("admin.server_ban_erase_player", false, CVar.ARCHIVE | CVar.SERVER | CVar.REPLICATED);

/// <summary>
/// Minimum players sharing a connection required to create an alert. -1 to disable the alert.
/// </summary>
/// <remarks>
/// If you set this to 0 or 1 then it will alert on every connection, so probably don't do that.
/// </remarks>
public static readonly CVarDef<int> AdminAlertMinPlayersSharingConnection =
CVarDef.Create("admin.alert.min_players_sharing_connection", -1, CVar.SERVERONLY);

/// <summary>
/// Minimum explosion intensity to create an admin alert message. -1 to disable the alert.
/// </summary>
Expand Down
17 changes: 17 additions & 0 deletions Content.Shared/Corvax/CCCVars/CCCVars.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Robust.Shared.Configuration;

namespace Content.Shared.Corvax.CCCVars;

/// <summary>
/// Corvax modules console variables
/// </summary>
[CVarDefs]
// ReSharper disable once InconsistentNaming
public sealed class CCCVars
{
/// <summary>
/// Deny any VPN connections.
/// </summary>
public static readonly CVarDef<bool> PanicBunkerDenyVPN =
CVarDef.Create("game.panic_bunker.deny_vpn", false, CVar.SERVERONLY);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ admin-ui-panic-bunker-count-deadminned-admins-tooltip = Count deadminned admins
admin-ui-panic-bunker-show-reason = Show Reason
admin-ui-panic-bunker-show-reason-tooltip = Show the user why they were blocked from connecting by the panic bunker.
admin-ui-panic-bunker-min-account-age = Min. Account Age
admin-ui-panic-bunker-min-overall-hours = Min. Overall Playtime
admin-ui-panic-bunker-min-overall-minutes = Min. Overall Playtime
admin-ui-panic-bunker-is-enabled = The panic bunker is currently enabled.
admin-ui-panic-bunker-enabled-admin-alert = The panic bunker has been enabled.
admin-ui-panic-bunker-disabled-admin-alert = The panic bunker has been disabled.
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
cmd-panicbunker_deny_vpn-desc = Включает или отключает запрет доступа через VPN-соединения.
cmd-panicbunker_deny_vpn-help = Использование: panicbunker_min_overall_hours <bool>
panicbunker-command-deny-vpn-enabled = Бункер теперь будет блокировать подключения через VPN.
panicbunker-command-deny-vpn-disabled = Бункер больше не будет блокировать подключения через VPN.
1 change: 1 addition & 0 deletions Resources/Locale/ru-RU/generic.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ generic-unknown-title = Неизвестно
generic-error = ошибка
generic-invalid = недействительно
generic-hours = часов
generic-minutes = минут
generic-playtime-title = Игровое время
generic-confirm = Подтвердить
Loading