Skip to content

Commit 01a0ec6

Browse files
committed
Add gssapi support
1 parent 4d14a51 commit 01a0ec6

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

setup.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,12 @@ dbt =
5050
dbt-singlestore
5151
ed22519 =
5252
PyNaCl>=1.4.0
53+
gssapi =
54+
gssapi
5355
ibis =
5456
ibis-singlestoredb
57+
kerberos =
58+
gssapi
5559
rsa =
5660
cryptography
5761
sqlalchemy =

singlestoredb/mysql/_auth.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
"""
33
Implements auth methods
44
"""
5-
from .err import OperationalError
5+
import getpass
66

7+
from .err import OperationalError
78

89
try:
910
from cryptography.hazmat.backends import default_backend
@@ -273,3 +274,28 @@ def caching_sha2_password_auth(conn, pkt):
273274

274275
data = sha2_rsa_encrypt(conn.password, conn.salt, conn.server_public_key)
275276
pkt = _roundtrip(conn, data)
277+
278+
279+
def gssapi_auth(user):
280+
try:
281+
import gssapi.raw
282+
except ImportError:
283+
raise ImportError(
284+
'The `gssapi` package must be '
285+
'installed for Kerberos authentication',
286+
)
287+
288+
if not user:
289+
user = getpass.getuser()
290+
291+
ctx = None
292+
try:
293+
ctx = gssapi.raw.init_sec_context(
294+
gssapi.raw.import_name(user, gssapi.raw.NameType.user),
295+
flags=[0], lifetime=0,
296+
)
297+
return ctx.token
298+
299+
finally:
300+
if ctx is not None:
301+
gssapi.raw.delete_sec_context(ctx.context)

singlestoredb/mysql/connection.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,9 @@ def _request_authentication(self): # noqa: C901
11111111
authresp = b'\1' # request public key
11121112
else:
11131113
authresp = b'\0' # empty password
1114+
elif self._auth_plugin_name == b'auth_gssapi_client':
1115+
plugin_name = b'auth_gssapi_client'
1116+
authresp = _auth.gssapi_auth(self.user)
11141117

11151118
if self.server_capabilities & CLIENT.PLUGIN_AUTH_LENENC_CLIENT_DATA:
11161119
data += _lenenc_int(len(authresp)) + authresp
@@ -1199,6 +1202,8 @@ def _process_auth(self, plugin_name, auth_packet):
11991202
elif plugin_name == b'mysql_clear_password':
12001203
# https://dev.mysql.com/doc/internals/en/clear-text-authentication.html
12011204
data = self.password + b'\0'
1205+
elif plugin_name == b'auth_gssapi_client':
1206+
data = _auth.gssapi_auth(self.user)
12021207
elif plugin_name == b'dialog':
12031208
pkt = auth_packet
12041209
while True:

0 commit comments

Comments
 (0)