#!/usr/bin/env python
#
# Copyright (C) 2001,2002,2003 Jason R. Mastaler <jason@mastaler.com>
#
# This file is part of TMDA.
#
# TMDA is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.  A copy of this license should
# be included in the file COPYING.
#
# TMDA is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with TMDA; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

"""Generate a unique 160-bit hex key.

Usage: %(program)s [-d <device>] [-b] [-V] [-h]

Where:
    -d <device>
    --device <device>
       Draw random numbers from a random data source device other than /dev/urandom

    -b
    --batch
       Output only the CRYPT_KEY.

    -V
    --version
       Print TMDA version information and exit.
       
    --help
    -h
       Print this help message and exit.
"""


import binascii
import commands
import getopt
import os
import sys

try:
    import paths
except ImportError:
    # Prepend /usr/lib/python2.x/site-packages/TMDA/pythonlib
    sitedir = os.path.join(sys.prefix, 'lib', 'python'+sys.version[:3],
                           'site-packages', 'TMDA', 'pythonlib')
    sys.path.insert(0, sitedir)

from TMDA import Version


batch = None
randomdev = '/dev/urandom'

program = sys.argv[0]

def usage(code, msg=''):
    print __doc__ % globals()
    if msg:
        print msg
    sys.exit(code)

try:
    opts, args = getopt.getopt(sys.argv[1:],
                               'bd:Vh', ['batch',
                                         'device=',
                                         'version',
                                         'help'])
except getopt.error, msg:
    usage(1, msg)

for opt, arg in opts:
    if opt in ('-h', '--help'):
        usage(0)
    if opt == '-V':
        print Version.ALL
        sys.exit()
    if opt == '--version':
        print Version.TMDA
        sys.exit()
    if opt in ('-d', '--device'):
        randomdev = arg
    elif opt in ('-b', '--batch'):
        batch = 1


def keygen():
    # Use the kernel's random number generator if available.
    if os.path.exists(randomdev):
        key = open(randomdev,'rb').read(20)
    else:
        # Otherwise generate some pseudo-random data from the system
        # and use the SHA of resulting key as the key.
        import sha
        if not batch:
            # Warn user that use of a cryptographic random number
            # generator is preferred.
            warning = ("key generation on a system without a "
                       + randomdev + " device is not recommended!")
            print "WARNING:"
            print '*' * len(warning)
            print warning
            print '*' * len(warning)
            print
        unpredictable = ( "date",
                          "fstat",
                          "iostat",
                          "vmstat",
                          "finger",
                          "ps -la",
                          "netstat",
                          "uname -a",
                          "cat /etc/passwd",
                          "cat /etc/aliases",
                          "cat /proc/interrupts" )
        key_data = ''
        for i in unpredictable:
            if commands.getstatusoutput(i)[0] == 0:
                key_data = key_data + os.popen(i).read()
        key = sha.new(key_data + "key").digest()
    return binascii.hexlify(key)


def main():
    
    if not batch:
        print "Generating a unique, 160-bit private key, please wait a moment.."
        print

    key = keygen()

    if len(key) != 40:
        print "Oops, generated key is not 40-characters long, exiting!"
        sys.exit()

    print key
    
    if not batch:
        print
        print "Now paste the above key into ~/.tmda/crypt_key"
        print "and make sure to keep your key secret! (chmod 600 ~/.tmda/crypt_key)"


# This is the end my friend.
if __name__ == '__main__':
    main()
