tomerfiliba / plumbum

Plumbum: Shell Combinators
https://plumbum.readthedocs.io
MIT License
2.79k stars 182 forks source link

cannot connect to Windows 10 OpenSSH server #592

Closed fanmingyu212 closed 2 years ago

fanmingyu212 commented 2 years ago

I cannot connect to an OpenSSH server running on a Windows 10 computer (computer A) using plumbum. The SSH authentication uses a key pair. On the same computer, I can connect using plumbum.SshMachine to another OpenSSH server running on a ubuntu 18.04 virtual machine (Computer B) though.

I tested the following things:

I am using OpenSSH_for_Windows_8.1p1, LibreSSL 3.0.2, and plumbum 1.7.1. MinGW coreutils is installed.

The error message with SshMachine is:

---------------------------------------------------------------------------
EOFError                                  Traceback (most recent call last)
C:\Anaconda3\lib\site-packages\plumbum\machines\session.py in communicate(self, input)
    124             try:
--> 125                 line = pipe.readline()
    126                 shell_logger.debug("%s> %r", name, line)

C:\Anaconda3\lib\site-packages\plumbum\machines\session.py in readline(self)
     68         if not line:
---> 69             raise EOFError()
     70         if line.strip() == self.marker:

EOFError:

During handling of the above exception, another exception occurred:

SSHCommsError                             Traceback (most recent call last)
<ipython-input-11-afdc1fc5ad47> in <module>
----> 1 a = SshMachine("127.0.0.1", user=username, port=12491, keyfile="~/.ssh/rdv_key")

C:\Anaconda3\lib\site-packages\plumbum\machines\ssh_machine.py in __init__(self, host, user, port, keyfile, ssh_command, scp_command, ssh_opts, scp_opts, password, encoding, connect_timeout, new_session)
    123         self._ssh_command = ssh_command[tuple(ssh_args)]
    124         self._scp_command = scp_command[tuple(scp_args)]
