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\Asn1\Type\IntegerType; 16use FreeDSx\Asn1\Type\OctetStringType; 17use FreeDSx\Asn1\Type\SequenceType; 18use FreeDSx\Ldap\Exception\ProtocolException; 19 20/** 21 * Represents a base bind request. RFC 4511, 4.2 22 * 23 * BindRequest ::= [APPLICATION 0] SEQUENCE { 24 * version INTEGER (1 .. 127), 25 * name LDAPDN, 26 * authentication AuthenticationChoice } 27 * 28 * @author Chad Sikorra <Chad.Sikorra@gmail.com> 29 */ 30abstract class BindRequest implements RequestInterface 31{ 32 protected const APP_TAG = 0; 33 34 /** 35 * @var int 36 */ 37 protected $version = 3; 38 39 /** 40 * @var string 41 */ 42 protected $username; 43 44 /** 45 * @param int $version 46 * @return $this 47 */ 48 public function setVersion(int $version) 49 { 50 $this->version = $version; 51 52 return $this; 53 } 54 55 /** 56 * @return int 57 */ 58 public function getVersion(): int 59 { 60 return $this->version; 61 } 62 63 /** 64 * @param string $username 65 * @return $this 66 */ 67 public function setUsername(string $username) 68 { 69 $this->username = $username; 70 71 return $this; 72 } 73 74 /** 75 * @return string 76 */ 77 public function getUsername(): string 78 { 79 return $this->username; 80 } 81 82 /** 83 * {@inheritdoc} 84 */ 85 public function toAsn1(): AbstractType 86 { 87 $this->validate(); 88 89 return Asn1::application(self::APP_TAG, Asn1::sequence( 90 Asn1::integer($this->version), 91 Asn1::octetString($this->username), 92 $this->getAsn1AuthChoice() 93 )); 94 } 95 96 /** 97 * {@inheritdoc} 98 */ 99 public static function fromAsn1(AbstractType $type) 100 { 101 if (!$type instanceof SequenceType) { 102 throw new ProtocolException('The bind request in malformed'); 103 } 104 $version = $type->getChild(0); 105 $name = $type->getChild(1); 106 $auth = $type->getChild(2); 107 108 if ($version === null || $name === null || $auth === null) { 109 throw new ProtocolException('The bind request in malformed'); 110 } 111 if (!($version instanceof IntegerType && $name instanceof OctetStringType)) { 112 throw new ProtocolException('The bind request in malformed'); 113 } 114 $version = $version->getValue(); 115 $name = $name->getValue(); 116 117 if ($auth->getTagNumber() !== 0) { 118 throw new ProtocolException(sprintf( 119 'Only a simple bind is currently supported, but got: %s', 120 $auth->getTagNumber() 121 )); 122 } 123 $auth = (string) $auth->getValue(); 124 125 if ($auth === '') { 126 return new AnonBindRequest($name, $version); 127 } else { 128 return new SimpleBindRequest($name, $auth, $version); 129 } 130 } 131 132 /** 133 * Get the ASN1 AuthenticationChoice for the bind request. 134 * 135 * @return AbstractType 136 */ 137 abstract protected function getAsn1AuthChoice(): AbstractType; 138 139 /** 140 * This is called as the request is transformed to ASN1 to be encoded. If the request parameters are not valid 141 * then the method should throw an exception. 142 */ 143 abstract protected function validate(): void; 144} 145