* Initialization for new repos AUTOMATED.
* Adding new users AUTOMATED. * Update docs for the new, more simplified installation processes. * Remove dependency on any particular paths, etc. Copy "bin" into a place along your path and everything should "just work". * Add support for Mercurial (not tested). * blackbox_addadmin now adds keys to the keyring for you. * Unified #! lines to "#!/usr/bin/env bash" so it works better on FreeBSD. * BUGFIX: (BugId#1) blackbox_update_all_files.sh expects hg, fails for git. * BUGFIX: (BugId#2) blackbox_postdeploy.sh assumes certain directory layout. * BUGFIX: Temporary files aren't deleted. * NEW FILE: bin/blackbox_initialize: Automates enabling BB for a repo (creates directories, files, and updates .gitignore). * NEW FILE: bin/blackbox_removeadmin: Automates removing an admit. * NEW FILE: tools/confidence_test.sh: A battery of tests to verify operations. * NEW FILE: bin/Makefile: Automate package creation. * NEW FILE: bin/_stack_lib.sh: A library of shell routines from StackExchange.
This commit is contained in:
5
Makefile
5
Makefile
@@ -33,3 +33,8 @@ lock:
|
|||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
sudo yum versionlock clear
|
sudo yum versionlock clear
|
||||||
|
|
||||||
|
test:
|
||||||
|
echo "You don't want to run this."
|
||||||
|
exit 1
|
||||||
|
pkill gpg-agent ; rm -rf /tmp/tmp.* ; export PATH=/home/tlimoncelli/gitwork/blackbox/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin ; cd ~/gitwork/blackbox;tools/confidence_test.sh;ls -lad /home/tlimoncelli/.gnupg || true
|
||||||
|
|||||||
51
README.md
51
README.md
@@ -50,7 +50,6 @@ What does this look like to the typical sysadmin?
|
|||||||
|
|
||||||
``bin/blackbox_edit_end FILENAME``
|
``bin/blackbox_edit_end FILENAME``
|
||||||
|
|
||||||
|
|
||||||
* Commit the changes.
|
* Commit the changes.
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -123,74 +122,56 @@ To join the list of people that can edit the file requires three steps; You crea
|
|||||||
|
|
||||||
### Step 1: YOU create a GPG key pair on a secure machine and add to public keychain.
|
### Step 1: YOU create a GPG key pair on a secure machine and add to public keychain.
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
KEYNAME=$USER@$DOMAINNAME
|
|
||||||
# For example...
|
|
||||||
KEYNAME=myusername@example.com
|
|
||||||
gpg --gen-key
|
gpg --gen-key
|
||||||
```
|
```
|
||||||
|
|
||||||
Pick defaults for encryption settings, 0 expiration. Pick a VERY GOOD passphrase.
|
Pick defaults for encryption settings, 0 expiration. Pick a VERY GOOD passphrase.
|
||||||
|
|
||||||
When GPG is generating entropy, consider running this on the machine in another window:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
dd if=/dev/sda of=/dev/null
|
blackbox_addadmin KEYNAME
|
||||||
|
```
|
||||||
|
...where "KEYNAME" is the email address listed in the gpg key you created previously. For example:
|
||||||
|
```
|
||||||
|
blackbox_addadmin tal@example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
Add your public key to the public key-ring.
|
When the command completes successfully, instructions on how to
|
||||||
|
commit these changes will be output. Run the command as give.
|
||||||
```
|
```
|
||||||
gpg --export -a $KEYNAME >~/.gnupg/pubkey.txt
|
NEXT STEP: Check these into the repo. Probably with a command like...
|
||||||
wc -l ~/.gnupg/pubkey.txt
|
git commit -m'NEW ADMIN: tal@example.com' keyrings/live/pubring.gpg keyrings/live/trustdb.gpg keyrings/live/blackbox-admins.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
The output of "wc" should be non-zero (usually it is 30 or more)
|
Role accounts: If you are adding the pubring.gpg of a role account, you can specify the directory where the pubring.gpg file can be found as a 2nd parameter:
|
||||||
|
|
||||||
Add your keyname to the list of keys:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
cd keyrings/live
|
blackbox_addadmin puppetmaster@puppet-master-1.example.com /path/to/the/dir
|
||||||
gpg --homedir=. --import ~/.gnupg/pubkey.txt
|
|
||||||
cd ../..
|
|
||||||
blackbox_addadmin $KEYNAME
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Check all these updates into the VCS:
|
|
||||||
|
|
||||||
```
|
|
||||||
git add pubring.gpg trustdb.gpg blackbox-admins.txt
|
|
||||||
git commit -m"Adding my gpg key" pubring.gpg trustdb.gpg blackbox-admins.txt
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
hg commit -m"Adding my gpg key" pubring.gpg trustdb.gpg blackbox-admins.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### Step 2: SOMEONE ELSE adds you to the system.
|
### Step 2: SOMEONE ELSE adds you to the system.
|
||||||
|
|
||||||
Ask someone that already has access to re-encrypt the data files. This gives you access. They simply decrypt and re-encrypt the data without making any changes:
|
Ask someone that already has access to re-encrypt the data files. This gives you access. They simply decrypt and re-encrypt the data without making any changes:
|
||||||
|
|
||||||
```
|
```
|
||||||
gpg --import keyrings/live/pubring.gpg
|
gpg --import keyrings/live/pubring.gpg
|
||||||
bin/blackbox_update_all_files
|
blackbox_update_all_files
|
||||||
```
|
```
|
||||||
|
|
||||||
Push the re-encrypted files:
|
Push the re-encrypted files:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
git commit -a
|
||||||
git push
|
git push
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
|
hg commit
|
||||||
hg push
|
hg push
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: YOU test.
|
### Step 3: YOU test.
|
||||||
|
|
||||||
Make sure you can decrypt a file. (NOTE: It is a good idea to keep a dummy file in VCS just for new people to practice on.)
|
Make sure you can decrypt a file. (Suggestion: Keep a dummy file in VCS just for new people to practice on.)
|
||||||
|
|
||||||
First Time Setup
|
First Time Setup
|
||||||
===========================
|
===========================
|
||||||
@@ -200,7 +181,7 @@ Overview:
|
|||||||
To add "blackbox" to a git repo, you'll need to do the following:
|
To add "blackbox" to a git repo, you'll need to do the following:
|
||||||
|
|
||||||
1. Create some directories
|
1. Create some directories
|
||||||
2. For each user, have them createa GPG key and add it to the key ring.
|
2. For each user, have them create a GPG key and add it to the key ring.
|
||||||
3. For any automated user (one that must be able to decrypt without a passphrase), create a GPG key and create a subkey with an empty passphrase.
|
3. For any automated user (one that must be able to decrypt without a passphrase), create a GPG key and create a subkey with an empty passphrase.
|
||||||
4. Add
|
4. Add
|
||||||
|
|
||||||
|
|||||||
5
bin/Makefile
Normal file
5
bin/Makefile
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
all: _stack_lib.sh
|
||||||
|
|
||||||
|
# Snatch _stack_lib.sh from another StackExchange project.
|
||||||
|
_stack_lib.sh: ../../scripts/misc/_stack_lib.sh
|
||||||
|
cp ../../scripts/misc/_stack_lib.sh $@
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
: ${BLACKBOXDATA:=keyrings/live} ; # If BLACKBOXDATA not set, set it.
|
: ${BLACKBOXDATA:=keyrings/live} ; # If BLACKBOXDATA not set, set it.
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Outputs a string that is the base directory of this VCS repo.
|
# Outputs a string that is the base directory of this VCS repo.
|
||||||
# By side-effect, sets the variable VCS_TYPE to either 'git', 'hg',
|
# By side-effect, sets the variable VCS_TYPE to either 'git', 'hg',
|
||||||
# or 'unknown'.
|
# or 'unknown'.
|
||||||
@@ -28,8 +28,10 @@ function _determine_vcs_base_and_type() {
|
|||||||
|
|
||||||
REPOBASE=$(_determine_vcs_base_and_type)
|
REPOBASE=$(_determine_vcs_base_and_type)
|
||||||
KEYRINGDIR="$REPOBASE/$BLACKBOXDATA"
|
KEYRINGDIR="$REPOBASE/$BLACKBOXDATA"
|
||||||
BB_ADMINS="${KEYRINGDIR}/blackbox-admins.txt"
|
BB_ADMINS_FILE="blackbox-admins.txt"
|
||||||
BB_FILES="${KEYRINGDIR}/blackbox-files.txt"
|
BB_ADMINS="${KEYRINGDIR}/${BB_ADMINS_FILE}"
|
||||||
|
BB_FILES_FILE="blackbox-files.txt"
|
||||||
|
BB_FILES="${KEYRINGDIR}/${BB_FILES_FILE}"
|
||||||
SECRING="${KEYRINGDIR}/secring.gpg"
|
SECRING="${KEYRINGDIR}/secring.gpg"
|
||||||
PUBRING="${KEYRINGDIR}/pubring.gpg"
|
PUBRING="${KEYRINGDIR}/pubring.gpg"
|
||||||
|
|
||||||
@@ -51,6 +53,16 @@ function fail_if_not_exists() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Exit we we aren't in a VCS repo.
|
||||||
|
function fail_if_not_in_repo() {
|
||||||
|
_determine_vcs_base_and_type
|
||||||
|
if [[ $VCS_TYPE = "unknown" ]]; then
|
||||||
|
echo "ERROR: This must be run in a VCS repo such as git or hg."
|
||||||
|
echo Exiting...
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Exit with error if filename is not registered on blackbox list.
|
# Exit with error if filename is not registered on blackbox list.
|
||||||
function fail_if_not_on_cryptlist() {
|
function fail_if_not_on_cryptlist() {
|
||||||
if ! grep -s -q "$name" "$BB_FILES" ; then
|
if ! grep -s -q "$name" "$BB_FILES" ; then
|
||||||
@@ -191,15 +203,18 @@ function enumerate_subdirs() {
|
|||||||
|
|
||||||
# Are we in git, hg, or unknown repo?
|
# Are we in git, hg, or unknown repo?
|
||||||
function which_vcs() {
|
function which_vcs() {
|
||||||
echo "$REPO_TYPE"
|
if [[ $VCS_TYPE = '' ]]; then
|
||||||
|
_determine_vcs_base_and_type >/dev/null
|
||||||
|
fi
|
||||||
|
echo "$VCS_TYPE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Is this file in the current repo?
|
# Is this file in the current repo?
|
||||||
function is_in_vcs() {
|
function is_in_vcs() {
|
||||||
is_in_$(which_vcs) """$@"""
|
is_in_$(which_vcs) """$@"""
|
||||||
}
|
}
|
||||||
|
# Mercurial
|
||||||
# Is this file in mercurial?
|
|
||||||
function is_in_hg() {
|
function is_in_hg() {
|
||||||
local filename
|
local filename
|
||||||
filename="$1"
|
filename="$1"
|
||||||
@@ -210,8 +225,7 @@ function is_in_hg() {
|
|||||||
echo false
|
echo false
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
# Git:
|
||||||
# Is this file in git?
|
|
||||||
function is_in_git() {
|
function is_in_git() {
|
||||||
local filename
|
local filename
|
||||||
filename="$1"
|
filename="$1"
|
||||||
@@ -223,18 +237,46 @@ function is_in_git() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Add a file to the repo (but don't commit it).
|
||||||
|
function vcs_add() {
|
||||||
|
vcs_add_$(which_vcs) """$@"""
|
||||||
|
}
|
||||||
|
# Mercurial
|
||||||
|
function vcs_add_hg() {
|
||||||
|
hg add """$@"""
|
||||||
|
}
|
||||||
|
# Git
|
||||||
|
function vcs_add_git() {
|
||||||
|
git add """$@"""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Commit a file to the repo
|
||||||
|
function vcs_commit() {
|
||||||
|
vcs_commit_$(which_vcs) """$@"""
|
||||||
|
}
|
||||||
|
# Mercurial
|
||||||
|
function vcs_commit_hg() {
|
||||||
|
hg commit -m"""$@"""
|
||||||
|
}
|
||||||
|
# Git
|
||||||
|
function vcs_commit_git() {
|
||||||
|
git commit -m"""$@"""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# TODO(tlim): Rename these vcs_rm_file* to be in sync with the others.
|
||||||
|
|
||||||
# Remove file from repo, even if it was deleted locally already.
|
# Remove file from repo, even if it was deleted locally already.
|
||||||
# If it doesn't exist yet in the repo, it should be a no-op.
|
# If it doesn't exist yet in the repo, it should be a no-op.
|
||||||
function rm_from_vcs() {
|
function vcs_remove() {
|
||||||
rm_from_$(which_vcs) """$@"""
|
vcs_remove$(which_vcs) """$@"""
|
||||||
}
|
}
|
||||||
|
# Mercurial
|
||||||
# rm from mercurial.
|
function vcs_remove_hg() {
|
||||||
function rm_from_hg() {
|
|
||||||
hg rm -A """$@"""
|
hg rm -A """$@"""
|
||||||
}
|
}
|
||||||
|
# Git
|
||||||
# rm from git.
|
function vcs_remove_git() {
|
||||||
function rm_from_git() {
|
|
||||||
git rm --ignore-unmatch -f -- """$@"""
|
git rm --ignore-unmatch -f -- """$@"""
|
||||||
}
|
}
|
||||||
|
|||||||
140
bin/_stack_lib.sh
Executable file
140
bin/_stack_lib.sh
Executable file
@@ -0,0 +1,140 @@
|
|||||||
|
# Library functions for bash scripts at Stack Exchange.
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# . _stack_lib.sh
|
||||||
|
|
||||||
|
# ----- Utility Functions -----
|
||||||
|
|
||||||
|
function debugmsg() {
|
||||||
|
# Log to stderr.
|
||||||
|
echo 1>&2 LOG: """$@"""
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
function logit() {
|
||||||
|
# Log to stderr.
|
||||||
|
echo 1>&2 LOG: """$@"""
|
||||||
|
}
|
||||||
|
|
||||||
|
function fail_out() {
|
||||||
|
echo "FAILED:" "$*"
|
||||||
|
echo 'Exiting...'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# on_exit and add_on_exit from http://www.linuxjournal.com/content/use-bash-trap-statement-cleanup-temporary-files
|
||||||
|
# Usage:
|
||||||
|
# add_on_exit rm -f /tmp/foo
|
||||||
|
# add_on_exit echo "I am exiting"
|
||||||
|
# tempfile=$(mktemp)
|
||||||
|
# add_on_exit rm -f "$tempfile"
|
||||||
|
function on_exit()
|
||||||
|
{
|
||||||
|
for i in "${on_exit_items[@]}"
|
||||||
|
do
|
||||||
|
eval $i
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_on_exit()
|
||||||
|
{
|
||||||
|
local n=${#on_exit_items[*]}
|
||||||
|
on_exit_items[$n]="$*"
|
||||||
|
if [[ $n -eq 0 ]]; then
|
||||||
|
trap on_exit EXIT
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Securely and portably create a temporary file that will be deleted
|
||||||
|
# on EXIT. $1 is the variable name to store the result.
|
||||||
|
function make_self_deleting_tempfile() {
|
||||||
|
local __resultvar="$1"
|
||||||
|
local name
|
||||||
|
|
||||||
|
case $(uname -s) in
|
||||||
|
Darwin )
|
||||||
|
: ${TMPDIR:=/tmp} ;
|
||||||
|
name=$(mktemp -t _stacklib_ )
|
||||||
|
;;
|
||||||
|
Linux )
|
||||||
|
name=$(mktemp)
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo 'ERROR: Unknown OS. Exiting.'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
add_on_exit rm -f "$name"
|
||||||
|
eval $__resultvar="$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_tempdir() {
|
||||||
|
local __resultvar="$1"
|
||||||
|
local name
|
||||||
|
|
||||||
|
case $(uname -s) in
|
||||||
|
Darwin )
|
||||||
|
: ${TMPDIR:=/tmp} ;
|
||||||
|
name=$(mktemp -d -t _stacklib_ )
|
||||||
|
;;
|
||||||
|
Linux )
|
||||||
|
name=$(mktemp -d)
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo 'ERROR: Unknown OS. Exiting.'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
eval $__resultvar="$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_self_deleting_tempdir() {
|
||||||
|
local __resultvar="$1"
|
||||||
|
local dirname
|
||||||
|
|
||||||
|
make_tempdir dirname
|
||||||
|
|
||||||
|
add_on_exit rm -rf "$dirname"
|
||||||
|
eval $__resultvar="$dirname"
|
||||||
|
}
|
||||||
|
|
||||||
|
function fail_if_not_running_as_root() {
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo 'ERROR: This command should only be run as root.'
|
||||||
|
echo 'Exiting...'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function fail_if_in_root_directory() {
|
||||||
|
# Verify nobody has tricked us into being in "/".
|
||||||
|
case $(uname -s) in
|
||||||
|
Darwin )
|
||||||
|
if [[ $(stat -f'%i' / ) == $(stat -f'%i' . ) ]] ; then
|
||||||
|
echo 'SECURITY ALERT: The current directory is the root directory.'
|
||||||
|
echo 'Exiting...'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
Linux )
|
||||||
|
if [[ $(stat -c'%i' / ) == $(stat -c'%i' . ) ]] ; then
|
||||||
|
echo 'SECURITY ALERT: The current directory is the root directory.'
|
||||||
|
echo 'Exiting...'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
CYGWIN* )
|
||||||
|
if [[ $(stat -c'%i' / ) == $(stat -c'%i' . ) ]] ; then
|
||||||
|
echo 'SECURITY ALERT: The current directory is the root directory.'
|
||||||
|
echo 'Exiting...'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo 'ERROR: Unknown OS. Exiting.'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
@@ -3,15 +3,51 @@
|
|||||||
#
|
#
|
||||||
# blackbox_addadmin -- Add an admin to the system
|
# blackbox_addadmin -- Add an admin to the system
|
||||||
#
|
#
|
||||||
#
|
|
||||||
# Example:
|
# Example:
|
||||||
# blackbox_addadmin tal@example.com
|
# blackbox_addadmin tal@example.com
|
||||||
#
|
#
|
||||||
|
|
||||||
. _blackbox_common.sh
|
. _blackbox_common.sh
|
||||||
|
. _stack_lib.sh
|
||||||
|
|
||||||
|
fail_if_not_in_repo
|
||||||
|
|
||||||
|
KEYNAME="$1"
|
||||||
|
: ${KEYNAME:?ERROR: First argument must be a keyname (email address)} ;
|
||||||
|
|
||||||
|
# The second argument, if present, is the directory to find the GPG keys to be imported.
|
||||||
|
if [[ "$2" == "" ]]; then
|
||||||
|
GPGEXPORTOPTIONS=""
|
||||||
|
else
|
||||||
|
GPGEXPORTOPTIONS=--homedir="${2}"
|
||||||
|
fi
|
||||||
|
# TODO(tlim): This could probably be done with GNUPGHOME
|
||||||
|
# but that affects all commands; we just want it to affect the key export.
|
||||||
|
|
||||||
|
|
||||||
# Add the email address to the BB_ADMINS file. Remove any duplicates.
|
# Add the email address to the BB_ADMINS file. Remove any duplicates.
|
||||||
|
|
||||||
# The file must exist for sort to act as we expect.
|
# The file must exist for sort to act as we expect.
|
||||||
touch "$BB_ADMINS"
|
touch "$BB_ADMINS"
|
||||||
sort -fdu -o "$BB_ADMINS" <(echo "$1") "$BB_ADMINS"
|
sort -fdu -o "$BB_ADMINS" <(echo "$1") "$BB_ADMINS"
|
||||||
|
|
||||||
|
|
||||||
|
# Add the user's key to the keychain.
|
||||||
|
|
||||||
|
# Extract it:
|
||||||
|
make_self_deleting_tempfile pubkeyfile
|
||||||
|
gpg $GPGEXPORTOPTIONS --export -a "$KEYNAME" >"$pubkeyfile"
|
||||||
|
if [[ $(wc -l < "$pubkeyfile") = 0 ]]; then
|
||||||
|
fail_out "GPG key '$KEYNAME' not found. Please create it with: gpg --gen-key"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Import it:
|
||||||
|
gpg --no-permission-warning --homedir="$KEYRINGDIR" --import "$pubkeyfile"
|
||||||
|
vcs_add "$KEYRINGDIR/pubring.gpg" "$KEYRINGDIR/trustdb.gpg" "$BB_ADMINS"
|
||||||
|
|
||||||
|
# Make a suggestion:
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo 'NEXT STEP: You need to manually check these in:'
|
||||||
|
echo ' ' $VCS_TYPE commit -m\'NEW ADMIN: $KEYNAME\' "$BLACKBOXDATA/pubring.gpg" "$BLACKBOXDATA/trustdb.gpg" "$BLACKBOXDATA/$BB_ADMINS_FILE"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# blackbox_edit_start.sh -- Decrypt a file for editing.
|
# blackbox_edit_start.sh -- Decrypt a file for editing.
|
||||||
|
|||||||
46
bin/blackbox_initialize
Executable file
46
bin/blackbox_initialize
Executable file
@@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# blackbox_initialize -- Enable blackbox for a GIT or HG repo.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# blackbox_initialize
|
||||||
|
#
|
||||||
|
|
||||||
|
. _blackbox_common.sh
|
||||||
|
|
||||||
|
_determine_vcs_base_and_type # Sets VCS_TYPE
|
||||||
|
|
||||||
|
if [[ $1 != 'yes' ]]; then
|
||||||
|
read -p "Enable blackbox for this $VCS_TYPE repo? (yes/no) " ans
|
||||||
|
if [[ $ans = 'no' || $ans = 'n' || $ans = '' ]]; then
|
||||||
|
echo 'Exiting...'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo cd "$REPOBASE"
|
||||||
|
cd "$REPOBASE"
|
||||||
|
|
||||||
|
# Update .gitignore or .hgignore
|
||||||
|
|
||||||
|
IGNOREFILE=".${VCS_TYPE}ignore"
|
||||||
|
if ! grep -sx >/dev/null 'pubring.gpg~' "$IGNOREFILE" ; then
|
||||||
|
echo 'pubring.gpg~' >>"$IGNOREFILE"
|
||||||
|
fi
|
||||||
|
if ! grep -sx >/dev/null 'secring.gpg' "$IGNOREFILE" ; then
|
||||||
|
echo 'secring.gpg' >>"$IGNOREFILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make directories
|
||||||
|
mkdir -p "${KEYRINGDIR}"
|
||||||
|
vcs_add "${KEYRINGDIR}"
|
||||||
|
touch "$BLACKBOXDATA/$BB_ADMINS_FILE" "$BLACKBOXDATA/$BB_FILES_FILE"
|
||||||
|
vcs_add "$IGNOREFILE" "$BLACKBOXDATA/$BB_ADMINS_FILE" "$BLACKBOXDATA/$BB_FILES_FILE"
|
||||||
|
|
||||||
|
# Make a suggestion:
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo 'NEXT STEP: You need to manually check these in:'
|
||||||
|
echo ' ' $VCS_TYPE commit -m\'INITIALIZE BLACKBOX\' keyrings "$IGNOREFILE"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# blackbox_postdeploy.sh -- Decrypt all blackbox files.
|
# blackbox_postdeploy.sh -- Decrypt all blackbox files.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# blackbox_register_new_file.sh -- Enroll a new file in the blackbox system.
|
# blackbox_register_new_file.sh -- Enroll a new file in the blackbox system.
|
||||||
@@ -8,6 +8,8 @@
|
|||||||
# to systems that need the plaintext (unencrypted) versions, run
|
# to systems that need the plaintext (unencrypted) versions, run
|
||||||
# blackbox_postdeploy.sh to decrypt all the files.
|
# blackbox_postdeploy.sh to decrypt all the files.
|
||||||
|
|
||||||
|
# TODO(tlim): Add the unencrypted file to .gitignore
|
||||||
|
|
||||||
. _blackbox_common.sh
|
. _blackbox_common.sh
|
||||||
|
|
||||||
unencrypted_file=$(get_unencrypted_filename "$1")
|
unencrypted_file=$(get_unencrypted_filename "$1")
|
||||||
@@ -36,17 +38,15 @@ shred_file "$unencrypted_file"
|
|||||||
|
|
||||||
VCSCMD=$(which_vcs)
|
VCSCMD=$(which_vcs)
|
||||||
if $SECRETSEXPOSED ; then
|
if $SECRETSEXPOSED ; then
|
||||||
rm_from_vcs "$unencrypted_file"
|
vcs_remove "$unencrypted_file"
|
||||||
$VCSCMD add "$encrypted_file"
|
vcs_add "$encrypted_file"
|
||||||
# NOTE(tlim): Because we use $VCSCMD as a command, we can only use commands
|
|
||||||
# that work for both git and hg.
|
|
||||||
COMMIT_FILES="$BB_FILES $encrypted_file $unencrypted_file"
|
COMMIT_FILES="$BB_FILES $encrypted_file $unencrypted_file"
|
||||||
else
|
else
|
||||||
COMMIT_FILES="$BB_FILES $encrypted_file"
|
COMMIT_FILES="$BB_FILES $encrypted_file"
|
||||||
fi
|
fi
|
||||||
echo 'NOTE: "already tracked!" messages are safe to ignore.'
|
echo 'NOTE: "already tracked!" messages are safe to ignore.'
|
||||||
$VCSCMD add $BB_FILES $encrypted_file
|
vcs_add $BB_FILES $encrypted_file
|
||||||
$VCSCMD commit -m"registered in blackbox: ${unencrypted_file}" $COMMIT_FILES
|
vcs_commit "registered in blackbox: ${unencrypted_file}" $COMMIT_FILES
|
||||||
echo "========== UPDATING VCS: DONE"
|
echo "========== UPDATING VCS: DONE"
|
||||||
echo "Local repo updated. Please push when ready."
|
echo "Local repo updated. Please push when ready."
|
||||||
echo " $VCSCMD push"
|
echo " $VCSCMD push"
|
||||||
|
|||||||
29
bin/blackbox_removeadmin
Executable file
29
bin/blackbox_removeadmin
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# blackbox_removeadmin -- Remove an admin to the system
|
||||||
|
# NOTE: Does not remove admin from the keyring.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Example:
|
||||||
|
# blackbox_removeadmin tal@example.com
|
||||||
|
#
|
||||||
|
|
||||||
|
. _blackbox_common.sh
|
||||||
|
. _stack_lib.sh
|
||||||
|
|
||||||
|
fail_if_not_in_repo
|
||||||
|
|
||||||
|
KEYNAME="$1"
|
||||||
|
: ${KEYNAME:?ERROR: First argument must be a keyname (email address)} ;
|
||||||
|
|
||||||
|
# Remove the email address from the BB_ADMINS file.
|
||||||
|
make_self_deleting_tempfile bbtemp
|
||||||
|
cp "$BB_ADMINS" "$bbtemp"
|
||||||
|
fgrep -v -x "$KEYNAME" <"$bbtemp" >"$BB_ADMINS"
|
||||||
|
|
||||||
|
# Make a suggestion:
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo 'NEXT STEP: Check these into the repo. Probably with a command like...'
|
||||||
|
echo $VCS_TYPE commit -m\'REMOVED ADMIN: $KEYNAME\' "$BLACKBOXDATA/$BB_ADMINS_FILE"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# blackbox_edit_start.sh -- Decrypt a file for editing.
|
# blackbox_edit_start.sh -- Decrypt a file for editing.
|
||||||
|
|||||||
@@ -50,12 +50,9 @@ done
|
|||||||
fail_if_keychain_has_secrets
|
fail_if_keychain_has_secrets
|
||||||
|
|
||||||
echo '========== COMMITING TO HG:'
|
echo '========== COMMITING TO HG:'
|
||||||
VCSCMD=$(which_vcs)
|
vcs_commit 'Re-encrypted keys' $(awk <$BB_FILES '{ print $1 ".gpg" }' )
|
||||||
$VCSCMD commit -m'Re-encrypted keys' $(awk <$BB_FILES '{ print $1 ".gpg" }' )
|
|
||||||
# NOTE(tlim): Because we use $VCSCMD as a command, we can only use commands
|
|
||||||
# that work for both git and hg. That's pretty lazy. We should add
|
|
||||||
# a function to _blackbox_common.sh that commits a file.
|
|
||||||
|
|
||||||
|
VCSCMD=$(which_vcs)
|
||||||
echo '========== DONE.'
|
echo '========== DONE.'
|
||||||
echo 'Likely next step:'
|
echo 'Likely next step:'
|
||||||
echo " ${VCSCMD} push"
|
echo " ${VCSCMD} push"
|
||||||
|
|||||||
225
tools/confidence_test.sh
Executable file
225
tools/confidence_test.sh
Executable file
@@ -0,0 +1,225 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
export PATH=/home/tlimoncelli/gitwork/blackbox/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
|
||||||
|
|
||||||
|
. _stack_lib.sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
function PHASE() {
|
||||||
|
echo '===================='
|
||||||
|
echo '===================='
|
||||||
|
echo '=========' """$@"""
|
||||||
|
echo '===================='
|
||||||
|
echo '===================='
|
||||||
|
}
|
||||||
|
|
||||||
|
function assert_file_missing() {
|
||||||
|
if [[ -e "$1" ]]; then
|
||||||
|
echo "ASSERT FAILED: ${1} should not exist."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function assert_file_exists() {
|
||||||
|
if [[ ! -e "$1" ]]; then
|
||||||
|
echo "ASSERT FAILED: ${1} should exist."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function assert_file_md5hash() {
|
||||||
|
local file="$1"
|
||||||
|
local wanted="$2"
|
||||||
|
local found=$(md5sum <"$file" | cut -d' ' -f1 )
|
||||||
|
assert_file_exists "$file"
|
||||||
|
if [[ "$wanted" != "$found" ]]; then
|
||||||
|
echo "ASSERT FAILED: $file hash wanted=$desired found=$found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
make_tempdir test_repository
|
||||||
|
cd "$test_repository"
|
||||||
|
|
||||||
|
make_self_deleting_tempdir fake_alice_home
|
||||||
|
make_self_deleting_tempdir fake_bob_home
|
||||||
|
export GNUPGHOME="$fake_alice_home"
|
||||||
|
eval $(gpg-agent --homedir "$fake_alice_home" --daemon)
|
||||||
|
GPG_AGENT_INFO_ALICE="$GPG_AGENT_INFO"
|
||||||
|
|
||||||
|
export GNUPGHOME="$fake_bob_home"
|
||||||
|
eval $(gpg-agent --homedir "$fake_alice_home" --daemon)
|
||||||
|
GPG_AGENT_INFO_BOB="$GPG_AGENT_INFO"
|
||||||
|
|
||||||
|
function become_alice() {
|
||||||
|
export GNUPGHOME="$fake_alice_home"
|
||||||
|
export GPG_AGENT_INFO="$GPG_AGENT_INFO_ALICE"
|
||||||
|
echo BECOMING ALICE: GNUPGHOME=$GNUPGHOME AGENT=$GPG_AGENT_INFO
|
||||||
|
git config --global user.name "Alice Example"
|
||||||
|
git config --global user.email alice@example.com
|
||||||
|
}
|
||||||
|
|
||||||
|
function become_bob() {
|
||||||
|
export GNUPGHOME="$fake_alice_home"
|
||||||
|
export GPG_AGENT_INFO="$GPG_AGENT_INFO_ALICE"
|
||||||
|
git config --global user.name "Bob Example"
|
||||||
|
git config --global user.email bob@example.com
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PHASE 'Alice creates a repo. She creates secret.txt.'
|
||||||
|
|
||||||
|
become_alice
|
||||||
|
git init
|
||||||
|
echo 'this is my secret' >secret.txt
|
||||||
|
|
||||||
|
|
||||||
|
PHASE 'Alice wants to be part of the secret system.'
|
||||||
|
PHASE 'She creates a GPG key...'
|
||||||
|
|
||||||
|
make_self_deleting_tempfile gpgconfig
|
||||||
|
cat >"$gpgconfig" <<EOF
|
||||||
|
%echo Generating a basic OpenPGP key
|
||||||
|
Key-Type: default
|
||||||
|
Subkey-Type: default
|
||||||
|
Name-Real: Alice Example
|
||||||
|
Name-Comment: with weak passphrase
|
||||||
|
Name-Email: alice@example.com
|
||||||
|
Expire-Date: 0
|
||||||
|
Passphrase: a
|
||||||
|
# Do a commit here, so that we can later print "done" :-)
|
||||||
|
%commit
|
||||||
|
%echo done
|
||||||
|
EOF
|
||||||
|
gpg --no-permission-warning --batch --gen-key "$gpgconfig"
|
||||||
|
|
||||||
|
#gpg --delete-key bob@example.com || true
|
||||||
|
#gpg --delete-key alice@example.com || true
|
||||||
|
|
||||||
|
|
||||||
|
PHASE 'Initializes BB...'
|
||||||
|
|
||||||
|
blackbox_initialize yes
|
||||||
|
git commit -m'INITIALIZE BLACKBOX' keyrings .gitignore
|
||||||
|
|
||||||
|
|
||||||
|
PHASE 'and adds herself as an admin.'
|
||||||
|
|
||||||
|
blackbox_addadmin alice@example.com
|
||||||
|
git commit -m'NEW ADMIN: alice@example.com' keyrings/live/pubring.gpg keyrings/live/trustdb.gpg keyrings/live/blackbox-admins.txt
|
||||||
|
|
||||||
|
|
||||||
|
PHASE 'Bob arrives.'
|
||||||
|
|
||||||
|
become_bob
|
||||||
|
|
||||||
|
|
||||||
|
PHASE 'Bob creates a gpg key.'
|
||||||
|
|
||||||
|
cat >"$gpgconfig" <<EOF
|
||||||
|
%echo Generating a basic OpenPGP key
|
||||||
|
Key-Type: default
|
||||||
|
Subkey-Type: default
|
||||||
|
Name-Real: Bob Example
|
||||||
|
Name-Comment: with weak passphrase
|
||||||
|
Name-Email: bob@example.com
|
||||||
|
Expire-Date: 0
|
||||||
|
Passphrase: b
|
||||||
|
# Do a commit here, so that we can later print "done" :-)
|
||||||
|
%commit
|
||||||
|
%echo done
|
||||||
|
EOF
|
||||||
|
gpg --no-permission-warning --batch --gen-key "$gpgconfig"
|
||||||
|
|
||||||
|
echo '========== Bob enrolls himself too.'
|
||||||
|
|
||||||
|
blackbox_addadmin bob@example.com
|
||||||
|
git commit -m'NEW ADMIN: alice@example.com' keyrings/live/pubring.gpg keyrings/live/trustdb.gpg keyrings/live/blackbox-admins.txt
|
||||||
|
|
||||||
|
PHASE 'Alice does the second part to enroll bob.'
|
||||||
|
become_alice
|
||||||
|
|
||||||
|
PHASE 'She enrolls bob.'
|
||||||
|
gpg --import keyrings/live/pubring.gpg
|
||||||
|
# TODO(tlim) That --import can be eliminated... maybe?
|
||||||
|
|
||||||
|
PHASE 'She enrolls secrets.txt.'
|
||||||
|
blackbox_register_new_file secret.txt
|
||||||
|
assert_file_missing secret.txt
|
||||||
|
assert_file_exists secret.txt.gpg
|
||||||
|
|
||||||
|
PHASE 'She decrypts secrets.txt.'
|
||||||
|
blackbox_edit_start secret.txt
|
||||||
|
assert_file_exists secret.txt
|
||||||
|
assert_file_exists secret.txt.gpg
|
||||||
|
assert_file_md5hash secret.txt "69923af35054e09cff786424e7b287aa"
|
||||||
|
|
||||||
|
PHASE 'She edits secrets.txt.'
|
||||||
|
echo 'this is MY NEW SECRET' >secret.txt
|
||||||
|
blackbox_edit_end secret.txt
|
||||||
|
assert_file_missing secret.txt
|
||||||
|
assert_file_exists secret.txt.gpg
|
||||||
|
|
||||||
|
|
||||||
|
PHASE 'Bob appears.'
|
||||||
|
become_bob
|
||||||
|
|
||||||
|
PHASE 'Bob makes sure he has all new keys.'
|
||||||
|
|
||||||
|
gpg --import keyrings/live/pubring.gpg
|
||||||
|
|
||||||
|
PHASE 'Bob postdeploys.'
|
||||||
|
blackbox_postdeploy
|
||||||
|
assert_file_exists secret.txt
|
||||||
|
assert_file_exists secret.txt.gpg
|
||||||
|
assert_file_md5hash secret.txt "08a3fa763a05c018a38e9924363b97e7"
|
||||||
|
|
||||||
|
PHASE 'Bob cleans up the secret.'
|
||||||
|
rm secret.txt
|
||||||
|
|
||||||
|
PHASE 'Bob removes alice.'
|
||||||
|
blackbox_removeadmin alice@example.com
|
||||||
|
if grep -xs >dev/null 'alice@example.com' keyrings/live/blackbox-admins.txt ; then
|
||||||
|
echo "ASSERT FAILED: alice@example.com should be removed from keyrings/live/blackbox-admins.txt"
|
||||||
|
echo ==== file start
|
||||||
|
cat keyrings/live/blackbox-admins.txt
|
||||||
|
echo ==== file end
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PHASE 'Bob reencrypts files so alice can not access them.'
|
||||||
|
blackbox_update_all_files
|
||||||
|
|
||||||
|
PHASE 'Bob decrypts secrets.txt.'
|
||||||
|
blackbox_edit_start secret.txt
|
||||||
|
assert_file_exists secret.txt
|
||||||
|
assert_file_exists secret.txt.gpg
|
||||||
|
assert_file_md5hash secret.txt "08a3fa763a05c018a38e9924363b97e7"
|
||||||
|
|
||||||
|
PHASE 'Bob edits secrets.txt.'
|
||||||
|
echo 'BOB BOB BOB BOB' >secret.txt
|
||||||
|
blackbox_edit_end secret.txt
|
||||||
|
assert_file_missing secret.txt
|
||||||
|
assert_file_exists secret.txt.gpg
|
||||||
|
|
||||||
|
PHASE 'Bob decrypts secrets.txt VERSION 3.'
|
||||||
|
blackbox_edit_start secret.txt
|
||||||
|
assert_file_exists secret.txt
|
||||||
|
assert_file_exists secret.txt.gpg
|
||||||
|
assert_file_md5hash secret.txt "beb0b0fd5701afb6f891de372abd35ed"
|
||||||
|
|
||||||
|
# TODO(tlim): Add test to make sure that now alice can NOT decrypt.
|
||||||
|
|
||||||
|
#
|
||||||
|
# ASSERTIONS
|
||||||
|
#
|
||||||
|
|
||||||
|
if [[ -e $HOME/.gnupg ]]; then
|
||||||
|
echo "ASSERT FAILED: $HOME/.gnupg should not exist."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
find * -ls
|
||||||
|
echo cd "$test_repository"
|
||||||
|
echo rm "$test_repository"
|
||||||
|
echo DONE.
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
exec /usr/blackbox/bin/blackbox_addadmin bin/blackbox_addadmin
|
read /etc/profile.d/usrblackbox.sh tools/profile.d-usrblackbox.sh
|
||||||
exec /usr/blackbox/bin/_blackbox_common.sh bin/_blackbox_common.sh
|
exec /usr/blackbox/bin/_blackbox_common.sh bin/_blackbox_common.sh
|
||||||
|
exec /usr/blackbox/bin/_stack_lib.sh bin/_stack_lib.sh
|
||||||
|
exec /usr/blackbox/bin/blackbox_addadmin bin/blackbox_addadmin
|
||||||
exec /usr/blackbox/bin/blackbox_edit_end bin/blackbox_edit_end
|
exec /usr/blackbox/bin/blackbox_edit_end bin/blackbox_edit_end
|
||||||
exec /usr/blackbox/bin/blackbox_edit_start bin/blackbox_edit_start
|
exec /usr/blackbox/bin/blackbox_edit_start bin/blackbox_edit_start
|
||||||
|
exec /usr/blackbox/bin/blackbox_initialize bin/blackbox_initialize
|
||||||
exec /usr/blackbox/bin/blackbox_postdeploy bin/blackbox_postdeploy
|
exec /usr/blackbox/bin/blackbox_postdeploy bin/blackbox_postdeploy
|
||||||
exec /usr/blackbox/bin/blackbox_register_new_file bin/blackbox_register_new_file
|
exec /usr/blackbox/bin/blackbox_register_new_file bin/blackbox_register_new_file
|
||||||
exec /usr/blackbox/bin/blackbox_update_all_files bin/blackbox_update_all_files
|
exec /usr/blackbox/bin/blackbox_removeadmin bin/blackbox_removeadmin
|
||||||
exec /usr/blackbox/bin/blackbox_start bin/blackbox_start
|
exec /usr/blackbox/bin/blackbox_start bin/blackbox_start
|
||||||
read /etc/profile.d/usrblackbox.sh tools/profile.d-usrblackbox.sh
|
exec /usr/blackbox/bin/blackbox_update_all_files bin/blackbox_update_all_files
|
||||||
|
|||||||
Reference in New Issue
Block a user