Re: "generating new host key..."

Previous thread: traceroute support for RFC 5837 by Claudio Jeker on Tuesday, September 7, 2010 - 7:40 am. (3 messages)

Next thread: Re: "generating new host key..." by Theo de Raadt on Tuesday, September 7, 2010 - 8:27 pm. (1 message)
From: Christian Weisgerber
Date: Tuesday, September 7, 2010 - 7:55 am

Theo has suggested that it would be nicer if the "generating new
host key" output was all on one line.

Basically we want "ssh-keygen: generating new host key:" to start
the line, followed by the algorith name as each key is generated.
In the unlikely event that an error happens, ssh-keygen will complain
verbosely, and we're again at the start of a line.

Here's what I currently have, but I'm not very happy with it.


ssh_keys=0
if [ ! -f /etc/ssh/ssh_host_dsa_key ]; then
	if [ $((ssh_keys++)) -eq 0 ]; then
		echo -n "ssh-keygen: generating new host key:"
	fi
	echo -n " DSA..."
	if ! /usr/bin/ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -N ''; then
		ssh_keys=0
	fi
fi
if [ ! -f /etc/ssh/ssh_host_ecdsa_key ]; then
	if [ $((ssh_keys++)) -eq 0 ]; then
		echo -n "ssh-keygen: generating new host key:"
	fi
	echo -n " ECDSA..."
	if ! /usr/bin/ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ''; then
		ssh_keys=0
	fi
fi
if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then
	if [ $((ssh_keys++)) -eq 0 ]; then
		echo -n "ssh-keygen: generating new host key:"
	fi
	echo -n " RSA..."
	if ! /usr/bin/ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N ''; then
		ssh_keys=0
	fi
fi
if [ ! -f /etc/ssh/ssh_host_key ]; then
	if [ $((ssh_keys++)) -eq 0 ]; then
		echo -n "ssh-keygen: generating new host key:"
	fi
	echo -n " RSA1..."
	/usr/bin/ssh-keygen -q -t rsa1 -f /etc/ssh/ssh_host_key -N ''
fi
if [ $ssh_keys -gt 0 ]; then
	echo
fi

-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de

From: Todd T. Fries
Date: Tuesday, September 7, 2010 - 8:15 am

I am not sure of a better way than what you've proposed, but the logic
does make perfect sense to me.

As a shortened version of what you proposed:

ssh_keys=0

# Generate ssh keys
# Usage: ssh_keygen lowercase_keyname uppercase_keyname [keyfile_string]
ssh_keygen() {
        local lc="$1" uc="$2" part="$3" file
        [ "$part" ] && part="${part}_"
        file=/etc/ssh/ssh_host_${part}key
	if [ $((ssh_keys++)) -eq 0 ]; then
		echo -n "ssh-keygen: generating new host key:"
	fi
        if [ ! -f $file ]; then
                echo -n " $uc..."
                if ! /usr/bin/ssh-keygen -q -t $lc -f $file -N ''; then
			ssh_keys=0
                fi
        fi
}
ssh_keygen rsa1 RSA1
ssh_keygen dsa DSA dsa
ssh_keygen rsa DSA rsa
ssh_keygen ecdsa ECDSA ecdsa
if [ $ssh_keys -gt 0 ]; then
	echo
fi

Penned by Christian Weisgerber on 20100907 16:55.45, we have:
| Theo has suggested that it would be nicer if the "generating new
| host key" output was all on one line.
| 
| Basically we want "ssh-keygen: generating new host key:" to start
| the line, followed by the algorith name as each key is generated.
| In the unlikely event that an error happens, ssh-keygen will complain
| verbosely, and we're again at the start of a line.
| 
| Here's what I currently have, but I'm not very happy with it.
| 
| 
| ssh_keys=0
| if [ ! -f /etc/ssh/ssh_host_dsa_key ]; then
| 	if [ $((ssh_keys++)) -eq 0 ]; then
| 		echo -n "ssh-keygen: generating new host key:"
| 	fi
| 	echo -n " DSA..."
| 	if ! /usr/bin/ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -N ''; then
| 		ssh_keys=0
| 	fi
| fi
| if [ ! -f /etc/ssh/ssh_host_ecdsa_key ]; then
| 	if [ $((ssh_keys++)) -eq 0 ]; then
| 		echo -n "ssh-keygen: generating new host key:"
| 	fi
| 	echo -n " ECDSA..."
| 	if ! /usr/bin/ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ''; then
| 		ssh_keys=0
| 	fi
| fi
| if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then
| 	if [ $((ssh_keys++)) -eq 0 ]; then
| 		echo -n "ssh-keygen: ...
From: TeXitoi
Date: Tuesday, September 7, 2010 - 8:56 am

