- (djm) [contrib/cygwin/Makefile contrib/cygwin/ssh-host-config]
[contrib/cygwin/ssh-user-config contrib/cygwin/sshd-inetd]
Revamped and simplified Cygwin ssh-host-config script that uses
unified csih configuration tool. Requires recent Cygwin.
Patch from vinschen AT redhat.com
diff --git a/ChangeLog b/ChangeLog
index dfc8dc5..d60f16c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -26,6 +26,11 @@
prototype; reported by cristian.ionescu-idbohrn AT axis.com
- (djm) [umac.c] Rename variable s/buffer_ptr/bufp/ to avoid clash;
reported by cristian.ionescu-idbohrn AT axis.com
+ - (djm) [contrib/cygwin/Makefile contrib/cygwin/ssh-host-config]
+ [contrib/cygwin/ssh-user-config contrib/cygwin/sshd-inetd]
+ Revamped and simplified Cygwin ssh-host-config script that uses
+ unified csih configuration tool. Requires recent Cygwin.
+ Patch from vinschen AT redhat.com
20080712
- (djm) OpenBSD CVS Sync
@@ -4662,4 +4667,4 @@
OpenServer 6 and add osr5bigcrypt support so when someone migrates
passwords between UnixWare and OpenServer they will still work. OK dtucker@
-$Id: ChangeLog,v 1.5082 2008/07/14 02:09:57 djm Exp $
+$Id: ChangeLog,v 1.5083 2008/07/14 02:12:52 djm Exp $
diff --git a/contrib/cygwin/Makefile b/contrib/cygwin/Makefile
index 5176ba0..3e2d264 100644
--- a/contrib/cygwin/Makefile
+++ b/contrib/cygwin/Makefile
@@ -8,6 +8,7 @@
cygdocdir=$(docdir)/Cygwin
sysconfdir=/etc
defaultsdir=$(sysconfdir)/defaults/etc
+inetdefdir=$(defaultsdir)/inetd.d
PRIVSEP_PATH=/var/empty
INSTALL=/usr/bin/install -c
@@ -27,6 +28,10 @@
remove-empty-dir:
rm -rf $(DESTDIR)$(PRIVSEP_PATH)
+install-inetd-config:
+ $(srcdir)/mkinstalldirs $(DESTDIR)$(inetdefdir)
+ $(INSTALL) -m 644 sshd-inetd $(DESTDIR)$(inetdefdir)/sshd-inetd
+
install-sshdoc:
$(srcdir)/mkinstalldirs $(DESTDIR)$(sshdocdir)
$(INSTALL) -m 644 $(srcdir)/CREDITS $(DESTDIR)$(sshdocdir)/CREDITS
@@ -37,6 +42,7 @@
$(INSTALL) -m 644 $(srcdir)/README.dns $(DESTDIR)$(sshdocdir)/README.dns
$(INSTALL) -m 644 $(srcdir)/README.privsep $(DESTDIR)$(sshdocdir)/README.privsep
$(INSTALL) -m 644 $(srcdir)/README.smartcard $(DESTDIR)$(sshdocdir)/README.smartcard
+ $(INSTALL) -m 644 $(srcdir)/RFC.nroff $(DESTDIR)$(sshdocdir)/RFC.nroff
$(INSTALL) -m 644 $(srcdir)/TODO $(DESTDIR)$(sshdocdir)/TODO
$(INSTALL) -m 644 $(srcdir)/WARNING.RNG $(DESTDIR)$(sshdocdir)/WARNING.RNG
@@ -51,5 +57,5 @@
$(INSTALL) -m 755 ssh-host-config $(DESTDIR)$(bindir)/ssh-host-config
$(INSTALL) -m 755 ssh-user-config $(DESTDIR)$(bindir)/ssh-user-config
-cygwin-postinstall: move-config-files remove-empty-dir install-doc install-scripts
+cygwin-postinstall: move-config-files remove-empty-dir install-inetd-config install-doc install-scripts
@echo "Cygwin specific configuration finished."
diff --git a/contrib/cygwin/ssh-host-config b/contrib/cygwin/ssh-host-config
index f90af8d..bbb6da4 100644
--- a/contrib/cygwin/ssh-host-config
+++ b/contrib/cygwin/ssh-host-config
@@ -4,6 +4,15 @@
#
# This file is part of the Cygwin port of OpenSSH.
+# ======================================================================
+# Initialization
+# ======================================================================
+PROGNAME=$(basename $0)
+_tdir=$(dirname $0)
+PROGDIR=$(cd $_tdir && pwd)
+
+CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh
+
# Subdirectory where the new package is being installed
PREFIX=/usr
@@ -11,43 +20,371 @@
SYSCONFDIR=/etc
LOCALSTATEDIR=/var
-progname=$0
-auto_answer=""
-port_number=22
+source ${CSIH_SCRIPT}
+port_number=22
privsep_configured=no
privsep_used=yes
-sshd_in_passwd=no
-sshd_in_sam=no
+cygwin_value="ntsec"
+password_value=
-request()
-{
- if [ "${auto_answer}" = "yes" ]
+# ======================================================================
+# Routine: create_host_keys
+# ======================================================================
+create_host_keys() {
+ if [ ! -f "${SYSCONFDIR}/ssh_host_key" ]
then
- echo "$1 (yes/no) yes"
- return 0
- elif [ "${auto_answer}" = "no" ]
- then
- echo "$1 (yes/no) no"
- return 1
+ csih_inform "Generating ${SYSCONFDIR}/ssh_host_key"
+ ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
fi
-
- answer=""
- while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ]
- do
- echo -n "$1 (yes/no) "
- read -e answer
- done
- if [ "X${answer}" = "Xyes" ]
+
+ if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
then
- return 0
+ csih_inform "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
+ ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
+ fi
+
+ if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ]
+ then
+ csih_inform "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
+ ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
+ fi
+} # --- End of create_host_keys --- #
+
+# ======================================================================
+# Routine: update_services_file
+# ======================================================================
+update_services_file() {
+ local _my_etcdir="/ssh-host-config.$$"
+ local _win_etcdir
+ local _services
+ local _spaces
+ local _serv_tmp
+ local _wservices
+
+ if csih_is_nt
+ then
+ _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
+ _services="${_my_etcdir}/services"
+ # On NT, 27 spaces, no space after the hash
+ _spaces=" #"
else
- return 1
+ _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.$$"
+
+ mount -t -f "${_win_etcdir}" "${_my_etcdir}"
+
+ # Depends on the above mount
+ _wservices=`cygpath -w "${_services}"`
+
+ # Remove sshd 22/port from services
+ if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
+ then
+ grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
+ if [ -f "${_serv_tmp}" ]
+ then
+ if mv "${_serv_tmp}" "${_services}"
+ then
+ csih_inform "Removing sshd from ${_wservices}"
+ else
+ csih_warning "Removing sshd from ${_wservices} failed!"
+ fi
+ rm -f "${_serv_tmp}"
+ else
+ csih_warning "Removing sshd from ${_wservices} failed!"
+ fi
+ fi
+
+ # Add ssh 22/tcp and ssh 22/udp to services
+ if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
+ 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}"
+ then
+ if mv "${_serv_tmp}" "${_services}"
+ then
+ csih_inform "Added ssh to ${_wservices}"
+ else
+ csih_warning "Adding ssh to ${_wservices} failed!"
+ fi
+ rm -f "${_serv_tmp}"
+ else
+ csih_warning "Adding ssh to ${_wservices} failed!"
+ fi
+ fi
+ umount "${_my_etcdir}"
+} # --- End of update_services_file --- #
-# Check options
+# ======================================================================
+# Routine: sshd_privsep
+# MODIFIES: privsep_configured privsep_used
+# ======================================================================
+sshd_privsep() {
+ local sshdconfig_tmp
+ if [ "${privsep_configured}" != "yes" ]
+ then
+ if csih_is_nt
+ then
+ 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
+ privsep_used=yes
+ if ! csih_create_unprivileged_user sshd
+ then
+ csih_warning "Couldn't create user 'sshd'!"
+ csih_warning "Privilege separation set to 'no' again!"
+ csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
+ privsep_used=no
+ fi
+ else
+ privsep_used=no
+ 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
+
+ # Create default sshd_config from skeleton files in /etc/defaults/etc or
+ # modify to add the missing privsep configuration option
+ if cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
+ then
+ csih_inform "Updating ${SYSCONFDIR}/sshd_config file"
+ sshdconfig_tmp=${SYSCONFDIR}/sshd_config.$$
+ sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
+ s/^#Port 22/Port ${port_number}/
+ s/^#StrictModes yes/StrictModes no/" \
+ < ${SYSCONFDIR}/sshd_config \
+ > "${sshdconfig_tmp}"
+ mv "${sshdconfig_tmp}" ${SYSCONFDIR}/sshd_config
+ elif [ "${privsep_configured}" != "yes" ]
+ then
+ echo >> ${SYSCONFDIR}/sshd_config
+ echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
+ fi
+} # --- End of sshd_privsep --- #
+
+# ======================================================================
+# Routine: update_inetd_conf
+# ======================================================================
+update_inetd_conf() {
+ local _inetcnf="${SYSCONFDIR}/inetd.conf"
+ local _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
+ local _inetcnf_dir="${SYSCONFDIR}/inetd.d"
+ local _sshd_inetd_conf="${_inetcnf_dir}/sshd-inetd"
+ local _sshd_inetd_conf_tmp="${_inetcnf_dir}/sshd-inetd.$$"
+ local _with_comment=1
+
+ if [ -d "${_inetcnf_dir}" ]
+ then
+ # we have inetutils-1.5 inetd.d support
+ if [ -f "${_inetcnf}" ]
+ then
+ grep -q '^[ \t]*ssh' "${_inetcnf}" && _with_comment=0
+
+ # check for sshd OR ssh in top-level inetd.conf file, and remove
+ # will be replaced by a file in inetd.d/
+ if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -eq 0 ]
+ then
+ grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}"
+ if [ -f "${_inetcnf_tmp}" ]
+ then
+ if mv "${_inetcnf_tmp}" "${_inetcnf}"
+ then
+ csih_inform "Removed ssh[d] from ${_inetcnf}"
+ else
+ csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
+ fi
+ rm -f "${_inetcnf_tmp}"
+ else
+ csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
+ fi
+ fi
+ fi
+
+ csih_install_config "${_sshd_inetd_conf}" "${SYSCONFDIR}/defaults"
+ if cmp "${SYSCONFDIR}/defaults${_sshd_inetd_conf}" "${_sshd_inetd_conf}" >/dev/null 2>&1
+ then
+ if [ "${_with_comment}" -eq 0 ]
+ then
+ sed -e 's/@COMMENT@[ \t]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
+ else
+ sed -e 's/@COMMENT@[ \t]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
+ fi
+ mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}"
+ csih_inform "Updated ${_sshd_inetd_conf}"
+ fi
+
+ elif [ -f "${_inetcnf}" ]
+ then
+ grep -q '^[ \t]*sshd' "${_inetcnf}" && _with_comment=0
+
+ # check for sshd in top-level inetd.conf file, and remove
+ # will be replaced by a file in inetd.d/
+ if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
+ then
+ grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
+ if [ -f "${_inetcnf_tmp}" ]
+ then
+ if mv "${_inetcnf_tmp}" "${_inetcnf}"
+ then
+ csih_inform "Removed sshd from ${_inetcnf}"
+ else
+ csih_warning "Removing sshd from ${_inetcnf} failed!"
+ fi
+ rm -f "${_inetcnf_tmp}"
+ else
+ csih_warning "Removing sshd from ${_inetcnf} failed!"
+ fi
+ fi
+
+ # Add ssh line to inetd.conf
+ if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
+ then
+ if [ "${_with_comment}" -eq 0 ]
+ then
+ echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
+ else
+ echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
+ fi
+ csih_inform "Added ssh to ${_inetcnf}"
+ fi
+ fi
+} # --- End of update_inetd_conf --- #
+
+# ======================================================================
+# Routine: install_service
+# Install sshd as a service
+# ======================================================================
+install_service() {
+ local run_service_as
+ local password
+
+ if csih_is_nt
+ then
+ if ! cygrunsrv -Q sshd >/dev/null 2>&1
+ then
+ echo
+ echo
+ csih_warning "The following functions require administrator privileges!"
+ 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
+ csih_inform "Note that the CYGWIN variable must contain at least \"ntsec\""
+ csih_inform "for sshd to be able to change user context without password."
+ csih_get_cygenv "${cygwin_value}"
+
+ if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] )
+ then
+ 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_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
+
+ # never returns empty if NT or above
+ run_service_as=$(csih_service_should_run_as)
+
+ if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ]
+ then
+ 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 [ -z "${password}" ]
+ then
+ if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a "-D" -y tcpip \
+ -e CYGWIN="${csih_cygenv}"
+ 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 \
+ -e CYGWIN="${csih_cygenv}" -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
+
+ # now, if successfully installed, set ownership of the affected files
+ if cygrunsrv -Q sshd >/dev/null 2>&1
+ then
+ chown "${run_service_as}" ${SYSCONFDIR}/ssh*
+ 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
+ csih_warning "Something went wrong installing the sshd service."
+ fi
+ fi # user allowed us to install as service
+ fi # service not yet installed
+ fi # csih_is_nt
+} # --- End of install_service --- #
+
+# ======================================================================
+# Main Entry Point
+# ======================================================================
+
+# Check how the script has been started. If
+# (1) it has been started by giving the full path and
+# that path is /etc/postinstall, OR
+# (2) Otherwise, if the environment variable
+# SSH_HOST_CONFIG_AUTO_ANSWER_NO is set
+# then set auto_answer to "no". This allows automatic
+# creation of the config files in /etc w/o overwriting
+# them if they already exist. In both cases, color
+# escape sequences are suppressed, so as to prevent
+# cluttering setup's logfiles.
+if [ "$PROGDIR" = "/etc/postinstall" ]
+then
+ csih_auto_answer="no"
+ csih_disable_color
+fi
+if [ -n "${SSH_HOST_CONFIG_AUTO_ANSWER_NO}" ]
+then
+ csih_auto_answer="no"
+ csih_disable_color
+fi
+
+# ======================================================================
+# Parse options
+# ======================================================================
while :
do
case $# in
@@ -62,14 +399,15 @@
case "${option}" in
-d | --debug )
set -x
+ csih_trace_on
;;
-y | --yes )
- auto_answer=yes
+ csih_auto_answer=yes
;;
-n | --no )
- auto_answer=no
+ csih_auto_answer=no
;;
-c | --cygwin )
@@ -87,6 +425,10 @@
shift
;;
+ --privileged )
+ csih_FORCE_PRIVILEGED_USER=yes
+ ;;
+
*)
echo "usage: ${progname} [OPTION]..."
echo
@@ -98,7 +440,9 @@
echo " --no -n Answer all questions with \"no\" automatically."
echo " --cygwin -c <options> Use \"options\" as value for CYGWIN environment var."
echo " --port -p <n> sshd listens on port n."
- echo " --pwd -w <passwd> Use \"pwd\" as password for user 'sshd_server'."
+ echo " --pwd -w <passwd> Use \"pwd\" as password for privileged user."
+ echo " --privileged On Windows NT/2k/XP, require privileged user"
+ echo " instead of LocalSystem for sshd service."
echo
exit 1
;;
@@ -106,73 +450,34 @@
esac
done
-# Check if running on NT
-_sys="`uname`"
-_nt=`expr "${_sys}" : "CYGWIN_NT"`
-# If running on NT, check if running under 2003 Server or later
-if [ ${_nt} -gt 0 ]
-then
- _nt2003=`uname | awk -F- '{print ( $2 >= 5.2 ) ? 1 : 0;}'`
-fi
+# ======================================================================
+# Action!
+# ======================================================================
# Check for running ssh/sshd processes first. Refuse to do anything while
# some ssh processes are still running
-
if ps -ef | grep -v grep | grep -q ssh
then
echo
- echo "There are still ssh processes running. Please shut them down first."
- echo
- exit 1
+ csih_error "There are still ssh processes running. Please shut them down first."
fi
# Check for ${SYSCONFDIR} directory
+csih_make_dir "${SYSCONFDIR}" "Cannot create global configuration files."
+chmod 775 "${SYSCONFDIR}"
+setfacl -m u:system:rwx "${SYSCONFDIR}"
-if [ -e "${SYSCONFDIR}" -a ! -d "${SYSCONFDIR}" ]
-then
- echo
- echo "${SYSCONFDIR} exists but is not a directory."
- echo "Cannot create global configuration files."
- echo
- exit 1
-fi
+# Check for /var/log directory
+csih_make_dir "${LOCALSTATEDIR}/log" "Cannot create log directory."
+chmod 775 "${LOCALSTATEDIR}/log"
+setfacl -m u:system:rwx "${LOCALSTATEDIR}/log"
-# Create it if necessary
-
-if [ ! -e "${SYSCONFDIR}" ]
-then
- mkdir "${SYSCONFDIR}"
- if [ ! -e "${SYSCONFDIR}" ]
- then
- echo
- echo "Creating ${SYSCONFDIR} directory failed"
- echo
- exit 1
- fi
-fi
-
-# Create /var/log and /var/log/lastlog if not already existing
-
-if [ -e ${LOCALSTATEDIR}/log -a ! -d ${LOCALSTATEDIR}/log ]
-then
- echo
- echo "${LOCALSTATEDIR}/log exists but is not a directory."
- echo "Cannot create ssh host configuration."
- echo
- exit 1
-fi
-if [ ! -e ${LOCALSTATEDIR}/log ]
-then
- mkdir -p ${LOCALSTATEDIR}/log
-fi
-
+# Create /var/log/lastlog if not already exists
if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ]
then
echo
- echo "${LOCALSTATEDIR}/log/lastlog exists, but is not a file."
- echo "Cannot create ssh host configuration."
- echo
- exit 1
+ csih_error_multi "${LOCALSTATEDIR}/log/lastlog exists, but is not a file." \
+ "Cannot create ssh host configuration."
fi
if [ ! -e ${LOCALSTATEDIR}/log/lastlog ]
then
@@ -181,443 +486,44 @@
fi
# Create /var/empty file used as chroot jail for privilege separation
-if [ -e ${LOCALSTATEDIR}/empty -a ! -d ${LOCALSTATEDIR}/empty ]
+csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create log directory."
+chmod 755 "${LOCALSTATEDIR}/empty"
+setfacl -m u:system:rwx "${LOCALSTATEDIR}/empty"
+
+# host keys
+create_host_keys
+
+# 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
+csih_install_config "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults"
+if cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1
then
- echo
- echo "${LOCALSTATEDIR}/empty exists but is not a directory."
- echo "Cannot create ssh host configuration."
- echo
- exit 1
-if [ ! -e ${LOCALSTATEDIR}/empty ]
-then
- if ! mkdir -p ${LOCALSTATEDIR}/empty
- then
- echo
- echo "Creating ${LOCALSTATEDIR}/empty directory failed."
- echo "Cannot create ssh host configuration."
- echo
- exit 1
- fi
- if [ ${_nt} -gt 0 ]
- then
- chmod 755 ${LOCALSTATEDIR}/empty
- fi
-fi
-
-# First generate host keys if not already existing
-
-if [ ! -f "${SYSCONFDIR}/ssh_host_key" ]
-then
- echo "Generating ${SYSCONFDIR}/ssh_host_key"
- ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
-fi
-
-if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
-then
- echo "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
- ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
-fi
-
-if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ]
-then
- echo "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
- ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
-fi
-
-# Check if ssh_config exists. If yes, ask for overwriting
-
-if [ -f "${SYSCONFDIR}/ssh_config" ]
-then
- if request "Overwrite existing ${SYSCONFDIR}/ssh_config file?"
- then
- rm -f "${SYSCONFDIR}/ssh_config"
- if [ -f "${SYSCONFDIR}/ssh_config" ]
- then
- echo "Can't overwrite. ${SYSCONFDIR}/ssh_config is write protected."
- fi
- fi
-fi
-
-# Create default ssh_config from skeleton file in /etc/defaults/etc
-
-if [ ! -f "${SYSCONFDIR}/ssh_config" ]
-then
- echo "Generating ${SYSCONFDIR}/ssh_config file"
- cp ${SYSCONFDIR}/defaults/etc/ssh_config ${SYSCONFDIR}/ssh_config
if [ "${port_number}" != "22" ]
then
+ csih_inform "Updating ${SYSCONFDIR}/ssh_config file with requested port"
echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
echo " Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
fi
fi
-# Check if sshd_config exists. If yes, ask for overwriting
-
-if [ -f "${SYSCONFDIR}/sshd_config" ]
+# handle sshd_config (and privsep)
+csih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults"
+if ! cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
then
- if request "Overwrite existing ${SYSCONFDIR}/sshd_config file?"
- then
- rm -f "${SYSCONFDIR}/sshd_config"
- if [ -f "${SYSCONFDIR}/sshd_config" ]
- then
- echo "Can't overwrite. ${SYSCONFDIR}/sshd_config is write protected."
- fi
- else
- grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
- fi
+ grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
fi
+sshd_privsep
-# Prior to creating or modifying sshd_config, care for privilege separation
-if [ "${privsep_configured}" != "yes" ]
-then
- if [ ${_nt} -gt 0 ]
- then
- echo "Privilege separation is set to yes by default since OpenSSH 3.3."
- echo "However, this requires a non-privileged account called 'sshd'."
- echo "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
- echo
- if request "Should privilege separation be used?"
- then
- privsep_used=yes
- grep -q '^sshd:' ${SYSCONFDIR}/passwd && sshd_in_passwd=yes
- net user sshd >/dev/null 2>&1 && sshd_in_sam=yes
- if [ "${sshd_in_passwd}" != "yes" ]
- then
- if [ "${sshd_in_sam}" != "yes" ]
- then
- echo "Warning: The following function requires administrator privileges!"
- if request "Should this script create a local user 'sshd' on this machine?"
- then
- dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
- net user sshd /add /fullname:"sshd privsep" "/homedir:${dos_var_empty}" /active:no > /dev/null 2>&1 && sshd_in_sam=yes
- if [ "${sshd_in_sam}" != "yes" ]
- then
- echo "Warning: Creating the user 'sshd' failed!"
- fi
- fi
- fi
- if [ "${sshd_in_sam}" != "yes" ]
- then
- echo "Warning: Can't create user 'sshd' in ${SYSCONFDIR}/passwd!"
- echo " Privilege separation set to 'no' again!"
- echo " Check your ${SYSCONFDIR}/sshd_config file!"
- privsep_used=no
- else
- mkpasswd -l -u sshd | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
- fi
- fi
- else
- privsep_used=no
- 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
-# Create default sshd_config from skeleton files in /etc/defaults/etc or
-# modify to add the missing privsep configuration option
-
-if [ ! -f "${SYSCONFDIR}/sshd_config" ]
-then
- echo "Generating ${SYSCONFDIR}/sshd_config file"
- sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
- s/^#Port 22/Port ${port_number}/
- s/^#StrictModes yes/StrictModes no/" \
- < ${SYSCONFDIR}/defaults/etc/sshd_config \
- > ${SYSCONFDIR}/sshd_config
-elif [ "${privsep_configured}" != "yes" ]
-then
- echo >> ${SYSCONFDIR}/sshd_config
- echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
-fi
-
-# Care for services file
-_my_etcdir="/ssh-host-config.$$"
-if [ ${_nt} -gt 0 ]
-then
- _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
- _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.$$"
-
-mount -t -f "${_win_etcdir}" "${_my_etcdir}"
-
-# Depends on the above mount
-_wservices=`cygpath -w "${_services}"`
-
-# Remove sshd 22/port from services
-if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
-then
- grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
- if [ -f "${_serv_tmp}" ]
- then
- if mv "${_serv_tmp}" "${_services}"
- then
- echo "Removing sshd from ${_wservices}"
- else
- echo "Removing sshd from ${_wservices} failed!"
- fi
- rm -f "${_serv_tmp}"
- else
- echo "Removing sshd from ${_wservices} failed!"
- fi
-fi
-
-# Add ssh 22/tcp and ssh 22/udp to services
-if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
-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}"
- then
- if mv "${_serv_tmp}" "${_services}"
- then
- echo "Added ssh to ${_wservices}"
- else
- echo "Adding ssh to ${_wservices} failed!"
- fi
- rm -f "${_serv_tmp}"
- else
- echo "WARNING: Adding ssh to ${_wservices} failed!"
- fi
-fi
-
-umount "${_my_etcdir}"
-
-# Care for inetd.conf file
-_inetcnf="${SYSCONFDIR}/inetd.conf"
-_inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
-
-if [ -f "${_inetcnf}" ]
-then
- # Check if ssh service is already in use as sshd
- with_comment=1
- grep -q '^[ \t]*sshd' "${_inetcnf}" && with_comment=0
- # Remove sshd line from inetd.conf
- if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
- then
- grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
- if [ -f "${_inetcnf_tmp}" ]
- then
- if mv "${_inetcnf_tmp}" "${_inetcnf}"
- then
- echo "Removed sshd from ${_inetcnf}"
- else
- echo "Removing sshd from ${_inetcnf} failed!"
- fi
- rm -f "${_inetcnf_tmp}"
- else
- echo "Removing sshd from ${_inetcnf} failed!"
- fi
- fi
-
- # Add ssh line to inetd.conf
- if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
- then
- if [ "${with_comment}" -eq 0 ]
- then
- echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
- else
- echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
- fi
- echo "Added ssh to ${_inetcnf}"
- fi
-fi
-
-# On NT ask if sshd should be installed as service
-if [ ${_nt} -gt 0 ]
-then
- # But only if it is not already installed
- if ! cygrunsrv -Q sshd > /dev/null 2>&1
- then
- echo
- echo
- echo "Warning: The following functions require administrator privileges!"
- echo
- echo "Do you want to install sshd as service?"
- if request "(Say \"no\" if it's already installed as service)"
- then
- if [ $_nt2003 -gt 0 ]
- then
- grep -q '^sshd_server:' ${SYSCONFDIR}/passwd && sshd_server_in_passwd=yes
- if [ "${sshd_server_in_passwd}" = "yes" ]
- then
- # Drop sshd_server from passwd since it could have wrong settings
- grep -v '^sshd_server:' ${SYSCONFDIR}/passwd > ${SYSCONFDIR}/passwd.$$
- rm -f ${SYSCONFDIR}/passwd
- mv ${SYSCONFDIR}/passwd.$$ ${SYSCONFDIR}/passwd
- chmod g-w,o-w ${SYSCONFDIR}/passwd
- fi
- net user sshd_server >/dev/null 2>&1 && sshd_server_in_sam=yes
- if [ "${sshd_server_in_sam}" != "yes" ]
- then
- echo
- echo "You appear to be running Windows 2003 Server or later. On 2003 and"
- echo "later systems, it's not possible to use the LocalSystem account"
- echo "if sshd should allow passwordless logon (e. g. public key authentication)."
- echo "If you want to enable that functionality, it's required to create a new"
- echo "account 'sshd_server' with special privileges, which is then used to run"
- echo "the sshd service under."
- echo
- echo "Should this script create a new local account 'sshd_server' which has"
- if request "the required privileges?"
- then
- _admingroup=`mkgroup -l | awk -F: '{if ( $2 == "S-1-5-32-544" ) print $1;}' `
- if [ -z "${_admingroup}" ]
- then
- echo "mkgroup -l produces no group with SID S-1-5-32-544 (Local administrators group)."
- exit 1
- fi
- dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
- while [ "${sshd_server_in_sam}" != "yes" ]
- do
- if [ -n "${password_value}" ]
- then
- _password="${password_value}"
- # Allow to ask for password if first try fails
- password_value=""
- else
- echo
- echo "Please enter a password for new user 'sshd_server'. Please be sure that"
- echo "this password matches the password rules given on your system."
- echo -n "Entering no password will exit the configuration. PASSWORD="
- read -e _password
- if [ -z "${_password}" ]
- then
- echo
- echo "Exiting configuration. No user sshd_server has been created,"
- echo "no sshd service installed."
- exit 1
- fi
- fi
- net user sshd_server "${_password}" /add /fullname:"sshd server account" "/homedir:${dos_var_empty}" /yes > /tmp/nu.$$ 2>&1 && sshd_server_in_sam=yes
- if [ "${sshd_server_in_sam}" != "yes" ]
- then
- echo "Creating the user 'sshd_server' failed! Reason:"
- cat /tmp/nu.$$
- rm /tmp/nu.$$
- fi
- done
- net localgroup "${_admingroup}" sshd_server /add > /dev/null 2>&1 && sshd_server_in_admingroup=yes
- if [ "${sshd_server_in_admingroup}" != "yes" ]
- then
- echo "WARNING: Adding user sshd_server to local group ${_admingroup} failed!"
- echo "Please add sshd_server to local group ${_admingroup} before"
- echo "starting the sshd service!"
- echo
- fi
- passwd_has_expiry_flags=`passwd -v | awk '/^passwd /{print ( $3 >= 1.5 ) ? "yes" : "no";}'`
- if [ "${passwd_has_expiry_flags}" != "yes" ]
- then
- echo
- echo "WARNING: User sshd_server has password expiry set to system default."
- echo "Please check that password never expires or set it to your needs."
- elif ! passwd -e sshd_server
- then
- echo
- echo "WARNING: Setting password expiry for user sshd_server failed!"
- echo "Please check that password never expires or set it to your needs."
- fi
- editrights -a SeAssignPrimaryTokenPrivilege -u sshd_server &&
- editrights -a SeCreateTokenPrivilege -u sshd_server &&
- editrights -a SeTcbPrivilege -u sshd_server &&
- editrights -a SeDenyInteractiveLogonRight -u sshd_server &&
- editrights -a SeDenyNetworkLogonRight -u sshd_server &&
- editrights -a SeDenyRemoteInteractiveLogonRight -u sshd_server &&
- editrights -a SeIncreaseQuotaPrivilege -u sshd_server &&
- editrights -a SeServiceLogonRight -u sshd_server &&
- sshd_server_got_all_rights="yes"
- if [ "${sshd_server_got_all_rights}" != "yes" ]
- then
- echo
- echo "Assigning the appropriate privileges to user 'sshd_server' failed!"
- echo "Can't create sshd service!"
- exit 1
- fi
- echo
- echo "User 'sshd_server' has been created with password '${_password}'."
- echo "If you change the password, please keep in mind to change the password"
- echo "for the sshd service, too."
- echo
- echo "Also keep in mind that the user sshd_server needs read permissions on all"
- echo "users' .ssh/authorized_keys file to allow public key authentication for"
- echo "these users!. (Re-)running ssh-user-config for each user will set the"
- echo "required permissions correctly."
- echo
- fi
- fi
- if [ "${sshd_server_in_sam}" = "yes" ]
- then
- mkpasswd -l -u sshd_server | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
- fi
- fi
- if [ -n "${cygwin_value}" ]
- then
- _cygwin="${cygwin_value}"
- else
- echo
- echo "Which value should the environment variable CYGWIN have when"
- echo "sshd starts? It's recommended to set at least \"ntsec\" to be"
- echo "able to change user context without password."
- echo -n "Default is \"ntsec\". CYGWIN="
- read -e _cygwin
- fi
- [ -z "${_cygwin}" ] && _cygwin="ntsec"
- if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
- then
- if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -u sshd_server -w "${_password}" -e "CYGWIN=${_cygwin}" -y tcpip
- then
- echo
- echo "The service has been installed under sshd_server account."
- echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
- fi
- else
- if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -e "CYGWIN=${_cygwin}" -y tcpip
- then
- echo
- echo "The service has been installed under LocalSystem account."
- echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
- fi
- fi
- fi
- # Now check if sshd has been successfully installed. This allows to
- # set the ownership of the affected files correctly.
- if cygrunsrv -Q sshd > /dev/null 2>&1
- then
- if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
- then
- _user="sshd_server"
- else
- _user="system"
- fi
- chown "${_user}" ${SYSCONFDIR}/ssh*
- chown "${_user}".544 ${LOCALSTATEDIR}/empty
- chown "${_user}".544 ${LOCALSTATEDIR}/log/lastlog
- if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
- then
- chown "${_user}".544 ${LOCALSTATEDIR}/log/sshd.log
- fi
- fi
- if ! ( mount | egrep -q 'on /(|usr/(bin|lib)) type system' )
- then
- echo
- echo "Warning: It appears that you have user mode mounts (\"Just me\""
- echo "chosen during install.) Any daemons installed as services will"
- echo "fail to function unless system mounts are used. To change this,"
- echo "re-run setup.exe and choose \"All users\"."
- echo
- echo "For more information, see http://cygwin.com/faq/faq0.html#TOC33"
- fi
- fi
-fi
+update_services_file
+update_inetd_conf
+install_service
echo
-echo "Host configuration finished. Have fun!"
+csih_inform "Host configuration finished. Have fun!"
+
diff --git a/contrib/cygwin/ssh-user-config b/contrib/cygwin/ssh-user-config
index 9482efe..f210bd5 100644
--- a/contrib/cygwin/ssh-user-config
+++ b/contrib/cygwin/ssh-user-config
@@ -1,52 +1,235 @@
-#!/bin/sh
+#!/bin/bash
#
# ssh-user-config, Copyright 2000, 2001, 2002, 2003, Red Hat Inc.
#
# This file is part of the Cygwin port of OpenSSH.
+# ======================================================================
+# Initialization
+# ======================================================================
+PROGNAME=$(basename -- $0)
+_tdir=$(dirname -- $0)
+PROGDIR=$(cd $_tdir && pwd)
+
+CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh
+
+# Subdirectory where the new package is being installed
+PREFIX=/usr
+
# Directory where the config files are stored
SYSCONFDIR=/etc
-progname=$0
-auto_answer=""
+source ${CSIH_SCRIPT}
+
auto_passphrase="no"
passphrase=""
+pwdhome=
+with_passphrase=
-request()
-{
- if [ "${auto_answer}" = "yes" ]
+# ======================================================================
+# Routine: create_ssh1_identity
+# optionally create ~/.ssh/identity[.pub]
+# optionally add result to ~/.ssh/authorized_keys
+# ======================================================================
+create_ssh1_identity() {
+ if [ ! -f "${pwdhome}/.ssh/identity" ]
then
- return 0
- elif [ "${auto_answer}" = "no" ]
- then
- return 1
+ if csih_request "Shall I create an SSH1 RSA identity file for you?"
+ then
+ csih_inform "Generating ${pwdhome}/.ssh/identity"
+ if [ "${with_passphrase}" = "yes" ]
+ then
+ ssh-keygen -t rsa1 -N "${passphrase}" -f "${pwdhome}/.ssh/identity" > /dev/null
+ else
+ ssh-keygen -t rsa1 -f "${pwdhome}/.ssh/identity" > /dev/null
+ fi
+ if csih_request "Do you want to use this identity to login to this machine?"
+ then
+ csih_inform "Adding to ${pwdhome}/.ssh/authorized_keys"
+ cat "${pwdhome}/.ssh/identity.pub" >> "${pwdhome}/.ssh/authorized_keys"
+ fi
+ fi
fi
+} # === End of create_ssh1_identity() === #
+readonly -f create_ssh1_identity
- answer=""
- while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ]
- do
- echo -n "$1 (yes/no) "
- read answer
- done
- if [ "X${answer}" = "Xyes" ]
+# ======================================================================
+# Routine: create_ssh2_rsa_identity
+# optionally create ~/.ssh/id_rsa[.pub]
+# optionally add result to ~/.ssh/authorized_keys
+# ======================================================================
+create_ssh2_rsa_identity() {
+ if [ ! -f "${pwdhome}/.ssh/id_rsa" ]
then
- return 0
- else
- return 1
+ if csih_request "Shall I create an SSH2 RSA identity file for you?"
+ then
+ csih_inform "Generating ${pwdhome}/.ssh/id_rsa"
+ if [ "${with_passphrase}" = "yes" ]
+ then
+ ssh-keygen -t rsa -N "${passphrase}" -f "${pwdhome}/.ssh/id_rsa" > /dev/null
+ else
+ ssh-keygen -t rsa -f "${pwdhome}/.ssh/id_rsa" > /dev/null
+ fi
+ if csih_request "Do you want to use this identity to login to this machine?"
+ then
+ csih_inform "Adding to ${pwdhome}/.ssh/authorized_keys"
+ cat "${pwdhome}/.ssh/id_rsa.pub" >> "${pwdhome}/.ssh/authorized_keys"
+ fi
+ fi
fi
-}
+} # === End of create_ssh2_rsa_identity() === #
+readonly -f create_ssh2_rsa_identity
-# Check if running on NT
-_sys="`uname -a`"
-_nt=`expr "$_sys" : "CYGWIN_NT"`
-# If running on NT, check if running under 2003 Server or later
-if [ $_nt -gt 0 ]
+# ======================================================================
+# Routine: create_ssh2_dsa_identity
+# optionally create ~/.ssh/id_dsa[.pub]
+# optionally add result to ~/.ssh/authorized_keys
+# ======================================================================
+create_ssh2_dsa_identity() {
+ if [ ! -f "${pwdhome}/.ssh/id_dsa" ]
+ then
+ if csih_request "Shall I create an SSH2 DSA identity file for you?"
+ then
+ csih_inform "Generating ${pwdhome}/.ssh/id_dsa"
+ if [ "${with_passphrase}" = "yes" ]
+ then
+ ssh-keygen -t dsa -N "${passphrase}" -f "${pwdhome}/.ssh/id_dsa" > /dev/null
+ else
+ ssh-keygen -t dsa -f "${pwdhome}/.ssh/id_dsa" > /dev/null
+ fi
+ if csih_request "Do you want to use this identity to login to this machine?"
+ then
+ csih_inform "Adding to ${pwdhome}/.ssh/authorized_keys"
+ cat "${pwdhome}/.ssh/id_dsa.pub" >> "${pwdhome}/.ssh/authorized_keys"
+ fi
+ fi
+ fi
+} # === End of create_ssh2_dsa_identity() === #
+readonly -f create_ssh2_dsa_identity
+
+# ======================================================================
+# Routine: check_user_homedir
+# Perform various checks on the user's home directory
+# SETS GLOBAL VARIABLE:
+# pwdhome
+# ======================================================================
+check_user_homedir() {
+ local uid=$(id -u)
+ pwdhome=$(awk -F: '{ if ( $3 == '${uid}' ) print $6; }' < ${SYSCONFDIR}/passwd)
+ if [ "X${pwdhome}" = "X" ]
+ then
+ csih_error_multiline \
+ "There is no home directory set for you in ${SYSCONFDIR}/passwd." \
+ 'Setting $HOME is not sufficient!'
+ fi
+
+ if [ ! -d "${pwdhome}" ]
+ then
+ csih_error_multiline \
+ "${pwdhome} is set in ${SYSCONFDIR}/passwd as your home directory" \
+ 'but it is not a valid directory. Cannot create user identity files.'
+ fi
+
+ # If home is the root dir, set home to empty string to avoid error messages
+ # in subsequent parts of that script.
+ if [ "X${pwdhome}" = "X/" ]
+ then
+ # But first raise a warning!
+ csih_warning "Your home directory in ${SYSCONFDIR}/passwd is set to root (/). This is not recommended!"
+ if csih_request "Would you like to proceed anyway?"
+ then
+ pwdhome=''
+ else
+ csih_warning "Exiting. Configuration is not complete"
+ exit 1
+ fi
+ fi
+
+ if [ -d "${pwdhome}" -a csih_is_nt -a -n "`chmod -c g-w,o-w "${pwdhome}"`" ]
+ then
+ echo
+ csih_warning 'group and other have been revoked write permission to your home'
+ csih_warning "directory ${pwdhome}."
+ csih_warning 'This is required by OpenSSH to allow public key authentication using'
+ csih_warning 'the key files stored in your .ssh subdirectory.'
+ csih_warning 'Revert this change ONLY if you know what you are doing!'
+ echo
+ fi
+} # === End of check_user_homedir() === #
+readonly -f check_user_homedir
+
+# ======================================================================
+# Routine: check_user_dot_ssh_dir
+# Perform various checks on the ~/.ssh directory
+# PREREQUISITE:
+# pwdhome -- check_user_homedir()
+# ======================================================================
+check_user_dot_ssh_dir() {
+ if [ -e "${pwdhome}/.ssh" -a ! -d "${pwdhome}/.ssh" ]
+ then
+ csih_error "${pwdhome}/.ssh is existant but not a directory. Cannot create user identity files."
+ fi
+
+ if [ ! -e "${pwdhome}/.ssh" ]
+ then
+ mkdir "${pwdhome}/.ssh"
+ if [ ! -e "${pwdhome}/.ssh" ]
+ then
+ csih_error "Creating users ${pwdhome}/.ssh directory failed"
+ fi
+ fi
+} # === End of check_user_dot_ssh_dir() === #
+readonly -f check_user_dot_ssh_dir
+
+# ======================================================================
+# Routine: fix_authorized_keys_perms
+# Corrects the permissions of ~/.ssh/authorized_keys
+# PREREQUISITE:
+# pwdhome -- check_user_homedir()
+# ======================================================================
+fix_authorized_keys_perms() {
+ if [ csih_is_nt -a -e "${pwdhome}/.ssh/authorized_keys" ]
+ then
+ if ! setfacl -m "u::rw-,g::---,o::---" "${pwdhome}/.ssh/authorized_keys"
+ then
+ csih_warning "Setting correct permissions to ${pwdhome}/.ssh/authorized_keys"
+ csih_warning "failed. Please care for the correct permissions. The minimum requirement"
+ csih_warning "is, the owner needs read permissions."
+ echo
+ fi
+ fi
+} # === End of fix_authorized_keys_perms() === #
+readonly -f fix_authorized_keys_perms
+
+
+# ======================================================================
+# Main Entry Point
+# ======================================================================
+
+# Check how the script has been started. If
+# (1) it has been started by giving the full path and
+# that path is /etc/postinstall, OR
+# (2) Otherwise, if the environment variable
+# SSH_USER_CONFIG_AUTO_ANSWER_NO is set
+# then set auto_answer to "no". This allows automatic
+# creation of the config files in /etc w/o overwriting
+# them if they already exist. In both cases, color
+# escape sequences are suppressed, so as to prevent
+# cluttering setup's logfiles.
+if [ "$PROGDIR" = "/etc/postinstall" ]
then
- _nt2003=`uname | awk -F- '{print ( $2 >= 5.2 ) ? 1 : 0;}'`
+ csih_auto_answer="no"
+ csih_disable_color
+fi
+if [ -n "${SSH_USER_CONFIG_AUTO_ANSWER_NO}" ]
+then
+ csih_auto_answer="no"
+ csih_disable_color
fi
-# Check options
-
+# ======================================================================
+# Parse options
+# ======================================================================
while :
do
case $# in
@@ -61,14 +244,15 @@
case "$option" in
-d | --debug )
set -x
+ csih_trace_on
;;
-y | --yes )
- auto_answer=yes
+ csih_auto_answer=yes
;;
-n | --no )
- auto_answer=no
+ csih_auto_answer=no
;;
-p | --passphrase )
@@ -77,8 +261,12 @@
shift
;;
+ --privileged )
+ csih_FORCE_PRIVILEGED_USER=yes
+ ;;
+
*)
- echo "usage: ${progname} [OPTION]..."
+ echo "usage: ${PROGNAME} [OPTION]..."
echo
echo "This script creates an OpenSSH user configuration."
echo
@@ -87,6 +275,8 @@
echo " --yes -y Answer all questions with \"yes\" automatically."
echo " --no -n Answer all questions with \"no\" automatically."
echo " --passphrase -p word Use \"word\" as passphrase automatically."
+ echo " --privileged On Windows NT/2k/XP, assume privileged user"
+ echo " instead of LocalSystem for sshd service."
echo
exit 1
;;
@@ -94,157 +284,27 @@
esac
done
-# Ask user if user identity should be generated
+# ======================================================================
+# Action!
+# ======================================================================
+# Check passwd file
if [ ! -f ${SYSCONFDIR}/passwd ]
then
- echo "${SYSCONFDIR}/passwd is nonexistant. Please generate an ${SYSCONFDIR}/passwd file"
- echo 'first using mkpasswd. Check if it contains an entry for you and'
- echo 'please care for the home directory in your entry as well.'
- exit 1
+ csih_error_multiline \
+ "${SYSCONFDIR}/passwd is nonexistant. Please generate an ${SYSCONFDIR}/passwd file" \
+ 'first using mkpasswd. Check if it contains an entry for you and' \
+ 'please care for the home directory in your entry as well.'
fi
-uid=`id -u`
-pwdhome=`awk -F: '{ if ( $3 == '${uid}' ) print $6; }' < ${SYSCONFDIR}/passwd`
-
-if [ "X${pwdhome}" = "X" ]
-then
- echo "There is no home directory set for you in ${SYSCONFDIR}/passwd."
- echo 'Setting $HOME is not sufficient!'
- exit 1
-fi
-
-if [ ! -d "${pwdhome}" ]
-then
- echo "${pwdhome} is set in ${SYSCONFDIR}/passwd as your home directory"
- echo 'but it is not a valid directory. Cannot create user identity files.'
- exit 1
-fi
-
-# If home is the root dir, set home to empty string to avoid error messages
-# in subsequent parts of that script.
-if [ "X${pwdhome}" = "X/" ]
-then
- # But first raise a warning!
- echo "Your home directory in ${SYSCONFDIR}/passwd is set to root (/). This is not recommended!"
- if request "Would you like to proceed anyway?"
- then
- pwdhome=''
- else
- exit 1
- fi
-fi
-
-if [ -d "${pwdhome}" -a $_nt -gt 0 -a -n "`chmod -c g-w,o-w "${pwdhome}"`" ]
-then
- echo
- echo 'WARNING: group and other have been revoked write permission to your home'
- echo " directory ${pwdhome}."
- echo ' This is required by OpenSSH to allow public key authentication using'
- echo ' the key files stored in your .ssh subdirectory.'
- echo ' Revert this change ONLY if you know what you are doing!'
- echo
-fi
-
-if [ -e "${pwdhome}/.ssh" -a ! -d "${pwdhome}/.ssh" ]
-then
- echo "${pwdhome}/.ssh is existant but not a directory. Cannot create user identity files."
- exit 1
-fi
-
-if [ ! -e "${pwdhome}/.ssh" ]
-then
- mkdir "${pwdhome}/.ssh"
- if [ ! -e "${pwdhome}/.ssh" ]
- then
- echo "Creating users ${pwdhome}/.ssh directory failed"
- exit 1
- fi
-fi
-
-if [ $_nt -gt 0 ]
-then
- _user="system"
- if [ $_nt2003 -gt 0 ]
- then
- grep -q '^sshd_server:' ${SYSCONFDIR}/passwd && _user="sshd_server"
- fi
- if ! setfacl -m "u::rwx,u:${_user}:r--,g::---,o::---" "${pwdhome}/.ssh"
- then
- echo "${pwdhome}/.ssh couldn't be given the correct permissions."
- echo "Please try to solve this problem first."
- exit 1
- fi
-fi
-
-if [ ! -f "${pwdhome}/.ssh/identity" ]
-then
- if request "Shall I create an SSH1 RSA identity file for you?"
- then
- echo "Generating ${pwdhome}/.ssh/identity"
- if [ "${with_passphrase}" = "yes" ]
- then
- ssh-keygen -t rsa1 -N "${passphrase}" -f "${pwdhome}/.ssh/identity" > /dev/null
- else
- ssh-keygen -t rsa1 -f "${pwdhome}/.ssh/identity" > /dev/null
- fi
- if request "Do you want to use this identity to login to this machine?"
- then
- echo "Adding to ${pwdhome}/.ssh/authorized_keys"
- cat "${pwdhome}/.ssh/identity.pub" >> "${pwdhome}/.ssh/authorized_keys"
- fi
- fi
-fi
-
-if [ ! -f "${pwdhome}/.ssh/id_rsa" ]
-then
- if request "Shall I create an SSH2 RSA identity file for you?"
- then
- echo "Generating ${pwdhome}/.ssh/id_rsa"
- if [ "${with_passphrase}" = "yes" ]
- then
- ssh-keygen -t rsa -N "${passphrase}" -f "${pwdhome}/.ssh/id_rsa" > /dev/null
- else
- ssh-keygen -t rsa -f "${pwdhome}/.ssh/id_rsa" > /dev/null
- fi
- if request "Do you want to use this identity to login to this machine?"
- then
- echo "Adding to ${pwdhome}/.ssh/authorized_keys"
- cat "${pwdhome}/.ssh/id_rsa.pub" >> "${pwdhome}/.ssh/authorized_keys"
- fi
- fi
-fi
-
-if [ ! -f "${pwdhome}/.ssh/id_dsa" ]
-then
- if request "Shall I create an SSH2 DSA identity file for you?"
- then
- echo "Generating ${pwdhome}/.ssh/id_dsa"
- if [ "${with_passphrase}" = "yes" ]
- then
- ssh-keygen -t dsa -N "${passphrase}" -f "${pwdhome}/.ssh/id_dsa" > /dev/null
- else
- ssh-keygen -t dsa -f "${pwdhome}/.ssh/id_dsa" > /dev/null
- fi
- if request "Do you want to use this identity to login to this machine?"
- then
- echo "Adding to ${pwdhome}/.ssh/authorized_keys"
- cat "${pwdhome}/.ssh/id_dsa.pub" >> "${pwdhome}/.ssh/authorized_keys"
- fi
- fi
-fi
-
-if [ $_nt -gt 0 -a -e "${pwdhome}/.ssh/authorized_keys" ]
-then
- if ! setfacl -m "u::rw-,u:${_user}:r--,g::---,o::---" "${pwdhome}/.ssh/authorized_keys"
- then
- echo
- echo "WARNING: Setting correct permissions to ${pwdhome}/.ssh/authorized_keys"
- echo "failed. Please care for the correct permissions. The minimum requirement"
- echo "is, the owner and ${_user} both need read permissions."
- echo
- fi
-fi
+check_user_homedir
+check_user_dot_ssh_dir
+create_ssh1_identity
+create_ssh2_rsa_identity
+create_ssh2_dsa_identity
+fix_authorized_keys_perms
echo
-echo "Configuration finished. Have fun!"
+csih_inform "Configuration finished. Have fun!"
+
+
diff --git a/contrib/cygwin/sshd-inetd b/contrib/cygwin/sshd-inetd
new file mode 100644
index 0000000..aa6bf07
--- /dev/null
+++ b/contrib/cygwin/sshd-inetd
@@ -0,0 +1,4 @@
+# This file can be used to enable sshd as a slave of the inetd service
+# To do so, the line below should be uncommented.
+@COMMENT@ ssh stream tcp nowait root /usr/sbin/sshd sshd -i
+