I'm attempting to write a plugin to allow pubcookie sessions to authenticate directly into roundcube without requiring any additional login from the user. First of all, has anyone done this already? It's not one of the standard plugins...
Assuming that pubcookie hasn't already been done, I've been looking at the roundcube architecture for how to integrate it. Unfortunately, if you use pubcookie, you get a userID and a kerberos credential (instead of a userID/password combo), so it looks like none of the standard roundcube hooks will do the right thing. I already have code that will build a pre-authenticated connection to my IMAP server, but I don't really see how to hand this back to roundcube while bypassing the normal login/imap connection building that is going on.
Can anyone provide some ideas on the best way to do this? I'd be happy to contribute the eventual plugin back to the pool.
Thanks,
Tod Pike Manager of Enterprise Services School of Computer Science Carnegie Mellon University, Pittsburgh, Pa _______________________________________________ List info: http://lists.roundcube.net/dev/ BT/aba52c80
Interesting....I learned a lot of new stuff, but in the end Roundcube has it's own imap functions instead of using the ones built into PHP and they don't support GSSAPI so I don't see anyway to do this short of an ugly hack.
The ugly hack would call for you to extend the HTTP authentication module and modify it to detect when someone has logged on via pubkey...then use the imap_connect event to change the userid/password from the userid for the specific user, to a system userid that has access to everyone's mailboxes.
The best way to do this would be to extend the imap functions to support gssapi when authenticating. But that would require hacking the source files.
List info: http://lists.roundcube.net/dev/ BT/aba52c80
Gary: I've already got an ugly hack ready - we did something similar to use squirrelmail against our GSSAPI IMAP server. We use the imtest helper program to open the GSSAPI-authenticated session (passing in the Kerberos credential file that we got from the pubcookie module). We passed that file descriptor back into squirrelmail, bypassing the normal connection open.
I'd like to something similar in roundcube, but it's pretty difficult using only plugins. I can certainly set up my own imap_connect hook that would open the proper connection, but I don't see any way to put the resulting file descriptor into the imap object, since all that stuff is private to the rcube_imap_generic module.
I'll admit that I'm not a PHP expert here, so maybe I'm looking at it all wrong.
Tod Pike
Gary Mort wrote:
Interesting....I learned a lot of new stuff, but in the end Roundcube has it's own imap functions instead of using the ones built into PHP and they don't support GSSAPI so I don't see anyway to do this short of an ugly hack.
The ugly hack would call for you to extend the HTTP authentication module and modify it to detect when someone has logged on via pubkey...then use the imap_connect event to change the userid/password from the userid for the specific user, to a system userid that has access to everyone's mailboxes.
The best way to do this would be to extend the imap functions to support gssapi when authenticating. But that would require hacking the source files.
On Wed, Dec 1, 2010 at 11:56 AM, Tod Pike tgp@cs.cmu.edu wrote:
Gary: I've already got an ugly hack ready - we did something similar to use squirrelmail against our GSSAPI IMAP server. We use the imtest helper program to open the GSSAPI-authenticated session (passing in the Kerberos credential file that we got from the pubcookie module). We passed that file descriptor back into squirrelmail, bypassing the normal connection open.
I'd love to see how that code works since the only gssapi implementations I can find seem to be in C using the C-Client library.
I'd like to something similar in roundcube, but it's pretty difficult using only plugins. I can certainly set up my own imap_connect hook that would open the proper connection, but I don't see any way to put the resulting file descriptor into the imap object, since all that stuff is private to the rcube_imap_generic module.
That's what I meant, you need to modify the core code. At a minimum, you need to modify rcube_imap_generic to include a case for using GSSAPI. Personally, once you start editing that, I'd say move the whole if/then structure to a switch/case structure as there are then 4 different mechanisms.
If you want to be really really nice, extend the auth_sasl code http://pear.php.net/package/Auth_SASL/
The module doesn't currently have a maintainer, so you could update it there to support GSSAPI and then bring it downstream to Roundcube.
I'm stuck at the moment in conceptualizing how to do GSSAPI authentication from within PHP[in theory, I know it's just a matter of passing the challenge token into the function over and over till you get to a success]
List info: http://lists.roundcube.net/dev/ BT/aba52c80
After looking through the code a bit, I think you can solve your issue using the imap_init plugin and one minor core change. All in all it looks like an hours coding and 3 hours testing.
imap_init is called in: program/include/rcmail.php so all you need to do there is
$imapsocket = yourconnection();
2)set imap->conn->fp property to the socket your have opened
$GLOBALS['IMAP']->conn->fp = $imapsocket;
3)set the logged property on connection so it knows it is connected
$GLOBALS['IMAP']->conn->logged = TRUE;
Now for the core code change: In the imap library, the connect code is a do/while loop. This means it always tries to connect at least once, even if you are already connected. And while it is possible to force the imap_generic option to abort the connection attempt by setting userid or password to nothing, it won't abort before setting logged to false, so roundcube will not think it is logged in. Change that from a do/while loop to a while loop[move the condition to the top], or surround it by an if not connected clause, and you can bypass processing if you have already connected.
/program/include/rcube_imap.php
*do {
$data = rcmail::get_instance()->plugins->exec_hook('imap_connect',
array('host' => $host, 'user' => $user, 'attempt' =>
++$attempt));
if (!empty($data['pass']))
$pass = $data['pass'];
$this->conn->connect($data['host'], $data['user'], $pass,
$this->options); } while(!$this->conn->connected() && $data['retry']);*
And that's it, you should be all good.
Sorry I couldn't be more help. I actually haven't used RoundCube before.... I was let go a couple months ago and am in the process of setting up my website for doing web engineering freelancing. The only reason I signed up to this list is because I want a webmail app to segregate out my email from multiple domains/addresses properly and RoundCube looks like the best one[Horde looks slightly better feature wise, but as too MANY features for my simple needs, while Squirrelmail has too few]. I don't currently have a test environment to throw all this onto to test it.
This was a fascinating problem though, so thanks for a few hours diversion.
-Gary
List info: http://lists.roundcube.net/dev/ BT/aba52c80
Gary: I'll give it a try over the weekend and see what I can come up with. Thanks for the help!
Tod
Gary Mort wrote:
After looking through the code a bit, I think you can solve your issue using the imap_init plugin and one minor core change. All in all it looks like an hours coding and 3 hours testing.
imap_init is called in: program/include/rcmail.php so all you need to do there is
- Create your own socket/connection to the server and logon
$imapsocket = yourconnection();
2)set imap->conn->fp property to the socket your have opened
$GLOBALS['IMAP']->conn->fp = $imapsocket;
3)set the logged property on connection so it knows it is connected
$GLOBALS['IMAP']->conn->logged = TRUE;
Now for the core code change: In the imap library, the connect code is a do/while loop. This means it always tries to connect at least once, even if you are already connected. And while it is possible to force the imap_generic option to abort the connection attempt by setting userid or password to nothing, it won't abort before setting logged to false, so roundcube will not think it is logged in. Change that from a do/while loop to a while loop[move the condition to the top], or surround it by an if not connected clause, and you can bypass processing if you have already connected.
/program/include/rcube_imap.php
/do { $data = rcmail::get_instance()->plugins->exec_hook('imap_connect', array('host' => $host, 'user' => $user, 'attempt' => ++$attempt)); if (!empty($data['pass'])) $pass = $data['pass']; $this->conn->connect($data['host'], $data['user'], $pass, $this->options); } while(!$this->conn->connected() && $data['retry']);/
And that's it, you should be all good.
Sorry I couldn't be more help. I actually haven't used RoundCube before.... I was let go a couple months ago and am in the process of setting up my website for doing web engineering freelancing. The only reason I signed up to this list is because I want a webmail app to segregate out my email from multiple domains/addresses properly and RoundCube looks like the best one[Horde looks slightly better feature wise, but as too MANY features for my simple needs, while Squirrelmail has too few]. I don't currently have a test environment to throw all this onto to test it.
This was a fascinating problem though, so thanks for a few hours diversion.
-Gary