What Every Developer Has To Know About IPv6

Illustration

Today I gave a talk at the Seattle Code Camp. Wonderful atmosphere, excellent organization, and a plenty of fun. Only bad thing was that it ended too soon (single day only).

My session was mostly geared toward the beginners and it covered just the basics of IPv6 and how we can use it from C#. I can only hope I lit some IPv6 fire in the great crowd that came.

I went to many other sessions myself and, while they did vary in quality, there was not a single bad one. My day was definitely fulfilled.

Feel free to download slides and examples.

Creating the Self-signed Key for the TLS

In my last post I described how to do the client-authenticated TLS and one of magic ingredients there was a certificate with the private key in the form of .pfx files.

Server and client certificates are essentially the same but I’ll show creating of both anyhow. For this I will assume that your Windows SDK files are in the C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\ and that we are storing files in the root of the drive D:

cd "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\"

makecert -n "CN=MyServer" -r -sv D:\server.pvk D:\server.cer
 Succeeded

makecert -n "CN=MyClient" -pe -r -sv D:\client.pvk D:\client.cer
 Succeeded

pvk2pfx -pvk D:\server.pvk -spc D:\server.cer -pfx D:\server.pfx

pvk2pfx -pvk D:\client.pvk -spc D:\client.cer -pfx D:\client.pfx

DEL D:\client.cer D:\client.pvk D:\server.cer D:\server.pvk

This results in the server.pfx and client.pfx files. We can opt to import them into the Windows Certificate Store (also possible with makecert command) or to use them directly as in this example.

Client-authenticated TLS in C#

Thanks to NSA, most probably every developer is aware of the HTTPS and the underlying TLS (or older SSL). While most scenarios involve authentication of a server, authentication of a client is often overlooked.

If you wonder what you gain, just be reminded of key-based authentication in the SSH. No need to exchange username/password with every client. You just exchange a (safely stored) key and you know who is on the other side.

Distribution and a safe storage of the client certificate is a non-trivial problem but easily handable on a smaller scale. Windows certificate store is not too bad and the client authentication makes it easy to block keys that aren’t trusted any more.

Here is the example code of a simple TLS encrypted TCP client/server with a self-signed certificates. Of course, one would expect proper certificates to be used in any production environment, but these will do in a pinch.

First we need to setup a server using just a standard TCP listener with a twist:

var serverCertificate = new X509Certificate2(ServerCertificateFile);

var listener = new TcpListener(IPAddress.Any, ServerPort);
listener.Start();

while (true) {
    using (var client = listener.AcceptTcpClient())
    using (var sslStream = new SslStream(client.GetStream(), false, App_CertificateValidation)) {
        sslStream.AuthenticateAsServer(serverCertificate, true, SslProtocols.Tls12, false);

        ``//send/receive from the sslStream``
    }
}

Client is equally simple:

var clientCertificate = new X509Certificate2(ClientCertificateFile);
var clientCertificateCollection = new X509CertificateCollection(new X509Certificate[] { clientCertificate });

using (var client = new TcpClient(ServerHostName, ServerPort))
using (var sslStream = new SslStream(client.GetStream(), false, App_CertificateValidation)) {
    sslStream.AuthenticateAsClient(ServerCertificateName, clientCertificateCollection, SslProtocols.Tls12, false);

    ``//send/receive from the sslStream``
}

Only trick in validation is to allow certificate chain errors. That is needed for self-signed certificates to work:

bool App_CertificateValidation(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
    if (sslPolicyErrors == SslPolicyErrors.None) { return true; }
    if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors) { return true; } //we don't have a proper certificate tree
    return false;
}

It is really this simple to convert any TCP socket code into the encrypted TLS.

Full example is available for download.

Sharp Video Play

Making a minimal C# video player in the Linux ought to be easy. I mean, both platforms are mature and something so basic should not present a problem.

GStreamer C# bindings seemed as a perfect choice at first. All needed was to “make” it. Simple enough - just use autogen.sh followed by make and enjoy the fruits of your labor.

