示例#1
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_sendto_kdc_flags(krb5_context context,
		      const krb5_data *send_data,
		      const krb5_realm *realm,
		      krb5_data *receive,
		      int flags)
{
    krb5_error_code ret;
    krb5_sendto_ctx ctx;

    ret = krb5_sendto_ctx_alloc(context, &ctx);
    if (ret)
	return ret;
    krb5_sendto_ctx_add_flags(ctx, flags);
    krb5_sendto_ctx_set_func(ctx, _krb5_kdc_retry, NULL);

    ret = krb5_sendto_context(context, ctx, send_data, *realm, receive);
    krb5_sendto_ctx_free(context, ctx);
    return ret;
}
示例#2
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;
}
示例#3
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;

}
	"\x6a\x81\xb8\x30\x81\xb5\xa1\x03\x02\x01\x05\xa2\x03\x02\x01\x0a"
	"\xa4\x81\xa8\x30\x81\xa5\xa0\x07\x03\x05\x00\x40\x01\x00\x00\xa1"
	"\x10\x30\x0e\xa0\x03\x02\x01\x01\xa1\x07\x30\x05\x1b\x03\x6c\x68"
	"\x61\xa2\x24\x1b\x22\x57\x45\x4c\x4c\x4b\x4e\x4f\x57\x4e\x3a\x43"
	"\x4f\x4d\x2e\x41\x50\x50\x4c\x45\x2e\x4c\x4b\x44\x43\x3a\x6c\x6f"
	"\x63\x61\x6c\x68\x6f\x73\x74\xa3\x37\x30\x35\xa0\x03\x02\x01\x01"
	"\xa1\x2e\x30\x2c\x1b\x06\x6b\x72\x62\x74\x67\x74\x1b\x22\x57\x45"
	"\x4c\x4c\x4b\x4e\x4f\x57\x4e\x3a\x43\x4f\x4d\x2e\x41\x50\x50\x4c"
	"\x45\x2e\x4c\x4b\x44\x43\x3a\x6c\x6f\x63\x61\x6c\x68\x6f\x73\x74"
	"\xa5\x11\x18\x0f\x32\x30\x31\x30\x30\x37\x33\x30\x31\x30\x33\x35"
	"\x31\x38\x5a\xa7\x06\x02\x04\x3a\xcc\xb8\xba\xa8\x0e\x30\x0c\x02"
	"\x01\x12\x02\x01\x11\x02\x01\x10\x02\x01\x17",
	.length = 187
    }, recv = { .data = NULL, .length = 0 };

    ret = krb5_sendto_ctx_alloc(context, &ctx);
    if (ret)
	krb5_err(context, 1, ret, "krb5_sendto_ctx_alloc");

    if (use_large_flag)
	krb5_sendto_ctx_add_flags(ctx, KRB5_KRBHST_FLAGS_LARGE_MSG);

    ret = krb5_sendto_context(context, ctx, &send, realm_string, &recv);
    if (ret)
	krb5_err(context, 1, ret, "krb5_sendto_context");

    krb5_sendto_ctx_free(context, ctx);

    krb5_free_context(context);

    return 0;
示例#5
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_sendto_context(krb5_context context,
		    krb5_sendto_ctx ctx,
		    const krb5_data *send_data,
		    const krb5_realm realm,
		    krb5_data *receive)
{
    krb5_error_code ret;
    krb5_krbhst_handle handle = NULL;
    int type, freectx = 0;
    int action;

    krb5_data_zero(receive);

    if (ctx == NULL) {
	freectx = 1;
	ret = krb5_sendto_ctx_alloc(context, &ctx);
	if (ret)
	    return ret;
    }

    type = ctx->type;
    if (type == 0) {
	if ((ctx->flags & KRB5_KRBHST_FLAGS_MASTER) || context->use_admin_kdc)
	    type = KRB5_KRBHST_ADMIN;
	else
	    type = KRB5_KRBHST_KDC;
    }

    if ((int)send_data->length > context->large_msg_size)
	ctx->flags |= KRB5_KRBHST_FLAGS_LARGE_MSG;

    /* loop until we get back a appropriate response */

    do {
	action = KRB5_SENDTO_DONE;

	krb5_data_free(receive);

	if (handle == NULL) {
	    ret = krb5_krbhst_init_flags(context, realm, type,
					 ctx->flags, &handle);
	    if (ret) {
		if (freectx)
		    krb5_sendto_ctx_free(context, ctx);
		return ret;
	    }
	}

	ret = krb5_sendto(context, send_data, handle, receive);
	if (ret)
	    break;
	if (ctx->func) {
	    ret = (*ctx->func)(context, ctx, ctx->data, receive, &action);
	    if (ret)
		break;
	}
	if (action != KRB5_SENDTO_CONTINUE) {
	    krb5_krbhst_free(context, handle);
	    handle = NULL;
	}
    } while (action != KRB5_SENDTO_DONE);
    if (handle)
	krb5_krbhst_free(context, handle);
    if (ret == KRB5_KDC_UNREACH)
	krb5_set_error_message(context, ret,
			       N_("unable to reach any KDC in realm %s", ""),
			       realm);
    if (ret)
	krb5_data_free(receive);
    if (freectx)
	krb5_sendto_ctx_free(context, ctx);
    return ret;
}
示例#6
0
static krb5_error_code
change_password_loop(krb5_context	context,
                     struct request *request,
                     int		*result_code,
                     krb5_data		*result_code_string,
                     krb5_data		*result_string,
                     struct kpwd_proc	*proc)
{
    krb5_error_code ret;
    krb5_data zero, zero2;
    krb5_sendto_ctx ctx = NULL;
    krb5_realm realm;

    krb5_data_zero(&zero);
    krb5_data_zero(&zero2);

    if (request->target)
        realm = request->target->realm;
    else
        realm = request->creds->client->realm;

    _krb5_debugx(context, 1, "trying to set password using: %s in realm %s",
                 proc->name, realm);

    ret = krb5_auth_con_init(context, &request->ac);
    if (ret)
        goto out;

    krb5_auth_con_setflags(context, request->ac, KRB5_AUTH_CONTEXT_DO_SEQUENCE);

    ret = krb5_sendto_ctx_alloc(context, &ctx);
    if (ret)
        goto out;

    krb5_sendto_ctx_set_type(ctx, KRB5_KRBHST_CHANGEPW);

    /* XXX this is a evil hack */
    if (request->creds->ticket.length > 700) {
        _krb5_debugx(context, 1, "using TCP since the ticket is large: %lu",
                     (unsigned long)request->creds->ticket.length);
        krb5_sendto_ctx_add_flags(ctx, KRB5_KRBHST_FLAGS_LARGE_MSG);
    }

    _krb5_sendto_ctx_set_prexmit(ctx, proc->prexmit, request);

    ret = krb5_sendto_context(context, ctx, &zero, realm, &zero2);

    if (ret == 0)
        ret = proc->process_rep(context, request->ac, &zero2,
                                result_code, result_code_string, result_string);

out:
    _krb5_debugx(context, 1, "set password using %s returned: %d result_code %d",
                 proc->name, ret, *result_code);

    krb5_auth_con_free(context, request->ac);
    if (ctx)
        krb5_sendto_ctx_free(context, ctx);

    krb5_data_free(&zero2);

    if (ret == KRB5_KDC_UNREACH) {
        krb5_set_error_message(context,
                               ret,
                               N_("Unable to reach any changepw server "
                                  " in realm %s", "realm"), realm);
        *result_code = KRB5_KPASSWD_HARDERROR;
    }
    return ret;
}