]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
basic_radius_auth: Fix several issues
authorAmos Jeffries <squid3@treenet.co.nz>
Mon, 26 Nov 2012 08:34:05 +0000 (01:34 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Mon, 26 Nov 2012 08:34:05 +0000 (01:34 -0700)
* 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

helpers/basic_auth/RADIUS/basic_radius_auth.cc

index 7045d4444d79fc9c3262583c39076d0dca172289..d88b960b39c7741103d227b5c0d2789b50e3a00a 100644 (file)
@@ -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) {