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