From 01e681035dc3cb874215e6cff947246f644f200c Mon Sep 17 00:00:00 2001 From: Tyler Akins Date: Fri, 12 Jun 2015 13:23:45 -0500 Subject: [PATCH] Adding file deregister tool + extrapolating code This solves some TODOs by moving shared code out into `_blackbox_common.sh`. New VCS commands were added, `vcs_ignore` and `vcs_notice` (the opposite of ignore). Made some utility functions * `remove_filename_from_cryptlist` - The opposite of `add_file_to_cryptlist` * `remove_line` - Removes a single line from a text file --- README.md | 8 +-- bin/_blackbox_common.sh | 114 +++++++++++++++++++++++++++++++++ bin/blackbox_deregister_file | 36 +++++++++++ bin/blackbox_initialize | 23 +------ bin/blackbox_register_new_file | 19 +----- 5 files changed, 157 insertions(+), 43 deletions(-) create mode 100755 bin/blackbox_deregister_file diff --git a/README.md b/README.md index 72f4cb4..84d53bb 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ Commands: | `blackbox_diff` | Diff decrypted files against their original crypted version | | `blackbox_initialize` | Enable blackbox for a GIT or HG repo | | `blackbox_register_new_file` | Encrypt a file for the first time | +| blackbox_deregister_file | Remove a file from blackbox | | `blackbox_list_files` | List the files maintained by blackbox | | `blackbox_decrypt_all_files` | Decrypt all managed files (INTERACTIVE) | | `blackbox_postdeploy` | Decrypt all managed files (batch) | @@ -290,10 +291,9 @@ How to remove a file from the system? ============================ This is a manual process. It happens quite rarely. - -1. Remove the file ``keyrings/live/blackbox-files.txt`` -2. Remove references from ``.gitignore`` or ``.hgignore`` -3. Use ``git rm`` or ``hg rm`` as expected. +``` +blackbox_deregister_file path/to/file.name.key +``` How to indoctrinate a new user into the system? ============================ diff --git a/bin/_blackbox_common.sh b/bin/_blackbox_common.sh index 275ef59..3f8e65e 100755 --- a/bin/_blackbox_common.sh +++ b/bin/_blackbox_common.sh @@ -164,6 +164,19 @@ function add_filename_to_cryptlist() { fi } +# Removes a file from the list of encrypted files +function remove_filename_from_cryptlist() { + # If the name is not already on the list, this is a no-op. + local name=$(vcs_relative_path "$1") + + if ! grep -s -q "$name" "$BB_FILES" ; then + echo ========== File is not registered. No need to remove from list. + else + echo ========== Removing file from list. + remove_line "$BB_FILES" "$name" + fi +} + # Print out who the current BB ADMINS are: function disclose_admins() { echo ========== blackbox administrators are: @@ -281,6 +294,21 @@ function vcs_relative_path() { python -c 'import os ; print(os.path.relpath("'"$(pwd -P)"'/'"$name"'", "'"$REPOBASE"'"))' } +# Removes a line from a text file +function remove_line() { + local tempfile + + tempfile="${1}.blackbox-temp.${RANDOM}.$$" + + # Ensure source file exists + touch "$1" + grep -Fsxv "$2" "$1" > "$tempfile" || true + + # Using cat+rm instead of cp will preserve permissions/ownership + cat "$tempfile" > "$1" + rm "$tempfile" +} + # # Portability Section: # @@ -452,3 +480,89 @@ function vcs_remove_p4() { function vcs_remove_unknown() { : } + + +# Ignore a file in a repo. If it was already ignored, this is a no-op. +function vcs_ignore() { + local file + for file in "$@"; do + vcs_ignore_$(which_vcs) "$file" + done +} +# Mercurial +function vcs_ignore_hg() { + vcs_ignore_generic_file "$REPOBASE/.hgignore" "$file" +} +# Git +function vcs_ignore_git() { + vcs_ignore_generic_file "$REPOBASE/.gitignore" "$file" +} +# Subversion +function vcs_ignore_svn() { + svn propset svn:ignore "$(vcs_relative_path "$file")" +} +# Perforce +function vcs_ignore_p4() { + : +} +# No repo +function vcs_ignore_unknown() { + : +} +# Generic - add line to file +function vcs_ignore_generic_file() { + local file + file="$(vcs_relative_path "$2")" + file="${file/\$\//}" + file="$(echo "/$file" | sed 's/\([\*\?]\)/\\\1/g')" + if ! grep -Fsx "$file" "$1" > /dev/null; then + echo "$file" >> "$1" + vcs_add "$1" + fi +} + + +# Notice (un-ignore) a file in a repo. If it was not ignored, this is +# a no-op +function vcs_notice() { + local file + for file in "$@"; do + vcs_notice_$(which_vcs) "$file" + done +} +# Mercurial +function vcs_notice_hg() { + vcs_notice_generic_file "$REPOBASE/.hgignore" "$file" +} +# Git +function vcs_notice_git() { + vcs_notice_generic_file "$REPOBASE/.gitignore" "$file" +} +# Subversion +function vcs_notice_svn() { + svn propdel svn:ignore "$(vcs_relative_path "$file")" +} +# Perforce +function vcs_notice_p4() { + : +} +# No repo +function vcs_notice_unknown() { + : +} +# Generic - remove line to file +function vcs_notice_generic_file() { + local file + file="$(vcs_relative_path "$2")" + file="${file/\$\//}" + file="$(echo "/$file" | sed 's/\([\*\?]\)/\\\1/g')" + if grep -Fsx "$file" "$1" > /dev/null; then + remove_line "$1" "$file" + vcs_add "$1" + fi + if grep -Fsx "${file:1}" "$1" > /dev/null; then + echo "WARNING: Found a non-absolute ignore match in $1" + echo "WARNING: Confirm the pattern is intended to only exclude $file" + echo "WARNING: If so, manually update the ignore file" + fi +} diff --git a/bin/blackbox_deregister_file b/bin/blackbox_deregister_file new file mode 100755 index 0000000..b5756bd --- /dev/null +++ b/bin/blackbox_deregister_file @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +# +# blackbox_deregister_file -- Remove a file from the blackbox system. +# +# Takes an encrypted file and removes it from the blackbox system. The +# encrypted file will also be removed from the filesystem. + +set -e +blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +source "${blackbox_home}/_blackbox_common.sh" +_determine_vcs_base_and_type + +unencrypted_file=$(get_unencrypted_filename "$1") +encrypted_file=$(get_encrypted_filename "$1") + +if [[ "$1" == "$unencrypted_file" ]]; then + echo ERROR: Please only deregister encrypted files. + exit 1 +fi + +echo ========== PLAINFILE "$unencrypted_file" +echo ========== ENCRYPTED "$encrypted_file" + +fail_if_not_exists "$encrypted_file" "Please specify an existing file." + +prepare_keychain +remove_filename_from_cryptlist "$unencrypted_file" +vcs_notice "$unencrypted_file" +git rm "$encrypted_file" +vcs_remove "$BB_FILES" + +vcs_commit "Removing from blackbox: ${unencrypted_file}" +echo "========== UPDATING VCS: DONE" +echo "Local repo updated. Please push when ready." +echo " $(which_vcs) push" diff --git a/bin/blackbox_initialize b/bin/blackbox_initialize index 2c55956..e85e8d9 100755 --- a/bin/blackbox_initialize +++ b/bin/blackbox_initialize @@ -25,28 +25,7 @@ fi change_to_vcs_root echo VCS_TYPE: $VCS_TYPE - -if [[ $VCS_TYPE = "git" || $VCS_TYPE = "hg" ]]; then - # Update .gitignore or .hgignore - - IGNOREFILE="${REPOBASE}/.${VCS_TYPE}ignore" - if ! grep -sx >/dev/null 'pubring.gpg~' "$IGNOREFILE" ; then - echo 'pubring.gpg~' >>"$IGNOREFILE" - fi - if ! grep -sx >/dev/null 'pubring.kbx~' "$IGNOREFILE" ; then - echo 'pubring.kbx~' >>"$IGNOREFILE" - fi - if ! grep -sx >/dev/null 'secring.gpg' "$IGNOREFILE" ; then - echo 'secring.gpg' >>"$IGNOREFILE" - fi -elif [[ $VCS_TYPE = "svn" ]]; then - # add file to svn ignore propset - IGNOREFILE=""; - svn propset svn:ignore 'pubring.gpg~ -pubring.kbx~ -secring.gpg' . - svn commit -m "ignore file list" -fi +vcs_ignore keyrings/live/pubring.gpg~ keyrings/live/pubring.kbx~ keyrings/live/secring.gpg # Make directories mkdir -p "${KEYRINGDIR}" diff --git a/bin/blackbox_register_new_file b/bin/blackbox_register_new_file index 19ad7cc..4a7120d 100755 --- a/bin/blackbox_register_new_file +++ b/bin/blackbox_register_new_file @@ -11,7 +11,6 @@ set -e blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) source "${blackbox_home}/_blackbox_common.sh" -_determine_vcs_base_and_type unencrypted_file=$(get_unencrypted_filename "$1") encrypted_file=$(get_encrypted_filename "$1") @@ -37,7 +36,6 @@ echo "========== CREATED: ${encrypted_file}" echo "========== UPDATING REPO:" shred_file "$unencrypted_file" -VCSCMD=$(which_vcs) if "$SECRETSEXPOSED" ; then vcs_remove "$unencrypted_file" vcs_add "$encrypted_file" @@ -46,23 +44,10 @@ else COMMIT_FILES=("$BB_FILES" "$encrypted_file") fi -# TODO(tlim): This should be moved to _blackbox_common.sh in a -# VCS-independent way. -IGNOREFILE="${REPOBASE}/.${VCS_TYPE}ignore" -if [[ $VCS_TYPE = 'git' ]]; then - relfile="$(vcs_relative_path "$unencrypted_file")" - relfileb="${relfile/\$\//}" - ignored_file="$(echo "${relfileb}" | sed 's/\([\*\?]\)/\\\1/g' | sed 's/^\([!#]\)/\\\1/')" - if ! grep -Fsx >/dev/null "$ignored_file" "$IGNOREFILE"; then - echo "$ignored_file" >>"$IGNOREFILE" - COMMIT_FILES+=("$IGNOREFILE") - fi - vcs_add "$IGNOREFILE" -fi - +vcs_ignore "$unencrypted_file" echo 'NOTE: "already tracked!" messages are safe to ignore.' vcs_add "$BB_FILES" "$encrypted_file" vcs_commit "registered in blackbox: ${unencrypted_file}" "${COMMIT_FILES[@]}" echo "========== UPDATING VCS: DONE" echo "Local repo updated. Please push when ready." -echo " $VCSCMD push" +echo " $(which_vcs) push"