]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
basic_radius_auth: Fix several issues
authorAmos Jeffries <squid3@treenet.co.nz>
Wed, 14 Nov 2012 00:51:40 +0000 (17:51 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Wed, 14 Nov 2012 00:51:40 +0000 (17:51 -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

helpers/basic_auth/RADIUS/basic_radius_auth.cc

index 73e2304f710af710728b101ff7178d32593d534a..d9a4f3520cc6195b7abf5b45abd7159a81834661 100644 (file)
@@ -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) {