From d52dfb1fcee76d19edbf7a4ee5c0f5488dab163d 2020-06-29 04:17:14
From: Branko Majic <branko@majic.rs>
Date: 2020-06-29 04:17:14
Subject: [PATCH] Committing the initial version of script. Implements initialisation and keyring management.

---

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
+