These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * PHPMailer POP-Before-SMTP Authentication Class. |
||
4 | * PHP Version 5.5 |
||
5 | * |
||
6 | * @package PHPMailer |
||
7 | * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project |
||
8 | * @author Marcus Bointon (Synchro/coolbru) <[email protected]> |
||
9 | * @author Jim Jagielski (jimjag) <[email protected]> |
||
10 | * @author Andy Prevost (codeworxtech) <[email protected]> |
||
11 | * @author Brent R. Matzelle (original founder) |
||
12 | * @copyright 2012 - 2016 Marcus Bointon |
||
13 | * @copyright 2010 - 2012 Jim Jagielski |
||
14 | * @copyright 2004 - 2009 Andy Prevost |
||
15 | * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License |
||
16 | * @note This program is distributed in the hope that it will be useful - WITHOUT |
||
17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
||
18 | * FITNESS FOR A PARTICULAR PURPOSE. |
||
19 | */ |
||
20 | |||
21 | namespace PHPMailer\PHPMailer; |
||
22 | |||
23 | /** |
||
24 | * PHPMailer POP-Before-SMTP Authentication Class. |
||
25 | * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication. |
||
26 | * 1) This class does not support APOP authentication. |
||
27 | * 2) Opening and closing lots of POP3 connections can be quite slow. If you need |
||
28 | * to send a batch of emails then just perform the authentication once at the start, |
||
29 | * and then loop through your mail sending script. Providing this process doesn't |
||
30 | * take longer than the verification period lasts on your POP3 server, you should be fine. |
||
31 | * 3) This is really ancient technology; you should only need to use it to talk to very old systems. |
||
32 | * 4) This POP3 class is deliberately lightweight and incomplete, and implements just |
||
33 | * enough to do authentication. |
||
34 | * If you want a more complete class there are other POP3 classes for PHP available. |
||
35 | * |
||
36 | * @package PHPMailer |
||
37 | * @author Richard Davey (original author) <[email protected]> |
||
38 | * @author Marcus Bointon (Synchro/coolbru) <[email protected]> |
||
39 | * @author Jim Jagielski (jimjag) <[email protected]> |
||
40 | * @author Andy Prevost (codeworxtech) <[email protected]> |
||
41 | */ |
||
42 | class POP3 |
||
43 | { |
||
44 | /** |
||
45 | * The POP3 PHPMailer Version number. |
||
46 | * |
||
47 | * @var string |
||
48 | */ |
||
49 | const VERSION = '6.0.0'; |
||
50 | |||
51 | /** |
||
52 | * Default POP3 port number. |
||
53 | * |
||
54 | * @var integer |
||
55 | */ |
||
56 | const DEFAULT_PORT = 110; |
||
57 | |||
58 | /** |
||
59 | * Default timeout in seconds. |
||
60 | * |
||
61 | * @var integer |
||
62 | */ |
||
63 | const DEFAULT_TIMEOUT = 30; |
||
64 | |||
65 | /** |
||
66 | * Debug display level. |
||
67 | * Options: 0 = no, 1+ = yes |
||
68 | * |
||
69 | * @var integer |
||
70 | */ |
||
71 | public $do_debug = 0; |
||
72 | |||
73 | /** |
||
74 | * POP3 mail server hostname. |
||
75 | * |
||
76 | * @var string |
||
77 | */ |
||
78 | public $host; |
||
79 | |||
80 | /** |
||
81 | * POP3 port number. |
||
82 | * |
||
83 | * @var integer |
||
84 | */ |
||
85 | public $port; |
||
86 | |||
87 | /** |
||
88 | * POP3 Timeout Value in seconds. |
||
89 | * |
||
90 | * @var integer |
||
91 | */ |
||
92 | public $tval; |
||
93 | |||
94 | /** |
||
95 | * POP3 username |
||
96 | * |
||
97 | * @var string |
||
98 | */ |
||
99 | public $username; |
||
100 | |||
101 | /** |
||
102 | * POP3 password. |
||
103 | * |
||
104 | * @var string |
||
105 | */ |
||
106 | public $password; |
||
107 | |||
108 | /** |
||
109 | * Resource handle for the POP3 connection socket. |
||
110 | * |
||
111 | * @var resource |
||
112 | */ |
||
113 | protected $pop_conn; |
||
114 | |||
115 | /** |
||
116 | * Are we connected? |
||
117 | * |
||
118 | * @var boolean |
||
119 | */ |
||
120 | protected $connected = false; |
||
121 | |||
122 | /** |
||
123 | * Error container. |
||
124 | * |
||
125 | * @var array |
||
126 | */ |
||
127 | protected $errors = []; |
||
128 | |||
129 | /** |
||
130 | * Line break constant |
||
131 | */ |
||
132 | const LE = "\r\n"; |
||
133 | |||
134 | /** |
||
135 | * Simple static wrapper for all-in-one POP before SMTP |
||
136 | * |
||
137 | * @param string $host |
||
138 | * @param integer|boolean $port The port number to connect to |
||
139 | * @param integer|boolean $timeout The timeout value |
||
140 | * @param string $username |
||
141 | * @param string $password |
||
142 | * @param integer $debug_level |
||
143 | * |
||
144 | * @return boolean |
||
145 | */ |
||
146 | public static function popBeforeSmtp( |
||
147 | $host, |
||
148 | $port = false, |
||
149 | $timeout = false, |
||
150 | $username = '', |
||
151 | $password = '', |
||
152 | $debug_level = 0 |
||
153 | ) { |
||
154 | $pop = new POP3; |
||
155 | return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level); |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * Authenticate with a POP3 server. |
||
160 | * A connect, login, disconnect sequence |
||
161 | * appropriate for POP-before SMTP authorisation. |
||
162 | * |
||
163 | * @param string $host The hostname to connect to |
||
164 | * @param integer|boolean $port The port number to connect to |
||
165 | * @param integer|boolean $timeout The timeout value |
||
166 | * @param string $username |
||
167 | * @param string $password |
||
168 | * @param integer $debug_level |
||
169 | * |
||
170 | * @return boolean |
||
171 | */ |
||
172 | public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0) |
||
173 | { |
||
174 | $this->host = $host; |
||
175 | // If no port value provided, use default |
||
176 | if (false === $port) { |
||
177 | $this->port = static::DEFAULT_PORT; |
||
178 | } else { |
||
179 | $this->port = (integer)$port; |
||
180 | } |
||
181 | // If no timeout value provided, use default |
||
182 | if (false === $timeout) { |
||
183 | $this->tval = static::DEFAULT_TIMEOUT; |
||
184 | } else { |
||
185 | $this->tval = (integer)$timeout; |
||
186 | } |
||
187 | $this->do_debug = $debug_level; |
||
188 | $this->username = $username; |
||
189 | $this->password = $password; |
||
190 | // Reset the error log |
||
191 | $this->errors = []; |
||
192 | // connect |
||
193 | $result = $this->connect($this->host, $this->port, $this->tval); |
||
194 | if ($result) { |
||
195 | $login_result = $this->login($this->username, $this->password); |
||
196 | if ($login_result) { |
||
197 | $this->disconnect(); |
||
198 | return true; |
||
199 | } |
||
200 | } |
||
201 | // We need to disconnect regardless of whether the login succeeded |
||
202 | $this->disconnect(); |
||
203 | return false; |
||
204 | } |
||
205 | |||
206 | /** |
||
207 | * Connect to a POP3 server. |
||
208 | * |
||
209 | * @param string $host |
||
210 | * @param integer|boolean $port |
||
211 | * @param integer $tval |
||
212 | * |
||
213 | * @return boolean |
||
214 | */ |
||
215 | public function connect($host, $port = false, $tval = 30) |
||
216 | { |
||
217 | // Are we already connected? |
||
218 | if ($this->connected) { |
||
219 | return true; |
||
220 | } |
||
221 | |||
222 | //On Windows this will raise a PHP Warning error if the hostname doesn't exist. |
||
223 | //Rather than suppress it with @fsockopen, capture it cleanly instead |
||
224 | set_error_handler([$this, 'catchWarning']); |
||
225 | |||
226 | if (false === $port) { |
||
227 | $port = static::DEFAULT_PORT; |
||
228 | } |
||
229 | |||
230 | // connect to the POP3 server |
||
231 | $this->pop_conn = fsockopen( |
||
232 | $host, // POP3 Host |
||
233 | $port, // Port # |
||
234 | $errno, // Error Number |
||
235 | $errstr, // Error Message |
||
236 | $tval |
||
237 | ); // Timeout (seconds) |
||
238 | // Restore the error handler |
||
239 | restore_error_handler(); |
||
240 | |||
241 | // Did we connect? |
||
242 | if (false === $this->pop_conn) { |
||
243 | // It would appear not... |
||
244 | $this->setError( |
||
245 | [ |
||
0 ignored issues
–
show
|
|||
246 | 'error' => "Failed to connect to server $host on port $port", |
||
247 | 'errno' => $errno, |
||
248 | 'errstr' => $errstr |
||
249 | ] |
||
250 | ); |
||
251 | return false; |
||
252 | } |
||
253 | |||
254 | // Increase the stream time-out |
||
255 | stream_set_timeout($this->pop_conn, $tval, 0); |
||
256 | |||
257 | // Get the POP3 server response |
||
258 | $pop3_response = $this->getResponse(); |
||
259 | // Check for the +OK |
||
260 | if ($this->checkResponse($pop3_response)) { |
||
261 | // The connection is established and the POP3 server is talking |
||
262 | $this->connected = true; |
||
263 | return true; |
||
264 | } |
||
265 | return false; |
||
266 | } |
||
267 | |||
268 | /** |
||
269 | * Log in to the POP3 server. |
||
270 | * Does not support APOP (RFC 2828, 4949). |
||
271 | * |
||
272 | * @param string $username |
||
273 | * @param string $password |
||
274 | * |
||
275 | * @return boolean |
||
276 | */ |
||
277 | public function login($username = '', $password = '') |
||
278 | { |
||
279 | if (!$this->connected) { |
||
280 | $this->setError('Not connected to POP3 server'); |
||
281 | } |
||
282 | if (empty($username)) { |
||
283 | $username = $this->username; |
||
284 | } |
||
285 | if (empty($password)) { |
||
286 | $password = $this->password; |
||
287 | } |
||
288 | |||
289 | // Send the Username |
||
290 | $this->sendString("USER $username" . static::LE); |
||
291 | $pop3_response = $this->getResponse(); |
||
292 | if ($this->checkResponse($pop3_response)) { |
||
293 | // Send the Password |
||
294 | $this->sendString("PASS $password" . static::LE); |
||
295 | $pop3_response = $this->getResponse(); |
||
296 | if ($this->checkResponse($pop3_response)) { |
||
297 | return true; |
||
298 | } |
||
299 | } |
||
300 | return false; |
||
301 | } |
||
302 | |||
303 | /** |
||
304 | * Disconnect from the POP3 server. |
||
305 | */ |
||
306 | public function disconnect() |
||
307 | { |
||
308 | $this->sendString('QUIT'); |
||
309 | //The QUIT command may cause the daemon to exit, which will kill our connection |
||
310 | //So ignore errors here |
||
311 | try { |
||
312 | @fclose($this->pop_conn); |
||
313 | } catch (Exception $e) { |
||
314 | //Do nothing |
||
315 | }; |
||
316 | } |
||
317 | |||
318 | /** |
||
319 | * Get a response from the POP3 server. |
||
320 | * $size is the maximum number of bytes to retrieve |
||
321 | * |
||
322 | * @param integer $size |
||
323 | * |
||
324 | * @return string |
||
325 | */ |
||
326 | protected function getResponse($size = 128) |
||
327 | { |
||
328 | $response = fgets($this->pop_conn, $size); |
||
329 | if ($this->do_debug >= 1) { |
||
330 | echo 'Server -> Client: ', $response; |
||
331 | } |
||
332 | return $response; |
||
333 | } |
||
334 | |||
335 | /** |
||
336 | * Send raw data to the POP3 server. |
||
337 | * |
||
338 | * @param string $string |
||
339 | * |
||
340 | * @return integer |
||
341 | */ |
||
342 | protected function sendString($string) |
||
343 | { |
||
344 | if ($this->pop_conn) { |
||
345 | if ($this->do_debug >= 2) { //Show client messages when debug >= 2 |
||
346 | echo 'Client -> Server: ', $string; |
||
347 | } |
||
348 | return fwrite($this->pop_conn, $string, strlen($string)); |
||
349 | } |
||
350 | return 0; |
||
351 | } |
||
352 | |||
353 | /** |
||
354 | * Checks the POP3 server response. |
||
355 | * Looks for for +OK or -ERR. |
||
356 | * |
||
357 | * @param string $string |
||
358 | * |
||
359 | * @return boolean |
||
360 | */ |
||
361 | protected function checkResponse($string) |
||
362 | { |
||
363 | if (substr($string, 0, 3) !== '+OK') { |
||
364 | $this->setError( |
||
365 | [ |
||
0 ignored issues
–
show
array('error' => "Server...' => 0, 'errstr' => '') is of type array<string,integer|str...er","errstr":"string"}> , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
366 | 'error' => "Server reported an error: $string", |
||
367 | 'errno' => 0, |
||
368 | 'errstr' => '' |
||
369 | ] |
||
370 | ); |
||
371 | return false; |
||
372 | } else { |
||
373 | return true; |
||
374 | } |
||
375 | } |
||
376 | |||
377 | /** |
||
378 | * Add an error to the internal error store. |
||
379 | * Also display debug output if it's enabled. |
||
380 | * |
||
381 | * @param string $error |
||
382 | */ |
||
383 | protected function setError($error) |
||
384 | { |
||
385 | $this->errors[] = $error; |
||
386 | if ($this->do_debug >= 1) { |
||
387 | echo '<pre>'; |
||
388 | foreach ($this->errors as $error) { |
||
389 | print_r($error); |
||
390 | } |
||
391 | echo '</pre>'; |
||
392 | } |
||
393 | } |
||
394 | |||
395 | /** |
||
396 | * Get an array of error messages, if any. |
||
397 | * |
||
398 | * @return array |
||
399 | */ |
||
400 | public function getErrors() |
||
401 | { |
||
402 | return $this->errors; |
||
403 | } |
||
404 | |||
405 | /** |
||
406 | * POP3 connection error handler. |
||
407 | * |
||
408 | * @param integer $errno |
||
409 | * @param string $errstr |
||
410 | * @param string $errfile |
||
411 | * @param integer $errline |
||
412 | */ |
||
413 | protected function catchWarning($errno, $errstr, $errfile, $errline) |
||
414 | { |
||
415 | $this->setError( |
||
416 | [ |
||
0 ignored issues
–
show
array('error' => 'Connec... 'errline' => $errline) is of type array<string,string|inte...","errline":"integer"}> , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
417 | 'error' => 'Connecting to the POP3 server raised a PHP warning: ', |
||
418 | 'errno' => $errno, |
||
419 | 'errstr' => $errstr, |
||
420 | 'errfile' => $errfile, |
||
421 | 'errline' => $errline |
||
422 | ] |
||
423 | ); |
||
424 | } |
||
425 | } |
||
426 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: