@@ -426,7 +426,7 @@ public function command($command, $valid)
426
426
*/
427
427
public function getResponse ()
428
428
{
429
- return array ($ this ->code , join ("\n" , $ this ->arguments ));
429
+ return array ($ this ->code , implode ("\n" , $ this ->arguments ));
430
430
}
431
431
432
432
/**
@@ -623,23 +623,77 @@ public function starttls()
623
623
/* STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT constant does not exist
624
624
* and STREAM_CRYPTO_METHOD_SSLv23_CLIENT constant is
625
625
* inconsistent across PHP versions. */
626
- $ crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT
627
- | @STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
628
- | @STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
626
+ $ crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT ;
627
+
628
+ if (defined ('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT ' )) {
629
+ $ crypto_method |= @STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
630
+ }
631
+
632
+ if (defined ('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT ' )) {
633
+ $ crypto_method |= @STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
634
+ }
635
+
636
+ if (defined ('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT ' )) {
637
+ $ crypto_method |= @STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT;
638
+ }
629
639
}
630
- if (PEAR ::isError ($ result = $ this ->socket ->enableCrypto (true , $ crypto_method ))) {
631
- return $ result ;
632
- } elseif ($ result !== true ) {
633
- return PEAR ::raiseError ('STARTTLS failed ' );
640
+
641
+ for ($ attempts = 1 ; $ attempts < 15 ; $ attempts ++) {
642
+ if (PEAR ::isError (
643
+ $ result = $ this ->socket ->enableCrypto (
644
+ true , $ crypto_method )
645
+ )
646
+ ) {
647
+ return $ result ;
648
+ }
649
+ if ($ this ->socket ->isBlocking () !== true ) {
650
+ usleep ($ attempts );
651
+ }
652
+ if ($ result !== 0 ) {
653
+ break ;
654
+ }
634
655
}
635
-
656
+
657
+ if ($ result !== true ) {
658
+ $ last_error = error_get_last ();
659
+ $ crypto_types_arr = $ this ->getDefinedConstantsKeyFilter (
660
+ 'STREAM_CRYPTO_METHOD_ '
661
+ );
662
+ $ error_types_arr = $ this ->getDefinedConstantsKeyFilter (
663
+ 'E_ '
664
+ );
665
+
666
+ $ resultErrorString = "STARTTLS failed " ;
667
+ //{enableCrypto: false;
668
+ $ resultErrorString .= "{enableCrypto: %s; " ;
669
+ //crypto_method: STREAM_CRYPTO_METHOD_TLS_CLIENT (3);
670
+ $ resultErrorString .= "crypto_method: %s (%s); " ;
671
+ //attempts: 1;
672
+ $ resultErrorString .= "attempts: %d; " ;
673
+ //E_ERROR (1): ErrorMessage}
674
+ $ resultErrorString .= "%s (%s): %s} " ;
675
+
676
+ return PEAR ::raiseError (
677
+ sprintf (
678
+ $ resultErrorString ,
679
+ var_export ($ result , true ),
680
+ array_search ($ crypto_method , $ crypto_types_arr ),
681
+ var_export ($ crypto_method , true ),
682
+ $ attempts ,
683
+ array_search ($ last_error ['type ' ], $ error_types_arr ),
684
+ $ last_error ['type ' ],
685
+ $ last_error ['message ' ]
686
+ )
687
+ );
688
+ }
689
+
636
690
/* Send EHLO again to recieve the AUTH string from the
637
691
* SMTP server. */
638
692
$ this ->negotiate ();
639
693
} else {
640
694
return false ;
641
695
}
642
-
696
+
643
697
return true ;
644
698
}
645
699
@@ -1475,4 +1529,25 @@ public function identifySender()
1475
1529
{
1476
1530
return true ;
1477
1531
}
1532
+
1533
+ /**
1534
+ * Backwards-compatibility method.
1535
+ * array_filter alternative in PHP5.4 for using
1536
+ * key filter because array_filter mode parameter
1537
+ * is only available since PHP5.6.
1538
+ *
1539
+ * @param string $filter The string to filter
1540
+ * @return array Filtered constants array.
1541
+ */
1542
+ private function getDefinedConstantsKeyFilter ($ filter ) {
1543
+ $ constants_filtered = array ();
1544
+ $ filter_length = strlen ($ filter );
1545
+ $ constants = get_defined_constants ();
1546
+ foreach ($ constants as $ key =>$ value ){
1547
+ if (substr ($ key , 0 , $ filter_length ) == $ filter ) {
1548
+ $ constants_filtered [$ key ] = $ value ;
1549
+ }
1550
+ }
1551
+ return $ constants_filtered ;
1552
+ }
1478
1553
}
0 commit comments