threads / discuss / 29537

Push from an SSH Terminal

Subject: Push from an SSH Terminal

## tl;dr

12 messages between Feb 3, 2012 and Feb 4, 2012.

replies: 11people: 4as markdown or json

Feanil Patel· Feb 3, 2012, 15:50 UTC · lore
Hi Everyone,

I tried looking for an answer to my problem online without much luck, perhaps you can help me. I'm SSHed from my laptop(Comp A) over to a computer(Comp B) that has my git repo on it. I made some changes and comitted them. Now I want to push them to my other server(Comp C). The repository is password protected so if I'm physically at Comp B, I get a gui prompt for my username and password. However Comp A does not have X Forwarding setup to Comp B so I can't get the gui interface for the username and password when I try to do the push. Is there an alternative way to provide my credentials when doing a git push that does not require a gui?

-- Feanil Patel

Neal Groothuis· Feb 3, 2012, 16:21 UTC · re: Feanil Patel · lore

Re: Push from an SSH Terminal

Show 7 quoted lines
> The
> repository is password protected so if I'm physically at Comp B, I get
> a gui prompt for my username and password. However Comp A does not
> have X Forwarding setup to Comp B so I can't get the gui interface for
> the username and password when I try to do the push.  Is there an
> alternative way to provide my credentials when doing a git push that
> does not require a gui?
What protocol are you using to access the repository on Comp C?
- Neal
Feanil Patel· Feb 3, 2012, 16:40 UTC · re: Neal Groothuis · lore

Re: Push from an SSH Terminal

On Fri, Feb 3, 2012 at 11:21 AM, Neal Groothuis <ngroot@lo-cal.org> wrote:
Show 12 quoted lines
>> The
>> repository is password protected so if I'm physically at Comp B, I get
>> a gui prompt for my username and password. However Comp A does not
>> have X Forwarding setup to Comp B so I can't get the gui interface for
>> the username and password when I try to do the push.  Is there an
>> alternative way to provide my credentials when doing a git push that
>> does not require a gui?
>
> What protocol are you using to access the repository on Comp C?
>
> - Neal
>
I'm pulling and pushing over HTTP from Comp C.
Neal Groothuis· Feb 3, 2012, 17:10 UTC · re: Feanil Patel · lore

Re: Push from an SSH Terminal

Show 12 quoted lines
> On Fri, Feb 3, 2012 at 11:21 AM, Neal Groothuis <ngroot@lo-cal.org> wrote:
>>> The
>>> repository is password protected so if I'm physically at Comp B, I get
>>> a gui prompt for my username and password. However Comp A does not
>>> have X Forwarding setup to Comp B so I can't get the gui interface for
>>> the username and password when I try to do the push.  Is there an
>>> alternative way to provide my credentials when doing a git push that
>>> does not require a gui?
>>
>> What protocol are you using to access the repository on Comp C?
>>
> I'm pulling and pushing over HTTP from Comp C.

Check to see if the GIT_ASKPASS and/or SSH_ASKPASS environment variables are set, and if the core.askpass config variable is set. If any of these are set, unset them. Git should fall back to a simple password prompt.

- Neal
Jeff King· Feb 3, 2012, 21:36 UTC · re: Neal Groothuis · lore

Re: Push from an SSH Terminal

On Fri, Feb 03, 2012 at 12:10:27PM -0500, Neal Groothuis wrote:
Show 16 quoted lines
> > On Fri, Feb 3, 2012 at 11:21 AM, Neal Groothuis <ngroot@lo-cal.org> wrote:
> >>> The
> >>> repository is password protected so if I'm physically at Comp B, I get
> >>> a gui prompt for my username and password. However Comp A does not
> >>> have X Forwarding setup to Comp B so I can't get the gui interface for
> >>> the username and password when I try to do the push.  Is there an
> >>> alternative way to provide my credentials when doing a git push that
> >>> does not require a gui?
> >>
> >> What protocol are you using to access the repository on Comp C?
> >>
> > I'm pulling and pushing over HTTP from Comp C.
> 
> Check to see if the GIT_ASKPASS and/or SSH_ASKPASS environment variables
> are set, and if the core.askpass config variable is set.  If any of these
> are set, unset them.  Git should fall back to a simple password prompt.

Hmm, yeah that is likely the problem. I was thinking git would fall back to asking on the terminal, but it does not. We probably should.

-Peff
Jeff King· Feb 3, 2012, 22:13 UTC · re: Jeff King · lore

Re: Push from an SSH Terminal

