Thursday, January 26, 2012

CAS-ifying Roundcube

Quick background/summary:
We have a CAS server for our campus, and we use Roundcube for our webmail system. Some time ago, I was asked to extend our Roundcube system to authenticate against CAS. Doing so would net us some nice benefits:
  • Graceful handling of locked accounts/expired passwords.
  • SSO to Webmail if already signed in to another SSO service.
  • Easy access for custom webapps wanting to access IMAP.
One of the first things I had to do was configure our IMAP server to accept CAS tickets as passwords. Our IMAP server (Dovecot) uses PAM for authentication, so all I had to do was follow the instructions on the Google translation of this page (French):
  • Create CAS services for HTTPS and IMAP URIs that ignore attributes and can proxy. On our older version of CAS I also had to restart the servlet container for the new services to be active.
  • Download, compile, install and configure pam_cas from https://sourcesup.cru.fr/frs/?group_id=213.
  • Add pam_cas to Dovecot's PAM stack with the IMAP service I created in CAS and the pam_cas.conf file I created in the options.
  • Test that Dovecot validates CAS tickets. You could use the CASTest utility that comes with pam_cas, but I chose to just open https://<CAS server>/login?service=<IMAP service> in a web browser and copy/paste the service ticket I got from CAS into a telnet session that was authenticating to our IMAP server. Be careful when testing! The default CAS Service Ticket life is 10 seconds, so you may have to move fast if you follow my testing method.
If you run in to problems in any of those steps, the best thing you can do is turn debug on in /etc/pam_cas.conf and send *.debug in your syslog config to a file that you can read. You should get good info from that as to why pam_cas is failing.

Once I had IMAP authenticating users with CAS tickets, Alex's plugin got me most of the way, but I found that I had to make 2 modifications to Roundcube's index.php file to get the plugin to work properly. I also wanted a few additional features that his plugin lacked:
  • The option of not using CAS for authentication. Alex's plugin forces it for authentication to Roundcube.
  • SMTP authentication using a CAS proxy ticket.
I was able to remove the need to modify Roundcube's source and add those features to my fork of his plugin. It is currently in production in our 8-node Roundcube cluster. There were a few "gotchas" along the way that I don't want to forget, and other people may find useful when working with my plugin or CAS' proxy feature in general:
  • If you run multiple Roundcube servers behind a load balancer, you need to be sure of 2 things:
    • You have the same version of phpCAS on all of your Roundcube servers.
    • You are using shared storage for PGTIOUs coming back from the CAS server. This page talks about this process but basically part of proxy CAS authentication is the CAS server will make an HTTP call to a URL that is supposed to store a necessary piece of information. Unless you're absolutely sure the CAS server will be sent to the same Roundcube server that the user is currently hitting, you need to make sure that all Roundcube servers can share the directory where PGTIOUs are saved.
  • If you are using CAS' proxy method for authenticating to IMAP, you all but need an IMAP proxy. Without it, you will need to generate and validate a new ticket from CAS (multiple HTTP trips) for each page load. With an IMAP proxy, the user's first IMAP ticket is validated by pam_cas by your actual IMAP server and saved in your IMAP proxy. Roundcube will continue to send the same ticket and the IMAP proxy will continue to believe the user is logged in, even though that ticket has been used and cannot be validated again by the IMAP server.

3 comments:

  1. Hi David,

    its a pretty good documentation. 99% of the howto was also working in my case.
    But i cannot understand the proxy chapter properly. Would be very nice if you could pass an example of the proxy feature. Information about this is very rare on the net.

    I would appreciate any hint.
    Thanks
    Andy

    ReplyDelete
  2. Hey there David! First off, you're a lifesaver! This is practically the only resource that I have found on doing CAS/Dovecot integration and I really appreciate you taking the time to do so.

    Would you be able to show any of the configurations that you used? I'm particularly interested in the "auth default { }" section of your dovecot.conf file, because I can now get roundcube to get a ticket but the roundcube logs show that the IMAP login fails.

    Also, I had to comment out the "phpCAS::setPGTStorageFile" line from the cas_authn plugin because I was getting an error about needing to have an absolute path to the storage (which I had in the configuration file, and permissions were fine). It seems to be working okay without that line, however, as I assume phpCAS uses the default at that point.

    Thanks for your time!

    ReplyDelete
  3. Hi David,
    Your plugin works perfectly on my roudncube install, but do you know if he is compatible with the managesieve plugin ?

    Thanks for your time.

    Nicolas

    ReplyDelete