Initial check in
This commit is contained in:
committed by
tlimoncelli@stackexchange.com
parent
e9a5bfab26
commit
73396c8a4d
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,7 +8,6 @@ __pycache__/
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
bin/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
|
||||
219
bin/blackbox_common.sh
Executable file
219
bin/blackbox_common.sh
Executable file
@@ -0,0 +1,219 @@
|
||||
|
||||
#
|
||||
# Common constants and functions used by the blackbox_* utilities.
|
||||
#
|
||||
|
||||
KEYRINGDIR=keyrings/live
|
||||
BB_ADMINS="${KEYRINGDIR}/blackbox-admins.txt"
|
||||
BB_FILES="${KEYRINGDIR}/blackbox-files.txt"
|
||||
SECRING="${KEYRINGDIR}/secring.gpg"
|
||||
PUBRING="${KEYRINGDIR}/pubring.gpg"
|
||||
|
||||
# Exit with error if the environment is not right.
|
||||
function fail_if_bad_environment() {
|
||||
# Current checked:
|
||||
# Are we in the base directory.
|
||||
|
||||
# Are we in the base directory.
|
||||
if [[ ! $(pwd) =~ \/puppet$ ]]; then
|
||||
echo 'ERROR: Please run this script from the base directory.'
|
||||
echo 'Exiting...'
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Exit with error if a file exists.
|
||||
function fail_if_exists() {
|
||||
if [[ -f "$1" ]]; then
|
||||
echo ERROR: "$1" exists. "$2"
|
||||
echo Exiting...
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Exit with error if a file is missing.
|
||||
function fail_if_not_exists() {
|
||||
if [[ ! -f "$1" ]]; then
|
||||
echo ERROR: "$1" not found. "$2"
|
||||
echo Exiting...
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Exit with error if filename is not registered on blackbox list.
|
||||
function fail_if_not_on_cryptlist() {
|
||||
if ! grep -s -q "$name" "$BB_FILES" ; then
|
||||
echo 'ERROR: Please run this script from the base directory.'
|
||||
echo 'Exiting...'
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Exit with error if keychain contains secret keys.
|
||||
function fail_if_keychain_has_secrets() {
|
||||
if [[ -s ${SECRING} ]]; then
|
||||
echo 'ERROR: The file' "$SECRING" 'should be empty.'
|
||||
echo 'Did someone accidentally add this private key to the ring?'
|
||||
echo 'Exiting...'
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Output the unencrypted filename.
|
||||
function get_unencrypted_filename() {
|
||||
echo $(dirname "$1")/$(basename "$1" .gpg) | sed -e 's#^\./##'
|
||||
}
|
||||
|
||||
# Output the encrypted filename.
|
||||
function get_encrypted_filename() {
|
||||
echo $(dirname "$1")/$(basename "$1" .gpg).gpg | sed -e 's#^\./##'
|
||||
}
|
||||
|
||||
# Prepare keychain for use.
|
||||
function prepare_keychain() {
|
||||
echo '========== Importing keychain: START'
|
||||
gpg --import "${PUBRING}" 2>&1 | egrep -v 'not changed$'
|
||||
echo '========== Importing keychain: DONE'
|
||||
}
|
||||
|
||||
# Add file to list of encrypted files.
|
||||
function add_filename_to_cryptlist() {
|
||||
# If the name is already on the list, this is a no-op.
|
||||
# However no matter what the datestamp is updated.
|
||||
local name
|
||||
name="$1"
|
||||
|
||||
if grep -s -q "$name" "$BB_FILES" ; then
|
||||
echo ========== File is registered. No need to add to list.
|
||||
else
|
||||
echo ========== Adding file to list.
|
||||
touch "$BB_FILES"
|
||||
sort -u -o "$BB_FILES" <(echo "$name") "$BB_FILES"
|
||||
fi
|
||||
}
|
||||
|
||||
# Print out who the current BB ADMINS are:
|
||||
function disclose_admins() {
|
||||
echo ========== blackbox administrators are:
|
||||
cat "$BB_ADMINS"
|
||||
}
|
||||
|
||||
# Encrypt file, overwriting .gpg if it exists.
|
||||
function encrypt_file() {
|
||||
local unencrypted
|
||||
local encrypted
|
||||
unencrypted="$1"
|
||||
encrypted="$2"
|
||||
|
||||
echo "========== Encrypting: $unencrypted"
|
||||
gpg --yes --trust-model=always --encrypt -o "$encrypted" $(awk '{ print "-r" $1 }' < "$BB_ADMINS") "$unencrypted"
|
||||
echo '========== Encrypting: DONE'
|
||||
}
|
||||
|
||||
# Decrypt .gpg file, asking "yes/no" before overwriting unencrypted file.
|
||||
function decrypt_file() {
|
||||
local encrypted
|
||||
local unencrypted
|
||||
encrypted="$1"
|
||||
unencrypted="$2"
|
||||
|
||||
echo "========== EXTRACTING $unencrypted"
|
||||
gpg -q --decrypt -o "$unencrypted" "$encrypted"
|
||||
}
|
||||
|
||||
# Decrypt .gpg file, overwriting unencrypted file if it exists.
|
||||
function decrypt_file_overwrite() {
|
||||
local encrypted
|
||||
local unencrypted
|
||||
local old_hash
|
||||
local new_hash
|
||||
encrypted="$1"
|
||||
unencrypted="$2"
|
||||
|
||||
if [[ -f "$unencrypted" ]]; then
|
||||
old_hash=$(md5sum < "$unencrypted"| awk '{ print $1 }')
|
||||
else
|
||||
old_hash=unmatchable
|
||||
fi
|
||||
gpg --yes -q --decrypt -o "$unencrypted" "$encrypted"
|
||||
new_hash=$(md5sum < "$unencrypted"| awk '{ print $1 }')
|
||||
if [[ $old_hash != $new_hash ]]; then
|
||||
echo "========== EXTRACTED $unencrypted"
|
||||
fi
|
||||
}
|
||||
|
||||
# Shred a file. If shred binary does not exist, delete it.
|
||||
function shred_file() {
|
||||
local name
|
||||
local CMD
|
||||
local OPT
|
||||
name="$1"
|
||||
|
||||
if which shred >/dev/null ; then
|
||||
CMD=shred
|
||||
OPT=-u
|
||||
else
|
||||
CMD=rm
|
||||
OPT=-f
|
||||
fi
|
||||
|
||||
$CMD $OPT "$name"
|
||||
}
|
||||
|
||||
# $1 is the name of a file that contains a list of files.
|
||||
# For each filename, output the individual subdirectories
|
||||
# leading up to that file. i.e. one one/two one/two/three
|
||||
function enumerate_subdirs() {
|
||||
local listfile
|
||||
local dir
|
||||
local filename
|
||||
listfile="$1"
|
||||
|
||||
while read filename; do
|
||||
dir=$(dirname "$filename")
|
||||
while [[ $dir != '.' && $dir != '/' ]]; do
|
||||
echo $dir
|
||||
dir=$(dirname $dir)
|
||||
done
|
||||
done <"$listfile" | sort -u
|
||||
}
|
||||
|
||||
# Are we in git, hg, or other repo?
|
||||
function which_vcs() {
|
||||
if [[ -d .git || git rev-parse --git-dir > /dev/null 2>&1 ]]; then
|
||||
echo git
|
||||
elif [[ -d .hg || hg status >/dev/null 2>&1 ]]; then
|
||||
echo hg
|
||||
else
|
||||
echo other
|
||||
fi
|
||||
}
|
||||
|
||||
# Is this file in the current repo?
|
||||
function is_in_vcs() {
|
||||
is_in_$(which_vcs) """$@"""
|
||||
}
|
||||
|
||||
# Is this file in mercurial?
|
||||
function is_in_hg() {
|
||||
local filename
|
||||
filename="$1"
|
||||
|
||||
if hg locate "$filename" ; then
|
||||
echo true
|
||||
else
|
||||
echo false
|
||||
fi
|
||||
}
|
||||
|
||||
# Is this file in git?
|
||||
function is_in_git() {
|
||||
local filename
|
||||
filename="$1"
|
||||
|
||||
if git ls-files --error-unmatch >/dev/null 2>&1 -- "$filename" ; then
|
||||
echo true
|
||||
else
|
||||
echo false
|
||||
fi
|
||||
}
|
||||
25
bin/blackbox_edit_end.sh
Executable file
25
bin/blackbox_edit_end.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# blackbox_edit_end.sh -- Re-encrypt file after edits.
|
||||
#
|
||||
|
||||
source bin/blackbox_common.sh
|
||||
set -e
|
||||
|
||||
fail_if_bad_environment
|
||||
unencrypted_file=$(get_unencrypted_filename "$1")
|
||||
encrypted_file=$(get_encrypted_filename "$1")
|
||||
echo ========== PLAINFILE "$unencrypted_file"
|
||||
echo ========== ENCRYPTED "$encrypted_file"
|
||||
|
||||
fail_if_not_on_cryptlist "$unencrypted_file"
|
||||
fail_if_not_exists "$unencrypted_file" "No unencrypted version to encrypt!"
|
||||
fail_if_keychain_has_secrets
|
||||
|
||||
encrypt_file "$unencrypted_file" "$encrypted_file"
|
||||
shred_file "$unencrypted_file"
|
||||
|
||||
echo "========== UPDATED ${encrypted_file}"
|
||||
echo "Likely next step:"
|
||||
echo " git commit -m\"${encrypted_file} updated\" $encrypted_file"
|
||||
29
bin/blackbox_edit_start.sh
Executable file
29
bin/blackbox_edit_start.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# blackbox_edit_start.sh -- Decrypt a file for editing.
|
||||
#
|
||||
|
||||
source bin/blackbox_common.sh
|
||||
set -e
|
||||
|
||||
fail_if_bad_environment
|
||||
|
||||
for param in """$@""" ; do
|
||||
unencrypted_file=$(get_unencrypted_filename "$param")
|
||||
encrypted_file=$(get_encrypted_filename "$param")
|
||||
echo ========== PLAINFILE "$unencrypted_file"
|
||||
|
||||
fail_if_not_on_cryptlist "$unencrypted_file"
|
||||
fail_if_not_exists "$encrypted_file" "This should not happen."
|
||||
if [[ ! -s "$unencrypted_file" ]]; then
|
||||
rm -f "$unencrypted_file"
|
||||
fi
|
||||
if [[ -f "$unencrypted_file" ]]; then
|
||||
echo SKIPPING: "$1" "Will not overwrite non-empty files."
|
||||
continue
|
||||
fi
|
||||
|
||||
prepare_keychain
|
||||
decrypt_file "$encrypted_file" "$unencrypted_file"
|
||||
done
|
||||
26
bin/blackbox_postdeploy.sh
Executable file
26
bin/blackbox_postdeploy.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# blackbox_postdeploy.sh -- Decrypt all blackbox files.
|
||||
#
|
||||
|
||||
: ${BASEDIR:=/etc/puppet} ;
|
||||
: ${CHGRP:=chgrp} ;
|
||||
|
||||
cd "$BASEDIR"
|
||||
export PATH=/usr/bin:/bin:"$BASEDIR"/bin:"$PATH"
|
||||
|
||||
source blackbox_common.sh
|
||||
set -e
|
||||
|
||||
prepare_keychain
|
||||
|
||||
# Decrypt:
|
||||
echo '========== Decrypting new/changed files: START'
|
||||
while read unencrypted_file; do
|
||||
encrypted_file=$(get_encrypted_filename "$unencrypted_file")
|
||||
decrypt_file_overwrite "$encrypted_file" "$unencrypted_file"
|
||||
chmod g+r,o-rwx "$unencrypted_file"
|
||||
$CHGRP puppet "$unencrypted_file"
|
||||
done <"$BB_FILES"
|
||||
echo '========== Decrypting new/changed files: DONE'
|
||||
53
bin/blackbox_register_new_file.sh
Executable file
53
bin/blackbox_register_new_file.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# blackbox_register_new_file.sh -- Enroll a new file in the blackbox system.
|
||||
#
|
||||
# Takes a previously unencrypted file and enters it into the blackbox
|
||||
# system. It will be kept in HG as an encrypted file. On deployment
|
||||
# to the puppet masters, it will be decrypted. The puppet masters
|
||||
# refer to the unencrypted filename.
|
||||
|
||||
source bin/blackbox_common.sh
|
||||
set -e
|
||||
|
||||
fail_if_bad_environment
|
||||
unencrypted_file=$(get_unencrypted_filename "$1")
|
||||
encrypted_file=$(get_encrypted_filename "$1")
|
||||
|
||||
if [[ $1 == $encrypted_file ]]; then
|
||||
echo ERROR: Please only register unencrypted files.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ========== PLAINFILE "$unencrypted_file"
|
||||
echo ========== ENCRYPTED "$encrypted_file"
|
||||
|
||||
fail_if_not_exists "$unencrypted_file" "Please specify an existing file."
|
||||
fail_if_exists "$encrypted_file" "Will not overwrite."
|
||||
|
||||
prepare_keychain
|
||||
encrypt_file "$unencrypted_file" "$encrypted_file"
|
||||
add_filename_to_cryptlist "$unencrypted_file"
|
||||
|
||||
# TODO(tlim): The code below should be rewritten to check
|
||||
# for HG vs. GIT use and DTRT depending.
|
||||
|
||||
# Is the unencrypted file already in HG? (ie. are we correcting a bad situation)
|
||||
SECRETSEXPOSED=$(is_in_hg ${unencrypted_file})
|
||||
echo "========== CREATED: ${encrypted_file}"
|
||||
echo "========== UPDATING HG:"
|
||||
shred_file "$unencrypted_file"
|
||||
if $SECRETSEXPOSED ; then
|
||||
hg rm -A "$unencrypted_file"
|
||||
hg add "$encrypted_file"
|
||||
COMMIT_FILES="$BB_FILES $encrypted_file $unencrypted_file"
|
||||
else
|
||||
COMMIT_FILES="$BB_FILES $encrypted_file"
|
||||
fi
|
||||
echo 'NOTE: "already tracked!" messages are safe to ignore.'
|
||||
hg add $BB_FILES $encrypted_file
|
||||
hg commit -m"registered in blackbox: ${unencrypted_file}" $COMMIT_FILES
|
||||
echo "========== UPDATING HG: DONE"
|
||||
echo "Local repo updated. Please push when ready."
|
||||
echo " hg push"
|
||||
60
bin/blackbox_update_all_files.sh
Executable file
60
bin/blackbox_update_all_files.sh
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# blackbox_edit_end.sh -- Re-encrypt file after edits.
|
||||
#
|
||||
|
||||
source bin/blackbox_common.sh
|
||||
set -e
|
||||
|
||||
fail_if_bad_environment
|
||||
|
||||
if [[ -z $GPG_AGENT_INFO ]]; then
|
||||
echo 'WARNING: You probably want to run gpg-agent as'
|
||||
echo 'you will be asked for your passphrase many times.'
|
||||
echo 'Example: $ eval $(gpg-agent --daemon)'
|
||||
read -p 'Press CTRL-C now to stop. ENTER to continue: '
|
||||
fi
|
||||
|
||||
disclose_admins
|
||||
|
||||
echo '========== ENCRYPTED FILES TO BE RE-ENCRYPTED:'
|
||||
awk <"$BB_FILES" '{ print " " $1 ".gpg" }'
|
||||
|
||||
echo '========== FILES IN THE WAY:'
|
||||
need_warning=false
|
||||
for i in $(<$BB_FILES) ; do
|
||||
unencrypted_file=$(get_unencrypted_filename "$i")
|
||||
encrypted_file=$(get_encrypted_filename "$i")
|
||||
if [[ -f "$unencrypted_file" ]]; then
|
||||
need_warning=true
|
||||
echo " $unencrypted_file"
|
||||
fi
|
||||
done
|
||||
if $need_warning ; then
|
||||
echo
|
||||
echo 'WARNING: This will overwrite any unencrypted files laying about.'
|
||||
read -p 'Press CTRL-C now to stop. ENTER to continue: '
|
||||
else
|
||||
echo 'All OK.'
|
||||
fi
|
||||
|
||||
echo '========== RE-ENCRYPTING FILES:'
|
||||
for i in $(<$BB_FILES) ; do
|
||||
unencrypted_file=$(get_unencrypted_filename "$i")
|
||||
encrypted_file=$(get_encrypted_filename "$i")
|
||||
echo ========== PROCESSING "$unencrypted_file"
|
||||
fail_if_not_on_cryptlist "$unencrypted_file"
|
||||
decrypt_file_overwrite "$encrypted_file" "$unencrypted_file"
|
||||
encrypt_file "$unencrypted_file" "$encrypted_file"
|
||||
shred_file "$unencrypted_file"
|
||||
done
|
||||
|
||||
fail_if_keychain_has_secrets
|
||||
|
||||
echo '========== COMMITING TO HG:'
|
||||
hg commit -m'Re-encrypted keys' $(awk <$BB_FILES '{ print $1 ".gpg" }' )
|
||||
|
||||
echo '========== DONE.'
|
||||
echo 'Likely next step:'
|
||||
echo ' hg push'
|
||||
21
bin/start
Executable file
21
bin/start
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# blackbox_edit_start.sh -- Decrypt a file for editing.
|
||||
#
|
||||
|
||||
source bin/blackbox_common.sh
|
||||
|
||||
fail_if_bad_environment
|
||||
|
||||
for param in """$@""" ; do
|
||||
unencrypted_file=$(get_unencrypted_filename "$param")
|
||||
encrypted_file=$(get_encrypted_filename "$param")
|
||||
|
||||
fail_if_not_on_cryptlist "$unencrypted_file"
|
||||
fail_if_not_exists "$encrypted_file" "This should not happen."
|
||||
rm -f "$unencrypted_file"
|
||||
|
||||
prepare_keychain
|
||||
decrypt_file "$encrypted_file" "$unencrypted_file"
|
||||
done
|
||||
Reference in New Issue
Block a user