ZP-828 IMAP contributions. Released under the Affero GNU General Public License (AGPL) version 3.

parent f9e71d7f
BackendIMAP - NOTES
===================
This backend support the Search operation in the mailbox.
Since the IMAP search operation is pretty slow, with a medium/big mailbox, or with a lots of folders,
the mobile device will timeout the operation before this is completed on server.
I'm using Dovecot + FTS-SOLR plugin so the real search is done against an Apache SOLR server.
It reduces a 1-2 minutes search to 1-5 seconds, and the response is given to the mobile device in time.
CHANGESSINK
===========
It supports ChangesSink method that will detect and send faster changes to your device.
SMTP
====
You can choice between 3 methods for send mails: mail (php mail), sendmail (native binary), smtp (php smtp direct connection).
Remember to configure it in the config.php
"mail" is a sendmail wrapper in Linux.
MBCONVERT
=========
A lot of messages come with wrong encoding, to them to look better with any device you can pre-convert them to UTF-8.
You will need to install the php-mbstring module
\ No newline at end of file
REQUIREMENTS:
php-imap
php-mbstring (optional but recommended)
libawl-php
IMAP server (Dovecot, Courier...)
\ No newline at end of file
*Drenalina SRL (www.drenalina.com)* sponsored the development of the following features in the BackendIMAP, any existing bug it's my fault not theirs ;-)
Thank you very much for helping to improve it!!
- Meeting invitations and attendees
\ No newline at end of file
......@@ -54,23 +54,174 @@ define('IMAP_PORT', 143);
// best cross-platform compatibility (see http://php.net/imap_open for options)
define('IMAP_OPTIONS', '/notls/norsh');
// overwrite the "from" header if it isn't set when sending emails
// options: 'username' - the username will be set (usefull if your login is equal to your emailaddress)
// 'domain' - the value of the "domain" field is used
// '@mydomain.com' - the username is used and the given string will be appended
define('IMAP_DEFAULTFROM', '');
// copy outgoing mail to this folder. If not set z-push will try the default folders
define('IMAP_SENTFOLDER', '');
// Mark messages as read when moving to Trash.
// BE AWARE that you will lose the unread flag, but some mail clients do this so the Trash folder doesn't get boldened
define('IMAP_AUTOSEEN_ON_DELETE', false);
// IMPORTANT: BASIC IMAP FOLDERS [ask your mail admin]
// We can have diferent cases (case insensitive):
// 1.
// inbox
// sent
// drafts
// trash
// 2.
// inbox
// common.sent
// common.drafts
// common.trash
// 3.
// common.inbox
// common.sent
// common.drafts
// common.trash
// 4.
// common
// common.sent
// common.drafts
// common.trash
//
// gmail is a special case, where the default folders are under the [gmail] prefix and the folders defined by the user are under INBOX.
// This configuration seems to work:
// define('IMAP_FOLDER_PREFIX', '');
// define('IMAP_FOLDER_INBOX', 'INBOX');
// define('IMAP_FOLDER_SENT', '[Gmail]/Sent');
// define('IMAP_FOLDER_DRAFTS', '[Gmail]/Drafts');
// define('IMAP_FOLDER_TRASH', '[Gmail]/Trash');
// define('IMAP_FOLDER_SPAM', '[Gmail]/Spam');
// define('IMAP_FOLDER_ARCHIVE', '[Gmail]/All Mail');
// Since I know you won't configure this, I will raise an error unless you do.
// When configured set this to true to remove the error
define('IMAP_FOLDER_CONFIGURED', false);
// Folder prefix is the common part in your names (3, 4)
define('IMAP_FOLDER_PREFIX', '');
// Inbox will have the preffix preppend (3 & 4 to true)
define('IMAP_FOLDER_PREFIX_IN_INBOX', false);
// Inbox folder name (case doesn't matter) - (empty in 4)
define('IMAP_FOLDER_INBOX', 'INBOX');
// forward messages inline (default false - as attachment)
define('IMAP_INLINE_FORWARD', false);
// Sent folder name (case doesn't matter)
define('IMAP_FOLDER_SENT', 'SENT');
// use imap_mail() to send emails (default) - if false mail() is used
define('IMAP_USE_IMAPMAIL', true);
// Draft folder name (case doesn't matter)
define('IMAP_FOLDER_DRAFT', 'DRAFTS');
// Trash folder name (case doesn't matter)
define('IMAP_FOLDER_TRASH', 'TRASH');
// Spam folder name (case doesn't matter). Only showed as special by iOS devices
define('IMAP_FOLDER_SPAM', 'SPAM');
// Archive folder name (case doesn't matter). Only showed as special by iOS devices
define('IMAP_FOLDER_ARCHIVE', 'ARCHIVE');
// forward messages inline (default true - inlined)
define('IMAP_INLINE_FORWARD', true);
/* BEGIN fmbiete's contribution r1527, ZP-319 */
// list of folders we want to exclude from sync. Names, or part of it, separated by |
// example: dovecot.sieve|archive|spam
define('IMAP_EXCLUDED_FOLDERS', '');
/* END fmbiete's contribution r1527, ZP-319 */
// overwrite the "from" header with some value
// options:
// '' - do nothing, use the From header
// 'username' - the username will be set (usefull if your login is equal to your emailaddress)
// 'domain' - the value of the "domain" field is used
// 'sql' - the username will be the result of a sql query. REMEMBER TO INSTALL PHP-PDO AND PHP-DATABASE
// 'ldap' - the username will be the result of a ldap query. REMEMBER TO INSTALL PHP-LDAP!!
// '@mydomain.com' - the username is used and the given string will be appended
define('IMAP_DEFAULTFROM', '');
// DSN: formatted PDO connection string
// mysql:host=xxx;port=xxx;dbname=xxx
// USER: username to DB
// PASSWORD: password to DB
// OPTIONS: array with options needed
// QUERY: query to execute
// FIELDS: columns in the query
// FROM: string that will be the from, replacing the column names with the values
define('IMAP_FROM_SQL_DSN', '');
define('IMAP_FROM_SQL_USER', '');
define('IMAP_FROM_SQL_PASSWORD', '');
define('IMAP_FROM_SQL_OPTIONS', serialize(array(PDO::ATTR_PERSISTENT => true)));
define('IMAP_FROM_SQL_QUERY', "select first_name, last_name, mail_address from users where mail_address = '#username@#domain'");
define('IMAP_FROM_SQL_FIELDS', serialize(array('first_name', 'last_name', 'mail_address')));
define('IMAP_FROM_SQL_FROM', '#first_name #last_name <#mail_address>');
define('IMAP_FROM_SQL_FULLNAME', '#first_name #last_name');
// SERVER: ldap server
// SERVER_PORT: ldap port
// USER: dn to use for connecting
// PASSWORD: password
// QUERY: query to execute
// FIELDS: columns in the query
// FROM: string that will be the from, replacing the field names with the values
define('IMAP_FROM_LDAP_SERVER', 'localhost');
define('IMAP_FROM_LDAP_SERVER_PORT', '389');
define('IMAP_FROM_LDAP_USER', 'cn=zpush,ou=servers,dc=zpush,dc=org');
define('IMAP_FROM_LDAP_PASSWORD', 'password');
define('IMAP_FROM_LDAP_BASE', 'dc=zpush,dc=org');
define('IMAP_FROM_LDAP_QUERY', '(mail=#username@#domain)');
define('IMAP_FROM_LDAP_FIELDS', serialize(array('givenname', 'sn', 'mail')));
define('IMAP_FROM_LDAP_FROM', '#givenname #sn <#mail>');
define('IMAP_FROM_LDAP_FULLNAME', '#givenname #sn');
// Method used for sending mail
// mail => mail() php function
// sendmail => sendmail executable
// smtp => direct connection against SMTP
define('IMAP_SMTP_METHOD', 'mail');
global $imap_smtp_params;
// SMTP Parameters
// mail : no params
$imap_smtp_params = array();
// sendmail
//$imap_smtp_params = array('sendmail_path' => '/usr/bin/sendmail', 'sendmail_args' => '-i');
// smtp
// "host" - The server to connect. Default is localhost.
// "port" - The port to connect. Default is 25.
// "auth" - Whether or not to use SMTP authentication. Default is FALSE.
// "username" - The username to use for SMTP authentication. "imap_username" for using the same username as the imap server
// "password" - The password to use for SMTP authentication. "imap_password" for using the same password as the imap server
// "localhost" - The value to give when sending EHLO or HELO. Default is localhost
// "timeout" - The SMTP connection timeout. Default is NULL (no timeout).
// "verp" - Whether to use VERP or not. Default is FALSE.
// "debug" - Whether to enable SMTP debug mode or not. Default is FALSE.
// "persist" - Indicates whether or not the SMTP connection should persist over multiple calls to the send() method.
// "pipelining" - Indicates whether or not the SMTP commands pipelining should be used.
// "verify_peer" - Require verification of SSL certificate used. Default is TRUE.
// "verify_peer_name" - Require verification of peer name. Default is TRUE.
// "allow_self_signed" - Allow self-signed certificates. Requires verify_peer. Default is FALSE.
//$imap_smtp_params = array('host' => 'localhost', 'port' => 25, 'auth' => false);
// If you want to use SSL with port 25 or port 465 you must preppend "ssl://" before the hostname or IP of your SMTP server
// IMPORTANT: To use SSL you must use PHP 5.1 or later, install openssl libs and use ssl:// within the host variable
// IMPORTANT: To use SSL with PHP 5.6 you should set verify_peer, verify_peer_name and allow_self_signed
//$imap_smtp_params = array('host' => 'ssl://localhost', 'port' => 465, 'auth' => true, 'username' => 'imap_username', 'password' => 'imap_password');
// If you are using IMAP_SMTP_METHOD = mail or sendmail and your sent messages are not correctly displayed you can change this to "\n".
// BUT, it doesn't comply with RFC 2822 and will break if using smtp method
define('MAIL_MIMEPART_CRLF', "\r\n");
// A file containing file mime types->extension mappings.
// SELINUX users: make sure the file has a security context accesible by your apache/php-fpm process
define('SYSTEM_MIME_TYPES_MAPPING', '/etc/mime.types');
// Use BackendCalDAV for Meetings. You cannot hope to get that functionality working without a caldav backend.
define('IMAP_MEETING_USE_CALDAV', false);
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
<?php
/**
* Returns the default value for "From"
*
* @access private
* @return string
*/
function getDefaultFromValue($username, $domain) {
$v = "";
if (defined('IMAP_DEFAULTFROM')) {
switch (IMAP_DEFAULTFROM) {
case 'username':
$v = $username;
break;
case 'domain':
$v = $domain;
break;
case 'ldap':
$v = getIdentityFromLdap($username, $domain, IMAP_FROM_LDAP_FROM, true);
break;
case 'sql':
$v = getIdentityFromSql($username, $domain, IMAP_FROM_SQL_FROM, true);
break;
case 'passwd':
$v = getIdentityFromPasswd($username, $domain, 'FROM', true);
break;
default:
$v = $username . IMAP_DEFAULTFROM;
break;
}
}
return $v;
}
/**
* Return the default value for "FullName"
*
* @access private
* @param string $username Username
* @return string
*/
function getDefaultFullNameValue($username, $domain) {
$v = $username;
if (defined('IMAP_DEFAULTFROM')) {
switch (IMAP_DEFAULTFROM) {
case 'ldap':
$v = getIdentityFromSql($username, $domain, IMAP_FROM_LDAP_FULLNAME, false);
break;
case 'sql':
$v = getIdentityFromSql($username, $domain, IMAP_FROM_SQL_FULLNAME, false);
break;
case 'passwd':
$v = getIdentityFromPasswd($username, $domain, 'FULLNAME', false);
break;
}
}
return $v;
}
/**
* Generate the "From"/"FullName" value stored in a LDAP server
*
* @access private
* @params string $username username value
* @params string $domain domain value
* @params string $identity pattern to fill with ldap values
* @params boolean $encode if the result should be encoded as a header
* @return string
*/
function getIdentityFromLdap($username, $domain, $identity, $encode = true) {
$ret_value = $username;
$ldap_conn = null;
try {
$ldap_conn = ldap_connect(IMAP_FROM_LDAP_SERVER, IMAP_FROM_LDAP_SERVER_PORT);
if ($ldap_conn) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromLdap() - Connected to LDAP"));
ldap_set_option($ldap_conn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap_conn, LDAP_OPT_REFERRALS, 0);
$ldap_bind = ldap_bind($ldap_conn, IMAP_FROM_LDAP_USER, IMAP_FROM_LDAP_PASSWORD);
if ($ldap_bind) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromLdap() - Authenticated in LDAP"));
$filter = str_replace('#username', $username, str_replace('#domain', $domain, IMAP_FROM_LDAP_QUERY));
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromLdap() - Searching From with filter: %s", $filter));
$search = ldap_search($ldap_conn, IMAP_FROM_LDAP_BASE, $filter, unserialize(IMAP_FROM_LDAP_FIELDS));
$items = ldap_get_entries($ldap_conn, $search);
if ($items['count'] > 0) {
$ret_value = $identity;
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromLdap() - Found entry in LDAP. Generating From"));
// We get the first object. It's your responsability to make the query unique
foreach (unserialize(IMAP_FROM_LDAP_FIELDS) as $field) {
$ret_value = str_replace('#'.$field, $items[0][$field][0], $ret_value);
}
if ($encode) {
$ret_value = encodeFrom($ret_value);
}
}
else {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromLdap() - No entry found in LDAP"));
}
}
else {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromLdap() - Not authenticated in LDAP server"));
}
}
else {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromLdap() - Not connected to LDAP server"));
}
}
catch(Exception $ex) {
ZLog::Write(LOGLEVEL_WARN, sprintf("BackendIMAP->getIdentityFromLdap() - Error getting From value from LDAP server: %s", $ex));
}
if ($ldap_conn != null) {
ldap_close($ldap_conn);
}
return $ret_value;
}
/**
* Generate the "From" value stored in a SQL Database
*
* @access private
* @params string $username username value
* @params string $domain domain value
* @return string
*/
function getIdentityFromSql($username, $domain, $identity, $encode = true) {
$ret_value = $username;
$dbh = $sth = $record = null;
try {
$dbh = new PDO(IMAP_FROM_SQL_DSN, IMAP_FROM_SQL_USER, IMAP_FROM_SQL_PASSWORD, unserialize(IMAP_FROM_SQL_OPTIONS));
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromSql() - Connected to SQL Database"));
$sql = str_replace('#username', $username, str_replace('#domain', $domain, IMAP_FROM_SQL_QUERY));
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromSql() - Searching From with filter: %s", $sql));
$sth = $dbh->prepare($sql);
$sth->execute();
$record = $sth->fetch(PDO::FETCH_ASSOC);
if ($record) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromSql() - Found entry in SQL Database. Generating From"));
$ret_value = $identity;
foreach (unserialize(IMAP_FROM_SQL_FIELDS) as $field) {
$ret_value = str_replace('#'.$field, $record[$field], $ret_value);
}
if ($encode) {
$ret_value = encodeFrom($ret_value);
}
}
else {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromSql() - No entry found in SQL Database"));
}
}
catch(PDOException $ex) {
ZLog::Write(LOGLEVEL_WARN, sprintf("BackendIMAP->getIdentityFromSql() - Error getting From value from SQL Database: %s", $ex));
}
$dbh = $sth = $record = null;
return $ret_value;
}
/**
* Generate the "From" value from the local posix passwd database
*
* @access private
* @params string $username username value
* @params string $domain domain value
* @return string
*/
function getIdentityFromPasswd($username, $domain, $identity, $encode = true) {
$ret_value = $username;
try {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromPasswd() - Fetching info for user %s", $username));
$local_user = posix_getpwnam($username);
if ($local_user) {
$tmp = $local_user['gecos'];
$tmp = explode(',', $tmp);
$name = $tmp[0];
unset($tmp);
switch ($identity) {
case 'FROM':
if (strlen($domain) > 0) {
$ret_value = sprintf("%s <%s@%s>", $name, $username, $domain);
} else {
ZLog::Write(LOGLEVEL_WARN, sprintf("BackendIMAP->getIdentityFromPasswd() - No domain passed. Cannot construct From address."));
}
break;
case 'FULLNAME':
$ret_value = sprintf("%s", $name);
break;
}
if ($encode) {
$ret_value = encodeFrom($ret_value);
}
} else {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->getIdentityFromPasswd() - No entry found in Password database"));
}
}
catch(Exception $ex) {
ZLog::Write(LOGLEVEL_WARN, sprintf("BackendIMAP->getIdentityFromPasswd() - Error getting From value from passwd database: %s", $ex));
}
return $ret_value;
}
/**
* Encode the From value as Base64
*
* @access private
* @param string $from From value
* @return string
*/
function encodeFrom($from) {
$items = explode("<", $from);
$name = trim($items[0]);
return "=?UTF-8?B?" . base64_encode($name) . "?= <" . $items[1];
}
\ No newline at end of file
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id$
/**
* Client implementation of various SASL mechanisms
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
/**
* Z-Push changes
*
* removed PEAR dependency by implementing own raiseError()
*
* Reference implementation used:
* http://download.pear.php.net/package/Auth_SASL-1.0.6.tgz
*
*
*/
//require_once('PEAR.php');
class Auth_SASL
{
/**
* Factory class. Returns an object of the request
* type.
*
* @param string $type One of: Anonymous
* Plain
* CramMD5
* DigestMD5
* SCRAM-* (any mechanism of the SCRAM family)
* Types are not case sensitive
*/
function &factory($type)
{
switch (strtolower($type)) {
case 'anonymous':
$filename = 'include/Auth/SASL/Anonymous.php';
$classname = 'Auth_SASL_Anonymous';
break;
case 'login':
$filename = 'include/Auth/SASL/Login.php';
$classname = 'Auth_SASL_Login';
break;
case 'plain':
$filename = 'include/Auth/SASL/Plain.php';
$classname = 'Auth_SASL_Plain';
break;
case 'external':
$filename = 'include/Auth/SASL/External.php';
$classname = 'Auth_SASL_External';
break;
case 'crammd5':
// $msg = 'Deprecated mechanism name. Use IANA-registered name: CRAM-MD5.';
// trigger_error($msg, E_USER_DEPRECATED);
case 'cram-md5':
$filename = 'include/Auth/SASL/CramMD5.php';
$classname = 'Auth_SASL_CramMD5';
break;
case 'digestmd5':
// $msg = 'Deprecated mechanism name. Use IANA-registered name: DIGEST-MD5.';
// trigger_error($msg, E_USER_DEPRECATED);
case 'digest-md5':
// $msg = 'DIGEST-MD5 is a deprecated SASL mechanism as per RFC-6331. Using it could be a security risk.';
// trigger_error($msg, E_USER_NOTICE);
$filename = 'include/Auth/SASL/DigestMD5.php';
$classname = 'Auth_SASL_DigestMD5';
break;
default:
$scram = '/^SCRAM-(.{1,9})$/i';
if (preg_match($scram, $type, $matches))
{
$hash = $matches[1];
$filename = 'include/Auth/SASL/SCRAM.php';
$classname = 'Auth_SASL_SCRAM';
$parameter = $hash;
break;
}
return Auth_SASL::raiseError('Invalid SASL mechanism type');
break;
}
require_once($filename);
if (isset($parameter))
$obj = new $classname($parameter);
else
$obj = new $classname();
return $obj;
}
/**
* Z-Push helper for error logging
* removing PEAR dependency
*
* @param string debug message
* @return boolean always false as there was an error
* @access private
*/
static function raiseError($message) {
ZLog::Write(LOGLEVEL_ERROR, "Auth_SASL error: ". $message);
return false;
}
}
\ No newline at end of file
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id$
/**
* Implmentation of ANONYMOUS SASL mechanism
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
class Auth_SASL_Anonymous extends Auth_SASL_Common
{
/**
* Not much to do here except return the token supplied.
* No encoding, hashing or encryption takes place for this
* mechanism, simply one of:
* o An email address
* o An opaque string not containing "@" that can be interpreted
* by the sysadmin
* o Nothing
*
* We could have some logic here for the second option, but this
* would by no means create something interpretable.
*
* @param string $token Optional email address or string to provide
* as trace information.
* @return string The unaltered input token
*/
function getResponse($token = '')
{
return $token;
}
}
\ No newline at end of file
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id$
/**
* Common functionality to SASL mechanisms
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
/**
* Z-Push changes
*
* removed PEAR dependency by implementing own raiseError()
*
* Reference implementation used:
* http://download.pear.php.net/package/Auth_SASL-1.0.6.tgz
*
*
*/
class Auth_SASL_Common
{
/**
* Function which implements HMAC MD5 digest
*
* @param string $key The secret key
* @param string $data The data to hash
* @param bool $raw_output Whether the digest is returned in binary or hexadecimal format.
*
* @return string The HMAC-MD5 digest
*/
function _HMAC_MD5($key, $data, $raw_output = FALSE)
{
if (strlen($key) > 64) {
$key = pack('H32', md5($key));
}
if (strlen($key) < 64) {
$key = str_pad($key, 64, chr(0));
}
$k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64);
$k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64);
$inner = pack('H32', md5($k_ipad . $data));
$digest = md5($k_opad . $inner, $raw_output);
return $digest;
}
/**
* Function which implements HMAC-SHA-1 digest
*
* @param string $key The secret key
* @param string $data The data to hash
* @param bool $raw_output Whether the digest is returned in binary or hexadecimal format.
* @return string The HMAC-SHA-1 digest
* @author Jehan <jehan.marmottard@gmail.com>
* @access protected
*/
protected function _HMAC_SHA1($key, $data, $raw_output = FALSE)
{
if (strlen($key) > 64) {
$key = sha1($key, TRUE);
}
if (strlen($key) < 64) {
$key = str_pad($key, 64, chr(0));
}
$k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64);
$k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64);
$inner = pack('H40', sha1($k_ipad . $data));
$digest = sha1($k_opad . $inner, $raw_output);
return $digest;
}
/**
* Z-Push helper for error logging
* removing PEAR dependency
*
* @param string debug message
* @return boolean always false as there was an error
* @access private
*/
function raiseError($message) {
ZLog::Write(LOGLEVEL_ERROR, "SCRAM error: ". $message);
return false;
}
}
\ No newline at end of file
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id$
/**
* Implmentation of CRAM-MD5 SASL mechanism
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
class Auth_SASL_CramMD5 extends Auth_SASL_Common
{
/**
* Implements the CRAM-MD5 SASL mechanism
* This DOES NOT base64 encode the return value,
* you will need to do that yourself.
*
* @param string $user Username
* @param string $pass Password
* @param string $challenge The challenge supplied by the server.
* this should be already base64_decoded.
*
* @return string The string to pass back to the server, of the form
* "<user> <digest>". This is NOT base64_encoded.
*/
function getResponse($user, $pass, $challenge)
{
return $user . ' ' . $this->_HMAC_MD5($pass, $challenge);
}
}
\ No newline at end of file
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id$
/**
* Implmentation of DIGEST-MD5 SASL mechanism
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
class Auth_SASL_DigestMD5 extends Auth_SASL_Common
{
/**
* Provides the (main) client response for DIGEST-MD5
* requires a few extra parameters than the other
* mechanisms, which are unavoidable.
*
* @param string $authcid Authentication id (username)
* @param string $pass Password
* @param string $challenge The digest challenge sent by the server
* @param string $hostname The hostname of the machine you're connecting to
* @param string $service The servicename (eg. imap, pop, acap etc)
* @param string $authzid Authorization id (username to proxy as)
* @return string The digest response (NOT base64 encoded)
* @access public
*/
function getResponse($authcid, $pass, $challenge, $hostname, $service, $authzid = '')
{
$challenge = $this->_parseChallenge($challenge);
$authzid_string = '';
if ($authzid != '') {
$authzid_string = ',authzid="' . $authzid . '"';
}
if (!empty($challenge)) {
$cnonce = $this->_getCnonce();
$digest_uri = sprintf('%s/%s', $service, $hostname);
$response_value = $this->_getResponseValue($authcid, $pass, $challenge['realm'], $challenge['nonce'], $cnonce, $digest_uri, $authzid);
if ($challenge['realm']) {
return sprintf('username="%s",realm="%s"' . $authzid_string .
',nonce="%s",cnonce="%s",nc=00000001,qop=auth,digest-uri="%s",response=%s,maxbuf=%d', $authcid, $challenge['realm'], $challenge['nonce'], $cnonce, $digest_uri, $response_value, $challenge['maxbuf']);
} else {
return sprintf('username="%s"' . $authzid_string . ',nonce="%s",cnonce="%s",nc=00000001,qop=auth,digest-uri="%s",response=%s,maxbuf=%d', $authcid, $challenge['nonce'], $cnonce, $digest_uri, $response_value, $challenge['maxbuf']);
}
} else {
return $this->raiseError('Invalid digest challenge');
}
}
/**
* Parses and verifies the digest challenge*
*
* @param string $challenge The digest challenge
* @return array The parsed challenge as an assoc
* array in the form "directive => value".
* @access private
*/
function _parseChallenge($challenge)
{
$tokens = array();
while (preg_match('/^([a-z-]+)=("[^"]+(?<!\\\)"|[^,]+)/i', $challenge, $matches)) {
// Ignore these as per rfc2831
if ($matches[1] == 'opaque' OR $matches[1] == 'domain') {
$challenge = substr($challenge, strlen($matches[0]) + 1);
continue;
}
// Allowed multiple "realm" and "auth-param"
if (!empty($tokens[$matches[1]]) AND ($matches[1] == 'realm' OR $matches[1] == 'auth-param')) {
if (is_array($tokens[$matches[1]])) {
$tokens[$matches[1]][] = preg_replace('/^"(.*)"$/', '\\1', $matches[2]);
} else {
$tokens[$matches[1]] = array($tokens[$matches[1]], preg_replace('/^"(.*)"$/', '\\1', $matches[2]));
}
// Any other multiple instance = failure
} elseif (!empty($tokens[$matches[1]])) {
$tokens = array();
break;
} else {
$tokens[$matches[1]] = preg_replace('/^"(.*)"$/', '\\1', $matches[2]);
}
// Remove the just parsed directive from the challenge
$challenge = substr($challenge, strlen($matches[0]) + 1);
}
/**
* Defaults and required directives
*/
// Realm
if (empty($tokens['realm'])) {
$tokens['realm'] = "";
}
// Maxbuf
if (empty($tokens['maxbuf'])) {
$tokens['maxbuf'] = 65536;
}
// Required: nonce, algorithm
if (empty($tokens['nonce']) OR empty($tokens['algorithm'])) {
return array();
}
return $tokens;
}
/**
* Creates the response= part of the digest response
*
* @param string $authcid Authentication id (username)
* @param string $pass Password
* @param string $realm Realm as provided by the server
* @param string $nonce Nonce as provided by the server
* @param string $cnonce Client nonce
* @param string $digest_uri The digest-uri= value part of the response
* @param string $authzid Authorization id
* @return string The response= part of the digest response
* @access private
*/
function _getResponseValue($authcid, $pass, $realm, $nonce, $cnonce, $digest_uri, $authzid = '')
{
if ($authzid == '') {
$A1 = sprintf('%s:%s:%s', pack('H32', md5(sprintf('%s:%s:%s', $authcid, $realm, $pass))), $nonce, $cnonce);
} else {
$A1 = sprintf('%s:%s:%s:%s', pack('H32', md5(sprintf('%s:%s:%s', $authcid, $realm, $pass))), $nonce, $cnonce, $authzid);
}
$A2 = 'AUTHENTICATE:' . $digest_uri;
return md5(sprintf('%s:%s:00000001:%s:auth:%s', md5($A1), $nonce, $cnonce, md5($A2)));
}
/**
* Creates the client nonce for the response
*
* @return string The cnonce value
* @access private
*/
function _getCnonce()
{
if (@file_exists('/dev/urandom') && $fd = @fopen('/dev/urandom', 'r')) {
return base64_encode(fread($fd, 32));
} elseif (@file_exists('/dev/random') && $fd = @fopen('/dev/random', 'r')) {
return base64_encode(fread($fd, 32));
} else {
$str = '';
for ($i=0; $i<32; $i++) {
$str .= chr(mt_rand(0, 255));
}
return base64_encode($str);
}
}
}
\ No newline at end of file
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2008 Christoph Schulz |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Christoph Schulz <develop@kristov.de> |
// +-----------------------------------------------------------------------+
//
// $Id$
/**
* Implmentation of EXTERNAL SASL mechanism
*
* @author Christoph Schulz <develop@kristov.de>
* @access public
* @version 1.0.3
* @package Auth_SASL
*/
class Auth_SASL_External extends Auth_SASL_Common
{
/**
* Returns EXTERNAL response
*
* @param string $authcid Authentication id (username)
* @param string $pass Password
* @param string $authzid Autorization id
* @return string EXTERNAL Response
*/
function getResponse($authcid, $pass, $authzid = '')
{
return $authzid;
}
}
\ No newline at end of file
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id$
/**
* This is technically not a SASL mechanism, however
* it's used by Net_Sieve, Net_Cyrus and potentially
* other protocols , so here is a good place to abstract
* it.
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
class Auth_SASL_Login extends Auth_SASL_Common
{
/**
* Pseudo SASL LOGIN mechanism
*
* @param string $user Username
* @param string $pass Password
* @return string LOGIN string
*/
function getResponse($user, $pass)
{
return sprintf('LOGIN %s %s', $user, $pass);
}
}
\ No newline at end of file
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@php.net> |
// +-----------------------------------------------------------------------+
//
// $Id$
/**
* Implmentation of PLAIN SASL mechanism
*
* @author Richard Heyes <richard@php.net>
* @access public
* @version 1.0
* @package Auth_SASL
*/
class Auth_SASL_Plain extends Auth_SASL_Common
{
/**
* Returns PLAIN response
*
* @param string $authcid Authentication id (username)
* @param string $pass Password
* @param string $authzid Autorization id
* @return string PLAIN Response
*/
function getResponse($authcid, $pass, $authzid = '')
{
return $authzid . chr(0) . $authcid . chr(0) . $pass;
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
<?php
/**
* internal PHP-mail() implementation of the PEAR Mail:: interface.
*
* PHP versions 4 and 5
*
* LICENSE:
*
* Copyright (c) 2010 Chuck Hagenbuch
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* o Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* o Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* o The names of the authors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category Mail
* @package Mail
* @author Chuck Hagenbuch <chuck@horde.org>
* @copyright 2010 Chuck Hagenbuch
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version CVS: $Id: mail.php 294747 2010-02-08 08:18:33Z clockwerx $
* @link http://pear.php.net/package/Mail/
*/
/**
* Z-Push changes
*
* removed PEAR dependency by implementing own raiseError()
*
* Reference implementation used:
* http://download.pear.php.net/package/Mail-1.2.0.tgz
*
*
*/
/**
* internal PHP-mail() implementation of the PEAR Mail:: interface.
* @package Mail
* @version $Revision: 294747 $
*/
class Mail_mail extends Mail {
/**
* Any arguments to pass to the mail() function.
* @var string
*/
var $_params = '';
/**
* Constructor.
*
* Instantiates a new Mail_mail:: object based on the parameters
* passed in.
*
* @param array $params Extra arguments for the mail() function.
*/
function Mail_mail($params = null)
{
// The other mail implementations accept parameters as arrays.
// In the interest of being consistent, explode an array into
// a string of parameter arguments.
if (is_array($params)) {
$this->_params = join(' ', $params);
} else {
$this->_params = $params;
}
/* Because the mail() function may pass headers as command
* line arguments, we can't guarantee the use of the standard
* "\r\n" separator. Instead, we use the system's native line
* separator. */
if (defined('PHP_EOL')) {
$this->sep = PHP_EOL;
} else {
$this->sep = (strpos(PHP_OS, 'WIN') === false) ? "\n" : "\r\n";
}
}
/**
* Implements Mail_mail::send() function using php's built-in mail()
* command.
*
* @param mixed $recipients Either a comma-seperated list of recipients
* (RFC822 compliant), or an array of recipients,
* each RFC822 valid. This may contain recipients not
* specified in the headers, for Bcc:, resending
* messages, etc.
*
* @param array $headers The array of headers to send with the mail, in an
* associative array, where the array key is the
* header name (ie, 'Subject'), and the array value
* is the header value (ie, 'test'). The header
* produced from those values would be 'Subject:
* test'.
*
* @param string $body The full text of the message body, including any
* Mime parts, etc.
*
* @return mixed Returns true on success, or a PEAR_Error
* containing a descriptive error message on
* failure.
*
* @access public
*/
function send($recipients, $headers, $body)
{
if (!is_array($headers)) {
return Mail_mail::raiseError('$headers must be an array');
}
$result = $this->_sanitizeHeaders($headers);
//if (is_a($result, 'PEAR_Error')) {
if ($result === false) {
return $result;
}
// If we're passed an array of recipients, implode it.
if (is_array($recipients)) {
$recipients = implode(', ', $recipients);
}
// Get the Subject out of the headers array so that we can
// pass it as a seperate argument to mail().
$subject = '';
if (isset($headers['Subject'])) {
$subject = $headers['Subject'];
unset($headers['Subject']);
}
// Also remove the To: header. The mail() function will add its own
// To: header based on the contents of $recipients.
unset($headers['To']);
// Flatten the headers out.
$headerElements = $this->prepareHeaders($headers);
//if (is_a($headerElements, 'PEAR_Error')) {
if ($headerElements === false) {
return $headerElements;
}
list(, $text_headers) = $headerElements;
// We only use mail()'s optional fifth parameter if the additional
// parameters have been provided and we're not running in safe mode.
if (empty($this->_params) || ini_get('safe_mode')) {
$result = mail($recipients, $subject, $body, $text_headers);
} else {
$result = mail($recipients, $subject, $body, $text_headers,
$this->_params);
}
// If the mail() function returned failure, we need to create a
// PEAR_Error object and return it instead of the boolean result.
if ($result === false) {
$result = Mail_mail::raiseError('mail() returned failure');
}
return $result;
}
/**
* Z-Push helper for error logging
* removing PEAR dependency
*
* @param string debug message
* @return boolean always false as there was an error
* @access private
*/
static function raiseError($message) {
ZLog::Write(LOGLEVEL_ERROR, "Mail<mail> error: ". $message);
return false;
}
}
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Chuck Hagenbuch <chuck@horde.org> |
// +----------------------------------------------------------------------+
/**
* Z-Push changes
*
* removed PEAR dependency by implementing own raiseError()
*
* Reference implementation used:
* http://download.pear.php.net/package/Mail-1.2.0.tgz
*
*
*/
/**
* Sendmail implementation of the PEAR Mail:: interface.
* @access public
* @package Mail
* @version $Revision: 294744 $
*/
class Mail_sendmail extends Mail {
/**
* The location of the sendmail or sendmail wrapper binary on the
* filesystem.
* @var string
*/
var $sendmail_path = '/usr/sbin/sendmail';
/**
* Any extra command-line parameters to pass to the sendmail or
* sendmail wrapper binary.
* @var string
*/
var $sendmail_args = '-i';
/**
* Constructor.
*
* Instantiates a new Mail_sendmail:: object based on the parameters
* passed in. It looks for the following parameters:
* sendmail_path The location of the sendmail binary on the
* filesystem. Defaults to '/usr/sbin/sendmail'.
*
* sendmail_args Any extra parameters to pass to the sendmail
* or sendmail wrapper binary.
*
* If a parameter is present in the $params array, it replaces the
* default.
*
* @param array $params Hash containing any parameters different from the
* defaults.
* @access public
*/
function Mail_sendmail($params)
{
if (isset($params['sendmail_path'])) {
$this->sendmail_path = $params['sendmail_path'];
}
if (isset($params['sendmail_args'])) {
$this->sendmail_args = $params['sendmail_args'];
}
/*
* Because we need to pass message headers to the sendmail program on
* the commandline, we can't guarantee the use of the standard "\r\n"
* separator. Instead, we use the system's native line separator.
*/
if (defined('PHP_EOL')) {
$this->sep = PHP_EOL;
} else {
$this->sep = (strpos(PHP_OS, 'WIN') === false) ? "\n" : "\r\n";
}
}
/**
* Implements Mail::send() function using the sendmail
* command-line binary.
*
* @param mixed $recipients Either a comma-seperated list of recipients
* (RFC822 compliant), or an array of recipients,
* each RFC822 valid. This may contain recipients not
* specified in the headers, for Bcc:, resending
* messages, etc.
*
* @param array $headers The array of headers to send with the mail, in an
* associative array, where the array key is the
* header name (ie, 'Subject'), and the array value
* is the header value (ie, 'test'). The header
* produced from those values would be 'Subject:
* test'.
*
* @param string $body The full text of the message body, including any
* Mime parts, etc.
*
* @return mixed Returns true on success, or a PEAR_Error
* containing a descriptive error message on
* failure.
* @access public
*/
function send($recipients, $headers, $body)
{
if (!is_array($headers)) {
return Mail_sendmail::raiseError('$headers must be an array');
}
$result = $this->_sanitizeHeaders($headers);
//if (is_a($result, 'PEAR_Error')) {
if ($result === false) {
return $result;
}
$recipients = $this->parseRecipients($recipients);
//if (is_a($recipients, 'PEAR_Error')) {
if ($recipients === false) {
return $recipients;
}
$recipients = implode(' ', array_map('escapeshellarg', $recipients));
$headerElements = $this->prepareHeaders($headers);
//if (is_a($headerElements, 'PEAR_Error')) {
if ($headerElements === false) {
return $headerElements;
}
list($from, $text_headers) = $headerElements;
/* Since few MTAs are going to allow this header to be forged
* unless it's in the MAIL FROM: exchange, we'll use
* Return-Path instead of From: if it's set. */
if (!empty($headers['Return-Path'])) {
$from = $headers['Return-Path'];
}
if (!isset($from)) {
return Mail_sendmail::raiseError('No from address given.');
} elseif (strpos($from, ' ') !== false ||
strpos($from, ';') !== false ||
strpos($from, '&') !== false ||
strpos($from, '`') !== false) {
return Mail_sendmail::raiseError('From address specified with dangerous characters.');
}
$from = escapeshellarg($from); // Security bug #16200
$mail = @popen($this->sendmail_path . (!empty($this->sendmail_args) ? ' ' . $this->sendmail_args : '') . " -f$from -- $recipients", 'w');
if (!$mail) {
return Mail_sendmail::raiseError('Failed to open sendmail [' . $this->sendmail_path . '] for execution.');
}
// Write the headers following by two newlines: one to end the headers
// section and a second to separate the headers block from the body.
fputs($mail, $text_headers . $this->sep . $this->sep);
fputs($mail, $body);
$result = pclose($mail);
if (version_compare(phpversion(), '4.2.3') == -1) {
// With older php versions, we need to shift the pclose
// result to get the exit code.
$result = $result >> 8 & 0xFF;
}
if ($result != 0) {
return Mail_sendmail::raiseError('sendmail returned error code ' . $result,
$result);
}
return true;
}
/**
* Z-Push helper for error logging
* removing PEAR dependency
*
* @param string debug message
* @return boolean always false as there was an error
* @access private
*/
static function raiseError($message) {
ZLog::Write(LOGLEVEL_ERROR, "Mail<sendmail> error: ". $message);
return false;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -7,6 +7,15 @@ $baseDir = dirname($vendorDir);
return array(
'ASDevice' => $baseDir . '/lib/core/asdevice.php',
'Auth_SASL' => $baseDir . '/include/Auth/SASL.php',
'Auth_SASL_Anonymous' => $baseDir . '/include/Auth/SASL/Anonymous.php',
'Auth_SASL_Common' => $baseDir . '/include/Auth/SASL/Common.php',
'Auth_SASL_CramMD5' => $baseDir . '/include/Auth/SASL/CramMD5.php',
'Auth_SASL_DigestMD5' => $baseDir . '/include/Auth/SASL/DigestMD5.php',
'Auth_SASL_External' => $baseDir . '/include/Auth/SASL/External.php',
'Auth_SASL_Login' => $baseDir . '/include/Auth/SASL/Login.php',
'Auth_SASL_Plain' => $baseDir . '/include/Auth/SASL/Plain.php',
'Auth_SASL_SCRAM' => $baseDir . '/include/Auth/SASL/SCRAM.php',
'AuthenticationRequiredException' => $baseDir . '/lib/exceptions/authenticationrequiredexception.php',
'Backend' => $baseDir . '/lib/default/backend.php',
'BackendDiff' => $baseDir . '/lib/default/diffbackend/diffbackend.php',
......@@ -42,10 +51,17 @@ return array(
'ItemOperations' => $baseDir . '/lib/request/itemoperations.php',
'Log' => $baseDir . '/lib/log/log.php',
'LoopDetection' => $baseDir . '/lib/core/loopdetection.php',
'Mail' => $baseDir . '/include/Mail.php',
'Mail_RFC822' => $baseDir . '/include/z_RFC822.php',
'Mail_mail' => $baseDir . '/include/Mail/mail.php',
'Mail_mimeDecode' => $baseDir . '/include/mimeDecode.php',
'Mail_mimePart' => $baseDir . '/include/mimePart.php',
'Mail_sendmail' => $baseDir . '/include/Mail/sendmail.php',
'Mail_smtp' => $baseDir . '/include/Mail/smtp.php',
'MeetingResponse' => $baseDir . '/lib/request/meetingresponse.php',
'MoveItems' => $baseDir . '/lib/request/moveitems.php',
'Net_SMTP' => $baseDir . '/include/Net/SMTP.php',
'Net_Socket' => $baseDir . '/include/Net/Socket.php',
'NoHierarchyCacheAvailableException' => $baseDir . '/lib/exceptions/nohierarchycacheavailableexception.php',
'NoPostRequestException' => $baseDir . '/lib/exceptions/nopostrequestexception.php',
'NotImplementedException' => $baseDir . '/lib/exceptions/notimplementedexception.php',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment