eryksun added the comment:

Albert, this issue was opened for Python 2.4 and was closed over 6 years ago. 
Open a new issue if you believe there's a bug or room for improvement in a 
currently supported Python version. 

FYI, on Windows _PyOS_URandom first initializes the Crypto API by calling 
[CryptAcquireContext][1]. As shown in the debug session below, this function 
requires the SystemRoot environment variable to be correctly defined. 

    C:\>cdb -g "C:\Program Files\Python27\python.exe"

    Microsoft (R) Windows Debugger Version 6.12.0002.633 AMD64
    Copyright (c) Microsoft Corporation. All rights reserved.

    ...

    >>> import os
    >>> from ctypes import *
    ...
    >>> PROV_RSA_FULL = 1
    >>> CRYPT_VERIFYCONTEXT = 0xf0000000
    >>> CryptAcquireContextA = WinDLL('advapi32').CryptAcquireContextA 
    >>> hcrypt = c_void_p()

    >>> del os.environ['SystemRoot']
    >>> CryptAcquireContextA(byref(hcrypt), None, None, PROV_RSA_FULL, 
CRYPT_VERIFYCONTEXT)
    ModLoad: 000007fe`fc480000 000007fe`fc498000   
C:\Windows\system32\CRYPTSP.dll
    CryptAcquireContext:  CheckSignatureInFile failed at cryptapi.c line 5198
    CryptAcquireContext:  Failed to read registry signature value at cryptapi.c 
line 873
    0

    >>> os.environ['SystemRoot'] = 'C:\\Windows'
    >>> CryptAcquireContextA(byref(hcrypt), None, None, PROV_RSA_FULL, 
CRYPT_VERIFYCONTEXT)
    ModLoad: 000007fe`fc180000 000007fe`fc1c7000   
C:\Windows\system32\rsaenh.dll
    ModLoad: 000007fe`fcae0000 000007fe`fcaef000   
C:\Windows\system32\CRYPTBASE.dll
    1
    >>> hcrypt
    c_void_p(4407952L)

It has always struck me as odd that this API uses the environment variable 
instead of the object manager's secured \SystemRoot object symbolic link. C'est 
la vie. 

Anyway, I don't think Python's os and subprocess modules should prevent you 
from shooting yourself in the foot here. When creating an environment block for 
a child process, excluding SystemRoot is generally a bad idea, but the language 
shouldn't get in the way. 

I think it's prudent to include at least all of the system-defined variables. 
Here's a function that calls [CreateEnvironmentBlock][2] and returns the system 
variables in a dict. It excludes user variables and doesn't inherit from the 
current process.

    import ctypes

    userenv = ctypes.WinDLL('userenv', use_last_error=True)

    def errcheck_bool(result, func, args):
        if not result:
            raise ctypes.WinError(ctypes.get_last_error())
        return args

    userenv.CreateEnvironmentBlock.argtypes = (ctypes.POINTER(ctypes.c_void_p),
                                               ctypes.c_void_p,
                                               ctypes.c_int)
    userenv.DestroyEnvironmentBlock.argtypes = (ctypes.c_void_p,)

    def get_system_environ():
        WCHAR_SIZE = ctypes.sizeof(ctypes.c_wchar)
        environ = {}
        cenv = ctypes.c_void_p()
        userenv.CreateEnvironmentBlock(ctypes.byref(cenv), None, 0)
        addr = cenv.value    
        try:
            while True:
                s = ctypes.c_wchar_p(addr).value
                if not s:
                    break
                i = s.find('=', 1)
                if i != -1:
                    environ[s[:i]] = s[i+1:]
                addr += (len(s) + 1) * WCHAR_SIZE
        finally:
            userenv.DestroyEnvironmentBlock(cenv)
        return environ

[1]: https://msdn.microsoft.com/en-us/library/aa379886
[2]: https://msdn.microsoft.com/en-us/library/bb762270

----------
nosy: +eryksun

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue1384175>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to