From: Ted Zlatanov <tzz@lifelogs•com>
To: git@vger•kernel.org
Subject: Re: [PATCH] git-send-email: add ~/.authinfo parsing
Date: Sat, 02 Feb 2013 06:57:29 -0500 [thread overview]
Message-ID: <87k3qrx712.fsf@lifelogs.com> (raw)
In-Reply-To: 20130131193844.GA14460@sigill.intra.peff.net
[-- Attachment #1: Type: text/plain, Size: 1489 bytes --]
On Thu, 31 Jan 2013 14:38:45 -0500 Jeff King <peff@peff•net> wrote:
JK> On Thu, Jan 31, 2013 at 10:23:51AM -0500, Ted Zlatanov wrote:
>> Jeff, is there a way for git-credential to currently support
>> authinfo/netrc parsing? I assume that's the right way, instead of using
>> Michal's proposal to parse internally?
>>
>> I'd like to add that, plus support for the 'string' and "string"
>> formats, and authinfo.gpg decoding through GPG. I'd write it in Perl,
>> if there's a choice.
JK> Yes, you could write a credential helper that understands netrc and
JK> friends; git talks to the helpers over a socket, so there is no problem
JK> with writing it in Perl. See Documentation/technical/api-credentials.txt
JK> for an overview, or the sample implementation in credential-store.c for a
JK> simple example.
I wrote a Perl credential helper for netrc parsing which is pretty
robust, has built-in docs with -h, and doesn't depend on external
modules. The netrc parser regex was stolen from Net::Netrc.
It will by default use ~/.authinfo.gpg, ~/.netrc.gpg, ~/.authinfo, and
~/.netrc (whichever is found first) and this can be overridden with -f.
If the file name ends with ".gpg", it will run "gpg --decrypt FILE" and
use the output. So non-interactively, that could hang if GPG was
waiting for input. Does Git handle that, or should I check for a TTY?
Take a look at the proposed patch and let me know if it's usable, if you
need a formal copyright assignment, etc.
Thanks
Ted
[-- Attachment #2: Add git-credential-netrc --]
[-- Type: text/x-patch, Size: 6016 bytes --]
commit 3d28bc2a610ebcc988eba5443d82d0ded92c24bc
Author: Ted Zlatanov <tzz@lifelogs•com>
Date: Sat Feb 2 06:42:13 2013 -0500
Add contrib/credentials/netrc with GPG support
diff --git a/contrib/credential/netrc/git-credential-netrc b/contrib/credential/netrc/git-credential-netrc
new file mode 100755
index 0000000..92fc306
--- /dev/null
+++ b/contrib/credential/netrc/git-credential-netrc
@@ -0,0 +1,242 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Data::Dumper;
+
+use Getopt::Long;
+use File::Basename;
+
+my $VERSION = "0.1";
+
+my %options = (
+ help => 0,
+ debug => 0,
+
+ # identical token maps, e.g. host -> host, will be inserted later
+ tmap => {
+ port => 'protocol',
+ machine => 'host',
+ path => 'path',
+ login => 'username',
+ user => 'username',
+ password => 'password',
+ }
+ );
+
+foreach my $v (values %{$options{tmap}})
+{
+ $options{tmap}->{$v} = $v;
+}
+
+foreach my $suffix ('.gpg', '')
+{
+ foreach my $base (qw/authinfo netrc/)
+ {
+ my $file = glob("~/.$base$suffix");
+ next unless (defined $file && -f $file);
+ $options{file} = $file ;
+ }
+}
+
+Getopt::Long::Configure("bundling");
+
+# TODO: maybe allow the token map $options{tmap} to be configurable.
+GetOptions(\%options,
+ "help|h",
+ "debug|d",
+ "file|f=s",
+ );
+
+if ($options{help})
+{
+ my $shortname = basename($0);
+ $shortname =~ s/git-credential-//;
+
+ print <<EOHIPPUS;
+
+$0 [-f AUTHFILE] [-d] get
+
+Version $VERSION by tzz\@lifelogs.com. License: any use is OK.
+
+Options:
+ -f AUTHFILE: specify a netrc-style file
+ -d: turn on debugging
+
+To enable (note that Git will prepend "git-credential-" to the helper
+name and look for it in the path):
+
+ git config credential.helper '$shortname -f AUTHFILE'
+
+And if you want lots of debugging info:
+
+ git config credential.helper '$shortname -f AUTHFILE -d'
+
+Only "get" mode is supported by this credential helper. It opens
+AUTHFILE and looks for entries that match the requested search
+criteria:
+
+ 'port|protocol':
+ The protocol that will be used (e.g., https). (protocol=X)
+
+ 'machine|host':
+ The remote hostname for a network credential. (host=X)
+
+ 'path':
+ The path with which the credential will be used. (path=X)
+
+ 'login|user|username':
+ The credential’s username, if we already have one. (username=X)
+
+Thus, when we get "protocol=https\nusername=tzz", this credential
+helper will look for lines in AUTHFILE that match
+
+port https login tzz
+
+OR
+
+protocol https login tzz
+
+OR... etc. acceptable tokens as listed above. Any unknown tokens are
+simply ignored.
+
+Then, the helper will print out whatever tokens it got from the line,
+including "password" tokens, mapping e.g. "port" back to "protocol".
+
+The first matching line is used. Tokens can be quoted as 'STRING' or
+"STRING".
+
+No caching is performed by this credential helper.
+
+EOHIPPUS
+
+ exit;
+}
+
+my $mode = shift @ARGV;
+
+# credentials may get 'get', 'store', or 'erase' as parameters but
+# only acknowledge 'get'
+die "Syntax: $0 [-f AUTHFILE] [-d] get" unless defined $mode;
+
+# only support 'get' mode
+exit unless $mode eq 'get';
+
+my $debug = $options{debug};
+my $file = $options{file};
+
+die "Sorry, you need to specify an existing netrc file (with or without a .gpg extension) with -f AUTHFILE"
+ unless defined $file;
+
+die "Sorry, the specified netrc $file is not accessible"
+ unless -f $file;
+
+if ($file =~ m/\.gpg$/)
+{
+ $file = "gpg --decrypt $file|";
+}
+
+my @data = load($file);
+chomp @data;
+
+die "Sorry, we could not load data from [$file]"
+ unless (scalar @data);
+
+# the query
+my %q;
+
+foreach my $v (values %{$options{tmap}})
+{
+ undef $q{$v};
+}
+
+while (<STDIN>)
+{
+ next unless m/([a-z]+)=(.+)/;
+
+ my ($token, $value) = ($1, $2);
+ die "Unknown search token $1" unless exists $q{$token};
+ $q{$token} = $value;
+}
+
+# build reverse token map
+my %rmap;
+foreach my $k (keys %{$options{tmap}})
+{
+ push @{$rmap{$options{tmap}->{$k}}}, $k;
+}
+
+# there are CPAN modules to do this better, but we want to avoid
+# dependencies and generally, complex netrc-style files are rare
+
+if ($debug)
+{
+ foreach (sort keys %q)
+ {
+ printf STDERR "searching for %s = %s\n",
+ $_, $q{$_} || '(any value)';
+ }
+}
+
+LINE: foreach my $line (@data)
+{
+
+ print STDERR "line [$line]\n" if $debug;
+ my @tok;
+ # gratefully stolen from Net::Netrc
+ while (length $line &&
+ $line =~ s/^("((?:[^"]+|\\.)*)"|((?:[^\\\s]+|\\.)*))\s*//)
+ {
+ (my $tok = $+) =~ s/\\(.)/$1/g;
+ push(@tok, $tok);
+ }
+
+ my %tokens;
+ while (@tok)
+ {
+ my ($k, $v) = (shift @tok, shift @tok);
+ next unless defined $v;
+ next unless exists $options{tmap}->{$k};
+ $tokens{$options{tmap}->{$k}} = $v;
+ }
+
+ foreach my $check (sort keys %q)
+ {
+ if (exists $tokens{$check} && defined $q{$check})
+ {
+ print STDERR "comparing [$tokens{$check}] to [$q{$check}] in line [$line]\n" if $debug;
+ next LINE unless $tokens{$check} eq $q{$check};
+ }
+ else
+ {
+ print STDERR "we could not find [$check] but it's OK\n" if $debug;
+ }
+ }
+
+ print STDERR "line has passed all the search checks\n" if $debug;
+ foreach my $token (sort keys %rmap)
+ {
+ print STDERR "looking for useful token $token\n" if $debug;
+ next unless exists $tokens{$token}; # did we match?
+
+ foreach my $rctoken (@{$rmap{$token}})
+ {
+ next if defined $q{$rctoken}; # don't re-print given tokens
+ }
+
+ print STDERR "FOUND: $token=$tokens{$token}\n" if $debug;
+ printf "%s=%s\n", $token, $tokens{$token};
+ }
+
+ last;
+}
+
+sub load
+{
+ my $file = shift;
+ # this supports pipes too
+ my $io = new IO::File($file) or die "Could not open $file: $!\n";
+
+ return <$io>; # whole file
+}
next prev parent reply other threads:[~2013-02-02 11:58 UTC|newest]
Thread overview: 78+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-29 19:13 [PATCH] git-send-email: add ~/.authinfo parsing Michal Nazarewicz
2013-01-29 19:53 ` Junio C Hamano
2013-01-29 21:08 ` [PATCHv2] " Michal Nazarewicz
2013-01-29 22:38 ` Junio C Hamano
2013-01-30 0:03 ` [PATCHv3] " Michal Nazarewicz
2013-01-30 0:34 ` Junio C Hamano
2013-01-30 7:43 ` [PATCH] " Jeff King
2013-01-30 15:57 ` Junio C Hamano
2013-01-31 15:23 ` Ted Zlatanov
2013-01-31 19:38 ` Jeff King
2013-02-02 11:57 ` Ted Zlatanov [this message]
2013-02-03 19:41 ` Jeff King
2013-02-04 16:40 ` Ted Zlatanov
2013-02-04 16:42 ` [PATCH 1/3] Add contrib/credentials/netrc with GPG support Ted Zlatanov
2013-02-04 16:57 ` Ted Zlatanov
2013-02-04 17:24 ` Junio C Hamano
2013-02-04 18:33 ` Ted Zlatanov
2013-02-04 19:06 ` Junio C Hamano
2013-02-04 19:40 ` Ted Zlatanov
2013-02-04 23:10 ` Junio C Hamano
2013-02-06 15:10 ` CodingGuidelines Perl amendment (was: [PATCH 1/3] Add contrib/credentials/netrc with GPG support) Ted Zlatanov
2013-02-06 16:29 ` CodingGuidelines Perl amendment Junio C Hamano
2013-02-06 17:45 ` demerphq
2013-02-06 18:08 ` Ted Zlatanov
2013-02-06 18:14 ` Junio C Hamano
2013-02-06 18:18 ` demerphq
2013-02-06 17:55 ` [PATCH] Update CodingGuidelines for Perl 5 Ted Zlatanov
2013-02-06 18:05 ` CodingGuidelines Perl amendment Ted Zlatanov
2013-02-06 18:16 ` Junio C Hamano
2013-02-06 18:27 ` Ted Zlatanov
2013-02-06 18:25 ` demerphq
2013-02-06 18:35 ` Ted Zlatanov
2013-02-06 18:44 ` demerphq
2013-02-06 18:54 ` Ted Zlatanov
2013-02-06 19:37 ` Junio C Hamano
2013-02-06 19:49 ` [PATCH v2] Update CodingGuidelines for Perl 5 Ted Zlatanov
2013-02-04 16:42 ` [PATCH 2/3] Skip blank and commented lines in contrib/credentials/netrc Ted Zlatanov
2013-02-04 16:43 ` [PATCH 3/3] Fix contrib/credentials/netrc minor issues: exit quietly; use 3-parameter open; etc Ted Zlatanov
2013-02-04 17:27 ` Junio C Hamano
2013-02-04 18:41 ` Ted Zlatanov
2013-02-04 16:33 ` [PATCH] git-send-email: add ~/.authinfo parsing Michal Nazarewicz
2013-02-04 17:00 ` Ted Zlatanov
2013-02-04 20:10 ` Jeff King
2013-02-04 20:28 ` Ted Zlatanov
2013-02-04 20:59 ` Jeff King
2013-02-04 21:08 ` Ted Zlatanov
2013-02-04 21:22 ` Jeff King
2013-02-04 21:41 ` Ted Zlatanov
2013-02-05 23:10 ` Junio C Hamano
2013-02-06 8:11 ` Matthieu Moy
2013-02-06 14:53 ` Ted Zlatanov
2013-02-06 15:10 ` Matthieu Moy
2013-02-06 15:58 ` Ted Zlatanov
2013-02-06 16:41 ` Matthieu Moy
2013-02-06 17:40 ` Ted Zlatanov
2013-02-06 18:11 ` [PATCH 0/4] Allow contrib/ to use Git's Makefile for perl code Matthieu Moy
2013-02-06 18:11 ` [PATCH 1/4] Makefile: extract perl-related rules to make them available from other dirs Matthieu Moy
2013-02-07 19:16 ` Junio C Hamano
2013-02-06 18:11 ` [PATCH 2/4] perl.mak: introduce $(GIT_ROOT_DIR) to allow inclusion from other directories Matthieu Moy
2013-02-06 18:11 ` [PATCH 3/4] Makefile: factor common configuration in git-default-config.mak Matthieu Moy
2013-02-07 19:28 ` Junio C Hamano
2013-02-08 17:05 ` Matthieu Moy
2013-02-08 17:31 ` [PATCH 1/2] Makefile: make script-related rules usable from subdirectories Matthieu Moy
2013-02-08 17:31 ` [PATCH 2/2] git-remote-mediawiki: use toplevel's Makefile Matthieu Moy
2013-02-06 18:11 ` [PATCH 4/4] git-remote-mediawiki: use Git's Makefile to build the script Matthieu Moy
2013-02-07 19:28 ` Junio C Hamano
2013-02-08 4:28 ` Jeff King
2013-02-08 17:34 ` Matthieu Moy
2013-02-08 17:43 ` Jeff King
2013-02-08 18:13 ` Junio C Hamano
2013-02-08 18:15 ` Jeff King
2013-02-06 21:57 ` [PATCH] git-send-email: add ~/.authinfo parsing Jeff King
2013-02-06 23:12 ` Ted Zlatanov
2013-02-07 7:08 ` Matthieu Moy
2013-02-07 14:30 ` Ted Zlatanov
2013-02-06 13:26 ` Michal Nazarewicz
2013-02-06 14:47 ` Ted Zlatanov
2013-01-30 15:03 ` Ted Zlatanov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87k3qrx712.fsf@lifelogs.com \
--to=tzz@lifelogs$(echo .)com \
--cc=git@vger$(echo .)kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox