Skip to content

Commit

Permalink
Merge pull request #49 from nextcloud/imap_rcube
Browse files Browse the repository at this point in the history
Do IMAP auth over direct socket connection
  • Loading branch information
violoncelloCH authored Mar 15, 2019
2 parents 36e8980 + b9fa972 commit c6de575
Show file tree
Hide file tree
Showing 3 changed files with 4,146 additions and 42 deletions.
21 changes: 6 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,37 +56,28 @@ needs to be activated.
IMAP
----
Authenticate Nextcloud users against an IMAP server.
IMAP user and password need to be given for the Nextcloud login
IMAP user and password need to be given for the Nextcloud login.


### Configuration
The parameters are `host, port, sslmode, domain`.
Add the following to your `config.php`:

'user_backends' => array(
array(
'class' => 'OC_User_IMAP',
'arguments' => array(
'{127.0.0.1:143/imap/readonly}', 'example.com'
'127.0.0.1', 993, ssl, 'example.com'
),
),
),

This connects to the IMAP server on IP `127.0.0.1`, in readonly mode.
This connects to the IMAP server on IP `127.0.0.1`.
The default port is 143; however if you want to restrict the domain, you need to specify the port and set sslmode to `null`.
If a domain name (e.g. example.com) is specified, then this makes sure that
only users from this domain will be allowed to login. After successfull
login the domain part will be striped and the rest used as username in
NextCloud. e.g. '[email protected]' will be 'username' in NextCloud.

Read the [imap_open][IMAP_0] PHP manual page to learn more about the allowed
parameters.

[IMAP_0]: http://php.net/imap_open#refsect1-function.imap-open-parameters


### Dependencies
The PHP [IMAP extension][IMAP_1] has to be activated.

[IMAP_1]: http://php.net/imap
Nextcloud. e.g. '[email protected]' will be 'username' in Nextcloud.



Expand Down
53 changes: 26 additions & 27 deletions lib/imap.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* See the COPYING-README file.
*/

use OCA\user_external\imap\imap_rcube;

/**
* User authentication against an IMAP mail server
*
Expand All @@ -17,19 +19,24 @@
*/
class OC_User_IMAP extends \OCA\user_external\Base {
private $mailbox;
private $port;
private $sslmode;
private $domain;

/**
* Create new IMAP authentication provider
*
* @param string $mailbox PHP imap_open mailbox definition, e.g.
* {127.0.0.1:143/imap/readonly}
* @param string $mailbox IMAP server domain/IP
* @param string $port IMAP server $port
* @param string $sslmode
* @param string $domain If provided, loging will be restricted to this domain
*/
public function __construct($mailbox, $domain = '') {
public function __construct($mailbox, $port = null, $sslmode = null, $domain = null) {
parent::__construct($mailbox);
$this->mailbox=$mailbox;
$this->domain=$domain;
$this->mailbox = $mailbox;
$this->port = $port === null ? 143 : $port;
$this->sslmode = $sslmode;
$this->domain= $domain === null ? '' : $domain;
}

/**
Expand All @@ -41,11 +48,6 @@ public function __construct($mailbox, $domain = '') {
* @return true/false
*/
public function checkPassword($uid, $password) {
if (!function_exists('imap_open')) {
OC::$server->getLogger()->error('ERROR: PHP imap extension is not installed', ['app' => 'user_external']);
return false;
}

// Replace escaped @ symbol in uid (which is a mail address)
// but only if there is no @ symbol and if there is a %40 inside the uid
if (!(strpos($uid, '@') !== false) && (strpos($uid, '%40') !== false)) {
Expand All @@ -66,28 +68,25 @@ public function checkPassword($uid, $password) {
$username = $uid;
}

$mbox = @imap_open($this->mailbox, $username, $password, OP_HALFOPEN, 1);
$imapErrors = imap_errors();
$imapAlerts = imap_alerts();
if (!empty($imapErrors)) {
OC::$server->getLogger()->error(
'ERROR: IMAP Error: ' . print_r($imapErrors, true),
['app' => 'user_external']
);
}
if (!empty($imapAlerts)) {
OC::$server->getLogger()->warning(
'WARNING: IMAP Warning: ' . print_r($imapAlerts, true),
['app' => 'user_external']
);
$rcube = new imap_rcube();

$params = ["port"=>$this->port, "timeout"=>10];

if ($this->sslmode !== null){
$params["ssl_mode"] = $this->sslmode;
}
if($mbox !== false) {
imap_close($mbox);
$canconnect = $rcube->connect(
$this->mailbox,
$username,
$password,
$params
);

if($canconnect) {
$uid = mb_strtolower($uid);
$this->storeUser($uid);
return $uid;
}

return false;
}
}
Loading

0 comments on commit c6de575

Please sign in to comment.