add some help function that is common between ENC_TS and SAM2
free the etype{,2}-infos on failure move the pa counter into krb5_get_init_creds_ctx git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@12984 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -45,6 +45,7 @@ typedef struct krb5_get_init_creds_ctx {
|
|||||||
unsigned nonce;
|
unsigned nonce;
|
||||||
|
|
||||||
AS_REQ as_req;
|
AS_REQ as_req;
|
||||||
|
int pa_counter;
|
||||||
|
|
||||||
const char *password;
|
const char *password;
|
||||||
krb5_s2k_proc key_proc;
|
krb5_s2k_proc key_proc;
|
||||||
@@ -690,11 +691,9 @@ pa_etype_info2(krb5_context context,
|
|||||||
memset(&e, 0, sizeof(e));
|
memset(&e, 0, sizeof(e));
|
||||||
ret = decode_ETYPE_INFO2(data->data, data->length, &e, &sz);
|
ret = decode_ETYPE_INFO2(data->data, data->length, &e, &sz);
|
||||||
if (ret)
|
if (ret)
|
||||||
return NULL;
|
goto out;
|
||||||
if (e.len == 0) {
|
if (e.len == 0)
|
||||||
free_ETYPE_INFO2(&e);
|
goto out;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
for (j = 0; j < asreq->req_body.etype.len; j++) {
|
for (j = 0; j < asreq->req_body.etype.len; j++) {
|
||||||
for (i = 0; i < e.len; i++) {
|
for (i = 0; i < e.len; i++) {
|
||||||
if (asreq->req_body.etype.val[j] == e.val[i].etype) {
|
if (asreq->req_body.etype.val[j] == e.val[i].etype) {
|
||||||
@@ -721,6 +720,7 @@ pa_etype_info2(krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
free_ETYPE_INFO2(&e);
|
free_ETYPE_INFO2(&e);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -740,11 +740,9 @@ pa_etype_info(krb5_context context,
|
|||||||
memset(&e, 0, sizeof(e));
|
memset(&e, 0, sizeof(e));
|
||||||
ret = decode_ETYPE_INFO(data->data, data->length, &e, &sz);
|
ret = decode_ETYPE_INFO(data->data, data->length, &e, &sz);
|
||||||
if (ret)
|
if (ret)
|
||||||
return NULL;
|
goto out;
|
||||||
if (e.len == 0) {
|
if (e.len == 0)
|
||||||
free_ETYPE_INFO(&e);
|
goto out;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
for (j = 0; j < asreq->req_body.etype.len; j++) {
|
for (j = 0; j < asreq->req_body.etype.len; j++) {
|
||||||
for (i = 0; i < e.len; i++) {
|
for (i = 0; i < e.len; i++) {
|
||||||
if (asreq->req_body.etype.val[j] == e.val[i].etype) {
|
if (asreq->req_body.etype.val[j] == e.val[i].etype) {
|
||||||
@@ -774,6 +772,7 @@ pa_etype_info(krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
free_ETYPE_INFO(&e);
|
free_ETYPE_INFO(&e);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -809,13 +808,23 @@ struct pa_info {
|
|||||||
heim_octet_string *);
|
heim_octet_string *);
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pa_info preauth_prefs[] = {
|
static struct pa_info pa_prefs[] = {
|
||||||
{ KRB5_PADATA_ETYPE_INFO2, pa_etype_info2 },
|
{ KRB5_PADATA_ETYPE_INFO2, pa_etype_info2 },
|
||||||
{ KRB5_PADATA_ETYPE_INFO, pa_etype_info },
|
{ KRB5_PADATA_ETYPE_INFO, pa_etype_info },
|
||||||
{ KRB5_PADATA_PW_SALT, pa_pw_or_afs3_salt },
|
{ KRB5_PADATA_PW_SALT, pa_pw_or_afs3_salt },
|
||||||
{ KRB5_PADATA_AFS3_SALT, pa_pw_or_afs3_salt }
|
{ KRB5_PADATA_AFS3_SALT, pa_pw_or_afs3_salt }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PA_DATA *
|
||||||
|
find_pa_data(const METHOD_DATA *md, int type)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < md->len; i++)
|
||||||
|
if (md->val[i].padata_type == type)
|
||||||
|
return &md->val[i];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct pa_info_data *
|
static struct pa_info_data *
|
||||||
process_pa_info(krb5_context context,
|
process_pa_info(krb5_context context,
|
||||||
const krb5_principal client,
|
const krb5_principal client,
|
||||||
@@ -823,23 +832,43 @@ process_pa_info(krb5_context context,
|
|||||||
struct pa_info_data *paid,
|
struct pa_info_data *paid,
|
||||||
METHOD_DATA *md)
|
METHOD_DATA *md)
|
||||||
{
|
{
|
||||||
int i, j;
|
struct pa_info_data *p = NULL;
|
||||||
struct pa_info *info;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(preauth_prefs)/sizeof(preauth_prefs[0]); i++) {
|
for (i = 0; p == NULL && i < sizeof(pa_prefs)/sizeof(pa_prefs[0]); i++) {
|
||||||
info = &preauth_prefs[i];
|
PA_DATA *pa = find_pa_data(md, pa_prefs[i].type);
|
||||||
for (j = 0; j < md->len; j++)
|
if (pa == NULL)
|
||||||
if (info->type == md->val[j].padata_type) {
|
continue;
|
||||||
paid->salt.salttype = info->type;
|
paid->salt.salttype = pa_prefs[i].type;
|
||||||
return (*info->salt_info)(context, client, asreq,
|
p = (*pa_prefs[i].salt_info)(context, client, asreq,
|
||||||
paid, &md->val[j].padata_value);
|
paid, &pa->padata_value);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pa_add_pa(krb5_context context, METHOD_DATA *md,
|
||||||
|
int type, void *buf, size_t len)
|
||||||
|
{
|
||||||
|
PA_DATA *pa;
|
||||||
|
|
||||||
|
pa = realloc (md->val, (md->len + 1) * sizeof(*md->val));
|
||||||
|
if (pa == NULL) {
|
||||||
|
krb5_set_error_string(context, "malloc: out of memory");
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
md->val = pa;
|
||||||
|
|
||||||
|
pa[md->len].padata_type = type;
|
||||||
|
pa[md->len].padata_value.length = len;
|
||||||
|
pa[md->len].padata_value.data = buf;
|
||||||
|
md->len++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
|
make_pa_enc_timestamp(krb5_context context, METHOD_DATA *md,
|
||||||
krb5_enctype etype, krb5_keyblock *key)
|
krb5_enctype etype, krb5_keyblock *key)
|
||||||
{
|
{
|
||||||
PA_ENC_TS_ENC p;
|
PA_ENC_TS_ENC p;
|
||||||
@@ -885,10 +914,11 @@ make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
|
|||||||
return ret;
|
return ret;
|
||||||
if(buf_size != len)
|
if(buf_size != len)
|
||||||
krb5_abortx(context, "internal error in ASN.1 encoder");
|
krb5_abortx(context, "internal error in ASN.1 encoder");
|
||||||
pa->padata_type = KRB5_PADATA_ENC_TIMESTAMP;
|
|
||||||
pa->padata_value.length = len;
|
ret = pa_add_pa(context, md, KRB5_PADATA_ENC_TIMESTAMP, buf, len);
|
||||||
pa->padata_value.data = buf;
|
if (ret)
|
||||||
return 0;
|
free(buf);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
@@ -903,7 +933,6 @@ add_enc_ts_padata(krb5_context context,
|
|||||||
krb5_data *s2kparams)
|
krb5_data *s2kparams)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
PA_DATA *pa2;
|
|
||||||
krb5_salt salt2;
|
krb5_salt salt2;
|
||||||
krb5_enctype *ep;
|
krb5_enctype *ep;
|
||||||
int i;
|
int i;
|
||||||
@@ -919,12 +948,6 @@ add_enc_ts_padata(krb5_context context,
|
|||||||
for (ep = enctypes; *ep != ETYPE_NULL; ep++)
|
for (ep = enctypes; *ep != ETYPE_NULL; ep++)
|
||||||
netypes++;
|
netypes++;
|
||||||
}
|
}
|
||||||
pa2 = realloc (md->val, (md->len + netypes) * sizeof(*md->val));
|
|
||||||
if (pa2 == NULL) {
|
|
||||||
krb5_set_error_string(context, "malloc: out of memory");
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
md->val = pa2;
|
|
||||||
|
|
||||||
for (i = 0; i < netypes; ++i) {
|
for (i = 0; i < netypes; ++i) {
|
||||||
krb5_keyblock *key;
|
krb5_keyblock *key;
|
||||||
@@ -933,12 +956,10 @@ add_enc_ts_padata(krb5_context context,
|
|||||||
*salt, s2kparams, &key);
|
*salt, s2kparams, &key);
|
||||||
if (ret)
|
if (ret)
|
||||||
continue;
|
continue;
|
||||||
ret = make_pa_enc_timestamp (context, &md->val[md->len],
|
ret = make_pa_enc_timestamp (context, md, enctypes[i], key);
|
||||||
enctypes[i], key);
|
|
||||||
krb5_free_keyblock (context, key);
|
krb5_free_keyblock (context, key);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
++md->len;
|
|
||||||
}
|
}
|
||||||
if(salt == &salt2)
|
if(salt == &salt2)
|
||||||
krb5_free_salt(context, salt2);
|
krb5_free_salt(context, salt2);
|
||||||
@@ -1005,7 +1026,6 @@ pa_data_add_pac_request(krb5_context context,
|
|||||||
size_t len, length;
|
size_t len, length;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
PA_PAC_REQUEST req;
|
PA_PAC_REQUEST req;
|
||||||
PA_DATA *pa;
|
|
||||||
void *buf;
|
void *buf;
|
||||||
|
|
||||||
switch (ctx->req_pac) {
|
switch (ctx->req_pac) {
|
||||||
@@ -1022,22 +1042,12 @@ pa_data_add_pac_request(krb5_context context,
|
|||||||
&req, &len, ret);
|
&req, &len, ret);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if(len != length)
|
if(len != length)
|
||||||
krb5_abortx(context, "internal error in ASN.1 encoder");
|
krb5_abortx(context, "internal error in ASN.1 encoder");
|
||||||
|
|
||||||
pa = realloc (md->val, (md->len + 1) * sizeof(*md->val));
|
ret = pa_add_pa(context, md, KRB5_PADATA_PA_PAC_REQUEST, buf, len);
|
||||||
if (pa == NULL) {
|
if (ret)
|
||||||
free(buf);
|
free(buf);
|
||||||
krb5_set_error_string(context, "malloc: out of memory");
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
md->val = pa;
|
|
||||||
|
|
||||||
pa[md->len].padata_type = KRB5_PADATA_PA_PAC_REQUEST;
|
|
||||||
pa[md->len].padata_value.length = len;
|
|
||||||
pa[md->len].padata_value.data = buf;
|
|
||||||
|
|
||||||
md->len++;
|
md->len++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1138,17 +1148,14 @@ init_cred_loop(krb5_context context,
|
|||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_kdc_rep rep;
|
krb5_kdc_rep rep;
|
||||||
|
METHOD_DATA md;
|
||||||
krb5_data resp;
|
krb5_data resp;
|
||||||
size_t len;
|
size_t len;
|
||||||
krb5_keyblock *key;
|
|
||||||
size_t size;
|
size_t size;
|
||||||
int pa_counter;
|
|
||||||
METHOD_DATA md;
|
|
||||||
int send_to_kdc_flags = 0;
|
int send_to_kdc_flags = 0;
|
||||||
|
|
||||||
memset(&md, 0, sizeof(md));
|
memset(&md, 0, sizeof(md));
|
||||||
memset(&rep, 0, sizeof(rep));
|
memset(&rep, 0, sizeof(rep));
|
||||||
key = NULL;
|
|
||||||
|
|
||||||
if (ret_as_reply)
|
if (ret_as_reply)
|
||||||
memset(ret_as_reply, 0, sizeof(*ret_as_reply));
|
memset(ret_as_reply, 0, sizeof(*ret_as_reply));
|
||||||
@@ -1165,9 +1172,12 @@ init_cred_loop(krb5_context context,
|
|||||||
|
|
||||||
#define MAX_PA_COUNTER 3
|
#define MAX_PA_COUNTER 3
|
||||||
|
|
||||||
for (pa_counter = 0; pa_counter < MAX_PA_COUNTER; pa_counter++) {
|
ctx->pa_counter = 0;
|
||||||
|
while (ctx->pa_counter < MAX_PA_COUNTER) {
|
||||||
krb5_data req;
|
krb5_data req;
|
||||||
|
|
||||||
|
ctx->pa_counter++;
|
||||||
|
|
||||||
if (ctx->as_req.padata) {
|
if (ctx->as_req.padata) {
|
||||||
free_METHOD_DATA(ctx->as_req.padata);
|
free_METHOD_DATA(ctx->as_req.padata);
|
||||||
ctx->as_req.padata = NULL;
|
ctx->as_req.padata = NULL;
|
||||||
@@ -1254,25 +1264,28 @@ init_cred_loop(krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = process_pa_data_to_key(context, ctx, creds,
|
{
|
||||||
&ctx->as_req, &rep, &key);
|
krb5_keyblock *key = NULL;
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = _krb5_extract_ticket(context,
|
ret = process_pa_data_to_key(context, ctx, creds,
|
||||||
&rep,
|
&ctx->as_req, &rep, &key);
|
||||||
creds,
|
if (ret)
|
||||||
key,
|
goto out;
|
||||||
NULL,
|
|
||||||
KRB5_KU_AS_REP_ENC_PART,
|
|
||||||
NULL,
|
|
||||||
ctx->nonce,
|
|
||||||
FALSE,
|
|
||||||
ctx->flags.b.request_anonymous,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
krb5_free_keyblock(context, key);
|
|
||||||
|
|
||||||
|
ret = _krb5_extract_ticket(context,
|
||||||
|
&rep,
|
||||||
|
creds,
|
||||||
|
key,
|
||||||
|
NULL,
|
||||||
|
KRB5_KU_AS_REP_ENC_PART,
|
||||||
|
NULL,
|
||||||
|
ctx->nonce,
|
||||||
|
FALSE,
|
||||||
|
ctx->flags.b.request_anonymous,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
krb5_free_keyblock(context, key);
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
free_METHOD_DATA(&md);
|
free_METHOD_DATA(&md);
|
||||||
memset(&md, 0, sizeof(md));
|
memset(&md, 0, sizeof(md));
|
||||||
|
Reference in New Issue
Block a user