Proyectos de Subversion Moodle

Rev

Rev 1 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 1 Rev 1441
Línea 11... Línea 11...
11
 * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
11
 * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
12
 * @author    Brent R. Matzelle (original founder)
12
 * @author    Brent R. Matzelle (original founder)
13
 * @copyright 2012 - 2020 Marcus Bointon
13
 * @copyright 2012 - 2020 Marcus Bointon
14
 * @copyright 2010 - 2012 Jim Jagielski
14
 * @copyright 2010 - 2012 Jim Jagielski
15
 * @copyright 2004 - 2009 Andy Prevost
15
 * @copyright 2004 - 2009 Andy Prevost
16
 * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
16
 * @license   https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
17
 * @note      This program is distributed in the hope that it will be useful - WITHOUT
17
 * @note      This program is distributed in the hope that it will be useful - WITHOUT
18
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
 * FITNESS FOR A PARTICULAR PURPOSE.
19
 * FITNESS FOR A PARTICULAR PURPOSE.
20
 */
20
 */
Línea 33... Línea 33...
33
    /**
33
    /**
34
     * The PHPMailer SMTP version number.
34
     * The PHPMailer SMTP version number.
35
     *
35
     *
36
     * @var string
36
     * @var string
37
     */
37
     */
38
    const VERSION = '6.9.1';
38
    const VERSION = '6.9.3';
Línea 39... Línea 39...
39
 
39
 
40
    /**
40
    /**
41
     * SMTP line break constant.
41
     * SMTP line break constant.
42
     *
42
     *
Línea 60... Línea 60...
60
 
60
 
61
    /**
61
    /**
62
     * The maximum line length allowed by RFC 5321 section 4.5.3.1.6,
62
     * The maximum line length allowed by RFC 5321 section 4.5.3.1.6,
63
     * *excluding* a trailing CRLF break.
63
     * *excluding* a trailing CRLF break.
64
     *
64
     *
65
     * @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.6
65
     * @see https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.6
66
     *
66
     *
67
     * @var int
67
     * @var int
68
     */
68
     */
Línea 69... Línea 69...
69
    const MAX_LINE_LENGTH = 998;
69
    const MAX_LINE_LENGTH = 998;
70
 
70
 
71
    /**
71
    /**
72
     * The maximum line length allowed for replies in RFC 5321 section 4.5.3.1.5,
72
     * The maximum line length allowed for replies in RFC 5321 section 4.5.3.1.5,
73
     * *including* a trailing CRLF line break.
73
     * *including* a trailing CRLF line break.
74
     *
74
     *
75
     * @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.5
75
     * @see https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.5
76
     *
76
     *
77
     * @var int
77
     * @var int
Línea 150... Línea 150...
150
    public $Debugoutput = 'echo';
150
    public $Debugoutput = 'echo';
Línea 151... Línea 151...
151
 
151
 
152
    /**
152
    /**
153
     * Whether to use VERP.
153
     * Whether to use VERP.
154
     *
154
     *
155
     * @see http://en.wikipedia.org/wiki/Variable_envelope_return_path
155
     * @see https://en.wikipedia.org/wiki/Variable_envelope_return_path
156
     * @see http://www.postfix.org/VERP_README.html Info on VERP
156
     * @see https://www.postfix.org/VERP_README.html Info on VERP
157
     *
157
     *
158
     * @var bool
158
     * @var bool
159
     */
159
     */
Línea 160... Línea 160...
160
    public $do_verp = false;
160
    public $do_verp = false;
161
 
161
 
162
    /**
162
    /**
163
     * The timeout value for connection, in seconds.
163
     * The timeout value for connection, in seconds.
164
     * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2.
164
     * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2.
165
     * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
165
     * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
166
     *
166
     *
167
     * @see http://tools.ietf.org/html/rfc2821#section-4.5.3.2
167
     * @see https://www.rfc-editor.org/rfc/rfc2821#section-4.5.3.2
168
     *
168
     *
169
     * @var int
169
     * @var int
Línea 185... Línea 185...
185
     *
185
     *
186
     * @var string[]
186
     * @var string[]
187
     */
