Completed
Branch develop (37f7b7)
by
unknown
24:41
created
htdocs/includes/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php 2 patches
Indentation   +301 added lines, -301 removed lines patch added patch discarded remove patch
@@ -15,305 +15,305 @@
 block discarded – undo
15 15
  */
16 16
 class Swift_Transport_StreamBuffer extends Swift_ByteStream_AbstractFilterableInputStream implements Swift_Transport_IoBuffer
17 17
 {
18
-    /** A primary socket */
19
-    private $stream;
20
-
21
-    /** The input stream */
22
-    private $in;
23
-
24
-    /** The output stream */
25
-    private $out;
26
-
27
-    /** Buffer initialization parameters */
28
-    private $params = [];
29
-
30
-    /** The ReplacementFilterFactory */
31
-    private $replacementFactory;
32
-
33
-    /** Translations performed on data being streamed into the buffer */
34
-    private $translations = [];
35
-
36
-    /**
37
-     * Create a new StreamBuffer using $replacementFactory for transformations.
38
-     */
39
-    public function __construct(Swift_ReplacementFilterFactory $replacementFactory)
40
-    {
41
-        $this->replacementFactory = $replacementFactory;
42
-    }
43
-
44
-    /**
45
-     * Perform any initialization needed, using the given $params.
46
-     *
47
-     * Parameters will vary depending upon the type of IoBuffer used.
48
-     */
49
-    public function initialize(array $params)
50
-    {
51
-        $this->params = $params;
52
-        switch ($params['type']) {
53
-            case self::TYPE_PROCESS:
54
-                $this->establishProcessConnection();
55
-                break;
56
-            case self::TYPE_SOCKET:
57
-            default:
58
-                $this->establishSocketConnection();
59
-                break;
60
-        }
61
-    }
62
-
63
-    /**
64
-     * Set an individual param on the buffer (e.g. switching to SSL).
65
-     *
66
-     * @param string $param
67
-     * @param mixed  $value
68
-     */
69
-    public function setParam($param, $value)
70
-    {
71
-        if (isset($this->stream)) {
72
-            switch ($param) {
73
-                case 'timeout':
74
-                    if ($this->stream) {
75
-                        stream_set_timeout($this->stream, $value);
76
-                    }
77
-                    break;
78
-
79
-                case 'blocking':
80
-                    if ($this->stream) {
81
-                        stream_set_blocking($this->stream, 1);
82
-                    }
83
-            }
84
-        }
85
-        $this->params[$param] = $value;
86
-    }
87
-
88
-    public function startTLS()
89
-    {
90
-        // STREAM_CRYPTO_METHOD_TLS_CLIENT only allow tls1.0 connections (some php versions)
91
-        // To support modern tls we allow explicit tls1.0, tls1.1, tls1.2
92
-        // Ssl3 and older are not allowed because they are vulnerable
93
-        // @TODO make tls arguments configurable
94
-        return stream_socket_enable_crypto($this->stream, true, STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);
95
-    }
96
-
97
-    /**
98
-     * Perform any shutdown logic needed.
99
-     */
100
-    public function terminate()
101
-    {
102
-        if (isset($this->stream)) {
103
-            switch ($this->params['type']) {
104
-                case self::TYPE_PROCESS:
105
-                    fclose($this->in);
106
-                    fclose($this->out);
107
-                    proc_close($this->stream);
108
-                    break;
109
-                case self::TYPE_SOCKET:
110
-                default:
111
-                    fclose($this->stream);
112
-                    break;
113
-            }
114
-        }
115
-        $this->stream = null;
116
-        $this->out = null;
117
-        $this->in = null;
118
-    }
119
-
120
-    /**
121
-     * Set an array of string replacements which should be made on data written
122
-     * to the buffer.
123
-     *
124
-     * This could replace LF with CRLF for example.
125
-     *
126
-     * @param string[] $replacements
127
-     */
128
-    public function setWriteTranslations(array $replacements)
129
-    {
130
-        foreach ($this->translations as $search => $replace) {
131
-            if (!isset($replacements[$search])) {
132
-                $this->removeFilter($search);
133
-                unset($this->translations[$search]);
134
-            }
135
-        }
136
-
137
-        foreach ($replacements as $search => $replace) {
138
-            if (!isset($this->translations[$search])) {
139
-                $this->addFilter(
140
-                    $this->replacementFactory->createFilter($search, $replace), $search
141
-                    );
142
-                $this->translations[$search] = true;
143
-            }
144
-        }
145
-    }
146
-
147
-    /**
148
-     * Get a line of output (including any CRLF).
149
-     *
150
-     * The $sequence number comes from any writes and may or may not be used
151
-     * depending upon the implementation.
152
-     *
153
-     * @param int $sequence of last write to scan from
154
-     *
155
-     * @return string
156
-     *
157
-     * @throws Swift_IoException
158
-     */
159
-    public function readLine($sequence)
160
-    {
161
-        if (isset($this->out) && !feof($this->out)) {
162
-            $line = fgets($this->out);
163
-            if (0 == \strlen($line)) {
164
-                $metas = stream_get_meta_data($this->out);
165
-                if ($metas['timed_out']) {
166
-                    throw new Swift_IoException('Connection to '.$this->getReadConnectionDescription().' Timed Out');
167
-                }
168
-            }
169
-
170
-            return $line;
171
-        }
172
-    }
173
-
174
-    /**
175
-     * Reads $length bytes from the stream into a string and moves the pointer
176
-     * through the stream by $length.
177
-     *
178
-     * If less bytes exist than are requested the remaining bytes are given instead.
179
-     * If no bytes are remaining at all, boolean false is returned.
180
-     *
181
-     * @param int $length
182
-     *
183
-     * @return string|bool
184
-     *
185
-     * @throws Swift_IoException
186
-     */
187
-    public function read($length)
188
-    {
189
-        if (isset($this->out) && !feof($this->out)) {
190
-            $ret = fread($this->out, $length);
191
-            if (0 == \strlen($ret)) {
192
-                $metas = stream_get_meta_data($this->out);
193
-                if ($metas['timed_out']) {
194
-                    throw new Swift_IoException('Connection to '.$this->getReadConnectionDescription().' Timed Out');
195
-                }
196
-            }
197
-
198
-            return $ret;
199
-        }
200
-    }
201
-
202
-    /** Not implemented */
203
-    public function setReadPointer($byteOffset)
204
-    {
205
-    }
206
-
207
-    /** Flush the stream contents */
208
-    protected function flush()
209
-    {
210
-        if (isset($this->in)) {
211
-            fflush($this->in);
212
-        }
213
-    }
214
-
215
-    /** Write this bytes to the stream */
216
-    protected function doCommit($bytes)
217
-    {
218
-        if (isset($this->in)) {
219
-            $bytesToWrite = \strlen($bytes);
220
-            $totalBytesWritten = 0;
221
-
222
-            while ($totalBytesWritten < $bytesToWrite) {
223
-                $bytesWritten = fwrite($this->in, substr($bytes, $totalBytesWritten));
224
-                if (false === $bytesWritten || 0 === $bytesWritten) {
225
-                    break;
226
-                }
227
-
228
-                $totalBytesWritten += $bytesWritten;
229
-            }
230
-
231
-            if ($totalBytesWritten > 0) {
232
-                return ++$this->sequence;
233
-            }
234
-        }
235
-    }
236
-
237
-    /**
238
-     * Establishes a connection to a remote server.
239
-     */
240
-    private function establishSocketConnection()
241
-    {
242
-        $host = $this->params['host'];
243
-        if (!empty($this->params['protocol'])) {
244
-            $host = $this->params['protocol'].'://'.$host;
245
-        }
246
-        $timeout = 15;
247
-        if (!empty($this->params['timeout'])) {
248
-            $timeout = $this->params['timeout'];
249
-        }
250
-        $options = [];
251
-        if (!empty($this->params['sourceIp'])) {
252
-            $options['socket']['bindto'] = $this->params['sourceIp'].':0';
253
-        }
254
-
255
-        if (isset($this->params['stream_context_options'])) {
256
-            $options = array_merge($options, $this->params['stream_context_options']);
257
-        }
258
-        $streamContext = stream_context_create($options);
259
-
260
-        set_error_handler(function ($type, $msg) {
261
-            throw new Swift_TransportException('Connection could not be established with host '.$this->params['host'].' :'.$msg);
262
-        });
263
-        try {
264
-            $this->stream = stream_socket_client($host.':'.$this->params['port'], $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $streamContext);
265
-        } finally {
266
-            restore_error_handler();
267
-        }
268
-
269
-        if (!empty($this->params['blocking'])) {
270
-            stream_set_blocking($this->stream, 1);
271
-        } else {
272
-            stream_set_blocking($this->stream, 0);
273
-        }
274
-        stream_set_timeout($this->stream, $timeout);
275
-        $this->in = &$this->stream;
276
-        $this->out = &$this->stream;
277
-    }
278
-
279
-    /**
280
-     * Opens a process for input/output.
281
-     */
282
-    private function establishProcessConnection()
283
-    {
284
-        $command = $this->params['command'];
285
-        $descriptorSpec = [
286
-            0 => ['pipe', 'r'],
287
-            1 => ['pipe', 'w'],
288
-            2 => ['pipe', 'w'],
289
-            ];
290
-        $pipes = [];
291
-        $this->stream = proc_open($command, $descriptorSpec, $pipes);
292
-        stream_set_blocking($pipes[2], 0);
293
-        if ($err = stream_get_contents($pipes[2])) {
294
-            throw new Swift_TransportException('Process could not be started ['.$err.']');
295
-        }
296
-        $this->in = &$pipes[0];
297
-        $this->out = &$pipes[1];
298
-    }
299
-
300
-    private function getReadConnectionDescription()
301
-    {
302
-        switch ($this->params['type']) {
303
-            case self::TYPE_PROCESS:
304
-                return 'Process '.$this->params['command'];
305
-                break;
306
-
307
-            case self::TYPE_SOCKET:
308
-            default:
309
-                $host = $this->params['host'];
310
-                if (!empty($this->params['protocol'])) {
311
-                    $host = $this->params['protocol'].'://'.$host;
312
-                }
313
-                $host .= ':'.$this->params['port'];
314
-
315
-                return $host;
316
-                break;
317
-        }
318
-    }
18
+	/** A primary socket */
19
+	private $stream;
20
+
21
+	/** The input stream */
22
+	private $in;
23
+
24
+	/** The output stream */
25
+	private $out;
26
+
27
+	/** Buffer initialization parameters */
28
+	private $params = [];
29
+
30
+	/** The ReplacementFilterFactory */
31
+	private $replacementFactory;
32
+
33
+	/** Translations performed on data being streamed into the buffer */
34
+	private $translations = [];
35
+
36
+	/**
37
+	 * Create a new StreamBuffer using $replacementFactory for transformations.
38
+	 */
39
+	public function __construct(Swift_ReplacementFilterFactory $replacementFactory)
40
+	{
41
+		$this->replacementFactory = $replacementFactory;
42
+	}
43
+
44
+	/**
45
+	 * Perform any initialization needed, using the given $params.
46
+	 *
47
+	 * Parameters will vary depending upon the type of IoBuffer used.
48
+	 */
49
+	public function initialize(array $params)
50
+	{
51
+		$this->params = $params;
52
+		switch ($params['type']) {
53
+			case self::TYPE_PROCESS:
54
+				$this->establishProcessConnection();
55
+				break;
56
+			case self::TYPE_SOCKET:
57
+			default:
58
+				$this->establishSocketConnection();
59
+				break;
60
+		}
61
+	}
62
+
63
+	/**
64
+	 * Set an individual param on the buffer (e.g. switching to SSL).
65
+	 *
66
+	 * @param string $param
67
+	 * @param mixed  $value
68
+	 */
69
+	public function setParam($param, $value)
70
+	{
71
+		if (isset($this->stream)) {
72
+			switch ($param) {
73
+				case 'timeout':
74
+					if ($this->stream) {
75
+						stream_set_timeout($this->stream, $value);
76
+					}
77
+					break;
78
+
79
+				case 'blocking':
80
+					if ($this->stream) {
81
+						stream_set_blocking($this->stream, 1);
82
+					}
83
+			}
84
+		}
85
+		$this->params[$param] = $value;
86
+	}
87
+
88
+	public function startTLS()
89
+	{
90
+		// STREAM_CRYPTO_METHOD_TLS_CLIENT only allow tls1.0 connections (some php versions)
91
+		// To support modern tls we allow explicit tls1.0, tls1.1, tls1.2
92
+		// Ssl3 and older are not allowed because they are vulnerable
93
+		// @TODO make tls arguments configurable
94
+		return stream_socket_enable_crypto($this->stream, true, STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);
95
+	}
96
+
97
+	/**
98
+	 * Perform any shutdown logic needed.
99
+	 */
100
+	public function terminate()
101
+	{
102
+		if (isset($this->stream)) {
103
+			switch ($this->params['type']) {
104
+				case self::TYPE_PROCESS:
105
+					fclose($this->in);
106
+					fclose($this->out);
107
+					proc_close($this->stream);
108
+					break;
109
+				case self::TYPE_SOCKET:
110
+				default:
111
+					fclose($this->stream);
112
+					break;
113
+			}
114
+		}
115
+		$this->stream = null;
116
+		$this->out = null;
117
+		$this->in = null;
118
+	}
119
+
120
+	/**
121
+	 * Set an array of string replacements which should be made on data written
122
+	 * to the buffer.
123
+	 *
124
+	 * This could replace LF with CRLF for example.
125
+	 *
126
+	 * @param string[] $replacements
127
+	 */
128
+	public function setWriteTranslations(array $replacements)
129
+	{
130
+		foreach ($this->translations as $search => $replace) {
131
+			if (!isset($replacements[$search])) {
132
+				$this->removeFilter($search);
133
+				unset($this->translations[$search]);
134
+			}
135
+		}
136
+
137
+		foreach ($replacements as $search => $replace) {
138
+			if (!isset($this->translations[$search])) {
139
+				$this->addFilter(
140
+					$this->replacementFactory->createFilter($search, $replace), $search
141
+					);
142
+				$this->translations[$search] = true;
143
+			}
144
+		}
145
+	}
146
+
147
+	/**
148
+	 * Get a line of output (including any CRLF).
149
+	 *
150
+	 * The $sequence number comes from any writes and may or may not be used
151
+	 * depending upon the implementation.
152
+	 *
153
+	 * @param int $sequence of last write to scan from
154
+	 *
155
+	 * @return string
156
+	 *
157
+	 * @throws Swift_IoException
158
+	 */
159
+	public function readLine($sequence)
160
+	{
161
+		if (isset($this->out) && !feof($this->out)) {
162
+			$line = fgets($this->out);
163
+			if (0 == \strlen($line)) {
164
+				$metas = stream_get_meta_data($this->out);
165
+				if ($metas['timed_out']) {
166
+					throw new Swift_IoException('Connection to '.$this->getReadConnectionDescription().' Timed Out');
167
+				}
168
+			}
169
+
170
+			return $line;
171
+		}
172
+	}
173
+
174
+	/**
175
+	 * Reads $length bytes from the stream into a string and moves the pointer
176
+	 * through the stream by $length.
177
+	 *
178
+	 * If less bytes exist than are requested the remaining bytes are given instead.
179
+	 * If no bytes are remaining at all, boolean false is returned.
180
+	 *
181
+	 * @param int $length
182
+	 *
183
+	 * @return string|bool
184
+	 *
185
+	 * @throws Swift_IoException
186
+	 */
187
+	public function read($length)
188
+	{
189
+		if (isset($this->out) && !feof($this->out)) {
190
+			$ret = fread($this->out, $length);
191
+			if (0 == \strlen($ret)) {
192
+				$metas = stream_get_meta_data($this->out);
193
+				if ($metas['timed_out']) {
194
+					throw new Swift_IoException('Connection to '.$this->getReadConnectionDescription().' Timed Out');
195
+				}
196
+			}
197
+
198
+			return $ret;
199
+		}
200
+	}
201
+
202
+	/** Not implemented */
203
+	public function setReadPointer($byteOffset)
204
+	{
205
+	}
206
+
207
+	/** Flush the stream contents */
208
+	protected function flush()
209
+	{
210
+		if (isset($this->in)) {
211
+			fflush($this->in);
212
+		}
213
+	}
214
+
215
+	/** Write this bytes to the stream */
216
+	protected function doCommit($bytes)
217
+	{
218
+		if (isset($this->in)) {
219
+			$bytesToWrite = \strlen($bytes);
220
+			$totalBytesWritten = 0;
221
+
222
+			while ($totalBytesWritten < $bytesToWrite) {
223
+				$bytesWritten = fwrite($this->in, substr($bytes, $totalBytesWritten));
224
+				if (false === $bytesWritten || 0 === $bytesWritten) {
225
+					break;
226
+				}
227
+
228
+				$totalBytesWritten += $bytesWritten;
229
+			}
230
+
231
+			if ($totalBytesWritten > 0) {
232
+				return ++$this->sequence;
233
+			}
234
+		}
235
+	}
236
+
237
+	/**
238
+	 * Establishes a connection to a remote server.
239
+	 */
240
+	private function establishSocketConnection()
241
+	{
242
+		$host = $this->params['host'];
243
+		if (!empty($this->params['protocol'])) {
244
+			$host = $this->params['protocol'].'://'.$host;
245
+		}
246
+		$timeout = 15;
247
+		if (!empty($this->params['timeout'])) {
248
+			$timeout = $this->params['timeout'];
249
+		}
250
+		$options = [];
251
+		if (!empty($this->params['sourceIp'])) {
252
+			$options['socket']['bindto'] = $this->params['sourceIp'].':0';
253
+		}
254
+
255
+		if (isset($this->params['stream_context_options'])) {
256
+			$options = array_merge($options, $this->params['stream_context_options']);
257
+		}
258
+		$streamContext = stream_context_create($options);
259
+
260
+		set_error_handler(function ($type, $msg) {
261
+			throw new Swift_TransportException('Connection could not be established with host '.$this->params['host'].' :'.$msg);
262
+		});
263
+		try {
264
+			$this->stream = stream_socket_client($host.':'.$this->params['port'], $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $streamContext);
265
+		} finally {
266
+			restore_error_handler();
267
+		}
268
+
269
+		if (!empty($this->params['blocking'])) {
270
+			stream_set_blocking($this->stream, 1);
271
+		} else {
272
+			stream_set_blocking($this->stream, 0);
273
+		}
274
+		stream_set_timeout($this->stream, $timeout);
275
+		$this->in = &$this->stream;
276
+		$this->out = &$this->stream;
277
+	}
278
+
279
+	/**
280
+	 * Opens a process for input/output.
281
+	 */
282
+	private function establishProcessConnection()
283
+	{
284
+		$command = $this->params['command'];
285
+		$descriptorSpec = [
286
+			0 => ['pipe', 'r'],
287
+			1 => ['pipe', 'w'],
288
+			2 => ['pipe', 'w'],
289
+			];
290
+		$pipes = [];
291
+		$this->stream = proc_open($command, $descriptorSpec, $pipes);
292
+		stream_set_blocking($pipes[2], 0);
293
+		if ($err = stream_get_contents($pipes[2])) {
294
+			throw new Swift_TransportException('Process could not be started ['.$err.']');
295
+		}
296
+		$this->in = &$pipes[0];
297
+		$this->out = &$pipes[1];
298
+	}
299
+
300
+	private function getReadConnectionDescription()
301
+	{
302
+		switch ($this->params['type']) {
303
+			case self::TYPE_PROCESS:
304
+				return 'Process '.$this->params['command'];
305
+				break;
306
+
307
+			case self::TYPE_SOCKET:
308
+			default:
309
+				$host = $this->params['host'];
310
+				if (!empty($this->params['protocol'])) {
311
+					$host = $this->params['protocol'].'://'.$host;
312
+				}
313
+				$host .= ':'.$this->params['port'];
314
+
315
+				return $host;
316
+				break;
317
+		}
318
+	}
319 319
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -257,7 +257,7 @@
 block discarded – undo
257 257
         }
