priyadi / roundcube-converse.js-xmpp-plugin

XMPP plugin for Roundcube Webmail based on converse.js
49 stars 18 forks source link

authenticate xmpp with roundcube login uid instead of imap e-mail address #6

Closed joe8 closed 11 years ago

joe8 commented 11 years ago

Hi there,

Thank you for the work invested. I have openfire and roundcube/converse plugin working via bosh with the exception of the 'user' argument:

In my setup (with kolab) it sends the IMAP username id aka primary e-mail address as the JID. But openfire expects the uid provided by ldap which was used to login to roundcube.

To illustrate:

  1. Login to roundcube with uid "john"
  2. After login rouncube populates the user with the primary e-mail address associated with the account which is john.doe@example.com,
  3. The plugin then uses this as (part) of the JID to authenticate with openfire, but openfire expects the uid and not the associated e-mail address.

I was able to authenticate successfully with the plugin after setting the user argument statically (so only one account can use the plugin) .

Is there a way to have the username which was logged in with used for pre-bind instead of the mapped imap username?

I believe another person also requested this functionality...I would not ask If was not at a loss.

Many thanks for your time.

priyadi commented 11 years ago

Hi,

If I understand you correctly:

Roundcube gets the email address 'john.doe@example.com' by querying LDAP for 'john'. Am I right here? And your openfire expects 'john.doe' as username part of the XMPP JID, but with different domain than john's email address.

It is probably possible by customizing 'converse_xmpp_username' function. Let me know first if my assumptions above are correct.

joe8 commented 11 years ago

Hey,

Thanks for answering. Unfortunately I must have been unclear. The first part of your analysis is inline with my problem, but not the second part. I will attempt in the same format:

- roundcube username: john
- IMAP username: john.doe@example.com
- XMPP username: john.@xmpp.example.com

Roundcube gets the email address/IMAP user for user id 'john' by querying LDAP for 'john'. Openfire is connected to the same ldap and it expects 'john' as the username part of the XMPP JID but the plugin sends the e-mail address/IMAP user instead of the ldap user id.

The discrepancies in (sub)domains can be easily resolved using the configuration you provide, but it is the JID which is the problem: roundcube-converse.js-xmpp-plugin sends john.doe@.......... where openfire expects john@.....

This morning I have been trying to alter the openfire configuration so it will concatenate multiple LDAP components in the ldap.usernameFieldL for example "{givenName}.{sn}" would construct the username "john.doe". But alas opefire falls short. There is an improvement request for this functionality which can be found here: http://issues.igniterealtime.org/browse/OF-520?page=com.atlassian.streams.streams-jira-plugin:activity-stream-issue-tab

A convoluted way of solving this would be to do an ldap query for the UID by matching the IMAP mail address and then passing this to the plugin. Unfortunately this surpasses my competence.

The easiest way would be that the plugin uses UID which was actualy used to authenticate with roundcube.

I don't know what to do anymore.

thomascube commented 11 years ago

Hey Joe

