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