#!/usr/bin/ksh
#
# ident "@(#)utcrca	1.4 02/04/15 SMI"
#
# Copyright 1998-2002 Sun Microsystems, Inc.  All rights reserved.
#
# CA generation and initialization script
#

#################################################################################
#
# Function definitions
#
#################################################################################

function usage {
	print `gettext utskicat 'usage: create_rootca [-v] [-e exponent] -k keypkg_owner [-l length]'`
}

function create_dir {
	if [[ ! -a $1 ]]; then
		# path does not exist
		mkdir $1
		status=$?
		if (($status != 0)); then
			print "$pgm: `gettext utskicat 'ERROR - Cannot create directory'` \"$1\""
			return $status
		fi

		# Set directory generation flag
		case $2 in
			CERTS )
				let certs_dir_created=1 ;;
			KEYPKGS )
				let keypkgs_dir_created=1 ;;
			SKI_CRED_DIR )
				let cred_dir_created=1 ;;
			ETCSKI )
				let ski_dir_created=1 ;;
			* )
				print "$pgm: `gettext utskicat 'ERROR - Unrecognized keyword in create_dir() routine'` '$keyword'"
				return 1 ;;
		esac
	else
		# path exists, check if it is a directory
		if [[ ! -d $1 ]]; then
			print "$pgm: `gettext utskicat 'ERROR - Not a directory'` \"$1\""
			return 1
		fi
	fi
	# Do we have write permission?
	if [[ ! -w $1 ]]; then
		print -n "$pgm: `gettext utskicat 'ERROR - You do not have WRITE permission: '`"
		print "\"$1\""
		return 1
	fi
}

#################################################################################

# set defaults
PATH=/bin:/usr/bin:/opt/SUNWut/http/ski/bin
export PATH
let def_validity=3650	# 10 years
let global_version=0
def_exponent=F4

# initialize option-related variables
owner=""
let validity=$def_validity
exponent=$def_exponent
verbose=""

pgm_path=$0
pgm=${pgm_path##/*/}

# Determine whether we are running an global or domestic version of SecTools
skilibvers=`/usr/bin/ls -al /opt/SUNWut/http/ski/lib/libski.so 2>/dev/null`
if [[ -z $skilibvers ]]; then
	print "$pgm: `gettext utskicat 'ERROR - Cannot determine if using global or domestic version of Sectools'`"
	exit 1
fi
skilibtype=${skilibvers##*-\> }
if [[ -z $skilibtype ]]; then
	print "$pgm: `getext 'ERROR - Cannot determine if using global or domestic version of Sectools'`"
	exit 1
fi
if [[ ! -s /opt/SUNWut/http/ski/lib/$skilibtype ]]; then
	print "$pgm: `gettext utskicat 'ERROR - Cannot determine if using global or domestic version of Sectools'`"
	exit 1
fi
ls -al /opt/SUNWut/http/ski/lib/$skilibtype 2>/dev/null | grep "global" >> /dev/null
status=$?
if (($status == 0)); then
	# global version
	let global_version=1
fi

# Set default key size
if (($global_version == 1)); then
	let keysize=512
else
	let keysize=1024
fi

# process command-line options
while getopts ":ve:k:l:" opt; do
	case $opt in
		v )
		    verbose="-v" ;;
		e )
		    exponent=$OPTARG
		    if [[ $exponent != F0 && $exponent != f0 &&
				$exponent != F4 && $exponent != f4 ]]; then
			print "$pgm: `gettext utskicat 'Public exponent must be either F0 or F4!'`"
			exit 1
		    fi ;;
		k )
		    owner=$OPTARG ;;
		l )
		    let keysize=$OPTARG
		    status=$?
		    if (($status != 0)); then
			exit $status
		    fi
		    if (($keysize <= 0)); then
			print "$pgm: `gettext utskicat 'Key length must be greater than 0!'`"
			exit 1
		    fi
		    if (($global_version == 1 && $keysize > 512)); then
			print "$pgm: `gettext utskicat 'RSA key size must not be greater than 512 bits (global version)!\n'`"
			exit 1
		    fi ;;
		\? )
		    usage
		    exit 1 ;;
	esac
done
shift $(($OPTIND - 1))

