Tunnelblick OpenVPN client


If you need a decent OpenVPN client on a Mac, Tunnelblick is an excellent choice. Importing the OpenVPN client configuration file (.ovpn extension) is slightly more contrived than it should be, but if you follow the steps shown by Tunnelblick you should be good to go in no time.

Advertisements

Android Studio


I have been an admirer of IntelliJ IDEA, but used mostly Eclipse and Netbeans. Google announced the early access preview of Android Studio around Google I/O, and it is evolving quickly. I have to say I am blown away by how good it is. It is based on the Community Edition of IntelliJ IDEA, an open source project.

I have found it extremely easy to migrate from Eclipse ADT to Android Studio. I’ll not repeat what is already well documented at Migrating from Eclipse. The interface designer is good and stable. Developers used to Visual Studio and Xcode have one less reason to fret Android development.

The SIM card flaw and me


Recent news reports from Forbes and other news outlets inform that security researcher Karsten Nohl has discovered a flaw in SIM cards that use the older DES encryption standard. I was wondering how the flaw affects me.

I am a prepaid customer

I have been a prepaid customer for a while. I use mobile phones as internet-enabled devices, instead of using their carrier-enabled features. The apps I use are similar to those I use on the PC, such as Skype. Using internet-enabled apps does not mean I am immune to attacks, just that potential vulnerabilities get patched more regularly. Being a prepaid customer limits my exposure to a SIM hack where the attacker is able to use my credit.

I use e-mail

I use e-mail, and you do too. You probably already know that e-mail travels over the Internet in plain text. I avoid sending sensitive data over e-mail. If you are requested to, don’t send more data than the other party needs. If you think sending more data will ensure agility, think twice. Someone can intercept your message and find the extra information useful for social engineering. What is valid for e-mail is also valid for SMS messages and phone calls. Don’t assume they are any more secure than e-mail. If you have to, spread sensitive data across e-mail, SMS, and a phone call.

Security through obscurity

In the past, standards were based on the principle of security through obscurity and intentionally weak cryptography. This reduced cost and attended to government regulations regarding use of strong cryptography. Modern standards implement security by design, based on stronger encryption, public key infrastructure, and dynamic information that makes every transaction unique. SIM cards, and even chip-based payment cards, have a greater say in barring transactions. I favor technology that implements modern standards, and is upgradable or discardable when a vulnerability is found. As luck would have it, SIM cards are discardable.

Serving static web content using WCF


This post demonstrates how static web content can be served from a WCF service using WebHttpBinding and webHttp behavior.

Service Interface

The service has just one method in its interface called StaticContent.

using System.IO;
using System.ServiceModel;

namespace WwwService
{
    [ServiceContract]
    interface IWwwService
    {
        [OperationContract]
        Stream StaticContent(string content);
    }
}

Service Implementation

The implementation of the service is shown below. The StaticContent method returns a FileStream with the content of the requested resource, and sets the content type and HTTP status code.

using System;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.IO;

namespace WwwService
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class WwwServiceImplementation : IWwwService
    {
        [WebInvoke(Method = "GET",
            BodyStyle = WebMessageBodyStyle.Bare,
            UriTemplate = "/{*content}")]
        public Stream StaticContent(string content)
        {
            OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
            string path = "www/" + (string.IsNullOrEmpty(content) ? "index.html" : content);
            string extension = Path.GetExtension(path);
            string contentType = string.Empty;

            switch (extension)
            {
                case ".htm":
                case ".html":
                    contentType = "text/html";
                    break;
                case ".jpg":
                    contentType = "image/jpeg";
                    break;
                case ".png":
                    contentType = "image/png";
                    break;
                case ".ico":
                    contentType = "image/x-icon";
                    break;
                case ".js":
                    contentType = "application/javascript";
                    break;
                case ".json":
                    contentType = "application/json";
                    break;
            }

            if (File.Exists(path) && !string.IsNullOrEmpty(contentType))
            {
                response.ContentType = contentType;
                response.StatusCode = System.Net.HttpStatusCode.OK;
                return File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            }
            else
            {
                response.StatusCode = System.Net.HttpStatusCode.NotFound;
                return null;
            }
        }
    }
}

You may want to add additional content types to the switch statement above, or implement an externally configurable mapping scheme.

Hosting the service

Here’s the App.config for the service.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBinding"/>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webHttp">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="WwwService.WwwServiceImplementation">
        <endpoint address="http://localhost:8003/wwwservice" binding="webHttpBinding" bindingConfiguration="webHttpBinding" contract="WwwService.IWwwService" behaviorConfiguration="webHttp"/>
      </service>
    </services>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>
</configuration>

Here’s a console program that hosts the service configured above.

using System;
using System.ServiceModel;

