#include <freeradius-devel/ident.h>
RCSID("$Id$")
-#include <freeradius-devel/autoconf.h>
-#include <freeradius-devel/missing.h>
#include <freeradius-devel/libradius.h>
#include "eap_types.h"
"pax",
"psk",
"sake",
- "ikev2"
+ "ikev2",
+ "50",
+ "51",
+ "pwd"
}; /* MUST have PW_EAP_MAX_TYPES */
/*
* Prefer the dictionary name over a number,
* if it exists.
*/
- dval = dict_valbyattr(PW_EAP_TYPE, type);
+ dval = dict_valbyattr(PW_EAP_TYPE, 0, type);
if (dval) {
snprintf(buffer, buflen, "%s", dval->name);
}
/*
* Prefer the dictionary name, if it exists.
*/
- dval = dict_valbyattr(PW_EAP_TYPE, type);
+ dval = dict_valbyattr(PW_EAP_TYPE, 0, type);
if (dval) {
snprintf(buffer, buflen, "%s", dval->name);
return buffer;
}
eap_packet = (eap_packet_t *)reply->packet;
- pairdelete(&(packet->vps), PW_EAP_MESSAGE);
+ pairdelete(&(packet->vps), PW_EAP_MESSAGE, 0, TAG_ANY);
vp = eap_packet2vp(eap_packet);
if (!vp) return RLM_MODULE_INVALID;
* Don't add a Message-Authenticator if it's already
* there.
*/
- vp = pairfind(packet->vps, PW_MESSAGE_AUTHENTICATOR);
+ vp = pairfind(packet->vps, PW_MESSAGE_AUTHENTICATOR, 0, TAG_ANY);
if (!vp) {
- vp = paircreate(PW_MESSAGE_AUTHENTICATOR, PW_TYPE_OCTETS);
+ vp = paircreate(PW_MESSAGE_AUTHENTICATOR, 0);
memset(vp->vp_strvalue, 0, AUTH_VECTOR_LEN);
vp->length = AUTH_VECTOR_LEN;
pairadd(&(packet->vps), vp);
size = total;
if (size > 253) size = 253;
- vp = paircreate(PW_EAP_MESSAGE, PW_TYPE_OCTETS);
+ vp = paircreate(PW_EAP_MESSAGE, 0);
if (!vp) {
pairfree(&head);
return NULL;
/*
* Get only EAP-Message attribute list
*/
- first = pairfind(vps, PW_EAP_MESSAGE);
+ first = pairfind(vps, PW_EAP_MESSAGE, 0, TAG_ANY);
if (first == NULL) {
- radlog(L_ERR, "rlm_eap: EAP-Message not found");
+ DEBUG("rlm_eap: EAP-Message not found");
return NULL;
}
* Sanity check the length before doing anything.
*/
if (first->length < 4) {
- radlog(L_ERR, "rlm_eap: EAP packet is too short.");
+ DEBUG("rlm_eap: EAP packet is too short.");
return NULL;
}
* Take out even more weird things.
*/
if (len < 4) {
- radlog(L_ERR, "rlm_eap: EAP packet has invalid length.");
+ DEBUG("rlm_eap: EAP packet has invalid length.");
return NULL;
}
* Sanity check the length, BEFORE malloc'ing memory.
*/
total_len = 0;
- for (vp = first; vp; vp = pairfind(vp->next, PW_EAP_MESSAGE)) {
+ for (vp = first; vp; vp = pairfind(vp->next, PW_EAP_MESSAGE, 0, TAG_ANY)) {
total_len += vp->length;
if (total_len > len) {
- radlog(L_ERR, "rlm_eap: Malformed EAP packet. Length in packet header does not match actual length");
+ DEBUG("rlm_eap: Malformed EAP packet. Length in packet header does not match actual length");
return NULL;
}
}
* If the length is SMALLER, die, too.
*/
if (total_len < len) {
- radlog(L_ERR, "rlm_eap: Malformed EAP packet. Length in packet header does not match actual length");
+ DEBUG("rlm_eap: Malformed EAP packet. Length in packet header does not match actual length");
return NULL;
}
ptr = (unsigned char *)eap_packet;
/* RADIUS ensures order of attrs, so just concatenate all */
- for (vp = first; vp; vp = pairfind(vp->next, PW_EAP_MESSAGE)) {
+ for (vp = first; vp; vp = pairfind(vp->next, PW_EAP_MESSAGE, 0, TAG_ANY)) {
memcpy(ptr, vp->vp_strvalue, vp->length);
ptr += vp->length;
}
return eap_packet;
}
+
+VALUE_PAIR *eap_chbind_packet2vp(const eap_chbind_packet_t *packet, size_t len)
+{
+ size_t size;
+ const uint8_t *ptr;
+ VALUE_PAIR *head = NULL;
+ VALUE_PAIR **tail = &head;
+ VALUE_PAIR *vp;
+
+ ptr = (const uint8_t *) packet;
+
+ do {
+ size = len;
+ if (size > 247) size = 247;
+
+ vp = paircreate(PW_VENDOR_SPECIFIC, VENDORPEC_UKERNA,
+ PW_TYPE_OCTETS);
+ if (!vp) {
+ pairfree(&head);
+ return NULL;
+ }
+ vp->vp_octets[0] = PW_UKERNA_CHBIND;
+ vp->vp_octets[1] = size;
+ memcpy(&vp->vp_octets[2], ptr, size);
+ vp->length = size + 2;
+
+ *tail = vp;
+ tail = &(vp->next);
+
+ ptr += size;
+ len -= size;
+ } while (len > 0);
+
+ return head;
+}
+
+
+/*
+ * Find the next EAP-CHANNEL-BINDING message in the
+ * pair list
+ */
+static VALUE_PAIR *eap_chbind_find_pair(VALUE_PAIR *vps)
+{
+ VALUE_PAIR *result = pairfind(vps, PW_VENDOR_SPECIFIC,
+ VENDORPEC_UKERNA);
+ while (result && (result->vp_octets[0] != PW_UKERNA_CHBIND))
+ result = result->next;
+ return result;
+}
+
+/*
+ * Handles multiple EAP-channel-binding Message attrs
+ * ie concatenates all to get the complete EAP-channel-binding packet.
+ */
+size_t eap_chbind_vp2packet(VALUE_PAIR *vps, eap_chbind_packet_t **result)
+{
+ VALUE_PAIR *first, *vp;
+ eap_chbind_packet_t *eap_chbind_packet;
+ unsigned char *ptr;
+ size_t len;
+
+ first = eap_chbind_find_pair(vps);
+
+ /*
+ * Sanity check the length, BEFORE malloc'ing memory.
+ */
+ len = 0;
+ for (vp = first; vp; vp = eap_chbind_find_pair(vp)) {
+ if ((vp->length < 2) ||
+ (vp->length != vp->vp_octets[1]+2)) {
+ DEBUG("rlm_eap: Malformed EAP channel binding value pair. Length in pair header does not match actual length");
+ return 0;
+ }
+ len += vp->vp_octets[1];
+ }
+
+ /*
+ * Now that we know the lengths are OK, allocate memory.
+ */
+ eap_chbind_packet = (eap_chbind_packet_t *) malloc(len);
+ if (eap_chbind_packet == NULL) {
+ radlog(L_ERR, "rlm_eap: out of memory");
+ return 0;
+ }
+
+ /*
+ * Copy the data from EAP-Message's over to our EAP packet.
+ */
+ ptr = (unsigned char *)eap_chbind_packet;
+
+ /* RADIUS ensures order of attrs, so just concatenate all */
+ for (vp = first; vp; vp = eap_chbind_find_pair(vp->next)) {
+ memcpy(ptr, vp->vp_octets+2, vp->length-2);
+ ptr += vp->length-2;
+ }
+
+ *result = eap_chbind_packet;
+ return len;
+}