Example #1
0
/*
 * Request:
 *      NameZ
 *      Cursor
 *
 * Response:
 *      Creds
 */
static krb5_error_code
kcm_get_next (krb5_context context,
		krb5_ccache id,
		krb5_cc_cursor *cursor,
		krb5_creds *creds)
{
    krb5_error_code ret;
    krb5_kcmcache *k = KCMCACHE(id);
    krb5_storage *request, *response;
    krb5_data response_data;

    ret = kcm_storage_request(context, KCM_OP_GET_NEXT, &request);
    if (ret)
	return ret;

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

    ret = krb5_store_int32(request, KCMCURSOR(*cursor));
    if (ret) {
	krb5_storage_free(request);
	return ret;
    }

    ret = kcm_call(context, k, request, &response, &response_data);
    if (ret) {
	krb5_storage_free(request);
	return ret;
    }

    ret = krb5_ret_creds(response, creds);
    if (ret)
	ret = KRB5_CC_IO;

    krb5_storage_free(request);
    krb5_storage_free(response);
    krb5_data_free(&response_data);

    return ret;
}
static OM_uint32 inquire_sec_context_authz_data
           (OM_uint32 *minor_status,
            const gsskrb5_ctx context_handle,
	    krb5_context context,
            unsigned ad_type,
            gss_buffer_set_t *data_set)
{
    krb5_data data;
    gss_buffer_desc ad_data;
    OM_uint32 ret;

    *minor_status = 0;
    *data_set = GSS_C_NO_BUFFER_SET;

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    if (context_handle->ticket == NULL) {
	HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
	*minor_status = EINVAL;
	_gsskrb5_set_status(EINVAL, "No ticket to obtain authz data from");
	return GSS_S_NO_CONTEXT;
    }

    ret = krb5_ticket_get_authorization_data_type(context,
						  context_handle->ticket,
						  ad_type,
						  &data);
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    ad_data.value = data.data;
    ad_data.length = data.length;

    ret = gss_add_buffer_set_member(minor_status,
				    &ad_data,
				    data_set);

    krb5_data_free(&data);

    return ret;
}
Example #3
0
static int
krb_enc_mit(krb5_context context,
	    krb5_enctype enctype,
	    krb5_keyblock *key,
	    unsigned usage,
	    krb5_data *cipher,
	    krb5_data *clear)
{
#ifndef HEIMDAL_SMALLER
    krb5_error_code ret;
    krb5_enc_data e;
    krb5_data decrypt;
    size_t len;

    e.kvno = 0;
    e.enctype = enctype;
    e.ciphertext = *cipher;

    ret = krb5_c_decrypt(context, *key, usage, NULL, &e, &decrypt);
    if (ret)
	return ret;

    if (decrypt.length != clear->length ||
	memcmp(decrypt.data, clear->data, decrypt.length) != 0) {
	krb5_warnx(context, "clear text not same");
	return EINVAL;
    }

    krb5_data_free(&decrypt);

    ret = krb5_c_encrypt_length(context, enctype, clear->length, &len);
    if (ret)
	return ret;

    if (len != cipher->length) {
	krb5_warnx(context, "c_encrypt_length wrong %lu != %lu",
		   (unsigned long)len, (unsigned long)cipher->length);
	return EINVAL;
    }
#endif /* HEIMDAL_SMALLER */
    return 0;
}
Example #4
0
static krb5_error_code
decrypt_tkt (krb5_context context,
	     krb5_keyblock *key,
	     krb5_key_usage usage,
	     krb5_const_pointer decrypt_arg,
	     krb5_kdc_rep *dec_rep)
{
    krb5_error_code ret;
    krb5_data data;
    size_t size;
    krb5_crypto crypto;

    ret = krb5_crypto_init(context, key, 0, &crypto);
    if (ret)
	return ret;

    ret = krb5_decrypt_EncryptedData (context,
				      crypto,
				      usage,
				      &dec_rep->kdc_rep.enc_part,
				      &data);
    krb5_crypto_destroy(context, crypto);

    if (ret)
	return ret;

    ret = krb5_decode_EncASRepPart(context,
				   data.data,
				   data.length,
				   &dec_rep->enc_part, 
				   &size);
    if (ret)
	ret = krb5_decode_EncTGSRepPart(context,
					data.data,
					data.length,
					&dec_rep->enc_part, 
					&size);
    krb5_data_free (&data);
    if (ret)
	return ret;
    return 0;
}
Example #5
0
static krb5_error_code
pac_verify(void *ctx, krb5_context context,
	   const krb5_principal client_principal,
	   struct hdb_entry_ex *client,
	   struct hdb_entry_ex *server,
	   krb5_pac *pac)
{
    krb5_error_code ret;
    krb5_data data;

    krb5_warnx(context, "pac_verify");

    ret = krb5_pac_get_buffer(context, *pac, 1, &data);
    if (ret)
	return ret;

    krb5_data_free(&data);

    return 0;
}
Example #6
0
static void
free_init_creds_ctx(krb5_context context, krb5_init_creds_context ctx)
{
    if (ctx->etypes)
	free(ctx->etypes);
    if (ctx->pre_auth_types)
	free (ctx->pre_auth_types);
    if (ctx->in_tkt_service)
	free(ctx->in_tkt_service);
    if (ctx->keytab_data)
	free(ctx->keytab_data);
    krb5_data_free(&ctx->req_buffer);
    krb5_free_cred_contents(context, &ctx->cred);
    free_METHOD_DATA(&ctx->md);
    free_AS_REP(&ctx->as_rep);
    free_EncKDCRepPart(&ctx->enc_part);
    free_KRB_ERROR(&ctx->error);
    free_AS_REQ(&ctx->as_req);
    memset(ctx, 0, sizeof(*ctx));
}
Example #7
0
static void
test_mic(struct client *c1, int32_t hc1, struct client *c2, int32_t hc2)
{
    krb5_data msg, mic;
    int32_t val;

    msg.data = "foo";
    msg.length = 3;

    krb5_data_zero(&mic);

    val = get_mic(c1, hc1, &msg, &mic);
    if (val)
	errx(1, "get_mic failed to host: %s", c1->moniker);
    val = verify_mic(c2, hc2, &msg, &mic);
    if (val)
	errx(1, "verify_mic failed to host: %s", c2->moniker);

    krb5_data_free(&mic);
}
Example #8
0
kadm5_ret_t
kadm5_log_replay_rename (kadm5_server_context *context,
			 u_int32_t ver,
			 u_int32_t len,
			 krb5_storage *sp)
{
    krb5_error_code ret;
    krb5_principal source;
    hdb_entry source_ent, target_ent;
    krb5_data value;
    off_t off;
    size_t princ_len, data_len;

    off = krb5_storage_seek(sp, 0, SEEK_CUR);
    krb5_ret_principal (sp, &source);
    princ_len = krb5_storage_seek(sp, 0, SEEK_CUR) - off;
    data_len = len - princ_len;
    ret = krb5_data_alloc (&value, data_len);
    if (ret) {
	krb5_free_principal (context->context, source);
	return ret;
    }
    krb5_storage_read (sp, value.data, data_len);
    ret = hdb_value2entry (context->context, &value, &target_ent);
    krb5_data_free(&value);
    if (ret) {
	krb5_free_principal (context->context, source);
	return ret;
    }
    ret = context->db->hdb_store (context->context, context->db, 
				  0, &target_ent);
    hdb_free_entry (context->context, &target_ent);
    if (ret) {
	krb5_free_principal (context->context, source);
	return ret;
    }
    source_ent.principal = source;
    ret = context->db->hdb_remove (context->context, context->db, &source_ent);
    krb5_free_principal (context->context, source);
    return ret;
}
Example #9
0
kadm5_ret_t
_kadm5_client_recv(kadm5_client_context *context, krb5_data *reply)
{
    krb5_error_code ret;
    krb5_data data;
    krb5_storage *sock;

    sock = krb5_storage_from_fd(context->sock);
    if(sock == NULL)
	return ENOMEM;
    ret = krb5_ret_data(sock, &data);
    krb5_storage_free(sock);
    if(ret == KRB5_CC_END)
	return KADM5_RPC_ERROR;
    else if(ret)
	return ret;

    ret = krb5_rd_priv(context->context, context->ac, &data, reply, NULL);
    krb5_data_free(&data);
    return ret;
}
Example #10
0
static krb5_error_code KRB5_CALLCONV
acc_close(krb5_context context,
	  krb5_ccache id)
{
    krb5_acc *a = ACACHE(id);

    if (a->ccache) {
	(*a->ccache->func->release)(a->ccache);
	a->ccache = NULL;
    }
    if (a->cache_name) {
	free(a->cache_name);
	a->cache_name = NULL;
    }
    if (a->context) {
	(*a->context->func->release)(a->context);
	a->context = NULL;
    }
    krb5_data_free(&id->data);
    return 0;
}
Example #11
0
/*
 * Request:
 *
 * Response:
 *      NameZ
 */
