From 69c954eb754f8a939e82948ce67916ff0dc850f3 Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Tue, 13 Nov 2012 17:51:40 -0700 Subject: [PATCH] basic_radius_auth: Fix several issues * abort on failed fcntl() non-blocking socket setup * retry send() on failure. Up to retry attempt count. Display send() errors to cache.log. * prevent buffer overflow on long command line arguments. * make compiler buffer overflow checks happier with RADIUS packet creation code. Detected by Coverity Scan. Issues 740314, 740315, 740410, 740474 --- .../basic_auth/RADIUS/basic_radius_auth.cc | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/helpers/basic_auth/RADIUS/basic_radius_auth.cc b/helpers/basic_auth/RADIUS/basic_radius_auth.cc index 73e2304f71..d9a4f3520c 100644 --- a/helpers/basic_auth/RADIUS/basic_radius_auth.cc +++ b/helpers/basic_auth/RADIUS/basic_radius_auth.cc @@ -321,7 +321,7 @@ authenticate(int socket_fd, const char *username, const char *passwd) length = MAXPWNAM; } *ptr = length + 2; - ++ptr; + ptr = (unsigned char*)send_buffer + sizeof(AUTH_HDR); memcpy(ptr, username, length); ptr += length; total_length += length + 2; @@ -424,7 +424,13 @@ authenticate(int socket_fd, const char *username, const char *passwd) * Send the request we've built. */ gettimeofday(&sent, NULL); - send(socket_fd, (char *) auth, total_length, 0); + if (send(socket_fd, (char *) auth, total_length, 0) < 0) { + // EAGAIN is expected at high traffic, just retry + // TODO: block/sleep a few ms to let the apparently full buffer drain ? + if (errno != EAGAIN && errno != EWOULDBLOCK) + fprintf(stderr,"ERROR: RADIUS send() failure: %s\n", xstrerror()); + continue; + } while ((time_spent = time_since(&sent)) < 1000000) { struct timeval tv; int rc, len; @@ -488,16 +494,16 @@ main(int argc, char **argv) cfname = optarg; break; case 'h': - strcpy(server, optarg); + strncpy(server, optarg, sizeof(server)); break; case 'p': - strcpy(svc_name, optarg); + strncpy(svc_name, optarg, sizeof(svc_name)); break; case 'w': - strcpy(secretkey, optarg); + strncpy(secretkey, optarg, sizeof(secretkey)); break; case 'i': - strcpy(identifier, optarg); + strncpy(identifier, optarg, sizeof(identifier)); break; case 't': retries = atoi(optarg); @@ -565,7 +571,10 @@ main(int argc, char **argv) exit(1); } #ifdef O_NONBLOCK - fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK); + if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK) < 0) { + fprintf(stderr,"%s| ERROR: fcntl() failure: %s\n", argv[0], xstrerror()); + exit(1); + } #endif nas_ipaddr = ntohl(salocal.sin_addr.s_addr); while (fgets(buf, HELPER_INPUT_BUFFER, stdin) != NULL) { -- 2.47.2