• Stars
    star
    261
  • Rank 156,630 (Top 4 %)
  • Language
    C#
  • License
    Other
  • Created about 12 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

IronPigeon is a decentralized communication protocol that provides high confidentiality and authenticity for the messages.

IronPigeon

IronPigeon is a decentralized communication protocol that provides high confidentiality and authenticity for the messages.

Build Status NuGet package

Messages are signed for authenticity, encrypted for confidentiality, and transmitted indirectly so that eavesdroppers find it difficult or impossible to establish whether two parties have even communicated, what was communicated or how much was communicated.

This project includes libraries that implement the protocol and a message relay web service project that provides the cloud component necessary for passing messages.

See the end of this file for instructions on contacting the author using the IronPigeon protocol.

Installing IronPigeon

The recommended way to acquire the binary is via the IronPigeon NuGet package.

For email-like message exchange, the IronPigeon.Dart NuGet package is recommended.

Hosting IronPigeon

Composition

There are a small collection of objects that work together to provide the functions required to send and receive messages. These objects can be manually and individually instantiated, and properties set on them to point to the other objects you've created. Or you can rely on MEF to do this work for you.

When targeting .NET 4.0, use MEF as it is found in the framework under the System.ComponentModel.Composition namespace. When targeting .NET 4.5 or Windows 8, you should use the MEF "v2" found in the Microsoft.Composition NuGet package. The code below assumes you're using the MEF framework from NuGet. Most fundamental IronPigeon services are in the core IronPigeon assembly, so we add that entire assembly to the MEF catalog:

var configuration = new ContainerConfiguration()
    .WithAssembly(typeof(Channel).Assembly);

// When targeting desktop apps:
configuration.WithPart(typeof(DesktopCryptoProvider));
// When targeting WinRT apps:
configuration.WithAssembly(typeof(WinRTChannel).Assembly);

According to standard MEF code, you'll need a container to begin using instances of these services:

var container = configuration.CreateContainer();

You will need to configure some of these services (setting properties, etc.) and other services you'll call methods on to actually send and receive messages. You can acquire these services directly from the container using:

var someService = container.GetExport<T>();

The preferred approach however is that you define your own MEF part with importing properties that will automatically be set to instances of these services, like this:

[Export]
public class MyImports {
    [Import]
    public /*WinRT*/Channel Channel { get; set; }

    [Import]
    public RelayCloudBlobStorageProvider MessageRelayService { get; set; }

    [Import]
    public ICryptoProvider CryptoProvider { get; set; }

    [Import]
    public OwnEndpointServices OwnEndpointServices { get; set; }
}

The latter approach will require that you add your part to the MEF catalog prior to creating the container:

configuration.WithPart(typeof(MyImports));

Configuration

IronPigeon has three settings that it needs to work:

  1. A URL to post public blobs to
  2. A URL to request new inboxes from
  3. The length of asymmetric keys to generate for newly created endpoints.

Assuming the context of running inside the MyImports class as defined above, the following code demonstrates configuring the above listed settings.

this.MessageRelayService.BlobPostUrl = new Uri("https://ironpigeon.azurewebsites.net/api/blob/");
this.MessageRelayService.InboxServiceUrl = new Uri("https://ironpigeon.azurewebsites.net/Inbox/");
this.CryptoProvider.ApplySecurityLevel(SecurityLevel.Minimum); // minimum is good for testing as keys generate faster

The URLs above are examples. They can point to any compatible cloud service.

Establishing a communications channel

To send a message via IronPigeon, a pair of endpoints must exist. Endpoints have both public and private components, containing the public and private cryptographic key pairs respectively. When party A shares its public endpoint with party B, party B can send party A messages. When two parties each create their own endpoints and exchange their public components, the two parties may communicate securely.

Creating an endpoint

The following code creates a new endpoint.

this.Channel.Endpoint = await this.OwnEndpointServices.CreateAsync();

An OwnEndpoint instance includes the private keys required for receiving messages at that endpoint. It is therefore usually advisable to persist the private keys after creating the endpoint so that messages can be received in a subsequent session of the application.

using (var stream = File.OpenWrite("user private endpoint file")) {
    await this.Channel.Endpoint.SaveAsync(stream);
}

Publishing an endpoint so others may send messages to it

The OwnEndpoint.PublicEndpoint property contains the public data that a remote party needs to send messages to your endpoint. The public endpoint may be transmitted to interested remote parties by any means. One method is to publish the public endpoint data to a web server and share the URL to that data with the remote party. Publishing the endpoint and obtaining the URL can be done with a single line:

