/* * try_ccache() * * Attempt to retrieve desired NXT_TGT from ccache. Point NXT_TGT to * it if successful. */ static krb5_error_code try_ccache(struct tr_state *ts, krb5_creds *tgtq) { krb5_error_code retval; krb5_timestamp saved_endtime; TR_DBG(ts, "try_ccache"); /* * Solaris Kerberos: * Ensure the retrieved cred isn't stale. * Set endtime to now so krb5_cc_retrieve_cred won't return an expired ticket. */ saved_endtime = tgtq->times.endtime; if ((retval = krb5_timeofday(ts->ctx, &(tgtq->times.endtime))) != 0) { tgtq->times.endtime = saved_endtime; return retval; } retval = krb5_cc_retrieve_cred(ts->ctx, ts->ccache, RETR_FLAGS, tgtq, ts->nxt_cc_tgt); if (!retval) { shift_cc_tgts(ts); ts->nxt_tgt = ts->cur_cc_tgt; } /* * Solaris Kerberos: * Ensure that tgtq->times.endtime is reset back to its original value so * that if tgtq is used to request a ticket from the KDC it doesn't request * a ticket with an endtime set to "now". */ tgtq->times.endtime = saved_endtime; TR_DBG_RET(ts, "try_ccache", retval); return retval; }
static int print_cred(krb5_context context, krb5_creds *cred) { char t1[128], t2[128], *str; krb5_error_code ret; krb5_timestamp sec; krb5_timeofday (context, &sec); if(cred->times.starttime) krb5_format_time(context, cred->times.starttime, t1, sizeof(t1), 1); else krb5_format_time(context, cred->times.authtime, t1, sizeof(t1), 1); if(cred->times.endtime > sec) krb5_format_time(context, cred->times.endtime, t2, sizeof(t2), 1); else strlcpy(t2, ">>>Expired<<<", sizeof(t2)); ret = krb5_unparse_name (context, cred->server, &str); if (ret) { lreply(500, "krb5_unparse_name: %d", ret); return 1; } lreply(200, "%-20s %-20s %s", t1, t2, str); free(str); return 0; }
/* kssl_validate_times() combines (and more importantly exposes) ** the MIT KRB5 internal function krb5_validate_times() and the ** in_clock_skew() macro. The authenticator client time is checked ** to be within clockskew secs of the current time and the current ** time is checked to be within the ticket start and expire times. ** Either check may be omitted by supplying a NULL value. ** Returns 0 for valid times, SSL_R_KRB5* error codes otherwise. ** See Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c ** 20010420 VRS */ krb5_error_code kssl_validate_times(krb5_timestamp atime, krb5_ticket_times *ttimes) { krb5_deltat skew; krb5_timestamp start, now; krb5_error_code rc; krb5_context context; if ((rc = krb5_init_context(&context))) return SSL_R_KRB5_S_BAD_TICKET; skew = get_rc_clockskew(context); if ((rc = krb5_timeofday(context, &now))) return SSL_R_KRB5_S_BAD_TICKET; krb5_free_context(context); if (atime && labs(atime - now) >= skew) return SSL_R_KRB5_S_TKT_SKEW; if (!ttimes) return 0; start = (ttimes->starttime != 0) ? ttimes->starttime : ttimes->authtime; if (start - now > skew) return SSL_R_KRB5_S_TKT_NYV; if ((now - ttimes->endtime) > skew) return SSL_R_KRB5_S_TKT_EXPIRED; #ifdef KSSL_DEBUG printf("kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n", start, atime, now, skew, ttimes->endtime); #endif /* KSSL_DEBUG */ return 0; }
OM_uint32 _gsskrb5_lifetime_left(OM_uint32 *minor_status, krb5_context context, OM_uint32 lifetime, OM_uint32 *lifetime_rec) { krb5_timestamp timeret; krb5_error_code kret; if (lifetime == 0) { *lifetime_rec = GSS_C_INDEFINITE; return GSS_S_COMPLETE; } kret = krb5_timeofday(context, &timeret); if (kret) { *minor_status = kret; return GSS_S_FAILURE; } if (lifetime < timeret) *lifetime_rec = 0; else *lifetime_rec = lifetime - timeret; return GSS_S_COMPLETE; }
static krb5_error_code nonce_generate(krb5_context ctx, unsigned int length, krb5_data *nonce_out) { krb5_data nonce; krb5_error_code retval; krb5_timestamp now; retval = krb5_timeofday(ctx, &now); if (retval != 0) return retval; retval = alloc_data(&nonce, sizeof(now) + length); if (retval != 0) return retval; retval = krb5_c_random_make_octets(ctx, &nonce); if (retval != 0) { free(nonce.data); return retval; } store_32_be(now, nonce.data); *nonce_out = nonce; return 0; }
krb5_error_code process_v4(const krb5_data *pkt, const krb5_fulladdr *client_fulladdr, krb5_data **resp) { struct sockaddr_in client_sockaddr; krb5_address *addr = client_fulladdr->address; krb5_error_code retval; krb5_timestamp now; KTEXT_ST v4_pkt; char *lrealm; /* Check if disabled completely */ if (kdc_v4 == KDC_V4_NONE) { (void) klog(L_KRB_PERR, "Disabled KRB V4 request"); return KRB5KDC_ERR_BAD_PVNO; } if ((retval = krb5_timeofday(kdc_context, &now))) return(retval); kerb_time.tv_sec = now; if (!*local_realm) { /* local-realm name already set up */ lrealm = master_princ->realm.data; if (master_princ->realm.length < sizeof(local_realm)) { memcpy(local_realm, lrealm, master_princ->realm.length); local_realm[master_princ->realm.length] = '\0'; } else retval = KRB5_CONFIG_NOTENUFSPACE; } /* convert client_fulladdr to client_sockaddr: */ client_sockaddr.sin_family = AF_INET; client_sockaddr.sin_port = client_fulladdr->port; if (client_fulladdr->address->addrtype != ADDRTYPE_INET) { klog(L_KRB_PERR, "got krb4 request from non-ipv4 address"); client_sockaddr.sin_addr.s_addr = 0; } else memcpy(&client_sockaddr.sin_addr, addr->contents, sizeof client_sockaddr.sin_addr); memset( client_sockaddr.sin_zero, 0, sizeof client_sockaddr.sin_zero); /* convert v5 packet structure to v4's. * this copy is gross, but necessary: */ if (pkt->length > MAX_KTXT_LEN) { (void) klog(L_KRB_PERR, "V4 request too long."); return KRB5KRB_ERR_FIELD_TOOLONG; } v4_pkt.length = pkt->length; v4_pkt.mbz = 0; memcpy( v4_pkt.dat, pkt->data, pkt->length); kerberos_v4( &client_sockaddr, &v4_pkt); *resp = response; return(retval); }
static isc_result_t check_credentials(krb5_context context, krb5_ccache ccache, krb5_principal service) { char *realm = NULL; krb5_creds creds; krb5_creds mcreds; krb5_error_code krberr; krb5_timestamp now; isc_result_t result = ISC_R_FAILURE; memset(&mcreds, 0, sizeof(mcreds)); memset(&creds, 0, sizeof(creds)); krberr = krb5_get_default_realm(context, &realm); CHECK_KRB5(context, krberr, "Failed to retrieve default realm"); krberr = krb5_build_principal(context, &mcreds.server, strlen(realm), realm, "krbtgt", realm, NULL); CHECK_KRB5(context, krberr, "Failed to build 'krbtgt/REALM' principal"); mcreds.client = service; krberr = krb5_cc_retrieve_cred(context, ccache, 0, &mcreds, &creds); if (krberr) { const char * errmsg = krb5_get_error_message(context, krberr); log_error("Credentials are not present in cache (%s)\n", errmsg); krb5_free_error_message(context, errmsg); result = ISC_R_FAILURE; goto cleanup; } CHECK_KRB5(context, krberr, "Credentials are not present in cache "); krberr = krb5_timeofday(context, &now); CHECK_KRB5(context, krberr, "Failed to get time of day"); if (now > (creds.times.endtime + KRB_MIN_TIME)) { log_error("Credentials cache expired"); result = ISC_R_FAILURE; goto cleanup; } else { char buf[255]; char fill = ' '; krb5_timestamp_to_sfstring(creds.times.endtime, buf, 16, &fill); log_info("Credentials valid til %s\n", buf); } result = ISC_R_SUCCESS; cleanup: krb5_free_cred_contents(context, &creds); if (mcreds.server) krb5_free_principal(context, mcreds.server); if (realm) krb5_free_default_realm(context, realm); return result; }
static OM_uint32 gsskrb5_get_creds( OM_uint32 * minor_status, krb5_ccache ccache, gsskrb5_ctx ctx, krb5_const_principal target_name, OM_uint32 time_req, OM_uint32 * time_rec, krb5_creds ** cred) { OM_uint32 ret; krb5_error_code kret; krb5_creds this_cred; OM_uint32 lifetime_rec; *cred = NULL; memset(&this_cred, 0, sizeof(this_cred)); this_cred.client = ctx->source; this_cred.server = ctx->target; if (time_req && time_req != GSS_C_INDEFINITE) { krb5_timestamp ts; krb5_timeofday (_gsskrb5_context, &ts); this_cred.times.endtime = ts + time_req; } else { this_cred.times.endtime = 0; } this_cred.session.keytype = KEYTYPE_NULL; kret = krb5_get_credentials(_gsskrb5_context, 0, ccache, &this_cred, cred); if (kret) { _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } ctx->lifetime = (*cred)->times.endtime; ret = _gsskrb5_lifetime_left(minor_status, ctx->lifetime, &lifetime_rec); if (ret) return ret; if (lifetime_rec == 0) { *minor_status = 0; return GSS_S_CONTEXT_EXPIRED; } if (time_rec) *time_rec = lifetime_rec; return GSS_S_COMPLETE; }
static krb5_error_code pk_check_pkauthenticator(krb5_context context, PKAuthenticator *a, const KDC_REQ *req) { u_char *buf = NULL; size_t buf_size; krb5_error_code ret; size_t len = 0; krb5_timestamp now; Checksum checksum; krb5_timeofday (context, &now); /* XXX cusec */ if (a->ctime == 0 || labs(a->ctime - now) > context->max_skew) { krb5_clear_error_message(context); return KRB5KRB_AP_ERR_SKEW; } ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, &req->req_body, &len, ret); if (ret) { krb5_clear_error_message(context); return ret; } if (buf_size != len) krb5_abortx(context, "Internal error in ASN.1 encoder"); ret = krb5_create_checksum(context, NULL, 0, CKSUMTYPE_SHA1, buf, len, &checksum); free(buf); if (ret) { krb5_clear_error_message(context); return ret; } if (a->paChecksum == NULL) { krb5_clear_error_message(context); ret = KRB5_KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED; goto out; } if (der_heim_octet_string_cmp(a->paChecksum, &checksum.checksum) != 0) { krb5_clear_error_message(context); ret = KRB5KRB_ERR_GENERIC; } out: free_Checksum(&checksum); return ret; }
/* * Set *mcreds and *fields to a matching credential and field set for * use with krb5_cc_retrieve_cred, based on a set of input credentials * and options. The fields of *mcreds will be aliased to the fields * of in_creds, so the contents of *mcreds should not be freed. */ krb5_error_code krb5int_construct_matching_creds(krb5_context context, krb5_flags options, krb5_creds *in_creds, krb5_creds *mcreds, krb5_flags *fields) { if (!in_creds || !in_creds->server || !in_creds->client) return EINVAL; memset(mcreds, 0, sizeof(krb5_creds)); mcreds->magic = KV5M_CREDS; if (in_creds->times.endtime != 0) { mcreds->times.endtime = in_creds->times.endtime; } else { krb5_error_code retval; retval = krb5_timeofday(context, &mcreds->times.endtime); if (retval != 0) return retval; } mcreds->keyblock = in_creds->keyblock; mcreds->authdata = in_creds->authdata; mcreds->server = in_creds->server; mcreds->client = in_creds->client; *fields = KRB5_TC_MATCH_TIMES /*XXX |KRB5_TC_MATCH_SKEY_TYPE */ | KRB5_TC_MATCH_AUTHDATA | KRB5_TC_SUPPORTED_KTYPES; if (mcreds->keyblock.enctype) { krb5_enctype *ktypes; krb5_error_code ret; int i; *fields |= KRB5_TC_MATCH_KTYPE; ret = krb5_get_tgs_ktypes(context, mcreds->server, &ktypes); for (i = 0; ktypes[i]; i++) if (ktypes[i] == mcreds->keyblock.enctype) break; if (ktypes[i] == 0) ret = KRB5_CC_NOT_KTYPE; free (ktypes); if (ret) return ret; } if (options & (KRB5_GC_USER_USER | KRB5_GC_CONSTRAINED_DELEGATION)) { /* also match on identical 2nd tkt and tkt encrypted in a session key */ *fields |= KRB5_TC_MATCH_2ND_TKT; if (options & KRB5_GC_USER_USER) { *fields |= KRB5_TC_MATCH_IS_SKEY; mcreds->is_skey = TRUE; } mcreds->second_ticket = in_creds->second_ticket; if (!in_creds->second_ticket.length) return KRB5_NO_2ND_TKT; } return 0; }
/* * Determine the starting IAKERB state for a context. If we already * have a ticket, we may not need to do IAKERB at all. */ static krb5_error_code iakerb_get_initial_state(iakerb_ctx_id_t ctx, krb5_gss_cred_id_t cred, krb5_gss_name_t target, OM_uint32 time_req, enum iakerb_state *state) { krb5_creds in_creds, *out_creds = NULL; krb5_error_code code; memset(&in_creds, 0, sizeof(in_creds)); in_creds.client = cred->name->princ; in_creds.server = target->princ; if (cred->name->ad_context != NULL) { code = krb5_authdata_export_authdata(ctx->k5c, cred->name->ad_context, AD_USAGE_TGS_REQ, &in_creds.authdata); if (code != 0) goto cleanup; } if (time_req != 0 && time_req != GSS_C_INDEFINITE) { krb5_timestamp now; code = krb5_timeofday(ctx->k5c, &now); if (code != 0) goto cleanup; in_creds.times.endtime = now + time_req; } /* Make an AS request if we have no creds or it's time to refresh them. */ if (cred->expire == 0 || kg_cred_time_to_refresh(ctx->k5c, cred)) { *state = IAKERB_AS_REQ; code = 0; goto cleanup; } code = krb5_get_credentials(ctx->k5c, KRB5_GC_CACHED, cred->ccache, &in_creds, &out_creds); if (code == KRB5_CC_NOTFOUND || code == KRB5_CC_NOT_KTYPE) { *state = cred->have_tgt ? IAKERB_TGS_REQ : IAKERB_AS_REQ; code = 0; } else if (code == 0) { *state = IAKERB_AP_REQ; krb5_free_creds(ctx->k5c, out_creds); } cleanup: krb5_free_authdata(ctx->k5c, in_creds.authdata); return code; }
/* time in seconds the tgt will be still valid */ int ka_tgt_valid_seconds () { krb5_timestamp now; if (krb5_timeofday (kcontext, &now)) return 0; return (creds_expiry - now); }
static void print_cred(krb5_context context, krb5_creds *cred, rtbl_t ct, int do_flags) { char *str; krb5_error_code ret; krb5_timestamp sec; krb5_timeofday (context, &sec); if(cred->times.starttime) rtbl_add_column_entry(ct, COL_ISSUED, printable_time(cred->times.starttime)); else rtbl_add_column_entry(ct, COL_ISSUED, printable_time(cred->times.authtime)); if(cred->times.endtime > sec) rtbl_add_column_entry(ct, COL_EXPIRES, printable_time(cred->times.endtime)); else rtbl_add_column_entry(ct, COL_EXPIRES, N_(">>>Expired<<<", "")); ret = krb5_unparse_name (context, cred->server, &str); if (ret) krb5_err(context, 1, ret, "krb5_unparse_name"); rtbl_add_column_entry(ct, COL_PRINCIPAL, str); if(do_flags) { char s[16], *sp = s; if(cred->flags.b.forwardable) *sp++ = 'F'; if(cred->flags.b.forwarded) *sp++ = 'f'; if(cred->flags.b.proxiable) *sp++ = 'P'; if(cred->flags.b.proxy) *sp++ = 'p'; if(cred->flags.b.may_postdate) *sp++ = 'D'; if(cred->flags.b.postdated) *sp++ = 'd'; if(cred->flags.b.renewable) *sp++ = 'R'; if(cred->flags.b.initial) *sp++ = 'I'; if(cred->flags.b.invalid) *sp++ = 'i'; if(cred->flags.b.pre_authent) *sp++ = 'A'; if(cred->flags.b.hw_authent) *sp++ = 'H'; *sp = '\0'; rtbl_add_column_entry(ct, COL_FLAGS, s); } free(str); }
struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[]) { char svrnam[MAILTMPLEN],cltnam[MAILTMPLEN]; krb5_context ctx; krb5_timestamp now; krb5_principal service; krb5_ccache ccache; krb5_error_code code; krb5_creds *crd = (krb5_creds *) memset (fs_get (sizeof (krb5_creds)),0, sizeof (krb5_creds)); struct passwd *ret = NIL; if (*pass) { /* only if password non-empty */ /* make service name */ sprintf (svrnam,"%.80s@%.512s", (char *) mail_parameters (NIL,GET_SERVICENAME,NIL), tcp_serverhost ()); /* make client name with principal */ sprintf (cltnam,"%.80s/%.80s",pw->pw_name, (char *) mail_parameters (NIL,GET_SERVICENAME,NIL)); /* get a context */ if (!krb5_init_context (&ctx)) { /* get time, client and server principals */ if (!krb5_timeofday (ctx,&now) && /* Normally, kerb_cp_svr_name (defined/set in env_unix.c) is NIL, so * only the user name is used as a client principal. A few sites want * to have separate client principals for different services, but many * other sites vehemently object... */ !krb5_parse_name (ctx,kerb_cp_svr_name ? cltnam : pw->pw_name, &crd->client) && !krb5_parse_name (ctx,svrnam,&service) && !krb5_build_principal_ext(ctx,&crd->server, krb5_princ_realm (ctx,crd->client)->length, krb5_princ_realm (ctx,crd->client)->data, KRB5_TGS_NAME_SIZE,KRB5_TGS_NAME, krb5_princ_realm (ctx,crd->client)->length, krb5_princ_realm (ctx,crd->client)->data, 0)) { /* expire in 3 minutes */ crd->times.endtime = now + (3 * 60); if (krb5_cc_resolve (ctx,"MEMORY:pwk",&ccache) || krb5_cc_initialize (ctx,ccache,crd->client)) ccache = 0; if (!krb5_get_in_tkt_with_password (ctx,NIL,NIL,NIL,NIL,pass,ccache, crd,0) && !krb5_verify_init_creds (ctx,crd,service,0,ccache ? &ccache : 0,0)) ret = pw; krb5_free_creds (ctx,crd);/* flush creds and service principal */ krb5_free_principal (ctx,service); } krb5_free_context (ctx); /* don't need context any more */ } } return ret; }
krb5_timestamp v5::getNow(krb5_context kcontext) { krb5_timestamp now; int e = krb5_timeofday(kcontext, &now); if(e != 0) { qWarning("Cannot get current time: %s", strerror(e)); return 0; } return now; }
krb5_error_code KRB5_CALLCONV krb5_rc_dfl_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep) { krb5_error_code ret; struct dfl_data *t; krb5_int32 now; ret = krb5_timeofday(context, &now); if (ret) return ret; ret = k5_mutex_lock(&id->lock); if (ret) return ret; switch(rc_store(context, id, rep, now, FALSE)) { case CMP_MALLOC: k5_mutex_unlock(&id->lock); return KRB5_RC_MALLOC; case CMP_REPLAY: k5_mutex_unlock(&id->lock); return KRB5KRB_AP_ERR_REPEAT; case 0: break; default: /* wtf? */ ; } t = (struct dfl_data *)id->data; #ifndef NOIOSTUFF ret = krb5_rc_io_store(context, t, rep); if (ret) { k5_mutex_unlock(&id->lock); return ret; } #endif /* Shall we automatically expunge? */ if (t->nummisses > t->numhits + EXCESSREPS) { ret = krb5_rc_dfl_expunge_locked(context, id); k5_mutex_unlock(&id->lock); return ret; } #ifndef NOIOSTUFF else { if (krb5_rc_io_sync(context, &t->d)) { k5_mutex_unlock(&id->lock); return KRB5_RC_IO; } } #endif k5_mutex_unlock(&id->lock); return 0; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_decrypt_ticket(krb5_context context, Ticket *ticket, krb5_keyblock *key, EncTicketPart *out, krb5_flags flags) { EncTicketPart t; krb5_error_code ret; ret = decrypt_tkt_enc_part(context, key, &ticket->enc_part, &t); if (ret) return ret; { krb5_timestamp now; time_t start = t.authtime; krb5_timeofday(context, &now); if(t.starttime) start = *t.starttime; if(start - now > context->max_skew || (t.flags.invalid && !(flags & KRB5_VERIFY_AP_REQ_IGNORE_INVALID))) { free_EncTicketPart(&t); krb5_clear_error_message(context); return KRB5KRB_AP_ERR_TKT_NYV; } if(now - t.endtime > context->max_skew) { free_EncTicketPart(&t); krb5_clear_error_message(context); return KRB5KRB_AP_ERR_TKT_EXPIRED; } if(!t.flags.transited_policy_checked) { ret = check_transited(context, ticket, &t); if(ret) { free_EncTicketPart(&t); return ret; } } } if(out) *out = t; else free_EncTicketPart(&t); return 0; }
krb5_boolean kdc_check_lookaside(krb5_data *inpkt, krb5_data **outpkt) { krb5_int32 timenow; register krb5_kdc_replay_ent *eptr, *last, *hold; time_t db_age; if (krb5_timeofday(kdc_context, &timenow) || krb5_db_get_age(kdc_context, 0, &db_age)) return FALSE; calls++; /* search for a replay entry in the queue, possibly removing stale entries while we're here */ if (root_ptr.next) { for (last = &root_ptr, eptr = root_ptr.next; eptr; eptr = eptr->next) { if (MATCH(eptr)) { eptr->num_hits++; hits++; if (krb5_copy_data(kdc_context, eptr->reply_packet, outpkt)) return FALSE; else return TRUE; /* return here, don't bother flushing even if it is stale. if we just matched, we may get another retransmit... */ } if (STALE(eptr)) { /* flush it and collect stats */ max_hits_per_entry = max(max_hits_per_entry, eptr->num_hits); krb5_free_data(kdc_context, eptr->req_packet); krb5_free_data(kdc_context, eptr->reply_packet); hold = eptr; last->next = eptr->next; eptr = last; free(hold); } else { /* this isn't it, just move along */ last = eptr; } } } return FALSE; }
static krb5_error_code pk_check_pkauthenticator_win2k(krb5_context context, PKAuthenticator_Win2k *a, const KDC_REQ *req) { krb5_timestamp now; krb5_timeofday (context, &now); /* XXX cusec */ if (a->ctime == 0 || labs(a->ctime - now) > context->max_skew) { krb5_clear_error_message(context); return KRB5KRB_AP_ERR_SKEW; } return 0; }
int v5::credentialCheck(krb5_context kcontext, krb5_principal kprincipal, int promptInterval, krb5_timestamp *tgtEndtime) { krb5_creds my_creds; krb5_timestamp now; Ktw::reqAction retval = Ktw::none; if (!getTgtFromCcache(kcontext, &my_creds)) { tgtEndtime = 0; return retval; } if (krb5_principal_compare (kcontext, my_creds.client, kprincipal)) { krb5_free_principal(kcontext, kprincipal); krb5_copy_principal(kcontext, my_creds.client, &kprincipal); } if ((krb5_timeofday(kcontext, &now) == 0) && (now + (promptInterval * 60) >= my_creds.times.endtime)) { qDebug("now: %d", now); qDebug("starttime: %d", my_creds.times.starttime); qDebug("endtime: %d", my_creds.times.endtime); qDebug("next Prompt: %d", (now + (promptInterval * 60))); qDebug("renew possible untill: %d", my_creds.times.renew_till); if(now + (promptInterval * 60) >= my_creds.times.renew_till) { retval = Ktw::reinit; } else { retval = Ktw::renew; } } *tgtEndtime = my_creds.times.endtime; krb5_free_cred_contents(kcontext, &my_creds); qDebug("credentials_expiring_real returns: %d", retval); return retval; }
/* * Initialise the krb5_tkt_creds context for the IAKERB context */ static krb5_error_code iakerb_tkt_creds_ctx(iakerb_ctx_id_t ctx, krb5_gss_cred_id_t cred, krb5_gss_name_t name, OM_uint32 time_req) { krb5_error_code code; krb5_creds creds; krb5_timestamp now; assert(cred->name != NULL); assert(cred->name->princ != NULL); memset(&creds, 0, sizeof(creds)); creds.client = cred->name->princ; creds.server = name->princ; if (time_req != 0 && time_req != GSS_C_INDEFINITE) { code = krb5_timeofday(ctx->k5c, &now); if (code != 0) goto cleanup; creds.times.endtime = now + time_req; } if (cred->name->ad_context != NULL) { code = krb5_authdata_export_authdata(ctx->k5c, cred->name->ad_context, AD_USAGE_TGS_REQ, &creds.authdata); if (code != 0) goto cleanup; } code = krb5_tkt_creds_init(ctx->k5c, cred->ccache, &creds, 0, &ctx->tcc); if (code != 0) goto cleanup; cleanup: krb5_free_authdata(ctx->k5c, creds.authdata); return code; }
static gboolean credentials_expiring_real (KaApplet *applet) { krb5_creds my_creds; krb5_timestamp now; gboolean retval = FALSE; if (!kcontext_valid) return retval; memset (&my_creds, 0, sizeof (my_creds)); ka_applet_set_tgt_renewable (applet, FALSE); if (!ka_get_tgt_from_ccache (kcontext, &my_creds)) { creds_expiry = 0; retval = TRUE; goto out; } /* copy principal from cache if any */ if (kprincipal == NULL || krb5_principal_compare (kcontext, my_creds.client, kprincipal)) { if (kprincipal) krb5_free_principal (kcontext, kprincipal); krb5_copy_principal (kcontext, my_creds.client, &kprincipal); } creds_expiry = my_creds.times.endtime; if ((krb5_timeofday (kcontext, &now) == 0) && (now + ka_applet_get_pw_prompt_secs (applet) > my_creds.times.endtime)) retval = TRUE; /* If our creds are expiring, determine whether they are renewable. * If the expiry is already at the renew_till time, don't consider * credentials renewable */ if (retval && get_cred_renewable (&my_creds) && my_creds.times.renew_till > now && my_creds.times.renew_till > creds_expiry) { ka_applet_set_tgt_renewable (applet, TRUE); } out: krb5_free_cred_contents (kcontext, &my_creds); ka_applet_update_status (applet, creds_expiry); return retval; }
/* * Function: kdb_put_entry * * Purpose: Stores the osa_princ_ent_t and krb5_db_entry into to * database. * * Arguments: * * handle (r) the server_handle * kdb (r/w) the krb5_db_entry to store * adb (r) the osa_princ_db_ent to store * * Effects: * * The last modifier field of the kdb is set to the caller at now. * adb is encoded with xdr_osa_princ_ent_ret and stored in kbd as * KRB5_TL_KADM_DATA. kdb is then written to the database. */ krb5_error_code kdb_put_entry(kadm5_server_handle_t handle, krb5_db_entry *kdb, osa_princ_ent_rec *adb) { krb5_error_code ret; krb5_int32 now; XDR xdrs; krb5_tl_data tl_data; int one; ret = krb5_timeofday(handle->context, &now); if (ret) return(ret); ret = krb5_dbe_update_mod_princ_data(handle->context, kdb, now, handle->current_caller); if (ret) return(ret); xdralloc_create(&xdrs, XDR_ENCODE); if(! xdr_osa_princ_ent_rec(&xdrs, adb)) { xdr_destroy(&xdrs); return(KADM5_XDR_FAILURE); } tl_data.tl_data_type = KRB5_TL_KADM_DATA; tl_data.tl_data_length = xdr_getpos(&xdrs); /* Solaris Kerberos */ tl_data.tl_data_contents = (unsigned char *) xdralloc_getdata(&xdrs); ret = krb5_dbe_update_tl_data(handle->context, kdb, &tl_data); xdr_destroy(&xdrs); if (ret) return(ret); one = 1; ret = krb5_db_put_principal(handle->context, kdb, &one); if (ret) return(ret); return(0); }
static krb5_error_code init_cred (krb5_context context, krb5_creds *cred, krb5_principal client, krb5_deltat start_time, krb5_get_init_creds_opt *options) { krb5_error_code ret; int tmp; krb5_timestamp now; krb5_timeofday (context, &now); memset (cred, 0, sizeof(*cred)); if (client) krb5_copy_principal(context, client, &cred->client); else { ret = krb5_get_default_principal (context, &cred->client); if (ret) goto out; } if (start_time) cred->times.starttime = now + start_time; if (options->flags & KRB5_GET_INIT_CREDS_OPT_TKT_LIFE) tmp = options->tkt_life; else tmp = 10 * 60 * 60; cred->times.endtime = now + tmp; if ((options->flags & KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE) && options->renew_life > 0) { cred->times.renew_till = now + options->renew_life; } return 0; out: krb5_free_cred_contents (context, cred); return ret; }
/* * Function: kdb_put_entry * * Purpose: Stores the osa_princ_ent_t and krb5_db_entry into to * database. * * Arguments: * * handle (r) the server_handle * kdb (r/w) the krb5_db_entry to store * adb (r) the osa_princ_db_ent to store * * Effects: * * The last modifier field of the kdb is set to the caller at now. * adb is encoded with xdr_osa_princ_ent_ret and stored in kbd as * KRB5_TL_KADM_DATA. kdb is then written to the database. */ krb5_error_code kdb_put_entry(kadm5_server_handle_t handle, krb5_db_entry *kdb, osa_princ_ent_rec *adb) { krb5_error_code ret; krb5_int32 now; XDR xdrs; krb5_tl_data tl_data; ret = krb5_timeofday(handle->context, &now); if (ret) return(ret); ret = krb5_dbe_update_mod_princ_data(handle->context, kdb, now, handle->current_caller); if (ret) return(ret); xdralloc_create(&xdrs, XDR_ENCODE); if(! xdr_osa_princ_ent_rec(&xdrs, adb)) { xdr_destroy(&xdrs); return(KADM5_XDR_FAILURE); } tl_data.tl_data_type = KRB5_TL_KADM_DATA; tl_data.tl_data_length = xdr_getpos(&xdrs); tl_data.tl_data_contents = (krb5_octet *)xdralloc_getdata(&xdrs); ret = krb5_dbe_update_tl_data(handle->context, kdb, &tl_data); xdr_destroy(&xdrs); if (ret) return(ret); /* we are always updating TL data */ kdb->mask |= KADM5_TL_DATA; ret = krb5_db_put_principal(handle->context, kdb); if (ret) return(ret); return(0); }
OM_uint32 gssapi_lifetime_left(OM_uint32 *minor_status, OM_uint32 lifetime, OM_uint32 *lifetime_rec) { krb5_timestamp timeret; krb5_error_code kret; kret = krb5_timeofday(gssapi_krb5_context, &timeret); if (kret) { *minor_status = kret; gssapi_krb5_set_error_string (); return GSS_S_FAILURE; } if (lifetime < timeret) *lifetime_rec = 0; else *lifetime_rec = lifetime - timeret; return GSS_S_COMPLETE; }
static krb5_error_code check_cc(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_creds *out_creds) { krb5_error_code ret; krb5_timestamp timeret; /* * If we got a credential, check if credential is expired before * returning it. */ ret = krb5_cc_retrieve_cred(context, ccache, options & KRB5_TC_MATCH_KEYTYPE, in_creds, out_creds); if (ret != 0) return ret; /* Caller will check for KRB5_CC_END */ /* * If we got a credential, check if credential is expired before * returning it, but only if KRB5_GC_EXPIRED_OK is not set. */ /* If expired ok, don't bother checking */ if (options & KRB5_GC_EXPIRED_OK) return 0; krb5_timeofday(context, &timeret); if (out_creds->times.endtime > timeret) return 0; /* Expired and not ok; remove and pretend we didn't find it */ if (options & KRB5_GC_CACHED) krb5_cc_remove_cred(context, ccache, 0, out_creds); krb5_free_cred_contents(context, out_creds); memset(out_creds, 0, sizeof (*out_creds)); return KRB5_CC_END; }
void kdc_insert_lookaside(krb5_data *inpkt, krb5_data *outpkt) { register krb5_kdc_replay_ent *eptr; krb5_int32 timenow; time_t db_age; if (krb5_timeofday(kdc_context, &timenow) || krb5_db_get_age(kdc_context, 0, &db_age)) return; /* this is a new entry */ eptr = (krb5_kdc_replay_ent *)calloc(1, sizeof(*eptr)); if (!eptr) return; eptr->timein = timenow; eptr->db_age = db_age; /* * This is going to hurt a lot malloc()-wise due to the need to * allocate memory for the krb5_data and krb5_address elements. * ARGH! */ if (krb5_copy_data(kdc_context, inpkt, &eptr->req_packet)) { free(eptr); return; } if (krb5_copy_data(kdc_context, outpkt, &eptr->reply_packet)) { krb5_free_data(kdc_context, eptr->req_packet); free(eptr); return; } eptr->next = root_ptr.next; root_ptr.next = eptr; num_entries++; return; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_get_creds(krb5_context context, krb5_get_creds_opt opt, krb5_ccache ccache, krb5_const_principal inprinc, krb5_creds **out_creds) { krb5_kdc_flags flags; krb5_flags options; krb5_creds in_creds; krb5_error_code ret; krb5_creds **tgts; krb5_creds *res_creds; int i; if (opt && opt->enctype) { ret = krb5_enctype_valid(context, opt->enctype); if (ret) return ret; } memset(&in_creds, 0, sizeof(in_creds)); in_creds.server = rk_UNCONST(inprinc); ret = krb5_cc_get_principal(context, ccache, &in_creds.client); if (ret) return ret; if (opt) options = opt->options; else options = 0; flags.i = 0; *out_creds = NULL; res_creds = calloc(1, sizeof(*res_creds)); if (res_creds == NULL) { krb5_free_principal(context, in_creds.client); krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } if (opt && opt->enctype) { in_creds.session.keytype = opt->enctype; options |= KRB5_TC_MATCH_KEYTYPE; } /* * If we got a credential, check if credential is expired before * returning it. */ ret = krb5_cc_retrieve_cred(context, ccache, options & KRB5_TC_MATCH_KEYTYPE, &in_creds, res_creds); /* * If we got a credential, check if credential is expired before * returning it, but only if KRB5_GC_EXPIRED_OK is not set. */ if (ret == 0) { krb5_timestamp timeret; /* If expired ok, don't bother checking */ if(options & KRB5_GC_EXPIRED_OK) { *out_creds = res_creds; krb5_free_principal(context, in_creds.client); goto out; } krb5_timeofday(context, &timeret); if(res_creds->times.endtime > timeret) { *out_creds = res_creds; krb5_free_principal(context, in_creds.client); goto out; } if(options & KRB5_GC_CACHED) krb5_cc_remove_cred(context, ccache, 0, res_creds); } else if(ret != KRB5_CC_END) { free(res_creds); krb5_free_principal(context, in_creds.client); goto out; } free(res_creds); if(options & KRB5_GC_CACHED) { krb5_free_principal(context, in_creds.client); ret = not_found(context, in_creds.server, KRB5_CC_NOTFOUND); goto out; } if(options & KRB5_GC_USER_USER) { flags.b.enc_tkt_in_skey = 1; options |= KRB5_GC_NO_STORE; } if (options & KRB5_GC_FORWARDABLE) flags.b.forwardable = 1; if (options & KRB5_GC_NO_TRANSIT_CHECK) flags.b.disable_transited_check = 1; if (options & KRB5_GC_CONSTRAINED_DELEGATION) { flags.b.request_anonymous = 1; /* XXX ARGH confusion */ flags.b.constrained_delegation = 1; } if (options & KRB5_GC_CANONICALIZE) flags.b.canonicalize = 1; tgts = NULL; ret = _krb5_get_cred_kdc_any(context, flags, ccache, &in_creds, opt->self, opt->ticket, out_creds, &tgts); krb5_free_principal(context, in_creds.client); for(i = 0; tgts && tgts[i]; i++) { krb5_cc_store_cred(context, ccache, tgts[i]); krb5_free_creds(context, tgts[i]); } free(tgts); if(ret == 0 && (options & KRB5_GC_NO_STORE) == 0) krb5_cc_store_cred(context, ccache, *out_creds); out: _krb5_debug(context, 5, "krb5_get_creds: ret = %d", ret); return ret; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_get_credentials_with_flags(krb5_context context, krb5_flags options, krb5_kdc_flags flags, krb5_ccache ccache, krb5_creds *in_creds, krb5_creds **out_creds) { krb5_error_code ret; krb5_creds **tgts; krb5_creds *res_creds; int i; if (in_creds->session.keytype) { ret = krb5_enctype_valid(context, in_creds->session.keytype); if (ret) return ret; } *out_creds = NULL; res_creds = calloc(1, sizeof(*res_creds)); if (res_creds == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } if (in_creds->session.keytype) options |= KRB5_TC_MATCH_KEYTYPE; /* * If we got a credential, check if credential is expired before * returning it. */ ret = krb5_cc_retrieve_cred(context, ccache, in_creds->session.keytype ? KRB5_TC_MATCH_KEYTYPE : 0, in_creds, res_creds); /* * If we got a credential, check if credential is expired before * returning it, but only if KRB5_GC_EXPIRED_OK is not set. */ if (ret == 0) { krb5_timestamp timeret; /* If expired ok, don't bother checking */ if(options & KRB5_GC_EXPIRED_OK) { *out_creds = res_creds; return 0; } krb5_timeofday(context, &timeret); if(res_creds->times.endtime > timeret) { *out_creds = res_creds; return 0; } if(options & KRB5_GC_CACHED) krb5_cc_remove_cred(context, ccache, 0, res_creds); } else if(ret != KRB5_CC_END) { free(res_creds); return ret; } free(res_creds); if(options & KRB5_GC_CACHED) return not_found(context, in_creds->server, KRB5_CC_NOTFOUND); if(options & KRB5_GC_USER_USER) flags.b.enc_tkt_in_skey = 1; if (flags.b.enc_tkt_in_skey) options |= KRB5_GC_NO_STORE; tgts = NULL; ret = _krb5_get_cred_kdc_any(context, flags, ccache, in_creds, NULL, NULL, out_creds, &tgts); for(i = 0; tgts && tgts[i]; i++) { krb5_cc_store_cred(context, ccache, tgts[i]); krb5_free_creds(context, tgts[i]); } free(tgts); if(ret == 0 && (options & KRB5_GC_NO_STORE) == 0) krb5_cc_store_cred(context, ccache, *out_creds); return ret; }