On Fri, Feb 03, 2012 at 04:36:54PM -0500, Jeff King wrote:
Show 6 quoted lines
> > Check to see if the GIT_ASKPASS and/or SSH_ASKPASS environment variables
> > are set, and if the core.askpass config variable is set.  If any of these
> > are set, unset them.  Git should fall back to a simple password prompt.
> 
> Hmm, yeah that is likely the problem. I was thinking git would fall back
> to asking on the terminal, but it does not. We probably should.
We should probably do this:
  [1/2]: prompt: clean up strbuf usage
  [2/2]: prompt: fall back to terminal if askpass fails
-Peff
Jeff King· Feb 3, 2012, 22:14 UTC · re: Jeff King · lore

[PATCH 1/2] prompt: clean up strbuf usage

The do_askpass function inherited a few bad habits from the original git_getpass. One, there's no need to strbuf_reset a buffer which was just initialized. And two, it's a good habit to use strbuf_detach to claim ownership of a buffer's string (even though in this case the owning buffer goes out of scope, so it's effectively the same thing).

Signed-off-by: Jeff King <peff@peff.net>
---
Neither is a big deal, but just some style cleanups while I was in the
area.
 prompt.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/prompt.c b/prompt.c
index 72ab9de..64f817b 100644
--- a/prompt.c
+++ b/prompt.c
@@ -21,7 +21,6 @@ static char *do_askpass(const char *cmd, const char *prompt)
 	if (start_command(&pass))
 		exit(1);
 
-	strbuf_reset(&buffer);
 	if (strbuf_read(&buffer, pass.out, 20) < 0)
 		die("failed to get '%s' from %s\n", prompt, cmd);
 
@@ -32,7 +31,7 @@ static char *do_askpass(const char *cmd, const char *prompt)
 
 	strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n"));
 
-	return buffer.buf;
+	return strbuf_detach(&buffer, NULL);
 }
 
 char *git_prompt(const char *prompt, int flags)
-- 
1.7.9.rc1.28.gf4be5
Jeff King· Feb 3, 2012, 22:16 UTC · re: Jeff King · lore

[PATCH 2/2] prompt: fall back to terminal if askpass fails

The current askpass code simply dies if calling an askpass helper fails. Worse, in some failure modes it doesn't even print an error (if start_command fails, then it prints its own error; if reading fails, we print an error; but if the command exits non-zero, finish_command fails and we print nothing!).

Let's be more kind to the user by printing an error message when askpass doesn't work out, and then falling back to the terminal (which also may fail, of course, but we die already there with a nice message).

While we're at it, let's clean up the existing error messages a bit. Now that our prompts are very long and contain quotes and colons themselves, our error messages are hard to read.

So the new failure modes look like:
  [before, with a terminal]
  $ GIT_ASKPASS=false git push
  $ echo $?
  128
  [before, with no terminal, and we must give up]
  $ setsid git push
  fatal: could not read 'Password for 'https://peff@github.com': ': No such device or address
  [after, with a terminal]
  $ GIT_ASKPASS=false git push
  error: unable to read askpass response from 'false'
  Password for 'https://peff@github.com':
  [after, with no terminal, and we must give up]
  $ GIT_ASKPASS=false setsid git push
  error: unable to read askpass response from 'false'
  fatal: could not read Password for 'https://peff@github.com': No such device or address
Signed-off-by: Jeff King <peff@peff.net>
---
Arguably, the terminal-failure error message shouldn't even bother
reporting errno. I can't imagine it failing for any reason other than
ENODEV, and the message would probably be less confusing as:
  fatal: could not prompt on terminal for Password for...
 prompt.c |   24 +++++++++++++++++-------
 1 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/prompt.c b/prompt.c
index 64f817b..d851807 100644
--- a/prompt.c
+++ b/prompt.c
@@ -9,6 +9,7 @@ static char *do_askpass(const char *cmd, const char *prompt)
 	struct child_process pass;
 	const char *args[3];
 	static struct strbuf buffer = STRBUF_INIT;
+	int err = 0;
 
 	args[0] = cmd;
 	args[1]	= prompt;
@@ -19,15 +20,21 @@ static char *do_askpass(const char *cmd, const char *prompt)
 	pass.out = -1;
 
 	if (start_command(&pass))
-		exit(1);
+		return NULL;
 
 	if (strbuf_read(&buffer, pass.out, 20) < 0)
-		die("failed to get '%s' from %s\n", prompt, cmd);
+		err = 1;
 
 	close(pass.out);
 
 	if (finish_command(&pass))