Uri shareableAddress = await this.OwnEndpointServices.PublishAddressBookEntryAsync(this.Channel.Endpoint);

A remote party can turn this URL back into a public Endpoint like this:

[Import]
public DirectEntryAddressBook AddressBook { get; set; }

Endpoint friend = await this.AddressBook.LookupAsync(shareableAddress);

Sending and receiving messages

Sending a message

A simple text message can be sent to a remote party:

var payload = new Payload(Encoding.UTF8.GetBytes("hello, world"), "text/plain");
var recipients = new[] { friend };
var expiration = DateTime.UtcNow + TimeSpan.FromMinutes(5);
await this.Channel.PostAsync(payload, recipients, expiration);

Receiving messages

Checking the cloud inbox for inbound messages to your endpoint can be done in any of a few ways.

This line will check for any incoming messages and immediately return with the set of messages that were waiting. If no messages were waiting, an empty set is returned:

var incoming = await this.Channel.ReceiveAsync();

To receive long-poll style push notification of any incoming messages, add a longPoll: true parameter. This will cause the receive operation to complete only when a message is actually received. In this way, you can use an asynchronous loop to continuously receive and process messages as soon as they arrive.

var incoming = await this.Channel.ReceiveAsync(longPoll: true);

Either way, processing the incoming messages is simple:

foreach (var payload in incoming) {
    var message = Encoding.UTF8.GetString(payload.Content);
    Console.WriteLine(message);
}

Finally, if you're building a Windows 8 app, you can employ the Windows Push Notification service and avoid using a long poll connection yourself, allowing your application to receive notifications even when it is not running, or when the computer is in a low power state:

[Import]
public WinRTChannel Channel { get; set; }

await this.Channel.RegisterPushNotificationChannelAsync(...);

Email-like communications

If the messages to exchange resemble emails, consider using Dart as the message format. This is facilitated by the PostalService and Message types:

configuration.WithAssembly(typeof(PostalService).Assembly);

[Import]
public PostalService PostalService { get; set; }

var message = new Message(ownEndpoint, recipients, "subject", "body");
await this.PostalService.PostAsync(message);
var incoming = await this.PostalService.ReceiveAsync(longPoll: true|false);

Contact the author

To contact the author using the IronPigeon protocol follow these steps:

  1. Clone this project.
  2. Open the IronPigeon.sln in Visual Studio 2013.
  3. Set the Clients\WpfChatroom project as the startup project.
  4. Press F5.
  5. Create your own endpoint and save it to disk so you can open it next time.
  6. Click the "Chat with author" button.
  7. Send me a message.

I may reply right away. But I may reply in a day or two. Check back occasionally by re-launching the sample and opening the same endpoint file you used to send me the message.

More Repositories

1

CodeGeneration.Roslyn

Assists in performing Roslyn-based code generation during a build.
C#
408
star
2

PCLCrypto

Platform crypto for portable libraries
C#
227
star
3

ImmutableObjectGraph

Code generation for immutable types
C#
160
star
4

Validation

Method input validation and runtime checks that report errors or throw exceptions when failures are detected.
C#
127
star
5

Xunit.Combinatorial

Adds combinatorial and pairwise testing capability to Xunit tests
C#
123
star
6

Xunit.SkippableFact

Adds Xunit dynamic skipping of facts and theories.
PowerShell
121
star
7

Library.Template

A template for a NuGet package with tests, stylecop, fxcop, versioning, and Azure Pipelines build ready to go.
PowerShell
114
star
8

Xunit.StaFact

Run your xunit-based tests on an STA thread with the WPF Dispatcher, a WinForms SynchronizationContext, or even a cross-platform generic UI thread emulation with a SynchronizationContext that keeps code running on a "main thread" for that test.
C#
80
star
9

MoneyMan

A financial money management library and applications that utilize it.
C#
39
star
10

SPSS.NET

A .NET library for read/writing SPSS Data (.sav) files. This wraps the functionality exposed by the spssio32.dll native library that comes with SPSS.
C#
31
star
11

StreamJsonRpc.Sample

Sample use of StreamJsonRpc that demonstrate separate client/server processes over named pipes.
C#
28
star
12

Nerdbank.MSBuildExtension

Package to make writing MSBuild extensions easier that work both with MSBuild Core and MSBuild (Full).
C#
23
star
13

PPApiForDotNet

Write PPAPI extensions for Chromium in your favorite .NET language.
C++
20
star
14

CSharpIsNull