My proposition, avoiding function:

ssh_keys=TOPRINT

for key in rsa1 dsa rsa ecdsa; do
        if [ "$key" = rsa1 ]; then
                file="/etc/ssh/ssh_host_key"
        else
                file="/etc/ssh/ssh_host_$key_key"
        fi

        if [ "$ssh_key" = TOPRINT ]; then
                echo -n "ssh-keygen: generating new host key:"
                ssh_key=PRINTED
        fi

        if [ ! -f "$file" ]; then
                echo -n " `echo "$key" | tr a-z A-Z`..."
                if ! /usr/bin/ssh-keygen -q -t "$key" -f "$file" -N ''; then
                        ssh_key=TOPRINT
                fi
        fi
done

if [ "$ssh_keys" = PRINTED ]; then
        echo
fi

Not tested, but you have the idea.

-- 
Guillaume Pinot                                http://www.texitoi.eu

+ Les grandes personnes ne comprennent jamais rien toutes seules, et
c'est fatigant, pour les enfants, de toujours leur donner des
explications... ; -- Antoine de Saint-Exupiry, Le Petit Prince

()  ASCII ribbon campaign      -- Against HTML e-mail
/\  http://www.asciiribbon.org -- Against proprietary attachments

From: Martin Pelikán
Date: Tuesday, September 7, 2010 - 9:55 am

Sorry, but the efficiency's giving us hard time, doesn't it?
How about:
echo -n "generating: "
for ; do
...
done
echo

-- 
Martin Pelikan

From: Todd T. Fries
Date: Tuesday, September 7, 2010 - 10:21 am

Penned by Martin Pelik??n on 20100907 18:55.00, we have:
| 2010/9/7, TeXitoi <texitoi+news@texitoi.eu>:
| > My proposition, avoiding function:
| >
| > ssh_keys=TOPRINT
| >
| > for key in rsa1 dsa rsa ecdsa; do
| >         if [ "$ssh_key" = TOPRINT ]; then
| >                 echo -n "ssh-keygen: generating new host key:"
| >                 ssh_key=PRINTED
| >         fi
| > done
| >
| > if [ "$ssh_keys" = PRINTED ]; then
| >         echo
| > fi
| 
| Sorry, but the efficiency's giving us hard time, doesn't it?
| How about:
| echo -n "generating: "
| for ; do
| ...
| done
| echo
| 
| -- 
| Martin Pelikan

Neither of the above solutions provide the same output.

