diff --git a/NEWS b/NEWS index c2d450b..086ebb4 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,27 @@ Issues noted as "Fabric #NN" can be found at https://github.com/fabric/fabric/. Releases ======== +v1.12.2 (21st Jan 2014) +----------------------- + +* #193 (and its attentant PRs #230 & #253): Fix SSH agent problems present on + Windows. Thanks to David Hobbs for initial report and to Aarni Koskela & Olle + Lundberg for the patches. + +v1.11.4 (21st Jan 2014) +----------------------- + +* #193 (and its attentant PRs #230 & #253): Fix SSH agent problems present on + Windows. Thanks to David Hobbs for initial report and to Aarni Koskela & Olle + Lundberg for the patches. + +v1.10.6 (21st Jan 2014) +----------------------- + +* #193 (and its attentant PRs #230 & #253): Fix SSH agent problems present on + Windows. Thanks to David Hobbs for initial report and to Aarni Koskela & Olle + Lundberg for the patches. + v1.12.1 (8th Jan 2014) ---------------------- diff --git a/paramiko/_winapi.py b/paramiko/_winapi.py index f141b00..b875924 100644 --- a/paramiko/_winapi.py +++ b/paramiko/_winapi.py @@ -10,6 +10,11 @@ import ctypes import ctypes.wintypes import __builtin__ +try: + USHORT = ctypes.wintypes.USHORT +except AttributeError: + USHORT = ctypes.c_ushort + ###################### # jaraco.windows.error @@ -81,9 +86,6 @@ def handle_nonzero_success(result): raise WindowsError() -##################### -# jaraco.windows.mmap - CreateFileMapping = ctypes.windll.kernel32.CreateFileMappingW CreateFileMapping.argtypes = [ ctypes.wintypes.HANDLE, @@ -130,15 +132,18 @@ class MemoryMap(object): self.pos = pos def write(self, msg): - ctypes.windll.msvcrt.memcpy(self.view + self.pos, msg, len(msg)) - self.pos += len(msg) + n = len(msg) + if self.pos + n >= self.length: # A little safety. + raise ValueError("Refusing to write %d bytes" % n) + ctypes.windll.kernel32.RtlMoveMemory(self.view + self.pos, msg, n) + self.pos += n def read(self, n): """ Read n bytes from mapped view. """ out = ctypes.create_string_buffer(n) - ctypes.windll.msvcrt.memcpy(out, self.view + self.pos, n) + ctypes.windll.kernel32.RtlMoveMemory(out, self.view + self.pos, n) self.pos += n return out.raw @@ -173,7 +178,7 @@ class SECURITY_DESCRIPTOR(ctypes.Structure): PACL Dacl; } SECURITY_DESCRIPTOR; """ - SECURITY_DESCRIPTOR_CONTROL = ctypes.wintypes.USHORT + SECURITY_DESCRIPTOR_CONTROL = USHORT REVISION = 1 _fields_ = [ diff --git a/paramiko/win_pageant.py b/paramiko/win_pageant.py index de1cd64..d588e81 100644 --- a/paramiko/win_pageant.py +++ b/paramiko/win_pageant.py @@ -23,14 +23,19 @@ Functions for communicating with Pageant, the basic windows ssh agent program. from __future__ import with_statement -import struct -import threading import array -import platform import ctypes.wintypes +import platform +import struct + +try: + import _thread as thread # Python 3.x +except ImportError: + import thread # Python 2.5-2.7 from . import _winapi + _AGENT_COPYDATA_ID = 0x804e50ba _AGENT_MAX_MSGLEN = 8192 # Note: The WM_COPYDATA value is pulled from win32con, as a workaround @@ -51,7 +56,10 @@ def can_talk_to_agent(): """ return bool(_get_pageant_window_object()) + ULONG_PTR = ctypes.c_uint64 if platform.architecture()[0] == '64bit' else ctypes.c_uint32 + + class COPYDATASTRUCT(ctypes.Structure): """ ctypes implementation of @@ -61,7 +69,8 @@ class COPYDATASTRUCT(ctypes.Structure): ('num_data', ULONG_PTR), ('data_size', ctypes.wintypes.DWORD), ('data_loc', ctypes.c_void_p), - ] + ] + def _query_pageant(msg): """ @@ -74,7 +83,7 @@ def _query_pageant(msg): return None # create a name for the mmap - map_name = 'PageantRequest%08x' % threading.current_thread().ident + map_name = 'PageantRequest%08x' % thread.get_ident() pymap = _winapi.MemoryMap(map_name, _AGENT_MAX_MSGLEN, _winapi.get_security_attributes_for_user(), @@ -98,7 +107,8 @@ def _query_pageant(msg): return datalen + pymap.read(retlen) return None -class PageantConnection (object): + +class PageantConnection(object): """ Mock "connection" to an agent which roughly approximates the behavior of a unix local-domain socket (as used by Agent). Requests are sent to the