#!/usr/bin/ksh
#
# Copyright (c) 1997-2001, by Sun Microsystems, Inc.
# All rights reserved.
#
# $Id: makeOpenSSHPackage.ksh,v 1.12 2001/07/18 15:42:05 kaw Exp $
#
# INTRODUCTION
#
#  This script creates an OpenSSH Solaris package.  Once OpenSSH is
#  compiled use this script to create a Solaris package stream.
#
#  For further information, see the Sun BluePrints[tm] OnLine article
#  entitled "Building and Deploying OpenSSH on the Solaris Operating
#  Environment".
#
#	http://www.sun.com/blueprints/0701/openSSH.pdf
#
#  The latest version of this script is available at the BluePrints
#  OnLine tools area:
#
#	http://www.sun.com/blueprints/tools/
#
# USAGE
#
#  Execute this script in the top-level OpenSSH source directory.  (Copy
#  the script to the OpenSSH source directory if needed.)  After OpenSSH
#  has been compiled, check the script variables listed below to verify
#  the configuration for the environment in which OpenSSH is to be
#  installed.  Execute this script to build a Solaris package stream.
#
# NOTES
#
#  This script borrows heavily from the Sun Enterprise Network Security
#  Service (SENSS) makepackage script.
#
#  This script has only been tested with OpenSSH version 2.9p2.
#
#  This script also uses the openssh.server init script which is copied
#  over and some of its contents are changed based on variables set in
#  this script.
#
#
#  History:
#      <3> Sean Boran/25.Jun.02: Adapt for SSH v3.3p1
#      <2> Sean Boran/13.Mar.02: Adapt for SSH v3.1p1 and add more package fields
#          Man pages in /usr/local, add tcp wrapper man pages, add ssh-rand-helper
#          to libexec
#      Keith A. Watson <keith.watson@sun.com>
#
#####################################################

# --------------------------------------------------------------------
# User configuration variables
# --------------------------------------------------------------------

#
# Installation directory.  
#
#  This should be a local directory on the systems that will install it.
#  If /opt is specified, the package name will be appended to the
#  install directory name (ie. /opt/OBSDssh).
#
#  The default value, if no argument is supplied on the command line, is
#  /opt.  Otherwise, the argument specified will be used.
#
installDir=/opt
#installDir=/usr/local
# <2>
installManDir=/usr/local

#
# OpenSSH Solaris package name.
#
packageName=OBSDssh

#
# Install config files in the same directory as the package files. 
#  Otherwise, the /etc directory is used.  (yes/no)
#
useInstallEtc=no

#
# Include the PRNGD tool and associate files.  (yes/no)
#
#includePRNGD=yes
includePRNGD=no

#
# Setup for v3.3 Priveledge separation feature?
privSeparation=yes

#
# PRNGD package location.  (PRNGD must already be compiled.)
#
PRNGDDir=../prngd-0.9.22

#
# Solaris system init script location.
#
initScript=../openssh.server

#
# Install ssh set-user-ID (SUID).  (yes/no)
# yes  - if you'll need host-based trusts
#installSSHSUID=yes
installSSHSUID=no

# --------------------------------------------------------------------
# No further user configuration should be required past this point.
# --------------------------------------------------------------------

PATH=/usr/bin:/usr/ccs/bin

# source/current directory
srcDir=$(pwd)

# build directory
buildDir=/tmp/$packageName/build

# package build directory
packageDir=/tmp/$packageName/package

# OpenSSH files final location
if [[ $installDir == "/opt" ]]; then
    openSSHDir=$installDir/$packageName
else
    openSSHDir=$installDir
fi

# determine where to place config files
if [[ $useInstallEtc == "yes" ]]; then
    if [[ $installDir == "/opt" ]]; then
	configDir=$installDir/$packageName/etc
    else
	configDir=$installDir/etc
    fi
else
    configDir=/etc/ssh
fi

# determine which ssh permissions to use
if [[ $installSSHSUID == "yes" ]]; then
    sshMode=4711
else
    sshMode=0711
fi

# cleanup and process
print "Cleaning up any old build files..."
rm -rf $buildDir $packageDir
mkdir -p $buildDir $packageDir

# create build subdirectories
print "Creating build subdirectories..."
mkdir -p $buildDir/$openSSHDir/bin
mkdir -p $buildDir/$openSSHDir/docs/OpenSSH
mkdir -p $buildDir/$openSSHDir/libexec
# <2>
#mkdir -p $buildDir/$openSSHDir/man/cat1
#mkdir -p $buildDir/$openSSHDir/man/cat8
mkdir -p $buildDir/$installManDir/man/cat1
mkdir -p $buildDir/$installManDir/man/cat8
# <2>
mkdir -p $buildDir/$installManDir/man/man5
mkdir -p $buildDir/$installManDir/man/man8

