diff -r 391cc8b60782 -r d7c0b67c807e .hgignore --- a/.hgignore Sun Dec 27 23:42:29 2015 +0800 +++ b/.hgignore Sun Dec 27 23:42:54 2015 +0800 @@ -81,6 +81,8 @@ PCbuild/amd64 PCbuild/obj PCbuild/win32 +Tools/lower_integrity_level/Debug/ +Tools/lower_integrity_level/Release/ Tools/unicode/build/ Tools/unicode/MAPPINGS/ BuildLog.htm diff -r 391cc8b60782 -r d7c0b67c807e Lib/test/support/__init__.py --- a/Lib/test/support/__init__.py Sun Dec 27 23:42:29 2015 +0800 +++ b/Lib/test/support/__init__.py Sun Dec 27 23:42:54 2015 +0800 @@ -104,7 +104,8 @@ # miscellaneous "check_warnings", "EnvironmentVarGuard", "run_with_locale", "swap_item", "swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict", - "run_with_tz", + "run_with_tz", "have_lower_integrity_level_tool", + "run_with_lower_integrity_level", ] class Error(Exception): @@ -2405,3 +2406,27 @@ "memory allocations") import _testcapi return _testcapi.run_in_subinterp(code) + + +def _get_lower_integrity_level_progname(): + ROOT_DIR = os.path.dirname( + os.path.dirname( # Lib + os.path.dirname( # test + os.path.dirname(__file__)))) # support + return os.path.join(ROOT_DIR, 'Tools', 'lower_integrity_level', + os.environ.get('conf', 'Release'), # Set in rt.bat + 'lower_integrity_level.exe') + + +def have_lower_integrity_level_tool(): + if not sys.platform.startswith("win") or sys.getwindowsversion().major < 6: + return False + + return os.path.exists(_get_lower_integrity_level_progname()) + + +def run_with_lower_integrity_level(code): + ret = subprocess.Popen([_get_lower_integrity_level_progname(), + sys.executable, '-c', code], + stdout=subprocess.PIPE).communicate()[0] + return ret diff -r 391cc8b60782 -r d7c0b67c807e Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py Sun Dec 27 23:42:29 2015 +0800 +++ b/Lib/test/test_ssl.py Sun Dec 27 23:42:54 2015 +0800 @@ -18,6 +18,7 @@ import weakref import platform import functools +import pickle ssl = support.import_module("ssl") @@ -624,6 +625,23 @@ self.assertIsInstance(element[0], bytes) self.assertIn(element[1], {"x509_asn", "pkcs_7_asn"}) + @unittest.skipUnless(support.have_lower_integrity_level_tool(), "not Windows Vista or above or lower_integrity_level.exe missing") + def test_enum_certificates_with_low_integrity(self): + for storename in ("CA", "ROOT"): + result = pickle.loads(support.run_with_lower_integrity_level(""" +import sys, ssl, pickle +pickle.dump(ssl.enum_certificates('%s'), sys.stdout.buffer) + """ % storename)) + self.assertCountEqual(result, ssl.enum_certificates(storename)) + + @unittest.skipUnless(support.have_lower_integrity_level_tool(), "not Windows Vista or above or lower_integrity_level.exe missing") + def test_enum_crls_with_low_integrity(self): + for storename in ("CA", "ROOT"): + result = pickle.loads(support.run_with_lower_integrity_level(""" +import sys, ssl, pickle +pickle.dump(ssl.enum_crls('%s'), sys.stdout.buffer) + """ % storename)) + self.assertCountEqual(result, ssl.enum_crls(storename)) def test_asn1object(self): expected = (129, 'serverAuth', 'TLS Web Server Authentication', diff -r 391cc8b60782 -r d7c0b67c807e PCbuild/build.bat --- a/PCbuild/build.bat Sun Dec 27 23:42:29 2015 +0800 +++ b/PCbuild/build.bat Sun Dec 27 23:42:54 2015 +0800 @@ -25,6 +25,7 @@ echo. -v Increased output messages echo. -k Attempt to kill any running Pythons before building (usually done echo. automatically by the pythoncore project) +echo. --build-testing-tools Also build tools for testing echo. echo.Available flags to avoid building certain modules. echo.These flags have no effect if '-e' is not given: @@ -51,6 +52,7 @@ set parallel=/m set verbose=/nologo /v:m set kill= +set build_testing_tools= :CheckOpts if "%~1"=="-h" goto Usage @@ -65,6 +67,7 @@ if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts if "%~1"=="--test-marker" (set UseTestMarker=true) & shift & goto CheckOpts if "%~1"=="-V" shift & goto Version +if "%~1"=="--build-testing-tools" (set build_testing_tools=true) & shift & goto CheckOpts rem These use the actual property names used by MSBuild. We could just let rem them in through the environment, but we specify them on the command line rem anyway for visibility so set defaults after this @@ -98,6 +101,10 @@ /p:UseTestMarker=%UseTestMarker%^ %1 %2 %3 %4 %5 %6 %7 %8 %9 +if "%build_testing_tools%"=="true" ( + msbuild /v:m "%dir%\..\Tools\lower_integrity_level\lower_integrity_level.vcxproj" /p:Configuration=%conf% /p:Platform=%platf% +) + @goto :eof :Version diff -r 391cc8b60782 -r d7c0b67c807e PCbuild/rt.bat --- a/PCbuild/rt.bat Sun Dec 27 23:42:29 2015 +0800 +++ b/PCbuild/rt.bat Sun Dec 27 23:42:54 2015 +0800 @@ -33,11 +33,12 @@ set qmode= set dashO= set regrtestargs= +set conf=Release :CheckOpts if "%1"=="-O" (set dashO=-O) & shift & goto CheckOpts if "%1"=="-q" (set qmode=yes) & shift & goto CheckOpts -if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts +if "%1"=="-d" (set suffix=_d & set conf=Debug) & shift & goto CheckOpts if "%1"=="-x64" (set prefix=%pcbuild%amd64\) & shift & goto CheckOpts if NOT "%1"=="" (set regrtestargs=%regrtestargs% %1) & shift & goto CheckOpts diff -r 391cc8b60782 -r d7c0b67c807e Tools/lower_integrity_level/lower_integrity_level.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/lower_integrity_level/lower_integrity_level.c Sun Dec 27 23:42:54 2015 +0800 @@ -0,0 +1,148 @@ +#include +#include +#include +#include +#include + +#pragma comment(lib, "shlwapi.lib") + +BOOL CreateLowProcess(LPTSTR szCommandLine) +{ + + BOOL fRet; + HANDLE hToken = NULL; + HANDLE hNewToken = NULL; + PSID pIntegritySid = NULL; + TOKEN_MANDATORY_LABEL TIL = {0}; + PROCESS_INFORMATION ProcInfo = {0}; + STARTUPINFO StartupInfo = {0}; + DWORD dwExitCode = -1; + + // Low integrity SID + _TCHAR szIntegritySid[20] = _T("S-1-16-4096"); + + fRet = OpenProcessToken(GetCurrentProcess(), + TOKEN_DUPLICATE | + TOKEN_ADJUST_DEFAULT | + TOKEN_QUERY | + TOKEN_ASSIGN_PRIMARY, + &hToken); + + if (!fRet) + { + fprintf (stderr, "OpenProcessToken() failed with error %d\n", GetLastError()); + goto CleanExit; + } + + fRet = DuplicateTokenEx(hToken, + 0, + NULL, + SecurityImpersonation, + TokenPrimary, + &hNewToken); + + if (!fRet) + { + fprintf (stderr, "DuplicateTokenEx() failed with error %d\n", GetLastError()); + goto CleanExit; + } + + fRet = ConvertStringSidToSid(szIntegritySid, &pIntegritySid); + + if (!fRet) + { + fprintf (stderr, "ConvertStringSidToSid() failed with error %d\n", GetLastError()); + goto CleanExit; + } + + TIL.Label.Attributes = SE_GROUP_INTEGRITY; + TIL.Label.Sid = pIntegritySid; + + // + // Set the process integrity level + // + + fRet = SetTokenInformation(hNewToken, + TokenIntegrityLevel, + &TIL, + sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid)); + + if (!fRet) + { + fprintf (stderr, "SetTokenInformation() failed with error %d\n", GetLastError()); + goto CleanExit; + } + + // + // Create the new process at Low integrity + // + + fRet = CreateProcessAsUser(hNewToken, + NULL, + szCommandLine, + NULL, + NULL, + FALSE, + 0, + NULL, + NULL, + &StartupInfo, + &ProcInfo); + + if (!fRet) + { + fprintf (stderr, "CreateProcessAsUser() failed with error %d\n", GetLastError()); + goto CleanExit; + } + + if (WaitForSingleObject(ProcInfo.hProcess, INFINITE)) + { + fprintf (stderr, "WaitForSingleObject() failed with error %d\n", GetLastError()); + goto CleanExit; + } + + fRet = GetExitCodeProcess(ProcInfo.hProcess, &dwExitCode); + + if (!fRet) + { + fprintf (stderr, "GetExitCodeProcess() failed with error %d\n", GetLastError()); + } + +CleanExit: + + if (ProcInfo.hProcess != NULL) + { + CloseHandle(ProcInfo.hProcess); + } + + if (ProcInfo.hThread != NULL) + { + CloseHandle(ProcInfo.hThread); + } + + LocalFree(pIntegritySid); + + if (hNewToken != NULL) + { + CloseHandle(hNewToken); + } + + if (hToken != NULL) + { + CloseHandle(hToken); + } + + return fRet; +} + +int _tmain(int argc, _TCHAR* argv[]) +{ + if (argc == 1) + { + _tprintf(_T("Usage: %s [command line of the target program]"), argv[0]); + return 1; + } + + LPTSTR cmd_pos = StrStr(GetCommandLine(), argv[1]); + return CreateLowProcess(cmd_pos); +} diff -r 391cc8b60782 -r d7c0b67c807e Tools/lower_integrity_level/lower_integrity_level.vcxproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/lower_integrity_level/lower_integrity_level.vcxproj Sun Dec 27 23:42:54 2015 +0800 @@ -0,0 +1,118 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {581E0EE8-E4C7-4A11-A59D-7E88BC4F6AA2} + lower_integrity_level + 8.1 + + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + + + + + Level3 + Disabled + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + + + + + \ No newline at end of file