]> andersk Git - gssapi-openssh.git/blob - openssh/contrib/cygwin/ssh-host-config
Import of OpenSSH 5.1p1
[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="ntsec"
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 -t -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_inform "Note that the CYGWIN variable must contain at least \"ntsec\""
282         csih_inform "for sshd to be able to change user context without password."
283         csih_get_cygenv "${cygwin_value}"
284
285         if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] )
286         then
287           csih_inform "On Windows Server 2003, Windows Vista, and above, the"
288           csih_inform "SYSTEM account cannot setuid to other users -- a capability"
289           csih_inform "sshd requires.  You need to have or to create a privileged"
290           csih_inform "account.  This script will help you do so."
291           echo
292           if ! csih_create_privileged_user "${password_value}"
293           then
294             csih_error_recoverable "There was a serious problem creating a privileged user."
295             csih_request "Do you want to proceed anyway?" || exit 1
296           fi
297         fi
298
299         # never returns empty if NT or above
300         run_service_as=$(csih_service_should_run_as)
301
302         if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ]
303         then
304           password="${csih_PRIVILEGED_PASSWORD}"
305           if [ -z "${password}" ]
306           then
307             csih_get_value "Please enter the password for user '${run_service_as}':" "-s"
308             password="${csih_value}"
309           fi
310         fi
311
312         # at this point, we either have $run_service_as = "system" and $password is empty,
313         # or $run_service_as is some privileged user and (hopefully) $password contains
314         # the correct password.  So, from here out, we use '-z "${password}"' to discriminate
315         # the two cases.
316
317         csih_check_user "${run_service_as}"
318
319         if [ -z "${password}" ]
320         then
321           if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a "-D" -y tcpip \
322              -e CYGWIN="${csih_cygenv}"
323           then
324             echo
325             csih_inform "The sshd service has been installed under the LocalSystem"
326             csih_inform "account (also known as SYSTEM). To start the service now, call"
327             csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'.  Otherwise, it"
328             csih_inform "will start automatically after the next reboot."
329           fi
330         else
331           if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a "-D" -y tcpip \
332              -e CYGWIN="${csih_cygenv}" -u "${run_service_as}" -w "${password}"
333           then
334             echo
335             csih_inform "The sshd service has been installed under the '${run_service_as}'"
336             csih_inform "account.  To start the service now, call \`net start sshd' or"
337             csih_inform "\`cygrunsrv -S sshd'.  Otherwise, it will start automatically"
338             csih_inform "after the next reboot."
339           fi
340         fi
341
342         # now, if successfully installed, set ownership of the affected files 
343         if cygrunsrv -Q sshd >/dev/null 2>&1
344         then
345           chown "${run_service_as}" ${SYSCONFDIR}/ssh*
346           chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty
347           chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog
348           if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
349           then
350             chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log
351           fi
352         else
353           csih_warning "Something went wrong installing the sshd service."
354         fi
355       fi # user allowed us to install as service
356     fi # service not yet installed
357   fi # csih_is_nt
358 } # --- End of install_service --- #
359
360 # ======================================================================
361 # Main Entry Point
362 # ======================================================================
363
364 # Check how the script has been started.  If
365 #   (1) it has been started by giving the full path and
366 #       that path is /etc/postinstall, OR
367 #   (2) Otherwise, if the environment variable
368 #       SSH_HOST_CONFIG_AUTO_ANSWER_NO is set
369 # then set auto_answer to "no".  This allows automatic
370 # creation of the config files in /etc w/o overwriting
371 # them if they already exist.  In both cases, color
372 # escape sequences are suppressed, so as to prevent
373 # cluttering setup's logfiles.
374 if [ "$PROGDIR" = "/etc/postinstall" ]
375 then
376   csih_auto_answer="no"
377   csih_disable_color
378 fi
379 if [ -n "${SSH_HOST_CONFIG_AUTO_ANSWER_NO}" ]
380 then
381   csih_auto_answer="no"
382   csih_disable_color
383 fi
384
385 # ======================================================================
386 # Parse options
387 # ======================================================================
388 while :
389 do
390   case $# in
391   0)
392     break
393     ;;
394   esac
395
396   option=$1
397   shift
398
399   case "${option}" in
400   -d | --debug )
401     set -x
402     csih_trace_on
403     ;;
404
405   -y | --yes )
406     csih_auto_answer=yes
407     ;;
408
409   -n | --no )
410     csih_auto_answer=no
411     ;;
412
413   -c | --cygwin )
414     cygwin_value="$1"
415     shift
416     ;;
417
418   -p | --port )
419     port_number=$1
420     shift
421     ;;
422
423   -w | --pwd )
424     password_value="$1"
425     shift
426     ;;
427
428   --privileged )
429     csih_FORCE_PRIVILEGED_USER=yes
430     ;;
431
432   *)
433     echo "usage: ${progname} [OPTION]..."
434     echo
435     echo "This script creates an OpenSSH host configuration."
436     echo
437     echo "Options:"
438     echo "  --debug  -d            Enable shell's debug output."
439     echo "  --yes    -y            Answer all questions with \"yes\" automatically."
440     echo "  --no     -n            Answer all questions with \"no\" automatically."
441     echo "  --cygwin -c <options>  Use \"options\" as value for CYGWIN environment var."
442     echo "  --port   -p <n>        sshd listens on port n."
443     echo "  --pwd    -w <passwd>   Use \"pwd\" as password for privileged user."
444     echo "  --privileged           On Windows NT/2k/XP, require privileged user"
445     echo "                         instead of LocalSystem for sshd service."
446     echo
447     exit 1
448     ;;
449
450   esac
451 done
452
453 # ======================================================================
454 # Action!
455 # ======================================================================
456
457 # Check for running ssh/sshd processes first. Refuse to do anything while
458 # some ssh processes are still running
459 if ps -ef | grep -v grep | grep -q ssh
460 then
461   echo
462   csih_error "There are still ssh processes running. Please shut them down first."
463 fi
464
465 # Check for ${SYSCONFDIR} directory
466 csih_make_dir "${SYSCONFDIR}" "Cannot create global configuration files."
467 chmod 775 "${SYSCONFDIR}"
468 setfacl -m u:system:rwx "${SYSCONFDIR}"
469
470 # Check for /var/log directory
471 csih_make_dir "${LOCALSTATEDIR}/log" "Cannot create log directory."
472 chmod 775 "${LOCALSTATEDIR}/log"
473 setfacl -m u:system:rwx "${LOCALSTATEDIR}/log"
474
475 # Create /var/log/lastlog if not already exists
476 if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ]
477 then
478   echo 
479   csih_error_multi "${LOCALSTATEDIR}/log/lastlog exists, but is not a file." \
480                    "Cannot create ssh host configuration."
481 fi
482 if [ ! -e ${LOCALSTATEDIR}/log/lastlog ]
483 then
484   cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
485   chmod 644 ${LOCALSTATEDIR}/log/lastlog
486 fi
487
488 # Create /var/empty file used as chroot jail for privilege separation
489 csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create log directory."
490 chmod 755 "${LOCALSTATEDIR}/empty"
491 setfacl -m u:system:rwx "${LOCALSTATEDIR}/empty"
492
493 # host keys
494 create_host_keys
495
496 # use 'cmp' program to determine if a config file is identical
497 # to the default version of that config file
498 csih_check_program_or_error cmp diffutils
499
500
501 # handle ssh_config
502 csih_install_config "${SYSCONFDIR}/ssh_config"   "${SYSCONFDIR}/defaults"
503 if cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1
504 then
505   if [ "${port_number}" != "22" ]
506   then
507     csih_inform "Updating ${SYSCONFDIR}/ssh_config file with requested port"
508     echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
509     echo "    Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
510   fi
511 fi
512
513 # handle sshd_config (and privsep)
514 csih_install_config "${SYSCONFDIR}/sshd_config"   "${SYSCONFDIR}/defaults"
515 if ! cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
516 then
517   grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
518 fi
519 sshd_privsep
520
521
522
523 update_services_file 
524 update_inetd_conf
525 install_service
526
527 echo
528 csih_inform "Host configuration finished. Have fun!"
529
This page took 0.075276 seconds and 5 git commands to generate.