From 1b2d41a34aa60fb90b4f145ae2776c4807550a4d Mon Sep 17 00:00:00 2001 From: Joachim Desroches Date: Thu, 17 Dec 2020 13:29:03 +0100 Subject: [PATCH 1/3] Initial implementation of the __pass type. --- type/__pass/gencode-local | 71 ++++++++++++++++++++++ type/__pass/man.rst | 79 +++++++++++++++++++++++++ type/__pass/parameter/boolean | 1 + type/__pass/parameter/optional | 1 + type/__pass/parameter/required | 1 + type/__pass/parameter/required_multiple | 1 + 6 files changed, 154 insertions(+) create mode 100755 type/__pass/gencode-local create mode 100644 type/__pass/man.rst create mode 100644 type/__pass/parameter/boolean create mode 100644 type/__pass/parameter/optional create mode 100644 type/__pass/parameter/required create mode 100644 type/__pass/parameter/required_multiple diff --git a/type/__pass/gencode-local b/type/__pass/gencode-local new file mode 100755 index 0000000..e9e983c --- /dev/null +++ b/type/__pass/gencode-local @@ -0,0 +1,71 @@ +#!/bin/sh -e +# +# 2020 Joachim Desroches (joachim.desroches@epfl.ch) +# +# 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 . +# + +# Length of generated password. +LENGTH= + +# Keep password strictly alphanumeric. +NOSYMB= + +# Check pass is installed. +command -v pass >/dev/null 2>&1 || + { + cat <<- EOF >&2 + __pass: this type requires pass installed. + See https://www.passwordstore.org/. + EOF + exit 1; + } + +# Check for optional length parameter. +if [ -f "${__object:?}/parameter/length" ]; +then + LENGTH="$(cat "${__object:?}/parameter/length")" +fi + +# Check for optional no symbols parameter. +if [ -f "${__object:?}/parameter/no-symbols" ]; +then + NOSYMB="-n" +fi + +# Load required GPG ID parameters. +set -- +while read -r id; +do + set -- "$@" "$id" +done < "${__object:?}/parameter/gpgid" + +# Load required password store location parameter. +PASSWORD_STORE_DIR="$(cat "${__object:?}/parameter/storedir")" +export PASSWORD_STORE_DIR + +# Run every time in case GPG IDs are updated. +pass init "$@" >/dev/null + +# Generate a password if it does not already exist. +if [ ! -f "${PASSWORD_STORE_DIR}/${__object_id:?}.gpg" ]; +then + # shellcheck disable=SC2086 + pass generate $NOSYMB "${__object_id:?}" $LENGTH +fi + +# Send it out to the messages. +pass "${__object_id:?}" >> "${__messages_out:?}" diff --git a/type/__pass/man.rst b/type/__pass/man.rst new file mode 100644 index 0000000..60bc6f8 --- /dev/null +++ b/type/__pass/man.rst @@ -0,0 +1,79 @@ +cdist-type__pass(7) +=================== + +NAME +---- +cdist-type__pass - Generate and use passwords using pass(1). + + +DESCRIPTION +----------- +This type allows a user to generate and query passwords stored using pass(1) on +the host machine. The password is then printed to the cdist message system, so +types depending on this one should require it. This enables an administrator to +ensure a password exists using this type and then, from another type, use it as +need be. + +This type also sets the GPG IDs used to encrypt the password store: beware that +the IDs passed in the last ran invocation of the type will be the ones set for +the store. + +REQUIRED PARAMETERS +------------------- +storedir + The host-local directory where the password store is to be found (or + created if it does not exist). + + +REQUIRED MULTIPLE PARAMETERS +---------------------------- +gpgid + The GPG IDs of the public keys used to encrypt the password store. + +OPTIONAL PARAMETERS +------------------- +length + The length of the password to be created if it does not exist. Note that if + it exists, this has no effect (and hence will not update the password, even + if the length is different from the one specified). + +BOOLEAN PARAMETERS +------------------ +no-symbols + If this parameter is set, then a newly generated password will only contain + alphanumeric characters, making it easier for typing by meatware. + + +EXAMPLES +-------- + +Assuming that __othertype takes the path of the password as an argument and +looks up in the cdist messages to find it: + +.. code-block:: sh + + __pass database/services/arandomservice + --storedir password/store/location + --gpgpid 92296965EAA1DD86A93284EF7B21E5AA32FB9810 + + require='__pass/database/services/arandomservice' \ + __othertype --password database/service/arandomservice + +-- + +SEE ALSO +-------- +`pass`\ (7) + + +AUTHORS +------- +Joachim Desroches + + +COPYING +------- +Copyright \(C) 2020 Joachim Desroches. 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. diff --git a/type/__pass/parameter/boolean b/type/__pass/parameter/boolean new file mode 100644 index 0000000..8be3749 --- /dev/null +++ b/type/__pass/parameter/boolean @@ -0,0 +1 @@ +no-symbols diff --git a/type/__pass/parameter/optional b/type/__pass/parameter/optional new file mode 100644 index 0000000..7f5e3b6 --- /dev/null +++ b/type/__pass/parameter/optional @@ -0,0 +1 @@ +length diff --git a/type/__pass/parameter/required b/type/__pass/parameter/required new file mode 100644 index 0000000..f2fc3a2 --- /dev/null +++ b/type/__pass/parameter/required @@ -0,0 +1 @@ +storedir diff --git a/type/__pass/parameter/required_multiple b/type/__pass/parameter/required_multiple new file mode 100644 index 0000000..bed3d4a --- /dev/null +++ b/type/__pass/parameter/required_multiple @@ -0,0 +1 @@ +gpgid From 0d431d086c967ee5bdf67d0bd568c06c1a504111 Mon Sep 17 00:00:00 2001 From: Joachim Desroches Date: Wed, 27 Jan 2021 16:06:28 +0100 Subject: [PATCH 2/3] Split initializing the password store from generating passwords. --- type/__pass/gencode-local | 20 +++---- type/__pass/man.rst | 16 ++---- type/__pass_init/gencode-local | 43 ++++++++++++++ type/__pass_init/man.rst | 56 +++++++++++++++++++ type/__pass_init/parameter/required | 1 + .../parameter/required_multiple | 0 type/__pass_init/singleton | 0 7 files changed, 115 insertions(+), 21 deletions(-) create mode 100755 type/__pass_init/gencode-local create mode 100644 type/__pass_init/man.rst create mode 100644 type/__pass_init/parameter/required rename type/{__pass => __pass_init}/parameter/required_multiple (100%) create mode 100644 type/__pass_init/singleton diff --git a/type/__pass/gencode-local b/type/__pass/gencode-local index e9e983c..e1277fa 100755 --- a/type/__pass/gencode-local +++ b/type/__pass/gencode-local @@ -46,25 +46,25 @@ then NOSYMB="-n" fi -# Load required GPG ID parameters. -set -- -while read -r id; -do - set -- "$@" "$id" -done < "${__object:?}/parameter/gpgid" - # Load required password store location parameter. PASSWORD_STORE_DIR="$(cat "${__object:?}/parameter/storedir")" export PASSWORD_STORE_DIR -# Run every time in case GPG IDs are updated. -pass init "$@" >/dev/null +# Check if the password store is initialized. +if ! pass ls >/dev/null 2>&1; +then + cat <<- EOF >&2 + __pass: this type requires the password store to be initialized. + See cdist-type__pass_init(7) and pass(1) for more information. + EOF + exit 1; +fi # Generate a password if it does not already exist. if [ ! -f "${PASSWORD_STORE_DIR}/${__object_id:?}.gpg" ]; then # shellcheck disable=SC2086 - pass generate $NOSYMB "${__object_id:?}" $LENGTH + pass generate $NOSYMB "${__object_id:?}" $LENGTH >/dev/null fi # Send it out to the messages. diff --git a/type/__pass/man.rst b/type/__pass/man.rst index 60bc6f8..ea9b93c 100644 --- a/type/__pass/man.rst +++ b/type/__pass/man.rst @@ -14,9 +14,6 @@ types depending on this one should require it. This enables an administrator to ensure a password exists using this type and then, from another type, use it as need be. -This type also sets the GPG IDs used to encrypt the password store: beware that -the IDs passed in the last ran invocation of the type will be the ones set for -the store. REQUIRED PARAMETERS ------------------- @@ -25,11 +22,6 @@ storedir created if it does not exist). -REQUIRED MULTIPLE PARAMETERS ----------------------------- -gpgid - The GPG IDs of the public keys used to encrypt the password store. - OPTIONAL PARAMETERS ------------------- length @@ -37,6 +29,7 @@ length it exists, this has no effect (and hence will not update the password, even if the length is different from the one specified). + BOOLEAN PARAMETERS ------------------ no-symbols @@ -52,18 +45,19 @@ looks up in the cdist messages to find it: .. code-block:: sh - __pass database/services/arandomservice + require=__pass_init \ + __pass database/services/arandomservice \ --storedir password/store/location - --gpgpid 92296965EAA1DD86A93284EF7B21E5AA32FB9810 require='__pass/database/services/arandomservice' \ __othertype --password database/service/arandomservice + -- SEE ALSO -------- -`pass`\ (7) +`pass`\ (7), `cdist-type__pass_init`\ (7) AUTHORS diff --git a/type/__pass_init/gencode-local b/type/__pass_init/gencode-local new file mode 100755 index 0000000..0be44d9 --- /dev/null +++ b/type/__pass_init/gencode-local @@ -0,0 +1,43 @@ +#!/bin/sh -e +# +# 2020 Joachim Desroches (joachim.desroches@epfl.ch) +# +# 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 . +# + +# Check pass is installed. +command -v pass >/dev/null 2>&1 || + { + cat <<- EOF >&2 + __pass_init: this type requires pass installed. + See https://www.passwordstore.org/. + EOF + exit 1; + } + +# Load required GPG ID parameters. +set -- +while read -r id; +do + set -- "$@" "$id" +done < "${__object:?}/parameter/gpgid" + +# Load required password store location parameter. +PASSWORD_STORE_DIR="$(cat "${__object:?}/parameter/storedir")" +export PASSWORD_STORE_DIR + +# Do our work. +pass init "$@" >/dev/null diff --git a/type/__pass_init/man.rst b/type/__pass_init/man.rst new file mode 100644 index 0000000..7a8d01e --- /dev/null +++ b/type/__pass_init/man.rst @@ -0,0 +1,56 @@ +cdist-type__pass_init(7) +======================== + +NAME +---- +cdist-type__pass_init - Initialize a local password store. + + +DESCRIPTION +----------- +This type is intented to be used as a prerequisite to the +cdist-type__pass(7) type. It will set up a pass(1) password +store with the provided GPP2(1) public encryption key IDs. + + +REQUIRED PARAMETERS +------------------- +storedir + The host-local directory where the password store is to be found (or + created if it does not exist). + + +REQUIRED MULTIPLE PARAMETERS +---------------------------- +gpgid + The GPG IDs of the public keys used to encrypt the password store. + + +EXAMPLES +-------- + +.. code-block:: sh + + # Setup a repository with a GPG ID + __pass_init + --storedir password/store/location + --gpgpid 92296965EAA1DD86A93284EF7B21E5AA32FB9810 + +-- + +SEE ALSO +-------- +`pass`\ (7), `cdist-type__pass`\ (7) + + +AUTHORS +------- +Joachim Desroches + + +COPYING +------- +Copyright \(C) 2021 Joachim Desroches. 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. diff --git a/type/__pass_init/parameter/required b/type/__pass_init/parameter/required new file mode 100644 index 0000000..f2fc3a2 --- /dev/null +++ b/type/__pass_init/parameter/required @@ -0,0 +1 @@ +storedir diff --git a/type/__pass/parameter/required_multiple b/type/__pass_init/parameter/required_multiple similarity index 100% rename from type/__pass/parameter/required_multiple rename to type/__pass_init/parameter/required_multiple diff --git a/type/__pass_init/singleton b/type/__pass_init/singleton new file mode 100644 index 0000000..e69de29 From 2d5b32db1c6c639be8ef4350ba169f451c14d670 Mon Sep 17 00:00:00 2001 From: Joachim Desroches Date: Sat, 13 Feb 2021 15:45:26 +0100 Subject: [PATCH 3/3] Wrap gencode-local in a heredoc. --- type/__pass/gencode-local | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/type/__pass/gencode-local b/type/__pass/gencode-local index e1277fa..3346707 100755 --- a/type/__pass/gencode-local +++ b/type/__pass/gencode-local @@ -18,6 +18,8 @@ # along with cdist. If not, see . # +cat <<- EOF + # Length of generated password. LENGTH= @@ -30,7 +32,7 @@ command -v pass >/dev/null 2>&1 || cat <<- EOF >&2 __pass: this type requires pass installed. See https://www.passwordstore.org/. - EOF + EOFF exit 1; } @@ -38,12 +40,14 @@ command -v pass >/dev/null 2>&1 || if [ -f "${__object:?}/parameter/length" ]; then LENGTH="$(cat "${__object:?}/parameter/length")" + export LENGTH fi # Check for optional no symbols parameter. if [ -f "${__object:?}/parameter/no-symbols" ]; then NOSYMB="-n" + export NOSYMB fi # Load required password store location parameter. @@ -53,19 +57,21 @@ export PASSWORD_STORE_DIR # Check if the password store is initialized. if ! pass ls >/dev/null 2>&1; then - cat <<- EOF >&2 + cat <<- EOFF >&2 __pass: this type requires the password store to be initialized. See cdist-type__pass_init(7) and pass(1) for more information. - EOF + EOFF exit 1; fi # Generate a password if it does not already exist. -if [ ! -f "${PASSWORD_STORE_DIR}/${__object_id:?}.gpg" ]; +if [ ! -f "\${PASSWORD_STORE_DIR}/${__object_id:?}.gpg" ]; then # shellcheck disable=SC2086 - pass generate $NOSYMB "${__object_id:?}" $LENGTH >/dev/null + pass generate \$NOSYMB "${__object_id:?}" $LENGTH >/dev/null fi # Send it out to the messages. pass "${__object_id:?}" >> "${__messages_out:?}" + +EOF