mongodb / winkerberos

A native Kerberos client implementation for Python on Windows
Apache License 2.0
54 stars 15 forks source link

Having confuse about usage of the winkerberos library: #85

Open jsuper opened 4 months ago

jsuper commented 4 months ago

Hello, I've encountered some issues while attempting to authenticate using the winkerberos library as a client. After reviewing the current documentation for the winkerberos library, I find myself somewhat at a loss on how to proceed.

I have set up a principal nginx/kerberos.example.com@EXAMPLE.COM on the KDC and obtained the corresponding keytab file. Could you guide me on how to properly pass parameters for authentication? I attempted to use the given example code, inputting the service as nginx/kerberos.example.com and the principal as nginx/kerberos.example.com@EXAMPLE.COM, but the execution resulted in an exception displaying garbled characters.

program output:

Traceback (most recent call last):
  File "D:\tmp\kerb5\test.py", line 50, in <module>
    authenticate_kerberos("nginx/kerberos.msxftest.com", "", "nginx/kerberos.msxftest.com@HADOOP.COM")
  File "D:\tmp\kerb5\test.py", line 21, in authenticate_kerberos
    status = kerberos.authGSSClientStep(ctx, "")
winkerberos.GSSError: SSPI: InitializeSecurityContext: �޷�Ϊ������֤��䷢����ȡ����ϵ��

example code:

import winkerberos as kerberos

def send_response_and_receive_challenge(response):
    # Your server communication code here...
    pass

def authenticate_kerberos(service, user, principal, channel_bindings=None):
    # Initialize the context object with a service principal.
    status, ctx = kerberos.authGSSClientInit(service, principal=principal)

    print("xxxxxxxxxxx", status)

    # GSSAPI is a "client goes first" SASL mechanism. Send the
    # first "response" to the server and receive its first
    # challenge.
    if channel_bindings is not None:
        status = kerberos.authGSSClientStep(ctx, "", channel_bindings=channel_bindings)
    else:
        status = kerberos.authGSSClientStep(ctx, "")
    response = kerberos.authGSSClientResponse(ctx)
    challenge = send_response_and_receive_challenge(response)

    # Keep processing challenges and sending responses until
    # authGSSClientStep reports AUTH_GSS_COMPLETE.
    while status == kerberos.AUTH_GSS_CONTINUE:
        if channel_bindings is not None:
            status = kerberos.authGSSClientStep(
                ctx, challenge, channel_bindings=channel_bindings
            )
        else:
            status = kerberos.authGSSClientStep(ctx, challenge)

        response = kerberos.authGSSClientResponse(ctx) or ""
        challenge = send_response_and_receive_challenge(response)

    # Decrypt the server's last challenge
    kerberos.authGSSClientUnwrap(ctx, challenge)
    data = kerberos.authGSSClientResponse(ctx)
    # Encrypt a response including the user principal to authorize.
    kerberos.authGSSClientWrap(ctx, data, user)
    response = kerberos.authGSSClientResponse(ctx)

    # Complete authentication.
    send_response_and_receive_challenge(response)

if __name__ == '__main__':
    authenticate_kerberos("nginx/kerberos.example.com", "", "nginx/kerberos.example.com@EXAMPLE.COM")
behackett commented 4 months ago

It's hard to say from the information you've provided what the failure is or where it's occurring. Kerberos authentication requires multiple calls to authGSSClientStep. I assume your real code is different from the example you pasted, which looks like a copy of the tutorial, so I can't tell which call fails. The error message from SSPI also isn't helpful.

I would suggest trying your code line by line in the python repl to see where the failure actually occurs. It's also worth mentioning that SSPI doesn't support keytab files. Those are for krb5.