Cogito, ergo sum

Here's hoping my musings can help you out!

Archive for April, 2009

Securing Netgear WPN824V3 Wireless G Router

Posted by mnshankar on April 26, 2009

The Netgear WPN824V3 is an excellent wireless router and has tons of features to ensure safe wireless access. It also boasts an enhanced range radio so your wireless signal can be accessed from the farthest points of your home.

The recommendations below summarize the steps that you should take to protect the security of data on your wireless network. The key idea is to use Defense in Depth so you make it harder for a potential hacker to compromise your network.

1. Disable SSID (Service Set Identifier) broadcast

By default, your router constantly broadcasts its SSID to ALL wireless devices in range. SSID’s are alphanumeric characters (max 32 chars). The first measure that you can take to improve network security is to disable this. Click on the ‘Wireless Settings’ option and uncheck the ‘Enable SSID Broadcast’ option.

image

2. Setup a wireless access list

Every wireless device has a  unique identifier called a MAC (Media Access Control) address. The idea is to restrict the router to allow connections ONLY from devices you recognize. Note that this is just one more barrier in our ‘Defense in Depth’ technique to protect the wireless network and can be broken by a hacker.

Under Wireless Settings, click on ‘Setup Access List’ (figure above) to reveal the wireless access list. Check the ‘Turn Access Control On’ option to enable the filter. Note that when you add subsequent devices to your home network, you will need to get back to this page and add the MAC addresses.

image

3. Restrict (Or turn off) DHCP

The DHCP service (Dynamic Host Configuration Protocol) running on your router is responsible for assigning valid IP addresses to devices. By default, an IP address is assigned to each device. You can restrict this to the number of devices that you know you will connect (or better yet assign static addresses to your devices and disable this service altogether)

image

Click on the ‘LAN Setup’ option and change the ‘Ending IP Address’ field. The above setting allows for a maximum of 5 devices.

4. Turn on Encryption

Without encryption, all data in your home wireless network is transmitted in clear text. Anyone with a laptop and network detection software (Ex. Kismet)  can view all data transmitted!

The WPN824V3 supports the strongest encryption system available today – WPA2. Note that ALL your wireless devices that connect to the router should have drivers capable of WPA2 encryption feature in order for this to work (Win XP users may need to download an update to make this happen)

Please be aware that earlier encryption methods -WEP (Wired Equivalent Privacy) and WPA (Wi FI Protected Access) have been cracked using simple tools.

There is an overhead associated with encryption but modern WI FI devices have dedicated hardware that handle the encryption and decryption.. The slight overhead is therefore a very minor tradeoff for the security offered.

image

The WPN824V3 has a combination setting that allows clients using either WPA-PSK [TKIP] or WPA2-PSK [AES]. This is a backwards-compatible mode to allow devices that dont support WPA2 – An excellent feature. Key in the passphrase and hit the ‘Apply’ button (You will need to enter both the SSID and the shared passphrase in your wireless devices).

In case you are using linux on your wireless devices, check out my post on WICD.. Works great for me!

5. Change the default password on your router

Last but not the least, be sure to change the router’s default password to a very secure password!

The default userid (admin) and the default password (password) is general knowledge and available in the user manual. If your router is compromised, all the above settings are useless and your network can be modified at will by the hacker.

Click on the ‘Set Password’ menu item to change the default password.

image

Posted in Computers and Internet | Tagged: , , , , | 1 Comment »

Scalable Authorization with Zend Framework

Posted by mnshankar on April 23, 2009

The Zend Framework offers a highly evolved and complex control flow model. The ZF provides three distinct ways to insert code – Front Plugins, Action Helpers and Controllers. The interplay between these is best expressed by the  diagram at http://surlandia.com/wp-content/uploads/2008/11/zf-dispatch-lifecycle-bw.jpg

Authorization to a page(controller/action) is to be checked on EVERY page request.

The main mechanism of implementing Authorization in the ZF is using Zend_ACL. If you are not careful with implementing this, you could easily end up loading the ACL object with EVERY action and controller in the application. We do NOT want to spend the time and memory loading the ACL with resources that will never be required!

A couple of months ago, I had written about how the ZF authorization could be automated using database tables. While this approach tries to alleviate some of the problems associated with dynamic ACL loading using a session variable, it is still wasteful of resources and is not advisable for large apps.

