Files
mastering-unix-ss/chapter12/mk_passwd.ksh
Fabio Scotto di Santolo 4cc88d2f6e initial commit
2020-07-28 19:28:25 +02:00

464 lines
12 KiB
Bash
Executable File

#!/bin/ksh
#
# AUTHOR: Randy Micahel
# SCRIPT: mk_passwd.ksh
# DATE: 11/12/2007
# REV: 2.5.P
#
# PLATFORM: Not Platform Dependent
#
# PURPOSE: This script is used to create pseudo-random passwords.
# An extrernal keyboard data file is utilized, which is
# defined by the KEYBOARD_FILE variable. This keyboard
# file is expected to have one character on each line.
# These characters are loaded into an array, and using
# pseudo-random numbers generated, the characters are
# "randomly" put together to form a string of characters.
# By default, this script produces 8 character passwords,
# but this length can be changed on the command line by
# adding an integer value after the script name. There are
# two command line options, -n, which creates the default
# KEYBOARD_FILE, and -m, which prints the manager's
# password report. This password report is intended
# to be lock in a safe for safe keeping.
#
# EXIT CODES:
# 0 - Normal script execution
# 1 - Usage error
# 2 - Trap exit
# 3 - Missing Keyboard data file
# 4 - $DEFAULT_PRINTER is NULL
# 5 - /dev/urandom file does not exist
#
# REV LIST:
# 6/26/2007: Added two command line options, -n, which
# creates a new $KEYBOARD_FILE, and -m, which prints
# the managers password report.
#
# 8/8/2007: Changed the random number method from the
# shell RANDOM variable to now use the /dev/urandom
# character special file in concert with dd and od.
#
# set -x # Uncomment to debug
# set -n # Uncomment to check syntax without any command execution
#
####################################################
########### DEFINE SOME VARIABLES HERE #############
####################################################
LENGTH=8 # Default Password Length
# Notification List for Printing the Manager's
# Password Report for Locking Away Passwords
# Just in Case You are Unavaliable.
NOTIFICATION_LIST="Donald Duck, Yogi Bear, and Mr. Ranger"
# Define the Default Printer for Printing the Manager's
# Password Report. The user has a chance to change this
# printer at execution time.
DEFAULT_PRINTER="hp4@yogi"
SCRIPT=$(basename $0)
OUTFILE="/tmp/tmppdw.file"
KEYBOARD_FILE=/scripts/keyboard.keys
PRINT_PASSWORD_MANAGER_REPORT="TO_BE_SET"
# This next test ensures we use the correct
# echo command based on the executing shell
ECHO="echo -e"
[[ $(basename $SHELL) = ksh ]] && ECHO=echo
####################################################
########## DEFINE FUNCTIONS HERE ###################
####################################################
#
function in_range_random_number
{
# Create a pseudo-random number less than or equal
# to the $UPPER_LIMIT value, which is defined in the
# main body of the shell script.
RN=$(dd if=/dev/urandom count=1 2>/dev/null \
| od -t u2 | awk '{print $2}'| head -n 1)
RANDOM_NUMBER=$(( RN % UPPER_LIMIT + 1))
echo "$RANDOM_NUMBER"
}
#
####################################################
#
function load_default_keyboard
{
# If a keyboard data file does not exist then the user
# prompted to load the standard keyboard data into the
# $KEYBOARD_FILE, which is defined in the main body of
# the shell script.
clear # Clear the screen
$ECHO "\nLoad the default keyboard data file? (Y/N): \c"
read REPLY
case $REPLY in
y|Y) :
;;
*) $ECHO "\nSkipping the load of the default keyboard file...\n"
return
;;
esac
cat /dev/null > $KEYBOARD_FILE
$ECHO "\nLoading the Standard Keyboard File...\c"
# Loop through each character in the following list and
# append each character to the $KEYBOARD_FILE file. This
# produces a file with one character on each line.
for CHAR in \` 1 2 3 4 5 6 7 8 9 0 - = \\ q w e r t y u i o \
p \[ \] a s d f g h j k l \; \' z x c v b n m \, \
\. \/ \\ \~ \! \@ \# \$ \% \^ \& \* \( \) _ \+ \| \
Q W E R T Y U I O P \{ \} A S D F G H J K L \: \" \
Z X C V B N M \< \> \? \| \. 0 1 2 3 4 5 6 7 8 9 \/ \
\* \- \+
do
$ECHO "$CHAR" >> $KEYBOARD_FILE
done
$ECHO "\n\n\t...Done...\n"
sleep 1
}
#
####################################################
#
function check_for_and_create_keyboard_file
{
# If the $KEYBOARD_FILE does not exist then
# ask the user to load the "standard" keyboard
# layout, which is done with the load_default_keyboard
# function.
if [ ! -s $KEYBOARD_FILE ]
then
$ECHO "\n\nERROR: Missing Keyboard File"
$ECHO "\n\nWould You Like to Load the"
$ECHO "Default Keyboard Layout?"
$ECHO "\n\t(Y/N): \c"
typeset -u REPLY=FALSE
read REPLY
if [ $REPLY != Y ]
then
$ECHO "\n\nERROR: This shell script cannot operate"
$ECHO "without a keyboard data file located in"
$ECHO "\n==> $KEYBOARD_FILE\n"
$ECHO "\nThis file expects one character per line."
$ECHO "\n\t...EXITING...\n"
exit 3
else
load_default_keyboard
$ECHO "\nPress ENTER when you are you ready to continue: \c"
read REPLY
clear
fi
fi
}
#
####################################################
#
function build_manager_password_report
{
# Build a file to print for the secure envelope
(
$ECHO "\n RESTRICTED USE!!!"
$ECHO "\n\n\tImmediately send an e-mail to:\n"
$ECHO " $NOTIFICATION_LIST"
$ECHO "\n\tif this password is revealed!"
$ECHO "\n\tAIX root password: $PW\n"
$ECHO "\n\n"
$ECHO "\n RESTRICTED USE!!!"
$ECHO "\n\n\tImmediately send an e-mail to:\n"
$ECHO " $NOTIFICATION_LIST"
$ECHO "\n\tif this password is revealed!"
$ECHO "\n\tAIX root password: $PW\n"
$ECHO "\n\n"
$ECHO "\n RESTRICTED USE!!!"
$ECHO "\n\n\tImmediately send an e-mail to:\n"
$ECHO " $NOTIFICATION_LIST"
$ECHO "\n\tif this password is revealed!"
$ECHO "\n\tAIX root password: $PW\n"
) > $OUTFILE
}
#
####################################################
#
function usage
{
$ECHO "\nUSAGE: $SCRIPT [-m] [-n] [password_length]\n"
$ECHO " Where:
-m Creates a password printout for Security
-n Loads the default keyboard data keys file
password_length - Interger value that overrides
the default 8 character
password length.\n"
}
#
####################################################
#
function trap_exit
{
rm -f $OUTFILE >/dev/null 2>&1
}
####################################################
########## END OF FUNCTION DEFINITIONS #############
####################################################
####################################################
########## ENSURE /dev/urandom EXISTS ##############
####################################################
if ! [ -c /dev/urandom ]
then
echo "\nERROR: This version of $(uname) does not have a /dev/urandom
character special file. This script requires this file to create
pseudo random numbers."
echo "\n...EXITING...\n"
usage
exit 5
fi
####################################################
####### VALIDATE EACH COMMAND LINE ARGUMENT ########
####################################################
# Check command line arguments - $# < 3
if (($# > 3))
then
usage
exit 1
fi
####################################################
#
# Test for valid command line arguments -
# Valid auguments are "-n, -N, -m, -M, and any integer
if (($# != 0))
then
for CMD_ARG in $@
do
case $CMD_ARG in
+([-0-9]))
# The '+([-0-9]))' test notation is looking for
# an integer. Any integer is assigned to the
# length of password variable, LENGTH
LENGTH=$CMD_ARG
;;
-n) :
;;
-N) :
;;
-m) :
;;
-M) :
;;
*)
usage
exit 1
;;
esac
done
fi
####################################################
#
# Ensure that the $LENGTH variable is an integer
case $LENGTH in
+([0-9])) : # The '+([-0]))' test notation is looking for
# an integer. If an integer then the
# No-Op, specified by a colon, (Do Nothina)i
# command is executed, otherwise this script
# exits with a return code of 1, one.
;;
*) usage
exit 1
;;
esac
####################################################
#
# Use the getopts function to parse the command
# line arguments.
while getopts ":nNmM" ARGUMENT 2>/dev/null
do
case $ARGUMENT in
n|N)
# Create a new Keyboard Data file
load_default_keyboard
$ECHO "\nPress ENTER when you are you ready to continue: \c"
read REPLY
clear
;;
m|M)
# Print the Manager Password Report
PRINT_PASSWORD_MANAGER_REPORT=TRUE
;;
\?) # Show the usage message
usage
exit 1
esac
done
####################################################
################ START OF MAIN #####################
####################################################
# Set a trap
trap 'trap_exit;exit 2' 1 2 3 15
####################################################
#
# Check for a keyboard data file
check_for_and_create_keyboard_file
####################################################
############### LOAD THE ARRAY #####################
####################################################
X=0 # Initialize the array counter to zero
# Load the array called "KEYS" with keyboard elements
# located in the $KEYBOARD_FILE.
while read ARRAY_ELEMENT
do
((X = X + 1)) # Increment the counter by 1
# Load an array element in the the array
KEYS[$X]=$ARRAY_ELEMENT
done < $KEYBOARD_FILE
UPPER_LIMIT=$X # Random Number Upper Limit
####################################################
#
# Create the pseudo-random password in this section
clear # Clear the screen
PW= # Initialize the password to NULL
# Build the password using random numbers to grab array
# elements from the KEYS array.
X=0
while ((X < LENGTH))
do
# Increment the password length counter
(( X = X + 1 ))
# Build the password one char at a time in this loop
PW=${PW}${KEYS[$(in_range_random_number $UPPER_LIMIT)]}
done
# Done building the password
####################################################
#
# Display the new pseudo-random password to the screen
$ECHO "\n\n The new $LENGTH character password is:\n"
$ECHO "\n ${PW}\n"
####################################################
#
# Print the Manager's password report, if specified
# on the command with the -m command switch.
if [ $PRINT_PASSWORD_MANAGER_REPORT = TRUE ]
then
typeset -u REPLY=N
$ECHO "\nPrint Password Sheet for the Secure Envelope? (Y/N)? \c"
read REPLY
if [[ $REPLY = 'Y' ]]
then
build_manager_password_report
REPLY= # Set REPLY to NULL
$ECHO "\nPrint to the Default Printer ${DEFAULT_PRINTER} (Y/N)? \c"
read REPLY
if [[ $REPLY = 'Y' ]]
then
$ECHO "\nPrinting to $DEFAULT_PRINTER\n"
lp -c -d $DEFAULT_PRINTER $OUTFILE
else
$ECHO "\nNEW PRINT QUEUE: \c"
read DEFAULT_PRINTER
if [ -z "$DEFAULT_PRINTER" ]
then
echo "ERROR: Default printer canot be NULL...Exiting..."
exit 5
fi
$ECHO "\nPrinting to $DEFAULT_PRINTER\n"
lp -c -d $DEFAULT_PRINTER $OUTFILE
fi
else
$ECHO "\n\n\tO.K. - Printing Skipped..."
fi
fi
####################################################
#
# Remove the $OUTFILE, if it exists and has a size
# greater than zero bytes.
[ -s $OUTFILE ] && rm $OUTFILE
####################################################
#
# Clear the screen and exit
$ECHO "\n\nPress ENTER to Clear the Screen and EXIT: \c"
read X
clear
# End of mk_passwd.ksh shell script