|
10 | 10 | use PgAsync\Command\Execute; |
11 | 11 | use PgAsync\Command\Parse; |
12 | 12 | use PgAsync\Command\PasswordMessage; |
| 13 | +use PgAsync\Command\SaslInitialResponse; |
| 14 | +use PgAsync\Command\SaslResponse; |
13 | 15 | use PgAsync\Command\Sync; |
14 | 16 | use PgAsync\Command\Terminate; |
15 | 17 | use PgAsync\Message\Authentication; |
@@ -119,6 +121,9 @@ class Connection extends EventEmitter |
119 | 121 | /** @var bool */ |
120 | 122 | private $cancelRequested; |
121 | 123 |
|
| 124 | + /** @var ScramSha256 */ |
| 125 | + private $scramSha256; |
| 126 | + |
122 | 127 | /** |
123 | 128 | * Can be 'I' for Idle, 'T' if in transactions block |
124 | 129 | * or 'E' if in failed transaction block (queries will fail until end of trans) |
@@ -174,6 +179,7 @@ public function __construct(array $parameters, LoopInterface $loop, ConnectorInt |
174 | 179 | $this->cancelRequested = false; |
175 | 180 |
|
176 | 181 | $this->parameters = $parameters; |
| 182 | + $this->scramSha256 = new ScramSha256($parameters['user'], $this->password ?: ''); |
177 | 183 | } |
178 | 184 |
|
179 | 185 | private function start() |
@@ -268,7 +274,9 @@ private function processData($data) |
268 | 274 |
|
269 | 275 | $type = $data[0]; |
270 | 276 |
|
271 | | - $message = Message::createMessageFromIdentifier($type); |
| 277 | + $message = Message::createMessageFromIdentifier($type, [ |
| 278 | + 'SCRAM_SHA_256' => $this->scramSha256 |
| 279 | + ]); |
272 | 280 | if ($message !== false) { |
273 | 281 | $this->currentMessage = $message; |
274 | 282 | return $data; |
@@ -388,6 +396,28 @@ private function handleAuthentication(Authentication $message) |
388 | 396 | return; |
389 | 397 | } |
390 | 398 |
|
| 399 | + if ($message->getAuthCode() === $message::AUTH_SCRAM) { |
| 400 | + $saslInitialResponse = new SaslInitialResponse($this->scramSha256); |
| 401 | + $this->stream->write($saslInitialResponse->encodedMessage()); |
| 402 | + |
| 403 | + return; |
| 404 | + } |
| 405 | + |
| 406 | + if ($message->getAuthCode() === $message::AUTH_SCRAM_CONTINUE) { |
| 407 | + $saslResponse = new SaslResponse($this->scramSha256); |
| 408 | + $this->stream->write($saslResponse->encodedMessage()); |
| 409 | + |
| 410 | + return; |
| 411 | + } |
| 412 | + |
| 413 | + if ($message->getAuthCode() === $message::AUTH_SCRAM_FIN) { |
| 414 | + if ($this->scramSha256->verify()) { |
| 415 | + return; |
| 416 | + } |
| 417 | + |
| 418 | + $this->lastError = 'Invalid server signature sent by server on SCRAM FIN stage'; |
| 419 | + } |
| 420 | + |
391 | 421 | $this->connStatus = $this::CONNECTION_BAD; |
392 | 422 | $this->failAllCommandsWith(new \Exception($this->lastError)); |
393 | 423 | $this->emit('error', [new \Exception($this->lastError)]); |
|
0 commit comments