RADIUS: Allow Message-Authenticator attribute as the first attribute
If a Message-Authenticator attribute was already added to a RADIUS message, use that attribute instead of adding a new one when finishing message building. This allows the Message-Authenticator attribute to be placed as the first attribute in the message. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
566dc139a0
commit
adac846bd0
2 changed files with 54 additions and 32 deletions
|
@ -423,25 +423,54 @@ void radius_msg_dump(struct radius_msg *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u8 * radius_msg_add_msg_auth(struct radius_msg *msg)
|
||||||
|
{
|
||||||
|
u8 auth[MD5_MAC_LEN];
|
||||||
|
struct radius_attr_hdr *attr;
|
||||||
|
|
||||||
|
os_memset(auth, 0, MD5_MAC_LEN);
|
||||||
|
attr = radius_msg_add_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
|
||||||
|
auth, MD5_MAC_LEN);
|
||||||
|
if (!attr) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"WARNING: Could not add Message-Authenticator");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (u8 *) (attr + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * radius_msg_auth_pos(struct radius_msg *msg)
|
||||||
|
{
|
||||||
|
u8 *pos;
|
||||||
|
size_t alen;
|
||||||
|
|
||||||
|
if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
|
||||||
|
&pos, &alen, NULL) == 0 &&
|
||||||
|
alen == MD5_MAC_LEN) {
|
||||||
|
/* Use already added Message-Authenticator attribute */
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a Message-Authenticator attribute */
|
||||||
|
return radius_msg_add_msg_auth(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
|
int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
|
||||||
size_t secret_len)
|
size_t secret_len)
|
||||||
{
|
{
|
||||||
if (secret) {
|
if (secret) {
|
||||||
u8 auth[MD5_MAC_LEN];
|
u8 *pos;
|
||||||
struct radius_attr_hdr *attr;
|
|
||||||
|
|
||||||
os_memset(auth, 0, MD5_MAC_LEN);
|
pos = radius_msg_auth_pos(msg);
|
||||||
attr = radius_msg_add_attr(msg,
|
if (!pos)
|
||||||
RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
|
|
||||||
auth, MD5_MAC_LEN);
|
|
||||||
if (attr == NULL) {
|
|
||||||
wpa_printf(MSG_WARNING, "RADIUS: Could not add "
|
|
||||||
"Message-Authenticator");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
|
msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
|
||||||
hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
|
if (hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
|
||||||
wpabuf_len(msg->buf), (u8 *) (attr + 1));
|
wpabuf_len(msg->buf), pos) < 0)
|
||||||
|
return -1;
|
||||||
} else
|
} else
|
||||||
msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
|
msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
|
||||||
|
|
||||||
|
@ -457,23 +486,19 @@ int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
|
||||||
int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,
|
int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,
|
||||||
size_t secret_len, const u8 *req_authenticator)
|
size_t secret_len, const u8 *req_authenticator)
|
||||||
{
|
{
|
||||||
u8 auth[MD5_MAC_LEN];
|
|
||||||
struct radius_attr_hdr *attr;
|
|
||||||
const u8 *addr[4];
|
const u8 *addr[4];
|
||||||
size_t len[4];
|
size_t len[4];
|
||||||
|
u8 *pos;
|
||||||
|
|
||||||
os_memset(auth, 0, MD5_MAC_LEN);
|
pos = radius_msg_auth_pos(msg);
|
||||||
attr = radius_msg_add_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
|
if (!pos)
|
||||||
auth, MD5_MAC_LEN);
|
|
||||||
if (attr == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "WARNING: Could not add Message-Authenticator");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
|
msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
|
||||||
os_memcpy(msg->hdr->authenticator, req_authenticator,
|
os_memcpy(msg->hdr->authenticator, req_authenticator,
|
||||||
sizeof(msg->hdr->authenticator));
|
sizeof(msg->hdr->authenticator));
|
||||||
hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
|
if (hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
|
||||||
wpabuf_len(msg->buf), (u8 *) (attr + 1));
|
wpabuf_len(msg->buf), pos) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret) */
|
/* ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret) */
|
||||||
addr[0] = (u8 *) msg->hdr;
|
addr[0] = (u8 *) msg->hdr;
|
||||||
|
@ -501,21 +526,17 @@ int radius_msg_finish_das_resp(struct radius_msg *msg, const u8 *secret,
|
||||||
{
|
{
|
||||||
const u8 *addr[2];
|
const u8 *addr[2];
|
||||||
size_t len[2];
|
size_t len[2];
|
||||||
u8 auth[MD5_MAC_LEN];
|
u8 *pos;
|
||||||
struct radius_attr_hdr *attr;
|
|
||||||
|
|
||||||
os_memset(auth, 0, MD5_MAC_LEN);
|
pos = radius_msg_auth_pos(msg);
|
||||||
attr = radius_msg_add_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
|
if (!pos)
|
||||||
auth, MD5_MAC_LEN);
|
|
||||||
if (attr == NULL) {
|
|
||||||
wpa_printf(MSG_WARNING, "Could not add Message-Authenticator");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
|
msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
|
||||||
os_memcpy(msg->hdr->authenticator, req_hdr->authenticator, 16);
|
os_memcpy(msg->hdr->authenticator, req_hdr->authenticator, 16);
|
||||||
hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
|
if (hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
|
||||||
wpabuf_len(msg->buf), (u8 *) (attr + 1));
|
wpabuf_len(msg->buf), pos) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret) */
|
/* ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret) */
|
||||||
addr[0] = wpabuf_head_u8(msg->buf);
|
addr[0] = wpabuf_head_u8(msg->buf);
|
||||||
|
|
|
@ -268,6 +268,7 @@ struct wpabuf * radius_msg_get_buf(struct radius_msg *msg);
|
||||||
struct radius_msg * radius_msg_new(u8 code, u8 identifier);
|
struct radius_msg * radius_msg_new(u8 code, u8 identifier);
|
||||||
void radius_msg_free(struct radius_msg *msg);
|
void radius_msg_free(struct radius_msg *msg);
|
||||||
void radius_msg_dump(struct radius_msg *msg);
|
void radius_msg_dump(struct radius_msg *msg);
|
||||||
|
u8 * radius_msg_add_msg_auth(struct radius_msg *msg);
|
||||||
int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
|
int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
|
||||||
size_t secret_len);
|
size_t secret_len);
|
||||||
int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,
|
int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,
|
||||||
|
|
Loading…
Reference in a new issue