#!/usr/bin/env python

##################################################################
#  Filename: netscreen.py
#
#  Please note this script will now run in Python version 3.x
#
# This script will generate a netscreen formatted password
#
# This program requires two command line arguments, and works in two modes:
#   Mode 1:
#    The first argument is a username
#    The second argument is a plaintext password
#   Mode 2:
#    The first argument is -f to indicate reading usernames and passwords from a file
#    The second argument is the filename to read
#
#  The input file should have one of the following formats (a "," or ":" separator):
#    <username>,<plain-text-password>
#    or
#    <username>:<plain-text-password>
#
#    (Don't put a "space" after the separator, unless it is part of the password)
#
#   Example input file:
#     admin,netscreen
#     cisco:cisco
#     robert,harris
#
# Output will be the username and hashed password in John the Ripper format
# If reading usernames and passwords from a file, the output file name will be: netscreen-JtR-output.txt
#      If the file netscreen-JtR-output.txt exists, it will be overwritten.
#
#  Version 2.04
#  Updated on September 13, 2010 by Robert B. Harris from VA and Brad Tilley
#     Updated to now run in Python v3.x (still works in Python 2.x)
#     Additional separator for the input file. It can now have the new separator ":" (or use the old one ",")
#     Now correctly handles a separator ("," or ":") in the password field when reading from a file.
#     Updated help text in script
#
#  Version 2.01
#  Updated on August 30, 2010 by Robert B. Harris from VA
#    Very minor changes, removed tab, noted it won't run in python 3.x
#
#  Version  2.0
#  Updated on August 12, 2010 by Robert B. Harris from VA
#    Updated to use the hashlib library
#    Updated to print help text if both input arguments are missing
#    Updated to optionally read from a file
#
##################################################################

import sys

def net(user, password):
  b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  middle = "Administration Tools"
  s = "%s:%s:%s" % (user, middle, password)

   # For versions of Python 2.5 and older
  if sys.version_info[0] == 2 and sys.version_info[1] < 6:
    import md5
    m = md5.new(s).digest()
  else:
    import hashlib
    m = hashlib.md5(s.encode('latin_1')).digest()

  narray = []
  for i in range(8):
     if sys.version_info[0] == 2:
           n1 = ord(m[2*i])
           n2 = ord(m[2*i+1])
           narray.append( (n1<<8 & 0xff00) | (n2 & 0xff) )

     if sys.version_info[0] == 3:
           n1 = ord(chr(m[2*i]))
           n2 = ord(chr(m[2*i+1]))
           narray.append( (n1<<8 & 0xff00) | (n2 & 0xff) )
  res = ""
  for i in narray:
    p1 = i >> 12 & 0xf
    p2 = i >> 6  & 0x3f
    p3 = i       & 0x3f
    res = res + b64[p1] + b64[p2] + b64[p3]

  for c, n in  zip("nrcstn", [0, 6, 12, 17, 23, 29]):
        res = res[:n] + c + res[n:]
  return res


if __name__ == '__main__':
  if len(sys.argv) == 3:
    if  (sys.argv[1])== "-f":  # If true, reading from a file
       in_file = (sys.argv[2])   # 2nd commandline arg is the filename to read from
       input_file = open( in_file, 'r')
       output_file = open ("netscreen-JtR-output.txt" , 'w')
       import re
       for line in input_file:
          data=line.strip('\n')
          if re.search(',',line):
             data=data.split(',',1) # line contains ,
          else:
             if re.search(':',line):
               data=data.split(':',1) # line contains :
             else:
                 print("\n\n\n", file=sys.stderr)
                 print("Error in input file.", file=sys.stderr)
                 print("The input file must have either a \",\" or \":\" separator on each line.", file=sys.stderr)
                 print("Also it should not contain any blank lines. Please correct the input file.", file=sys.stderr)
                 break
          username = data[0]
          password = data[1]
          ciphertext = net(username,password)
          output_file.write ("%s:%s$%s" % (username,username,ciphertext))
          output_file.write ("\n")
       input_file.close()
       print("\nThe output file has been created.", file=sys.stderr)
       output_file.close()
    else:   # We are not reading from a file
      username = sys.argv[1]
      password = sys.argv[2]
      ciphertext = net(username,password)
      print(("%s:%s$%s" % (username,username,ciphertext)))
  else:   # User did not input the required two commandline arguments
    print("\n\n", file=sys.stderr)
    print("This program requires two commandline arguments:", file=sys.stderr)
    print("The first argument is a username, or -f to indicate reading from a file.", file=sys.stderr)
    print("The second argument is a plaintext password, or the name of the file to read from.", file=sys.stderr)
    print("See the additional text at the beginning of this script for more details.\n", file=sys.stderr)
    print("Output will be the username and the (Netscreen algorithm based) hashed password, in John the Ripper format. \n\n", file=sys.stderr)
    print("Example", file=sys.stderr)
    print("Input: netscreen.py admin netscreen", file=sys.stderr)
    print("Output: admin:admin$nKv3LvrdAVtOcE5EcsGIpYBtniNbUn", file=sys.stderr)
    print("(Netscreen uses the username as the salt, file=sys.stderr)")
