/*
- * $Id: sendserver.c,v 1.2 2002/03/04 14:59:52 dfs Exp $
+ * $Id: sendserver.c,v 1.4 2002/04/02 14:09:35 dfs Exp $
*
* Copyright (C) 1995,1996,1997 Lars Fenneberg
*
#include <pathnames.h>
static void rc_random_vector (unsigned char *);
-static int rc_check_reply (AUTH_HDR *, char *, unsigned char *, unsigned char);
+static int rc_check_reply (AUTH_HDR *, int, char *, unsigned char *, unsigned char);
/*
* Function: rc_pack_list
*
*/
-int rc_send_server (SEND_DATA *data, char *msg)
+int rc_send_server (SEND_DATA *data, char *msg, REQUEST_INFO *info)
{
int sockfd;
struct sockaddr salocal;
else
{
rc_random_vector (vector);
- memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
+ memcpy (auth->vector, vector, AUTH_VECTOR_LEN);
total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;
recv_auth = (AUTH_HDR *)recv_buffer;
- result = rc_check_reply (recv_auth, secret, vector, data->seq_nbr);
+ result = rc_check_reply (recv_auth, BUFFER_LEN, secret, vector, data->seq_nbr);
data->receive_pairs = rc_avpair_gen(recv_auth);
close (sockfd);
+ if (info)
+ {
+ memcpy(info->secret, secret, sizeof(info->secret));
+ memcpy(info->request_vector, vector,
+ sizeof(info->request_vector));
+ }
memset (secret, '\0', sizeof (secret));
if (result != OK_RC) return (result);
*
*/
-static int rc_check_reply (AUTH_HDR *auth, char *secret, unsigned char *vector,\
- unsigned char seq_nbr)
+static int rc_check_reply (AUTH_HDR *auth, int bufferlen, char *secret,
+ unsigned char *vector, unsigned char seq_nbr)
{
int secretlen;
int totallen;
totallen = ntohs (auth->length);
+ secretlen = strlen (secret);
+
+ /* Do sanity checks on packet length */
+ if ((totallen < 20) || (totallen > 4096))
+ {
+ rc_log(LOG_ERR, "rc_check_reply: received RADIUS server response with invalid length");
+ return (BADRESP_RC);
+ }
+
+ /* Verify buffer space, should never trigger with current buffer size and check above */
+ if ((totallen + secretlen) > bufferlen)
+ {
+ rc_log(LOG_ERR, "rc_check_reply: not enough buffer space to verify RADIUS server response");
+ return (BADRESP_RC);
+ }
/* Verify that id (seq. number) matches what we sent */
if (auth->id != seq_nbr)
{
- rc_log(LOG_ERR, "check_radius_reply: received non-matching id in RADIUS server response");
+ rc_log(LOG_ERR, "rc_check_reply: received non-matching id in RADIUS server response");
return (BADRESP_RC);
}
/* Verify the reply digest */
memcpy ((char *) reply_digest, (char *) auth->vector, AUTH_VECTOR_LEN);
memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
- secretlen = strlen (secret);
memcpy ((char *) auth + totallen, secret, secretlen);
rc_md5_calc (calc_digest, (char *) auth, totallen + secretlen);
if (auth->code == PW_ACCOUNTING_RESPONSE)
return (OK_RC);
#endif
- rc_log(LOG_ERR, "check_radius_reply: received invalid reply digest from RADIUS server");
+ rc_log(LOG_ERR, "rc_check_reply: received invalid reply digest from RADIUS server");
return (BADRESP_RC);
}