Add a return value to simaka_message_t.generate()

This commit is contained in:
Martin Willi 2012-07-05 18:04:41 +02:00
parent cbfbba7d86
commit 264e702109
6 changed files with 264 additions and 90 deletions

View File

@ -80,13 +80,31 @@ struct private_eap_aka_peer_t {
u_int16_t counter; u_int16_t counter;
}; };
/**
* Generate a payload from a message, destroy message
*/
static bool generate_payload(simaka_message_t *message, chunk_t data,
eap_payload_t **out)
{
chunk_t chunk;
bool ok;
ok = message->generate(message, data, &chunk);
if (ok)
{
*out = eap_payload_create_data_own(chunk);
}
message->destroy(message);
return ok;
}
/** /**
* Create a AKA_CLIENT_ERROR: "Unable to process" * Create a AKA_CLIENT_ERROR: "Unable to process"
*/ */
static eap_payload_t* create_client_error(private_eap_aka_peer_t *this) static bool create_client_error(private_eap_aka_peer_t *this,
eap_payload_t **out)
{ {
simaka_message_t *message; simaka_message_t *message;
eap_payload_t *out;
u_int16_t encoded; u_int16_t encoded;
DBG1(DBG_IKE, "sending client error '%N'", DBG1(DBG_IKE, "sending client error '%N'",
@ -97,9 +115,8 @@ static eap_payload_t* create_client_error(private_eap_aka_peer_t *this)
encoded = htons(AKA_UNABLE_TO_PROCESS); encoded = htons(AKA_UNABLE_TO_PROCESS);
message->add_attribute(message, AT_CLIENT_ERROR_CODE, message->add_attribute(message, AT_CLIENT_ERROR_CODE,
chunk_create((char*)&encoded, sizeof(encoded))); chunk_create((char*)&encoded, sizeof(encoded)));
out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message); return generate_payload(message, chunk_empty, out);
return out;
} }
/** /**
@ -134,8 +151,11 @@ static status_t process_identity(private_eap_aka_peer_t *this,
default: default:
if (!simaka_attribute_skippable(type)) if (!simaka_attribute_skippable(type))
{ {
*out = create_client_error(this);
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (!create_client_error(this, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
break; break;
@ -175,9 +195,10 @@ static status_t process_identity(private_eap_aka_peer_t *this,
{ {
message->add_attribute(message, AT_IDENTITY, id); message->add_attribute(message, AT_IDENTITY, id);
} }
*out = eap_payload_create_data_own(message->generate(message, chunk_empty)); if (!generate_payload(message, chunk_empty, out))
message->destroy(message); {
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -210,8 +231,11 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
default: default:
if (!simaka_attribute_skippable(type)) if (!simaka_attribute_skippable(type))
{ {
*out = create_client_error(this);
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (!create_client_error(this, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
break; break;
@ -222,7 +246,10 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
if (!rand.len || !autn.len) if (!rand.len || !autn.len)
{ {
DBG1(DBG_IKE, "received invalid EAP-AKA challenge message"); DBG1(DBG_IKE, "received invalid EAP-AKA challenge message");
*out = create_client_error(this); if (!create_client_error(this, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -237,9 +264,10 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
AKA_SYNCHRONIZATION_FAILURE, this->crypto); AKA_SYNCHRONIZATION_FAILURE, this->crypto);
message->add_attribute(message, AT_AUTS, message->add_attribute(message, AT_AUTS,
chunk_create(auts, AKA_AUTS_LEN)); chunk_create(auts, AKA_AUTS_LEN));
*out = eap_payload_create_data_own(message->generate(message, if (!generate_payload(message, chunk_empty, out))
chunk_empty)); {
message->destroy(message); return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
if (status != SUCCESS) if (status != SUCCESS)
@ -248,9 +276,10 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
this->permanent, simaka_subtype_names, AKA_AUTHENTICATION_REJECT); this->permanent, simaka_subtype_names, AKA_AUTHENTICATION_REJECT);
message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA, message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA,
AKA_AUTHENTICATION_REJECT, this->crypto); AKA_AUTHENTICATION_REJECT, this->crypto);
*out = eap_payload_create_data_own(message->generate(message, if (!generate_payload(message, chunk_empty, out))
chunk_empty)); {
message->destroy(message); return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -270,7 +299,10 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
* reading encrypted attributes */ * reading encrypted attributes */
if (!in->verify(in, chunk_empty) || !in->parse(in)) if (!in->verify(in, chunk_empty) || !in->parse(in))
{ {
*out = create_client_error(this); if (!create_client_error(this, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -300,8 +332,10 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
message = simaka_message_create(FALSE, this->identifier, EAP_AKA, message = simaka_message_create(FALSE, this->identifier, EAP_AKA,
AKA_CHALLENGE, this->crypto); AKA_CHALLENGE, this->crypto);
message->add_attribute(message, AT_RES, chunk_create(res, res_len)); message->add_attribute(message, AT_RES, chunk_create(res, res_len));
*out = eap_payload_create_data_own(message->generate(message, chunk_empty)); if (!generate_payload(message, chunk_empty, out))
message->destroy(message); {
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -332,7 +366,10 @@ static status_t process_reauthentication(private_eap_aka_peer_t *this,
{ {
DBG1(DBG_IKE, "received %N, but not expected", DBG1(DBG_IKE, "received %N, but not expected",
simaka_subtype_names, AKA_REAUTHENTICATION); simaka_subtype_names, AKA_REAUTHENTICATION);
*out = create_client_error(this); if (!create_client_error(this, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -342,7 +379,10 @@ static status_t process_reauthentication(private_eap_aka_peer_t *this,
/* verify MAC and parse again with decryption key */ /* verify MAC and parse again with decryption key */
if (!in->verify(in, chunk_empty) || !in->parse(in)) if (!in->verify(in, chunk_empty) || !in->parse(in))
{ {
*out = create_client_error(this); if (!create_client_error(this, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -363,8 +403,11 @@ static status_t process_reauthentication(private_eap_aka_peer_t *this,
default: default:
if (!simaka_attribute_skippable(type)) if (!simaka_attribute_skippable(type))
{ {
*out = create_client_error(this);
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (!create_client_error(this, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
break; break;
@ -375,7 +418,10 @@ static status_t process_reauthentication(private_eap_aka_peer_t *this,
if (!nonce.len || !counter.len) if (!nonce.len || !counter.len)
{ {
DBG1(DBG_IKE, "EAP-AKA/Request/Reauthentication message incomplete"); DBG1(DBG_IKE, "EAP-AKA/Request/Reauthentication message incomplete");
*out = create_client_error(this); if (!create_client_error(this, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -403,8 +449,10 @@ static status_t process_reauthentication(private_eap_aka_peer_t *this,
} }
} }
message->add_attribute(message, AT_COUNTER, counter); message->add_attribute(message, AT_COUNTER, counter);
*out = eap_payload_create_data_own(message->generate(message, nonce)); if (!generate_payload(message, nonce, out))
message->destroy(message); {
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -454,13 +502,17 @@ static status_t process_notification(private_eap_aka_peer_t *this,
{ /* empty notification reply */ { /* empty notification reply */
message = simaka_message_create(FALSE, this->identifier, EAP_AKA, message = simaka_message_create(FALSE, this->identifier, EAP_AKA,
AKA_NOTIFICATION, this->crypto); AKA_NOTIFICATION, this->crypto);
*out = eap_payload_create_data_own(message->generate(message, if (!generate_payload(message, chunk_empty, out))
chunk_empty)); {
message->destroy(message); return FAILED;
}
} }
else else
{ {
*out = create_client_error(this); if (!create_client_error(this, out))
{
return FAILED;
}
} }
return NEED_MORE; return NEED_MORE;
} }
@ -478,13 +530,19 @@ METHOD(eap_method_t, process, status_t,
message = simaka_message_create_from_payload(in->get_data(in), this->crypto); message = simaka_message_create_from_payload(in->get_data(in), this->crypto);
if (!message) if (!message)
{ {
*out = create_client_error(this); if (!create_client_error(this, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
if (!message->parse(message)) if (!message->parse(message))
{ {
message->destroy(message); message->destroy(message);
*out = create_client_error(this); if (!create_client_error(this, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
switch (message->get_subtype(message)) switch (message->get_subtype(message))
@ -504,8 +562,14 @@ METHOD(eap_method_t, process, status_t,
default: default:
DBG1(DBG_IKE, "unable to process EAP-AKA subtype %N", DBG1(DBG_IKE, "unable to process EAP-AKA subtype %N",
simaka_subtype_names, message->get_subtype(message)); simaka_subtype_names, message->get_subtype(message));
*out = create_client_error(this); if (!create_client_error(this, out))
status = NEED_MORE; {
status = FAILED;
}
else
{
status = NEED_MORE;
}
break; break;
} }
message->destroy(message); message->destroy(message);

View File

@ -118,6 +118,24 @@ struct private_eap_aka_server_t {
bool synchronized; bool synchronized;
}; };
/**
* Generate a payload from a message, destroy message
*/
static bool generate_payload(simaka_message_t *message, chunk_t data,
eap_payload_t **out)
{
chunk_t chunk;
bool ok;
ok = message->generate(message, data, &chunk);
if (ok)
{
*out = eap_payload_create_data_own(chunk);
}
message->destroy(message);
return ok;
}
/** /**
* Create EAP-AKA/Request/Identity message * Create EAP-AKA/Request/Identity message
*/ */
@ -139,9 +157,10 @@ static status_t identity(private_eap_aka_server_t *this, eap_payload_t **out)
{ {
message->add_attribute(message, AT_PERMANENT_ID_REQ, chunk_empty); message->add_attribute(message, AT_PERMANENT_ID_REQ, chunk_empty);
} }
*out = eap_payload_create_data_own(message->generate(message, chunk_empty)); if (!generate_payload(message, chunk_empty, out))
message->destroy(message); {
return FAILED;
}
this->pending = AKA_IDENTITY; this->pending = AKA_IDENTITY;
return NEED_MORE; return NEED_MORE;
} }
@ -190,6 +209,7 @@ static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out)
message->add_attribute(message, AT_RAND, this->rand); message->add_attribute(message, AT_RAND, this->rand);
message->add_attribute(message, AT_AUTN, chunk_create(autn, AKA_AUTN_LEN)); message->add_attribute(message, AT_AUTN, chunk_create(autn, AKA_AUTN_LEN));
id = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk.ptr); id = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk.ptr);
free(mk.ptr);
if (id) if (id)
{ {
message->add_attribute(message, AT_NEXT_REAUTH_ID, message->add_attribute(message, AT_NEXT_REAUTH_ID,
@ -203,10 +223,10 @@ static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out)
id->get_encoding(id)); id->get_encoding(id));
id->destroy(id); id->destroy(id);
} }
*out = eap_payload_create_data_own(message->generate(message, chunk_empty)); if (!generate_payload(message, chunk_empty, out))
message->destroy(message); {
return FAILED;
free(mk.ptr); }
this->pending = AKA_CHALLENGE; this->pending = AKA_CHALLENGE;
return NEED_MORE; return NEED_MORE;
} }
@ -247,9 +267,10 @@ static status_t reauthenticate(private_eap_aka_server_t *this,
next->get_encoding(next)); next->get_encoding(next));
next->destroy(next); next->destroy(next);
} }
*out = eap_payload_create_data_own(message->generate(message, chunk_empty)); if (!generate_payload(message, chunk_empty, out))
message->destroy(message); {
return FAILED;
}
this->pending = SIM_REAUTHENTICATION; this->pending = SIM_REAUTHENTICATION;
return NEED_MORE; return NEED_MORE;
} }

View File

@ -105,14 +105,31 @@ struct private_eap_sim_peer_t {
/* version of SIM protocol we speak */ /* version of SIM protocol we speak */
static chunk_t version = chunk_from_chars(0x00,0x01); static chunk_t version = chunk_from_chars(0x00,0x01);
/**
* Generate a payload from a message, destroy message
*/
static bool generate_payload(simaka_message_t *message, chunk_t data,
eap_payload_t **out)
{
chunk_t chunk;
bool ok;
ok = message->generate(message, data, &chunk);
if (ok)
{
*out = eap_payload_create_data_own(chunk);
}
message->destroy(message);
return ok;
}
/** /**
* Create a SIM_CLIENT_ERROR * Create a SIM_CLIENT_ERROR
*/ */
static eap_payload_t* create_client_error(private_eap_sim_peer_t *this, static bool create_client_error(private_eap_sim_peer_t *this,
simaka_client_error_t code) simaka_client_error_t code, eap_payload_t **out)
{ {
simaka_message_t *message; simaka_message_t *message;
eap_payload_t *out;
u_int16_t encoded; u_int16_t encoded;
DBG1(DBG_IKE, "sending client error '%N'", simaka_client_error_names, code); DBG1(DBG_IKE, "sending client error '%N'", simaka_client_error_names, code);
@ -122,9 +139,7 @@ static eap_payload_t* create_client_error(private_eap_sim_peer_t *this,
encoded = htons(code); encoded = htons(code);
message->add_attribute(message, AT_CLIENT_ERROR_CODE, message->add_attribute(message, AT_CLIENT_ERROR_CODE,
chunk_create((char*)&encoded, sizeof(encoded))); chunk_create((char*)&encoded, sizeof(encoded)));
out = eap_payload_create_data_own(message->generate(message, chunk_empty)); return generate_payload(message, chunk_empty, out);
message->destroy(message);
return out;
} }
/** /**
@ -175,8 +190,11 @@ static status_t process_start(private_eap_sim_peer_t *this,
default: default:
if (!simaka_attribute_skippable(type)) if (!simaka_attribute_skippable(type))
{ {
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (!create_client_error(this, SIM_UNABLE_TO_PROCESS, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
break; break;
@ -187,7 +205,10 @@ static status_t process_start(private_eap_sim_peer_t *this,
if (!supported) if (!supported)
{ {
DBG1(DBG_IKE, "server does not support EAP-SIM version number 1"); DBG1(DBG_IKE, "server does not support EAP-SIM version number 1");
*out = create_client_error(this, SIM_UNSUPPORTED_VERSION); if (!create_client_error(this, SIM_UNSUPPORTED_VERSION, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -234,9 +255,10 @@ static status_t process_start(private_eap_sim_peer_t *this,
{ {
message->add_attribute(message, AT_IDENTITY, id); message->add_attribute(message, AT_IDENTITY, id);
} }
*out = eap_payload_create_data_own(message->generate(message, chunk_empty)); if (!generate_payload(message, chunk_empty, out))
message->destroy(message); {
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -270,8 +292,11 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
default: default:
if (!simaka_attribute_skippable(type)) if (!simaka_attribute_skippable(type))
{ {
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (!create_client_error(this, SIM_UNABLE_TO_PROCESS, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
break; break;
@ -285,7 +310,10 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
memeq(rands.ptr, rands.ptr + SIM_RAND_LEN, SIM_RAND_LEN)) memeq(rands.ptr, rands.ptr + SIM_RAND_LEN, SIM_RAND_LEN))
{ {
DBG1(DBG_IKE, "no valid AT_RAND received"); DBG1(DBG_IKE, "no valid AT_RAND received");
*out = create_client_error(this, SIM_INSUFFICIENT_CHALLENGES); if (!create_client_error(this, SIM_INSUFFICIENT_CHALLENGES, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
/* get two or three KCs/SRESes from SIM using RANDs */ /* get two or three KCs/SRESes from SIM using RANDs */
@ -297,7 +325,10 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
rands.ptr, sres.ptr, kc.ptr)) rands.ptr, sres.ptr, kc.ptr))
{ {
DBG1(DBG_IKE, "unable to get EAP-SIM triplet"); DBG1(DBG_IKE, "unable to get EAP-SIM triplet");
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS); if (!create_client_error(this, SIM_UNABLE_TO_PROCESS, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
DBG3(DBG_IKE, "got triplet for RAND %b\n Kc %b\n SRES %b", DBG3(DBG_IKE, "got triplet for RAND %b\n Kc %b\n SRES %b",
@ -322,7 +353,10 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
* parse() again after key derivation, reading encrypted attributes */ * parse() again after key derivation, reading encrypted attributes */
if (!in->verify(in, this->nonce) || !in->parse(in)) if (!in->verify(in, this->nonce) || !in->parse(in))
{ {
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS); if (!create_client_error(this, SIM_UNABLE_TO_PROCESS, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -352,8 +386,10 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
/* build response with AT_MAC, built over "EAP packet | n*SRES" */ /* build response with AT_MAC, built over "EAP packet | n*SRES" */
message = simaka_message_create(FALSE, this->identifier, EAP_SIM, message = simaka_message_create(FALSE, this->identifier, EAP_SIM,
SIM_CHALLENGE, this->crypto); SIM_CHALLENGE, this->crypto);
*out = eap_payload_create_data_own(message->generate(message, sreses)); if (!generate_payload(message, sreses, out))
message->destroy(message); {
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -384,7 +420,10 @@ static status_t process_reauthentication(private_eap_sim_peer_t *this,
{ {
DBG1(DBG_IKE, "received %N, but not expected", DBG1(DBG_IKE, "received %N, but not expected",
simaka_subtype_names, SIM_REAUTHENTICATION); simaka_subtype_names, SIM_REAUTHENTICATION);
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS); if (!create_client_error(this, SIM_UNABLE_TO_PROCESS, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -394,7 +433,10 @@ static status_t process_reauthentication(private_eap_sim_peer_t *this,
/* verify MAC and parse again with decryption key */ /* verify MAC and parse again with decryption key */
if (!in->verify(in, chunk_empty) || !in->parse(in)) if (!in->verify(in, chunk_empty) || !in->parse(in))
{ {
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS); if (!create_client_error(this, SIM_UNABLE_TO_PROCESS, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -415,8 +457,11 @@ static status_t process_reauthentication(private_eap_sim_peer_t *this,
default: default:
if (!simaka_attribute_skippable(type)) if (!simaka_attribute_skippable(type))
{ {
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (!create_client_error(this, SIM_UNABLE_TO_PROCESS, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
break; break;
@ -427,7 +472,10 @@ static status_t process_reauthentication(private_eap_sim_peer_t *this,
if (!nonce.len || !counter.len) if (!nonce.len || !counter.len)
{ {
DBG1(DBG_IKE, "EAP-SIM/Request/Re-Authentication message incomplete"); DBG1(DBG_IKE, "EAP-SIM/Request/Re-Authentication message incomplete");
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS); if (!create_client_error(this, SIM_UNABLE_TO_PROCESS, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -455,8 +503,10 @@ static status_t process_reauthentication(private_eap_sim_peer_t *this,
} }
} }
message->add_attribute(message, AT_COUNTER, counter); message->add_attribute(message, AT_COUNTER, counter);
*out = eap_payload_create_data_own(message->generate(message, nonce)); if (!generate_payload(message, nonce, out))
message->destroy(message); {
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
@ -506,13 +556,17 @@ static status_t process_notification(private_eap_sim_peer_t *this,
{ /* empty notification reply */ { /* empty notification reply */
message = simaka_message_create(FALSE, this->identifier, EAP_SIM, message = simaka_message_create(FALSE, this->identifier, EAP_SIM,
SIM_NOTIFICATION, this->crypto); SIM_NOTIFICATION, this->crypto);
*out = eap_payload_create_data_own(message->generate(message, if (!generate_payload(message, chunk_empty, out))
chunk_empty)); {
message->destroy(message); return FAILED;
}
} }
else else
{ {
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS); if (!create_client_error(this, SIM_UNABLE_TO_PROCESS, out))
{
return FAILED;
}
} }
return NEED_MORE; return NEED_MORE;
} }
@ -529,13 +583,19 @@ METHOD(eap_method_t, process, status_t,
message = simaka_message_create_from_payload(in->get_data(in), this->crypto); message = simaka_message_create_from_payload(in->get_data(in), this->crypto);
if (!message) if (!message)
{ {
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS); if (!create_client_error(this, SIM_UNABLE_TO_PROCESS, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
if (!message->parse(message)) if (!message->parse(message))
{ {
message->destroy(message); message->destroy(message);
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS); if (!create_client_error(this, SIM_UNABLE_TO_PROCESS, out))
{
return FAILED;
}
return NEED_MORE; return NEED_MORE;
} }
switch (message->get_subtype(message)) switch (message->get_subtype(message))
@ -555,8 +615,14 @@ METHOD(eap_method_t, process, status_t,
default: default:
DBG1(DBG_IKE, "unable to process EAP-SIM subtype %N", DBG1(DBG_IKE, "unable to process EAP-SIM subtype %N",
simaka_subtype_names, message->get_subtype(message)); simaka_subtype_names, message->get_subtype(message));
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS); if (!create_client_error(this, SIM_UNABLE_TO_PROCESS, out))
status = NEED_MORE; {
status = FAILED;
}
else
{
status = NEED_MORE;
}
break; break;
} }
message->destroy(message); message->destroy(message);

View File

@ -113,6 +113,24 @@ struct private_eap_sim_server_t {
/* version of SIM protocol we speak */ /* version of SIM protocol we speak */
static chunk_t version = chunk_from_chars(0x00,0x01); static chunk_t version = chunk_from_chars(0x00,0x01);
/**
* Generate a payload from a message, destroy message
*/
static bool generate_payload(simaka_message_t *message, chunk_t data,
eap_payload_t **out)
{
chunk_t chunk;
bool ok;
ok = message->generate(message, data, &chunk);
if (ok)
{
*out = eap_payload_create_data_own(chunk);
}
message->destroy(message);
return ok;
}
METHOD(eap_method_t, initiate, status_t, METHOD(eap_method_t, initiate, status_t,
private_eap_sim_server_t *this, eap_payload_t **out) private_eap_sim_server_t *this, eap_payload_t **out)
{ {
@ -133,9 +151,10 @@ METHOD(eap_method_t, initiate, status_t,
{ {
message->add_attribute(message, AT_PERMANENT_ID_REQ, chunk_empty); message->add_attribute(message, AT_PERMANENT_ID_REQ, chunk_empty);
} }
*out = eap_payload_create_data_own(message->generate(message, chunk_empty)); if (!generate_payload(message, chunk_empty, out))
message->destroy(message); {
return FAILED;
}
this->pending = SIM_START; this->pending = SIM_START;
return NEED_MORE; return NEED_MORE;
} }
@ -176,9 +195,10 @@ static status_t reauthenticate(private_eap_sim_server_t *this,
next->get_encoding(next)); next->get_encoding(next));
next->destroy(next); next->destroy(next);
} }
*out = eap_payload_create_data_own(message->generate(message, chunk_empty)); if (!generate_payload(message, chunk_empty, out))
message->destroy(message); {
return FAILED;
}
this->pending = SIM_REAUTHENTICATION; this->pending = SIM_REAUTHENTICATION;
return NEED_MORE; return NEED_MORE;
} }
@ -393,6 +413,7 @@ static status_t process_start(private_eap_sim_server_t *this,
SIM_CHALLENGE, this->crypto); SIM_CHALLENGE, this->crypto);
message->add_attribute(message, AT_RAND, rands); message->add_attribute(message, AT_RAND, rands);
id = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk.ptr); id = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk.ptr);
free(mk.ptr);
if (id) if (id)
{ {
message->add_attribute(message, AT_NEXT_REAUTH_ID, message->add_attribute(message, AT_NEXT_REAUTH_ID,
@ -406,10 +427,10 @@ static status_t process_start(private_eap_sim_server_t *this,
id->get_encoding(id)); id->get_encoding(id));
id->destroy(id); id->destroy(id);
} }
*out = eap_payload_create_data_own(message->generate(message, nonce)); if (!generate_payload(message, nonce, out))
message->destroy(message); {
return FAILED;
free(mk.ptr); }
this->pending = SIM_CHALLENGE; this->pending = SIM_CHALLENGE;
return NEED_MORE; return NEED_MORE;
} }

View File

@ -599,8 +599,8 @@ METHOD(simaka_message_t, verify, bool,
return TRUE; return TRUE;
} }
METHOD(simaka_message_t, generate, chunk_t, METHOD(simaka_message_t, generate, bool,
private_simaka_message_t *this, chunk_t sigdata) private_simaka_message_t *this, chunk_t sigdata, chunk_t *gen)
{ {
/* buffers large enough for messages we generate */ /* buffers large enough for messages we generate */
char out_buf[1024], encr_buf[512]; char out_buf[1024], encr_buf[512];
@ -827,7 +827,8 @@ METHOD(simaka_message_t, generate, chunk_t,
call_hook(this, FALSE, FALSE); call_hook(this, FALSE, FALSE);
return chunk_clone(out); *gen = chunk_clone(out);
return TRUE;
} }
METHOD(simaka_message_t, destroy, void, METHOD(simaka_message_t, destroy, void,

View File

@ -236,9 +236,10 @@ struct simaka_message_t {
* Generate a message, optionally encrypt attributes and create a MAC. * Generate a message, optionally encrypt attributes and create a MAC.
* *
* @param sigdata additional data to include in signature, if any * @param sigdata additional data to include in signature, if any
* @return allocated data of generated message * @param gen allocated generated data, if successful
* @return TRUE if successful
*/ */
chunk_t (*generate)(simaka_message_t *this, chunk_t sigdata); bool (*generate)(simaka_message_t *this, chunk_t sigdata, chunk_t *gen);
/** /**
* Destroy a simaka_message_t. * Destroy a simaka_message_t.