- (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 _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
then _services="${_my_etcdir}/services"
_win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc" _spaces=" #"
_services="${_my_etcdir}/services"
# On NT, 27 spaces, no space after the hash
_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,51 +185,57 @@ 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 then
if csih_is_nt 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 "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
if csih_request "Should privilege separation be used?"
then then
csih_inform "Privilege separation is set to yes by default since OpenSSH 3.3." privsep_used=yes
csih_inform "However, this requires a non-privileged account called 'sshd'." if ! csih_create_unprivileged_user sshd
csih_inform "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
if csih_request "Should privilege separation be used?"
then then
privsep_used=yes csih_error_recoverable "Couldn't create user 'sshd'!"
if ! csih_create_unprivileged_user sshd csih_error_recoverable "Privilege separation set to 'no' again!"
then csih_error_recoverable "Check your ${SYSCONFDIR}/sshd_config file!"
csih_warning "Couldn't create user 'sshd'!" let ++ret
csih_warning "Privilege separation set to 'no' again!"
csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
privsep_used=no
fi
else
privsep_used=no privsep_used=no
fi fi
else else
# On 9x don't use privilege separation. Since security isn't
# available it just adds useless additional processes.
privsep_used=no privsep_used=no
fi 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
if /usr/bin/mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}"
then
csih_inform "Updated ${_sshd_inetd_conf}"
else
csih_warning "Updating ${_sshd_inetd_conf} failed!"
let ++ret
fi fi
mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}"
csih_inform "Updated ${_sshd_inetd_conf}"
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
csih_inform "Added ssh to ${_inetcnf}" if [ $? -eq 0 ]
then
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,103 +420,97 @@ 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."
check_service_files_ownership "" || let ret+=$?
else
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)"
then then
echo csih_get_cygenv "${cygwin_value}"
echo
csih_warning "The following functions require administrator privileges!" if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] )
echo
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)"
then then
csih_get_cygenv "${cygwin_value}" csih_inform "On Windows Server 2003, Windows Vista, and above, the"
csih_inform "SYSTEM account cannot setuid to other users -- a capability"
csih_inform "sshd requires. You need to have or to create a privileged"
csih_inform "account. This script will help you do so."
echo
if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] ) [ "${opt_force}" = "yes" ] && opt_f=-f
[ -n "${user_account}" ] && opt_u="-u ""${user_account}"""
csih_select_privileged_username ${opt_f} ${opt_u} sshd
if ! csih_create_privileged_user "${password_value}"
then then
csih_inform "On Windows Server 2003, Windows Vista, and above, the" csih_error_recoverable "There was a serious problem creating a privileged user."
csih_inform "SYSTEM account cannot setuid to other users -- a capability" csih_request "Do you want to proceed anyway?" || exit 1
csih_inform "sshd requires. You need to have or to create a privileged" let ++ret
csih_inform "account. This script will help you do so."
echo
[ "${opt_force}" = "yes" ] && opt_f=-f
[ -n "${user_account}" ] && opt_u="-u ""${user_account}"""
csih_select_privileged_username ${opt_f} ${opt_u} sshd
if ! csih_create_privileged_user "${password_value}"
then
csih_error_recoverable "There was a serious problem creating a privileged user."
csih_request "Do you want to proceed anyway?" || exit 1
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}" ]
then then
password="${csih_PRIVILEGED_PASSWORD}" password="${csih_PRIVILEGED_PASSWORD}"
if [ -z "${password}" ]
then
csih_get_value "Please enter the password for user '${run_service_as}':" "-s"
password="${csih_value}"
fi
fi
# at this point, we either have $run_service_as = "system" and $password is empty,
# or $run_service_as is some privileged user and (hopefully) $password contains
# the correct password. So, from here out, we use '-z "${password}"' to discriminate
# the two cases.
csih_check_user "${run_service_as}"
if [ -n "${csih_cygenv}" ]
then
cygwin_env=( -e "CYGWIN=${csih_cygenv}" )
fi
if [ -z "${password}" ] if [ -z "${password}" ]
then then
if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \ csih_get_value "Please enter the password for user '${run_service_as}':" "-s"
-a "-D" -y tcpip "${cygwin_env[@]}" password="${csih_value}"
then
echo
csih_inform "The sshd service has been installed under the LocalSystem"
csih_inform "account (also known as SYSTEM). To start the service now, call"
csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'. Otherwise, it"
csih_inform "will start automatically after the next reboot."
fi
else
if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \
-a "-D" -y tcpip "${cygwin_env[@]}" \
-u "${run_service_as}" -w "${password}"
then
echo
csih_inform "The sshd service has been installed under the '${run_service_as}'"
csih_inform "account. To start the service now, call \`net start sshd' or"
csih_inform "\`cygrunsrv -S sshd'. Otherwise, it will start automatically"
csih_inform "after the next reboot."
fi
fi fi
fi
# now, if successfully installed, set ownership of the affected files # At this point, we either have $run_service_as = "system" and
if cygrunsrv -Q sshd >/dev/null 2>&1 # $password is empty, or $run_service_as is some privileged user and
# (hopefully) $password contains the correct password. So, from here
# out, we use '-z "${password}"' to discriminate the two cases.
csih_check_user "${run_service_as}"
if [ -n "${csih_cygenv}" ]
then
cygwin_env=( -e "CYGWIN=${csih_cygenv}" )
fi
if [ -z "${password}" ]
then
if /usr/bin/cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \
-a "-D" -y tcpip "${cygwin_env[@]}"
then then
chown "${run_service_as}" ${SYSCONFDIR}/ssh* echo
chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty csih_inform "The sshd service has been installed under the LocalSystem"
chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog csih_inform "account (also known as SYSTEM). To start the service now, call"
if [ -f ${LOCALSTATEDIR}/log/sshd.log ] csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'. Otherwise, it"
then csih_inform "will start automatically after the next reboot."
chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log
fi
else
csih_warning "Something went wrong installing the sshd service."
fi fi
fi # user allowed us to install as service else
fi # service not yet installed if /usr/bin/cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \
fi # csih_is_nt -a "-D" -y tcpip "${cygwin_env[@]}" \
-u "${run_service_as}" -w "${password}"
then
echo
csih_inform "The sshd service has been installed under the '${run_service_as}'"
csih_inform "account. To start the service now, call \`net start sshd' or"
csih_inform "\`cygrunsrv -S sshd'. Otherwise, it will start automatically"
csih_inform "after the next reboot."
fi
fi
if /usr/bin/cygrunsrv -Q sshd >/dev/null 2>&1
then
check_service_files_ownership "${run_service_as}" || let ret+=$?
else
csih_error_recoverable "Installing sshd as a service failed!"
let ++ret
fi
fi # user allowed us to install as service
fi # service not yet installed
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
csih_inform "Host configuration finished. Have fun!" if [ $warning_cnt -eq 0 ]
then
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