Ejemplo n.º 1
0
/*
 * 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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
/*
 * 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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
/* 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);
}
Ejemplo n.º 13
0
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);
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
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;
}
Ejemplo n.º 21
0
/*
 * 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;
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
/*
 * 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);
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
0
/*
 * 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);
}
Ejemplo n.º 26
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;
}
Ejemplo n.º 27
0
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;
}
Ejemplo n.º 28
0
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;
}
Ejemplo n.º 29
0
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;
}
Ejemplo n.º 30
0
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;
}