187
     */
188
    protected $smtp_transaction_id_patterns = [
188
    protected $smtp_transaction_id_patterns = [
189
        'exim' => '/[\d]{3} OK id=(.*)/',
189
        'exim' => '/[\d]{3} OK id=(.*)/',
190
        'sendmail' => '/[\d]{3} 2.0.0 (.*) Message/',
190
        'sendmail' => '/[\d]{3} 2\.0\.0 (.*) Message/',
191
        'postfix' => '/[\d]{3} 2.0.0 Ok: queued as (.*)/',
191
        'postfix' => '/[\d]{3} 2\.0\.0 Ok: queued as (.*)/',
192
        'Microsoft_ESMTP' => '/[0-9]{3} 2.[\d].0 (.*)@(?:.*) Queued mail for delivery/',
192
        'Microsoft_ESMTP' => '/[0-9]{3} 2\.[\d]\.0 (.*)@(?:.*) Queued mail for delivery/',
193
        'Amazon_SES' => '/[\d]{3} Ok (.*)/',
193
        'Amazon_SES' => '/[\d]{3} Ok (.*)/',
194
        'SendGrid' => '/[\d]{3} Ok: queued as (.*)/',
194
        'SendGrid' => '/[\d]{3} Ok: queued as (.*)/',
195
        'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/',
195
        'CampaignMonitor' => '/[\d]{3} 2\.0\.0 OK:([a-zA-Z\d]{48})/',
196
        'Haraka' => '/[\d]{3} Message Queued \((.*)\)/',
196
        'Haraka' => '/[\d]{3} Message Queued \((.*)\)/',
197
        'ZoneMTA' => '/[\d]{3} Message queued as (.*)/',
197
        'ZoneMTA' => '/[\d]{3} Message queued as (.*)/',
198
        'Mailjet' => '/[\d]{3} OK queued as (.*)/',
198
        'Mailjet' => '/[\d]{3} OK queued as (.*)/',
199
    ];
199
    ];
Línea 278... Línea 278...
278
        if ($level > $this->do_debug) {
278
        if ($level > $this->do_debug) {
279
            return;
279
            return;
280
        }
280
        }
281
        //Is this a PSR-3 logger?
281
        //Is this a PSR-3 logger?
282
        if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) {
282
        if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) {
-
 
283
            //Remove trailing line breaks potentially added by calls to SMTP::client_send()
283
            $this->Debugoutput->debug($str);
284
            $this->Debugoutput->debug(rtrim($str, "\r\n"));
Línea 284... Línea 285...
284
 
285
 
285
            return;
286
            return;
286
        }
287
        }
287
        //Avoid clash with built-in function names
288
        //Avoid clash with built-in function names
Línea 291... Línea 292...
291
            return;
292
            return;
292
        }
293
        }