That was a plan until I started the dependency dance. First I had to make GtkSharp myself since my latest library versions were too low for GStreamer. Then I had to get GStreamer. Then I had to get GStreamer plugins. And then I gave up.

Between compiling, downloading, and resolving dependencies I have installed around 50 packages, manually compiled multiple libraries, and I was still on the “just one more” stage. Call me spoiled, but I find this unacceptable.

Fortunately Linux is full of choices and my next try was with the MPlayerControl. It too needed a few packets on the top of a clean Mint 17 installation but nowhere close to the dependency hell:

sudo apt-get install mono-complete monodevelop mplayer git

After that I had to get the latest MPlayerControl source:

git clone https://github.com/majorsilence/MPlayerControl MPlayerControl

And that was it. Shockingly, example within the source was working perfectly albeit it was not the smallest one they could make. I created my own sample form (with a reference to the LibMPlayerCommon) to play a single file as simply as possible:

using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using LibMPlayerCommon;

namespace TestMedia {
  public class MainForm : Form {
    private MPlayer mPlayer;

    public MainForm() {
      this.WindowState = FormWindowState.Maximized;
      this.mPlayer = new MPlayer(this.Handle.ToInt32(), MplayerBackends.GL2);

      this.Load += delegate(object sender, EventArgs e) {
      this.Text = this.fileQueue.Peek();
        this.mPlayer.Play("~/somefilename.mp4");
      };
      this.mPlayer.VideoExited += delegate(object sender, MplayerEvent e) {
        this.Close();
      };
    }
  }
}

While GStreamer more complete solution by far, I found MPlayerControl infinitely easier to use and setup.

BOM Away

I find the Visual Studio the best development tool there is and I always find myself missing it whenever I have to work in some other tool (damn you Java!). However, there is one annoying “feature” that bugged me through all .NET versions.

Whenever Visual Studio decides file needs Unicode encoding, it does so by converting it to the UTF-8 which I personally find quite a good decision. What I hate is that file also gets “spoiled” by adding BOM (byte order mark). Now my every UTF-8 file has three nonsense bytes as a prefix (0xEF,0xBB,0xBF).

Although Unicode does not recommend usage of this marking and most programs do right by omitting it, Microsoft decided to use it back in the dark ages of Visual Studio .NET (and Unicode Notepad). At that time this might have been good decision considering how bad everybody treated Unicode. But in the year 2014 it is feature that survived for no good reason (not completely dissimilar to using a Ctrl+Z as an end-of-file character).

If you perform your work in a mixed OS environment (god forbid you have some Unix/Linux laying around) it gets quite annoying dealing with those simple bytes. While partial blame for this is on encoding-challenged Linux tools, truth is that nobody really needs that BOM if we assume all input files are already UTF-8 (which is fair assumption, I believe).

Source control makes this problem visible to the extreme. On multiple occasions I would accidentally check-in a file with no change other than the pesky BOM. As I am a fan of an overkill reactions I decided to stop this issue once and for all. It was the time to build the extension for the Mercurial, my source control of choice.

In order to use this extension just copy killbom.py to a location of your choice and, in the project configuration or global configuration file, add it in the extensions section:

[extensions]
killbom = C:/path/to/killbom.py

From that moment everything you commit will have it’s BOM stripped and it will get converted to the UTF-8. Be it annoying UTF-8 with BOM, just unusual UTF-16BE, or any other Unicode encoding. Everything will get an UTF-8 face-lift.

Of course, you can check how new files are doing using hg checkbom, modify existing files by using hg killbom --all or just check on state of your repository with hg checkbom --all.

Those just wanting to know whether files are proper UTF-8 but cringe on the thought of the modifying extension are fine too. You can force extension to only report offending files or only to check for certain offences, e.g. to make it verify-only and sensitive to only big-endian encoding you would add following in the configuration:

[killbom]
action = verify
extensions = utf-8 utf-16be utf-32be

Full source for the extension is available at GitHub.

PS: There is also a Git version of this hook.