using System; namespace Unosquare.Swan.Networking.Ldap { /// /// Represents an Ldap Control. ///
  /// Control ::= SEQUENCE {
  /// controlType             LdapOID,
  /// criticality             BOOLEAN DEFAULT FALSE,
  /// controlValue            OCTET STRING OPTIONAL }
  /// 
///
/// internal class RfcControl : Asn1Sequence { /// /// Initializes a new instance of the class. /// Note: criticality is only added if true, as per RFC 2251 sec 5.1 part /// (4): If a value of a type is its default value, it MUST be /// absent. /// /// Type of the control. /// The criticality. /// The control value. public RfcControl(String controlType, Asn1Boolean criticality = null, Asn1Object controlValue = null) : base(3) { this.Add(controlType); this.Add(criticality ?? new Asn1Boolean(false)); if(controlValue != null) { this.Add(controlValue); } } public RfcControl(Asn1Structured seqObj) : base(3) { for(Int32 i = 0; i < seqObj.Size(); i++) { this.Add(seqObj.Get(i)); } } public Asn1OctetString ControlType => (Asn1OctetString)this.Get(0); public Asn1Boolean Criticality => this.Size() > 1 && this.Get(1) is Asn1Boolean boolean ? boolean : new Asn1Boolean(false); public Asn1OctetString ControlValue { get { if(this.Size() > 2) { // MUST be a control value return (Asn1OctetString)this.Get(2); } return this.Size() > 1 && this.Get(1) is Asn1OctetString s ? s : null; } set { if(value == null) { return; } if(this.Size() == 3) { // We already have a control value, replace it this.Set(2, value); return; } if(this.Size() == 2) { // Get the second element Asn1Object obj = this.Get(1); // Is this a control value if(obj is Asn1OctetString) { // replace this one this.Set(1, value); } else { // add a new one at the end this.Add(value); } } } } } /// /// Represents Ldap Sasl Credentials. ///
  /// SaslCredentials ::= SEQUENCE {
  /// mechanism               LdapString,
  /// credentials             OCTET STRING OPTIONAL }
  /// 
/// internal class RfcSaslCredentials : Asn1Sequence { public RfcSaslCredentials(String mechanism, SByte[] credentials = null) : base(2) { this.Add(mechanism); if(credentials != null) { this.Add(new Asn1OctetString(credentials)); } } } /// /// Represents an Ldap Authentication Choice. ///
  /// AuthenticationChoice ::= CHOICE {
  /// simple                  [0] OCTET STRING,
  /// -- 1 and 2 reserved
  /// sasl                    [3] SaslCredentials }
  /// 
/// internal class RfcAuthenticationChoice : Asn1Choice { public RfcAuthenticationChoice(SByte[] passwd) : base(new Asn1Tagged(new Asn1Identifier(0), new Asn1OctetString(passwd), false)) { } public RfcAuthenticationChoice(String mechanism, SByte[] credentials) : base(new Asn1Tagged(new Asn1Identifier(3, true), new RfcSaslCredentials(mechanism, credentials), false)) { // implicit tagging } } }