The pymssql
module claims to support Kerberos Authentication (and delegation) and yet I can't seem to enable it.
The client I am running is on Windows. I need to connect with a double-hop through a reverse database proxy. The client, the proxy, and the database are all part of the domain. And when I try to connect with SQL Server Manager I am successful. But when I try to connect with the pymssql
module in Python it doesn't work. If I connect directly from the client to the database I am able to get the Kerberos Authentication to work. But again, when I try to go through the proxy it fails.
This leads me to believe that the Kerberos Authentication works, but that the Delegation (double-hop) does not.
According to the section on FreeTDS I should be able to create a file at C:/freetds.conf
and it should read connection information from there. I don't seem to be able to verify this in any meaningful way. Additionally, according to the freetds schema I should be able add a parameter enable gssapi delegation
which when enabled (off by default) allows Kerberos Delegation.
Bottom Line: I am looking to enable Kerberos Delegation (so that the double-hop will work) for pymssql on windows.
At the moment I have created a file at C:/freetds.conf
and have tried a few ways to configure it.
[global]
enable gssapi delegation = on
and
[global]
enable gssapi delegation = true
This is pretty easy to answer and is rooted in a shortcoming in FreeTDS. You did nothing wrong.
If we take a look at the GSS-API C code of FreeTDS, we see in lines 307 to 308
if (tds->login->gssapi_use_delegation)
gssapi_flags |= GSS_C_DELEG_FLAG;
that your config parameter is read in the delegation flag is set.
Since you are on Windows and Windows uses its own flavor of GSS-API, namely SSPI, we have a look at that C code: lines 273 to 278 do
status = sec_fn->InitializeSecurityContext(&auth->cred, NULL, auth->sname,
ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT
| ISC_REQ_CONNECTION | ISC_REQ_ALLOCATE_MEMORY,
0, SECURITY_NETWORK_DREP,NULL, 0, &auth->cred_ctx, &desc, &attrs, &ts);
as you can see, the context flags are not in a variable but passed directly. Neither the config param is evaluated nor ISC_REQ_DELEGATE
is passed.
This is the problem you are seeing. You have two options now:
Side note: there is several stuff I do not like about both code parts at all:
ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT
and GSS_C_REPLAY_FLAG | GSS_C_INTEG_FLAG
. There are only necessary if you require further transport security which is not employed here.I highly recommend to raise some issues here too.