diff --git a/cdist/conf/type/__ssh_authorized_keys/explorer/entry b/cdist/conf/type/__ssh_authorized_keys/explorer/entry new file mode 100755 index 00000000..9992d32d --- /dev/null +++ b/cdist/conf/type/__ssh_authorized_keys/explorer/entry @@ -0,0 +1,45 @@ +#!/bin/sh +# +# 2012 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 . +# + +owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")" +if [ -f "$__object/parameter/file" ]; then + file="$(cat "$__object/parameter/file")" +else + home="$("$__type_explorer/passwd" | cut -d':' -f 6)" + file="$home/.ssh/authorized_keys" +fi + +# no authorized_keys file, nothing we could do +[ -f "$file" ] || exit 0 + +# NOTE: keep variables in sync in manifest/explorer/gencode-* +prefix="#cdist:$__object_name" +suffix="#/cdist:$__object_name" +awk -v prefix="$prefix" -v suffix="$suffix" '{ + if (index($0,prefix)) { + triggered=1 + } + if (triggered) { + if (index($0,suffix)) { + triggered=0 + } + print + } +}' "$file" diff --git a/cdist/conf/type/__ssh_authorized_keys/explorer/passwd b/cdist/conf/type/__ssh_authorized_keys/explorer/passwd new file mode 100755 index 00000000..e6352ee0 --- /dev/null +++ b/cdist/conf/type/__ssh_authorized_keys/explorer/passwd @@ -0,0 +1,23 @@ +#!/bin/sh +# +# 2012 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 . +# + +owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")" + +getent passwd "$owner" || true diff --git a/cdist/conf/type/__ssh_authorized_keys/gencode-remote b/cdist/conf/type/__ssh_authorized_keys/gencode-remote new file mode 100755 index 00000000..cc86cc19 --- /dev/null +++ b/cdist/conf/type/__ssh_authorized_keys/gencode-remote @@ -0,0 +1,82 @@ +#!/bin/sh +# +# 2012 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 . +# + +owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")" +if [ -f "$__object/parameter/file" ]; then + file="$(cat "$__object/parameter/file")" +else + home="$(cut -d':' -f 6 "$__object/explorer/passwd")" + file="$home/.ssh/authorized_keys" +fi + +entry="$__object/files/entry" +if [ ! -s "$__object/explorer/entry" ]; then + state_is='absent' +else + state_is=$(diff -q "$entry" "$__object/explorer/entry" >/dev/null \ + && echo present \ + || echo changed + ) +fi + +state_should="$(cat "$__object/parameter/state" 2>/dev/null || echo present)" +if [ "$state_should" = "$state_is" ]; then + # Nothing to do, move along + exit 0 +fi + +remove_entry() { + # NOTE: keep variables in sync in manifest/explorer/gencode-* + prefix="#cdist:$__object_name" + suffix="#/cdist:$__object_name" + cat << DONE +tmpfile=\$(mktemp) +awk -v prefix="$prefix" -v suffix="$suffix" ' +{ + if (index(\$0,prefix)) { + triggered=1 + } + if (triggered) { + if (index(\$0,suffix)) { + triggered=0 + } + } else { + print + } +}' "$file" > "\$tmpfile" +mv -f "\$tmpfile" "$file" +DONE +} + +case "$state_should" in + present) + if [ "$state_is" = "changed" ]; then + remove_entry + fi + cat << DONE +cat >> "$file" << ${__type##*/}_DONE +$(cat "$entry") +${__type##*/}_DONE +DONE + ;; + absent) + remove_entry + ;; +esac diff --git a/cdist/conf/type/__ssh_authorized_keys/man.text b/cdist/conf/type/__ssh_authorized_keys/man.text new file mode 100644 index 00000000..7177f26e --- /dev/null +++ b/cdist/conf/type/__ssh_authorized_keys/man.text @@ -0,0 +1,101 @@ +cdist-type__ssh_authorized_keys(7) +================================== +Steven Armstrong + + +NAME +---- +cdist-type__ssh_authorized_keys - manage ssh authorized_keys files + + +DESCRIPTION +----------- +Adds or removes ssh keys from a authorized_keys file. + +This type also manages the directory containing the authorized_keys +file and sets strict ownership and permissions. 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 +permissions work with ssh. + + +REQUIRED PARAMETERS +------------------- +key:: + the ssh key which shall be added to this authorized_keys file. + Must be a string and can be specified multiple times. + + +OPTIONAL PARAMETERS +------------------- +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 + +comment:: + an optional comment + + +BOOLEAN PARAMETERS +------------------ +noparent:: + don't create or change ownership and permissions of the directory containing + the authorized_keys file + +nofile:: + don't manage existence, ownership and permissions of the the authorized_keys + file + + +EXAMPLES +-------- + +-------------------------------------------------------------------------------- +# add your ssh key to remote root's authorized_keys file +__ssh_authorized_keys root \ + --key "$(cat ~/.ssh/id_rsa.pub)" + +# allow key to login as user-name +__ssh_authorized_keys user-name \ + --key "ssh-rsa AXYZAAB3NzaC1yc2..." + +# same as above, but with explicit owner, two keys and a comment +__ssh_authorized_keys some-fancy-id \ + --owner user-name \ + --key "ssh-rsa AXYZAAB3NzaC1yc2..." \ + --key "ssh-rsa AZXYAAB3NzaC1yc2..." \ + --comment "allow the members of project foo to login" + +# same as above, but authorized_keys file in non standard location +__ssh_authorized_keys some-fancy-id \ + --file /etc/ssh/keys/user-name/authorized_keys \ + --owner user-name \ + --key "ssh-rsa AXYZAAB3NzaC1yc2..." + +# same as above, but directory and authorized_keys file is created elswhere +__ssh_authorized_keys some-fancy-id \ + --file /etc/ssh/keys/user-name/authorized_keys \ + --owner user-name \ + --noparent \ + --nofile \ + --key "ssh-rsa AXYZAAB3NzaC1yc2..." +-------------------------------------------------------------------------------- + + +SEE ALSO +-------- +- cdist-type(7) + + +COPYING +------- +Copyright \(C) 2012 Steven Armstrong. Free use of this software is +granted under the terms of the GNU General Public License version 3 (GPLv3). diff --git a/cdist/conf/type/__ssh_authorized_keys/manifest b/cdist/conf/type/__ssh_authorized_keys/manifest new file mode 100755 index 00000000..268b1fbe --- /dev/null +++ b/cdist/conf/type/__ssh_authorized_keys/manifest @@ -0,0 +1,74 @@ +#!/bin/sh +# +# 2012 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 . +# + +owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")" +state="$(cat "$__object/parameter/present" 2>/dev/null || echo "present")" +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 + +if [ ! -f "$__object/parameter/noparent" -o ! -f "$__object/parameter/nofile" ]; then + group="$(cut -d':' -f 4 "$__object/explorer/passwd")" + if [ -z "$group" ]; then + echo "Failed to get owners group from explorer." >&2 + exit 1 + fi + + if [ ! -f "$__object/parameter/noparent" ]; then + # Ensure that the directory in which the authorized_keys shall be exists and + # has the right permissions. + ssh_directory="${file%/*}" + __directory "$ssh_directory" --state present --parents \ + --owner "$owner" --group "$group" --mode 0700 + export require="__directory/$ssh_directory" + fi + if [ ! -f "$__object/parameter/nofile" ]; then + # Ensure that authorized_keys file exists and has the right permissions. + __file "$file" \ + --owner "$owner" \ + --group "$group" \ + --mode 0600 \ + --state exists + fi +fi + +# NOTE: keep variables in sync in manifest/explorer/gencode-* +prefix="#cdist:$__object_name" +suffix="#/cdist:$__object_name" + +mkdir "$__object/files" + +# Generate entry for inclusion in authorized_keys file +entry="$__object/files/entry" +echo "$prefix" > "$entry" +if [ -f "$__object/parameter/comment" ]; then + echo "# $(cat "$__object/parameter/comment")" >> "$entry" +fi +cat "$__object/parameter/key" >> "$entry" +# ensure we have a newline after keys +echo >> "$entry" +echo "$suffix" >> "$entry" diff --git a/cdist/conf/type/__ssh_authorized_keys/parameter/boolean b/cdist/conf/type/__ssh_authorized_keys/parameter/boolean new file mode 100644 index 00000000..4bb126fe --- /dev/null +++ b/cdist/conf/type/__ssh_authorized_keys/parameter/boolean @@ -0,0 +1,2 @@ +noparent +nofile diff --git a/cdist/conf/type/__ssh_authorized_keys/parameter/optional b/cdist/conf/type/__ssh_authorized_keys/parameter/optional new file mode 100644 index 00000000..bfbd72ab --- /dev/null +++ b/cdist/conf/type/__ssh_authorized_keys/parameter/optional @@ -0,0 +1,4 @@ +owner +state +file +comment diff --git a/cdist/conf/type/__ssh_authorized_keys/parameter/required_multiple b/cdist/conf/type/__ssh_authorized_keys/parameter/required_multiple new file mode 100644 index 00000000..06bfde49 --- /dev/null +++ b/cdist/conf/type/__ssh_authorized_keys/parameter/required_multiple @@ -0,0 +1 @@ +key