Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# EditorConfig: http://EditorConfig.org
# VS extension: https://visualstudiogallery.msdn.microsoft.com/c8bccfe2-650c-4b42-bc5c-845e21f96328

# tab indentation
[*.cs]
indent_style = tab
indent_size = 4
19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
language: csharp
mono: none
dotnet: 2.0.0
dist: trusty

addons:
apt:
sources:
- sourceline: 'deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main'
key_url: 'https://packages.microsoft.com/keys/microsoft.asc'
packages:
- dotnet-hostfxr-1.0.1
- dotnet-sharedframework-microsoft.netcore.app-1.0.5

script:
- dotnet restore src
- dotnet build src
- dotnet test src/MessageWire.Tests

5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# MessageWire

[![Appveyor build status](https://ci.appveyor.com/api/projects/status/3pctff9644pdxx3i?svg=true)](https://ci.appveyor.com/project/yallie/messagewire)
[![Travis-CI build status](https://travis-ci.org/yallie/MessageWire.svg?branch=master)](https://travis-ci.org/yallie/MessageWire)
[![MessageWire NuGet version](https://img.shields.io/nuget/v/MessageWire.svg)](https://www.nuget.org/packages/MessageWire/)

MessageWire is a Secure Remote Password Protocol v6 implementation, a kind of zero Knowledge proof, that enables secure authentication and encryption without passing the actual identity key (password) or any other knowledge required to crack the encryption for messages exchanged between client (dealer socket) and server (router socket) using the NetMQ library, a .NET implementation of ZeroMQ.

Get the [NuGet package](https://www.nuget.org/packages/MessageWire).
Expand Down
10 changes: 10 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 1.0.{build}
image: Visual Studio 2017
install:
- cmd: appveyor downloadfile https://dist.nuget.org/win-x86-commandline/v4.3.0/nuget.exe
before_build:
- cmd: nuget restore src
build:
verbosity: minimal
test_script:
- cmd: dotnet test src/MessageWire.Tests
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssemblyName>MessageWire.Tests</AssemblyName>
<PackageId>MessageWire.Tests</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
<PackageTargetFallback>$(PackageTargetFallback);dnxcore50</PackageTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
Expand All @@ -17,9 +15,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-beta5-build1225" />
<PackageReference Include="xunit" Version="2.2.0-beta5-build3474" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.2.0" />
</ItemGroup>

</Project>
237 changes: 237 additions & 0 deletions src/MessageWire.Tests/RouterDealerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
using System;
using System.Collections.Generic;
using Xunit;
using System.Threading;

namespace MessageWire.Tests
{
public class RouterDealerTests : IDisposable
{
public RouterDealerTests()
{
Wire.Linger = new TimeSpan(0, 0, 0, 1);
}

void IDisposable.Dispose()
{
Wire.Cleanup();
}

[Fact]
public void BasicSendReceiveTest()
{
var serverReceived = false;
var clientReceived = false;
var connString = "tcp://127.0.0.1:5800";

using (IHost server = new Host(connString))
{
server.MessageReceived += (s, e) =>
{
Assert.Equal("Hello, I'm the client.", e.Message.Frames[0].ConvertToString());
Assert.Equal("This is my second line.", e.Message.Frames[1].ConvertToString());

var replyData = new List<byte[]>();
replyData.Add("Hello, I'm the server. You sent.".ConvertToBytes());
replyData.AddRange(e.Message.Frames);
server.Send(e.Message.ClientId, replyData);
serverReceived = true;
Assert.True(e.Message.Frames.Count == 2, "Server received message did not have 2 frames.");
Assert.True(replyData.Count == 3, "Server message did not have 3 frames.");
};

using (IClient client = new Client(connString))
{
client.MessageReceived += (s, e) =>
{
clientReceived = true;
Assert.True(e.Message.Frames.Count == 3, "Received message did not have 3 frames.");
Assert.Equal("Hello, I'm the server. You sent.", e.Message.Frames[0].ConvertToString());
Assert.Equal("Hello, I'm the client.", e.Message.Frames[1].ConvertToString());
Assert.Equal("This is my second line.", e.Message.Frames[2].ConvertToString());
};

var clientMessageData = new List<byte[]>();
clientMessageData.Add("Hello, I'm the client.".ConvertToBytes());
clientMessageData.Add("This is my second line.".ConvertToBytes());
client.Send(clientMessageData);

var count = 0;
while (count < 20 && (!clientReceived || !serverReceived))
{
Thread.Sleep(20);
count++;
}
Assert.True(count < 100, "Test took too long.");
Assert.True(serverReceived, "Server failed to receive and send.");
Assert.True(clientReceived, "Client failed to receive.");
}
}
}

[Fact]
public void EncryptedSendReceiveTest()
{
var serverReceived = false;
var clientReceived = false;
var connString = "tcp://127.0.0.1:5800";

using (IHost server = new Host(connString, new TestZkRepository()))
{
server.MessageReceived += (s, e) =>
{
Assert.Equal("Hello, I'm the client.", e.Message.Frames[0].ConvertToString());
Assert.Equal("This is my second line.", e.Message.Frames[1].ConvertToString());

var replyData = new List<byte[]>();
replyData.Add("Hello, I'm the server. You sent.".ConvertToBytes());
replyData.AddRange(e.Message.Frames);
server.Send(e.Message.ClientId, replyData);
serverReceived = true;
Assert.True(e.Message.Frames.Count == 2, "Server received message did not have 2 frames.");
Assert.True(replyData.Count == 3, "Server message did not have 3 frames.");
};

using (IClient client = new Client(connString, "testid", "....++++...."))
{
var established = false;
client.EcryptionProtocolEstablished += (s, e) =>
{
established = true;
};

client.EcryptionProtocolFailed += (s, e) =>
{
Assert.True(false, "Protocol failed.");
};

client.MessageReceived += (s, e) =>
{
clientReceived = true;
Assert.True(e.Message.Frames.Count == 3, "Received message did not have 3 frames.");
Assert.Equal("Hello, I'm the server. You sent.", e.Message.Frames[0].ConvertToString());
Assert.Equal("Hello, I'm the client.", e.Message.Frames[1].ConvertToString());
Assert.Equal("This is my second line.", e.Message.Frames[2].ConvertToString());
};

client.SecureConnection(blockUntilComplete: false);

var count = 0;
while (count < 20000 && !established)
{
Thread.Sleep(20);
count++;
}
Assert.True(count < 20000, "SecureConnection took too long.");
Assert.True(established, "SecureConnection not established.");

var clientMessageData = new List<byte[]>();
clientMessageData.Add("Hello, I'm the client.".ConvertToBytes());
clientMessageData.Add("This is my second line.".ConvertToBytes());
client.Send(clientMessageData);

count = 0;
while (count < 20 && (!established || !clientReceived || !serverReceived))
{
Thread.Sleep(20);
count++;
}
Assert.True(count < 20, "Test took too long.");
Assert.True(serverReceived, "Server failed to receive and send.");
Assert.True(clientReceived, "Client failed to receive.");
}
}
}

[Fact]
public void HeartBeatTest()
{
var serverReceived = false;
var clientReceived = false;
var connString = "tcp://127.0.0.1:5800";

using (IHost server = new Host(connString, new TestZkRepository()))
{
server.MessageReceived += (s, e) =>
{
Assert.Equal("Hello, I'm the client.", e.Message.Frames[0].ConvertToString());
Assert.Equal("This is my second line.", e.Message.Frames[1].ConvertToString());

var replyData = new List<byte[]>();
replyData.Add("Hello, I'm the server. You sent.".ConvertToBytes());
replyData.AddRange(e.Message.Frames);
server.Send(e.Message.ClientId, replyData);
serverReceived = true;
Assert.True(e.Message.Frames.Count == 2, "Server received message did not have 2 frames.");
Assert.True(replyData.Count == 3, "Server message did not have 3 frames.");
};

using (IClient client = new Client(connString, "testid", "....++++....",
heartBeatIntervalMs: 1000, maxSkippedHeartBeatReplies: 4))
{
var established = false;
client.EcryptionProtocolEstablished += (s, e) =>
{
established = true;
};

client.EcryptionProtocolFailed += (s, e) =>
{
Assert.True(false, "Protocol failed.");
};

client.MessageReceived += (s, e) =>
{
clientReceived = true;
Assert.True(e.Message.Frames.Count == 3, "Received message did not have 3 frames.");
Assert.Equal("Hello, I'm the server. You sent.", e.Message.Frames[0].ConvertToString());
Assert.Equal("Hello, I'm the client.", e.Message.Frames[1].ConvertToString());
Assert.Equal("This is my second line.", e.Message.Frames[2].ConvertToString());
};

client.SecureConnection(blockUntilComplete: false);

var count = 0;
while (count < 200 && !established)
{
Thread.Sleep(20);
count++;
}
Assert.True(count < 200, "SecureConnection took too long.");
Assert.True(established, "SecureConnection not established.");

var clientMessageData = new List<byte[]>();
clientMessageData.Add("Hello, I'm the client.".ConvertToBytes());
clientMessageData.Add("This is my second line.".ConvertToBytes());
client.Send(clientMessageData);

count = 0;
while (count < 20 && (!established || !clientReceived || !serverReceived))
{
Thread.Sleep(20);
count++;
}
Assert.True(count < 20, "Test took too long.");
Assert.True(serverReceived, "Server failed to receive and send.");
Assert.True(clientReceived, "Client failed to receive.");

count = 0;
while (count < 200 && client.HeartBeatsSentCount < 2 && client.HeartBeatsReceivedCount < 2)
{
Thread.Sleep(500);
count++;
}

Assert.True(count < 200, "Test took too long.");
var serverKeys = server.GetCurrentSessionKeys();
Assert.Equal(1, serverKeys.Length);
var session = server.GetSession(serverKeys[0]);
Assert.NotNull(session);
Assert.True("testid" == session.ClientIdentity, "Client identity does not match.");
Assert.True(client.ClientId == session.ClientId, "ClientId does not match.");
Assert.True(session.HeartBeatsReceivedCount > 1, "Server failed to receive heartbeats.");
}
}
}
}
}
9 changes: 6 additions & 3 deletions src/MessageWire.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
VisualStudioVersion = 15.0.26730.8
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B2B7F7CF-457D-4EBE-B34C-7AF0B49C0B54}"
EndProject
Expand All @@ -12,9 +12,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".docs", ".docs", "{2A8A94FC
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessageWire", "src\MessageWire\MessageWire.csproj", "{42CEE435-2735-4E99-AF3F-FBB18E55892E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessageWire", "MessageWire\MessageWire.csproj", "{42CEE435-2735-4E99-AF3F-FBB18E55892E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessageWire.Tests", "src\MessageWire.Tests\MessageWire.Tests.csproj", "{FADEA2FC-B1BC-4218-A64C-C795FE4EDB79}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessageWire.Tests", "MessageWire.Tests\MessageWire.Tests.csproj", "{FADEA2FC-B1BC-4218-A64C-C795FE4EDB79}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -38,4 +38,7 @@ Global
{42CEE435-2735-4E99-AF3F-FBB18E55892E} = {B2B7F7CF-457D-4EBE-B34C-7AF0B49C0B54}
{FADEA2FC-B1BC-4218-A64C-C795FE4EDB79} = {B2B7F7CF-457D-4EBE-B34C-7AF0B49C0B54}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4D78F946-1236-4D86-9C64-1353CC6D049E}
EndGlobalSection
EndGlobal
Loading