Add support for SMTP
Signed-off-by: Shin'ya Minazuki <shinyoukai@laidback.moe>
This commit is contained in:
@@ -220,6 +220,9 @@ Add the following to your `config.php`:
|
||||
**⚠⚠ Warning:** If you need to set *5 (Hashed Password in Database)* to false, your Prosody Instance is storing passwords in plaintext. This is insecure and not recommended. We highly recommend that you change your Prosody configuration to protect the passwords of your Prosody users. ⚠⚠
|
||||
|
||||
|
||||
## SMTP
|
||||
Works the same way as the IMAP section above, but authenticates against an SMTP server.
|
||||
|
||||
Alternatives
|
||||
------------
|
||||
Other extensions allow connecting to external user databases directly via SQL, which may be faster:
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
* FTP
|
||||
* WebDAV
|
||||
* HTTP BasicAuth
|
||||
* SMTP
|
||||
* SSH
|
||||
* XMPP
|
||||
|
||||
@@ -33,6 +34,6 @@ Read the [documentation](https://github.com/nextcloud/user_external#readme) to l
|
||||
<bugs>https://github.com/nextcloud/user_external/issues</bugs>
|
||||
<repository type="git">https://github.com/nextcloud/user_external.git</repository>
|
||||
<dependencies>
|
||||
<nextcloud min-version="25" max-version="30" />
|
||||
<nextcloud min-version="25" max-version="32" />
|
||||
</dependencies>
|
||||
</info>
|
||||
|
||||
141
lib/SMTP.php
Normal file
141
lib/SMTP.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Robin Appelman <icewind@owncloud.com>
|
||||
* @author Jonas Sulzer <jonas@violoncello.ch>
|
||||
* @copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* @copyright (c) 2026 Yakumo Laboratories -- https://yakumolabs.privatedns.org --
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\UserExternal;
|
||||
|
||||
/**
|
||||
* User authentication against an SMTP mail server
|
||||
* (modified from IMAP.php)
|
||||
*
|
||||
* @category Apps
|
||||
* @package UserExternal
|
||||
* @author Robin Appelman <icewind@owncloud.com>
|
||||
* @license http://www.gnu.org/licenses/agpl AGPL
|
||||
* @link http://github.com/owncloud/apps
|
||||
*/
|
||||
class SMTP extends Base {
|
||||
private $mailbox;
|
||||
private $port;
|
||||
private $sslmode;
|
||||
private $domain;
|
||||
private $stripeDomain;
|
||||
private $groupDomain;
|
||||
|
||||
/**
|
||||
* Create new SMTP authentication provider
|
||||
*
|
||||
* @param string $mailbox SMTP server domain/IP
|
||||
* @param int $port SMTP server $port
|
||||
* @param string $sslmode
|
||||
* @param string $domain If provided, loging will be restricted to this domain
|
||||
* @param boolean $stripeDomain (whether to stripe the domain part from the username or not)
|
||||
* @param boolean $groupDomain (whether to add the usere to a group corresponding to the domain of the address)
|
||||
*/
|
||||
public function __construct($mailbox, $port = null, $sslmode = null, $domain = null, $stripeDomain = true, $groupDomain = false) {
|
||||
parent::__construct($mailbox);
|
||||
$this->mailbox = $mailbox;
|
||||
$this->port = $port === null ? 25 : $port;
|
||||
$this->sslmode = $sslmode;
|
||||
$this->domain = $domain === null ? '' : $domain;
|
||||
$this->stripeDomain = $stripeDomain;
|
||||
$this->groupDomain = $groupDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the password is correct without logging in the user
|
||||
*
|
||||
* @param string $uid The username
|
||||
* @param string $password The password
|
||||
*
|
||||
* @return true/false
|
||||
*/
|
||||
public function checkPassword($uid, $password) {
|
||||
// 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)) {
|
||||
$uid = str_replace("%40", "@", $uid);
|
||||
}
|
||||
|
||||
$pieces = explode('@', $uid);
|
||||
if ($this->domain !== '') {
|
||||
if (count($pieces) === 1) {
|
||||
$username = $uid . '@' . $this->domain;
|
||||
} elseif (count($pieces) === 2 && $pieces[1] === $this->domain) {
|
||||
$username = $uid;
|
||||
if ($this->stripeDomain) {
|
||||
$uid = $pieces[0];
|
||||
}
|
||||
} else {
|
||||
$this->logger->error(
|
||||
'ERROR: User has a wrong domain! Expecting: '.$this->domain,
|
||||
['app' => 'user_external']
|
||||
);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$username = $uid;
|
||||
}
|
||||
|
||||
$groups = [];
|
||||
if ((count($pieces) > 1) && $this->groupDomain && $pieces[1]) {
|
||||
$groups[] = $pieces[1];
|
||||
}
|
||||
|
||||
$protocol = ($this->sslmode === "ssl") ? "smtps" : "smtp";
|
||||
$url = "{$protocol}://{$this->mailbox}:{$this->port}";
|
||||
$ch = curl_init();
|
||||
if ($this->sslmode === 'tls') {
|
||||
curl_setopt($ch, CURLOPT_USE_SSL, CURLUSESSL_ALL);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $username.":".$password);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
|
||||
|
||||
curl_exec($ch);
|
||||
$errorcode = curl_errno($ch);
|
||||
|
||||
if ($errorcode === 0) {
|
||||
curl_close($ch);
|
||||
$uid = mb_strtolower($uid);
|
||||
$this->storeUser($uid, $groups);
|
||||
return $uid;
|
||||
} elseif ($errorcode === CURLE_COULDNT_CONNECT ||
|
||||
$errorcode === CURLE_SSL_CONNECT_ERROR ||
|
||||
$errorcode === 28) {
|
||||
# This is not defined in PHP-8.x
|
||||
# 28: CURLE_OPERATION_TIMEDOUT
|
||||
$this->logger->error(
|
||||
'ERROR: Could not connect to smtp server via curl: ' . curl_strerror($errorcode),
|
||||
['app' => 'user_external']
|
||||
);
|
||||
} elseif ($errorcode === 9 ||
|
||||
$errorcode === 67 ||
|
||||
$errorcode === 94) {
|
||||
# These are not defined in PHP-8.x
|
||||
# 9: CURLE_REMOTE_ACCESS_DENIED
|
||||
# 67: CURLE_LOGIN_DENIED
|
||||
# 94: CURLE_AUTH_ERROR)
|
||||
$this->logger->error(
|
||||
'ERROR: SMTP Login failed via curl: ' . curl_strerror($errorcode),
|
||||
['app' => 'user_external']
|
||||
);
|
||||
} else {
|
||||
$this->logger->error(
|
||||
'ERROR: SMTP server returned an error: ' . $errorcode . ' / ' . curl_strerror($errorcode),
|
||||
['app' => 'user_external']
|
||||
);
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user