mkdir -p $buildDir/$openSSHDir/sbin
mkdir -p $buildDir/$configDir
mkdir -p $buildDir/etc/init.d
mkdir -p $buildDir/etc/rc0.d
mkdir -p $buildDir/etc/rc1.d
mkdir -p $buildDir/etc/rc2.d
mkdir -p $buildDir/etc/rc3.d
mkdir -p $buildDir/etc/rcS.d
[[ $includePRNGD == "yes" ]] && {
    mkdir -p $buildDir/$openSSHDir/docs/PRNGD
    mkdir -p $buildDir/var/spool/prngd
}

[[ $privSeparation == "yes" ]] && {
    echo "Priviledge separation enabled, create /var/empty"
    mkdir -p        $buildDir/var/empty
    chown root:sys  $buildDir/var/empty
    chmod 755       $buildDir/var/empty
}

# copy OpenSSH executables
print "Copying OpenSSH client executables:\c"
dir=$buildDir/$openSSHDir/bin
# <3>for file in ssh scp sftp ssh-add ssh-agent ssh-keygen ssh-keyscan; do
for file in ssh scp sftp ssh-add ssh-agent ssh-keygen ssh-keyscan ssh-keysign; do
    cp $file $dir
    strip $dir/$file
    chmod 755 $dir/$file
    print " $file\c"
done
print "."

# copy OpenSSH server executable
print "Copying OpenSSH server executable: \c"
dir=$buildDir/$openSSHDir/sbin
file=sshd
cp $file $dir
strip $dir/$file
chmod 755 $dir/$file
print " $file."

# copy OpenSSH sftp server executable and other libexec stuff
print "Copying OpenSSH libexec executables: \c"
dir=$buildDir/$openSSHDir/libexec
# <2>file=sftp-server
for file in sftp-server ssh-rand-helper; do
    cp $file $dir
    strip $dir/$file
    chmod 755 $dir/$file
    print " $file\c"
done
print "."

# install only the preformatted man pages since Solaris nroff does not
#  understand the BSD formatted ones
print "Copying OpenSSH user preformatted man pages:\c"
#<2> dir=$buildDir/$openSSHDir/man/cat1
dir=$buildDir/$installManDir/man/cat1
#<3> for file in ssh.0 scp.0 sftp.0 ssh-add.0 ssh-keygen.0 ssh-agent.0 \
for file in ssh.0 scp.0 sftp.0 ssh-add.0 ssh-keygen.0 ssh-agent.0 ssh-keysign.0 \
    ssh-keyscan.0; do
    cp $file $dir
    chmod 644 $dir/$file
    print " $file\c"
done
print "."

print "Copying OpenSSH admin preformatted man pages:\c"
#<2> dir=$buildDir/$openSSHDir/man/cat8
dir=$buildDir/$installManDir/man/cat8
for file in sftp-server.0 sshd.0; do
    cp $file $dir
    chmod 644 $dir/$file
    print " $file\c"
done
print "."

