#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright (C) 2006 Edgewall Software # Copyright (C) 2006 Matthew Good # All rights reserved. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms # are also available at http://trac.edgewall.org/wiki/TracLicense. # # This software consists of voluntary contributions made by many # individuals. For the exact contribution history, see the revision # history and logs, available at http://trac.edgewall.org/log/. # # Author: Matthew Good import errno import fileinput import sys from optparse import OptionParser from getpass import getpass # The md5 module is deprecated in Python 2.5 try: from hashlib import md5 except ImportError: from md5 import md5 def ask_pass(): pass1 = getpass('New password: ') pass2 = getpass('Re-type new password: ') if pass1 != pass2: print >>sys.stderr, "They don't match, sorry" sys.exit(1) return pass1 def get_digest(userprefix, password=None): if password == None: password = ask_pass() return make_digest(userprefix, password) def make_digest(userprefix, password): return userprefix + md5(userprefix + password).hexdigest() usage = "%prog [-c] [-b] passwordfile realm username" parser = OptionParser(usage=usage) parser.add_option('-c', action='store_true', dest='create', default=False, help='Create a new file') parser.add_option('-b', action='store_true', dest='batch', default=False, help='Batch mode, password on the commandline.') opts, args = parser.parse_args() try: if opts.batch: filename, realm, username, password = args else: filename, realm, username = args password = None except ValueError: parser.error('Wrong number of arguments') prefix = '%s:%s:' % (username, realm) if opts.create: try: f = open(filename, 'w') except EnvironmentError, e: if e.errno == errno.EACCES: print >>sys.stderr, 'Unable to update file', filename sys.exit(1) else: raise try: print >>f, get_digest(prefix, password) finally: f.close() else: try: matched = False for line in fileinput.input(filename, inplace=True): if line.startswith(prefix): if not matched: print get_digest(prefix, password) matched = True else: print line, if not matched: f = open(filename, 'a') try: print >>f, get_digest(prefix, password) finally: f.close() except EnvironmentError, e: if e.errno == errno.ENOENT: print >>sys.stderr, 'Could not open passwd file %s for reading.' \ % filename print >>sys.stderr, 'Use -c option to create a new one.' sys.exit(1) elif e.errno == errno.EACCES: print >>sys.stderr, 'Unable to update file', filename sys.exit(1) else: raise