C# null test syntax analyzers to guard against bugs in testing null against a struct.
PowerShell
14
star
15

AssemblyRefScanner

Scans a given directory tree for interesting assembly references
C#
14
star
16

Nerdbank.Algorithms

A collection of algorithms I've implemented and found generally useful
C#
13
star
17

Pfx2Snk

Converts PFX files to SNK files.
Visual Basic
12
star
18

DotNetRepoTools

A CLI tool with commands to help maintain .NET codebases
C#
11
star
19

PInvoke.exp

C#
10
star
20

Bitcoin.NET

A .NET Bitcoin library
C#
9
star
21

nerdbank.stylecop.rules

Custom rules for StyleCop
C#
9
star
22

GuidGen

A GuidGen tool similar to the one that ships with VS, but less than a decade old.
PowerShell
8
star
23

ReadOnlySourceTree

A NuGet package that makes your project build to top-level bin and obj directories.
C#
7
star
24

PlugInServer

A network server that can do whatever the live-dropin modules tell it to (HTTP, telnet, ASP.NET, PHP, etc.)
C#
6
star
25

MessagePackDualVersions

Demonstrates how an application can run multiple incompatible versions of a library at once (MessagePack).
C#
5
star
26

Node.js.redist

Builds packages that contain Node.js that can be used to redistribute across platforms
PowerShell
5
star
27

OpenIDForSharepoint

A MembershipProvider for Sharepoint that enabled OpenID logins (forked from CodePlex). BEWARE: Read the README.txt file.
C#
5
star
28

csharplibrarystarterkit

A starting point for C# library development, including logging, tests and build system
JavaScript
4
star
29

YouTubeDownloader

A CLI tool for downloading YouTube videos.
C#
4
star
30

win-buildagent

Docker image build for a windows build agent
Dockerfile
4
star
31

pr-autocomplete-app

A GitHub App that adds auto-complete functionality to pull requests similar to that found in Azure Repos.
TypeScript
4
star
32

dotnetxri

A C# port of the OpenXri4j library
C#
4
star
33

JavascriptCssPackerTargets

An MSBuild-based .targets file and task assembly for minifying js and css embedded resources
C#
4
star
34

cloudbuild-task

Contracts and adapter NPM packages for various cloud build services
TypeScript
4
star
35

PCLCommandBase

A common base class for ICommand implementations, and a BindableBase class for your viewmodels
PowerShell
3
star
36

Nerdbank.Qif

C#
3
star
37

HttpClientEcho

Enables automated tests with HTTP calls to avoid incurring the cost and instability of network traffic by recording a "live" test run and replaying it for subsequent test runs.
C#
3
star
38

dasblog

A private dasblog playground for assembling patches for the official version on CodePlex
C#
3
star
39

StreamingMsgPackSample

A sample of streaming MessagePack from a child process to a parent process
C#
3
star
40

VSIXProjectWithPackageReferences

A sample of a VSIX project that uses PackageReference instead of packages.config. The grass is greener here.
C#
2
star
41

ClueBuddy

A program to run while playing the popular game Clue to help you deduce all the possible clues possible and win
C#
2
star
42

AsyncAndThreadingDemo.Wpf

A simple WPF that shows up async/threading patterns, including JTF
C#
2
star
43

atom2blogger

A blog-to-blog conversion utility for transferring a blog published by Atom feed to Blogger.
C#
2
star
44

Clue

A Clue board game partner to help you deduce clues. Written in Ruby.
Ruby
1
star
45

IdentitySelector

FireFox plug-in for Information Cards support
C++
1
star
46

GoogleAppEngineHiPy

The Hello World app for Google App Engine in Python
Python
1
star
47

setup-dotnet-test

C#
1
star
48

StaticPGO_Example

How to collect a static (not the dynamic one) PGO and re-use it during "dotnet publish"
C#
1
star
49

googauth

Sample .NET web site that uses Google authentication
C#
1
star
50

EnlistmentInfo

A NuGet package that imports EnlistmentInfo .props and .targets from a parent directory.
1
star
51

VSPerfDemo

A repo demonstrating a VS Package that evolves from causing UI delays to a responsive extension.
C#
1
star
52

Nerdbank.Cryptocurrencies

.NET libraries for processing Zcash and other cryptocurrencies.
C#
1
star
53

MyNHibernateContrib

C#
1
star
54

Nerdbank.Algorithms.rs

Rust
1
star
55

pr-autocomplete-scratch

Just a scratch pad for testing PR auto-complete GitHub Actions
PowerShell
1
star