258 258
         $streamContext = stream_context_create($options);
259 259
 
260
-        set_error_handler(function ($type, $msg) {
260
+        set_error_handler(function($type, $msg) {
261 261
             throw new Swift_TransportException('Connection could not be established with host '.$this->params['host'].' :'.$msg);
262 262
         });
263 263
         try {
Please login to merge, or discard this patch.
includes/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php 1 patch
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -15,22 +15,22 @@
 block discarded – undo
15 15
  */
16 16
 interface Swift_Transport_Esmtp_Authenticator
17 17
 {
18
-    /**
19
-     * Get the name of the AUTH mechanism this Authenticator handles.
20
-     *
21
-     * @return string
22
-     */
23
-    public function getAuthKeyword();
18
+	/**
19
+	 * Get the name of the AUTH mechanism this Authenticator handles.
20
+	 *
21
+	 * @return string
22
+	 */
23
+	public function getAuthKeyword();
24 24
 
25
-    /**
26
-     * Try to authenticate the user with $username and $password.
27
-     *
28
-     * @param string $username
29
-     * @param string $password
30
-     *
31
-     * @return bool true if authentication worked (returning false is deprecated, throw a Swift_TransportException instead)
32
-     *
33
-     * @throws Swift_TransportException Allows the message to bubble up when authentication was not successful
34
-     */
35
-    public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password);
25
+	/**
26
+	 * Try to authenticate the user with $username and $password.
27
+	 *
28
+	 * @param string $username
29
+	 * @param string $password
30
+	 *
31
+	 * @return bool true if authentication worked (returning false is deprecated, throw a Swift_TransportException instead)
32
+	 *
33
+	 * @throws Swift_TransportException Allows the message to bubble up when authentication was not successful
34
+	 */
35
+	public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password);
36 36
 }
Please login to merge, or discard this patch.
includes/swiftmailer/lib/classes/Swift/Transport/Esmtp/SmtpUtf8Handler.php 1 patch
Indentation   +72 added lines, -72 removed lines patch added patch discarded remove patch
@@ -23,85 +23,85 @@
 block discarded – undo
23 23
  */
24 24
 class Swift_Transport_Esmtp_SmtpUtf8Handler implements Swift_Transport_EsmtpHandler
25 25
 {
26
-    public function __construct()
27
-    {
28
-    }
26
+	public function __construct()
27
+	{
28
+	}
29 29
 
30
-    /**
31
-     * Get the name of the ESMTP extension this handles.
32
-     *
33
-     * @return string
34
-     */
35
-    public function getHandledKeyword()
36
-    {
37
-        return 'SMTPUTF8';
38
-    }
30
+	/**
31
+	 * Get the name of the ESMTP extension this handles.
32
+	 *
33
+	 * @return string
34
+	 */
35
+	public function getHandledKeyword()
36
+	{
37
+		return 'SMTPUTF8';
38
+	}
39 39
 
40
-    /**
41
-     * Not used.
42
-     */
43
-    public function setKeywordParams(array $parameters)
44
-    {
45
-    }
40
+	/**
41
+	 * Not used.
42
+	 */
43
+	public function setKeywordParams(array $parameters)
44
+	{
45
+	}
46 46
 
47
-    /**
48
-     * Not used.
49
-     */
50
-    public function afterEhlo(Swift_Transport_SmtpAgent $agent)
51
-    {
52
-    }
47
+	/**
48
+	 * Not used.
49
+	 */
50
+	public function afterEhlo(Swift_Transport_SmtpAgent $agent)
51
+	{
52
+	}
53 53
 
54
-    /**
55
-     * Get params which are appended to MAIL FROM:<>.
56
-     *
57
-     * @return string[]
58
-     */
59
-    public function getMailParams()
60
-    {
61
-        return ['SMTPUTF8'];
62
-    }
54
+	/**
55
+	 * Get params which are appended to MAIL FROM:<>.
56
+	 *
57
+	 * @return string[]
58
+	 */
59
+	public function getMailParams()
60
+	{
61
+		return ['SMTPUTF8'];
62
+	}
63 63
 
64
-    /**
65
-     * Not used.
66
-     */
67
-    public function getRcptParams()
68
-    {
69
-        return [];
70
-    }
64
+	/**
65
+	 * Not used.
66
+	 */
67
+	public function getRcptParams()
68
+	{
69
+		return [];
70
+	}
71 71
 
72
-    /**
73
-     * Not used.
74
-     */
75
-    public function onCommand(Swift_Transport_SmtpAgent $agent, $command, $codes = [], &$failedRecipients = null, &$stop = false)
76
-    {
77
-    }
72
+	/**
73
+	 * Not used.
74
+	 */
75
+	public function onCommand(Swift_Transport_SmtpAgent $agent, $command, $codes = [], &$failedRecipients = null, &$stop = false)
76
+	{
77
+	}
78 78
 
79
-    /**
80
-     * Returns +1, -1 or 0 according to the rules for usort().
81
-     *
82
-     * This method is called to ensure extensions can be execute in an appropriate order.
83
-     *
84
-     * @param string $esmtpKeyword to compare with
85
-     *
86
-     * @return int
87
-     */
88
-    public function getPriorityOver($esmtpKeyword)
89
-    {
90
-        return 0;
91
-    }
79
+	/**
80
+	 * Returns +1, -1 or 0 according to the rules for usort().
81
+	 *
82
+	 * This method is called to ensure extensions can be execute in an appropriate order.
83
+	 *
84
+	 * @param string $esmtpKeyword to compare with
85
+	 *
86
+	 * @return int
87
+	 */
88
+	public function getPriorityOver($esmtpKeyword)
89
+	{
90
+		return 0;
91
+	}
92 92
 
93
-    /**
94
-     * Not used.
95
-     */
96
-    public function exposeMixinMethods()
97
-    {
98
-        return [];
99
-    }
93
+	/**
94
+	 * Not used.
95
+	 */
96
+	public function exposeMixinMethods()
97
+	{
98
+		return [];
99
+	}
100 100
 
101
-    /**
102
-     * Not used.
103
-     */
104
-    public function resetState()
105
-    {
106
-    }
101
+	/**
102
+	 * Not used.
103
+	 */
104
+	public function resetState()
105
+	{
106
+	}
107 107
 }
Please login to merge, or discard this patch.
swiftmailer/lib/classes/Swift/Transport/Esmtp/EightBitMimeHandler.php 1 patch
Indentation   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -22,92 +22,92 @@
 block discarded – undo
22 22
  */
23 23
 class Swift_Transport_Esmtp_EightBitMimeHandler implements Swift_Transport_EsmtpHandler
24 24
 {
25
-    protected $encoding;
25
+	protected $encoding;
26 26
 
27
-    /**
28
-     * @param string $encoding The parameter so send with the MAIL FROM command;
29
-     *                         either "8BITMIME" or "7BIT"
30
-     */
31
-    public function __construct(string $encoding = '8BITMIME')
32
-    {
33
-        $this->encoding = $encoding;
34
-    }
27
+	/**
28
+	 * @param string $encoding The parameter so send with the MAIL FROM command;
29
+	 *                         either "8BITMIME" or "7BIT"
30
+	 */
31
+	public function __construct(string $encoding = '8BITMIME')
32
+	{
33
+		$this->encoding = $encoding;
34
+	}
35 35
 
36
-    /**
37
-     * Get the name of the ESMTP extension this handles.
38
-     *
39
-     * @return string
40
-     */
41
-    public function getHandledKeyword()
42
-    {
43
-        return '8BITMIME';
44
-    }
36
+	/**
37
+	 * Get the name of the ESMTP extension this handles.
38
+	 *
39
+	 * @return string
40
+	 */
41
+	public function getHandledKeyword()
42
+	{
43
+		return '8BITMIME';
44
+	}
45 45
 
46
-    /**
47
-     * Not used.
48
-     */
49
-    public function setKeywordParams(array $parameters)
50
-    {
51
-    }
46
+	/**
47
+	 * Not used.
48
+	 */
49
+	public function setKeywordParams(array $parameters)
50
+	{
51
+	}
52 52
 
53
-    /**
54
-     * Not used.
55
-     */
56
-    public function afterEhlo(Swift_Transport_SmtpAgent $agent)
57
-    {
58
-    }
53
+	/**
54
+	 * Not used.
55
+	 */
56
+	public function afterEhlo(Swift_Transport_SmtpAgent $agent)
57
+	{
58
+	}
59 59
 
60
-    /**
61
-     * Get params which are appended to MAIL FROM:<>.
62
-     *
63
-     * @return string[]
64
-     */
65
-    public function getMailParams()
66
-    {
67
-        return ['BODY='.$this->encoding];
68
-    }
60
+	/**
61
+	 * Get params which are appended to MAIL FROM:<>.
62
+	 *
63
+	 * @return string[]
64
+	 */
65
+	public function getMailParams()
66
+	{
67
+		return ['BODY='.$this->encoding];
68
+	}
69 69
 
70
-    /**
71
-     * Not used.
72
-     */
73
-    public function getRcptParams()
74
-    {
75
-        return [];
76
-    }
70
+	/**
71
+	 * Not used.
72
+	 */
73
+	public function getRcptParams()
74
+	{
75
+		return [];
76
+	}
77 77
 
78
-    /**
79
-     * Not used.
80
-     */
81
-    public function onCommand(Swift_Transport_SmtpAgent $agent, $command, $codes = [], &$failedRecipients = null, &$stop = false)
82
-    {
83
-    }
78
+	/**
79
+	 * Not used.
80
+	 */
81
+	public function onCommand(Swift_Transport_SmtpAgent $agent, $command, $codes = [], &$failedRecipients = null, &$stop = false)
82
+	{
83
+	}
84 84
 
85
-    /**
86
-     * Returns +1, -1 or 0 according to the rules for usort().
87
-     *
88
-     * This method is called to ensure extensions can be execute in an appropriate order.
89
-     *
90
-     * @param string $esmtpKeyword to compare with
91
-     *
92
-     * @return int
93
-     */
94
-    public function getPriorityOver($esmtpKeyword)
95
-    {
96
-        return 0;
97
-    }
85
+	/**
86
+	 * Returns +1, -1 or 0 according to the rules for usort().
87
+	 *
88
+	 * This method is called to ensure extensions can be execute in an appropriate order.
89
+	 *
90
+	 * @param string $esmtpKeyword to compare with
91
+	 *
92
+	 * @return int
93
+	 */
94
+	public function getPriorityOver($esmtpKeyword)
95
+	{
96
+		return 0;
97
+	}
98 98
 
99
-    /**
100
-     * Not used.
101
-     */
102
-    public function exposeMixinMethods()
103
-    {
104
-        return [];
105
-    }
99
+	/**
100
+	 * Not used.
101
+	 */
102
+	public function exposeMixinMethods()
103
+	{
104
+		return [];
105
+	}
106 106
 
107
-    /**
108
-     * Not used.
109
-     */
110
-    public function resetState()
111
-    {
112
-    }
107
+	/**
108
+	 * Not used.
109
+	 */
110
+	public function resetState()
111
+	{
112
+	}
113 113
 }
Please login to merge, or discard this patch.
swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php 1 patch
Indentation   +49 added lines, -49 removed lines patch added patch discarded remove patch
@@ -15,61 +15,61 @@
 block discarded – undo
15 15
  */
16 16
 class Swift_Transport_Esmtp_Auth_CramMd5Authenticator implements Swift_Transport_Esmtp_Authenticator
17 17
 {
18
-    /**
19
-     * Get the name of the AUTH mechanism this Authenticator handles.
20
-     *
21
-     * @return string
22
-     */
23
-    public function getAuthKeyword()
24
-    {
25
-        return 'CRAM-MD5';
26
-    }
18
+	/**
19
+	 * Get the name of the AUTH mechanism this Authenticator handles.
20
+	 *
21
+	 * @return string
22
+	 */
23
+	public function getAuthKeyword()
24
+	{
25
+		return 'CRAM-MD5';
26
+	}
27 27
 
28
-    /**
29
-     * {@inheritdoc}
30
-     */
31
-    public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password)
32
-    {
33
-        try {
34
-            $challenge = $agent->executeCommand("AUTH CRAM-MD5\r\n", [334]);
35
-            $challenge = base64_decode(substr($challenge, 4));
36
-            $message = base64_encode(
37
-                $username.' '.$this->getResponse($password, $challenge)
38
-            );
39
-            $agent->executeCommand(sprintf("%s\r\n", $message), [235]);
28
+	/**
29
+	 * {@inheritdoc}
30
+	 */
31
+	public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password)
32
+	{
33
+		try {
34
+			$challenge = $agent->executeCommand("AUTH CRAM-MD5\r\n", [334]);
35
+			$challenge = base64_decode(substr($challenge, 4));
36
+			$message = base64_encode(
37
+				$username.' '.$this->getResponse($password, $challenge)
38
+			);
39
+			$agent->executeCommand(sprintf("%s\r\n", $message), [235]);
40 40
 
41
-            return true;
42
-        } catch (Swift_TransportException $e) {
43
-            $agent->executeCommand("RSET\r\n", [250]);
41
+			return true;
42
+		} catch (Swift_TransportException $e) {
43
+			$agent->executeCommand("RSET\r\n", [250]);
44 44
 
45
-            throw $e;
46
-        }
47
-    }
45
+			throw $e;
46
+		}
47
+	}
48 48
 
