Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement blackbox in Golang #250

Merged
merged 76 commits into from
Jul 24, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
ff792cf
vendor github.com/pkg/errors vendor/github.com/urfave/cli
tlimoncelli Apr 21, 2018
57702a1
New command: blackbox: Parses subcommands and calls bash scripts.
tlimoncelli Apr 21, 2018
3a5e4b6
Implement status and nlist commands
tlimoncelli Apr 22, 2018
5681903
Add "blackbox admin nlist" command.
tlimoncelli Apr 22, 2018
d393d7e
First draft of ndecrypt
tlimoncelli Apr 22, 2018
a6b9c17
Merge branch 'master' into golang
tlimoncelli Jul 3, 2018
3cc7e46
Partial commit
tlimoncelli Sep 10, 2018
e1e6dee
Merge branch 'master' into golang
tlimoncelli Sep 10, 2018
b62ec37
Merge branch 'master' into golang
tlimoncelli Dec 4, 2018
5671b71
Merge branch 'master' into golang
tlimoncelli Dec 9, 2018
ffde3ae
Restructure
tlimoncelli Dec 9, 2018
a5cd829
wip!
tlimoncelli Dec 18, 2018
a47f038
Merge branch 'master' into golang
tlimoncelli Mar 3, 2019
36e1774
Merge branch 'master' into golang
Apr 19, 2020
1fb5701
NEW: DESIGN.md
Apr 19, 2020
b3e052b
Merge branch 'master' into golang
tlimoncelli Jun 6, 2020
c9bd587
tmp
tlimoncelli Jun 6, 2020
a630c6b
flags.go and parse.go complete
tlimoncelli Jun 6, 2020
0bdffb3
Draft
tlimoncelli Jun 6, 2020
a6ec716
Box discovers admins and files.
tlimoncelli Jun 6, 2020
50fa2e5
Snapshot
tlimoncelli Jun 7, 2020
d7bdd49
Fixed the signature mismatch problem!!!
tlimoncelli Jun 7, 2020
ac8105c
linting
tlimoncelli Jun 7, 2020
4979113
Implement Discover()
tlimoncelli Jun 7, 2020
bc5dab7
Implement: files list
tlimoncelli Jun 7, 2020
2425c0f
"blackbox status" works.
tlimoncelli Jun 7, 2020
bf1f1e2
Unvendor
tlimoncelli Jun 7, 2020
148aa3d
Unvendor
tlimoncelli Jun 7, 2020
6c260d1
Cleanup
tlimoncelli Jun 7, 2020
126f60f
cleanup
tlimoncelli Jun 7, 2020
edad8a8
snapshot
tlimoncelli Jun 7, 2020
66eeea2
snapshot!
tlimoncelli Jun 7, 2020
9998758
Rename pkgs
tlimoncelli Jun 7, 2020
8c329b1
linting
tlimoncelli Jun 7, 2020
56665df
Implement decrypt --askagent and --umask
tlimoncelli Jun 8, 2020
f860c73
Random fixes
tlimoncelli Jun 8, 2020
b3aa045
snapshot
tlimoncelli Jun 8, 2020
df2bb78
integration test framework works
tlimoncelli Jun 9, 2020
164376f
Integration tests work all the way through "init".
tlimoncelli Jun 10, 2020
2c8400c
init completed
tlimoncelli Jun 11, 2020
b544a02
Mostly working
tlimoncelli Jun 12, 2020
e831a5a
logging works
tlimoncelli Jun 12, 2020
0a0068d
fix logging
tlimoncelli Jun 12, 2020
a189a4a
wip!
tlimoncelli Jun 14, 2020
e0e61f5
wip!
tlimoncelli Jun 15, 2020
7276fae
Now working: init, admin add, file add, encrypt, decrypt, shred
tlimoncelli Jun 15, 2020
b17a11a
Cat works!
tlimoncelli Jun 16, 2020
a47bc5d
cat and other commands now work. shell commands replaced
tlimoncelli Jun 16, 2020
fa2a643
create binv2
tlimoncelli Jun 19, 2020
0518006
integration tests working
tlimoncelli Jun 19, 2020
b963da0
Now works on CentOS 7
TomOnTime Jun 19, 2020
b3e9e52
aRough out Docs
tlimoncelli Jun 23, 2020
eccea8d
fix comment
tlimoncelli Jul 2, 2020
ac66afd
linting
tlimoncelli Jul 2, 2020
bea3af3
Refactor how NeedsCommit is done
tlimoncelli Jul 2, 2020
4f79084
add missing files
tlimoncelli Jul 3, 2020
56ecdc8
git commit messages are more pretty
tlimoncelli Jul 3, 2020
433b357
cleanup
tlimoncelli Jul 3, 2020
c0d1883
Fixing commits
tlimoncelli Jul 3, 2020
0eb9fd1
bx.* dirs are now relative
tlimoncelli Jul 4, 2020
afcec7d
linting
tlimoncelli Jul 4, 2020
6b8deb4
Clean up redact
tlimoncelli Jul 4, 2020
7ab79e0
Fix bug: filenames with spaces dont work
tlimoncelli Jul 4, 2020
6ff8d0d
macos doesn't need gpg-agent
tlimoncelli Jul 4, 2020
68a17b5
Fix umask display. All --all commands now work from any directory
tlimoncelli Jul 5, 2020
fdb2559
Fix --debug. Fix --group
tlimoncelli Jul 5, 2020
fa53022
Fix links
tlimoncelli Jul 5, 2020
b3b54fa
Refactor makesafe
tlimoncelli Jul 5, 2020
259ba65
cleanig up code
tlimoncelli Jul 6, 2020
b6d4fee
linting
tlimoncelli Jul 6, 2020
f886ea5
mDocs
tlimoncelli Jul 14, 2020
ccc2439
fix reencrypt commit messages
tlimoncelli Jul 17, 2020
92e791a
Fix
tlimoncelli Jul 18, 2020
9e088db
Rewrite shred detector
tlimoncelli Jul 18, 2020
4c47af8
do some integration tests from a funny subdir
tlimoncelli Jul 18, 2020
053b8a6
Rewrite shred detector
tlimoncelli Jul 18, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Random fixes
  • Loading branch information
