-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove false dependency on pywin32 #226
Comments
@stonebig: If you delete those lines can you install jupyter-core on PyPy windows? |
trying now.. now pip is looking for alternate send2trash wheels when I ask "jupyter" directly... obscure new pip.
so, apparently, pywinpty is my next blocker to Jupyter on PyPy3 windows, and I'm clueless to compile it |
Note that the names of the modules that are used are not the same name as the package. pywin32 imports are used e.g. here: jupyter_core/jupyter_core/paths.py Lines 387 to 388 in e69a436
|
Thanks for the clarification. I guess this is a hard dependency then until
|
If it's the only blocker between Jupyter and PyPy on Windows, a rescue team will come ... re-checking if I can workaround |
failed with this receipe:
jupyter notebook launches the welcome page, but kernel crashes when creating a new notebook |
any good idea for next try welcomed (not an absolute failure on "jupyter notebook", but not good) |
faling to compile pywin32 with PyPy3 too ... a bad luck day. |
Compiles without issues but terminado might require an older version? https://www.lfd.uci.edu/~gohlke/pythonlibs/#pywinpty
should be easy, no? I ran into another Traceback (most recent call last):
File "X:\pypy3\site-packages\tornado\web.py", line 1704, in _execute
result = await result
File "X:\pypy3\site-packages\jupyter_server\services\contents\handlers.py", line 111, in get
path=path, type=type, format=format, content=content,
File "X:\pypy3\site-packages\jupyter_server\services\contents\filemanager.py", line 393, in get
model = self._dir_model(path, content=content)
File "X:\pypy3\site-packages\jupyter_server\services\contents\filemanager.py", line 293, in _dir_model
if self.allow_hidden or not is_file_hidden(os_path, stat_res=st):
File "X:\pypy3\site-packages\jupyter_core\paths.py", line 270, in is_file_hidden_win
if stat_res.st_file_attributes & stat.FILE_ATTRIBUTE_HIDDEN:
AttributeError: 'stat_result' object has no attribute 'st_file_attributes' |
It seems PyPy never added that attribute, which was part of python3.5 for windows. I opened a PyPy issue. |
I suppose "easy" for Christoph means "doable" for Steve Dower, but "hard" is a better word for me. Baby step1
|
for "LookupAccountName", I found someone who may have done it: https://github.com/MarioVilas/winappdbg for "win32security.CreateWellKnownSid(win32security.WinBuiltinAdministratorsSid)", I found something there: threre are pieces in https://github.com/openstack/os-win, but its depedencies end up using pywin32... |
Sorry, my comment wasn't meant to be serious. Using Win32 API and ctypes is very tedious and you'll end up with hundreds lines of code to replace a few lines of pywin32. |
well, I was not sure it was "easy" or "not so complex" before trying, so I tried, as otherwise Jupyter will not work on PyPy3 |
To experiment on PyPy3, you can use an empty |
Probably unrelated. But yes, I get the same error. Others too. |
Works for me, but not well tested. Maybe someone can try it: def win32_restrict_file_to_user(fname):
"""Secure a windows file to read-only access for the user.
Follows guidance from win32 library creator:
http://timgolden.me.uk/python/win32_how_do_i/add-security-to-a-file.html
This method should be executed against an already generated file which
has no secrets written to it yet.
Parameters
----------
fname : unicode
The path to the file to secure
"""
import ctypes
from ctypes import wintypes
advapi32 = ctypes.WinDLL('advapi32', use_last_error=True)
secur32 = ctypes.WinDLL('secur32', use_last_error=True)
NameSamCompatible = 2
WinBuiltinAdministratorsSid = 26
DACL_SECURITY_INFORMATION = 4
ACL_REVISION = 2
ERROR_INSUFFICIENT_BUFFER = 122
ERROR_MORE_DATA = 234
SYNCHRONIZE = 0x100000
DELETE = 0x00010000
STANDARD_RIGHTS_REQUIRED = 0xF0000
STANDARD_RIGHTS_READ = 0x20000
STANDARD_RIGHTS_WRITE = 0x20000
FILE_READ_DATA = 1
FILE_READ_EA = 8
FILE_READ_ATTRIBUTES = 128
FILE_WRITE_DATA = 2
FILE_APPEND_DATA = 4
FILE_WRITE_EA = 16
FILE_WRITE_ATTRIBUTES = 256
FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF
FILE_GENERIC_READ = (
STANDARD_RIGHTS_READ
| FILE_READ_DATA
| FILE_READ_ATTRIBUTES
| FILE_READ_EA
| SYNCHRONIZE
)
FILE_GENERIC_WRITE = (
STANDARD_RIGHTS_WRITE
| FILE_WRITE_DATA
| FILE_WRITE_ATTRIBUTES
| FILE_WRITE_EA
| FILE_APPEND_DATA
| SYNCHRONIZE
)
class ACL(ctypes.Structure):
_fields_ = [
('AclRevision', wintypes.BYTE),
('Sbz1', wintypes.BYTE),
('AclSize', wintypes.WORD),
('AceCount', wintypes.WORD),
('Sbz2', wintypes.WORD),
]
PSID = ctypes.c_void_p
PACL = ctypes.POINTER(ACL)
PSECURITY_DESCRIPTOR = ctypes.POINTER(wintypes.BYTE)
def _nonzero_success(result, func, args):
if not result:
raise ctypes.WinError(ctypes.get_last_error())
return args
secur32.GetUserNameExW.errcheck = _nonzero_success
secur32.GetUserNameExW.restype = wintypes.BOOL
secur32.GetUserNameExW.argtypes = (
ctypes.c_int, # EXTENDED_NAME_FORMAT NameFormat
wintypes.LPWSTR, # LPWSTR lpNameBuffer,
wintypes.PULONG, # PULONG nSize
)
advapi32.CreateWellKnownSid.errcheck = _nonzero_success
advapi32.CreateWellKnownSid.restype = wintypes.BOOL
advapi32.CreateWellKnownSid.argtypes = (
wintypes.DWORD, # WELL_KNOWN_SID_TYPE WellKnownSidType
PSID, # PSID DomainSid
PSID, # PSID pSid
wintypes.PDWORD, # DWORD *cbSid
)
advapi32.LookupAccountNameW.errcheck = _nonzero_success
advapi32.LookupAccountNameW.restype = wintypes.BOOL
advapi32.LookupAccountNameW.argtypes = (
wintypes.LPWSTR, # LPCWSTR lpSystemName
wintypes.LPWSTR, # LPCWSTR lpAccountName
PSID, # PSID Sid
wintypes.LPDWORD, # LPDWORD cbSid
wintypes.LPWSTR, # LPCWSTR ReferencedDomainName
wintypes.LPDWORD, # LPDWORD cchReferencedDomainName
wintypes.LPDWORD, # PSID_NAME_USE peUse
)
advapi32.AddAccessAllowedAce.errcheck = _nonzero_success
advapi32.AddAccessAllowedAce.restype = wintypes.BOOL
advapi32.AddAccessAllowedAce.argtypes = (
PACL, # PACL pAcl
wintypes.DWORD, # DWORD dwAceRevision
wintypes.DWORD, # DWORD AccessMask
PSID, # PSID pSid
)
advapi32.SetSecurityDescriptorDacl.errcheck = _nonzero_success
advapi32.SetSecurityDescriptorDacl.restype = wintypes.BOOL
advapi32.SetSecurityDescriptorDacl.argtypes = (
PSECURITY_DESCRIPTOR, # PSECURITY_DESCRIPTOR pSecurityDescriptor
wintypes.BOOL, # BOOL bDaclPresent
PACL, # PACL pDacl
wintypes.BOOL, # BOOL bDaclDefaulted
)
advapi32.GetFileSecurityW.errcheck = _nonzero_success
advapi32.GetFileSecurityW.restype = wintypes.BOOL
advapi32.GetFileSecurityW.argtypes = (
wintypes.LPCWSTR, # LPCWSTR lpFileName
wintypes.DWORD, # SECURITY_INFORMATION RequestedInformation
PSECURITY_DESCRIPTOR, # PSECURITY_DESCRIPTOR pSecurityDescriptor
wintypes.DWORD, # DWORD nLength
wintypes.LPDWORD, # LPDWORD lpnLengthNeeded
)
advapi32.SetFileSecurityW.errcheck = _nonzero_success
advapi32.SetFileSecurityW.restype = wintypes.BOOL
advapi32.SetFileSecurityW.argtypes = (
wintypes.LPCWSTR, # LPCWSTR lpFileName
wintypes.DWORD, # SECURITY_INFORMATION SecurityInformation
PSECURITY_DESCRIPTOR, # PSECURITY_DESCRIPTOR pSecurityDescriptor
)
advapi32.MakeAbsoluteSD.errcheck = _nonzero_success
advapi32.MakeAbsoluteSD.restype = wintypes.BOOL
advapi32.MakeAbsoluteSD.argtypes = (
PSECURITY_DESCRIPTOR, # pSelfRelativeSecurityDescriptor
PSECURITY_DESCRIPTOR, # pAbsoluteSecurityDescriptor
wintypes.LPDWORD, # LPDWORD lpdwAbsoluteSecurityDescriptorSize
PACL, # PACL pDacl
wintypes.LPDWORD, # LPDWORD lpdwDaclSize
PACL, # PACL pSacl
wintypes.LPDWORD, # LPDWORD lpdwSaclSize
PSID, # PSID pOwner
wintypes.LPDWORD, # LPDWORD lpdwOwnerSize
PSID, # PSID pPrimaryGroup
wintypes.LPDWORD, # LPDWORD lpdwPrimaryGroupSize
)
advapi32.MakeSelfRelativeSD.errcheck = _nonzero_success
advapi32.MakeSelfRelativeSD.restype = wintypes.BOOL
advapi32.MakeSelfRelativeSD.argtypes = (
PSECURITY_DESCRIPTOR, # pAbsoluteSecurityDescriptor
PSECURITY_DESCRIPTOR, # pSelfRelativeSecurityDescriptor
wintypes.LPDWORD, # LPDWORD lpdwBufferLength
)
advapi32.InitializeAcl.errcheck = _nonzero_success
advapi32.InitializeAcl.restype = wintypes.BOOL
advapi32.InitializeAcl.argtypes = (
PACL, # PACL pAcl,
wintypes.DWORD, # DWORD nAclLength,
wintypes.DWORD, # DWORD dwAclRevision
)
def CreateWellKnownSid(WellKnownSidType):
# return a SID for predefined aliases
pSid = (ctypes.c_char * 1)()
cbSid = wintypes.DWORD()
try:
advapi32.CreateWellKnownSid(
WellKnownSidType, None, pSid, ctypes.byref(cbSid)
)
except OSError as e:
if e.winerror != ERROR_INSUFFICIENT_BUFFER:
raise
pSid = (ctypes.c_char * cbSid.value)()
advapi32.CreateWellKnownSid(
WellKnownSidType, None, pSid, ctypes.byref(cbSid)
)
return pSid[:]
def GetUserNameEx(NameFormat):
# return the user or other security principal associated with
# the calling thread
nSize = ctypes.pointer(ctypes.c_ulong(0))
try:
secur32.GetUserNameExW(NameFormat, None, nSize)
except WindowsError as e:
if e.winerror != ERROR_MORE_DATA:
raise
if not nSize.contents.value:
return None
lpNameBuffer = ctypes.create_unicode_buffer(nSize.contents.value)
secur32.GetUserNameExW(NameFormat, lpNameBuffer, nSize)
return lpNameBuffer.value
def LookupAccountName(lpSystemName, lpAccountName):
# return a security identifier (SID) for an account on a system
# and the name of the domain on which the account was found
cbSid = wintypes.DWORD(0)
cchReferencedDomainName = wintypes.DWORD(0)
peUse = wintypes.DWORD(0)
try:
advapi32.LookupAccountNameW(
lpSystemName,
lpAccountName,
None,
ctypes.byref(cbSid),
None,
ctypes.byref(cchReferencedDomainName),
ctypes.byref(peUse),
)
except WindowsError as e:
if e.winerror != ERROR_INSUFFICIENT_BUFFER:
raise
Sid = ctypes.create_unicode_buffer('', cbSid.value)
pSid = ctypes.cast(ctypes.pointer(Sid), wintypes.LPVOID)
lpReferencedDomainName = ctypes.create_unicode_buffer(
'', cchReferencedDomainName.value + 1
)
success = advapi32.LookupAccountNameW(
lpSystemName,
lpAccountName,
pSid,
ctypes.byref(cbSid),
lpReferencedDomainName,
ctypes.byref(cchReferencedDomainName),
ctypes.byref(peUse),
)
if not success:
raise ctypes.WinError()
return pSid, lpReferencedDomainName.value, peUse.value
def AddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid):
# add an access-allowed access control entry (ACE)
# to an access control list (ACL)
advapi32.AddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid)
def GetFileSecurity(lpFileName, RequestedInformation):
# return information about the security of a file or directory
nLength = wintypes.DWORD(0)
try:
advapi32.GetFileSecurityW(
lpFileName,
RequestedInformation,
None,
0,
ctypes.byref(nLength),
)
except WindowsError as e:
if e.winerror != ERROR_INSUFFICIENT_BUFFER:
raise
if not nLength.value:
return None
pSecurityDescriptor = (wintypes.BYTE * nLength.value)()
advapi32.GetFileSecurityW(
lpFileName,
RequestedInformation,
pSecurityDescriptor,
nLength,
ctypes.byref(nLength),
)
return pSecurityDescriptor
def SetFileSecurity(lpFileName, RequestedInformation, pSecurityDescriptor):
# set the security of a file or directory object
advapi32.SetFileSecurityW(
lpFileName, RequestedInformation, pSecurityDescriptor
)
def SetSecurityDescriptorDacl(
pSecurityDescriptor, bDaclPresent, pDacl, bDaclDefaulted
):
# set information in a discretionary access control list (DACL)
advapi32.SetSecurityDescriptorDacl(
pSecurityDescriptor, bDaclPresent, pDacl, bDaclDefaulted
)
def MakeAbsoluteSD(pSelfRelativeSecurityDescriptor):
# return a security descriptor in absolute format
# by using a security descriptor in self-relative format as a template
pAbsoluteSecurityDescriptor = None
lpdwAbsoluteSecurityDescriptorSize = wintypes.DWORD(0)
pDacl = None
lpdwDaclSize = wintypes.DWORD(0)
pSacl = None
lpdwSaclSize = wintypes.DWORD(0)
pOwner = None
lpdwOwnerSize = wintypes.DWORD(0)
pPrimaryGroup = None
lpdwPrimaryGroupSize = wintypes.DWORD(0)
try:
advapi32.MakeAbsoluteSD(
pSelfRelativeSecurityDescriptor,
pAbsoluteSecurityDescriptor,
ctypes.byref(lpdwAbsoluteSecurityDescriptorSize),
pDacl,
ctypes.byref(lpdwDaclSize),
pSacl,
ctypes.byref(lpdwSaclSize),
pOwner,
ctypes.byref(lpdwOwnerSize),
pPrimaryGroup,
ctypes.byref(lpdwPrimaryGroupSize),
)
except WindowsError as e:
if e.winerror != ERROR_INSUFFICIENT_BUFFER:
raise
pAbsoluteSecurityDescriptor = (
wintypes.BYTE * lpdwAbsoluteSecurityDescriptorSize.value
)()
pDaclData = (wintypes.BYTE * lpdwDaclSize.value)()
pDacl = ctypes.cast(pDaclData, PACL).contents
pSaclData = (wintypes.BYTE * lpdwSaclSize.value)()
pSacl = ctypes.cast(pSaclData, PACL).contents
pOwnerData = (wintypes.BYTE * lpdwOwnerSize.value)()
pOwner = ctypes.cast(pOwnerData, PSID)
pPrimaryGroupData = (wintypes.BYTE * lpdwPrimaryGroupSize.value)()
pPrimaryGroup = ctypes.cast(pPrimaryGroupData, PSID)
advapi32.MakeAbsoluteSD(
pSelfRelativeSecurityDescriptor,
pAbsoluteSecurityDescriptor,
ctypes.byref(lpdwAbsoluteSecurityDescriptorSize),
pDacl,
ctypes.byref(lpdwDaclSize),
pSacl,
ctypes.byref(lpdwSaclSize),
pOwner,
lpdwOwnerSize,
pPrimaryGroup,
ctypes.byref(lpdwPrimaryGroupSize),
)
return pAbsoluteSecurityDescriptor
def MakeSelfRelativeSD(pAbsoluteSecurityDescriptor):
# return a security descriptor in self-relative format
# by using a security descriptor in absolute format as a template
pSelfRelativeSecurityDescriptor = None
lpdwBufferLength = wintypes.DWORD(0)
try:
advapi32.MakeSelfRelativeSD(
pAbsoluteSecurityDescriptor,
pSelfRelativeSecurityDescriptor,
ctypes.byref(lpdwBufferLength),
)
except WindowsError as e:
if e.winerror != ERROR_INSUFFICIENT_BUFFER:
raise
pSelfRelativeSecurityDescriptor = (
wintypes.BYTE * lpdwBufferLength.value
)()
advapi32.MakeSelfRelativeSD(
pAbsoluteSecurityDescriptor,
pSelfRelativeSecurityDescriptor,
ctypes.byref(lpdwBufferLength),
)
return pSelfRelativeSecurityDescriptor
def NewAcl():
# return a new, initialized ACL (access control list) structure
nAclLength = 32767 # TODO: calculate this: ctypes.sizeof(ACL) + ?
acl_data = ctypes.create_string_buffer(nAclLength)
pAcl = ctypes.cast(acl_data, PACL).contents
advapi32.InitializeAcl(pAcl, nAclLength, ACL_REVISION)
return pAcl
SidAdmins = CreateWellKnownSid(WinBuiltinAdministratorsSid)
SidUser = LookupAccountName('', GetUserNameEx(NameSamCompatible))[0]
Acl = NewAcl()
AddAccessAllowedAce(Acl, ACL_REVISION, FILE_ALL_ACCESS, SidAdmins)
AddAccessAllowedAce(
Acl,
ACL_REVISION,
FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE,
SidUser,
)
SelfRelativeSD = GetFileSecurity(fname, DACL_SECURITY_INFORMATION)
AbsoluteSD = MakeAbsoluteSD(SelfRelativeSD)
SetSecurityDescriptorDacl(AbsoluteSD, 1, Acl, 0)
SelfRelativeSD = MakeSelfRelativeSD(AbsoluteSD)
SetFileSecurity(fname, DACL_SECURITY_INFORMATION, SelfRelativeSD) |
Re |
Re |
Are you using the Cython backend? With the default cffi backend I get occasional crashes when closing sockets... |
No clue, how do I know that ? |
I don't see instability tonight in my longer experiments, |
This has drifted quite off-topic for this issue. Please continue the discussion on the PyPy issue. |
There is a stray dependency on pywin32 in
setup.cfg
jupyter_core/setup.cfg
Line 27 in 46a9c51
Is it still needed?
The text was updated successfully, but these errors were encountered: