Protocol.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. /*
  3. * File: ImapProtocol.php
  4. * Category: Protocol
  5. * Author: M.Goldenbaum
  6. * Created: 16.09.20 18:27
  7. * Updated: -
  8. *
  9. * Description:
  10. * -
  11. */
  12. namespace Webklex\PHPIMAP\Connection\Protocols;
  13. use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
  14. /**
  15. * Class Protocol
  16. *
  17. * @package Webklex\PHPIMAP\Connection\Protocols
  18. */
  19. abstract class Protocol implements ProtocolInterface {
  20. /**
  21. * Default connection timeout in seconds
  22. */
  23. protected $connection_timeout = 30;
  24. /**
  25. * @var boolean
  26. */
  27. protected $debug = false;
  28. /**
  29. * @var false|resource
  30. */
  31. public $stream = false;
  32. /**
  33. * Connection encryption method
  34. * @var mixed $encryption
  35. */
  36. protected $encryption = false;
  37. /**
  38. * Set to false to ignore SSL certificate validation
  39. * @var bool
  40. */
  41. protected $cert_validation = true;
  42. /**
  43. * Proxy settings
  44. * @var array
  45. */
  46. protected $proxy = [
  47. 'socket' => null,
  48. 'request_fulluri' => false,
  49. 'username' => null,
  50. 'password' => null,
  51. ];
  52. /**
  53. * Get an available cryptographic method
  54. *
  55. * @return int
  56. */
  57. public function getCryptoMethod() {
  58. // Allow the best TLS version(s) we can
  59. $cryptoMethod = STREAM_CRYPTO_METHOD_TLS_CLIENT;
  60. // PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
  61. // so add them back in manually if we can
  62. if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
  63. $cryptoMethod = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
  64. }elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT')) {
  65. $cryptoMethod = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
  66. }
  67. return $cryptoMethod;
  68. }
  69. /**
  70. * Enable SSL certificate validation
  71. *
  72. * @return $this
  73. */
  74. public function enableCertValidation() {
  75. $this->cert_validation = true;
  76. return $this;
  77. }
  78. /**
  79. * Disable SSL certificate validation
  80. * @return $this
  81. */
  82. public function disableCertValidation() {
  83. $this->cert_validation = false;
  84. return $this;
  85. }
  86. /**
  87. * Set SSL certificate validation
  88. * @var int $cert_validation
  89. *
  90. * @return $this
  91. */
  92. public function setCertValidation($cert_validation) {
  93. $this->cert_validation = $cert_validation;
  94. return $this;
  95. }
  96. /**
  97. * Should we validate SSL certificate?
  98. *
  99. * @return bool
  100. */
  101. public function getCertValidation() {
  102. return $this->cert_validation;
  103. }
  104. /**
  105. * Set connection proxy settings
  106. * @var array $options
  107. *
  108. * @return $this
  109. */
  110. public function setProxy($options) {
  111. foreach ($this->proxy as $key => $val) {
  112. if (isset($options[$key])) {
  113. $this->proxy[$key] = $options[$key];
  114. }
  115. }
  116. return $this;
  117. }
  118. /**
  119. * Get the current proxy settings
  120. *
  121. * @return array
  122. */
  123. public function getProxy() {
  124. return $this->proxy;
  125. }
  126. /**
  127. * Prepare socket options
  128. * @var string $transport
  129. *
  130. * @return array
  131. */
  132. private function defaultSocketOptions($transport) {
  133. $options = [];
  134. if ($this->encryption != false) {
  135. $options["ssl"] = [
  136. 'verify_peer_name' => $this->getCertValidation(),
  137. 'verify_peer' => $this->getCertValidation(),
  138. ];
  139. }
  140. if ($this->proxy["socket"] != null) {
  141. $options[$transport]["proxy"] = $this->proxy["socket"];
  142. $options[$transport]["request_fulluri"] = $this->proxy["request_fulluri"];
  143. if ($this->proxy["username"] != null) {
  144. $auth = base64_encode($this->proxy["username"].':'.$this->proxy["password"]);
  145. $options[$transport]["header"] = [
  146. "Proxy-Authorization: Basic $auth"
  147. ];
  148. }
  149. }
  150. return $options;
  151. }
  152. /**
  153. * Create a new resource stream
  154. * @param $transport
  155. * @param string $host hostname or IP address of IMAP server
  156. * @param int $port of IMAP server, default is 143 (993 for ssl)
  157. * @param int $timeout timeout in seconds for initiating session
  158. *
  159. * @return resource|boolean The socket created.
  160. * @throws ConnectionFailedException
  161. */
  162. protected function createStream($transport, $host, $port, $timeout) {
  163. $socket = "$transport://$host:$port";
  164. $stream = stream_socket_client($socket, $errno, $errstr, $timeout,
  165. STREAM_CLIENT_CONNECT,
  166. stream_context_create($this->defaultSocketOptions($transport))
  167. );
  168. //stream_set_timeout($stream, $timeout); // Hang id $strem empty and already done line 199
  169. if (!$stream) {
  170. throw new ConnectionFailedException($errstr, $errno);
  171. }
  172. if (false === stream_set_timeout($stream, $timeout)) {
  173. throw new ConnectionFailedException('Failed to set stream timeout');
  174. }
  175. return $stream;
  176. }
  177. /**
  178. * @return int
  179. */
  180. public function getConnectionTimeout() {
  181. return $this->connection_timeout;
  182. }
  183. /**
  184. * @param int $connection_timeout
  185. * @return Protocol
  186. */
  187. public function setConnectionTimeout($connection_timeout) {
  188. if ($connection_timeout !== null) {
  189. $this->connection_timeout = $connection_timeout;
  190. }
  191. return $this;
  192. }
  193. }