]> andersk Git - openssh.git/blob - contrib/cygwin/ssh-host-config
- (dtucker) [contrib/cygwin/ssh-host-config] Add a test and warning for a
[openssh.git] / 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 # Subdirectory where the new package is being installed
8 PREFIX=/usr
9
10 # Directory where the config files are stored
11 SYSCONFDIR=/etc
12 LOCALSTATEDIR=/var
13
14 progname=$0
15 auto_answer=""
16 port_number=22
17
18 privsep_configured=no
19 privsep_used=yes
20 sshd_in_passwd=no
21 sshd_in_sam=no
22
23 request()
24 {
25   if [ "${auto_answer}" = "yes" ]
26   then
27     echo "$1 (yes/no) yes"
28     return 0
29   elif [ "${auto_answer}" = "no" ]
30   then
31     echo "$1 (yes/no) no"
32     return 1
33   fi
34
35   answer=""
36   while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ]
37   do
38     echo -n "$1 (yes/no) "
39     read -e answer
40   done
41   if [ "X${answer}" = "Xyes" ]
42   then
43     return 0
44   else
45     return 1
46   fi
47 }
48
49 # Check options
50
51 while :
52 do
53   case $# in
54   0)
55     break
56     ;;
57   esac
58
59   option=$1
60   shift
61
62   case "${option}" in
63   -d | --debug )
64     set -x
65     ;;
66
67   -y | --yes )
68     auto_answer=yes
69     ;;
70
71   -n | --no )
72     auto_answer=no
73     ;;
74
75   -c | --cygwin )
76     cygwin_value="$1"
77     shift
78     ;;
79
80   -p | --port )
81     port_number=$1
82     shift
83     ;;
84
85   -w | --pwd )
86     password_value="$1"
87     shift
88     ;;
89
90   *)
91     echo "usage: ${progname} [OPTION]..."
92     echo
93     echo "This script creates an OpenSSH host configuration."
94     echo
95     echo "Options:"
96     echo "  --debug  -d            Enable shell's debug output."
97     echo "  --yes    -y            Answer all questions with \"yes\" automatically."
98     echo "  --no     -n            Answer all questions with \"no\" automatically."
99     echo "  --cygwin -c <options>  Use \"options\" as value for CYGWIN environment var."
100     echo "  --port   -p <n>        sshd listens on port n."
101     echo "  --pwd    -w <passwd>   Use \"pwd\" as password for user 'sshd_server'."
102     echo
103     exit 1
104     ;;
105
106   esac
107 done
108
109 # Check if running on NT
110 _sys="`uname`"
111 _nt=`expr "${_sys}" : "CYGWIN_NT"`
112 # If running on NT, check if running under 2003 Server or later
113 if [ ${_nt} -gt 0 ]
114 then
115   _nt2003=`uname | awk -F- '{print ( $2 >= 5.2 ) ? 1 : 0;}'`
116 fi
117
118 # Check for running ssh/sshd processes first. Refuse to do anything while
119 # some ssh processes are still running
120
121 if ps -ef | grep -v grep | grep -q ssh
122 then
123   echo
124   echo "There are still ssh processes running. Please shut them down first."
125   echo
126   exit 1
127 fi
128
129 # Check for ${SYSCONFDIR} directory
130
131 if [ -e "${SYSCONFDIR}" -a ! -d "${SYSCONFDIR}" ]
132 then
133   echo
134   echo "${SYSCONFDIR} is existant but not a directory."
135   echo "Cannot create global configuration files."
136   echo
137   exit 1
138 fi
139
140 # Create it if necessary
141
142 if [ ! -e "${SYSCONFDIR}" ]
143 then
144   mkdir "${SYSCONFDIR}"
145   if [ ! -e "${SYSCONFDIR}" ]
146   then
147     echo
148     echo "Creating ${SYSCONFDIR} directory failed"
149     echo
150     exit 1
151   fi
152 fi
153
154 # Create /var/log and /var/log/lastlog if not already existing
155
156 if [ -f ${LOCALSTATEDIR}/log ]
157 then
158   echo "Creating ${LOCALSTATEDIR}/log failed!"
159 else
160   if [ ! -d ${LOCALSTATEDIR}/log ]
161   then
162     mkdir -p ${LOCALSTATEDIR}/log
163   fi
164   if [ -d ${LOCALSTATEDIR}/log/lastlog ]
165   then
166     chmod 777 ${LOCALSTATEDIR}/log/lastlog
167   elif [ ! -f ${LOCALSTATEDIR}/log/lastlog ]
168   then
169     cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
170     chmod 666 ${LOCALSTATEDIR}/log/lastlog
171   fi
172 fi
173
174 # Create /var/empty file used as chroot jail for privilege separation
175 if [ -f ${LOCALSTATEDIR}/empty ]
176 then
177   echo "Creating ${LOCALSTATEDIR}/empty failed!"
178 else
179   mkdir -p ${LOCALSTATEDIR}/empty
180   if [ ${_nt} -gt 0 ]
181   then
182     chmod 755 ${LOCALSTATEDIR}/empty
183   fi
184 fi
185
186 # First generate host keys if not already existing
187
188 if [ ! -f "${SYSCONFDIR}/ssh_host_key" ]
189 then
190   echo "Generating ${SYSCONFDIR}/ssh_host_key"
191   ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
192 fi
193
194 if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
195 then
196   echo "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
197   ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
198 fi
199
200 if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ]
201 then
202   echo "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
203   ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
204 fi
205
206 # Check if ssh_config exists. If yes, ask for overwriting
207
208 if [ -f "${SYSCONFDIR}/ssh_config" ]
209 then
210   if request "Overwrite existing ${SYSCONFDIR}/ssh_config file?"
211   then
212     rm -f "${SYSCONFDIR}/ssh_config"
213     if [ -f "${SYSCONFDIR}/ssh_config" ]
214     then
215       echo "Can't overwrite. ${SYSCONFDIR}/ssh_config is write protected."
216     fi
217   fi
218 fi
219
220 # Create default ssh_config from skeleton file in /etc/defaults/etc
221
222 if [ ! -f "${SYSCONFDIR}/ssh_config" ]
223 then
224   echo "Generating ${SYSCONFDIR}/ssh_config file"
225   cp ${SYSCONFDIR}/defaults/etc/ssh_config ${SYSCONFDIR}/ssh_config
226   if [ "${port_number}" != "22" ]
227   then
228     echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
229     echo "    Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
230   fi
231 fi
232
233 # Check if sshd_config exists. If yes, ask for overwriting
234
235 if [ -f "${SYSCONFDIR}/sshd_config" ]
236 then
237   if request "Overwrite existing ${SYSCONFDIR}/sshd_config file?"
238   then
239     rm -f "${SYSCONFDIR}/sshd_config"
240     if [ -f "${SYSCONFDIR}/sshd_config" ]
241     then
242       echo "Can't overwrite. ${SYSCONFDIR}/sshd_config is write protected."
243     fi
244   else
245     grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
246   fi
247 fi
248
249 # Prior to creating or modifying sshd_config, care for privilege separation
250
251 if [ "${privsep_configured}" != "yes" ]
252 then
253   if [ ${_nt} -gt 0 ]
254   then
255     echo "Privilege separation is set to yes by default since OpenSSH 3.3."
256     echo "However, this requires a non-privileged account called 'sshd'."
257     echo "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
258     echo
259     if request "Should privilege separation be used?"
260     then
261       privsep_used=yes
262       grep -q '^sshd:' ${SYSCONFDIR}/passwd && sshd_in_passwd=yes
263       net user sshd >/dev/null 2>&1 && sshd_in_sam=yes
264       if [ "${sshd_in_passwd}" != "yes" ]
265       then
266         if [ "${sshd_in_sam}" != "yes" ]
267         then
268           echo "Warning: The following function requires administrator privileges!"
269           if request "Should this script create a local user 'sshd' on this machine?"
270           then
271             dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
272             net user sshd /add /fullname:"sshd privsep" "/homedir:${dos_var_empty}" /active:no > /dev/null 2>&1 && sshd_in_sam=yes
273             if [ "${sshd_in_sam}" != "yes" ]
274             then
275               echo "Warning: Creating the user 'sshd' failed!"
276             fi
277           fi
278         fi
279         if [ "${sshd_in_sam}" != "yes" ]
280         then
281           echo "Warning: Can't create user 'sshd' in ${SYSCONFDIR}/passwd!"
282           echo "         Privilege separation set to 'no' again!"
283           echo "         Check your ${SYSCONFDIR}/sshd_config file!"
284           privsep_used=no
285         else
286           mkpasswd -l -u sshd | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
287         fi
288       fi
289     else
290       privsep_used=no
291     fi
292   else
293     # On 9x don't use privilege separation.  Since security isn't
294     # available it just adds useless additional processes.
295     privsep_used=no
296   fi
297 fi
298
299 # Create default sshd_config from skeleton files in /etc/defaults/etc or
300 # modify to add the missing privsep configuration option
301
302 if [ ! -f "${SYSCONFDIR}/sshd_config" ]
303 then
304   echo "Generating ${SYSCONFDIR}/sshd_config file"
305   sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
306           s/^#Port 22/Port ${port_number}/
307           s/^#StrictModes yes/StrictModes no/" \
308       < ${SYSCONFDIR}/defaults/etc/sshd_config \
309       > ${SYSCONFDIR}/sshd_config
310 elif [ "${privsep_configured}" != "yes" ]
311 then
312   echo >> ${SYSCONFDIR}/sshd_config
313   echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
314 fi
315
316 # Care for services file
317 _my_etcdir="/ssh-host-config.$$"
318 if [ ${_nt} -gt 0 ]
319 then
320   _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
321   _services="${_my_etcdir}/services"
322   # On NT, 27 spaces, no space after the hash
323   _spaces="                           #"
324 else
325   _win_etcdir="${WINDIR}"
326   _services="${_my_etcdir}/SERVICES"
327   # On 9x, 18 spaces (95 is very touchy), a space after the hash
328   _spaces="                  # "
329 fi
330 _serv_tmp="${_my_etcdir}/srv.out.$$"
331
332 mount -t -f "${_win_etcdir}" "${_my_etcdir}"
333
334 # Depends on the above mount
335 _wservices=`cygpath -w "${_services}"`
336
337 # Remove sshd 22/port from services
338 if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
339 then
340   grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
341   if [ -f "${_serv_tmp}" ]
342   then
343     if mv "${_serv_tmp}" "${_services}"
344     then
345       echo "Removing sshd from ${_wservices}"
346     else
347       echo "Removing sshd from ${_wservices} failed!"
348     fi
349     rm -f "${_serv_tmp}"
350   else
351     echo "Removing sshd from ${_wservices} failed!"
352   fi
353 fi
354
355 # Add ssh 22/tcp  and ssh 22/udp to services
356 if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
357 then
358   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}"
359   then
360     if mv "${_serv_tmp}" "${_services}"
361     then
362       echo "Added ssh to ${_wservices}"
363     else
364       echo "Adding ssh to ${_wservices} failed!"
365     fi
366     rm -f "${_serv_tmp}"
367   else
368     echo "WARNING: Adding ssh to ${_wservices} failed!"
369   fi
370 fi
371
372 umount "${_my_etcdir}"
373
374 # Care for inetd.conf file
375 _inetcnf="${SYSCONFDIR}/inetd.conf"
376 _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
377
378 if [ -f "${_inetcnf}" ]
379 then
380   # Check if ssh service is already in use as sshd
381   with_comment=1
382   grep -q '^[ \t]*sshd' "${_inetcnf}" && with_comment=0
383   # Remove sshd line from inetd.conf
384   if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
385   then
386     grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
387     if [ -f "${_inetcnf_tmp}" ]
388     then
389       if mv "${_inetcnf_tmp}" "${_inetcnf}"
390       then
391         echo "Removed sshd from ${_inetcnf}"
392       else
393         echo "Removing sshd from ${_inetcnf} failed!"
394       fi
395       rm -f "${_inetcnf_tmp}"
396     else
397       echo "Removing sshd from ${_inetcnf} failed!"
398     fi
399   fi
400
401   # Add ssh line to inetd.conf
402   if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
403   then
404     if [ "${with_comment}" -eq 0 ]
405     then
406       echo 'ssh  stream  tcp     nowait  root    /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
407     else
408       echo '# ssh  stream  tcp     nowait  root    /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
409     fi
410     echo "Added ssh to ${_inetcnf}"
411   fi
412 fi
413
414 # On NT ask if sshd should be installed as service
415 if [ ${_nt} -gt 0 ]
416 then
417   # But only if it is not already installed
418   if ! cygrunsrv -Q sshd > /dev/null 2>&1
419   then
420     echo
421     echo
422     echo "Warning: The following functions require administrator privileges!"
423     echo
424     echo "Do you want to install sshd as service?"
425     if request "(Say \"no\" if it's already installed as service)"
426     then
427       if [ $_nt2003 -gt 0 ]
428       then
429         grep -q '^sshd_server:' ${SYSCONFDIR}/passwd && sshd_server_in_passwd=yes
430         if [ "${sshd_server_in_passwd}" = "yes" ]
431         then
432           # Drop sshd_server from passwd since it could have wrong settings
433           grep -v '^sshd_server:' ${SYSCONFDIR}/passwd > ${SYSCONFDIR}/passwd.$$
434           rm -f ${SYSCONFDIR}/passwd
435           mv ${SYSCONFDIR}/passwd.$$ ${SYSCONFDIR}/passwd
436           chmod g-w,o-w ${SYSCONFDIR}/passwd
437         fi
438         net user sshd_server >/dev/null 2>&1 && sshd_server_in_sam=yes
439         if [ "${sshd_server_in_sam}" != "yes" ]
440         then
441           echo
442           echo "You appear to be running Windows 2003 Server or later.  On 2003 and"
443           echo "later systems, it's not possible to use the LocalSystem account"
444           echo "if sshd should allow passwordless logon (e. g. public key authentication)."
445           echo "If you want to enable that functionality, it's required to create a new"
446           echo "account 'sshd_server' with special privileges, which is then used to run"
447           echo "the sshd service under."
448           echo
449           echo "Should this script create a new local account 'sshd_server' which has"
450           if request "the required privileges?"
451           then
452             _admingroup=`mkgroup -l | awk -F: '{if ( $2 == "S-1-5-32-544" ) print $1;}' `
453             if [ -z "${_admingroup}" ]
454             then
455               echo "mkgroup -l produces no group with SID S-1-5-32-544 (Local administrators group)."
456               exit 1
457             fi
458             dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
459             while [ "${sshd_server_in_sam}" != "yes" ]
460             do
461               if [ -n "${password_value}" ]
462               then
463                 _password="${password_value}"
464                 # Allow to ask for password if first try fails
465                 password_value=""
466               else
467                 echo
468                 echo "Please enter a password for new user 'sshd_server'.  Please be sure that"
469                 echo "this password matches the password rules given on your system."
470                 echo -n "Entering no password will exit the configuration.  PASSWORD="
471                 read -e _password
472                 if [ -z "${_password}" ]
473                 then
474                   echo
475                   echo "Exiting configuration.  No user sshd_server has been created,"
476                   echo "no sshd service installed."
477                   exit 1
478                 fi
479               fi
480               net user sshd_server "${_password}" /add /fullname:"sshd server account" "/homedir:${dos_var_empty}" /yes > /tmp/nu.$$ 2>&1 && sshd_server_in_sam=yes
481               if [ "${sshd_server_in_sam}" != "yes" ]
482               then
483                 echo "Creating the user 'sshd_server' failed!  Reason:"
484                 cat /tmp/nu.$$
485                 rm /tmp/nu.$$
486               fi
487             done
488             net localgroup "${_admingroup}" sshd_server /add > /dev/null 2>&1 && sshd_server_in_admingroup=yes
489             if [ "${sshd_server_in_admingroup}" != "yes" ]
490             then
491               echo "WARNING: Adding user sshd_server to local group ${_admingroup} failed!"
492               echo "Please add sshd_server to local group ${_admingroup} before"
493               echo "starting the sshd service!"
494               echo
495             fi
496             passwd_has_expiry_flags=`passwd -v | awk '/^passwd /{print ( $3 >= 1.5 ) ? "yes" : "no";}'`
497             if [ "${passwd_has_expiry_flags}" != "yes" ]
498             then
499               echo
500               echo "WARNING: User sshd_server has password expiry set to system default."
501               echo "Please check that password never expires or set it to your needs."
502             elif ! passwd -e sshd_server
503             then
504               echo
505               echo "WARNING: Setting password expiry for user sshd_server failed!"
506               echo "Please check that password never expires or set it to your needs."
507             fi
508             editrights -a SeAssignPrimaryTokenPrivilege -u sshd_server &&
509             editrights -a SeCreateTokenPrivilege -u sshd_server &&
510             editrights -a SeDenyInteractiveLogonRight -u sshd_server &&
511             editrights -a SeDenyNetworkLogonRight -u sshd_server &&
512             editrights -a SeDenyRemoteInteractiveLogonRight -u sshd_server &&
513             editrights -a SeIncreaseQuotaPrivilege -u sshd_server &&
514             editrights -a SeServiceLogonRight -u sshd_server &&
515             sshd_server_got_all_rights="yes"
516             if [ "${sshd_server_got_all_rights}" != "yes" ]
517             then
518               echo
519               echo "Assigning the appropriate privileges to user 'sshd_server' failed!"
520               echo "Can't create sshd service!"
521               exit 1
522             fi
523             echo
524             echo "User 'sshd_server' has been created with password '${_password}'."
525             echo "If you change the password, please keep in mind to change the password"
526             echo "for the sshd service, too."
527             echo
528             echo "Also keep in mind that the user sshd_server needs read permissions on all"
529             echo "users' .ssh/authorized_keys file to allow public key authentication for"
530             echo "these users!.  (Re-)running ssh-user-config for each user will set the"
531             echo "required permissions correctly."
532             echo
533           fi
534         fi
535         if [ "${sshd_server_in_sam}" = "yes" ]
536         then
537           mkpasswd -l -u sshd_server | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
538         fi
539       fi
540       if [ -n "${cygwin_value}" ]
541       then
542         _cygwin="${cygwin_value}"
543       else
544         echo
545         echo "Which value should the environment variable CYGWIN have when"
546         echo "sshd starts? It's recommended to set at least \"ntsec\" to be"
547         echo "able to change user context without password."
548         echo -n "Default is \"ntsec\".  CYGWIN="
549         read -e _cygwin
550       fi
551       [ -z "${_cygwin}" ] && _cygwin="ntsec"
552       if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
553       then
554         if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -u sshd_server -w "${_password}" -e "CYGWIN=${_cygwin}"
555         then
556           echo
557           echo "The service has been installed under sshd_server account."
558           echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
559         fi
560       else
561         if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -e "CYGWIN=${_cygwin}"
562         then
563           echo
564           echo "The service has been installed under LocalSystem account."
565           echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
566         fi
567       fi
568     fi
569     # Now check if sshd has been successfully installed.  This allows to
570     # set the ownership of the affected files correctly.
571     if cygrunsrv -Q sshd > /dev/null 2>&1
572     then
573       if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
574       then
575         _user="sshd_server"
576       else
577         _user="system"
578       fi
579       chown "${_user}" ${SYSCONFDIR}/ssh*
580       chown "${_user}".544 ${LOCALSTATEDIR}/empty
581       if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
582       then
583         chown "${_user}".544 ${LOCALSTATEDIR}/log/sshd.log
584       fi
585     fi
586     if ! ( mount | egrep -q 'on /(|usr/(bin|lib)) type system' )
587     then
588       echo
589       echo "Warning: It appears that you have user mode mounts (\"Just me\""
590       echo "chosen during install.)  Any daemons installed as services will"
591       echo "fail to function unless system mounts are used.  To change this,"
592       echo "re-run setup.exe and choose \"All users\"."
593       echo
594       echo "For more information, see http://cygwin.com/faq/faq0.html#TOC33"
595     fi
596   fi
597 fi
598
599 echo
600 echo "Host configuration finished. Have fun!"
This page took 0.511282 seconds and 5 git commands to generate.