diff options
-rw-r--r-- | paramiko/ecdsakey.py | 2 | ||||
-rw-r--r-- | paramiko/ed25519key.py | 2 | ||||
-rw-r--r-- | paramiko/kex_group14.py | 2 | ||||
-rw-r--r-- | paramiko/kex_group16.py | 2 | ||||
-rw-r--r-- | paramiko/proxy.py | 2 | ||||
-rw-r--r-- | paramiko/win_openssh.py | 26 | ||||
-rw-r--r-- | sites/www/changelog.rst | 5 |
7 files changed, 31 insertions, 10 deletions
diff --git a/paramiko/ecdsakey.py b/paramiko/ecdsakey.py index 62bc8d9b..ad84fe31 100644 --- a/paramiko/ecdsakey.py +++ b/paramiko/ecdsakey.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/paramiko/ed25519key.py b/paramiko/ed25519key.py index b29d82c5..c9e37e0a 100644 --- a/paramiko/ed25519key.py +++ b/paramiko/ed25519key.py @@ -5,7 +5,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/paramiko/kex_group14.py b/paramiko/kex_group14.py index 2d82d764..8dee5515 100644 --- a/paramiko/kex_group14.py +++ b/paramiko/kex_group14.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/paramiko/kex_group16.py b/paramiko/kex_group16.py index b53aad38..c675f877 100644 --- a/paramiko/kex_group16.py +++ b/paramiko/kex_group16.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/paramiko/proxy.py b/paramiko/proxy.py index 3e3e61a6..f7609c98 100644 --- a/paramiko/proxy.py +++ b/paramiko/proxy.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/paramiko/win_openssh.py b/paramiko/win_openssh.py index 5dd71cd4..614b5898 100644 --- a/paramiko/win_openssh.py +++ b/paramiko/win_openssh.py @@ -18,23 +18,39 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import os.path +import time PIPE_NAME = r"\\.\pipe\openssh-ssh-agent" def can_talk_to_agent(): - return os.path.exists(PIPE_NAME) + # use os.listdir() instead of os.path.exists(), because os.path.exists() + # uses CreateFileW() API and the pipe cannot be reopen unless the server + # calls DisconnectNamedPipe(). + dir_, name = os.path.split(PIPE_NAME) + name = name.lower() + return any(name == n.lower() for n in os.listdir(dir_)) class OpenSSHAgentConnection: def __init__(self): - self._pipe = open(PIPE_NAME, "rb+", buffering=0) + while True: + try: + self._pipe = os.open(PIPE_NAME, os.O_RDWR | os.O_BINARY) + except OSError as e: + # retry when errno 22 which means that the server has not + # called DisconnectNamedPipe() yet. + if e.errno != 22: + raise + else: + break + time.sleep(0.1) def send(self, data): - return self._pipe.write(data) + return os.write(self._pipe, data) def recv(self, n): - return self._pipe.read(n) + return os.read(self._pipe, n) def close(self): - return self._pipe.close() + return os.close(self._pipe) diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 5e8af902..060963b8 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,11 @@ Changelog ========= +- :bug:`2008` (via :issue:`2010`) Windows-native SSH agent support as merged in + 2.10 could encounter ``Errno 22`` ``OSError`` exceptions in some scenarios + (eg server not cleanly closing a relevant named pipe). This has been worked + around and should be less problematic. Reported by Danilo Campana Fuchs and + patched by Jun Omae. - :release:`2.10.4 <2022-04-25>` - :release:`2.9.4 <2022-04-25>` - :support:`1838 backported` (via :issue:`1870`/:issue:`2028`) Update |