complete rewrite

- add support for authorized_keys options see sshd(8)
- add support for explicit comment after key
- do not allow a key to exist more then once in an authorized_keys file
- remove all conflicting keys

Signed-off-by: Steven Armstrong <steven@icarus.ethz.ch>
This commit is contained in:
Steven Armstrong 2014-09-25 16:16:15 +02:00
parent 5a895480b7
commit ffd2935cc4
6 changed files with 88 additions and 35 deletions

View file

@ -0,0 +1,32 @@
#!/bin/sh
#
# 2014 Steven Armstrong (steven-cdist at armstrong.cc)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
# Find and sort any entries in the authorized_keys file that we care about
file="$($__type_explorer/file)"
(
while read key; do
# extract the keytype and base64 encoded key ignoring any options and comment
type_and_key="$(echo "$key" | tr ' ' '\n' | awk '/^(ssh|ecdsa)-[^ ]+/ { printf $1" "; getline; printf $1 }')"
# emit any entries that match the type and key
grep ".*$type_and_key[ \n]" "$file"
done < "$__object/parameter/key"
) | sort

View file

@ -1,6 +1,6 @@
#!/bin/sh
#
# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
# 2014 Steven Armstrong (steven-cdist at armstrong.cc)
#
# This file is part of cdist.
#
@ -18,6 +18,10 @@
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
getent passwd "$owner" || true
if [ -f "$__object/parameter/file" ]; then
cat "$__object/parameter/file"
else
owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
home=$(getent passwd "$owner" | cut -d':' -f 6)
echo "$home/.ssh/authorized_keys"
fi

View file

@ -18,5 +18,6 @@
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
gid="$("$__type_explorer/passwd" | cut -d':' -f 4)"
owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
gid="$(getent passwd "$owner" | cut -d':' -f 4)"
getent group "$gid" || true

View file

@ -12,13 +12,13 @@ DESCRIPTION
-----------
Adds or removes ssh keys from a authorized_keys file.
This type uses the __ssh_dot_ssh type to the directory containing
the authorized_keys file.
You can disable this feature with the --noparent boolean parameter.
This type uses the __ssh_dot_ssh type to manage the directory containing
the authorized_keys file. You can disable this feature with the --noparent
boolean parameter.
The existence, ownership and permissions of the authorized_keys file itself are
also managed. This can be disabled with the --nofile boolean parameter. It is
then left to the user to ensure that the file exists and that ownership and
then left to the user to ensure that the file exists and that ownership and
permissions work with ssh.
@ -31,15 +31,23 @@ key::
OPTIONAL PARAMETERS
-------------------
comment::
explicit comment instead of the one which may be trailing the given key
file::
an alternative destination file, defaults to ~$owner/.ssh/authorized_keys
option::
an option to set for all created authorized_key entries.
Can be specified multiple times.
See sshd(8) for available options.
owner::
the user owning the authorized_keys file, defaults to object_id.
state::
if the given keys should be 'present' or 'absent', defaults to 'present'.
file::
an alternative destination file, defaults to ~$owner/.ssh/authorized_keys
BOOLEAN PARAMETERS
------------------
@ -64,13 +72,24 @@ __ssh_authorized_keys root \
__ssh_authorized_keys user-name \
--key "ssh-rsa AXYZAAB3NzaC1yc2..."
# allow key to login as user-name with options and expicit comment
__ssh_authorized_keys user-name \
--key "ssh-rsa AXYZAAB3NzaC1yc2..." \
--option no-agent-forwarding \
--option 'from="*.example.com"' \
--comment 'backup server'
# same as above, but with explicit owner and two keys
# note that the options are set for all given keys
__ssh_authorized_keys some-fancy-id \
--owner user-name \
--key "ssh-rsa AXYZAAB3NzaC1yc2..." \
--key "ssh-rsa AZXYAAB3NzaC1yc2..."
--key "ssh-rsa AZXYAAB3NzaC1yc2..." \
--option no-agent-forwarding \
--option 'from="*.example.com"' \
--comment 'backup server'
# same as above, but authorized_keys file in non standard location
# authorized_keys file in non standard location
__ssh_authorized_keys some-fancy-id \
--file /etc/ssh/keys/user-name/authorized_keys \
--owner user-name \
@ -89,6 +108,7 @@ __ssh_authorized_keys some-fancy-id \
SEE ALSO
--------
- cdist-type(7)
- sshd(8)
COPYING

View file

@ -21,16 +21,7 @@
owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
state="$(cat "$__object/parameter/state" 2>/dev/null)"
if [ -f "$__object/parameter/file" ]; then
file="$(cat "$__object/parameter/file")"
else
home="$(cut -d':' -f 6 "$__object/explorer/passwd")"
if [ -z "$home" ]; then
echo "Failed to get home directory from explorer." >&2
exit 1
fi
file="$home/.ssh/authorized_keys"
fi
file="$(cat "$__object/explorer/file")"
if [ ! -f "$__object/parameter/noparent" -o ! -f "$__object/parameter/nofile" ]; then
group="$(cut -d':' -f 1 "$__object/explorer/group")"
@ -50,6 +41,7 @@ if [ ! -f "$__object/parameter/noparent" -o ! -f "$__object/parameter/nofile" ];
--group "$group" \
--mode 0600 \
--state exists
export require="__file/$file"
fi
fi
@ -63,22 +55,24 @@ __block "$__object_name" \
--text - << DONE
remove legacy block
DONE
export require="__block/$__object_name"
_cksum() {
echo "$1" | cksum | cut -d' ' -f 1
}
while read key; do
cksum_key="$(_cksum "$key")"
line_id="${owner}-${cksum_key}"
set -- "$line_id"
type_and_key="$(echo "$key" | tr ' ' '\n' | awk '/^(ssh|ecdsa)-[^ ]+/ { printf $1" "; getline; printf $1 }')"
object_id="$(_cksum "$file")-$(_cksum "$type_and_key")"
set -- "$object_id"
set -- "$@" --file "$file"
set -- "$@" --regex ".*$key.*"
if [ "$state" = 'present' ]; then
set -- "$@" --line "$key"
fi
set -- "$@" --key "$key"
set -- "$@" --state "$state"
# Ensure __line does not read stdin
require="__block/$__object_name" __line "$@" < /dev/null
if [ -f "$__object/parameter/option" ]; then
set -- "$@" --option "$(cat "$__object/parameter/option")"
fi
if [ -f "$__object/parameter/comment" ]; then
set -- "$@" --comment "$(cat "$__object/parameter/comment")"
fi
__ssh_authorized_key "$@"
done < "$__object/parameter/key"

View file

@ -1,3 +1,5 @@
comment
file
option
owner
state
file