]> andersk Git - openssh.git/blob - contrib/cygwin/ssh-host-config
- (dtucker) [contrib/cygwin/ssh-host-config] Update to match current Cygwin
[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=`awk -F: '{if ( $1 != "root" && $2 == "S-1-5-32-544" ) print $1;}' ${SYSCONFDIR}/group`
453             if [ -z "${_admingroup}" ]
454             then
455               echo "There's no group with SID S-1-5-32-544 (Local administrators group) in"
456               echo "your ${SYSCONFDIR}/group file.  Please regenerate this entry using 'mkgroup -l'"
457               echo "and restart this script."
458               exit 1
459             fi
460             dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
461             while [ "${sshd_server_in_sam}" != "yes" ]
462             do
463               if [ -n "${password_value}" ]
464               then
465                 _password="${password_value}"
466                 # Allow to ask for password if first try fails
467                 password_value=""
468               else
469                 echo
470                 echo "Please enter a password for new user 'sshd_server'.  Please be sure that"
471                 echo "this password matches the password rules given on your system."
472                 echo -n "Entering no password will exit the configuration.  PASSWORD="
473                 read -e _password
474                 if [ -z "${_password}" ]
475                 then
476                   echo
477                   echo "Exiting configuration.  No user sshd_server has been created,"
478                   echo "no sshd service installed."
479                   exit 1
480                 fi
481               fi
482               net user sshd_server "${_password}" /add /fullname:"sshd server account" "/homedir:${dos_var_empty}" /yes > /tmp/nu.$$ 2>&1 && sshd_server_in_sam=yes
483               if [ "${sshd_server_in_sam}" != "yes" ]
484               then
485                 echo "Creating the user 'sshd_server' failed!  Reason:"
486                 cat /tmp/nu.$$
487                 rm /tmp/nu.$$
488               fi
489             done
490             net localgroup "${_admingroup}" sshd_server /add > /dev/null 2>&1 && sshd_server_in_admingroup=yes
491             if [ "${sshd_server_in_admingroup}" != "yes" ]
492             then
493               echo "WARNING: Adding user sshd_server to local group ${_admingroup} failed!"
494               echo "Please add sshd_server to local group ${_admingroup} before"
495               echo "starting the sshd service!"
496               echo
497             fi
498             passwd_has_expiry_flags=`passwd -v | awk '/^passwd /{print ( $3 >= 1.5 ) ? "yes" : "no";}'`
499             if [ "${passwd_has_expiry_flags}" != "yes" ]
500             then
501               echo
502               echo "WARNING: User sshd_server has password expiry set to system default."
503               echo "Please check that password never expires or set it to your needs."
504             elif ! passwd -e sshd_server
505             then
506               echo
507               echo "WARNING: Setting password expiry for user sshd_server failed!"
508               echo "Please check that password never expires or set it to your needs."
509             fi
510             editrights -a SeAssignPrimaryTokenPrivilege -u sshd_server &&
511             editrights -a SeCreateTokenPrivilege -u sshd_server &&
512             editrights -a SeDenyInteractiveLogonRight -u sshd_server &&
513             editrights -a SeDenyNetworkLogonRight -u sshd_server &&
514             editrights -a SeDenyRemoteInteractiveLogonRight -u sshd_server &&
515             editrights -a SeIncreaseQuotaPrivilege -u sshd_server &&
516             editrights -a SeServiceLogonRight -u sshd_server &&
517             sshd_server_got_all_rights="yes"
518             if [ "${sshd_server_got_all_rights}" != "yes" ]
519             then
520               echo
521               echo "Assigning the appropriate privileges to user 'sshd_server' failed!"
522               echo "Can't create sshd service!"
523               exit 1
524             fi
525             echo
526             echo "User 'sshd_server' has been created with password '${_password}'."
527             echo "If you change the password, please keep in mind to change the password"
528             echo "for the sshd service, too."
529             echo
530             echo "Also keep in mind that the user sshd_server needs read permissions on all"
531             echo "users' .ssh/authorized_keys file to allow public key authentication for"
532             echo "these users!.  (Re-)running ssh-user-config for each user will set the"
533             echo "required permissions correctly."
534             echo
535           fi
536         fi
537         if [ "${sshd_server_in_sam}" = "yes" ]
538         then
539           mkpasswd -l -u sshd_server | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
540         fi
541       fi
542       if [ -n "${cygwin_value}" ]
543       then
544         _cygwin="${cygwin_value}"
545       else
546         echo
547         echo "Which value should the environment variable CYGWIN have when"
548         echo "sshd starts? It's recommended to set at least \"ntsec\" to be"
549         echo "able to change user context without password."
550         echo -n "Default is \"ntsec\".  CYGWIN="
551         read -e _cygwin
552       fi
553       [ -z "${_cygwin}" ] && _cygwin="ntsec"
554       if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
555       then
556         if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -u sshd_server -w "${_password}" -e "CYGWIN=${_cygwin}"
557         then
558           echo
559           echo "The service has been installed under sshd_server account."
560           echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
561         fi
562       else
563         if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -e "CYGWIN=${_cygwin}"
564         then
565           echo
566           echo "The service has been installed under LocalSystem account."
567           echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
568         fi
569       fi
570     fi
571     # Now check if sshd has been successfully installed.  This allows to
572     # set the ownership of the affected files correctly.
573     if cygrunsrv -Q sshd > /dev/null 2>&1
574     then
575       if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
576       then
577         _user="sshd_server"
578       else
579         _user="system"
580       fi
581       chown "${_user}" ${SYSCONFDIR}/ssh*
582       chown "${_user}".544 ${LOCALSTATEDIR}/empty
583       if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
584       then
585         chown "${_user}".544 ${LOCALSTATEDIR}/log/sshd.log
586       fi
587     fi
588   fi
589 fi
590
591 echo
592 echo "Host configuration finished. Have fun!"
This page took 0.075912 seconds and 5 git commands to generate.