Git fork

git-credential-netrc: accept gpg option

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@gmail.com>
Acked-by: Ted Zlatanov <tzz@lifelogs.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Luis Marsano and committed by
Junio C Hamano
786ef50a f07eeed1

+62 -24
+38 -20
contrib/credential/netrc/git-credential-netrc
··· 2 3 use strict; 4 use warnings; 5 6 use Getopt::Long; 7 use File::Basename; 8 9 - my $VERSION = "0.1"; 10 11 my %options = ( 12 help => 0, ··· 54 "insecure|k", 55 "verbose|v", 56 "file|f=s@", 57 ); 58 59 if ($options{help}) { ··· 62 63 print <<EOHIPPUS; 64 65 - $0 [-f AUTHFILE1] [-f AUTHFILEN] [-d] [-v] [-k] get 66 67 Version $VERSION by tzz\@lifelogs.com. License: BSD. 68 69 Options: 70 71 - -f|--file AUTHFILE : specify netrc-style files. Files with the .gpg extension 72 - will be decrypted by GPG before parsing. Multiple -f 73 - arguments are OK. They are processed in order, and the 74 - first matching entry found is returned via the credential 75 - helper protocol (see below). 76 77 - When no -f option is given, .authinfo.gpg, .netrc.gpg, 78 - .authinfo, and .netrc files in your home directory are used 79 - in this order. 80 81 - -k|--insecure : ignore bad file ownership or permissions 82 83 - -d|--debug : turn on debugging (developer info) 84 85 - -v|--verbose : be more verbose (show files and information found) 86 87 To enable this credential helper: 88 ··· 99 100 git config credential.helper '$shortname -f AUTHFILE -v' 101 102 - Only "get" mode is supported by this credential helper. It opens every AUTHFILE 103 - and looks for the first entry that matches the requested search criteria: 104 105 'port|protocol': 106 The protocol that will be used (e.g., https). (protocol=X) ··· 120 protocol=https 121 username=tzz 122 123 - this credential helper will look for the first entry in every AUTHFILE that 124 matches 125 126 machine github.com port https login tzz ··· 137 back to "protocol". Any redundant entry tokens (part of the original query) are 138 skipped. 139 140 - Again, note that only the first matching entry from all the AUTHFILEs, processed 141 - in the sequence given on the command line, is used. 142 143 Netrc/authinfo tokens can be quoted as 'STRING' or "STRING". 144 ··· 152 my $mode = shift @ARGV; 153 154 # Credentials must get a parameter, so die if it's missing. 155 - die "Syntax: $0 [-f AUTHFILE1] [-f AUTHFILEN] [-d] get" unless defined $mode; 156 157 # Only support 'get' mode; with any other unsupported ones we just exit. 158 exit 0 unless $mode eq 'get'; ··· 171 172 $files = $options{file} = [ map { glob $_ } @candidates ]; 173 } 174 175 my $query = read_credential_data_from_stdin(); 176 ··· 233 234 my $io; 235 if ($gpgmode) { 236 - my @cmd = (qw(gpg --decrypt), $file); 237 log_verbose("Using GPG to open $file: [@cmd]"); 238 open $io, "-|", @cmd; 239 } else { ··· 409 log_debug("FOUND: $git_token=$entry->{$git_token}"); 410 printf "%s=%s\n", $git_token, $entry->{$git_token}; 411 } 412 } 413 sub log_verbose { 414 return unless $options{verbose};
··· 2 3 use strict; 4 use warnings; 5 + use autodie; 6 7 use Getopt::Long; 8 use File::Basename; 9 + use Git; 10 11 + my $VERSION = "0.2"; 12 13 my %options = ( 14 help => 0, ··· 56 "insecure|k", 57 "verbose|v", 58 "file|f=s@", 59 + 'gpg|g:s', 60 ); 61 62 if ($options{help}) { ··· 65 66 print <<EOHIPPUS; 67 68 + $0 [(-f <authfile>)...] [-g <program>] [-d] [-v] [-k] get 69 70 Version $VERSION by tzz\@lifelogs.com. License: BSD. 71 72 Options: 73 74 + -f|--file <authfile>: specify netrc-style files. Files with the .gpg 75 + extension will be decrypted by GPG before parsing. 76 + Multiple -f arguments are OK. They are processed in 77 + order, and the first matching entry found is returned 78 + via the credential helper protocol (see below). 79 80 + When no -f option is given, .authinfo.gpg, .netrc.gpg, 81 + .authinfo, and .netrc files in your home directory are 82 + used in this order. 83 84 + -g|--gpg <program> : specify the program for GPG. By default, this is the 85 + value of gpg.program in the git repository or global 86 + option or gpg. 87 88 + -k|--insecure : ignore bad file ownership or permissions 89 90 + -d|--debug : turn on debugging (developer info) 91 + 92 + -v|--verbose : be more verbose (show files and information found) 93 94 To enable this credential helper: 95 ··· 106 107 git config credential.helper '$shortname -f AUTHFILE -v' 108 109 + Only "get" mode is supported by this credential helper. It opens every 110 + <authfile> and looks for the first entry that matches the requested search 111 + criteria: 112 113 'port|protocol': 114 The protocol that will be used (e.g., https). (protocol=X) ··· 128 protocol=https 129 username=tzz 130 131 + this credential helper will look for the first entry in every <authfile> that 132 matches 133 134 machine github.com port https login tzz ··· 145 back to "protocol". Any redundant entry tokens (part of the original query) are 146 skipped. 147 148 + Again, note that only the first matching entry from all the <authfile>s, 149 + processed in the sequence given on the command line, is used. 150 151 Netrc/authinfo tokens can be quoted as 'STRING' or "STRING". 152 ··· 160 my $mode = shift @ARGV; 161 162 # Credentials must get a parameter, so die if it's missing. 163 + die "Syntax: $0 [(-f <authfile>)...] [-d] get" unless defined $mode; 164 165 # Only support 'get' mode; with any other unsupported ones we just exit. 166 exit 0 unless $mode eq 'get'; ··· 179 180 $files = $options{file} = [ map { glob $_ } @candidates ]; 181 } 182 + 183 + load_config(\%options); 184 185 my $query = read_credential_data_from_stdin(); 186 ··· 243 244 my $io; 245 if ($gpgmode) { 246 + my @cmd = ($options{'gpg'}, qw(--decrypt), $file); 247 log_verbose("Using GPG to open $file: [@cmd]"); 248 open $io, "-|", @cmd; 249 } else { ··· 419 log_debug("FOUND: $git_token=$entry->{$git_token}"); 420 printf "%s=%s\n", $git_token, $entry->{$git_token}; 421 } 422 + } 423 + sub load_config { 424 + # load settings from git config 425 + my $options = shift; 426 + # set from command argument, gpg.program option, or default to gpg 427 + $options->{'gpg'} //= Git->repository()->config('gpg.program') 428 + // 'gpg'; 429 + log_verbose("using $options{'gpg'} for GPG operations"); 430 } 431 sub log_verbose { 432 return unless $options{verbose};
+1 -1
contrib/credential/netrc/t-git-credential-netrc.sh
··· 18 19 test_expect_success \ 20 'set up test repository' \ 21 - : 22 23 # The external test will outputs its own plan 24 test_external_has_tap=1
··· 18 19 test_expect_success \ 20 'set up test repository' \ 21 + 'git config --add gpg.program test.git-config-gpg' 22 23 # The external test will outputs its own plan 24 test_external_has_tap=1
+2
contrib/credential/netrc/test.command-option-gpg
···
··· 1 + #!/bin/sh 2 + echo machine command-option-gpg login username password password
+2
contrib/credential/netrc/test.git-config-gpg
···
··· 1 + #!/bin/sh 2 + echo machine git-config-gpg login username password password
contrib/credential/netrc/test.netrc.gpg

This is a binary file and will not be displayed.

+19 -3
contrib/credential/netrc/test.pl
··· 9 use IPC::Open2; 10 11 BEGIN { 12 - # t-git-credential-netrc.sh kicks off our testing, so we have to go from there. 13 Test::More->builder->current_test(1); 14 Test::More->builder->no_ending(1); 15 } 16 17 my @global_credential_args = @ARGV; 18 my $scriptDir = dirname rel2abs $0; 19 - my $netrc = catfile $scriptDir, 'test.netrc'; 20 - my $gcNetrc = catfile $scriptDir, 'git-credential-netrc'; 21 local $ENV{PATH} = join ':' 22 , $scriptDir 23 , $ENV{PATH} ··· 87 is($cred->{password}, 'bobwillknow', "Got correct 'host:port kills host' password"); 88 is($cred->{username}, 'bob', "Got correct 'host:port kills host' username"); 89 90 91 sub run_credential 92 {
··· 9 use IPC::Open2; 10 11 BEGIN { 12 + # t-git-credential-netrc.sh kicks off our testing, so we have to go 13 + # from there. 14 Test::More->builder->current_test(1); 15 Test::More->builder->no_ending(1); 16 } 17 18 my @global_credential_args = @ARGV; 19 my $scriptDir = dirname rel2abs $0; 20 + my ($netrc, $netrcGpg, $gcNetrc) = map { catfile $scriptDir, $_; } 21 + qw(test.netrc 22 + test.netrc.gpg 23 + git-credential-netrc); 24 local $ENV{PATH} = join ':' 25 , $scriptDir 26 , $ENV{PATH} ··· 90 is($cred->{password}, 'bobwillknow', "Got correct 'host:port kills host' password"); 91 is($cred->{username}, 'bob', "Got correct 'host:port kills host' username"); 92 93 + diag 'Testing netrc file decryption by git config gpg.program setting\n'; 94 + $cred = run_credential( ['-f', $netrcGpg, 'get'] 95 + , { host => 'git-config-gpg' } 96 + ); 97 + 98 + ok(scalar keys %$cred == 2, 'Got keys decrypted by git config option'); 99 + 100 + diag 'Testing netrc file decryption by gpg option\n'; 101 + $cred = run_credential( ['-f', $netrcGpg, '-g', 'test.command-option-gpg', 'get'] 102 + , { host => 'command-option-gpg' } 103 + ); 104 + 105 + ok(scalar keys %$cred == 2, 'Got keys decrypted by command option'); 106 107 sub run_credential 108 {