--> 125         BaseRemoteMachine.__init__(
    126             self,
    127             encoding=encoding,

C:\Anaconda3\lib\site-packages\plumbum\machines\remote.py in __init__(self, encoding, connect_timeout, new_session)
    175         self.custom_encoding = encoding
    176         self.connect_timeout = connect_timeout
--> 177         self._session = self.session(new_session=new_session)
    178         self.uname = self._get_uname()
    179         self.env = RemoteEnv(self)

C:\Anaconda3\lib\site-packages\plumbum\machines\ssh_machine.py in session(self, isatty, new_session)
    211     @_setdoc(BaseRemoteMachine)
    212     def session(self, isatty=False, new_session=False):
--> 213         return ShellSession(
    214             self.popen(
    215                 ["/bin/sh"], (["-tt"] if isatty else ["-T"]), new_session=new_session

C:\Anaconda3\lib\site-packages\plumbum\machines\session.py in __init__(self, proc, encoding, isatty, connect_timeout)
    228             timer.start()
    229         try:
--> 230             self.run("")
    231         finally:
    232             if connect_timeout:

C:\Anaconda3\lib\site-packages\plumbum\machines\session.py in run(self, cmd, retcode)
    321         """
    322         with self._lock:
--> 323             return run_proc(self.popen(cmd), retcode)

C:\Anaconda3\lib\site-packages\plumbum\commands\processes.py in run_proc(proc, retcode, timeout)
    310     """
    311     _register_proc_timeout(proc, timeout)
--> 312     stdout, stderr = proc.communicate()
    313     proc._end_time = time.time()
    314     if not stdout:

C:\Anaconda3\lib\site-packages\plumbum\machines\session.py in communicate(self, input)
    151                     )
    152                 elif returncode != 0:
--> 153                     raise SSHCommsError(
    154                         argv,
    155                         returncode,

SSHCommsError: SSH communication failed
Return code:  | None
Command line: | 'true '
Stderr:       | The system cannot find the path specified.

The error message with PuttyMachine is:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-16-b84b20c912c2> in <module>
----> 1 a = PuttyMachine("localhost", user=username, port=12491, keyfile="~/.ssh/rdv_key.ppk")

C:\Anaconda3\lib\site-packages\plumbum\machines\ssh_machine.py in __init__(self, host, user, port, keyfile, ssh_command, scp_command, ssh_opts, scp_opts, encoding, connect_timeout, new_session)
    366             scp_opts = list(scp_opts) + ["-P", str(port)]
    367             port = None
--> 368         SshMachine.__init__(
    369             self,
    370             host,

C:\Anaconda3\lib\site-packages\plumbum\machines\ssh_machine.py in __init__(self, host, user, port, keyfile, ssh_command, scp_command, ssh_opts, scp_opts, password, encoding, connect_timeout, new_session)
    123         self._ssh_command = ssh_command[tuple(ssh_args)]
    124         self._scp_command = scp_command[tuple(scp_args)]
--> 125         BaseRemoteMachine.__init__(
    126             self,
    127             encoding=encoding,

C:\Anaconda3\lib\site-packages\plumbum\machines\remote.py in __init__(self, encoding, connect_timeout, new_session)
    175         self.custom_encoding = encoding
    176         self.connect_timeout = connect_timeout
--> 177         self._session = self.session(new_session=new_session)
    178         self.uname = self._get_uname()
    179         self.env = RemoteEnv(self)

C:\Anaconda3\lib\site-packages\plumbum\machines\ssh_machine.py in session(self, isatty, new_session)
    390     @_setdoc(BaseRemoteMachine)
    391     def session(self, isatty=False, new_session=False):
--> 392         return ShellSession(
    393             self.popen((), (["-t"] if isatty else ["-T"]), new_session=new_session),
    394             self.custom_encoding,

C:\Anaconda3\lib\site-packages\plumbum\machines\session.py in __init__(self, proc, encoding, isatty, connect_timeout)
    228             timer.start()
    229         try:
--> 230             self.run("")
    231         finally:
    232             if connect_timeout:

C:\Anaconda3\lib\site-packages\plumbum\machines\session.py in run(self, cmd, retcode)
    321         """
    322         with self._lock:
--> 323             return run_proc(self.popen(cmd), retcode)

C:\Anaconda3\lib\site-packages\plumbum\commands\processes.py in run_proc(proc, retcode, timeout)
    310     """
    311     _register_proc_timeout(proc, timeout)
--> 312     stdout, stderr = proc.communicate()
    313     proc._end_time = time.time()
    314     if not stdout:

C:\Anaconda3\lib\site-packages\plumbum\machines\session.py in communicate(self, input)
    123             name, coll, pipe = sources[i]
    124             try:
--> 125                 line = pipe.readline()
    126                 shell_logger.debug("%s> %r", name, line)
    127             except EOFError:

C:\Anaconda3\lib\site-packages\plumbum\machines\session.py in readline(self)
     65         if self.pipe is None:
     66             return six.b("")
---> 67         line = self.pipe.readline()
     68         if not line:
     69             raise EOFError()

ValueError: readline of closed file
fanmingyu212 commented 2 years ago

The full command that it is trying to run withSshMachine seems to be true ; echo $? ; echo '--.END1324553574.9031646.--' ; echo '--.END1324553574.9031646.--' 1>&2 where the SSHCommsError occurs. I can run this command with no error in a command line SSH interface though.

fanmingyu212 commented 2 years ago

This is a duplicate of #478. The issue is due to that the default shell with Windows 10 OpenSSH is cmd, while a POSIX-compatible shell is needed.

A workaround is changing the default shell of OpenSSH to a bash shell (e.g. the one that comes with the coreutils installation). You can change the default shell following this example: https://jeremyverda.net/change-openssh-server-default-shell-on-windows-server-2019/.