Verifying Anti-Forgery Token for Form POST only

As many of you know, the ASP.NET MVC Anti-Forgery token helps thwart Cross Site Request Forgery attacks. Any site that uses authenticated sessions (99% of web apps) should use similar mechanisms so these attacks cannot occur.

Very often, I would write GET and POST actions in the same method. This allows fall through to that same code we used for GET request if POST validation fails, ensuring consistency.
[csharp]
public ActionResult EditPerson(Person person)
{
if (Request.HttpMethod == "POST" && ModelState.IsValid)
{
// do edit person…

return RedirectToAction("Index");
}

// do get person

return View(person);
}
[/csharp]
If I use that sort of paradigm, then the [VerifyAntiForgeryToken] attribute would block both GET and POST requests when the token is not supplied. I want the token to be only verified when I POST. Since ASP.NET MVC is extensible, the normal way to go about that would be modify the behaviour of [VerifyAntiForgeryToken] by subclassing. Unfortuantely, VerifyAntiForgeryTokenAttribute is sealed which means it can’t be inherited from. Luckily, borrowing from the same trick that Http*Base classes use to combat sealed Http* classes, we can just create a new attribute that wraps the old attribute, implementing the same members and proxying the calls back to the wrapped base class. That’s exactly what I did and it works quite well. The result is [ValidateAntiForgeryTokenOnPost] which will only verify the form anti-forgery token on a POST request:
[csharp]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class ValidateAntiForgeryTokenOnPostAttribute : FilterAttribute, IAuthorizationFilter
{
private ValidateAntiForgeryTokenAttribute _wrapped;
public ValidateAntiForgeryTokenOnPostAttribute()
{
_wrapped = new ValidateAntiForgeryTokenAttribute();
}

public string Salt { get { return _wrapped.Salt; } set { _wrapped.Salt = value; } }

public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.HttpMethod == "POST")
{
_wrapped.OnAuthorization(filterContext);
}
}
}
[/csharp]
This will teach those sealed classes!

iptsafe – iptables with dead man’s switch

When dealing with iptables remotely, you can easily set a firewall rule which would lock yourself out of machine. After that, the only way to unlock yourself is to physically go the machine and unset the firewall rules it through the terminal. If this was a VPS or dedicated server, chances are you can’t physically access the machine and have to contact the service provider to reset the firewall rules.

This is an instance where a dead man’s switch would help. The theory goes that if an operator is detected incapacitated, then an certain action will occur. In our case, the action is to undo our firewall changes. How does it know we are incapacitated? Well if we don’t report back in a certain amount of time, then we’re probably dead. A long time application of this is actually found when you try to change your monitor’s resolution, it ask you if you want to keep it. If it gets no response, it’ll revert back automatically.

Do you want to keep these settings

The iptsafe script works on the same principle. It is a wrapper around the iptables command. It takes the same command parameters as iptables, with the exception that if you only specify one parameter, then it’ll assume it is an iptables-save’d file and use it on iptables-restore. Once iptsafe is run, it’ll first use iptables-save to store a copy of the current iptables state, then apply the changes you requested. After that, it prompts you to keep the changes, and if you don’t respond within 15 seconds, it’ll revert back to the original state.

Here’s iptsafe

Sample usage:
# iptsafe -A INPUT -i eth0 -p tcp -s 192.168.0.1 -j ACCEPT
or
# iptsafe my-saved-iptables

An intuitive Dictionary Model Binder for ASP.NET MVC

The other day I was working on an ASP.NET MVC website and came across a need to post an array from the browser into the web app. The framework comes with something called a Model Binder that automagically converts submitted form data into action parameters of the controller. For example, if we have form submitted data such as
person.FirstName=John&person.LastName=smith
for a theoretical model class ‘Person’, and
[csharp]public ActionResult SavePerson(Person person)[/csharp]
as the action method signature, SavePerson will be executed with the parameter equivalent to
[csharp]new Person() { FirstName = "John", LastName = "Smith" }[/csharp]

The default model binder is pretty powerful, using reflection to dig out and assign all the fields. It also supports arrays and dictionaries, but with big limitations. The array must start at 0 and be unbroken. That is understandable for arrays, but what if you had a dictionary? Surely it can start at any position? Not so. The dictionary has even more obscure requirements, with the need to specify explicit .Key and .Value parameters in your form submission. For example:
dict[0].Key=mykey&dict[0].Value=myvalue
This represented extra work to generate the form on the client side. I just want to input something more intuitive like:
dict[mykey]=myvalue
The ASP.NET MVC framework is highly extensible. It allows you to define your own custom model binder so that’s exactly what I did. Inheriting off DefaultModelBinder, I created DefaultDictionaryBinder that overrode the BindModel method and intercepts when a IDictionary<,> class is being bound.

