Forum OpenACS Q&A: New mini-package: auth-hash

Collapse
Posted by Cathy Sarisky on
Strictly in the department of writing code to scratch an itch...
I've written a small package called auth-hash.

Scenario:

  • You run an OpenACS server. All your users already have logins on a campus wide web-portal.
  • For whatever reason (OpenACS server off-campus, IT doesn't trust you, firewall, etc), you can't authenticate your users on the campus LDAP server.
  • Campus IT is at least a little bit willing to work with you, as long as you don't get access to anything sensitive.

Solution

  • The campus admin generates a page on the campus network. That page redirects the student to the OpenACS server. The student's GET request includes an MD5 hash, the student's email address, and the student's first_names and last_name. The MD5 hash has a mutually agreed upon SecretString, the student's email address, and the time & date.
  • auth-hash checks the time in the GET request to see that it is within so many minutes of the current server time. If it is, auth-hash generates an MD5 hash using the same SecretString, and the email address, date and time from the GET request. (If it isn't, we tell them to go back to the portal and follow the link again.)
  • If the MD5 hashes match, auth-hash checks to see if the user is already in cc_users. If the user is in cc_users, we log them in. If the user isn't in cc_users, we create the user (using first_names and last_name) and log them in.

Comments welcome. If anyone would like to test, I'll make the package available after I clean it up a bit.

Collapse
Posted by Nima Mazloumi on
I would love to take a look. Will you commit it to CVS?
Best regards,
Nima
Collapse
Posted by Malte Sussdorff on
Sounds very familiar. It is the same technique we used some time back with AIESEC when we had to intergrate various systems, so it is not only useful in the scenario described by Cathy, but in general. It would be great if you could make this generally available for people to test, so we could add this to OpenACS authentication as an additional login method (and market this feature heavily with reluctant IT departments). For obvious reasons we need to put this in 5.2 and TIP it before.
Collapse
Posted by Cathy Sarisky on
Auth-hash is available at http://acornhosting.net/code/auth-hash-0.1d.apm.  The coding style and documentation are somewhat un-beautiful, but everything should be functional.

I don't have CVS commit privs, but someone who does is welcome to drop it into CVS.

Collapse
Posted by Cathy Sarisky on
I agree that a fuller implementation/integration requires a TIP.  The present implementation is just a no-datamodel single tcl file (plus an error page).

[Aside: it should be relatively oACS version agnostic, as long as auth::create_user and ad_user_login are around, but I've only tested with my hybrid dotLRN 2.0.3 / oACS 5.1 install.]

There's currently no tracking that the user is logging in via hash, and the system sends out welcome messages and redirects for login assuming the user is logging in locally.  I need to muck around with the existing auth system and figure out how to get better integration...

Collapse
Posted by Andrew Grumet on
I'll try to look at this code when I can come up for air from the Sloan upgrade.

Two quick thoughts without having looked at the code:

a) This sounds like it could be implemented as an external authentication method in acs-authentication, if it isn't already.

b) Below a slightly more complicated variant that I believe is more secure because no secrets are ever passed.  Downside is it's a bit more complex.  I've implemented it a couple of times and its not too bad.

i) User logs in to campus network

ii) Campus network generates a unique but otherwise random string, saves it plus the user id plus a timestamp and redirects user to OACS with the random string as a URL argument.

iii) OACS issues a backend GET request to campus network with the random string.  Campus network maps random string to user id and timestamp.  If everything checks out, campus network returns user id.

iv) OACS maps campus user id to local user id, and logs user in.

Collapse
Posted by Cathy Sarisky on
Andrew, that does sound better, but it is unfortunately that was more than I could really ask for the remote admin.

This sounds like it could be implemented as an external authentication method in acs-authentication, if it isn't already.
It isn't, but I'm looking at doing so.

Collapse
Posted by Andrew Grumet on
Here's some sample php that implements the remote services for a case where we didn't need to map individual user id's. This implementation uses the filesystem for persistent storage, saving the random string as the filename. The timestamp is the file's mtime. The user id could be echoed into the file instead of simply touching it.

login.php (redirects user)

<?
$code = md5($_SERVER['REMOTE_ADDR'] . mt_rand(0,100000000));
touch("codes/$code");
if ($_REQUEST['service'] != '') {
  $service = $_REQUEST['service'];
} else {
  $service = "http://oacs.url/remote-login";
}
$location = $service . "?code=$code";
if ($_REQUEST['return_url'] != '') {
  $location .= "&return_url=" . urlencode($_REQUEST['return_url']);
}
header("Location: $location");
exit;
?>
login-verify.php (backend verifier)
<?
$code = $_GET['code'];
if (strlen($code) != 32) {
  echo "Fail";
  exit;
}
$path = path_to_codes_directory/$code";
if (!file_exists($path)) {
  echo "Fail";
  exit;
} else {
  echo "Ok";
  unlink($path);
}
?>
The login.php page should only be reachable by logged-in users. The location of the login-verify.php page should be secret and, ideally, only reachable by OACS.
Collapse
Posted by Andrew Grumet on
Hey Cathy, didn't see your last post until after I posted the php code.  Totally understandable.  So just consider the php an fyi for anybody else doing this kind of thing.
Collapse
Posted by Andrew Grumet on
One quick note, the login-verify.php above isn't hardened against funky path attacks.  Caveat emptor.