Skip to content

Commit

Permalink
Merge pull request #83 from TheButlah/thebutlah/break-out-password-auth
Browse files Browse the repository at this point in the history
introduce IAuth and PasswordAuth
  • Loading branch information
dooly123 authored Dec 29, 2024
2 parents 94852fd + c6a42f9 commit c4112d9
Show file tree
Hide file tree
Showing 24 changed files with 388 additions and 201 deletions.
32 changes: 12 additions & 20 deletions Basis Server/BasisNetworkCore/Serializable/AuthenticationMessage.cs
Original file line number Diff line number Diff line change
@@ -1,41 +1,33 @@
#nullable enable

using LiteNetLib.Utils;

namespace Basis.Network.Core.Serializable
{
public static partial class SerializableBasis
{
/// Consistes of a ushort length, followed by byte array (of same length)
[System.Serializable]
public struct AuthenticationMessage
{
public ushort MessageLength;
public byte[] Message;
public byte[] bytes;
public void Deserialize(NetDataReader Reader)
{
if (Reader.TryGetUShort(out MessageLength))
if (Reader.TryGetUShort(out ushort msgLength))
{
Message = new byte[MessageLength];
Reader.GetBytes(Message, MessageLength);
bytes = new byte[msgLength];
Reader.GetBytes(bytes, msgLength);
}
else
{
BNL.LogError("missing Message Length!");
}
}
public void Dispose()

public readonly void Serialize(NetDataWriter Writer)
{
}
public void Serialize(NetDataWriter Writer)
{
if (Message != null)
{
MessageLength = (ushort)Message.Length;
Writer.Put(MessageLength);
Writer.Put(Message);
}
else
{
MessageLength = 0;
Writer.Put(MessageLength);
}
Writer.Put(checked((ushort)bytes.Length));
Writer.Put(bytes);
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions Basis Server/BasisNetworkServer/Auth/Interface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using AuthenticationMessage = Basis.Network.Core.Serializable.SerializableBasis.AuthenticationMessage;

namespace Basis.Network.Server.Auth
{
public interface IAuth
{
public bool IsAuthenticated(AuthenticationMessage msg);
}
}
64 changes: 64 additions & 0 deletions Basis Server/BasisNetworkServer/Auth/Password.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#nullable enable

using System.Runtime.Serialization;
using Encoding = System.Text.Encoding;
using static Basis.Network.Core.Serializable.SerializableBasis;

namespace Basis.Network.Server.Auth
{

/// Newtype on `string`. This represents the server's configured password.
internal readonly struct ServerPassword
{
public readonly string V { get; }
public ServerPassword(string password) { V = password; }
}

/// Newtype on `string`. This represents the user's password.
internal readonly struct UserPassword
{
public readonly string V { get; }
public UserPassword(string password) { V = password; }
}

internal readonly struct Deserialized
{
public readonly UserPassword Password { get; }
public Deserialized(AuthenticationMessage msg)
{
Password = new UserPassword(Encoding.UTF8.GetString(msg.bytes));
}
}

public class PasswordAuth : IAuth
{
private readonly ServerPassword serverPassword;

/// If `serverPassword` is an empty string, the server has no password and any user can connect.
public PasswordAuth(string serverPassword)
{
this.serverPassword = new ServerPassword(serverPassword);
}

private static bool CheckPassword(ServerPassword serverPassword, UserPassword userPassword)
{
if (serverPassword.V == string.Empty)
{
BNL.Log("No server password set, user is allowed");
return true;
}
if (userPassword.V == string.Empty)
{
BNL.Log("User had an empty password, user is rejected");
return false;
}
return serverPassword.V == userPassword.V;
}

public bool IsAuthenticated(AuthenticationMessage msg)
{
var deserialized = new Deserialized(msg);
return CheckPassword(serverPassword, deserialized.Password);
}
}
}
72 changes: 38 additions & 34 deletions Basis Server/BasisNetworkServer/BasisNetworkServer.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Basis.Network.Core;
using Basis.Network.Server;
using Basis.Network.Server.Auth;
using Basis.Network.Server.Generic;
using Basis.Network.Server.Ownership;
using Basis.Network.Server.Password;
using LiteNetLib;
using LiteNetLib.Utils;
using System;
Expand All @@ -21,10 +21,13 @@ public static class BasisNetworkServer
public static ConcurrentDictionary<ushort, NetPeer> Peers = new ConcurrentDictionary<ushort, NetPeer>();
public static Configuration Configuration;
public static Thread serverIncomeThread;
private static IAuth auth;

public static void StartServer(Configuration configuration)
{
Configuration = configuration;
BasisServerReductionSystem.Configuration = configuration;
auth = new PasswordAuth(configuration.Password ?? string.Empty);

SetupServer(configuration);
SetupServerEvents(configuration);
Expand Down Expand Up @@ -122,41 +125,42 @@ private static void HandleConnectionRequest(ConnectionRequest request)
return;
}

ProcessConnectionApproval(request, ServerCount);
}
catch (Exception e)
{
BNL.LogError(e.Message + " " + e.StackTrace);
}
}
// Decide if connection should be approved
{

private static void ProcessConnectionApproval(ConnectionRequest request, int ServerCount)
{
AuthenticationMessage authMessage = new AuthenticationMessage();
authMessage.Deserialize(request.Data);
AuthenticationMessage authMessage = new AuthenticationMessage();
authMessage.Deserialize(request.Data);

if (!BasisPasswordImplementation.CheckPassword(authMessage, Configuration, out string UsedPassword))
{
RejectWithReason(request, "Authentication failed Expected " + Configuration.Password + " but got " + UsedPassword);
return;
}

BNL.Log("Player approved. Current count: " + ServerCount);
ApproveAndInitializeConnection(request);
}
private static void ApproveAndInitializeConnection(ConnectionRequest request)
{
NetPeer newPeer = request.Accept();
if (Peers.TryAdd((ushort)newPeer.Id, newPeer))
{
BNL.Log($"Peer connected: {newPeer.Id}");
ReadyMessage readyMessage = new ReadyMessage();
readyMessage.Deserialize(request.Data);
SendRemoteSpawnMessage(newPeer, readyMessage);
if (auth.IsAuthenticated(authMessage))
{
RejectWithReason(request, "Authentication failed, password rejected");
return;
}

BNL.Log("Player approved. Current count: " + ServerCount);
}

// Finalize connection
{

NetPeer newPeer = request.Accept();
if (Peers.TryAdd((ushort)newPeer.Id, newPeer))
{
BNL.Log($"Peer connected: {newPeer.Id}");
ReadyMessage readyMessage = new ReadyMessage();
readyMessage.Deserialize(request.Data);
SendRemoteSpawnMessage(newPeer, readyMessage);
}
else
{
RejectWithReason(request, "Peer already exists.");
}
}
}
else
catch (Exception e)
{
RejectWithReason(request, "Peer already exists.");
BNL.LogError(e.Message + " " + e.StackTrace);
}
}

Expand Down Expand Up @@ -210,7 +214,7 @@ private static void HandleNetworkReceiveEvent(NetPeer peer, NetPacketReader read
{
if (reader.TryGetByte(out byte Byte))
{
// BNL.Log($"Found Channel {Byte} {reader.AvailableBytes}");
// BNL.Log($"Found Channel {Byte} {reader.AvailableBytes}");
HandleNetworkReceiveEvent(peer, reader, Byte, deliveryMethod);
}
else
Expand Down Expand Up @@ -353,7 +357,7 @@ private static void SendVoiceMessageToClients(ServerAudioSegmentMessage audioSeg
};
NetDataWriter NetDataWriter = new NetDataWriter();
audioSegment.Serialize(NetDataWriter);
// BNL.Log("Sending Voice Data To Clients");
// BNL.Log("Sending Voice Data To Clients");
BroadcastMessageToClients(NetDataWriter, channel, endPoints, DeliveryMethod.Sequenced);
}
else
Expand Down Expand Up @@ -450,7 +454,7 @@ private static void SendClientListToNewClient(NetPeer authClient)
List<ServerReadyMessage> copied = new List<ServerReadyMessage>();

IEnumerable<NetPeer> clientsToNotify = Peers.Values.Where(client => client != authClient);
BNL.Log("Notifing Newly Connected Client about "+ clientsToNotify.Count());
BNL.Log("Notifing Newly Connected Client about " + clientsToNotify.Count());
foreach (NetPeer client in clientsToNotify)
{
ServerReadyMessage serverReadyMessage = new ServerReadyMessage();
Expand Down

This file was deleted.

3 changes: 2 additions & 1 deletion Basis/BasisNetworkServer.Player.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,11 @@
<Compile Include="Packages\Basis Server\BasisNetworkServer\BasisNetworking\BasisNetworkOwnership.cs" />
<Compile Include="Packages\Basis Server\BasisNetworkServer\BasisNetworking\BasisServerReductionSystem.cs" />
<Compile Include="Packages\Basis Server\BasisNetworkServer\BasisNetworkHealthCheck.cs" />
<Compile Include="Packages\Basis Server\BasisNetworkServer\Auth\Password.cs" />
<Compile Include="Packages\Basis Server\BasisNetworkServer\BasisNetworking\BasisSavedState.cs" />
<Compile Include="Packages\Basis Server\BasisNetworkServer\BasisNetworkServer.cs" />
<Compile Include="Packages\Basis Server\BasisNetworkServer\Promethus\BasisPromethus.cs" />
<Compile Include="Packages\Basis Server\BasisNetworkServer\Password\BasisPasswordImplementation.cs" />
<Compile Include="Packages\Basis Server\BasisNetworkServer\Auth\Interface.cs" />
<Compile Include="Packages\Basis Server\BasisNetworkServer\BasisNetworking\BasisNetworkingGeneric.cs" />
<Compile Include="Packages\Basis Server\BasisNetworkServer\BasisNetworking\BasisServerConfiguration.cs" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public void Connect(ushort Port, string IpString,string PrimitivePassword)
Debug.Log("Network Starting Client");
BasisNetworkClient.AuthenticationMessage = new Network.Core.Serializable.SerializableBasis.AuthenticationMessage
{
Message = Encoding.UTF8.GetBytes(PrimitivePassword)
bytes = Encoding.UTF8.GetBytes(PrimitivePassword)
};
// Debug.Log("Size is " + BasisNetworkClient.AuthenticationMessage.Message.Length);
LocalPlayerPeer = BasisNetworkClient.StartClient(IpString, Port, readyMessage);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,42 +1,34 @@
using LiteNetLib.Utils;
#nullable enable

using LiteNetLib.Utils;

namespace Basis.Network.Core.Serializable
{
public static partial class SerializableBasis
{
/// Consistes of a ushort length, followed by byte array (of same length)
[System.Serializable]
public struct AuthenticationMessage
{
public ushort MessageLength;
public byte[] Message;
public void Deserialize(NetDataReader Writer)
public byte[] bytes;
public void Deserialize(NetDataReader Reader)
{
if (Writer.TryGetUShort(out MessageLength))
if (Reader.TryGetUShort(out ushort msgLength))
{
Message = new byte[MessageLength];
Writer.GetBytes(Message, MessageLength);
bytes = new byte[msgLength];
Reader.GetBytes(bytes, msgLength);
}
else
{
BNL.LogError("missing Message Length!");
}
}
public void Dispose()

public readonly void Serialize(NetDataWriter Writer)
{
}
public void Serialize(NetDataWriter Writer)
{
if (Message != null)
{
MessageLength = (ushort)Message.Length;
Writer.Put(MessageLength);
Writer.Put(Message);
}
else
{
MessageLength = 0;
Writer.Put(MessageLength);
}
Writer.Put(checked((ushort)bytes.Length));
Writer.Put(bytes);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void Deserialize(NetDataReader Writer)
throw new ArgumentException($"Invalid recipientsSize: {recipientsSize}");
}
recipients = new ushort[recipientsSize];
BNL.Log("Recipients is " + recipientsSize);
// BNL.Log("Recipients is " + recipientsSize);
for (int index = 0; index < recipientsSize; index++)
{
if (!Writer.TryGetUShort(out recipients[index]))
Expand Down
Loading

0 comments on commit c4112d9

Please sign in to comment.