git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCHv3] git-send-email: add ~/.authinfo parsing

From
MNMichal Nazarewicz <mpn@google.com>
Date
Jan 30, 2013, 00:03 UTC
Message-ID
<5d18d777d6ddf6f01bbf460f37af637d3dc28ed5.1359503987.git.mina86@mina86.com>
In-Reply-To
<7vehh3obs0.fsf@alter.siamese.dyndns.org>
From: Michal Nazarewicz <mina86@mina86.com>

Make git-send-email read password from a ~/.authinfo or ~/.netrc file instead of requiring it to be stored in git configuration, passed as command line argument or typed in.

There are various other applications that use this file for authentication information so letting users use it for git-send-email is convinient. Furthermore, some users store their ~/.gitconfig file in a public repository and having to store password there makes it easy to publish the password.

Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
---
 Documentation/git-send-email.txt | 47 +++++++++++++++++---
 git-send-email.perl              | 93 ++++++++++++++++++++++++++++++++++------
 2 files changed, 122 insertions(+), 18 deletions(-)
On Tue, Jan 29 2013, Junio C Hamano wrote:
Show 8 quoted lines
> But .netrc/.authinfo format separates its entries with SP, HT, or
> LF.  An entry begins with "machine <remote-hostname>" token pair.
>
> split(/\s+/) will not work for an entry that span multiple lines but
> CSV will not help, either.
>
> Is it bad to use Net::Netrc instead?  This looks like exactly the
> use case that module was written for, no?

I don't think that's the case. For one, Net::Netrc does not seem to process port number.

There is a Text::Authinfo module but it just uses Text::CSV.

I can change the code to use Net::Netrc, but I dunno if that's really the best option, since I feel people would expect parsing to be somehow compatible with <http://www.gnu.org/software/emacs/manual/html_node/gnus/NNTP.html> rather than the original .netrc file format.

> Hmph.  I would have expected to see getservbyname.
Ha!  Even better. :]
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index eeb561c..ac020d1 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -158,14 +158,49 @@ Sending
 --smtp-pass[=<password>]::
 	Password for SMTP-AUTH. The argument is optional: If no
 	argument is specified, then the empty string is used as
-	the password. Default is the value of 'sendemail.smtppass',
-	however '--smtp-pass' always overrides this value.
+	the password. Default is the value of 'sendemail.smtppass'
+	or value read from ~/.authinfo file, however '--smtp-pass'
+	always overrides this value.
 +
