Compare commits
195 Commits
v1.2015111
...
v1.2015111
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a391c0abc6 | ||
|
|
384f04af48 | ||
|
|
d83b2fbd21 | ||
|
|
b11c918e4f | ||
|
|
372a35036f | ||
|
|
074c0831c0 | ||
|
|
65ae375828 | ||
|
|
3ec645fd13 | ||
|
|
0355095a59 | ||
|
|
733408a6b7 | ||
|
|
ece750b710 | ||
|
|
54c6c2c037 | ||
|
|
93bc410449 | ||
|
|
52e029a587 | ||
|
|
aa14bef555 | ||
|
|
b8ad2ba33d | ||
|
|
e637584d77 | ||
|
|
ca2cc76bcd | ||
|
|
885a3a25b3 | ||
|
|
bb336a56fd | ||
|
|
0b637bb917 | ||
|
|
fd78fb5ed3 | ||
|
|
7c73009461 | ||
|
|
159c3cc93b | ||
|
|
8fab12de6b | ||
|
|
dd494be320 | ||
|
|
343b85a34c | ||
|
|
1f2d99436d | ||
|
|
23cc07d1e3 | ||
|
|
5ae47a69ea | ||
|
|
59685d580b | ||
|
|
aee22fc99d | ||
|
|
8956be47a3 | ||
|
|
649a75e459 | ||
|
|
4bd8b63c3c | ||
|
|
7d9c07678b | ||
|
|
3c8e7acf4f | ||
|
|
c6e72a8373 | ||
|
|
c18d3732c3 | ||
|
|
e1802f4c03 | ||
|
|
1d6d65af13 | ||
|
|
1d4edfaa10 | ||
|
|
6765988274 | ||
|
|
01a6758ab8 | ||
|
|
76884eb396 | ||
|
|
96c71e3254 | ||
|
|
53c686fc57 | ||
|
|
2b432e1f3a | ||
|
|
b56300a8c7 | ||
|
|
a5bf8a5a81 | ||
|
|
97030854fa | ||
|
|
805f66b6b3 | ||
|
|
38b8ced5dd | ||
|
|
26eb8e48cc | ||
|
|
eab0418ffe | ||
|
|
ae2dd5070d | ||
|
|
f5eeffd043 | ||
|
|
626ff178b6 | ||
|
|
4afb1b2554 | ||
|
|
1b443ff682 | ||
|
|
a648fb8e46 | ||
|
|
85e1ea7ccc | ||
|
|
4c7078e4c4 | ||
|
|
1cf8b709f4 | ||
|
|
4c0f45856f | ||
|
|
1aaeb1184e | ||
|
|
cef09190e9 | ||
|
|
c66a0befa6 | ||
|
|
521d108df9 | ||
|
|
7c99a8f94c | ||
|
|
efe7bbc8cd | ||
|
|
64e019c8e6 | ||
|
|
b523067536 | ||
|
|
415b55b1c7 | ||
|
|
d45625086a | ||
|
|
c0dda22c9c | ||
|
|
cc1d7a1851 | ||
|
|
11b2cae683 | ||
|
|
78fd5d42ec | ||
|
|
4466c202fb | ||
|
|
082809bab2 | ||
|
|
792d11e85a | ||
|
|
6de7cd99cb | ||
|
|
33429b3ca6 | ||
|
|
a3fc4cbf4a | ||
|
|
c129d06ea0 | ||
|
|
12943b3021 | ||
|
|
e0f7f88beb | ||
|
|
3968dab7c8 | ||
|
|
af7db40263 | ||
|
|
287b97ccd6 | ||
|
|
6e04e42f4a | ||
|
|
161117242e | ||
|
|
e79f87f9b3 | ||
|
|
cf170d957c | ||
|
|
83249517a5 | ||
|
|
db9b2eef60 | ||
|
|
01e681035d | ||
|
|
501c09ccd5 | ||
|
|
2a839f1520 | ||
|
|
3bcb76c129 | ||
|
|
bef40214b8 | ||
|
|
592c726b1d | ||
|
|
02700b547a | ||
|
|
9ba966445f | ||
|
|
24ee6b3923 | ||
|
|
6392a475e5 | ||
|
|
6489733299 | ||
|
|
9a0905a139 | ||
|
|
fbbadd658c | ||
|
|
56232aafc8 | ||
|
|
d960a59904 | ||
|
|
c3fa7a8261 | ||
|
|
4a5787cad8 | ||
|
|
ba503c33a4 | ||
|
|
7604c10be2 | ||
|
|
05edc204ae | ||
|
|
123cad5e41 | ||
|
|
ccc9a42bef | ||
|
|
74c0481f10 | ||
|
|
26dc0c2c57 | ||
|
|
7bbf1a4040 | ||
|
|
9a7365dbf1 | ||
|
|
6185f50942 | ||
|
|
caf7402a03 | ||
|
|
08ece7bd60 | ||
|
|
cbf0139cf5 | ||
|
|
ea72a7cd04 | ||
|
|
120f3cb42b | ||
|
|
a154c7546a | ||
|
|
9bfb3e964f | ||
|
|
5fe2ecb15e | ||
|
|
3b76c6c936 | ||
|
|
d5a82166f3 | ||
|
|
124f265825 | ||
|
|
ff50a7a30f | ||
|
|
1debbd918b | ||
|
|
a7b8c32da0 | ||
|
|
f78d25b004 | ||
|
|
d8fb3e855d | ||
|
|
08b0103136 | ||
|
|
225d38ee11 | ||
|
|
ccba841cd8 | ||
|
|
6817724205 | ||
|
|
fcaceab817 | ||
|
|
b35c09609b | ||
|
|
e2defec756 | ||
|
|
65a1c938ab | ||
|
|
faa40c71c7 | ||
|
|
90dc874d56 | ||
|
|
c474e1f0a8 | ||
|
|
8d1d09b454 | ||
|
|
d7a3c791e9 | ||
|
|
f505eb96dc | ||
|
|
19532b82d5 | ||
|
|
6e32500adc | ||
|
|
2591c768e7 | ||
|
|
b183931cf5 | ||
|
|
9c9691c5d6 | ||
|
|
a9562e73d6 | ||
|
|
5baec75e4b | ||
|
|
5428aed2d7 | ||
|
|
971b6bf63a | ||
|
|
f8016871f5 | ||
|
|
65d11ff6d5 | ||
|
|
d380b43ab7 | ||
|
|
d6fc4b1dac | ||
|
|
b8881d7bff | ||
|
|
19facd35da | ||
|
|
ee3b6612ff | ||
|
|
7cfb47c09b | ||
|
|
f18a6a0a8a | ||
|
|
503b26d354 | ||
|
|
27df8eadf0 | ||
|
|
79ae5d33ab | ||
|
|
63b5dc9de4 | ||
|
|
d4fd6cf8ed | ||
|
|
e5028b0fdb | ||
|
|
9b5af9f85c | ||
|
|
a95a5ef629 | ||
|
|
0e5fdf6fa3 | ||
|
|
1c69a11cdf | ||
|
|
28b8c413c0 | ||
|
|
86fe5ae352 | ||
|
|
bb6e7e3451 | ||
|
|
de3ec22655 | ||
|
|
511d59e7bb | ||
|
|
a772aea1d7 | ||
|
|
ca3d319c82 | ||
|
|
9c6525161c | ||
|
|
ce5174691d | ||
|
|
992b8f773d | ||
|
|
767751c24a | ||
|
|
3f9d2a3044 | ||
|
|
d4012bfeac |
89
Makefile
89
Makefile
@@ -1,12 +1,13 @@
|
|||||||
SHELL=/bin/sh
|
SHELL=/bin/sh
|
||||||
BIN=tools
|
|
||||||
|
|
||||||
PKGNAME=stack_blackbox
|
PKGNAME=stack_blackbox
|
||||||
|
|
||||||
all:
|
all:
|
||||||
@echo 'Menu:'
|
@echo 'Menu:'
|
||||||
|
@echo ' make update Update any generated files'
|
||||||
@echo ' make packages Make RPM packages'
|
@echo ' make packages Make RPM packages'
|
||||||
@echo ' make install (incomplete)
|
@echo ' make packages-deb Make DEB packages'
|
||||||
|
@echo ' make install (incomplete)'
|
||||||
|
|
||||||
install:
|
install:
|
||||||
@echo 'To install, copy the files from bin to somewhere in your PATH.'
|
@echo 'To install, copy the files from bin to somewhere in your PATH.'
|
||||||
@@ -19,8 +20,11 @@ packages: packages-rpm
|
|||||||
# RPM builds
|
# RPM builds
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# NOTE: mk_rpm_fpmdir.stack_blackbox.txt is the master list of files. All
|
||||||
|
# other packages should generate their list from it.
|
||||||
|
|
||||||
packages-rpm:
|
packages-rpm:
|
||||||
PKGRELEASE="$${PKGRELEASE}" $(BIN)/build_rpm.sh stack_blackbox tools/rpm_filelist.txt
|
cd tools && PKGRELEASE="$${PKGRELEASE}" PKGDESCRIPTION="Safely store secrets in git/hg/svn repos using GPG encryption" ./mk_rpm_fpmdir stack_blackbox mk_rpm_fpmdir.stack_blackbox.txt
|
||||||
|
|
||||||
packages-rpm-debug:
|
packages-rpm-debug:
|
||||||
@echo BUILD:
|
@echo BUILD:
|
||||||
@@ -41,16 +45,85 @@ lock-rpm:
|
|||||||
unlock-rpm:
|
unlock-rpm:
|
||||||
sudo yum versionlock clear
|
sudo yum versionlock clear
|
||||||
|
|
||||||
|
#
|
||||||
|
# Manual install
|
||||||
|
#
|
||||||
|
manual-install:
|
||||||
|
@echo 'Symlinking files from ./bin to /usr/local/bin'
|
||||||
|
@cd bin && for f in `find . -type f -iname "*" ! -iname "Makefile"`; do ln -fs `pwd`/$$f /usr/local/bin/$$f; done
|
||||||
|
@echo 'Done.'
|
||||||
|
|
||||||
|
manual-uninstall:
|
||||||
|
@echo 'Removing blackbox files from /usr/local/bin'
|
||||||
|
@cd bin && for f in `find . -type f -iname "*" ! -iname "Makefile"`; do rm /usr/local/bin/$$f; done
|
||||||
|
@echo 'Done.'
|
||||||
|
|
||||||
|
#
|
||||||
|
# DEB builds
|
||||||
|
#
|
||||||
|
|
||||||
|
packages-deb: tools/mk_deb_fpmdir.stack_blackbox.txt
|
||||||
|
cd tools && PKGRELEASE="$${PKGRELEASE}" PKGDESCRIPTION="Safely store secrets in git/hg/svn repos using GPG encryption" ./mk_deb_fpmdir stack_blackbox mk_deb_fpmdir.stack_blackbox.txt
|
||||||
|
|
||||||
|
# Make mk_deb_fpmdir.vcs_blackbox.txt from mk_rpm_fpmdir.stack_blackbox.txt:
|
||||||
|
tools/mk_deb_fpmdir.stack_blackbox.txt: tools/mk_rpm_fpmdir.stack_blackbox.txt
|
||||||
|
sed -e '/^#/d' -e 's@/usr/blackbox/bin/@/usr/bin/@g' -e '/profile.d-usrblackbox.sh/d' <tools/mk_rpm_fpmdir.stack_blackbox.txt >$@
|
||||||
|
|
||||||
|
packages-deb-debug: tools/mk_deb_fpmdir.stack_blackbox.txt
|
||||||
|
@echo BUILD:
|
||||||
|
@PKGRELEASE=99 make packages-deb
|
||||||
|
@echo ITEMS TO BE PACKAGED:
|
||||||
|
find ~/debbuild-$(PKGNAME)/installroot -type f
|
||||||
|
@echo ITEMS ACTUALLY IN PACKAGE:
|
||||||
|
@dpkg --contents $$(cat ~/debbuild-$(PKGNAME)/bin-packages.txt)
|
||||||
|
|
||||||
|
local-deb:
|
||||||
|
@PKGRELEASE=1 make packages
|
||||||
|
-@sudo dpkg -e $(PKGNAME)
|
||||||
|
sudo dpkg -i $$(cat ~/rpmbuild-$(PKGNAME)/bin-packages.txt)
|
||||||
|
|
||||||
|
#
|
||||||
|
# MacPorts builds
|
||||||
|
#
|
||||||
|
# To test:
|
||||||
|
# rm -rf /tmp/foo ; mkdir -p /tmp/foo;make packages-macports DESTDIR=/tmp/foo;find /tmp/foo -ls
|
||||||
|
|
||||||
|
# Make mk_macports.vcs_blackbox.txt from mk_rpm_fpmdir.stack_blackbox.txt:
|
||||||
|
tools/mk_macports.vcs_blackbox.txt: tools/mk_rpm_fpmdir.stack_blackbox.txt
|
||||||
|
sed -e '/^#/d' -e 's@/usr/blackbox/bin/@bin/@g' -e '/profile.d-usrblackbox.sh/d' <tools/mk_rpm_fpmdir.stack_blackbox.txt >$@
|
||||||
|
|
||||||
|
# MacPorts expects to run: make packages-macports DESTDIR=${destroot}
|
||||||
|
packages-macports: tools/mk_macports.vcs_blackbox.txt
|
||||||
|
mkdir -p $(DESTDIR)/bin
|
||||||
|
cd tools && ./mk_macports mk_macports.vcs_blackbox.txt
|
||||||
|
|
||||||
|
# stow is a pretty easy way to manage simple local installs on GNU systems
|
||||||
|
install-stow:
|
||||||
|
mkdir -p /usr/local/stow/blackbox/bin
|
||||||
|
cp bin/* /usr/local/stow/blackbox/bin
|
||||||
|
rm /usr/local/stow/blackbox/bin/Makefile
|
||||||
|
cd /usr/local/stow; stow -R blackbox
|
||||||
|
uninstall-stow:
|
||||||
|
cd /usr/local/stow; stow -D blackbox
|
||||||
|
rm -rf /usr/local/stow/blackbox
|
||||||
|
|
||||||
# Add other package types here.
|
# Add other package types here.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Updates
|
||||||
|
#
|
||||||
|
update: tools/mk_deb_fpmdir.stack_blackbox.txt tools/mk_macports.vcs_blackbox.txt
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm tools/mk_deb_fpmdir.stack_blackbox.txt tools/mk_macports.vcs_blackbox.txt
|
||||||
|
|
||||||
#
|
#
|
||||||
# System Test:
|
# System Test:
|
||||||
#
|
#
|
||||||
|
|
||||||
confidence:
|
confidence:
|
||||||
@if [[ -e ~/.gnupg ]]; then echo ERROR: '~/.gnupg should not exist. If it does, bugs may polute your .gnupg configuration. If the code has no bugs everything will be fine. Do you feel lucky?'; false ; fi
|
@if [ -e ~/.gnupg ]; then echo ERROR: '~/.gnupg should not exist. If it does, bugs may polute your .gnupg configuration. If the code has no bugs everything will be fine. Do you feel lucky?'; false ; fi
|
||||||
@if which >/dev/null gpg-agent ; then pkill gpg-agent ; rm -rf /tmp/tmp.* ; fi
|
@if which >/dev/null gpg-agent ; then pkill gpg-agent ; rm -rf /tmp/tmp.* ; fi
|
||||||
@export PATH=~/gitwork/blackbox/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin ;
|
@export PATH="$(PWD)/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/local/bin:$(PATH)" ; tools/confidence_test.sh
|
||||||
cd ~/gitwork/blackbox && tools/confidence_test.sh
|
tools/confidence_test.sh
|
||||||
@if which >/dev/null gpg-agent ; then pkill gpg-agent ; fi
|
@if which >/dev/null gpg-agent ; then pkill gpg-agent ; fi
|
||||||
@if [[ -e ~/.gnupg ]]; then echo ERROR: '~/.gnupg was created which means the scripts might be poluting GnuPG configuration. Fix this bug.'; false ; fi
|
@if [ -e ~/.gnupg ]; then echo ERROR: '~/.gnupg was created which means the scripts might be poluting GnuPG configuration. Fix this bug.'; false ; fi
|
||||||
|
|||||||
218
README.md
218
README.md
@@ -1,7 +1,7 @@
|
|||||||
BlackBox
|
BlackBox
|
||||||
========
|
========
|
||||||
|
|
||||||
Safely store secrets in a VCS repo (i.e. Git, Mercurial, or Subversion). These
|
Safely store secrets in a VCS repo (i.e. Git, Mercurial, Subversion or Perforce). These
|
||||||
commands make it easy
|
commands make it easy
|
||||||
for you to Gnu Privacy Guard (GPG) encrypt specific files in a repo so they are
|
for you to Gnu Privacy Guard (GPG) encrypt specific files in a repo so they are
|
||||||
"encrypted at rest" in your repository. However, the scripts
|
"encrypted at rest" in your repository. However, the scripts
|
||||||
@@ -11,6 +11,31 @@ for Puppet, BlackBox now works with any Git or Mercurial repository.
|
|||||||
|
|
||||||
A slide presentation about an older release [is on SlideShare](http://www.slideshare.net/TomLimoncelli/the-blackbox-project-sfae).
|
A slide presentation about an older release [is on SlideShare](http://www.slideshare.net/TomLimoncelli/the-blackbox-project-sfae).
|
||||||
|
|
||||||
|
Table of Contents
|
||||||
|
===============
|
||||||
|
|
||||||
|
* [Overview](#overview)
|
||||||
|
* [Why is this important?](#why-is-this-important)
|
||||||
|
* [Installation Instructions](#installation-instructions)
|
||||||
|
* [Commands](#commands)
|
||||||
|
* [Compatibility](#compatibility)
|
||||||
|
* [How is the encryption done?](#how-is-the-encryption-done)
|
||||||
|
* [What does this look like to the typical user?](#what-does-this-look-like-to-the-typical-user)
|
||||||
|
* [How to use the secrets with Puppet?](#how-to-use-the-secrets-with-puppet)
|
||||||
|
* [How to enroll a new file into the system?](#how-to-enroll-a-new-file-into-the-system)
|
||||||
|
* [How to remove a file from the system?](#how-to-remove-a-file-from-the-system)
|
||||||
|
* [How to indoctrinate a new user into the system?](#how-to-indoctrinate-a-new-user-into-the-system)
|
||||||
|
* [How to remove a user from the system?](#how-to-remove-a-user-from-the-system)
|
||||||
|
* [Enabling Blackbox For a Repo](#enabling-blackbox-for-a-repo)
|
||||||
|
* [Set up automated users or "role accounts"](#set-up-automated-users-or-role-accounts)
|
||||||
|
* [Some common errors](#some-common-errors)
|
||||||
|
* [Using Blackbox without a repo](#using-blackbox-without-a-repo)
|
||||||
|
* [How to submit bugs or ask questions?](#how-to-submit-bugs-or-ask-questions)
|
||||||
|
* [Developer Info](#developer-info)
|
||||||
|
* [Alternatives](#alternatives)
|
||||||
|
* [License](#license)
|
||||||
|
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
========
|
========
|
||||||
|
|
||||||
@@ -42,8 +67,8 @@ files. Simply set up a GPG key for the Puppet master (or the role
|
|||||||
account that pushes new files to the Puppet master) and have that
|
account that pushes new files to the Puppet master) and have that
|
||||||
user run `blackbox_postdeploy` after any files are updated.
|
user run `blackbox_postdeploy` after any files are updated.
|
||||||
|
|
||||||
Getting started is easy. Just `cd` into a Git, Mercurial or Subversion
|
Getting started is easy. Just `cd` into a Git, Mercurial, Subversion or
|
||||||
repository and run `blackbox_initialize`. After that, if a file is to
|
Perforce repository and run `blackbox_initialize`. After that, if a file is to
|
||||||
be encrypted, run `blackbox_register_new_file` and you are done. Add
|
be encrypted, run `blackbox_register_new_file` and you are done. Add
|
||||||
and remove keys with `blackbox_addadmin` and `blackbox_removeadmin`.
|
and remove keys with `blackbox_addadmin` and `blackbox_removeadmin`.
|
||||||
To view and/or edit a file, run `blackbox_edit`; this will decrypt the
|
To view and/or edit a file, run `blackbox_edit`; this will decrypt the
|
||||||
@@ -63,10 +88,10 @@ and passwords to be leaked.
|
|||||||
|
|
||||||
NOT SO OBVIOUSLY when we store "secrets" in a VCS repo like Git or
|
NOT SO OBVIOUSLY when we store "secrets" in a VCS repo like Git or
|
||||||
Mercurial, suddenly we are less able to share our code with other
|
Mercurial, suddenly we are less able to share our code with other
|
||||||
people. Communciation between subteams of an organization is hurt.
|
people. Communication between subteams of an organization is hurt.
|
||||||
You can't collaborate as well. Either you find yourself emailing
|
You can't collaborate as well. Either you find yourself emailing
|
||||||
individual files around (yuck!), making a special repo with just
|
individual files around (yuck!), making a special repo with just
|
||||||
the files needed by your collaborators (yuck!), or just deciding that
|
the files needed by your collaborators (yuck!!), or just deciding that
|
||||||
collaboration isn't worth all that effort (yuck!!!).
|
collaboration isn't worth all that effort (yuck!!!).
|
||||||
|
|
||||||
The ability to be open and transparent about our code, with the
|
The ability to be open and transparent about our code, with the
|
||||||
@@ -74,6 +99,42 @@ exception of a few specific files, is key to the kind of
|
|||||||
collaboration that DevOps and modern IT practitioniers
|
collaboration that DevOps and modern IT practitioniers
|
||||||
need to do.
|
need to do.
|
||||||
|
|
||||||
|
Installation Instructions:
|
||||||
|
==========================
|
||||||
|
|
||||||
|
* *The MacPorts Way*: `sudo port install vcs_blackbox`
|
||||||
|
* *The RPM way*: Check out the repo and make an RPM via `make packages-rpm`; now you can distribute the RPM via local methods.
|
||||||
|
* *The Debian/Ubuntu way*: Check out the repo and install [fpm](https://github.com/jordansissel/fpm). Now you can make a DEB `make packages-deb` that can be distributed via local methods.
|
||||||
|
* *The hard way*: Copy all the files in "bin" to your "bin".
|
||||||
|
* *The manual way*: `make manual-install` to install. `make manual-uninstall` to uninstall.
|
||||||
|
* *The Antigen Way*: Add `antigen bundle StackExchange/blackbox` to your .zshrc
|
||||||
|
* *The Zgen Way*: Add `zgen load StackExchange/blackbox` to your .zshrc where you're loading your other plugins.
|
||||||
|
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
============================
|
||||||
|
|
||||||
|
|
||||||
|
| Name: | Description: |
|
||||||
|
| --- | --- |
|
||||||
|
| `blackbox_edit` | Decrypt, run $EDITOR, re-encrypt a file |
|
||||||
|
| `blackbox_edit_start` | Decrypt a file so it can be updated |
|
||||||
|
| `blackbox_edit_end` | Encrypt a file after blackbox_edit_start was used |
|
||||||
|
| `blackbox_cat` | Decrypt and view the contents of a file |
|
||||||
|
| `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) |
|
||||||
|
| `blackbox_addadmin` | Add someone to the list of people that can encrypt/decrypt secrets |
|
||||||
|
| `blackbox_removeadmin` | Remove someone from the list of people that can encrypt/decrypt secrets |
|
||||||
|
| `blackbox_shred_all_files` | Safely delete any decrypted files |
|
||||||
|
| `blackbox_update_all_files` | Decrypt then re-encrypt all files. Useful after keys are changed |
|
||||||
|
| `blackbox_whatsnew` | show what has changed in the last commit for a given file |
|
||||||
|
|
||||||
|
|
||||||
Compatibility:
|
Compatibility:
|
||||||
============================
|
============================
|
||||||
|
|
||||||
@@ -86,8 +147,10 @@ It has been tested to work with many operating systems.
|
|||||||
* `git` -- The Git
|
* `git` -- The Git
|
||||||
* `hg` -- Mercurial
|
* `hg` -- Mercurial
|
||||||
* `svn` -- SubVersion (Thanks, Ben Drasin!)
|
* `svn` -- SubVersion (Thanks, Ben Drasin!)
|
||||||
|
* `p4` -- Perforce
|
||||||
|
* none -- The files can be decrypted outside of a repo if the keyrings directory is intact
|
||||||
* Operating system
|
* Operating system
|
||||||
* CentOS
|
* CentOS / RedHat
|
||||||
* MacOS X
|
* MacOS X
|
||||||
* Cygwin (Thanks, Ben Drasin!)
|
* Cygwin (Thanks, Ben Drasin!)
|
||||||
|
|
||||||
@@ -102,7 +165,7 @@ Note: Cywin support requires the following packages:
|
|||||||
|
|
||||||
* Normal operation:
|
* Normal operation:
|
||||||
* gnupg
|
* gnupg
|
||||||
* git or mercurial or subversion (as appropriate)
|
* git or mercurial or subversion or perforce (as appropriate)
|
||||||
* Development (if you will be adding code and want to run the confidence test)
|
* Development (if you will be adding code and want to run the confidence test)
|
||||||
* procps
|
* procps
|
||||||
* make
|
* make
|
||||||
@@ -157,7 +220,7 @@ their network.
|
|||||||
*If you use Puppet, why didn't you just use hiera-eyaml?*
|
*If you use Puppet, why didn't you just use hiera-eyaml?*
|
||||||
There are 4 reasons:
|
There are 4 reasons:
|
||||||
|
|
||||||
1. This works works with any Git or Mercurial repo, even if you aren't using Puppet.
|
1. This works with any Git or Mercurial repo, even if you aren't using Puppet.
|
||||||
2. hiera-eyaml decrypts "on demand" which means your Puppet Master now uses a lot of CPU to decrypt keys every time it is contacted. It slows down your master, which, in my case, is already slow enough.
|
2. hiera-eyaml decrypts "on demand" which means your Puppet Master now uses a lot of CPU to decrypt keys every time it is contacted. It slows down your master, which, in my case, is already slow enough.
|
||||||
3. This works with binary files, without having to ASCIIify them and paste them into a YAML file. Have you tried to do this with a cert that is 10K long and changes every few weeks? Ick.
|
3. This works with binary files, without having to ASCIIify them and paste them into a YAML file. Have you tried to do this with a cert that is 10K long and changes every few weeks? Ick.
|
||||||
4. hiera-eyaml didn't exist when I wrote this.
|
4. hiera-eyaml didn't exist when I wrote this.
|
||||||
@@ -167,13 +230,13 @@ What does this look like to the typical user?
|
|||||||
================================
|
================================
|
||||||
|
|
||||||
* If you need to, start the GPG Agent: `eval $(gpg-agent --daemon)`
|
* If you need to, start the GPG Agent: `eval $(gpg-agent --daemon)`
|
||||||
* Decrypt the file so it is editable: `blackbox_edit FILENAME`
|
* Decrypt the file so it is editable: `blackbox_edit_start FILENAME`
|
||||||
* (You will need to enter your GPG passphrase.)
|
* (You will need to enter your GPG passphrase.)
|
||||||
* Edit FILENAME as you desire: `vim FILENAME`
|
* Edit FILENAME as you desire: `vim FILENAME`
|
||||||
* Re-encrypt the file: `blackbox_edit_end FILENAME`
|
* Re-encrypt the file: `blackbox_edit_end FILENAME`
|
||||||
* Commit the changes. `git commit -a` or `hg commit`
|
* Commit the changes. `git commit -a` or `hg commit`
|
||||||
|
|
||||||
Wait... it can be even easier than than!
|
Wait... it can be even easier than that!
|
||||||
Run `blackbox_edit FILENAME`, and it'll decrypt the file
|
Run `blackbox_edit FILENAME`, and it'll decrypt the file
|
||||||
in a temp file and call `$EDITOR` on it, re-encrypting again after the editor
|
in a temp file and call `$EDITOR` on it, re-encrypting again after the editor
|
||||||
is closed.
|
is closed.
|
||||||
@@ -250,14 +313,24 @@ How to enroll a new file into the system?
|
|||||||
blackbox_register_new_file path/to/file.name.key
|
blackbox_register_new_file path/to/file.name.key
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Multiple file names can be specified on the command line:
|
||||||
|
|
||||||
|
Example 1: Register 2 files:
|
||||||
|
|
||||||
|
blackbox_register_new_file file1.txt file2.txt
|
||||||
|
|
||||||
|
Example 2: Register all the files in `$DIR`:
|
||||||
|
|
||||||
|
find $DIR -type f -not -name '*.gpg' -print0 | xargs -0 blackbox_register_new_file
|
||||||
|
|
||||||
|
|
||||||
How to remove a file from the system?
|
How to remove a file from the system?
|
||||||
============================
|
============================
|
||||||
|
|
||||||
This is a manual process. It happens quite rarely.
|
This happens quite rarely, but we've got it covered:
|
||||||
|
```
|
||||||
1. Remove the file ``keyrings/live/blackbox-files.txt``
|
blackbox_deregister_file path/to/file.name.key
|
||||||
2. Remove references from ``.gitignore`` or ``.hgignore``
|
```
|
||||||
3. Use ``git rm`` or ``hg rm`` as expected.
|
|
||||||
|
|
||||||
How to indoctrinate a new user into the system?
|
How to indoctrinate a new user into the system?
|
||||||
============================
|
============================
|
||||||
@@ -271,11 +344,15 @@ 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.
|
||||||
|
|
||||||
|
If you don't already have a GPG key, here's how to generate one:
|
||||||
|
|
||||||
```
|
```
|
||||||
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. Store the private key securely. Tip: Store it on a secure machine, or one with little or no internet access, with full-disk-encryption, etc. Your employer problably has rules about how to store such things.
|
||||||
|
|
||||||
|
Now that you have a GPG key, add yourself as an admin:
|
||||||
|
|
||||||
```
|
```
|
||||||
blackbox_addadmin KEYNAME
|
blackbox_addadmin KEYNAME
|
||||||
@@ -287,23 +364,41 @@ blackbox_addadmin KEYNAME
|
|||||||
blackbox_addadmin tal@example.com
|
blackbox_addadmin tal@example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
When the command completes successfully, instructions on how to
|
When the command completes successfully, instructions on how to commit these changes will be output. Run the command as given to commit the changes. It will look like this:
|
||||||
commit these changes will be output. Run the command as give.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
NEXT STEP: Check these into the repo. Probably with a command like...
|
|
||||||
git commit -m'NEW ADMIN: tal@example.com' keyrings/live/pubring.gpg keyrings/live/trustdb.gpg keyrings/live/blackbox-admins.txt
|
git commit -m'NEW ADMIN: tal@example.com' keyrings/live/pubring.gpg keyrings/live/trustdb.gpg keyrings/live/blackbox-admins.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
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:
|
Then push it to the repo:
|
||||||
|
|
||||||
```
|
```
|
||||||
blackbox_addadmin puppetmaster@puppet-master-1.example.com /path/to/the/dir
|
git push
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
ht push
|
||||||
|
|
||||||
|
(or whatever is appropriate)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
NOTE: Creating a Role Account? 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: `blackbox_addadmin puppetmaster@puppet-master-1.example.com /path/to/the/dir`
|
||||||
|
|
||||||
|
|
||||||
### 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.
|
||||||
|
|
||||||
|
Pre-check: Verify the new keys look good.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ gpg --homedir=keyrings/live --list-keys
|
||||||
|
```
|
||||||
|
|
||||||
|
For example, examine the key name (email address) to make sure
|
||||||
|
it conforms to corporate standards.
|
||||||
|
|
||||||
|
Import the keychain into your personal keychain and reencrypt:
|
||||||
|
|
||||||
```
|
```
|
||||||
gpg --import keyrings/live/pubring.gpg
|
gpg --import keyrings/live/pubring.gpg
|
||||||
@@ -359,7 +454,7 @@ so on just like when anyone that had privileged access leaves an
|
|||||||
organization.
|
organization.
|
||||||
|
|
||||||
|
|
||||||
First Time Setup (enabling Blackbox for a repo)
|
Enabling Blackbox For a Repo
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
Overview:
|
Overview:
|
||||||
@@ -584,27 +679,81 @@ rm -rf /tmp/NEWMASTER
|
|||||||
Also shred any other temporary files you may have made.
|
Also shred any other temporary files you may have made.
|
||||||
|
|
||||||
|
|
||||||
Help out: Submit bugs, pull requests and ideas:
|
Some common errors:
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
`gpg: filename: skipped: No public key` -- Usually this means there
|
||||||
|
is an item in `keyrings/live/blackbox-admins.txt` that is not the
|
||||||
|
name of the key. Either something invalid was inserted (like a
|
||||||
|
filename instead of a username) or a user has left the organization
|
||||||
|
and their key was removed from the keychain, but their name wasn't
|
||||||
|
removed from the blackbox-admins.txt file.
|
||||||
|
|
||||||
|
`gpg: decryption failed: No secret key` -- Usually means you forgot
|
||||||
|
to re-encrypt the file with the new key.
|
||||||
|
|
||||||
|
|
||||||
|
Using Blackbox without a repo
|
||||||
|
===========================
|
||||||
|
|
||||||
|
If the files are copied out of a repo they can still be decrypted
|
||||||
|
and edited. Obviously edits, changes to keys, and such will be lost
|
||||||
|
if they are made outside the repo. Also note that commands are most
|
||||||
|
likely to only work if run from the base directory (i.e. the parent to
|
||||||
|
the keyrings directory).
|
||||||
|
|
||||||
|
The following commands have been tested outside a repo:
|
||||||
|
|
||||||
|
* `blackbox_postdeploy`
|
||||||
|
* `blackbox_edit_start`
|
||||||
|
* `blackbox_edit_end`
|
||||||
|
|
||||||
|
|
||||||
|
How to submit bugs or ask questions?
|
||||||
============
|
============
|
||||||
|
|
||||||
I welcome code changes, questions, bug reports and feedback!
|
We welcome questions, bug reports and feedback!
|
||||||
|
|
||||||
* Submit code: https://github.com/StackExchange/blackbox
|
* https://github.com/StackExchange/blackbox/issues
|
||||||
* Report bugs/questions: https://github.com/StackExchange/blackbox/issues
|
|
||||||
|
|
||||||
Tip for submitting code:
|
Developer Info
|
||||||
|
============
|
||||||
|
|
||||||
After you make a change, please re-run the confidence tests. This
|
Code submissions are gladly welcomed! The code is
|
||||||
runs through various procedures and checks the results.
|
fairly easy to read.
|
||||||
|
|
||||||
To run the tests:
|
|
||||||
|
Get the code:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone git@github.com:StackExchange/blackbox.git
|
||||||
|
```
|
||||||
|
|
||||||
|
Test your changes:
|
||||||
|
|
||||||
```
|
```
|
||||||
make confidence
|
make confidence
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This runs through a number of system tests. It
|
||||||
|
creates a repo, encrypts files, decrypts files, and so on.
|
||||||
|
You can run these tests to verify that the changes you made
|
||||||
|
didn't break anything. You can also use these tests to
|
||||||
|
verify that the system works with a new operating system.
|
||||||
|
|
||||||
|
Please submit tests with code changes:
|
||||||
|
|
||||||
|
The best way to change Blackbox is via Test Driven Development.
|
||||||
|
First add a test to `tools/confidence.sh`. This test should
|
||||||
|
fail, and demonstrate the need for the change you are about to
|
||||||
|
make. Then fix the bug or add the feature you want. When
|
||||||
|
you are done, `make confidence` should pass all tests.
|
||||||
|
The PR you submit should include your code as well as the new
|
||||||
|
test. This way the confidence tests accumulate as the system
|
||||||
|
grows as we know future changes don't break old features.
|
||||||
|
|
||||||
Note: The tests currently assume "git" and have been tested
|
Note: The tests currently assume "git" and have been tested
|
||||||
on CentOS and Cygwin.
|
only on CentOS, Mac OS X, and Cygwin. Patches welcome!
|
||||||
|
|
||||||
|
|
||||||
Alternatives
|
Alternatives
|
||||||
@@ -612,9 +761,12 @@ Alternatives
|
|||||||
|
|
||||||
Here are other open source packages that do something similar to Blackbox. If you like them better than Blackbox, please use them.
|
Here are other open source packages that do something similar to Blackbox. If you like them better than Blackbox, please use them.
|
||||||
|
|
||||||
|
* git-crypt: https://www.agwa.name/projects/git-crypt/
|
||||||
* Pass: http://www.zx2c4.com/projects/password-store/
|
* Pass: http://www.zx2c4.com/projects/password-store/
|
||||||
* Transcrypt: https://github.com/elasticdog/transcrypt
|
* Transcrypt: https://github.com/elasticdog/transcrypt
|
||||||
* git-crypt: https://www.agwa.name/projects/git-crypt/
|
|
||||||
|
git-crypt has the best git integration. Once set up it is nearly transparent to the users. However it only works with git.
|
||||||
|
|
||||||
|
|
||||||
License
|
License
|
||||||
=======
|
=======
|
||||||
|
|||||||
119
RELEASE_ENGINEERING.md
Normal file
119
RELEASE_ENGINEERING.md
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
# Branches and Tags:
|
||||||
|
|
||||||
|
There are 3 branches/tags:
|
||||||
|
|
||||||
|
* **HEAD:** The cutting edge of development.
|
||||||
|
* **tag stable:** Stable enough for use by most people.
|
||||||
|
* **tag production:** Burned in long enough that we are confident it can be widely adopted.
|
||||||
|
|
||||||
|
If you are packaging Blackbox for distribution, you should track the *tag production*. You might also want to provide a separate package that tracks *tag stable:* for early adopters.
|
||||||
|
|
||||||
|
# Build Tasks
|
||||||
|
|
||||||
|
# Stable Releases
|
||||||
|
|
||||||
|
Marking the software to be "stable":
|
||||||
|
|
||||||
|
Step 1. Tag it.
|
||||||
|
|
||||||
|
```
|
||||||
|
git pull
|
||||||
|
git tag -d stable
|
||||||
|
git push origin :stable
|
||||||
|
git tag stable
|
||||||
|
git push origin tag stable
|
||||||
|
```
|
||||||
|
|
||||||
|
Step 2. Mark your calendar 1 week from today to check
|
||||||
|
to see if this should be promoted to production.
|
||||||
|
|
||||||
|
|
||||||
|
# Production Releases
|
||||||
|
|
||||||
|
If no bugs have been reported a full week after a stable tag has been pushed, mark the release to be "production".
|
||||||
|
|
||||||
|
```
|
||||||
|
git fetch
|
||||||
|
git checkout stable
|
||||||
|
git tag -d production
|
||||||
|
git push origin :production
|
||||||
|
git tag production
|
||||||
|
git push origin tag production
|
||||||
|
R="v1.$(date +%Y%m%d)"
|
||||||
|
git tag "$R"
|
||||||
|
git push origin tag "$R"
|
||||||
|
```
|
||||||
|
|
||||||
|
# Updating MacPorts (automatic)
|
||||||
|
|
||||||
|
Step 1: Generate the Portfile
|
||||||
|
|
||||||
|
```
|
||||||
|
tools/macports_report_upgrade.sh 1.20150222
|
||||||
|
```
|
||||||
|
|
||||||
|
This script will generate a file called `Portfile-vcs_blackbox.diff` and instructions on how to submit it as a update request.
|
||||||
|
|
||||||
|
Step 2: Submit the update request.
|
||||||
|
|
||||||
|
Submit the diff file as a bug as instructed. The instructions should look like this:
|
||||||
|
|
||||||
|
* PLEASE OPEN A TICKET WITH THIS INFORMATION:
|
||||||
|
https://trac.macports.org/newticket
|
||||||
|
* Summary: `vcs_blackbox @1.20150222 Update to latest upstream`
|
||||||
|
* Description: ```New upstream of vcs_blackbox.
|
||||||
|
github.setup and checksums updated.```
|
||||||
|
* Type: `update`
|
||||||
|
* Component: `ports`
|
||||||
|
* Port: `vcs_blackbox`
|
||||||
|
* Keywords: `maintainer haspatch`
|
||||||
|
* Attach this file: `Portfile-vcs_blackbox.diff`
|
||||||
|
|
||||||
|
Step 3: Watch for the update to happen.
|
||||||
|
|
||||||
|
# Updating MacPorts (manual)
|
||||||
|
|
||||||
|
This is the old, manual, procedure. If the automated procedure fails to work, these notes may or may not be helpful.
|
||||||
|
|
||||||
|
The ultimate result of the script should be the output of `diff -u Portfile.orig Portfile` which is sent as an attachment to MacPorts. The new `Portfile` should have these changes:
|
||||||
|
|
||||||
|
1. The `github.setup` line should have a new version number.
|
||||||
|
2. The `checksums` line(s) should have updated checksums.
|
||||||
|
|
||||||
|
How to generate the checksums?
|
||||||
|
|
||||||
|
The easiest way is to to make a Portfile with incorrect checksums, then run `sudo port -v checksum vcs_blackbox` to see what they should have been. Fix the file, and try again until the checksum command works.
|
||||||
|
|
||||||
|
Next run `port lint vcs_blackbox` and make sure it has no errors.
|
||||||
|
|
||||||
|
Some useful commands:
|
||||||
|
|
||||||
|
Change repos in sources.conf:
|
||||||
|
```
|
||||||
|
sudo vi /opt/local/etc/macports/sources.conf
|
||||||
|
Add this line early in the file:
|
||||||
|
file:///var/tmp/ports
|
||||||
|
```
|
||||||
|
|
||||||
|
Add a local repo:
|
||||||
|
```
|
||||||
|
fgrep >/dev/null -x 'file:///var/tmp/ports' /opt/local/etc/macports/sources.conf || sudo sed -i -e '1s@^@file:///var/tmp/ports\'$'\n@' /opt/local/etc/macports/sources.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove the local repo:
|
||||||
|
```
|
||||||
|
sudo sed -i -e '\@^file:///var/tmp/ports@d' /opt/local/etc/macports/sources.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Test a Portfile:
|
||||||
|
```
|
||||||
|
sudo port uninstall vcs_blackbox
|
||||||
|
sudo port clean --all vcs_blackbox
|
||||||
|
rm -rf ~/.macports/opt/local/var/macports/sources/rsync.macports.org/release/tarballs/ports/security/vcs_blackbox/
|
||||||
|
rm -rf /var/tmp/ports
|
||||||
|
mkdir -p /var/tmp/ports/security/vcs_blackbox
|
||||||
|
cp Portfile /var/tmp/ports/security/vcs_blackbox
|
||||||
|
cd /var/tmp/ports && portindex
|
||||||
|
sudo port -v checksum vcs_blackbox
|
||||||
|
sudo port install vcs_blackbox
|
||||||
|
```
|
||||||
@@ -7,69 +7,91 @@
|
|||||||
# Usage:
|
# Usage:
|
||||||
#
|
#
|
||||||
# set -e
|
# set -e
|
||||||
# . _blackbox_common.sh
|
# source "${0%/*}/_blackbox_common.sh"
|
||||||
|
|
||||||
|
# Load additional useful functions
|
||||||
|
source "${0%/*}"/_stack_lib.sh
|
||||||
|
|
||||||
|
# Where are we?
|
||||||
|
: "${BLACKBOX_HOME:="$(cd "${0%/*}" ; pwd)"}" ;
|
||||||
|
|
||||||
# Where in the VCS repo should the blackbox data be found?
|
# Where in the VCS repo should the blackbox data be found?
|
||||||
: ${BLACKBOXDATA:=keyrings/live} ; # If BLACKBOXDATA not set, set it.
|
: "${BLACKBOXDATA:=keyrings/live}" ; # If BLACKBOXDATA not set, set it.
|
||||||
|
|
||||||
# Outputs a string that is the base directory of this VCS repo.
|
|
||||||
# By side-effect, sets the variable VCS_TYPE to either 'git', 'hg',
|
# If $EDITOR is not set, set it to "vi":
|
||||||
# 'svn' or 'unknown'.
|
: "${EDITOR:=vi}" ;
|
||||||
function _determine_vcs_base_and_type() {
|
|
||||||
if git rev-parse --show-toplevel 2>/dev/null ; then
|
# Allow overriding gpg command
|
||||||
|
: "${GPG:=gpg}" ;
|
||||||
|
|
||||||
|
function physical_directory_of() {
|
||||||
|
local d=$(dirname "$1")
|
||||||
|
local f=$(basename "$1")
|
||||||
|
(cd "$d" && echo "$(pwd -P)/$f" )
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set REPOBASE to the top of the repository
|
||||||
|
# Set VCS_TYPE to 'git', 'hg', 'svn' or 'unknown'
|
||||||
|
if which >/dev/null 2>/dev/null git && git rev-parse --show-toplevel >/dev/null 2>&1 ; then
|
||||||
VCS_TYPE=git
|
VCS_TYPE=git
|
||||||
elif [ -d ".svn" ] ; then
|
REPOBASE=$(git rev-parse --show-toplevel)
|
||||||
#find topmost dir with .svn sub-dir
|
elif [ -d ".svn" ] ; then
|
||||||
|
# Find topmost dir with .svn sub-dir
|
||||||
parent=""
|
parent=""
|
||||||
grandparent="."
|
grandparent="."
|
||||||
mydir=`pwd`
|
|
||||||
while [ -d "$grandparent/.svn" ]; do
|
while [ -d "$grandparent/.svn" ]; do
|
||||||
parent=$grandparent
|
parent=$grandparent
|
||||||
grandparent="$parent/.."
|
grandparent="$parent/.."
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ ! -z "$parent" ]; then
|
REPOBASE=$(cd "$parent" ; pwd)
|
||||||
cd $parent
|
|
||||||
echo `pwd`
|
|
||||||
else
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
cd $mydir
|
|
||||||
VCS_TYPE=svn
|
VCS_TYPE=svn
|
||||||
elif hg root 2>/dev/null ; then
|
elif which >/dev/null 2>/dev/null hg && hg root >/dev/null 2>&1 ; then
|
||||||
# NOTE: hg has to be tested last because it always "succeeds".
|
# NOTE: hg has to be tested last because it always "succeeds".
|
||||||
VCS_TYPE=hg
|
VCS_TYPE=hg
|
||||||
else
|
REPOBASE=$(hg root 2>/dev/null)
|
||||||
echo /dev/null
|
else
|
||||||
|
# We aren't in a repo at all. Assume the cwd is the root
|
||||||
|
# of the tree.
|
||||||
VCS_TYPE=unknown
|
VCS_TYPE=unknown
|
||||||
fi
|
REPOBASE="$(pwd)"
|
||||||
export VCS_TYPE
|
fi
|
||||||
# FIXME: Verify this function by checking for .hg or .git
|
export VCS_TYPE
|
||||||
# after determining what we believe to be the answer.
|
export REPOBASE=$(physical_directory_of "$REPOBASE")
|
||||||
}
|
# FIXME: Verify this function by checking for .hg or .git
|
||||||
|
# after determining what we believe to be the answer.
|
||||||
|
|
||||||
REPOBASE=$(_determine_vcs_base_and_type)
|
|
||||||
KEYRINGDIR="$REPOBASE/$BLACKBOXDATA"
|
KEYRINGDIR="$REPOBASE/$BLACKBOXDATA"
|
||||||
BB_ADMINS_FILE="blackbox-admins.txt"
|
BB_ADMINS_FILE="blackbox-admins.txt"
|
||||||
BB_ADMINS="${KEYRINGDIR}/${BB_ADMINS_FILE}"
|
BB_ADMINS="${KEYRINGDIR}/${BB_ADMINS_FILE}"
|
||||||
BB_FILES_FILE="blackbox-files.txt"
|
BB_FILES_FILE="blackbox-files.txt"
|
||||||
BB_FILES="${KEYRINGDIR}/${BB_FILES_FILE}"
|
BB_FILES="${KEYRINGDIR}/${BB_FILES_FILE}"
|
||||||
SECRING="${KEYRINGDIR}/secring.gpg"
|
SECRING="${KEYRINGDIR}/secring.gpg"
|
||||||
PUBRING="${KEYRINGDIR}/pubring.gpg"
|
: "${DECRYPT_UMASK:=0022}" ;
|
||||||
: ${DECRYPT_UMASK:=o=} ;
|
# : ${DECRYPT_UMASK:=o=} ;
|
||||||
|
|
||||||
|
# Checks if $1 is 0 bytes, and if $1/keyrings
|
||||||
|
# is a directory
|
||||||
|
function is_blackbox_repo() {
|
||||||
|
if [[ -n "$1" ]] && [[ -d "$1/keyrings" ]]; then
|
||||||
|
return 0 # Yep, its a repo
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Return error if not on cryptlist.
|
# Return error if not on cryptlist.
|
||||||
function is_on_cryptlist() {
|
function is_on_cryptlist() {
|
||||||
# Assumes $1 does NOT have the .gpg extension
|
# Assumes $1 does NOT have the .gpg extension
|
||||||
local rname=$(vcs_relative_path "$1")
|
file_contains_line "$BB_FILES" "$(vcs_relative_path "$1")"
|
||||||
grep -F -x -s -q "$rname" "$BB_FILES"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Exit with error if a file exists.
|
# Exit with error if a file exists.
|
||||||
function fail_if_exists() {
|
function fail_if_exists() {
|
||||||
if [[ -f "$1" ]]; then
|
if [[ -f "$1" ]]; then
|
||||||
echo ERROR: "$1" exists. "$2"
|
echo ERROR: "$1" exists. "$2" >&2
|
||||||
echo Exiting...
|
echo Exiting... >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -77,18 +99,17 @@ function fail_if_exists() {
|
|||||||
# Exit with error if a file is missing.
|
# Exit with error if a file is missing.
|
||||||
function fail_if_not_exists() {
|
function fail_if_not_exists() {
|
||||||
if [[ ! -f "$1" ]]; then
|
if [[ ! -f "$1" ]]; then
|
||||||
echo ERROR: "$1" not found. "$2"
|
echo ERROR: "$1" not found. "$2" >&2
|
||||||
echo Exiting...
|
echo Exiting... >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Exit we we aren't in a VCS repo.
|
# Exit we we aren't in a VCS repo.
|
||||||
function fail_if_not_in_repo() {
|
function fail_if_not_in_repo() {
|
||||||
_determine_vcs_base_and_type
|
|
||||||
if [[ $VCS_TYPE = "unknown" ]]; then
|
if [[ $VCS_TYPE = "unknown" ]]; then
|
||||||
echo "ERROR: This must be run in a VCS repo: git, hg, or svn."
|
echo "ERROR: This must be run in a VCS repo: git, hg, or svn." >&2
|
||||||
echo Exiting...
|
echo Exiting... >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -100,9 +121,9 @@ function fail_if_not_on_cryptlist() {
|
|||||||
local name="$1"
|
local name="$1"
|
||||||
|
|
||||||
if ! is_on_cryptlist "$name" ; then
|
if ! is_on_cryptlist "$name" ; then
|
||||||
echo "ERROR: $name not found in $BB_FILES"
|
echo "ERROR: $name not found in $BB_FILES" >&2
|
||||||
echo "PWD="$(/bin/pwd)
|
echo "PWD=$(/bin/pwd)" >&2
|
||||||
echo 'Exiting...'
|
echo 'Exiting...' >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -110,48 +131,75 @@ function fail_if_not_on_cryptlist() {
|
|||||||
# Exit with error if keychain contains secret keys.
|
# Exit with error if keychain contains secret keys.
|
||||||
function fail_if_keychain_has_secrets() {
|
function fail_if_keychain_has_secrets() {
|
||||||
if [[ -s ${SECRING} ]]; then
|
if [[ -s ${SECRING} ]]; then
|
||||||
echo 'ERROR: The file' "$SECRING" 'should be empty.'
|
echo 'ERROR: The file' "$SECRING" 'should be empty.' >&2
|
||||||
echo 'Did someone accidentally add this private key to the ring?'
|
echo 'Did someone accidentally add this private key to the ring?' >&2
|
||||||
echo 'Exiting...'
|
echo 'Exiting...' >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_pubring_path() {
|
||||||
|
if [[ -f "${KEYRINGDIR}/pubring.gpg" ]]; then
|
||||||
|
echo "${KEYRINGDIR}/pubring.gpg"
|
||||||
|
else
|
||||||
|
echo "${KEYRINGDIR}/pubring.kbx"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Output the unencrypted filename.
|
# Output the unencrypted filename.
|
||||||
function get_unencrypted_filename() {
|
function get_unencrypted_filename() {
|
||||||
echo $(dirname "$1")/$(basename "$1" .gpg) | sed -e 's#^\./##'
|
echo "$(dirname "$1")/$(basename "$1" .gpg)" | sed -e 's#^\./##'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Output the encrypted filename.
|
# Output the encrypted filename.
|
||||||
function get_encrypted_filename() {
|
function get_encrypted_filename() {
|
||||||
echo $(dirname "$1")/$(basename "$1" .gpg).gpg | sed -e 's#^\./##'
|
echo "$(dirname "$1")/$(basename "$1" .gpg).gpg" | sed -e 's#^\./##'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prepare keychain for use.
|
# Prepare keychain for use.
|
||||||
function prepare_keychain() {
|
function prepare_keychain() {
|
||||||
echo '========== Importing keychain: START'
|
echo '========== Importing keychain: START' >&2
|
||||||
gpg --import "${PUBRING}" 2>&1 | egrep -v 'not changed$'
|
$GPG --import "$(get_pubring_path)" 2>&1 | egrep -v 'not changed$' >&2
|
||||||
echo '========== Importing keychain: DONE'
|
echo '========== Importing keychain: DONE' >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add file to list of encrypted files.
|
# Add file to list of encrypted files.
|
||||||
function add_filename_to_cryptlist() {
|
function add_filename_to_cryptlist() {
|
||||||
# If the name is already on the list, this is a no-op.
|
# If the name is already on the list, this is a no-op.
|
||||||
# However no matter what the datestamp is updated.
|
# However no matter what the datestamp is updated.
|
||||||
local name=$(vcs_relative_path "$1")
|
|
||||||
|
|
||||||
if grep -s -q "$name" "$BB_FILES" ; then
|
# https://github.com/koalaman/shellcheck/wiki/SC2155
|
||||||
echo ========== File is registered. No need to add to list.
|
local name
|
||||||
|
name=$(vcs_relative_path "$1")
|
||||||
|
|
||||||
|
if file_contains_line "$BB_FILES" "$name" ; then
|
||||||
|
echo "========== File is registered. No need to add to list."
|
||||||
else
|
else
|
||||||
echo ========== Adding file to list.
|
echo "========== Adding file to list."
|
||||||
touch "$BB_FILES"
|
touch "$BB_FILES"
|
||||||
sort -u -o "$BB_FILES" <(echo "$name") "$BB_FILES"
|
sort -u -o "$BB_FILES" <(echo "$name") "$BB_FILES"
|
||||||
fi
|
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.
|
||||||
|
|
||||||
|
# https://github.com/koalaman/shellcheck/wiki/SC2155
|
||||||
|
local name
|
||||||
|
name=$(vcs_relative_path "$1")
|
||||||
|
|
||||||
|
if ! file_contains_line "$BB_FILES" "$name" ; 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:
|
# Print out who the current BB ADMINS are:
|
||||||
function disclose_admins() {
|
function disclose_admins() {
|
||||||
echo ========== blackbox administrators are:
|
echo "========== blackbox administrators are:"
|
||||||
cat "$BB_ADMINS"
|
cat "$BB_ADMINS"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,9 +210,9 @@ function encrypt_file() {
|
|||||||
unencrypted="$1"
|
unencrypted="$1"
|
||||||
encrypted="$2"
|
encrypted="$2"
|
||||||
|
|
||||||
echo "========== Encrypting: $unencrypted"
|
echo "========== Encrypting: $unencrypted" >&2
|
||||||
gpg --yes --trust-model=always --encrypt -o "$encrypted" $(awk '{ print "-r" $1 }' < "$BB_ADMINS") "$unencrypted"
|
$GPG --use-agent --yes --trust-model=always --encrypt -o "$encrypted" $(awk '{ print "-r" $1 }' < "$BB_ADMINS") "$unencrypted" >&2
|
||||||
echo '========== Encrypting: DONE'
|
echo '========== Encrypting: DONE' >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
# Decrypt .gpg file, asking "yes/no" before overwriting unencrypted file.
|
# Decrypt .gpg file, asking "yes/no" before overwriting unencrypted file.
|
||||||
@@ -175,12 +223,12 @@ function decrypt_file() {
|
|||||||
encrypted="$1"
|
encrypted="$1"
|
||||||
unencrypted="$2"
|
unencrypted="$2"
|
||||||
|
|
||||||
echo "========== EXTRACTING $unencrypted"
|
echo "========== EXTRACTING $unencrypted" >&2
|
||||||
|
|
||||||
old_umask=$(umask)
|
old_umask=$(umask)
|
||||||
umask $DECRYPT_UMASK
|
umask "$DECRYPT_UMASK"
|
||||||
gpg -q --decrypt -o "$unencrypted" "$encrypted"
|
$GPG --use-agent -q --decrypt -o "$unencrypted" "$encrypted" >&2
|
||||||
umask $old_umask
|
umask "$old_umask"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Decrypt .gpg file, overwriting unencrypted file if it exists.
|
# Decrypt .gpg file, overwriting unencrypted file if it exists.
|
||||||
@@ -200,13 +248,13 @@ function decrypt_file_overwrite() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
old_umask=$(umask)
|
old_umask=$(umask)
|
||||||
umask $DECRYPT_UMASK
|
umask "$DECRYPT_UMASK"
|
||||||
gpg --yes -q --decrypt -o "$unencrypted" "$encrypted"
|
$GPG --use-agent --yes -q --decrypt -o "$unencrypted" "$encrypted" >&2
|
||||||
umask $old_umask
|
umask "$old_umask"
|
||||||
|
|
||||||
new_hash=$(md5sum_file "$unencrypted")
|
new_hash=$(md5sum_file "$unencrypted")
|
||||||
if [[ $old_hash != $new_hash ]]; then
|
if [[ "$old_hash" != "$new_hash" ]]; then
|
||||||
echo "========== EXTRACTED $unencrypted"
|
echo "========== EXTRACTED $unencrypted" >&2
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,10 +265,10 @@ function shred_file() {
|
|||||||
local OPT
|
local OPT
|
||||||
name="$1"
|
name="$1"
|
||||||
|
|
||||||
if which shred >/dev/null ; then
|
if which shred >/dev/null 2>/dev/null ; then
|
||||||
CMD=shred
|
CMD=shred
|
||||||
OPT=-u
|
OPT=-u
|
||||||
elif which srm >/dev/null ; then
|
elif which srm >/dev/null 2>/dev/null ; then
|
||||||
#NOTE: srm by default uses 35-pass Gutmann algorithm
|
#NOTE: srm by default uses 35-pass Gutmann algorithm
|
||||||
CMD=srm
|
CMD=srm
|
||||||
OPT=-f
|
OPT=-f
|
||||||
@@ -244,17 +292,69 @@ function enumerate_subdirs() {
|
|||||||
while read filename; do
|
while read filename; do
|
||||||
dir=$(dirname "$filename")
|
dir=$(dirname "$filename")
|
||||||
while [[ $dir != '.' && $dir != '/' ]]; do
|
while [[ $dir != '.' && $dir != '/' ]]; do
|
||||||
echo $dir
|
echo "$dir"
|
||||||
dir=$(dirname $dir)
|
dir=$(dirname "$dir")
|
||||||
done
|
done
|
||||||
done <"$listfile" | sort -u
|
done <"$listfile" | sort -u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# chdir to the base of the repo.
|
||||||
|
function change_to_vcs_root() {
|
||||||
|
# if vcs_root not explicitly defined, use $REPOBASE
|
||||||
|
|
||||||
|
local rbase=${1:-$REPOBASE} # use $1 but if unset use $REPOBASE
|
||||||
|
|
||||||
|
cd "$rbase"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 is a string pointing to a directory. Outputs a
|
||||||
|
# list of valid blackbox repos,relative to $1
|
||||||
|
function enumerate_blackbox_repos() {
|
||||||
|
if [[ -z "$1" ]]; then
|
||||||
|
echo "enumerate_blackbox_repos: ERROR: No Repo provided to Enumerate"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# https://github.com/koalaman/shellcheck/wiki/Sc2045
|
||||||
|
for dir in $1*/; do
|
||||||
|
if is_blackbox_repo "$dir"; then
|
||||||
|
echo "$dir"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
# Output the path of a file relative to the repo base
|
# Output the path of a file relative to the repo base
|
||||||
function vcs_relative_path() {
|
function vcs_relative_path() {
|
||||||
# Usage: vcs_relative_path file
|
# Usage: vcs_relative_path file
|
||||||
local name="$1"
|
local name="$1"
|
||||||
python -c 'import os ; print(os.path.relpath("'$(pwd -P)'/'"$name"'", "'"$REPOBASE"'"))'
|
#python -c 'import os ; print(os.path.relpath("'"$(pwd -P)"'/'"$name"'", "'"$REPOBASE"'"))'
|
||||||
|
local p=$( printf "%s" "$( pwd -P )/${1}" | sed 's#//*#/#g' )
|
||||||
|
local name="${p#$REPOBASE}"
|
||||||
|
name=$( printf "%s" "$name" | sed 's#^/##g' | sed 's#/$##g' )
|
||||||
|
printf "%s" "$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Removes a line from a text file
|
||||||
|
function remove_line() {
|
||||||
|
local tempfile
|
||||||
|
|
||||||
|
make_self_deleting_tempfile tempfile
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine if a file contains a given line
|
||||||
|
function file_contains_line() {
|
||||||
|
# $1: the file
|
||||||
|
# $2: the line
|
||||||
|
grep -xsqF "$2" "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -271,35 +371,40 @@ function md5sum_file() {
|
|||||||
Darwin )
|
Darwin )
|
||||||
md5 -r "$1" | awk '{ print $1 }'
|
md5 -r "$1" | awk '{ print $1 }'
|
||||||
;;
|
;;
|
||||||
Linux )
|
Linux | CYGWIN* | MINGW* )
|
||||||
md5sum "$1" | awk '{ print $1 }'
|
|
||||||
;;
|
|
||||||
CYGWIN* )
|
|
||||||
md5sum "$1" | awk '{ print $1 }'
|
md5sum "$1" | awk '{ print $1 }'
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
echo 'ERROR: Unknown OS. Exiting.'
|
echo 'ERROR: Unknown OS. Exiting. (md5sum_file)'
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cp_permissions() {
|
||||||
|
# Copy the perms of $1 onto $2 .. end.
|
||||||
|
case $(uname -s) in
|
||||||
|
Darwin )
|
||||||
|
chmod $( stat -f '%p' "$1" ) "${@:2}"
|
||||||
|
;;
|
||||||
|
Linux | CYGWIN* | MINGW* )
|
||||||
|
chmod --reference "$1" "${@:2}"
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo 'ERROR: Unknown OS. Exiting. (cp_permissions)'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Abstract the difference between git and hg:
|
# Abstract the difference between git and hg:
|
||||||
#
|
#
|
||||||
|
|
||||||
# Are we in git, hg, or unknown repo?
|
|
||||||
function which_vcs() {
|
|
||||||
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_$VCS_TYPE "$@"
|
||||||
}
|
}
|
||||||
# Mercurial
|
# Mercurial
|
||||||
function is_in_hg() {
|
function is_in_hg() {
|
||||||
@@ -334,73 +439,196 @@ function is_in_svn() {
|
|||||||
echo false
|
echo false
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
# Perforce
|
||||||
|
function is_in_p4() {
|
||||||
|
local filename
|
||||||
|
filename="$1"
|
||||||
|
|
||||||
|
if p4 list "$filename" ; then
|
||||||
|
echo true
|
||||||
|
else
|
||||||
|
echo false
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
# No repo
|
||||||
|
function is_in_unknown() {
|
||||||
|
echo true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Add a file to the repo (but don't commit it).
|
# Add a file to the repo (but don't commit it).
|
||||||
function vcs_add() {
|
function vcs_add() {
|
||||||
vcs_add_$(which_vcs) """$@"""
|
vcs_add_$VCS_TYPE "$@"
|
||||||
}
|
}
|
||||||
# Mercurial
|
# Mercurial
|
||||||
function vcs_add_hg() {
|
function vcs_add_hg() {
|
||||||
hg add """$@"""
|
hg add "$@"
|
||||||
}
|
}
|
||||||
# Git
|
# Git
|
||||||
function vcs_add_git() {
|
function vcs_add_git() {
|
||||||
git add """$@"""
|
git add "$@"
|
||||||
}
|
}
|
||||||
# Subversion
|
# Subversion
|
||||||
function vcs_add_svn() {
|
function vcs_add_svn() {
|
||||||
svn add --parents """$@"""
|
svn add --parents "$@"
|
||||||
|
}
|
||||||
|
# Perfoce
|
||||||
|
function vcs_add_p4() {
|
||||||
|
p4 add "$@"
|
||||||
|
}
|
||||||
|
# No repo
|
||||||
|
function vcs_add_unknown() {
|
||||||
|
:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Commit a file to the repo
|
# Commit a file to the repo
|
||||||
function vcs_commit() {
|
function vcs_commit() {
|
||||||
vcs_commit_$(which_vcs) """$@"""
|
vcs_commit_$VCS_TYPE "$@"
|
||||||
}
|
}
|
||||||
# Mercurial
|
# Mercurial
|
||||||
function vcs_commit_hg() {
|
function vcs_commit_hg() {
|
||||||
hg commit -m"""$@"""
|
hg commit -m "$@"
|
||||||
}
|
}
|
||||||
# Git
|
# Git
|
||||||
function vcs_commit_git() {
|
function vcs_commit_git() {
|
||||||
git commit -m"""$@"""
|
git commit -m "$@"
|
||||||
}
|
}
|
||||||
# Subversion
|
# Subversion
|
||||||
function vcs_commit_svn() {
|
function vcs_commit_svn() {
|
||||||
svn commit -m"""$@"""
|
svn commit -m "$@"
|
||||||
|
}
|
||||||
|
# Perforce
|
||||||
|
function vcs_commit_p4() {
|
||||||
|
p4 submit -d "$@"
|
||||||
|
}
|
||||||
|
# No repo
|
||||||
|
function vcs_commit_unknown() {
|
||||||
|
:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 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 vcs_remove() {
|
function vcs_remove() {
|
||||||
vcs_remove_$(which_vcs) """$@"""
|
vcs_remove_$VCS_TYPE "$@"
|
||||||
}
|
}
|
||||||
# Mercurial
|
# Mercurial
|
||||||
function vcs_remove_hg() {
|
function vcs_remove_hg() {
|
||||||
hg rm -A -- """$@"""
|
hg rm -A -- "$@"
|
||||||
}
|
}
|
||||||
# Git
|
# Git
|
||||||
function vcs_remove_git() {
|
function vcs_remove_git() {
|
||||||
git rm --ignore-unmatch -f -- """$@"""
|
git rm --ignore-unmatch -f -- "$@"
|
||||||
}
|
}
|
||||||
# Subversion
|
# Subversion
|
||||||
function vcs_remove_svn() {
|
function vcs_remove_svn() {
|
||||||
svn delete """$@"""
|
svn delete "$@"
|
||||||
|
}
|
||||||
|
# Perforce
|
||||||
|
function vcs_remove_p4() {
|
||||||
|
p4 delete "$@"
|
||||||
|
}
|
||||||
|
# No repo
|
||||||
|
function vcs_remove_unknown() {
|
||||||
|
:
|
||||||
}
|
}
|
||||||
|
|
||||||
function change_to_root() {
|
# Get a path for the ignore file if possible in current vcs
|
||||||
# If BASEDIR is not set, use REPOBASE.
|
function vcs_ignore_file_path() {
|
||||||
if [[ "$BASEDIR" = "" ]]; then
|
vcs_ignore_file_path_$VCS_TYPE
|
||||||
BASEDIR="$REPOBASE"
|
}
|
||||||
fi
|
# Mercurial
|
||||||
|
function vcs_ignore_file_path_hg() {
|
||||||
|
echo "$REPOBASE/.hgignore"
|
||||||
|
}
|
||||||
|
# Git
|
||||||
|
function vcs_ignore_file_path_git() {
|
||||||
|
echo "$REPOBASE/.gitignore"
|
||||||
|
}
|
||||||
|
|
||||||
if [[ "$BASEDIR" = "/dev/null" ]]; then
|
|
||||||
echo 'WARNING: Not in a VCS repo. Not changing directory.'
|
# Ignore a file in a repo. If it was already ignored, this is a no-op.
|
||||||
else
|
function vcs_ignore() {
|
||||||
echo "CDing to $BASEDIR"
|
local file
|
||||||
cd "$BASEDIR"
|
for file in "$@"; do
|
||||||
|
vcs_ignore_$VCS_TYPE "$file"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
# Mercurial
|
||||||
|
function vcs_ignore_hg() {
|
||||||
|
vcs_ignore_generic_file "$(vcs_ignore_file_path)" "$file"
|
||||||
|
}
|
||||||
|
# Git
|
||||||
|
function vcs_ignore_git() {
|
||||||
|
vcs_ignore_generic_file "$(vcs_ignore_file_path)" "$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 ! file_contains_line "$1" "$file" ; 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_$VCS_TYPE "$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 file_contains_line "$1" "$file" ; then
|
||||||
|
remove_line "$1" "$file"
|
||||||
|
vcs_add "$1"
|
||||||
|
fi
|
||||||
|
if file_contains_line "$1" "${file:1}" ; 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
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
25
bin/_blackbox_common_test.sh
Executable file
25
bin/_blackbox_common_test.sh
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# _blackbox_common_test.sh -- Unit tests of functions from _blackbox_common.sh
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
. "${0%/*}/_blackbox_common.sh"
|
||||||
|
. tools/test_functions.sh
|
||||||
|
|
||||||
|
PHASE 'Test cp-permissions: TestA'
|
||||||
|
touch TestA TestB TestC TestD
|
||||||
|
chmod 0347 TestA
|
||||||
|
chmod 0700 TestB
|
||||||
|
chmod 0070 TestC
|
||||||
|
chmod 0070 TestD
|
||||||
|
cp_permissions TestA TestB TestC
|
||||||
|
# NOTE: cp_permissions is not touching TestD.
|
||||||
|
assert_file_perm '--wxr--rwx' TestA
|
||||||
|
assert_file_perm '--wxr--rwx' TestB
|
||||||
|
assert_file_perm '--wxr--rwx' TestC
|
||||||
|
assert_file_perm '----rwx---' TestD # TestD doesn't change.
|
||||||
|
rm -f TestA TestB TestC TestD
|
||||||
|
|
||||||
|
echo '========== DONE.'
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
# Library functions for bash scripts at Stack Exchange.
|
# Library functions for bash scripts at Stack Exchange.
|
||||||
|
|
||||||
|
# NOTE: This file is open sourced. Do not put Stack-proprietary code here.
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
|
#
|
||||||
# set -e
|
# set -e
|
||||||
# . _stack_lib.sh
|
# . _stack_lib.sh
|
||||||
|
|
||||||
@@ -8,13 +11,13 @@
|
|||||||
|
|
||||||
function debugmsg() {
|
function debugmsg() {
|
||||||
# Log to stderr.
|
# Log to stderr.
|
||||||
echo 1>&2 LOG: """$@"""
|
echo 1>&2 LOG: "$@"
|
||||||
:
|
:
|
||||||
}
|
}
|
||||||
|
|
||||||
function logit() {
|
function logit() {
|
||||||
# Log to stderr.
|
# Log to stderr.
|
||||||
echo 1>&2 LOG: """$@"""
|
echo 1>&2 LOG: "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
function fail_out() {
|
function fail_out() {
|
||||||
@@ -46,6 +49,48 @@ function add_on_exit()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function create_self_deleting_tempfile() {
|
||||||
|
local filename
|
||||||
|
|
||||||
|
case $(uname -s) in
|
||||||
|
Darwin )
|
||||||
|
: "${TMPDIR:=/tmp}"
|
||||||
|
filename=$(mktemp -t _stacklib_.XXXXXXXX )
|
||||||
|
;;
|
||||||
|
Linux | CYGWIN* | MINGW* )
|
||||||
|
filename=$(mktemp)
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo 'ERROR: Unknown OS. Exiting. (create_self_deleting_tempfile)'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
add_on_exit rm -f "$filename"
|
||||||
|
echo "$filename"
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_self_deleting_tempdir() {
|
||||||
|
local filename
|
||||||
|
|
||||||
|
case $(uname -s) in
|
||||||
|
Darwin )
|
||||||
|
: "${TMPDIR:=/tmp}"
|
||||||
|
filename=$(mktemp -d -t _stacklib_.XXXXXXXX )
|
||||||
|
;;
|
||||||
|
Linux | CYGWIN* | MINGW* )
|
||||||
|
filename=$(mktemp -d)
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo 'ERROR: Unknown OS. Exiting. (create_self_deleting_tempdir)'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
add_on_exit rm -rf "$filename"
|
||||||
|
echo "$filename"
|
||||||
|
}
|
||||||
|
|
||||||
# Securely and portably create a temporary file that will be deleted
|
# Securely and portably create a temporary file that will be deleted
|
||||||
# on EXIT. $1 is the variable name to store the result.
|
# on EXIT. $1 is the variable name to store the result.
|
||||||
function make_self_deleting_tempfile() {
|
function make_self_deleting_tempfile() {
|
||||||
@@ -54,17 +99,14 @@ function make_self_deleting_tempfile() {
|
|||||||
|
|
||||||
case $(uname -s) in
|
case $(uname -s) in
|
||||||
Darwin )
|
Darwin )
|
||||||
: ${TMPDIR:=/tmp} ;
|
: "${TMPDIR:=/tmp}"
|
||||||
name=$(mktemp -t _stacklib_ )
|
name=$(mktemp -t _stacklib_.XXXXXXXX )
|
||||||
;;
|
;;
|
||||||
Linux )
|
Linux | CYGWIN* | MINGW* )
|
||||||
name=$(mktemp)
|
|
||||||
;;
|
|
||||||
CYGWIN* )
|
|
||||||
name=$(mktemp)
|
name=$(mktemp)
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
echo 'ERROR: Unknown OS. Exiting.'
|
echo 'ERROR: Unknown OS. Exiting. (make_self_deleting_tempfile)'
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -79,17 +121,14 @@ function make_tempdir() {
|
|||||||
|
|
||||||
case $(uname -s) in
|
case $(uname -s) in
|
||||||
Darwin )
|
Darwin )
|
||||||
: ${TMPDIR:=/tmp} ;
|
: "${TMPDIR:=/tmp}"
|
||||||
name=$(mktemp -d -t _stacklib_ )
|
name=$(mktemp -d -t _stacklib_.XXXXXXXX )
|
||||||
;;
|
;;
|
||||||
Linux )
|
Linux | CYGWIN* | MINGW* )
|
||||||
name=$(mktemp -d)
|
|
||||||
;;
|
|
||||||
CYGWIN* )
|
|
||||||
name=$(mktemp -d)
|
name=$(mktemp -d)
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
echo 'ERROR: Unknown OS. Exiting.'
|
echo 'ERROR: Unknown OS. Exiting. (make_tempdir)'
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -99,12 +138,12 @@ function make_tempdir() {
|
|||||||
|
|
||||||
function make_self_deleting_tempdir() {
|
function make_self_deleting_tempdir() {
|
||||||
local __resultvar="$1"
|
local __resultvar="$1"
|
||||||
local dirname
|
local dname
|
||||||
|
|
||||||
make_tempdir dirname
|
make_tempdir dname
|
||||||
|
|
||||||
add_on_exit rm -rf "$dirname"
|
add_on_exit rm -rf "$dname"
|
||||||
eval $__resultvar="$dirname"
|
eval $__resultvar="$dname"
|
||||||
}
|
}
|
||||||
|
|
||||||
function fail_if_not_running_as_root() {
|
function fail_if_not_running_as_root() {
|
||||||
@@ -125,14 +164,7 @@ function fail_if_in_root_directory() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
Linux )
|
Linux | CYGWIN* | MINGW* )
|
||||||
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
|
if [[ $(stat -c'%i' / ) == $(stat -c'%i' . ) ]] ; then
|
||||||
echo 'SECURITY ALERT: The current directory is the root directory.'
|
echo 'SECURITY ALERT: The current directory is the root directory.'
|
||||||
echo 'Exiting...'
|
echo 'Exiting...'
|
||||||
@@ -140,7 +172,7 @@ function fail_if_in_root_directory() {
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
echo 'ERROR: Unknown OS. Exiting.'
|
echo 'ERROR: Unknown OS. Exiting. (fail_if_in_root_directory)'
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -9,24 +9,12 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
source ${blackbox_home}/_blackbox_common.sh
|
|
||||||
source ${blackbox_home}/_stack_lib.sh
|
|
||||||
|
|
||||||
fail_if_not_in_repo
|
fail_if_not_in_repo
|
||||||
|
|
||||||
KEYNAME="$1"
|
KEYNAME="$1"
|
||||||
: ${KEYNAME:?ERROR: First argument must be a keyname (email address)} ;
|
: "${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.
|
||||||
@@ -38,18 +26,28 @@ sort -fdu -o "$BB_ADMINS" <(echo "$1") "$BB_ADMINS"
|
|||||||
|
|
||||||
# Extract it:
|
# Extract it:
|
||||||
make_self_deleting_tempfile pubkeyfile
|
make_self_deleting_tempfile pubkeyfile
|
||||||
gpg $GPGEXPORTOPTIONS --export -a "$KEYNAME" >"$pubkeyfile"
|
|
||||||
|
# The second argument, if present, is the directory to find the GPG keys to be imported.
|
||||||
|
if [[ -z $2 ]]; then
|
||||||
|
$GPG --export -a "$KEYNAME" >"$pubkeyfile"
|
||||||
|
else
|
||||||
|
# TODO(tlim): This could probably be done with GNUPGHOME
|
||||||
|
# but that affects all commands; we just want it to affect the key export.
|
||||||
|
$GPG --homedir="$2" --export -a "$KEYNAME" >"$pubkeyfile"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $(wc -l < "$pubkeyfile") = 0 ]]; then
|
if [[ $(wc -l < "$pubkeyfile") = 0 ]]; then
|
||||||
fail_out "GPG key '$KEYNAME' not found. Please create it with: gpg --gen-key"
|
fail_out "GPG key '$KEYNAME' not found. Please create it with: $GPG --gen-key"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Import it:
|
# Import it:
|
||||||
gpg --no-permission-warning --homedir="$KEYRINGDIR" --import "$pubkeyfile"
|
$GPG --no-permission-warning --homedir="$KEYRINGDIR" --import "$pubkeyfile"
|
||||||
vcs_add "$KEYRINGDIR/pubring.gpg" "$KEYRINGDIR/trustdb.gpg" "$BB_ADMINS"
|
pubring_path=$(get_pubring_path)
|
||||||
|
vcs_add "$pubring_path" "$KEYRINGDIR/trustdb.gpg" "$BB_ADMINS"
|
||||||
|
|
||||||
# Make a suggestion:
|
# Make a suggestion:
|
||||||
echo
|
echo
|
||||||
echo
|
echo
|
||||||
echo 'NEXT STEP: You need to manually check these in:'
|
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"
|
echo ' ' $VCS_TYPE commit -m\'NEW ADMIN: $KEYNAME\' "$BLACKBOXDATA/$(basename ${pubring_path})" "$BLACKBOXDATA/trustdb.gpg" "$BLACKBOXDATA/$BB_ADMINS_FILE"
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# blackbox_cat.sh -- Decrypt a file, cat it, shred it
|
# blackbox_cat -- Decrypt a file, cat it, shred it
|
||||||
#
|
#
|
||||||
set -e
|
set -e
|
||||||
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
source ${blackbox_home}/_blackbox_common.sh
|
|
||||||
|
|
||||||
for param in """$@""" ; do
|
for param in "$@" ; do
|
||||||
shreddable=0
|
shreddable=0
|
||||||
unencrypted_file=$(get_unencrypted_filename "$param")
|
unencrypted_file=$(get_unencrypted_filename "$param")
|
||||||
if [[ ! -e "$unencrypted_file" ]]; then
|
if [[ ! -e "$unencrypted_file" ]]; then
|
||||||
blackbox_edit_start "$param"
|
"${BLACKBOX_HOME}/blackbox_edit_start" "$param"
|
||||||
shreddable=1
|
shreddable=1
|
||||||
fi
|
fi
|
||||||
cat "$unencrypted_file"
|
cat "$unencrypted_file"
|
||||||
|
|||||||
22
bin/blackbox_decrypt_all_files
Executable file
22
bin/blackbox_decrypt_all_files
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# blackbox_decrypt_all_files -- Decrypt all blackbox files (INTERACTIVE).
|
||||||
|
#
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# blackbox_decrypt_all_files [GROUP]
|
||||||
|
# GROUP is optional. If supplied, the resulting files
|
||||||
|
# are chgrp'ed to that group.
|
||||||
|
|
||||||
|
# Since this is often run in a security-critical situation, we
|
||||||
|
# force /usr/bin and /bin to the front of the PATH.
|
||||||
|
export PATH=/usr/bin:/bin:"$PATH"
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [[ -z $GPG_AGENT_INFO ]]; then
|
||||||
|
eval $(gpg-agent --daemon)
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec blackbox_postdeploy "$@"
|
||||||
34
bin/blackbox_deregister_file
Executable file
34
bin/blackbox_deregister_file
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
#!/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.
|
||||||
|
# The unencrypted file, if it exists, will be left alone.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
|
|
||||||
|
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_remove "$encrypted_file"
|
||||||
|
vcs_add "$BB_FILES"
|
||||||
|
|
||||||
|
vcs_commit "Removing from blackbox: ${unencrypted_file}" "$BB_FILES" "$encrypted_file"
|
||||||
|
echo "========== UPDATING VCS: DONE"
|
||||||
|
echo "Local repo updated. Please push when ready."
|
||||||
|
echo " $VCS_TYPE push"
|
||||||
52
bin/blackbox_diff
Executable file
52
bin/blackbox_diff
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# blackbox_diff -- Show all differences.
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
|
|
||||||
|
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 -r -p 'Press CTRL-C now to stop. ENTER to continue: '
|
||||||
|
fi
|
||||||
|
|
||||||
|
prepare_keychain
|
||||||
|
|
||||||
|
modified_files=()
|
||||||
|
modifications=()
|
||||||
|
echo '========== DIFFING FILES: START'
|
||||||
|
while IFS= read <&99 -r unencrypted_file; do
|
||||||
|
unencrypted_file=$(get_unencrypted_filename "$unencrypted_file")
|
||||||
|
encrypted_file=$(get_encrypted_filename "$unencrypted_file")
|
||||||
|
fail_if_not_on_cryptlist "$unencrypted_file"
|
||||||
|
if [[ -f "$unencrypted_file" ]]; then
|
||||||
|
out=$(diff -u <($GPG --yes -q --decrypt "$encrypted_file") "$unencrypted_file" || true)
|
||||||
|
if [ "$out" != "" ]; then
|
||||||
|
modified_files+=("$unencrypted_file")
|
||||||
|
modifications+=("$out")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done 99<"$BB_FILES"
|
||||||
|
modified_files_number=${#modified_files[@]}
|
||||||
|
for (( i=0; i<${modified_files_number}; i++ )); do
|
||||||
|
echo ========== PROCESSING '"'${modified_files[$i]}'"'
|
||||||
|
echo -e "${modifications[$i]}\n"
|
||||||
|
done
|
||||||
|
echo '========== DIFFING FILES: DONE'
|
||||||
|
|
||||||
|
fail_if_keychain_has_secrets
|
||||||
|
|
||||||
|
echo '========== DONE.'
|
||||||
|
|
||||||
|
if [ ${#modified_files[@]} -eq 0 ] ; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 'Likely next steps:'
|
||||||
|
for f in "${modified_files[@]}" ; do
|
||||||
|
echo " blackbox_edit_end" '"'$f'"'
|
||||||
|
done
|
||||||
@@ -1,27 +1,33 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# blackbox_edit.sh -- Decrypt a file temporarily for edition, then re-encrypts it again
|
# blackbox_edit -- Decrypt a file temporarily for edition, then re-encrypts it again
|
||||||
#
|
#
|
||||||
set -e
|
set -e
|
||||||
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
source ${blackbox_home}/_blackbox_common.sh
|
|
||||||
|
for param in "$@" ; do
|
||||||
|
|
||||||
for param in """$@""" ; do
|
|
||||||
unencrypted_file=$(get_unencrypted_filename "$param")
|
unencrypted_file=$(get_unencrypted_filename "$param")
|
||||||
if ! is_on_cryptlist "$param" && ! is_on_cryptlist "$unencrypted_file" ; then
|
encrypted_file=$(get_encrypted_filename "$param")
|
||||||
|
|
||||||
|
echo >&2 ========== PLAINFILE '"'$unencrypted_file'"'
|
||||||
|
echo >&2 ========== ENCRYPTED '"'$encrypted_file'"'
|
||||||
|
|
||||||
|
if ! is_on_cryptlist "$encrypted_file" && ! is_on_cryptlist "$unencrypted_file" ; then
|
||||||
read -r -p "Encrypt file $param? (y/n) " ans
|
read -r -p "Encrypt file $param? (y/n) " ans
|
||||||
case "$ans" in
|
case "$ans" in
|
||||||
y* | Y*)
|
y* | Y*)
|
||||||
blackbox_register_new_file "$param"
|
"${BLACKBOX_HOME}/blackbox_register_new_file" "$unencrypted_file"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo 'Skipping...'
|
echo >&2 'Skipping...'
|
||||||
continue
|
continue
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
blackbox_edit_start "$param"
|
"${BLACKBOX_HOME}/blackbox_edit_start" "$unencrypted_file"
|
||||||
$EDITOR $(get_unencrypted_filename $param)
|
$EDITOR "$(get_unencrypted_filename "$unencrypted_file")"
|
||||||
blackbox_edit_end "$param"
|
"${BLACKBOX_HOME}/blackbox_edit_end" "$unencrypted_file"
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -5,23 +5,31 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
source ${blackbox_home}/_blackbox_common.sh
|
|
||||||
|
|
||||||
unencrypted_file=$(get_unencrypted_filename "$1")
|
next_steps=()
|
||||||
encrypted_file=$(get_encrypted_filename "$1")
|
|
||||||
echo ========== PLAINFILE "$unencrypted_file"
|
|
||||||
echo ========== ENCRYPTED "$encrypted_file"
|
|
||||||
|
|
||||||
fail_if_not_on_cryptlist "$unencrypted_file"
|
for param in "$@" ; do
|
||||||
fail_if_not_exists "$unencrypted_file" "No unencrypted version to encrypt!"
|
|
||||||
fail_if_keychain_has_secrets
|
|
||||||
|
|
||||||
encrypt_file "$unencrypted_file" "$encrypted_file"
|
unencrypted_file=$(get_unencrypted_filename "$param")
|
||||||
shred_file "$unencrypted_file"
|
encrypted_file=$(get_encrypted_filename "$param")
|
||||||
|
|
||||||
_determine_vcs_base_and_type
|
echo >&2 ========== PLAINFILE '"'$unencrypted_file'"'
|
||||||
|
echo >&2 ========== ENCRYPTED '"'$encrypted_file'"'
|
||||||
|
|
||||||
echo "========== UPDATED ${encrypted_file}"
|
fail_if_not_on_cryptlist "$unencrypted_file"
|
||||||
echo "Likely next step:"
|
fail_if_not_exists "$unencrypted_file" "No unencrypted version to encrypt!"
|
||||||
echo " $VCS_TYPE commit -m\"${encrypted_file} updated\" $encrypted_file"
|
fail_if_keychain_has_secrets
|
||||||
|
|
||||||
|
encrypt_file "$unencrypted_file" "$encrypted_file"
|
||||||
|
shred_file "$unencrypted_file"
|
||||||
|
echo >&2 ========== UPDATED '"'$encrypted_file'"'
|
||||||
|
next_steps+=( " $VCS_TYPE commit -m\"${encrypted_file} updated\" \"$encrypted_file\"" )
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
echo >&2 "Likely next step:"
|
||||||
|
for x in "${next_steps[@]}"
|
||||||
|
do
|
||||||
|
echo >&2 "$x"
|
||||||
|
done
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# blackbox_edit_start.sh -- Decrypt a file for editing.
|
# blackbox_edit_start -- Decrypt a file for editing.
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
source ${blackbox_home}/_blackbox_common.sh
|
|
||||||
|
for param in "$@" ; do
|
||||||
|
|
||||||
for param in """$@""" ; do
|
|
||||||
unencrypted_file=$(get_unencrypted_filename "$param")
|
unencrypted_file=$(get_unencrypted_filename "$param")
|
||||||
encrypted_file=$(get_encrypted_filename "$param")
|
encrypted_file=$(get_encrypted_filename "$param")
|
||||||
echo ========== PLAINFILE "$unencrypted_file"
|
|
||||||
|
echo >&2 ========== PLAINFILE '"'$unencrypted_file'"'
|
||||||
|
|
||||||
fail_if_not_on_cryptlist "$unencrypted_file"
|
fail_if_not_on_cryptlist "$unencrypted_file"
|
||||||
fail_if_not_exists "$encrypted_file" "This should not happen."
|
fail_if_not_exists "$encrypted_file" "This should not happen."
|
||||||
@@ -19,10 +20,12 @@ for param in """$@""" ; do
|
|||||||
rm -f "$unencrypted_file"
|
rm -f "$unencrypted_file"
|
||||||
fi
|
fi
|
||||||
if [[ -f "$unencrypted_file" ]]; then
|
if [[ -f "$unencrypted_file" ]]; then
|
||||||
echo SKIPPING: "$1" "Will not overwrite non-empty files."
|
echo >&2 SKIPPING: "$1" "Will not overwrite non-empty files."
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
prepare_keychain
|
prepare_keychain
|
||||||
|
# FIXME(tlim): prepare_keychain only needs to run once, outside of the loop.
|
||||||
decrypt_file "$encrypted_file" "$unencrypted_file"
|
decrypt_file "$encrypted_file" "$unencrypted_file"
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -9,10 +9,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
source ${blackbox_home}/_blackbox_common.sh
|
|
||||||
|
|
||||||
_determine_vcs_base_and_type # Sets VCS_TYPE
|
|
||||||
|
|
||||||
if [[ $1 != 'yes' ]]; then
|
if [[ $1 != 'yes' ]]; then
|
||||||
read -r -p "Enable blackbox for this $VCS_TYPE repo? (yes/no) " ans
|
read -r -p "Enable blackbox for this $VCS_TYPE repo? (yes/no) " ans
|
||||||
@@ -22,34 +19,19 @@ if [[ $1 != 'yes' ]]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo cd "$REPOBASE"
|
change_to_vcs_root
|
||||||
cd "$REPOBASE"
|
|
||||||
|
|
||||||
echo VCS_TYPE: $VCS_TYPE
|
echo VCS_TYPE: $VCS_TYPE
|
||||||
|
vcs_ignore keyrings/live/pubring.gpg~ keyrings/live/pubring.kbx~ keyrings/live/secring.gpg
|
||||||
if [[ $VCS_TYPE = "git" || $VCS_TYPE = "hg" ]]; then
|
|
||||||
# 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
|
|
||||||
elif [[ $VCS_TYPE = "svn" ]]; then
|
|
||||||
# add file to svn ignore propset
|
|
||||||
IGNOREFILE="";
|
|
||||||
svn propset svn:ignore 'pubring.gpg~
|
|
||||||
secring.gpg' .
|
|
||||||
svn commit -m "ignore file list"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make directories
|
# Make directories
|
||||||
mkdir -p "${KEYRINGDIR}"
|
mkdir -p "${KEYRINGDIR}"
|
||||||
vcs_add "${KEYRINGDIR}"
|
vcs_add "${KEYRINGDIR}"
|
||||||
touch "$BLACKBOXDATA/$BB_ADMINS_FILE" "$BLACKBOXDATA/$BB_FILES_FILE"
|
touch "$BLACKBOXDATA/$BB_ADMINS_FILE" "$BLACKBOXDATA/$BB_FILES_FILE"
|
||||||
vcs_add "$IGNOREFILE" "$BLACKBOXDATA/$BB_ADMINS_FILE" "$BLACKBOXDATA/$BB_FILES_FILE"
|
vcs_add "$BLACKBOXDATA/$BB_ADMINS_FILE" "$BLACKBOXDATA/$BB_FILES_FILE"
|
||||||
|
|
||||||
|
IGNOREFILE="$(vcs_ignore_file_path)"
|
||||||
|
test -f "$IGNOREFILE" && vcs_add "$IGNOREFILE"
|
||||||
|
|
||||||
# Make a suggestion:
|
# Make a suggestion:
|
||||||
echo
|
echo
|
||||||
|
|||||||
8
bin/blackbox_list_files
Executable file
8
bin/blackbox_list_files
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# blackbox_list_files -- List files that black box is tracking
|
||||||
|
#
|
||||||
|
set -e
|
||||||
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
|
cat "$BB_FILES"
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# blackbox_postdeploy.sh -- Decrypt all blackbox files.
|
# blackbox_postdeploy -- Decrypt all blackbox files.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
@@ -14,8 +14,7 @@
|
|||||||
export PATH=/usr/bin:/bin:"$PATH"
|
export PATH=/usr/bin:/bin:"$PATH"
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
source ${blackbox_home}/_blackbox_common.sh
|
|
||||||
|
|
||||||
if [[ "$1" == "" ]]; then
|
if [[ "$1" == "" ]]; then
|
||||||
FILE_GROUP=""
|
FILE_GROUP=""
|
||||||
@@ -23,7 +22,7 @@ else
|
|||||||
FILE_GROUP="$1"
|
FILE_GROUP="$1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
change_to_root
|
change_to_vcs_root
|
||||||
prepare_keychain
|
prepare_keychain
|
||||||
|
|
||||||
# Decrypt:
|
# Decrypt:
|
||||||
@@ -31,9 +30,11 @@ echo '========== Decrypting new/changed files: START'
|
|||||||
while IFS= read <&99 -r unencrypted_file; do
|
while IFS= read <&99 -r unencrypted_file; do
|
||||||
encrypted_file=$(get_encrypted_filename "$unencrypted_file")
|
encrypted_file=$(get_encrypted_filename "$unencrypted_file")
|
||||||
decrypt_file_overwrite "$encrypted_file" "$unencrypted_file"
|
decrypt_file_overwrite "$encrypted_file" "$unencrypted_file"
|
||||||
chmod g+r "$unencrypted_file"
|
cp_permissions "$encrypted_file" "$unencrypted_file"
|
||||||
if [[ ! -z "$FILE_GROUP" ]]; then
|
if [[ ! -z "$FILE_GROUP" ]]; then
|
||||||
chgrp $FILE_GROUP "$unencrypted_file"
|
chmod g+r "$unencrypted_file"
|
||||||
|
chgrp "$FILE_GROUP" "$unencrypted_file"
|
||||||
fi
|
fi
|
||||||
done 99<"$BB_FILES"
|
done 99<"$BB_FILES"
|
||||||
|
|
||||||
echo '========== Decrypting new/changed files: DONE'
|
echo '========== Decrypting new/changed files: DONE'
|
||||||
|
|||||||
6
bin/blackbox_recurse
Executable file
6
bin/blackbox_recurse
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# proposed space for blackbox recurion...coming soon
|
||||||
|
set -e
|
||||||
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
|
|
||||||
|
echo "$REBOBASE"
|
||||||
@@ -1,68 +1,56 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# blackbox_register_new_file.sh -- Enroll a new file in the blackbox system.
|
# blackbox_register_new_file -- Enroll new file(s) in the blackbox system.
|
||||||
#
|
#
|
||||||
# Takes a previously unencrypted file and enrolls it into the blackbox
|
# Takes previously unencrypted file(s) and enrolls them into the blackbox
|
||||||
# system. It will be kept in the repo as an encrypted file. On deployment
|
# system. Each file will be kept in the repo as an encrypted file. On deployment
|
||||||
# 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 .hgignore
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
source ${blackbox_home}/_blackbox_common.sh
|
|
||||||
_determine_vcs_base_and_type
|
|
||||||
|
|
||||||
unencrypted_file=$(get_unencrypted_filename "$1")
|
function register_new_file() {
|
||||||
encrypted_file=$(get_encrypted_filename "$1")
|
unencrypted_file=$(get_unencrypted_filename "$1")
|
||||||
|
encrypted_file=$(get_encrypted_filename "$1")
|
||||||
|
|
||||||
if [[ $1 == $encrypted_file ]]; then
|
if [[ "$1" == "$encrypted_file" ]]; then
|
||||||
echo ERROR: Please only register unencrypted files.
|
echo ERROR: Please only register unencrypted files.
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ========== PLAINFILE "$unencrypted_file"
|
echo "========== PLAINFILE $unencrypted_file"
|
||||||
echo ========== ENCRYPTED "$encrypted_file"
|
echo "========== ENCRYPTED $encrypted_file"
|
||||||
|
|
||||||
fail_if_not_exists "$unencrypted_file" "Please specify an existing file."
|
fail_if_not_exists "$unencrypted_file" "Please specify an existing file."
|
||||||
fail_if_exists "$encrypted_file" "Will not overwrite."
|
fail_if_exists "$encrypted_file" "Will not overwrite."
|
||||||
|
|
||||||
prepare_keychain
|
prepare_keychain
|
||||||
encrypt_file "$unencrypted_file" "$encrypted_file"
|
encrypt_file "$unencrypted_file" "$encrypted_file"
|
||||||
add_filename_to_cryptlist "$unencrypted_file"
|
add_filename_to_cryptlist "$unencrypted_file"
|
||||||
|
|
||||||
# Is the unencrypted file already in HG? (ie. are we correcting a bad situation)
|
# Is the unencrypted file already in HG? (ie. are we correcting a bad situation)
|
||||||
SECRETSEXPOSED=$(is_in_vcs ${unencrypted_file})
|
SECRETSEXPOSED=$(is_in_vcs "${unencrypted_file}")
|
||||||
echo "========== CREATED: ${encrypted_file}"
|
echo "========== CREATED: ${encrypted_file}"
|
||||||
echo "========== UPDATING REPO:"
|
echo "========== UPDATING REPO:"
|
||||||
shred_file "$unencrypted_file"
|
shred_file "$unencrypted_file"
|
||||||
|
|
||||||
VCSCMD=$(which_vcs)
|
if "$SECRETSEXPOSED" ; then
|
||||||
if $SECRETSEXPOSED ; then
|
|
||||||
vcs_remove "$unencrypted_file"
|
vcs_remove "$unencrypted_file"
|
||||||
vcs_add "$encrypted_file"
|
vcs_add "$encrypted_file"
|
||||||
COMMIT_FILES="$BB_FILES $encrypted_file $unencrypted_file"
|
|
||||||
else
|
|
||||||
COMMIT_FILES="$BB_FILES $encrypted_file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# TODO(tlim): This should be moved to _blackbox_common.sh in a
|
|
||||||
# VCS-independent way.
|
|
||||||
IGNOREFILE=".${VCS_TYPE}ignore"
|
|
||||||
if [[ $VCS_TYPE = 'git' ]]; then
|
|
||||||
ignored_file="$(echo "$unencrypted_file" | sed 's/\([\*\?]\)/\\\1/g' | sed 's/^\([!#]\)/\\\1/')"
|
|
||||||
if ! grep -Fsx >/dev/null "$ignored_file" "$IGNOREFILE"; then
|
|
||||||
echo "$ignored_file" >>"$IGNOREFILE"
|
|
||||||
COMMIT_FILES="$COMMIT_FILES $IGNOREFILE"
|
|
||||||
fi
|
fi
|
||||||
vcs_add "$IGNOREFILE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo 'NOTE: "already tracked!" messages are safe to ignore.'
|
vcs_ignore "$unencrypted_file"
|
||||||
vcs_add $BB_FILES $encrypted_file
|
echo 'NOTE: "already tracked!" messages are safe to ignore.'
|
||||||
vcs_commit "registered in blackbox: ${unencrypted_file}" $COMMIT_FILES
|
vcs_add "$BB_FILES" "$encrypted_file"
|
||||||
|
vcs_commit "registered in blackbox: ${unencrypted_file}" "$BB_FILES" "$encrypted_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
for target in "$@"; do
|
||||||
|
register_new_file "$target"
|
||||||
|
done
|
||||||
|
|
||||||
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 " $VCS_TYPE push"
|
||||||
|
|||||||
@@ -10,19 +10,15 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
source ${blackbox_home}/_blackbox_common.sh
|
|
||||||
source ${blackbox_home}/_stack_lib.sh
|
|
||||||
|
|
||||||
fail_if_not_in_repo
|
fail_if_not_in_repo
|
||||||
|
|
||||||
KEYNAME="$1"
|
KEYNAME="$1"
|
||||||
: ${KEYNAME:?ERROR: First argument must be a keyname (email address)} ;
|
: "${KEYNAME:?ERROR: First argument must be a keyname (email address)}" ;
|
||||||
|
|
||||||
# Remove the email address from the BB_ADMINS file.
|
# Remove the email address from the BB_ADMINS file.
|
||||||
make_self_deleting_tempfile bbtemp
|
remove_line "$BB_ADMINS" "$KEYNAME"
|
||||||
cp "$BB_ADMINS" "$bbtemp"
|
|
||||||
fgrep -v -x "$KEYNAME" <"$bbtemp" >"$BB_ADMINS"
|
|
||||||
|
|
||||||
# Make a suggestion:
|
# Make a suggestion:
|
||||||
echo
|
echo
|
||||||
|
|||||||
@@ -16,19 +16,18 @@
|
|||||||
# have been decrypted for editing, you will see an empty list.
|
# have been decrypted for editing, you will see an empty list.
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
source ${blackbox_home}/_blackbox_common.sh
|
|
||||||
|
|
||||||
change_to_root
|
change_to_vcs_root
|
||||||
|
|
||||||
echo '========== FILES BEING SHREDDED:'
|
echo '========== FILES BEING SHREDDED:'
|
||||||
for i in $(<$BB_FILES) ; do
|
while IFS= read <&99 -r unencrypted_file; do
|
||||||
unencrypted_file=$(get_unencrypted_filename "$i")
|
unencrypted_file=$(get_unencrypted_filename "$unencrypted_file")
|
||||||
encrypted_file=$(get_encrypted_filename "$i")
|
encrypted_file=$(get_encrypted_filename "$unencrypted_file")
|
||||||
if [[ -f "$unencrypted_file" ]]; then
|
if [[ -f "$unencrypted_file" ]]; then
|
||||||
echo " $unencrypted_file"
|
echo " $unencrypted_file"
|
||||||
shred_file "$unencrypted_file"
|
shred_file "$unencrypted_file"
|
||||||
fi
|
fi
|
||||||
done
|
done 99<"$BB_FILES"
|
||||||
|
|
||||||
echo '========== DONE.'
|
echo '========== DONE.'
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# blackbox_update_all_files -- Re-encrypt file after edits.
|
# blackbox_update_all_files -- Decrypt then re-encrypt all files. Useful after keys are changed.
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
source ${blackbox_home}/_blackbox_common.sh
|
|
||||||
|
|
||||||
if [[ -z $GPG_AGENT_INFO ]]; then
|
if [[ -z $GPG_AGENT_INFO ]]; then
|
||||||
echo 'WARNING: You probably want to run gpg-agent as'
|
echo 'WARNING: You probably want to run gpg-agent as'
|
||||||
@@ -19,19 +18,21 @@ disclose_admins
|
|||||||
prepare_keychain
|
prepare_keychain
|
||||||
|
|
||||||
echo '========== ENCRYPTED FILES TO BE RE-ENCRYPTED:'
|
echo '========== ENCRYPTED FILES TO BE RE-ENCRYPTED:'
|
||||||
awk <"$BB_FILES" '{ print " " $1 ".gpg" }'
|
while IFS= read <&99 -r unencrypted_file; do
|
||||||
|
echo " $unencrypted_file.gpg"
|
||||||
|
done 99<"$BB_FILES"
|
||||||
|
|
||||||
echo '========== FILES IN THE WAY:'
|
echo '========== FILES IN THE WAY:'
|
||||||
need_warning=false
|
need_warning=false
|
||||||
for i in $(<$BB_FILES) ; do
|
while IFS= read <&99 -r unencrypted_file; do
|
||||||
unencrypted_file=$(get_unencrypted_filename "$i")
|
unencrypted_file=$(get_unencrypted_filename "$unencrypted_file")
|
||||||
encrypted_file=$(get_encrypted_filename "$i")
|
encrypted_file=$(get_encrypted_filename "$unencrypted_file")
|
||||||
if [[ -f "$unencrypted_file" ]]; then
|
if [[ -f "$unencrypted_file" ]]; then
|
||||||
need_warning=true
|
need_warning=true
|
||||||
echo " $unencrypted_file"
|
echo " $unencrypted_file"
|
||||||
fi
|
fi
|
||||||
done
|
done 99<"$BB_FILES"
|
||||||
if $need_warning ; then
|
if "$need_warning" ; then
|
||||||
echo
|
echo
|
||||||
echo 'WARNING: This will overwrite any unencrypted files laying about.'
|
echo 'WARNING: This will overwrite any unencrypted files laying about.'
|
||||||
read -r -p 'Press CTRL-C now to stop. ENTER to continue: '
|
read -r -p 'Press CTRL-C now to stop. ENTER to continue: '
|
||||||
@@ -40,22 +41,24 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo '========== RE-ENCRYPTING FILES:'
|
echo '========== RE-ENCRYPTING FILES:'
|
||||||
for i in $(<$BB_FILES) ; do
|
while IFS= read <&99 -r unencrypted_file; do
|
||||||
unencrypted_file=$(get_unencrypted_filename "$i")
|
unencrypted_file=$(get_unencrypted_filename "$unencrypted_file")
|
||||||
encrypted_file=$(get_encrypted_filename "$i")
|
encrypted_file=$(get_encrypted_filename "$unencrypted_file")
|
||||||
echo ========== PROCESSING "$unencrypted_file"
|
echo ========== PROCESSING '"'$unencrypted_file'"'
|
||||||
fail_if_not_on_cryptlist "$unencrypted_file"
|
fail_if_not_on_cryptlist "$unencrypted_file"
|
||||||
decrypt_file_overwrite "$encrypted_file" "$unencrypted_file"
|
decrypt_file_overwrite "$encrypted_file" "$unencrypted_file"
|
||||||
encrypt_file "$unencrypted_file" "$encrypted_file"
|
encrypt_file "$unencrypted_file" "$encrypted_file"
|
||||||
shred_file "$unencrypted_file"
|
shred_file "$unencrypted_file"
|
||||||
done
|
done 99<"$BB_FILES"
|
||||||
|
|
||||||
fail_if_keychain_has_secrets
|
fail_if_keychain_has_secrets
|
||||||
|
|
||||||
echo '========== COMMITING TO VCS:'
|
echo '========== COMMITING TO VCS:'
|
||||||
vcs_commit 'Re-encrypted keys' $(awk <$BB_FILES '{ print $1 ".gpg" }' )
|
while IFS= read <&99 -r unencrypted_file; do
|
||||||
|
vcs_add "$unencrypted_file.gpg"
|
||||||
|
done 99<"$BB_FILES"
|
||||||
|
vcs_commit 'Re-encrypted keys'
|
||||||
|
|
||||||
VCSCMD=$(which_vcs)
|
|
||||||
echo '========== DONE.'
|
echo '========== DONE.'
|
||||||
echo 'Likely next step:'
|
echo 'Likely next step:'
|
||||||
echo " ${VCSCMD} push"
|
echo " $VCS_TYPE push"
|
||||||
|
|||||||
55
bin/blackbox_whatsnew
Executable file
55
bin/blackbox_whatsnew
Executable file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# blackbox_whatsnew - show what has changed in the last commit for a given file
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
source "${0%/*}/_blackbox_common.sh"
|
||||||
|
|
||||||
|
if [[ $# -ne 1 ]]
|
||||||
|
then
|
||||||
|
echo "Pass only 1 file at a time"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
fail_if_not_in_repo
|
||||||
|
|
||||||
|
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 -r -p 'Press CTRL-C now to stop. ENTER to continue: '
|
||||||
|
fi
|
||||||
|
|
||||||
|
COLUMNS=`tput cols`
|
||||||
|
FILE=$1
|
||||||
|
GIT="git log --abbrev-commit --pretty=oneline"
|
||||||
|
CURR_COMMIT=`$GIT $FILE | head -1 | awk '{print $1}'`
|
||||||
|
PREV_COMMIT=`$GIT ${CURR_COMMIT}~1 $FILE | head -1 | awk '{print $1}'`
|
||||||
|
# Use colordiff if available
|
||||||
|
if which colordiff > /dev/null 2>&1
|
||||||
|
then DIFF="colordiff"
|
||||||
|
else DIFF="diff"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat_commit()
|
||||||
|
{
|
||||||
|
COMMIT=$1
|
||||||
|
git checkout $COMMIT $FILE
|
||||||
|
echo "[$COMMIT] $FILE"
|
||||||
|
echo "---------------------"
|
||||||
|
"${BLACKBOX_HOME}/blackbox_cat" $FILE | sed '/========== PLAINFILE/,/========== EXTRACTING/d'
|
||||||
|
}
|
||||||
|
|
||||||
|
CURR_CONTENT=`cat_commit $CURR_COMMIT`
|
||||||
|
PREV_CONTENT=`cat_commit $PREV_COMMIT`
|
||||||
|
clear
|
||||||
|
|
||||||
|
# For some unknown reason this command executes fine but return exit code 1
|
||||||
|
$DIFF -y --width $COLUMNS \
|
||||||
|
<(echo "CURRENT" "$CURR_CONTENT" | fold -w $(( $COLUMNS / 2 - 4 )) ) \
|
||||||
|
<(echo "PREVIOUS" "$PREV_CONTENT" | fold -w $(( $COLUMNS / 2 - 4 )) )
|
||||||
|
|
||||||
|
git checkout $CURR_COMMIT $FILE
|
||||||
|
echo
|
||||||
31
tools/Portfile.template
Normal file
31
tools/Portfile.template
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
|
||||||
|
# $Id: Portfile 132962 2015-02-16 10:33:02Z ryandesign@macports.org $
|
||||||
|
|
||||||
|
PortSystem 1.0
|
||||||
|
PortGroup github 1.0
|
||||||
|
|
||||||
|
github.setup StackExchange blackbox @@VERSION@@ v
|
||||||
|
name vcs_blackbox
|
||||||
|
categories security
|
||||||
|
platforms darwin
|
||||||
|
maintainers whatexit.org:tal openmaintainer
|
||||||
|
license BSD
|
||||||
|
supported_archs noarch
|
||||||
|
|
||||||
|
description Safely store secrets in git/hg/svn repos using GPG encryption
|
||||||
|
|
||||||
|
long_description Storing secrets such as passwords, certificates and private keys \
|
||||||
|
in Git/Mercurial/SubVersion is dangerous. Blackbox makes it easy \
|
||||||
|
to store secrets safely using GPG encryption. They can be easily \
|
||||||
|
decrypted for editing or use in production.
|
||||||
|
|
||||||
|
checksums rmd160 @@RMD160@@ \
|
||||||
|
sha256 @@SHA256@@
|
||||||
|
|
||||||
|
use_configure no
|
||||||
|
|
||||||
|
build {}
|
||||||
|
|
||||||
|
# This project's Makefile uses DESTDIR incorrectly.
|
||||||
|
destroot.destdir DESTDIR=${destroot}${prefix}
|
||||||
|
destroot.target packages-macports
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# build_rpm.sh - Build an RPM of these files. (uses FPM)
|
|
||||||
|
|
||||||
# Usage:
|
|
||||||
# make_rpm.sh PACKAGENAME MANIFEST1 MANIFEST2 ...
|
|
||||||
|
|
||||||
# Example:
|
|
||||||
# Make a package foopkg manifest.txt
|
|
||||||
# Where "manifest.txt" contains:
|
|
||||||
# exec /usr/bin/foo foo/foo
|
|
||||||
# exec /usr/bin/bar bar/bar.sh
|
|
||||||
# read /usr/man/man1/bar.1 bar/bar.1.man
|
|
||||||
# 0444 /etc/foo.conf bar/foo.conf
|
|
||||||
#
|
|
||||||
# Col1 chmod-style permissions or "exec" for 0755, "read" for 0744.
|
|
||||||
# Col2 Installation location.
|
|
||||||
# Col3 Source of the file.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Parameters for this RPM:
|
|
||||||
PACKAGENAME=${1?"First arg must be the package name."}
|
|
||||||
shift
|
|
||||||
|
|
||||||
# Defaults that can be overridden via env variables:
|
|
||||||
# All packages are 1.0 unless otherwise specifed:
|
|
||||||
: ${PKGVERSION:=1.0} ;
|
|
||||||
# If there is no iteration setting, assume "1":
|
|
||||||
: ${PKGRELEASE:=1}
|
|
||||||
|
|
||||||
# The RPM is output here: (should be a place that can be wiped)
|
|
||||||
OUTPUTDIR="${HOME}/rpmbuild-$PACKAGENAME"
|
|
||||||
# Our build system expects to find the list of artifacts here:
|
|
||||||
RPM_BIN_LIST="${OUTPUTDIR}/bin-packages.txt"
|
|
||||||
|
|
||||||
# -- Now the real work can be done.
|
|
||||||
|
|
||||||
# Clean the output dir.
|
|
||||||
rm -rf "$OUTPUTDIR"
|
|
||||||
mkdir -p "$OUTPUTDIR/installroot"
|
|
||||||
|
|
||||||
# Copy the files into place:
|
|
||||||
cat """$@""" | grep -v '^$' | while read -a arr ; do
|
|
||||||
PERM="${arr[0]}"
|
|
||||||
DEST="${arr[1]}"
|
|
||||||
SRC="${arr[2]}"
|
|
||||||
echo ========== "$PERM $DEST"
|
|
||||||
case $PERM in
|
|
||||||
\#*) continue ;; # Skip comments.
|
|
||||||
exec) PERM=0755 ;;
|
|
||||||
read) PERM=0744 ;;
|
|
||||||
*) ;;
|
|
||||||
esac
|
|
||||||
FULLDEST="$OUTPUTDIR/installroot/${arr[1]}"
|
|
||||||
install -D -T -b -m "$PERM" -T "$SRC" "$FULLDEST"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Build the RPM:
|
|
||||||
cd "$OUTPUTDIR" && fpm -s dir -t rpm \
|
|
||||||
-a x86_64 \
|
|
||||||
--epoch '0' \
|
|
||||||
-n "${PACKAGENAME}" \
|
|
||||||
--version "${PKGVERSION}" \
|
|
||||||
--iteration "${PKGRELEASE}" \
|
|
||||||
--description 'Safely store secrets in Git/Hg repos using GPG encryption' \
|
|
||||||
-C "$OUTPUTDIR/installroot" \
|
|
||||||
.
|
|
||||||
|
|
||||||
# Our build system expects to find the list of all packages created
|
|
||||||
# in bin-packages.txt. Generate that list:
|
|
||||||
find "$OUTPUTDIR" -maxdepth 1 -name '*.rpm' >"$RPM_BIN_LIST"
|
|
||||||
# Output the list for debugging purposes:
|
|
||||||
echo ========== "$RPM_BIN_LIST"
|
|
||||||
cat "$RPM_BIN_LIST"
|
|
||||||
@@ -1,90 +1,17 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/../bin
|
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/../bin
|
||||||
export PATH=${blackbox_home}:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
|
export PATH="${blackbox_home}:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/local/bin"
|
||||||
|
|
||||||
. _stack_lib.sh
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
. _stack_lib.sh
|
||||||
|
. tools/test_functions.sh
|
||||||
|
|
||||||
function PHASE() {
|
PHASE 'UNIT TESTS'
|
||||||
echo '********************'
|
|
||||||
echo '********************'
|
|
||||||
echo '*********' """$@"""
|
|
||||||
echo '********************'
|
|
||||||
echo '********************'
|
|
||||||
}
|
|
||||||
|
|
||||||
function assert_file_missing() {
|
_blackbox_common_test.sh
|
||||||
if [[ -e "$1" ]]; then
|
|
||||||
echo "ASSERT FAILED: ${1} should not exist."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function assert_file_exists() {
|
PHASE 'SYSTEM TESTS'
|
||||||
if [[ ! -e "$1" ]]; then
|
|
||||||
echo "ASSERT FAILED: ${1} should exist."
|
|
||||||
echo "PWD="$(/bin/pwd -P)
|
|
||||||
#echo "LS START"
|
|
||||||
#ls -la
|
|
||||||
#echo "LS END"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
function assert_file_md5hash() {
|
|
||||||
local file="$1"
|
|
||||||
local wanted="$2"
|
|
||||||
assert_file_exists "$file"
|
|
||||||
local found=$(md5sum <"$file" | cut -d' ' -f1 )
|
|
||||||
if [[ "$wanted" != "$found" ]]; then
|
|
||||||
echo "ASSERT FAILED: $file hash wanted=$wanted found=$found"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
function assert_file_group() {
|
|
||||||
local file="$1"
|
|
||||||
local wanted="$2"
|
|
||||||
assert_file_exists "$file"
|
|
||||||
|
|
||||||
case $(uname -s) in
|
|
||||||
CYGWIN* )
|
|
||||||
echo "ASSERT_FILE_GROUP: Running on Cygwin. Not being tested."
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
local found=$(ls -l "$file" | awk '{ print $4 }')
|
|
||||||
# NB(tlim): We could do this with 'stat' but it would break on BSD-style OSs.
|
|
||||||
if [[ "$wanted" != "$found" ]]; then
|
|
||||||
echo "ASSERT FAILED: $file chgrp wanted=$wanted found=$found"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
function assert_line_not_exists() {
|
|
||||||
local target="$1"
|
|
||||||
local file="$2"
|
|
||||||
assert_file_exists "$file"
|
|
||||||
if grep -F -x -s -q >/dev/null "$target" "$file" ; then
|
|
||||||
echo "ASSERT FAILED: line '$target' should not exist in file $file"
|
|
||||||
echo ==== file contents: START "$file"
|
|
||||||
cat "$file"
|
|
||||||
echo ==== file contents: END "$file"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
function assert_line_exists() {
|
|
||||||
local target="$1"
|
|
||||||
local file="$2"
|
|
||||||
assert_file_exists "$file"
|
|
||||||
if ! grep -F -x -s -q >/dev/null "$target" "$file" ; then
|
|
||||||
echo "ASSERT FAILED: line '$target' should not exist in file $file"
|
|
||||||
echo ==== file contents: START "$file"
|
|
||||||
cat "$file"
|
|
||||||
echo ==== file contents: END "$file"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
make_tempdir test_repository
|
make_tempdir test_repository
|
||||||
cd "$test_repository"
|
cd "$test_repository"
|
||||||
@@ -92,29 +19,30 @@ cd "$test_repository"
|
|||||||
make_self_deleting_tempdir fake_alice_home
|
make_self_deleting_tempdir fake_alice_home
|
||||||
make_self_deleting_tempdir fake_bob_home
|
make_self_deleting_tempdir fake_bob_home
|
||||||
export GNUPGHOME="$fake_alice_home"
|
export GNUPGHOME="$fake_alice_home"
|
||||||
eval $(gpg-agent --homedir "$fake_alice_home" --daemon)
|
eval "$(gpg-agent --homedir "$fake_alice_home" --daemon)"
|
||||||
GPG_AGENT_INFO_ALICE="$GPG_AGENT_INFO"
|
GPG_AGENT_INFO_ALICE="$GPG_AGENT_INFO"
|
||||||
|
|
||||||
export GNUPGHOME="$fake_bob_home"
|
export GNUPGHOME="$fake_bob_home"
|
||||||
eval $(gpg-agent --homedir "$fake_alice_home" --daemon)
|
eval "$(gpg-agent --homedir "$fake_bob_home" --daemon)"
|
||||||
GPG_AGENT_INFO_BOB="$GPG_AGENT_INFO"
|
GPG_AGENT_INFO_BOB="$GPG_AGENT_INFO"
|
||||||
|
|
||||||
function become_alice() {
|
function become_alice() {
|
||||||
export GNUPGHOME="$fake_alice_home"
|
export GNUPGHOME="$fake_alice_home"
|
||||||
export GPG_AGENT_INFO="$GPG_AGENT_INFO_ALICE"
|
export GPG_AGENT_INFO="$GPG_AGENT_INFO_ALICE"
|
||||||
echo BECOMING ALICE: GNUPGHOME=$GNUPGHOME AGENT=$GPG_AGENT_INFO
|
echo BECOMING ALICE: GNUPGHOME="$GNUPGHOME AGENT=$GPG_AGENT_INFO"
|
||||||
git config --global user.name "Alice Example"
|
mkdir -p .git ; touch .git/config
|
||||||
git config --global user.email alice@example.com
|
git config user.name "Alice Example"
|
||||||
|
git config user.email alice@example.com
|
||||||
}
|
}
|
||||||
|
|
||||||
function become_bob() {
|
function become_bob() {
|
||||||
export GNUPGHOME="$fake_alice_home"
|
export GNUPGHOME="$fake_bob_home"
|
||||||
export GPG_AGENT_INFO="$GPG_AGENT_INFO_ALICE"
|
export GPG_AGENT_INFO="$GPG_AGENT_INFO_BOB"
|
||||||
git config --global user.name "Bob Example"
|
mkdir -p .git ; touch .git/config
|
||||||
git config --global user.email bob@example.com
|
git config user.name "Bob Example"
|
||||||
|
git config user.email bob@example.com
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PHASE 'Alice creates a repo. She creates secret.txt.'
|
PHASE 'Alice creates a repo. She creates secret.txt.'
|
||||||
|
|
||||||
become_alice
|
become_alice
|
||||||
@@ -195,6 +123,7 @@ PHASE 'She enrolls secrets.txt.'
|
|||||||
blackbox_register_new_file secret.txt
|
blackbox_register_new_file secret.txt
|
||||||
assert_file_missing secret.txt
|
assert_file_missing secret.txt
|
||||||
assert_file_exists secret.txt.gpg
|
assert_file_exists secret.txt.gpg
|
||||||
|
assert_line_exists '/secret.txt' .gitignore
|
||||||
|
|
||||||
PHASE 'She decrypts secrets.txt.'
|
PHASE 'She decrypts secrets.txt.'
|
||||||
blackbox_edit_start secret.txt
|
blackbox_edit_start secret.txt
|
||||||
@@ -209,7 +138,51 @@ assert_file_missing secret.txt
|
|||||||
assert_file_exists secret.txt.gpg
|
assert_file_exists secret.txt.gpg
|
||||||
|
|
||||||
|
|
||||||
PHASE 'Bob appears.'
|
PHASE 'Alice copies files to a non-repo directory. (NO REPO)'
|
||||||
|
|
||||||
|
# Copy the repo entirely:
|
||||||
|
make_self_deleting_tempdir fake_alice_filedir
|
||||||
|
tar cf - . | ( cd "$fake_alice_filedir" && tar xpvf - )
|
||||||
|
# Remove the .git directory
|
||||||
|
rm -rf "$fake_alice_filedir/.git"
|
||||||
|
(
|
||||||
|
cd "$fake_alice_filedir"
|
||||||
|
assert_file_missing '.git'
|
||||||
|
assert_file_exists 'secret.txt.gpg'
|
||||||
|
assert_file_missing 'secret.txt'
|
||||||
|
blackbox_postdeploy
|
||||||
|
assert_file_missing '.git'
|
||||||
|
assert_file_exists 'secret.txt.gpg'
|
||||||
|
assert_file_exists 'secret.txt'
|
||||||
|
assert_file_md5hash secret.txt "08a3fa763a05c018a38e9924363b97e7"
|
||||||
|
|
||||||
|
PHASE 'Alice shreds these non-repo files. (NO REPO)'
|
||||||
|
blackbox_shred_all_files
|
||||||
|
assert_file_missing '.git'
|
||||||
|
assert_file_exists 'secret.txt.gpg'
|
||||||
|
assert_file_missing 'secret.txt'
|
||||||
|
|
||||||
|
PHASE 'Alice decrypts secrets.txt (NO REPO).'
|
||||||
|
blackbox_edit_start secret.txt
|
||||||
|
assert_file_exists secret.txt
|
||||||
|
assert_file_exists secret.txt.gpg
|
||||||
|
assert_file_md5hash secret.txt "08a3fa763a05c018a38e9924363b97e7"
|
||||||
|
|
||||||
|
PHASE 'Alice edits secrets.txt. (NO REPO EDIT)'
|
||||||
|
echo 'NOREPO EDIT' >secret.txt
|
||||||
|
assert_file_md5hash secret.txt "d3e6bbdfc76fae7fd0a921f3408db1d1"
|
||||||
|
blackbox_edit_end secret.txt
|
||||||
|
assert_file_missing secret.txt
|
||||||
|
assert_file_exists secret.txt.gpg
|
||||||
|
|
||||||
|
PHASE 'Alice decrypts secrets.txt (NO REPO EDIT).'
|
||||||
|
blackbox_edit_start secret.txt
|
||||||
|
assert_file_exists secret.txt
|
||||||
|
assert_file_exists secret.txt.gpg
|
||||||
|
assert_file_md5hash secret.txt "d3e6bbdfc76fae7fd0a921f3408db1d1"
|
||||||
|
)
|
||||||
|
|
||||||
|
PHASE 'appears.'
|
||||||
become_bob
|
become_bob
|
||||||
|
|
||||||
PHASE 'Bob makes sure he has all new keys.'
|
PHASE 'Bob makes sure he has all new keys.'
|
||||||
@@ -217,12 +190,14 @@ PHASE 'Bob makes sure he has all new keys.'
|
|||||||
gpg --import keyrings/live/pubring.gpg
|
gpg --import keyrings/live/pubring.gpg
|
||||||
|
|
||||||
# Pick a GID to use:
|
# Pick a GID to use:
|
||||||
TEST_GID_NUM=$(id -G | fmt -1 | tail -n +2 | grep -xv $(id -u) | head -n 1)
|
# This users's default group:
|
||||||
TEST_GID_NAME=$(getent group "$TEST_GID_NUM" | cut -d: -f1)
|
DEFAULT_GID_NAME=$(id -gn)
|
||||||
DEFAULT_GID_NAME=$(getent group $(id -u) | cut -d: -f1)
|
# Pick a group that is not the default group:
|
||||||
echo TEST_GID_NUM=$TEST_GID_NUM
|
TEST_GID_NUM=$(id -G | fmt -1 | tail -n +2 | grep -xv "$(id -u)" | head -n 1)
|
||||||
echo TEST_GID_NAME=$TEST_GID_NAME
|
TEST_GID_NAME=$(python -c 'import grp; print grp.getgrgid('"$TEST_GID_NUM"').gr_name')
|
||||||
echo DEFAULT_GID_NAME=$DEFAULT_GID_NAME
|
echo "DEFAULT_GID_NAME=$DEFAULT_GID_NAME"
|
||||||
|
echo "TEST_GID_NUM=$TEST_GID_NUM"
|
||||||
|
echo "TEST_GID_NAME=$TEST_GID_NAME"
|
||||||
|
|
||||||
PHASE 'Bob postdeploys... default.'
|
PHASE 'Bob postdeploys... default.'
|
||||||
blackbox_postdeploy
|
blackbox_postdeploy
|
||||||
@@ -232,7 +207,7 @@ assert_file_md5hash secret.txt "08a3fa763a05c018a38e9924363b97e7"
|
|||||||
assert_file_group secret.txt "$DEFAULT_GID_NAME"
|
assert_file_group secret.txt "$DEFAULT_GID_NAME"
|
||||||
|
|
||||||
PHASE 'Bob postdeploys... with a GID.'
|
PHASE 'Bob postdeploys... with a GID.'
|
||||||
blackbox_postdeploy $TEST_GID_NUM
|
blackbox_postdeploy "$TEST_GID_NUM"
|
||||||
assert_file_exists secret.txt
|
assert_file_exists secret.txt
|
||||||
assert_file_exists secret.txt.gpg
|
assert_file_exists secret.txt.gpg
|
||||||
assert_file_md5hash secret.txt "08a3fa763a05c018a38e9924363b97e7"
|
assert_file_md5hash secret.txt "08a3fa763a05c018a38e9924363b97e7"
|
||||||
@@ -241,7 +216,7 @@ assert_file_group secret.txt "$TEST_GID_NAME"
|
|||||||
PHASE 'Bob cleans up the secret.'
|
PHASE 'Bob cleans up the secret.'
|
||||||
rm secret.txt
|
rm secret.txt
|
||||||
|
|
||||||
PHASE 'Bob removes alice.'
|
PHASE 'Bob removes Alice.'
|
||||||
blackbox_removeadmin alice@example.com
|
blackbox_removeadmin alice@example.com
|
||||||
assert_line_not_exists 'alice@example.com' keyrings/live/blackbox-admins.txt
|
assert_line_not_exists 'alice@example.com' keyrings/live/blackbox-admins.txt
|
||||||
|
|
||||||
@@ -276,6 +251,7 @@ blackbox_register_new_file mistake.txt
|
|||||||
assert_file_missing mistake.txt
|
assert_file_missing mistake.txt
|
||||||
assert_file_exists mistake.txt.gpg
|
assert_file_exists mistake.txt.gpg
|
||||||
# NOTE: It is still in the history. That should be corrected someday.
|
# NOTE: It is still in the history. That should be corrected someday.
|
||||||
|
assert_line_exists '/mistake.txt' .gitignore
|
||||||
|
|
||||||
PHASE 'Bob enrolls my/path/to/relsecrets.txt.'
|
PHASE 'Bob enrolls my/path/to/relsecrets.txt.'
|
||||||
mkdir my my/path my/path/to
|
mkdir my my/path my/path/to
|
||||||
@@ -284,6 +260,9 @@ cd my/path/to
|
|||||||
blackbox_register_new_file relsecrets.txt
|
blackbox_register_new_file relsecrets.txt
|
||||||
assert_file_missing relsecrets.txt
|
assert_file_missing relsecrets.txt
|
||||||
assert_file_exists relsecrets.txt.gpg
|
assert_file_exists relsecrets.txt.gpg
|
||||||
|
assert_file_missing .gitignore
|
||||||
|
assert_file_exists ../../../.gitignore
|
||||||
|
assert_line_exists '/my/path/to/relsecrets.txt' ../../../.gitignore
|
||||||
|
|
||||||
PHASE 'Bob decrypts relsecrets.txt.'
|
PHASE 'Bob decrypts relsecrets.txt.'
|
||||||
cd ..
|
cd ..
|
||||||
@@ -298,34 +277,139 @@ echo A very important file >'!important!.txt'
|
|||||||
blackbox_register_new_file '!important!.txt'
|
blackbox_register_new_file '!important!.txt'
|
||||||
assert_file_missing '!important!.txt'
|
assert_file_missing '!important!.txt'
|
||||||
assert_file_exists '!important!.txt'.gpg
|
assert_file_exists '!important!.txt'.gpg
|
||||||
assert_line_exists '\!important!.txt' .gitignore
|
assert_line_exists '/!important!.txt' .gitignore
|
||||||
|
|
||||||
PHASE 'Bob enrolls #andpounds.txt'
|
PHASE 'Bob enrolls #andpounds.txt'
|
||||||
echo A very commented file >'#andpounds.txt'
|
echo A very commented file >'#andpounds.txt'
|
||||||
blackbox_register_new_file '#andpounds.txt'
|
blackbox_register_new_file '#andpounds.txt'
|
||||||
assert_file_missing '#andpounds.txt'
|
assert_file_missing '#andpounds.txt'
|
||||||
assert_file_exists '#andpounds.txt'.gpg
|
assert_file_exists '#andpounds.txt'.gpg
|
||||||
assert_line_exists '\#andpounds.txt' .gitignore
|
assert_line_exists '/#andpounds.txt' .gitignore
|
||||||
|
|
||||||
PHASE 'Bob enrolls stars*bars?.txt'
|
PHASE 'Bob enrolls stars*bars?.txt'
|
||||||
echo A very commented file >'stars*bars?.txt'
|
echo A very wild and questioned file >'stars*bars?.txt'
|
||||||
blackbox_register_new_file 'stars*bars?.txt'
|
blackbox_register_new_file 'stars*bars?.txt'
|
||||||
assert_file_missing 'stars*bars?.txt'
|
assert_file_missing 'stars*bars?.txt'
|
||||||
assert_file_exists 'stars*bars?.txt'.gpg
|
assert_file_exists 'stars*bars?.txt'.gpg
|
||||||
assert_line_exists 'stars\*bars\?.txt' .gitignore
|
assert_line_exists '/stars\*bars\?.txt' .gitignore
|
||||||
|
|
||||||
# TODO(tlim): Add test to make sure that now alice can NOT decrypt.
|
PHASE 'Bob enrolls space space.txt'
|
||||||
|
echo A very spacey file >'space space.txt'
|
||||||
|
blackbox_register_new_file 'space space.txt'
|
||||||
|
assert_file_missing 'space space.txt'
|
||||||
|
assert_file_exists 'space space.txt'.gpg
|
||||||
|
assert_line_exists '/space space.txt' .gitignore
|
||||||
|
|
||||||
|
PHASE 'Bob checks out stars*bars?.txt.'
|
||||||
|
blackbox_edit_start 'stars*bars?.txt'
|
||||||
|
assert_file_exists 'stars*bars?.txt'
|
||||||
|
assert_file_exists 'stars*bars?.txt'
|
||||||
|
assert_file_md5hash 'stars*bars?.txt' "448e018faade28cede2bf6f33c3c2dfb"
|
||||||
|
|
||||||
|
PHASE 'Bob checks out space space.txt.'
|
||||||
|
blackbox_edit_start 'space space.txt'
|
||||||
|
assert_file_exists 'space space.txt'
|
||||||
|
assert_file_exists 'space space.txt'
|
||||||
|
assert_file_md5hash 'space space.txt' "de1d4e4a07046f81af5d3c0194b78742"
|
||||||
|
|
||||||
|
PHASE 'Bob shreds all exposed files.'
|
||||||
|
assert_file_exists 'my/path/to/relsecrets.txt'
|
||||||
|
assert_file_exists 'secret.txt'
|
||||||
|
blackbox_shred_all_files
|
||||||
|
assert_file_missing '!important!.txt'
|
||||||
|
assert_file_missing '#andpounds.txt'
|
||||||
|
assert_file_missing 'mistake.txt'
|
||||||
|
assert_file_missing 'my/path/to/relsecrets.txt'
|
||||||
|
assert_file_missing 'secret.txt'
|
||||||
|
assert_file_missing 'space space.txt'
|
||||||
|
assert_file_missing 'stars*bars?.txt'
|
||||||
|
assert_file_exists '!important!.txt.gpg'
|
||||||
|
assert_file_exists '#andpounds.txt.gpg'
|
||||||
|
assert_file_exists 'mistake.txt.gpg'
|
||||||
|
assert_file_exists 'my/path/to/relsecrets.txt.gpg'
|
||||||
|
assert_file_exists 'secret.txt.gpg'
|
||||||
|
assert_file_exists 'space space.txt.gpg'
|
||||||
|
assert_file_exists 'stars*bars?.txt.gpg'
|
||||||
|
|
||||||
|
PHASE 'Bob updates all files.'
|
||||||
|
blackbox_update_all_files
|
||||||
|
assert_file_missing '!important!.txt'
|
||||||
|
assert_file_missing '#andpounds.txt'
|
||||||
|
assert_file_missing 'mistake.txt'
|
||||||
|
assert_file_missing 'my/path/to/relsecrets.txt'
|
||||||
|
assert_file_missing 'secret.txt'
|
||||||
|
assert_file_missing 'space space.txt'
|
||||||
|
assert_file_missing 'stars*bars?.txt'
|
||||||
|
assert_file_exists '!important!.txt.gpg'
|
||||||
|
assert_file_exists '#andpounds.txt.gpg'
|
||||||
|
assert_file_exists 'mistake.txt.gpg'
|
||||||
|
assert_file_exists 'my/path/to/relsecrets.txt.gpg'
|
||||||
|
assert_file_exists 'secret.txt.gpg'
|
||||||
|
assert_file_exists 'space space.txt.gpg'
|
||||||
|
assert_file_exists 'stars*bars?.txt.gpg'
|
||||||
|
|
||||||
|
PHASE 'Bob DEregisters mistake.txt'
|
||||||
|
touch 'mistake.txt'
|
||||||
|
blackbox_deregister_file 'mistake.txt.gpg'
|
||||||
|
assert_file_exists 'keyrings/live/blackbox-admins.txt'
|
||||||
|
assert_file_exists 'keyrings/live/blackbox-files.txt'
|
||||||
|
assert_line_not_exists 'mistake.txt' 'keyrings/live/blackbox-files.txt'
|
||||||
|
assert_file_missing 'mistake.txt.gpg'
|
||||||
|
assert_file_exists 'mistake.txt'
|
||||||
|
# Now remove 'mistake.txt' to leave the area clean.
|
||||||
|
rm 'mistake.txt'
|
||||||
|
|
||||||
|
PHASE 'Bob enrolls multiple files: multi1.txt and multi2.txt'
|
||||||
|
echo 'One singular sensation.' >'multi1.txt'
|
||||||
|
echo 'Another singular sensation.' >'multi2.txt'
|
||||||
|
blackbox_register_new_file 'multi1.txt' 'multi2.txt'
|
||||||
|
assert_file_missing 'multi1.txt'
|
||||||
|
assert_file_exists 'multi1.txt'.gpg
|
||||||
|
assert_line_exists '/multi1.txt' .gitignore
|
||||||
|
assert_file_missing 'multi2.txt'
|
||||||
|
assert_file_exists 'multi2.txt'.gpg
|
||||||
|
assert_line_exists '/multi2.txt' .gitignore
|
||||||
|
|
||||||
|
PHASE 'Alice returns. She should be locked out'
|
||||||
|
assert_file_missing 'secret.txt'
|
||||||
|
become_alice
|
||||||
|
PHASE 'Alice tries to decrypt secret.txt. Is blocked.'
|
||||||
|
if blackbox_edit_start secret.txt ; then
|
||||||
|
echo 'ERROR: Alice was able to decrypt secret.txt! She should have been blocked.'
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo 'NOTE: Alice was not able to decrypt secret.txt as expected.'
|
||||||
|
fi
|
||||||
|
|
||||||
|
PHASE 'Bob returns. Tries to update all files with a corrupt blackbox-admins.txt'
|
||||||
|
become_bob
|
||||||
|
# Corrupt the blackbox-admins.txt list:
|
||||||
|
echo 'abba@notarealuser.com' >> keyrings/live/blackbox-admins.txt
|
||||||
|
# Make sure it fails.
|
||||||
|
if blackbox_update_all_files; then
|
||||||
|
echo '!!!!! blackbox_update_all_files should have failed and it did NOT.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# Cleanup:
|
||||||
|
blackbox_removeadmin abba@notarealuser.com
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: Create a new directory. "git clone" the repo into it.
|
||||||
|
|
||||||
#
|
#
|
||||||
# ASSERTIONS
|
# ASSERTIONS
|
||||||
#
|
#
|
||||||
|
|
||||||
|
echo '========== Verifying .gnupg was not accidentally created.'
|
||||||
|
|
||||||
if [[ -e $HOME/.gnupg ]]; then
|
if [[ -e $HOME/.gnupg ]]; then
|
||||||
echo "ASSERT FAILED: $HOME/.gnupg should not exist."
|
echo "ASSERT FAILED: $HOME/.gnupg should not exist."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo '========== DONE with tests. Outputing some diagnostics:'
|
||||||
|
|
||||||
find .git?* * -type f -ls
|
find .git?* * -type f -ls
|
||||||
echo cd "$test_repository"
|
echo cd "$test_repository"
|
||||||
echo rm "$test_repository"
|
echo rm -rf "$test_repository"
|
||||||
echo DONE.
|
echo 'SUCCESS! Doing final clean-up then exiting.'
|
||||||
|
|||||||
67
tools/macports_report_upgrade.sh
Executable file
67
tools/macports_report_upgrade.sh
Executable file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Turn the Portfile.template into a Portfile.
|
||||||
|
# Usage:
|
||||||
|
# mk_portfile.sh TEMPLATE OUTPUTFILE VERSION
|
||||||
|
|
||||||
|
set -e
|
||||||
|
blackbox_home=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||||
|
source ${blackbox_home}/../bin/_stack_lib.sh
|
||||||
|
|
||||||
|
TEMPLATEFILE=tools/Portfile.template
|
||||||
|
OUTPUTFILE=Portfile
|
||||||
|
PORTVERSION=${1?"Arg 1 must be a version number like 1.20150222 (with no v)"} ; shift
|
||||||
|
|
||||||
|
# Add the version number to the template.
|
||||||
|
sed <"$TEMPLATEFILE" >"$OUTPUTFILE" -e 's/@@VERSION@@/'"$PORTVERSION"'/g'
|
||||||
|
|
||||||
|
# Test it. Record the failure in $checksumout
|
||||||
|
fgrep >/dev/null -x 'file:///var/tmp/ports' /opt/local/etc/macports/sources.conf || sudo sed -i -e '1s@^@file:///var/tmp/ports\'$'\n@' /opt/local/etc/macports/sources.conf
|
||||||
|
rm -rf /var/tmp/ports
|
||||||
|
mkdir -p /var/tmp/ports/security/vcs_blackbox
|
||||||
|
cp Portfile /var/tmp/ports/security/vcs_blackbox
|
||||||
|
( cd /var/tmp/ports && sudo portindex )
|
||||||
|
make_self_deleting_tempfile checksumout
|
||||||
|
set +e
|
||||||
|
sudo port -v checksum vcs_blackbox > "$checksumout" 2>/dev/null
|
||||||
|
ret=$?
|
||||||
|
|
||||||
|
# If it failed, grab the checksums. Then re-process the template with them.
|
||||||
|
if [[ $ret != 0 ]]; then
|
||||||
|
RMD160=$(awk <"$checksumout" '/^Distfile checksum: .*rmd160/ { print $NF }')
|
||||||
|
SHA256=$(awk <"$checksumout" '/^Distfile checksum: .*sha256/ { print $NF }')
|
||||||
|
echo RMD160=$RMD160
|
||||||
|
echo SHA256=$SHA256
|
||||||
|
echo
|
||||||
|
if [[ $RMD160 != '' && $SHA256 != '' ]]; then
|
||||||
|
sed <"$TEMPLATEFILE" >"$OUTPUTFILE" -e 's/@@VERSION@@/'"$PORTVERSION"'/g' -e 's/@@RMD160@@/'"$RMD160"'/g' -e 's/@@SHA256@@/'"$SHA256"'/g'
|
||||||
|
cp Portfile /var/tmp/ports/security/vcs_blackbox
|
||||||
|
( cd /var/tmp/ports && sudo portindex )
|
||||||
|
sudo port -v checksum vcs_blackbox
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate the diff
|
||||||
|
cp /opt/local/var/macports/sources/rsync.macports.org/release/tarballs/ports/security/vcs_blackbox/Portfile /var/tmp/ports/security/vcs_blackbox/Portfile.orig
|
||||||
|
( cd /var/tmp/ports/security/vcs_blackbox && diff --ignore-matching-lines='Id:' -u Portfile.orig Portfile ) > Portfile-vcs_blackbox.diff
|
||||||
|
open -R Portfile-vcs_blackbox.diff
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo 'portfile is in:'
|
||||||
|
echo ' /var/tmp/ports/security/vcs_blackbox/Portfile'
|
||||||
|
echo 'cleanup:'
|
||||||
|
echo ' sudo vi /opt/local/etc/macports/sources.conf'
|
||||||
|
|
||||||
|
echo "
|
||||||
|
PLEASE OPEN A TICKET WITH THIS INFORMATION:
|
||||||
|
https://trac.macports.org/newticket
|
||||||
|
Summary: vcs_blackbox @$PORTVERSION Update to latest upstream
|
||||||
|
Description:
|
||||||
|
New upstream of vcs_blackbox.
|
||||||
|
github.setup and checksums updated.
|
||||||
|
Type: update
|
||||||
|
Component: ports
|
||||||
|
Port: vcs_blackbox
|
||||||
|
Keywords: maintainer haspatch
|
||||||
|
"
|
||||||
|
echo 'Attach: Portfile-vcs_blackbox.diff'
|
||||||
76
tools/mk_deb_fpmdir
Executable file
76
tools/mk_deb_fpmdir
Executable file
@@ -0,0 +1,76 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
|
||||||
|
# Use fpm to package up files into a DEB .
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# mk_deb_fpmdir PACKAGENAME MANIFEST1 MANIFEST2 ...
|
||||||
|
|
||||||
|
# Example:
|
||||||
|
# Make a package foopkg manifest.txt
|
||||||
|
# Where "manifest.txt" contains:
|
||||||
|
# exec /usr/bin/stack_makefqdn misc/stack_makefqdn.py
|
||||||
|
# exec /usr/bin/bar bar/bar.sh
|
||||||
|
# read /usr/man/man1/bar.1 bar/bar.1.man
|
||||||
|
# 0444 /etc/foo.conf bar/foo.conf
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Parameters for this DEB:
|
||||||
|
PACKAGENAME=${1?"First arg must be the package name."}
|
||||||
|
shift
|
||||||
|
|
||||||
|
# Defaults that can be overridden:
|
||||||
|
# All packages are 1.0 unless otherwise specifed:
|
||||||
|
: ${PKGVERSION:=1.0} ;
|
||||||
|
# If there is no iteration setting, assume "1":
|
||||||
|
: ${PKGRELEASE:=1}
|
||||||
|
# If there is no epoch, assume 0
|
||||||
|
: ${PKGEPOCH:=0}
|
||||||
|
|
||||||
|
# The DEB is output here: (should be a place that can be wiped)
|
||||||
|
OUTPUTDIR="${HOME}/debbuild-$PACKAGENAME"
|
||||||
|
# The TeamCity templates expect to find the list of artifacts here:
|
||||||
|
DEB_BIN_LIST="${OUTPUTDIR}/bin-packages.txt"
|
||||||
|
|
||||||
|
# -- Now the real work can be done.
|
||||||
|
|
||||||
|
# Clean the output dir.
|
||||||
|
rm -rf "$OUTPUTDIR"
|
||||||
|
mkdir -p "$OUTPUTDIR/installroot"
|
||||||
|
|
||||||
|
# Copy the files into place:
|
||||||
|
set -o pipefail # Error out if any manifest is not found.
|
||||||
|
cat """$@""" | while read -a arr ; do
|
||||||
|
PERM="${arr[0]}"
|
||||||
|
case $PERM in
|
||||||
|
\#*) continue ;; # Skip comments.
|
||||||
|
exec) PERM=0755 ;;
|
||||||
|
read) PERM=0744 ;;
|
||||||
|
*) ;;
|
||||||
|
esac
|
||||||
|
DST="$OUTPUTDIR/installroot/${arr[1]}"
|
||||||
|
SRC="${arr[2]}"
|
||||||
|
if [[ $SRC == "cmd/"* || $SRC == *"/cmd/"* ]]; then
|
||||||
|
( cd $(dirname "$SRC" ) && go build -a -v )
|
||||||
|
fi
|
||||||
|
install -D -T -b -m "$PERM" -T "$SRC" "$DST"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Build the DEB:
|
||||||
|
cd "$OUTPUTDIR" && fpm -s dir -t deb \
|
||||||
|
-a all \
|
||||||
|
-n "${PACKAGENAME}" \
|
||||||
|
--epoch "${PKGEPOCH}" \
|
||||||
|
--version "${PKGVERSION}" \
|
||||||
|
--iteration "${PKGRELEASE}" \
|
||||||
|
${PKGDESCRIPTION:+ --description="${PKGDESCRIPTION}"} \
|
||||||
|
${PKGVENDOR:+ --vendor="${PKGVENDOR}"} \
|
||||||
|
-C "$OUTPUTDIR/installroot" \
|
||||||
|
.
|
||||||
|
|
||||||
|
# TeamCity templates for DEBS expect to find
|
||||||
|
# the list of all packages created in bin-packages.txt.
|
||||||
|
# Generate that list:
|
||||||
|
find "$OUTPUTDIR" -maxdepth 1 -name '*.deb' >"$DEB_BIN_LIST"
|
||||||
|
# Output it for debugging purposes:
|
||||||
|
cat "$DEB_BIN_LIST"
|
||||||
18
tools/mk_deb_fpmdir.stack_blackbox.txt
Normal file
18
tools/mk_deb_fpmdir.stack_blackbox.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
exec /usr/bin/_blackbox_common.sh ../bin/_blackbox_common.sh
|
||||||
|
exec /usr/bin/_stack_lib.sh ../bin/_stack_lib.sh
|
||||||
|
exec /usr/bin/blackbox_addadmin ../bin/blackbox_addadmin
|
||||||
|
exec /usr/bin/blackbox_cat ../bin/blackbox_cat
|
||||||
|
exec /usr/bin/blackbox_decrypt_all_files ../bin/blackbox_decrypt_all_files
|
||||||
|
exec /usr/bin/blackbox_deregister_file ../bin/blackbox_deregister_file
|
||||||
|
exec /usr/bin/blackbox_diff ../bin/blackbox_diff
|
||||||
|
exec /usr/bin/blackbox_edit ../bin/blackbox_edit
|
||||||
|
exec /usr/bin/blackbox_edit_end ../bin/blackbox_edit_end
|
||||||
|
exec /usr/bin/blackbox_edit_start ../bin/blackbox_edit_start
|
||||||
|
exec /usr/bin/blackbox_initialize ../bin/blackbox_initialize
|
||||||
|
exec /usr/bin/blackbox_list_files ../bin/blackbox_list_files
|
||||||
|
exec /usr/bin/blackbox_postdeploy ../bin/blackbox_postdeploy
|
||||||
|
exec /usr/bin/blackbox_register_new_file ../bin/blackbox_register_new_file
|
||||||
|
exec /usr/bin/blackbox_removeadmin ../bin/blackbox_removeadmin
|
||||||
|
exec /usr/bin/blackbox_shred_all_files ../bin/blackbox_shred_all_files
|
||||||
|
exec /usr/bin/blackbox_update_all_files ../bin/blackbox_update_all_files
|
||||||
|
exec /usr/bin/blackbox_whatsnew ../bin/blackbox_whatsnew
|
||||||
32
tools/mk_macports
Executable file
32
tools/mk_macports
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Install files into MacPorts DESTDIR
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# mk_macports MANIFEST MANIFEST1 ...
|
||||||
|
|
||||||
|
# Where "manifest.txt" contains:
|
||||||
|
# exec /usr/bin/stack_makefqdn misc/stack_makefqdn.py
|
||||||
|
# exec /usr/bin/bar bar/bar.sh
|
||||||
|
# read /usr/man/man1/bar.1 bar/bar.1.man
|
||||||
|
# 0444 /etc/foo.conf bar/foo.conf
|
||||||
|
# (NOTE: "exec" means 0755; "read" means 0744)
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Fail if DESTDIR is not set.
|
||||||
|
DESTDIR="${DESTDIR?"Envvar DESTDIR must be set to destination dir."}"
|
||||||
|
|
||||||
|
# Copy the files into place:
|
||||||
|
cat """$@""" | while read -a arr ; do
|
||||||
|
PERM="${arr[0]}"
|
||||||
|
case $PERM in
|
||||||
|
\#*) continue ;; # Skip comments.
|
||||||
|
exec) PERM=0755 ;;
|
||||||
|
read) PERM=0744 ;;
|
||||||
|
*) ;;
|
||||||
|
esac
|
||||||
|
DST="$DESTDIR/${arr[1]}"
|
||||||
|
SRC="${arr[2]}"
|
||||||
|
install -m "$PERM" "$SRC" "$DST"
|
||||||
|
done
|
||||||
18
tools/mk_macports.vcs_blackbox.txt
Normal file
18
tools/mk_macports.vcs_blackbox.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
exec bin/_blackbox_common.sh ../bin/_blackbox_common.sh
|
||||||
|
exec bin/_stack_lib.sh ../bin/_stack_lib.sh
|
||||||
|
exec bin/blackbox_addadmin ../bin/blackbox_addadmin
|
||||||
|
exec bin/blackbox_cat ../bin/blackbox_cat
|
||||||
|
exec bin/blackbox_decrypt_all_files ../bin/blackbox_decrypt_all_files
|
||||||
|
exec bin/blackbox_deregister_file ../bin/blackbox_deregister_file
|
||||||
|
exec bin/blackbox_diff ../bin/blackbox_diff
|
||||||
|
exec bin/blackbox_edit ../bin/blackbox_edit
|
||||||
|
exec bin/blackbox_edit_end ../bin/blackbox_edit_end
|
||||||
|
exec bin/blackbox_edit_start ../bin/blackbox_edit_start
|
||||||
|
exec bin/blackbox_initialize ../bin/blackbox_initialize
|
||||||
|
exec bin/blackbox_list_files ../bin/blackbox_list_files
|
||||||
|
exec bin/blackbox_postdeploy ../bin/blackbox_postdeploy
|
||||||
|
exec bin/blackbox_register_new_file ../bin/blackbox_register_new_file
|
||||||
|
exec bin/blackbox_removeadmin ../bin/blackbox_removeadmin
|
||||||
|
exec bin/blackbox_shred_all_files ../bin/blackbox_shred_all_files
|
||||||
|
exec bin/blackbox_update_all_files ../bin/blackbox_update_all_files
|
||||||
|
exec bin/blackbox_whatsnew ../bin/blackbox_whatsnew
|
||||||
76
tools/mk_rpm_fpmdir
Executable file
76
tools/mk_rpm_fpmdir
Executable file
@@ -0,0 +1,76 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
|
||||||
|
# Use fpm to package up files into an RPM.
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# mk_rpm_fpmdir PACKAGENAME MANIFEST1 MANIFEST2 ...
|
||||||
|
|
||||||
|
# Example:
|
||||||
|
# Make a package foopkg manifest.txt
|
||||||
|
# Where "manifest.txt" contains:
|
||||||
|
# exec /usr/bin/stack_makefqdn misc/stack_makefqdn.py
|
||||||
|
# exec /usr/bin/bar bar/bar.sh
|
||||||
|
# read /usr/man/man1/bar.1 bar/bar.1.man
|
||||||
|
# 0444 /etc/foo.conf bar/foo.conf
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Parameters for this RPM:
|
||||||
|
PACKAGENAME=${1?"First arg must be the package name."}
|
||||||
|
shift
|
||||||
|
|
||||||
|
# Defaults that can be overridden:
|
||||||
|
# All packages are 1.0 unless otherwise specifed:
|
||||||
|
: ${PKGVERSION:=1.0} ;
|
||||||
|
# If there is no iteration setting, assume "1":
|
||||||
|
: ${PKGRELEASE:=1}
|
||||||
|
# If there is no epoch, assume 0
|
||||||
|
: ${PKGEPOCH:=0}
|
||||||
|
|
||||||
|
# The RPM is output here: (should be a place that can be wiped)
|
||||||
|
OUTPUTDIR="${HOME}/rpmbuild-$PACKAGENAME"
|
||||||
|
# The TeamCity templates expect to find the list of artifacts here:
|
||||||
|
RPM_BIN_LIST="${OUTPUTDIR}/bin-packages.txt"
|
||||||
|
|
||||||
|
# -- Now the real work can be done.
|
||||||
|
|
||||||
|
# Clean the output dir.
|
||||||
|
rm -rf "$OUTPUTDIR"
|
||||||
|
mkdir -p "$OUTPUTDIR/installroot"
|
||||||
|
|
||||||
|
# Copy the files into place:
|
||||||
|
set -o pipefail # Error out if any manifest is not found.
|
||||||
|
cat """$@""" | while read -a arr ; do
|
||||||
|
PERM="${arr[0]}"
|
||||||
|
case $PERM in
|
||||||
|
\#*) continue ;; # Skip comments.
|
||||||
|
exec) PERM=0755 ;;
|
||||||
|
read) PERM=0744 ;;
|
||||||
|
*) ;;
|
||||||
|
esac
|
||||||
|
DST="$OUTPUTDIR/installroot/${arr[1]}"
|
||||||
|
SRC="${arr[2]}"
|
||||||
|
if [[ $SRC == "cmd/"* || $SRC == *"/cmd/"* ]]; then
|
||||||
|
( cd $(dirname "$SRC" ) && go build -a -v )
|
||||||
|
fi
|
||||||
|
install -D -T -b -m "$PERM" -T "$SRC" "$DST"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Build the RPM:
|
||||||
|
cd "$OUTPUTDIR" && fpm -s dir -t rpm \
|
||||||
|
-a all \
|
||||||
|
-n "${PACKAGENAME}" \
|
||||||
|
--epoch "${PKGEPOCH}" \
|
||||||
|
--version "${PKGVERSION}" \
|
||||||
|
--iteration "${PKGRELEASE}" \
|
||||||
|
${PKGDESCRIPTION:+ --description="${PKGDESCRIPTION}"} \
|
||||||
|
${PKGVENDOR:+ --vendor="${PKGVENDOR}"} \
|
||||||
|
-C "$OUTPUTDIR/installroot" \
|
||||||
|
.
|
||||||
|
|
||||||
|
# TeamCity templates for RPMS expect to find
|
||||||
|
# the list of all packages created in bin-packages.txt.
|
||||||
|
# Generate that list:
|
||||||
|
find "$OUTPUTDIR" -maxdepth 1 -name '*.rpm' >"$RPM_BIN_LIST"
|
||||||
|
# Output it for debugging purposes:
|
||||||
|
cat "$RPM_BIN_LIST"
|
||||||
20
tools/mk_rpm_fpmdir.stack_blackbox.txt
Normal file
20
tools/mk_rpm_fpmdir.stack_blackbox.txt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Update tools/mk_rpm_fpmdir.stack_blackbox.txt. Other files generate from it.
|
||||||
|
read /etc/profile.d/usrblackbox.sh profile.d-usrblackbox.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_cat ../bin/blackbox_cat
|
||||||
|
exec /usr/blackbox/bin/blackbox_decrypt_all_files ../bin/blackbox_decrypt_all_files
|
||||||
|
exec /usr/blackbox/bin/blackbox_deregister_file ../bin/blackbox_deregister_file
|
||||||
|
exec /usr/blackbox/bin/blackbox_diff ../bin/blackbox_diff
|
||||||
|
exec /usr/blackbox/bin/blackbox_edit ../bin/blackbox_edit
|
||||||
|
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_initialize ../bin/blackbox_initialize
|
||||||
|
exec /usr/blackbox/bin/blackbox_list_files ../bin/blackbox_list_files
|
||||||
|
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_removeadmin ../bin/blackbox_removeadmin
|
||||||
|
exec /usr/blackbox/bin/blackbox_shred_all_files ../bin/blackbox_shred_all_files
|
||||||
|
exec /usr/blackbox/bin/blackbox_update_all_files ../bin/blackbox_update_all_files
|
||||||
|
exec /usr/blackbox/bin/blackbox_whatsnew ../bin/blackbox_whatsnew
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
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/_stack_lib.sh bin/_stack_lib.sh
|
|
||||||
exec /usr/blackbox/bin/blackbox_addadmin bin/blackbox_addadmin
|
|
||||||
exec /usr/blackbox/bin/blackbox_cat bin/blackbox_cat
|
|
||||||
exec /usr/blackbox/bin/blackbox_edit bin/blackbox_edit
|
|
||||||
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_initialize bin/blackbox_initialize
|
|
||||||
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_removeadmin bin/blackbox_removeadmin
|
|
||||||
exec /usr/blackbox/bin/blackbox_shred_all_files bin/blackbox_shred_all_files
|
|
||||||
exec /usr/blackbox/bin/blackbox_update_all_files bin/blackbox_update_all_files
|
|
||||||
134
tools/test_functions.sh
Executable file
134
tools/test_functions.sh
Executable file
@@ -0,0 +1,134 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
function PHASE() {
|
||||||
|
echo '********************'
|
||||||
|
echo '********************'
|
||||||
|
echo '*********' """$@"""
|
||||||
|
echo '********************'
|
||||||
|
echo '********************'
|
||||||
|
}
|
||||||
|
|
||||||
|
function md5sum_file() {
|
||||||
|
# Portably generate the MD5 hash of file $1.
|
||||||
|
case $(uname -s) in
|
||||||
|
Darwin )
|
||||||
|
md5 -r "$1" | awk '{ print $1 }'
|
||||||
|
;;
|
||||||
|
Linux )
|
||||||
|
md5sum "$1" | awk '{ print $1 }'
|
||||||
|
;;
|
||||||
|
CYGWIN* )
|
||||||
|
md5sum "$1" | awk '{ print $1 }'
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo 'ERROR: Unknown OS. Exiting.'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
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."
|
||||||
|
echo "PWD=$(/bin/pwd -P)"
|
||||||
|
#echo "LS START"
|
||||||
|
#ls -la
|
||||||
|
#echo "LS END"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function assert_file_md5hash() {
|
||||||
|
local file="$1"
|
||||||
|
local wanted="$2"
|
||||||
|
assert_file_exists "$file"
|
||||||
|
local found
|
||||||
|
found=$(md5sum_file "$file")
|
||||||
|
if [[ "$wanted" != "$found" ]]; then
|
||||||
|
echo "ASSERT FAILED: $file hash wanted=$wanted found=$found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function assert_file_group() {
|
||||||
|
local file="$1"
|
||||||
|
local wanted="$2"
|
||||||
|
local found
|
||||||
|
assert_file_exists "$file"
|
||||||
|
|
||||||
|
case $(uname -s) in
|
||||||
|
Darwin|FreeBSD )
|
||||||
|
found=$(stat -f '%Sg' "$file")
|
||||||
|
;;
|
||||||
|
Linux )
|
||||||
|
found=$(stat -c '%G' "$file")
|
||||||
|
;;
|
||||||
|
CYGWIN* )
|
||||||
|
echo "ASSERT_FILE_GROUP: Running on Cygwin. Not being tested."
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo 'ERROR: Unknown OS. Exiting.'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ "$wanted" != "$found" ]]; then
|
||||||
|
echo "ASSERT FAILED: $file chgrp wanted=$wanted found=$found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function assert_file_perm() {
|
||||||
|
local wanted="$1"
|
||||||
|
local file="$2"
|
||||||
|
local found
|
||||||
|
assert_file_exists "$file"
|
||||||
|
|
||||||
|
case $(uname -s) in
|
||||||
|
Darwin|FreeBSD )
|
||||||
|
found=$(stat -f '%Sp' "$file")
|
||||||
|
;;
|
||||||
|
# NB(tlim): CYGWIN hasn't been tested. It might be more like Darwin.
|
||||||
|
Linux | CYGWIN* )
|
||||||
|
found=$(stat -c '%A' "$file")
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo 'ERROR: Unknown OS. Exiting.'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ "$wanted" != "$found" ]]; then
|
||||||
|
echo "ASSERT FAILED: $file chgrp wanted=$wanted found=$found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function assert_line_not_exists() {
|
||||||
|
local target="$1"
|
||||||
|
local file="$2"
|
||||||
|
assert_file_exists "$file"
|
||||||
|
if grep -F -x -s -q >/dev/null "$target" "$file" ; then
|
||||||
|
echo "ASSERT FAILED: line '$target' should not exist in file $file"
|
||||||
|
echo "==== file contents: START $file"
|
||||||
|
cat "$file"
|
||||||
|
echo "==== file contents: END $file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function assert_line_exists() {
|
||||||
|
local target="$1"
|
||||||
|
local file="$2"
|
||||||
|
assert_file_exists "$file"
|
||||||
|
if ! grep -F -x -s -q >/dev/null "$target" "$file" ; then
|
||||||
|
echo "ASSERT FAILED: line '$target' should exist in file $file"
|
||||||
|
echo "==== file contents: START $file"
|
||||||
|
cat "$file"
|
||||||
|
echo "==== file contents: END $file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user