tlimoncelli committed Jun 8, 2020
commit f860c73a12155c7e98204460e18fb8820f1e1e65
35 changes: 4 additions & 31 deletions Version2-Ideas.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,6 @@ These are the things I'd like to change someday.

There should be one program, with subcommands that have names that make more sense:

* `blackbox init`
* `blackbox info`
* `blackbox admin add <key>`
* `blackbox admin remove <key>`
* `blackbox admin list`
* `blackbox files add`
* `blackbox files list`
* `blackbox files remove`
* `blackbox encrypt <filename> ...`
* `blackbox decrypt <filename> ...`
* `blackbox cat <filename> ...`
* `blackbox edit <filename> ...`
* `blackbox reencrypt`
* `blackbox shred`
* `blackbox diff <filename> ...`
* `blackbox files list-unchanged`
* `blackbox files list-changed`

* `blackbox admin add <key>`
* `blackbox admin list`
* `blackbox admin remove <key>`
Expand All @@ -44,23 +26,14 @@ There should be one program, with subcommands that have names that make more sen
* `blackbox diff <filename> ...`
* `blackbox edit <filename> ...`
* `blackbox encrypt <filename> ...`
* `blackbox file add`
* `blackbox file add <filename> ...`
* `blackbox file list`
* `blackbox file remove`
* `blackbox file remove <filename> ...`
* `blackbox info`
* `blackbox init`
* `blackbox reencrypt`
* `blackbox shred`
* `blackbox status all`
* `blackbox status changed`
* `blackbox status unchanged`


Flags where appropriate

* -verbose -v
* -noshred
* -debug
* `blackbox shred --all|<filename> ...`
* `blackbox status --all|<filename> ...`

Backwards compatibility: The old scripts will be rewritten to use the new commands.

Expand Down
83 changes: 83 additions & 0 deletions integrationTest/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@



Something like...

# Startup
* Create a repo (git, none)

# Test basic operations:
* As Alice:
* initialize blackbox, add her keys to it, see that the usual files
exist. See her name in bb-admins.txt
* encrypt a file, see that the plaintext is deleted, see the file in bb-files.txt
* decrypt the file, see the original plaintext is recovered.
* Encrypt a file --noshred.
* Decrypt the file, it should fail as the plaintext exists.
* Remove the plaintext.
* Decrypt the file, it should fail as the plaintext exists.