-Furthermore, passwords need not be specified in configuration files
-or on the command line. If a username has been specified (with
+Furthermore, passwords need not be specified in configuration files or
+on the command line. If a username has been specified (with
 '--smtp-user' or a 'sendemail.smtpuser'), but no password has been
-specified (with '--smtp-pass' or 'sendemail.smtppass'), then the
-user is prompted for a password while the input is masked for privacy.
+specified (with '--smtp-pass', 'sendemail.smtppass' or via
+~/.authinfo file), then the user is prompted for a password while
+the input is masked for privacy.
++
+The ~/.authinfo file should contain a line with the following
+format:
++
+  machine <domain> port <port> login <user> password <pass>
++
+Instead of `machine <domain>` pair a `default` token can be used
+instead in which case all domains will match.  Similarly, `port
+<port>` and `login <user>` pairs can be omitted in which case matching
+of the given value will be skipped.  `<port>` can be either an integer
+or a symbolic name.  Lines are interpreted in order and password from
+the first line that matches will be used.  For instance, one may end
+up with:
++
+  machine example.com login jane port ssmtp password smtppassword
+  machine example.com login jane            password janepassword
+  default             login janedoe         password doepassword
++
+if she wants to use `smtppassword` for authenticating as `jane` to
+a service at example.com:465 (SSMTP), `janepassword` for all other
+services at example.com; and `doepassword` when authonticating as
+`janedoe` to any service.  If ~/.authinfo file is missing,
+'git-send-email' will also try ~/.netrc file (even though parsing is
+not fully compatible with ftp's .netrc file format).
++
+Note that you should never make ~/.authinfo file world-readable.  To
+help guarantee that, you might want to create the file with the
+following command:
++
+  ( umask 077; cat >~/.authinfo <<EOF
+  ... file contents ...
+  EOF
+  )
 
 --smtp-server=<host>::
 	If set, specifies the outgoing SMTP server to use (e.g.
diff --git a/git-send-email.perl b/git-send-email.perl
index be809e5..a62dfa4 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -1045,6 +1045,86 @@ sub maildomain {
 	return maildomain_net() || maildomain_mta() || 'localhost.localdomain';
 }
 
+
+sub read_password_from_stdin {
+	my $line;
+
+	system "stty -echo";
+
+	do {
+		print "Password: ";
+		$line = <STDIN>;
+		print "\n";
+	} while (!defined $line);
+
+	system "stty echo";
+
+	chomp $line;
+	return $line;
+}
+
+sub authinfo_is_port_eq {
+	my ($from_file, $value, $filename) = @_;
+
+	if (!defined $from_file) {
+		return 1;
+	} elsif ($from_file =~ /^\d+$/) {
+		return $from_file == $value;
+	}
+
+	my $port = getservbyname $from_file, 'tcp';
+	if (!defined $port) {
+		print STDERR "$filename: invalid port name: $from_file\n";
+		return;
+	}
+
+	return $port == $value;
+}
+
+sub read_password_from_authinfo {
+	my $filename = join '/', $ENV{'HOME'}, $_[0] // '.authinfo';
+	my $fd;
+	if (!open $fd, '<', $filename) {
+		return;
+	}
+
+	my $password;
+	while (my $line = <$fd>) {
+		$line =~ s/^\s+|\s+$//g;
+		my @line = split /\s+/, $line;
+		my %line;
+		while (@line) {
+			my $token = shift @line;
+			if ($token eq 'default') {
+				$line{'machine'} = $smtp_server;
+			} elsif (@line) {
+				$line{$token} = shift @line;
+			}
+		}
+
+		if (defined $line{'password'} &&
+		    defined $line{'machine'} &&
+		    $line{'machine'} eq $smtp_server &&
+		    (!defined $line{'login'} ||
+		     $line{'login'} eq $smtp_authuser) &&
+		    authinfo_is_port_eq($line{'port'}, $smtp_server_port, $filename)) {
+			$password = $line{'password'};
+			last;
+		}
+	}
+
+	close $fd;
+	return $password;
+}
+
+sub read_password {
+	return
+	  read_password_from_authinfo '.authinfo' ||
+	  read_password_from_authinfo '.netrc' ||
+	  read_password_from_stdin;
+}
+
+
 # Returns 1 if the message was sent, and 0 otherwise.
 # In actuality, the whole program dies when there
 # is an error sending a message.
@@ -1194,18 +1274,7 @@ X-Mailer: git-send-email $gitversion
 			};
 
 			if (!defined $smtp_authpass) {
-
-				system "stty -echo";
-
-				do {
-					print "Password: ";
-					$_ = <STDIN>;
-					print "\n";
-				} while (!defined $_);
-
-				chomp($smtp_authpass = $_);
-
-				system "stty echo";
+				$smtp_authpass = read_password
 			}
 
 			$auth ||= $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;
-- 
1.8.1
Previous: Junio C HamanoNext: Junio C Hamano
Message 5 of 78 in “git-send-email: add ~/.authinfo parsing”
  1. git-send-email: add ~/.authinfo parsingMichal Nazarewicz, Jan 29, 2013
  2. Junio C HamanoJan 29, 2013
  3. [PATCHv2] git-send-email: add ~/.authinfo parsingMichal Nazarewicz, Jan 29, 2013
  4. Junio C HamanoJan 29, 2013
  5. [PATCHv3] git-send-email: add ~/.authinfo parsingMichal Nazarewicz, Jan 30, 2013
  6. Junio C HamanoJan 30, 2013
  7. Jeff KingJan 30, 2013
  8. Junio C HamanoJan 30, 2013
  9. Ted ZlatanovJan 31, 2013
  10. Jeff KingJan 31, 2013
  11. Ted ZlatanovFeb 2, 2013
  12. Jeff KingFeb 3, 2013
  13. Ted ZlatanovFeb 4, 2013
  14. 1/3 Add contrib/credentials/netrc with GPG supportTed Zlatanov, Feb 4, 2013
  15. Ted ZlatanovFeb 4, 2013
  16. Junio C HamanoFeb 4, 2013
  17. Ted ZlatanovFeb 4, 2013
  18. Junio C HamanoFeb 4, 2013
  19. Ted ZlatanovFeb 4, 2013
  20. Junio C HamanoFeb 4, 2013
  21. CodingGuidelines Perl amendment (was: [PATCH 1/3] Add contrib/credentials/netrc with GPG support)Ted Zlatanov, Feb 6, 2013
  22. Junio C HamanoFeb 6, 2013
  23. demerphqFeb 6, 2013
  24. Ted ZlatanovFeb 6, 2013
  25. Junio C HamanoFeb 6, 2013
  26. demerphqFeb 6, 2013
  27. Update CodingGuidelines for Perl 5Ted Zlatanov, Feb 6, 2013
  28. Ted ZlatanovFeb 6, 2013
  29. Junio C HamanoFeb 6, 2013
  30. Ted ZlatanovFeb 6, 2013
  31. demerphqFeb 6, 2013
  32. Ted ZlatanovFeb 6, 2013
  33. demerphqFeb 6, 2013
  34. Ted ZlatanovFeb 6, 2013
  35. Junio C HamanoFeb 6, 2013
  36. Update CodingGuidelines for Perl 5Ted Zlatanov, Feb 6, 2013
  37. 2/3 Skip blank and commented lines in contrib/credentials/netrcTed Zlatanov, Feb 4, 2013
  38. 3/3 Fix contrib/credentials/netrc minor issues: exit quietly; use 3-parameter open; etc.Ted Zlatanov, Feb 4, 2013
  39. Junio C HamanoFeb 4, 2013
  40. Ted ZlatanovFeb 4, 2013
  41. Michal NazarewiczFeb 4, 2013
  42. Ted ZlatanovFeb 4, 2013
  43. Jeff KingFeb 4, 2013
  44. Ted ZlatanovFeb 4, 2013
  45. Jeff KingFeb 4, 2013
  46. Ted ZlatanovFeb 4, 2013
  47. Jeff KingFeb 4, 2013
  48. Ted ZlatanovFeb 4, 2013
  49. Junio C HamanoFeb 5, 2013
  50. Matthieu MoyFeb 6, 2013
  51. Ted ZlatanovFeb 6, 2013
  52. Matthieu MoyFeb 6, 2013
  53. Ted ZlatanovFeb 6, 2013
  54. Matthieu MoyFeb 6, 2013
  55. Ted ZlatanovFeb 6, 2013
  56. 0/4 Allow contrib/ to use Git's Makefile for perl codeMatthieu Moy, Feb 6, 2013
  57. 1/4 Makefile: extract perl-related rules to make them available from other dirsMatthieu Moy, Feb 6, 2013
  58. Junio C HamanoFeb 7, 2013
  59. 2/4 perl.mak: introduce $(GIT_ROOT_DIR) to allow inclusion from other directoriesMatthieu Moy, Feb 6, 2013
  60. 3/4 Makefile: factor common configuration in git-default-config.makMatthieu Moy, Feb 6, 2013
  61. Junio C HamanoFeb 7, 2013
  62. Matthieu MoyFeb 8, 2013
  63. 1/2 Makefile: make script-related rules usable from subdirectoriesMatthieu Moy, Feb 8, 2013
  64. 2/2 git-remote-mediawiki: use toplevel's MakefileMatthieu Moy, Feb 8, 2013
  65. 4/4 git-remote-mediawiki: use Git's Makefile to build the scriptMatthieu Moy, Feb 6, 2013
  66. Junio C HamanoFeb 7, 2013
  67. Jeff KingFeb 8, 2013
  68. Matthieu MoyFeb 8, 2013
  69. Jeff KingFeb 8, 2013
  70. Junio C HamanoFeb 8, 2013
  71. Jeff KingFeb 8, 2013
  72. Jeff KingFeb 6, 2013
  73. Ted ZlatanovFeb 6, 2013
  74. Matthieu MoyFeb 7, 2013
  75. Ted ZlatanovFeb 7, 2013
  76. Michal NazarewiczFeb 6, 2013
  77. Ted ZlatanovFeb 6, 2013
  78. Ted ZlatanovJan 30, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.