The following technique is, in my opinion, a smarter approach to handling ACL’s and authorization (Credit goes to Rob Allen, author of Zend Framework in Action). The key to using this method is to understand the correct place to implement ACL checking and rule creation.

image

Here is a simplified flowchart of what we plan to do:

image

Create a custom ACL class and load all the roles (along with inheritance information). For establishing the inheritance hierarchy, we can add the following lines to the config.ini

acl.roles.guest=null
acl.roles.member=guest
acl.roles.admin=member

the member role inherits from guest and admin role inherits from member.. Simple!

<?php
class CustomACL extends Zend_Acl
{
public function __construct()
{
$config = Zend_Registry::get(‘config’);
$roles = $config->acl->roles;
$this->addRoles($roles);
}
protected function addRoles($roles)
{
foreach ($roles as $child=>$parents)
{
if (!$this->hasRole($child))
{
if (empty($parents))
$parents=null;
else
$parents = explode(‘,’,$parents);
$this->addRole(new Zend_Acl_Role($child),$parents);
}
}
}
}
?>

Next, we code the Action Controller Plugin:

<?php
class AuthHelper extends Zend_Controller_Action_Helper_Abstract
{
protected $auth;
protected $acl;
protected $controllerName;
protected $actionName;
protected $defaultRole=’guest’;
public function __construct(Zend_View_Interface $view=null, array $options)
{
$this->auth=Zend_Auth::getInstance();
$this->acl = $options['acl'];
}
public function preDispatch()
{
$this->controllerName = $this->getActionController()->getRequest()->getControllerName();
$this->actionName = $this->getActionController()->getRequest()->getActionName();
if (!$this->acl->has($this->controllerName))
{
$this->acl->add(new Zend_Acl_Resource($this->controllerName));
}
if ($this->auth->hasIdentity())
{
$session_role = new Zend_Session_Namespace(‘role’);
$role=$session_role->role;
}
else
$role=$this->defaultRole;
//redirect to login page if not authorized!
if (!$this->acl->isAllowed($role,$this->controllerName, $this->actionName))
{
$this->getActionController()->getRequest()->setControllerName(‘auth’);
$this->getActionController()->getRequest()->setActionName(‘login’);
$this->getActionController()->getRequest()->isDispatched()=false; //this line is important!

}
}
public function allow($roles=null, $actions=null)
{
$resource = $this->controllerName;
$this->acl->allow($roles,$resource, $actions);
return $this;
}
public function deny($roles=null, $actions=null)
{
$resource = $this->controllerName;
$this->acl->deny($roles,$resource, $actions);
return $this;
}
}
?>

PLEASE NOTE the $this->getActionController()->getRequest()->isDispatched()=false directive immediately after setting the new controller and action. If this is not included, it would execute the code within the original action anyway .. although the results will be discarded from buffer and never rendered on screen (You can put in a log message to verify this!). Adding this directive will skip the code in the action function. This will make more sense after you understand the detailed dispatch control flow within the Zend Framework.

dispatch

The index.php bootstrapper is modified accordingly to load up the front controller plugin above:

$acl = new CustomACL();
$authHelper = new AuthHelper(null,array(‘acl’=>$acl));
Zend_Controller_Action_HelperBroker::addHelper($authHelper);

Here’s what my BaseController.php and AuthController.php look like:

<?php
class BaseController extends Zend_Controller_Action
{
protected $db;
protected $auth;
public function preDispatch()
{
$this->db = Zend_Db_Table::getDefaultAdapter();
$this->view->baseUrl = Zend_Controller_Front::getInstance()->getBaseUrl();
$this->auth=Zend_Auth::getInstance();
}
}
?>

