On Thu, Mar 02, 2023 at 09:31:57AM -0700, Theo de Raadt wrote:
> Using a global variable like that is poor style.

OK, I'm gonna give it one more attempt:

In RFC 2865 there is no auth code for discarding a message but there is a
255 reserved value which we may be able to use as a hack.  Refer to page
14 of RFC 2865.

The updated patch then returns from rad_recv() with that 255 and is caught
in the switch/case, and executes with a following goto retry.

Again I don't have a test network for this.

Best Regards,
-peter


Index: raddauth.c
===================================================================
RCS file: /cvs/src/libexec/login_radius/raddauth.c,v
retrieving revision 1.30
diff -u -p -u -r1.30 raddauth.c
--- raddauth.c  28 Jun 2019 13:32:53 -0000      1.30
+++ raddauth.c  2 Mar 2023 16:46:37 -0000
@@ -105,6 +105,7 @@
 #define        PW_CLIENT_PORT_ID               5
 #define PW_PORT_MESSAGE                        18
 #define PW_STATE                       24
+#define PW_SILENT_DISCARD              255     /* Reserved in RFC 2865 */
 
 #ifndef        RADIUS_DIR
 #define RADIUS_DIR             "/etc/raddb"
@@ -324,6 +325,10 @@ retry:
                                passwd = "";
                        break;
 
+               case PW_SILENT_DISCARD:
+                       goto retry;
+                       break;
+
                default:
                        if (timedout)
                                goto retry;
@@ -451,17 +456,22 @@ rad_recv(char *state, char *challenge, u
        struct sockaddr_in sin;
        u_char recv_vector[AUTH_VECTOR_LEN], test_vector[AUTH_VECTOR_LEN];
        MD5_CTX context;
+       ssize_t total_length;
 
        salen = sizeof(sin);
 
        alarm(timeout);
-       if ((recvfrom(sockfd, &auth, sizeof(auth), 0,
-           (struct sockaddr *)&sin, &salen)) < AUTH_HDR_LEN) {
+       total_length = recvfrom(sockfd, &auth, sizeof(auth), 0,
+           (struct sockaddr *)&sin, &salen);
+       alarm(0);
+       if (total_length < AUTH_HDR_LEN) {
                if (timedout)
                        return(-1);
                errx(1, "bogus auth packet from server");
        }
-       alarm(0);
+       if (ntohs(auth.length) > total_length) {
+               return (PW_SILENT_DISCARD);
+       }
 
        if (sin.sin_addr.s_addr != auth_server)
                errx(1, "bogus authentication server");

Reply via email to