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\Operation\Request;
12
13use FreeDSx\Asn1\Asn1;
14use FreeDSx\Asn1\Type\AbstractType;
15use FreeDSx\Ldap\Exception\BindException;
16
17/**
18 * Represents a SASL bind request consisting of a mechanism challenge / response.
19 *
20 *  AuthenticationChoice ::= CHOICE {
21 *     simple                  [0] OCTET STRING,
22 *     -- 1 and 2 reserved
23 *     sasl                    [3] SaslCredentials,
24 *     ...  }
25 *
26 *  SaslCredentials ::= SEQUENCE {
27 *     mechanism               LDAPString,
28 *     credentials             OCTET STRING OPTIONAL }
29 *
30 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
31 */
32class SaslBindRequest extends BindRequest
33{
34    /**
35     * @var string
36     */
37    protected $mechanism;
38
39    /**
40     * @var string|null
41     */
42    protected $credentials;
43
44    /**
45     * @var array
46     */
47    protected $options;
48
49    public function __construct(string $mechanism, ?string $credentials = null, array $options = [])
50    {
51        $this->username = '';
52        $this->mechanism = $mechanism;
53        $this->credentials = $credentials;
54        $this->options = $options;
55    }
56
57    public function getMechanism(): string
58    {
59        return $this->mechanism;
60    }
61
62    public function setMechanism(string $mech): self
63    {
64        $this->mechanism = $mech;
65
66        return $this;
67    }
68
69    public function getCredentials(): ?string
70    {
71        return $this->credentials;
72    }
73
74    public function getOptions(): array
75    {
76        return $this->options;
77    }
78
79    /**
80     * {@inheritDoc}
81     */
82    protected function getAsn1AuthChoice(): AbstractType
83    {
84        $sasl = Asn1::sequence(Asn1::octetString($this->mechanism));
85        if ($this->credentials !== null) {
86            $sasl->addChild(Asn1::octetString($this->credentials));
87        }
88
89        return Asn1::context(3, $sasl);
90    }
91
92    /**
93     * {@inheritDoc}
94     */
95    protected function validate(): void
96    {
97        if ($this->mechanism === '') {
98            throw new BindException('The mechanism name cannot be empty.');
99        }
100    }
101}
102