1<?php
2/**
3 * This file is part of the FreeDSx LDAP package.
4 *
5 * (c) Chad Sikorra <Chad.Sikorra@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11namespace FreeDSx\Ldap\Protocol\ServerProtocolHandler;
12
13use FreeDSx\Ldap\Operation\LdapResult;
14use FreeDSx\Ldap\Operation\Request\ExtendedRequest;
15use FreeDSx\Ldap\Operation\Response\ExtendedResponse;
16use FreeDSx\Ldap\Operation\ResultCode;
17use FreeDSx\Ldap\Protocol\LdapMessageRequest;
18use FreeDSx\Ldap\Protocol\LdapMessageResponse;
19use FreeDSx\Ldap\Protocol\Queue\ServerQueue;
20use FreeDSx\Ldap\Server\RequestHandler\RequestHandlerInterface;
21use FreeDSx\Ldap\Server\Token\TokenInterface;
22
23/**
24 * Handles StartTLS logic.
25 *
26 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
27 */
28class ServerStartTlsHandler implements ServerProtocolHandlerInterface
29{
30    /**
31     * @var bool
32     */
33    protected static $hasOpenssl;
34
35    public function __construct()
36    {
37        if (self::$hasOpenssl === null) {
38            $this::$hasOpenssl = \extension_loaded('openssl');
39        }
40    }
41
42    /**
43     * {@inheritDoc}
44     */
45    public function handleRequest(LdapMessageRequest $message, TokenInterface $token, RequestHandlerInterface $dispatcher, ServerQueue $queue, array $options): void
46    {
47        # If we don't have a SSL cert or the OpenSSL extension is not available, then we can do nothing...
48        if (!isset($options['ssl_cert']) || !self::$hasOpenssl) {
49            $queue->sendMessage(new LdapMessageResponse($message->getMessageId(), new ExtendedResponse(
50                new LdapResult(ResultCode::PROTOCOL_ERROR),
51                ExtendedRequest::OID_START_TLS
52            )));
53
54            return;
55        }
56        # If we are already encrypted, then consider this an operations error...
57        if ($queue->isEncrypted()) {
58            $queue->sendMessage(new LdapMessageResponse($message->getMessageId(), new ExtendedResponse(
59                new LdapResult(ResultCode::OPERATIONS_ERROR, '', 'The current LDAP session is already encrypted.'),
60                ExtendedRequest::OID_START_TLS
61            )));
62
63            return;
64        }
65
66        $queue->sendMessage(new LdapMessageResponse($message->getMessageId(), new ExtendedResponse(
67            new LdapResult(ResultCode::SUCCESS),
68            ExtendedRequest::OID_START_TLS
69        )));
70        $queue->encrypt();
71    }
72}
73