MIT Kerberos sname типы - PullRequest
       4

MIT Kerberos sname типы

0 голосов
/ 08 января 2020

У меня есть служба kerberos, на которую я могу попросить билет с помощью kinit и knvo. Я вижу в wireshark, что sname установлен в KRB5_NT_PRINCIPAL. Я пытаюсь сгенерировать заявку с помощью API MIT C, но не могу найти службу. Я заметил в WireShark, что разница в имени. С кодом c он отправляет sname-type как «KRB5_NT_SRV_HST» и завершается ошибкой. Я попытался установить тип service_principal на KRB5_NT_PRINCIPAL, но он все еще не работает. Запросы не выполняются в функции krb5_mk_req, которая является сообщением TGS-REQ. Вот мой код:

#include <stdio.h>
#include <krb5.h>
#include <com_err.h>
#include <string.h>
#include <unistd.h>

#define TKT_LIFETIME 30
#define NO_REPLAYCACHE

static void syslog_err(const char* tag, long code, const char*format, va_list args){
    printf("%s: %s in %s\n", tag, error_message(code), format);
}

#define check_code(err, tag)\
    if(err){\
        void (*proc)(const char*, long, const char*, va_list);\
        proc=set_com_err_hook(syslog_err);\
        com_err("ERROR: ",(err),(tag));\
        (void)set_com_err_hook(proc);\
        goto cleanup;\
    }

int main() {
    const char *username="foo@BAR";
    const char *password="foobar";
    //const char *host="foobar";

    const char kt_pathname[256] = "/etc/krb5.keytab";
    char service[256]="krbtgt";
    char host[256]="BAR";
    krb5_error_code err;
    krb5_error_code err_t;
    krb5_context context;
    krb5_auth_context auth_context = NULL;
    krb5_creds credentials;
    krb5_principal user_principal,
                    service_principal;
    krb5_verify_init_creds_opt vic_options;
    krb5_keytab keytab=NULL;
    krb5_ccache ccache;
    //char ccache_name[L_tmpnam + 8];
    char ccache_name[19]="/tmp/krb5cc_XXXXXX";
    krb5_get_init_creds_opt * gic_options;
#ifndef NO_REPLAYCACHE
    krb5_verify_init_creds_opt vic_options;
#endif
    krb5_data apreq_pkt;
    char myhostname[256],sprinc[256];
    int have_user_principal =0,
        have_service_principal=0,
        have_keytab=0,
        have_credentials=0,
        success=-1,
        ccache_retval;
    apreq_pkt.data=NULL;

    err = krb5_init_context(&context);
    check_code(err, "failed to init krb5 context");

    ccache_retval = mkstemp(&ccache_name[12]);
    if (ccache_retval == -1) printf("Error: failed to create a cache file");
    err = krb5_cc_resolve(context,ccache_name,&ccache);
    check_code(err, "fill a ccache file");

    err = krb5_parse_name(context, username, &user_principal);
    check_code(err, "parse principal name");
    have_user_principal=1;

    err = krb5_cc_initialize(context,ccache,user_principal);
    check_code(err, "initialize cc cache");

    (void) memset( (char*)&credentials, 0, sizeof(credentials));

    krb5_get_init_creds_opt_alloc(context, &gic_options); // Allocate a new initial credential options structure
    krb5_get_init_creds_opt_set_tkt_life(gic_options, TKT_LIFETIME); // Set the ticket lifetime in initial credential options

    err = krb5_get_init_creds_password(context, &credentials, user_principal,password,0,0,0,NULL,gic_options); //Get initial credentials using a password
    check_code(err, "get initial credentials")

    // at this point, we have a ticket (stored in credentials)
    err = krb5_cc_store_cred(context, ccache, &credentials); // Store credentials in a credential cache
    err_t=err;
    check_code(err, "store credentials");
    if(err_t) have_credentials=1;


    err = krb5_sname_to_principal(context,host,service,KRB5_NT_SRV_HST,&service_principal); //Generate a full principal name from a service name KRB5_NT_UNKNOWN
    check_code(err, "sname_to_principal");
    service_principal->type=KRB5_NT_PRINCIPAL;

    have_service_principal=1;

    err = krb5_kt_resolve(context,kt_pathname,&keytab); //Get a handle for a key table
    check_code(err, "kt_resolve");
    have_keytab=1;


#ifndef NO_REPLAYCACHE

    krb5_verify_init_creds_opt_init(&vic_options); //Initialize a credential verification options structure
    krb5_verify_init_creds_opt_set_ap_req_nofail(&vic_options,1); //Set whether credential verification is required
    err = krb5_verify_init_creds(context, &credentials, service_principal, keytab,0,&vic_options); //Verify initial credentials against a keytab
    check_code(err,"verify init credentials");
#else

    err = krb5_mk_req(context,&auth_context,0,service,host,NULL,ccache,&apreq_pkt);
    check_code(err, "apreq_pkt request");
    if(auth_context){
        krb5_auth_con_free(context,auth_context); //Free a krb5_auth_context structure.
        auth_context=NULL;
    }
    err = krb5_auth_con_init(context,&auth_context); //Create and initialize an authentication context
    check_code(err, "auth init");
    err = krb5_auth_con_setflags(context,auth_context,~KRB5_AUTH_CONTEXT_DO_TIME); //Set a flags field in a krb5_auth_context structure
    check_code(err, "auth set flags");
    err = krb5_rd_req(context,&auth_context,&apreq_pkt,service_principal,keytab,NULL,NULL); // This function parses, decrypts and verifies a AP-REQ message
    check_code(err, "decrypt & verify AP-REQ message");
    if(auth_context){
        krb5_auth_con_free(context,auth_context); //Free a krb5_auth_context structure.
        auth_context=NULL;
    }
#endif
    err = krb5_cc_destroy(context,ccache);
    if (err!=0)
        printf("[*] Failed to destroy kerberos context \n");
    else
        success=1;
*/


    cleanup:
    if(apreq_pkt.data)
        krb5_free_data_contents(context,&apreq_pkt); // Free the contents of a krb5_data structure and zero the data field
    if(have_keytab){
        krb5_kt_close(context,keytab);
        if (err!=0)
            printf("[*] Failed to destroy the keytab \n"); //Close a key table handle
    }

    krb5_cc_destroy(context,ccache);
    if(have_user_principal)
        krb5_free_principal(context,user_principal);
    if(have_service_principal)
        krb5_free_principal(context,service_principal);
    if(have_credentials)
        krb5_free_cred_contents(context,&credentials);
    if(context)
        krb5_free_context(context);


    return 0;
}

файлы krb5.conf как на клиенте, так и на сервере:

KDC & Client krb5.conf:
[libdefaults]
    encryption & properties
    .
    .
    .
    default_realm = TEST1.EXAMPLE.COM

[domain_realms]
    .test1.example.com = TEST1.EXAMPLE.COM
    test1.example.com = TEST1.EXAMPLE.COM
[logging]
    files configurations
    .
    .  
    .
[realms]
    TEST1.EXAMPLE.COM = {
    kdc = TEST1.EXAMPLE.COM:88
    default_domain = TEST1.EXAMPLE.COM
    admin_server=TEST1.EXAMPLE.COM
    }

, где TEST1.EXAMPLE.COM - их область (клиент и сервер & сервер приложений). IP-адрес каждого компьютера отображается в файле / etc / hosts, то есть: 192.168.xx

Спасибо!

...