- (dtucker) [contrib/cygwin/ssh-host-config] From Corinna: revamp of the

Cygwin-specific service installer script ssh-host-config.  The actual
   functionality is the same, the revisited version is just more
   exact when it comes to check for problems which disallow to run
   certain aspects of the script.  So, part of this script and the also
   rearranged service helper script library "csih" is to check if all
   the tools required to run the script are available on the system.
   The new script also is more thorough to inform the user why the
   script failed.  Patch from vinschen at redhat com.
This commit is contained in:
Darren Tucker 2011-02-21 21:41:29 +11:00
parent 0588beba39
commit e541aaaf0f
2 changed files with 380 additions and 179 deletions

View File

@ -1,3 +1,14 @@
20110221
- (dtucker) [contrib/cygwin/ssh-host-config] From Corinna: revamp of the
Cygwin-specific service installer script ssh-host-config. The actual
functionality is the same, the revisited version is just more
exact when it comes to check for problems which disallow to run
certain aspects of the script. So, part of this script and the also
rearranged service helper script library "csih" is to check if all
the tools required to run the script are available on the system.
The new script also is more thorough to inform the user why the
script failed. Patch from vinschen at redhat com.
20110218 20110218
- OpenBSD CVS Sync - OpenBSD CVS Sync
- djm@cvs.openbsd.org 2011/02/16 00:31:14 - djm@cvs.openbsd.org 2011/02/16 00:31:14

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# #
# ssh-host-config, Copyright 2000-2009 Red Hat Inc. # ssh-host-config, Copyright 2000-2011 Red Hat Inc.
# #
# This file is part of the Cygwin port of OpenSSH. # This file is part of the Cygwin port of OpenSSH.
# #
@ -19,12 +19,39 @@
# ====================================================================== # ======================================================================
# Initialization # Initialization
# ====================================================================== # ======================================================================
PROGNAME=$(basename $0)
_tdir=$(dirname $0)
PROGDIR=$(cd $_tdir && pwd)
CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh
# List of apps used. This is checkad for existance in csih_sanity_check
# Don't use *any* transient commands before sourcing the csih helper script,
# otherwise the sanity checks are short-circuited.
declare -a csih_required_commands=(
/usr/bin/basename coreutils
/usr/bin/cat coreutils
/usr/bin/chmod coreutils
/usr/bin/dirname coreutils
/usr/bin/id coreutils
/usr/bin/mv coreutils
/usr/bin/rm coreutils
/usr/bin/cygpath cygwin
/usr/bin/mount cygwin
/usr/bin/ps cygwin
/usr/bin/setfacl cygwin
/usr/bin/umount cygwin
/usr/bin/cmp diffutils
/usr/bin/grep grep
/usr/bin/awk gawk
/usr/bin/ssh-keygen openssh
/usr/sbin/sshd openssh
/usr/bin/sed sed
)
csih_sanity_check_server=yes
source ${CSIH_SCRIPT}
PROGNAME=$(/usr/bin/basename $0)
_tdir=$(/usr/bin/dirname $0)
PROGDIR=$(cd $_tdir && pwd)
# Subdirectory where the new package is being installed # Subdirectory where the new package is being installed
PREFIX=/usr PREFIX=/usr
@ -32,8 +59,6 @@ PREFIX=/usr
SYSCONFDIR=/etc SYSCONFDIR=/etc
LOCALSTATEDIR=/var LOCALSTATEDIR=/var
source ${CSIH_SCRIPT}
port_number=22 port_number=22
privsep_configured=no privsep_configured=no
privsep_used=yes privsep_used=yes
@ -46,29 +71,48 @@ opt_force=no
# Routine: create_host_keys # Routine: create_host_keys
# ====================================================================== # ======================================================================
create_host_keys() { create_host_keys() {
local ret=0
if [ ! -f "${SYSCONFDIR}/ssh_host_key" ] if [ ! -f "${SYSCONFDIR}/ssh_host_key" ]
then then
csih_inform "Generating ${SYSCONFDIR}/ssh_host_key" csih_inform "Generating ${SYSCONFDIR}/ssh_host_key"
ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null if ! /usr/bin/ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
then
csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!"
let ++ret
fi
fi fi
if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ] if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
then then
csih_inform "Generating ${SYSCONFDIR}/ssh_host_rsa_key" csih_inform "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null if ! /usr/bin/ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
then
csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!"
let ++ret
fi
fi fi
if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ] if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ]
then then
csih_inform "Generating ${SYSCONFDIR}/ssh_host_dsa_key" csih_inform "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null if ! /usr/bin/ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
then
csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!"
let ++ret
fi
fi fi
if [ ! -f "${SYSCONFDIR}/ssh_host_ecdsa_key" ] if [ ! -f "${SYSCONFDIR}/ssh_host_ecdsa_key" ]
then then
csih_inform "Generating ${SYSCONFDIR}/ssh_host_ecdsa_key" csih_inform "Generating ${SYSCONFDIR}/ssh_host_ecdsa_key"
ssh-keygen -t ecdsa -f ${SYSCONFDIR}/ssh_host_ecdsa_key -N '' > /dev/null if ! /usr/bin/ssh-keygen -t ecdsa -f ${SYSCONFDIR}/ssh_host_ecdsa_key -N '' > /dev/null
then
csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!"
let ++ret
fi fi
fi
return $ret
} # --- End of create_host_keys --- # } # --- End of create_host_keys --- #
# ====================================================================== # ======================================================================
@ -81,61 +125,58 @@ update_services_file() {
local _spaces local _spaces
local _serv_tmp local _serv_tmp
local _wservices local _wservices
local ret=0
if csih_is_nt
then
_win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc" _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
_services="${_my_etcdir}/services" _services="${_my_etcdir}/services"
# On NT, 27 spaces, no space after the hash
_spaces=" #" _spaces=" #"
else
_win_etcdir="${WINDIR}"
_services="${_my_etcdir}/SERVICES"
# On 9x, 18 spaces (95 is very touchy), a space after the hash
_spaces=" # "
fi
_serv_tmp="${_my_etcdir}/srv.out.$$" _serv_tmp="${_my_etcdir}/srv.out.$$"
mount -o text,posix=0,noacl -f "${_win_etcdir}" "${_my_etcdir}" /usr/bin/mount -o text,posix=0,noacl -f "${_win_etcdir}" "${_my_etcdir}"
# Depends on the above mount # Depends on the above mount
_wservices=`cygpath -w "${_services}"` _wservices=`cygpath -w "${_services}"`
# Remove sshd 22/port from services # Remove sshd 22/port from services
if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ] if [ `/usr/bin/grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
then then
grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}" /usr/bin/grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
if [ -f "${_serv_tmp}" ] if [ -f "${_serv_tmp}" ]
then then
if mv "${_serv_tmp}" "${_services}" if /usr/bin/mv "${_serv_tmp}" "${_services}"
then then
csih_inform "Removing sshd from ${_wservices}" csih_inform "Removing sshd from ${_wservices}"
else else
csih_warning "Removing sshd from ${_wservices} failed!" csih_warning "Removing sshd from ${_wservices} failed!"
let ++ret
fi fi
rm -f "${_serv_tmp}" /usr/bin/rm -f "${_serv_tmp}"
else else
csih_warning "Removing sshd from ${_wservices} failed!" csih_warning "Removing sshd from ${_wservices} failed!"
let ++ret
fi fi
fi fi
# Add ssh 22/tcp and ssh 22/udp to services # Add ssh 22/tcp and ssh 22/udp to services
if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ] if [ `/usr/bin/grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
then then
if awk '{ if ( $2 ~ /^23\/tcp/ ) print "ssh 22/tcp'"${_spaces}"'SSH Remote Login Protocol\nssh 22/udp'"${_spaces}"'SSH Remote Login Protocol"; print $0; }' < "${_services}" > "${_serv_tmp}" if /usr/bin/awk '{ if ( $2 ~ /^23\/tcp/ ) print "ssh 22/tcp'"${_spaces}"'SSH Remote Login Protocol\nssh 22/udp'"${_spaces}"'SSH Remote Login Protocol"; print $0; }' < "${_services}" > "${_serv_tmp}"
then then
if mv "${_serv_tmp}" "${_services}" if /usr/bin/mv "${_serv_tmp}" "${_services}"
then then
csih_inform "Added ssh to ${_wservices}" csih_inform "Added ssh to ${_wservices}"
else else
csih_warning "Adding ssh to ${_wservices} failed!" csih_warning "Adding ssh to ${_wservices} failed!"
let ++ret
fi fi
rm -f "${_serv_tmp}" /usr/bin/rm -f "${_serv_tmp}"
else else
csih_warning "Adding ssh to ${_wservices} failed!" csih_warning "Adding ssh to ${_wservices} failed!"
let ++ret
fi fi
fi fi
umount "${_my_etcdir}" /usr/bin/umount "${_my_etcdir}"
return $ret
} # --- End of update_services_file --- # } # --- End of update_services_file --- #
# ====================================================================== # ======================================================================
@ -144,10 +185,9 @@ update_services_file() {
# ====================================================================== # ======================================================================
sshd_privsep() { sshd_privsep() {
local sshdconfig_tmp local sshdconfig_tmp
local ret=0
if [ "${privsep_configured}" != "yes" ] if [ "${privsep_configured}" != "yes" ]
then
if csih_is_nt
then then
csih_inform "Privilege separation is set to yes by default since OpenSSH 3.3." csih_inform "Privilege separation is set to yes by default since OpenSSH 3.3."
csih_inform "However, this requires a non-privileged account called 'sshd'." csih_inform "However, this requires a non-privileged account called 'sshd'."
@ -157,38 +197,45 @@ sshd_privsep() {
privsep_used=yes privsep_used=yes
if ! csih_create_unprivileged_user sshd if ! csih_create_unprivileged_user sshd
then then
csih_warning "Couldn't create user 'sshd'!" csih_error_recoverable "Couldn't create user 'sshd'!"
csih_warning "Privilege separation set to 'no' again!" csih_error_recoverable "Privilege separation set to 'no' again!"
csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" csih_error_recoverable "Check your ${SYSCONFDIR}/sshd_config file!"
let ++ret
privsep_used=no privsep_used=no
fi fi
else else
privsep_used=no privsep_used=no
fi fi
else
# On 9x don't use privilege separation. Since security isn't
# available it just adds useless additional processes.
privsep_used=no
fi
fi fi
# Create default sshd_config from skeleton files in /etc/defaults/etc or # Create default sshd_config from skeleton files in /etc/defaults/etc or
# modify to add the missing privsep configuration option # modify to add the missing privsep configuration option
if cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1 if /usr/bin/cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
then then
csih_inform "Updating ${SYSCONFDIR}/sshd_config file" csih_inform "Updating ${SYSCONFDIR}/sshd_config file"
sshdconfig_tmp=${SYSCONFDIR}/sshd_config.$$ sshdconfig_tmp=${SYSCONFDIR}/sshd_config.$$
sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/ /usr/bin/sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
s/^#Port 22/Port ${port_number}/ s/^#Port 22/Port ${port_number}/
s/^#StrictModes yes/StrictModes no/" \ s/^#StrictModes yes/StrictModes no/" \
< ${SYSCONFDIR}/sshd_config \ < ${SYSCONFDIR}/sshd_config \
> "${sshdconfig_tmp}" > "${sshdconfig_tmp}"
mv "${sshdconfig_tmp}" ${SYSCONFDIR}/sshd_config if ! /usr/bin/mv "${sshdconfig_tmp}" ${SYSCONFDIR}/sshd_config
then
csih_warning "Setting privilege separation to 'yes' failed!"
csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
let ++ret
fi
elif [ "${privsep_configured}" != "yes" ] elif [ "${privsep_configured}" != "yes" ]
then then
echo >> ${SYSCONFDIR}/sshd_config echo >> ${SYSCONFDIR}/sshd_config
echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config if ! echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
then
csih_warning "Setting privilege separation to 'yes' failed!"
csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
let ++ret
fi fi
fi
return $ret
} # --- End of sshd_privsep --- # } # --- End of sshd_privsep --- #
# ====================================================================== # ======================================================================
@ -201,72 +248,82 @@ update_inetd_conf() {
local _sshd_inetd_conf="${_inetcnf_dir}/sshd-inetd" local _sshd_inetd_conf="${_inetcnf_dir}/sshd-inetd"
local _sshd_inetd_conf_tmp="${_inetcnf_dir}/sshd-inetd.$$" local _sshd_inetd_conf_tmp="${_inetcnf_dir}/sshd-inetd.$$"
local _with_comment=1 local _with_comment=1
local ret=0
if [ -d "${_inetcnf_dir}" ] if [ -d "${_inetcnf_dir}" ]
then then
# we have inetutils-1.5 inetd.d support # we have inetutils-1.5 inetd.d support
if [ -f "${_inetcnf}" ] if [ -f "${_inetcnf}" ]
then then
grep -q '^[ \t]*ssh' "${_inetcnf}" && _with_comment=0 /usr/bin/grep -q '^[ \t]*ssh' "${_inetcnf}" && _with_comment=0
# check for sshd OR ssh in top-level inetd.conf file, and remove # check for sshd OR ssh in top-level inetd.conf file, and remove
# will be replaced by a file in inetd.d/ # will be replaced by a file in inetd.d/
if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -eq 0 ] if [ `/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -eq 0 ]
then then
grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}" /usr/bin/grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}"
if [ -f "${_inetcnf_tmp}" ] if [ -f "${_inetcnf_tmp}" ]
then then
if mv "${_inetcnf_tmp}" "${_inetcnf}" if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}"
then then
csih_inform "Removed ssh[d] from ${_inetcnf}" csih_inform "Removed ssh[d] from ${_inetcnf}"
else else
csih_warning "Removing ssh[d] from ${_inetcnf} failed!" csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
let ++ret
fi fi
rm -f "${_inetcnf_tmp}" /usr/bin/rm -f "${_inetcnf_tmp}"
else else
csih_warning "Removing ssh[d] from ${_inetcnf} failed!" csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
let ++ret
fi fi
fi fi
fi fi
csih_install_config "${_sshd_inetd_conf}" "${SYSCONFDIR}/defaults" csih_install_config "${_sshd_inetd_conf}" "${SYSCONFDIR}/defaults"
if cmp "${SYSCONFDIR}/defaults${_sshd_inetd_conf}" "${_sshd_inetd_conf}" >/dev/null 2>&1 if /usr/bin/cmp "${SYSCONFDIR}/defaults${_sshd_inetd_conf}" "${_sshd_inetd_conf}" >/dev/null 2>&1
then then
if [ "${_with_comment}" -eq 0 ] if [ "${_with_comment}" -eq 0 ]
then then
sed -e 's/@COMMENT@[ \t]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" /usr/bin/sed -e 's/@COMMENT@[ \t]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
else else
sed -e 's/@COMMENT@[ \t]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" /usr/bin/sed -e 's/@COMMENT@[ \t]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
fi fi
mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}" if /usr/bin/mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}"
then
csih_inform "Updated ${_sshd_inetd_conf}" csih_inform "Updated ${_sshd_inetd_conf}"
else
csih_warning "Updating ${_sshd_inetd_conf} failed!"
let ++ret
fi
fi fi
elif [ -f "${_inetcnf}" ] elif [ -f "${_inetcnf}" ]
then then
grep -q '^[ \t]*sshd' "${_inetcnf}" && _with_comment=0 /usr/bin/grep -q '^[ \t]*sshd' "${_inetcnf}" && _with_comment=0
# check for sshd in top-level inetd.conf file, and remove # check for sshd in top-level inetd.conf file, and remove
# will be replaced by a file in inetd.d/ # will be replaced by a file in inetd.d/
if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ] if [ `/usr/bin/grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
then then
grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}" /usr/bin/grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
if [ -f "${_inetcnf_tmp}" ] if [ -f "${_inetcnf_tmp}" ]
then then
if mv "${_inetcnf_tmp}" "${_inetcnf}" if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}"
then then
csih_inform "Removed sshd from ${_inetcnf}" csih_inform "Removed sshd from ${_inetcnf}"
else else
csih_warning "Removing sshd from ${_inetcnf} failed!" csih_warning "Removing sshd from ${_inetcnf} failed!"
let ++ret
fi fi
rm -f "${_inetcnf_tmp}" /usr/bin/rm -f "${_inetcnf_tmp}"
else else
csih_warning "Removing sshd from ${_inetcnf} failed!" csih_warning "Removing sshd from ${_inetcnf} failed!"
let ++ret
fi fi
fi fi
# Add ssh line to inetd.conf # Add ssh line to inetd.conf
if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ] if [ `/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
then then
if [ "${_with_comment}" -eq 0 ] if [ "${_with_comment}" -eq 0 ]
then then
@ -274,11 +331,88 @@ update_inetd_conf() {
else else
echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}" echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
fi fi
if [ $? -eq 0 ]
then
csih_inform "Added ssh to ${_inetcnf}" csih_inform "Added ssh to ${_inetcnf}"
else
csih_warning "Adding ssh to ${_inetcnf} failed!"
let ++ret
fi fi
fi fi
fi
return $ret
} # --- End of update_inetd_conf --- # } # --- End of update_inetd_conf --- #
# ======================================================================
# Routine: check_service_files_ownership
# Checks that the files in /etc and /var belong to the right owner
# ======================================================================
check_service_files_ownership() {
local run_service_as=$1
local ret=0
if [ -z "${run_service_as}" ]
then
accnt_name=$(/usr/bin/cygrunsrv -VQ sshd | /usr/bin/sed -ne 's/^Account *: *//gp')
if [ "${accnt_name}" = "LocalSystem" ]
then
# Convert "LocalSystem" to "SYSTEM" as is the correct account name
accnt_name="SYSTEM:"
elif [[ "${accnt_name}" =~ ^\.\\ ]]
then
# Convert "." domain to local machine name
accnt_name="U-${COMPUTERNAME}${accnt_name#.},"
fi
run_service_as=$(/usr/bin/grep -Fi "${accnt_name}" /etc/passwd | /usr/bin/awk -F: '{print $1;}')
if [ -z "${run_service_as}" ]
then
csih_warning "Couldn't determine name of user running sshd service from /etc/passwd!"
csih_warning "As a result, this script cannot make sure that the files used"
csih_warning "by the sshd service belong to the user running the service."
csih_warning "Please re-run the mkpasswd tool to make sure the /etc/passwd"
csih_warning "file is in a good shape."
return 1
fi
fi
for i in "${SYSCONFDIR}"/ssh_config "${SYSCONFDIR}"/sshd_config "${SYSCONFDIR}"/ssh_host_*key "${SYSCONFDIR}"/ssh_host_*key.pub
do
if [ -f "$i" ]
then
if ! chown "${run_service_as}".544 "$i" >/dev/null 2>&1
then
csih_warning "Couldn't change owner of $i!"
let ++ret
fi
fi
done
if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty >/dev/null 2>&1
then
csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/empty!"
let ++ret
fi
if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1
then
csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/lastlog!"
let ++ret
fi
if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
then
if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log >/dev/null 2>&1
then
csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/sshd.log!"
let ++ret
fi
fi
if [ $ret -ne 0 ]
then
csih_warning "Couldn't change owner of important files to ${run_service_as}!"
csih_warning "This may cause the sshd service to fail! Please make sure that"
csih_warning "you have suufficient permissions to change the ownership of files"
csih_warning "and try to run the ssh-host-config script again."
fi
return $ret
} # --- End of check_service_files_ownership --- #
# ====================================================================== # ======================================================================
# Routine: install_service # Routine: install_service
# Install sshd as a service # Install sshd as a service
@ -286,15 +420,14 @@ update_inetd_conf() {
install_service() { install_service() {
local run_service_as local run_service_as
local password local password
local ret=0
if csih_is_nt echo
if /usr/bin/cygrunsrv -Q sshd >/dev/null 2>&1
then then
if ! cygrunsrv -Q sshd >/dev/null 2>&1 csih_inform "Sshd service is already installed."
then check_service_files_ownership "" || let ret+=$?
echo else
echo
csih_warning "The following functions require administrator privileges!"
echo
echo -e "${_csih_QUERY_STR} Do you want to install sshd as a service?" echo -e "${_csih_QUERY_STR} Do you want to install sshd as a service?"
if csih_request "(Say \"no\" if it is already installed as a service)" if csih_request "(Say \"no\" if it is already installed as a service)"
then then
@ -316,10 +449,11 @@ install_service() {
then then
csih_error_recoverable "There was a serious problem creating a privileged user." csih_error_recoverable "There was a serious problem creating a privileged user."
csih_request "Do you want to proceed anyway?" || exit 1 csih_request "Do you want to proceed anyway?" || exit 1
let ++ret
fi fi
fi fi
# never returns empty if NT or above # Never returns empty if NT or above
run_service_as=$(csih_service_should_run_as) run_service_as=$(csih_service_should_run_as)
if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ] if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ]
@ -332,10 +466,10 @@ install_service() {
fi fi
fi fi
# at this point, we either have $run_service_as = "system" and $password is empty, # At this point, we either have $run_service_as = "system" and
# or $run_service_as is some privileged user and (hopefully) $password contains # $password is empty, or $run_service_as is some privileged user and
# the correct password. So, from here out, we use '-z "${password}"' to discriminate # (hopefully) $password contains the correct password. So, from here
# the two cases. # out, we use '-z "${password}"' to discriminate the two cases.
csih_check_user "${run_service_as}" csih_check_user "${run_service_as}"
@ -345,7 +479,7 @@ install_service() {
fi fi
if [ -z "${password}" ] if [ -z "${password}" ]
then then
if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \ if /usr/bin/cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \
-a "-D" -y tcpip "${cygwin_env[@]}" -a "-D" -y tcpip "${cygwin_env[@]}"
then then
echo echo
@ -355,7 +489,7 @@ install_service() {
csih_inform "will start automatically after the next reboot." csih_inform "will start automatically after the next reboot."
fi fi
else else
if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \ if /usr/bin/cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \
-a "-D" -y tcpip "${cygwin_env[@]}" \ -a "-D" -y tcpip "${cygwin_env[@]}" \
-u "${run_service_as}" -w "${password}" -u "${run_service_as}" -w "${password}"
then then
@ -367,22 +501,16 @@ install_service() {
fi fi
fi fi
# now, if successfully installed, set ownership of the affected files if /usr/bin/cygrunsrv -Q sshd >/dev/null 2>&1
if cygrunsrv -Q sshd >/dev/null 2>&1
then then
chown "${run_service_as}" ${SYSCONFDIR}/ssh* check_service_files_ownership "${run_service_as}" || let ret+=$?
chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty
chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog
if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
then
chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log
fi
else else
csih_warning "Something went wrong installing the sshd service." csih_error_recoverable "Installing sshd as a service failed!"
let ++ret
fi fi
fi # user allowed us to install as service fi # user allowed us to install as service
fi # service not yet installed fi # service not yet installed
fi # csih_is_nt return $ret
} # --- End of install_service --- # } # --- End of install_service --- #
# ====================================================================== # ======================================================================
@ -494,21 +622,71 @@ done
# Check for running ssh/sshd processes first. Refuse to do anything while # Check for running ssh/sshd processes first. Refuse to do anything while
# some ssh processes are still running # some ssh processes are still running
if ps -ef | grep -q '/sshd\?$' if /usr/bin/ps -ef | /usr/bin/grep -q '/sshd\?$'
then then
echo echo
csih_error "There are still ssh processes running. Please shut them down first." csih_error "There are still ssh processes running. Please shut them down first."
fi fi
# Make sure the user is running in an administrative context
admin=$(/usr/bin/id -G | /usr/bin/grep -Eq '\<544\>' && echo yes || echo no)
if [ "${admin}" != "yes" ]
then
echo
csih_warning "Running this script typically requires administrator privileges!"
csih_warning "However, it seems your account does not have these privileges."
csih_warning "Here's the list of groups in your user token:"
echo
for i in $(/usr/bin/id -G)
do
/usr/bin/awk -F: "/[^:]*:[^:]*:$i:/{ print \" \" \$1; }" /etc/group
done
echo
csih_warning "This usually means you're running this script from a non-admin"
csih_warning "desktop session, or in a non-elevated shell under UAC control."
echo
csih_warning "Make sure you have the appropriate privileges right now,"
csih_warning "otherwise parts of this script will probably fail!"
echo
echo -e "${_csih_QUERY_STR} Are you sure you want to continue? (Say \"no\" if you're not sure"
if ! csih_request "you have the required privileges)"
then
echo
csih_inform "Ok. Exiting. Make sure to switch to an administrative account"
csih_inform "or to start this script from an elevated shell."
exit 1
fi
fi
echo
warning_cnt=0
# Check for ${SYSCONFDIR} directory # Check for ${SYSCONFDIR} directory
csih_make_dir "${SYSCONFDIR}" "Cannot create global configuration files." csih_make_dir "${SYSCONFDIR}" "Cannot create global configuration files."
chmod 775 "${SYSCONFDIR}" if ! /usr/bin/chmod 775 "${SYSCONFDIR}" >/dev/null 2>&1
setfacl -m u:system:rwx "${SYSCONFDIR}" then
csih_warning "Can't set permissions on ${SYSCONFDIR}!"
let ++warning_cnt
fi
if ! /usr/bin/setfacl -m u:system:rwx "${SYSCONFDIR}" >/dev/null 2>&1
then
csih_warning "Can't set extended permissions on ${SYSCONFDIR}!"
let ++warning_cnt
fi
# Check for /var/log directory # Check for /var/log directory
csih_make_dir "${LOCALSTATEDIR}/log" "Cannot create log directory." csih_make_dir "${LOCALSTATEDIR}/log" "Cannot create log directory."
chmod 775 "${LOCALSTATEDIR}/log" if ! /usr/bin/chmod 775 "${LOCALSTATEDIR}/log" >/dev/null 2>&1
setfacl -m u:system:rwx "${LOCALSTATEDIR}/log" then
csih_warning "Can't set permissions on ${LOCALSTATEDIR}/log!"
let ++warning_cnt
fi
if ! /usr/bin/setfacl -m u:system:rwx "${LOCALSTATEDIR}/log" >/dev/null 2>&1
then
csih_warning "Can't set extended permissions on ${LOCALSTATEDIR}/log!"
let ++warning_cnt
fi
# Create /var/log/lastlog if not already exists # Create /var/log/lastlog if not already exists
if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ] if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ]
@ -519,26 +697,33 @@ then
fi fi
if [ ! -e ${LOCALSTATEDIR}/log/lastlog ] if [ ! -e ${LOCALSTATEDIR}/log/lastlog ]
then then
cat /dev/null > ${LOCALSTATEDIR}/log/lastlog /usr/bin/cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
chmod 644 ${LOCALSTATEDIR}/log/lastlog if ! /usr/bin/chmod 644 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1
then
csih_warning "Can't set permissions on ${LOCALSTATEDIR}/log/lastlog!"
let ++warning_cnt
fi
fi fi
# Create /var/empty file used as chroot jail for privilege separation # Create /var/empty file used as chroot jail for privilege separation
csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create ${LOCALSTATEDIR}/empty directory." csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create ${LOCALSTATEDIR}/empty directory."
chmod 755 "${LOCALSTATEDIR}/empty" if ! /usr/bin/chmod 755 "${LOCALSTATEDIR}/empty" >/dev/null 2>&1
setfacl -m u:system:rwx "${LOCALSTATEDIR}/empty" then
csih_warning "Can't set permissions on ${LOCALSTATEDIR}/empty!"
let ++warning_cnt
fi
if ! /usr/bin/setfacl -m u:system:rwx "${LOCALSTATEDIR}/empty" >/dev/null 2>&1
then
csih_warning "Can't set extended permissions on ${LOCALSTATEDIR}/empty!"
let ++warning_cnt
fi
# host keys # host keys
create_host_keys create_host_keys || let warning_cnt+=$?
# use 'cmp' program to determine if a config file is identical
# to the default version of that config file
csih_check_program_or_error cmp diffutils
# handle ssh_config # handle ssh_config
csih_install_config "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults" csih_install_config "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt
if cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1 if /usr/bin/cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1
then then
if [ "${port_number}" != "22" ] if [ "${port_number}" != "22" ]
then then
@ -549,19 +734,24 @@ then
fi fi
# handle sshd_config (and privsep) # handle sshd_config (and privsep)
csih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults" csih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt
if ! cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1 if ! /usr/bin/cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
then then
grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes /usr/bin/grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
fi fi
sshd_privsep sshd_privsep || let warning_cnt+=$?
update_services_file || let warning_cnt+=$?
update_inetd_conf || let warning_cnt+=$?
update_services_file install_service || let warning_cnt+=$?
update_inetd_conf
install_service
echo echo
if [ $warning_cnt -eq 0 ]
then
csih_inform "Host configuration finished. Have fun!" csih_inform "Host configuration finished. Have fun!"
else
csih_warning "Host configuration exited with ${warning_cnt} errors or warnings!"
csih_warning "Make sure that all problems reported are fixed,"
csih_warning "then re-run ssh-host-config."
fi
exit $warning_cnt