示例#1
0
krb5_error_code KRB5_LIB_FUNCTION
_krb5_krb_create_ciph(krb5_context context,
		      const krb5_keyblock *session,
		      const char *service,
		      const char *instance,
		      const char *realm,
		      uint32_t life,
		      unsigned char kvno,
		      const krb5_data *ticket,
		      uint32_t kdc_time,
		      const krb5_keyblock *key,
		      krb5_data *enc_data)
{
    krb5_error_code ret;
    krb5_storage *sp;

    krb5_data_zero(enc_data);

    sp = krb5_storage_emem();
    if (sp == NULL) {
	krb5_set_error_string(context, "malloc: out of memory");
	return ENOMEM;
    }
    krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);

    /* session key */
    ret = krb5_storage_write(sp,
			     session->keyvalue.data, 
			     session->keyvalue.length);
    if (ret != session->keyvalue.length) {
	ret = EINVAL;
	goto error;
    }

    RCHECK(ret, put_nir(sp, service, instance, realm), error);
    RCHECK(ret, krb5_store_int8(sp, life), error);
    RCHECK(ret, krb5_store_int8(sp, kvno), error);
    RCHECK(ret, krb5_store_int8(sp, ticket->length), error);
    ret = krb5_storage_write(sp, ticket->data, ticket->length);
    if (ret != ticket->length) {
	ret = EINVAL;
	goto error;
    }
    RCHECK(ret, krb5_store_int32(sp, kdc_time), error);

    ret = storage_to_etext(context, sp, key, enc_data);

 error:
    krb5_storage_free(sp);
    if (ret)
	krb5_set_error_string(context, "Failed to encode kerberos 4 ticket");

    return ret;
}
示例#2
0
int
krb_mk_req(KTEXT authent,
	   char *service, char *instance, char *realm, 
	   int32_t checksum)

#endif
{
    CREDENTIALS cr;
    KTEXT_ST req;
    krb5_storage *sp;
    int code;
    /* XXX get user realm */
    const char *myrealm = realm;
    krb5_data a;

    code = krb_get_cred(service, instance, realm, &cr);
    if(code || time(NULL) > krb_life_to_time(cr.issue_date, cr.lifetime)){
	code = get_ad_tkt((char *)service,
			  (char *)instance, (char *)realm, lifetime);
	if(code == KSUCCESS)
	    code = krb_get_cred(service, instance, realm, &cr);
    }

    if(code)
	return code;

    sp = krb5_storage_emem();

    krb5_store_int8(sp, KRB_PROT_VERSION);
    krb5_store_int8(sp, AUTH_MSG_APPL_REQUEST);
    
    krb5_store_int8(sp, cr.kvno);
    krb5_store_stringz(sp, realm);
    krb5_store_int8(sp, cr.ticket_st.length);

    build_request(&req, cr.pname, cr.pinst, myrealm, checksum);
    encrypt_ktext(&req, &cr.session, DES_ENCRYPT);

    krb5_store_int8(sp, req.length);

    krb5_storage_write(sp, cr.ticket_st.dat, cr.ticket_st.length);
    krb5_storage_write(sp, req.dat, req.length);
    krb5_storage_to_data(sp, &a);
    krb5_storage_free(sp);
    memcpy(authent->dat, a.data, a.length);
    authent->length = a.length;
    krb5_data_free(&a);

    memset(&cr, 0, sizeof(cr));
    memset(&req, 0, sizeof(req));

    return KSUCCESS;
}
示例#3
0
krb5_error_code KRB5_LIB_FUNCTION
_krb5_krb_create_ticket(krb5_context context,
			unsigned char flags,
			const char *pname,
			const char *pinstance,
			const char *prealm,
			int32_t paddress,
			const krb5_keyblock *session,
			int16_t life,
			int32_t life_sec,
			const char *sname,
			const char *sinstance,
			const krb5_keyblock *key,
			krb5_data *enc_data)
{
    krb5_error_code ret;
    krb5_storage *sp;

    krb5_data_zero(enc_data);

    sp = krb5_storage_emem();
    if (sp == NULL) {
	krb5_set_error_string(context, "malloc: out of memory");
	return ENOMEM;
    }
    krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);

    RCHECK(ret, krb5_store_int8(sp, flags), error);
    RCHECK(ret, put_nir(sp, pname, pinstance, prealm), error);
    RCHECK(ret, krb5_store_int32(sp, ntohl(paddress)), error);

    /* session key */
    ret = krb5_storage_write(sp,
			     session->keyvalue.data, 
			     session->keyvalue.length);
    if (ret != session->keyvalue.length) {
	ret = EINVAL;
	goto error;
    }

    RCHECK(ret, krb5_store_int8(sp, life), error);
    RCHECK(ret, krb5_store_int32(sp, life_sec), error);
    RCHECK(ret, put_nir(sp, sname, sinstance, NULL), error);

    ret = storage_to_etext(context, sp, key, enc_data);

 error:
    krb5_storage_free(sp);
    if (ret)
	krb5_set_error_string(context, "Failed to encode kerberos 4 ticket");

    return ret;
}
示例#4
0
文件: fcache.c 项目: AllardJ/Tomato
static krb5_error_code
fcc_initialize(krb5_context context,
	       krb5_ccache id,
	       krb5_principal primary_principal)
{
    krb5_fcache *f = FCACHE(id);
    int ret = 0;
    int fd;
    char *filename = f->filename;

    unlink (filename);

    ret = fcc_open(context, id, &fd, O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, 0600);
    if(ret)
	return ret;
    {
	krb5_storage *sp;
	sp = krb5_storage_emem();
	krb5_storage_set_eof_code(sp, KRB5_CC_END);
	if(context->fcache_vno != 0)
	    f->version = context->fcache_vno;
	else
	    f->version = KRB5_FCC_FVNO_4;
	ret |= krb5_store_int8(sp, 5);
	ret |= krb5_store_int8(sp, f->version);
	storage_set_flags(context, sp, f->version);
	if(f->version == KRB5_FCC_FVNO_4 && ret == 0) {
	    /* V4 stuff */
	    if (context->kdc_sec_offset) {
		ret |= krb5_store_int16 (sp, 12); /* length */
		ret |= krb5_store_int16 (sp, FCC_TAG_DELTATIME); /* Tag */
		ret |= krb5_store_int16 (sp, 8); /* length of data */
		ret |= krb5_store_int32 (sp, context->kdc_sec_offset);
		ret |= krb5_store_int32 (sp, context->kdc_usec_offset);
	    } else {
		ret |= krb5_store_int16 (sp, 0);
	    }
	}
	ret |= krb5_store_principal(sp, primary_principal);
	
	ret |= write_storage(context, sp, fd);

	krb5_storage_free(sp);
    }
    fcc_unlock(context, fd);
    if (close(fd) < 0)
	if (ret == 0) {
	    ret = errno;
	    krb5_set_error_message (context, ret, N_("close %s: %s", ""),
				    FILENAME(id), strerror(ret));
	}
    return ret;
}
示例#5
0
static krb5_error_code KRB5_CALLCONV
fkt_setup_keytab(krb5_context context,
		 krb5_keytab id,
		 krb5_storage *sp)
{
    krb5_error_code ret;
    ret = krb5_store_int8(sp, 5);
    if(ret)
	return ret;
    if(id->version == 0)
	id->version = KRB5_KT_VNO;
    return krb5_store_int8 (sp, id->version);
}
示例#6
0
文件: store.c 项目: brianmay/heimdal
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
{
    int ret;

    ret = krb5_store_principal(sp, creds->client);
    if(ret)
	return ret;
    ret = krb5_store_principal(sp, creds->server);
    if(ret)
	return ret;
    ret = krb5_store_keyblock(sp, creds->session);
    if(ret)
	return ret;
    ret = krb5_store_times(sp, creds->times);
    if(ret)
	return ret;
    ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
    if(ret)
	return ret;
    ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
    if(ret)
	return ret;
    ret = krb5_store_addrs(sp, creds->addresses);
    if(ret)
	return ret;
    ret = krb5_store_authdata(sp, creds->authdata);
    if(ret)
	return ret;
    ret = krb5_store_data(sp, creds->ticket);
    if(ret)
	return ret;
    ret = krb5_store_data(sp, creds->second_ticket);
    return ret;
}
示例#7
0
krb5_error_code KRB5_LIB_FUNCTION
_krb5_krb_create_auth_reply(krb5_context context,
			    const char *pname,
			    const char *pinst,
			    const char *prealm,
			    int32_t time_ws,
			    int n,
			    uint32_t x_date,
			    unsigned char kvno,
			    const krb5_data *cipher,
			    krb5_data *data)
{
    krb5_error_code ret;
    krb5_storage *sp;

    krb5_data_zero(data);

    sp = krb5_storage_emem();
    if (sp == NULL) {
	krb5_set_error_string(context, "malloc: out of memory");
	return ENOMEM;
    }
    krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);

    RCHECK(ret, krb5_store_int8(sp, KRB_PROT_VERSION), error);
    RCHECK(ret, krb5_store_int8(sp, AUTH_MSG_KDC_REPLY), error);
    RCHECK(ret, put_nir(sp, pname, pinst, prealm), error);
    RCHECK(ret, krb5_store_int32(sp, time_ws), error);
    RCHECK(ret, krb5_store_int8(sp, n), error);
    RCHECK(ret, krb5_store_int32(sp, x_date), error);
    RCHECK(ret, krb5_store_int8(sp, kvno), error);
    RCHECK(ret, krb5_store_int16(sp, cipher->length), error);
    ret = krb5_storage_write(sp, cipher->data, cipher->length);
    if (ret != cipher->length) {
	ret = EINVAL;
	goto error;
    }

    ret = krb5_storage_to_data(sp, data);

 error:
    krb5_storage_free(sp);
    if (ret)
	krb5_set_error_string(context, "Failed to encode kerberos 4 ticket");
	
    return ret;
}
示例#8
0
/*
 * Request:
 *      NameZ
 *
 * Request:
 *      NameZ
 *      ClientPrincipal
 *      ServerPrincipalPresent
 *      ServerPrincipal OPTIONAL
 *      Password
 *
 * Repsonse:
 *
 */
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_kcm_get_initial_ticket(krb5_context context,
			     krb5_ccache id,
			     krb5_principal client,
			     krb5_principal server,
			     const char *password)
{
    krb5_kcmcache *k = KCMCACHE(id);
    krb5_error_code ret;
    krb5_storage *request;

    if (id->ops != &krb5_kcm_ops && id->ops != &krb5_akcm_ops) {
	krb5_set_error_message(context, EINVAL, "Cache is not a KCM cache");
	return EINVAL;
    }

    ret = krb5_kcm_storage_request(context, KCM_OP_GET_INITIAL_TICKET, &request);
    if (ret)
	return ret;

    ret = krb5_store_stringz(request, k->name);
    if (ret) {
	krb5_storage_free(request);
	return ret;
    }

    ret = krb5_store_principal(request, client);
    if (ret) {
	krb5_storage_free(request);
	return ret;
    }

    ret = krb5_store_int8(request, (server == NULL) ? 0 : 1);
    if (ret) {
	krb5_storage_free(request);
	return ret;
    }

    if (server != NULL) {
	ret = krb5_store_principal(request, server);
	if (ret) {
	    krb5_storage_free(request);
	    return ret;
	}
    }

    ret = krb5_store_stringz(request, password);
    if (ret) {
	krb5_storage_free(request);
	return ret;
    }

    ret = krb5_kcm_call(context, request, NULL, NULL);
    krb5_storage_free(request);

    return ret;
}
示例#9
0
krb5_error_code KRB5_LIB_FUNCTION
_krb5_krb_cr_err_reply(krb5_context context,
		       const char *name,
		       const char *inst,
		       const char *realm,
		       uint32_t time_ws,
		       uint32_t e,
		       const char *e_string,
		       krb5_data *data)
{
    krb5_error_code ret;
    krb5_storage *sp;

    krb5_data_zero(data);

    if (name == NULL) name = "";
    if (inst == NULL) inst = "";
    if (realm == NULL) realm = "";
    if (e_string == NULL) e_string = "";

    sp = krb5_storage_emem();
    if (sp == NULL) {
	krb5_set_error_string(context, "malloc: out of memory");
	return ENOMEM;
    }
    krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);

    RCHECK(ret, krb5_store_int8(sp, KRB_PROT_VERSION), error);
    RCHECK(ret, krb5_store_int8(sp, AUTH_MSG_ERR_REPLY), error);
    RCHECK(ret, put_nir(sp, name, inst, realm), error);
    RCHECK(ret, krb5_store_int32(sp, time_ws), error);
    RCHECK(ret, krb5_store_int32(sp, e), error);
    RCHECK(ret, krb5_store_stringz(sp, e_string), error);

    ret = krb5_storage_to_data(sp, data);

 error:
    krb5_storage_free(sp);
    if (ret)
	krb5_set_error_string(context, "Failed to encode kerberos 4 error");
	
    return 0;
}
示例#10
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_kcm_storage_request(krb5_context context,
			 uint16_t opcode,
			 krb5_storage **storage_p)
{
    krb5_storage *sp;
    krb5_error_code ret;

    *storage_p = NULL;

    sp = krb5_storage_emem();
    if (sp == NULL) {
	krb5_set_error_message(context, KRB5_CC_NOMEM, N_("malloc: out of memory", ""));
	return KRB5_CC_NOMEM;
    }

    /* Send MAJOR | VERSION | OPCODE */
    ret  = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MAJOR);
    if (ret)
	goto fail;
    ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MINOR);
    if (ret)
	goto fail;
    ret = krb5_store_int16(sp, opcode);
    if (ret)
	goto fail;

    *storage_p = sp;
 fail:
    if (ret) {
	krb5_set_error_message(context, ret,
			       N_("Failed to encode KCM request", ""));
	krb5_storage_free(sp);
    }

    return ret;
}
示例#11
0
static krb5_error_code
kcm_storage_request(krb5_context context,
		    kcm_operation opcode,
		    krb5_storage **storage_p)
{
    krb5_storage *sp;
    krb5_error_code ret;

    *storage_p = NULL;

    sp = krb5_storage_emem();
    if (sp == NULL) {
	krb5_set_error_string(context, "malloc: out of memory");
	return KRB5_CC_NOMEM;
    }

    /* Send MAJOR | VERSION | OPCODE */
    ret  = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MAJOR);
    if (ret)
	goto fail;
    ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MINOR);
    if (ret)
	goto fail;
    ret = krb5_store_int16(sp, opcode);
    if (ret)
	goto fail;

    *storage_p = sp;
 fail:
    if (ret) {
	krb5_set_error_string(context, "Failed to encode request");
	krb5_storage_free(sp);
    }
   
    return ret; 
}
示例#12
0
/*
 * Request:
 *      NameZ
 *      ServerPrincipalPresent
 *      ServerPrincipal OPTIONAL
 *      Key
 *
 * Repsonse:
 *
 */
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_kcm_get_initial_ticket(krb5_context context,
			     krb5_ccache id,
			     krb5_principal server,
			     krb5_keyblock *key)
{
    krb5_kcmcache *k = KCMCACHE(id);
    krb5_error_code ret;
    krb5_storage *request;

    ret = krb5_kcm_storage_request(context, KCM_OP_GET_INITIAL_TICKET, &request);
    if (ret)
	return ret;

    ret = krb5_store_stringz(request, k->name);
    if (ret) {
	krb5_storage_free(request);
	return ret;
    }

    ret = krb5_store_int8(request, (server == NULL) ? 0 : 1);
    if (ret) {
	krb5_storage_free(request);
	return ret;
    }

    if (server != NULL) {
	ret = krb5_store_principal(request, server);
	if (ret) {
	    krb5_storage_free(request);
	    return ret;
	}
    }

    ret = krb5_store_keyblock(request, *key);
    if (ret) {
	krb5_storage_free(request);
	return ret;
    }

    ret = krb5_kcm_call(context, request, NULL, NULL);

    krb5_storage_free(request);
    return ret;
}
示例#13
0
static void
build_request(KTEXT req,
	      const char *name, const char *inst, const char *realm, 
	      u_int32_t checksum)
{
    struct timeval tv;
    krb5_storage *sp;
    krb5_data data;
    sp = krb5_storage_emem();
    krb5_store_stringz(sp, name);
    krb5_store_stringz(sp, inst);
    krb5_store_stringz(sp, realm);
    krb5_store_int32(sp, checksum);
    gettimeofday(&tv, NULL);
    krb5_store_int8(sp, tv.tv_usec  / 5000);
    krb5_store_int32(sp, tv.tv_sec);
    krb5_storage_to_data(sp, &data);
    krb5_storage_free(sp);
    memcpy(req->dat, data.data, data.length);
    req->length = (data.length + 7) & ~7;
    krb5_data_free(&data);
}
示例#14
0
static void
test_int8(krb5_context context, krb5_storage *sp)
{
    krb5_error_code ret;
    int i;
    int8_t val[] = {
	0, 1, -1, 128, -127
    }, v;

    krb5_storage_truncate(sp, 0);

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

	ret = krb5_store_int8(sp, val[i]);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_store_int8");
	krb5_storage_seek(sp, 0, SEEK_SET);
	ret = krb5_ret_int8(sp, &v);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_ret_int8");
	if (v != val[i])
	    krb5_errx(context, 1, "store and ret mismatch");
    }
}
示例#15
0
static krb5_error_code KRB5_CALLCONV
fkt_add_entry(krb5_context context,
	      krb5_keytab id,
	      krb5_keytab_entry *entry)
{
    int ret;
    int fd;
    krb5_storage *sp;
    struct fkt_data *d = id->data;
    krb5_data keytab;
    int32_t len;

    fd = open (d->filename, O_RDWR | O_BINARY | O_CLOEXEC);
    if (fd < 0) {
	fd = open (d->filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, 0600);
	if (fd < 0) {
	    ret = errno;
	    krb5_set_error_message(context, ret,
				   N_("open(%s): %s", ""), d->filename,
				   strerror(ret));
	    return ret;
	}
	rk_cloexec(fd);

	ret = _krb5_xlock(context, fd, 1, d->filename);
	if (ret) {
	    close(fd);
	    return ret;
	}
	sp = krb5_storage_from_fd(fd);
	krb5_storage_set_eof_code(sp, KRB5_KT_END);
	ret = fkt_setup_keytab(context, id, sp);
	if(ret) {
	    goto out;
	}
	storage_set_flags(context, sp, id->version);
    } else {
	int8_t pvno, tag;

	rk_cloexec(fd);

	ret = _krb5_xlock(context, fd, 1, d->filename);
	if (ret) {
	    close(fd);
	    return ret;
	}
	sp = krb5_storage_from_fd(fd);
	krb5_storage_set_eof_code(sp, KRB5_KT_END);
	ret = krb5_ret_int8(sp, &pvno);
	if(ret) {
	    /* we probably have a zero byte file, so try to set it up
               properly */
	    ret = fkt_setup_keytab(context, id, sp);
	    if(ret) {
		krb5_set_error_message(context, ret,
				       N_("%s: keytab is corrupted: %s", ""),
				       d->filename, strerror(ret));
		goto out;
	    }
	    storage_set_flags(context, sp, id->version);
	} else {
	    if(pvno != 5) {
		ret = KRB5_KEYTAB_BADVNO;
		krb5_set_error_message(context, ret,
				       N_("Bad version in keytab %s", ""),
				       d->filename);
		goto out;
	    }
	    ret = krb5_ret_int8 (sp, &tag);
	    if (ret) {
		krb5_set_error_message(context, ret,
				       N_("failed reading tag from "
					  "keytab %s", ""),
				       d->filename);
		goto out;
	    }
	    id->version = tag;
	    storage_set_flags(context, sp, id->version);
	}
    }

    {
	krb5_storage *emem;
	emem = krb5_storage_emem();
	if(emem == NULL) {
	    ret = krb5_enomem(context);
	    goto out;
	}
	ret = krb5_kt_store_principal(context, emem, entry->principal);
	if(ret) {
	    krb5_set_error_message(context, ret,
				   N_("Failed storing principal "
				      "in keytab %s", ""),
				   d->filename);
	    krb5_storage_free(emem);
	    goto out;
	}
	ret = krb5_store_int32 (emem, entry->timestamp);
	if(ret) {
	    krb5_set_error_message(context, ret,
				   N_("Failed storing timpstamp "
				      "in keytab %s", ""),
				   d->filename);
	    krb5_storage_free(emem);
	    goto out;
	}
	ret = krb5_store_int8 (emem, entry->vno % 256);
	if(ret) {
	    krb5_set_error_message(context, ret,
				   N_("Failed storing kvno "
				      "in keytab %s", ""),
				   d->filename);
	    krb5_storage_free(emem);
	    goto out;
	}
	ret = krb5_kt_store_keyblock (context, d, emem, &entry->keyblock);
	if(ret) {
	    krb5_storage_free(emem);
	    goto out;
	}
	if ((d->flags & KRB5_KT_FL_JAVA) == 0) {
	    ret = krb5_store_int32 (emem, entry->vno);
	    if (ret) {
		krb5_set_error_message(context, ret,
				       N_("Failed storing extended kvno "
					  "in keytab %s", ""),
				       d->filename);
		krb5_storage_free(emem);
		goto out;
	    }
	    ret = krb5_store_uint32 (emem, entry->flags);
	    if (ret) {
		krb5_set_error_message(context, ret,
				       N_("Failed storing extended kvno "
					  "in keytab %s", ""),
				       d->filename);
		krb5_storage_free(emem);
		goto out;
	    }
	}

	ret = krb5_storage_to_data(emem, &keytab);
	krb5_storage_free(emem);
	if(ret) {
	    krb5_set_error_message(context, ret,
				   N_("Failed converting keytab entry "
				      "to memory block for keytab %s", ""),
				   d->filename);
	    goto out;
	}
    }

    while(1) {
	ret = krb5_ret_int32(sp, &len);
	if(ret == KRB5_KT_END) {
	    len = keytab.length;
	    break;
	}
	if(len < 0) {
	    len = -len;
	    if(len >= (int)keytab.length) {
		krb5_storage_seek(sp, -4, SEEK_CUR);
		break;
	    }
	}
	krb5_storage_seek(sp, len, SEEK_CUR);
    }
    ret = krb5_store_int32(sp, len);
    if(krb5_storage_write(sp, keytab.data, keytab.length) < 0) {
	ret = errno;
	krb5_set_error_message(context, ret,
			       N_("Failed writing keytab block "
				  "in keytab %s: %s", ""),
			       d->filename, strerror(ret));
    }
    memset(keytab.data, 0, keytab.length);
    krb5_data_free(&keytab);
  out:
    krb5_storage_free(sp);
    _krb5_xunlock(context, fd);
    close(fd);
    return ret;
}
示例#16
0
文件: store.c 项目: 2asoft/freebsd
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_uint8(krb5_storage *sp,
		 uint8_t value)
{
    return krb5_store_int8(sp, (int8_t)value);
}
示例#17
0
文件: store.c 项目: 2asoft/freebsd
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
{
    int ret;
    int32_t header = 0;

    if (creds->client)
	header |= SC_CLIENT_PRINCIPAL;
    if (creds->server)
	header |= SC_SERVER_PRINCIPAL;
    if (creds->session.keytype != ETYPE_NULL)
	header |= SC_SESSION_KEY;
    if (creds->ticket.data)
	header |= SC_TICKET;
    if (creds->second_ticket.length)
	header |= SC_SECOND_TICKET;
    if (creds->authdata.len)
	header |= SC_AUTHDATA;
    if (creds->addresses.len)
	header |= SC_ADDRESSES;

    ret = krb5_store_int32(sp, header);
    if (ret)
	return ret;

    if (creds->client) {
	ret = krb5_store_principal(sp, creds->client);
	if(ret)
	    return ret;
    }

    if (creds->server) {
	ret = krb5_store_principal(sp, creds->server);
	if(ret)
	    return ret;
    }

    if (creds->session.keytype != ETYPE_NULL) {
	ret = krb5_store_keyblock(sp, creds->session);
	if(ret)
	    return ret;
    }

    ret = krb5_store_times(sp, creds->times);
    if(ret)
	return ret;
    ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
    if(ret)
	return ret;

    ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
    if(ret)
	return ret;

    if (creds->addresses.len) {
	ret = krb5_store_addrs(sp, creds->addresses);
	if(ret)
	    return ret;
    }

    if (creds->authdata.len) {
	ret = krb5_store_authdata(sp, creds->authdata);
	if(ret)
	    return ret;
    }

    if (creds->ticket.data) {
	ret = krb5_store_data(sp, creds->ticket);
	if(ret)
	    return ret;
    }

    if (creds->second_ticket.data) {
	ret = krb5_store_data(sp, creds->second_ticket);
	if (ret)
	    return ret;
    }

    return ret;
}
示例#18
0
static krb5_error_code
fkt_add_entry(krb5_context context,
	      krb5_keytab id,
	      krb5_keytab_entry *entry)
{
    int ret;
    int fd;
    krb5_storage *sp;
    struct fkt_data *d = id->data;
    krb5_data keytab;
    int32_t len;
    
    fd = open (d->filename, O_RDWR | O_BINARY);
    if (fd < 0) {
	fd = open (d->filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
	if (fd < 0) {
	    ret = errno;
	    krb5_set_error_string(context, "open(%s): %s", d->filename,
				  strerror(ret));
	    return ret;
	}
	ret = _krb5_xlock(context, fd, 1, d->filename);
	if (ret) {
	    close(fd);
	    return ret;
	}
	sp = krb5_storage_from_fd(fd);
	krb5_storage_set_eof_code(sp, KRB5_KT_END);
	ret = fkt_setup_keytab(context, id, sp);
	if(ret) {
	    goto out;
	}
	storage_set_flags(context, sp, id->version);
    } else {
	int8_t pvno, tag;
	ret = _krb5_xlock(context, fd, 1, d->filename);
	if (ret) {
	    close(fd);
	    return ret;
	}
	sp = krb5_storage_from_fd(fd);
	krb5_storage_set_eof_code(sp, KRB5_KT_END);
	ret = krb5_ret_int8(sp, &pvno);
	if(ret) {
	    /* we probably have a zero byte file, so try to set it up
               properly */
	    ret = fkt_setup_keytab(context, id, sp);
	    if(ret) {
		krb5_set_error_string(context, "%s: keytab is corrupted: %s", 
				      d->filename, strerror(ret));
		goto out;
	    }
	    storage_set_flags(context, sp, id->version);
	} else {
	    if(pvno != 5) {
		ret = KRB5_KEYTAB_BADVNO;
		krb5_set_error_string(context, "%s: %s", 
				      d->filename, strerror(ret));
		goto out;
	    }
	    ret = krb5_ret_int8 (sp, &tag);
	    if (ret) {
		krb5_set_error_string(context, "%s: reading tag: %s", 
				      d->filename, strerror(ret));
		goto out;
	    }
	    id->version = tag;
	    storage_set_flags(context, sp, id->version);
	}
    }

    {
	krb5_storage *emem;
	emem = krb5_storage_emem();
	if(emem == NULL) {
	    ret = ENOMEM;
	    krb5_set_error_string (context, "malloc: out of memory");
	    goto out;
	}
	ret = krb5_kt_store_principal(context, emem, entry->principal);
	if(ret) {
	    krb5_storage_free(emem);
	    goto out;
	}
	ret = krb5_store_int32 (emem, entry->timestamp);
	if(ret) {
	    krb5_storage_free(emem);
	    goto out;
	}
	ret = krb5_store_int8 (emem, entry->vno % 256);
	if(ret) {
	    krb5_storage_free(emem);
	    goto out;
	}
	ret = krb5_kt_store_keyblock (context, emem, &entry->keyblock);
	if(ret) {
	    krb5_storage_free(emem);
	    goto out;
	}
	if ((d->flags & KRB5_KT_FL_JAVA) == 0) {
	    ret = krb5_store_int32 (emem, entry->vno);
	    if (ret) {
		krb5_storage_free(emem);
		goto out;
	    }
	}

	ret = krb5_storage_to_data(emem, &keytab);
	krb5_storage_free(emem);
	if(ret)
	    goto out;
    }
    
    while(1) {
	ret = krb5_ret_int32(sp, &len);
	if(ret == KRB5_KT_END) {
	    len = keytab.length;
	    break;
	}
	if(len < 0) {
	    len = -len;
	    if(len >= keytab.length) {
		krb5_storage_seek(sp, -4, SEEK_CUR);
		break;
	    }
	}
	krb5_storage_seek(sp, len, SEEK_CUR);
    }
    ret = krb5_store_int32(sp, len);
    if(krb5_storage_write(sp, keytab.data, keytab.length) < 0)
	ret = errno;
    memset(keytab.data, 0, keytab.length);
    krb5_data_free(&keytab);
  out:
    krb5_storage_free(sp);
    _krb5_xunlock(context, fd);
    close(fd);
    return ret;
}