diff --git a/doc/git-integration.md b/doc/git-integration.md index 401d4da..230c9cf 100644 --- a/doc/git-integration.md +++ b/doc/git-integration.md @@ -112,10 +112,23 @@ To create and verify these signatures we simply wrap the gpg binary with our own code, `ots-git-gpg-wrapper`. Git allows you to override the default GnuPG binary (`/usr/bin/gpg`) with your own using the `gpg.program` config option. Unfortunately that option doesn't let you set additional command line flags, so -we use one more wrapper, `ots-git-gpg-wrapper.sh`. You can set all this up with the -following: - - git config --global gpg.program +we use one more wrapper, `ots-git-gpg-wrapper.sh`. You can set all this up with +either of the following: + +```bash +# just specify ots-git-gpg-wrapper.sh and let `git` find it itself +git config --global gpg.program ots-git-gpg-wrapper.sh +# manually enter the full path to ots-git-gpg-wrapper.sh +git config --global gpg.program +# auto-detect the full path using `which` +git config --global gpg.program "`which ots-git-gpg-wrapper.sh`" +``` + +> **Note:** If you get errors that it doesn't find the +> `ots-git-gpg-wrapper.sh`, make sure that your `PATH` includes the +> installation location, e.g. by appending `export +> PATH="$PATH:$HOME/.local/bin"` to your `.bashrc`. You can check the +> installation location with `pip show -f opentimestamps-client`. Now try creating a test repository and signing a commit: @@ -347,3 +360,47 @@ calendar servers: gpg: using RSA key 6399011044E8AFB2 gpg: Good signature from "Peter Todd " gpg: aka "[jpeg image of size 5220]" + + +Configuration +------------- + +The OpenTimestamps GPG wrapper can be configured in the following ways: + + +```bash +# Disable OpenTimestamps for the current repository: +git config opentimestamps.enable false + +# Disable OpenTimestamps by default for all git repositories on this machine: +git config --global opentimestamps.enable false + +# Temporarily (re)enable OpenTimestamps signatures in `git log`: +OPENTIMESTAMPS=true git log --show-signature + +# Temporarily ignore OpenTimestamps signatures in `git log`: +OPENTIMESTAMPS=false git log --show-signature + +# Don't use OpenTimestamps for timestamping for one commit: +OPENTIMESTAMPS=false git commit -m "commit message" + +# Only use OpenTimestamps for `git show` and `git commit` (not e.g. `git log`) +git config --global opentimestamps.only-for show,commit + +# Don't try to use a local Bitcoin node for verification. +# This gets rids of error messages in `git show` and `git log` +# when you don't have a Bitcoin node running. +git config --global opentimestamps.flags '--no-bitcoin' +``` + +Troubleshooting +--------------- + +You can troubleshoot the OpenTimestamps process like this: + +```bash +# Debug the OpenTimeStamps process +GIT_TRACE=true OPENTIMESTAMPS_GIT_GPG_WRAPPER_DEBUG=true OPENTIMESTAMPS_GIT_GPG_WRAPPER_FLAGS='-vvvvv' git log --show-signature +``` + +This however does not seem to work properly for `git commit` unfortunately. diff --git a/ots-git-gpg-wrapper.sh b/ots-git-gpg-wrapper.sh index 32668e7..c38ec28 100755 --- a/ots-git-gpg-wrapper.sh +++ b/ots-git-gpg-wrapper.sh @@ -5,4 +5,100 @@ # Required because git's gpg.program option doesn't allow you to set command # line options; see the doc/git-integration.md -ots-git-gpg-wrapper --gpg-program "`which gpg`" -- "$@" +############################## +### Configuration Examples ### +############################## + +# Disable OpenTimestamps for the current repository: +# +# > git config opentimestamps.enable false +# +# Disable OpenTimestamps by default for all git repositories on this machine: +# +# > git config --global opentimestamps.enable false +# +# Temporarily (re)enable OpenTimestamps signatures in `git log`: +# +# > OPENTIMESTAMPS=true git log --show-signature +# +# Temporarily ignore OpenTimestamps signatures in `git log`: +# +# > OPENTIMESTAMPS=false git log --show-signature +# +# Don't use OpenTimestamps for timestamping for one commit: +# +# > OPENTIMESTAMPS=false git commit -m "commit message" +# +# Debug the OpenTimeStamps process for one call: +# +# > OPENTIMESTAMPS_GIT_GPG_WRAPPER_DEBUG=true OPENTIMESTAMPS_GIT_GPG_WRAPPER_FLAGS='-vvvvv' git log --show-signature +# +# Always debug the OpenTimeStamps process: +# +# > git config --global opentimestamps.debug true +# > git config --global opentimestamps.flags -vvvvvvv +# +# Don't attempt to connect to a local Bitcoin node (e.g. for verification). +# +# > git config --global opentimestamps.flags '--no-bitcoin' + +# defaults +test -n "$GPG" || GPG=gpg +test -n "$OPENTIMESTAMPS_GIT_GPG_WRAPPER_DEBUG" || OPENTIMESTAMPS_GIT_GPG_WRAPPER_DEBUG="`git config opentimestamps.debug 2>/dev/null || true`" +test -n "$OPENTIMESTAMPS_GIT_GPG_WRAPPER" || OPENTIMESTAMPS_GIT_GPG_WRAPPER=ots-git-gpg-wrapper +test -n "$OPENTIMESTAMPS_GIT_GPG_WRAPPER_FLAGS" || OPENTIMESTAMPS_GIT_GPG_WRAPPER_FLAGS="`git config opentimestamps.flags 2>/dev/null || true`" + +function debug() { if is_true "$OPENTIMESTAMPS_GIT_GPG_WRAPPER_DEBUG";then echo >&2 "ots: $@";fi } + +# config value pattern matching +true_pattern='^(y(es)?|true|enable)$' +false_pattern='^(no?|false|disable)$' +function check_pattern() { echo "$1" | grep -Eiq "$2"; } +function is_true() { if check_pattern "$1" "$false_pattern";then return 1;fi;check_pattern "$1" "$true_pattern"; } +# This git subcommand-detection fails if there are direct arguments to `git` before the subcommand. +# The full git cmdline should be parsed properly. Instead, we skip the git subcommand check in this case. +git_command="`cat /proc/"$PPID"/cmdline | tr '\0' '\n' | tail -n+2 | head -n1`" +if (echo "$git_command" | grep -qvx '[a-z]\+');then + debug "Can't determine git command if there are direct options to git, sorry..." + git_command= +fi +function opentimestamps_enabled() { + if test -n "$OPENTIMESTAMPS";then + if is_true "$OPENTIMESTAMPS";then + debug "Enabling OpenTimestamps due to OPENTIMESTAMPS='$OPENTIMESTAMPS'" + return 0 + else + debug "Disabling OpenTimestamps due to OPENTIMESTAMPS='$OPENTIMESTAMPS'" + return 1 + fi + fi + git_config_opentimestamps_only_for="`git config opentimestamps.only-for 2>/dev/null`" + if test -n "$git_config_opentimestamps_only_for" -a -n "$git_command";then + if (echo "$git_config_opentimestamps_only_for" | grep -o '[a-z]\+' | grep -qFx "$git_command" >/dev/null 2>/dev/null);then + debug "Enabling OpenTimestamps as \`git config opentimestamps.only-for\` = '$git_config_opentimestamps_only_for' contains the current git command '$git_command'" + else + debug "Disabling OpenTimestamps as \`git config opentimestamps.only-for\` = '$git_config_opentimestamps_only_for' doesn't contain the current git command '$git_command'" + return 1 + fi + fi + git_config_opentimestamps_enable="`git config opentimestamps.enable 2>/dev/null`" + if test -n "$git_config_opentimestamps_enable";then + if is_true "$git_config_opentimestamps_enable";then + debug "Enabling OpenTimestamps due to \`git config opentimestamps.enable\` = '$git_config_opentimestamps_enable'" + return 0 + else + debug "Disabling OpenTimestamps due to \`git config opentimestamps.enable\` = '$git_config_opentimestamps_enable'" + return 1 + fi + fi + debug "Enabling OpenTimestamps" + return 0 +} + +if opentimestamps_enabled;then + debug "executing >>>$OPENTIMESTAMPS_GIT_GPG_WRAPPER $OPENTIMESTAMPS_GIT_GPG_WRAPPER_FLAGS -- $@<<<" + exec $OPENTIMESTAMPS_GIT_GPG_WRAPPER $OPENTIMESTAMPS_GIT_GPG_WRAPPER_FLAGS -- "$@" +else + debug "executing >>>$GPG $@<<<" + exec $GPG "$@" +fi diff --git a/otsclient/git_gpg_wrapper.py b/otsclient/git_gpg_wrapper.py index 698ec84..871c53b 100644 --- a/otsclient/git_gpg_wrapper.py +++ b/otsclient/git_gpg_wrapper.py @@ -16,6 +16,7 @@ import bitcoin import logging import subprocess +import shutil import git from opentimestamps.core.git import GitTreeTimestamper @@ -30,7 +31,7 @@ def main(): parser = otsclient.args.make_common_options_arg_parser() - parser.add_argument("-g", "--gpg-program", action="store", default="/usr/bin/gpg", + parser.add_argument("-g", "--gpg-program", action="store", default=shutil.which("gpg") or "/usr/bin/gpg", help="Path to the GnuPG binary (default %(default)s)") parser.add_argument('-c','--calendar', metavar='URL', dest='calendar_urls', action='append', type=str, diff --git a/setup.py b/setup.py index 86c105c..e72b2c6 100644 --- a/setup.py +++ b/setup.py @@ -101,4 +101,7 @@ 'ots-git-gpg-wrapper = otsclient.git_gpg_wrapper:main', ], }, + + # Install the ots-git-gpg-wrapper.sh-script + scripts = ["ots-git-gpg-wrapper.sh"], )