improved authentication process

This commit is contained in:
Kai Jan Kriegel 2020-11-12 10:12:56 +01:00
parent d219163f7b
commit ad778d174d
2 changed files with 65 additions and 31 deletions

View File

@ -1,18 +1,14 @@
using System; using Capnp;
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 FabAccessAPI.Schema; using FabAccessAPI.Schema;
using S22.Sasl; 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 /// Authentication Identity
/// ///
/// Under the hood a string because the form depends heavily on the method /// 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 /// This struct contains the user as is passed to the actual authentication/authorization
/// subsystems /// subsystems
/// ///
public struct User { public struct AuthUser {
/// Contains the Authentication ID used /// Contains the Authentication ID used
/// ///
/// The authentication ID is an identifier for the authentication exchange. This is different /// The authentication ID is an identifier for the authentication exchange. This is different
@ -101,6 +97,11 @@ namespace FabAccessAPI
} }
class UnauthorizedException : Exception{}
/// <summary>
/// THIS IS VERY INCOMPLETE!
/// </summary>
class Auth { class Auth {
private IAuthentication _authCap; private IAuthentication _authCap;
public Auth(IAuthentication authCap) { public Auth(IAuthentication authCap) {
@ -111,7 +112,7 @@ namespace FabAccessAPI
return _authCap.Mechanisms(); return _authCap.Mechanisms();
} }
public async Task<bool> Handshake() { public bool Handshake(Stream stream) {
var host = "localhost"; var host = "localhost";
var asm = typeof(Api).Assembly; var asm = typeof(Api).Assembly;
var program = $"{asm.FullName}-{asm.GetName().Version}"; var program = $"{asm.FullName}-{asm.GetName().Version}";
@ -141,9 +142,14 @@ namespace FabAccessAPI
Console.WriteLine($"Server: {serverInfo.Host}"); Console.WriteLine($"Server: {serverInfo.Host}");
Console.WriteLine($"Version: {serverInfo.Program}"); Console.WriteLine($"Version: {serverInfo.Program}");
Console.WriteLine($"API-Version: {serverInfo.Major}.{serverInfo.Minor}"); 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<object> Authenticate(string mech, Dictionary<string, object> properties) { public async Task<bool> Authenticate(string mech, Dictionary<string, object> properties) {
//TODO: Perform Handshake to verify that we are compatible with server
var m = SaslFactory.Create(mech); var m = SaslFactory.Create(mech);
foreach (KeyValuePair<string, object> entry in properties) { foreach (KeyValuePair<string, object> entry in properties) {
m.Properties.Add(entry.Key, entry.Value); 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;
} }

View File

@ -1,19 +1,16 @@
using System; using Capnp.Rpc;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Capnp;
using Capnp.Rpc;
using FabAccessAPI.Schema; using FabAccessAPI.Schema;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace FabAccessAPI namespace FabAccessAPI {
{
class Connection { class Connection {
private TcpRpcClient _rpcClient; private TcpRpcClient? _rpcClient = null;
private IBootstrap _bootstrapCap; private IBootstrap? _bootstrapCap = null;
private User _user; private AuthUser? _authUser = null;
private Auth _auth; private Auth? _auth = null;
private Machines? _machines = null;
/// <summary> /// <summary>
/// ///
@ -24,9 +21,31 @@ namespace FabAccessAPI
_bootstrapCap = _rpcClient.GetMain<IBootstrap>(); _bootstrapCap = _rpcClient.GetMain<IBootstrap>();
} }
async Task Auth(string mech, Dictionary<string, string> kvs) { /// <summary>
/// Authenticate this connection.
/// Calling this more then once is UB
/// </summary>
/// <param name="mech">The desired authentication mechanism</param>
/// <param name="kvs">Key-Value data specific to the mechanism</param>
/// <returns></returns>
async Task Auth(string mech, Dictionary<string, object> kvs) {
_auth = new Auth(await _bootstrapCap.Auth()); _auth = new Auth(await _bootstrapCap.Auth());
var mechs = await _auth.GetMechanisms().ConfigureAwait(false); 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);
}
/// <summary>
/// Get a wrapped capability to interact with machines
/// </summary>
/// <returns>A wrapped capability to interact with machines</returns>
async Task<Machines> AccessMachines() {
_machines ??= new Machines((await _bootstrapCap.Machines().ConfigureAwait(false)));
return _machines;
} }
} }
} }