From ad778d174df2bd5693d7c878da057ce3feb5171e Mon Sep 17 00:00:00 2001 From: Kai Jan Kriegel Date: Thu, 12 Nov 2020 10:12:56 +0100 Subject: [PATCH] improved authentication process --- FabAccessAPI/Auth.cs | 49 +++++++++++++++++++++++++------------- FabAccessAPI/Connection.cs | 47 +++++++++++++++++++++++++----------- 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/FabAccessAPI/Auth.cs b/FabAccessAPI/Auth.cs index 9f68def..7ac5096 100644 --- a/FabAccessAPI/Auth.cs +++ b/FabAccessAPI/Auth.cs @@ -1,18 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Capnp; -using Capnp.Rpc; +using Capnp; using FabAccessAPI.Schema; using S22.Sasl; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Exception = System.Exception; -namespace FabAccessAPI -{ +namespace FabAccessAPI { /// Authentication Identity /// /// Under the hood a string because the form depends heavily on the method @@ -49,7 +45,7 @@ namespace FabAccessAPI /// This struct contains the user as is passed to the actual authentication/authorization /// subsystems /// - public struct User { + public struct AuthUser { /// Contains the Authentication ID used /// /// The authentication ID is an identifier for the authentication exchange. This is different @@ -101,6 +97,11 @@ namespace FabAccessAPI } + class UnauthorizedException : Exception{} + + /// + /// THIS IS VERY INCOMPLETE! + /// class Auth { private IAuthentication _authCap; public Auth(IAuthentication authCap) { @@ -111,7 +112,7 @@ namespace FabAccessAPI return _authCap.Mechanisms(); } - public async Task Handshake() { + public bool Handshake(Stream stream) { var host = "localhost"; var asm = typeof(Api).Assembly; var program = $"{asm.FullName}-{asm.GetName().Version}"; @@ -125,7 +126,7 @@ namespace FabAccessAPI }; var msg = MessageBuilder.Create(); - var root = msg.BuildRoot(); + var root = msg.BuildRoot(); message.serialize(root); var pump = new FramePump(stream); @@ -141,9 +142,14 @@ namespace FabAccessAPI Console.WriteLine($"Server: {serverInfo.Host}"); Console.WriteLine($"Version: {serverInfo.Program}"); Console.WriteLine($"API-Version: {serverInfo.Major}.{serverInfo.Minor}"); + + //TODO: Check if we are actually compatible. This will probably need some internal lookup or well defined versioning semantics + return true; } - public async Task Authenticate(string mech, Dictionary properties) { + public async Task Authenticate(string mech, Dictionary properties) { + //TODO: Perform Handshake to verify that we are compatible with server + var m = SaslFactory.Create(mech); foreach (KeyValuePair entry in properties) { m.Properties.Add(entry.Key, entry.Value); @@ -170,8 +176,17 @@ namespace FabAccessAPI } } + 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 null; + return false; } diff --git a/FabAccessAPI/Connection.cs b/FabAccessAPI/Connection.cs index 7688e51..8156d8c 100644 --- a/FabAccessAPI/Connection.cs +++ b/FabAccessAPI/Connection.cs @@ -1,19 +1,16 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading.Tasks; -using Capnp; -using Capnp.Rpc; +using Capnp.Rpc; using FabAccessAPI.Schema; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; -namespace FabAccessAPI -{ +namespace FabAccessAPI { class Connection { - private TcpRpcClient _rpcClient; - private IBootstrap _bootstrapCap; - private User _user; - private Auth _auth; + private TcpRpcClient? _rpcClient = null; + private IBootstrap? _bootstrapCap = null; + private AuthUser? _authUser = null; + private Auth? _auth = null; + private Machines? _machines = null; /// /// @@ -24,9 +21,31 @@ namespace FabAccessAPI _bootstrapCap = _rpcClient.GetMain(); } - async Task Auth(string mech, Dictionary kvs) { + /// + /// Authenticate this connection. + /// Calling this more then once is UB + /// + /// The desired authentication mechanism + /// Key-Value data specific to the mechanism + /// + async Task Auth(string mech, Dictionary kvs) { _auth = new Auth(await _bootstrapCap.Auth()); var mechs = await _auth.GetMechanisms().ConfigureAwait(false); + Console.WriteLine("The Server supports the following auth mechs:"); + Console.Write(mechs); + + // TODO: Check that the requested auth mech is actually available. + + await _auth.Authenticate(mech, kvs).ConfigureAwait(false); + } + + /// + /// Get a wrapped capability to interact with machines + /// + /// A wrapped capability to interact with machines + async Task AccessMachines() { + _machines ??= new Machines((await _bootstrapCap.Machines().ConfigureAwait(false))); + return _machines; } } }