Skip to content
This repository has been archived by the owner on Jun 16, 2022. It is now read-only.

Commit

Permalink
Committed in broken state.
Browse files Browse the repository at this point in the history
Completed logical flow of authentication of sessions.
  • Loading branch information
DJGosnell committed Sep 21, 2016
1 parent 4c96eaa commit 3da6df9
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,11 @@ public class RpcServerInfoDataContract {
/// </summary>
[ProtoMember(3)]
public byte[] Data { get; set; }

/// <summary>
/// True if the server requires authentication before proceeding; False otherwise.
/// </summary>
[ProtoMember(4)]
public byte[] RequireAuthentication { get; set; }
}
}
20 changes: 18 additions & 2 deletions src/DtronixMessageQueue/Rpc/RpcAuthenticateEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,28 @@
using System.Threading.Tasks;

namespace DtronixMessageQueue.Rpc {
public class RpcAuthenticateEventArgs : EventArgs {
public class RpcAuthenticateEventArgs<TSession, TConfig> : EventArgs
where TSession : RpcSession<TSession, TConfig>, new()
where TConfig : RpcConfig {

/// <summary>
/// Connected session.
/// </summary>
public TSession Session { get; }

/// <summary>
/// Authentication frame to be passed to the server for verification.
/// </summary>
public MqFrame AuthFrame { get; set; }
public byte[] AuthData { get; set; }

/// <summary>
/// (Server)
/// Set to true if the authentication data passed is valid; False otherwise.
/// </summary>
public bool Authenticated { get; set; }

public RpcAuthenticateEventArgs(TSession session) {
Session = session;
}
}
}
6 changes: 4 additions & 2 deletions src/DtronixMessageQueue/Rpc/RpcClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public RpcClient(TConfig config) : base(config) {
WorkerThreadPool = new SmartThreadPool(config.ThreadPoolTimeout, config.MaxExecutionThreads, 1);
}



protected override TSession CreateSession() {
var session = base.CreateSession();
return session;
}
}
}
5 changes: 0 additions & 5 deletions src/DtronixMessageQueue/Rpc/RpcServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ public class RpcServer<TSession, TConfig> : MqServer<TSession, TConfig>
/// </summary>
public SmartThreadPool WorkerThreadPool { get; }

/// <summary>
/// Verify the authenticity of the newly connected client.
/// </summary>
public event EventHandler<RpcAuthenticateEventArgs> Authenticate;

/// <summary>
/// Creates a new instance of the server with the specified configurations.
/// </summary>
Expand Down
109 changes: 74 additions & 35 deletions src/DtronixMessageQueue/Rpc/RpcSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,21 @@ public abstract class RpcSession<TSession, TConfig> : MqSession<TSession, TConfi
/// </summary>
public RpcClient<TSession, TConfig> Client { get; private set; }

/// <summary>
/// Verify the authenticity of the newly connected client.
/// </summary>
public event EventHandler<RpcAuthenticateEventArgs<TSession, TConfig>> Authenticate;

/// <summary>
/// Verify the authenticity of the newly connected client.
/// </summary>
public event EventHandler<SessionEventArgs<TSession, TConfig>> AuthenticationResult;

/// <summary>
/// True if this session has passed authentication; False otherwise.
/// </summary>
public bool Authenticated { get; set; }

/// <summary>
/// Called when this session is being setup.
/// </summary>
Expand Down Expand Up @@ -115,34 +130,76 @@ protected override void ProcessCommand(MqFrame frame) {
try {
var rpc_command_type = frame.ReadByte(1);

// Process the rpc sub-command
switch (rpc_command_type) {
case 0: // Welcome message.
// Verify that this is executing on the client.
if (BaseSocket.Mode != SocketMode.Client) {
Close(SocketCloseReason.ProtocolError);
return;
}
if (rpc_command_type == 0) {
// Welcome message.
if (BaseSocket.Mode != SocketMode.Client) {
Close(SocketCloseReason.ProtocolError);
return;
}

var serializer = SerializationCache.Get();
var serializer = SerializationCache.Get();

serializer.MessageReader.Message = new MqMessage(frame);
serializer.MessageReader.Message = new MqMessage(frame);

// Try to read the information from the server about the server.
Client.ServerInfo = serializer.DeserializeFromReader(typeof(RpcServerInfoDataContract), 0) as RpcServerInfoDataContract;
// Try to read the information from the server about the server.
Client.ServerInfo =
serializer.DeserializeFromReader(typeof(RpcServerInfoDataContract), 0) as RpcServerInfoDataContract;

SerializationCache.Put(serializer);
SerializationCache.Put(serializer);

break;
var auth_args = new RpcAuthenticateEventArgs<TSession, TConfig>(this);

default:
Authenticate?.Invoke(this, auth_args);

if (auth_args.AuthData != null) {
var auth_frame = CreateFrame(new byte[auth_args.AuthData.Length + 2], MqFrameType.Command);
auth_frame.Write(0, (byte) MqCommandType.RpcCommand);
auth_frame.Write(1, 1);
auth_frame.Write(2, auth_args.AuthData, 0, auth_args.AuthData.Length);
Send(auth_frame);
}

} else if (rpc_command_type == 1) {
// Authentication request
if (BaseSocket.Mode != SocketMode.Server) {
Close(SocketCloseReason.ProtocolError);
break;
return;
}

byte[] auth_bytes = new byte[frame.DataLength - 1];
frame.Read(1, auth_bytes, 0, auth_bytes.Length);

var auth_args = new RpcAuthenticateEventArgs();

Authenticate?.Invoke(this, auth_args);

Authenticated = auth_args.Authenticated;

if (Authenticated == false) {
Close(SocketCloseReason.AuthenticationFailure);
} else {
var auth_frame = CreateFrame(new byte[auth_args.AuthData.Length + 2], MqFrameType.Command);
auth_frame.Write(0, (byte) MqCommandType.RpcCommand);
auth_frame.Write(1, 2);

Send(auth_frame);
}

} else if (rpc_command_type == 2) {
if (BaseSocket.Mode != SocketMode.Client) {
Close(SocketCloseReason.ProtocolError);
return;
}

Authenticated = true;
} else {
Close(SocketCloseReason.ProtocolError);
}

} catch (Exception) {
Close(SocketCloseReason.ProtocolError);
}


}

Expand Down Expand Up @@ -493,23 +550,5 @@ void IProcessRpcSession.CancelWaitOperation(ushort id) {
}
}

/// <summary>
/// Called by the RpcServer to verify the authentication request by the client.
/// </summary>
/// <param name="message">Message received from the client to validate.</param>
/// <returns>True if the client has been authenticated; False otherwise.</returns>
protected virtual bool Authenticate(MqMessage message) {
return true;
}

/// <summary>
/// Called by the RpcClient to request authentication from the RpcServer.
/// Override to specify custom authentication
/// </summary>
/// <returns>Returned MqMessage is passed to the server and then validated.</returns>
protected virtual MqMessage RequestAuthentication() {
return null;
}

}
}

0 comments on commit 3da6df9

Please sign in to comment.