The code is now up at github: DefaultDictionaryBinder.cs. Note that if you are using this on ASP.NET MVC 1, please define the macro ASPNETMVC1. If you are using it with MVC 2 or MVC 3, it should work as is.

To use, you have to override the default model binder. In global.asax.cs in Application_Start(), add the line:
[csharp]
ModelBinders.Binders.DefaultBinder = new DefaultDictionaryBinder();
[/csharp]

The code is very flexible, only requiring the dictionary key to be of a basic type convertible from string, ie. Dictionary or Dictionary. The value can be any object that is able to be bound by the default model binder.
An example follows:
If your form input is
persons[3].FirstName=John&persons[3].LastName=Smith&persons[4].FirstName=Jane&persons[4].LastName=Doe&
and our action signature
[csharp]public ActionResult SavePersons(Dictionary<int, Person> persons)[/csharp]
the persons parameter would be
[csharp]
new Dictionary<int, Person>() {
{ 3, new Person() {"John", "Smith"} },
{ 4, new Person() {"Jane", "Doe"} },
}
[/csharp]

Simple and intuitive.

Download: DefaultDictionaryBinder.cs Simple Example Project (ASP.NET MVC 3 required)

Thinking about Geolocation APIs for Windows Mobile

Since owning a WinMo phone (or windows phone?), I’ve been thinking of developing some real applications on it. Currently, Geolocation is all the rage, allowing a application to respond different depending on your current location. This is done automatically via different mechanisms such as the most obvious and accurate one, GPS, and less reliable ones such as Cell Tower ID and nearby WIFI hotspot mac addresses.

So I set about searching for a Geo-Location API for windows mobile. Unfortunately, compared to Android and iPhone, the WinMo API is severely lacking in this regard. There seems to be some support in the next version of the .NET Compact Framework (4), but nothing in the current released APIs.

So I set about looking at third party APIs, most notably Google Gears. Google Gears is a framework that plugs into browsers, giving web pages expanded functionality such as offline storage. It also provides what appears to be, a comprehensive Location API, supporting gps, cell ID, and wifi for positioning and returning the Longitude/Latitude and street address. There are 2 gear plugins available for Windows Mobile, one for IE Mobile and one for Opera Mobile. The gears framework API seems to be available only to web browsers, thus web page developers, but not normal application developers.

So I set about seeing if I can access the google location web service directly. Helpfully, google posts the web service API specifications to build your own location API service provider. Unfortunately, it doesn’t tell you where the google service end point is. According to this page, google only allows interaction with the location service via Gears API. So it seems that even if you sniffed out the end point URL, you’ll be in violation of the google TOS to use the service.

But all is not lost – a workaround to all this, is to somehow embed Google Gears in your own application. Since google gears is open source software, BSD licensed, you can freely embed and distribute it along with your application. Searching the web, there seems to be very little information regarding embedding. Looking at the source, there are code relating to integrating with specific browsers. Ideally, we should link with a distributed google gears runtime by emulating an already defined browser interface. The NPAPI interface seems to be the most hopeful. I suspect Gears for Opera Mobile uses the NPAPI interface.

My aim is to provide a Windows Mobile .NET CF interface to the location api of google gears. If I am successful in that endeavour, there will a part two of this post. If not, I hope this post helps someone out there.

Quick tip: Why is my service binding to ipv6 localhost instead of ipv4?

So you just got a brand new VPS and installed a service, say PostgreSQL onto it. You then run your web application and found it complaining that it can’t connect to 127.0.0.1 on port 5432. Since you’re a seasoned administrator, you verify it by doing netstat -an. To your surprise, you find postgresql is binding to ::1:5432, the ipv6 localhost address. You curse the VPS provider for enabling and giving you an ipv6 network interface. You don’t even need ipv6 until 2050! But all is not lost. The reason why postgresql is binding to ::1:5432 is because it binds to localhost, which points to both ::1 (ipv6) and 127.0.0.1 (ipv4). The solution is simple. Open up /etc/hosts and find a line that says
[code]::1 localhost[/code]
and comment it out. Restart postgresql or any other service and enjoy dotted-quad goodness again.

Which words have the letter P in it and what’s the percentage?

Another code snippet from the useless dept, this time for PHP. If you’ve ever written a post and wondered how many words use the letter P (or any character), here’s something for you in PHP:
[php]
function find_words_with_letters($letter, $str) {

$a = preg_split("#[ \n\r]+#", $str);

$letterupper = strtoupper($letter);
$letterlower = strtolower($letter);

$result = array();
$result[‘word_count’] = count($a);
$result[‘words_with_letter’] = array();

foreach($a as $i) {
if (strpos($i, $letterlower) !== false || strpos($i, $letterupper) !== false) {
$result[‘words_with_letter’][] = $i;
}
}
$result[‘words_with_letter_ratio’] = count($result[‘words_with_letter’]) / count($a);

return $result;
}

// use it
print_r(find_words_with_letters(‘p’, ‘This message has one P’));

[/php]

By the way, 17.3% of this post have P’s in it!

Javascript snippet to convert raw UTF8 to unicode

For the I-don’t-a-sane-use-for-this department comes this piece of code which takes a stream of raw UTF-8 bytes, decodes it and fromCharCode it, rendering it in a unicode supported browser. A possible use would be if the web page character set is not UTF-8 and you want to display UTF-8. To use it, just put it in a script tag and call utf8decode(myrawutf8string). But seriously, all web pages should be UTF-8 by default nowadays. Here it is, in case anyone wants it:

[js]
function TryGetCharUTF8(c, intc, b, i, count)
{
/*
* 10000000 80
* 11000000 C0
* 11100000 E0
* 11110000 F0
* 11111000 F8
* 11111100 FC
*
* FEFF = 65279 = BOM
*
* string musicalbassclef = "" + (char)0xD834 + (char)0xDD1E; 119070 0x1D11E
*/

if ((b.charCodeAt(i) & 0x80) == 0)
{
intc = b.charCodeAt(i);
}
else
{
if ((b.charCodeAt(i) & 0xE0) == 0xC0)
{
//if (i+1 >= count) return false;
intc = ((b.charCodeAt(i) & 0x1F) << 6) | ((b.charCodeAt(i + 1) & 0x3F));

i += 1;
}
else if ((b.charCodeAt(i) & 0xF0) == 0xE0)
{
// 3 bytes Covers the rest of the BMP
//if (i+2 >= count) return false;
intc = ((b.charCodeAt(i) & 0xF) << 12) | ((b.charCodeAt(i + 1) & 0x3F) << 6) | ((b.charCodeAt(i + 2) & 0x3F));
alert(b.charCodeAt(i) + ‘ ‘+b.charCodeAt(i + 1) +’ ‘+b.charCodeAt(i + 2));
i += 2;
}
else if ((b.charCodeAt(i) & 0xF8) == 0xF0)
{
intc = ((b.charCodeAt(i) & 0x7) << 18) | ((b.charCodeAt(i + 1) & 0x3F) << 12) | ((b.charCodeAt(i + 2) & 0x3F) << 6) | ((b.charCodeAt(i + 3) & 0x3F));

i += 1;
}
else
return false;
}
window.utf8_out_intc = intc;
window.utf8_out_i = i;
return true;
}

function utf8decode(s) {
var ss = "";
for(utf8_out_i = 0; utf8_out_i < s.length; utf8_out_i++) {
TryGetCharUTF8(window.utf8_out_c, window.utf8_out_intc, s, window.utf8_out_i, s.length);
ss += String.fromCharCode(window.utf8_out_intc);
}
return ss;
}
[/js]

NTLM authentication in PHP – Now with NTLMv2 hash checking

A few years ago, I investigated NTLM and PHP and managed to write a simple PHP script that can retrieve the current windows username. However, it was only partly finished as it did not authenticate the user. Inspired by a recent comment, I’ve decided to revisit this problem and solve the authentication issue. For the better part of the afternoon, I wrestled with the NTLMv2 hash checking as detailed here.

It turns out that NT passwords are stored as a MD4 hash of the UTF16LE password string. So once we have this hash, we can begin verifying passwords. Obtaining this hash for a user is relatively easy with Samba, but seems to pose a challenge on Windows. In a later blog post I will detail how to integrate PHP authentication with Samba. For now, the code will assume you have already obtained a database of your users MD4 hashed passwords.

The crux of the NTLMv2 authentication involves using HMAC-MD5 on challenges and nonces using the MD4 hashed password as the key. The result is a 150 line source code that perform authentication on clients supporting NTLMv2. On the support NTLMv2, Internet Explorer supports it fine. Firefox on the other hand only has limited support for NTLMv2. In Firefox on Windows, if you have whitelisted your server with network.automatic-ntlm-auth.trusted-uris, Firefox will attempt to use Windows’ SSPI support (sys-ntlm) to perform single sign on. The SSPI module supports NTLMv2 fine. However, if you are using Firefox’s own cross platform NTLM module, you’re out of luck, it only supports the legacy NTLM and LM hashes. Perhaps it will support NTLMv2 in the future.

