#define VENDORPEC_FREERADIUS 11344
#define VENDORPEC_WIMAX 24757
#define VENDORPEC_EXTENDED (1 << 25)
+#define VENDORPEC_UKERNA 25622
/*
* Vendor specific attributes
#define PW_VQP_MAC 0x2c06
#define PW_VQP_UNKNOWN 0x2c07
#define PW_VQP_COOKIE 0x2c08
+
+/*
+ * JANET's code for transporting eap channel binding data over ttls
+ */
+
+#define PW_UKERNA_CHBIND 134
uint8_t data[1];
} eap_packet_t;
+/*
+ * Structure to represent eap channel binding packet format *on wire*
+ */
+typedef struct eap_chbind_packet_t {
+ uint8_t code;
+ uint8_t data[1];
+} eap_chbind_packet_t;
+
/*
* interfaces in eapcommon.c
extern int eap_basic_compose(RADIUS_PACKET *packet, EAP_PACKET *reply);
extern VALUE_PAIR *eap_packet2vp(const eap_packet_t *reply);
extern eap_packet_t *eap_vp2packet(VALUE_PAIR *vps);
+extern VALUE_PAIR *eap_chbind_packet2vp(const eap_chbind_packet_t *packet, size_t len);
+extern size_t eap_chbind_vp2packet(VALUE_PAIR *vps, eap_chbind_packet_t **packet);
#endif /* _EAP_TYPES_H */
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;
+}
const uint8_t *data;
size_t data_len;
REQUEST *request = handler->request;
+ eap_chbind_packet_t *chbind_packet;
+ size_t chbind_len;
rad_assert(request != NULL);
}
/*
+ * Process channel binding here.
+ */
+ chbind_len = eap_chbind_vp2packet(fake->packet->vps, &chbind_packet);
+ if (chbind_len > 0) {
+ /*CHBIND_REQ *req = chbind_allocate();
+ req->chbind_req = chbind_packet;
+ req->chbind_req_len = chbind_len;
+ if (fake->username) {
+ req->username = fake->username->vp_octets;
+ req->username_len = fake->username->length;
+ } else {
+ req->username = NULL;
+ req->username_len = 0;
+ }
+ chbind_process(request, req);
+ */
+
+ /* free the chbind packet; we're done with it */
+ free(chbind_packet);
+
+ /* encapsulate response here */
+ /*pairadd(replyvps, eap_chbind_packet2vp(req->chbind_resp,
+ req->chbind_resp_len));
+ */
+
+ /* clean up chbind req */
+ /*chbind_free(req);*/
+ }
+
+ /*
* Call authentication recursively, which will
* do PAP, CHAP, MS-CHAP, etc.
*/