# Test hand-off from Alice to Bob.
* As Bob
* add himself to the admins.
* As Alice
* Update-all-files
* Create a new file. Encrypt it.
* As Bob
* Decrypt both files
* Verify contents of the new file, and the file from previous.
* Create a new file. Encrypt it.
* As Alice:
* Decrypt all files.
* Verify contents of the 3 plaintext files.

# Test a git-less directory
* Copy the old repo somewhere. Remove the .git directory.
* As Alice:
* Decrypt all
* Verify plaintext contents

# Test post-deploy with/without GID
* Back at the original repo:
* Shred all
* Run post-deploy. Verify.
* Shred all
* Run post-deploy with a custom GID. Verify.

# Test removing an admin
* As Bob:
* removes Alice. (Verify)
* Re-encrypt
* Decrypt all & verify.
* As alice
* Decrypting should fail.

# Test funny names and paths
* my/path/to/relsecrets.txt
* cwd=other/place ../../my/path/to/relsecrets.txt
* !important!.txt
* #andpounds.txt
* stars*bars?.txt
* space space.txt
* Do add/encrypt/decrypt
* Do blackbox_update_all_files
* Do remove them all

# When people start asking for commands to work with relative paths
# Test from outside the repo
* mkdir ../other/place
* cd ../other/place
* decrypt ../../secret1.txt
* encrypt ../../secret1.txt

# Test specific commands:
# blackbox admins list
# blackbox file list
# blackbox status --name-only (create 1 of each "type")
# blackbox status --type=FOO

# These should all fail:
# blackbox file list --all
# blackbox file list blah
# blackbox shred list --all
# blackbox shred list blah
16 changes: 10 additions & 6 deletions pkg/box/verbs.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,18 @@ func (bx *Box) Info() error {
logErr.Printf("getFiles error: %v", err)
}

fmt.Println("BLACKBOX:")
fmt.Printf("bx.ConfigDir=%q\n", bx.ConfigDir)
//fmt.Printf("bx.Admins=%q\n", bx.Admins)
fmt.Printf("len(bx.Admins)=%v\n", len(bx.Admins))
//fmt.Printf("bx.Files=%q\n", bx.Files)
fmt.Printf("len(bx.Files)=%v\n", len(bx.Files))
fmt.Printf("bx.Vcs=%v\n", bx.Vcs)
fmt.Printf("bx.VcsName=%q\n", bx.VcsName)

fmt.Println("BLACKBOX:")
fmt.Printf(" ConfigDir: %q\n", bx.ConfigDir)
fmt.Printf(" RepoBaseDir: %q\n", bx.RepoBaseDir)
fmt.Printf(" Admins: count=%v\n", len(bx.Admins))
fmt.Printf(" Files: count=%v\n", len(bx.Files))
fmt.Printf(" Vcs: %v\n", bx.Vcs)
fmt.Printf(" VcsName: %q\n", bx.VcsName)
fmt.Printf(" Crypter: %v\n", bx.Crypter)
fmt.Printf(" CrypterName: %q\n", bx.CrypterName)

return nil
}
Expand Down
7 changes: 3 additions & 4 deletions pkg/crypters/gnupg/gnupg.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package gnupg
import (
"os"
"os/exec"
"syscall"

"github.com/StackExchange/blackbox/v2/pkg/bbutil"
"github.com/StackExchange/blackbox/v2/pkg/crypters"
Expand Down Expand Up @@ -41,16 +42,14 @@ func (crypt CrypterHandle) Decrypt(name string, overwrite bool, umask int) error
_ = os.Remove(name)
}

crypt.prepareKeyChain()

//oldumask := syscall.Umask(umask)
oldumask := syscall.Umask(umask)
err := bbutil.RunBash(crypt.GPGCmd,
"--use-agent",
"-q",
"--decrypt",
"-o", name,
name+".gpg",
)
//syscall.Umask(oldumask)
syscall.Umask(oldumask)
return err
}
107 changes: 107 additions & 0 deletions pkg/crypters/gnupg/keychain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package gnupg

