dkg wites: > the typesafety checks in imap-dl turn out to make imap-dl fail when > python3-gssapi is installed. In particular: > > try: > import gssapi # type: ignore > except ModuleNotFoundError: > gssapi = None > […] > class GSSAPI_handler(): > gss_vc:gssapi.SecurityContext > > > this fails when the gssapi module isn't installed. I should have caught > it earlier, sorry! > > not sure the right way to handle this while retaining the type-safety > though.
Ugh. My suggestion is to just make the class definition contingent on the library's presence. Patch for that attached. Thanks, --Robbie
signature.asc
Description: PGP signature
>From 2a6d814dbe9976e55edd152982e60d1111a6ce61 Mon Sep 17 00:00:00 2001 From: Robbie Harwood <rharw...@redhat.com> Date: Fri, 27 Mar 2020 13:46:42 -0400 Subject: [PATCH] imap-dl: Fix failure when python3-gssapi isn't installed The type annotation of the SecurityContext in GSSAPI_helper causes python to actually use the gssapi object, which is None when python3-gssapi isn't present. Work around this by making the class definition contingent on the presence of python3-gssapi. Also adjust shebang to work properly with venvs. Signed-off-by: Robbie Harwood <rharw...@redhat.com> --- imap-dl | 60 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/imap-dl b/imap-dl index 5a8494c..2052842 100755 --- a/imap-dl +++ b/imap-dl @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 # PYTHON_ARGCOMPLETE_OK # -*- coding: utf-8 -*- @@ -95,39 +95,41 @@ def auth_builtin(username:str, imap:imaplib.IMAP4_SSL, if resp[0] != 'OK': raise Exception(f'login failed with {resp} as user {username} on {server}') -# imaplib auth methods need to be in the form of callables, and they all -# requre both additional parameters and storage beyond what the function -# interface provides. -class GSSAPI_handler(): - gss_vc:gssapi.SecurityContext - username:str +if gssapi: + # imaplib auth methods need to be in the form of callables, and they all + # requre both additional parameters and storage beyond what the function + # interface provides. + class GSSAPI_handler(): + gss_vc:gssapi.SecurityContext + username:str - def __init__(self, server:str, username:str) -> None: - name = gssapi.Name(f'imap@{server}', gssapi.NameType.hostbased_service) - self.gss_vc = gssapi.SecurityContext(usage="initiate", name=name) - self.username = username + def __init__(self, server:str, username:str) -> None: + name = gssapi.Name(f'imap@{server}', + gssapi.NameType.hostbased_service) + self.gss_vc = gssapi.SecurityContext(usage="initiate", name=name) + self.username = username - def __call__(self, token:Optional[bytes]) -> bytes: - if token == b"": - token = None - if not self.gss_vc.complete: - response = self.gss_vc.step(token) - return response if response else b"" # type: ignore - elif token is None: - return b"" + def __call__(self, token:Optional[bytes]) -> bytes: + if token == b"": + token = None + if not self.gss_vc.complete: + response = self.gss_vc.step(token) + return response if response else b"" # type: ignore + elif token is None: + return b"" - response = self.gss_vc.unwrap(token) + response = self.gss_vc.unwrap(token) - # Preserve the "length" of the message we received, and set the first - # byte to one. If username is provided, it's next. - reply:List[int] = [] - reply[0:4] = response.message[0:4] - reply[0] = 1 - if self.username: - reply[5:] = self.username.encode("utf-8") + # Preserve the "length" of the message we received, and set the + # first byte to one. If username is provided, it's next. + reply:List[int] = [] + reply[0:4] = response.message[0:4] + reply[0] = 1 + if self.username: + reply[5:] = self.username.encode("utf-8") - response = self.gss_vc.wrap(bytes(reply), response.encrypted) - return response.message if response.message else b"" # type: ignore + response = self.gss_vc.wrap(bytes(reply), response.encrypted) + return response.message if response.message else b"" # type: ignore def auth_gssapi(username:str, imap:imaplib.IMAP4_SSL, conf:configparser.ConfigParser, server:str) -> None: -- 2.25.1