EAP-pwd peer: Fix fragmentation of PWD-Confirm-Resp

This is somewhat of a corner case since there is no real point in using
so short a fragmentation threshold that it would result in this message
getting fragmented. Anyway, it is better be complete and support this
case as well.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2014-04-06 00:51:00 +03:00
parent 48f668eecf
commit 9437c2d0ea

View file

@ -16,7 +16,8 @@
struct eap_pwd_data { struct eap_pwd_data {
enum { enum {
PWD_ID_Req, PWD_Commit_Req, PWD_Confirm_Req, SUCCESS, FAILURE PWD_ID_Req, PWD_Commit_Req, PWD_Confirm_Req,
SUCCESS_ON_FRAG_COMPLETION, SUCCESS, FAILURE
} state; } state;
u8 *id_peer; u8 *id_peer;
size_t id_peer_len; size_t id_peer_len;
@ -57,6 +58,8 @@ static const char * eap_pwd_state_txt(int state)
return "PWD-Commit-Req"; return "PWD-Commit-Req";
case PWD_Confirm_Req: case PWD_Confirm_Req:
return "PWD-Confirm-Req"; return "PWD-Confirm-Req";
case SUCCESS_ON_FRAG_COMPLETION:
return "SUCCESS_ON_FRAG_COMPLETION";
case SUCCESS: case SUCCESS:
return "SUCCESS"; return "SUCCESS";
case FAILURE: case FAILURE:
@ -660,13 +663,12 @@ fin:
os_free(cruft); os_free(cruft);
BN_free(x); BN_free(x);
BN_free(y); BN_free(y);
ret->methodState = METHOD_DONE;
if (data->outbuf == NULL) { if (data->outbuf == NULL) {
ret->methodState = METHOD_DONE;
ret->decision = DECISION_FAIL; ret->decision = DECISION_FAIL;
eap_pwd_state(data, FAILURE); eap_pwd_state(data, FAILURE);
} else { } else {
ret->decision = DECISION_UNCOND_SUCC; eap_pwd_state(data, SUCCESS_ON_FRAG_COMPLETION);
eap_pwd_state(data, SUCCESS);
} }
} }
@ -743,6 +745,11 @@ eap_pwd_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret,
wpa_printf(MSG_DEBUG, "EAP-pwd: Send %s fragment of %d bytes", wpa_printf(MSG_DEBUG, "EAP-pwd: Send %s fragment of %d bytes",
data->out_frag_pos == 0 ? "last" : "next", data->out_frag_pos == 0 ? "last" : "next",
(int) len); (int) len);
if (data->state == SUCCESS_ON_FRAG_COMPLETION) {
ret->methodState = METHOD_DONE;
ret->decision = DECISION_UNCOND_SUCC;
eap_pwd_state(data, SUCCESS);
}
return resp; return resp;
} }
@ -875,6 +882,11 @@ eap_pwd_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret,
wpabuf_free(data->outbuf); wpabuf_free(data->outbuf);
data->outbuf = NULL; data->outbuf = NULL;
data->out_frag_pos = 0; data->out_frag_pos = 0;
if (data->state == SUCCESS_ON_FRAG_COMPLETION) {
ret->methodState = METHOD_DONE;
ret->decision = DECISION_UNCOND_SUCC;
eap_pwd_state(data, SUCCESS);
}
} }
return resp; return resp;