| #!/usr/bin/env python |
| # -*- coding: utf-8 -*- |
| # |
| # Copyright (C)2006-2009 Edgewall Software |
| # Copyright (C) 2006 Matthew Good <matt@matt-good.net> |
| # 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 <matt@matt-good.net> |
| |
| import errno |
| import fileinput |
| from getpass import getpass |
| from hashlib import md5 |
| from optparse import OptionParser |
| import sys |
| |
| |
| 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 |