diff --git a/Libraries/Esiur/Net/Packets/EpAuthPacket.cs b/Libraries/Esiur/Net/Packets/EpAuthPacket.cs index 78c0f36..3274038 100644 --- a/Libraries/Esiur/Net/Packets/EpAuthPacket.cs +++ b/Libraries/Esiur/Net/Packets/EpAuthPacket.cs @@ -145,6 +145,8 @@ public class EpAuthPacket : Packet public override long Parse(byte[] data, uint offset, uint ends) { + Tdu = null; + var oOffset = offset; if (NotEnough(offset, ends, 1)) @@ -155,7 +157,7 @@ public class EpAuthPacket : Packet if (Command == EpAuthPacketCommand.Initialize) { - AuthMode = (AuthenticationMode)(data[offset] >> 2 & 0x4); + AuthMode = (AuthenticationMode)(data[offset] >> 2 & 0x3); EncryptionMode = (EncryptionMode)(data[offset++] & 0x7); } else if (Command == EpAuthPacketCommand.Acknowledge) @@ -185,6 +187,8 @@ public class EpAuthPacket : Packet Tdu = PlainTdu.Parse(data, offset, ends);//, _warehouse); + Console.WriteLine("Auth TDU " + Tdu.Value.PayloadLength); + if (Tdu.Value.Class == TduClass.Invalid) return -(int)Tdu.Value.TotalLength; diff --git a/Libraries/Esiur/Net/Packets/EpAuthPacketMethod.cs b/Libraries/Esiur/Net/Packets/EpAuthPacketMethod.cs index 0870bd0..e03d42e 100644 --- a/Libraries/Esiur/Net/Packets/EpAuthPacketMethod.cs +++ b/Libraries/Esiur/Net/Packets/EpAuthPacketMethod.cs @@ -27,9 +27,10 @@ namespace Esiur.Net.Packets SessionEstablished = 0x47, // session established, session Id provided, switch to session mode, connection is still open // Events - ErrorTerminate = 0xC0, - ErrorMustEncrypt = 0xC1, - ErrorRetry = 0xC2, + Established = 0xC0, + ErrorTerminate = 0xC1, + ErrorMustEncrypt = 0xC2, + ErrorRetry = 0xC3, IndicationEstablished = 0xC8, diff --git a/Libraries/Esiur/Protocol/EpConnection.cs b/Libraries/Esiur/Protocol/EpConnection.cs index 5f68a00..83f2907 100644 --- a/Libraries/Esiur/Protocol/EpConnection.cs +++ b/Libraries/Esiur/Protocol/EpConnection.cs @@ -118,18 +118,21 @@ public partial class EpConnection : NetworkConnection, IStore /// /// EpServer _server; - public EpServer Server - { - get => _server; - internal set - { - _server = value; - if (_authPacket == null) - _authPacket = new EpAuthPacket(value.Instance.Warehouse); - if (_packet == null) - _packet = new EpPacket(value.Instance.Warehouse); - } - } + Warehouse _serverWarehouse; + + public EpServer Server => _server; + //public EpServer Server + //{ + // get => _server; + // internal set + // { + // _server = value; + // if (_authPacket == null) + // _authPacket = new EpAuthPacket(value.Instance.Warehouse); + // if (_packet == null) + // _packet = new EpPacket(value.Instance.Warehouse); + // } + //} /// @@ -152,7 +155,7 @@ public partial class EpConnection : NetworkConnection, IStore public ExceptionLevel ExceptionLevel { get; set; } = ExceptionLevel.Code | ExceptionLevel.Message | ExceptionLevel.Source | ExceptionLevel.Trace; - + //[Attribute] public bool AutoReconnect { get; set; } = false; @@ -228,9 +231,9 @@ public partial class EpConnection : NetworkConnection, IStore /// Data to send. public override void Send(byte[] data) { - #if VERBOSE +#if VERBOSE Console.WriteLine("Client: {0}", Data.Length); - #endif +#endif Global.Counters["Ep Sent Packets"]++; base.Send(data); @@ -281,10 +284,12 @@ public partial class EpConnection : NetworkConnection, IStore if (_session.AuthenticationHandler == null) throw new Exception("Authentication handler must be assigned for the session."); - var initAuthData = _session.AuthenticationHandler.Process(null); + var initAuthResult = _session.AuthenticationHandler.Process(null); headers.Add((byte)EpAuthPacketHeader.AuthenticationProtocol, _session.AuthenticationHandler.Protocol); - headers.Add((byte)EpAuthPacketHeader.AuthenticationData, initAuthData); + headers.Add((byte)EpAuthPacketHeader.AuthenticationData, initAuthResult.AuthenticationData); + headers.Add((byte)EpAuthPacketHeader.Domain, _remoteDomain); + } if (_session.EncryptionMode != EncryptionMode.None) @@ -720,9 +725,13 @@ public partial class EpConnection : NetworkConnection, IStore return offset; } - //@TODO: check if allowed, pass for testing SendAuthHeaders(EpAuthPacketMethod.SessionEstablished, localHeaders); - AuthenticatonCompleted(null, "guest"); + + _session.Authenticated = true; + _session.LocalIdentity = null; + _session.RemoteIdentity = null; + AuthenticatonCompleted(); + return offset; } @@ -734,7 +743,7 @@ public partial class EpConnection : NetworkConnection, IStore return offset; } - var provider = Instance.Warehouse.GetAuthenticationProvider(_session.RemoteHeaders[EpAuthPacketHeader.AuthenticationProtocol].ToString()); + var provider = _serverWarehouse.GetAuthenticationProvider(_session.RemoteHeaders[EpAuthPacketHeader.AuthenticationProtocol].ToString()); var handler = provider.CreateAuthenticationHandler(new AuthenticationContext() { @@ -760,7 +769,7 @@ public partial class EpConnection : NetworkConnection, IStore // send acknowledgements - localHeaders.Add(EpAuthPacketHeader.AuthenticationData, + localHeaders.Add((byte)EpAuthPacketHeader.AuthenticationData, authResult.AuthenticationData); if (authResult.Ruling == AuthenticationRuling.Failed) @@ -776,7 +785,13 @@ public partial class EpConnection : NetworkConnection, IStore else if (authResult.Ruling == AuthenticationRuling.Succeeded) { SendAuthHeaders(EpAuthPacketMethod.SessionEstablished, localHeaders); - AuthenticatonCompleted(authResult.LocalIdentity, authResult.RemoteIdentity); + + _session.Authenticated = true; + _session.LocalIdentity = authResult.LocalIdentity; + _session.RemoteIdentity = authResult.RemoteIdentity; + _session.Key = authResult.SessionKey; + + AuthenticatonCompleted(); } } else if (_authPacket.Command == EpAuthPacketCommand.Acknowledge) @@ -811,7 +826,11 @@ public partial class EpConnection : NetworkConnection, IStore { if (_authPacket.Method == EpAuthPacketMethod.SessionEstablished) { - AuthenticatonCompleted("guest", null); + _session.Authenticated = true; + _session.LocalIdentity = null; + _session.RemoteIdentity = null; + _session.Key = null; + AuthenticatonCompleted(); } else { @@ -834,8 +853,10 @@ public partial class EpConnection : NetworkConnection, IStore else if (authResult.Ruling == AuthenticationRuling.InProgress) { if (_authPacket.Method == EpAuthPacketMethod.ProceedToHandshake) + { SendAuthData(EpAuthPacketMethod.Handshake, - authResult.AuthenticationData); + authResult.AuthenticationData); + } else { throw new Exception("Bad protocol sequence."); @@ -843,15 +864,27 @@ public partial class EpConnection : NetworkConnection, IStore } else if (authResult.Ruling == AuthenticationRuling.Succeeded) { + _session.Authenticated = true; + _session.Key = authResult.SessionKey; + _session.LocalIdentity = authResult.LocalIdentity; + _session.RemoteIdentity = authResult.RemoteIdentity; - if (_authPacket.Method == EpAuthPacketMethod.SessionEstablished) - { - AuthenticatonCompleted(authResult.LocalIdentity, authResult.RemoteIdentity); - } - else if (_authPacket.Method == EpAuthPacketMethod.ProceedToEstablishSession) - { - // @TODO: Send establish request - } + // send final handshake with data + SendAuthData(EpAuthPacketMethod.FinalHandshake, + authResult.AuthenticationData); + + //if (_authPacket.Method == EpAuthPacketMethod.SessionEstablished) + //{ + // AuthenticatonCompleted(authResult.LocalIdentity, authResult.RemoteIdentity); + //} + //else if (_authPacket.Method == EpAuthPacketMethod.ProceedToEstablishSession + // || _authPacket.Method == EpAuthPacketMethod.FinalHandshake) + //{ + // // Send establish request + + // SendAuthData(EpAuthPacketMethod.FinalHandshake, + // authResult.AuthenticationData); + //} } @@ -863,11 +896,12 @@ public partial class EpConnection : NetworkConnection, IStore if (_authPacket.Tdu != null) { - var parsed = Codec.ParseSync(_authPacket.Tdu.Value, Instance.Warehouse); + var parsed = Codec.ParseSync(_authPacket.Tdu.Value, _serverWarehouse); authData = parsed; } - if (_authPacket.Method == EpAuthPacketMethod.Handshake) + if (_authPacket.Method == EpAuthPacketMethod.Handshake + || _authPacket.Method == EpAuthPacketMethod.FinalHandshake) { var authResult = _session.AuthenticationHandler.Process(authData); @@ -875,7 +909,8 @@ public partial class EpConnection : NetworkConnection, IStore { SendAuth(EpAuthPacketMethod.ErrorTerminate); _invalidCredentials = true; - Close(); + Task.Delay(100).ContinueWith(x => Close()); + // Close(); } else if (authResult.Ruling == AuthenticationRuling.InProgress) { @@ -883,15 +918,24 @@ public partial class EpConnection : NetworkConnection, IStore } else if (authResult.Ruling == AuthenticationRuling.Succeeded) { + _session.Authenticated = true; + _session.Key = authResult.SessionKey; + _session.LocalIdentity = authResult.LocalIdentity; + _session.RemoteIdentity = authResult.RemoteIdentity; + if (authResult.AuthenticationData != null) { SendAuthData(EpAuthPacketMethod.FinalHandshake, authResult.AuthenticationData); } - else + + if (_authDirection == AuthenticationDirection.Responder + && _authPacket.Method == EpAuthPacketMethod.FinalHandshake) { - SendAuth(EpAuthPacketMethod.SessionEstablished); - AuthenticatonCompleted(authResult.LocalIdentity, authResult.RemoteIdentity); + // Send established event + SendAuth(EpAuthPacketMethod.Established); + AuthenticatonCompleted(); } + } } } @@ -907,6 +951,20 @@ public partial class EpConnection : NetworkConnection, IStore Close(); } + else if (_authPacket.Method == EpAuthPacketMethod.Established) + { + if (_session.Authenticated) + { + AuthenticatonCompleted(); + } + else + { + _invalidCredentials = true; + OnError?.Invoke(this, _authPacket.ErrorCode, "Authentication error."); + _openReply?.TriggerError(new AsyncException(ErrorType.Management, _authPacket.ErrorCode, "Authentication error.")); + Close(); + } + } else if (_authPacket.Method == EpAuthPacketMethod.IndicationEstablished) { // @TODO: handle multi-factor authentication indication @@ -922,7 +980,7 @@ public partial class EpConnection : NetworkConnection, IStore - void AuthenticatonCompleted(string localIdentity, string remoteIdentity) + void AuthenticatonCompleted() { if (this.Instance == null) @@ -931,8 +989,6 @@ public partial class EpConnection : NetworkConnection, IStore Server.Instance.Link + "/" + this.GetHashCode().ToString().Replace("/", "_"), this) .Then(x => { - _session.LocalIdentity = localIdentity; - _session.RemoteIdentity = remoteIdentity; _authenticated = true; @@ -953,8 +1009,6 @@ public partial class EpConnection : NetworkConnection, IStore } else { - _session.LocalIdentity = localIdentity; - _session.RemoteIdentity = remoteIdentity; _authenticated = true; Status = EpConnectionStatus.Connected; _openReply?.Trigger(true); @@ -1694,14 +1748,22 @@ public partial class EpConnection : NetworkConnection, IStore /// public AsyncReply Handle(ResourceOperation trigger, IResourceContext context = null) { - - - if (trigger == ResourceOperation.Initialize) + if (trigger == ResourceOperation.Configure) { - _authPacket = new EpAuthPacket(Instance.Warehouse); - _packet = new EpPacket(Instance.Warehouse); - - + if (context is EpServerConnectionContext serverContext) + { + _server = serverContext.Server; + _serverWarehouse = serverContext.Warehouse; + _authPacket = new EpAuthPacket(_serverWarehouse); + _packet = new EpPacket(_serverWarehouse); + } + } + else if (trigger == ResourceOperation.Initialize) + { + if (_authPacket == null) + _authPacket = new EpAuthPacket(Instance.Warehouse); + if (_packet == null) + _packet = new EpPacket(Instance.Warehouse); } else if (trigger == ResourceOperation.Open) { @@ -1716,29 +1778,34 @@ public partial class EpConnection : NetworkConnection, IStore var port = host.Length > 1 ? ushort.Parse(host[1]) : (ushort)10518; // assign domain from hostname if not provided - - if (context is EpConnectionContext epContext) { var provider = Instance.Warehouse.GetAuthenticationProvider(epContext.AuthenticationProtocol); _remoteDomain = epContext.Domain ?? address; - Session.AuthenticationHandler = provider.CreateAuthenticationHandler(new AuthenticationContext(){ + _session.AuthenticationHandler = provider.CreateAuthenticationHandler(new AuthenticationContext() + { Direction = AuthenticationDirection.Initiator, Domain = _remoteDomain, HostName = address, InitiatorIdentity = epContext.Identity, - Mode = epContext.AuthenticationMode, + Mode = epContext.AuthenticationMode, }); - Session.LocalIdentity = epContext.Identity; + _session.AuthenticationMode = epContext.AuthenticationMode; + _session.LocalIdentity = epContext.Identity; ReconnectInterval = epContext.ReconnectInterval; ExceptionLevel = epContext.ExceptionLevel; UseWebSocket = epContext.UseWebSocket; SecureWebSocket = epContext.SecureWebSocket; _remoteDomain = epContext.Domain; AutoReconnect = epContext.AutoReconnect; + _hostname = address; + _port = port; + + return Connect(); + } else if (_remoteDomain == null) _remoteDomain = address; @@ -1771,8 +1838,12 @@ public partial class EpConnection : NetworkConnection, IStore _invalidCredentials = false; _session.LocalHeaders[EpAuthPacketHeader.Domain] = domain; + _hostname = hostname; } + if (port > 0) + this._port = port; + if (_session == null) throw new AsyncException(ErrorType.Exception, 0, "Session not initialized"); @@ -1785,10 +1856,6 @@ public partial class EpConnection : NetworkConnection, IStore socket = new TcpSocket(); } - if (port > 0) - this._port = port; - if (hostname != null) - this._hostname = hostname; connectSocket(socket); diff --git a/Libraries/Esiur/Protocol/EpServer.cs b/Libraries/Esiur/Protocol/EpServer.cs index a38643a..24a0a08 100644 --- a/Libraries/Esiur/Protocol/EpServer.cs +++ b/Libraries/Esiur/Protocol/EpServer.cs @@ -167,14 +167,18 @@ public class EpServer : NetworkServer, IResource public override void Add(EpConnection connection) { - connection.Server = this; + connection.Handle(ResourceOperation.Configure, + new EpServerConnectionContext() { + Server = this, + Warehouse = Instance.Warehouse } + ); + connection.ExceptionLevel = ExceptionLevel; base.Add(connection); } public override void Remove(EpConnection connection) { - connection.Server = null; base.Remove(connection); } diff --git a/Libraries/Esiur/Protocol/EpServerConnectionContext.cs b/Libraries/Esiur/Protocol/EpServerConnectionContext.cs new file mode 100644 index 0000000..9cdb976 --- /dev/null +++ b/Libraries/Esiur/Protocol/EpServerConnectionContext.cs @@ -0,0 +1,20 @@ +using Esiur.Data; +using Esiur.Resource; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esiur.Protocol +{ + public struct EpServerConnectionContext : IResourceContext + { + public Map Attributes => null; + + public Map Properties => null; + + public ulong Age => 0; + + public EpServer Server; + public Warehouse Warehouse; + } +} diff --git a/Libraries/Esiur/Security/Authority/Providers/IdentityPassword.cs b/Libraries/Esiur/Security/Authority/Providers/IdentityPassword.cs new file mode 100644 index 0000000..175779d --- /dev/null +++ b/Libraries/Esiur/Security/Authority/Providers/IdentityPassword.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esiur.Security.Authority.Providers +{ + public struct IdentityPassword + { + public string Identity { get; set; } + public byte[] Password { get; set; } + + public IdentityPassword(string identity, byte[] password) + { + Identity = identity; + Password = password; + } + } +} diff --git a/Libraries/Esiur/Security/Authority/Providers/PasswordAuthenticationHandler.cs b/Libraries/Esiur/Security/Authority/Providers/PasswordAuthenticationHandler.cs index 1b834d8..17e8baf 100644 --- a/Libraries/Esiur/Security/Authority/Providers/PasswordAuthenticationHandler.cs +++ b/Libraries/Esiur/Security/Authority/Providers/PasswordAuthenticationHandler.cs @@ -9,7 +9,7 @@ using Esiur.Data.Types; namespace Esiur.Security.Authority.Providers { - internal class PasswordAuthenticationHandler : IAuthenticationHandler + public class PasswordAuthenticationHandler : IAuthenticationHandler { public string Protocol => "hash"; @@ -33,7 +33,7 @@ namespace Esiur.Security.Authority.Providers public IAuthenticationProvider Provider => _provider; - public byte[] ComputeSha3(byte[] data, int bitLength = 256) + public static byte[] ComputeSha3(byte[] data, int bitLength = 256) { // 1. Initialize the digest (supports 224, 256, 384, 512) var digest = new Sha3Digest(bitLength); @@ -50,6 +50,7 @@ namespace Esiur.Security.Authority.Providers public AuthenticationResult Process(object authData) { + Console.WriteLine($"PasswordAuthenticationHandler: {this.GetHashCode()} Step {_step}, Mode {_mode}, Direction {_direction}"); var remoteAuthData = (object[])authData; var localAuthData = new List(); @@ -66,7 +67,11 @@ namespace Esiur.Security.Authority.Providers { // step 0: send local nonce and initiator identity. if (_initiatorIdentity == null) - (_initiatorIdentity, _initiatorPassword) = _provider.GetSelfIdentityAndCredential(_domain, _hostName); + { + var identityPassword = _provider.GetSelfIdentityAndCredential(_domain, _hostName); + _initiatorIdentity = identityPassword.Identity; + _initiatorPassword = identityPassword.Password; + } else _initiatorPassword = _provider.GetSelfCredential(_initiatorIdentity, _domain, _hostName); @@ -77,6 +82,7 @@ namespace Esiur.Security.Authority.Providers localAuthData.Add(_localNonce); localAuthData.Add(_initiatorIdentity); + _step = 1; return new AuthenticationResult(AuthenticationRuling.InProgress, localAuthData); } @@ -155,7 +161,9 @@ namespace Esiur.Security.Authority.Providers } // check if responder identity is valid and get password. - (_localSalt, _responderPassword) = _provider.GetHostedAccountCredential(_responderIdentity, _domain); + var hostedAccountCredential = _provider.GetHostedAccountCredential(_responderIdentity, _domain); + _localSalt = hostedAccountCredential.Salt; + _responderPassword = hostedAccountCredential.Hash; if (_responderPassword == null) { @@ -216,7 +224,11 @@ namespace Esiur.Security.Authority.Providers { // step 0: send local nonce and initiator identity. if (_initiatorIdentity == null) - (_initiatorIdentity, _initiatorPassword) = _provider.GetSelfIdentityAndCredential(_domain, _hostName); + { + var identityPassword = _provider.GetSelfIdentityAndCredential(_domain, _hostName); + _initiatorIdentity = identityPassword.Identity; + _initiatorPassword = identityPassword.Password; + } else _initiatorPassword = _provider.GetSelfCredential(_initiatorIdentity, _domain, _hostName); @@ -245,7 +257,9 @@ namespace Esiur.Security.Authority.Providers } // check if responder identity is valid and get password. - (_localSalt, _responderPassword) = _provider.GetHostedAccountCredential(_responderIdentity, _domain); + var hostedAccountCredential = _provider.GetHostedAccountCredential(_responderIdentity, _domain); + _localSalt = hostedAccountCredential.Salt; + _responderPassword = hostedAccountCredential.Hash; if (_responderPassword == null) { @@ -339,7 +353,9 @@ namespace Esiur.Security.Authority.Providers } // get initiator password from provider. - (_localSalt, _initiatorPassword) = _provider.GetHostedAccountCredential(_initiatorIdentity, _domain); + var hostedAccountCredential = _provider.GetHostedAccountCredential(_initiatorIdentity, _domain); + _localSalt = hostedAccountCredential.Salt; + _initiatorPassword = hostedAccountCredential.Hash; // account not found or no password for this account. if (_initiatorPassword == null || _initiatorIdentity == null) @@ -416,7 +432,11 @@ namespace Esiur.Security.Authority.Providers // get responder identity from provider. if (_responderIdentity == null) - (_responderIdentity, _responderPassword) = _provider.GetSelfIdentityAndCredential(_domain, _hostName); + { + var identityPassword = _provider.GetSelfIdentityAndCredential(_domain, _hostName); + _responderIdentity = identityPassword.Identity; + _responderPassword = identityPassword.Password; + } else _responderPassword = _provider.GetSelfCredential(_responderIdentity, _domain, _hostName); @@ -500,7 +520,11 @@ namespace Esiur.Security.Authority.Providers // get responder identity from provider. if (_responderIdentity == null) - (_responderIdentity, _responderPassword) = _provider.GetSelfIdentityAndCredential(_domain, _hostName); + { + var identityPassword = _provider.GetSelfIdentityAndCredential(_domain, _hostName); + _responderIdentity = identityPassword.Identity; + _responderPassword = identityPassword.Password; + } else _responderPassword = _provider.GetSelfCredential(_responderIdentity, _domain, _hostName); @@ -510,7 +534,9 @@ namespace Esiur.Security.Authority.Providers } // get initiator password from provider. - (_localSalt, _initiatorPassword) = _provider.GetHostedAccountCredential(_initiatorIdentity, _domain); + var hostedAccountCredential = _provider.GetHostedAccountCredential(_initiatorIdentity, _domain); + _localSalt = hostedAccountCredential.Salt; + _initiatorPassword = hostedAccountCredential.Hash; // account not found or no password for this account. if (_initiatorPassword == null || _initiatorIdentity == null) diff --git a/Libraries/Esiur/Security/Authority/Providers/PasswordAuthenticationProvider.cs b/Libraries/Esiur/Security/Authority/Providers/PasswordAuthenticationProvider.cs index f0a76ea..4975f57 100644 --- a/Libraries/Esiur/Security/Authority/Providers/PasswordAuthenticationProvider.cs +++ b/Libraries/Esiur/Security/Authority/Providers/PasswordAuthenticationProvider.cs @@ -22,14 +22,14 @@ namespace Esiur.Security.Authority.Providers return authHandler; } - public virtual (byte[], byte[]) GetHostedAccountCredential(string identity, string domain) + public virtual PasswordHash GetHostedAccountCredential(string identity, string domain) { - return (null, null); + return new PasswordHash(); } - public virtual (string, byte[]) GetSelfIdentityAndCredential(string domain, string hostname) + public virtual IdentityPassword GetSelfIdentityAndCredential(string domain, string hostname) { - return (null, null); + return new IdentityPassword(); } public virtual byte[] GetSelfCredential(string identity, string domain, string hostname) diff --git a/Libraries/Esiur/Security/Authority/Providers/PasswordHash.cs b/Libraries/Esiur/Security/Authority/Providers/PasswordHash.cs new file mode 100644 index 0000000..4b9864b --- /dev/null +++ b/Libraries/Esiur/Security/Authority/Providers/PasswordHash.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esiur.Security.Authority.Providers +{ + public struct PasswordHash + { + public byte[] Hash { get; set; } + public byte[] Salt { get; set; } + + public PasswordHash(byte[] hash, byte[] salt) + { + Hash = hash; + Salt = salt; + } + } +} diff --git a/Libraries/Esiur/Security/Authority/Session.cs b/Libraries/Esiur/Security/Authority/Session.cs index 28171cd..68605dc 100644 --- a/Libraries/Esiur/Security/Authority/Session.cs +++ b/Libraries/Esiur/Security/Authority/Session.cs @@ -61,4 +61,8 @@ public class Session public string LocalIdentity { get; set; } public string RemoteIdentity { get; set; } + + public bool Authenticated { get; set; } = false; + + public byte[] Key { get; set; } } diff --git a/Tests/Features/Functional/ClientAuthenticationProvider.cs b/Tests/Features/Functional/ClientAuthenticationProvider.cs index 4ed9638..12efb8e 100644 --- a/Tests/Features/Functional/ClientAuthenticationProvider.cs +++ b/Tests/Features/Functional/ClientAuthenticationProvider.cs @@ -10,7 +10,7 @@ namespace Esiur.Tests.Functional { internal class ClientAuthenticationProvider : PasswordAuthenticationProvider { - public override (byte[], byte[]) GetHostedAccountCredential(string identity, string domain) + public override PasswordHash GetHostedAccountCredential(string identity, string domain) { throw new NotImplementedException(); } @@ -23,12 +23,12 @@ namespace Esiur.Tests.Functional return null; } - public override (string, byte[]) GetSelfIdentityAndCredential(string domain, string hostname) + public override IdentityPassword GetSelfIdentityAndCredential(string domain, string hostname) { if (domain == "test" && hostname == "localhost") - return ("tester", new byte[] { 1, 2, 3, 4, 5 }); + return new IdentityPassword { Identity = "tester", Password = new byte[] { 1, 2, 3, 4, 5 } }; else - return (null, null); + return new IdentityPassword { Identity = null, Password = null }; } public override AsyncReply Login(Session session) diff --git a/Tests/Features/Functional/Program.cs b/Tests/Features/Functional/Program.cs index b71b0f4..e7a6c24 100644 --- a/Tests/Features/Functional/Program.cs +++ b/Tests/Features/Functional/Program.cs @@ -50,6 +50,7 @@ using Esiur.Net.Packets; using System.Numerics; using Esiur.Protocol; using Esiur.Security.Authority.Providers; +using Esiur.Security.Authority; namespace Esiur.Tests.Functional; @@ -144,10 +145,11 @@ class Program var wh = new Warehouse(); wh.RegisterAuthenticationProvider(new ServerAuthenticationProvider()); - + // Create stores to keep objects. var system = await wh.Put("sys", new MemoryStore()); - var server = await wh.Put("sys/server", new EpServer() { + var server = await wh.Put("sys/server", new EpServer() + { AllowedAuthenticationProviders = new string[] { "hash" }, }); @@ -218,16 +220,18 @@ class Program var auth = new ClientAuthenticationProvider(); wh.RegisterAuthenticationProvider(auth); - var con = await wh.Get("EP://localhost", new EpConnectionContext + var con = await wh.Get("ep://localhost", new EpConnectionContext { + AuthenticationMode = AuthenticationMode.InitializerIdentity, AutoReconnect = true, Identity = "tester", - AuthenticationProtocol = "hash" + AuthenticationProtocol = "hash", + Domain = "test", }); - dynamic remote = await con.Get("sys/service"); - + dynamic remote = await con.Get("sys/service"); + TestObjectProps(local, remote); //return; diff --git a/Tests/Features/Functional/ServerAuthenticationProvider.cs b/Tests/Features/Functional/ServerAuthenticationProvider.cs index 1852feb..f878db2 100644 --- a/Tests/Features/Functional/ServerAuthenticationProvider.cs +++ b/Tests/Features/Functional/ServerAuthenticationProvider.cs @@ -7,24 +7,25 @@ using System.Text; namespace Esiur.Tests.Functional { - internal class ServerAuthenticationProvider: PasswordAuthenticationProvider + internal class ServerAuthenticationProvider : PasswordAuthenticationProvider { - public override (byte[], byte[]) GetHostedAccountCredential(string identity, string domain) + public override PasswordHash GetHostedAccountCredential(string identity, string domain) { if (identity == "tester" && domain == "test") - return (new byte[] { 1, 2, 3, 4, 5 }, new byte[] { 6, 7, 8, 9, 10 }); + return new PasswordHash(PasswordAuthenticationHandler.ComputeSha3(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }), + new byte[] { 6, 7, 8, 9, 10 }); else - return (null, null); + return new PasswordHash(null, null); } public override byte[] GetSelfCredential(string identity, string domain, string hostname) { - return base.GetSelfCredential(identity, domain, hostname); + throw new NotImplementedException(); } - public override (string, byte[]) GetSelfIdentityAndCredential(string domain, string hostname) + public override IdentityPassword GetSelfIdentityAndCredential(string domain, string hostname) { - return base.GetSelfIdentityAndCredential(domain, hostname); + throw new NotImplementedException(); } public override AsyncReply Login(Session session)