# Push from an SSH Terminal

12 messages from 2012-02-03 to 2012-02-04. Participants: Feanil Patel, Neal Groothuis, Jeff King, Junio C Hamano.
Thread: https://gitlist.dev/t/29537

## Feanil Patel, 2012-02-03 15:50

Subject: Push from an SSH Terminal
Message-ID: <CAG94OYxX5foffvaFLQv7=wXguGC2TLgccdDFrC+ERzv_gXZ=ug@mail.gmail.com>
URL: https://gitlist.dev/e/CAG94OYxX5foffvaFLQv7%3DwXguGC2TLgccdDFrC%2BERzv_gXZ%3Dug%40mail.gmail.com

```
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, 2012-02-03 16:21

Subject: Re: Push from an SSH Terminal
Message-ID: <21607.38.96.167.131.1328286083.squirrel@mail.lo-cal.org>
URL: https://gitlist.dev/e/21607.38.96.167.131.1328286083.squirrel%40mail.lo-cal.org
In-Reply-To: <CAG94OYxX5foffvaFLQv7=wXguGC2TLgccdDFrC+ERzv_gXZ=ug@mail.gmail.com>

```
> 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, 2012-02-03 16:40

Subject: Re: Push from an SSH Terminal
Message-ID: <CAG94OYxbOYCjd5qNBh8EF2gyezHWMqX1-R2MYgk8gkFYcrMjuQ@mail.gmail.com>
URL: https://gitlist.dev/e/CAG94OYxbOYCjd5qNBh8EF2gyezHWMqX1-R2MYgk8gkFYcrMjuQ%40mail.gmail.com
In-Reply-To: <21607.38.96.167.131.1328286083.squirrel@mail.lo-cal.org>

```
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?
>
> - Neal
>

I'm pulling and pushing over HTTP from Comp C.

```

## Neal Groothuis, 2012-02-03 17:10

Subject: Re: Push from an SSH Terminal
Message-ID: <34592.38.96.167.131.1328289027.squirrel@mail.lo-cal.org>
URL: https://gitlist.dev/e/34592.38.96.167.131.1328289027.squirrel%40mail.lo-cal.org
In-Reply-To: <CAG94OYxbOYCjd5qNBh8EF2gyezHWMqX1-R2MYgk8gkFYcrMjuQ@mail.gmail.com>

```
> 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, 2012-02-03 21:35

Subject: Re: Push from an SSH Terminal
Message-ID: <20120203213508.GC1890@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20120203213508.GC1890%40sigill.intra.peff.net
In-Reply-To: <CAG94OYxX5foffvaFLQv7=wXguGC2TLgccdDFrC+ERzv_gXZ=ug@mail.gmail.com>

```
On Fri, Feb 03, 2012 at 10:50:02AM -0500, Feanil Patel wrote:

> 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

```

## Jeff King, 2012-02-03 21:36

Subject: Re: Push from an SSH Terminal
Message-ID: <20120203213654.GD1890@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20120203213654.GD1890%40sigill.intra.peff.net
In-Reply-To: <34592.38.96.167.131.1328289027.squirrel@mail.lo-cal.org>

```
On Fri, Feb 03, 2012 at 12:10:27PM -0500, Neal Groothuis wrote:

> > 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, 2012-02-03 22:13

Subject: Re: Push from an SSH Terminal
Message-ID: <20120203221324.GA8048@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20120203221324.GA8048%40sigill.intra.peff.net
In-Reply-To: <20120203213654.GD1890@sigill.intra.peff.net>

```
On Fri, Feb 03, 2012 at 04:36:54PM -0500, Jeff King 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.

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, 2012-02-03 22:14

Subject: [PATCH 1/2] prompt: clean up strbuf usage
Message-ID: <20120203221411.GA8065@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20120203221411.GA8065%40sigill.intra.peff.net
In-Reply-To: <20120203213654.GD1890@sigill.intra.peff.net>

```
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, 2012-02-03 22:16

Subject: [PATCH 2/2] prompt: fall back to terminal if askpass fails
Message-ID: <20120203221602.GB8065@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20120203221602.GB8065%40sigill.intra.peff.net
In-Reply-To: <20120203213654.GD1890@sigill.intra.peff.net>

```
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, 2012-02-04 07:47

Subject: Re: Push from an SSH Terminal
Message-ID: <7vwr83hwg0.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vwr83hwg0.fsf%40alter.siamese.dyndns.org
In-Reply-To: <20120203213654.GD1890@sigill.intra.peff.net>

```
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 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, 2012-02-04 08:09

Subject: Re: Push from an SSH Terminal
Message-ID: <20120204080910.GA28317@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20120204080910.GA28317%40sigill.intra.peff.net
In-Reply-To: <7vwr83hwg0.fsf@alter.siamese.dyndns.org>

```
On Fri, Feb 03, 2012 at 11:47:11PM -0800, Junio C Hamano wrote:

> 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, 2012-02-04 08:16

Subject: Re: Push from an SSH Terminal
Message-ID: <7vhaz7hv3u.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vhaz7hv3u.fsf%40alter.siamese.dyndns.org
In-Reply-To: <20120204080910.GA28317@sigill.intra.peff.net>

```
Jeff King <peff@peff.net> writes:

> 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.

> 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".

> 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.

> [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 ;-).

```
