ssh-host-config revision 294328
1180740Sdes#!/bin/bash 2180740Sdes# 3221377Sdes# ssh-host-config, Copyright 2000-2011 Red Hat Inc. 4180740Sdes# 5180740Sdes# This file is part of the Cygwin port of OpenSSH. 6197670Sdes# 7197670Sdes# Permission to use, copy, modify, and distribute this software for any 8197670Sdes# purpose with or without fee is hereby granted, provided that the above 9197670Sdes# copyright notice and this permission notice appear in all copies. 10197670Sdes# 11197670Sdes# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 12197670Sdes# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 13197670Sdes# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 14197670Sdes# IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15197670Sdes# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 16197670Sdes# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 17197670Sdes# THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18180740Sdes 19180750Sdes# ====================================================================== 20180750Sdes# Initialization 21180750Sdes# ====================================================================== 22180750Sdes 23180750SdesCSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh 24180750Sdes 25221377Sdes# List of apps used. This is checkad for existance in csih_sanity_check 26221377Sdes# Don't use *any* transient commands before sourcing the csih helper script, 27221377Sdes# otherwise the sanity checks are short-circuited. 28221377Sdesdeclare -a csih_required_commands=( 29221377Sdes /usr/bin/basename coreutils 30221377Sdes /usr/bin/cat coreutils 31221377Sdes /usr/bin/chmod coreutils 32221377Sdes /usr/bin/dirname coreutils 33221377Sdes /usr/bin/id coreutils 34221377Sdes /usr/bin/mv coreutils 35221377Sdes /usr/bin/rm coreutils 36221377Sdes /usr/bin/cygpath cygwin 37294328Sdes /usr/bin/mkpasswd cygwin 38221377Sdes /usr/bin/mount cygwin 39221377Sdes /usr/bin/ps cygwin 40221377Sdes /usr/bin/umount cygwin 41221377Sdes /usr/bin/cmp diffutils 42221377Sdes /usr/bin/grep grep 43221377Sdes /usr/bin/awk gawk 44221377Sdes /usr/bin/ssh-keygen openssh 45221377Sdes /usr/sbin/sshd openssh 46221377Sdes /usr/bin/sed sed 47221377Sdes) 48221377Sdescsih_sanity_check_server=yes 49221377Sdessource ${CSIH_SCRIPT} 50221377Sdes 51221377SdesPROGNAME=$(/usr/bin/basename $0) 52221377Sdes_tdir=$(/usr/bin/dirname $0) 53221377SdesPROGDIR=$(cd $_tdir && pwd) 54221377Sdes 55180740Sdes# Subdirectory where the new package is being installed 56180740SdesPREFIX=/usr 57180740Sdes 58180740Sdes# Directory where the config files are stored 59180740SdesSYSCONFDIR=/etc 60180740SdesLOCALSTATEDIR=/var 61180740Sdes 62294328Sdessshd_config_configured=no 63180740Sdesport_number=22 64294328Sdesstrictmodes=yes 65180740Sdesprivsep_used=yes 66189006Sdescygwin_value="" 67197670Sdesuser_account= 68180750Sdespassword_value= 69197670Sdesopt_force=no 70180740Sdes 71180750Sdes# ====================================================================== 72180750Sdes# Routine: update_services_file 73180750Sdes# ====================================================================== 74180750Sdesupdate_services_file() { 75180750Sdes local _my_etcdir="/ssh-host-config.$$" 76180750Sdes local _win_etcdir 77180750Sdes local _services 78180750Sdes local _spaces 79180750Sdes local _serv_tmp 80180750Sdes local _wservices 81221377Sdes local ret=0 82180750Sdes 83221377Sdes _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc" 84221377Sdes _services="${_my_etcdir}/services" 85221377Sdes _spaces=" #" 86180750Sdes _serv_tmp="${_my_etcdir}/srv.out.$$" 87189006Sdes 88221377Sdes /usr/bin/mount -o text,posix=0,noacl -f "${_win_etcdir}" "${_my_etcdir}" 89189006Sdes 90180750Sdes # Depends on the above mount 91180750Sdes _wservices=`cygpath -w "${_services}"` 92189006Sdes 93180750Sdes # Add ssh 22/tcp and ssh 22/udp to services 94294328Sdes if [ `/usr/bin/grep -q 'ssh[[:space:]][[:space:]]*22' "${_services}"; echo $?` -ne 0 ] 95180750Sdes then 96221377Sdes if /usr/bin/awk '{ if ( $2 ~ /^23\/tcp/ ) print "ssh 22/tcp'"${_spaces}"'SSH Remote Login Protocol\nssh 22/udp'"${_spaces}"'SSH Remote Login Protocol"; print $0; }' < "${_services}" > "${_serv_tmp}" 97180750Sdes then 98221377Sdes if /usr/bin/mv "${_serv_tmp}" "${_services}" 99180750Sdes then 100189006Sdes csih_inform "Added ssh to ${_wservices}" 101180750Sdes else 102189006Sdes csih_warning "Adding ssh to ${_wservices} failed!" 103221377Sdes let ++ret 104180750Sdes fi 105221377Sdes /usr/bin/rm -f "${_serv_tmp}" 106180750Sdes else 107180750Sdes csih_warning "Adding ssh to ${_wservices} failed!" 108221377Sdes let ++ret 109180750Sdes fi 110180750Sdes fi 111221377Sdes /usr/bin/umount "${_my_etcdir}" 112221377Sdes return $ret 113180750Sdes} # --- End of update_services_file --- # 114180740Sdes 115180750Sdes# ====================================================================== 116294328Sdes# Routine: sshd_strictmodes 117294328Sdes# MODIFIES: strictmodes 118294328Sdes# ====================================================================== 119294328Sdessshd_strictmodes() { 120294328Sdes if [ "${sshd_config_configured}" != "yes" ] 121294328Sdes then 122294328Sdes echo 123294328Sdes csih_inform "StrictModes is set to 'yes' by default." 124294328Sdes csih_inform "This is the recommended setting, but it requires that the POSIX" 125294328Sdes csih_inform "permissions of the user's home directory, the user's .ssh" 126294328Sdes csih_inform "directory, and the user's ssh key files are tight so that" 127294328Sdes csih_inform "only the user has write permissions." 128294328Sdes csih_inform "On the other hand, StrictModes don't work well with default" 129294328Sdes csih_inform "Windows permissions of a home directory mounted with the" 130294328Sdes csih_inform "'noacl' option, and they don't work at all if the home" 131294328Sdes csih_inform "directory is on a FAT or FAT32 partition." 132294328Sdes if ! csih_request "Should StrictModes be used?" 133294328Sdes then 134294328Sdes strictmodes=no 135294328Sdes fi 136294328Sdes fi 137294328Sdes return 0 138294328Sdes} 139294328Sdes 140294328Sdes# ====================================================================== 141180750Sdes# Routine: sshd_privsep 142294328Sdes# MODIFIES: privsep_used 143180750Sdes# ====================================================================== 144180750Sdessshd_privsep() { 145221377Sdes local ret=0 146180740Sdes 147294328Sdes if [ "${sshd_config_configured}" != "yes" ] 148180750Sdes then 149294328Sdes echo 150294328Sdes csih_inform "Privilege separation is set to 'sandbox' by default since" 151294328Sdes csih_inform "OpenSSH 6.1. This is unsupported by Cygwin and has to be set" 152294328Sdes csih_inform "to 'yes' or 'no'." 153294328Sdes csih_inform "However, using privilege separation requires a non-privileged account" 154294328Sdes csih_inform "called 'sshd'." 155221377Sdes csih_inform "For more info on privilege separation read /usr/share/doc/openssh/README.privsep." 156221377Sdes if csih_request "Should privilege separation be used?" 157180750Sdes then 158221377Sdes privsep_used=yes 159221377Sdes if ! csih_create_unprivileged_user sshd 160180750Sdes then 161221377Sdes csih_error_recoverable "Couldn't create user 'sshd'!" 162221377Sdes csih_error_recoverable "Privilege separation set to 'no' again!" 163221377Sdes csih_error_recoverable "Check your ${SYSCONFDIR}/sshd_config file!" 164221377Sdes let ++ret 165189006Sdes privsep_used=no 166180750Sdes fi 167180750Sdes else 168180750Sdes privsep_used=no 169180750Sdes fi 170180750Sdes fi 171294328Sdes return $ret 172294328Sdes} # --- End of sshd_privsep --- # 173189006Sdes 174294328Sdes# ====================================================================== 175294328Sdes# Routine: sshd_config_tweak 176294328Sdes# ====================================================================== 177294328Sdessshd_config_tweak() { 178294328Sdes local ret=0 179294328Sdes 180294328Sdes # Modify sshd_config 181294328Sdes csih_inform "Updating ${SYSCONFDIR}/sshd_config file" 182294328Sdes if [ "${port_number}" -ne 22 ] 183180750Sdes then 184294328Sdes /usr/bin/sed -i -e "s/^#\?[[:space:]]*Port[[:space:]].*/Port ${port_number}/" \ 185294328Sdes ${SYSCONFDIR}/sshd_config 186294328Sdes if [ $? -ne 0 ] 187221377Sdes then 188294328Sdes csih_warning "Setting listening port to ${port_number} failed!" 189294328Sdes csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" 190294328Sdes let ++ret 191221377Sdes fi 192294328Sdes fi 193294328Sdes if [ "${strictmodes}" = "no" ] 194180750Sdes then 195294328Sdes /usr/bin/sed -i -e "s/^#\?[[:space:]]*StrictModes[[:space:]].*/StrictModes no/" \ 196294328Sdes ${SYSCONFDIR}/sshd_config 197294328Sdes if [ $? -ne 0 ] 198221377Sdes then 199294328Sdes csih_warning "Setting StrictModes to 'no' failed!" 200294328Sdes csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" 201294328Sdes let ++ret 202221377Sdes fi 203180750Sdes fi 204294328Sdes if [ "${sshd_config_configured}" != "yes" ] 205294328Sdes then 206294328Sdes /usr/bin/sed -i -e " 207294328Sdes s/^#\?UsePrivilegeSeparation .*/UsePrivilegeSeparation ${privsep_used}/" \ 208294328Sdes ${SYSCONFDIR}/sshd_config 209294328Sdes if [ $? -ne 0 ] 210294328Sdes then 211294328Sdes csih_warning "Setting privilege separation failed!" 212294328Sdes csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" 213294328Sdes let ++ret 214294328Sdes fi 215294328Sdes fi 216221377Sdes return $ret 217294328Sdes} # --- End of sshd_config_tweak --- # 218180750Sdes 219180750Sdes# ====================================================================== 220180750Sdes# Routine: update_inetd_conf 221180750Sdes# ====================================================================== 222180750Sdesupdate_inetd_conf() { 223180750Sdes local _inetcnf="${SYSCONFDIR}/inetd.conf" 224180750Sdes local _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$" 225180750Sdes local _inetcnf_dir="${SYSCONFDIR}/inetd.d" 226180750Sdes local _sshd_inetd_conf="${_inetcnf_dir}/sshd-inetd" 227180750Sdes local _sshd_inetd_conf_tmp="${_inetcnf_dir}/sshd-inetd.$$" 228180750Sdes local _with_comment=1 229221377Sdes local ret=0 230180750Sdes 231180750Sdes if [ -d "${_inetcnf_dir}" ] 232180750Sdes then 233180750Sdes # we have inetutils-1.5 inetd.d support 234180750Sdes if [ -f "${_inetcnf}" ] 235180750Sdes then 236294328Sdes /usr/bin/grep -q '^[[:space:]]*ssh' "${_inetcnf}" && _with_comment=0 237180750Sdes 238180750Sdes # check for sshd OR ssh in top-level inetd.conf file, and remove 239180750Sdes # will be replaced by a file in inetd.d/ 240294328Sdes if [ $(/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?) -eq 0 ] 241180750Sdes then 242221377Sdes /usr/bin/grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}" 243189006Sdes if [ -f "${_inetcnf_tmp}" ] 244189006Sdes then 245221377Sdes if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}" 246189006Sdes then 247180750Sdes csih_inform "Removed ssh[d] from ${_inetcnf}" 248189006Sdes else 249180750Sdes csih_warning "Removing ssh[d] from ${_inetcnf} failed!" 250221377Sdes let ++ret 251189006Sdes fi 252221377Sdes /usr/bin/rm -f "${_inetcnf_tmp}" 253189006Sdes else 254189006Sdes csih_warning "Removing ssh[d] from ${_inetcnf} failed!" 255221377Sdes let ++ret 256189006Sdes fi 257180750Sdes fi 258180750Sdes fi 259180750Sdes 260180750Sdes csih_install_config "${_sshd_inetd_conf}" "${SYSCONFDIR}/defaults" 261221377Sdes if /usr/bin/cmp "${SYSCONFDIR}/defaults${_sshd_inetd_conf}" "${_sshd_inetd_conf}" >/dev/null 2>&1 262180750Sdes then 263180750Sdes if [ "${_with_comment}" -eq 0 ] 264180750Sdes then 265294328Sdes /usr/bin/sed -e 's/@COMMENT@[[:space:]]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" 266180750Sdes else 267294328Sdes /usr/bin/sed -e 's/@COMMENT@[[:space:]]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" 268180750Sdes fi 269221377Sdes if /usr/bin/mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}" 270221377Sdes then 271221377Sdes csih_inform "Updated ${_sshd_inetd_conf}" 272221377Sdes else 273221377Sdes csih_warning "Updating ${_sshd_inetd_conf} failed!" 274221377Sdes let ++ret 275221377Sdes fi 276189006Sdes fi 277180750Sdes 278180750Sdes elif [ -f "${_inetcnf}" ] 279180750Sdes then 280294328Sdes /usr/bin/grep -q '^[[:space:]]*sshd' "${_inetcnf}" && _with_comment=0 281180750Sdes 282180750Sdes # check for sshd in top-level inetd.conf file, and remove 283180750Sdes # will be replaced by a file in inetd.d/ 284294328Sdes if [ `/usr/bin/grep -q '^#\?[[:space:]]*sshd' "${_inetcnf}"; echo $?` -eq 0 ] 285180750Sdes then 286294328Sdes /usr/bin/grep -v '^#\?[[:space:]]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}" 287180750Sdes if [ -f "${_inetcnf_tmp}" ] 288180750Sdes then 289221377Sdes if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}" 290189006Sdes then 291180750Sdes csih_inform "Removed sshd from ${_inetcnf}" 292189006Sdes else 293180750Sdes csih_warning "Removing sshd from ${_inetcnf} failed!" 294221377Sdes let ++ret 295189006Sdes fi 296221377Sdes /usr/bin/rm -f "${_inetcnf_tmp}" 297180750Sdes else 298189006Sdes csih_warning "Removing sshd from ${_inetcnf} failed!" 299221377Sdes let ++ret 300180750Sdes fi 301180750Sdes fi 302189006Sdes 303180750Sdes # Add ssh line to inetd.conf 304221377Sdes if [ `/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ] 305180750Sdes then 306180750Sdes if [ "${_with_comment}" -eq 0 ] 307180750Sdes then 308189006Sdes echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}" 309180750Sdes else 310189006Sdes echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}" 311180750Sdes fi 312221377Sdes if [ $? -eq 0 ] 313221377Sdes then 314221377Sdes csih_inform "Added ssh to ${_inetcnf}" 315221377Sdes else 316221377Sdes csih_warning "Adding ssh to ${_inetcnf} failed!" 317221377Sdes let ++ret 318221377Sdes fi 319180750Sdes fi 320180750Sdes fi 321221377Sdes return $ret 322180750Sdes} # --- End of update_inetd_conf --- # 323180750Sdes 324180750Sdes# ====================================================================== 325221377Sdes# Routine: check_service_files_ownership 326221377Sdes# Checks that the files in /etc and /var belong to the right owner 327221377Sdes# ====================================================================== 328221377Sdescheck_service_files_ownership() { 329221377Sdes local run_service_as=$1 330221377Sdes local ret=0 331221377Sdes 332221377Sdes if [ -z "${run_service_as}" ] 333221377Sdes then 334294328Sdes accnt_name=$(/usr/bin/cygrunsrv -VQ sshd | 335294328Sdes /usr/bin/sed -ne 's/^Account *: *//gp') 336221377Sdes if [ "${accnt_name}" = "LocalSystem" ] 337221377Sdes then 338221377Sdes # Convert "LocalSystem" to "SYSTEM" as is the correct account name 339294328Sdes run_service_as="SYSTEM" 340294328Sdes else 341294328Sdes dom="${accnt_name%%\\*}" 342294328Sdes accnt_name="${accnt_name#*\\}" 343294328Sdes if [ "${dom}" = '.' ] 344294328Sdes then 345294328Sdes # Check local account 346294328Sdes run_service_as=$(/usr/bin/mkpasswd -l -u "${accnt_name}" | 347294328Sdes /usr/bin/awk -F: '{print $1;}') 348294328Sdes else 349294328Sdes # Check domain 350294328Sdes run_service_as=$(/usr/bin/mkpasswd -d "${dom}" -u "${accnt_name}" | 351294328Sdes /usr/bin/awk -F: '{print $1;}') 352294328Sdes fi 353221377Sdes fi 354221377Sdes if [ -z "${run_service_as}" ] 355221377Sdes then 356221377Sdes csih_warning "Couldn't determine name of user running sshd service from /etc/passwd!" 357221377Sdes csih_warning "As a result, this script cannot make sure that the files used" 358221377Sdes csih_warning "by the sshd service belong to the user running the service." 359221377Sdes csih_warning "Please re-run the mkpasswd tool to make sure the /etc/passwd" 360221377Sdes csih_warning "file is in a good shape." 361221377Sdes return 1 362221377Sdes fi 363221377Sdes fi 364221377Sdes for i in "${SYSCONFDIR}"/ssh_config "${SYSCONFDIR}"/sshd_config "${SYSCONFDIR}"/ssh_host_*key "${SYSCONFDIR}"/ssh_host_*key.pub 365221377Sdes do 366221377Sdes if [ -f "$i" ] 367221377Sdes then 368221377Sdes if ! chown "${run_service_as}".544 "$i" >/dev/null 2>&1 369221377Sdes then 370221377Sdes csih_warning "Couldn't change owner of $i!" 371221377Sdes let ++ret 372221377Sdes fi 373221377Sdes fi 374221377Sdes done 375221377Sdes if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty >/dev/null 2>&1 376221377Sdes then 377221377Sdes csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/empty!" 378221377Sdes let ++ret 379221377Sdes fi 380221377Sdes if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1 381221377Sdes then 382221377Sdes csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/lastlog!" 383221377Sdes let ++ret 384221377Sdes fi 385221377Sdes if [ -f ${LOCALSTATEDIR}/log/sshd.log ] 386221377Sdes then 387221377Sdes if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log >/dev/null 2>&1 388221377Sdes then 389221377Sdes csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/sshd.log!" 390221377Sdes let ++ret 391221377Sdes fi 392221377Sdes fi 393221377Sdes if [ $ret -ne 0 ] 394221377Sdes then 395221377Sdes csih_warning "Couldn't change owner of important files to ${run_service_as}!" 396221377Sdes csih_warning "This may cause the sshd service to fail! Please make sure that" 397221377Sdes csih_warning "you have suufficient permissions to change the ownership of files" 398221377Sdes csih_warning "and try to run the ssh-host-config script again." 399221377Sdes fi 400221377Sdes return $ret 401221377Sdes} # --- End of check_service_files_ownership --- # 402221377Sdes 403221377Sdes# ====================================================================== 404180750Sdes# Routine: install_service 405180750Sdes# Install sshd as a service 406180750Sdes# ====================================================================== 407180750Sdesinstall_service() { 408180750Sdes local run_service_as 409180750Sdes local password 410221377Sdes local ret=0 411180750Sdes 412221377Sdes echo 413221377Sdes if /usr/bin/cygrunsrv -Q sshd >/dev/null 2>&1 414180750Sdes then 415221377Sdes csih_inform "Sshd service is already installed." 416221377Sdes check_service_files_ownership "" || let ret+=$? 417221377Sdes else 418221377Sdes echo -e "${_csih_QUERY_STR} Do you want to install sshd as a service?" 419221377Sdes if csih_request "(Say \"no\" if it is already installed as a service)" 420180750Sdes then 421221377Sdes csih_get_cygenv "${cygwin_value}" 422221377Sdes 423221377Sdes if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] ) 424180750Sdes then 425221377Sdes csih_inform "On Windows Server 2003, Windows Vista, and above, the" 426221377Sdes csih_inform "SYSTEM account cannot setuid to other users -- a capability" 427221377Sdes csih_inform "sshd requires. You need to have or to create a privileged" 428221377Sdes csih_inform "account. This script will help you do so." 429221377Sdes echo 430180750Sdes 431221377Sdes [ "${opt_force}" = "yes" ] && opt_f=-f 432221377Sdes [ -n "${user_account}" ] && opt_u="-u ""${user_account}""" 433221377Sdes csih_select_privileged_username ${opt_f} ${opt_u} sshd 434221377Sdes 435221377Sdes if ! csih_create_privileged_user "${password_value}" 436189006Sdes then 437221377Sdes csih_error_recoverable "There was a serious problem creating a privileged user." 438221377Sdes csih_request "Do you want to proceed anyway?" || exit 1 439221377Sdes let ++ret 440189006Sdes fi 441221377Sdes fi 442180750Sdes 443221377Sdes # Never returns empty if NT or above 444221377Sdes run_service_as=$(csih_service_should_run_as) 445180750Sdes 446221377Sdes if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ] 447221377Sdes then 448221377Sdes password="${csih_PRIVILEGED_PASSWORD}" 449221377Sdes if [ -z "${password}" ] 450189006Sdes then 451221377Sdes csih_get_value "Please enter the password for user '${run_service_as}':" "-s" 452221377Sdes password="${csih_value}" 453189006Sdes fi 454221377Sdes fi 455180750Sdes 456221377Sdes # At this point, we either have $run_service_as = "system" and 457221377Sdes # $password is empty, or $run_service_as is some privileged user and 458221377Sdes # (hopefully) $password contains the correct password. So, from here 459221377Sdes # out, we use '-z "${password}"' to discriminate the two cases. 460180750Sdes 461221377Sdes csih_check_user "${run_service_as}" 462180750Sdes 463221377Sdes if [ -n "${csih_cygenv}" ] 464221377Sdes then 465221377Sdes cygwin_env=( -e "CYGWIN=${csih_cygenv}" ) 466221377Sdes fi 467221377Sdes if [ -z "${password}" ] 468221377Sdes then 469221377Sdes if /usr/bin/cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \ 470221377Sdes -a "-D" -y tcpip "${cygwin_env[@]}" 471189006Sdes then 472221377Sdes echo 473221377Sdes csih_inform "The sshd service has been installed under the LocalSystem" 474221377Sdes csih_inform "account (also known as SYSTEM). To start the service now, call" 475221377Sdes csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'. Otherwise, it" 476221377Sdes csih_inform "will start automatically after the next reboot." 477189006Sdes fi 478221377Sdes else 479221377Sdes if /usr/bin/cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \ 480221377Sdes -a "-D" -y tcpip "${cygwin_env[@]}" \ 481221377Sdes -u "${run_service_as}" -w "${password}" 482189006Sdes then 483239849Sdes /usr/bin/editrights -u "${run_service_as}" -a SeServiceLogonRight 484221377Sdes echo 485221377Sdes csih_inform "The sshd service has been installed under the '${run_service_as}'" 486221377Sdes csih_inform "account. To start the service now, call \`net start sshd' or" 487221377Sdes csih_inform "\`cygrunsrv -S sshd'. Otherwise, it will start automatically" 488221377Sdes csih_inform "after the next reboot." 489189006Sdes fi 490221377Sdes fi 491180750Sdes 492221377Sdes if /usr/bin/cygrunsrv -Q sshd >/dev/null 2>&1 493221377Sdes then 494221377Sdes check_service_files_ownership "${run_service_as}" || let ret+=$? 495221377Sdes else 496221377Sdes csih_error_recoverable "Installing sshd as a service failed!" 497221377Sdes let ++ret 498221377Sdes fi 499221377Sdes fi # user allowed us to install as service 500221377Sdes fi # service not yet installed 501221377Sdes return $ret 502180750Sdes} # --- End of install_service --- # 503180750Sdes 504180750Sdes# ====================================================================== 505180750Sdes# Main Entry Point 506180750Sdes# ====================================================================== 507180750Sdes 508180750Sdes# Check how the script has been started. If 509180750Sdes# (1) it has been started by giving the full path and 510180750Sdes# that path is /etc/postinstall, OR 511180750Sdes# (2) Otherwise, if the environment variable 512180750Sdes# SSH_HOST_CONFIG_AUTO_ANSWER_NO is set 513180750Sdes# then set auto_answer to "no". This allows automatic 514180750Sdes# creation of the config files in /etc w/o overwriting 515180750Sdes# them if they already exist. In both cases, color 516180750Sdes# escape sequences are suppressed, so as to prevent 517180750Sdes# cluttering setup's logfiles. 518180750Sdesif [ "$PROGDIR" = "/etc/postinstall" ] 519180750Sdesthen 520180750Sdes csih_auto_answer="no" 521180750Sdes csih_disable_color 522197670Sdes opt_force=yes 523180750Sdesfi 524180750Sdesif [ -n "${SSH_HOST_CONFIG_AUTO_ANSWER_NO}" ] 525180750Sdesthen 526180750Sdes csih_auto_answer="no" 527180750Sdes csih_disable_color 528197670Sdes opt_force=yes 529180750Sdesfi 530180750Sdes 531180750Sdes# ====================================================================== 532180750Sdes# Parse options 533180750Sdes# ====================================================================== 534180740Sdeswhile : 535180740Sdesdo 536180740Sdes case $# in 537180740Sdes 0) 538180740Sdes break 539180740Sdes ;; 540180740Sdes esac 541180740Sdes 542180740Sdes option=$1 543180740Sdes shift 544180740Sdes 545180740Sdes case "${option}" in 546180740Sdes -d | --debug ) 547180740Sdes set -x 548180750Sdes csih_trace_on 549180740Sdes ;; 550180740Sdes 551180740Sdes -y | --yes ) 552180750Sdes csih_auto_answer=yes 553197670Sdes opt_force=yes 554180740Sdes ;; 555180740Sdes 556180740Sdes -n | --no ) 557180750Sdes csih_auto_answer=no 558197670Sdes opt_force=yes 559180740Sdes ;; 560180740Sdes 561180740Sdes -c | --cygwin ) 562180740Sdes cygwin_value="$1" 563180740Sdes shift 564180740Sdes ;; 565180740Sdes 566180740Sdes -p | --port ) 567180740Sdes port_number=$1 568180740Sdes shift 569180740Sdes ;; 570180740Sdes 571197670Sdes -u | --user ) 572197670Sdes user_account="$1" 573197670Sdes shift 574197670Sdes ;; 575197670Sdes 576180740Sdes -w | --pwd ) 577180740Sdes password_value="$1" 578180740Sdes shift 579180740Sdes ;; 580180740Sdes 581180750Sdes --privileged ) 582180750Sdes csih_FORCE_PRIVILEGED_USER=yes 583180750Sdes ;; 584180750Sdes 585180740Sdes *) 586180740Sdes echo "usage: ${progname} [OPTION]..." 587180740Sdes echo 588180740Sdes echo "This script creates an OpenSSH host configuration." 589180740Sdes echo 590180740Sdes echo "Options:" 591180740Sdes echo " --debug -d Enable shell's debug output." 592180740Sdes echo " --yes -y Answer all questions with \"yes\" automatically." 593180740Sdes echo " --no -n Answer all questions with \"no\" automatically." 594180740Sdes echo " --cygwin -c <options> Use \"options\" as value for CYGWIN environment var." 595180740Sdes echo " --port -p <n> sshd listens on port n." 596255670Sdes echo " --user -u <account> privileged user for service, default 'cyg_server'." 597180750Sdes echo " --pwd -w <passwd> Use \"pwd\" as password for privileged user." 598255670Sdes echo " --privileged On Windows XP, require privileged user" 599180750Sdes echo " instead of LocalSystem for sshd service." 600180740Sdes echo 601180740Sdes exit 1 602180740Sdes ;; 603180740Sdes 604180740Sdes esac 605180740Sdesdone 606180740Sdes 607180750Sdes# ====================================================================== 608180750Sdes# Action! 609180750Sdes# ====================================================================== 610180740Sdes 611180740Sdes# Check for running ssh/sshd processes first. Refuse to do anything while 612180740Sdes# some ssh processes are still running 613221377Sdesif /usr/bin/ps -ef | /usr/bin/grep -q '/sshd\?$' 614180740Sdesthen 615180740Sdes echo 616180750Sdes csih_error "There are still ssh processes running. Please shut them down first." 617180740Sdesfi 618180740Sdes 619221377Sdes# Make sure the user is running in an administrative context 620221377Sdesadmin=$(/usr/bin/id -G | /usr/bin/grep -Eq '\<544\>' && echo yes || echo no) 621221377Sdesif [ "${admin}" != "yes" ] 622221377Sdesthen 623221377Sdes echo 624221377Sdes csih_warning "Running this script typically requires administrator privileges!" 625221377Sdes csih_warning "However, it seems your account does not have these privileges." 626221377Sdes csih_warning "Here's the list of groups in your user token:" 627221377Sdes echo 628221377Sdes for i in $(/usr/bin/id -G) 629221377Sdes do 630221377Sdes /usr/bin/awk -F: "/[^:]*:[^:]*:$i:/{ print \" \" \$1; }" /etc/group 631221377Sdes done 632221377Sdes echo 633221377Sdes csih_warning "This usually means you're running this script from a non-admin" 634221377Sdes csih_warning "desktop session, or in a non-elevated shell under UAC control." 635221377Sdes echo 636221377Sdes csih_warning "Make sure you have the appropriate privileges right now," 637221377Sdes csih_warning "otherwise parts of this script will probably fail!" 638221377Sdes echo 639221377Sdes echo -e "${_csih_QUERY_STR} Are you sure you want to continue? (Say \"no\" if you're not sure" 640221377Sdes if ! csih_request "you have the required privileges)" 641221377Sdes then 642221377Sdes echo 643221377Sdes csih_inform "Ok. Exiting. Make sure to switch to an administrative account" 644221377Sdes csih_inform "or to start this script from an elevated shell." 645221377Sdes exit 1 646221377Sdes fi 647221377Sdesfi 648221377Sdes 649221377Sdesecho 650221377Sdes 651221377Sdeswarning_cnt=0 652221377Sdes 653180750Sdes# Create /var/log/lastlog if not already exists 654180740Sdesif [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ] 655180740Sdesthen 656189006Sdes echo 657180750Sdes csih_error_multi "${LOCALSTATEDIR}/log/lastlog exists, but is not a file." \ 658189006Sdes "Cannot create ssh host configuration." 659180740Sdesfi 660180740Sdesif [ ! -e ${LOCALSTATEDIR}/log/lastlog ] 661180740Sdesthen 662221377Sdes /usr/bin/cat /dev/null > ${LOCALSTATEDIR}/log/lastlog 663221377Sdes if ! /usr/bin/chmod 644 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1 664221377Sdes then 665221377Sdes csih_warning "Can't set permissions on ${LOCALSTATEDIR}/log/lastlog!" 666221377Sdes let ++warning_cnt 667221377Sdes fi 668180740Sdesfi 669180740Sdes 670180740Sdes# Create /var/empty file used as chroot jail for privilege separation 671197670Sdescsih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create ${LOCALSTATEDIR}/empty directory." 672221377Sdesif ! /usr/bin/chmod 755 "${LOCALSTATEDIR}/empty" >/dev/null 2>&1 673221377Sdesthen 674221377Sdes csih_warning "Can't set permissions on ${LOCALSTATEDIR}/empty!" 675221377Sdes let ++warning_cnt 676221377Sdesfi 677180740Sdes 678261320Sdes# generate missing host keys 679294328Sdescsih_inform "Generating missing SSH host keys" 680261320Sdes/usr/bin/ssh-keygen -A || let warning_cnt+=$? 681180740Sdes 682180750Sdes# handle ssh_config 683221377Sdescsih_install_config "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt 684221377Sdesif /usr/bin/cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1 685180740Sdesthen 686180740Sdes if [ "${port_number}" != "22" ] 687180740Sdes then 688180750Sdes csih_inform "Updating ${SYSCONFDIR}/ssh_config file with requested port" 689180740Sdes echo "Host localhost" >> ${SYSCONFDIR}/ssh_config 690180740Sdes echo " Port ${port_number}" >> ${SYSCONFDIR}/ssh_config 691180740Sdes fi 692180740Sdesfi 693180740Sdes 694180750Sdes# handle sshd_config (and privsep) 695221377Sdescsih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt 696221377Sdesif ! /usr/bin/cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1 697180740Sdesthen 698294328Sdes sshd_config_configured=yes 699180740Sdesfi 700294328Sdessshd_strictmodes || let warning_cnt+=$? 701221377Sdessshd_privsep || let warning_cnt+=$? 702294328Sdessshd_config_tweak || let warning_cnt+=$? 703221377Sdesupdate_services_file || let warning_cnt+=$? 704221377Sdesupdate_inetd_conf || let warning_cnt+=$? 705221377Sdesinstall_service || let warning_cnt+=$? 706180740Sdes 707180750Sdesecho 708221377Sdesif [ $warning_cnt -eq 0 ] 709221377Sdesthen 710221377Sdes csih_inform "Host configuration finished. Have fun!" 711221377Sdeselse 712221377Sdes csih_warning "Host configuration exited with ${warning_cnt} errors or warnings!" 713221377Sdes csih_warning "Make sure that all problems reported are fixed," 714221377Sdes csih_warning "then re-run ssh-host-config." 715221377Sdesfi 716221377Sdesexit $warning_cnt 717