Sorry, the requirement is to `notice' we are on a new line if an error occurs,
and only do the final echo if we are not on a new line at the end.

Thanks,
-- 
Todd Fries .. todd@fries.net

 _____________________________________________
|                                             \  1.636.410.0632 (voice)
| Free Daemon Consulting, LLC                 \  1.405.227.9094 (voice)
| http://FreeDaemonConsulting.com             \  1.866.792.3418 (FAX)
| 2525 NW Expy #525, Oklahoma City, OK 73112  \  sip:freedaemon@ekiga.net
| "..in support of free software solutions."  \  sip:4052279094@ekiga.net
 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
                                                 
              37E7 D3EB 74D0 8D66 A68D  B866 0326 204E 3F42 004A
                        http://todd.fries.net/pgp.txt

From: Dan Harnett
Date: Tuesday, September 7, 2010 - 11:18 am

Another shot at this using mktemp to save the ssh-keygen output to a
temporary file.  The output looks a little cleaner, IMHO.


ssh_keys=0

for _type in dsa ecdsa rsa rsa1; do
	if [ "${_type}" = "rsa1" ]; then
		_key='/etc/ssh/ssh_host_key'
	else
		_key="/etc/ssh/ssh_host_${_type}_key"
	fi

	_name=`echo ${_type} | tr a-z A-Z`

	if [ ! -f "${_key}" ]; then
		if [ "${ssh_keys}" -eq 0 ]; then
			echo -n 'ssh-keygen: generating new host key:'
			ssh_keys=1
		fi

		_tmp=`mktemp /tmp/_keygen.XXXXXXXXXX`

		echo -n " ${_name}"
		ssh-keygen -q -t "${_type}" -f "${_key}" -N '' > ${_tmp} 2>&1
		if [ $? -ne 0 ]; then
			echo
			cat "${_tmp}"
			ssh_keys=0
		fi

		rm -f ${_tmp}
	fi
done

if [ "${ssh_keys}" -eq 1 ]; then
	echo '.'
fi

From: Dan Harnett
Date: Tuesday, September 7, 2010 - 10:50 am

Another loop that should meet the requirements.


ssh_keys=0

for _type in dsa ecdsa rsa rsa1; do
	if [ "${_type}" = "rsa1" ]; then
		_keyfile='/etc/ssh/ssh_host_key'
	else
		_keyfile="/etc/ssh/ssh_host_${_type}_key"
	fi

	_name=`echo "${_type}" | tr a-z A-Z`

	if [ ! -f "${_keyfile}" ]; then
		if [ "${ssh_keys}" -eq 0 ]; then
			echo -n 'ssh-keygen: generating new host key:'
			ssh_keys=1
		fi

		echo -n " ${_name}..."
		if ! ssh-keygen -q -t "${_type}" -f "${_keyfile}" -N ''; then
			ssh_keys=0
		fi
	fi
done

if [ "${ssh_keys}" -eq 1 ]; then
	echo
fi

From: Alexander Hall
Date: Tuesday, September 7, 2010 - 3:47 pm

My shot at it. 

- Errors at their own line, no need for temp file.
- Parentheses as a simple way to keep variables local. Remove and/or
  rename variables at will.

I also want to kill the IMO useless "ssh-keygen: " part of the output,
if noone opposes.

/Alexander

(
first=1
for type in dsa ecdsa rsa rsa1; do
	keyfile=/etc/ssh/ssh_host_${type}_key
	[ $type = rsa1 ] && keyfile=/etc/ssh/ssh_host_key
	if [ ! -f $keyfile ]; then
		[ $first ] && echo -n "ssh-keygen: generating new host key:"
		typeset -u uc=$type
		echo -n " $uc"
		first=
		if ! error=$(/usr/bin/ssh-keygen -q -t $type -f $keyfile -N '' 2>&1); then
			echo
			print -r -- "$error"
			first=1
		fi
	fi
done
[ $first ] || echo
)

From: Alexander Hall
Date: Tuesday, September 7, 2010 - 4:08 pm

I oppose. Disregard that.

From: Ted Unangst
Date: Tuesday, September 7, 2010 - 4:12 pm

On Tue, Sep 7, 2010 at 6:47 PM, Alexander Hall <halex@openbsd.org> wrote:




$first || echo

From: Alexander Hall
Date: Tuesday, September 7, 2010 - 4:18 pm

No... but it does work. :-)

[ ]  == false
[ 1 ] == true

also,

$ which true false
/usr/bin/true
/usr/bin/false

while those should be available to /etc/rc, I'd prefer not using them.

( I did consider using ":" as true and "! :" as false but did not as it
  would be less readable... :-) )


From: Ted Unangst
Date: Wednesday, September 8, 2010 - 8:39 am

-5 points for using which. :)

$ whence -v true
true is a shell builtin

I happen to think that explicit true and false values make things
easier to read, without as much [ ] noise.

From: Bret S. Lambert
Date: Wednesday, September 8, 2010 - 8:42 am

Truly, you do not grasp the simple elegance of a banana-shaped bikeshed.

From: Alexander Hall
Date: Wednesday, September 8, 2010 - 10:29 am

Yup. I totally agree then. :)

From: Damien Miller
Date: Tuesday, September 7, 2010 - 5:31 pm

my, that is complicated. Is there anything we could do in ssh-keygen to
make this simpler?

-d

From: Damien Miller
Date: Tuesday, September 7, 2010 - 9:20 pm

So, what would be nice is if ssh-keygen could automatically generate all
the hostkeys that don't already exist. The default paths are already there
in pathnames.h, so we just need a new option to iterate through each keytype
checking whether it exists and, if not, generating it and saving it to
the appropriate path.

Anyone want to have a go at this? (I won't have time for a couple of weeks)

-d

Previous thread: traceroute support for RFC 5837 by Claudio Jeker on Tuesday, September 7, 2010 - 7:40 am. (3 messages)

Next thread: Re: "generating new host key..." by Theo de Raadt on Tuesday, September 7, 2010 - 8:27 pm. (1 message)