2022-03-16 00:37:08 +01:00

82 lines
2.5 KiB
C#

using FabAccessAPI.Schema;
using S22.Sasl;
using System.Collections.Generic;
using System.Threading.Tasks;
using FabAccessAPI.Exceptions;
using System.Linq;
namespace FabAccessAPI
{
/// <summary>
/// Authenticate with SASL
/// </summary>
public class Auth
{
#region Private Fields
private readonly IAuthentication _AuthCap;
#endregion
#region Constructors
public Auth(IAuthentication authCap)
{
_AuthCap = authCap;
}
#endregion
#region Methods
public async Task<Session> Authenticate(string mech, Dictionary<string, object> properties)
{
SaslMechanism? saslMechanism = SaslFactory.Create(mech);
foreach (KeyValuePair<string, object> entry in properties)
{
saslMechanism.Properties.Add(entry.Key, entry.Value);
}
byte[] data = new byte[0];
if (saslMechanism.HasInitial)
{
data = saslMechanism.GetResponse(new byte[0]);
}
Response? response = await _AuthCap.Step(data);
while (!saslMechanism.IsCompleted)
{
if(response.Failed != null)
{
switch (response.Failed.Code)
{
case Response.Error.badMechanism:
throw new BadMechanismException();
case Response.Error.invalidCredentials:
throw new InvalidCredentialsException();
case Response.Error.aborted:
case Response.Error.failed:
default:
throw new AuthenticationFailedException(response.Failed.AdditionalData.ToArray());
}
}
if(response.Challenge != null)
{
byte[]? additional = saslMechanism.GetResponse(response.Challenge.ToArray());
response = await _AuthCap.Step(additional);
}
else
{
throw new AuthenticationFailedException();
}
}
if (response.Successful != null)
{
return response.Successful.Session;
}
else
{
throw new AuthenticationFailedException();
}
}
#endregion
}
}