Add fake pop server and POP-before-SMTP tests.
Update POP before SMTP example to use new static method.
This commit is contained in:
parent
3374536cac
commit
73093a32a3
|
|
@ -35,6 +35,10 @@
|
|||
* Introduce autoloader
|
||||
* Allow overriding of SMTP class
|
||||
* Overhaul of PHPDocs
|
||||
* Fix broken Q-encoding
|
||||
* Czech language update (Thanks to @nemelu)
|
||||
* Removal of excess blank lines in messages
|
||||
* Added fake POP server and unit tests for POP-before-SMTP
|
||||
|
||||
## Version 5.2.6 (April 11th 2013)
|
||||
* Reflect move to PHPMailer GitHub organisation at https://github.com/PHPMailer/PHPMailer
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ class POP3
|
|||
* POP3 Carriage Return + Line Feed.
|
||||
* @type string
|
||||
* @access public
|
||||
* @deprecated Use the constant instead
|
||||
*/
|
||||
public $CRLF = "\r\n";
|
||||
|
||||
|
|
@ -123,10 +124,14 @@ class POP3
|
|||
*/
|
||||
private $error;
|
||||
|
||||
/**
|
||||
* Line break constant
|
||||
*/
|
||||
const CRLF = "\r\n";
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @access public
|
||||
* @access private
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -135,6 +140,21 @@ class POP3
|
|||
$this->error = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple static wrapper for all-in-one POP before SMTP
|
||||
* @param $host
|
||||
* @param bool $port
|
||||
* @param bool $tval
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return bool
|
||||
*/
|
||||
public static function popBeforeSmtp($host, $port = false, $tval = false, $username = '', $password = '')
|
||||
{
|
||||
$pop = new POP3;
|
||||
return $pop->authorise($host, $port, $tval, $username, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate with a POP3 server.
|
||||
* A connect, login, disconnect sequence
|
||||
|
|
@ -151,14 +171,14 @@ class POP3
|
|||
public function authorise($host, $port = false, $tval = false, $username = '', $password = '', $debug_level = 0)
|
||||
{
|
||||
$this->host = $host;
|
||||
// If no port value is passed, retrieve it
|
||||
if ($port == false) {
|
||||
// If no port value provided, use default
|
||||
if ($port === false) {
|
||||
$this->port = $this->POP3_PORT;
|
||||
} else {
|
||||
$this->port = $port;
|
||||
}
|
||||
// If no port value is passed, retrieve it
|
||||
if ($tval == false) {
|
||||
// If no timeout value provided, use default
|
||||
if ($tval === false) {
|
||||
$this->tval = $this->POP3_TIMEOUT;
|
||||
} else {
|
||||
$this->tval = $tval;
|
||||
|
|
@ -177,7 +197,7 @@ class POP3
|
|||
return true;
|
||||
}
|
||||
}
|
||||
// We need to disconnect regardless if the login succeeded
|
||||
// We need to disconnect regardless of whether the login succeeded
|
||||
$this->disconnect();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -274,14 +294,13 @@ class POP3
|
|||
if (empty($password)) {
|
||||
$password = $this->password;
|
||||
}
|
||||
$pop_username = "USER $username" . $this->CRLF;
|
||||
$pop_password = "PASS $password" . $this->CRLF;
|
||||
// send the Username
|
||||
$this->sendString($pop_username);
|
||||
|
||||
// Send the Username
|
||||
$this->sendString("USER $username" . self::CRLF);
|
||||
$pop3_response = $this->getResponse();
|
||||
if ($this->checkResponse($pop3_response)) {
|
||||
// send the Password
|
||||
$this->sendString($pop_password);
|
||||
// Send the Password
|
||||
$this->sendString("PASS $password" . self::CRLF);
|
||||
$pop3_response = $this->getResponse();
|
||||
if ($this->checkResponse($pop3_response)) {
|
||||
return true;
|
||||
|
|
@ -297,7 +316,9 @@ class POP3
|
|||
public function disconnect()
|
||||
{
|
||||
$this->sendString('QUIT');
|
||||
fclose($this->pop_conn);
|
||||
//The QUIT command may cause the daemon to exit, which will kill our connection
|
||||
//So ignore errors here
|
||||
@fclose($this->pop_conn);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -309,8 +330,7 @@ class POP3
|
|||
*/
|
||||
private function getResponse($size = 128)
|
||||
{
|
||||
$pop3_response = fgets($this->pop_conn, $size);
|
||||
return $pop3_response;
|
||||
return fgets($this->pop_conn, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -321,8 +341,10 @@ class POP3
|
|||
*/
|
||||
private function sendString($string)
|
||||
{
|
||||
$bytes_sent = fwrite($this->pop_conn, $string, strlen($string));
|
||||
return $bytes_sent;
|
||||
if ($this->pop_conn) {
|
||||
return fwrite($this->pop_conn, $string, strlen($string));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -8,12 +8,10 @@
|
|||
<?php
|
||||
require '../PHPMailerAutoload.php';
|
||||
|
||||
//Create a new POP client instance
|
||||
$pop = new POP3();
|
||||
//authenticate via POP
|
||||
$pop->authorise('pop3.yourdomain.com', 110, 30, 'username', 'password', 1);
|
||||
//Authenticate via POP3
|
||||
//Now you should be clear to submit messages over SMTP for a while
|
||||
//Only applies if your host supports POP-before-SMTP
|
||||
$pop = POP3::popBeforeSmtp('pop3.example.com', 110, 30, 'username', 'password', 1);
|
||||
|
||||
//Create a new PHPMailer instance
|
||||
//Passing true to the constructor enables the use of exceptions for error handling
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Fake POP3 server
|
||||
# By Marcus Bointon <phpmailer@synchromedia.co.uk>
|
||||
# Based on code by 'Frater' found at http://www.linuxquestions.org/questions/programming-9/fake-pop3-server-to-capture-pop3-passwords-933733
|
||||
# Does not actually serve any mail, but supports commands sufficient to test POP-before SMTP
|
||||
# Can be run directly from a shell like this:
|
||||
# mkfifo fifo; nc -l 1100 <fifo |./fakepopserver.sh >fifo; rm fifo
|
||||
# It will accept any user name and will return a positive response for the password 'test'
|
||||
|
||||
# Licensed under the GNU Lesser General Public License: http://www.gnu.org/copyleft/lesser.html
|
||||
|
||||
# Enable debug output
|
||||
#set -xv
|
||||
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
|
||||
|
||||
LOGFOLDER=/tmp
|
||||
|
||||
LOGFILE=${LOGFOLDER}/fakepop.log
|
||||
|
||||
LOGGING=1
|
||||
DEBUG=1
|
||||
TIMEOUT=10
|
||||
|
||||
POP_USER=
|
||||
POP_PASSWRD=test
|
||||
|
||||
LINES=1
|
||||
BREAK=0
|
||||
|
||||
write_log () {
|
||||
if [ ${LINES} -eq 1 ] ; then
|
||||
echo '---' >>${LOGFILE}
|
||||
fi
|
||||
let LINES+=1
|
||||
[ ${LOGGING} = 0 ] || echo -e "`date '+%b %d %H:%M'` pop3 $*" >>${LOGFILE}
|
||||
}
|
||||
|
||||
ANSWER="+OK Fake POP3 Service Ready"
|
||||
|
||||
while [ ${BREAK} -eq 0 ] ; do
|
||||
echo -en "${ANSWER}\r\n"
|
||||
|
||||
REPLY=""
|
||||
|
||||
#Input appears in $REPLY
|
||||
read -t ${TIMEOUT}
|
||||
|
||||
ANSWER="+OK "
|
||||
COMMAND=""
|
||||
ARGS=""
|
||||
TIMEOUT=30
|
||||
|
||||
if [ "$REPLY" ] ; then
|
||||
write_log "RAW input: '`echo "${REPLY}" | tr -cd '[ -~]'`'"
|
||||
|
||||
COMMAND="`echo "${REPLY}" | awk '{print $1}' | tr -cd '\40-\176' | tr 'a-z' 'A-Z'`"
|
||||
ARGS="`echo "${REPLY}" | tr -cd '\40-\176' | awk '{for(i=2;i<=NF;i++){printf "%s ", $i};printf "\n"}' | sed 's/ $//'`"
|
||||
|
||||
write_log "Command: \"${COMMAND}\""
|
||||
write_log "Arguments: \"${ARGS}\""
|
||||
|
||||
case "$COMMAND" in
|
||||
QUIT)
|
||||
break
|
||||
;;
|
||||
USER)
|
||||
if [ -n "${ARGS}" ] ; then
|
||||
POP_USER="${ARGS}"
|
||||
ANSWER="+OK Please send PASS command"
|
||||
fi
|
||||
;;
|
||||
AUTH)
|
||||
ANSWER="+OK \r\n."
|
||||
;;
|
||||
CAPA)
|
||||
ANSWER="+OK Capabilities include\r\nUSER\r\nCAPA\r\n."
|
||||
;;
|
||||
PASS)
|
||||
if [ "${POP_PASSWRD}" == "${ARGS}" ] ; then
|
||||
ANSWER="+OK Logged in.\r\n"
|
||||
AUTH=1
|
||||
else
|
||||
ANSWER="-ERR Login failed\r\n"
|
||||
fi
|
||||
;;
|
||||
LIST)
|
||||
if [ "${AUTH}" = 0 ] ; then
|
||||
ANSWER="-ERR Not authenticated"
|
||||
else
|
||||
if [ -z "${ARGS}" ] ; then
|
||||
ANSWER="+OK No messages, really\r\n."
|
||||
else
|
||||
ANSWER="-ERR No messages, no list, no status"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
RSET)
|
||||
ANSWER="+OK Resetting or whatever\r\n."
|
||||
;;
|
||||
LAST)
|
||||
if [ "${AUTH}" = 0 ] ; then
|
||||
ANSWER="-ERR Not authenticated"
|
||||
else
|
||||
ANSWER="+OK 0"
|
||||
fi
|
||||
;;
|
||||
STAT)
|
||||
if [ "${AUTH}" = 0 ] ; then
|
||||
ANSWER="-ERR Not authenticated"
|
||||
else
|
||||
ANSWER="+OK 0 0"
|
||||
fi
|
||||
;;
|
||||
NOOP)
|
||||
ANSWER="+OK Hang on, doing nothing"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo "+OK Connection timed out\r\n"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
echo "+OK Bye!\r\n"
|
||||
|
|
@ -58,6 +58,13 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase
|
|||
*/
|
||||
public $INCLUDE_DIR = '../';
|
||||
|
||||
/**
|
||||
* PIDs of any processes we need to kill
|
||||
* @type array
|
||||
* @access private
|
||||
*/
|
||||
private $pids = array();
|
||||
|
||||
/**
|
||||
* Run before each test is started.
|
||||
*/
|
||||
|
|
@ -121,6 +128,11 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase
|
|||
$this->Mail = null;
|
||||
$this->ChangeLog = array();
|
||||
$this->NoteLog = array();
|
||||
|
||||
foreach ($this->pids as $pid) {
|
||||
$p = escapeshellarg($pid);
|
||||
shell_exec("ps $p && kill -TERM $p");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1136,7 +1148,7 @@ EOT;
|
|||
}
|
||||
|
||||
/**
|
||||
* Encoding tests
|
||||
* Encoding and charset tests
|
||||
*/
|
||||
public function testEncodings()
|
||||
{
|
||||
|
|
@ -1170,6 +1182,13 @@ EOT;
|
|||
);
|
||||
}
|
||||
|
||||
public function testBase64()
|
||||
{
|
||||
$this->Mail->Subject .= ': Base-64 encoding';
|
||||
$this->Mail->Encoding = 'base64';
|
||||
$this->buildBody();
|
||||
$this->assertTrue($this->Mail->send(), 'Base64 encoding failed');
|
||||
}
|
||||
/**
|
||||
* S/MIME Signing tests
|
||||
*/
|
||||
|
|
@ -1259,6 +1278,34 @@ EOT;
|
|||
$this->assertEquals($target, PHPMailer::normalizeBreaks($mixedsrc), 'Mixed break reformatting failed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a fake POP3 server to test POP-before-SMTP auth
|
||||
*/
|
||||
public function testPopBeforeSmtp()
|
||||
{
|
||||
//Start a fake POP server
|
||||
$pid = shell_exec('nohup ./runfakepopserver.sh >/dev/null 2>/dev/null & printf "%u" $!');
|
||||
$this->pids[] = $pid;
|
||||
|
||||
//Test a known-good login
|
||||
$this->assertTrue(
|
||||
POP3::popBeforeSmtp('localhost', 1100, 10, 'user', 'test'),
|
||||
'POP before SMTP failed'
|
||||
);
|
||||
//Kill the fake server
|
||||
shell_exec('kill -TERM '.escapeshellarg($pid));
|
||||
|
||||
$pid = shell_exec('nohup ./runfakepopserver.sh >/dev/null 2>/dev/null & printf "%u" $!');
|
||||
$this->pids[] = $pid;
|
||||
|
||||
//Test a known-bad login
|
||||
$this->assertFalse(
|
||||
POP3::popBeforeSmtp('localhost', 1100, 10, 'user', 'xxx'),
|
||||
'POP before SMTP should have failed'
|
||||
);
|
||||
shell_exec('kill -TERM '.escapeshellarg($pid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Miscellaneous calls to improve test coverage and some small tests
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Run the fake pop server from bash
|
||||
# Idea from http://blog.ale-re.net/2007/09/ipersimple-remote-shell-with-netcat.html
|
||||
# Defaults to port 1100 so it can be run by unpriv users and not clash with a real server
|
||||
|
||||
mkfifo fifo
|
||||
nc -l 1100 <fifo |bash ./fakepopserver.sh >fifo
|
||||
rm fifo
|
||||
Loading…
Reference in New Issue