(krb5_rd_req_ctx): Add context all singing-all dancing version of the
krb5_rd_req and implement krb5_rd_req and krb5_rd_req_with_keyblock using it. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@18925 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -506,6 +506,134 @@ krb5_verify_ap_req2(krb5_context context,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct krb5_rd_req_in_ctx {
|
||||||
|
krb5_keytab keytab;
|
||||||
|
krb5_keyblock *keyblock;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct krb5_rd_req_out_ctx {
|
||||||
|
krb5_keyblock *keyblock;
|
||||||
|
krb5_flags ap_req_options;
|
||||||
|
krb5_ticket *ticket;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
krb5_error_code KRB5_LIB_FUNCTION
|
||||||
|
krb5_rd_req_in_ctx_alloc(krb5_context context, krb5_rd_req_in_ctx *ctx)
|
||||||
|
{
|
||||||
|
*ctx = calloc(1, sizeof(**ctx));
|
||||||
|
if (*ctx == NULL) {
|
||||||
|
krb5_set_error_string(context, "out of memory");
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_error_code KRB5_LIB_FUNCTION
|
||||||
|
krb5_rd_req_in_set_keytab(krb5_context context,
|
||||||
|
krb5_rd_req_in_ctx in,
|
||||||
|
krb5_keytab keytab)
|
||||||
|
{
|
||||||
|
in->keytab = keytab; /* XXX should make copy */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_error_code KRB5_LIB_FUNCTION
|
||||||
|
krb5_rd_req_in_set_keyblock(krb5_context context,
|
||||||
|
krb5_rd_req_in_ctx in,
|
||||||
|
krb5_keyblock *keyblock)
|
||||||
|
{
|
||||||
|
in->keyblock = keyblock; /* XXX should make copy */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_error_code KRB5_LIB_FUNCTION
|
||||||
|
krb5_rd_req_out_get_keyblock(krb5_context context,
|
||||||
|
krb5_rd_req_out_ctx out,
|
||||||
|
krb5_keyblock **keyblock)
|
||||||
|
{
|
||||||
|
return krb5_copy_keyblock(context, out->keyblock, keyblock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KRB5_LIB_FUNCTION
|
||||||
|
krb5_rd_req_in_ctx_free(krb5_context context, krb5_rd_req_in_ctx ctx)
|
||||||
|
{
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_error_code KRB5_LIB_FUNCTION
|
||||||
|
_krb5_rd_req_out_ctx_alloc(krb5_context context, krb5_rd_req_out_ctx *ctx)
|
||||||
|
{
|
||||||
|
*ctx = calloc(1, sizeof(**ctx));
|
||||||
|
if (*ctx == NULL) {
|
||||||
|
krb5_set_error_string(context, "out of memory");
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KRB5_LIB_FUNCTION
|
||||||
|
krb5_rd_req_out_ctx_free(krb5_context context, krb5_rd_req_out_ctx ctx)
|
||||||
|
{
|
||||||
|
krb5_free_keyblock(context, ctx->keyblock);
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
krb5_error_code KRB5_LIB_FUNCTION
|
||||||
|
krb5_rd_req(krb5_context context,
|
||||||
|
krb5_auth_context *auth_context,
|
||||||
|
const krb5_data *inbuf,
|
||||||
|
krb5_const_principal server,
|
||||||
|
krb5_keytab keytab,
|
||||||
|
krb5_flags *ap_req_options,
|
||||||
|
krb5_ticket **ticket)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
krb5_rd_req_in_ctx in;
|
||||||
|
krb5_rd_req_out_ctx out;
|
||||||
|
|
||||||
|
ret = krb5_rd_req_in_ctx_alloc(context, &in);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = krb5_rd_req_in_set_keytab(context, in, keytab);
|
||||||
|
if (ret) {
|
||||||
|
krb5_rd_req_in_ctx_free(context, in);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = krb5_rd_req_ctx(context, auth_context, inbuf, server, in, &out);
|
||||||
|
krb5_rd_req_in_ctx_free(context, in);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (ap_req_options)
|
||||||
|
*ap_req_options = out->ap_req_options;
|
||||||
|
if (ticket) {
|
||||||
|
ret = krb5_copy_ticket(context, out->ticket, ticket);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
krb5_rd_req_out_ctx_free(context, out);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
krb5_error_code KRB5_LIB_FUNCTION
|
krb5_error_code KRB5_LIB_FUNCTION
|
||||||
krb5_rd_req_with_keyblock(krb5_context context,
|
krb5_rd_req_with_keyblock(krb5_context context,
|
||||||
@@ -517,31 +645,41 @@ krb5_rd_req_with_keyblock(krb5_context context,
|
|||||||
krb5_ticket **ticket)
|
krb5_ticket **ticket)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_ap_req ap_req;
|
krb5_rd_req_in_ctx in;
|
||||||
|
krb5_rd_req_out_ctx out;
|
||||||
|
|
||||||
if (*auth_context == NULL) {
|
ret = krb5_rd_req_in_ctx_alloc(context, &in);
|
||||||
ret = krb5_auth_con_init(context, auth_context);
|
if (ret)
|
||||||
if (ret)
|
return ret;
|
||||||
return ret;
|
|
||||||
|
ret = krb5_rd_req_in_set_keyblock(context, in, keyblock);
|
||||||
|
if (ret) {
|
||||||
|
krb5_rd_req_in_ctx_free(context, in);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_decode_ap_req(context, inbuf, &ap_req);
|
ret = krb5_rd_req_ctx(context, auth_context, inbuf, server, in, &out);
|
||||||
if(ret)
|
krb5_rd_req_in_ctx_free(context, in);
|
||||||
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = krb5_verify_ap_req(context,
|
if (ap_req_options)
|
||||||
auth_context,
|
*ap_req_options = out->ap_req_options;
|
||||||
&ap_req,
|
if (ticket) {
|
||||||
server,
|
ret = krb5_copy_ticket(context, out->ticket, ticket);
|
||||||
keyblock,
|
if (ret)
|
||||||
0,
|
goto out;
|
||||||
ap_req_options,
|
}
|
||||||
ticket);
|
|
||||||
|
|
||||||
free_AP_REQ(&ap_req);
|
out:
|
||||||
|
krb5_rd_req_out_ctx_free(context, out);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
get_key_from_keytab(krb5_context context,
|
get_key_from_keytab(krb5_context context,
|
||||||
krb5_auth_context *auth_context,
|
krb5_auth_context *auth_context,
|
||||||
@@ -582,35 +720,44 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
krb5_error_code KRB5_LIB_FUNCTION
|
krb5_error_code KRB5_LIB_FUNCTION
|
||||||
krb5_rd_req(krb5_context context,
|
krb5_rd_req_ctx(krb5_context context,
|
||||||
krb5_auth_context *auth_context,
|
krb5_auth_context *auth_context,
|
||||||
const krb5_data *inbuf,
|
const krb5_data *inbuf,
|
||||||
krb5_const_principal server,
|
krb5_const_principal server,
|
||||||
krb5_keytab keytab,
|
krb5_rd_req_in_ctx inctx,
|
||||||
krb5_flags *ap_req_options,
|
krb5_rd_req_out_ctx *outctx)
|
||||||
krb5_ticket **ticket)
|
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_ap_req ap_req;
|
krb5_ap_req ap_req;
|
||||||
krb5_keyblock *keyblock = NULL;
|
|
||||||
krb5_principal service = NULL;
|
krb5_principal service = NULL;
|
||||||
|
krb5_rd_req_out_ctx o = NULL;
|
||||||
|
|
||||||
|
ret = _krb5_rd_req_out_ctx_alloc(context, &o);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (*auth_context == NULL) {
|
if (*auth_context == NULL) {
|
||||||
ret = krb5_auth_con_init(context, auth_context);
|
ret = krb5_auth_con_init(context, auth_context);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_decode_ap_req(context, inbuf, &ap_req);
|
ret = krb5_decode_ap_req(context, inbuf, &ap_req);
|
||||||
if(ret)
|
if(ret)
|
||||||
return ret;
|
goto out;
|
||||||
|
|
||||||
if(server == NULL){
|
if(server == NULL){
|
||||||
_krb5_principalname2krb5_principal(context,
|
ret = _krb5_principalname2krb5_principal(context,
|
||||||
&service,
|
&service,
|
||||||
ap_req.ticket.sname,
|
ap_req.ticket.sname,
|
||||||
ap_req.ticket.realm);
|
ap_req.ticket.realm);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
server = service;
|
server = service;
|
||||||
}
|
}
|
||||||
if (ap_req.ap_options.use_session_key &&
|
if (ap_req.ap_options.use_session_key &&
|
||||||
@@ -621,35 +768,51 @@ krb5_rd_req(krb5_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((*auth_context)->keyblock == NULL){
|
if((*auth_context)->keyblock){
|
||||||
|
ret = krb5_copy_keyblock(context,
|
||||||
|
(*auth_context)->keyblock,
|
||||||
|
&o->keyblock);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
} else if(inctx->keyblock){
|
||||||
|
ret = krb5_copy_keyblock(context,
|
||||||
|
inctx->keyblock,
|
||||||
|
&o->keyblock);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
krb5_keytab keytab = NULL;
|
||||||
|
|
||||||
|
if (inctx && inctx->keytab)
|
||||||
|
keytab = inctx->keytab;
|
||||||
|
|
||||||
ret = get_key_from_keytab(context,
|
ret = get_key_from_keytab(context,
|
||||||
auth_context,
|
auth_context,
|
||||||
&ap_req,
|
&ap_req,
|
||||||
server,
|
server,
|
||||||
keytab,
|
keytab,
|
||||||
&keyblock);
|
&o->keyblock);
|
||||||
if(ret)
|
if(ret)
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
|
||||||
ret = krb5_copy_keyblock(context,
|
|
||||||
(*auth_context)->keyblock,
|
|
||||||
&keyblock);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_verify_ap_req(context,
|
ret = krb5_verify_ap_req(context,
|
||||||
auth_context,
|
auth_context,
|
||||||
&ap_req,
|
&ap_req,
|
||||||
server,
|
server,
|
||||||
keyblock,
|
o->keyblock,
|
||||||
0,
|
0,
|
||||||
ap_req_options,
|
&o->ap_req_options,
|
||||||
ticket);
|
&o->ticket);
|
||||||
|
|
||||||
krb5_free_keyblock(context, keyblock);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (ret || outctx == NULL) {
|
||||||
|
krb5_rd_req_out_ctx_free(context, o);
|
||||||
|
} else
|
||||||
|
*outctx = o;
|
||||||
|
|
||||||
free_AP_REQ(&ap_req);
|
free_AP_REQ(&ap_req);
|
||||||
if(service)
|
if(service)
|
||||||
krb5_free_principal(context, service);
|
krb5_free_principal(context, service);
|
||||||
|
Reference in New Issue
Block a user