49
-    /**
50
-     * Generate a CRAM-MD5 response from a server challenge.
51
-     *
52
-     * @param string $secret
53
-     * @param string $challenge
54
-     *
55
-     * @return string
56
-     */
57
-    private function getResponse($secret, $challenge)
58
-    {
59
-        if (\strlen($secret) > 64) {
60
-            $secret = pack('H32', md5($secret));
61
-        }
49
+	/**
50
+	 * Generate a CRAM-MD5 response from a server challenge.
51
+	 *
52
+	 * @param string $secret
53
+	 * @param string $challenge
54
+	 *
55
+	 * @return string
56
+	 */
57
+	private function getResponse($secret, $challenge)
58
+	{
59
+		if (\strlen($secret) > 64) {
60
+			$secret = pack('H32', md5($secret));
61
+		}
62 62
 
63
-        if (\strlen($secret) < 64) {
64
-            $secret = str_pad($secret, 64, \chr(0));
65
-        }
63
+		if (\strlen($secret) < 64) {
64
+			$secret = str_pad($secret, 64, \chr(0));
65
+		}
66 66
 
67
-        $k_ipad = substr($secret, 0, 64) ^ str_repeat(\chr(0x36), 64);
68
-        $k_opad = substr($secret, 0, 64) ^ str_repeat(\chr(0x5C), 64);
67
+		$k_ipad = substr($secret, 0, 64) ^ str_repeat(\chr(0x36), 64);
68
+		$k_opad = substr($secret, 0, 64) ^ str_repeat(\chr(0x5C), 64);
69 69
 
70
-        $inner = pack('H32', md5($k_ipad.$challenge));
71
-        $digest = md5($k_opad.$inner);
70
+		$inner = pack('H32', md5($k_ipad.$challenge));
71
+		$digest = md5($k_opad.$inner);
72 72
 
73
-        return $digest;
74
-    }
73
+		return $digest;
74
+	}
75 75
 }