-		exit(1);
+		err = 1;
+
+	if (err) {
+		error("unable to read askpass response from '%s'", cmd);
+		strbuf_release(&buffer);
+		return NULL;
+	}
 
 	strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n"));
 
@@ -36,7 +43,7 @@ static char *do_askpass(const char *cmd, const char *prompt)
 
 char *git_prompt(const char *prompt, int flags)
 {
-	char *r;
+	char *r = NULL;
 
 	if (flags & PROMPT_ASKPASS) {
 		const char *askpass;
@@ -47,12 +54,15 @@ char *git_prompt(const char *prompt, int flags)
 		if (!askpass)
 			askpass = getenv("SSH_ASKPASS");
 		if (askpass && *askpass)
-			return do_askpass(askpass, prompt);
+			r = do_askpass(askpass, prompt);
 	}
 
-	r = git_terminal_prompt(prompt, flags & PROMPT_ECHO);
 	if (!r)
-		die_errno("could not read '%s'", prompt);
+		r = git_terminal_prompt(prompt, flags & PROMPT_ECHO);
+	if (!r) {
+		/* prompts already contain ": " at the end */
+		die("could not read %s%s", prompt, strerror(errno));
+	}
 	return r;
 }
 
-- 
1.7.9.rc1.28.gf4be5
Junio C Hamano· Feb 4, 2012, 07:47 UTC · re: Jeff King · lore

Re: Push from an SSH Terminal

Jeff King <peff@peff.net> writes:
Show 8 quoted lines
> On Fri, Feb 03, 2012 at 12:10:27PM -0500, Neal Groothuis wrote:
> ...
>> Check to see if the GIT_ASKPASS and/or SSH_ASKPASS environment variables
>> are set, and if the core.askpass config variable is set.  If any of these
>> are set, unset them.  Git should fall back to a simple password prompt.
>
> Hmm, yeah that is likely the problem. I was thinking git would fall back
> to asking on the terminal, but it does not. We probably should.

How well would it mesh with the goal of the ss/git-svn-prompt-sans-terminal topic, which is now stalled [*1*]? I do not mean this change and the other topic textually conflict with each other---but the philosophies of this topic and the other one seem to conflict. Not falling back to the terminal that is not available and failing the command outright might make more sense.

I dunno.
[Footnote]

*1* Will the topic see any action soon? I am inclined to throw the topic into "not even the original author is not interested" category otherwise.

Jeff King· Feb 4, 2012, 08:09 UTC · re: Junio C Hamano · lore

Re: Push from an SSH Terminal

On Fri, Feb 03, 2012 at 11:47:11PM -0800, Junio C Hamano wrote:
Show 17 quoted lines
> Jeff King <peff@peff.net> writes:
> 
> > On Fri, Feb 03, 2012 at 12:10:27PM -0500, Neal Groothuis wrote:
> > ...
> >> Check to see if the GIT_ASKPASS and/or SSH_ASKPASS environment variables
> >> are set, and if the core.askpass config variable is set.  If any of these
> >> are set, unset them.  Git should fall back to a simple password prompt.
> >
> > Hmm, yeah that is likely the problem. I was thinking git would fall back
> > to asking on the terminal, but it does not. We probably should.
> 
> How well would it mesh with the goal of the ss/git-svn-prompt-sans-terminal
> topic, which is now stalled [*1*]?  I do not mean this change and the other
> topic textually conflict with each other---but the philosophies of this
> topic and the other one seem to conflict.  Not falling back to the terminal
> that is not available and failing the command outright might make more
> sense.

I don't see a conflict in the two series. That one seems to do two things for perl programs:

  1. respect SSH_ASKPASS along with GIT_ASKPASS
  2. prefer askpass over asking on the terminal
But both of those are already the case in the C code.

If you look into the original complaint mentioned in the commit messages, though, you will see that the some GUIs will appear to hang when the terminal is prompted (because the prompt is reading from some location invisible to the user). So in that sense, my patches could be a regression for those users, as outright failing is better for them.

But I would argue that the bug is not prompting on the terminal, but rather that the terminal-prompting code does not recognize when there is no terminal connection to the user (and AFAICT, this is a Windows problem). Any solution that doesn't fix that is really just papering over the problem, and hurting people[1] on sane systems.

So I'd rather see the version of getpass() in compat/mingw.c better learn to realize when we aren't actually connected to a console.

