#!/usr/bin/env python

# This script extracts hashes from AIX /etc/security/passwd
# cat /etc/security/passwd
# root:
#         password = mrXXXXXXXXXX
#         lastupdate = 1343960660
#         flags =
#
# admin:
#         password = oiXXXXXXXXXX
#         lastupdate = 1339748349
#         flags =
# ...

# Note: Some of this functionality is also covered by the unshadow program.


import argparse
import sys
import re


def process_file(filename, is_standard):
    try:
        fd = open(filename, "r")
    except IOError:
        e = sys.exc_info()[1]
        sys.stderr.write("%s\n" % str(e))
        return

    username = "?"

    for line in fd.readlines():
        if re.match(r'^\s*\S+\s*:\s*$',line):
            username = line.split(':')[0]

        if "password = " in line and "smd5" in line:
            h = line.split("=")[1].strip()
            if len(h) != 37:
                continue
            if is_standard:
                sys.stdout.write("%s:$1$%s\n" % (username, h[6:]))
            else:
                sys.stdout.write("%s:%s\n" % (username,
                    h))

        elif "password = " in line and "ssha" in line:
            h = line.split("=")[1].strip()

            tc, salt, h = h.split('$')

            sys.stdout.write("%s:%s$%s$%s\n" % (username,
                    tc, salt, h))

        elif "password = " in line:  # DES
            h = line.split("=")[1].strip()
            if h != "*":
                sys.stdout.write("%s:%s\n" % (username, h))


if __name__ == "__main__":

    parser = argparse.ArgumentParser()
    parser.add_argument('-s', action="store_true",
        default=False,
        dest="is_standard",
        help='Use this option if "lpa_options = std_hash=true" is activated'
    )

    parser.add_argument("filename",
        help='The AIX shadow file to read (usually /etc/security/passwd)'
    )

    args = parser.parse_args()

    process_file(args.filename, args.is_standard)
