Added 'original' packet to rad_send(), so that it can calculate
authoraland <aland>
Wed, 29 Aug 2001 15:00:05 +0000 (15:00 +0000)
committeraland <aland>
Wed, 29 Aug 2001 15:00:05 +0000 (15:00 +0000)
the Message-Authenticator properly for Access-Accept packets,
which depend on the Access-Request authentication vector.

Updated the rest of the code to call rad_send() with the original
packet, where possible.

src/include/libradius.h
src/lib/radius.c
src/main/proxy.c
src/main/radclient.c
src/main/radiusd.c
src/main/radzap.c

index e0d5513..d25aeb3 100644 (file)
@@ -178,7 +178,7 @@ void lrad_hmac_md5(const unsigned char *text, int text_len,
                   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);
index 916ebfd..8734f14 100644 (file)
@@ -79,7 +79,7 @@ static void make_secret(unsigned char *digest, uint8_t *vector,
  *     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;
@@ -354,10 +354,24 @@ int rad_send(RADIUS_PACKET *packet, const char *secret)
                  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);
                  }
 
 
@@ -714,6 +728,17 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, const char *secre
                        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,
index 40e87ae..42acb87 100644 (file)
@@ -301,7 +301,7 @@ int proxy_send(REQUEST *request)
        /*
         *      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;
index 2dbc2f5..1b35f91 100644 (file)
@@ -143,7 +143,7 @@ static int send_packet(RADIUS_PACKET *req, RADIUS_PACKET **rep)
        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);
@@ -382,24 +382,15 @@ int main(int argc, char **argv)
        
 
                /*
-                *      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';
                }
@@ -418,28 +409,28 @@ int main(int argc, char **argv)
                        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);
                }
index 4ae3b30..2073fb8 100644 (file)
@@ -1243,7 +1243,7 @@ static void rad_reject(REQUEST *request)
         *  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);
 }
 
 /*
@@ -1254,22 +1254,33 @@ static void rfc_clean(RADIUS_PACKET *packet)
        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.
+        */
 }
 
 /* 
@@ -1484,7 +1495,7 @@ int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
                if (vp != NULL) 
                        pairadd(&(request->reply->vps), vp);
 
-               rad_send(request->reply, request->secret);
+               rad_send(request->reply, request->packet, request->secret);
        }
 
        /*
@@ -1775,7 +1786,7 @@ static REQUEST *rad_check_list(REQUEST *request)
                                                " 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
@@ -1791,7 +1802,7 @@ static REQUEST *rad_check_list(REQUEST *request)
                                                       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.",
@@ -2362,7 +2373,7 @@ static int refresh_request(REQUEST *request, void *data)
        /*
         *  Send the proxy packet.
         */
-       rad_send(request->proxy, request->proxysecret);
+       rad_send(request->proxy, NULL, request->proxysecret);
 
 setup_timeout:
        /*
index 0ede6f6..e0a806c 100644 (file)
@@ -323,7 +323,7 @@ static int do_packet(int allports, uint32_t nasaddr, const struct radutmp *u)
        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);