The plugin actually does take the username used for authentication in Roundcube unless you configured it otherwise. The clue in you case is probably the kolab_auth plugin (you said you're using it with Kolab) which alters the username entered in the login form to the canonic primary email address which is used for IMAP and SMTP authentication.

So how to solve your situation? The config of the converse plugin (see plugins/converse/config.inc.php) can contain functions that provide certain parameters. For example you can hack this config option and modify the $args['user'] argument:

$rcmail_config['converse_xmpp_username'] = function($args) {
    list($user,$host) = explode('@', $args['user']);
    return preg_replace('/\..+$/', '.', $user);
};

or, when looking at the kolab_auth plugin, you can even access the UID property form the initial LDAP query directly. It's made globally available as $_SESSION['kolab_uid']. Thus, although without actually having tested it, this configuration should also work:

$rcmail_config['converse_xmpp_username'] = $_SESSION['kolab_uid'];
joe8 commented 11 years ago

Hi Thomas,

Wow, I'm humbled by the response of such a significant contributor.

As far as i can tell the first solution uses the first part of the primary e-mail address which is not necessarily the same as the User ID (although in my example of uid "john" vs the canonic primary email address "john.doe@example.com", this would work).

The second solution seems the more robust, but unfortunately did not work for me, from the openfire log: "jivesoftware.openfire.net.SASLAuthentication - User Login Failed. PLAIN authentication failed for: john.doe@example/Roundcube"

When looking at the kolab_auth plugin as defined in /kolab_auth/kolab_auth.php could it be that the primary mail addres is used:

$rcmail_config['kolab_auth_filter'] = '(&' . '(objectclass=inetorgperson)' . '(|(uid=%u)(mail=%fu)(alias=%fu)))'; $_SESSION['kolab_uid'] = is_array($record['uid']) ? $record['uid'][0] : $record['uid'];

What to do?

Btw.. I'm not a developer just a hacker trying to get this to work for personal use and your input is much appreciated.

thomascube commented 11 years ago

Well, the $rcmail_config['kolab_auth_filter'] property is used for the LDAP query when logging in to Roundcube. The goal is to allow users to authenticate with their uid, primary email or alias email address equally.

It's now about to find out what UID value is returned by that LDAP query. You could add console($SESSION['kolab_uid']); right after the $SESSION['kolab_uid'] = ...; line in the kolab_auth plugin code. That will write the UID to /var/log/roundcubemail/console when you log in to Roundcube. In case the UID value is empty, you probably have to add it to the fieldmap in the kolab_auth plugin's config file:

$rcmail_config['kolab_auth_addressbook'] = array(
    'hosts'         => array('127.0.0.1'),
    'port'          => 389,
    'use_tls'       => false,
    'user_specific' => false,
    'base_dn'       => 'ou=People,dc=example,dc=org',
    'bind_dn'       => 'uid=kolab-service,ou=Special Users,dc=example,dc=org',
    ...
    'fieldmap' => array(
        'name'    => 'cn',
        'email'   => 'mailPrimaryAddress',
        'alias'   => 'alias',
        'role'    => 'nsRole',
        'uid'     => 'uid',
    ),
    ...
);
joe8 commented 11 years ago

Ok,

I added console line to kolab_auth.php (for the benefit of others with underscore after $). The output in "/var/log/roundcubemail/console" is: "[03-Nov-2013 15:45:12,000000 +0100]: john"

And that is exactly the user id I want the converse plugin to use!

But in "/var/log/roundcubemail/userlogins" it shows: "[03-Nov-2013 15:45:13,000000 +0100]: Successful login for john.doe@example.com (ID: 1) from 192.168.1.94 in session 7p6qef56pi4iusns0m6a8c1vs3"

Hence the problems I'm having.

I seem to have solved it with the following hack in the config of kolab_auth:

Change: // Use this fields (from fieldmap configuration) to get authentication ID $rcmail_config['kolab_auth_login'] = 'email';

To: // Use this fields (from fieldmap configuration) to get authentication ID $rcmail_config['kolab_auth_login'] = 'uid';

And everything seems to work ok, roundcube even still displays the canonical primary email address but the converse logs in with the user id that was used to log in.

joe8 commented 11 years ago

Just reopened because the dirty hack I mentioned earlier has side effects:

Altering the field name in config of kolab_auth in the following line:

$rcmail_config['kolab_auth_login'] = 'email';

makes the converse plugin use the original user id but breaks other things like populating the global address book. It was wishful thinking on my part to believe that it would not break other stuff.

I have tried many things to no avail, including adding the following property to the config file of the plugin:

$rcmail_config['converse_xmpp_username'] = $_SESSION['kolab_uid'];
thomascube commented 11 years ago

Did you once add the console() debug output as suggested further above to check what value $_SESSION['kolab_uid'] contains?

joe8 commented 11 years ago

@thomascube absolutely, see 7th post in this thread:

I added console line to kolab_auth.php (for the benefit of others with underscore after $). The output in "/var/log/roundcubemail/console" is: "[03-Nov-2013 15:45:12,000000 +0100]: john"

And that is exactly the user id I want the converse plugin to use!

The value of kolab_uid is correct. To take things a step further I temporarily added the same console line to the plugin config see what it would spit out, after fresh login it outputs:

[05-Nov-2013 09:22:12,000000 +0100]: NULL
[05-Nov-2013 09:22:13,000000 +0100]: joe

The global session property kolab_uid is available and correct from within the plugin. But when I try using it so: $rcmail_config['converse_xmpp_username']= $_SESSION['kolab_uid']; No joy!

And related, the userlogins log shows [05-Nov-2013 09:32:29,000000 +0100]: Successful login for john.doe@example.com (ID: 1) from 192.168.1.1 in session nnpjrsccp6qjfcvsmsp3mq96q6

But when I cripple $rcmail_config['kolab_auth_login'] = 'email'; in .../kolab_auth/config.inc.php the userlogins log shows:

[04-Nov-2013 15:43:01,000000 +0100]: Successful login for joe (ID: 3) from 192.168.1.1 in session sn2i3aboqh8almjkrtpn9t5hh6

And the plugin authenticates successfully with the 'user' argument :

$rcmail_config['converse_xmpp_username']= function($args) {
  return $args['user'];
};

Sorry for the elaborate post.

thomascube commented 11 years ago

User logins are OK and should be done with the full email address. But I think I see the reason why my initial suggestion doesn't work:

$_SESSION['kolab_uid'] is set in the 'authenticate' plugin hook but the configuration file is read before that and thus the value is still empty. So let's try the following in the converse plugin config:

$rcmail_config['converse_xmpp_username']= function($args) {
  return $_SESSION['kolab_uid'];
};

Also make sure the 'converse' plugin is listed after 'kolab_auth' in the plugins list in Roundcube's main config file.

Sorry for bouncing this back and forth. You're just a bit too early because we actually have plans to integrate the converse plugin with Kolab but now you accidentally became the testing guinea pig for the Kolab setup. So whatever we'll figure out together here will directly contribute to the Kolab project and is very valuable.

joe8 commented 11 years ago

@thomascube your suggestion works!!!

I came to a similar conclusion about loading sequence after adding //console($rcmail_config['converse_xmpp_username']); after the line $rcmail_config['converse_xmpp_username']= ($_SESSION['kolab_uid']); and it printed the correct user id to console log.

So with my current set-up I'm fine and will concentrate on other aspects of the plugin.

I suppose your code block which is specific to Kolab could be included in the default plugin config being commented out with an explanation. But maybe you have a more elegant solution where the code can check if kolab exists and else do the default.

I might create a branch to play around and depending on what you want to do I will at least include your solution in commented form and make a pull request to prijadi.

Next up (and I'm my opinion just as blocking as not being able to log in) issue #7

Cheers