| #!/bin/sh |
| # |
| # ssh-host-config, Copyright 2000, Red Hat Inc. |
| # |
| # This file is part of the Cygwin port of OpenSSH. |
| |
| # Subdirectory where the new package is being installed |
| PREFIX=/usr |
| |
| # Directory where the config files are stored |
| SYSCONFDIR=/etc |
| |
| # Subdirectory where an old package might be installed |
| OLDPREFIX=/usr/local |
| OLDSYSCONFDIR=${OLDPREFIX}/etc |
| |
| progname=$0 |
| auto_answer="" |
| port_number=22 |
| |
| privsep_configured=no |
| privsep_used=yes |
| sshd_in_passwd=no |
| sshd_in_sam=no |
| |
| request() |
| { |
| if [ "${auto_answer}" = "yes" ] |
| then |
| return 0 |
| elif [ "${auto_answer}" = "no" ] |
| then |
| return 1 |
| fi |
| |
| answer="" |
| while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ] |
| do |
| echo -n "$1 (yes/no) " |
| read answer |
| done |
| if [ "X${answer}" = "Xyes" ] |
| then |
| return 0 |
| else |
| return 1 |
| fi |
| } |
| |
| # Check options |
| |
| while : |
| do |
| case $# in |
| 0) |
| break |
| ;; |
| esac |
| |
| option=$1 |
| shift |
| |
| case "$option" in |
| -d | --debug ) |
| set -x |
| ;; |
| |
| -y | --yes ) |
| auto_answer=yes |
| ;; |
| |
| -n | --no ) |
| auto_answer=no |
| ;; |
| |
| -p | --port ) |
| port_number=$1 |
| shift |
| ;; |
| |
| *) |
| echo "usage: ${progname} [OPTION]..." |
| echo |
| echo "This script creates an OpenSSH host configuration." |
| echo |
| echo "Options:" |
| echo " --debug -d Enable shell's debug output." |
| echo " --yes -y Answer all questions with \"yes\" automatically." |
| echo " --no -n Answer all questions with \"no\" automatically." |
| echo " --port -p <n> sshd listens on port n." |
| echo |
| exit 1 |
| ;; |
| |
| esac |
| done |
| |
| # Check if running on NT |
| _sys="`uname -a`" |
| _nt=`expr "$_sys" : "CYGWIN_NT"` |
| |
| # 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 |
| fi |
| |
| # Check for ${SYSCONFDIR} directory |
| |
| if [ -e "${SYSCONFDIR}" -a ! -d "${SYSCONFDIR}" ] |
| then |
| echo |
| echo "${SYSCONFDIR} is existant but not a directory." |
| echo "Cannot create global configuration files." |
| echo |
| exit 1 |
| fi |
| |
| # 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 [ -f /var/log ] |
| then |
| echo "Creating /var/log failed\!" |
| else |
| if [ ! -d /var/log ] |
| then |
| mkdir -p /var/log |
| fi |
| if [ -d /var/log/lastlog ] |
| then |
| echo "Creating /var/log/lastlog failed\!" |
| elif [ ! -f /var/log/lastlog ] |
| then |
| cat /dev/null > /var/log/lastlog |
| fi |
| fi |
| |
| # Create /var/empty file used as chroot jail for privilege separation |
| if [ -f /var/empty ] |
| then |
| echo "Creating /var/empty failed\!" |
| else |
| mkdir -p /var/empty |
| # On NT change ownership of that dir to user "system" |
| if [ $_nt -gt 0 ] |
| then |
| chown system.system /var/empty |
| fi |
| fi |
| |
| # Check for an old installation in ${OLDPREFIX} unless ${OLDPREFIX} isn't |
| # the same as ${PREFIX} |
| |
| old_install=0 |
| if [ "${OLDPREFIX}" != "${PREFIX}" ] |
| then |
| if [ -f "${OLDPREFIX}/sbin/sshd" ] |
| then |
| echo |
| echo "You seem to have an older installation in ${OLDPREFIX}." |
| echo |
| # Check if old global configuration files exist |
| if [ -f "${OLDSYSCONFDIR}/ssh_host_key" ] |
| then |
| if request "Do you want to copy your config files to your new installation?" |
| then |
| cp -f ${OLDSYSCONFDIR}/ssh_host_key ${SYSCONFDIR} |
| cp -f ${OLDSYSCONFDIR}/ssh_host_key.pub ${SYSCONFDIR} |
| cp -f ${OLDSYSCONFDIR}/ssh_host_dsa_key ${SYSCONFDIR} |
| cp -f ${OLDSYSCONFDIR}/ssh_host_dsa_key.pub ${SYSCONFDIR} |
| cp -f ${OLDSYSCONFDIR}/ssh_config ${SYSCONFDIR} |
| cp -f ${OLDSYSCONFDIR}/sshd_config ${SYSCONFDIR} |
| fi |
| fi |
| if request "Do you want to erase your old installation?" |
| then |
| rm -f ${OLDPREFIX}/bin/ssh.exe |
| rm -f ${OLDPREFIX}/bin/ssh-config |
| rm -f ${OLDPREFIX}/bin/scp.exe |
| rm -f ${OLDPREFIX}/bin/ssh-add.exe |
| rm -f ${OLDPREFIX}/bin/ssh-agent.exe |
| rm -f ${OLDPREFIX}/bin/ssh-keygen.exe |
| rm -f ${OLDPREFIX}/bin/slogin |
| rm -f ${OLDSYSCONFDIR}/ssh_host_key |
| rm -f ${OLDSYSCONFDIR}/ssh_host_key.pub |
| rm -f ${OLDSYSCONFDIR}/ssh_host_dsa_key |
| rm -f ${OLDSYSCONFDIR}/ssh_host_dsa_key.pub |
| rm -f ${OLDSYSCONFDIR}/ssh_config |
| rm -f ${OLDSYSCONFDIR}/sshd_config |
| rm -f ${OLDPREFIX}/man/man1/ssh.1 |
| rm -f ${OLDPREFIX}/man/man1/scp.1 |
| rm -f ${OLDPREFIX}/man/man1/ssh-add.1 |
| rm -f ${OLDPREFIX}/man/man1/ssh-agent.1 |
| rm -f ${OLDPREFIX}/man/man1/ssh-keygen.1 |
| rm -f ${OLDPREFIX}/man/man1/slogin.1 |
| rm -f ${OLDPREFIX}/man/man8/sshd.8 |
| rm -f ${OLDPREFIX}/sbin/sshd.exe |
| rm -f ${OLDPREFIX}/sbin/sftp-server.exe |
| fi |
| old_install=1 |
| 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 here script |
| |
| if [ ! -f "${SYSCONFDIR}/ssh_config" ] |
| then |
| echo "Generating ${SYSCONFDIR}/ssh_config file" |
| cat > ${SYSCONFDIR}/ssh_config << EOF |
| # This is the ssh client system-wide configuration file. See |
| # ssh_config(5) for more information. This file provides defaults for |
| # users, and the values can be changed in per-user configuration files |
| # or on the command line. |
| |
| # Configuration data is parsed as follows: |
| # 1. command line options |
| # 2. user-specific file |
| # 3. system-wide file |
| # Any configuration value is only changed the first time it is set. |
| # Thus, host-specific definitions should be at the beginning of the |
| # configuration file, and defaults at the end. |
| |
| # Site-wide defaults for various options |
| |
| # Host * |
| # ForwardAgent no |
| # ForwardX11 no |
| # RhostsAuthentication no |
| # RhostsRSAAuthentication no |
| # RSAAuthentication yes |
| # PasswordAuthentication yes |
| # BatchMode no |
| # CheckHostIP yes |
| # StrictHostKeyChecking ask |
| # IdentityFile ~/.ssh/identity |
| # IdentityFile ~/.ssh/id_dsa |
| # IdentityFile ~/.ssh/id_rsa |
| # Port 22 |
| # Protocol 2,1 |
| # Cipher 3des |
| # Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc |
| # EscapeChar ~ |
| EOF |
| if [ "$port_number" != "22" ] |
| then |
| 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" ] |
| 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 |
| fi |
| |
| # 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/doc/openssh/README.privsep." |
| echo |
| if request "Shall 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 "Shall this script create a local user 'sshd' on this machine?" |
| then |
| dos_var_empty=`cygpath -w /var/empty` |
| net user sshd /add /fullname:"sshd privsep" "/HOMEDIR:$dos_var_empty" > /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 >> ${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 addtional processes. |
| privsep_used=no |
| fi |
| fi |
| |
| # Create default sshd_config from here script or modify to add the |
| # missing privsep configuration option |
| |
| if [ ! -f "${SYSCONFDIR}/sshd_config" ] |
| then |
| echo "Generating ${SYSCONFDIR}/sshd_config file" |
| cat > ${SYSCONFDIR}/sshd_config << EOF |
| # This is the sshd server system-wide configuration file. See |
| # sshd_config(5) for more information. |
| |
| # The strategy used for options in the default sshd_config shipped with |
| # OpenSSH is to specify options with their default value where |
| # possible, but leave them commented. Uncommented options change a |
| # default value. |
| |
| Port $port_number |
| #Protocol 2,1 |
| #ListenAddress 0.0.0.0 |
| #ListenAddress :: |
| |
| # HostKey for protocol version 1 |
| #HostKey ${SYSCONFDIR}/ssh_host_key |
| # HostKeys for protocol version 2 |
| #HostKey ${SYSCONFDIR}/ssh_host_rsa_key |
| #HostKey ${SYSCONFDIR}/ssh_host_dsa_key |
| |
| # Lifetime and size of ephemeral version 1 server ke |
| #KeyRegenerationInterval 3600 |
| #ServerKeyBits 768 |
| |
| # Logging |
| #obsoletes QuietMode and FascistLogging |
| #SyslogFacility AUTH |
| #LogLevel INFO |
| |
| # Authentication: |
| |
| #LoginGraceTime 600 |
| #PermitRootLogin yes |
| # The following setting overrides permission checks on host key files |
| # and directories. For security reasons set this to "yes" when running |
| # NT/W2K, NTFS and CYGWIN=ntsec. |
| StrictModes no |
| |
| #RSAAuthentication yes |
| #PubkeyAuthentication yes |
| #AuthorizedKeysFile %h/.ssh/authorized_keys |
| |
| # rhosts authentication should not be used |
| #RhostsAuthentication no |
| # Don't read ~/.rhosts and ~/.shosts files |
| #IgnoreRhosts yes |
| # For this to work you will also need host keys in ${SYSCONFDIR}/ssh_known_hosts |
| #RhostsRSAAuthentication no |
| # similar for protocol version 2 |
| #HostbasedAuthentication no |
| # Change to yes if you don't trust ~/.ssh/known_hosts for |
| # RhostsRSAAuthentication and HostbasedAuthentication |
| #IgnoreUserKnownHosts no |
| |
| # To disable tunneled clear text passwords, change to no here! |
| #PasswordAuthentication yes |
| #PermitEmptyPasswords no |
| |
| # Change to no to disable s/key passwords |
| #ChallengeResponseAuthentication yes |
| |
| #X11Forwarding no |
| #X11DisplayOffset 10 |
| #X11UseLocalhost yes |
| #PrintMotd yes |
| #PrintLastLog yes |
| #KeepAlive yes |
| #UseLogin no |
| UsePrivilegeSeparation $privsep_used |
| #Compression yes |
| |
| #MaxStartups 10 |
| # no default banner path |
| #Banner /some/path |
| #VerifyReverseMapping no |
| |
| # override default of no subsystems |
| Subsystem sftp /usr/sbin/sftp-server |
| EOF |
| elif [ "$privsep_configured" != "yes" ] |
| then |
| echo >> ${SYSCONFDIR}/sshd_config |
| echo "UsePrivilegeSeparation $privsep_used" >> ${SYSCONFDIR}/sshd_config |
| fi |
| |
| # Care for services file |
| if [ $_nt -gt 0 ] |
| then |
| _wservices="${SYSTEMROOT}\\system32\\drivers\\etc\\services" |
| _wserv_tmp="${SYSTEMROOT}\\system32\\drivers\\etc\\srv.out.$$" |
| else |
| _wservices="${WINDIR}\\SERVICES" |
| _wserv_tmp="${WINDIR}\\SERV.$$" |
| fi |
| _services=`cygpath -u "${_wservices}"` |
| _serv_tmp=`cygpath -u "${_wserv_tmp}"` |
| |
| mount -t -f "${_wservices}" "${_services}" |
| mount -t -f "${_wserv_tmp}" "${_serv_tmp}" |
| |
| # 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 ${_services}" |
| else |
| echo "Removing sshd from ${_services} failed\!" |
| fi |
| rm -f "${_serv_tmp}" |
| else |
| echo "Removing sshd from ${_services} 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 |
| awk '{ if ( $2 ~ /^23\/tcp/ ) print "ssh 22/tcp #SSH Remote Login Protocol\nssh 22/udp #SSH Remote Login Protocol"; print $0; }' < "${_services}" > "${_serv_tmp}" |
| if [ -f "${_serv_tmp}" ] |
| then |
| if mv "${_serv_tmp}" "${_services}" |
| then |
| echo "Added ssh to ${_services}" |
| else |
| echo "Adding ssh to ${_services} failed\!" |
| fi |
| rm -f "${_serv_tmp}" |
| else |
| echo "Adding ssh to ${_services} failed\!" |
| fi |
| fi |
| |
| umount "${_services}" |
| umount "${_serv_tmp}" |
| |
| # 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 |
| echo |
| echo "Do you want to install sshd as service?" |
| if request "(Say \"no\" if it's already installed as service)" |
| then |
| 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 \"binmode ntsec tty\". CYGWIN=" |
| read _cygwin |
| [ -z "${_cygwin}" ] && _cygwin="binmode ntsec tty" |
| if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -e "CYGWIN=${_cygwin}" |
| then |
| chown system ${SYSCONFDIR}/ssh* |
| echo |
| echo "The service has been installed under LocalSystem account." |
| fi |
| fi |
| fi |
| |
| if [ "${old_install}" = "1" ] |
| then |
| echo |
| echo "Note: If you have used sshd as service or from inetd, don't forget to" |
| echo " change the path to sshd.exe in the service entry or in inetd.conf." |
| fi |
| |
| echo |
| echo "Host configuration finished. Have fun!" |