]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/plugins/radius/radiusclient/lib/sendserver.c
Add support for radius Class attribute. Possibly broken if chap is set to
[ppp.git] / pppd / plugins / radius / radiusclient / lib / sendserver.c
index 23a056695e59ee01f1031e8d6c34c2f5b7d70da0..7166ed0ce9ba788c20b0f74c1babf949ede9fe7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $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
  *
@@ -20,7 +20,7 @@
 #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
@@ -190,7 +190,7 @@ static int rc_pack_list (VALUE_PAIR *vp, char *secret, AUTH_HDR *auth)
  *
  */
 
-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;
@@ -279,7 +279,7 @@ int rc_send_server (SEND_DATA *data, char *msg)
        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;
 
@@ -343,11 +343,17 @@ int rc_send_server (SEND_DATA *data, char *msg)
 
        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);
@@ -388,8 +394,8 @@ int rc_send_server (SEND_DATA *data, char *msg)
  *
  */
 
-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;
@@ -398,17 +404,31 @@ static int rc_check_reply (AUTH_HDR *auth, char *secret, unsigned char *vector,\
 
        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);
 
@@ -445,7 +465,7 @@ static int rc_check_reply (AUTH_HDR *auth, char *secret, unsigned char *vector,\
                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);
        }