For Internet Explorer 8, intranet settings are now off by default, which means single sign on won’t automatically activate. To fix this, you should see a yellow bar prompting you whether to apply intranet settings.

The php ntlm authentication library is available here: PHP NTLM Github

To use it just put

[php]
include(‘ntlm.php’);

function get_ntlm_user_hash($user) {
$userdb = array(‘loune’=>’test’, ‘you’=>’gg’, ‘a’=> ‘a’);

if (!isset($userdb[strtolower($user)]))
return false;
return mhash(MHASH_MD4, ntlm_utf8_to_utf16le($userdb[strtolower($user)]));
}

session_start();
$auth = ntlm_prompt("testwebsite", "testdomain", "mycomputer", "testdomain.local", "mycomputer.local", "get_ntlm_user_hash");

if ($auth[‘authenticated’]) {
print "You are authenticated as $auth[username] from $auth[domain]/$auth[workstation]";
}
[/php]

You need to provide your own implementation of the callback function get_ntlm_user_hash($user) which should return the MD4/Unicode hashed password of the requested $user. You can get that by doing mhash(MHASH_MD4, ntlm_utf8_to_utf16le("password")). You also need session_start() as the script needs to persist challenge information across http requests.

Next time, I will blog about the best way to integrate it with Samba on Linux.

Quick Tip: The platform “Windows Mobile 6 Professional SDK (ARMV4I)” is not defined within Visual Studio.

If you are setting up Qt Visual Studio Addin in Vista and get this message when trying to add the Qt folder (in Qt Options > Qt Versions):
The platform “Windows Mobile 6 Professional SDK (ARMV4I)” is not defined within Visual Studio. Make sure you have installed the required SDK.
-or-
The platform “Windows Mobile 5.0 Pocket PC SDK (ARMV4I)” is not defined within Visual Studio. Make sure you have installed the required SDK.

You need to make sure you have Visual Studio running in Administrator mode. You also need to be in Administrator mode when creating your WinCE project.

You can also type in the command line: checksdk -list to check that you have the correct Windows CE SDK installed.

Getting the intersection points of two [path] geometries in WPF

While working on an app that utilises geometries in WPF, I needed a way to get the intersection points of the lines of two arbitrary geometries. A google search didn’t yield any useful hints except a post suggesting to use mathematics. That would be ideal for very simple geometries like lines, but with complex geometries, it becomes tiresome real quick. The framework doesn’t seem to have any built in functions that calculate that, so it’s time for some hack and slash.

After a few days of thinking, I came up with a simple, yet effective (but not the most efficient solution). For those who just want the intersection between two geometries, there is the CombinedGeometry geometry class which takes input in the form of two geometries. Setting the GeometryCombineMode to Intersect gives a geometry which is the intersection of the two. At the otherside of the WPF realm, we have Geometry.GetWidenedPathGeometry(). This method basically converts/strokes path lines to an approximate geometry. Combining these two concepts, we can produce an intersection from two widened path geometries (the two paths which we want the intersection of).

[csharp]
public static Point[] GetIntersectionPoints(Geometry g1, Geometry g2)
{
Geometry og1 = g1.GetWidenedPathGeometry(new Pen(Brushes.Black, 1.0));
Geometry og2 = g2.GetWidenedPathGeometry(new Pen(Brushes.Black, 1.0));

CombinedGeometry cg = new CombinedGeometry(GeometryCombineMode.Intersect, og1, og2);

PathGeometry pg = cg.GetFlattenedPathGeometry();
Point[] result = new Point[pg.Figures.Count];
for (int i = 0; i < pg.Figures.Count; i++)
{
Rect fig = new PathGeometry(new PathFigure[] { pg.Figures[i] }).Bounds;
result[i] = new Point(fig.Left + fig.Width / 2.0, fig.Top + fig.Height / 2.0);
}
return result;
}
[/csharp]

The function will return an array of zero or more points of intersection. To test it

[csharp]
sg1 = StreamGeometry.Parse("M0,0 L100,100");
sg2 = StreamGeometry.Parse("M0,100 L100,0");
Point[] pts = GetIntersectionPoints(sg1, sg2);
// pts[0] is {50,50}
[/csharp]

Hope this helps someone.