unsigned char *digest);
/* radius.c */
-int rad_send(RADIUS_PACKET *, const char *secret);
+int rad_send(RADIUS_PACKET *, const RADIUS_PACKET *, const char *secret);
RADIUS_PACKET *rad_recv(int fd);
int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, const char *secret);
RADIUS_PACKET *rad_alloc(int newvector);
* Reply to the request. Also attach
* reply attribute value pairs and any user message provided.
*/
-int rad_send(RADIUS_PACKET *packet, const char *secret)
+int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original, const char *secret)
{
VALUE_PAIR *reply;
struct sockaddr_in saremote;
if (msg_auth_ptr) {
uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
+ switch (packet->code) {
+ default:
+ break;
+
+ case PW_AUTHENTICATION_ACK:
+ case PW_AUTHENTICATION_REJECT:
+ case PW_ACCESS_CHALLENGE:
+ if (original) {
+ memcpy(hdr->vector, original->vector, AUTH_VECTOR_LEN);
+ }
+ break;
+ }
+
memset(msg_auth_ptr + 2, 0, AUTH_VECTOR_LEN);
lrad_hmac_md5(packet->data, packet->data_len,
secret, secretlen, calc_auth_vector);
memcpy(msg_auth_ptr + 2, calc_auth_vector, AUTH_VECTOR_LEN);
+ memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
}
memcpy(msg_auth_vector, &ptr[2], sizeof(msg_auth_vector));
memset(&ptr[2], 0, AUTH_VECTOR_LEN);
+ switch (packet->code) {
+ default:
+ break;
+
+ case PW_AUTHENTICATION_ACK:
+ case PW_AUTHENTICATION_REJECT:
+ case PW_ACCESS_CHALLENGE:
+ memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
+ break;
+ }
+
lrad_hmac_md5(packet->data, packet->data_len,
secret, strlen(secret), calc_auth_vector);
if (memcmp(calc_auth_vector, msg_auth_vector,
/*
* Send the request.
*/
- rad_send(request->proxy, (char *)realm->secret);
+ rad_send(request->proxy, NULL, (char *)realm->secret);
memcpy(request->proxysecret, realm->secret, sizeof(request->proxysecret));
request->proxy_is_replicate = replicating;
request->proxy_try_count = proxy_retry_count - 1;
for (i = 0; i < retries; i++) {
fd_set rdfdesc;
- rad_send(req, secret);
+ rad_send(req, NULL, secret);
/* And wait for reply, timing out as necessary */
FD_ZERO(&rdfdesc);
/*
- * Encrypt the Password attribute.
+ * Keep a copy of the the Password attribute.
*/
if ((vp = pairfind(req->vps, PW_PASSWORD)) != NULL) {
strNcpy(password, (char *)vp->strvalue, sizeof(vp->strvalue));
- vp->length = strlen(password);
- rad_pwencode((char *)vp->strvalue,
- &(vp->length),
- secret, (char *)req->vector);
-
/*
- * Not there, encrypt the CHAP-Password attribute.
+ * Otherwise keep a copy of the CHAP-Password attribute.
*/
} else if ((vp = pairfind(req->vps, PW_CHAP_PASSWORD)) != NULL) {
strNcpy(password, (char *)vp->strvalue, sizeof(vp->strvalue));
- rad_chap_encode(req, (char *) vp->strvalue, req->id, vp);
- vp->length = 17;
-
-
} else {
*password = '\0';
}
if (req->data) {
free(req->data);
req->data = NULL;
+ }
- librad_md5_calc(req->vector, req->vector,
- sizeof(req->vector));
+ librad_md5_calc(req->vector, req->vector,
+ sizeof(req->vector));
- if (*password != '\0') {
- vp = pairfind(req->vps, PW_PASSWORD);
- if (vp) {
- strNcpy((char *)vp->strvalue, password, vp->length + 1);
- vp->length = strlen(password);
-
- rad_pwencode((char *)vp->strvalue,
- &(vp->length),
- secret, (char *)req->vector);
- } else if ((vp = pairfind(req->vps, PW_CHAP_PASSWORD)) != NULL) {
- strNcpy((char *)vp->strvalue, password, vp->length + 1);
- vp->length = strlen(password);
-
- rad_chap_encode(req, (char *) vp->strvalue, req->id, vp);
- vp->length = 17;
- }
- } /* there WAS a password */
- } /* there WAS a packet sent. */
+ if (*password != '\0') {
+ vp = pairfind(req->vps, PW_PASSWORD);
+ if (vp) {
+ strNcpy((char *)vp->strvalue, password, vp->length + 1);
+ vp->length = strlen(password);
+
+ rad_pwencode((char *)vp->strvalue,
+ &(vp->length),
+ secret, (char *)req->vector);
+ } else if ((vp = pairfind(req->vps, PW_CHAP_PASSWORD)) != NULL) {
+ strNcpy((char *)vp->strvalue, password, vp->length + 1);
+ vp->length = strlen(password);
+
+ rad_chap_encode(req, (char *) vp->strvalue, req->id, vp);
+ vp->length = 17;
+ }
+ } /* there WAS a password */
send_packet(req, &rep);
rad_free(&rep);
}
* If a reply exists, send it.
*/
if (request->reply->code != 0)
- rad_send(request->reply, request->secret);
+ rad_send(request->reply, request->packet, request->secret);
}
/*
VALUE_PAIR *vps = NULL;
switch (packet->code) {
- default:
- break;
-
- /*
- * Authentication REJECT's can have only
- * Reply-Mesaage and Proxy-State. We delete
- * everything other than Reply-Message, and
- * Proxy-State is added below, just before
- * the reply is sent.
- */
- case PW_AUTHENTICATION_REJECT:
- pairmove2(&vps, &(packet->vps), PW_REPLY_MESSAGE);
- pairfree(&packet->vps);
- packet->vps = vps;
- break;
+ default:
+ break;
+
+ /*
+ * FIXME: Accounting responses can only contain
+ * Proxy-State and VSA's.
+ */
+ case PW_ACCOUNTING_RESPONSE:
+ break;
+
+ /*
+ * Authentication REJECT's can have only
+ * Reply-Message and Proxy-State. We delete
+ * everything other than Reply-Message, and
+ * Proxy-State is added below, just before
+ * the reply is sent.
+ */
+ case PW_AUTHENTICATION_REJECT:
+ pairmove2(&vps, &(packet->vps), PW_REPLY_MESSAGE);
+ pairfree(&packet->vps);
+ packet->vps = vps;
+ break;
}
+
+ /*
+ * FIXME: Perform other, more generic sanity checks.
+ */
}
/*
if (vp != NULL)
pairadd(&(request->reply->vps), vp);
- rad_send(request->reply, request->secret);
+ rad_send(request->reply, request->packet, request->secret);
}
/*
" to client %s:%d - ID: %d", client_name(curreq->packet->src_ipaddr),
curreq->packet->src_port, curreq->packet->id);
- rad_send(curreq->reply, curreq->secret);
+ rad_send(curreq->reply, curreq->packet, curreq->secret);
/*
* There's no reply, but maybe there's
curreq->proxy->id);
curreq->proxy_next_try = request->timestamp + proxy_retry_delay;
- rad_send(curreq->proxy, curreq->proxysecret);
+ rad_send(curreq->proxy, curreq->packet, curreq->proxysecret);
} else {
DEBUG2("Ignoring duplicate authentication packet"
" from client %s:%d - ID: %d, as the proxy reply is currently being processed.",
/*
* Send the proxy packet.
*/
- rad_send(request->proxy, request->proxysecret);
+ rad_send(request->proxy, NULL, request->proxysecret);
setup_timeout:
/*
for (i = 0; i < retries; i++) {
fd_set rdfdesc;
- rad_send(req, secret);
+ rad_send(req, NULL, secret);
/* And wait for reply, timing out as necessary */
FD_ZERO(&rdfdesc);