]> andersk Git - gssapi-openssh.git/blame - openssh/contrib/cygwin/ssh-host-config
Import of OpenSSH 4.0p1
[gssapi-openssh.git] / openssh / contrib / cygwin / ssh-host-config
CommitLineData
cdd66111 1#!/bin/bash
3c0ef626 2#
cdd66111 3# ssh-host-config, Copyright 2000, 2001, 2002, 2003 Red Hat Inc.
3c0ef626 4#
5# This file is part of the Cygwin port of OpenSSH.
6
7# Subdirectory where the new package is being installed
8PREFIX=/usr
9
10# Directory where the config files are stored
11SYSCONFDIR=/etc
cdd66111 12LOCALSTATEDIR=/var
3c0ef626 13
14progname=$0
15auto_answer=""
16port_number=22
17
41b2f314 18privsep_configured=no
19privsep_used=yes
20sshd_in_passwd=no
21sshd_in_sam=no
22
3c0ef626 23request()
24{
25 if [ "${auto_answer}" = "yes" ]
26 then
cdd66111 27 echo "$1 (yes/no) yes"
3c0ef626 28 return 0
29 elif [ "${auto_answer}" = "no" ]
30 then
cdd66111 31 echo "$1 (yes/no) no"
3c0ef626 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) "
cdd66111 39 read -e answer
3c0ef626 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
51while :
52do
53 case $# in
54 0)
55 break
56 ;;
57 esac
58
59 option=$1
60 shift
61
cdd66111 62 case "${option}" in
3c0ef626 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
cdd66111 75 -c | --cygwin )
76 cygwin_value="$1"
77 shift
78 ;;
79
3c0ef626 80 -p | --port )
81 port_number=$1
82 shift
83 ;;
84
cdd66111 85 -w | --pwd )
86 password_value="$1"
87 shift
88 ;;
89
3c0ef626 90 *)
91 echo "usage: ${progname} [OPTION]..."
92 echo
93 echo "This script creates an OpenSSH host configuration."
94 echo
95 echo "Options:"
cdd66111 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'."
3c0ef626 102 echo
103 exit 1
104 ;;
105
106 esac
107done
108
41b2f314 109# Check if running on NT
cdd66111 110_sys="`uname`"
111_nt=`expr "${_sys}" : "CYGWIN_NT"`
112# If running on NT, check if running under 2003 Server or later
113if [ ${_nt} -gt 0 ]
114then
115 _nt2003=`uname | awk -F- '{print ( $2 >= 5.2 ) ? 1 : 0;}'`
116fi
41b2f314 117
3c0ef626 118# Check for running ssh/sshd processes first. Refuse to do anything while
119# some ssh processes are still running
120
121if ps -ef | grep -v grep | grep -q ssh
122then
123 echo
124 echo "There are still ssh processes running. Please shut them down first."
125 echo
41b2f314 126 exit 1
3c0ef626 127fi
128
129# Check for ${SYSCONFDIR} directory
130
131if [ -e "${SYSCONFDIR}" -a ! -d "${SYSCONFDIR}" ]
132then
133 echo
134 echo "${SYSCONFDIR} is existant but not a directory."
135 echo "Cannot create global configuration files."
136 echo
137 exit 1
138fi
139
140# Create it if necessary
141
142if [ ! -e "${SYSCONFDIR}" ]
143then
144 mkdir "${SYSCONFDIR}"
145 if [ ! -e "${SYSCONFDIR}" ]
146 then
147 echo
148 echo "Creating ${SYSCONFDIR} directory failed"
149 echo
150 exit 1
151 fi
152fi
153
41b2f314 154# Create /var/log and /var/log/lastlog if not already existing
155
cdd66111 156if [ -f ${LOCALSTATEDIR}/log ]
41b2f314 157then
cdd66111 158 echo "Creating ${LOCALSTATEDIR}/log failed!"
41b2f314 159else
cdd66111 160 if [ ! -d ${LOCALSTATEDIR}/log ]
41b2f314 161 then
cdd66111 162 mkdir -p ${LOCALSTATEDIR}/log
41b2f314 163 fi
cdd66111 164 if [ -d ${LOCALSTATEDIR}/log/lastlog ]
41b2f314 165 then
cdd66111 166 chmod 777 ${LOCALSTATEDIR}/log/lastlog
167 elif [ ! -f ${LOCALSTATEDIR}/log/lastlog ]
41b2f314 168 then
cdd66111 169 cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
170 chmod 666 ${LOCALSTATEDIR}/log/lastlog
41b2f314 171 fi
172fi
173
174# Create /var/empty file used as chroot jail for privilege separation
cdd66111 175if [ -f ${LOCALSTATEDIR}/empty ]
41b2f314 176then
cdd66111 177 echo "Creating ${LOCALSTATEDIR}/empty failed!"
41b2f314 178else
cdd66111 179 mkdir -p ${LOCALSTATEDIR}/empty
180 if [ ${_nt} -gt 0 ]
41b2f314 181 then
cdd66111 182 chmod 755 ${LOCALSTATEDIR}/empty
3c0ef626 183 fi
184fi
185
186# First generate host keys if not already existing
187
188if [ ! -f "${SYSCONFDIR}/ssh_host_key" ]
189then
190 echo "Generating ${SYSCONFDIR}/ssh_host_key"
191 ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
192fi
193
194if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
195then
196 echo "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
197 ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
198fi
199
200if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ]
201then
202 echo "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
203 ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
204fi
205
206# Check if ssh_config exists. If yes, ask for overwriting
207
208if [ -f "${SYSCONFDIR}/ssh_config" ]
209then
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
218fi
219
cdd66111 220# Create default ssh_config from skeleton file in /etc/defaults/etc
3c0ef626 221
222if [ ! -f "${SYSCONFDIR}/ssh_config" ]
223then
224 echo "Generating ${SYSCONFDIR}/ssh_config file"
cdd66111 225 cp ${SYSCONFDIR}/defaults/etc/ssh_config ${SYSCONFDIR}/ssh_config
226 if [ "${port_number}" != "22" ]
3c0ef626 227 then
228 echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
cdd66111 229 echo " Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
3c0ef626 230 fi
231fi
232
233# Check if sshd_config exists. If yes, ask for overwriting
234
235if [ -f "${SYSCONFDIR}/sshd_config" ]
236then
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
41b2f314 244 else
245 grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
3c0ef626 246 fi
247fi
248
41b2f314 249# Prior to creating or modifying sshd_config, care for privilege separation
250
cdd66111 251if [ "${privsep_configured}" != "yes" ]
41b2f314 252then
cdd66111 253 if [ ${_nt} -gt 0 ]
41b2f314 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'."
cdd66111 257 echo "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
41b2f314 258 echo
cdd66111 259 if request "Should privilege separation be used?"
41b2f314 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
cdd66111 264 if [ "${sshd_in_passwd}" != "yes" ]
41b2f314 265 then
cdd66111 266 if [ "${sshd_in_sam}" != "yes" ]
41b2f314 267 then
268 echo "Warning: The following function requires administrator privileges!"
cdd66111 269 if request "Should this script create a local user 'sshd' on this machine?"
41b2f314 270 then
cdd66111 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" ]
41b2f314 274 then
275 echo "Warning: Creating the user 'sshd' failed!"
276 fi
277 fi
278 fi
cdd66111 279 if [ "${sshd_in_sam}" != "yes" ]
41b2f314 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
cdd66111 294 # available it just adds useless additional processes.
41b2f314 295 privsep_used=no
296 fi
297fi
298
cdd66111 299# Create default sshd_config from skeleton files in /etc/defaults/etc or
300# modify to add the missing privsep configuration option
3c0ef626 301
302if [ ! -f "${SYSCONFDIR}/sshd_config" ]
303then
304 echo "Generating ${SYSCONFDIR}/sshd_config file"
cdd66111 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
310elif [ "${privsep_configured}" != "yes" ]
41b2f314 311then
312 echo >> ${SYSCONFDIR}/sshd_config
cdd66111 313 echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
3c0ef626 314fi
315
316# Care for services file
cdd66111 317_my_etcdir="/ssh-host-config.$$"
318if [ ${_nt} -gt 0 ]
3c0ef626 319then
cdd66111 320 _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
321 _services="${_my_etcdir}/services"
322 # On NT, 27 spaces, no space after the hash
323 _spaces=" #"
3c0ef626 324else
cdd66111 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=" # "
3c0ef626 329fi
cdd66111 330_serv_tmp="${_my_etcdir}/srv.out.$$"
3c0ef626 331
cdd66111 332mount -t -f "${_win_etcdir}" "${_my_etcdir}"
333
334# Depends on the above mount
335_wservices=`cygpath -w "${_services}"`
3c0ef626 336
337# Remove sshd 22/port from services
338if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
339then
340 grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
341 if [ -f "${_serv_tmp}" ]
cdd66111 342 then
3c0ef626 343 if mv "${_serv_tmp}" "${_services}"
344 then
cdd66111 345 echo "Removing sshd from ${_wservices}"
3c0ef626 346 else
cdd66111 347 echo "Removing sshd from ${_wservices} failed!"
348 fi
3c0ef626 349 rm -f "${_serv_tmp}"
350 else
cdd66111 351 echo "Removing sshd from ${_wservices} failed!"
3c0ef626 352 fi
353fi
354
355# Add ssh 22/tcp and ssh 22/udp to services
356if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
357then
cdd66111 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}"
3c0ef626 359 then
360 if mv "${_serv_tmp}" "${_services}"
361 then
cdd66111 362 echo "Added ssh to ${_wservices}"
3c0ef626 363 else
cdd66111 364 echo "Adding ssh to ${_wservices} failed!"
3c0ef626 365 fi
366 rm -f "${_serv_tmp}"
367 else
cdd66111 368 echo "WARNING: Adding ssh to ${_wservices} failed!"
3c0ef626 369 fi
370fi
371
cdd66111 372umount "${_my_etcdir}"
3c0ef626 373
374# Care for inetd.conf file
41b2f314 375_inetcnf="${SYSCONFDIR}/inetd.conf"
376_inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
3c0ef626 377
378if [ -f "${_inetcnf}" ]
379then
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
cdd66111 391 echo "Removed sshd from ${_inetcnf}"
3c0ef626 392 else
cdd66111 393 echo "Removing sshd from ${_inetcnf} failed!"
3c0ef626 394 fi
395 rm -f "${_inetcnf_tmp}"
396 else
cdd66111 397 echo "Removing sshd from ${_inetcnf} failed!"
3c0ef626 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
700318f3 406 echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
3c0ef626 407 else
700318f3 408 echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
3c0ef626 409 fi
410 echo "Added ssh to ${_inetcnf}"
411 fi
412fi
413
3c0ef626 414# On NT ask if sshd should be installed as service
cdd66111 415if [ ${_nt} -gt 0 ]
3c0ef626 416then
cdd66111 417 # But only if it is not already installed
418 if ! cygrunsrv -Q sshd > /dev/null 2>&1
3c0ef626 419 then
420 echo
cdd66111 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
996d5e62 452 _admingroup=`awk -F: '{if ( $1 != "root" && $2 == "S-1-5-32-544" ) print $1;}' ${SYSCONFDIR}/group`
cdd66111 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
3c0ef626 574 then
cdd66111 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
3c0ef626 587 fi
588 fi
589fi
590
3c0ef626 591echo
592echo "Host configuration finished. Have fun!"
This page took 0.147222 seconds and 5 git commands to generate.