git-credential-netrc was hardcoded to decrypt with 'gpg' regardless of the gpg.program option. This is a problem on distributions like Debian that call modern GnuPG something else, like 'gpg2'. Set the command according to these settings in descending precedence 1. the git-credential-netrc command -g|--gpg option 2. the git gpg.program configuration option 3. the default: 'gpg' For conformance with Documentation/CodingGuidelines - use Git.pm for repository and global option queries - document -g|--gpg command option in command usage - test repository & command options - write documentation placeholders according to main standards Signed-off-by: Luis Marsano <luis.marsano@xxxxxxxxx> Acked-by: Ted Zlatanov <tzz@xxxxxxxxxxxx> --- contrib/credential/netrc/git-credential-netrc | 58 ++++++++++++------- .../netrc/t-git-credential-netrc.sh | 2 +- .../credential/netrc/test.command-option-gpg | 2 + contrib/credential/netrc/test.git-config-gpg | 2 + contrib/credential/netrc/test.netrc.gpg | 0 contrib/credential/netrc/test.pl | 22 ++++++- 6 files changed, 62 insertions(+), 24 deletions(-) create mode 100755 contrib/credential/netrc/test.command-option-gpg create mode 100755 contrib/credential/netrc/test.git-config-gpg create mode 100644 contrib/credential/netrc/test.netrc.gpg diff --git a/contrib/credential/netrc/git-credential-netrc b/contrib/credential/netrc/git-credential-netrc index 1571a7b26..0b9a94102 100755 --- a/contrib/credential/netrc/git-credential-netrc +++ b/contrib/credential/netrc/git-credential-netrc @@ -2,11 +2,13 @@ use strict; use warnings; +use autodie; use Getopt::Long; use File::Basename; +use Git; -my $VERSION = "0.1"; +my $VERSION = "0.2"; my %options = ( help => 0, @@ -54,6 +56,7 @@ GetOptions(\%options, "insecure|k", "verbose|v", "file|f=s@", + 'gpg|g:s', ); if ($options{help}) { @@ -62,27 +65,31 @@ if ($options{help}) { print <<EOHIPPUS; -$0 [-f AUTHFILE1] [-f AUTHFILEN] [-d] [-v] [-k] get +$0 [(-f <authfile>)...] [-g <program>] [-d] [-v] [-k] get Version $VERSION by tzz\@lifelogs.com. License: BSD. Options: - -f|--file AUTHFILE : specify netrc-style files. Files with the .gpg extension - will be decrypted by GPG before parsing. Multiple -f - arguments are OK. They are processed in order, and the - first matching entry found is returned via the credential - helper protocol (see below). + -f|--file <authfile>: specify netrc-style files. Files with the .gpg + extension will be decrypted by GPG before parsing. + Multiple -f arguments are OK. They are processed in + order, and the first matching entry found is returned + via the credential helper protocol (see below). - When no -f option is given, .authinfo.gpg, .netrc.gpg, - .authinfo, and .netrc files in your home directory are used - in this order. + When no -f option is given, .authinfo.gpg, .netrc.gpg, + .authinfo, and .netrc files in your home directory are + used in this order. - -k|--insecure : ignore bad file ownership or permissions + -g|--gpg <program> : specify the program for GPG. By default, this is the + value of gpg.program in the git repository or global + option or gpg. - -d|--debug : turn on debugging (developer info) + -k|--insecure : ignore bad file ownership or permissions - -v|--verbose : be more verbose (show files and information found) + -d|--debug : turn on debugging (developer info) + + -v|--verbose : be more verbose (show files and information found) To enable this credential helper: @@ -99,8 +106,9 @@ in the path.) git config credential.helper '$shortname -f AUTHFILE -v' -Only "get" mode is supported by this credential helper. It opens every AUTHFILE -and looks for the first entry that matches the requested search criteria: +Only "get" mode is supported by this credential helper. It opens every +<authfile> and looks for the first entry that matches the requested search +criteria: 'port|protocol': The protocol that will be used (e.g., https). (protocol=X) @@ -120,7 +128,7 @@ host=github.com protocol=https username=tzz -this credential helper will look for the first entry in every AUTHFILE that +this credential helper will look for the first entry in every <authfile> that matches machine github.com port https login tzz @@ -137,8 +145,8 @@ Then, the helper will print out whatever tokens it got from the entry, including back to "protocol". Any redundant entry tokens (part of the original query) are skipped. -Again, note that only the first matching entry from all the AUTHFILEs, processed -in the sequence given on the command line, is used. +Again, note that only the first matching entry from all the <authfile>s, +processed in the sequence given on the command line, is used. Netrc/authinfo tokens can be quoted as 'STRING' or "STRING". @@ -152,7 +160,7 @@ EOHIPPUS my $mode = shift @ARGV; # Credentials must get a parameter, so die if it's missing. -die "Syntax: $0 [-f AUTHFILE1] [-f AUTHFILEN] [-d] get" unless defined $mode; +die "Syntax: $0 [(-f <authfile>)...] [-d] get" unless defined $mode; # Only support 'get' mode; with any other unsupported ones we just exit. exit 0 unless $mode eq 'get'; @@ -172,6 +180,8 @@ unless (scalar @$files) { $files = $options{file} = [ map { glob $_ } @candidates ]; } +load_config(\%options); + my $query = read_credential_data_from_stdin(); FILE: @@ -233,7 +243,7 @@ sub load_netrc { my $io; if ($gpgmode) { - my @cmd = (qw(gpg --decrypt), $file); + my @cmd = ($options{'gpg'}, qw(--decrypt), $file); log_verbose("Using GPG to open $file: [@cmd]"); open $io, "-|", @cmd; } else { @@ -410,6 +420,14 @@ sub print_credential_data { printf "%s=%s\n", $git_token, $entry->{$git_token}; } } +sub load_config { + # load settings from git config + my $options = shift; + # set from command argument, gpg.program option, or default to gpg + $options->{'gpg'} //= Git->repository()->config('gpg.program') + // 'gpg'; + log_verbose("using $options{'gpg'} for GPG operations"); +} sub log_verbose { return unless $options{verbose}; printf STDERR @_; diff --git a/contrib/credential/netrc/t-git-credential-netrc.sh b/contrib/credential/netrc/t-git-credential-netrc.sh index efb81efed..58191a62f 100755 --- a/contrib/credential/netrc/t-git-credential-netrc.sh +++ b/contrib/credential/netrc/t-git-credential-netrc.sh @@ -18,7 +18,7 @@ test_expect_success \ 'set up test repository' \ - : + 'git config --add gpg.program test.git-config-gpg' # The external test will outputs its own plan test_external_has_tap=1 diff --git a/contrib/credential/netrc/test.command-option-gpg b/contrib/credential/netrc/test.command-option-gpg new file mode 100755 index 000000000..d8f1285d4 --- /dev/null +++ b/contrib/credential/netrc/test.command-option-gpg @@ -0,0 +1,2 @@ +#!/bin/sh +echo machine command-option-gpg login username password password diff --git a/contrib/credential/netrc/test.git-config-gpg b/contrib/credential/netrc/test.git-config-gpg new file mode 100755 index 000000000..65cf594c2 --- /dev/null +++ b/contrib/credential/netrc/test.git-config-gpg @@ -0,0 +1,2 @@ +#!/bin/sh +echo machine git-config-gpg login username password password diff --git a/contrib/credential/netrc/test.netrc.gpg b/contrib/credential/netrc/test.netrc.gpg new file mode 100644 index 000000000..e69de29bb diff --git a/contrib/credential/netrc/test.pl b/contrib/credential/netrc/test.pl index ea95a2c8a..1e1001030 100755 --- a/contrib/credential/netrc/test.pl +++ b/contrib/credential/netrc/test.pl @@ -9,15 +9,18 @@ use File::Spec::Functions qw(:DEFAULT rel2abs); use IPC::Open2; BEGIN { - # t-git-credential-netrc.sh kicks off our testing, so we have to go from there. + # t-git-credential-netrc.sh kicks off our testing, so we have to go + # from there. Test::More->builder->current_test(1); Test::More->builder->no_ending(1); } my @global_credential_args = @ARGV; my $scriptDir = dirname rel2abs $0; -my $netrc = catfile $scriptDir, 'test.netrc'; -my $gcNetrc = catfile $scriptDir, 'git-credential-netrc'; +my ($netrc, $netrcGpg, $gcNetrc) = map { catfile $scriptDir, $_; } + qw(test.netrc + test.netrc.gpg + git-credential-netrc); local $ENV{PATH} = join ':' , $scriptDir , $ENV{PATH} @@ -87,6 +90,19 @@ ok(scalar keys %$cred == 2, "Got 2 'host:port kills host' keys"); is($cred->{password}, 'bobwillknow', "Got correct 'host:port kills host' password"); is($cred->{username}, 'bob', "Got correct 'host:port kills host' username"); +diag 'Testing netrc file decryption by git config gpg.program setting\n'; +$cred = run_credential( ['-f', $netrcGpg, 'get'] + , { host => 'git-config-gpg' } + ); + +ok(scalar keys %$cred == 2, 'Got keys decrypted by git config option'); + +diag 'Testing netrc file decryption by gpg option\n'; +$cred = run_credential( ['-f', $netrcGpg, '-g', 'test.command-option-gpg', 'get'] + , { host => 'command-option-gpg' } + ); + +ok(scalar keys %$cred == 2, 'Got keys decrypted by command option'); sub run_credential { -- 2.17.0