Skip to content

Commit

Permalink
GSSAPI support for IMAP
Browse files Browse the repository at this point in the history
Adapted from code snippet by Yves Fischer.
https://gist.github.com/yvesf/7cc8300176df8322c913
  • Loading branch information
tukss committed Oct 18, 2022
1 parent 29f78b3 commit 16b322d
Showing 1 changed file with 42 additions and 1 deletion.
43 changes: 42 additions & 1 deletion i3pystatus/mail/imap.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import contextlib
import time
import socket
import base64
from threading import Thread

from i3pystatus.mail import Backend
Expand All @@ -17,6 +18,41 @@
IMAP_EXCEPTIONS = (socket.error, socket.gaierror, IMAP4.abort, IMAP4.error)


class IMAPGSSMixin(object):
def gss_cb(self,challenge):
import kerberos
input_token = base64.b64encode(challenge).decode('utf-8')

if self.step == 0:
ret = kerberos.authGSSClientStep(self._gss_context, input_token)
if ret != kerberos.AUTH_GSS_CONTINUE:
self.step = 1
elif self.step == 1:
ret = kerberos.authGSSClientUnwrap(self._gss_context, input_token)
response = kerberos.authGSSClientResponse(self._gss_context)
ret = kerberos.authGSSClientWrap(self._gss_context, response, self.user)
response = kerberos.authGSSClientResponse(self._gss_context)

if response is None:
return ""
else:
return base64.b64decode(response)

def login_gssapi(self, user):
import kerberos
self.user = user
self.step = 0
_unused, self._gss_context = kerberos.authGSSClientInit("imap@{}".format(self.host))
return self.authenticate(b"GSSAPI", self.gss_cb)


class IMAP4_SSL(IMAP4_SSL, IMAPGSSMixin):
pass

class IMAP4(IMAP4, IMAPGSSMixin):
pass


class IMAP(Backend):
"""
Checks for mail on a IMAP server
Expand All @@ -27,6 +63,7 @@ class IMAP(Backend):
"username", "password",
('keyring_backend', 'alternative keyring backend for retrieving credentials'),
"ssl",
"gssapi",
"mailbox",
)
required = ("host", "username", "password")
Expand All @@ -35,6 +72,7 @@ class IMAP(Backend):
port = 993
ssl = True
mailbox = "INBOX"
gssapi = False

imap_class = IMAP4
connection = None
Expand All @@ -56,7 +94,10 @@ def ensure_connection(self):
self.connection.select(self.mailbox)
if not self.connection:
self.connection = self.imap_class(self.host, self.port)
self.connection.login(self.username, self.password)
if self.gssapi:
self.connection.login_gssapi(self.username)
else:
self.connection.login(self.username, self.password)
self.connection.select(self.mailbox)
yield
except IMAP_EXCEPTIONS:
Expand Down

0 comments on commit 16b322d

Please sign in to comment.