static krb5_error_code
kcm_gen_new(krb5_context context, krb5_ccache *id)
{
    krb5_kcmcache *k;
    krb5_error_code ret;
    krb5_storage *request, *response;
    krb5_data response_data;

    ret = kcm_alloc(context, NULL, id);
    if (ret)
	return ret;

    k = KCMCACHE(*id);

    ret = krb5_kcm_storage_request(context, KCM_OP_GEN_NEW, &request);
    if (ret) {
	kcm_free(context, id);
	return ret;
    }

    ret = krb5_kcm_call(context, request, &response, &response_data);
    if (ret) {
	krb5_storage_free(request);
	kcm_free(context, id);
	return ret;
    }

    ret = krb5_ret_stringz(response, &k->name);
    if (ret)
	ret = KRB5_CC_IO;

    krb5_storage_free(request);
    krb5_storage_free(response);
    krb5_data_free(&response_data);

    if (ret)
	kcm_free(context, id);

    return ret;
}
Example #12
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_init_creds_get(krb5_context context, krb5_init_creds_context ctx)
{
    krb5_sendto_ctx stctx = NULL;
    krb5_krbhst_info *hostinfo = NULL;
    krb5_error_code ret;
    krb5_data in, out;
    unsigned int flags = 0;

    krb5_data_zero(&in);
    krb5_data_zero(&out);

    ret = krb5_sendto_ctx_alloc(context, &stctx);
    if (ret)
	goto out;
    krb5_sendto_ctx_set_func(stctx, _krb5_kdc_retry, NULL);

    while (1) {
	flags = 0;
	ret = krb5_init_creds_step(context, ctx, &in, &out, hostinfo, &flags);
	krb5_data_free(&in);
	if (ret)
	    goto out;

	if ((flags & 1) == 0)
	    break;

	ret = krb5_sendto_context (context, stctx, &out, 
				   ctx->cred.client->realm, &in);
    	if (ret)
	    goto out;

    }

 out:
    if (stctx)
	krb5_sendto_ctx_free(context, stctx);

    return ret;
}
Example #13
0
static OM_uint32
_gss_ntlm_destroy_kcm_cred(gss_cred_id_t *cred_handle)
{
    krb5_storage *request, *response;
    krb5_data response_data;
    krb5_context context;
    krb5_error_code ret;
    ntlm_cred cred;

    cred = (ntlm_cred)*cred_handle;

    ret = krb5_init_context(&context);
    if (ret)
        return ret;

    ret = krb5_kcm_storage_request(context, KCM_OP_DEL_NTLM_CRED, &request);
    if (ret)
	goto out;

    ret = krb5_store_stringz(request, cred->username);
    if (ret)
	goto out;

    ret = krb5_store_stringz(request, cred->domain);
    if (ret)
	goto out;

    ret = krb5_kcm_call(context, request, &response, &response_data);
    if (ret)
	goto out;

    krb5_storage_free(request);
    krb5_storage_free(response);
    krb5_data_free(&response_data);

 out:
    krb5_free_context(context);

    return ret;
}
Example #14
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_read_message (krb5_context context,
		   krb5_pointer p_fd,
		   krb5_data *data)
{
    krb5_error_code ret;
    krb5_ssize_t sret;
    uint32_t len;
    uint8_t buf[4];

    krb5_data_zero(data);

    sret = krb5_net_read (context, p_fd, buf, 4);
    if(sret == -1) {
	ret = errno;
	krb5_clear_error_message (context);
	return ret;
    }
    if(sret < 4) {
	krb5_clear_error_message(context);
	return HEIM_ERR_EOF;
    }
    len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
    if (len > UINT_MAX / 16) {
	krb5_set_error_message(context, ERANGE, N_("packet to large", ""));
	return ERANGE;
    }
    ret = krb5_data_alloc (data, len);
    if (ret) {
	krb5_clear_error_message(context);
	return ret;
    }
    if (krb5_net_read (context, p_fd, data->data, len) != (ssize_t)len) {
	ret = errno;
	krb5_data_free (data);
	krb5_clear_error_message (context);
	return ret;
    }
    return 0;
}
Example #15
0
static int
HandleOP(Wrap)
{
    OM_uint32 maj_stat, min_stat;
    int32_t hContext, flags, seqno;
    krb5_data token;
    gss_ctx_id_t ctx;
    gss_buffer_desc input_token, output_token;
    int conf_state;

    ret32(c, hContext);
    ret32(c, flags);
    ret32(c, seqno);
    retdata(c, token);

    ctx = find_handle(c->handles, hContext, handle_context);
    if (ctx == NULL)
	errx(1, "wrap: reference to unknown context");

    input_token.length = token.length;
    input_token.value = token.data;

    maj_stat = gss_wrap(&min_stat, ctx, flags, 0, &input_token,
			&conf_state, &output_token);
    if (maj_stat != GSS_S_COMPLETE)
	errx(1, "gss_wrap failed");

    krb5_data_free(&token);

    token.data = output_token.value;
    token.length = output_token.length;

    put32(c, 0); /* XXX fix gsm_error */
    putdata(c, token);

    gss_release_buffer(&min_stat, &output_token);

    return 0;
}
Example #16
0
static krb5_error_code
kcm_send_request(krb5_context context,
		 krb5_kcmcache *k,
		 krb5_storage *request,
		 krb5_data *response_data)
{
    krb5_error_code ret;
    krb5_data request_data;
    int i;

    response_data->data = NULL;
    response_data->length = 0;

    ret = krb5_storage_to_data(request, &request_data);
    if (ret) {
	krb5_clear_error_string(context);
	return KRB5_CC_NOMEM;
    }

    ret = KRB5_CC_IO;

    for (i = 0; i < context->max_retries; i++) {
	ret = try_door(context, k, &request_data, response_data);
	if (ret == 0 && response_data->length != 0)
	    break;
	ret = try_unix_socket(context, k, &request_data, response_data);
	if (ret == 0 && response_data->length != 0)
	    break;
    }

    krb5_data_free(&request_data);

    if (ret) {
	krb5_clear_error_string(context);
	ret = KRB5_CC_IO;
    }

    return ret;
}
Example #17
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);
}
Example #18
0
kadm5_ret_t
kadm5_log_replay_create (kadm5_server_context *context,
			 u_int32_t ver,
			 u_int32_t len,
			 krb5_storage *sp)
{
    krb5_error_code ret;
    krb5_data data;
    hdb_entry ent;

    ret = krb5_data_alloc (&data, len);
    if (ret)
	return ret;
    krb5_storage_read (sp, data.data, len);
    ret = hdb_value2entry (context->context, &data, &ent);
    krb5_data_free(&data);
    if (ret)
	return ret;
    ret = context->db->hdb_store(context->context, context->db, 0, &ent);
    hdb_free_entry (context->context, &ent);
    return ret;
}
static OM_uint32
change_hold(OM_uint32 *minor_status, gsskrb5_cred cred,
	    krb5_error_code (*func)(krb5_context, krb5_ccache))
{
    krb5_error_code ret;
    krb5_context context;
    krb5_data data;

    *minor_status = 0;
    krb5_data_zero(&data);

    GSSAPI_KRB5_INIT (&context);

    if (cred == NULL)
	return GSS_S_COMPLETE;

    if (cred->usage != GSS_C_INITIATE && cred->usage != GSS_C_BOTH) {
	*minor_status = GSS_KRB5_S_G_BAD_USAGE;
	return GSS_S_FAILURE;
    }

    /* XXX only refcount nah-created credentials */
    ret = krb5_cc_get_config(context, cred->ccache, NULL, "nah-created", &data);
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }
    krb5_data_free(&data);

    ret = func(context, cred->ccache);

    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    return GSS_S_COMPLETE;
}
Example #20
0
static void
print_and_decode_tkt (krb5_context context,
		      krb5_data *ticket,
		      krb5_principal server,
		      krb5_enctype enctype)
{
    krb5_error_code ret;
    krb5_crypto crypto;
    krb5_data dec_data;
    size_t len;
    EncTicketPart decr_part;
    krb5_keyblock key;
    Ticket tkt;

    ret = decode_Ticket (ticket->data, ticket->length, &tkt, &len);
    if (ret)
	krb5_err (context, 1, ret, "decode_Ticket");

    ret = krb5_string_to_key (context, enctype, "foo", server, &key);
    if (ret)
	krb5_err (context, 1, ret, "krb5_string_to_key");

    ret = krb5_crypto_init(context, &key, 0, &crypto);
    if (ret)
	krb5_err (context, 1, ret, "krb5_crypto_init");

    ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET,
				      &tkt.enc_part, &dec_data);
    krb5_crypto_destroy (context, crypto);
    if (ret)
	krb5_err (context, 1, ret, "krb5_decrypt_EncryptedData");
    ret = decode_EncTicketPart (dec_data.data, dec_data.length,
				&decr_part, &len);
    krb5_data_free (&dec_data);
    if (ret)
	krb5_err (context, 1, ret, "krb5_decode_EncTicketPart");
    free_EncTicketPart(&decr_part);
}
Example #21
0
File: kdc.c Project: Arkhont/samba
static NTSTATUS kdc_proxy_unavailable_error(struct kdc_server *kdc,
					    TALLOC_CTX *mem_ctx,
					    DATA_BLOB *out)
{
	int kret;
	krb5_data k5_error_blob;

	kret = krb5_mk_error(kdc->smb_krb5_context->krb5_context,
			     KRB5KDC_ERR_SVC_UNAVAILABLE, NULL, NULL,
			     NULL, NULL, NULL, NULL, &k5_error_blob);
	if (kret != 0) {
		DEBUG(2,(__location__ ": Unable to form krb5 error reply\n"));
		return NT_STATUS_INTERNAL_ERROR;
	}

	*out = data_blob_talloc(mem_ctx, k5_error_blob.data, k5_error_blob.length);
	krb5_data_free(&k5_error_blob);
	if (!out->data) {
		return NT_STATUS_NO_MEMORY;
	}

	return NT_STATUS_OK;
}
Example #22
0
static krb5_error_code
write_storage(krb5_context context, krb5_storage *sp, int fd)
{
    krb5_error_code ret;
    krb5_data data;
    ssize_t sret;

    ret = krb5_storage_to_data(sp, &data);
    if (ret) {
	krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
	return ret;
    }
    sret = write(fd, data.data, data.length);
    ret = (sret != data.length);
    krb5_data_free(&data);
    if (ret) {
	ret = errno;
	krb5_set_error_message(context, ret,
			       N_("Failed to write FILE credential data", ""));
	return ret;
    }
    return 0;
}
Example #23
0
static krb5_error_code
HMAC_MD5_any_checksum(krb5_context context,
		      const krb5_keyblock *key,
		      const void *data,
		      size_t len,
		      unsigned usage,
		      Checksum *result)
{
    struct _krb5_key_data local_key;
    struct krb5_crypto_iov iov;
    krb5_error_code ret;

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

    ret = krb5_copy_keyblock(context, key, &local_key.key);
    if (ret)
	return ret;

    ret = krb5_data_alloc (&result->checksum, 16);
    if (ret) {
	krb5_free_keyblock(context, local_key.key);
	return ret;
    }

    result->cksumtype = CKSUMTYPE_HMAC_MD5;
    iov.data.data = (void *)data;
    iov.data.length = len;
    iov.flags = KRB5_CRYPTO_TYPE_DATA;

    ret = _krb5_HMAC_MD5_checksum(context, NULL, &local_key, usage, &iov, 1,
                                  result);
    if (ret)
	krb5_data_free(&result->checksum);

    krb5_free_keyblock(context, local_key.key);
    return ret;
}
Example #24
0
krb5_error_code
v5_prop(krb5_context context, HDB *db, hdb_entry_ex *entry, void *appdata)
{
    krb5_error_code ret;
    struct prop_data *pd = appdata;
    krb5_data data;

    if(encrypt_flag) {
	ret = hdb_seal_keys_mkey(context, &entry->entry, mkey5);
	if (ret) {
	    krb5_warn(context, ret, "hdb_seal_keys_mkey");
	    return ret;
	}
    }
    if(decrypt_flag) {
	ret = hdb_unseal_keys_mkey(context, &entry->entry, mkey5);
	if (ret) {
	    krb5_warn(context, ret, "hdb_unseal_keys_mkey");
	    return ret;
	}
    }

    ret = hdb_entry2value(context, &entry->entry, &data);
    if(ret) {
	krb5_warn(context, ret, "hdb_entry2value");
	return ret;
    }

    if(to_stdout)
	ret = krb5_write_message(context, &pd->sock, &data);
    else
	ret = krb5_write_priv_message(context, pd->auth_context,
				      &pd->sock, &data);
    krb5_data_free(&data);
    return ret;
}
Example #25
0
static krb5_error_code
resolve_by_uuid_oid(krb5_context context, const krb5_cc_ops *ops, krb5_ccache id, krb5_uuid uuid)
{
    krb5_storage *request, *response;
    krb5_data response_data;
    krb5_error_code ret;
    char *name;
    ssize_t sret;
    
    ret = krb5_kcm_storage_request(context, KCM_OP_GET_CACHE_BY_UUID, &request);
    if (ret)
	return ret;
    
    sret = krb5_storage_write(request, uuid, sizeof(krb5_uuid));
    if (sret != sizeof(krb5_uuid)) {
	krb5_storage_free(request);
	krb5_clear_error_message(context);
	return ENOMEM;
    }
    
    ret = krb5_kcm_call(context, request, &response, &response_data);
    krb5_storage_free(request);
    if (ret)
	return ret;

    ret = krb5_ret_stringz(response, &name);
    krb5_storage_free(response);
    krb5_data_free(&response_data);
    if (ret)
	return ret;
    
    ret = kcm_alloc(context, name, &id);
    krb5_xfree(name);
    
    return ret;
}
Example #26
0
/*
 * Request:
 *      NameZ
 *
 * Response:
 *      Principal
 */