Please login to merge, or discard this patch.
swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -15,31 +15,31 @@
 block discarded – undo
15 15
  */
16 16
 class Swift_Transport_Esmtp_Auth_LoginAuthenticator implements Swift_Transport_Esmtp_Authenticator
17 17
 {
18
-    /**
19
-     * Get the name of the AUTH mechanism this Authenticator handles.
20
-     *
21
-     * @return string
22
-     */
23
-    public function getAuthKeyword()
24
-    {
25
-        return 'LOGIN';
26
-    }
18
+	/**
19
+	 * Get the name of the AUTH mechanism this Authenticator handles.
20
+	 *
21
+	 * @return string
22
+	 */
23
+	public function getAuthKeyword()
24
+	{
25
+		return 'LOGIN';
26
+	}
27 27
 
28
-    /**
29
-     * {@inheritdoc}
30
-     */
31
-    public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password)
32
-    {
33
-        try {
34
-            $agent->executeCommand("AUTH LOGIN\r\n", [334]);
35
-            $agent->executeCommand(sprintf("%s\r\n", base64_encode($username ?? '')), [334]);
36
-            $agent->executeCommand(sprintf("%s\r\n", base64_encode($password ?? '')), [235]);
28
+	/**
29
+	 * {@inheritdoc}
30
+	 */
31
+	public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password)
32
+	{
33
+		try {
34
+			$agent->executeCommand("AUTH LOGIN\r\n", [334]);
35
+			$agent->executeCommand(sprintf("%s\r\n", base64_encode($username ?? '')), [334]);
36
+			$agent->executeCommand(sprintf("%s\r\n", base64_encode($password ?? '')), [235]);
37 37
 
38
-            return true;
39
-        } catch (Swift_TransportException $e) {
40
-            $agent->executeCommand("RSET\r\n", [250]);
38
+			return true;
39
+		} catch (Swift_TransportException $e) {
40
+			$agent->executeCommand("RSET\r\n", [250]);
41 41
 
42
-            throw $e;
43
-        }
44
-    }
42
+			throw $e;
43
+		}
44
+	}
45 45
 }
Please login to merge, or discard this patch.
swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php 2 patches
Indentation   +649 added lines, -649 removed lines patch added patch discarded remove patch
@@ -17,229 +17,229 @@  discard block
 block discarded – undo
17 17
  */
18 18
 class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Esmtp_Authenticator
19 19
 {
20
-    const NTLMSIG = "NTLMSSP\x00";
21
-    const DESCONST = 'KGS!@#$%';
22
-
23
-    /**
24
-     * Get the name of the AUTH mechanism this Authenticator handles.
25
-     *
26
-     * @return string
27
-     */
28
-    public function getAuthKeyword()
29
-    {
30
-        return 'NTLM';
31
-    }
32
-
33
-    /**
34
-     * {@inheritdoc}
35
-     *
36
-     * @throws \LogicException
37
-     */
38
-    public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password)
39
-    {
40
-        if (!\function_exists('openssl_encrypt')) {
41
-            throw new LogicException('The OpenSSL extension must be enabled to use the NTLM authenticator.');
42
-        }
43
-
44
-        if (!\function_exists('bcmul')) {
45
-            throw new LogicException('The BCMath functions must be enabled to use the NTLM authenticator.');
46
-        }
47
-
48
-        try {
49
-            // execute AUTH command and filter out the code at the beginning
50
-            // AUTH NTLM xxxx
51
-            $response = base64_decode(substr(trim($this->sendMessage1($agent) ?? ''), 4));
52
-
53
-            // extra parameters for our unit cases
54
-            $timestamp = \func_num_args() > 3 ? func_get_arg(3) : $this->getCorrectTimestamp(bcmul(microtime(true), '1000'));
55
-            $client = \func_num_args() > 4 ? func_get_arg(4) : random_bytes(8);
56
-
57
-            // Message 3 response
58
-            $this->sendMessage3($response, $username, $password, $timestamp, $client, $agent);
59
-
60
-            return true;
61
-        } catch (Swift_TransportException $e) {
62
-            $agent->executeCommand("RSET\r\n", [250]);
63
-
64
-            throw $e;
65
-        }
66
-    }
67
-
68
-    protected function si2bin($si, $bits = 32)
69
-    {
70
-        $bin = null;
71
-        if ($si >= -2 ** ($bits - 1) && ($si <= 2 ** ($bits - 1))) {
72
-            // positive or zero
73
-            if ($si >= 0) {
74
-                $bin = base_convert($si, 10, 2);
75
-                // pad to $bits bit
76
-                $bin_length = \strlen($bin);
77
-                if ($bin_length < $bits) {
78
-                    $bin = str_repeat('0', $bits - $bin_length).$bin;
79
-                }
80
-            } else {
81
-                // negative
82
-                $si = -$si - 2 ** $bits;
83
-                $bin = base_convert($si, 10, 2);
84
-                $bin_length = \strlen($bin);
85
-                if ($bin_length > $bits) {
86
-                    $bin = str_repeat('1', $bits - $bin_length).$bin;
87
-                }
88
-            }
89
-        }
90
-
91
-        return $bin;
92
-    }
93
-
94
-    /**
95
-     * Send our auth message and returns the response.
96
-     *
97
-     * @return string SMTP Response
98
-     */
99
-    protected function sendMessage1(Swift_Transport_SmtpAgent $agent)
100
-    {
101
-        $message = $this->createMessage1();
102
-
103
-        return $agent->executeCommand(sprintf("AUTH %s %s\r\n", $this->getAuthKeyword(), base64_encode($message)), [334]);
104
-    }
105
-
106
-    /**
107
-     * Fetch all details of our response (message 2).
108
-     *
109
-     * @param string $response
110
-     *
111
-     * @return array our response parsed
112
-     */
113
-    protected function parseMessage2($response)
114
-    {
115
-        $responseHex = bin2hex($response);
116
-        $length = floor(hexdec(substr($responseHex, 28, 4)) / 256) * 2;
117
-        $offset = floor(hexdec(substr($responseHex, 32, 4)) / 256) * 2;
118
-        $challenge = hex2bin(substr($responseHex, 48, 16));
119
-        $context = hex2bin(substr($responseHex, 64, 16));
120
-        $targetInfoH = hex2bin(substr($responseHex, 80, 16));
121
-        $targetName = hex2bin(substr($responseHex, $offset, $length));
122
-        $offset = floor(hexdec(substr($responseHex, 88, 4)) / 256) * 2;
123
-        $targetInfoBlock = substr($responseHex, $offset);
124
-        list($domainName, $serverName, $DNSDomainName, $DNSServerName, $terminatorByte) = $this->readSubBlock($targetInfoBlock);
125
-
126
-        return [
127
-            $challenge,
128
-            $context,
129
-            $targetInfoH,
130
-            $targetName,
131
-            $domainName,
132
-            $serverName,
133
-            $DNSDomainName,
134
-            $DNSServerName,
135
-            hex2bin($targetInfoBlock),
136
-            $terminatorByte,
137
-        ];
138
-    }
139
-
140
-    /**
141
-     * Read the blob information in from message2.
142
-     *
143
-     * @return array
144
-     */
145
-    protected function readSubBlock($block)
146
-    {
147
-        // remove terminatorByte cause it's always the same
148
-        $block = substr($block, 0, -8);
149
-
150
-        $length = \strlen($block);
151
-        $offset = 0;
152
-        $data = [];
153
-        while ($offset < $length) {
154
-            $blockLength = hexdec(substr(substr($block, $offset, 8), -4)) / 256;
155
-            $offset += 8;
156
-            $data[] = hex2bin(substr($block, $offset, $blockLength * 2));
157
-            $offset += $blockLength * 2;
158
-        }
159
-
160
-        if (3 == \count($data)) {
161
-            $data[] = $data[2];
162
-            $data[2] = '';
163
-        }
164
-
165
-        $data[] = $this->createByte('00');
166
-
167
-        return $data;
168
-    }
169
-
170
-    /**
171
-     * Send our final message with all our data.
172
-     *
173
-     * @param string $response  Message 1 response (message 2)
174
-     * @param string $username
175
-     * @param string $password
176
-     * @param string $timestamp
177
-     * @param string $client
178
-     * @param bool   $v2        Use version2 of the protocol
179
-     *
180
-     * @return string
181
-     */
182
-    protected function sendMessage3($response, $username, $password, $timestamp, $client, Swift_Transport_SmtpAgent $agent, $v2 = true)
183
-    {
184
-        list($domain, $username) = $this->getDomainAndUsername($username);
185
-        //$challenge, $context, $targetInfoH, $targetName, $domainName, $workstation, $DNSDomainName, $DNSServerName, $blob, $ter
186
-        list($challenge, , , , , $workstation, , , $blob) = $this->parseMessage2($response);
187
-
188
-        if (!$v2) {
189
-            // LMv1
190
-            $lmResponse = $this->createLMPassword($password, $challenge);
191
-            // NTLMv1
192
-            $ntlmResponse = $this->createNTLMPassword($password, $challenge);
193
-        } else {
194
-            // LMv2
195
-            $lmResponse = $this->createLMv2Password($password, $username, $domain, $challenge, $client);
196
-            // NTLMv2
197
-            $ntlmResponse = $this->createNTLMv2Hash($password, $username, $domain, $challenge, $blob, $timestamp, $client);
198
-        }
199
-
200
-        $message = $this->createMessage3($domain, $username, $workstation, $lmResponse, $ntlmResponse);
201
-
202
-        return $agent->executeCommand(sprintf("%s\r\n", base64_encode($message)), [235]);
203
-    }
204
-
205
-    /**
206
-     * Create our message 1.
207
-     *
208
-     * @return string
209
-     */
210
-    protected function createMessage1()
211
-    {
212
-        return self::NTLMSIG
213
-        .$this->createByte('01') // Message 1
20
+	const NTLMSIG = "NTLMSSP\x00";
21
+	const DESCONST = 'KGS!@#$%';
22
+
23
+	/**
24
+	 * Get the name of the AUTH mechanism this Authenticator handles.
25
+	 *
26
+	 * @return string
27
+	 */
28
+	public function getAuthKeyword()
29
+	{
30
+		return 'NTLM';
31
+	}
32
+
33
+	/**
34
+	 * {@inheritdoc}
35
+	 *
36
+	 * @throws \LogicException
37
+	 */
38
+	public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password)
39
+	{
40
+		if (!\function_exists('openssl_encrypt')) {
41
+			throw new LogicException('The OpenSSL extension must be enabled to use the NTLM authenticator.');
42
+		}
43
+
44
+		if (!\function_exists('bcmul')) {
45
+			throw new LogicException('The BCMath functions must be enabled to use the NTLM authenticator.');
46
+		}
47
+
48
+		try {
49
+			// execute AUTH command and filter out the code at the beginning
50
+			// AUTH NTLM xxxx
51
+			$response = base64_decode(substr(trim($this->sendMessage1($agent) ?? ''), 4));
52
+
53
+			// extra parameters for our unit cases
54
+			$timestamp = \func_num_args() > 3 ? func_get_arg(3) : $this->getCorrectTimestamp(bcmul(microtime(true), '1000'));
55
+			$client = \func_num_args() > 4 ? func_get_arg(4) : random_bytes(8);
56
+
57
+			// Message 3 response
58
+			$this->sendMessage3($response, $username, $password, $timestamp, $client, $agent);
59
+
60
+			return true;
61
+		} catch (Swift_TransportException $e) {
62
+			$agent->executeCommand("RSET\r\n", [250]);
63
+
64
+			throw $e;
65
+		}
66
+	}
67
+
68
+	protected function si2bin($si, $bits = 32)
69
+	{
70
+		$bin = null;
71
+		if ($si >= -2 ** ($bits - 1) && ($si <= 2 ** ($bits - 1))) {
72
+			// positive or zero
73
+			if ($si >= 0) {
74
+				$bin = base_convert($si, 10, 2);
75
+				// pad to $bits bit
76
+				$bin_length = \strlen($bin);
77
+				if ($bin_length < $bits) {
78
+					$bin = str_repeat('0', $bits - $bin_length).$bin;
79
+				}
80
+			} else {
81
+				// negative
82
+				$si = -$si - 2 ** $bits;
83
+				$bin = base_convert($si, 10, 2);
84
+				$bin_length = \strlen($bin);
85
+				if ($bin_length > $bits) {
86
+					$bin = str_repeat('1', $bits - $bin_length).$bin;
87
+				}
88
+			}
89
+		}
90
+
91
+		return $bin;
92
+	}
93
+
94
+	/**
95
+	 * Send our auth message and returns the response.
96
+	 *
97
+	 * @return string SMTP Response
98
+	 */
99
+	protected function sendMessage1(Swift_Transport_SmtpAgent $agent)
100
+	{
101
+		$message = $this->createMessage1();
102
+
103
+		return $agent->executeCommand(sprintf("AUTH %s %s\r\n", $this->getAuthKeyword(), base64_encode($message)), [334]);
104
+	}
105
+
106
+	/**
107
+	 * Fetch all details of our response (message 2).
108
+	 *
109
+	 * @param string $response
110
+	 *
111
+	 * @return array our response parsed
112
+	 */
113
+	protected function parseMessage2($response)
114
+	{
115
+		$responseHex = bin2hex($response);
116
+		$length = floor(hexdec(substr($responseHex, 28, 4)) / 256) * 2;
117
+		$offset = floor(hexdec(substr($responseHex, 32, 4)) / 256) * 2;
118
+		$challenge = hex2bin(substr($responseHex, 48, 16));
119
+		$context = hex2bin(substr($responseHex, 64, 16));
120
+		$targetInfoH = hex2bin(substr($responseHex, 80, 16));
121
+		$targetName = hex2bin(substr($responseHex, $offset, $length));
122
+		$offset = floor(hexdec(substr($responseHex, 88, 4)) / 256) * 2;
123
+		$targetInfoBlock = substr($responseHex, $offset);
124
+		list($domainName, $serverName, $DNSDomainName, $DNSServerName, $terminatorByte) = $this->readSubBlock($targetInfoBlock);
125
+
126
+		return [
127
+			$challenge,
128
+			$context,
129
+			$targetInfoH,
130
+			$targetName,
131
+			$domainName,
132
+			$serverName,
133
+			$DNSDomainName,
134
+			$DNSServerName,
135
+			hex2bin($targetInfoBlock),
136
+			$terminatorByte,
137
+		];
138
+	}
139
+
140
+	/**
141
+	 * Read the blob information in from message2.
142
+	 *
143
+	 * @return array
144
+	 */
145
+	protected function readSubBlock($block)
146
+	{
147
+		// remove terminatorByte cause it's always the same
148
+		$block = substr($block, 0, -8);
149
+
150
+		$length = \strlen($block);
151
+		$offset = 0;
152
+		$data = [];
153
+		while ($offset < $length) {
154
+			$blockLength = hexdec(substr(substr($block, $offset, 8), -4)) / 256;
155
+			$offset += 8;
156
+			$data[] = hex2bin(substr($block, $offset, $blockLength * 2));
157
+			$offset += $blockLength * 2;
158
+		}
159
+
160
+		if (3 == \count($data)) {
161
+			$data[] = $data[2];
162
+			$data[2] = '';
163
+		}
164
+
165
+		$data[] = $this->createByte('00');
166
+
167
+		return $data;
168
+	}
169
+
170
+	/**
171
+	 * Send our final message with all our data.
172
+	 *
173
+	 * @param string $response  Message 1 response (message 2)
174
+	 * @param string $username
175
+	 * @param string $password
176
+	 * @param string $timestamp
177
+	 * @param string $client
178
+	 * @param bool   $v2        Use version2 of the protocol
179
+	 *
180
+	 * @return string
181
+	 */
182
+	protected function sendMessage3($response, $username, $password, $timestamp, $client, Swift_Transport_SmtpAgent $agent, $v2 = true)
183
+	{
184
+		list($domain, $username) = $this->getDomainAndUsername($username);
185
+		//$challenge, $context, $targetInfoH, $targetName, $domainName, $workstation, $DNSDomainName, $DNSServerName, $blob, $ter
186
+		list($challenge, , , , , $workstation, , , $blob) = $this->parseMessage2($response);
187
+
188
+		if (!$v2) {
189
+			// LMv1
190
+			$lmResponse = $this->createLMPassword($password, $challenge);
191
+			// NTLMv1
192
+			$ntlmResponse = $this->createNTLMPassword($password, $challenge);
193
+		} else {
194
+			// LMv2
195
+			$lmResponse = $this->createLMv2Password($password, $username, $domain, $challenge, $client);
196
+			// NTLMv2
197
+			$ntlmResponse = $this->createNTLMv2Hash($password, $username, $domain, $challenge, $blob, $timestamp, $client);
198
+		}
199
+
200
+		$message = $this->createMessage3($domain, $username, $workstation, $lmResponse, $ntlmResponse);
201
+
202
+		return $agent->executeCommand(sprintf("%s\r\n", base64_encode($message)), [235]);
203
+	}
204
+
205
+	/**
206
+	 * Create our message 1.
207
+	 *
208
+	 * @return string
209
+	 */
210
+	protected function createMessage1()
211
+	{
212
+		return self::NTLMSIG
213
+		.$this->createByte('01') // Message 1
214 214
 .$this->createByte('0702'); // Flags
215
-    }
216
-
217
-    /**
218
-     * Create our message 3.
219
-     *
220
-     * @param string $domain
221
-     * @param string $username
222
-     * @param string $workstation
223
-     * @param string $lmResponse
224
-     * @param string $ntlmResponse
225
-     *
226
-     * @return string
227
-     */
228
-    protected function createMessage3($domain, $username, $workstation, $lmResponse, $ntlmResponse)
229
-    {
230
-        // Create security buffers
231
-        $domainSec = $this->createSecurityBuffer($domain, 64);
232
-        $domainInfo = $this->readSecurityBuffer(bin2hex($domainSec));
233
-        $userSec = $this->createSecurityBuffer($username, ($domainInfo[0] + $domainInfo[1]) / 2);
234
-        $userInfo = $this->readSecurityBuffer(bin2hex($userSec));
235
-        $workSec = $this->createSecurityBuffer($workstation, ($userInfo[0] + $userInfo[1]) / 2);
236
-        $workInfo = $this->readSecurityBuffer(bin2hex($workSec));
237
-        $lmSec = $this->createSecurityBuffer($lmResponse, ($workInfo[0] + $workInfo[1]) / 2, true);
238
-        $lmInfo = $this->readSecurityBuffer(bin2hex($lmSec));
239
-        $ntlmSec = $this->createSecurityBuffer($ntlmResponse, ($lmInfo[0] + $lmInfo[1]) / 2, true);
240
-
241
-        return self::NTLMSIG
242
-        .$this->createByte('03') // TYPE 3 message
215
+	}
216
+
217
+	/**
218
+	 * Create our message 3.
219
+	 *
220
+	 * @param string $domain
221
+	 * @param string $username
222
+	 * @param string $workstation
223
+	 * @param string $lmResponse
224
+	 * @param string $ntlmResponse
225
+	 *
226
+	 * @return string
227
+	 */
228
+	protected function createMessage3($domain, $username, $workstation, $lmResponse, $ntlmResponse)
229
+	{
230
+		// Create security buffers
231
+		$domainSec = $this->createSecurityBuffer($domain, 64);
232
+		$domainInfo = $this->readSecurityBuffer(bin2hex($domainSec));
233
+		$userSec = $this->createSecurityBuffer($username, ($domainInfo[0] + $domainInfo[1]) / 2);
234
+		$userInfo = $this->readSecurityBuffer(bin2hex($userSec));
235
+		$workSec = $this->createSecurityBuffer($workstation, ($userInfo[0] + $userInfo[1]) / 2);
236
+		$workInfo = $this->readSecurityBuffer(bin2hex($workSec));
237
+		$lmSec = $this->createSecurityBuffer($lmResponse, ($workInfo[0] + $workInfo[1]) / 2, true);
238
+		$lmInfo = $this->readSecurityBuffer(bin2hex($lmSec));
239
+		$ntlmSec = $this->createSecurityBuffer($ntlmResponse, ($lmInfo[0] + $lmInfo[1]) / 2, true);
240
+
241
+		return self::NTLMSIG
242
+		.$this->createByte('03') // TYPE 3 message
243 243
 .$lmSec // LM response header
244 244
 .$ntlmSec // NTLM response header
245 245
 .$domainSec // Domain header
@@ -251,431 +251,431 @@  discard block
 block discarded – undo
251 251
 .$this->convertTo16bit($username) // username
252 252
 .$this->convertTo16bit($workstation) // workstation
253 253
 .$lmResponse
254
-        .$ntlmResponse;
255
-    }
256
-
257
-    /**
258
-     * @param string $timestamp  Epoch timestamp in microseconds
259
-     * @param string $client     Random bytes
260
-     * @param string $targetInfo
261
-     *
262
-     * @return string
263
-     */
264
-    protected function createBlob($timestamp, $client, $targetInfo)
265
-    {
266
-        return $this->createByte('0101')
267
-        .$this->createByte('00')
268
-        .$timestamp
269
-        .$client
270
-        .$this->createByte('00')
271
-        .$targetInfo
272
-        .$this->createByte('00');
273
-    }
274
-
275
-    /**
276
-     * Get domain and username from our username.
277
-     *
278
-     * @example DOMAIN\username
279
-     *
280
-     * @param string $name
281
-     *
282
-     * @return array
283
-     */
284
-    protected function getDomainAndUsername($name)
285
-    {
286
-        if (false !== strpos($name, '\\')) {
287
-            return explode('\\', $name);
288
-        }
289
-
290
-        if (false !== strpos($name, '@')) {
291
-            list($user, $domain) = explode('@', $name);
292
-
293
-            return [$domain, $user];
294
-        }
295
-
296
-        // no domain passed
297
-        return ['', $name];
298
-    }
299
-
300
-    /**
301
-     * Create LMv1 response.
302
-     *
303
-     * @param string $password
304
-     * @param string $challenge
305
-     *
306
-     * @return string
307
-     */
308
-    protected function createLMPassword($password, $challenge)
309
-    {
310
-        // FIRST PART
311
-        $password = $this->createByte(strtoupper($password), 14, false);
312
-        list($key1, $key2) = str_split($password, 7);
313
-
314
-        $desKey1 = $this->createDesKey($key1);
315
-        $desKey2 = $this->createDesKey($key2);
316
-
317
-        $constantDecrypt = $this->createByte($this->desEncrypt(self::DESCONST, $desKey1).$this->desEncrypt(self::DESCONST, $desKey2), 21, false);
318
-
319
-        // SECOND PART
320
-        list($key1, $key2, $key3) = str_split($constantDecrypt, 7);
321
-
322
-        $desKey1 = $this->createDesKey($key1);
323
-        $desKey2 = $this->createDesKey($key2);
324
-        $desKey3 = $this->createDesKey($key3);
325
-
326
-        return $this->desEncrypt($challenge, $desKey1).$this->desEncrypt($challenge, $desKey2).$this->desEncrypt($challenge, $desKey3);
327
-    }
328
-
329
-    /**
330
-     * Create NTLMv1 response.
331
-     *
332
-     * @param string $password
333
-     * @param string $challenge
334
-     *
335
-     * @return string
336
-     */
337
-    protected function createNTLMPassword($password, $challenge)
338
-    {
339
-        // FIRST PART
340
-        $ntlmHash = $this->createByte($this->md4Encrypt($password), 21, false);
341
-        list($key1, $key2, $key3) = str_split($ntlmHash, 7);
342
-
343
-        $desKey1 = $this->createDesKey($key1);
344
-        $desKey2 = $this->createDesKey($key2);
345
-        $desKey3 = $this->createDesKey($key3);
346
-
347
-        return $this->desEncrypt($challenge, $desKey1).$this->desEncrypt($challenge, $desKey2).$this->desEncrypt($challenge, $desKey3);
348
-    }
349
-
350
-    /**
351
-     * Convert a normal timestamp to a tenth of a microtime epoch time.
352
-     *
353
-     * @param string $time
354
-     *
355
-     * @return string
356
-     */
357
-    protected function getCorrectTimestamp($time)
358
-    {
359
-        // Get our timestamp (tricky!)
360
-        $time = number_format($time, 0, '.', ''); // save microtime to string
361
-        $time = bcadd($time, '11644473600000', 0); // add epoch time
362
-        $time = bcmul($time, 10000, 0); // tenths of a microsecond.
363
-
364
-        $binary = $this->si2bin($time, 64); // create 64 bit binary string
365
-        $timestamp = '';
366
-        for ($i = 0; $i < 8; ++$i) {
367
-            $timestamp .= \chr(bindec(substr($binary, -(($i + 1) * 8), 8)));
368
-        }
369
-
370
-        return $timestamp;
371
-    }
372
-
373
-    /**
374
-     * Create LMv2 response.
375
-     *
376
-     * @param string $password
377
-     * @param string $username
378
-     * @param string $domain
379
-     * @param string $challenge NTLM Challenge
380
-     * @param string $client    Random string
381
-     *
382
-     * @return string
383
-     */
384
-    protected function createLMv2Password($password, $username, $domain, $challenge, $client)
385
-    {
386
-        $lmPass = '00'; // by default 00
387
-        // if $password > 15 than we can't use this method
388
-        if (\strlen($password) <= 15) {
389
-            $ntlmHash = $this->md4Encrypt($password);
390
-            $ntml2Hash = $this->md5Encrypt($ntlmHash, $this->convertTo16bit(strtoupper($username).$domain));
391
-
392
-            $lmPass = bin2hex($this->md5Encrypt($ntml2Hash, $challenge.$client).$client);
393
-        }
394
-
395
-        return $this->createByte($lmPass, 24);
396
-    }
397
-
398
-    /**
399
-     * Create NTLMv2 response.
400
-     *
401
-     * @param string $password
402
-     * @param string $username
403
-     * @param string $domain
404
-     * @param string $challenge  Hex values
405
-     * @param string $targetInfo Hex values
406
-     * @param string $timestamp
407
-     * @param string $client     Random bytes
408
-     *
409
-     * @return string
410
-     *
411
-     * @see http://davenport.sourceforge.net/ntlm.html#theNtlmResponse
412
-     */
413
-    protected function createNTLMv2Hash($password, $username, $domain, $challenge, $targetInfo, $timestamp, $client)
414
-    {
415
-        $ntlmHash = $this->md4Encrypt($password);
416
-        $ntml2Hash = $this->md5Encrypt($ntlmHash, $this->convertTo16bit(strtoupper($username).$domain));
417
-
418
-        // create blob
419
-        $blob = $this->createBlob($timestamp, $client, $targetInfo);
420
-
421
-        $ntlmv2Response = $this->md5Encrypt($ntml2Hash, $challenge.$blob);
422
-
423
-        return $ntlmv2Response.$blob;
424
-    }
425
-
426
-    protected function createDesKey($key)
427
-    {
428
-        $material = [bin2hex($key[0])];
429
-        $len = \strlen($key);
430
-        for ($i = 1; $i < $len; ++$i) {
431
-            list($high, $low) = str_split(bin2hex($key[$i]));
432
-            $v = $this->castToByte(\ord($key[$i - 1]) << (7 + 1 - $i) | $this->uRShift(hexdec(dechex(hexdec($high) & 0xf).dechex(hexdec($low) & 0xf)), $i));
433
-            $material[] = str_pad(substr(dechex($v), -2), 2, '0', STR_PAD_LEFT); // cast to byte
434
-        }
435
-        $material[] = str_pad(substr(dechex($this->castToByte(\ord($key[6]) << 1)), -2), 2, '0');
436
-
437
-        // odd parity
438
-        foreach ($material as $k => $v) {
439
-            $b = $this->castToByte(hexdec($v));
440
-            $needsParity = 0 == (($this->uRShift($b, 7) ^ $this->uRShift($b, 6) ^ $this->uRShift($b, 5)
441
-                        ^ $this->uRShift($b, 4) ^ $this->uRShift($b, 3) ^ $this->uRShift($b, 2)
442
-                        ^ $this->uRShift($b, 1)) & 0x01);
443
-
444
-            list($high, $low) = str_split($v);
445
-            if ($needsParity) {
446
-                $material[$k] = dechex(hexdec($high) | 0x0).dechex(hexdec($low) | 0x1);
447
-            } else {
448
-                $material[$k] = dechex(hexdec($high) & 0xf).dechex(hexdec($low) & 0xe);
449
-            }
450
-        }
451
-
452
-        return hex2bin(implode('', $material));
453
-    }
454
-
455
-    /** HELPER FUNCTIONS */
456
-
457
-    /**
458
-     * Create our security buffer depending on length and offset.
459
-     *
460
-     * @param string $value  Value we want to put in
461
-     * @param int    $offset start of value
462
-     * @param bool   $is16   Do we 16bit string or not?
463
-     *
464
-     * @return string
465
-     */
466
-    protected function createSecurityBuffer($value, $offset, $is16 = false)
467
-    {
468
-        $length = \strlen(bin2hex($value));
469
-        $length = $is16 ? $length / 2 : $length;
470
-        $length = $this->createByte(str_pad(dechex($length), 2, '0', STR_PAD_LEFT), 2);
471
-
472
-        return $length.$length.$this->createByte(dechex($offset), 4);
473
-    }
474
-
475
-    /**
476
-     * Read our security buffer to fetch length and offset of our value.
477
-     *
478
-     * @param string $value Securitybuffer in hex
479
-     *
480
-     * @return array array with length and offset
481
-     */
482
-    protected function readSecurityBuffer($value)
483
-    {
484
-        $length = floor(hexdec(substr($value, 0, 4)) / 256) * 2;
485
-        $offset = floor(hexdec(substr($value, 8, 4)) / 256) * 2;
486
-
487
-        return [$length, $offset];
488
-    }
489
-
490
-    /**
491
-     * Cast to byte java equivalent to (byte).
492
-     *
493
-     * @param int $v
494
-     *
495
-     * @return int
496
-     */
497
-    protected function castToByte($v)
498
-    {
499
-        return (($v + 128) % 256) - 128;
500
-    }
501
-
502
-    /**
503
-     * Java unsigned right bitwise
504
-     * $a >>> $b.
505
-     *
506
-     * @param int $a
507
-     * @param int $b
508
-     *
509
-     * @return int
510
-     */
511
-    protected function uRShift($a, $b)
512
-    {
513
-        if (0 == $b) {
514
-            return $a;
515
-        }
516
-
517
-        return ($a >> $b) & ~(1 << (8 * PHP_INT_SIZE - 1) >> ($b - 1));
518
-    }
519
-
520
-    /**
521
-     * Right padding with 0 to certain length.
522
-     *
523
-     * @param string $input
524
-     * @param int    $bytes Length of bytes
525
-     * @param bool   $isHex Did we provided hex value
526
-     *
527
-     * @return string
528
-     */
529
-    protected function createByte($input, $bytes = 4, $isHex = true)
530
-    {
531
-        if ($isHex) {
532
-            $byte = hex2bin(str_pad($input, $bytes * 2, '00'));
533
-        } else {
534
-            $byte = str_pad($input, $bytes, "\x00");
535
-        }
536
-
537
-        return $byte;
538
-    }
539
-
540
-    /** ENCRYPTION ALGORITHMS */
541
-
542
-    /**
543
-     * DES Encryption.
544
-     *
545
-     * @param string $value An 8-byte string
546
-     * @param string $key
547
-     *
548
-     * @return string
549
-     */
550
-    protected function desEncrypt($value, $key)
551
-    {
552
-        return substr(openssl_encrypt($value, 'DES-ECB', $key, \OPENSSL_RAW_DATA), 0, 8);
553
-    }
554
-
555
-    /**
556
-     * MD5 Encryption.
557
-     *
558
-     * @param string $key Encryption key
559
-     * @param string $msg Message to encrypt
560
-     *
561
-     * @return string
562
-     */
563
-    protected function md5Encrypt($key, $msg)
564
-    {
565
-        $blocksize = 64;
566
-        if (\strlen($key) > $blocksize) {
567
-            $key = pack('H*', md5($key));
568
-        }
569
-
570
-        $key = str_pad($key, $blocksize, "\0");
571
-        $ipadk = $key ^ str_repeat("\x36", $blocksize);
572
-        $opadk = $key ^ str_repeat("\x5c", $blocksize);
573
-
574
-        return pack('H*', md5($opadk.pack('H*', md5($ipadk.$msg))));
575
-    }
576
-
577
-    /**
578
-     * MD4 Encryption.
579
-     *
580
-     * @param string $input
581
-     *
582
-     * @return string
583
-     *
584
-     * @see https://secure.php.net/manual/en/ref.hash.php
585
-     */
586
-    protected function md4Encrypt($input)
587
-    {
588
-        $input = $this->convertTo16bit($input);
589
-
590
-        return \function_exists('hash') ? hex2bin(hash('md4', $input)) : mhash(MHASH_MD4, $input);
591
-    }
592
-
593
-    /**
594
-     * Convert UTF-8 to UTF-16.
595
-     *
596
-     * @param string $input
597
-     *
598
-     * @return string
599
-     */
600
-    protected function convertTo16bit($input)
601
-    {
602
-        return iconv('UTF-8', 'UTF-16LE', $input);
603
-    }
604
-
605
-    /**
606
-     * @param string $message
607
-     */
608
-    protected function debug($message)
609
-    {
610
-        $message = bin2hex($message);
611
-        $messageId = substr($message, 16, 8);
612
-        echo substr($message, 0, 16)." NTLMSSP Signature<br />\n";
613
-        echo $messageId." Type Indicator<br />\n";
614
-
615
-        if ('02000000' == $messageId) {
616
-            $map = [
617
-                'Challenge',
618
-                'Context',
619
-                'Target Information Security Buffer',
620
-                'Target Name Data',
621
-                'NetBIOS Domain Name',
622
-                'NetBIOS Server Name',
623
-                'DNS Domain Name',
624
-                'DNS Server Name',
625
-                'BLOB',
626
-                'Target Information Terminator',
627
-            ];
628
-
629
-            $data = $this->parseMessage2(hex2bin($message));
630
-
631
-            foreach ($map as $key => $value) {
632
-                echo bin2hex($data[$key]).' - '.$data[$key].' ||| '.$value."<br />\n";
633
-            }
634
-        } elseif ('03000000' == $messageId) {
635
-            $i = 0;
636
-            $data[$i++] = substr($message, 24, 16);
637
-            list($lmLength, $lmOffset) = $this->readSecurityBuffer($data[$i - 1]);
638
-
639
-            $data[$i++] = substr($message, 40, 16);
640
-            list($ntmlLength, $ntmlOffset) = $this->readSecurityBuffer($data[$i - 1]);
641
-
642
-            $data[$i++] = substr($message, 56, 16);
643
-            list($targetLength, $targetOffset) = $this->readSecurityBuffer($data[$i - 1]);
644
-
645
-            $data[$i++] = substr($message, 72, 16);
646
-            list($userLength, $userOffset) = $this->readSecurityBuffer($data[$i - 1]);
647
-
648
-            $data[$i++] = substr($message, 88, 16);
649
-            list($workLength, $workOffset) = $this->readSecurityBuffer($data[$i - 1]);
650
-
651
-            $data[$i++] = substr($message, 104, 16);
652
-            $data[$i++] = substr($message, 120, 8);
653
-            $data[$i++] = substr($message, $targetOffset, $targetLength);
654
-            $data[$i++] = substr($message, $userOffset, $userLength);
655
-            $data[$i++] = substr($message, $workOffset, $workLength);
656
-            $data[$i++] = substr($message, $lmOffset, $lmLength);
657
-            $data[$i] = substr($message, $ntmlOffset, $ntmlLength);
658
-
659
-            $map = [
660
-                'LM Response Security Buffer',
661
-                'NTLM Response Security Buffer',
662
-                'Target Name Security Buffer',
663
-                'User Name Security Buffer',
664
-                'Workstation Name Security Buffer',
665
-                'Session Key Security Buffer',
666
-                'Flags',
667
-                'Target Name Data',
668
-                'User Name Data',
669
-                'Workstation Name Data',
670
-                'LM Response Data',
671
-                'NTLM Response Data',
672
-            ];
673
-
674
-            foreach ($map as $key => $value) {
675
-                echo $data[$key].' - '.hex2bin($data[$key]).' ||| '.$value."<br />\n";
676
-            }
677
-        }
678
-
679
-        echo '<br /><br />';
680
-    }
254
+		.$ntlmResponse;
255
+	}
256
+
257
+	/**
258
+	 * @param string $timestamp  Epoch timestamp in microseconds
259
+	 * @param string $client     Random bytes
260
+	 * @param string $targetInfo
261
+	 *
262
+	 * @return string
263
+	 */
264
+	protected function createBlob($timestamp, $client, $targetInfo)
265
+	{
266
+		return $this->createByte('0101')
267
+		.$this->createByte('00')
268
+		.$timestamp
269
+		.$client
270
+		.$this->createByte('00')
271
+		.$targetInfo
272
+		.$this->createByte('00');
273
+	}
274
+
275
+	/**
276
+	 * Get domain and username from our username.
277
+	 *
278
+	 * @example DOMAIN\username
279
+	 *
280
+	 * @param string $name
281
+	 *
282
+	 * @return array
283
+	 */
284
+	protected function getDomainAndUsername($name)
285
+	{
286
+		if (false !== strpos($name, '\\')) {
287
+			return explode('\\', $name);
288
+		}
289
+
290
+		if (false !== strpos($name, '@')) {
291
+			list($user, $domain) = explode('@', $name);
292
+
293
+			return [$domain, $user];
294
+		}
295
+
296
+		// no domain passed
297
+		return ['', $name];
298
+	}
299
+
300
+	/**
301
+	 * Create LMv1 response.
302
+	 *
303
+	 * @param string $password
304
+	 * @param string $challenge
305
+	 *
306
+	 * @return string
307
+	 */
308
+	protected function createLMPassword($password, $challenge)
309
+	{
310
+		// FIRST PART
311
+		$password = $this->createByte(strtoupper($password), 14, false);
312
+		list($key1, $key2) = str_split($password, 7);
313
+
314
+		$desKey1 = $this->createDesKey($key1);
315
+		$desKey2 = $this->createDesKey($key2);
316
+
317
+		$constantDecrypt = $this->createByte($this->desEncrypt(self::DESCONST, $desKey1).$this->desEncrypt(self::DESCONST, $desKey2), 21, false);
318
+
319
+		// SECOND PART
320
+		list($key1, $key2, $key3) = str_split($constantDecrypt, 7);
321
+
322
+		$desKey1 = $this->createDesKey($key1);
323
+		$desKey2 = $this->createDesKey($key2);
324
+		$desKey3 = $this->createDesKey($key3);
325
+
326
+		return $this->desEncrypt($challenge, $desKey1).$this->desEncrypt($challenge, $desKey2).$this->desEncrypt($challenge, $desKey3);
327
+	}
328
+
329
+	/**
330
+	 * Create NTLMv1 response.
331
+	 *
332
+	 * @param string $password
333
+	 * @param string $challenge
334
+	 *
335
+	 * @return string
336
+	 */
337
+	protected function createNTLMPassword($password, $challenge)
338
+	{
339
+		// FIRST PART
340
+		$ntlmHash = $this->createByte($this->md4Encrypt($password), 21, false);
341
+		list($key1, $key2, $key3) = str_split($ntlmHash, 7);
342
+
343
+		$desKey1 = $this->createDesKey($key1);
344
+		$desKey2 = $this->createDesKey($key2);
345
+		$desKey3 = $this->createDesKey($key3);
346
+
347
+		return $this->desEncrypt($challenge, $desKey1).$this->desEncrypt($challenge, $desKey2).$this->desEncrypt($challenge, $desKey3);
348
+	}
349
+
350
+	/**
351
+	 * Convert a normal timestamp to a tenth of a microtime epoch time.
352
+	 *
353
+	 * @param string $time
354
+	 *
355
+	 * @return string
356
+	 */
357
+	protected function getCorrectTimestamp($time)
358
+	{
359
+		// Get our timestamp (tricky!)
360
+		$time = number_format($time, 0, '.', ''); // save microtime to string
361
+		$time = bcadd($time, '11644473600000', 0); // add epoch time
362
+		$time = bcmul($time, 10000, 0); // tenths of a microsecond.
363
+
364
+		$binary = $this->si2bin($time, 64); // create 64 bit binary string
365
+		$timestamp = '';
366
+		for ($i = 0; $i < 8; ++$i) {
367
+			$timestamp .= \chr(bindec(substr($binary, -(($i + 1) * 8), 8)));
368
+		}
369
+
370
+		return $timestamp;
371
+	}
372
+
373
+	/**
374
+	 * Create LMv2 response.
375
+	 *
376
+	 * @param string $password
377
+	 * @param string $username
378
+	 * @param string $domain
379
+	 * @param string $challenge NTLM Challenge
380
+	 * @param string $client    Random string
381
+	 *
382
+	 * @return string
383
+	 */
384
+	protected function createLMv2Password($password, $username, $domain, $challenge, $client)
385
+	{
386
+		$lmPass = '00'; // by default 00
387
+		// if $password > 15 than we can't use this method
388
+		if (\strlen($password) <= 15) {
389
+			$ntlmHash = $this->md4Encrypt($password);
390
+			$ntml2Hash = $this->md5Encrypt($ntlmHash, $this->convertTo16bit(strtoupper($username).$domain));
391
+
392
+			$lmPass = bin2hex($this->md5Encrypt($ntml2Hash, $challenge.$client).$client);
393
+		}
394
+
395
+		return $this->createByte($lmPass, 24);
396
+	}
397
+
398
+	/**
399
+	 * Create NTLMv2 response.
400
+	 *
401
+	 * @param string $password
402
+	 * @param string $username
403
+	 * @param string $domain
404
+	 * @param string $challenge  Hex values
405
+	 * @param string $targetInfo Hex values
406
+	 * @param string $timestamp
407
+	 * @param string $client     Random bytes
408
+	 *
409
+	 * @return string
410
+	 *
411
+	 * @see http://davenport.sourceforge.net/ntlm.html#theNtlmResponse
412
+	 */
413
+	protected function createNTLMv2Hash($password, $username, $domain, $challenge, $targetInfo, $timestamp, $client)
414
+	{
415
+		$ntlmHash = $this->md4Encrypt($password);
416
+		$ntml2Hash = $this->md5Encrypt($ntlmHash, $this->convertTo16bit(strtoupper($username).$domain));
417
+
418
+		// create blob
419
+		$blob = $this->createBlob($timestamp, $client, $targetInfo);
420
+
421
+		$ntlmv2Response = $this->md5Encrypt($ntml2Hash, $challenge.$blob);
422
+
423
+		return $ntlmv2Response.$blob;
424
+	}
425
+
426
+	protected function createDesKey($key)
427
+	{
428
+		$material = [bin2hex($key[0])];
429
+		$len = \strlen($key);
430
+		for ($i = 1; $i < $len; ++$i) {
431
+			list($high, $low) = str_split(bin2hex($key[$i]));
432
+			$v = $this->castToByte(\ord($key[$i - 1]) << (7 + 1 - $i) | $this->uRShift(hexdec(dechex(hexdec($high) & 0xf).dechex(hexdec($low) & 0xf)), $i));
433
+			$material[] = str_pad(substr(dechex($v), -2), 2, '0', STR_PAD_LEFT); // cast to byte
434
+		}
435
+		$material[] = str_pad(substr(dechex($this->castToByte(\ord($key[6]) << 1)), -2), 2, '0');
436
+
437
+		// odd parity
438
+		foreach ($material as $k => $v) {
439
+			$b = $this->castToByte(hexdec($v));
440
+			$needsParity = 0 == (($this->uRShift($b, 7) ^ $this->uRShift($b, 6) ^ $this->uRShift($b, 5)
441
+						^ $this->uRShift($b, 4) ^ $this->uRShift($b, 3) ^ $this->uRShift($b, 2)
442
+						^ $this->uRShift($b, 1)) & 0x01);
443
+
444
+			list($high, $low) = str_split($v);
445
+			if ($needsParity) {
446
+				$material[$k] = dechex(hexdec($high) | 0x0).dechex(hexdec($low) | 0x1);
447
+			} else {
448
+				$material[$k] = dechex(hexdec($high) & 0xf).dechex(hexdec($low) & 0xe);
449
+			}
450
+		}
451
+
452
+		return hex2bin(implode('', $material));
453
+	}
454
+
455
+	/** HELPER FUNCTIONS */
456
+
457
+	/**
458
+	 * Create our security buffer depending on length and offset.
459
+	 *
460
+	 * @param string $value  Value we want to put in
461
+	 * @param int    $offset start of value
462
+	 * @param bool   $is16   Do we 16bit string or not?
463
+	 *
464
+	 * @return string
465
+	 */
466
+	protected function createSecurityBuffer($value, $offset, $is16 = false)
467
+	{
468
+		$length = \strlen(bin2hex($value));
469
+		$length = $is16 ? $length / 2 : $length;
470
+		$length = $this->createByte(str_pad(dechex($length), 2, '0', STR_PAD_LEFT), 2);
471
+
472
+		return $length.$length.$this->createByte(dechex($offset), 4);
473
+	}
474
+
475
+	/**
476
+	 * Read our security buffer to fetch length and offset of our value.
477
+	 *
478
+	 * @param string $value Securitybuffer in hex
479
+	 *
480
+	 * @return array array with length and offset
481
+	 */
482
+	protected function readSecurityBuffer($value)
483
+	{
484
+		$length = floor(hexdec(substr($value, 0, 4)) / 256) * 2;
485
+		$offset = floor(hexdec(substr($value, 8, 4)) / 256) * 2;
486
+
487
+		return [$length, $offset];
488
+	}
489
+
490
+	/**
491
+	 * Cast to byte java equivalent to (byte).
492
+	 *
493
+	 * @param int $v
494
+	 *
495
+	 * @return int
496
+	 */
497
+	protected function castToByte($v)
498
+	{
499
+		return (($v + 128) % 256) - 128;
500
+	}
501
+
502
+	/**
503
+	 * Java unsigned right bitwise
504
+	 * $a >>> $b.
505
+	 *
506
+	 * @param int $a
507
+	 * @param int $b
508
+	 *
509
+	 * @return int
510
+	 */
511
+	protected function uRShift($a, $b)
512
+	{
513
+		if (0 == $b) {
514
+			return $a;
515
+		}
516
+
517
+		return ($a >> $b) & ~(1 << (8 * PHP_INT_SIZE - 1) >> ($b - 1));
518
+	}
519
+
520
+	/**
521
+	 * Right padding with 0 to certain length.
522
+	 *
523
+	 * @param string $input
524
+	 * @param int    $bytes Length of bytes
525
+	 * @param bool   $isHex Did we provided hex value
526
+	 *
527
+	 * @return string
528
+	 */
529
+	protected function createByte($input, $bytes = 4, $isHex = true)
530
+	{
531
+		if ($isHex) {
532
+			$byte = hex2bin(str_pad($input, $bytes * 2, '00'));
533
+		} else {
534
+			$byte = str_pad($input, $bytes, "\x00");
535
+		}
536
+
537
+		return $byte;
538
+	}
539
+
540
+	/** ENCRYPTION ALGORITHMS */
541
+
542
+	/**
543
+	 * DES Encryption.
544
+	 *
545
+	 * @param string $value An 8-byte string
546
+	 * @param string $key
547
+	 *
548
+	 * @return string
549
+	 */
550
+	protected function desEncrypt($value, $key)
551
+	{
552
+		return substr(openssl_encrypt($value, 'DES-ECB', $key, \OPENSSL_RAW_DATA), 0, 8);
553
+	}
554
+
555
+	/**
556
+	 * MD5 Encryption.
557
+	 *
558
+	 * @param string $key Encryption key
559
+	 * @param string $msg Message to encrypt
560
+	 *
561
+	 * @return string
562
+	 */
563
+	protected function md5Encrypt($key, $msg)
564
+	{
565
+		$blocksize = 64;
566
+		if (\strlen($key) > $blocksize) {
567
+			$key = pack('H*', md5($key));
568
+		}
569
+
570
+		$key = str_pad($key, $blocksize, "\0");
571
+		$ipadk = $key ^ str_repeat("\x36", $blocksize);
572
+		$opadk = $key ^ str_repeat("\x5c", $blocksize);
573
+
574
+		return pack('H*', md5($opadk.pack('H*', md5($ipadk.$msg))));
575
+	}
576
+
577
+	/**
578
+	 * MD4 Encryption.
579
+	 *
580
+	 * @param string $input
581
+	 *
582
+	 * @return string
583
+	 *
584
+	 * @see https://secure.php.net/manual/en/ref.hash.php
585
+	 */
586
+	protected function md4Encrypt($input)
587
+	{
588
+		$input = $this->convertTo16bit($input);
589
+
590
+		return \function_exists('hash') ? hex2bin(hash('md4', $input)) : mhash(MHASH_MD4, $input);
591
+	}
592
+
593
+	/**
594
+	 * Convert UTF-8 to UTF-16.
595
+	 *
596
+	 * @param string $input
597
+	 *
598
+	 * @return string
599
+	 */
600
+	protected function convertTo16bit($input)
601
+	{
602
+		return iconv('UTF-8', 'UTF-16LE', $input);
603
+	}
604
+
605
+	/**
606
+	 * @param string $message
607
+	 */
608
+	protected function debug($message)
609
+	{
610
+		$message = bin2hex($message);
611
+		$messageId = substr($message, 16, 8);
612
+		echo substr($message, 0, 16)." NTLMSSP Signature<br />\n";
613
+		echo $messageId." Type Indicator<br />\n";
614
+
615
+		if ('02000000' == $messageId) {
616
+			$map = [
617
+				'Challenge',
618
+				'Context',
619
+				'Target Information Security Buffer',
620
+				'Target Name Data',
621
+				'NetBIOS Domain Name',
622
+				'NetBIOS Server Name',
623
+				'DNS Domain Name',
624
+				'DNS Server Name',
625
+				'BLOB',
626
+				'Target Information Terminator',
627
+			];
628
+
629
+			$data = $this->parseMessage2(hex2bin($message));
630
+
631
+			foreach ($map as $key => $value) {
632
+				echo bin2hex($data[$key]).' - '.$data[$key].' ||| '.$value."<br />\n";
633
+			}
634
+		} elseif ('03000000' == $messageId) {
635
+			$i = 0;
636
+			$data[$i++] = substr($message, 24, 16);
637
+			list($lmLength, $lmOffset) = $this->readSecurityBuffer($data[$i - 1]);
638
+
639
+			$data[$i++] = substr($message, 40, 16);
640
+			list($ntmlLength, $ntmlOffset) = $this->readSecurityBuffer($data[$i - 1]);
641
+
642
+			$data[$i++] = substr($message, 56, 16);
643
+			list($targetLength, $targetOffset) = $this->readSecurityBuffer($data[$i - 1]);
644
+
645
+			$data[$i++] = substr($message, 72, 16);
646
+			list($userLength, $userOffset) = $this->readSecurityBuffer($data[$i - 1]);
647
+
648
+			$data[$i++] = substr($message, 88, 16);
649
+			list($workLength, $workOffset) = $this->readSecurityBuffer($data[$i - 1]);
650
+
651
+			$data[$i++] = substr($message, 104, 16);
652
+			$data[$i++] = substr($message, 120, 8);
653
+			$data[$i++] = substr($message, $targetOffset, $targetLength);
654
+			$data[$i++] = substr($message, $userOffset, $userLength);
655
+			$data[$i++] = substr($message, $workOffset, $workLength);
656
+			$data[$i++] = substr($message, $lmOffset, $lmLength);
657
+			$data[$i] = substr($message, $ntmlOffset, $ntmlLength);
658
+
659
+			$map = [
660
+				'LM Response Security Buffer',
661
+				'NTLM Response Security Buffer',
662
+				'Target Name Security Buffer',
663
+				'User Name Security Buffer',
664
+				'Workstation Name Security Buffer',
665
+				'Session Key Security Buffer',
666
+				'Flags',
667
+				'Target Name Data',
668
+				'User Name Data',
669
+				'Workstation Name Data',
670
+				'LM Response Data',
671
+				'NTLM Response Data',
672
+			];
673
+
674
+			foreach ($map as $key => $value) {
675
+				echo $data[$key].' - '.hex2bin($data[$key]).' ||| '.$value."<br />\n";
676
+			}
677
+		}
678
+
679
+		echo '<br /><br />';
680
+	}
681 681
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -183,7 +183,7 @@
 block discarded – undo
