From 3cb0c75d4c11d73e439f7644bf0a3ba77b695c33 Mon Sep 17 00:00:00 2001 From: Roger Aiudi Date: Tue, 24 Mar 2020 16:29:33 -0400 Subject: [PATCH] Configure Windows at import time [rharwood@redhat.com: Squash commits] Merges: #194 --- gssapi/__init__.py | 2 ++ gssapi/_win_config.py | 56 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 gssapi/_win_config.py diff --git a/gssapi/__init__.py b/gssapi/__init__.py index 4d6eba43..cb89f73f 100644 --- a/gssapi/__init__.py +++ b/gssapi/__init__.py @@ -26,6 +26,8 @@ low-level API functions. """ +import gssapi._win_config # noqa + from gssapi.raw.types import NameType, RequirementFlag, AddressType # noqa from gssapi.raw.types import MechType, IntEnumFlagSet # noqa from gssapi.raw.oids import OID # noqa diff --git a/gssapi/_win_config.py b/gssapi/_win_config.py new file mode 100644 index 00000000..bf95e07e --- /dev/null +++ b/gssapi/_win_config.py @@ -0,0 +1,56 @@ +""" +Using GSSAPI on Windows requires having an installation of Kerberos for Windows +(KfW) available in the user's PATH. This module should be imported before +anything else to check for that installation, add it to the PATH if necessary, +and throw any errors before they manifest as cryptic missing DLL errors later +down the import tree. +""" + +import os +import ctypes + +#: Path to normal KfW installed bin folder +KFW_BIN = os.path.join( + os.environ.get('ProgramFiles', r'C:\Program Files'), + 'MIT', 'Kerberos', 'bin', +) +#: Download location for KfW +KFW_DL = "https://web.mit.edu/KERBEROS/dist" + + +def k4w_in_path(): + """Return if the main GSSAPI DLL for KfW is available in the PATH""" + try: # to load the main GSSAPI DLL + ctypes.WinDLL('gssapi64.dll') + except OSError: # DLL is not in PATH + return False + else: # DLL is in PATH, everything should work + return True + + +def error_not_found(): + """Raise an OSError detailing that KfW is missing and how to get it""" + raise OSError( + "Could not find KfW installation. Please download and install " + "the 64bit Kerberos for Windows MSI from %s and ensure the " + "'bin' folder (%s) is in your PATH." + % (KFW_DL, KFW_BIN) + ) + + +def configure_windows(): + """ + Validate that KfW appears to be installed correctly and add it to the + PATH if necessary. In the case that it can't be located, raise an error. + """ + if k4w_in_path(): + return # All set, necessary DLLs should be available + if os.path.exists(KFW_BIN): # In standard location + os.environ['PATH'] += os.pathsep + KFW_BIN + if k4w_in_path(): + return + error_not_found() + + +if os.name == 'nt': # Make sure we have the required DLLs + configure_windows()