3 # ssh-host-config, Copyright 2000, 2001, 2002, 2003 Red Hat Inc.
5 # This file is part of the Cygwin port of OpenSSH.
7 # Subdirectory where the new package is being installed
10 # Directory where the config files are stored
25 if [ "${auto_answer}" = "yes" ]
27 echo "$1 (yes/no) yes"
29 elif [ "${auto_answer}" = "no" ]
36 while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ]
38 echo -n "$1 (yes/no) "
41 if [ "X${answer}" = "Xyes" ]
91 echo "usage: ${progname} [OPTION]..."
93 echo "This script creates an OpenSSH host configuration."
96 echo " --debug -d Enable shell's debug output."
97 echo " --yes -y Answer all questions with \"yes\" automatically."
98 echo " --no -n Answer all questions with \"no\" automatically."
99 echo " --cygwin -c <options> Use \"options\" as value for CYGWIN environment var."
100 echo " --port -p <n> sshd listens on port n."
101 echo " --pwd -w <passwd> Use \"pwd\" as password for user 'sshd_server'."
109 # Check if running on NT
111 _nt=`expr "${_sys}" : "CYGWIN_NT"`
112 # If running on NT, check if running under 2003 Server or later
115 _nt2003=`uname | awk -F- '{print ( $2 >= 5.2 ) ? 1 : 0;}'`
118 # Check for running ssh/sshd processes first. Refuse to do anything while
119 # some ssh processes are still running
121 if ps -ef | grep -v grep | grep -q ssh
124 echo "There are still ssh processes running. Please shut them down first."
129 # Check for ${SYSCONFDIR} directory
131 if [ -e "${SYSCONFDIR}" -a ! -d "${SYSCONFDIR}" ]
134 echo "${SYSCONFDIR} is existant but not a directory."
135 echo "Cannot create global configuration files."
140 # Create it if necessary
142 if [ ! -e "${SYSCONFDIR}" ]
144 mkdir "${SYSCONFDIR}"
145 if [ ! -e "${SYSCONFDIR}" ]
148 echo "Creating ${SYSCONFDIR} directory failed"
154 # Create /var/log and /var/log/lastlog if not already existing
156 if [ -f ${LOCALSTATEDIR}/log ]
158 echo "Creating ${LOCALSTATEDIR}/log failed!"
160 if [ ! -d ${LOCALSTATEDIR}/log ]
162 mkdir -p ${LOCALSTATEDIR}/log
164 if [ -d ${LOCALSTATEDIR}/log/lastlog ]
166 chmod 777 ${LOCALSTATEDIR}/log/lastlog
167 elif [ ! -f ${LOCALSTATEDIR}/log/lastlog ]
169 cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
170 chmod 666 ${LOCALSTATEDIR}/log/lastlog
174 # Create /var/empty file used as chroot jail for privilege separation
175 if [ -f ${LOCALSTATEDIR}/empty ]
177 echo "Creating ${LOCALSTATEDIR}/empty failed!"
179 mkdir -p ${LOCALSTATEDIR}/empty
182 chmod 755 ${LOCALSTATEDIR}/empty
186 # First generate host keys if not already existing
188 if [ ! -f "${SYSCONFDIR}/ssh_host_key" ]
190 echo "Generating ${SYSCONFDIR}/ssh_host_key"
191 ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
194 if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
196 echo "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
197 ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
200 if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ]
202 echo "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
203 ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
206 # Check if ssh_config exists. If yes, ask for overwriting
208 if [ -f "${SYSCONFDIR}/ssh_config" ]
210 if request "Overwrite existing ${SYSCONFDIR}/ssh_config file?"
212 rm -f "${SYSCONFDIR}/ssh_config"
213 if [ -f "${SYSCONFDIR}/ssh_config" ]
215 echo "Can't overwrite. ${SYSCONFDIR}/ssh_config is write protected."
220 # Create default ssh_config from skeleton file in /etc/defaults/etc
222 if [ ! -f "${SYSCONFDIR}/ssh_config" ]
224 echo "Generating ${SYSCONFDIR}/ssh_config file"
225 cp ${SYSCONFDIR}/defaults/etc/ssh_config ${SYSCONFDIR}/ssh_config
226 if [ "${port_number}" != "22" ]
228 echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
229 echo " Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
233 # Check if sshd_config exists. If yes, ask for overwriting
235 if [ -f "${SYSCONFDIR}/sshd_config" ]
237 if request "Overwrite existing ${SYSCONFDIR}/sshd_config file?"
239 rm -f "${SYSCONFDIR}/sshd_config"
240 if [ -f "${SYSCONFDIR}/sshd_config" ]
242 echo "Can't overwrite. ${SYSCONFDIR}/sshd_config is write protected."
245 grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
249 # Prior to creating or modifying sshd_config, care for privilege separation
251 if [ "${privsep_configured}" != "yes" ]
255 echo "Privilege separation is set to yes by default since OpenSSH 3.3."
256 echo "However, this requires a non-privileged account called 'sshd'."
257 echo "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
259 if request "Should privilege separation be used?"
262 grep -q '^sshd:' ${SYSCONFDIR}/passwd && sshd_in_passwd=yes
263 net user sshd >/dev/null 2>&1 && sshd_in_sam=yes
264 if [ "${sshd_in_passwd}" != "yes" ]
266 if [ "${sshd_in_sam}" != "yes" ]
268 echo "Warning: The following function requires administrator privileges!"
269 if request "Should this script create a local user 'sshd' on this machine?"
271 dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
272 net user sshd /add /fullname:"sshd privsep" "/homedir:${dos_var_empty}" /active:no > /dev/null 2>&1 && sshd_in_sam=yes
273 if [ "${sshd_in_sam}" != "yes" ]
275 echo "Warning: Creating the user 'sshd' failed!"
279 if [ "${sshd_in_sam}" != "yes" ]
281 echo "Warning: Can't create user 'sshd' in ${SYSCONFDIR}/passwd!"
282 echo " Privilege separation set to 'no' again!"
283 echo " Check your ${SYSCONFDIR}/sshd_config file!"
286 mkpasswd -l -u sshd | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
293 # On 9x don't use privilege separation. Since security isn't
294 # available it just adds useless additional processes.
299 # Create default sshd_config from skeleton files in /etc/defaults/etc or
300 # modify to add the missing privsep configuration option
302 if [ ! -f "${SYSCONFDIR}/sshd_config" ]
304 echo "Generating ${SYSCONFDIR}/sshd_config file"
305 sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
306 s/^#Port 22/Port ${port_number}/
307 s/^#StrictModes yes/StrictModes no/" \
308 < ${SYSCONFDIR}/defaults/etc/sshd_config \
309 > ${SYSCONFDIR}/sshd_config
310 elif [ "${privsep_configured}" != "yes" ]
312 echo >> ${SYSCONFDIR}/sshd_config
313 echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
316 # Care for services file
317 _my_etcdir="/ssh-host-config.$$"
320 _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
321 _services="${_my_etcdir}/services"
322 # On NT, 27 spaces, no space after the hash
325 _win_etcdir="${WINDIR}"
326 _services="${_my_etcdir}/SERVICES"
327 # On 9x, 18 spaces (95 is very touchy), a space after the hash
330 _serv_tmp="${_my_etcdir}/srv.out.$$"
332 mount -t -f "${_win_etcdir}" "${_my_etcdir}"
334 # Depends on the above mount
335 _wservices=`cygpath -w "${_services}"`
337 # Remove sshd 22/port from services
338 if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
340 grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
341 if [ -f "${_serv_tmp}" ]
343 if mv "${_serv_tmp}" "${_services}"
345 echo "Removing sshd from ${_wservices}"
347 echo "Removing sshd from ${_wservices} failed!"
351 echo "Removing sshd from ${_wservices} failed!"
355 # Add ssh 22/tcp and ssh 22/udp to services
356 if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
358 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}"
360 if mv "${_serv_tmp}" "${_services}"
362 echo "Added ssh to ${_wservices}"
364 echo "Adding ssh to ${_wservices} failed!"
368 echo "WARNING: Adding ssh to ${_wservices} failed!"
372 umount "${_my_etcdir}"
374 # Care for inetd.conf file
375 _inetcnf="${SYSCONFDIR}/inetd.conf"
376 _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
378 if [ -f "${_inetcnf}" ]
380 # Check if ssh service is already in use as sshd
382 grep -q '^[ \t]*sshd' "${_inetcnf}" && with_comment=0
383 # Remove sshd line from inetd.conf
384 if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
386 grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
387 if [ -f "${_inetcnf_tmp}" ]
389 if mv "${_inetcnf_tmp}" "${_inetcnf}"
391 echo "Removed sshd from ${_inetcnf}"
393 echo "Removing sshd from ${_inetcnf} failed!"
395 rm -f "${_inetcnf_tmp}"
397 echo "Removing sshd from ${_inetcnf} failed!"
401 # Add ssh line to inetd.conf
402 if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
404 if [ "${with_comment}" -eq 0 ]
406 echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
408 echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
410 echo "Added ssh to ${_inetcnf}"
414 # On NT ask if sshd should be installed as service
417 # But only if it is not already installed
418 if ! cygrunsrv -Q sshd > /dev/null 2>&1
422 echo "Warning: The following functions require administrator privileges!"
424 echo "Do you want to install sshd as service?"
425 if request "(Say \"no\" if it's already installed as service)"
427 if [ $_nt2003 -gt 0 ]
429 grep -q '^sshd_server:' ${SYSCONFDIR}/passwd && sshd_server_in_passwd=yes
430 if [ "${sshd_server_in_passwd}" = "yes" ]
432 # Drop sshd_server from passwd since it could have wrong settings
433 grep -v '^sshd_server:' ${SYSCONFDIR}/passwd > ${SYSCONFDIR}/passwd.$$
434 rm -f ${SYSCONFDIR}/passwd
435 mv ${SYSCONFDIR}/passwd.$$ ${SYSCONFDIR}/passwd
436 chmod g-w,o-w ${SYSCONFDIR}/passwd
438 net user sshd_server >/dev/null 2>&1 && sshd_server_in_sam=yes
439 if [ "${sshd_server_in_sam}" != "yes" ]
442 echo "You appear to be running Windows 2003 Server or later. On 2003 and"
443 echo "later systems, it's not possible to use the LocalSystem account"
444 echo "if sshd should allow passwordless logon (e. g. public key authentication)."
445 echo "If you want to enable that functionality, it's required to create a new"
446 echo "account 'sshd_server' with special privileges, which is then used to run"
447 echo "the sshd service under."
449 echo "Should this script create a new local account 'sshd_server' which has"
450 if request "the required privileges?"
452 _admingroup=`mkgroup -l | awk -F: '{if ( $2 == "S-1-5-32-544" ) print $1;}' `
453 if [ -z "${_admingroup}" ]
455 echo "mkgroup -l produces no group with SID S-1-5-32-544 (Local administrators group)."
458 dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
459 while [ "${sshd_server_in_sam}" != "yes" ]
461 if [ -n "${password_value}" ]
463 _password="${password_value}"
464 # Allow to ask for password if first try fails
468 echo "Please enter a password for new user 'sshd_server'. Please be sure that"
469 echo "this password matches the password rules given on your system."
470 echo -n "Entering no password will exit the configuration. PASSWORD="
472 if [ -z "${_password}" ]
475 echo "Exiting configuration. No user sshd_server has been created,"
476 echo "no sshd service installed."
480 net user sshd_server "${_password}" /add /fullname:"sshd server account" "/homedir:${dos_var_empty}" /yes > /tmp/nu.$$ 2>&1 && sshd_server_in_sam=yes
481 if [ "${sshd_server_in_sam}" != "yes" ]
483 echo "Creating the user 'sshd_server' failed! Reason:"
488 net localgroup "${_admingroup}" sshd_server /add > /dev/null 2>&1 && sshd_server_in_admingroup=yes
489 if [ "${sshd_server_in_admingroup}" != "yes" ]
491 echo "WARNING: Adding user sshd_server to local group ${_admingroup} failed!"
492 echo "Please add sshd_server to local group ${_admingroup} before"
493 echo "starting the sshd service!"
496 passwd_has_expiry_flags=`passwd -v | awk '/^passwd /{print ( $3 >= 1.5 ) ? "yes" : "no";}'`
497 if [ "${passwd_has_expiry_flags}" != "yes" ]
500 echo "WARNING: User sshd_server has password expiry set to system default."
501 echo "Please check that password never expires or set it to your needs."
502 elif ! passwd -e sshd_server
505 echo "WARNING: Setting password expiry for user sshd_server failed!"
506 echo "Please check that password never expires or set it to your needs."
508 editrights -a SeAssignPrimaryTokenPrivilege -u sshd_server &&
509 editrights -a SeCreateTokenPrivilege -u sshd_server &&
510 editrights -a SeDenyInteractiveLogonRight -u sshd_server &&
511 editrights -a SeDenyNetworkLogonRight -u sshd_server &&
512 editrights -a SeDenyRemoteInteractiveLogonRight -u sshd_server &&
513 editrights -a SeIncreaseQuotaPrivilege -u sshd_server &&
514 editrights -a SeServiceLogonRight -u sshd_server &&
515 sshd_server_got_all_rights="yes"
516 if [ "${sshd_server_got_all_rights}" != "yes" ]
519 echo "Assigning the appropriate privileges to user 'sshd_server' failed!"
520 echo "Can't create sshd service!"
524 echo "User 'sshd_server' has been created with password '${_password}'."
525 echo "If you change the password, please keep in mind to change the password"
526 echo "for the sshd service, too."
528 echo "Also keep in mind that the user sshd_server needs read permissions on all"
529 echo "users' .ssh/authorized_keys file to allow public key authentication for"
530 echo "these users!. (Re-)running ssh-user-config for each user will set the"
531 echo "required permissions correctly."
535 if [ "${sshd_server_in_sam}" = "yes" ]
537 mkpasswd -l -u sshd_server | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
540 if [ -n "${cygwin_value}" ]
542 _cygwin="${cygwin_value}"
545 echo "Which value should the environment variable CYGWIN have when"
546 echo "sshd starts? It's recommended to set at least \"ntsec\" to be"
547 echo "able to change user context without password."
548 echo -n "Default is \"ntsec\". CYGWIN="
551 [ -z "${_cygwin}" ] && _cygwin="ntsec"
552 if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
554 if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -u sshd_server -w "${_password}" -e "CYGWIN=${_cygwin}"
557 echo "The service has been installed under sshd_server account."
558 echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
561 if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -e "CYGWIN=${_cygwin}"
564 echo "The service has been installed under LocalSystem account."
565 echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
569 # Now check if sshd has been successfully installed. This allows to
570 # set the ownership of the affected files correctly.
571 if cygrunsrv -Q sshd > /dev/null 2>&1
573 if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
579 chown "${_user}" ${SYSCONFDIR}/ssh*
580 chown "${_user}".544 ${LOCALSTATEDIR}/empty
581 if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
583 chown "${_user}".544 ${LOCALSTATEDIR}/log/sshd.log
586 if ! ( mount | egrep -q 'on /(|usr/(bin|lib)) type system' )
589 echo "Warning: It appears that you have user mode mounts (\"Just me\""
590 echo "chosen during install.) Any daemons installed as services will"
591 echo "fail to function unless system mounts are used. To change this,"
592 echo "re-run setup.exe and choose \"All users\"."
594 echo "For more information, see http://cygwin.com/faq/faq0.html#TOC33"
600 echo "Host configuration finished. Have fun!"