diff --git a/openpgp/gitprotect.sh b/openpgp/gitprotect.sh new file mode 100755 index 0000000000000000000000000000000000000000..22dfc1f67726110794dcfe66173ef3e67445d27b --- /dev/null +++ b/openpgp/gitprotect.sh @@ -0,0 +1,224 @@ +#!/bin/bash +# +# gitprotect.sh +# +# Copyright (C) 2013, Branko Majic <branko@majic.rs> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +program="gitprotect.sh" +version="0.1" + +function usage() { + cat <<EOF +$program $version, a utility for managing GPG-protected directories in a git +repository. + +Usage: $program [OPTIONS] command + +$program is a utility for managing GPG-protected directories in a git +repository. The main intention of the utility is to provide a viable solution +for storing the passwords centrally, allowing small geographically disperse +teams to exchange them in a secure manner. The utility relies on using GnuPG +utility for performing all tasks related to encryption and decryption. + +The following commands are provided for managing the repository/directories: + + init + + Initialises the current directory of a git repository, setting it up for use + with gitencrypt. + + addkey + + Adds keys to directory's GnuPG public keyring, and marks them as + trusted. Command expects one or more positional arguments which should be + either files containing an OpenPGP public key, or key identifiers from + user's own keyring. + + rmkey + + Removes one or more keys from the git repository GnuPG keyring. Command + expects one or more positional arguments which should be key identifiers + from the git repository directory's GnuPG keyring. + + listkeys + + Lists the keys from the git repository GnuPG keyring. + +$program accepts the following options: + + -v show script version and licensing information + -h show usage help + + +Please report bugs and send feature requests to <branko@majic.rs>. +EOF +} + +function version() { + cat <<EOF +$program, version $version + ++-----------------------------------------------------------------------+ +| Copyright (C) 2013, Branko Majic <branko@majic.rs> | +| | +| This program is free software: you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by | +| the Free Software Foundation, either version 3 of the License, or | +| (at your option) any later version. | +| | +| This program is distributed in the hope that it will be useful, | +| but WITHOUT ANY WARRANTY; without even the implied warranty of | +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | +| GNU General Public License for more details. | +| | +| You should have received a copy of the GNU General Public License | +| along with this program. If not, see <http://www.gnu.org/licenses/>. | ++-----------------------------------------------------------------------+ + +EOF +} + +# +# Checks if the current directory is a sub-directory of a git repository or not. +# +# Returns: +# 0 if the current directory is a sub-directory of a git repository, 1 +# otherwise. +# +# Outputs: +# If the current directory is not a sub-directory of a git repository, it will +# output an informative message +# +function inGit() { + # Check if we are inside of a git repository. + if ! git rev-parse --git-dir >/dev/null 2>&1; then + echo "ERROR: $program must be executed from within a git repository." >&2 + echo "Working directory is '$(pwd)'" >&2 + return 1 + fi + + return 0 +} + +# +# Checks if the current directory has been configured for gitprotect or not. +# +# Returns: +# 0 if the current directory has been configured for use with gitprotect, 1 +# otherwise. +# +# Outputs: +# If the current directory has not been configured, it will output an +# informative error message. +function gitprotectConfigured() { + if ! [[ -d "$gnupgHome" ]]; then + echo "ERROR: Current directory has not been configured for use with $program." >&2 + echo "You can initialise the current directory with command '$program init'." >&2 + echo "Working directory is '$(pwd)'." >&2 + return 1 + fi + + return 0 +} + +# +# Error codes. +# +ERR_NOTINGIT=10 +ERR_NOCONFIG=11 + +# If no arguments were given, just show usage help. +if [[ -z $1 ]]; then + usage + exit 0 +fi + +# Parse the arguments +while getopts "vh" opt; do + case "$opt" in + v) version + exit 0;; + h) usage + exit 0;; + *) usage + exit 1;; + esac +done +i=$OPTIND +shift $(($i-1)) + +# Read the command parameter. +command="$1" +shift + +# Make sure the command is run from within a git repository. +inGit || exit "$ERR_NOTINGIT" + +# Set-up some default values. +gnupgHome="$(pwd)/.gnupg" + +if [[ $command == "init" ]]; then + if [[ -d $gnupgHome ]]; then + echo "Directory already set-up." + exit 0 + fi + + # Created the local .gnupg directory. + mkdir "$gnupgHome" + chmod 700 "$gnupgHome" + gpg2 --homedir "$gnupgHome" --list-keys 2>/dev/null +elif [[ $command == "addkey" ]]; then + gitprotectConfigured || exit "$ERR_NOCONFIG" + + # Process all the keys specified. + for key in "$@"; do + # First try accessing a file by the given key name. Otherwise treat it + # as key identifier. + if [[ -f $key ]]; then + if ! gpg2 --homedir "$gnupgHome" --import "$key"; then + echo "ERROR: Failed to add key from file '$key'." >&2 + fi + else + if ! gpg2 --list-keys "$key" >/dev/null 2>&1; then + echo "WARN: Key with identifier '$key' not found in user's GnuPG keyring. Skipping." >&2 + else + if ! gpg2 --armor --export "$key" | gpg2 --homedir "$gnupgHome" --import; then + echo "ERROR: Failed to add key with identifier '$key')." >&2 + fi + fi + fi + done +elif [[ $command = "rmkey" ]]; then + gitprotectConfigured || exit "$ERR_NOCONFIG" + + # Process all the keys specified. + for key in "$@"; do + if ! gpg2 --homedir "$gnupgHome" --list-key "$key" 2>/dev/null; then + echo "WARN: Key with identifier '$key' not found in git repository directory's GnuPG keyring. Skipping" >&2 + else + if ! gpg2 --homedir "$gnupgHome" --yes --delete-key "$key"; then + echo "ERROR: Failed to remove the key with identifier '$key'." >&2 + fi + fi + done +elif [[ $command = "listkeys" ]]; then + gitprotectConfigured || exit "$ERR_NOCONFIG" + gpg2 --fingerprint --homedir "$gnupgHome" --list-public-keys --keyid-format long +else + echo "ERROR: Unsupported command '$command'" >&2 +fi +