#include "eap_chbind.h"
-#define MAX_PACKET_LEN 1024
+#define MAX_PACKET_LEN 4096
/*
* Process any channel bindings included in the request.
*/
-CHBIND_REQ *chbind_allocate()
+CHBIND_REQ *chbind_allocate(void)
{
CHBIND_REQ *ret;
- ret = malloc(sizeof CHBIND_REQUQEST);
+ ret = malloc(sizeof *ret);
if (0 != ret)
- memset(ret, 0, sizeof CHBIND_REQUEST);
+ memset(ret, 0, sizeof *ret);
return ret;
}
-void *chbind_free(CHBIND_REQ *chbind)
+void chbind_free(CHBIND_REQ *chbind)
{
/* free the chbind response, if allocated by chbind_process */
if (chbind->chbind_resp)
- free(chbind_resp);
+ free(chbind->chbind_resp);
free(chbind);
}
{
int rcode = PW_AUTHENTICATION_REJECT;
REQUEST *fake = NULL;
- VALUE_PAIR *user_vp = NULL;
+ VALUE_PAIR *vp = NULL;
uint8_t *attr_data;
- uint8_t attr_len = 0;
- int i = 0;
+ size_t datalen = 0;
/* check input parameters */
- rad_assert((request != NULL) &&
+ rad_assert((req != NULL) &&
(chbind_req != NULL) &&
- (chbind_req->username != NULL) &&
- (chbind_req->chbind_req_buf != NULL));
- if (chbind_req->len < 4)
+ (chbind_req->chbind_req_pkt != NULL));
+ if (chbind_req->chbind_req_len < 4)
return PW_AUTHENTICATION_REJECT; /* Is this the right response? */
/* Set-up NULL response for cases where channel bindings can't be processed */
chbind_req->chbind_resp_len = 0;
/* Set-up the fake request */
- fake = request_alloc_fake(request);
+ fake = request_alloc_fake(req);
rad_assert(fake->packet->vps == NULL);
vp = pairmake("Freeradius-Proxied-To", "127.0.0.1", T_OP_EQ);
if (vp) {
}
/* Add the username to the fake request */
- vp = paircreate(PW_USER_NAME, 0, PW_TYPE_STRING);
- rad_assert(vp);
- memcpy(vp->vp_octets, chbind_req->username, chbind_req->username_len);
- vp->length = chbind_req->username_len;
+ if (chbind_req->username) {
+ vp = paircreate(PW_USER_NAME, 0, PW_TYPE_STRING);
+ rad_assert(vp);
+ memcpy(vp->vp_octets, chbind_req->username, chbind_req->username_len);
+ vp->length = chbind_req->username_len;
- pairadd(&fake->packet-vps, vp);
+ pairadd(&fake->packet->vps, vp);
fake->username = pairfind(fake->packet->vps, PW_USER_NAME, 0);
+ }
/* Copy the request state into the fake request */
- vp = paircopy(req->state);
+ /*xxx vp = paircopy(req->state);
if (vp)
- pairadd(&fake->packet->vps, vp);
+ pairadd(&fake->packet->vps, vp);*/
/* Add the channel binding attributes to the fake packet */
- if (0 != (datalen = chbind_get_data((chbind_packet_t *)chbind_req, chbind_req_len,
+ if (0 != (datalen = chbind_get_data((CHBIND_PACKET_T *)chbind_req->chbind_req_pkt, chbind_req->chbind_req_len,
CHBIND_NSID_RADIUS, &attr_data))) {
- if (0 < radattr2vp(NULL, NULL, NULL, attr_data, datalen, &vp)) {
+ if (rad_attr2vp(NULL, NULL, NULL, attr_data, datalen, &vp) <= 0) {
/* If radaddr2vp fails, return NULL string for channel binding response */
- request_free(fake);
- return PW_AUTHENTICATION_OK;
+ request_free(&fake);
+ return PW_AUTHENTICATION_ACK;
}
if (vp)
pairadd(&fake->packet->vps, vp);
fake->server = pairmake("Virtual-Server", "chbind", T_OP_EQ);
/* Call rad_authenticate */
- rad_authenticate(fake);
+ rcode = rad_authenticate(fake);
- switch(fake->reply->code) {
+ switch(rcode) {
/* If rad_authenticate succeeded, build a reply */
case RLM_MODULE_OK:
case RLM_MODULE_HANDLED:
break;
}
- request_free(fake);
+ request_free(&fake);
return rcode;
}
* See http://tools.ietf.org/html/draft-ietf-emu-chbind-13#section-5.3.2:
*/
-size_t chbind_get_data(chbind_packet_t *chbind_packet,
+size_t chbind_get_data(CHBIND_PACKET_T *chbind_packet,
size_t chbind_packet_len,
int desired_nsid,
uint8_t **radbuf_data)
return 0;
}
-uint8_t *chbind_build_response(REQUEST *req, int *resp_len)
+uint8_t *chbind_build_response(REQUEST *req, size_t *resp_len)
{
uint8_t *resp, *rp = NULL;
uint16_t rlen, len = 0;
+ VALUE_PAIR *vp = NULL;
*resp_len = 0;
resp = malloc(MAX_PACKET_LEN + 4);
rad_assert(resp);
/* Set-up the chbind header fields (except length, computed later) */
- vp = pairfind(fake->config_items, PW_CHBIND_RESPONSE_CODE, 0);
- resp[0] = vp->vp_integer;
+ vp = pairfind(req->config_items, PW_CHBIND_RESPONSE_CODE, 0);
+ if (vp)
+ resp[0] = vp->vp_integer;
+ else resp[0] = 3; /*failure*/
+
resp[3] = CHBIND_NSID_RADIUS;
/* Encode the chbind attributes into the response */
- for (vp = fake->reply->vps, rlen = 4;
+ for (vp = req->reply->vps, rlen = 4;
(vp != NULL) && (rlen < MAX_PACKET_LEN + 4);
rlen += len) {
- len = rad_vp2attr(NULL, NULL, NULL, *vp, resp[rlen], (MAX_PACKET_LEN + 4) - rlen);
+ len = rad_vp2attr(NULL, NULL, NULL, vp, resp[rlen], (MAX_PACKET_LEN + 4) - rlen);
}
/* Write the length field into the header */
resp[1] = (uint8_t)(rlen >> 8);
resp[2] = (uint8_t)(rlen & 0x00FF);
- size_t len = (chbind_packet->data[pos] << 8) +
- chbind_packet->data[pos + 1];
/* Output the length of the entire response (attrs + header) */
*resp_len = rlen + 4;
#include "eap.h"
/* Structure to hold channel bindings req/resp information */
-typdef struct CHBIND_REQ {
+typedef struct CHBIND_REQ {
uint8_t *username; /* the username */
size_t username_len; /* length of the username */
- uint8_t *chbind_req; /* channel binding request buffer */
+ uint8_t *chbind_req_pkt; /* channel binding request buffer */
size_t chbind_req_len; /* length of the request buffer */
uint8_t *chbind_resp; /* channel binding response buffer */
size_t chbind_resp_len; /* length of the response buffer */
-};
+} CHBIND_REQ;
/* Structure to represent eap channel binding packet format */
typedef struct chbind_packet_t {
uint8_t code;
uint8_t data[1];
-} eap_chbind_packet_t;
+} CHBIND_PACKET_T;
/* Protocol constants */
#define CHBIND_NSID_RADIUS 1
#define CHBIND_CODE_FAILURE 3
/* Channel binding function prototypes */
-CHBIND_REQ *chbind_allocate();
-void *chbind_free(CHBIND_REQ *chbind);
+CHBIND_REQ *chbind_allocate(void);
+void chbind_free(CHBIND_REQ *chbind);
int chbind_process(REQUEST *req, CHBIND_REQ *chbind_req);
-size_t chbind_get_data(chbind_packet_t *chbind_packet, size_t chbind_packet_len, int desired_nsid, uint8_t **radbuf_data);
-uint8_t *chbind_build_response(REQUEST *req, int *resp_len);
+size_t chbind_get_data(CHBIND_PACKET_T *chbind_packet, size_t chbind_packet_len, int desired_nsid, uint8_t **radbuf_data);
+uint8_t *chbind_build_response(REQUEST *req, size_t *resp_len);
+#endif /*_EAP_CHBIND_H*/