/usr/bin/id | /usr/bin/grep "uid=0" >> /dev/null
status=$?
if (($status == 0)); then
	print "$pgm `gettext utskicat 'must not be run by \'root\''`"
	exit 1
fi

# Prompt for DN
if [[ -z $owner ]]; then
	done=false
	while [[ $done = false ]]; do
		print "#"
		print "# `gettext utskicat 'Distinguished Name:'`"
		print "#\n"
		
		print "\t `gettext utskicat 'Enter Distinguished Name (e.g. \"o=SUN, c=US\")'`"
		read REPLY?"`gettext utskicat '         or q[uit]: '`"
		print "\n"

		if [[ -z $REPLY ]]; then
			print "\t `gettext utskicat 'No Distinguished Name given - try again!\n'`"
		elif [[ $REPLY = q || $REPLY = quit ||
				$REPLY = Q || $REPLY = QUIT ]]; then
			exit 0
		else
			owner=$REPLY
			done=true
		fi
	done

	# remove leading ", if given
	owner=${owner#\"}
	# remove trailing ", if given
	owner=${owner%\"}
fi

#
# Prompt for Directory pathname
#
done=false
cred_dir="/tmp/creds"
certs_dir="certs"
keypkg_dir="keypkgs"
new_cred_owners_file_name="new_cred_list"
while [[ $done = false ]]; do
	print "#"
	print "# `gettext utskicat 'Directory for Storing RootCA Credentials:'`"
	print "#\n"
	print "\t `gettext utskicat 'Enter directory pathname under which the key package and'`"
	print "\t `gettext utskicat 'certificate will be stored, or q[uit].\n'`"
	read REPLY?"`gettext utskicat '         Directory name ? '`"
	print "\n"
	if [[ -z $REPLY ]]; then
		print "\t `gettext utskicat 'No directory pathname given - try again!\n'`"
	elif [[ "$REPLY" = "q" || "$REPLY" = "quit" ||
		"$REPLY" = "Q" || "$REPLY" = "QUIT" ]]; then
		exit 0
	else
		if [[ "$REPLY" = "/etc/opt/SUNWut/http/ski" ]]; then
			print "\t `gettext utskicat 'Not allowed to store into /etc/opt/SUNWut/http/ski - try again\n'`"
		else
			cred_dir=$REPLY
			done=true
		fi
	fi
done

#
# Create the directory to store certs and keypkgs
#
create_dir $cred_dir SKI_CRED_DIR
status=$?
if (($status != 0)); then
	exit $status
fi
dot=`echo $cred_dir | awk -F/ '{print $1}'`;
if [[ $dot == "." || $dot == ".." ]]; then
	PWD=`pwd`
	cd $cred_dir
	cred_dir=`pwd`
	cd $PWD
fi

# Determine the user's UID
username=`/usr/bin/id | /usr/bin/nawk '{ pos_open=match($0, "\\\\("); pos_close=match($0, "\\\\)");
	name=substr($0, pos_open+1, pos_close-pos_open-1); print name }'`

#
#	Directories and paths for KEYPKGS and CERTS
#
certs_path="$cred_dir/$certs_dir"
certs_file="$certs_path/$username.CERT"
keypkgs_path="$cred_dir/$keypkg_dir"
keypkgs_file="$keypkgs_path/$username.KEYPKG"
new_cred_owners_file="$cred_dir/$new_cred_owners_file_name"
certreq_file="$cred_dir/certreq"

# Check if the keypks and cert directories and new_cred_owners_file/
# new_password_file files already exist.
# If they do exist, ask the user to back them up or to quit
done=false
while [[ $done = false ]]; do
	if [[ -a $new_cred_owners_file || -a $keypkgs_path || -a $certs_path ]]; then
		print `gettext utskicat 'The following files/directories already exist:\n'`
		if [[ -a $new_cred_owners_file ]]; then
			print "\t$new_cred_owners_file"
		fi
		if [[ -a $keypkgs_path ]]; then
			print "\t$keypkgs_path"
		fi
		if [[ -a $certs_path ]]; then
			print "\t$certs_path"
		fi
		print "\n"
		print `gettext utskicat 'Please archive the above files/directories.\n'`
		print `gettext utskicat 'You can either quit this program now, or archive the above'`
		print `gettext utskicat 'files/directories and then continue with this program.\n'`
		read REPLY?"`gettext utskicat 'Do you want to quit this program now? [n]: '`"
		if [[ "$REPLY" = "y" || "$REPLY" = "Y" ]]; then
			exit 0
		else
			print "\n"
			print `gettext utskicat 'Creating shell from where you can archive the\nspecified files/directories ...'`
			print `gettext utskicat 'Donot forget to type \"exit\" to exit the shell.\n'`
			export PS1=`gettext utskicat 'Archival shell--> '`
			/usr/bin/ksh
			print "\n"
			read REPLY?"`gettext utskicat 'Hit any key when done archiving: '`"
			print "\n"
		fi
	else
		done=true
	fi
done

#
# Setup the environment for generating keypkg and credentials
#
create_dir $certs_path CERTS
status=$?
if (($status != 0)); then
	exit $status
fi

create_dir $keypkgs_path KEYPKGS
status=$?
if (($status != 0)); then
	exit $status
fi

print "$username\t$owner" >> $new_cred_owners_file

# Generate CA key package
keypkg -I -u $keypkgs_file -k "$owner" -l $keysize -e $exponent $verbose
status=$?
if (($status != 0)); then
	skilogout
	exit $status
fi

# Generate certification request and certify it
certreq -u $keypkgs_file $verbose $certreq_file
status=$?
if (($status != 0)); then
	# logout from SKI keyserver and remove generated keypkg
	# print "The system administrator should run \"keypkg -D -k $username\""
	# print "to remove the incorrectly generated key package from the"
	# print "naming service\n";
	skilogout
	/bin/rm $certreq_file
	exit $status
fi
certify -t $validity $verbose -o $certs_file $certreq_file
status=$?
if (($status != 0)); then
	# logount from SKI keyserver and remove generated keypkg
	# print "The system administrator should run \"keypkg -D -k $username\""
	# print "to remove the incorrectly generated key package from the"
	# print "naming service\n";
	skilogout
	/bin/rm $certreq_file
	exit $status
fi
/usr/bin/chmod 644 $certs_file
/bin/rm $certreq_file

# Logout CA private key from SKI key server
skilogout $verbose
status=$?
if (($status != 0)); then
	# remove generated keypkg
	# do not keypkg -D
	exit $status
fi

# success
#
#	Provide EOU information
#
print "#"
done=false
while [[ $done = false ]]; do
	read REPLY?"# `gettext utskicat ' Do you want to store RootCA creds in the naming service[y/n]: '`"
	print "\n"
	if [[ -z $REPLY ]]; then
		read REPLY?"# `gettext utskicat 'Try agian [y/n]? '`"
	fi
	if [[ "$REPLY" = "y" || "$REPLY" = "yes" || "$REPLY" = "Yes" ||
	    "$REPLY" = "Y" ]]; then
		print "#"
		print "# `gettext utskicat 'Storing the RootCA creds in the naming serive'`"
		print "# `gettext utskicat 'You need to enter the root password\n'`"
		#print -n "Password: " 
		{ /sbin/su - root -c "/opt/SUNWut/http/ski/bin/skistore -d $cred_dir"; } >/dev/null 
		print "\n#"
		print "# `gettext utskicat 'The Rootca creds are stored in the naming service'`"
		done=true
	else
		if [[ "$REPLY" = "n" || "$REPLY" = "no" || "$REPLY" = "No" ||
                    "$REPLY" = "N" ]]; then
			print "#"
			print "# `gettext utskicat 'The system administrator should run: '` skistore -d $cred_dir"
			print "# `gettext utskicat 'to store the credentials in naming service\n'`"
			done=true
		fi
	fi
done

#{ skistore -d $cred_dir; }
#exit 
#print "The Rootca creds are stored in the naming service"

#print "#"
#print "# Directory for Storing RootCA's Credentials:"
#print "#\n"
#print "\tThe system administrator should run \"skistore -d $cred_dir\""
#print "\tto store the credentials in naming service\n"

#print "#"
#print "# Directory for Storing RootCA's Credentials:"
#print "#\n"
#print "\tThe system administrator should run \"skistore -d $cred_dir\""
#print "\tto store the credentials in naming service\n"
exit 0