namespace WwwService
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(WwwService.WwwServiceImplementation));
            host.Open();

            Console.WriteLine("Hit Enter to quit.");
            Console.ReadLine();
        }
    }
}

Where to put static content

Create a folder called www inside the folder where the service is started, store your static content there, and name the default web page index.html. Then, when the browser requests content starting with the URL http://localhost:8003/wwwservice, it will be served static content by the StaticContent method, or returned a Not Found status code.

Customize how objects are serialized to JSON in a WCF service


This post presents an improved version of the service presented in Cleaner JSON from a WCF service with webHttp behavior. I demonstrate how to customize serialization of an object to JSON.

Custom object

I define a new Person class, annotated using the DataContract attribute. The DataMember attribute applied to each attribute of the class allows us to specify an alternative name for the attribute, whether it is required to be present, the order in which it is serialized, and so on.

using System.Runtime.Serialization;

namespace RestService
{
    [DataContract()]
    public class Person : IExtensibleDataObject
    {
        [DataMember(Name = "id", IsRequired = false)]
        public string ID { get; set; }

        [DataMember(Name = "name", IsRequired = true)]
        public string Name { get; set; }

        [DataMember(Name = "numbers", IsRequired = false)]
        public string[] PhoneNumbers { get; set; }

        public ExtensionDataObject ExtensionData { get; set; }
    }
}

Service interface

The IRestService interface is modified to add additional method signatures that consume and return Person objects.

using System.ServiceModel;

namespace RestService
{
    [ServiceContract]
    interface IRestService
    {
        [OperationContract]
        void Options();

        [OperationContract]
        string Person(Person p);

        [OperationContract]
        Person GetPerson(string id);
    }

}

Service implementation

The service method Person receives an instance of Person using HTTP POST to URI /Person. WCF handles conversion of JSON to the Person object, and vice-versa. The service method GetPerson handles requests to retrieve details of a Person with an ID.

using System.Collections.Concurrent;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Threading;

namespace RestService
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class RestServiceImplementation : IRestService
    {
        static private int nextID = 1;
        static ConcurrentDictionary<string, Person> people = new ConcurrentDictionary<string, Person>();

        #region IMyService Members

        [WebInvoke(Method = "OPTIONS",
            UriTemplate = "/*")]
        public void Options()
        {

        }

        [WebInvoke(Method = "POST",
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "/Person")]
        public string Person(Person p)
        {
            if(p.ID == null)
            {
                p.ID = nextID.ToString();
                Interlocked.Increment(ref nextID);
            }
            people[p.ID] = p;
            return p.ID;
        }

        [WebInvoke(Method = "GET",
            ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "/Person/{id}")]
        public Person GetPerson(string id)
        {
            Person p;
            p = people.TryGetValue(id, out p) ? p : null;
            return p;
        }
        #endregion
    }
}

App.config

The app.config doesn’t need to be changed. It states for instance that our service endpoint is http://localhost:8002/restservice. Note the use of custom behavior webHttpCORS, that allows the service to accessed from other domains.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBinding"/>
      </webHttpBinding>
    </bindings>
    <extensions>
      <behaviorExtensions>
        <add name="crossOriginResourceSharingBehavior" type="RestService.EnableCrossOriginResourceSharingBehavior, RestService"/>
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webHttpCORS">
          <webHttp/>
          <crossOriginResourceSharingBehavior/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="RestService.RestServiceImplementation">
        <endpoint address="http://localhost:8002/restservice" binding="webHttpBinding" bindingConfiguration="webHttpBinding" contract="RestService.IRestService" behaviorConfiguration="webHttpCORS"/>
      </service>
    </services>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>
</configuration>

Hosting the service

The service can be hosted in a console app as follows.

using System;
using System.ServiceModel;

namespace WebHttp
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(WebHttp.JsonService.MyServiceImplementation));
            host.Open();

            Console.WriteLine("Hit Enter to quit.");
            Console.ReadLine();
        }
    }
}

Testing with Fiddler

Fiddler is a powerful Web debugger written in .NET. It can be used to send HTTP requests and observe HTTP responses. The following figure shows the raw request and response when creating a new Person called John. It is important to set the Content-Type header to application/json. Try and send the JSON shown in the request pane using the Composer tab. The service responds with the identifier of the Person added or updated.

Fiddler Post Request

The following figure shows a query to read Person with id 1. Try the GET request by using the Composer tab.

Fiddler Get Request

Using jQuery to access the service

Here’s a simple web page that uses jQuery to interact with the service.

<!DOCTYPE html>
<html>
<head>
    <title>www</title>
    <script type="text/javascript"
        src="https://code.jquery.com/jquery-2.1.4.min.js">
    </script>
    <script type="text/javascript"
        src="js/jqueryHelper.js">
    </script>
