xref: /plugin/pureldap/vendor/freedsx/sasl/src/FreeDSx/Sasl/Encoder/PlainEncoder.php (revision 0b3fd2d31e4d1997548a8fbc53fa771027c4a47f)
1*0b3fd2d3SAndreas Gohr<?php
2*0b3fd2d3SAndreas Gohr
3*0b3fd2d3SAndreas Gohr/**
4*0b3fd2d3SAndreas Gohr * This file is part of the FreeDSx SASL package.
5*0b3fd2d3SAndreas Gohr *
6*0b3fd2d3SAndreas Gohr * (c) Chad Sikorra <Chad.Sikorra@gmail.com>
7*0b3fd2d3SAndreas Gohr *
8*0b3fd2d3SAndreas Gohr * For the full copyright and license information, please view the LICENSE
9*0b3fd2d3SAndreas Gohr * file that was distributed with this source code.
10*0b3fd2d3SAndreas Gohr */
11*0b3fd2d3SAndreas Gohr
12*0b3fd2d3SAndreas Gohrnamespace FreeDSx\Sasl\Encoder;
13*0b3fd2d3SAndreas Gohr
14*0b3fd2d3SAndreas Gohruse FreeDSx\Sasl\Exception\SaslEncodingException;
15*0b3fd2d3SAndreas Gohruse FreeDSx\Sasl\Message;
16*0b3fd2d3SAndreas Gohruse FreeDSx\Sasl\SaslContext;
17*0b3fd2d3SAndreas Gohr
18*0b3fd2d3SAndreas Gohr/**
19*0b3fd2d3SAndreas Gohr * Responsible for encoding / decoding PLAIN messages.
20*0b3fd2d3SAndreas Gohr *
21*0b3fd2d3SAndreas Gohr * @author Chad Sikorra <Chad.Sikorra@gmail.com>
22*0b3fd2d3SAndreas Gohr */
23*0b3fd2d3SAndreas Gohrclass PlainEncoder implements EncoderInterface
24*0b3fd2d3SAndreas Gohr{
25*0b3fd2d3SAndreas Gohr    /**
26*0b3fd2d3SAndreas Gohr     * {@inheritDoc}
27*0b3fd2d3SAndreas Gohr     */
28*0b3fd2d3SAndreas Gohr    public function encode(Message $message, SaslContext $context): string
29*0b3fd2d3SAndreas Gohr    {
30*0b3fd2d3SAndreas Gohr        if (!$message->has('authzid')) {
31*0b3fd2d3SAndreas Gohr            throw new SaslEncodingException('The PLAIN message must contain a authzid.');
32*0b3fd2d3SAndreas Gohr        }
33*0b3fd2d3SAndreas Gohr        if (!$message->has('authcid')) {
34*0b3fd2d3SAndreas Gohr            throw new SaslEncodingException('The PLAIN message must contain a authzid.');
35*0b3fd2d3SAndreas Gohr        }
36*0b3fd2d3SAndreas Gohr        if (!$message->has('password')) {
37*0b3fd2d3SAndreas Gohr            throw new SaslEncodingException('The PLAIN message must contain a password.');
38*0b3fd2d3SAndreas Gohr        }
39*0b3fd2d3SAndreas Gohr        $authzid = $this->validate($message->get('authzid'));
40*0b3fd2d3SAndreas Gohr        $authcid = $this->validate($message->get('authcid'));
41*0b3fd2d3SAndreas Gohr        $password = $this->validate($message->get('password'));
42*0b3fd2d3SAndreas Gohr
43*0b3fd2d3SAndreas Gohr        return $authzid . "\x00" . $authcid . "\x00" . $password;
44*0b3fd2d3SAndreas Gohr    }
45*0b3fd2d3SAndreas Gohr
46*0b3fd2d3SAndreas Gohr    /**
47*0b3fd2d3SAndreas Gohr     * {@inheritDoc}
48*0b3fd2d3SAndreas Gohr     */
49*0b3fd2d3SAndreas Gohr    public function decode(string $data, SaslContext $context): Message
50*0b3fd2d3SAndreas Gohr    {
51*0b3fd2d3SAndreas Gohr        if (preg_match('/^([^\x0]+)\x00([^\x0]+)\x00([^\x0]+)$/', $data, $matches) === 0) {
52*0b3fd2d3SAndreas Gohr            throw new SaslEncodingException('The PLAIN message data is malformed.');
53*0b3fd2d3SAndreas Gohr        }
54*0b3fd2d3SAndreas Gohr
55*0b3fd2d3SAndreas Gohr        return new Message([
56*0b3fd2d3SAndreas Gohr            'authzid' => $matches[1],
57*0b3fd2d3SAndreas Gohr            'authcid' => $matches[2],
58*0b3fd2d3SAndreas Gohr            'password' => $matches[3],
59*0b3fd2d3SAndreas Gohr        ]);
60*0b3fd2d3SAndreas Gohr    }
61*0b3fd2d3SAndreas Gohr
62*0b3fd2d3SAndreas Gohr    protected function validate(string $data): string
63*0b3fd2d3SAndreas Gohr    {
64*0b3fd2d3SAndreas Gohr        if (strpos($data,"\x00") !== false) {
65*0b3fd2d3SAndreas Gohr            throw new SaslEncodingException('PLAIN mechanism data cannot contain a null character.');
66*0b3fd2d3SAndreas Gohr        }
67*0b3fd2d3SAndreas Gohr
68*0b3fd2d3SAndreas Gohr        return $data;
69*0b3fd2d3SAndreas Gohr    }
70*0b3fd2d3SAndreas Gohr}
71