<?php
class AuthController extends BaseController
{
public function init()
{
$this->_helper->AuthHelper->allow(null);
}
public function indexAction()
{
$this->_forward(‘login’);
}
public function loginAction()
{
if ($this->auth->hasIdentity())
$this->_redirect(‘index’);

$config = Zend_Registry::get(‘config’);
$errors = array ();
$request = $this->getRequest();

if ($request->isPost())
{
$redirect = $request->getPost(‘redirect’);
$username = $request->getPost(‘username’);
$password = $request->getPost(‘password’);
if (strlen($username) == 0)
$errors['username'] = ‘Username is a required
field’;
if (strlen($password) == 0)
$errors['password'] = ‘password is a required field’;
if (count($errors) == 0)
{
//data is valid.. do authenticate
$authAdapter = $this->getAuthAdapter($username, $password);
$result = $this->auth->authenticate($authAdapter);

if ($result->isValid())
{
//success.. store data in session..
//and redirect
$this->getRole($username);
$this->_redirect($redirect);

}
else
{
//ldap auth failed
$errors['auth'] = “LDAP authentication failed.. please check username and password”;
}
}
}

$this->view->errors = $errors;
$this->view->redirect = $redirect;
//throw the login page again!
}
public function logoutAction()
{
$this->auth->clearIdentity();
$this->_redirect(‘/’);
}
protected function getAuthAdapter($username, $password)
{
$config = Zend_Registry::get(‘config’);
//get the ldap adapter and return to caller.
$authAdapter = new Zend_Auth_Adapter_Ldap($config->ldap->toArray(), $username, $password);
//print_r($username.$password);
return $authAdapter;
}
protected function getRole($username)
{
$db = Zend_Db_Table::getDefaultAdapter();
$result = $db->fetchOne(“select role from users where userid=?”,$username);
$session_role = new Zend_Session_Namespace(‘role’);
$session_role->role=$result;
}
}
?>

The loginAction() attempts an LDAP authentication. If successfully authenticated, a call is made to getRole(). This function looks up the database table named ‘users’ and determines the ‘role’ to which the user belongs. This role is stored in a session variable – Note that this is accessed in the preDispatch() method of our action controller plugin.

Also note the init() function, it basically gives everyone access to the Auth controller.

The login.phtml file code follows:

<?php
$errors = $this->errors;
if (strlen($this->redirect)==0)
$redirect = str_replace(“/internal/inventory/”, “/”, $_SERVER['REQUEST_URI']);
else
$redirect = $this->redirect;
?>
<h2>Sorry! You are not authorized to use the section</h2>
<h1>Please login here</h1>

<div class=”error”> <?php if (isset($errors['auth'])) echo $errors['auth'] ?></div>
<form method=”post” action=”<?php echo $this->baseUrl?>/auth/login”>
<input type=”hidden” name=”redirect” value=”<?php echo  $redirect?>” />
<div>
<label>
Username
</label>
<input type=”text” name=”username” value=”"/>
<div class=”error”><?php if (isset($errors['username'])) echo $errors['username']?></div>
</div>
<div>
<label>
Password
</label>
<input type=”password” name=”password” value=”" />
<div class=”error”><?php if (isset($errors['password'])) echo $errors['password']?></div>
</div>
<div>
<input type=”submit” name=”login” value=”Login”/>
</div>
</form>

Note the use of the ‘Redirect’ hidden variable… That is used to redirect users to the original page after due authentication.

Thats it! Now, you just have to add init() functions on your controllers to specify ACL rules.. The rest is handled at runtime!

A more involved init() function would look like:

class InternalController extends BaseController {

function init()
{
$guestActions = array(‘index’);
$this->_helper->AuthHelper->allow(‘guest’, $guestActions);
$adminActions = array(‘add’, ‘edit’);
$this->_helper->AuthHelper->allow(‘admin’, $adminActions);
}

……

……

}

What the above code does is grant the ‘guest’ role access to /internal/index and demand the ‘admin’ role for urls ‘/internal/add’ and ‘/internal/edit’.

Thats it! Please feel free to drop your comments and questions.

Posted in Zend Framework | Tagged: , , , , | Leave a Comment »

WICD on Ubuntu (Intrepid)

Posted by mnshankar on April 19, 2009

I was having the hardest time using wireless on my laptop (running Ubuntu 8.10).
My wireless router is configured to use WEP and the Network Manager applet on Ubuntu by default manages the WEP key  using the ‘Seahorse’ keyring manager.
Everytime during startup, the keyring manager would prompt for password in order to connect to the internet. Surprisingly, even the correct admin password would not work sometimes.. Now this was a real pain.
After reading countless message boards, I found out that the way to wireless bliss on Ubuntu is to switch from Network Manager to WICD (Pronounced ‘Wicked’).
Within about 5 minutes of fiddling with Wicd (and uninstalling Network Manager), I was connected to my wireless! And no annoying prompts on boot up! It works perfectly (even after suspend/hibernate!)
WICD does not use Seahorse.. The key is instead stored in a file /etc/wicd/wireless-settings.conf (Ofcourse with permissions set at 600). It is really lightweight and has no GNOME dependencies. I strongly recommend WICD to anyone having wireless problems with NM.

