| #! /bin/sh |
| |
| generate_key() { |
| local FILE=$1 |
| local TYPE=$2 |
| local DIR="$(dirname "$FILE")" |
| |
| mkdir -p "$DIR" |
| rm -f ${FILE}.tmp |
| ssh-keygen -q -f "${FILE}.tmp" -N '' -t $TYPE |
| |
| # Atomically rename file public key |
| mv -f "${FILE}.tmp.pub" "${FILE}.pub" |
| |
| # This sync does double duty: Ensuring that the data in the temporary |
| # private key file is on disk before the rename, and ensuring that the |
| # public key rename is completed before the private key rename, since we |
| # switch on the existence of the private key to trigger key generation. |
| # This does mean it is possible for the public key to exist, but be garbage |
| # but this is OK because in that case the private key won't exist and the |
| # keys will be regenerated. |
| # |
| # In the event that sync understands arguments that limit what it tries to |
| # fsync(), we provided them. If it does not, it will simply call sync() |
| # which is just as well |
| sync "${FILE}.pub" "$DIR" "${FILE}.tmp" |
| |
| mv "${FILE}.tmp" "$FILE" |
| |
| # sync to ensure the atomic rename is committed |
| sync "$DIR" |
| } |
| |
| # /etc/default/ssh may set SYSCONFDIR and SSHD_OPTS |
| if test -f /etc/default/ssh; then |
| . /etc/default/ssh |
| fi |
| |
| [ -z "$SYSCONFDIR" ] && SYSCONFDIR=/etc/ssh |
| mkdir -p $SYSCONFDIR |
| |
| # parse sshd options |
| set -- ${SSHD_OPTS} -- |
| sshd_config=/etc/ssh/sshd_config |
| while true ; do |
| case "$1" in |
| -f*) if [ "$1" = "-f" ] ; then |
| sshd_config="$2" |
| shift |
| else |
| sshd_config="${1#-f}" |
| fi |
| shift |
| ;; |
| --) shift; break;; |
| *) shift;; |
| esac |
| done |
| |
| HOST_KEYS=$(sed -n 's/^[ \t]*HostKey[ \t]\+\(.*\)/\1/p' "${sshd_config}") |
| [ -z "${HOST_KEYS}" ] && HOST_KEYS="$SYSCONFDIR/ssh_host_rsa_key $SYSCONFDIR/ssh_host_ecdsa_key $SYSCONFDIR/ssh_host_ed25519_key" |
| |
| for key in ${HOST_KEYS} ; do |
| [ -f $key ] && continue |
| case $key in |
| *_rsa_key) |
| echo " generating ssh RSA host key..." |
| generate_key $key rsa |
| ;; |
| *_ecdsa_key) |
| echo " generating ssh ECDSA host key..." |
| generate_key $key ecdsa |
| ;; |
| *_ed25519_key) |
| echo " generating ssh ED25519 host key..." |
| generate_key $key ed25519 |
| ;; |
| esac |
| done |