2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2026-06-13 14:38:43 +00:00
This commit is contained in:
2026-05-25 17:30:09 +03:00
parent 7e27d3cfac
commit 959bc76721
11 changed files with 256 additions and 209 deletions
+2
View File
@@ -70,6 +70,7 @@
<Compile Remove="Net\Sockets\TcpSocket.cs" /> <Compile Remove="Net\Sockets\TcpSocket.cs" />
<Compile Remove="Protocol\Authentication\HashAnonymousAuthenticator.cs" /> <Compile Remove="Protocol\Authentication\HashAnonymousAuthenticator.cs" />
<Compile Remove="Security\Authority\AuthenticationMethod.cs" /> <Compile Remove="Security\Authority\AuthenticationMethod.cs" />
<Compile Remove="Security\Membership\IMembership.cs" />
<Compile Remove="Security\Membership\SimpleMembership.cs" /> <Compile Remove="Security\Membership\SimpleMembership.cs" />
</ItemGroup> </ItemGroup>
@@ -90,6 +91,7 @@
<None Include="Protocol\Authentication\HashAnonymousAuthenticator.cs" /> <None Include="Protocol\Authentication\HashAnonymousAuthenticator.cs" />
<None Include="README.md" Pack="true" PackagePath="" /> <None Include="README.md" Pack="true" PackagePath="" />
<None Include="Security\Authority\AuthenticationMethod.cs" /> <None Include="Security\Authority\AuthenticationMethod.cs" />
<None Include="Security\Membership\IMembership.cs" />
<None Include="Security\Membership\SimpleMembership.cs" /> <None Include="Security\Membership\SimpleMembership.cs" />
</ItemGroup> </ItemGroup>
+9 -3
View File
@@ -934,7 +934,8 @@ public partial class EpConnection : NetworkConnection, IStore
_openReply = null; _openReply = null;
OnReady?.Invoke(this); OnReady?.Invoke(this);
Server?.Membership?.Login(_session); _session.AuthenticationHandler?.Provider?.Login(_session);
//Server?.Membership?.Login(_session);
LoginDate = DateTime.Now; LoginDate = DateTime.Now;
}).Error(x => }).Error(x =>
@@ -952,7 +953,9 @@ public partial class EpConnection : NetworkConnection, IStore
_openReply?.Trigger(true); _openReply?.Trigger(true);
_openReply = null; _openReply = null;
OnReady?.Invoke(this); OnReady?.Invoke(this);
Server?.Membership?.Login(_session);
_session.AuthenticationHandler?.Provider?.Login(_session);
//Server?.Membership?.Login(_session);
} }
} }
//private void ProcessClientAuth(byte[] data) //private void ProcessClientAuth(byte[] data)
@@ -1975,7 +1978,10 @@ public partial class EpConnection : NetworkConnection, IStore
Instance?.Warehouse?.Remove(this); Instance?.Warehouse?.Remove(this);
if (_authenticated) if (_authenticated)
Server.Membership?.Logout(_session); {
_session.AuthenticationHandler?.Provider.Logout(_session);
//Server.Membership?.Logout(_session);
}
} }
else if (AutoReconnect && !_invalidCredentials) else if (AutoReconnect && !_invalidCredentials)
+17 -14
View File
@@ -53,23 +53,26 @@ public class EpServer : NetworkServer<EpConnection>, IResource
set; set;
} }
IMembership membership; //IMembership membership;
[Attribute] //[Attribute]
public IMembership Membership //public IMembership Membership
{ //{
get => membership; // get => membership;
set // set
{ // {
//if (membership != null) // //if (membership != null)
// membership.Authorization -= Membership_Authorization; // // membership.Authorization -= Membership_Authorization;
membership = value; // membership = value;
//if (membership != null) // //if (membership != null)
// membership.Authorization += Membership_Authorization; // // membership.Authorization += Membership_Authorization;
} // }
} //}
//[Attribute]
//public string MembershipProvider { get; set; }
//private void Membership_Authorization(AuthorizationIndication indication) //private void Membership_Authorization(AuthorizationIndication indication)
//{ //{
@@ -8,6 +8,7 @@ namespace Esiur.Security.Authority
public interface IAuthenticationHandler public interface IAuthenticationHandler
{ {
IAuthenticationProvider Provider { get; }
public string Protocol { get; } public string Protocol { get; }
//public AuthenticationMode Mode { get; } //public AuthenticationMode Mode { get; }
//public AuthenticationResult Initialize(object authData); //public AuthenticationResult Initialize(object authData);
@@ -1,4 +1,5 @@
using System; using Esiur.Core;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@@ -10,5 +11,9 @@ namespace Esiur.Security.Authority
CreateAuthenticationHandler(AuthenticationContext context); CreateAuthenticationHandler(AuthenticationContext context);
public string DefaultName { get; } public string DefaultName { get; }
AsyncReply<bool> Login(Session session);
AsyncReply<bool> Logout(Session session);
} }
} }
@@ -1,4 +1,5 @@
using System; using Esiur.Core;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@@ -12,5 +13,15 @@ namespace Esiur.Security.Authority
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public AsyncReply<bool> Login(Session session)
{
throw new NotImplementedException();
}
public AsyncReply<bool> Logout(Session session)
{
throw new NotImplementedException();
}
} }
} }
@@ -13,21 +13,24 @@ namespace Esiur.Security.Authority.Providers
{ {
public string Protocol => "hash"; public string Protocol => "hash";
byte[] localNonce, remoteNonce;
byte[] localSalt, remoteSalt;
string initiatorIdentity, responderIdentity; byte[] _localNonce, _remoteNonce;
byte[] _localSalt, _remoteSalt;
byte[] initiatorPassword, responderPassword; string _initiatorIdentity, _responderIdentity;
string hostName, domain; byte[] _initiatorPassword, _responderPassword;
int step = 0; string _hostName, _domain;
AuthenticationMode mode; int _step = 0;
AuthenticationDirection direction;
PasswordAuthenticationProvider provider; AuthenticationMode _mode;
AuthenticationDirection _direction;
PasswordAuthenticationProvider _provider;
public IAuthenticationProvider Provider => _provider;
public byte[] ComputeSha3(byte[] data, int bitLength = 256) public byte[] ComputeSha3(byte[] data, int bitLength = 256)
@@ -50,156 +53,156 @@ namespace Esiur.Security.Authority.Providers
var remoteAuthData = (object[])authData; var remoteAuthData = (object[])authData;
var localAuthData = new List<object>(); var localAuthData = new List<object>();
if (direction == AuthenticationDirection.Initiator) if (_direction == AuthenticationDirection.Initiator)
{ {
if (mode == AuthenticationMode.None) if (_mode == AuthenticationMode.None)
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
else if (mode == AuthenticationMode.InitializerIdentity) else if (_mode == AuthenticationMode.InitializerIdentity)
{ {
if (step == 0) if (_step == 0)
{ {
// step 0: send local nonce and initiator identity. // step 0: send local nonce and initiator identity.
if (initiatorIdentity == null) if (_initiatorIdentity == null)
(initiatorIdentity, initiatorPassword) = provider.GetSelfIdentityAndCredential(domain, hostName); (_initiatorIdentity, _initiatorPassword) = _provider.GetSelfIdentityAndCredential(_domain, _hostName);
else else
initiatorPassword = provider.GetSelfCredential(initiatorIdentity, domain, hostName); _initiatorPassword = _provider.GetSelfCredential(_initiatorIdentity, _domain, _hostName);
if (initiatorPassword == null || initiatorIdentity == null) if (_initiatorPassword == null || _initiatorIdentity == null)
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
// send local nonce and initiator identity // send local nonce and initiator identity
localAuthData.Add(localNonce); localAuthData.Add(_localNonce);
localAuthData.Add(initiatorIdentity); localAuthData.Add(_initiatorIdentity);
return new AuthenticationResult(AuthenticationRuling.InProgress, localAuthData); return new AuthenticationResult(AuthenticationRuling.InProgress, localAuthData);
} }
else if (step == 1) else if (_step == 1)
{ {
// expect remote nonce, salt and challenge. // expect remote nonce, salt and challenge.
remoteNonce = (byte[])remoteAuthData[0]; _remoteNonce = (byte[])remoteAuthData[0];
remoteSalt = (byte[])remoteAuthData[1]; _remoteSalt = (byte[])remoteAuthData[1];
var remoteChallenge = (byte[])remoteAuthData[2]; var remoteChallenge = (byte[])remoteAuthData[2];
// prevent reply attack by checking if remote nonce is same as local nonce. // prevent reply attack by checking if remote nonce is same as local nonce.
if (remoteNonce.SequenceEqual(localNonce)) if (_remoteNonce.SequenceEqual(_localNonce))
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// make salted hash of password. // make salted hash of password.
var hashedPassword = ComputeSha3(initiatorPassword.Concat(remoteSalt).ToArray()); var hashedPassword = ComputeSha3(_initiatorPassword.Concat(_remoteSalt).ToArray());
var expectedRemoteChallenge = ComputeSha3(remoteNonce.Concat(hashedPassword) var expectedRemoteChallenge = ComputeSha3(_remoteNonce.Concat(hashedPassword)
.Concat(localNonce) .Concat(_localNonce)
.ToArray()); .ToArray());
// compare remote challenge // compare remote challenge
if (!remoteChallenge.SequenceEqual(expectedRemoteChallenge)) if (!remoteChallenge.SequenceEqual(expectedRemoteChallenge))
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// make hash challenge response. // make hash challenge response.
var localChallenge = ComputeSha3(localNonce.Concat(hashedPassword) var localChallenge = ComputeSha3(_localNonce.Concat(hashedPassword)
.Concat(remoteNonce) .Concat(_remoteNonce)
.ToArray()); .ToArray());
localAuthData.Add(localChallenge); localAuthData.Add(localChallenge);
step = -1; _step = -1;
// derive a session key from nonces and password. // derive a session key from nonces and password.
// initiator identity + initiator password + initiator nonce + responder nonce // initiator identity + initiator password + initiator nonce + responder nonce
var sessionKey = ComputeSha3(initiatorIdentity.ToBytes() var sessionKey = ComputeSha3(_initiatorIdentity.ToBytes()
.Concat(hashedPassword) .Concat(hashedPassword)
.Concat(localNonce) .Concat(_localNonce)
.Concat(remoteNonce) .Concat(_remoteNonce)
.ToArray(), 512); .ToArray(), 512);
return new AuthenticationResult(AuthenticationRuling.Succeeded, localAuthData, initiatorIdentity, null, sessionKey); return new AuthenticationResult(AuthenticationRuling.Succeeded, localAuthData, _initiatorIdentity, null, sessionKey);
} }
else else
{ {
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
} }
else if (mode == AuthenticationMode.ResponderIdentity) else if (_mode == AuthenticationMode.ResponderIdentity)
{ {
if (step == 0) if (_step == 0)
{ {
// just send local nonce. // just send local nonce.
localAuthData.Add(localNonce); localAuthData.Add(_localNonce);
return new AuthenticationResult(AuthenticationRuling.InProgress, localAuthData); return new AuthenticationResult(AuthenticationRuling.InProgress, localAuthData);
} }
else if (step == 1) else if (_step == 1)
{ {
// expect responder identity and nonce. // expect responder identity and nonce.
remoteNonce = (byte[])remoteAuthData[0]; _remoteNonce = (byte[])remoteAuthData[0];
responderIdentity = (string)remoteAuthData[1]; _responderIdentity = (string)remoteAuthData[1];
// prevent reply attack by checking if remote nonce is same as local nonce. // prevent reply attack by checking if remote nonce is same as local nonce.
if (remoteNonce.SequenceEqual(localNonce)) if (_remoteNonce.SequenceEqual(_localNonce))
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// check if responder identity is valid and get password. // check if responder identity is valid and get password.
(localSalt, responderPassword) = provider.GetHostedAccountCredential(responderIdentity, domain); (_localSalt, _responderPassword) = _provider.GetHostedAccountCredential(_responderIdentity, _domain);
if (responderPassword == null) if (_responderPassword == null)
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// make hash challenge response. // make hash challenge response.
var localChallenge = ComputeSha3(localNonce.Concat(responderPassword) var localChallenge = ComputeSha3(_localNonce.Concat(_responderPassword)
.Concat(remoteNonce) .Concat(_remoteNonce)
.ToArray()); .ToArray());
// send localSalt and challenge // send localSalt and challenge
localAuthData.Add(localSalt); localAuthData.Add(_localSalt);
localAuthData.Add(localChallenge); localAuthData.Add(localChallenge);
step = 2; _step = 2;
return new AuthenticationResult(AuthenticationRuling.InProgress, localAuthData); return new AuthenticationResult(AuthenticationRuling.InProgress, localAuthData);
} }
else if (step == 2) else if (_step == 2)
{ {
// expect remote challenge. // expect remote challenge.
var remoteChallenge = (byte[])remoteAuthData[0]; var remoteChallenge = (byte[])remoteAuthData[0];
// compare remote challenge // compare remote challenge
var expectedRemoteChallenge = ComputeSha3(remoteNonce.Concat(responderPassword) var expectedRemoteChallenge = ComputeSha3(_remoteNonce.Concat(_responderPassword)
.Concat(localNonce) .Concat(_localNonce)
.ToArray()); .ToArray());
if (!remoteChallenge.SequenceEqual(expectedRemoteChallenge)) if (!remoteChallenge.SequenceEqual(expectedRemoteChallenge))
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// derive a session key from nonces and password. // derive a session key from nonces and password.
// responder identity + responder hashed password + initiator nonce + responder nonce // responder identity + responder hashed password + initiator nonce + responder nonce
var sessionKey = ComputeSha3(responderIdentity.ToBytes() var sessionKey = ComputeSha3(_responderIdentity.ToBytes()
.Concat(responderPassword) .Concat(_responderPassword)
.Concat(localNonce) .Concat(_localNonce)
.Concat(remoteNonce) .Concat(_remoteNonce)
.ToArray(), 512); .ToArray(), 512);
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Succeeded, null, initiatorIdentity, responderIdentity, sessionKey); return new AuthenticationResult(AuthenticationRuling.Succeeded, null, _initiatorIdentity, _responderIdentity, sessionKey);
} }
else else
@@ -207,99 +210,99 @@ namespace Esiur.Security.Authority.Providers
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
} }
else if (mode == AuthenticationMode.DualIdentity) else if (_mode == AuthenticationMode.DualIdentity)
{ {
if (step == 0) if (_step == 0)
{ {
// step 0: send local nonce and initiator identity. // step 0: send local nonce and initiator identity.
if (initiatorIdentity == null) if (_initiatorIdentity == null)
(initiatorIdentity, initiatorPassword) = provider.GetSelfIdentityAndCredential(domain, hostName); (_initiatorIdentity, _initiatorPassword) = _provider.GetSelfIdentityAndCredential(_domain, _hostName);
else else
initiatorPassword = provider.GetSelfCredential(initiatorIdentity, domain, hostName); _initiatorPassword = _provider.GetSelfCredential(_initiatorIdentity, _domain, _hostName);
if (initiatorPassword == null || initiatorIdentity == null) if (_initiatorPassword == null || _initiatorIdentity == null)
{ {
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
localAuthData.Add(localNonce); localAuthData.Add(_localNonce);
localAuthData.Add(initiatorIdentity); localAuthData.Add(_initiatorIdentity);
return new AuthenticationResult(AuthenticationRuling.InProgress, localAuthData); return new AuthenticationResult(AuthenticationRuling.InProgress, localAuthData);
} }
else if (step == 1) else if (_step == 1)
{ {
// expect responder identity, nonce and salt. // expect responder identity, nonce and salt.
remoteNonce = (byte[])remoteAuthData[0]; _remoteNonce = (byte[])remoteAuthData[0];
responderIdentity = (string)remoteAuthData[1]; _responderIdentity = (string)remoteAuthData[1];
remoteSalt = (byte[])remoteAuthData[2]; _remoteSalt = (byte[])remoteAuthData[2];
// prevent reply attack by checking if remote nonce is same as local nonce. // prevent reply attack by checking if remote nonce is same as local nonce.
if (remoteNonce.SequenceEqual(localNonce)) if (_remoteNonce.SequenceEqual(_localNonce))
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// check if responder identity is valid and get password. // check if responder identity is valid and get password.
(localSalt, responderPassword) = provider.GetHostedAccountCredential(responderIdentity, domain); (_localSalt, _responderPassword) = _provider.GetHostedAccountCredential(_responderIdentity, _domain);
if (responderPassword == null) if (_responderPassword == null)
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// make salted hash of password. // make salted hash of password.
var hashedPassword = ComputeSha3(initiatorPassword.Concat(remoteSalt).ToArray()); var hashedPassword = ComputeSha3(_initiatorPassword.Concat(_remoteSalt).ToArray());
// make hash challenge response. // make hash challenge response.
var localChallenge = ComputeSha3(localNonce.Concat(hashedPassword) var localChallenge = ComputeSha3(_localNonce.Concat(hashedPassword)
.Concat(responderPassword) .Concat(_responderPassword)
.Concat(remoteNonce) .Concat(_remoteNonce)
.ToArray()); .ToArray());
// send localSalt and challenge // send localSalt and challenge
localAuthData.Add(localSalt); localAuthData.Add(_localSalt);
localAuthData.Add(localChallenge); localAuthData.Add(localChallenge);
step = 2; _step = 2;
return new AuthenticationResult(AuthenticationRuling.InProgress, localAuthData); return new AuthenticationResult(AuthenticationRuling.InProgress, localAuthData);
} }
else if (step == 2) else if (_step == 2)
{ {
// expect remote challenge. // expect remote challenge.
var remoteChallenge = (byte[])remoteAuthData[0]; var remoteChallenge = (byte[])remoteAuthData[0];
// make salted hash of password. // make salted hash of password.
var hashedPassword = ComputeSha3(initiatorPassword.Concat(remoteSalt).ToArray()); var hashedPassword = ComputeSha3(_initiatorPassword.Concat(_remoteSalt).ToArray());
// compare remote challenge // compare remote challenge
var expectedRemoteChallenge = ComputeSha3(remoteNonce.Concat(hashedPassword) var expectedRemoteChallenge = ComputeSha3(_remoteNonce.Concat(hashedPassword)
.Concat(responderPassword) .Concat(_responderPassword)
.Concat(localNonce) .Concat(_localNonce)
.ToArray()); .ToArray());
if (!remoteChallenge.SequenceEqual(expectedRemoteChallenge)) if (!remoteChallenge.SequenceEqual(expectedRemoteChallenge))
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// derive a session key from nonces and password. // derive a session key from nonces and password.
// responder identity + responder password + initiator nonce + responder nonce // responder identity + responder password + initiator nonce + responder nonce
var sessionKey = ComputeSha3(initiatorIdentity.ToBytes() var sessionKey = ComputeSha3(_initiatorIdentity.ToBytes()
.Concat(responderIdentity.ToBytes()) .Concat(_responderIdentity.ToBytes())
.Concat(hashedPassword) .Concat(hashedPassword)
.Concat(responderPassword) .Concat(_responderPassword)
.Concat(localNonce) .Concat(_localNonce)
.Concat(remoteNonce) .Concat(_remoteNonce)
.ToArray(), 512); .ToArray(), 512);
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Succeeded, null, initiatorIdentity, responderIdentity, sessionKey); return new AuthenticationResult(AuthenticationRuling.Succeeded, null, _initiatorIdentity, _responderIdentity, sessionKey);
} }
else else
@@ -309,66 +312,66 @@ namespace Esiur.Security.Authority.Providers
} }
} }
else if (direction == AuthenticationDirection.Responder) else if (_direction == AuthenticationDirection.Responder)
{ {
if (mode == AuthenticationMode.None) if (_mode == AuthenticationMode.None)
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
else if (mode == AuthenticationMode.InitializerIdentity) else if (_mode == AuthenticationMode.InitializerIdentity)
{ {
if (step == 0) if (_step == 0)
{ {
if (remoteAuthData.Length < 2) if (remoteAuthData.Length < 2)
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
// step 0: expect remote nonce and initiator identity. // step 0: expect remote nonce and initiator identity.
remoteNonce = (byte[])remoteAuthData[0]; _remoteNonce = (byte[])remoteAuthData[0];
initiatorIdentity = (string)remoteAuthData[1]; _initiatorIdentity = (string)remoteAuthData[1];
// prevent reply attack by checking if remote nonce is same as local nonce. // prevent reply attack by checking if remote nonce is same as local nonce.
// @TODO: We can change our localNonce then send it // @TODO: We can change our localNonce then send it
if (remoteNonce.SequenceEqual(localNonce)) if (_remoteNonce.SequenceEqual(_localNonce))
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// get initiator password from provider. // get initiator password from provider.
(localSalt, initiatorPassword) = provider.GetHostedAccountCredential(initiatorIdentity, domain); (_localSalt, _initiatorPassword) = _provider.GetHostedAccountCredential(_initiatorIdentity, _domain);
// account not found or no password for this account. // account not found or no password for this account.
if (initiatorPassword == null || initiatorIdentity == null) if (_initiatorPassword == null || _initiatorIdentity == null)
{ {
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
var localChallenge = ComputeSha3(localNonce.Concat(initiatorPassword) var localChallenge = ComputeSha3(_localNonce.Concat(_initiatorPassword)
.Concat(remoteNonce) .Concat(_remoteNonce)
.ToArray()); .ToArray());
// send local nonce, salt and challenge. // send local nonce, salt and challenge.
localAuthData.Add(localNonce); localAuthData.Add(_localNonce);
localAuthData.Add(localSalt); localAuthData.Add(_localSalt);
localAuthData.Add(localChallenge); localAuthData.Add(localChallenge);
step = 1; _step = 1;
return new AuthenticationResult(AuthenticationRuling.InProgress, return new AuthenticationResult(AuthenticationRuling.InProgress,
localAuthData); localAuthData);
} }
else if (step == 1) else if (_step == 1)
{ {
// expect challenge response. // expect challenge response.
var remoteChallenge = (byte[])remoteAuthData[0]; var remoteChallenge = (byte[])remoteAuthData[0];
var expectedRemoteChallenge = ComputeSha3(remoteNonce.Concat(initiatorPassword) var expectedRemoteChallenge = ComputeSha3(_remoteNonce.Concat(_initiatorPassword)
.Concat(localNonce) .Concat(_localNonce)
.ToArray()); .ToArray());
// compare remote challenge // compare remote challenge
if (!expectedRemoteChallenge.SequenceEqual(remoteChallenge)) if (!expectedRemoteChallenge.SequenceEqual(remoteChallenge))
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
@@ -377,14 +380,14 @@ namespace Esiur.Security.Authority.Providers
// derive a session key from nonces and password. // derive a session key from nonces and password.
// initiator identity + initiator password + initiator nonce + responder nonce // initiator identity + initiator password + initiator nonce + responder nonce
var sessionKey = ComputeSha3(initiatorIdentity.ToBytes() var sessionKey = ComputeSha3(_initiatorIdentity.ToBytes()
.Concat(initiatorPassword) .Concat(_initiatorPassword)
.Concat(remoteNonce) .Concat(_remoteNonce)
.Concat(localNonce) .Concat(_localNonce)
.ToArray(), 512); .ToArray(), 512);
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Succeeded, null, initiatorIdentity, responderIdentity, sessionKey); return new AuthenticationResult(AuthenticationRuling.Succeeded, null, _initiatorIdentity, _responderIdentity, sessionKey);
} }
else else
@@ -393,82 +396,82 @@ namespace Esiur.Security.Authority.Providers
} }
} }
else if (mode == AuthenticationMode.ResponderIdentity) else if (_mode == AuthenticationMode.ResponderIdentity)
{ {
if (step == 0) if (_step == 0)
{ {
if (remoteAuthData.Length < 1) if (remoteAuthData.Length < 1)
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
// step 0: receive remote nonce. // step 0: receive remote nonce.
remoteNonce = (byte[])remoteAuthData[0]; _remoteNonce = (byte[])remoteAuthData[0];
// prevent reply attack by checking if remote nonce is same as local nonce. // prevent reply attack by checking if remote nonce is same as local nonce.
// @TODO: We can change our localNonce then send it // @TODO: We can change our localNonce then send it
if (remoteNonce.SequenceEqual(localNonce)) if (_remoteNonce.SequenceEqual(_localNonce))
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// get responder identity from provider. // get responder identity from provider.
if (responderIdentity == null) if (_responderIdentity == null)
(responderIdentity, responderPassword) = provider.GetSelfIdentityAndCredential(domain, hostName); (_responderIdentity, _responderPassword) = _provider.GetSelfIdentityAndCredential(_domain, _hostName);
else else
responderPassword = provider.GetSelfCredential(responderIdentity, domain, hostName); _responderPassword = _provider.GetSelfCredential(_responderIdentity, _domain, _hostName);
if (responderPassword == null || responderIdentity == null) if (_responderPassword == null || _responderIdentity == null)
{ {
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
localAuthData.Add(localNonce); localAuthData.Add(_localNonce);
localAuthData.Add(responderIdentity); localAuthData.Add(_responderIdentity);
step = 1; _step = 1;
// send local nonce and identity. // send local nonce and identity.
return new AuthenticationResult(AuthenticationRuling.InProgress, return new AuthenticationResult(AuthenticationRuling.InProgress,
localAuthData localAuthData
); );
} }
else if (step == 1) else if (_step == 1)
{ {
// expect remote salt and challenge. // expect remote salt and challenge.
remoteSalt = (byte[])remoteAuthData[0]; _remoteSalt = (byte[])remoteAuthData[0];
var remoteChallenge = (byte[])remoteAuthData[1]; var remoteChallenge = (byte[])remoteAuthData[1];
// compute expected challenge response. // compute expected challenge response.
var hashedPassword = ComputeSha3(responderPassword.Concat(remoteSalt).ToArray()); var hashedPassword = ComputeSha3(_responderPassword.Concat(_remoteSalt).ToArray());
var expectedRemoteChallenge = ComputeSha3(remoteNonce.Concat(hashedPassword) var expectedRemoteChallenge = ComputeSha3(_remoteNonce.Concat(hashedPassword)
.Concat(localNonce) .Concat(_localNonce)
.ToArray()); .ToArray());
// compare remote challenge // compare remote challenge
if (!expectedRemoteChallenge.SequenceEqual(remoteChallenge)) if (!expectedRemoteChallenge.SequenceEqual(remoteChallenge))
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// compute our challenge response. // compute our challenge response.
var localChallenge = ComputeSha3(localNonce.Concat(hashedPassword) var localChallenge = ComputeSha3(_localNonce.Concat(hashedPassword)
.Concat(remoteNonce) .Concat(_remoteNonce)
.ToArray()); .ToArray());
// derive a session key from nonces and password. // derive a session key from nonces and password.
// responder identity + responder hashed password + initiator nonce + responder nonce // responder identity + responder hashed password + initiator nonce + responder nonce
var sessionKey = ComputeSha3(responderIdentity.ToBytes() var sessionKey = ComputeSha3(_responderIdentity.ToBytes()
.Concat(hashedPassword) .Concat(hashedPassword)
.Concat(remoteNonce) .Concat(_remoteNonce)
.Concat(localNonce) .Concat(_localNonce)
.ToArray(), 512); .ToArray(), 512);
localAuthData.Add(localChallenge); localAuthData.Add(localChallenge);
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Succeeded, localAuthData, responderIdentity, null, sessionKey); return new AuthenticationResult(AuthenticationRuling.Succeeded, localAuthData, _responderIdentity, null, sessionKey);
} }
else else
{ {
@@ -476,83 +479,83 @@ namespace Esiur.Security.Authority.Providers
} }
} }
else if (mode == AuthenticationMode.DualIdentity) else if (_mode == AuthenticationMode.DualIdentity)
{ {
if (step == 0) if (_step == 0)
{ {
if (remoteAuthData.Length < 2) if (remoteAuthData.Length < 2)
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
// step 0: receive remote nonce and initiator identity. // step 0: receive remote nonce and initiator identity.
remoteNonce = (byte[])remoteAuthData[0]; _remoteNonce = (byte[])remoteAuthData[0];
initiatorIdentity = (string)remoteAuthData[1]; _initiatorIdentity = (string)remoteAuthData[1];
// prevent reply attack by checking if remote nonce is same as local nonce. // prevent reply attack by checking if remote nonce is same as local nonce.
// @TODO: We can change our localNonce then send it // @TODO: We can change our localNonce then send it
if (remoteNonce.SequenceEqual(localNonce)) if (_remoteNonce.SequenceEqual(_localNonce))
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// get responder identity from provider. // get responder identity from provider.
if (responderIdentity == null) if (_responderIdentity == null)
(responderIdentity, responderPassword) = provider.GetSelfIdentityAndCredential(domain, hostName); (_responderIdentity, _responderPassword) = _provider.GetSelfIdentityAndCredential(_domain, _hostName);
else else
responderPassword = provider.GetSelfCredential(responderIdentity, domain, hostName); _responderPassword = _provider.GetSelfCredential(_responderIdentity, _domain, _hostName);
if (responderPassword == null || responderIdentity == null) if (_responderPassword == null || _responderIdentity == null)
{ {
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// get initiator password from provider. // get initiator password from provider.
(localSalt, initiatorPassword) = provider.GetHostedAccountCredential(initiatorIdentity, domain); (_localSalt, _initiatorPassword) = _provider.GetHostedAccountCredential(_initiatorIdentity, _domain);
// account not found or no password for this account. // account not found or no password for this account.
if (initiatorPassword == null || initiatorIdentity == null) if (_initiatorPassword == null || _initiatorIdentity == null)
{ {
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// send local nonce, salt and responder identity. // send local nonce, salt and responder identity.
localAuthData.Add(localNonce); localAuthData.Add(_localNonce);
localAuthData.Add(localSalt); localAuthData.Add(_localSalt);
localAuthData.Add(responderIdentity); localAuthData.Add(_responderIdentity);
step = 1; _step = 1;
// send local nonce and identity. // send local nonce and identity.
return new AuthenticationResult(AuthenticationRuling.InProgress, return new AuthenticationResult(AuthenticationRuling.InProgress,
localAuthData localAuthData
); );
} }
else if (step == 1) else if (_step == 1)
{ {
// expect initiator salt and challenge. // expect initiator salt and challenge.
var remoteSalt = (byte[])remoteAuthData[0]; var remoteSalt = (byte[])remoteAuthData[0];
var remoteChallenge = (byte[])remoteAuthData[1]; var remoteChallenge = (byte[])remoteAuthData[1];
// compute expected challenge response. // compute expected challenge response.
var hashedPassword = ComputeSha3(responderPassword.Concat(remoteSalt).ToArray()); var hashedPassword = ComputeSha3(_responderPassword.Concat(remoteSalt).ToArray());
// compare remote challenge // compare remote challenge
var expectedRemoteChallenge = ComputeSha3(remoteNonce.Concat(initiatorPassword) var expectedRemoteChallenge = ComputeSha3(_remoteNonce.Concat(_initiatorPassword)
.Concat(hashedPassword) .Concat(hashedPassword)
.Concat(localNonce) .Concat(_localNonce)
.ToArray()); .ToArray());
// compare remote challenge // compare remote challenge
if (!expectedRemoteChallenge.SequenceEqual(remoteChallenge)) if (!expectedRemoteChallenge.SequenceEqual(remoteChallenge))
{ {
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
// compute our challenge // compute our challenge
var localChallenge = ComputeSha3(localNonce.Concat(hashedPassword) var localChallenge = ComputeSha3(_localNonce.Concat(hashedPassword)
.Concat(initiatorPassword) .Concat(_initiatorPassword)
.Concat(remoteNonce) .Concat(_remoteNonce)
.ToArray()); .ToArray());
localAuthData.Add(localChallenge); localAuthData.Add(localChallenge);
@@ -560,16 +563,16 @@ namespace Esiur.Security.Authority.Providers
// derive a session key from nonces and password. // derive a session key from nonces and password.
// responder identity + responder password + initiator nonce + responder nonce // responder identity + responder password + initiator nonce + responder nonce
var sessionKey = ComputeSha3(initiatorIdentity.ToBytes() var sessionKey = ComputeSha3(_initiatorIdentity.ToBytes()
.Concat(responderIdentity.ToBytes()) .Concat(_responderIdentity.ToBytes())
.Concat(initiatorPassword) .Concat(_initiatorPassword)
.Concat(hashedPassword) .Concat(hashedPassword)
.Concat(remoteNonce) .Concat(_remoteNonce)
.Concat(localNonce) .Concat(_localNonce)
.ToArray(), 512); .ToArray(), 512);
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Succeeded, localAuthData, initiatorIdentity, responderIdentity, sessionKey); return new AuthenticationResult(AuthenticationRuling.Succeeded, localAuthData, _initiatorIdentity, _responderIdentity, sessionKey);
} }
else else
@@ -580,7 +583,7 @@ namespace Esiur.Security.Authority.Providers
} }
step = -1; _step = -1;
return new AuthenticationResult(AuthenticationRuling.Failed, null); return new AuthenticationResult(AuthenticationRuling.Failed, null);
} }
@@ -592,15 +595,15 @@ namespace Esiur.Security.Authority.Providers
string domain, string domain,
PasswordAuthenticationProvider provider) PasswordAuthenticationProvider provider)
{ {
localNonce = Global.GenerateBytes(20); _localNonce = Global.GenerateBytes(20);
this.provider = provider; this._provider = provider;
this.initiatorIdentity = initiatorIdentity; this._initiatorIdentity = initiatorIdentity;
this.responderIdentity = responderIdentity; this._responderIdentity = responderIdentity;
this.mode = mode; this._mode = mode;
this.direction = direction; this._direction = direction;
this.domain = domain; this._domain = domain;
this.hostName = hostName; this._hostName = hostName;
} }
} }
} }
@@ -1,4 +1,5 @@
using System; using Esiur.Core;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@@ -35,5 +36,15 @@ namespace Esiur.Security.Authority.Providers
{ {
return null; return null;
} }
public AsyncReply<bool> Login(Session session)
{
throw new NotImplementedException();
}
public AsyncReply<bool> Logout(Session session)
{
throw new NotImplementedException();
}
} }
} }
@@ -7,4 +7,8 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Libraries\Esiur\Esiur.csproj" />
</ItemGroup>
</Project> </Project>
@@ -8,7 +8,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\..\..\Libraries\Esiur\Esiur.csproj" /> <ProjectReference Include="..\..\..\..\Libraries\Esiur\Esiur.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+1
View File
@@ -146,6 +146,7 @@ class Program
// Create stores to keep objects. // Create stores to keep objects.
var system = await wh.Put("sys", new MemoryStore()); 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() {
// Membership = membership // Membership = membership
}); });