We want to implement one-time password based web-server authentication against our Radius server. Mod_auth_radius seems to be quite nice apache(2) module for this purpose.

Unfortunately there was some weaknesses:
1) one-time password authentication and initial directory access (problem described in README "Some warnings"). Annoying!
2) manual logout - at first I didn't see any good solution to give user an ability to logout and relogin (if she/he want to) without restarting the browser.
3) absolute time for ticket (cookie) timeout - parameter AddRadiusCookieValid allows only n minute access to web-browser after login, no matter how often you access the web-server. I would prefer an "idle timeout" - when web-server haven't accessed n minute, then ticket would timeouts



I think that I have found solutions to all these problems. What does think the freeradius community about these ones?


1) Initially accessing the directory (e.g. https://server.com/) is possible by using apache rewrite module:

RewriteRule ^/$ /index.php

Of cource this rule match only for root-directory, but it's better than nothing (users insert to the browser's url-bar only hostname, generally)

2) manual logout methot is following:
- quering url https://server.com/logout.php, the cookie in browser would deleted.
<?php
# /logout.php
setcookie("RADIUS","",0,"/");
echo("Logged out");
?>
- in apache conf set a line:
ErrorDocument 401 /error/HTTP_UNAUTHORIZED.php
(of cource /error/* is not in restricted area)
<?php
# /error/HTTP_UNAUTHORIZED.php
Header("WWW-Authenticate: Basic realm=\"Radius\"");
header('HTTP/1.0 401 Unauthorized');
echo("Authorization required!");
exit;
?>


This methot doesn't require browser restart. Trying to access restricted area, browser will ask username and password again.

3) Now the most complicated problem: how to implement "idle timeout"
I dared to change the module code in a way, that parameter AddRadiusCookieValid means a "idle timeout" (in minute). Algoritm for timeout check is:


if ( last_access_time + idle_timeout < current_access_time ) {
        return EXPIRED;
} else {
        update_cookie("Radius",current_access_time)
        return OK;
}

there are my patch for this:

--- mod_auth_radius-2.0.c.orig  2004-01-27 20:06:25.000000000 +0200
+++ mod_auth_radius-2.0.c       2004-01-28 09:25:05.000000000 +0200
@@ -705,6 +705,9 @@
 valid_cookie(request_rec *r, const char *cookie, const char *passwd)
 {
   time_t expires, now;
+  server_rec *s = r->server;
+  radius_server_config_rec *scr = (radius_server_config_rec *)
+    ap_get_module_config (s->module_config, &radius_auth_module);

if (strlen(cookie) < (16 + 4)*2) { /* MD5 is 16 bytes, and expiry date is 4*/
return FALSE; /* invalid */
@@ -713,14 +716,16 @@
sscanf(&cookie[32], "%8lx", &expires);


now = time(NULL);
- if (expires < now) { /* valid only for a short window of time */
+ if ( ( expires + ( scr->timeout * 60 ) ) < now) { /* valid only for a short window of time */
return FALSE; /* invalid: expired */
}


/* Is the returned cookie identical to one made from our secret? */
- if (strcmp(cookie, make_cookie(r, expires, passwd, NULL)) == 0)
+ if (strcmp(cookie, make_cookie(r, expires, passwd, NULL)) == 0) {
+ add_cookie(r, r->headers_out, make_cookie(r, now, passwd, NULL), now);
return TRUE;
-
+ }
+
return FALSE; /* cookie doesn't match: re-validate */
}
/* Add a cookie to an outgoing request */
/* ----- End of patch -------------------------- */




Any comments are very welcome.

Tanel


- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html

Reply via email to