예제 #1
0
static krb5_error_code
decode_rx_header (krb5_storage *sp,
		  struct rx_header *h)
{
    krb5_error_code ret;

    ret = krb5_ret_uint32(sp, &h->epoch);
    if (ret) return ret;
    ret = krb5_ret_uint32(sp, &h->connid);
    if (ret) return ret;
    ret = krb5_ret_uint32(sp, &h->callid);
    if (ret) return ret;
    ret = krb5_ret_uint32(sp, &h->seqno);
    if (ret) return ret;
    ret = krb5_ret_uint32(sp, &h->serialno);
    if (ret) return ret;
    ret = krb5_ret_uint8(sp,  &h->type);
    if (ret) return ret;
    ret = krb5_ret_uint8(sp,  &h->flags);
    if (ret) return ret;
    ret = krb5_ret_uint8(sp,  &h->status);
    if (ret) return ret;
    ret = krb5_ret_uint8(sp,  &h->secindex);
    if (ret) return ret;
    ret = krb5_ret_uint16(sp, &h->reserved);
    if (ret) return ret;
    ret = krb5_ret_uint16(sp, &h->serviceid);
    if (ret) return ret;

    return 0;
}
예제 #2
0
파일: test_store.c 프로젝트: Henauxg/minix
static void
test_uint8(krb5_context context, krb5_storage *sp)
{
    krb5_error_code ret;
    int i;
    uint8_t val[] = {
	0, 1, 255
    }, v;

    krb5_storage_truncate(sp, 0);

    for (i = 0; i < sizeof(val[0])/sizeof(val); i++) {

	ret = krb5_store_uint8(sp, val[i]);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_store_uint8");
	krb5_storage_seek(sp, 0, SEEK_SET);
	ret = krb5_ret_uint8(sp, &v);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_ret_uint8");
	if (v != val[i])
	    krb5_errx(context, 1, "store and ret mismatch");
    }
}
예제 #3
0
krb5_error_code KRB5_LIB_FUNCTION
_krb5_krb_rd_req(krb5_context context,
		 krb5_data *authent,
		 const char *service,
		 const char *instance,
		 const char *local_realm,
		 int32_t from_addr,
		 const krb5_keyblock *key,
		 struct _krb5_krb_auth_data *ad)
{
    krb5_error_code ret;
    krb5_storage *sp;
    krb5_data ticket, eaut, aut;
    krb5_ssize_t size;
    int little_endian;
    int8_t pvno;
    int8_t type;
    int8_t s_kvno;
    uint8_t ticket_length;
    uint8_t eaut_length;
    uint8_t time_5ms;
    char *realm = NULL;
    char *sname = NULL;
    char *sinstance = NULL;
    char *r_realm = NULL;
    char *r_name = NULL;
    char *r_instance = NULL;

    uint32_t r_time_sec;	/* Coarse time from authenticator */
    unsigned long delta_t;      /* Time in authenticator - local time */
    long tkt_age;		/* Age of ticket */

    struct timeval tv;

    krb5_data_zero(&ticket);
    krb5_data_zero(&eaut);
    krb5_data_zero(&aut);

    sp = krb5_storage_from_data(authent);
    if (sp == NULL) {
	krb5_set_error_string(context, "alloc: out of memory");
	return ENOMEM;
    }

    krb5_storage_set_eof_code(sp, EINVAL); /* XXX */

    ret = krb5_ret_int8(sp, &pvno);
    if (ret)
	goto error;

    if (pvno != KRB_PROT_VERSION) {
	ret = EINVAL; /* XXX */
	goto error;
    }

    ret = krb5_ret_int8(sp, &type);
    if (ret)
	goto error;

    little_endian = type & 1;
    type &= ~1;
    
    if(type != AUTH_MSG_APPL_REQUEST && type != AUTH_MSG_APPL_REQUEST_MUTUAL) {
	ret = EINVAL; /* RD_AP_MSG_TYPE */
	goto error;
    }

    RCHECK(ret, krb5_ret_int8(sp, &s_kvno), error);
    RCHECK(ret, get_v4_stringz(sp, &realm, REALM_SZ), error);
    RCHECK(ret, krb5_ret_uint8(sp, &ticket_length), error);
    RCHECK(ret, krb5_ret_uint8(sp, &eaut_length), error);
    RCHECK(ret, krb5_data_alloc(&ticket, ticket_length), error);

    size = krb5_storage_read(sp, ticket.data, ticket.length);
    if (size != ticket.length) {
	ret = EINVAL;
	goto error;
    }

    /* Decrypt and take apart ticket */
    ret = _krb5_krb_decomp_ticket(context, &ticket, key, local_realm, 
				  &sname, &sinstance, ad);
    if (ret)
	goto error;

    RCHECK(ret, krb5_data_alloc(&eaut, eaut_length), error);

    size = krb5_storage_read(sp, eaut.data, eaut.length);
    if (size != eaut.length) {
	ret = EINVAL;
	goto error;
    }

    krb5_storage_free(sp);
    sp = NULL;

    ret = decrypt_etext(context, &ad->session, &eaut, &aut);
    if (ret)
	goto error;

    sp = krb5_storage_from_data(&aut);
    if (sp == NULL) {
	krb5_set_error_string(context, "alloc: out of memory");
	ret = ENOMEM;
	goto error;
    }

