1<?php 2 3/** 4 * This file is part of the FreeDSx LDAP package. 5 * 6 * (c) Chad Sikorra <Chad.Sikorra@gmail.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace FreeDSx\Ldap\Protocol\ServerProtocolHandler; 13 14use FreeDSx\Ldap\Exception\OperationException; 15use FreeDSx\Ldap\Exception\RuntimeException; 16use FreeDSx\Ldap\Operation\Request\BindRequest; 17use FreeDSx\Ldap\Operation\Request\SimpleBindRequest; 18use FreeDSx\Ldap\Operation\ResultCode; 19use FreeDSx\Ldap\Protocol\LdapMessageRequest; 20use FreeDSx\Ldap\Protocol\Queue\ServerQueue; 21use FreeDSx\Ldap\Server\RequestHandler\RequestHandlerInterface; 22use FreeDSx\Ldap\Server\Token\BindToken; 23use FreeDSx\Ldap\Server\Token\TokenInterface; 24 25/** 26 * Handles a simple bind request. 27 * 28 * @author Chad Sikorra <Chad.Sikorra@gmail.com> 29 */ 30class ServerBindHandler extends BaseServerHandler implements BindHandlerInterface 31{ 32 /** 33 * @inheritDoc 34 * @throws RuntimeException 35 * @throws OperationException 36 */ 37 public function handleBind(LdapMessageRequest $message, RequestHandlerInterface $dispatcher, ServerQueue $queue, array $options): TokenInterface 38 { 39 /** @var BindRequest $request */ 40 $request = $message->getRequest(); 41 if (!$request instanceof SimpleBindRequest) { 42 throw new RuntimeException(sprintf( 43 'Expected a SimpleBindRequest, got: %s', 44 get_class($request) 45 )); 46 } 47 48 $this->validateVersion($request); 49 $token = $this->simpleBind($dispatcher, $request); 50 $queue->sendMessage($this->responseFactory->getStandardResponse($message)); 51 52 return $token; 53 } 54 55 /** 56 * @return BindToken 57 * @throws OperationException 58 */ 59 protected function simpleBind(RequestHandlerInterface $dispatcher, SimpleBindRequest $request): TokenInterface 60 { 61 if (!$dispatcher->bind($request->getUsername(), $request->getPassword())) { 62 throw new OperationException( 63 'Invalid credentials.', 64 ResultCode::INVALID_CREDENTIALS 65 ); 66 } 67 68 return new BindToken($request->getUsername(), $request->getPassword()); 69 } 70 71 /** 72 * @throws OperationException 73 */ 74 protected function validateVersion(BindRequest $request): void 75 { 76 # Per RFC 4.2, a result code of protocol error must be sent back for unsupported versions. 77 if ($request->getVersion() !== 3) { 78 throw new OperationException( 79 'Only LDAP version 3 is supported.', 80 ResultCode::PROTOCOL_ERROR 81 ); 82 } 83 } 84} 85