/*

# How does Blackbox manage key rings?

Blackbox uses the user's .gnupg directory for most actions, such as decrypting data.
Decrypting requires the user's private key, which is stored by the user in their
home directory (and up to them to store safely).
Black box does not store the user's private key in the repo.

When encrypting data, black needs the public key of all the admins, not just the users.
To assure that the user's `.gnupg` has all these public keys, prior to
encrypting data the public keys are imported from .blackbox, which stores
a keychain that stores the public (not private!) keys of all the admins.

FYI: v1 does this import before decrypting, because I didn't know any better.

# Binary compatibility:

When writing v1, we didn't realize that the pubkey.gpg file is a binary format
that is not intended to be portable. In fact, it is intentionally not portable.
This means that all admins must use the exact same version of GnuPG
or the files (pubring.gpg or pubring.kbx) may get corrupted.

In v2, we store the public keys in the portable ascii format
in a file called `.blackbox/public-keys-db.asc`.
It will also update the binary files if they exist.
If `.blackbox/public-keys-db.asc` doesn't exist, it will be created.

Eventually we will stop updating the binary files.

# Importing public keys to the user

How to import the public keys to the user's GPG system:

If pubkeyring-ascii.txt exists:
gpg --import pubkeyring-ascii.asc
Else if pubring.kbx
gpg --import pubring.kbx
Else if pubring.gpg
gpg --import pubring.gpg

This is what v1 does:
#if gpg2 is installed next to gpg like on ubuntu 16
if [[ "$GPG" != "gpg2" ]]; then
$GPG --export --no-default-keyring --keyring "$(get_pubring_path)" >"$keyringasc"
$GPG --import "$keyringasc" 2>&1 | egrep -v 'not changed$' >&2
else
$GPG --keyring "$(get_pubring_path)" --export | $GPG --import
fi

# How to add a key to the keyring?

Old, binary format:
# Get the key they want to add:
FOO is a user-specified directory, otherwise $HOME/.gnupg:
$GPG --homedir="FOO" --export -a "$KEYNAME" >TEMPFILE
# Import into the binary files:
KEYRINGDIR is .blackbox
$GPG --no-permission-warning --homedir="$KEYRINGDIR" --import TEMPFILE
# Git add any of these files if they exist:
pubring.gpg pubring.kbx trustdb.gpg blackbox-admins.txt
# Tell the user to git commit them.

New, ascii format:
# Get the key to be added. Write to a TEMPFILE
FOO is a user-specified directory, otherwise $HOME/.gnupg:
$GPG --homedir="FOO" --export -a "$KEYNAME" >TEMPFILE
# Make a tempdir called TEMPDIR
# Import the pubkeyring-ascii.txt to TEMPDIR's keyring. (Skip if file not found)
# Import the temp1 data to TEMPDIR
# Export the TEMPDIR to create a new .blackbox/pubkeyring-ascii.txt
PATH_TO_BINARY is the path to .blackbox/pubring.gpg; if that's not found then pubring.kbx
$GPG --keyring PATH_TO_BINARY --export -a --output .blackbox/pubkeyring-ascii.txt
# Git add .blackbox/pubkeyring-ascii.txt and .blackbox/blackbox-admins.txt
# Tell the user to git commit them.
# Delete TEMPDIR

# How to remove a key from the keyring?

Old, binary format:
# Remove key from the binary file
$GPG --no-permission-warning --homedir="$KEYRINGDIR" --batch --yes --delete-key "$KEYNAME" || true
# Git add any of these files if they exist:
pubring.gpg pubring.kbx trustdb.gpg blackbox-admins.txt
# Tell the user to git commit them.

New, ascii format:
# Make a tempdir called TEMPDIR
# Import the pubkeyring-ascii.txt to TEMPDIR's keyring. (Skip if file not found)
# Remove key from the ring file
$GPG --no-permission-warning --homedir="$KEYRINGDIR" --batch --yes --delete-key "$KEYNAME" || true
# Export the TEMPDIR to create a new .blackbox/pubkeyring-ascii.txt
PATH_TO_BINARY is the path to .blackbox/pubring.gpg; if that's not found then pubring.kbx
$GPG --keyring PATH_TO_BINARY --export -a --output .blackbox/pubkeyring-ascii.txt
# Git add .blackbox/pubkeyring-ascii.txt and .blackbox/blackbox-admins.txt
# Update the .blackbox copy of pubring.gpg, pubring.kbx, or trustdb.gpg (if they exist)
# with copies from TEMPDIR (if they exist). Git add any files that are updated.
# Tell the user to git commit them.
# Delete TEMPDIR

*/

func prepareUserKeychain() error {
return nil
}