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.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.