static krb5_error_code
kcm_get_principal(krb5_context context,
		  krb5_ccache id,
		  krb5_principal *principal)
{
    krb5_error_code ret;
    krb5_kcmcache *k = KCMCACHE(id);
    krb5_storage *request, *response;
    krb5_data response_data;

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

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

    ret = krb5_kcm_call(context, request, &response, &response_data);
    if (ret) {
	krb5_storage_free(request);
	return ret;
    }

    ret = krb5_ret_principal(response, principal);
    if (ret)
	ret = KRB5_CC_IO;

    krb5_storage_free(request);
    krb5_storage_free(response);
    krb5_data_free(&response_data);

    return ret;
}
Example #27
0
static void
send_im_here (krb5_context context, int fd,
	      krb5_auth_context auth_context)
{
    krb5_storage *sp;
    krb5_data data;
    int ret;

    ret = krb5_data_alloc (&data, 4);
    if (ret)
	krb5_err (context, 1, ret, "send_im_here");

    sp = krb5_storage_from_data (&data);
    if (sp == NULL)
	krb5_errx (context, 1, "krb5_storage_from_data");
    krb5_store_int32(sp, I_AM_HERE);
    krb5_storage_free(sp);

    ret = krb5_write_priv_message(context, auth_context, &fd, &data);
    krb5_data_free(&data);

    if (ret)
	krb5_err (context, 1, ret, "krb5_write_priv_message");
}
Example #28
0
static krb5_error_code
decrypt_authenticator (krb5_context context,
		       EncryptionKey *key,
		       EncryptedData *enc_part,
		       Authenticator *authenticator,
		       krb5_key_usage usage)
{
    krb5_error_code ret;
    krb5_data plain;
    size_t len;
    krb5_crypto crypto;

    ret = krb5_crypto_init(context, key, 0, &crypto);
    if (ret)
	return ret;
    ret = krb5_decrypt_EncryptedData (context,
				      crypto,
				      usage /* KRB5_KU_AP_REQ_AUTH */,
				      enc_part,
				      &plain);
    /* for backwards compatibility, also try the old usage */
    if (ret && usage == KRB5_KU_TGS_REQ_AUTH)
	ret = krb5_decrypt_EncryptedData (context,
					  crypto,
					  KRB5_KU_AP_REQ_AUTH,
					  enc_part,
					  &plain);
    krb5_crypto_destroy(context, crypto);
    if (ret)
	return ret;

    ret = decode_Authenticator(plain.data, plain.length,
			       authenticator, &len);
    krb5_data_free (&plain);
    return ret;
}
Example #29
0
static krb5_error_code
get_cred_kdc(krb5_context context,
	     krb5_ccache id,
	     krb5_kdc_flags flags,
	     krb5_addresses *addresses,
	     krb5_creds *in_creds,
	     krb5_creds *krbtgt,
	     krb5_principal impersonate_principal,
	     Ticket *second_ticket,
	     krb5_creds *out_creds)
{
    TGS_REQ req;
    krb5_data enc;
    krb5_data resp;
    krb5_kdc_rep rep;
    KRB_ERROR error;
    krb5_error_code ret;
    unsigned nonce;
    krb5_keyblock *subkey = NULL;
    size_t len;
    Ticket second_ticket_data;
    METHOD_DATA padata;

    krb5_data_zero(&resp);
    krb5_data_zero(&enc);
    padata.val = NULL;
    padata.len = 0;

    krb5_generate_random_block(&nonce, sizeof(nonce));
    nonce &= 0xffffffff;

    if(flags.b.enc_tkt_in_skey && second_ticket == NULL){
	ret = decode_Ticket(in_creds->second_ticket.data,
			    in_creds->second_ticket.length,
			    &second_ticket_data, &len);
	if(ret)
	    return ret;
	second_ticket = &second_ticket_data;
    }


    if (impersonate_principal) {
	krb5_crypto crypto;
	PA_S4U2Self self;
	krb5_data data;
	void *buf;
	size_t size;

	self.name = impersonate_principal->name;
	self.realm = impersonate_principal->realm;
	self.auth = estrdup("Kerberos");
	
	ret = _krb5_s4u2self_to_checksumdata(context, &self, &data);
	if (ret) {
	    free(self.auth);
	    goto out;
	}

	ret = krb5_crypto_init(context, &krbtgt->session, 0, &crypto);
	if (ret) {
	    free(self.auth);
	    krb5_data_free(&data);
	    goto out;
	}

	ret = krb5_create_checksum(context,
				   crypto,
				   KRB5_KU_OTHER_CKSUM,
				   0,
				   data.data,
				   data.length,
				   &self.cksum);
	krb5_crypto_destroy(context, crypto);
	krb5_data_free(&data);
	if (ret) {
	    free(self.auth);
	    goto out;
	}

	ASN1_MALLOC_ENCODE(PA_S4U2Self, buf, len, &self, &size, ret);
	free(self.auth);
	free_Checksum(&self.cksum);
	if (ret)
	    goto out;
	if (len != size)
	    krb5_abortx(context, "internal asn1 error");
	
	ret = krb5_padata_add(context, &padata, KRB5_PADATA_FOR_USER, buf, len);
	if (ret)
	    goto out;
    }

    ret = init_tgs_req (context,
			id,
			addresses,
			flags,
			second_ticket,
			in_creds,
			krbtgt,
			nonce,
			&padata,
			&subkey,
			&req);
    if (ret)
	goto out;

    ASN1_MALLOC_ENCODE(TGS_REQ, enc.data, enc.length, &req, &len, ret);
    if (ret)
	goto out;
    if(enc.length != len)
	krb5_abortx(context, "internal error in ASN.1 encoder");

    /* don't free addresses */
    req.req_body.addresses = NULL;
    free_TGS_REQ(&req);

    /*
     * Send and receive
     */
    {
	krb5_sendto_ctx stctx;
	ret = krb5_sendto_ctx_alloc(context, &stctx);
	if (ret)
	    return ret;
	krb5_sendto_ctx_set_func(stctx, _krb5_kdc_retry, NULL);

	ret = krb5_sendto_context (context, stctx, &enc,
				   krbtgt->server->name.name_string.val[1],
				   &resp);
	krb5_sendto_ctx_free(context, stctx);
    }
    if(ret)
	goto out;

    memset(&rep, 0, sizeof(rep));
    if(decode_TGS_REP(resp.data, resp.length, &rep.kdc_rep, &len) == 0) {
	unsigned eflags = 0;

	ret = krb5_copy_principal(context,
				  in_creds->client,
				  &out_creds->client);
	if(ret)
	    goto out2;
	ret = krb5_copy_principal(context,
				  in_creds->server,
				  &out_creds->server);
	if(ret)
	    goto out2;
	/* this should go someplace else */
	out_creds->times.endtime = in_creds->times.endtime;

	/* XXX should do better testing */
	if (flags.b.constrained_delegation || impersonate_principal)
	    eflags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH;

	ret = _krb5_extract_ticket(context,
				   &rep,
				   out_creds,
				   &krbtgt->session,
				   NULL,
				   0,
				   &krbtgt->addresses,
				   nonce,
				   eflags,
				   decrypt_tkt_with_subkey,
				   subkey);
    out2:
	krb5_free_kdc_rep(context, &rep);
    } else if(krb5_rd_error(context, &resp, &error) == 0) {
	ret = krb5_error_from_rd_error(context, &error, in_creds);
	krb5_free_error_contents(context, &error);
    } else if(resp.length > 0 && ((char*)resp.data)[0] == 4) {
	ret = KRB5KRB_AP_ERR_V4_REPLY;
	krb5_clear_error_message(context);
    } else {
	ret = KRB5KRB_AP_ERR_MSG_TYPE;
	krb5_clear_error_message(context);
    }

out:
    if (second_ticket == &second_ticket_data)
	free_Ticket(&second_ticket_data);
    free_METHOD_DATA(&padata);
    krb5_data_free(&resp);
    krb5_data_free(&enc);
    if(subkey)
	krb5_free_keyblock(context, subkey);
    return ret;

}
Example #30
0
OM_uint32
gss_import_sec_context (
    OM_uint32 * minor_status,
    const gss_buffer_t interprocess_token,
    gss_ctx_id_t * context_handle
    )
{
    OM_uint32 ret = GSS_S_FAILURE;
    krb5_error_code kret;
    krb5_storage *sp;
    krb5_auth_context ac;
    krb5_address local, remote;
    krb5_address *localp, *remotep;
    krb5_data data;
    gss_buffer_desc buffer;
    krb5_keyblock keyblock;
    int32_t tmp;
    int32_t flags;
    OM_uint32 minor;
    int is_cfx = 0;

    GSSAPI_KRB5_INIT ();

    localp = remotep = NULL;

    sp = krb5_storage_from_mem (interprocess_token->value,
				interprocess_token->length);
    if (sp == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    *context_handle = malloc(sizeof(**context_handle));
    if (*context_handle == NULL) {
	*minor_status = ENOMEM;
	krb5_storage_free (sp);
	return GSS_S_FAILURE;
    }
    memset (*context_handle, 0, sizeof(**context_handle));
    HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex);

    kret = krb5_auth_con_init (gssapi_krb5_context,
			       &(*context_handle)->auth_context);
    if (kret) {
	gssapi_krb5_set_error_string ();
	*minor_status = kret;
	ret = GSS_S_FAILURE;
	goto failure;
    }

    /* flags */

    *minor_status = 0;

    if (krb5_ret_int32 (sp, &flags) != 0)
	goto failure;

    /* retrieve the auth context */

    ac = (*context_handle)->auth_context;
    krb5_ret_int32 (sp, &ac->flags);
    if (flags & SC_LOCAL_ADDRESS) {
	if (krb5_ret_address (sp, localp = &local) != 0)
	    goto failure;
    }

    if (flags & SC_REMOTE_ADDRESS) {
	if (krb5_ret_address (sp, remotep = &remote) != 0)
	    goto failure;
    }

    krb5_auth_con_setaddrs (gssapi_krb5_context, ac, localp, remotep);
    if (localp)
	krb5_free_address (gssapi_krb5_context, localp);
    if (remotep)
	krb5_free_address (gssapi_krb5_context, remotep);
    localp = remotep = NULL;

    if (krb5_ret_int16 (sp, &ac->local_port) != 0)
	goto failure;

    if (krb5_ret_int16 (sp, &ac->remote_port) != 0)
	goto failure;
    if (flags & SC_KEYBLOCK) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setkey (gssapi_krb5_context, ac, &keyblock);
	krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock);
    }
    if (flags & SC_LOCAL_SUBKEY) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setlocalsubkey (gssapi_krb5_context, ac, &keyblock);
	krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock);
    }
    if (flags & SC_REMOTE_SUBKEY) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setremotesubkey (gssapi_krb5_context, ac, &keyblock);
	krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock);
    }
    if (krb5_ret_int32 (sp, &ac->local_seqnumber))
	goto failure;
    if (krb5_ret_int32 (sp, &ac->remote_seqnumber))
	goto failure;

    if (krb5_ret_int32 (sp, &tmp) != 0)
	goto failure;
    ac->keytype = tmp;
    if (krb5_ret_int32 (sp, &tmp) != 0)
	goto failure;
    ac->cksumtype = tmp;

    /* names */

    if (krb5_ret_data (sp, &data))
	goto failure;
    buffer.value  = data.data;
    buffer.length = data.length;

    ret = gss_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
			   &(*context_handle)->source);
    if (ret) {
	ret = gss_import_name (minor_status, &buffer, GSS_C_NO_OID,
			       &(*context_handle)->source);
	if (ret) {
	    krb5_data_free (&data);
	    goto failure;
	}
    }
    krb5_data_free (&data);

    if (krb5_ret_data (sp, &data) != 0)
	goto failure;
    buffer.value  = data.data;
    buffer.length = data.length;

    ret = gss_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
			   &(*context_handle)->target);
    if (ret) {
	ret = gss_import_name (minor_status, &buffer, GSS_C_NO_OID,
			       &(*context_handle)->target);
	if (ret) {
	    krb5_data_free (&data);
	    goto failure;
	}
    }    
    krb5_data_free (&data);

    if (krb5_ret_int32 (sp, &tmp))
	goto failure;
    (*context_handle)->flags = tmp;
    if (krb5_ret_int32 (sp, &tmp))
	goto failure;
    (*context_handle)->more_flags = tmp;
    if (krb5_ret_int32 (sp, &tmp) == 0)
	(*context_handle)->lifetime = tmp;
    else
	(*context_handle)->lifetime = GSS_C_INDEFINITE;

    gsskrb5_is_cfx(*context_handle, &is_cfx);

    ret = _gssapi_msg_order_create(minor_status,
				   &(*context_handle)->order,
				   _gssapi_msg_order_f((*context_handle)->flags),
				   0, 0, is_cfx);
    if (ret)
	goto failure;

    krb5_storage_free (sp);
    return GSS_S_COMPLETE;

failure:
    krb5_auth_con_free (gssapi_krb5_context,
			(*context_handle)->auth_context);
    if ((*context_handle)->source != NULL)
	gss_release_name(&minor, &(*context_handle)->source);
    if ((*context_handle)->target != NULL)
	gss_release_name(&minor, &(*context_handle)->target);
    if (localp)
	krb5_free_address (gssapi_krb5_context, localp);
    if (remotep)
	krb5_free_address (gssapi_krb5_context, remotep);
    if((*context_handle)->order)
	_gssapi_msg_order_destroy(&(*context_handle)->order);
    HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex);
    krb5_storage_free (sp);
    free (*context_handle);
    *context_handle = GSS_C_NO_CONTEXT;
    return ret;
}