Wednesday, April 17, 2013

Automated guest Wifi password (Linksys Smart Wifi)

Here's my requirement: I want to automatically change the password on my guest wireless network, so that if I hand it out to guests, they can't pass it on to others or use it indefinitely.  That's all :)

I have 3 Wifi routers around the house.  Obviously I don't want to log in to all three each day and change the passwords.  With the risk of making mistakes.  So I want my linux server to take care of this feat.

I had implemented this once already with these three devices, but I recently upgraded their firmware and the mechanism broke completely.  The Wifi routers are Linksys 4200's which I upgraded to firmware 2.1.39.something.  This is called Linksys Smart Wifi firmware.  To make things even worse, I have them configured in bridge mode, so most functionality is not available.  There isn't even a UI to change guest network parameters manually even if I wanted to!
I knew guest network is still available because the SSID is broadcast, and I can see it on my laptop.

So I logged on to the router, and used the magic touch: F12 key opens developer tools in Google Chrome (I think it does now in IE as well).

I noticed several HTTP POST messages to the device like this:

Request URL: http://192.168.2.13/JNAP/
Request Method: POST

Headers:

Accept:*/* Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 
Accept-Encoding:gzip,deflate,sdch 
Accept-Language:en-US,en;q=0.8,nl;q=0.6 
Authorization:Basic YWRtayouwishTAwN3M= 
Connection:keep-alive 
Content-Length:1312
Content-Type:application/json; charset=UTF-8 
Host:192.168.2.13 
Origin:http://192.168.2.13 
Referer:http://192.168.2.13/ User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31 
X-JNAP-Action:http://cisco.com/jnap/core/Transaction 
X-JNAP-Authorization:Basic YWRtayouwishTAwN3M=
X-Requested-With:XMLHttpRequest 

  Payload:

[{"action":"http://cisco.com/jnap/wirelessap/GetRadioInfo","request":{}},{"action":"http://cisco.com/jnap/locale/GetTimeSettings","request":{}},{"action":"http://cisco.com/jnap/routerleds/GetRouterLEDSettings","request":{}},{"action":"http://cisco.com/jnap/firmwareupdate/GetFirmwareUpdateSettings","request":{}},{"action":"http://cisco.com/jnap/core/GetAdminPasswordRestrictions","request":{}},{"action":"http://cisco.com/jnap/core/GetDeviceInfo","request":{}},{"action":"http://cisco.com/jnap/guestnetwork/GetGuestNetworkSettings","request":{}},{"action":"http://cisco.com/jnap/router/GetWANSettings","request":{}},{"action":"http://cisco.com/jnap/router/GetMACAddressCloneSettings","request":{}},{"action":"http://cisco.com/jnap/router/GetIPv6Settings","request":{}},{"action":"http://cisco.com/jnap/router/GetLANSettings","request":{}},{"action":"http://cisco.com/jnap/networkconnections/GetNetworkConnections","request":{}},{"action":"http://cisco.com/jnap/router/GetDHCPClientLeases","request":{}},{"action":"http://cisco.com/jnap/router/GetRoutingSettings","request":{}},{"action":"http://cisco.com/jnap/routermanagement/GetManagementSettings","request":{}},{"action":"http://cisco.com/jnap/routerupnp/GetUPnPSettings","request":{}},{"action":"http://cisco.com/jnap/firewall/GetALGSettings","request":{}}]

Interesting no? I left out the response, but there was a truck load of useful information.  The response was organized per action.  So for each 'action' in the payload, a response section is returned in JSON.
The routers apparently use some kind of REST-like protocol called JNAP.  Never heard of it.  But there's on of interest:

{"action":"http://cisco.com/jnap/guestnetwork/GetGuestNetworkSettings","request":{}}

So I used curl on a linux box to send this separate request:

USER="admin:router_password"
POST_DATA="[{\"action\":\"http://cisco.com/jnap/guestnetwork/GetGuestNetworkSettings\",\"request\":{}}]"
curl -H "X-JNAP-Action:http://cisco.com/jnap/core/Transaction" -H "X-JNAP-Authorization:Basic YWRtayouwishTAwN3M=" -d $POST_DATA -u $USER http://192.168.2.13/JNAP/

And this returns:

{
  "result": "OK",
  "responses": [
  {
  "result": "OK",
  "output": {
    "isGuestNetworkEnabled": true,
    "broadcastGuestSSID": true,
    "guestSSID": "ducnet-guest",
    "guestPassword": "guestpwd",
    "maxSimultaneousGuests": 5,
    "canEnableGuestNetwork": true,
    "guestPasswordRestrictions": {
      "minLength": 4,
      "maxLength": 32,
      "allowedCharacters": [
        {
        "lowCodepoint": 48,
        "highCodepoint": 57
        },
        {
        "lowCodepoint": 65,
        "highCodepoint": 90
        },
        {
        "lowCodepoint": 97,
        "highCodepoint": 122
        }
        ]
      },
    "maxSimultaneousGuestsLimit": 50
    }
  }
  ]
}


So with some trial and error, I figured out that I can send following payload as a POST request to the router and the password would be set:

[{"action":"http://cisco.com/jnap/guestnetwork/SetGuestNetworkSettings","request":{"isGuestNetworkEnabled":true,"broadcastGuestSSID":true,"guestSSID":"ducnet-guest","guestPassword":"otherpwd","maxSimultaneousGuests":5}}]
Pay attention to these things when sending the request:

  • Remove spaces from the JSON in the payload.  The response appears as if it worked, but it doesn't.
  • Set the 2 JNAP headers (X-JNAP-Action and X-JNAP-Authorization)
  • Provide the username and password for the HTTP authentication (-u param with curl)

The response looks like this:

{
  "result": "OK",
  "responses": [{
    "result": "OK"
  }]
}

And that's it.  Poor all this in some additional scripts and add cron to launch it whenever you like (e.g. use current month and year as password).  Works for me!

Thursday, January 31, 2013

Cloud application requirements and faster horses


Wanted to share my experiences gathering requirements for private cloud apps in an enterprise environment… no rocket science, just some thoughts.

What triggered this post is a quote from Henry Ford.  Ford was known to have at the forefront of the automotive industry and built first version of his vehicle without much customer input.  When asked about this strategy he responded: "If I had asked people what they wanted, they would have said faster horses".  This illustrates a challenge I encountered when defining cloud application requirements for enterprises:  how do you ensure that clients providing input for requirements do this in such a way that it stimulates innovation rather than bend innovation back into what is known.

Typically, you go through an iterative process with clients to find out about their needs.  You create a solution or part of it and validate progress with your clients.  This assumes that your clients know exactly what they want and for cloud environments that they understand the promise, benefits and capabilities of a cloud environment.

Today, most people take cloud, IaaS and PaaS for granted.  It's in every presentation I attend these days (yes, also in mine!).  In addition, everyone can go to Amazon and request a virtual machine without much difficulties.
However, to be able to provide requirements that define an end-to-end cloud platform in an enterprise  environment requires a very detailed and thorough understanding of cloud concepts.  In fact, your stakeholders rely on you to acquire that expertise and use it to create systems that are easy to use.  They want you to hide the complexity… just like their experience with Amazon and the likes.
As with most innovations and revolutionary steps in technology, your users only understand the possibilities once they've seen a glimpse of what is possible.

As such, gathering requirements for enterprise cloud environments requires some homework to be done before getting clients input.  In general, avoid asking open ended questions like: how do you think your applications will look like in 5 years.  This requires your stakeholders to have figured out an entire cloud application strategy and from there formulate requirements. This is not something all of your client have a readily available answer for.  Again, they rely on you to create such strategy.
Instead, provide specific proposals for components of the cloud platform and get feedback on those.  This gives your clients a reference for their feedback.  This allows them to fairly quickly relate to the use cases they have and decide whether the proposed solutions can work.
By extension, in some environments it might even be useful to create a proof of concept that you use to demonstrate business capabilities and highlight specific advancements.  Of course, this assumes that you have access to up-front budget to invest in such proof of concept.

Disclaimer:  the context here is private cloud solutions for large enterprises, so your mileage may vary.  In other environments other guidance might apply.