-
Notifications
You must be signed in to change notification settings - Fork 423
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into pre-commit-ci-update-config
- Loading branch information
Showing
7 changed files
with
117 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
### Enhancements | ||
|
||
* For Windows users, the stub executables used for Python entrypoints in packages are now codesigned. (#5252) | ||
|
||
### Bug fixes | ||
|
||
* <news item> | ||
|
||
### Deprecations | ||
|
||
* <news item> | ||
|
||
### Docs | ||
|
||
* <news item> | ||
|
||
### Other | ||
|
||
* <news item> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# Copyright (C) 2014 Anaconda, Inc | ||
# SPDX-License-Identifier: BSD-3-Clause | ||
from __future__ import annotations | ||
|
||
import os | ||
from functools import lru_cache | ||
from pathlib import Path | ||
from shutil import which | ||
from subprocess import CalledProcessError, check_output, run | ||
|
||
import pytest | ||
|
||
from conda_build.utils import on_win | ||
|
||
HERE = os.path.abspath(os.path.dirname(__file__)) | ||
REPO_ROOT = (Path(HERE) / "..").resolve().absolute() | ||
STUB_FOLDER = REPO_ROOT / "conda_build" | ||
|
||
|
||
@lru_cache(maxsize=None) | ||
def find_signtool() -> str | None: | ||
"""Tries to find signtool | ||
Prefers signtool on PATH otherwise searches system. | ||
Ref: | ||
- https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe | ||
- https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool | ||
- https://learn.microsoft.com/en-us/windows/win32/seccrypto/using-signtool-to-verify-a-file-signature | ||
""" | ||
signtool_path = which("signtool") | ||
if signtool_path: | ||
return signtool_path | ||
|
||
# Common installation directories where signtool might be located | ||
common_paths = [ | ||
"C:\\Program Files (x86)\\Windows Kits\\10\\bin", | ||
"C:\\Program Files\\Windows Kits\\10\\bin", | ||
"C:\\Windows\\System32", | ||
] | ||
|
||
signtool_path = None | ||
# Search for signtool in common paths | ||
for path in common_paths: | ||
if signtool_path: | ||
# We found one already | ||
return signtool_path | ||
if not os.path.exists(path): | ||
continue | ||
signtool_path = os.path.join(path, "signtool.exe") | ||
if os.path.exists(signtool_path): | ||
return signtool_path | ||
elif "Windows Kits" in path: | ||
signtool_path = None | ||
max_version = 0 | ||
for dirname in os.listdir(path): | ||
# Use most recent signtool version | ||
if not dirname.endswith(".0"): | ||
continue # next dirname | ||
if int(dirname.replace(".", "")) < max_version: | ||
continue # next dirname | ||
|
||
maybe_signtool_path = os.path.join(path, dirname, "x64", "signtool.exe") | ||
if os.path.exists(maybe_signtool_path): | ||
signtool_path = maybe_signtool_path | ||
return signtool_path | ||
|
||
|
||
@lru_cache(maxsize=None) | ||
def signtool_unsupported_because() -> str: | ||
reason = "" | ||
if not on_win: | ||
reason = "Only verifying signatures of stub exe's on windows" | ||
return reason | ||
signtool = find_signtool() | ||
if not signtool: | ||
reason = "signtool: unable to locate signtool.exe" | ||
try: | ||
check_output([signtool, "verify", "/?"]) | ||
except CalledProcessError as exc: | ||
reason = f"signtool: something went wrong while running 'signtool verify /?', output:\n{exc.output}\n" | ||
return reason | ||
|
||
|
||
def signtool_unsupported() -> bool: | ||
return bool(signtool_unsupported_because()) | ||
|
||
|
||
@pytest.mark.skipif(signtool_unsupported(), reason=signtool_unsupported_because()) | ||
@pytest.mark.parametrize( | ||
"stub_file_name", ["cli-32.exe", "cli-64.exe", "gui-32.exe", "gui-64.exe"] | ||
) | ||
def test_stub_exe_signatures(stub_file_name: str) -> None: | ||
"""Verify that signtool verifies the signature of the stub exes""" | ||
stub_file = STUB_FOLDER / stub_file_name | ||
signtool_exe = find_signtool() | ||
completed_process = run([signtool_exe, "verify", "/pa", "/v", stub_file]) | ||
assert completed_process.returncode == 0 |