Apply by doing: cd /usr/src patch -p0 < 020_radius.patch Then rebuild and install login_radius: cd libexec/login_radius make clean make make install Index: libexec/login_radius/raddauth.c =================================================================== RCS file: /cvs/src/libexec/login_radius/raddauth.c,v retrieving revision 1.16 retrieving revision 1.16.2.1 diff -u -p -r1.16 -r1.16.2.1 --- libexec/login_radius/raddauth.c 10 Mar 2004 21:30:27 -0000 1.16 +++ libexec/login_radius/raddauth.c 11 Sep 2004 21:06:56 -0000 1.16.2.1 @@ -131,7 +131,7 @@ typedef struct { void servtimeout(int); in_addr_t get_ipaddr(char *); in_addr_t gethost(void); -int rad_recv(char *, char *); +int rad_recv(char *, char *, u_char *); void parse_challenge(auth_hdr_t *, char *, char *); void rad_request(pid_t, char *, char *, int, char *, char *); void getsecret(void); @@ -278,7 +278,7 @@ retry: rad_request(req_id, userstyle, passwd, auth_port, vector, pwstate); - switch (i = rad_recv(_pwstate, challenge)) { + switch (i = rad_recv(_pwstate, challenge, vector)) { case PW_AUTHENTICATION_ACK: /* * Make sure we don't think a challenge was issued. @@ -437,11 +437,13 @@ rad_request(pid_t id, char *name, char * * Receive UDP responses from the radius server */ int -rad_recv(char *state, char *challenge) +rad_recv(char *state, char *challenge, u_char *req_vector) { auth_hdr_t auth; socklen_t salen; struct sockaddr_in sin; + u_char recv_vector[AUTH_VECTOR_LEN], test_vector[AUTH_VECTOR_LEN]; + MD5_CTX context; salen = sizeof(sin); @@ -456,6 +458,16 @@ rad_recv(char *state, char *challenge) if (sin.sin_addr.s_addr != auth_server) errx(1, "bogus authentication server"); + + /* verify server's shared secret */ + memcpy(recv_vector, auth.vector, AUTH_VECTOR_LEN); + memcpy(auth.vector, req_vector, AUTH_VECTOR_LEN); + MD5Init(&context); + MD5Update(&context, (u_char *)&auth, ntohs(auth.length)); + MD5Update(&context, auth_secret, strlen(auth_secret)); + MD5Final(test_vector, &context); + if (memcmp(recv_vector, test_vector, AUTH_VECTOR_LEN) != 0) + errx(1, "shared secret incorrect"); if (auth.code == PW_ACCESS_CHALLENGE) parse_challenge(&auth, state, challenge);