Posted in Computers and Internet | Leave a Comment »

Mortgage Refinancing

Posted by mnshankar on April 9, 2009

Technorati Tags: ,

So, I did a lot of math to figure out if

refinancing my current mortgage could help me. Here are some of my parameters: I took out a mortgage for 180,800 in Aug 2007 at 6% from ProvidentFunding. As of April 2009, the balance on my account is 172,000 (quite a blood sucker.. only 8000 down after 22 months!)

Owing to the drop in interest rates during the last couple of months, PF started a ‘streamlined refinance’ system in a  bid to provide an easier way for existing customers to refinance with them (as a ‘customer retention’ mechanism). The process is simple..sign on to their secure web site, click on the ‘refinance’ link, answer a few ‘finance related’ questions. That’s it! They don’t require any paperwork, or Appraisal or Escrow fees.. very sweet! They do charge an ‘administrative fee’ of 1099.. but I’m not complaining!

Of course whether or not you should refinance is a personal choice depending on how long you intend to stay in the house, your current financial status, interest rate offered etc..

After filling in the ref application, I was offered a rate of 4.875% on a 20 year fixed mortgage with closing costs in the vicinity of $3500 – Yes.. the refinance does keep me in debt for 2 years longer longer than the original loan.. But I don’t intend on holding on to it that long.

After a lot of searching, I settled on the following two mortgage calculators based on their simplicity and clarity of results:

  1. http://www.calculators4mortgages.com/mortgage-calculator/refinance
    This web site succinctly displays the savings accrued due to refinance
  2. http://www.statefarm.com/apps/mortgage-calculators/Calc_Amort_Prepay.asp?PageId=Prepay
    This web site gives the savings in total mortgage costs due to prepayment in the mortgage

Is it Worth It?

This is the first question that comes to mind. The main point to understand with mortgage refinance is that it pays off in the long run. Because of the closing costs involved, there is never an immediate gain (they can be quite steep depending on the principal you borrow, taxes, points, origination, fees etc..). I started off my analysis by seeing what throwing 3500$ at the mortgage would achieve..  So in a span of 20 yrs, it would save me 6700K… not bad..

image

The next screenshot shows the effect of doing the refinance and bringing down the rate to 4.875:

 image  image

Ok.. A bottom line saving of 172 bucks every single month and clearly a greater savings over the span of 20 yrs after the refinance when compared to the down payment of 3500. Yay!

The Kicker!

I am quite comfortable with my current payments.. so what if I refinance, get the lower rate and continue to make my current payments? Here’s a snapshot of what that will do to the mortgage:

image

Excellent! So not only do I get to save 21K overall, I can also own my home by May 2025! We have a clear plan :-)

Why not do a 10 or 15 yr mortgage you ask? Flexibility.. If I feel cash-constrained at any time, I can pull back on my payments and not worry about defaulting on my payments.

Posted in Personal | Leave a Comment »

Twitter – I just dont get it!

Posted by mnshankar on April 4, 2009

Seriously.. what the devil is Twitter? For the life of me, I do not understand what all the fuss is about! And now, Google thinks it is a valuable service?

Just to straddle my curiosity, I went over to the website of Twitter and read some random strangers ‘Twits’.. Asinine is the first word that comes to mind! Other words – Unimportant, Spam, Vain, Narcissistic, Inarticulate.

The website infact proclaims on the ‘jobs’ link – “We believe we are changing the world”. Sure you are.. but is it for the better?

The whole concept of ‘social websites’ – blogging, myspace, Orkut etc is to provide an outlet for folks to express their individuality and creativity. Some even say blogging is cathartic.

Twitter posts on the other hand are restricted to 140 characters (micro blogging) and that pretty much makes it a collection of keywords (wait.. maybe I just understood why Google is interested in it!). It is essentially a dumbed down version of blogging. Nothing meaningful and/or thought provoking can be posted in 140 characters (a Haiku poem maybe!).

Kudos to the creators though.. they actually made this trivial concept a runaway hit!

Posted in Personal | Leave a Comment »

Remote control code for Sony KDL-40S4100

Posted by mnshankar on April 2, 2009

I had a hard time programming my new LCD TV (Sony KDL-40S4100) that comes with remote type RM-YD025. The Sony esupport website was of no use.
After trying tonnes of codes out there on the internet, I finally found one that works!
The code that works is : 1100

Posted in Personal | Tagged: , , , , | Leave a Comment »