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 [ -e ${LOCALSTATEDIR}/log -a ! -d ${LOCALSTATEDIR}/log ]
159 echo "${LOCALSTATEDIR}/log is existant but not a directory."
160 echo "Cannot create ssh host configuration."
164 if [ ! -e ${LOCALSTATEDIR}/log ]
166 mkdir -p ${LOCALSTATEDIR}/log
169 if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ]
172 echo "${LOCALSTATEDIR}/log/lastlog exists, but is not a file."
173 echo "Cannot create ssh host configuration."
177 if [ ! -e ${LOCALSTATEDIR}/log/lastlog ]
179 cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
180 chmod 644 ${LOCALSTATEDIR}/log/lastlog
183 # Create /var/empty file used as chroot jail for privilege separation
184 if [ -f ${LOCALSTATEDIR}/empty ]
186 echo "Creating ${LOCALSTATEDIR}/empty failed!"
188 mkdir -p ${LOCALSTATEDIR}/empty
191 chmod 755 ${LOCALSTATEDIR}/empty
195 # First generate host keys if not already existing
197 if [ ! -f "${SYSCONFDIR}/ssh_host_key" ]
199 echo "Generating ${SYSCONFDIR}/ssh_host_key"
200 ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
203 if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
205 echo "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
206 ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
209 if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ]
211 echo "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
212 ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
215 # Check if ssh_config exists. If yes, ask for overwriting
217 if [ -f "${SYSCONFDIR}/ssh_config" ]
219 if request "Overwrite existing ${SYSCONFDIR}/ssh_config file?"
221 rm -f "${SYSCONFDIR}/ssh_config"
222 if [ -f "${SYSCONFDIR}/ssh_config" ]
224 echo "Can't overwrite. ${SYSCONFDIR}/ssh_config is write protected."
229 # Create default ssh_config from skeleton file in /etc/defaults/etc
231 if [ ! -f "${SYSCONFDIR}/ssh_config" ]
233 echo "Generating ${SYSCONFDIR}/ssh_config file"
234 cp ${SYSCONFDIR}/defaults/etc/ssh_config ${SYSCONFDIR}/ssh_config
235 if [ "${port_number}" != "22" ]
237 echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
238 echo " Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
242 # Check if sshd_config exists. If yes, ask for overwriting
244 if [ -f "${SYSCONFDIR}/sshd_config" ]
246 if request "Overwrite existing ${SYSCONFDIR}/sshd_config file?"
248 rm -f "${SYSCONFDIR}/sshd_config"
249 if [ -f "${SYSCONFDIR}/sshd_config" ]
251 echo "Can't overwrite. ${SYSCONFDIR}/sshd_config is write protected."
254 grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
258 # Prior to creating or modifying sshd_config, care for privilege separation
260 if [ "${privsep_configured}" != "yes" ]
264 echo "Privilege separation is set to yes by default since OpenSSH 3.3."
265 echo "However, this requires a non-privileged account called 'sshd'."
266 echo "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
268 if request "Should privilege separation be used?"
271 grep -q '^sshd:' ${SYSCONFDIR}/passwd && sshd_in_passwd=yes
272 net user sshd >/dev/null 2>&1 && sshd_in_sam=yes
273 if [ "${sshd_in_passwd}" != "yes" ]
275 if [ "${sshd_in_sam}" != "yes" ]
277 echo "Warning: The following function requires administrator privileges!"
278 if request "Should this script create a local user 'sshd' on this machine?"
280 dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
281 net user sshd /add /fullname:"sshd privsep" "/homedir:${dos_var_empty}" /active:no > /dev/null 2>&1 && sshd_in_sam=yes
282 if [ "${sshd_in_sam}" != "yes" ]
284 echo "Warning: Creating the user 'sshd' failed!"
288 if [ "${sshd_in_sam}" != "yes" ]
290 echo "Warning: Can't create user 'sshd' in ${SYSCONFDIR}/passwd!"
291 echo " Privilege separation set to 'no' again!"
292 echo " Check your ${SYSCONFDIR}/sshd_config file!"
295 mkpasswd -l -u sshd | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
302 # On 9x don't use privilege separation. Since security isn't
303 # available it just adds useless additional processes.
308 # Create default sshd_config from skeleton files in /etc/defaults/etc or
309 # modify to add the missing privsep configuration option
311 if [ ! -f "${SYSCONFDIR}/sshd_config" ]
313 echo "Generating ${SYSCONFDIR}/sshd_config file"
314 sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
315 s/^#Port 22/Port ${port_number}/
316 s/^#StrictModes yes/StrictModes no/" \
317 < ${SYSCONFDIR}/defaults/etc/sshd_config \
318 > ${SYSCONFDIR}/sshd_config
319 elif [ "${privsep_configured}" != "yes" ]
321 echo >> ${SYSCONFDIR}/sshd_config
322 echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
325 # Care for services file
326 _my_etcdir="/ssh-host-config.$$"
329 _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
330 _services="${_my_etcdir}/services"
331 # On NT, 27 spaces, no space after the hash
334 _win_etcdir="${WINDIR}"
335 _services="${_my_etcdir}/SERVICES"
336 # On 9x, 18 spaces (95 is very touchy), a space after the hash
339 _serv_tmp="${_my_etcdir}/srv.out.$$"
341 mount -t -f "${_win_etcdir}" "${_my_etcdir}"
343 # Depends on the above mount
344 _wservices=`cygpath -w "${_services}"`
346 # Remove sshd 22/port from services
347 if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
349 grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
350 if [ -f "${_serv_tmp}" ]
352 if mv "${_serv_tmp}" "${_services}"
354 echo "Removing sshd from ${_wservices}"
356 echo "Removing sshd from ${_wservices} failed!"
360 echo "Removing sshd from ${_wservices} failed!"
364 # Add ssh 22/tcp and ssh 22/udp to services
365 if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
367 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}"
369 if mv "${_serv_tmp}" "${_services}"
371 echo "Added ssh to ${_wservices}"
373 echo "Adding ssh to ${_wservices} failed!"
377 echo "WARNING: Adding ssh to ${_wservices} failed!"
381 umount "${_my_etcdir}"
383 # Care for inetd.conf file
384 _inetcnf="${SYSCONFDIR}/inetd.conf"
385 _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
387 if [ -f "${_inetcnf}" ]
389 # Check if ssh service is already in use as sshd
391 grep -q '^[ \t]*sshd' "${_inetcnf}" && with_comment=0
392 # Remove sshd line from inetd.conf
393 if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
395 grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
396 if [ -f "${_inetcnf_tmp}" ]
398 if mv "${_inetcnf_tmp}" "${_inetcnf}"
400 echo "Removed sshd from ${_inetcnf}"
402 echo "Removing sshd from ${_inetcnf} failed!"
404 rm -f "${_inetcnf_tmp}"
406 echo "Removing sshd from ${_inetcnf} failed!"
410 # Add ssh line to inetd.conf
411 if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
413 if [ "${with_comment}" -eq 0 ]
415 echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
417 echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
419 echo "Added ssh to ${_inetcnf}"
423 # On NT ask if sshd should be installed as service
426 # But only if it is not already installed
427 if ! cygrunsrv -Q sshd > /dev/null 2>&1
431 echo "Warning: The following functions require administrator privileges!"
433 echo "Do you want to install sshd as service?"
434 if request "(Say \"no\" if it's already installed as service)"
436 if [ $_nt2003 -gt 0 ]
438 grep -q '^sshd_server:' ${SYSCONFDIR}/passwd && sshd_server_in_passwd=yes
439 if [ "${sshd_server_in_passwd}" = "yes" ]
441 # Drop sshd_server from passwd since it could have wrong settings
442 grep -v '^sshd_server:' ${SYSCONFDIR}/passwd > ${SYSCONFDIR}/passwd.$$
443 rm -f ${SYSCONFDIR}/passwd
444 mv ${SYSCONFDIR}/passwd.$$ ${SYSCONFDIR}/passwd
445 chmod g-w,o-w ${SYSCONFDIR}/passwd
447 net user sshd_server >/dev/null 2>&1 && sshd_server_in_sam=yes
448 if [ "${sshd_server_in_sam}" != "yes" ]
451 echo "You appear to be running Windows 2003 Server or later. On 2003 and"
452 echo "later systems, it's not possible to use the LocalSystem account"
453 echo "if sshd should allow passwordless logon (e. g. public key authentication)."
454 echo "If you want to enable that functionality, it's required to create a new"
455 echo "account 'sshd_server' with special privileges, which is then used to run"
456 echo "the sshd service under."
458 echo "Should this script create a new local account 'sshd_server' which has"
459 if request "the required privileges?"
461 _admingroup=`mkgroup -l | awk -F: '{if ( $2 == "S-1-5-32-544" ) print $1;}' `
462 if [ -z "${_admingroup}" ]
464 echo "mkgroup -l produces no group with SID S-1-5-32-544 (Local administrators group)."
467 dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
468 while [ "${sshd_server_in_sam}" != "yes" ]
470 if [ -n "${password_value}" ]
472 _password="${password_value}"
473 # Allow to ask for password if first try fails
477 echo "Please enter a password for new user 'sshd_server'. Please be sure that"
478 echo "this password matches the password rules given on your system."
479 echo -n "Entering no password will exit the configuration. PASSWORD="
481 if [ -z "${_password}" ]
484 echo "Exiting configuration. No user sshd_server has been created,"
485 echo "no sshd service installed."
489 net user sshd_server "${_password}" /add /fullname:"sshd server account" "/homedir:${dos_var_empty}" /yes > /tmp/nu.$$ 2>&1 && sshd_server_in_sam=yes
490 if [ "${sshd_server_in_sam}" != "yes" ]
492 echo "Creating the user 'sshd_server' failed! Reason:"
497 net localgroup "${_admingroup}" sshd_server /add > /dev/null 2>&1 && sshd_server_in_admingroup=yes
498 if [ "${sshd_server_in_admingroup}" != "yes" ]
500 echo "WARNING: Adding user sshd_server to local group ${_admingroup} failed!"
501 echo "Please add sshd_server to local group ${_admingroup} before"
502 echo "starting the sshd service!"
505 passwd_has_expiry_flags=`passwd -v | awk '/^passwd /{print ( $3 >= 1.5 ) ? "yes" : "no";}'`
506 if [ "${passwd_has_expiry_flags}" != "yes" ]
509 echo "WARNING: User sshd_server has password expiry set to system default."
510 echo "Please check that password never expires or set it to your needs."
511 elif ! passwd -e sshd_server
514 echo "WARNING: Setting password expiry for user sshd_server failed!"
515 echo "Please check that password never expires or set it to your needs."
517 editrights -a SeAssignPrimaryTokenPrivilege -u sshd_server &&
518 editrights -a SeCreateTokenPrivilege -u sshd_server &&
519 editrights -a SeTcbPrivilege -u sshd_server &&
520 editrights -a SeDenyInteractiveLogonRight -u sshd_server &&
521 editrights -a SeDenyNetworkLogonRight -u sshd_server &&
522 editrights -a SeDenyRemoteInteractiveLogonRight -u sshd_server &&
523 editrights -a SeIncreaseQuotaPrivilege -u sshd_server &&
524 editrights -a SeServiceLogonRight -u sshd_server &&
525 sshd_server_got_all_rights="yes"
526 if [ "${sshd_server_got_all_rights}" != "yes" ]
529 echo "Assigning the appropriate privileges to user 'sshd_server' failed!"
530 echo "Can't create sshd service!"
534 echo "User 'sshd_server' has been created with password '${_password}'."
535 echo "If you change the password, please keep in mind to change the password"
536 echo "for the sshd service, too."
538 echo "Also keep in mind that the user sshd_server needs read permissions on all"
539 echo "users' .ssh/authorized_keys file to allow public key authentication for"
540 echo "these users!. (Re-)running ssh-user-config for each user will set the"
541 echo "required permissions correctly."
545 if [ "${sshd_server_in_sam}" = "yes" ]
547 mkpasswd -l -u sshd_server | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
550 if [ -n "${cygwin_value}" ]
552 _cygwin="${cygwin_value}"
555 echo "Which value should the environment variable CYGWIN have when"
556 echo "sshd starts? It's recommended to set at least \"ntsec\" to be"
557 echo "able to change user context without password."
558 echo -n "Default is \"ntsec\". CYGWIN="
561 [ -z "${_cygwin}" ] && _cygwin="ntsec"
562 if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
564 if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -u sshd_server -w "${_password}" -e "CYGWIN=${_cygwin}" -y tcpip
567 echo "The service has been installed under sshd_server account."
568 echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
571 if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -e "CYGWIN=${_cygwin}" -y tcpip
574 echo "The service has been installed under LocalSystem account."
575 echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
579 # Now check if sshd has been successfully installed. This allows to
580 # set the ownership of the affected files correctly.
581 if cygrunsrv -Q sshd > /dev/null 2>&1
583 if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
589 chown "${_user}" ${SYSCONFDIR}/ssh*
590 chown "${_user}".544 ${LOCALSTATEDIR}/empty
591 chown "${_user}".544 ${LOCALSTATEDIR}/log/lastlog
592 if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
594 chown "${_user}".544 ${LOCALSTATEDIR}/log/sshd.log
597 if ! ( mount | egrep -q 'on /(|usr/(bin|lib)) type system' )
600 echo "Warning: It appears that you have user mode mounts (\"Just me\""
601 echo "chosen during install.) Any daemons installed as services will"
602 echo "fail to function unless system mounts are used. To change this,"
603 echo "re-run setup.exe and choose \"All users\"."
605 echo "For more information, see http://cygwin.com/faq/faq0.html#TOC33"
611 echo "Host configuration finished. Have fun!"