# <2>
print "Copying TCPD wrapper man pages:\c"
dir=$buildDir/$installManDir/man/man8
for file in $srcDir/../tcp_wrappers_7.6/*.8; do
    cp $file $dir
    chmod 644 $dir/*
    print " $file\c"
done
dir=$buildDir/$installManDir/man/man5
for file in $srcDir/../tcp_wrappers_7.6/*.5; do
    cp $file $dir
    chmod 644 $dir/*
    print " $file\c"
done
print "."

# create symbolic links to slogin and associated man page
print "Creating symbolic links to slogin and slogin.0..."
( cd $buildDir/$openSSHDir/bin; ln -s ./ssh slogin )
#<2>( cd $buildDir/$openSSHDir/man/cat1; ln -s ./ssh.0 slogin.0 )
( cd $buildDir/$installManDir/man/cat1; ln -s ./ssh.0 slogin.0 )

# copy over auxilary config files
#  (Note: The ssh_prng_cmds file is only necessary if PRNGD is not used
#   but it is included anyways.)
print "Copying OpenSSH config files:\c"
dir=$buildDir/$configDir
#for file in primes ssh_prng_cmds; do
for file in moduli ssh_prng_cmds; do
    cp $file $dir
    chmod 644 $dir/$file
    print " $file\c"
done
cp ssh_config.out $dir/ssh_config
cp sshd_config.out $dir/sshd_config
chmod 644 $dir/ssh_config $dir/sshd_config
print " ssh_config sshd_config."

# copy over, fix permissions and ownerships, and link up the system
#  init script
print "Copying and linking the OpenSSH system init script..."
cat $initScript | \
    sed -e "s#%%configDir%%#$configDir#g" 		\
	-e "s#%%openSSHDir%%#$openSSHDir#g"	\
	-e "s#%%includePRNGD%%#$includePRNGD#g"	\
	> $buildDir/etc/init.d/openssh.server

chmod 744 $buildDir/etc/init.d/openssh.server
ln $buildDir/etc/init.d/openssh.server \
    $buildDir/etc/rc3.d/S25openssh.server
ln $buildDir/etc/init.d/openssh.server \
    $buildDir/etc/rcS.d/K30openssh.server
ln $buildDir/etc/init.d/openssh.server \
    $buildDir/etc/rc0.d/K30openssh.server
ln $buildDir/etc/init.d/openssh.server \
    $buildDir/etc/rc1.d/K30openssh.server
ln $buildDir/etc/init.d/openssh.server \
    $buildDir/etc/rc2.d/K40openssh.server

# if PRNGD is used, copy over the exectuable and config files
[[ $includePRNGD == "yes" ]] && {
    print "Copying PRNGD Solaris specific config files..."
    cp $PRNGDDir/prngd $buildDir/$openSSHDir/sbin
    cp $PRNGDDir/contrib/Solaris-2.6/prngd.conf.solaris-26 \
	$buildDir/$configDir/prngd.conf-solaris-2.6
    cp $PRNGDDir/contrib/Solaris-7/prngd.conf.solaris-7 \
	$buildDir/$configDir/prngd.conf-solaris-2.7
}

# copy over documentation files for OpenSSH and PRNGD
print "Copying OpenSSH and PRNGD documentation files:\c"
dir=$buildDir/$openSSHDir/docs/OpenSSH
for file in CREDITS README LICENCE; do
    cp $file $dir
    chmod 644 $dir/$file
    print " $file\c"
done

[[ $includePRNGD == "yes" ]] && {
    cp $PRNGDDir/00README \
	$buildDir/$openSSHDir/docs/PRNGD/README
    chmod 644 $buildDir/$openSSHDir/docs/PRNGD/README
    print " README (PRNGD)\c"
}
print "."

# create a Solaris package prototype file
print "Creating the Solaris package prototype file..."
(
    cd $buildDir
    #<3> $3 == "var/empty"	{ $4="0755"; $6="sys"; }
    #<2> add /usr
    #$3 ~  /^usr/	{            $6="sys"; }

    find . ! -name prototype | sort | pkgproto | \
	awk '
	    { $5="root"; $6="other"; }
	    $3 ~  /^etc/	{            $6="sys"; }
	    $3 ~  /^var/	{	     $6="sys"; }
	    $3 == "var/spool"	{	     $6="bin"; }
	    $3 == "var/empty"	{ $4="0755"; $6="sys"; }
	    $3 == "opt"		{ $4="0775"; $6="sys"; }
	    $3 ~  /^usr/        { $4="0755"; $6="sys"; }
	    { print; }
	    END { print "i pkginfo=info" }' > prototype.temp

    sed -e "s/bin\/ssh 0755/bin\/ssh $sshMode/" < prototype.temp \
	| grep -v prototype.temp > prototype
    rm -f prototype.temp
)

# create an info file <2>
# <3> fix getting of version
#VERSION="$(tail -1 $srcDir/version.h | sed -e 's/.*_\([0-9]\)/\1/g')
myversion=`grep SSH_VERSION $srcDir/version.h|awk -F\" '{print $2}'`

print "Creating the Solaris package pkginfo file..."
cat > $buildDir/info << __EOF__
PKG=$packageName
NAME=OpenSSH for Solaris
VENDOR=www.openssh.com
ARCH=$(uname -p)
EMAIL=sean AT boran.com www.boran.com/security/sp/ssh-part2.html
PSTAMP=Sean Boran on `date`
VERSION="$myversion"
CATEGORY=application
CLASSES=none
BASEDIR=/
__EOF__

# <3> debugging:
#cat prototype
#cat $buildDir/info

# make a package, using the prototype/info files, writing to the scratchdir
print "Creating the Solaris package directory..."
pkgmk -d $packageDir -f $buildDir/prototype -r $buildDir -o

# store it as Solaris package stream format
print "Creating the Solaris package stream."
print | pkgtrans -os $packageDir $srcDir/$packageName.pkg

# messages
print
print "Package stream file is: $srcDir/$packageName.pkg"
print "To install: pkgadd -d $packageName.pkg $packageName"

# done
exit 0
