//using FabAccessAPI.Schema; //using S22.Sasl; //using System.Collections.Generic; //using System.Linq; //using System.Threading.Tasks; //using Exception = System.Exception; //namespace FabAccessAPI //{ // / Authentication Identity // / // / Under the hood a string because the form depends heavily on the method // public struct AuthCId { // public string Id { get; private set; } // public AuthCId(string id) : this() { Id = id; } // } // / Authorization Identity // / // / This identity is internal to FabAccess and completely independent from the authentication // / method or source // public struct AuthZId { // / Main User ID. Generally an user name or similar // public string Uid; // / Sub user ID. // / // / Can change scopes for permissions, e.g. having a +admin account with more permissions than // / the default account and +dashboard et.al. accounts that have restricted permissions for // / their applications // public string Subuid; // / Realm this account originates. // / // / The Realm is usually described by a domain name but local policy may dictate an unrelated // / mapping // public string Realm; // } // / Authentication/Authorization user object. // / // / This struct contains the user as is passed to the actual authentication/authorization // / subsystems // / // public struct AuthUser { // / Contains the Authentication ID used // / // / The authentication ID is an identifier for the authentication exchange. This is different // / than the ID of the user to be authenticated; for example when using x509 the authcid is // / the dn of the certificate, when using GSSAPI the authcid is of form `@` // public AuthCId Authcid; // / Contains the Authorization ID // / // / This is the identifier of the user to *authenticate as*. This in several cases is different // / to the `authcid`: // / If somebody wants to authenticate as somebody else, su-style. // / If a person wants to authenticate as a higher-permissions account, e.g. foo may set authzid foo+admin // / to split normal user and "admin" accounts. // / If a method requires a specific authcid that is different from the identifier of the user // / to authenticate as, e.g. GSSAPI, x509 client certificates, API TOKEN authentication. // public AuthZId Authzid; // / Contains the authentication method used // / // / For the most part this is the SASL method // public string AuthMethod; // / Method-specific key-value pairs // / // / Each method can use their own key-value pairs. // / E.g. EXTERNAL encodes the actual method used (x509 client certs, UID/GID for unix sockets, // / ...) // public Dictionary Kvs; // } // Authentication has two parts: Granting the authentication itself and then performing the // authentication. // Granting the authentication checks if // a) the given authcid fits with the given (authMethod, kvs). In general a failure here indicates // a programming failure — the authcid come from the same source as that tuple // b) the given authcid may authenticate as the given authzid. E.g. if a given client certificate // has been configured for that user, if a GSSAPI user maps to a given user, // public enum AuthError { // / Authentication ID is bad/unknown/.. // BadAuthcid, // / Authorization ID is unknown/.. // BadAuthzid, // / Authorization ID is not of form user+uid@realm // MalformedAuthzid, // / User may not use that authorization id // NotAllowedAuthzid, // } // public class UnauthorizedException : Exception{} // public class UnsupportedMechanismException : Exception{} // / // / THIS IS VERY INCOMPLETE! // / // public class Auth { // #region Log // private static readonly log4net.ILog _Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); // #endregion // private IAuthentication _authCap; // public Auth(IAuthentication authCap) { // _authCap = authCap; // } // public Task> GetMechanisms() { // return _authCap.Mechanisms(); // } // public async Task Authenticate(string mech, Dictionary properties) { // var m = SaslFactory.Create(mech); // foreach (KeyValuePair entry in properties) { // m.Properties.Add(entry.Key, entry.Value); // } // var initialResponse = new Request.initialResponse(); // if (m.HasInitial) { // initialResponse.Initial = m.GetResponse(new byte[0]); // } // var req = new Request { // Mechanism = m.Name, // InitialResponse = initialResponse // }; // var resp = await _authCap.Start(req); // while (!m.IsCompleted) { // if (resp.which == Response.WHICH.Challence) { // var additional = m.GetResponse(resp.Challence.ToArray()); // resp = await _authCap.Step(additional); // } // else { // break; // } // } // if (resp.which == Response.WHICH.Outcome) { // if (resp.Outcome.Result == Response.Result.successful) { // return true; // } // else { // TODO: Provide meaningful info about auth failure // return false; // } // } // return false; // } // } //}