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\Challenge; 13*0b3fd2d3SAndreas Gohr 14*0b3fd2d3SAndreas Gohruse FreeDSx\Sasl\Encoder\AnonymousEncoder; 15*0b3fd2d3SAndreas Gohruse FreeDSx\Sasl\Message; 16*0b3fd2d3SAndreas Gohruse FreeDSx\Sasl\SaslContext; 17*0b3fd2d3SAndreas Gohr 18*0b3fd2d3SAndreas Gohr/** 19*0b3fd2d3SAndreas Gohr * The ANONYMOUS challenge / response class. 20*0b3fd2d3SAndreas Gohr * 21*0b3fd2d3SAndreas Gohr * @author Chad Sikorra <Chad.Sikorra@gmail.com> 22*0b3fd2d3SAndreas Gohr */ 23*0b3fd2d3SAndreas Gohrclass AnonymousChallenge implements ChallengeInterface 24*0b3fd2d3SAndreas Gohr{ 25*0b3fd2d3SAndreas Gohr /** 26*0b3fd2d3SAndreas Gohr * @var SaslContext 27*0b3fd2d3SAndreas Gohr */ 28*0b3fd2d3SAndreas Gohr protected $context; 29*0b3fd2d3SAndreas Gohr 30*0b3fd2d3SAndreas Gohr /** 31*0b3fd2d3SAndreas Gohr * @var AnonymousEncoder 32*0b3fd2d3SAndreas Gohr */ 33*0b3fd2d3SAndreas Gohr protected $encoder; 34*0b3fd2d3SAndreas Gohr 35*0b3fd2d3SAndreas Gohr public function __construct(bool $isServerMode = false) 36*0b3fd2d3SAndreas Gohr { 37*0b3fd2d3SAndreas Gohr $this->encoder = new AnonymousEncoder(); 38*0b3fd2d3SAndreas Gohr $this->context = new SaslContext(); 39*0b3fd2d3SAndreas Gohr $this->context->setIsServerMode($isServerMode); 40*0b3fd2d3SAndreas Gohr } 41*0b3fd2d3SAndreas Gohr 42*0b3fd2d3SAndreas Gohr /** 43*0b3fd2d3SAndreas Gohr * {@inheritDoc} 44*0b3fd2d3SAndreas Gohr */ 45*0b3fd2d3SAndreas Gohr public function challenge(?string $received = null, array $options = []): SaslContext 46*0b3fd2d3SAndreas Gohr { 47*0b3fd2d3SAndreas Gohr if ($this->context->isServerMode()) { 48*0b3fd2d3SAndreas Gohr $this->processServer($received); 49*0b3fd2d3SAndreas Gohr } else { 50*0b3fd2d3SAndreas Gohr $this->processClient($options); 51*0b3fd2d3SAndreas Gohr } 52*0b3fd2d3SAndreas Gohr 53*0b3fd2d3SAndreas Gohr return $this->context; 54*0b3fd2d3SAndreas Gohr } 55*0b3fd2d3SAndreas Gohr 56*0b3fd2d3SAndreas Gohr protected function processServer(?string $received): void 57*0b3fd2d3SAndreas Gohr { 58*0b3fd2d3SAndreas Gohr if ($received === null) { 59*0b3fd2d3SAndreas Gohr return; 60*0b3fd2d3SAndreas Gohr } 61*0b3fd2d3SAndreas Gohr $received = $this->encoder->decode($received, $this->context); 62*0b3fd2d3SAndreas Gohr 63*0b3fd2d3SAndreas Gohr $this->context->setIsComplete(true); 64*0b3fd2d3SAndreas Gohr $this->context->setIsAuthenticated(true); 65*0b3fd2d3SAndreas Gohr 66*0b3fd2d3SAndreas Gohr if ($received->has('trace')) { 67*0b3fd2d3SAndreas Gohr $this->context->set('trace', $received->get('trace')); 68*0b3fd2d3SAndreas Gohr } 69*0b3fd2d3SAndreas Gohr } 70*0b3fd2d3SAndreas Gohr 71*0b3fd2d3SAndreas Gohr protected function processClient(array $options): void 72*0b3fd2d3SAndreas Gohr { 73*0b3fd2d3SAndreas Gohr $data = []; 74*0b3fd2d3SAndreas Gohr 75*0b3fd2d3SAndreas Gohr if (isset($options['username']) || isset($options['trace'])) { 76*0b3fd2d3SAndreas Gohr $data['trace'] = $options['trace'] ?? $options['username']; 77*0b3fd2d3SAndreas Gohr } 78*0b3fd2d3SAndreas Gohr 79*0b3fd2d3SAndreas Gohr $this->context->setResponse($this->encoder->encode(new Message($data), $this->context)); 80*0b3fd2d3SAndreas Gohr $this->context->setIsComplete(true); 81*0b3fd2d3SAndreas Gohr $this->context->setIsAuthenticated(true); 82*0b3fd2d3SAndreas Gohr } 83*0b3fd2d3SAndreas Gohr} 84