sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
# sshaskpass.py
|
|
|
|
#
|
|
|
|
# Copyright 2016 Facebook, Inc.
|
|
|
|
#
|
|
|
|
# This software may be used and distributed according to the terms of the
|
|
|
|
# GNU General Public License version 2 or any later version.
|
|
|
|
|
|
|
|
"""ssh-askpass implementation that works with chg
|
|
|
|
|
|
|
|
chg runs ssh at server side, and ssh does not have access to /dev/tty thus
|
|
|
|
unable to ask for password interactively when its output is being piped (ex.
|
|
|
|
during hg push or pull).
|
|
|
|
|
|
|
|
When ssh is unable to use /dev/tty, it will try to run SSH_ASKPASS if DISPLAY
|
|
|
|
is set, which is usually a GUI program. Here we set it to a special program
|
|
|
|
receiving fds from a simple unix socket server.
|
|
|
|
|
2016-08-11 23:42:54 +03:00
|
|
|
This file is both a mercurial extension to start that tty server and a
|
|
|
|
standalone ssh-askpass script.
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
"""
|
|
|
|
|
2017-01-05 20:04:34 +03:00
|
|
|
# Attention: Do NOT import anything inside mercurial here. This file also runs
|
|
|
|
# standalone without the mercurial environment, in which case it cannot import
|
|
|
|
# mercurial modules correctly.
|
|
|
|
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
import contextlib
|
|
|
|
import os
|
|
|
|
import signal
|
|
|
|
import socket
|
|
|
|
import sys
|
|
|
|
import tempfile
|
|
|
|
|
2017-01-05 20:04:34 +03:00
|
|
|
try:
|
|
|
|
from mercurial import encoding
|
|
|
|
environ = encoding.environ
|
|
|
|
except ImportError:
|
|
|
|
environ = getattr(os, 'environ')
|
|
|
|
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
from multiprocessing.reduction import recv_handle, send_handle
|
|
|
|
|
2016-10-17 23:28:33 +03:00
|
|
|
# backup tty fds. useful if we lose them later, like chg starting the pager
|
|
|
|
_ttyfds = []
|
|
|
|
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
@contextlib.contextmanager
|
|
|
|
def _silentexception(terminate=False):
|
|
|
|
"""silent common exceptions
|
|
|
|
|
|
|
|
useful if we don't want to pollute the terminal
|
|
|
|
exit if terminal is True
|
|
|
|
"""
|
|
|
|
exitcode = 0
|
|
|
|
try:
|
|
|
|
yield
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
exitcode = 1
|
|
|
|
except Exception:
|
|
|
|
exitcode = 2
|
|
|
|
if terminate:
|
|
|
|
os._exit(exitcode)
|
|
|
|
|
|
|
|
def _sockbind(sock, addr):
|
|
|
|
"""shim for util.bindunixsocket"""
|
|
|
|
sock.bind(addr)
|
|
|
|
|
|
|
|
def _isttyserverneeded():
|
|
|
|
# respect user's setting, SSH_ASKPASS is likely a gui program
|
2017-01-05 20:04:34 +03:00
|
|
|
if 'SSH_ASKPASS' in environ:
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
return False
|
|
|
|
|
|
|
|
# the tty server is not needed if /dev/tty can be opened
|
|
|
|
try:
|
|
|
|
with open('/dev/tty'):
|
|
|
|
return False
|
|
|
|
except Exception:
|
|
|
|
pass
|
|
|
|
|
2016-10-17 23:28:33 +03:00
|
|
|
# if no backup tty fds, and neither stdin nor stderr are tty, give up
|
|
|
|
if not _ttyfds and not all(f.isatty() for f in [sys.stdin, sys.stderr]):
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
return False
|
|
|
|
|
|
|
|
# tty server is needed
|
|
|
|
return True
|
|
|
|
|
|
|
|
def _startttyserver():
|
|
|
|
"""start a tty fd server
|
|
|
|
|
|
|
|
the server will send tty read and write fds via unix socket
|
|
|
|
|
|
|
|
listens at sockpath: $TMPDIR/ttysrv$UID/$PID
|
|
|
|
returns (pid, sockpath)
|
|
|
|
"""
|
2016-08-16 21:51:47 +03:00
|
|
|
sockpath = os.path.join(tempfile.mkdtemp('ttysrv'), str(os.getpid()))
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
pipes = os.pipe()
|
|
|
|
pid = os.fork()
|
|
|
|
if pid:
|
|
|
|
# parent, wait for the child to start listening
|
|
|
|
os.close(pipes[1])
|
|
|
|
os.read(pipes[0], 1)
|
|
|
|
os.close(pipes[0])
|
|
|
|
return pid, sockpath
|
|
|
|
|
|
|
|
# child, starts the server
|
2016-10-17 23:28:33 +03:00
|
|
|
ttyrfd, ttywfd = _ttyfds or [sys.stdin.fileno(), sys.stderr.fileno()]
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
|
|
|
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
|
|
getattr(util, 'bindunixsocket', _sockbind)(sock, sockpath)
|
|
|
|
sock.listen(1)
|
|
|
|
|
|
|
|
# unblock parent
|
|
|
|
os.close(pipes[0])
|
|
|
|
os.write(pipes[1], ' ')
|
|
|
|
os.close(pipes[1])
|
|
|
|
with _silentexception(terminate=True):
|
|
|
|
while True:
|
|
|
|
conn, addr = sock.accept()
|
|
|
|
# 0: a dummy destination_pid, is ignored on posix systems
|
2016-10-17 23:28:33 +03:00
|
|
|
send_handle(conn, ttyrfd, 0)
|
|
|
|
send_handle(conn, ttywfd, 0)
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
conn.close()
|
|
|
|
|
|
|
|
def _killprocess(pid):
|
|
|
|
"""kill and reap a child process"""
|
|
|
|
os.kill(pid, signal.SIGTERM)
|
|
|
|
try:
|
|
|
|
os.waitpid(pid, 0)
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
pass
|
|
|
|
except Exception:
|
|
|
|
pass
|
|
|
|
|
|
|
|
def _receivefds(sockpath):
|
|
|
|
"""get fds from the tty server listening at sockpath
|
|
|
|
|
|
|
|
returns (readfd, writefd)
|
|
|
|
"""
|
|
|
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
|
|
# use chdir to handle long sockpath
|
|
|
|
os.chdir(os.path.dirname(sockpath) or '.')
|
|
|
|
sock.connect(os.path.basename(sockpath))
|
|
|
|
rfd = recv_handle(sock)
|
|
|
|
wfd = recv_handle(sock)
|
|
|
|
return (rfd, wfd)
|
|
|
|
|
2017-12-14 22:12:22 +03:00
|
|
|
def _validaterepo(orig, self, sshcmd, args, remotecmd, sshenv=None):
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
if not _isttyserverneeded():
|
2017-12-14 22:12:22 +03:00
|
|
|
return orig(self, sshcmd, args, remotecmd, sshenv=sshenv)
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
|
2016-08-11 23:42:54 +03:00
|
|
|
pid = sockpath = scriptpath = None
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
with _silentexception(terminate=False):
|
|
|
|
pid, sockpath = _startttyserver()
|
2016-08-11 23:42:54 +03:00
|
|
|
scriptpath = sockpath + '.sh'
|
|
|
|
with open(scriptpath, 'w') as f:
|
|
|
|
f.write('#!/bin/bash\nexec %s %s "$@"'
|
|
|
|
% (util.shellquote(sys.executable),
|
|
|
|
util.shellquote(__file__)))
|
|
|
|
os.chmod(scriptpath, 0o755)
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
env = {
|
|
|
|
# ssh will not use SSH_ASKPASS if DISPLAY is not set
|
2017-01-05 20:04:34 +03:00
|
|
|
'DISPLAY': environ.get('DISPLAY', ''),
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
'SSH_ASKPASS': util.shellquote(scriptpath),
|
|
|
|
'TTYSOCK': util.shellquote(sockpath),
|
|
|
|
}
|
|
|
|
prefix = ' '.join('%s=%s' % (k, v) for k, v in env.items())
|
|
|
|
# modify sshcmd to include new environ
|
|
|
|
sshcmd = '%s %s' % (prefix, sshcmd)
|
|
|
|
|
|
|
|
try:
|
2017-12-14 22:12:22 +03:00
|
|
|
return orig(self, sshcmd, args, remotecmd, sshenv=sshenv)
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
finally:
|
|
|
|
if pid:
|
|
|
|
_killprocess(pid)
|
2016-08-11 23:42:54 +03:00
|
|
|
for path in [scriptpath, sockpath]:
|
|
|
|
if path and os.path.exists(path):
|
|
|
|
util.unlinkpath(path, ignoremissing=True)
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
|
2016-10-17 23:28:33 +03:00
|
|
|
def _attachio(orig, self):
|
|
|
|
orig(self)
|
|
|
|
# backup read, write tty fds to _ttyfds
|
|
|
|
if _ttyfds:
|
|
|
|
return
|
|
|
|
ui = self.ui
|
|
|
|
if ui.fin.isatty() and ui.ferr.isatty():
|
|
|
|
rfd = os.dup(ui.fin.fileno())
|
|
|
|
wfd = os.dup(ui.ferr.fileno())
|
|
|
|
_ttyfds[:] = [rfd, wfd]
|
|
|
|
|
|
|
|
def _patchchgserver():
|
|
|
|
"""patch chgserver so we can backup tty fds before they are replaced if
|
|
|
|
chg starts the pager.
|
|
|
|
"""
|
2016-11-29 18:14:51 +03:00
|
|
|
chgserver = None
|
2016-10-17 23:28:33 +03:00
|
|
|
try:
|
2016-11-29 18:14:51 +03:00
|
|
|
from mercurial import chgserver
|
|
|
|
except ImportError:
|
|
|
|
try:
|
|
|
|
chgserver = extensions.find('chgserver')
|
|
|
|
except KeyError:
|
|
|
|
pass
|
|
|
|
server = getattr(chgserver, 'chgcmdserver', None)
|
|
|
|
if server and 'attachio' in server.capabilities:
|
|
|
|
orig = server.attachio
|
|
|
|
server.capabilities['attachio'] = extensions.bind(_attachio, orig)
|
2016-10-17 23:28:33 +03:00
|
|
|
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
def uisetup(ui):
|
|
|
|
# _validaterepo runs ssh and needs to be wrapped
|
|
|
|
extensions.wrapfunction(sshpeer.sshpeer, '_validaterepo', _validaterepo)
|
2016-10-17 23:28:33 +03:00
|
|
|
_patchchgserver()
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
|
|
|
|
def _setecho(ttyr, enableecho):
|
|
|
|
import termios
|
|
|
|
attrs = termios.tcgetattr(ttyr)
|
|
|
|
if bool(enableecho) == bool(attrs[3] & termios.ECHO):
|
|
|
|
return
|
|
|
|
attrs[3] ^= termios.ECHO
|
|
|
|
termios.tcsetattr(ttyr, termios.TCSANOW, attrs)
|
|
|
|
|
|
|
|
def _shoulddisableecho(prompt):
|
|
|
|
# we don't have the "flag" information from openssh's
|
|
|
|
# read_passphrase(const char *prompt, int flags).
|
|
|
|
# guess from the prompt string.
|
2018-04-12 01:57:17 +03:00
|
|
|
# do not match "Passcode or option"
|
|
|
|
if 'Passcode or option' in prompt:
|
|
|
|
return False
|
|
|
|
# match "password", "Password", "passphrase", "Passphrase".
|
|
|
|
return prompt.find('ass') >= 0
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
|
|
|
|
def _sshaskpassmain(prompt):
|
|
|
|
"""the ssh-askpass client"""
|
2017-01-05 20:04:34 +03:00
|
|
|
rfd, wfd = _receivefds(environ['TTYSOCK'])
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
r, w = os.fdopen(rfd, 'r'), os.fdopen(wfd, 'a')
|
2016-08-11 23:56:31 +03:00
|
|
|
w.write('\033[31;1m==== AUTHENTICATING FOR SSH ====\033[0m\n')
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
w.write(prompt)
|
|
|
|
w.flush()
|
2016-08-11 23:56:31 +03:00
|
|
|
shouldecho = not _shoulddisableecho(prompt)
|
|
|
|
_setecho(r, shouldecho)
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
try:
|
|
|
|
line = r.readline()
|
|
|
|
finally:
|
2016-08-11 23:56:31 +03:00
|
|
|
if not shouldecho:
|
|
|
|
w.write('\n')
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
_setecho(r, True)
|
|
|
|
sys.stdout.write(line)
|
|
|
|
sys.stdout.flush()
|
2016-08-11 23:56:31 +03:00
|
|
|
w.write('\033[31;1m==== AUTHENTICATION COMPLETE ====\033[0m\n')
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
|
2017-01-05 20:04:34 +03:00
|
|
|
if __name__ == '__main__' and all(n in environ
|
sshaskpass: enable ssh to ask password if running with chg
Summary:
During chg pull or push over ssh, ssh is started by chgserver which does not
have a controlling tty. Therefore the ssh process won't be able to ask for
passwords interactively.
This is actually a hard issue because an unprivileged process without a ctty
cannot attach to a ctty of another process.
The discussion at upstream tends to make it clear it's part of limitations
of chg. Therefore if we decide to workaround it, it has to live outside core,
thus fb-hgext.
GUI ssh-askpass is actually a good and clean choice. See D3510178 and D3515604.
However, they are for OS X but not Linux.
This diff is a very hacky solution to make ssh-askpass works in terminal.
It starts a "tty server" providing tty I/O fds and set `SSH_ASKPASS` to use a
custom script talking to the "tty server".
Test Plan:
Run the new test. Start a sshd locally and try:
```
$ hg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
$ chg push ssh://root@localhost/tmp
pushing to ssh://root@localhost/tmp
==== SSH Authenticating ====
root@localhost's password:
remote: Permission denied (publickey,password).
abort: no suitable response from remote hg!
```
Reviewers: #mercurial, ttung, mpm
Reviewed By: mpm
Subscribers: durham, mpm, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3577509
Tasks: 12029680
Signature: t1:3577509:1469467700:cd93565bd47e535bb4cb41fcdaa39e45dddfae28
2016-07-17 22:35:34 +03:00
|
|
|
for n in ['SSH_ASKPASS', 'TTYSOCK']):
|
|
|
|
# started by ssh as ssh-askpass
|
|
|
|
with _silentexception(terminate=True):
|
|
|
|
_sshaskpassmain(' '.join(sys.argv[1:]))
|
2016-08-31 23:05:00 +03:00
|
|
|
else:
|
|
|
|
# imported as a mercurial extension
|
|
|
|
from mercurial import (
|
|
|
|
extensions,
|
|
|
|
sshpeer,
|
|
|
|
util,
|
|
|
|
)
|