fishnet installed

This commit is contained in:
2023-05-31 11:32:21 -04:00
parent 47b25269f1
commit a001fe1b04
1291 changed files with 126631 additions and 1 deletions

View File

@ -0,0 +1,21 @@

using FishNet.Broadcast;
namespace FishNet.Example.Authenticating
{
public struct HostPasswordBroadcast : IBroadcast
{
public string Password;
}
public struct PasswordBroadcast : IBroadcast
{
public string Password;
}
public struct ResponseBroadcast : IBroadcast
{
public bool Passed;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d26bb0c99070e9b49bc8632dc0b68214
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,152 @@
using FishNet.Connection;
using FishNet.Example.Authenticating;
using FishNet.Managing;
using FishNet.Transporting;
using System;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
namespace FishNet.Authenticating
{
/// <summary>
/// This authenticator is an example of how to let host bypass the authentication process.
/// When checking to authenticate on the client side call AuthenticateAsHost, and if returned true skip normal authentication.
/// </summary>
public abstract class HostAuthenticator : Authenticator
{
#region Serialized.
/// <summary>
/// True to enable use of AuthenticateAsHost.
/// </summary>
[Tooltip("True to enable use of AuthenticateAsHost.")]
[SerializeField]
private bool _allowHostAuthentication;
/// <summary>
/// Sets if to allow host authentication.
/// </summary>
/// <param name="value"></param>
public void SetAllowHostAuthentication(bool value) => _allowHostAuthentication = value;
/// <summary>
/// Returns if AllowHostAuthentication is enabled.
/// </summary>
/// <returns></returns>
public bool GetAllowHostAuthentication() => _allowHostAuthentication;
#endregion
#region Private.
/// <summary>
/// A random hash which only exist if the server is started.
/// </summary>
private static string _hostHash = string.Empty;
#endregion
/// <summary>
/// Initializes this script for use.
/// </summary>
/// <param name="networkManager"></param>
public override void InitializeOnce(NetworkManager networkManager)
{
base.InitializeOnce(networkManager);
//Listen for connection state of local server to set hash.
base.NetworkManager.ServerManager.OnServerConnectionState += ServerManager_OnServerConnectionState;
//Listen for broadcast from client. Be sure to set requireAuthentication to false.
base.NetworkManager.ServerManager.RegisterBroadcast<HostPasswordBroadcast>(OnHostPasswordBroadcast, false);
}
/// <summary>
/// Called after the local server connection state changes.
/// </summary>
private void ServerManager_OnServerConnectionState(ServerConnectionStateArgs obj)
{
int length = (obj.ConnectionState == LocalConnectionState.Started) ? 25 : 0;
SetHostHash(length);
}
/// <summary>
/// Received on server when a client sends the password broadcast message.
/// </summary>
/// <param name="conn">Connection sending broadcast.</param>
/// <param name="hpb"></param>
private void OnHostPasswordBroadcast(NetworkConnection conn, HostPasswordBroadcast hpb)
{
//Not accepting host authentications. This could be an attack.
if (!_allowHostAuthentication)
{
conn.Disconnect(true);
return;
}
/* If client is already authenticated this could be an attack. Connections
* are removed when a client disconnects so there is no reason they should
* already be considered authenticated. */
if (conn.Authenticated)
{
conn.Disconnect(true);
return;
}
bool correctPassword = (hpb.Password == _hostHash);
OnHostAuthenticationResult(conn, correctPassword);
}
/// <summary>
/// Called after handling a host authentication result.
/// </summary>
/// <param name="conn">Connection authenticating.</param>
/// <param name="authenticated">True if authentication passed.</param>
protected abstract void OnHostAuthenticationResult(NetworkConnection conn, bool authenticated);
/// <summary>
/// Sets a host hash of length.
/// </summary>
/// https://stackoverflow.com/questions/32932679/using-rngcryptoserviceprovider-to-generate-random-string
private void SetHostHash(int length)
{
if (length <= 0)
{
_hostHash = string.Empty;
}
else
{
const string charPool = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()";
StringBuilder result = new StringBuilder();
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
byte[] uintBuffer = new byte[sizeof(uint)];
while (length-- > 0)
{
rng.GetBytes(uintBuffer);
uint num = BitConverter.ToUInt32(uintBuffer, 0);
result.Append(charPool[(int)(num % (uint)charPool.Length)]);
}
}
_hostHash = result.ToString();
}
}
/// <summary>
/// Returns true if authentication was sent as host.
/// </summary>
/// <returns></returns>
protected bool AuthenticateAsHost()
{
if (!_allowHostAuthentication)
return false;
if (_hostHash == string.Empty)
return false;
HostPasswordBroadcast hpb = new HostPasswordBroadcast()
{
Password = _hostHash,
};
base.NetworkManager.ClientManager.Broadcast(hpb);
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c7497d751bb68f444b4343e3edc28e39
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,132 @@
using FishNet.Authenticating;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Logging;
using FishNet.Transporting;
using System;
using UnityEngine;
namespace FishNet.Example.Authenticating
{
/// <summary>
/// This is an example of a password authenticator.
/// Never send passwords without encryption.
/// </summary>
public class PasswordAuthenticator : HostAuthenticator
{
#region Public.
/// <summary>
/// Called when authenticator has concluded a result for a connection. Boolean is true if authentication passed, false if failed.
/// Server listens for this event automatically.
/// </summary>
public override event Action<NetworkConnection, bool> OnAuthenticationResult;
#endregion
#region Serialized.
/// <summary>
/// Password to authenticate.
/// </summary>
[Tooltip("Password to authenticate.")]
[SerializeField]
private string _password = "HelloWorld";
#endregion
public override void InitializeOnce(NetworkManager networkManager)
{
base.InitializeOnce(networkManager);
//Listen for connection state change as client.
base.NetworkManager.ClientManager.OnClientConnectionState += ClientManager_OnClientConnectionState;
//Listen for broadcast from client. Be sure to set requireAuthentication to false.
base.NetworkManager.ServerManager.RegisterBroadcast<PasswordBroadcast>(OnPasswordBroadcast, false);
//Listen to response from server.
base.NetworkManager.ClientManager.RegisterBroadcast<ResponseBroadcast>(OnResponseBroadcast);
}
/// <summary>
/// Called when a connection state changes for the local client.
/// </summary>
private void ClientManager_OnClientConnectionState(ClientConnectionStateArgs args)
{
/* If anything but the started state then exit early.
* Only try to authenticate on started state. The server
* doesn't have to send an authentication request before client
* can authenticate, that is entirely optional and up to you. In this
* example the client tries to authenticate soon as they connect. */
if (args.ConnectionState != LocalConnectionState.Started)
return;
//Authentication was sent as host, no need to authenticate normally.
if (AuthenticateAsHost())
return;
PasswordBroadcast pb = new PasswordBroadcast()
{
Password = _password
};
base.NetworkManager.ClientManager.Broadcast(pb);
}
/// <summary>
/// Received on server when a client sends the password broadcast message.
/// </summary>
/// <param name="conn">Connection sending broadcast.</param>
/// <param name="pb"></param>
private void OnPasswordBroadcast(NetworkConnection conn, PasswordBroadcast pb)
{
/* If client is already authenticated this could be an attack. Connections
* are removed when a client disconnects so there is no reason they should
* already be considered authenticated. */
if (conn.Authenticated)
{
conn.Disconnect(true);
return;
}
bool correctPassword = (pb.Password == _password);
SendAuthenticationResponse(conn, correctPassword);
/* Invoke result. This is handled internally to complete the connection or kick client.
* It's important to call this after sending the broadcast so that the broadcast
* makes it out to the client before the kick. */
OnAuthenticationResult?.Invoke(conn, correctPassword);
}
/// <summary>
/// Received on client after server sends an authentication response.
/// </summary>
/// <param name="rb"></param>
private void OnResponseBroadcast(ResponseBroadcast rb)
{
string result = (rb.Passed) ? "Authentication complete." : "Authenitcation failed.";
NetworkManager.Log(result);
}
/// <summary>
/// Sends an authentication result to a connection.
/// </summary>
private void SendAuthenticationResponse(NetworkConnection conn, bool authenticated)
{
/* Tell client if they authenticated or not. This is
* entirely optional but does demonstrate that you can send
* broadcasts to client on pass or fail. */
ResponseBroadcast rb = new ResponseBroadcast()
{
Passed = authenticated
};
base.NetworkManager.ServerManager.Broadcast(conn, rb, false);
}
/// <summary>
/// Called after handling a host authentication result.
/// </summary>
/// <param name="conn">Connection authenticating.</param>
/// <param name="authenticated">True if authentication passed.</param>
protected override void OnHostAuthenticationResult(NetworkConnection conn, bool authenticated)
{
SendAuthenticationResponse(conn, authenticated);
OnAuthenticationResult?.Invoke(conn, authenticated);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 226e4eaf2fa685f48bdc3dfaa87c1453
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: