Exemplo n.º 1
0
long
not_an_API_LeashKRB5GetTickets(TICKETINFO *ticketinfo,
                               krb5_context *krbv5Context)
{
    krb5_error_code code;
    krb5_principal me = 0;
    krb5_context ctx = 0;
    krb5_ccache cache = 0;
    char *PrincipalName = NULL;

    code = Leash_krb5_initialize(krbv5Context);
    if (code)
        return code;

    ctx = *krbv5Context;

    // @TEMP fixme; shouldn't be necessary
    // save default principal name in ticketinfo
    if (ticketinfo != NULL) {
        ticketinfo->btickets = NO_TICKETS;
        ticketinfo->principal = NULL;
        ticketinfo->ccache_name = NULL;
        ticketinfo->next = NULL;
        ticketinfo->ticket_list = NULL;

        code = pkrb5_cc_default(ctx, &cache);
        if (code)
            goto cleanup;
        ticketinfo->ccache_name = strdup(pkrb5_cc_get_name(ctx, cache));
        if (ticketinfo->ccache_name == NULL) {
            code = ENOMEM;
            goto cleanup;
        }
        if (!pkrb5_cc_get_principal(ctx, cache, &me)) {
            code = (*pkrb5_unparse_name)(ctx, me, &PrincipalName);
            if (code)
                goto cleanup;
            if (PrincipalName) {
                ticketinfo->principal = strdup(PrincipalName);
                pkrb5_free_unparsed_name(ctx, PrincipalName);
            }
        }
    }

    do_all_ccaches(*krbv5Context, &ticketinfo->next);
    // @TEMP aggregate ticket info here?

cleanup:
    if (code)
        not_an_API_LeashKRB5FreeTickets(ticketinfo);
    if (cache)
        pkrb5_cc_close(ctx, cache);
    if (me)
        pkrb5_free_principal(ctx, me);
    return code;
}
Exemplo n.º 2
0
int
Leash_krb5_kinit(
krb5_context alt_ctx,
HWND hParent,
char *principal_name,
char *password,
krb5_deltat lifetime,
DWORD                       forwardable,
DWORD                       proxiable,
krb5_deltat                 renew_life,
DWORD                       addressless,
DWORD                       publicIP
)
{
#ifdef NO_KRB5
    return(0);
#else
    krb5_error_code		        code = 0;
    krb5_context		        ctx = 0;
    krb5_ccache			        cc = 0, defcache = 0;
    krb5_principal		        me = 0;
    char*                       name = 0;
    krb5_creds			        my_creds;
    krb5_get_init_creds_opt *   options = NULL;
    krb5_address **             addrs = NULL;
    int                         i = 0, addr_count = 0;
    int                         cc_new = 0;
    const char *                deftype = NULL;

    if (!pkrb5_init_context)
        return 0;

    memset(&my_creds, 0, sizeof(my_creds));

    if (alt_ctx)
    {
        ctx = alt_ctx;
    }
    else
    {
        code = pkrb5_init_context(&ctx);
        if (code) goto cleanup;
    }

    code = pkrb5_get_init_creds_opt_alloc(ctx, &options);
    if (code) goto cleanup;

    code = pkrb5_cc_default(ctx, &defcache);
    if (code) goto cleanup;

    code = pkrb5_parse_name(ctx, principal_name, &me);
    if (code) goto cleanup;

    deftype = pkrb5_cc_get_type(ctx, defcache);
    if (me != NULL && pkrb5_cc_support_switch(ctx, deftype)) {
        /* Use an existing cache for the specified principal if we can. */
        code = pkrb5_cc_cache_match(ctx, me, &cc);
        if (code != 0 && code != KRB5_CC_NOTFOUND)
            goto cleanup;
        if (code == KRB5_CC_NOTFOUND) {
            code = pkrb5_cc_new_unique(ctx, deftype, NULL, &cc);
            if (code)
                goto cleanup;
            cc_new = 1;
        }
        pkrb5_cc_close(ctx, defcache);
    } else {
        cc = defcache;
    }

    code = pkrb5_unparse_name(ctx, me, &name);
    if (code) goto cleanup;

    if (lifetime == 0)
        lifetime = Leash_get_default_lifetime();
    else
        lifetime *= 5*60;

	if (renew_life > 0)
		renew_life *= 5*60;

    if (lifetime)
        pkrb5_get_init_creds_opt_set_tkt_life(options, lifetime);
	pkrb5_get_init_creds_opt_set_forwardable(options,
                                             forwardable ? 1 : 0);
	pkrb5_get_init_creds_opt_set_proxiable(options,
                                           proxiable ? 1 : 0);
	pkrb5_get_init_creds_opt_set_renew_life(options,
                                            renew_life);
    if (addressless)
        pkrb5_get_init_creds_opt_set_address_list(options,NULL);
    else {
		if (publicIP)
        {
            // we are going to add the public IP address specified by the user
            // to the list provided by the operating system
            krb5_address ** local_addrs=NULL;
            DWORD           netIPAddr;

            pkrb5_os_localaddr(ctx, &local_addrs);
            while ( local_addrs[i++] );
            addr_count = i + 1;

            addrs = (krb5_address **) malloc((addr_count+1) * sizeof(krb5_address *));
            if ( !addrs ) {
                pkrb5_free_addresses(ctx, local_addrs);
                assert(0);
            }
            memset(addrs, 0, sizeof(krb5_address *) * (addr_count+1));
            i = 0;
            while ( local_addrs[i] ) {
                addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
                if (addrs[i] == NULL) {
                    pkrb5_free_addresses(ctx, local_addrs);
                    assert(0);
                }

                addrs[i]->magic = local_addrs[i]->magic;
                addrs[i]->addrtype = local_addrs[i]->addrtype;
                addrs[i]->length = local_addrs[i]->length;
                addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
                if (!addrs[i]->contents) {
                    pkrb5_free_addresses(ctx, local_addrs);
                    assert(0);
                }

                memcpy(addrs[i]->contents,local_addrs[i]->contents,
                        local_addrs[i]->length);        /* safe */
                i++;
            }
            pkrb5_free_addresses(ctx, local_addrs);

            addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
            if (addrs[i] == NULL)
                assert(0);

            addrs[i]->magic = KV5M_ADDRESS;
            addrs[i]->addrtype = AF_INET;
            addrs[i]->length = 4;
            addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
            if (!addrs[i]->contents)
                assert(0);

            netIPAddr = htonl(publicIP);
            memcpy(addrs[i]->contents,&netIPAddr,4);

            pkrb5_get_init_creds_opt_set_address_list(options,addrs);

        }
    }

    code = pkrb5_get_init_creds_opt_set_out_ccache(ctx, options, cc);
    if (code)
        goto cleanup;

    code = pkrb5_get_init_creds_password(ctx,
                                       &my_creds,
                                       me,
                                       password, // password
                                       leash_krb5_prompter, // prompter
                                       hParent, // prompter data
                                       0, // start time
                                       0, // service name
                                       options);
    // @TODO: make this an option
    if ((!code) && (cc != defcache)) {
        code = pkrb5_cc_switch(ctx, cc);
        if (!code) {
            const char *cctype = pkrb5_cc_get_type(ctx, cc);
            if (cctype != NULL) {
                char defname[20];
                sprintf_s(defname, sizeof(defname), "%s:", cctype);
                pkrb5int_cc_user_set_default_name(ctx, defname);
            }
        }
    }
 cleanup:
    if (code && cc_new) {
        // don't leave newly-generated empty ccache lying around on failure
        pkrb5_cc_destroy(ctx, cc);
        cc = NULL;
    }
    if ( addrs ) {
        for ( i=0;i<addr_count;i++ ) {
            if ( addrs[i] ) {
                if ( addrs[i]->contents )
                    free(addrs[i]->contents);
                free(addrs[i]);
            }
        }
    }
    if (my_creds.client == me)
	my_creds.client = 0;
    pkrb5_free_cred_contents(ctx, &my_creds);
    if (name)
	pkrb5_free_unparsed_name(ctx, name);
    if (me)
	pkrb5_free_principal(ctx, me);
    if (cc)
	pkrb5_cc_close(ctx, cc);
    if (options)
        pkrb5_get_init_creds_opt_free(ctx, options);
    if (ctx && (ctx != alt_ctx))
	pkrb5_free_context(ctx);
    return(code);
#endif //!NO_KRB5
}
Exemplo n.º 3
0
int
do_ccache(krb5_context ctx,
          krb5_ccache cache,
          TICKETINFO ***ticketInfoTail)
{
    krb5_cc_cursor cur;
    krb5_creds creds;
    krb5_principal princ = NULL;
    krb5_flags flags;
    krb5_error_code code;
    char *defname = NULL;
    char *functionName = NULL;
    TicketList **ticketListTail;
    TICKETINFO *ticketinfo;

    flags = 0;                          /* turns off OPENCLOSE mode */
    code = pkrb5_cc_set_flags(ctx, cache, flags);
    if (code) {
        functionName = "krb5_cc_set_flags";
        goto cleanup;
    }
    code = pkrb5_cc_get_principal(ctx, cache, &princ);
    if (code) {
        functionName = "krb5_cc_get_principal";
        goto cleanup;
    }
    code = pkrb5_unparse_name(ctx, princ, &defname);
    if (code) {
        functionName = "krb5_unparse_name";
        goto cleanup;
    }
    code = pkrb5_cc_start_seq_get(ctx, cache, &cur);
    if (code) {
        functionName = "krb5_cc_start_seq_get";
        goto cleanup;
    }

    ticketinfo = calloc(1, sizeof(TICKETINFO));
    if (ticketinfo == NULL) {
        functionName = "calloc";
        code = ENOMEM;
        goto cleanup;
    }
    ticketinfo->next = NULL;
    ticketinfo->ticket_list = NULL;
    ticketinfo->principal = strdup(defname);
    if (ticketinfo->principal == NULL) {
        functionName = "strdup";
        code = ENOMEM;
        goto cleanup;
    }
    ticketinfo->ccache_name = strdup(pkrb5_cc_get_name(ctx, cache));
    if (ticketinfo->ccache_name == NULL) {
        functionName = "strdup";
        code = ENOMEM;
        goto cleanup;
    }
    **ticketInfoTail = ticketinfo;
    *ticketInfoTail = &ticketinfo->next;
    ticketListTail = &ticketinfo->ticket_list;
    while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) {
        if (pkrb5_is_config_principal(ctx, creds.server))
            continue;
        CredToTicketList(ctx, creds, defname, &ticketListTail);
        CredToTicketInfo(creds, ticketinfo);
        pkrb5_free_cred_contents(ctx, &creds);
    }
    if (code == KRB5_CC_END) {
        code = pkrb5_cc_end_seq_get(ctx, cache, &cur);
        if (code) {
            functionName = "krb5_cc_end_seq_get";
            goto cleanup;
        }
        flags = KRB5_TC_OPENCLOSE;      /* turns on OPENCLOSE mode */
        code = pkrb5_cc_set_flags(ctx, cache, flags);
        if (code) {
            functionName = "krb5_cc_set_flags";
            goto cleanup;
        }
    } else {
        functionName = "krb5_cc_next_cred";
        goto cleanup;
    }
cleanup:
    if (code) {
        Leash_krb5_error(code, functionName, 0, NULL, NULL);
    }
    if (princ)
        pkrb5_free_principal(ctx, princ);
    if (defname)
        pkrb5_free_unparsed_name(ctx, defname);
    return code ? 1 : 0;
}
Exemplo n.º 4
0
khm_int32 KHMAPI
khm_get_identity_expiration_time(krb5_context ctx, krb5_ccache cc, 
                                 khm_handle ident, 
                                 krb5_timestamp * pexpiration)
{
    krb5_principal principal = 0;
    char * princ_name = NULL;
    krb5_creds creds;
    krb5_error_code code;
    krb5_error_code cc_code;
    krb5_cc_cursor cur;
    krb5_timestamp now, expiration = 0;

    wchar_t w_ident_name[KCDB_IDENT_MAXCCH_NAME];
    char    ident_name[KCDB_IDENT_MAXCCH_NAME];
    khm_size cb;

    khm_int32 rv = KHM_ERROR_NOT_FOUND;

    if (!ctx || !cc || !ident || !pexpiration)
        return KHM_ERROR_GENERAL;

    code = pkrb5_cc_get_principal(ctx, cc, &principal);

    if ( code )
        return KHM_ERROR_INVALID_PARAM;

    cb = sizeof(w_ident_name);
    kcdb_identity_get_name(ident, w_ident_name, &cb);
    UnicodeStrToAnsi(ident_name, sizeof(ident_name), w_ident_name);

    code = pkrb5_unparse_name(ctx, principal, &princ_name);

    /* compare principal to ident. */

    if ( code || !princ_name ||
         strcmp(princ_name, ident_name) ) {
        if (princ_name)
            pkrb5_free_unparsed_name(ctx, princ_name);
        pkrb5_free_principal(ctx, principal);
        return KHM_ERROR_UNKNOWN;
    }

    pkrb5_free_unparsed_name(ctx, princ_name);
    pkrb5_free_principal(ctx, principal);

    code = pkrb5_timeofday(ctx, &now);

    if (code)
        return KHM_ERROR_UNKNOWN;

    cc_code = pkrb5_cc_start_seq_get(ctx, cc, &cur);

    while (!(cc_code = pkrb5_cc_next_cred(ctx, cc, &cur, &creds))) {
        krb5_data * c0 = krb5_princ_name(ctx, creds.server);
        krb5_data * c1  = krb5_princ_component(ctx, creds.server, 1);
        krb5_data * r = krb5_princ_realm(ctx, creds.server);

        if ( c0 && c1 && r && c1->length == r->length && 
             !strncmp(c1->data,r->data,r->length) &&
             !strncmp("krbtgt",c0->data,c0->length) ) {

            /* we have a TGT, check for the expiration time.
             * if it is valid and renewable, use the renew time 
             */

            if (!(creds.ticket_flags & TKT_FLG_INVALID) &&
                creds.times.starttime < (now + TIMET_TOLERANCE) && 
                (creds.times.endtime + TIMET_TOLERANCE) > now) {
                expiration = creds.times.endtime;

                if ((creds.ticket_flags & TKT_FLG_RENEWABLE) && 
                    (creds.times.renew_till > creds.times.endtime)) {
                    expiration = creds.times.renew_till;
                }
            }
        }
    }

    if (cc_code == KRB5_CC_END) {
        cc_code = pkrb5_cc_end_seq_get(ctx, cc, &cur);
        rv = KHM_ERROR_SUCCESS;
        *pexpiration = expiration;
    }

    return rv;
}