在 C/C++ 中获取 Kerberos 票证

问题描述

有谁知道如何使用 C/C++ 中的 MIT krb5 API 从密钥分发中心 (KDC) 获取票证?

我已经有一个可用的 Java 客户端,它使用 GSS-API 从 KDC 获取票证(使用本地 TGT)并将其转发到 Java 服务器。

服务器使用以下逻辑接受安全上下文:

private GSSContext acceptSecurityContext(Subject serverSubject,final byte[] kerberosServiceTicket) {
 return Subject.doAs(serverSubject,(PrivilegedAction<GSSContext>) () -> {
            GSSContext gssContext;
            try {
                gssContext = manager.createContext((GSSCredential) null);
            } catch (GSSException ex) {
                LOGGER.warn("Could not create Kerberos gssContext: " + ex.getMessage(),ex);
                return null;
            }
            try {
                gssContext.acceptSecContext(kerberosServiceTicket,kerberosServiceTicket.length);
            } catch (GSSException ex) {
                LOGGER.warn("Could not accept security context: " + ex.getMessage(),ex);
                return null;
            }
            return gssContext;
        });
}

我正在尝试使用 MIT krb5 API 实现一个 C 客户端 - 类似于 Java 客户端,但我似乎无法让它工作。到目前为止,这是我的 C 客户端代码

    krb5_context context;
    krb5_ccache ccache;
    krb5_creds *outCreds = NULL;
    krb5_creds inCreds;
    int retval;
    char *principal = "...";

    retval = krb5_init_secure_context(&context);
    ...

    retval = krb5_cc_default(context,&ccache);
    ...

    memset(&inCreds,sizeof(inCreds));
    retval = krb5_parse_name(context,principal,&inCreds.server);
    ...

    retval = krb5_cc_get_principal(context,ccache,&inCreds.client);
    ...

    retval = krb5_get_credentials(context,&inCreds,&outCreds);
    ...

    // also tried using the following: krb5Ticket->enc_part.ciphertext.data
    // (maybe this is the correct way,but I should somehow decrypt it and use krb5Ticket->enc_part2 ?)
    // retval = krb5_decode_ticket(&outCreds->ticket,&krb5Ticket);
    // ...

    char *base64KerberosTicket = base64_encode(outCreds->ticket.data,strlen(outCreds->ticket.data));

    char *response = loginKerberos(base64KerberosTicket);
    ...

解决方法

经过进一步阅读后,我的方法似乎不适合我的用例。我应该直接使用 GSS-API。

以下代码段有效:

_In_reads_bytes_opt_