Friday, April 20, 2012

Automating Password Checkouts with Python

Security tools like password managers suck.  Now don't get me wrong, from a security perspective, they are a really good.  They do what is needed of them.  You can set up generic accounts in a password checkout system (such as adventnet, or powerkeeper) and then track usage of those generic accounts.  You can use these systems to manage password so that you don't have to worry about password reuse, or silly things like password ageing.

The problem with some of these tools is that they make the process so onerous.  The system that is used at my company takes at least 10 click (along with mouse movements, etc) to get a password out.  No wonder nobody likes using it.  Having done a fair bit of web programming / design myself, I am just simply baffled by how unusable some products are.

I decided today to spend some more time learning about python.  As usual, I looked for a problem that I could solve.. and this happened to make the top of the list.

I'm not going to post my full code, but rather, I'm going to go through some of the things I looked at while building this.

1)  Handel SIGINT
The first thing I wanted to take care of was if someone tried to terminate my program before it was finished.  I wanted to intercept this and handle it by clearing the terminal window.

In python this can be handled by the signal library.  You can find all you need to know at this link.

2)  Password Input
I didn't want the password to be added via the command line, but rather by input directly into the python program.  The raw_input command works well, but it echos the input back to the screen.  You probably don't want that in case the session is being logged.  It turns out that there is getpass library that can be used for these situations.  Take a look at this answer.

3)  Username to the system and username being requested should be imputed on the command line.

It turns out that argparse works perfectly for this type of situation.  You just need to set the required = True setting on a parsed argument.

4) HTTP Interaction
This password manager operations from a website with basic authentication and cookies.  Originally, I started using the base urllib and urllib2 libraries, but then found the httplib2 library.  It was just much cleaner (imho) to use this than the base libraries.

5) HTML Parsing
There is no formal integration with the password manager, so I have to resort to pulling information out of html files to figure out what is going on.  I relied heavily on the live https headers plugin with firefox to determine exactly what was being sent up to the server.  As for the HTML parsing / searching in python, I found Beautiful Soup to be beautiful indeed.  Worked perfectly and provided enough options for me to parse through the results and get the data I needed to any requests.

That about sums it up.  I'm really starting to like the python language!

Monday, April 9, 2012

Simple Roman Numeral Converter

So I was reading the daily wtf, and noticed this article. 

Since I am trying to learn python, I decided to give this little task a quick shot.

The first thing to do here is to go and read about Roman numerals.  Once you do, you will find that the only trick is that if a lower Roman numeral precedes a larger one, it actually acts as a subtract.

#!/usr/bin/env python

import sys

                                'I' : 1,
                                'V' : 5,
                                'X' : 10,
                                'L' : 50,
                                'C' : 100,
                                'D' : 500,
                                'M' : 1000

def IsRomanNumeral(romanNumeralPart):
    return romanNumeralPart in ROMAN_NUMERAL_DICTIONARY

def GetDigitValueOf(romanNumeralPart):
    return ROMAN_NUMERAL_DICTIONARY[romanNumeralPart]

args = sys.argv
if (len(args) < 2):
    print "Please pass an argument to convert."

romanNumeral = args[1]

decimalNumber = 0
counter = 0

while counter <= (len(romanNumeral) -1):
    currentNumeral = romanNumeral[counter]
    if not IsRomanNumeral(currentNumeral):
        print "Invalid roman numeral... exiting.. "
    currentDigit = GetDigitValueOf(currentNumeral)
    if (counter + 1 >= len(romanNumeral)):
        decimalNumber = decimalNumber + currentDigit
    nextDigit = GetDigitValueOf(romanNumeral[counter + 1])
    if (currentDigit < nextDigit):
        decimalNumber = decimalNumber + nextDigit - currentDigit
        counter = counter + 2
        decimalNumber = decimalNumber + currentDigit
        counter = counter + 1

print romanNumeral + "=" + str(decimalNumber)

Probably not the best python.. but I'm still learning!