#!/usr/bin/env python # encoding: utf-8 """ htdigest.py A barebones stand-in for the apache htdigest tool. It lacks the -c switch of the original and doesn't handle comments or blank lines. Caveat sysadmin... Created by Christian Swinehart on 2011-10-30. Copyright (c) 2011 Samizdat Drafting Co. All rights reserved. """ from __future__ import with_statement import sys import os from hashlib import md5 from getpass import getpass class Passwd(object): def __init__(self, pth): super(Passwd, self).__init__() self.pth = os.path.abspath(pth) self.creds = [] if not os.path.exists(self.pth): while True: resp = raw_input('%s does not exist. Create it? (y/n) '%self.pth).lower() if resp == 'y': break if resp == 'n': sys.exit(1) else: with file(self.pth) as f: for line in f.readlines(): self.creds.append(line.strip().split(":")) def update(self, username, realm): user_matches = [c for c in self.creds if c[0]==username and c[1]==realm] if user_matches: password = getpass('Change password for "%s" to: '%username) else: password = getpass('Password for new user "%s": '%username) if password != getpass('Please repeat the password: '): print "Passwords didn't match. %s unchanged."%self.pth sys.exit(1) pw_hash = md5(':'.join([username,realm,password])).hexdigest() if user_matches: user_matches[0][2] = pw_hash else: self.creds.append([username, realm, pw_hash]) new_passwd = "\n".join(":".join(cred) for cred in self.creds) with file(self.pth,'w') as f: f.write(new_passwd) if __name__ == '__main__': if len(sys.argv) != 4: print "usage: htdigest.py passwdfile username 'realm name'" sys.exit(1) fn,user,realm = sys.argv[1:4] passwd = Passwd(fn) passwd.update(user,realm)