Merge pull request #49 from nextcloud/imap_rcube

Do IMAP auth over direct socket connection
This commit is contained in:
violoncello.ch
2019-03-15 11:21:51 +01:00
committed by GitHub
3 changed files with 4146 additions and 42 deletions

View File

@@ -56,37 +56,28 @@ needs to be activated.
IMAP IMAP
---- ----
Authenticate Nextcloud users against an IMAP server. 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 ### Configuration
The parameters are `host, port, sslmode, domain`.
Add the following to your `config.php`: Add the following to your `config.php`:
'user_backends' => array( 'user_backends' => array(
array( array(
'class' => 'OC_User_IMAP', 'class' => 'OC_User_IMAP',
'arguments' => array( '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 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 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 login the domain part will be striped and the rest used as username in
NextCloud. e.g. 'username@example.com' will be 'username' in NextCloud. Nextcloud. e.g. 'username@example.com' 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

View File

@@ -6,6 +6,8 @@
* See the COPYING-README file. * See the COPYING-README file.
*/ */
use OCA\user_external\imap\imap_rcube;
/** /**
* User authentication against an IMAP mail server * User authentication against an IMAP mail server
* *
@@ -17,19 +19,24 @@
*/ */
class OC_User_IMAP extends \OCA\user_external\Base { class OC_User_IMAP extends \OCA\user_external\Base {
private $mailbox; private $mailbox;
private $port;
private $sslmode;
private $domain; private $domain;
/** /**
* Create new IMAP authentication provider * Create new IMAP authentication provider
* *
* @param string $mailbox PHP imap_open mailbox definition, e.g. * @param string $mailbox IMAP server domain/IP
* {127.0.0.1:143/imap/readonly} * @param string $port IMAP server $port
* @param string $sslmode
* @param string $domain If provided, loging will be restricted to this domain * @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); parent::__construct($mailbox);
$this->mailbox=$mailbox; $this->mailbox = $mailbox;
$this->domain=$domain; $this->port = $port === null ? 143 : $port;
$this->sslmode = $sslmode;
$this->domain= $domain === null ? '' : $domain;
} }
/** /**
@@ -41,11 +48,6 @@ class OC_User_IMAP extends \OCA\user_external\Base {
* @return true/false * @return true/false
*/ */
public function checkPassword($uid, $password) { 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) // 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 // but only if there is no @ symbol and if there is a %40 inside the uid
if (!(strpos($uid, '@') !== false) && (strpos($uid, '%40') !== false)) { if (!(strpos($uid, '@') !== false) && (strpos($uid, '%40') !== false)) {
@@ -66,28 +68,25 @@ class OC_User_IMAP extends \OCA\user_external\Base {
$username = $uid; $username = $uid;
} }
$mbox = @imap_open($this->mailbox, $username, $password, OP_HALFOPEN, 1); $rcube = new imap_rcube();
$imapErrors = imap_errors();
$imapAlerts = imap_alerts(); $params = ["port"=>$this->port, "timeout"=>10];
if (!empty($imapErrors)) {
OC::$server->getLogger()->error( if ($this->sslmode !== null){
'ERROR: IMAP Error: ' . print_r($imapErrors, true), $params["ssl_mode"] = $this->sslmode;
['app' => 'user_external']
);
} }
if (!empty($imapAlerts)) { $canconnect = $rcube->connect(
OC::$server->getLogger()->warning( $this->mailbox,
'WARNING: IMAP Warning: ' . print_r($imapAlerts, true), $username,
['app' => 'user_external'] $password,
); $params
} );
if($mbox !== false) {
imap_close($mbox); if($canconnect) {
$uid = mb_strtolower($uid); $uid = mb_strtolower($uid);
$this->storeUser($uid); $this->storeUser($uid);
return $uid; return $uid;
} }
return false; return false;
} }
} }

4114
lib/imap/imap_rcube.php Normal file

File diff suppressed because it is too large Load Diff