feat: add option to reject new clients
Also check for magic bytes for new protocol change.
This commit is contained in:
parent
1c3eb05621
commit
902d9af11f
|
@ -17,6 +17,8 @@ namespace XIVChatPlugin {
|
|||
|
||||
public bool PairingMode { get; set; } = true;
|
||||
|
||||
public bool AcceptNewClients { get; set; } = true;
|
||||
|
||||
public Dictionary<Guid, Tuple<string, byte[]>> TrustedKeys { get; set; } = new Dictionary<Guid, Tuple<string, byte[]>>();
|
||||
public KeyPair KeyPair { get; set; } = null;
|
||||
|
||||
|
|
|
@ -138,8 +138,8 @@ namespace XIVChatPlugin {
|
|||
this.plugin.Config.SendBattle = sendBattle;
|
||||
this.plugin.Config.Save();
|
||||
}
|
||||
|
||||
ImGui.TextUnformatted("Changing this setting will not affect messages already in the backlog.");
|
||||
ImGui.SameLine();
|
||||
HelpMarker("Changing this setting will not affect messages already in the backlog.");
|
||||
|
||||
ImGui.Spacing();
|
||||
|
||||
|
@ -150,6 +150,16 @@ namespace XIVChatPlugin {
|
|||
}
|
||||
ImGui.SameLine();
|
||||
HelpMarker("While in pairing mode, XIVChat Server will listen for information requests from clients broadcast on your local network and respond with information about the server. This will make it easier to add your server to a client, but this should be turned off when not actively adding new devices.");
|
||||
|
||||
ImGui.Spacing();
|
||||
|
||||
bool acceptNew = this.plugin.Config.AcceptNewClients;
|
||||
if (WithWhiteText(() => ImGui.Checkbox("Accept new clients", ref acceptNew))) {
|
||||
this.plugin.Config.AcceptNewClients = acceptNew;
|
||||
this.plugin.Config.Save();
|
||||
}
|
||||
ImGui.SameLine();
|
||||
HelpMarker("If this is disabled, XIVChat Server will only allow clients with already-trusted keys to connect.");
|
||||
}
|
||||
|
||||
if (WithWhiteText(() => ImGui.CollapsingHeader("Trusted keys"))) {
|
||||
|
|
|
@ -243,6 +243,12 @@ namespace XIVChatPlugin {
|
|||
this.plugin.Functions.ProcessChatBox(message);
|
||||
}
|
||||
|
||||
private static readonly IReadOnlyList<byte> MAGIC = new byte[] {
|
||||
14,
|
||||
20,
|
||||
67,
|
||||
};
|
||||
|
||||
private void SpawnClientTask(TcpClient conn) {
|
||||
if (conn == null) {
|
||||
return;
|
||||
|
@ -251,6 +257,28 @@ namespace XIVChatPlugin {
|
|||
Task.Run(async () => {
|
||||
var stream = conn.GetStream();
|
||||
|
||||
// get ready for reading magic bytes
|
||||
var magic = new byte[MAGIC.Count];
|
||||
var read = 0;
|
||||
|
||||
// only listen for magic for five seconds
|
||||
using var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(TimeSpan.FromSeconds(5));
|
||||
|
||||
// read magic bytes
|
||||
while (read < magic.Length) {
|
||||
if (cts.IsCancellationRequested) {
|
||||
return;
|
||||
}
|
||||
|
||||
read += await stream.ReadAsync(magic, read, magic.Length - read, cts.Token);
|
||||
}
|
||||
|
||||
// ignore this connection if incorrect magic bytes
|
||||
if (!magic.SequenceEqual(MAGIC)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var handshake = await KeyExchange.ServerHandshake(this.plugin.Config.KeyPair, stream);
|
||||
var newClient = new Client(conn) {
|
||||
Handshake = handshake,
|
||||
|
@ -258,6 +286,11 @@ namespace XIVChatPlugin {
|
|||
|
||||
// if this public key isn't trusted, prompt first
|
||||
if (!this.plugin.Config.TrustedKeys.Values.Any(entry => entry.Item2.SequenceEqual(handshake.RemotePublicKey))) {
|
||||
// if configured to not accept new clients, reject connection
|
||||
if (!this.plugin.Config.AcceptNewClients) {
|
||||
return;
|
||||
}
|
||||
|
||||
var accepted = Channel.CreateBounded<bool>(1);
|
||||
|
||||
await this.pendingClients.Writer.WriteAsync(Tuple.Create(newClient, accepted));
|
||||
|
@ -392,7 +425,11 @@ namespace XIVChatPlugin {
|
|||
|
||||
this.clients.TryRemove(id, out var _);
|
||||
PluginLog.Log($"Client thread ended: {id}");
|
||||
});
|
||||
}).ContinueWith(_ => {
|
||||
try {
|
||||
conn.Close();
|
||||
} catch (ObjectDisposedException) { }
|
||||
}); ;
|
||||
}
|
||||
|
||||
private static readonly Regex colorRegex = new Regex(@"<Color\(.+?\)>", RegexOptions.Compiled);
|
||||
|
|
Loading…
Reference in New Issue
Block a user