From: Amos Jeffries Date: Mon, 26 Nov 2012 08:34:05 +0000 (-0700) Subject: basic_radius_auth: Fix several issues X-Git-Tag: SQUID_3_2_4~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=70a9b8e514a02f95352de288368790b58a77ea7a;p=thirdparty%2Fsquid.git 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, 743276 --- diff --git a/helpers/basic_auth/RADIUS/basic_radius_auth.cc b/helpers/basic_auth/RADIUS/basic_radius_auth.cc index 7045d4444d..d88b960b39 100644 --- a/helpers/basic_auth/RADIUS/basic_radius_auth.cc +++ b/helpers/basic_auth/RADIUS/basic_radius_auth.cc @@ -322,7 +322,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; @@ -425,7 +425,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; @@ -489,16 +495,20 @@ main(int argc, char **argv) cfname = optarg; break; case 'h': - strcpy(server, optarg); + strncpy(server, optarg, sizeof(server)-1); + server[sizeof(server)-1] = '\0'; break; case 'p': - strcpy(svc_name, optarg); + strncpy(svc_name, optarg, sizeof(svc_name)-1); + svc_name[sizeof(svc_name)-1] = '\0'; break; case 'w': - strcpy(secretkey, optarg); + strncpy(secretkey, optarg, sizeof(secretkey)-1); + secretkey[sizeof(secretkey)-1] = '\0'; break; case 'i': - strcpy(identifier, optarg); + strncpy(identifier, optarg, sizeof(identifier)-1); + identifier[sizeof(identifier)-1] = '\0'; break; case 't': retries = atoi(optarg); @@ -566,7 +576,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) {