Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 1 | #! /bin/sh |
| 2 | |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 3 | generate_key() { |
| 4 | local FILE=$1 |
| 5 | local TYPE=$2 |
| 6 | local DIR="$(dirname "$FILE")" |
| 7 | |
| 8 | mkdir -p "$DIR" |
Andrew Geissler | 5f35090 | 2021-07-23 13:09:54 -0400 | [diff] [blame^] | 9 | rm -f ${FILE}.tmp |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 10 | ssh-keygen -q -f "${FILE}.tmp" -N '' -t $TYPE |
| 11 | |
| 12 | # Atomically rename file public key |
| 13 | mv -f "${FILE}.tmp.pub" "${FILE}.pub" |
| 14 | |
| 15 | # This sync does double duty: Ensuring that the data in the temporary |
| 16 | # private key file is on disk before the rename, and ensuring that the |
| 17 | # public key rename is completed before the private key rename, since we |
| 18 | # switch on the existence of the private key to trigger key generation. |
| 19 | # This does mean it is possible for the public key to exist, but be garbage |
| 20 | # but this is OK because in that case the private key won't exist and the |
| 21 | # keys will be regenerated. |
| 22 | # |
| 23 | # In the event that sync understands arguments that limit what it tries to |
| 24 | # fsync(), we provided them. If it does not, it will simply call sync() |
| 25 | # which is just as well |
| 26 | sync "${FILE}.pub" "$DIR" "${FILE}.tmp" |
| 27 | |
| 28 | mv "${FILE}.tmp" "$FILE" |
| 29 | |
| 30 | # sync to ensure the atomic rename is committed |
| 31 | sync "$DIR" |
| 32 | } |
| 33 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 34 | # /etc/default/ssh may set SYSCONFDIR and SSHD_OPTS |
| 35 | if test -f /etc/default/ssh; then |
| 36 | . /etc/default/ssh |
| 37 | fi |
| 38 | |
| 39 | [ -z "$SYSCONFDIR" ] && SYSCONFDIR=/etc/ssh |
| 40 | mkdir -p $SYSCONFDIR |
| 41 | |
| 42 | # parse sshd options |
| 43 | set -- ${SSHD_OPTS} -- |
| 44 | sshd_config=/etc/ssh/sshd_config |
| 45 | while true ; do |
| 46 | case "$1" in |
| 47 | -f*) if [ "$1" = "-f" ] ; then |
| 48 | sshd_config="$2" |
| 49 | shift |
| 50 | else |
| 51 | sshd_config="${1#-f}" |
| 52 | fi |
| 53 | shift |
| 54 | ;; |
| 55 | --) shift; break;; |
| 56 | *) shift;; |
| 57 | esac |
| 58 | done |
| 59 | |
Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 60 | HOST_KEYS=$(sed -n 's/^[ \t]*HostKey[ \t]\+\(.*\)/\1/p' "${sshd_config}") |
| 61 | [ -z "${HOST_KEYS}" ] && HOST_KEYS="$SYSCONFDIR/ssh_host_rsa_key $SYSCONFDIR/ssh_host_ecdsa_key $SYSCONFDIR/ssh_host_ed25519_key" |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 62 | |
Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 63 | for key in ${HOST_KEYS} ; do |
| 64 | [ -f $key ] && continue |
| 65 | case $key in |
| 66 | *_rsa_key) |
| 67 | echo " generating ssh RSA host key..." |
| 68 | generate_key $key rsa |
| 69 | ;; |
| 70 | *_ecdsa_key) |
| 71 | echo " generating ssh ECDSA host key..." |
| 72 | generate_key $key ecdsa |
| 73 | ;; |
| 74 | *_ed25519_key) |
| 75 | echo " generating ssh ED25519 host key..." |
| 76 | generate_key $key ed25519 |
| 77 | ;; |
| 78 | esac |
| 79 | done |