</head>
<body>
    <form action="">
        <input id="name" type="text" value="" />
        <input id="add" type="button" value="Add" />
    </form>
    <p>
        List of people you've added:
        <ul id="people"></ul>
    </p>
    <img src="image/HTML5_Logo_64.png" />

    <script type="text/javascript">
        var url = 'http://localhost:8002/restservice/'; // base url

        $(document).ready(documentReady);

        function documentReady() {
            $("#add").click(addClick);
        }

        function addClick() {
            var person = new Object();
            person.name = $('#name').val();
            var json = JSON.stringify(person);
            var urlAdd = url + 'Person';
            $.ajax({
                url: urlAdd,
                method: "POST",
                dataType: "json",
                data: json,
                contentType: "application/json; charset=utf-8",
            }).done(function (data) {
                person.id = parseInt(data);
                $('<li></li>')
                    .text(person.id + ':' + person.name)
                    .appendTo('#people');
            });
        }
    </script>
</body>
</html>

Further Reading

I refer you to Stand-Alone JSON Serialization for reading further about how JSON serialization works for complex types, but I strongly suggest keeping things simple for maximum portability.

Thinking in shades of gray


There is black and there is white. That is how monochrome displays represented colors, maybe the white was sometimes green, but it was white nevertheless. Shades of gray began to appear, the grayscale display was born. It wouldn’t be long before color displays sprung up. That is how technology evolves, from the bottom, whatever is possible, up to a point it becomes like clay. You make whatever you want to out of it, just get your hands dirty and keep an open mind.

For a computer programmer, a bit is the smallest unit of information, a sequence of 8 bits is a byte. The beauty of the bit is that, any information that long is either there or not there, black or white, true or false. The moment you go beyond a bit, you need to be prepared to think in shades of gray. There cease to be absolutes, several other possibilities emerge between the two absolutes.

We know that even the physical world is not what our eyes would have us believe. It is a quantum world that appears to us as a cohesive whole. Whatever gives rise to the quantum world is yet, and probably meant to be, beyond our comprehension. As an aside, my take is that we are a simulation, and cannot step out of the simulation, just as a computer program cannot step out of the computer. We would need to step out of the simulation to observe what keeps us going. Easier thought than done. I know a very popular movie that was based on the idea.

As software and product designers we need to think in shades of gray, we need to let our absolutes be marred by a series of possibilities. It is easy to think of a simple solution to a problem, it is harder to step back and see all the solutions to a problem, and pick the best. It takes hard iterative work, because often we are led astray. We need to step back, learn, iterate.

Exposing the right level of complexity to the user, who we ourselves should be very often, is a challenge software designers face daily. The lay user interacting with the product will never know the layer upon layer of complex interactions happening below the hood. As developers we regularly embrace complexity to expose simplicity.

If I sound like I have a practice to preach, I’d like to clarify that I don’t. I just go along with whatever works, or refuses to work otherwise.

Android 4.2.2 on PandaBoard using Linaro 13.06 binaries


Those who have been reading this blog may remember that I run Linux in a VirtualBox VM, and the host OS is Windows 8. I have tried recent Linaro binaries on PandaBoard by writing the image file (pandaboard.img.bz2) to an SD Card using Win32DiskImager. It has not worked well before, I realize now, due to lack of graphics drivers.

To get the graphics drivers on to the system partition requires that I mount the SD Card and run a shell script from my Linux VM. The problem being, getting the VM to see the internal SD Card reader of my laptop. Problem solved, the SD Card reader is a USB device and can be mounted by VirtualBox, once you install a proprietary extension and enable USB 2.0 in the VM settings.

How to install

Download Linaro 13.06. The instructions to prepare the SD card are under Binary Image Installation. I had some difficulty with disabling automount using dconf, but found Ubuntu’s Mount/USB instructions helpful.

I am now a happy user of Android 4.2.2 on the PandaBoard!

How does it run?

Here’s a list of positive observations:

  1. Display performance is flawless.
  2. WiFi works. Ethernet works after switching to Ethernet configuration eth0 under Settings.
  3. Browser works well. YouTube videos play all right. I haven’t tried any HD video yet.
  4. DVI and HDMI display ports work.
  5. Audio from the stereo output jack works.

Some negative observations:

  1. Bluetooth does not work.
  2. Often, the display is put to sleep and does not wake up. Switching from DVI to HDMI, or vice-versa, often wakes it up. HDMI audio does not work.
  3. No Google Play store, for obvious reasons.
  4. External USB webcam does not work.
  5. ADB interface stops working at around the time display is put to sleep.
  6. Lots of test apps installed, so you are reminded it is a development build.