-Peff
[1] The amount of hurt is relatively small, though. It only hurts people
    who set GIT_ASKPASS but can't use it (e.g., you set it in your
    .bashrc because you connect via "ssh -X", but this time you happen
    to be ssh-ing from a Windows box). And you can generally fix that
    outside of git (e.g., by checking $DISPLAY before setting the
    variable).
    So one one hand, I don't want to make a decision on behavior for
    Unix users because we have to cater to Windows shortcomings. On the
    other hand, while fixing the root problem is preferable, if
    for whatever reason we can't reliably find out whether the user is
    actually going to see and respond to the prompt on Windows, it may
    be practical to just paper over the issue. On the gripping hand,
    after the Sven's series, TortoiseGit users would see the hang
    (instead of a failure) _only_ if their askpass command failed. Which
    is also perhaps not that big a deal.
Junio C Hamano· Feb 4, 2012, 08:16 UTC · re: Jeff King · lore

Re: Push from an SSH Terminal

Jeff King <peff@peff.net> writes:
Show 11 quoted lines
> On Fri, Feb 03, 2012 at 11:47:11PM -0800, Junio C Hamano wrote:
>
>> Jeff King <peff@peff.net> writes:
>>  ...
>> How well would it mesh with the goal of the ss/git-svn-prompt-sans-terminal
>> topic, which is now stalled [*1*]?  I do not mean this change and the other
>> topic textually conflict with each other---but the philosophies of this
>> topic and the other one seem to conflict.
>
> I don't see a conflict in the two series. That one seems to do two
> things for perl programs ...
That is the "[not] textually conflict" part of my message.
Show 5 quoted lines
> If you look into the original complaint mentioned in the commit
> messages, though, you will see that the some GUIs will appear to hang
> when the terminal is prompted (because the prompt is reading from some
> location invisible to the user). So in that sense, my patches could be a
> regression for those users, as outright failing is better for them.
Yes, that is what I meant by "philosophies conflict".
Show 8 quoted lines
> But I would argue that the bug is not prompting on the terminal, but
> rather that the terminal-prompting code does not recognize when there is
> no terminal connection to the user (and AFAICT, this is a Windows
> problem). Any solution that doesn't fix that is really just papering
> over the problem, and hurting people[1] on sane systems.
>
> So I'd rather see the version of getpass() in compat/mingw.c better
> learn to realize when we aren't actually connected to a console.
That is a sane diagnosis, I'd have to agree.
Thanks for a dose of sanity.
Show 16 quoted lines
> [1] The amount of hurt is relatively small, though. It only hurts people
>     who set GIT_ASKPASS but can't use it (e.g., you set it in your
>     .bashrc because you connect via "ssh -X", but this time you happen
>     to be ssh-ing from a Windows box). And you can generally fix that
>     outside of git (e.g., by checking $DISPLAY before setting the
>     variable).
>
>     So one one hand, I don't want to make a decision on behavior for
>     Unix users because we have to cater to Windows shortcomings. On the
>     other hand, while fixing the root problem is preferable, if
>     for whatever reason we can't reliably find out whether the user is
>     actually going to see and respond to the prompt on Windows, it may
>     be practical to just paper over the issue. On the gripping hand,
>     after the Sven's series, TortoiseGit users would see the hang
>     (instead of a failure) _only_ if their askpass command failed. Which
>     is also perhaps not that big a deal.
Wow, you do have many hands ;-).
Jeff King· Feb 3, 2012, 21:35 UTC · re: Feanil Patel · lore

Re: Push from an SSH Terminal

On Fri, Feb 03, 2012 at 10:50:02AM -0500, Feanil Patel wrote:
Show 10 quoted lines
> I tried looking for an answer to my problem online without much luck,
> perhaps you can help me.  I'm SSHed from my laptop(Comp A) over to a
> computer(Comp B) that has my git repo on it. I made some changes and
> comitted them. Now I want to push them to my other server(Comp C). The
> repository is password protected so if I'm physically at Comp B, I get
> a gui prompt for my username and password. However Comp A does not
> have X Forwarding setup to Comp B so I can't get the gui interface for
> the username and password when I try to do the push.  Is there an
> alternative way to provide my credentials when doing a git push that
> does not require a gui?

Git should prompt you on the terminal (i.e., the ssh session) if it needs credentials. If it is not, and the terminal is accessible, it might be a bug. There were some fixes around this area that went into 1.7.9; you might try using that version.

Also, 1.7.9 ships with support for credential helper scripts, which can help you avoid putting in your password less frequently (see "git help credentials" in git 1.7.9).

-Peff

← back to recent threads