ssh-host-config 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. #!/bin/bash
  2. #
  3. # ssh-host-config, Copyright 2000-2014 Red Hat Inc.
  4. #
  5. # This file is part of the Cygwin port of OpenSSH.
  6. #
  7. # Permission to use, copy, modify, and distribute this software for any
  8. # purpose with or without fee is hereby granted, provided that the above
  9. # copyright notice and this permission notice appear in all copies.
  10. #
  11. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  12. # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  13. # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  14. # IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  15. # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
  17. # THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  18. # ======================================================================
  19. # Initialization
  20. # ======================================================================
  21. CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh
  22. # List of apps used. This is checkad for existence in csih_sanity_check
  23. # Don't use *any* transient commands before sourcing the csih helper script,
  24. # otherwise the sanity checks are short-circuited.
  25. declare -a csih_required_commands=(
  26. /usr/bin/basename coreutils
  27. /usr/bin/cat coreutils
  28. /usr/bin/chmod coreutils
  29. /usr/bin/dirname coreutils
  30. /usr/bin/id coreutils
  31. /usr/bin/mv coreutils
  32. /usr/bin/rm coreutils
  33. /usr/bin/cygpath cygwin
  34. /usr/bin/mkpasswd cygwin
  35. /usr/bin/mount cygwin
  36. /usr/bin/ps cygwin
  37. /usr/bin/umount cygwin
  38. /usr/bin/cmp diffutils
  39. /usr/bin/grep grep
  40. /usr/bin/awk gawk
  41. /usr/bin/ssh-keygen openssh
  42. /usr/sbin/sshd openssh
  43. /usr/bin/sed sed
  44. )
  45. csih_sanity_check_server=yes
  46. source ${CSIH_SCRIPT}
  47. PROGNAME=$(/usr/bin/basename $0)
  48. _tdir=$(/usr/bin/dirname $0)
  49. PROGDIR=$(cd $_tdir && pwd)
  50. # Subdirectory where the new package is being installed
  51. PREFIX=/usr
  52. # Directory where the config files are stored
  53. SYSCONFDIR=/etc
  54. LOCALSTATEDIR=/var
  55. sshd_config_configured=no
  56. port_number=22
  57. service_name=cygsshd
  58. strictmodes=yes
  59. cygwin_value=""
  60. user_account=
  61. password_value=
  62. opt_force=no
  63. # ======================================================================
  64. # Routine: update_services_file
  65. # ======================================================================
  66. update_services_file() {
  67. local _my_etcdir="/ssh-host-config.$$"
  68. local _win_etcdir
  69. local _services
  70. local _spaces
  71. local _serv_tmp
  72. local _wservices
  73. local ret=0
  74. _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
  75. _services="${_my_etcdir}/services"
  76. _spaces=" #"
  77. _serv_tmp="${_my_etcdir}/srv.out.$$"
  78. /usr/bin/mount -o text,posix=0,noacl -f "${_win_etcdir}" "${_my_etcdir}"
  79. # Depends on the above mount
  80. _wservices=`cygpath -w "${_services}"`
  81. # Add ssh 22/tcp and ssh 22/udp to services
  82. if [ `/usr/bin/grep -q 'ssh[[:space:]][[:space:]]*22' "${_services}"; echo $?` -ne 0 ]
  83. then
  84. 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}"
  85. then
  86. if /usr/bin/mv "${_serv_tmp}" "${_services}"
  87. then
  88. csih_inform "Added ssh to ${_wservices}"
  89. else
  90. csih_warning "Adding ssh to ${_wservices} failed!"
  91. let ++ret
  92. fi
  93. /usr/bin/rm -f "${_serv_tmp}"
  94. else
  95. csih_warning "Adding ssh to ${_wservices} failed!"
  96. let ++ret
  97. fi
  98. fi
  99. /usr/bin/umount "${_my_etcdir}"
  100. return $ret
  101. } # --- End of update_services_file --- #
  102. # ======================================================================
  103. # Routine: sshd_strictmodes
  104. # MODIFIES: strictmodes
  105. # ======================================================================
  106. sshd_strictmodes() {
  107. if [ "${sshd_config_configured}" != "yes" ]
  108. then
  109. echo
  110. csih_inform "StrictModes is set to 'yes' by default."
  111. csih_inform "This is the recommended setting, but it requires that the POSIX"
  112. csih_inform "permissions of the user's home directory, the user's .ssh"
  113. csih_inform "directory, and the user's ssh key files are tight so that"
  114. csih_inform "only the user has write permissions."
  115. csih_inform "On the other hand, StrictModes don't work well with default"
  116. csih_inform "Windows permissions of a home directory mounted with the"
  117. csih_inform "'noacl' option, and they don't work at all if the home"
  118. csih_inform "directory is on a FAT or FAT32 partition."
  119. if ! csih_request "Should StrictModes be used?"
  120. then
  121. strictmodes=no
  122. fi
  123. fi
  124. return 0
  125. }
  126. # ======================================================================
  127. # Routine: sshd_privsep
  128. # Try to create ssshd user account
  129. # ======================================================================
  130. sshd_privsep() {
  131. local ret=0
  132. if [ "${sshd_config_configured}" != "yes" ]
  133. then
  134. if ! csih_create_unprivileged_user sshd
  135. then
  136. csih_error_recoverable "Could not create user 'sshd'!"
  137. csih_error_recoverable "You will not be able to run an sshd service"
  138. csih_error_recoverable "under a privileged account successfully."
  139. csih_error_recoverable "Make sure to create a non-privileged user 'sshd'"
  140. csih_error_recoverable "manually before trying to run the service!"
  141. let ++ret
  142. fi
  143. fi
  144. return $ret
  145. } # --- End of sshd_privsep --- #
  146. # ======================================================================
  147. # Routine: sshd_config_tweak
  148. # ======================================================================
  149. sshd_config_tweak() {
  150. local ret=0
  151. # Modify sshd_config
  152. csih_inform "Updating ${SYSCONFDIR}/sshd_config file"
  153. if [ "${port_number}" -ne 22 ]
  154. then
  155. /usr/bin/sed -i -e "s/^#\?[[:space:]]*Port[[:space:]].*/Port ${port_number}/" \
  156. ${SYSCONFDIR}/sshd_config
  157. if [ $? -ne 0 ]
  158. then
  159. csih_warning "Setting listening port to ${port_number} failed!"
  160. csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
  161. let ++ret
  162. fi
  163. fi
  164. if [ "${strictmodes}" = "no" ]
  165. then
  166. /usr/bin/sed -i -e "s/^#\?[[:space:]]*StrictModes[[:space:]].*/StrictModes no/" \
  167. ${SYSCONFDIR}/sshd_config
  168. if [ $? -ne 0 ]
  169. then
  170. csih_warning "Setting StrictModes to 'no' failed!"
  171. csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
  172. let ++ret
  173. fi
  174. fi
  175. return $ret
  176. } # --- End of sshd_config_tweak --- #
  177. # ======================================================================
  178. # Routine: update_inetd_conf
  179. # ======================================================================
  180. update_inetd_conf() {
  181. local _inetcnf="${SYSCONFDIR}/inetd.conf"
  182. local _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
  183. local _inetcnf_dir="${SYSCONFDIR}/inetd.d"
  184. local _sshd_inetd_conf="${_inetcnf_dir}/sshd-inetd"
  185. local _sshd_inetd_conf_tmp="${_inetcnf_dir}/sshd-inetd.$$"
  186. local _with_comment=1
  187. local ret=0
  188. if [ -d "${_inetcnf_dir}" ]
  189. then
  190. # we have inetutils-1.5 inetd.d support
  191. if [ -f "${_inetcnf}" ]
  192. then
  193. /usr/bin/grep -q '^[[:space:]]*ssh' "${_inetcnf}" && _with_comment=0
  194. # check for sshd OR ssh in top-level inetd.conf file, and remove
  195. # will be replaced by a file in inetd.d/
  196. if [ $(/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?) -eq 0 ]
  197. then
  198. /usr/bin/grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}"
  199. if [ -f "${_inetcnf_tmp}" ]
  200. then
  201. if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}"
  202. then
  203. csih_inform "Removed ssh[d] from ${_inetcnf}"
  204. else
  205. csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
  206. let ++ret
  207. fi
  208. /usr/bin/rm -f "${_inetcnf_tmp}"
  209. else
  210. csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
  211. let ++ret
  212. fi
  213. fi
  214. fi
  215. csih_install_config "${_sshd_inetd_conf}" "${SYSCONFDIR}/defaults"
  216. if /usr/bin/cmp "${SYSCONFDIR}/defaults${_sshd_inetd_conf}" "${_sshd_inetd_conf}" >/dev/null 2>&1
  217. then
  218. if [ "${_with_comment}" -eq 0 ]
  219. then
  220. /usr/bin/sed -e 's/@COMMENT@[[:space:]]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
  221. else
  222. /usr/bin/sed -e 's/@COMMENT@[[:space:]]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
  223. fi
  224. if /usr/bin/mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}"
  225. then
  226. csih_inform "Updated ${_sshd_inetd_conf}"
  227. else
  228. csih_warning "Updating ${_sshd_inetd_conf} failed!"
  229. let ++ret
  230. fi
  231. fi
  232. elif [ -f "${_inetcnf}" ]
  233. then
  234. /usr/bin/grep -q '^[[:space:]]*sshd' "${_inetcnf}" && _with_comment=0
  235. # check for sshd in top-level inetd.conf file, and remove
  236. # will be replaced by a file in inetd.d/
  237. if [ `/usr/bin/grep -q '^#\?[[:space:]]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
  238. then
  239. /usr/bin/grep -v '^#\?[[:space:]]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
  240. if [ -f "${_inetcnf_tmp}" ]
  241. then
  242. if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}"
  243. then
  244. csih_inform "Removed sshd from ${_inetcnf}"
  245. else
  246. csih_warning "Removing sshd from ${_inetcnf} failed!"
  247. let ++ret
  248. fi
  249. /usr/bin/rm -f "${_inetcnf_tmp}"
  250. else
  251. csih_warning "Removing sshd from ${_inetcnf} failed!"
  252. let ++ret
  253. fi
  254. fi
  255. # Add ssh line to inetd.conf
  256. if [ `/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
  257. then
  258. if [ "${_with_comment}" -eq 0 ]
  259. then
  260. echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
  261. else
  262. echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
  263. fi
  264. if [ $? -eq 0 ]
  265. then
  266. csih_inform "Added ssh to ${_inetcnf}"
  267. else
  268. csih_warning "Adding ssh to ${_inetcnf} failed!"
  269. let ++ret
  270. fi
  271. fi
  272. fi
  273. return $ret
  274. } # --- End of update_inetd_conf --- #
  275. # ======================================================================
  276. # Routine: check_service_files_ownership
  277. # Checks that the files in /etc and /var belong to the right owner
  278. # ======================================================================
  279. check_service_files_ownership() {
  280. local run_service_as=$1
  281. local ret=0
  282. if [ -z "${run_service_as}" ]
  283. then
  284. accnt_name=$(/usr/bin/cygrunsrv -VQ "${service_name}" |
  285. /usr/bin/sed -ne 's/^Account *: *//gp')
  286. if [ "${accnt_name}" = "LocalSystem" ]
  287. then
  288. # Convert "LocalSystem" to "SYSTEM" as is the correct account name
  289. run_service_as="SYSTEM"
  290. else
  291. dom="${accnt_name%%\\*}"
  292. accnt_name="${accnt_name#*\\}"
  293. if [ "${dom}" = '.' ]
  294. then
  295. # Check local account
  296. run_service_as=$(/usr/bin/mkpasswd -l -u "${accnt_name}" |
  297. /usr/bin/awk -F: '{print $1;}')
  298. else
  299. # Check domain
  300. run_service_as=$(/usr/bin/mkpasswd -d "${dom}" -u "${accnt_name}" |
  301. /usr/bin/awk -F: '{print $1;}')
  302. fi
  303. fi
  304. if [ -z "${run_service_as}" ]
  305. then
  306. csih_warning "Couldn't determine name of user running ${service_name} service from account database!"
  307. csih_warning "As a result, this script cannot make sure that the files used"
  308. csih_warning "by the ${service_name} service belong to the user running the service."
  309. return 1
  310. fi
  311. fi
  312. for i in "${SYSCONFDIR}"/ssh_config "${SYSCONFDIR}"/sshd_config "${SYSCONFDIR}"/ssh_host_*key "${SYSCONFDIR}"/ssh_host_*key.pub
  313. do
  314. if [ -f "$i" ]
  315. then
  316. if ! chown "${run_service_as}".544 "$i" >/dev/null 2>&1
  317. then
  318. csih_warning "Couldn't change owner of $i!"
  319. let ++ret
  320. fi
  321. fi
  322. done
  323. if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty >/dev/null 2>&1
  324. then
  325. csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/empty!"
  326. let ++ret
  327. fi
  328. if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1
  329. then
  330. csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/lastlog!"
  331. let ++ret
  332. fi
  333. if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
  334. then
  335. if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log >/dev/null 2>&1
  336. then
  337. csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/sshd.log!"
  338. let ++ret
  339. fi
  340. fi
  341. if [ $ret -ne 0 ]
  342. then
  343. csih_warning "Couldn't change owner of important files to ${run_service_as}!"
  344. csih_warning "This may cause the ${service_name} service to fail! Please make sure that"
  345. csih_warning "you have sufficient permissions to change the ownership of files"
  346. csih_warning "and try to run the ssh-host-config script again."
  347. fi
  348. return $ret
  349. } # --- End of check_service_files_ownership --- #
  350. # ======================================================================
  351. # Routine: install_service
  352. # Install sshd as a service
  353. # ======================================================================
  354. install_service() {
  355. local run_service_as
  356. local password
  357. local ret=0
  358. echo
  359. if /usr/bin/cygrunsrv -Q ${service_name} >/dev/null 2>&1
  360. then
  361. csih_inform "Sshd service is already installed."
  362. check_service_files_ownership "" || let ret+=$?
  363. else
  364. echo -e "${_csih_QUERY_STR} Do you want to install sshd as a service?"
  365. if csih_request "(Say \"no\" if it is already installed as a service)"
  366. then
  367. csih_get_cygenv "${cygwin_value}"
  368. if ( [ "$csih_FORCE_PRIVILEGED_USER" != "yes" ] )
  369. then
  370. # Enforce using privileged user on 64 bit Vista or W7 under WOW64
  371. is_wow64=$(/usr/bin/uname | /usr/bin/grep -q 'WOW' && echo 1 || echo 0)
  372. if ( csih_is_nt2003 && ! csih_is_windows8 && [ "${is_wow64}" = "1" ] )
  373. then
  374. csih_inform "Running 32 bit Cygwin on 64 bit Windows Vista or Windows 7"
  375. csih_inform "the SYSTEM account is not sufficient to setuid to a local"
  376. csih_inform "user account. You need to have or to create a privileged"
  377. csih_inform "account. This script will help you do so."
  378. echo
  379. csih_FORCE_PRIVILEGED_USER=yes
  380. fi
  381. fi
  382. if ( [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] )
  383. then
  384. [ "${opt_force}" = "yes" ] && opt_f=-f
  385. [ -n "${user_account}" ] && opt_u="-u ""${user_account}"""
  386. csih_select_privileged_username ${opt_f} ${opt_u} sshd
  387. if ! csih_create_privileged_user "${password_value}"
  388. then
  389. csih_error_recoverable "There was a serious problem creating a privileged user."
  390. csih_request "Do you want to proceed anyway?" || exit 1
  391. let ++ret
  392. fi
  393. # Never returns empty if NT or above
  394. run_service_as=$(csih_service_should_run_as)
  395. else
  396. run_service_as="SYSTEM"
  397. fi
  398. if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ]
  399. then
  400. password="${csih_PRIVILEGED_PASSWORD}"
  401. if [ -z "${password}" ]
  402. then
  403. csih_get_value "Please enter the password for user '${run_service_as}':" "-s"
  404. password="${csih_value}"
  405. fi
  406. fi
  407. # At this point, we either have $run_service_as = "system" and
  408. # $password is empty, or $run_service_as is some privileged user and
  409. # (hopefully) $password contains the correct password. So, from here
  410. # out, we use '-z "${password}"' to discriminate the two cases.
  411. csih_check_user "${run_service_as}"
  412. if [ -n "${csih_cygenv}" ]
  413. then
  414. cygwin_env=( -e "CYGWIN=${csih_cygenv}" )
  415. fi
  416. if [ -z "${password}" ]
  417. then
  418. if /usr/bin/cygrunsrv -I ${service_name} -d "CYGWIN ${service_name}" -p /usr/sbin/sshd \
  419. -a "-D" -y tcpip "${cygwin_env[@]}"
  420. then
  421. echo
  422. csih_inform "The sshd service has been installed under the LocalSystem"
  423. csih_inform "account (also known as SYSTEM). To start the service now, call"
  424. csih_inform "\`net start ${service_name}' or \`cygrunsrv -S ${service_name}'. Otherwise, it"
  425. csih_inform "will start automatically after the next reboot."
  426. fi
  427. else
  428. if /usr/bin/cygrunsrv -I ${service_name} -d "CYGWIN ${service_name}" -p /usr/sbin/sshd \
  429. -a "-D" -y tcpip "${cygwin_env[@]}" \
  430. -u "${run_service_as}" -w "${password}"
  431. then
  432. /usr/bin/editrights -u "${run_service_as}" -a SeServiceLogonRight
  433. echo
  434. csih_inform "The sshd service has been installed under the '${run_service_as}'"
  435. csih_inform "account. To start the service now, call \`net start ${service_name}' or"
  436. csih_inform "\`cygrunsrv -S ${service_name}'. Otherwise, it will start automatically"
  437. csih_inform "after the next reboot."
  438. fi
  439. fi
  440. if /usr/bin/cygrunsrv -Q ${service_name} >/dev/null 2>&1
  441. then
  442. check_service_files_ownership "${run_service_as}" || let ret+=$?
  443. else
  444. csih_error_recoverable "Installing sshd as a service failed!"
  445. let ++ret
  446. fi
  447. fi # user allowed us to install as service
  448. fi # service not yet installed
  449. return $ret
  450. } # --- End of install_service --- #
  451. # ======================================================================
  452. # Main Entry Point
  453. # ======================================================================
  454. # Check how the script has been started. If
  455. # (1) it has been started by giving the full path and
  456. # that path is /etc/postinstall, OR
  457. # (2) Otherwise, if the environment variable
  458. # SSH_HOST_CONFIG_AUTO_ANSWER_NO is set
  459. # then set auto_answer to "no". This allows automatic
  460. # creation of the config files in /etc w/o overwriting
  461. # them if they already exist. In both cases, color
  462. # escape sequences are suppressed, so as to prevent
  463. # cluttering setup's logfiles.
  464. if [ "$PROGDIR" = "/etc/postinstall" ]
  465. then
  466. csih_auto_answer="no"
  467. csih_disable_color
  468. opt_force=yes
  469. fi
  470. if [ -n "${SSH_HOST_CONFIG_AUTO_ANSWER_NO}" ]
  471. then
  472. csih_auto_answer="no"
  473. csih_disable_color
  474. opt_force=yes
  475. fi
  476. # ======================================================================
  477. # Parse options
  478. # ======================================================================
  479. while :
  480. do
  481. case $# in
  482. 0)
  483. break
  484. ;;
  485. esac
  486. option=$1
  487. shift
  488. case "${option}" in
  489. -d | --debug )
  490. set -x
  491. csih_trace_on
  492. ;;
  493. -y | --yes )
  494. csih_auto_answer=yes
  495. opt_force=yes
  496. ;;
  497. -n | --no )
  498. csih_auto_answer=no
  499. opt_force=yes
  500. ;;
  501. -c | --cygwin )
  502. cygwin_value="$1"
  503. shift
  504. ;;
  505. -N | --name )
  506. service_name=$1
  507. shift
  508. ;;
  509. -p | --port )
  510. port_number=$1
  511. shift
  512. ;;
  513. -u | --user )
  514. user_account="$1"
  515. shift
  516. ;;
  517. -w | --pwd )
  518. password_value="$1"
  519. shift
  520. ;;
  521. --privileged )
  522. csih_FORCE_PRIVILEGED_USER=yes
  523. ;;
  524. *)
  525. echo "usage: ${progname} [OPTION]..."
  526. echo
  527. echo "This script creates an OpenSSH host configuration."
  528. echo
  529. echo "Options:"
  530. echo " --debug -d Enable shell's debug output."
  531. echo " --yes -y Answer all questions with \"yes\" automatically."
  532. echo " --no -n Answer all questions with \"no\" automatically."
  533. echo " --cygwin -c <options> Use \"options\" as value for CYGWIN environment var."
  534. echo " --name -N <name> sshd windows service name."
  535. echo " --port -p <n> sshd listens on port n."
  536. echo " --user -u <account> privileged user for service, default 'cyg_server'."
  537. echo " --pwd -w <passwd> Use \"pwd\" as password for privileged user."
  538. echo " --privileged On Windows XP, require privileged user"
  539. echo " instead of LocalSystem for sshd service."
  540. echo
  541. exit 1
  542. ;;
  543. esac
  544. done
  545. # ======================================================================
  546. # Action!
  547. # ======================================================================
  548. # Check for running ssh/sshd processes first. Refuse to do anything while
  549. # some ssh processes are still running
  550. if /usr/bin/ps -ef | /usr/bin/grep -q '/sshd\?$'
  551. then
  552. echo
  553. csih_error "There are still ssh processes running. Please shut them down first."
  554. fi
  555. # Make sure the user is running in an administrative context
  556. admin=$(/usr/bin/id -G | /usr/bin/grep -Eq '\<544\>' && echo yes || echo no)
  557. if [ "${admin}" != "yes" ]
  558. then
  559. echo
  560. csih_warning "Running this script typically requires administrator privileges!"
  561. csih_warning "However, it seems your account does not have these privileges."
  562. csih_warning "Here's the list of groups in your user token:"
  563. echo
  564. /usr/bin/id -Gnz | xargs -0n1 echo " "
  565. echo
  566. csih_warning "This usually means you're running this script from a non-admin"
  567. csih_warning "desktop session, or in a non-elevated shell under UAC control."
  568. echo
  569. csih_warning "Make sure you have the appropriate privileges right now,"
  570. csih_warning "otherwise parts of this script will probably fail!"
  571. echo
  572. echo -e "${_csih_QUERY_STR} Are you sure you want to continue? (Say \"no\" if you're not sure"
  573. if ! csih_request "you have the required privileges)"
  574. then
  575. echo
  576. csih_inform "Ok. Exiting. Make sure to switch to an administrative account"
  577. csih_inform "or to start this script from an elevated shell."
  578. exit 1
  579. fi
  580. fi
  581. echo
  582. warning_cnt=0
  583. # Create /var/log/lastlog if not already exists
  584. if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ]
  585. then
  586. echo
  587. csih_error_multi "${LOCALSTATEDIR}/log/lastlog exists, but is not a file." \
  588. "Cannot create ssh host configuration."
  589. fi
  590. if [ ! -e ${LOCALSTATEDIR}/log/lastlog ]
  591. then
  592. /usr/bin/cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
  593. if ! /usr/bin/chmod 644 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1
  594. then
  595. csih_warning "Can't set permissions on ${LOCALSTATEDIR}/log/lastlog!"
  596. let ++warning_cnt
  597. fi
  598. fi
  599. # Create /var/empty file used as chroot jail for privilege separation
  600. csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create ${LOCALSTATEDIR}/empty directory."
  601. if ! /usr/bin/chmod 755 "${LOCALSTATEDIR}/empty" >/dev/null 2>&1
  602. then
  603. csih_warning "Can't set permissions on ${LOCALSTATEDIR}/empty!"
  604. let ++warning_cnt
  605. fi
  606. # generate missing host keys
  607. csih_inform "Generating missing SSH host keys"
  608. /usr/bin/ssh-keygen -A || let warning_cnt+=$?
  609. # handle ssh_config
  610. csih_install_config "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt
  611. if /usr/bin/cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1
  612. then
  613. if [ "${port_number}" != "22" ]
  614. then
  615. csih_inform "Updating ${SYSCONFDIR}/ssh_config file with requested port"
  616. echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
  617. echo " Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
  618. fi
  619. fi
  620. # handle sshd_config
  621. # make sure not to change the existing file
  622. mod_before=""
  623. if [ -e "${SYSCONFDIR}/sshd_config" ]
  624. then
  625. mod_before=$(stat "${SYSCONFDIR}/sshd_config" | grep '^Modify:')
  626. fi
  627. csih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt
  628. mod_now=$(stat "${SYSCONFDIR}/sshd_config" | grep '^Modify:')
  629. if ! /usr/bin/cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
  630. then
  631. sshd_config_configured=yes
  632. fi
  633. if [ "${mod_before}" != "${mod_now}" ]
  634. then
  635. sshd_strictmodes || let warning_cnt+=$?
  636. sshd_config_tweak || let warning_cnt+=$?
  637. fi
  638. #sshd_privsep || let warning_cnt+=$?
  639. update_services_file || let warning_cnt+=$?
  640. update_inetd_conf || let warning_cnt+=$?
  641. install_service || let warning_cnt+=$?
  642. echo
  643. if [ $warning_cnt -eq 0 ]
  644. then
  645. csih_inform "Host configuration finished. Have fun!"
  646. else
  647. csih_warning "Host configuration exited with ${warning_cnt} errors or warnings!"
  648. csih_warning "Make sure that all problems reported are fixed,"
  649. csih_warning "then re-run ssh-host-config."
  650. fi
  651. exit $warning_cnt