]> andersk Git - gssapi-openssh.git/blob - openssh/contrib/cygwin/ssh-host-config
Import of OpenSSH 5.2p1
[gssapi-openssh.git] / openssh / contrib / cygwin / ssh-host-config
1 #!/bin/bash
2 #
3 # ssh-host-config, Copyright 2000, 2001, 2002, 2003 Red Hat Inc.
4 #
5 # This file is part of the Cygwin port of OpenSSH.
6
7 # ======================================================================
8 # Initialization
9 # ======================================================================
10 PROGNAME=$(basename $0)
11 _tdir=$(dirname $0)
12 PROGDIR=$(cd $_tdir && pwd)
13
14 CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh
15
16 # Subdirectory where the new package is being installed
17 PREFIX=/usr
18
19 # Directory where the config files are stored
20 SYSCONFDIR=/etc
21 LOCALSTATEDIR=/var
22
23 source ${CSIH_SCRIPT}
24
25 port_number=22
26 privsep_configured=no
27 privsep_used=yes
28 cygwin_value=""
29 password_value=
30
31 # ======================================================================
32 # Routine: create_host_keys
33 # ======================================================================
34 create_host_keys() {
35   if [ ! -f "${SYSCONFDIR}/ssh_host_key" ]
36   then
37     csih_inform "Generating ${SYSCONFDIR}/ssh_host_key"
38     ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
39   fi
40
41   if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
42   then
43     csih_inform "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
44     ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
45   fi
46
47   if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ]
48   then
49     csih_inform "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
50     ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
51   fi
52 } # --- End of create_host_keys --- #
53
54 # ======================================================================
55 # Routine: update_services_file
56 # ======================================================================
57 update_services_file() {
58   local _my_etcdir="/ssh-host-config.$$"
59   local _win_etcdir
60   local _services
61   local _spaces
62   local _serv_tmp
63   local _wservices
64
65   if csih_is_nt
66   then
67     _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
68     _services="${_my_etcdir}/services"
69     # On NT, 27 spaces, no space after the hash
70     _spaces="                           #"
71   else
72     _win_etcdir="${WINDIR}"
73     _services="${_my_etcdir}/SERVICES"
74     # On 9x, 18 spaces (95 is very touchy), a space after the hash
75     _spaces="                  # "
76   fi
77   _serv_tmp="${_my_etcdir}/srv.out.$$"
78
79   mount -o text -f "${_win_etcdir}" "${_my_etcdir}"
80
81   # Depends on the above mount
82   _wservices=`cygpath -w "${_services}"`
83
84   # Remove sshd 22/port from services
85   if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
86   then
87     grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
88     if [ -f "${_serv_tmp}" ]
89     then
90       if mv "${_serv_tmp}" "${_services}"
91       then
92         csih_inform "Removing sshd from ${_wservices}"
93       else
94         csih_warning "Removing sshd from ${_wservices} failed!"
95       fi
96       rm -f "${_serv_tmp}"
97     else
98       csih_warning "Removing sshd from ${_wservices} failed!"
99     fi
100   fi
101
102   # Add ssh 22/tcp  and ssh 22/udp to services
103   if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
104   then
105     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}"
106     then
107       if mv "${_serv_tmp}" "${_services}"
108       then
109         csih_inform "Added ssh to ${_wservices}"
110       else
111         csih_warning "Adding ssh to ${_wservices} failed!"
112       fi
113       rm -f "${_serv_tmp}"
114     else
115       csih_warning "Adding ssh to ${_wservices} failed!"
116     fi
117   fi
118   umount "${_my_etcdir}"
119 } # --- End of update_services_file --- #
120
121 # ======================================================================
122 # Routine: sshd_privsep
123 #  MODIFIES: privsep_configured  privsep_used
124 # ======================================================================
125 sshd_privsep() {
126   local sshdconfig_tmp
127
128   if [ "${privsep_configured}" != "yes" ]
129   then
130     if csih_is_nt
131     then
132       csih_inform "Privilege separation is set to yes by default since OpenSSH 3.3."
133       csih_inform "However, this requires a non-privileged account called 'sshd'."
134       csih_inform "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
135       if csih_request "Should privilege separation be used?"
136       then
137         privsep_used=yes
138         if ! csih_create_unprivileged_user sshd
139         then
140           csih_warning "Couldn't create user 'sshd'!"
141           csih_warning "Privilege separation set to 'no' again!"
142           csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
143           privsep_used=no
144         fi
145       else
146         privsep_used=no
147       fi
148     else
149       # On 9x don't use privilege separation.  Since security isn't
150       # available it just adds useless additional processes.
151       privsep_used=no
152     fi
153   fi
154
155   # Create default sshd_config from skeleton files in /etc/defaults/etc or
156   # modify to add the missing privsep configuration option
157   if cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
158   then
159     csih_inform "Updating ${SYSCONFDIR}/sshd_config file"
160     sshdconfig_tmp=${SYSCONFDIR}/sshd_config.$$
161     sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
162           s/^#Port 22/Port ${port_number}/
163           s/^#StrictModes yes/StrictModes no/" \
164         < ${SYSCONFDIR}/sshd_config \
165         > "${sshdconfig_tmp}"
166     mv "${sshdconfig_tmp}" ${SYSCONFDIR}/sshd_config
167   elif [ "${privsep_configured}" != "yes" ]
168   then
169     echo >> ${SYSCONFDIR}/sshd_config
170     echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
171   fi
172 } # --- End of sshd_privsep --- #
173
174 # ======================================================================
175 # Routine: update_inetd_conf
176 # ======================================================================
177 update_inetd_conf() {
178   local _inetcnf="${SYSCONFDIR}/inetd.conf"
179   local _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
180   local _inetcnf_dir="${SYSCONFDIR}/inetd.d"
181   local _sshd_inetd_conf="${_inetcnf_dir}/sshd-inetd"
182   local _sshd_inetd_conf_tmp="${_inetcnf_dir}/sshd-inetd.$$"
183   local _with_comment=1
184
185   if [ -d "${_inetcnf_dir}" ]
186   then
187     # we have inetutils-1.5 inetd.d support
188     if [ -f "${_inetcnf}" ]
189     then
190       grep -q '^[ \t]*ssh' "${_inetcnf}" && _with_comment=0
191
192       # check for sshd OR ssh in top-level inetd.conf file, and remove
193       # will be replaced by a file in inetd.d/
194       if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -eq 0 ]
195       then
196         grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}"
197         if [ -f "${_inetcnf_tmp}" ]
198         then
199           if mv "${_inetcnf_tmp}" "${_inetcnf}"
200           then
201             csih_inform "Removed ssh[d] from ${_inetcnf}"
202           else
203             csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
204           fi
205           rm -f "${_inetcnf_tmp}"
206         else
207           csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
208         fi
209       fi
210     fi
211
212     csih_install_config "${_sshd_inetd_conf}"   "${SYSCONFDIR}/defaults"
213     if cmp "${SYSCONFDIR}/defaults${_sshd_inetd_conf}" "${_sshd_inetd_conf}" >/dev/null 2>&1
214     then
215       if [ "${_with_comment}" -eq 0 ]
216       then
217         sed -e 's/@COMMENT@[ \t]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
218       else
219         sed -e 's/@COMMENT@[ \t]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
220       fi
221       mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}"
222       csih_inform "Updated ${_sshd_inetd_conf}"
223     fi
224
225   elif [ -f "${_inetcnf}" ]
226   then
227     grep -q '^[ \t]*sshd' "${_inetcnf}" && _with_comment=0
228
229     # check for sshd in top-level inetd.conf file, and remove
230     # will be replaced by a file in inetd.d/
231     if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
232     then
233       grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
234       if [ -f "${_inetcnf_tmp}" ]
235       then
236         if mv "${_inetcnf_tmp}" "${_inetcnf}"
237         then
238             csih_inform "Removed sshd from ${_inetcnf}"
239         else
240             csih_warning "Removing sshd from ${_inetcnf} failed!"
241         fi
242         rm -f "${_inetcnf_tmp}"
243       else
244         csih_warning "Removing sshd from ${_inetcnf} failed!"
245       fi
246     fi
247
248     # Add ssh line to inetd.conf
249     if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
250     then
251       if [ "${_with_comment}" -eq 0 ]
252       then
253         echo 'ssh  stream  tcp     nowait  root    /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
254       else
255         echo '# ssh  stream  tcp     nowait  root    /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
256       fi
257       csih_inform "Added ssh to ${_inetcnf}"
258     fi
259   fi
260 } # --- End of update_inetd_conf --- #
261
262 # ======================================================================
263 # Routine: install_service
264 #   Install sshd as a service
265 # ======================================================================
266 install_service() {
267   local run_service_as
268   local password
269
270   if csih_is_nt
271   then
272     if ! cygrunsrv -Q sshd >/dev/null 2>&1
273     then
274       echo
275       echo
276       csih_warning "The following functions require administrator privileges!"
277       echo
278       echo -e "${_csih_QUERY_STR} Do you want to install sshd as a service?"
279       if csih_request "(Say \"no\" if it is already installed as a service)"
280       then
281         csih_get_cygenv "${cygwin_value}"
282
283         if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] )
284         then
285           csih_inform "On Windows Server 2003, Windows Vista, and above, the"
286           csih_inform "SYSTEM account cannot setuid to other users -- a capability"
287           csih_inform "sshd requires.  You need to have or to create a privileged"
288           csih_inform "account.  This script will help you do so."
289           echo
290           if ! csih_create_privileged_user "${password_value}"
291           then
292             csih_error_recoverable "There was a serious problem creating a privileged user."
293             csih_request "Do you want to proceed anyway?" || exit 1
294           fi
295         fi
296
297         # never returns empty if NT or above
298         run_service_as=$(csih_service_should_run_as)
299
300         if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ]
301         then
302           password="${csih_PRIVILEGED_PASSWORD}"
303           if [ -z "${password}" ]
304           then
305             csih_get_value "Please enter the password for user '${run_service_as}':" "-s"
306             password="${csih_value}"
307           fi
308         fi
309
310         # at this point, we either have $run_service_as = "system" and $password is empty,
311         # or $run_service_as is some privileged user and (hopefully) $password contains
312         # the correct password.  So, from here out, we use '-z "${password}"' to discriminate
313         # the two cases.
314
315         csih_check_user "${run_service_as}"
316
317         if [ -n "${csih_cygenv}" ]
318         then
319           cygwin_env="-e CYGWIN=\"${csih_cygenv}\""
320         fi
321         if [ -z "${password}" ]
322         then
323           if eval cygrunsrv -I sshd -d \"CYGWIN sshd\" -p /usr/sbin/sshd \
324                             -a "-D" -y tcpip ${cygwin_env}
325           then
326             echo
327             csih_inform "The sshd service has been installed under the LocalSystem"
328             csih_inform "account (also known as SYSTEM). To start the service now, call"
329             csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'.  Otherwise, it"
330             csih_inform "will start automatically after the next reboot."
331           fi
332         else
333           if eval cygrunsrv -I sshd -d \"CYGWIN sshd\" -p /usr/sbin/sshd \
334                             -a "-D" -y tcpip ${cygwin_env} \
335                             -u "${run_service_as}" -w "${password}"
336           then
337             echo
338             csih_inform "The sshd service has been installed under the '${run_service_as}'"
339             csih_inform "account.  To start the service now, call \`net start sshd' or"
340             csih_inform "\`cygrunsrv -S sshd'.  Otherwise, it will start automatically"
341             csih_inform "after the next reboot."
342           fi
343         fi
344
345         # now, if successfully installed, set ownership of the affected files
346         if cygrunsrv -Q sshd >/dev/null 2>&1
347         then
348           chown "${run_service_as}" ${SYSCONFDIR}/ssh*
349           chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty
350           chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog
351           if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
352           then
353             chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log
354           fi
355         else
356           csih_warning "Something went wrong installing the sshd service."
357         fi
358       fi # user allowed us to install as service
359     fi # service not yet installed
360   fi # csih_is_nt
361 } # --- End of install_service --- #
362
363 # ======================================================================
364 # Main Entry Point
365 # ======================================================================
366
367 # Check how the script has been started.  If
368 #   (1) it has been started by giving the full path and
369 #       that path is /etc/postinstall, OR
370 #   (2) Otherwise, if the environment variable
371 #       SSH_HOST_CONFIG_AUTO_ANSWER_NO is set
372 # then set auto_answer to "no".  This allows automatic
373 # creation of the config files in /etc w/o overwriting
374 # them if they already exist.  In both cases, color
375 # escape sequences are suppressed, so as to prevent
376 # cluttering setup's logfiles.
377 if [ "$PROGDIR" = "/etc/postinstall" ]
378 then
379   csih_auto_answer="no"
380   csih_disable_color
381 fi
382 if [ -n "${SSH_HOST_CONFIG_AUTO_ANSWER_NO}" ]
383 then
384   csih_auto_answer="no"
385   csih_disable_color
386 fi
387
388 # ======================================================================
389 # Parse options
390 # ======================================================================
391 while :
392 do
393   case $# in
394   0)
395     break
396     ;;
397   esac
398
399   option=$1
400   shift
401
402   case "${option}" in
403   -d | --debug )
404     set -x
405     csih_trace_on
406     ;;
407
408   -y | --yes )
409     csih_auto_answer=yes
410     ;;
411
412   -n | --no )
413     csih_auto_answer=no
414     ;;
415
416   -c | --cygwin )
417     cygwin_value="$1"
418     shift
419     ;;
420
421   -p | --port )
422     port_number=$1
423     shift
424     ;;
425
426   -w | --pwd )
427     password_value="$1"
428     shift
429     ;;
430
431   --privileged )
432     csih_FORCE_PRIVILEGED_USER=yes
433     ;;
434
435   *)
436     echo "usage: ${progname} [OPTION]..."
437     echo
438     echo "This script creates an OpenSSH host configuration."
439     echo
440     echo "Options:"
441     echo "  --debug  -d            Enable shell's debug output."
442     echo "  --yes    -y            Answer all questions with \"yes\" automatically."
443     echo "  --no     -n            Answer all questions with \"no\" automatically."
444     echo "  --cygwin -c <options>  Use \"options\" as value for CYGWIN environment var."
445     echo "  --port   -p <n>        sshd listens on port n."
446     echo "  --pwd    -w <passwd>   Use \"pwd\" as password for privileged user."
447     echo "  --privileged           On Windows NT/2k/XP, require privileged user"
448     echo "                         instead of LocalSystem for sshd service."
449     echo
450     exit 1
451     ;;
452
453   esac
454 done
455
456 # ======================================================================
457 # Action!
458 # ======================================================================
459
460 # Check for running ssh/sshd processes first. Refuse to do anything while
461 # some ssh processes are still running
462 if ps -ef | grep -q '/sshd\?$'
463 then
464   echo
465   csih_error "There are still ssh processes running. Please shut them down first."
466 fi
467
468 # Check for ${SYSCONFDIR} directory
469 csih_make_dir "${SYSCONFDIR}" "Cannot create global configuration files."
470 chmod 775 "${SYSCONFDIR}"
471 setfacl -m u:system:rwx "${SYSCONFDIR}"
472
473 # Check for /var/log directory
474 csih_make_dir "${LOCALSTATEDIR}/log" "Cannot create log directory."
475 chmod 775 "${LOCALSTATEDIR}/log"
476 setfacl -m u:system:rwx "${LOCALSTATEDIR}/log"
477
478 # Create /var/log/lastlog if not already exists
479 if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ]
480 then
481   echo
482   csih_error_multi "${LOCALSTATEDIR}/log/lastlog exists, but is not a file." \
483                    "Cannot create ssh host configuration."
484 fi
485 if [ ! -e ${LOCALSTATEDIR}/log/lastlog ]
486 then
487   cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
488   chmod 644 ${LOCALSTATEDIR}/log/lastlog
489 fi
490
491 # Create /var/empty file used as chroot jail for privilege separation
492 csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create log directory."
493 chmod 755 "${LOCALSTATEDIR}/empty"
494 setfacl -m u:system:rwx "${LOCALSTATEDIR}/empty"
495
496 # host keys
497 create_host_keys
498
499 # use 'cmp' program to determine if a config file is identical
500 # to the default version of that config file
501 csih_check_program_or_error cmp diffutils
502
503
504 # handle ssh_config
505 csih_install_config "${SYSCONFDIR}/ssh_config"   "${SYSCONFDIR}/defaults"
506 if cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1
507 then
508   if [ "${port_number}" != "22" ]
509   then
510     csih_inform "Updating ${SYSCONFDIR}/ssh_config file with requested port"
511     echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
512     echo "    Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
513   fi
514 fi
515
516 # handle sshd_config (and privsep)
517 csih_install_config "${SYSCONFDIR}/sshd_config"   "${SYSCONFDIR}/defaults"
518 if ! cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
519 then
520   grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
521 fi
522 sshd_privsep
523
524
525
526 update_services_file
527 update_inetd_conf
528 install_service
529
530 echo
531 csih_inform "Host configuration finished. Have fun!"
532
This page took 0.273306 seconds and 5 git commands to generate.