293
        switch ($this->Debugoutput) {
294
        switch ($this->Debugoutput) {
294
            case 'error_log':
295
            case 'error_log':
295
                //Don't output, just log
296
                //Don't output, just log
-
 
297
                /** @noinspection ForgottenDebugOutputInspection */
296
                error_log($str);
298
                error_log($str);
297
                break;
299
                break;
298
            case 'html':
300
            case 'html':
299
                //Cleans up output a bit for a better looking, HTML-safe output
301
                //Cleans up output a bit for a better looking, HTML-safe output
300
                echo gmdate('Y-m-d H:i:s'), ' ', htmlentities(
302
                echo gmdate('Y-m-d H:i:s'), ' ', htmlentities(
Línea 369... Línea 371...
369
        if ($responseCode === 220) {
371
        if ($responseCode === 220) {
370
            return true;
372
            return true;
371
        }
373
        }
372
        //Anything other than a 220 response means something went wrong
374
        //Anything other than a 220 response means something went wrong
373
        //RFC 5321 says the server will wait for us to send a QUIT in response to a 554 error
375
        //RFC 5321 says the server will wait for us to send a QUIT in response to a 554 error
374
        //https://tools.ietf.org/html/rfc5321#section-3.1
376
        //https://www.rfc-editor.org/rfc/rfc5321#section-3.1
375
        if ($responseCode === 554) {
377
        if ($responseCode === 554) {
376
            $this->quit();
378
            $this->quit();
377
        }
379
        }
378
        //This will handle 421 responses which may not wait for a QUIT (e.g. if the server is being shut down)
380
        //This will handle 421 responses which may not wait for a QUIT (e.g. if the server is being shut down)
379
        $this->edebug('Connection: closing due to error', self::DEBUG_CONNECTION);
381
        $this->edebug('Connection: closing due to error', self::DEBUG_CONNECTION);
Línea 402... Línea 404...
402
 
404
 
403
        $errno = 0;
405
        $errno = 0;
404
        $errstr = '';
406
        $errstr = '';
405
        if ($streamok) {
407
        if ($streamok) {
406
            $socket_context = stream_context_create($options);
408
            $socket_context = stream_context_create($options);
-
 
409
            set_error_handler(function () {
-
 
410
                call_user_func_array([$this, 'errorHandler'], func_get_args());
407
            set_error_handler([$this, 'errorHandler']);
411
            });
408
            $connection = stream_socket_client(
412
            $connection = stream_socket_client(
409
                $host . ':' . $port,
413
                $host . ':' . $port,
410
                $errno,
414
                $errno,
411
                $errstr,
415
                $errstr,
Línea 417... Línea 421...
417
            //Fall back to fsockopen which should work in more places, but is missing some features
421
            //Fall back to fsockopen which should work in more places, but is missing some features
418
            $this->edebug(
422
            $this->edebug(
419
                'Connection: stream_socket_client not available, falling back to fsockopen',
423
                'Connection: stream_socket_client not available, falling back to fsockopen',
420
                self::DEBUG_CONNECTION
424
                self::DEBUG_CONNECTION
421
            );
425
            );
422
            set_error_handler([$this, 'errorHandler']);
426
            set_error_handler(function () {
-
 
427
                call_user_func_array([$this, 'errorHandler'], func_get_args());
-
 
428
            });
423
            $connection = fsockopen(
429
            $connection = fsockopen(
424
                $host,
430
                $host,
425
                $port,
431
                $port,
426
                $errno,
432
                $errno,
427
                $errstr,
433
                $errstr,
Línea 481... Línea 487...
481
            $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
487
            $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
482
            $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
488
            $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
483
        }
489
        }
Línea 484... Línea 490...
484
 
490
 
485
        //Begin encrypted connection
491
        //Begin encrypted connection
-
 
492
            set_error_handler(function () {
-
 
493
                call_user_func_array([$this, 'errorHandler'], func_get_args());
486
        set_error_handler([$this, 'errorHandler']);
494
            });
487
        $crypto_ok = stream_socket_enable_crypto(
495
        $crypto_ok = stream_socket_enable_crypto(
488
            $this->smtp_conn,
496
            $this->smtp_conn,
489
            true,
497
            true,
490
            $crypto_method
498
            $crypto_method
Línea 572... Línea 580...
572
                if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
580
                if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
573
                    return false;
581
                    return false;
574
                }
582
                }
575
                //Send encoded username and password
583
                //Send encoded username and password
576
                if (
584
                if (
577
                    //Format from https://tools.ietf.org/html/rfc4616#section-2
585
                    //Format from https://www.rfc-editor.org/rfc/rfc4616#section-2
578
                    //We skip the first field (it's forgery), so the string starts with a null byte
586
                    //We skip the first field (it's forgery), so the string starts with a null byte
579
                    !$this->sendCommand(
587
                    !$this->sendCommand(
580
                        'User & Password',
588
                        'User & Password',
581
                        base64_encode("\0" . $username . "\0" . $password),
589
                        base64_encode("\0" . $username . "\0" . $password),
582
                        235
590
                        235
Línea 646... Línea 654...
646
        if (function_exists('hash_hmac')) {
654
        if (function_exists('hash_hmac')) {
647
            return hash_hmac('md5', $data, $key);
655
            return hash_hmac('md5', $data, $key);
648
        }
656
        }
Línea 649... Línea 657...
649
 
657
 
650
        //The following borrowed from
658
        //The following borrowed from
Línea 651... Línea 659...
651
        //http://php.net/manual/en/function.mhash.php#27225
659
        //https://www.php.net/manual/en/function.mhash.php#27225
652
 
660
 
653
        //RFC 2104 HMAC implementation for php.
661
        //RFC 2104 HMAC implementation for php.
654
        //Creates an md5 HMAC.
662
        //Creates an md5 HMAC.
Línea 785... Línea 793...
785
            $lines_out[] = $line;
793
            $lines_out[] = $line;
Línea 786... Línea 794...
786
 
794
 
787
            //Send the lines to the server
795
            //Send the lines to the server
788
            foreach ($lines_out as $line_out) {
796
            foreach ($lines_out as $line_out) {
789
                //Dot-stuffing as per RFC5321 section 4.5.2
797
                //Dot-stuffing as per RFC5321 section 4.5.2
790
                //https://tools.ietf.org/html/rfc5321#section-4.5.2
798
                //https://www.rfc-editor.org/rfc/rfc5321#section-4.5.2
791
                if (!empty($line_out) && $line_out[0] === '.') {
799
                if (!empty($line_out) && $line_out[0] === '.') {
792
                    $line_out = '.' . $line_out;
800
                    $line_out = '.' . $line_out;
793
                }
801
                }
794
                $this->client_send($line_out . static::LE, 'DATA');
802
                $this->client_send($line_out . static::LE, 'DATA');
Línea 1160... Línea 1168...
1160
        ) {
1168
        ) {
1161
            $this->edebug('CLIENT -> SERVER: [credentials hidden]', self::DEBUG_CLIENT);
1169
            $this->edebug('CLIENT -> SERVER: [credentials hidden]', self::DEBUG_CLIENT);
1162
        } else {
1170
        } else {
1163
            $this->edebug('CLIENT -> SERVER: ' . $data, self::DEBUG_CLIENT);
1171
            $this->edebug('CLIENT -> SERVER: ' . $data, self::DEBUG_CLIENT);
1164
        }
1172
        }
1165
        set_error_handler([$this, 'errorHandler']);
1173
        set_error_handler(function () {
-
 
1174
            call_user_func_array([$this, 'errorHandler'], func_get_args());
-
 
1175
        });
1166
        $result = fwrite($this->smtp_conn, $data);
1176
        $result = fwrite($this->smtp_conn, $data);
1167
        restore_error_handler();
1177
        restore_error_handler();
Línea 1168... Línea 1178...
1168
 
1178
 
1169
        return $result;
1179
        return $result;
Línea 1263... Línea 1273...
1263
        $selR = [$this->smtp_conn];
1273
        $selR = [$this->smtp_conn];
1264
        $selW = null;
1274
        $selW = null;
1265
        while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
1275
        while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
1266
            //Must pass vars in here as params are by reference
1276
            //Must pass vars in here as params are by reference
1267
            //solution for signals inspired by https://github.com/symfony/symfony/pull/6540
1277
            //solution for signals inspired by https://github.com/symfony/symfony/pull/6540
1268
            set_error_handler([$this, 'errorHandler']);
1278
            set_error_handler(function () {
-
 
1279
                call_user_func_array([$this, 'errorHandler'], func_get_args());
-
 
1280
            });
1269
            $n = stream_select($selR, $selW, $selW, $this->Timelimit);
1281
            $n = stream_select($selR, $selW, $selW, $this->Timelimit);
1270
            restore_error_handler();
1282
            restore_error_handler();
Línea 1271... Línea 1283...
1271
 
1283
 
1272
            if ($n === false) {
1284
            if ($n === false) {