Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Mar 2003 17:59:13 +0800
From:      Gea-Suan Lin <gslin@ccreader.nctu.edu.tw>
To:        net@FreeBSD.ORG
Subject:   Re: [mpd] radius and dynamic bundles
Message-ID:  <20030303095913.GA52116@ccreader.nctu.edu.tw>
In-Reply-To: <3E63245D.6040800@jawa.at>
References:  <200303022347.10283.vjardin@wanadoo.fr> <3E63245D.6040800@jawa.at>

next in thread | previous in thread | raw e-mail | index | archive | help

--SUOF0GtieIMvvwua
Content-Type: text/plain; charset=big5
Content-Disposition: inline

I find the function rad_send_request() in /usr/src/lib/libradius/libradius.c
will break the stack so that mpd gets segfault in FreeBSD 4.7-RELEASE-p3,
but I can't figure out where it does.

If somebody want the core file, I can mail him.

I copied rad_send_request() into mpd's radius.c last week, and it worked
fine.  I attach my patch file in this mail.

On Mon, Mar 03, 2003 at 10:46:05AM +0100, Michael Bretterklieber wrote:
> Hi,
> 
> Vincent Jardin schrieb:
> >1/ When Radius is used with mpd and the answer delay of the Radius server 
> >is high, how can some PAP or CHAP timeout be avoided ?
> >
> you mean, that the client times out during authentication saying that 
> the server didn't responded?
> 
> A known issue is that mpd is blocked during RADIUS requests, the 
> solution will be to change from rad_send_request(); to 
> rad_init_send_request() and rad_continue_send_request(); to avoid 
> blocking of mpd.
> 
> I have this on my todo-list, but atm it has low prio.
> 
> bye,

-- 
* Gea-Suan Lin  (public key: http://ccreader.nctu.edu.tw/~gslin/key.txt)
* If you cannot convince them, confuse them.           -- Harry S Truman

--SUOF0GtieIMvvwua
Content-Type: text/plain; charset=big5
Content-Disposition: attachment; filename="radius.c.diff"

--- /usr/ports/net/mpd/work/mpd-3.12/src/radius.c	Tue Feb 11 06:21:15 2003
+++ radius.c	Mon Mar  3 17:48:47 2003
@@ -152,10 +152,10 @@
     return 0;
 }
 
-void RadiusInit(void) {
+static void
+RadiusInit(void) {
   struct radius *rad = &bund->radius;
 
-  if (rad->radh != NULL) rad_close(rad->radh);
   memset(rad, 0, sizeof(struct radius) - sizeof(struct radiusconf));
 }
 
@@ -209,6 +209,7 @@
 
   if (rad_create_request(rad->radh, RAD_ACCESS_REQUEST) == -1) {
     Log(LG_RADIUS, ("[%s] RADIUS: rad_create_request: %s", lnk->name, rad_strerror(rad->radh)));
+    rad_close(rad->radh);
     return (RAD_NACK);
   }
 
@@ -343,37 +344,86 @@
     }
   }
 
-  switch (rad_send_request(rad->radh)) {
+  Log(LG_RADIUS, ("[%s] RADIUS: %s: XXX 1 name=%s passlen=%d challenge_size=%d chapid=%d auth_type=%d", lnk->name, function, name, passlen, challenge_size, chapid, auth_type));
 
-    case RAD_ACCESS_ACCEPT:
-      rad->valid = 1;
-      Log(LG_RADIUS, ("[%s] RADIUS: %s: RAD_ACCESS_ACCEPT for user %s", lnk->name, function, name));
-      break;
+  {
+    struct timeval timelimit;
+    struct timeval tv;
+    int fd;
+    int n;
 
-    case RAD_ACCESS_REJECT:
-      Log(LG_RADIUS, ("[%s] RADIUS: %s: RAD_ACCESS_REJECT for user %s", lnk->name, function, name));
-      rad_close(rad->radh);
-      return(RAD_NACK);
-      break;
+    n = rad_init_send_request(rad->radh, &fd, &tv);
 
-    case -1:
-      Log(LG_RADIUS, ("[%s] RADIUS: %s: rad_send_request failed %s", lnk->name,
-      function, rad_strerror(rad->radh)));
-      return(RAD_NACK);
-      break;
-    default:
-      Log(LG_RADIUS, ("[%s] RADIUS: %s: rad_send_request: unexpected "
-      "return value %s", lnk->name, function, rad_strerror(rad->radh)));
-      rad_close(rad->radh);
-      return(RAD_NACK);
+    if (n != 0)
+      return n;
+
+    gettimeofday(&timelimit, NULL);
+    timeradd(&tv, &timelimit, &timelimit);
+
+    for ( ; ; ) {
+      fd_set readfds;
+
+      FD_ZERO(&readfds);
+      FD_SET(fd, &readfds);
+
+      n = select(fd + 1, &readfds, NULL, NULL, &tv);
+
+      if (n == -1)
+	break;
+
+      if (!FD_ISSET(fd, &readfds)) {
+	/* Compute a new timeout */
+	gettimeofday(&tv, NULL);
+	timersub(&timelimit, &tv, &tv);
+	if (tv.tv_sec > 0 || (tv.tv_sec == 0 && tv.tv_usec > 0))
+	  /* Continue the select */
+	  continue;
+      }
+
+      Log(LG_RADIUS, ("[%s] RADIUS: %s: XXX 1 %s Host:%s PeerIp: %s", lnk->name, function, name, host, peeripname));
+      n = rad_continue_send_request(rad->radh, n, &fd, &tv);
+      Log(LG_RADIUS, ("[%s] RADIUS: %s: XXX 2 %s Host:%s PeerIp: %s", lnk->name, function, name, host, peeripname));
+
+      if (n != 0)
+	break;
+
+      gettimeofday(&timelimit, NULL);
+      timeradd(&tv, &timelimit, &timelimit);
     }
 
-    // Remember authname
-    strncpy(rad->authname, name, AUTH_MAX_AUTHNAME);
-    res = RadiusGetParams();
-    if (res == RAD_NACK) rad->valid = 0;
-    rad_close(rad->radh);
-    return(res);
+    switch (n) {
+
+      case RAD_ACCESS_ACCEPT:
+	rad->valid = 1;
+	Log(LG_RADIUS, ("[%s] RADIUS: %s: RAD_ACCESS_ACCEPT for user %s", lnk->name, function, name));
+	break;
+
+      case RAD_ACCESS_REJECT:
+	Log(LG_RADIUS, ("[%s] RADIUS: %s: RAD_ACCESS_REJECT for user %s", lnk->name, function, name));
+	rad_close(rad->radh);
+	return(RAD_NACK);
+	break;
+
+      case -1:
+	Log(LG_RADIUS, ("[%s] RADIUS: %s: rad_send_request failed %s", lnk->name,
+	function, rad_strerror(rad->radh)));
+	return(RAD_NACK);
+	break;
+
+      default:
+	Log(LG_RADIUS, ("[%s] RADIUS: %s: rad_send_request: unexpected "
+	"return value %s", lnk->name, function, rad_strerror(rad->radh)));
+	rad_close(rad->radh);
+	return(RAD_NACK);
+    }
+  }
+
+  // Remember authname
+  strncpy(rad->authname, name, AUTH_MAX_AUTHNAME);
+  res = RadiusGetParams();
+  if (res == RAD_NACK) rad->valid = 0;
+  rad_close(rad->radh);
+  return(res);
 }
 
 int

--SUOF0GtieIMvvwua--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030303095913.GA52116>