183 183
     {
184 184
         list($domain, $username) = $this->getDomainAndUsername($username);
185 185
         //$challenge, $context, $targetInfoH, $targetName, $domainName, $workstation, $DNSDomainName, $DNSServerName, $blob, $ter
186
-        list($challenge, , , , , $workstation, , , $blob) = $this->parseMessage2($response);
186
+        list($challenge,,,,, $workstation,,, $blob) = $this->parseMessage2($response);
187 187
 
188 188
         if (!$v2) {
189 189
             // LMv1
Please login to merge, or discard this patch.
swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php 1 patch
Indentation   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -25,40 +25,40 @@
 block discarded – undo
25 25
  */
26 26
 class Swift_Transport_Esmtp_Auth_XOAuth2Authenticator implements Swift_Transport_Esmtp_Authenticator
27 27
 {
28
-    /**
29
-     * Get the name of the AUTH mechanism this Authenticator handles.
30
-     *
31
-     * @return string
32
-     */
33
-    public function getAuthKeyword()
34
-    {
35
-        return 'XOAUTH2';
36
-    }
28
+	/**
29
+	 * Get the name of the AUTH mechanism this Authenticator handles.
30
+	 *
31
+	 * @return string
32
+	 */
33
+	public function getAuthKeyword()
34
+	{
35
+		return 'XOAUTH2';
36
+	}
37 37
 
38
-    /**
39
-     * {@inheritdoc}
40
-     */
41
-    public function authenticate(Swift_Transport_SmtpAgent $agent, $email, $token)
42
-    {
43
-        try {
44
-            $param = $this->constructXOAuth2Params($email, $token);
45
-            $agent->executeCommand('AUTH XOAUTH2 '.$param."\r\n", [235]);
38
+	/**
39
+	 * {@inheritdoc}
40
+	 */
41
+	public function authenticate(Swift_Transport_SmtpAgent $agent, $email, $token)
42
+	{
43
+		try {
44
+			$param = $this->constructXOAuth2Params($email, $token);
45
+			$agent->executeCommand('AUTH XOAUTH2 '.$param."\r\n", [235]);
46 46
 
47
-            return true;
48
-        } catch (Swift_TransportException $e) {
49
-            $agent->executeCommand("RSET\r\n", [250]);
47
+			return true;
48
+		} catch (Swift_TransportException $e) {
49
+			$agent->executeCommand("RSET\r\n", [250]);
50 50
 
51
-            throw $e;
52
-        }
53
-    }
51
+			throw $e;
52
+		}
53
+	}
54 54
 
55
-    /**
56
-     * Construct the auth parameter.
57
-     *
58
-     * @see https://developers.google.com/google-apps/gmail/xoauth2_protocol#the_sasl_xoauth2_mechanism
59
-     */
60
-    protected function constructXOAuth2Params($email, $token)
61
-    {
62
-        return base64_encode("user=$email\1auth=Bearer $token\1\1");
63
-    }
55
+	/**
56
+	 * Construct the auth parameter.
57
+	 *
58
+	 * @see https://developers.google.com/google-apps/gmail/xoauth2_protocol#the_sasl_xoauth2_mechanism
59
+	 */
60
+	protected function constructXOAuth2Params($email, $token)
61
+	{
62
+		return base64_encode("user=$email\1auth=Bearer $token\1\1");
63
+	}
64 64
 }
Please login to merge, or discard this patch.
swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php 1 patch
Indentation   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -15,30 +15,30 @@
 block discarded – undo
15 15
  */
16 16
 class Swift_Transport_Esmtp_Auth_PlainAuthenticator implements Swift_Transport_Esmtp_Authenticator
17 17
 {
18
-    /**
19
-     * Get the name of the AUTH mechanism this Authenticator handles.
20
-     *
21
-     * @return string
22
-     */
23
-    public function getAuthKeyword()
24
-    {
25
-        return 'PLAIN';
26
-    }
18
+	/**
19
+	 * Get the name of the AUTH mechanism this Authenticator handles.
20
+	 *
21
+	 * @return string
22
+	 */
23
+	public function getAuthKeyword()
24
+	{
25
+		return 'PLAIN';
26
+	}
27 27
 
28
-    /**
29
-     * {@inheritdoc}
30
-     */
31
-    public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password)
32
-    {
33
-        try {
34
-            $message = base64_encode($username.\chr(0).$username.\chr(0).$password);
35
-            $agent->executeCommand(sprintf("AUTH PLAIN %s\r\n", $message), [235]);
28
+	/**
29
+	 * {@inheritdoc}
30
+	 */
31
+	public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password)
32
+	{
33
+		try {
34
+			$message = base64_encode($username.\chr(0).$username.\chr(0).$password);
35
+			$agent->executeCommand(sprintf("AUTH PLAIN %s\r\n", $message), [235]);
36 36
 
37
-            return true;
38
-        } catch (Swift_TransportException $e) {
39
-            $agent->executeCommand("RSET\r\n", [250]);
37
+			return true;
38
+		} catch (Swift_TransportException $e) {
39
+			$agent->executeCommand("RSET\r\n", [250]);
40 40
 
41
-            throw $e;
42
-        }
43
-    }
41
+			throw $e;
42
+		}
43
+	}
44 44
 }
Please login to merge, or discard this patch.