    if (little_endian)
	krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE);
    else
	krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);

    RCHECK(ret, get_v4_stringz(sp, &r_name, ANAME_SZ), error);
    RCHECK(ret, get_v4_stringz(sp, &r_instance, INST_SZ), error);
    RCHECK(ret, get_v4_stringz(sp, &r_realm, REALM_SZ), error);

    RCHECK(ret, krb5_ret_uint32(sp, &ad->checksum), error);
    RCHECK(ret, krb5_ret_uint8(sp, &time_5ms), error);
    RCHECK(ret, krb5_ret_uint32(sp, &r_time_sec), error);

    if (strcmp(ad->pname, r_name) != 0 ||
	strcmp(ad->pinst, r_instance) != 0 ||
	strcmp(ad->prealm, r_realm) != 0) {
	ret = EINVAL; /* RD_AP_INCON */
	goto error;
    }
    
    if (from_addr && from_addr != ad->address) {
	ret = EINVAL; /* RD_AP_BADD */
	goto error;
    }

    gettimeofday(&tv, NULL);
    delta_t = abs((int)(tv.tv_sec - r_time_sec));
    if (delta_t > CLOCK_SKEW) {
        ret = EINVAL; /* RD_AP_TIME */
	goto error;
    }

    /* Now check for expiration of ticket */

    tkt_age = tv.tv_sec - ad->time_sec;
    
    if ((tkt_age < 0) && (-tkt_age > CLOCK_SKEW)) {
        ret = EINVAL; /* RD_AP_NYV */
	goto error;
    }

    if (tv.tv_sec > _krb5_krb_life_to_time(ad->time_sec, ad->life)) {
	ret = EINVAL; /* RD_AP_EXP */
	goto error;
    }

    ret = 0;
 error:
    krb5_data_free(&ticket);
    krb5_data_free(&eaut);
    krb5_data_free(&aut);
    if (realm)
	free(realm);
    if (sname)
	free(sname);
    if (sinstance)
	free(sinstance);
    if (r_name)
	free(r_name);
    if (r_instance)
	free(r_instance);
    if (r_realm)
	free(r_realm);
    if (sp)
	krb5_storage_free(sp);

    if (ret)
	krb5_clear_error_string(context);

    return ret;
}
예제 #4
0
krb5_error_code KRB5_LIB_FUNCTION
_krb5_krb_decomp_ticket(krb5_context context,
			const krb5_data *enc_ticket,
			const krb5_keyblock *key,
			const char *local_realm,
			char **sname,
			char **sinstance,
			struct _krb5_krb_auth_data *ad)
{
    krb5_error_code ret;
    krb5_ssize_t size;
    krb5_storage *sp = NULL;
    krb5_data ticket;
    unsigned char des_key[8];

    memset(ad, 0, sizeof(*ad));
    krb5_data_zero(&ticket);

    *sname = NULL;
    *sinstance = NULL;

    RCHECK(ret, decrypt_etext(context, key, enc_ticket, &ticket), error);

    sp = krb5_storage_from_data(&ticket);
    if (sp == NULL) {
	krb5_data_free(&ticket);
	krb5_set_error_string(context, "alloc: out of memory");
	return ENOMEM;
    }

    krb5_storage_set_eof_code(sp, EINVAL); /* XXX */

    RCHECK(ret, krb5_ret_int8(sp, &ad->k_flags), error);
    RCHECK(ret, get_v4_stringz(sp, &ad->pname, ANAME_SZ), error);
    RCHECK(ret, get_v4_stringz(sp, &ad->pinst, INST_SZ), error);
    RCHECK(ret, get_v4_stringz(sp, &ad->prealm, REALM_SZ), error);
    RCHECK(ret, krb5_ret_uint32(sp, &ad->address), error);
	
    size = krb5_storage_read(sp, des_key, sizeof(des_key));
    if (size != sizeof(des_key)) {
	ret = EINVAL; /* XXX */
	goto error;
    }

    RCHECK(ret, krb5_ret_uint8(sp, &ad->life), error);

    if (ad->k_flags & 1)
	krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE);
    else
	krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);

    RCHECK(ret, krb5_ret_uint32(sp, &ad->time_sec), error);

    RCHECK(ret, get_v4_stringz(sp, sname, ANAME_SZ), error);
    RCHECK(ret, get_v4_stringz(sp, sinstance, INST_SZ), error);

    ret = krb5_keyblock_init(context, ETYPE_DES_PCBC_NONE,
			     des_key, sizeof(des_key), &ad->session);
    if (ret)
	goto error;

    if (strlen(ad->prealm) == 0) {
	free(ad->prealm);
	ad->prealm = strdup(local_realm);
	if (ad->prealm == NULL) {
	    ret = ENOMEM;
	    goto error;
	}
    }

 error:
    memset(des_key, 0, sizeof(des_key));
    if (sp)
	krb5_storage_free(sp);
    krb5_data_free(&ticket);
    if (ret) {
	if (*sname) {
	    free(*sname);
	    *sname = NULL;
	}
	if (*sinstance) {
	    free(*sinstance);
	    *sinstance = NULL;
	}
	_krb5_krb_free_auth_data(context, ad);
	krb5_set_error_string(context, "Failed to decode v4 ticket");
    }
    return ret;
}