public static async ValueTask <RfcControls> Decode(IAsn1Decoder dec, Stream inRenamed, int len, CancellationToken cancellationToken) { return(new RfcControls((await DecodeStructured(dec, inRenamed, len, cancellationToken) .ConfigureAwait(false)) .Select <Asn1Object, Asn1Object>(item => new RfcControl((Asn1Sequence)item)) .ToArray())); }
public static async ValueTask <RfcExtendedResponse> Decode(IAsn1Decoder dec, Stream inRenamed, int len, CancellationToken cancellationToken) { var response = new RfcExtendedResponse(await DecodeStructured(dec, inRenamed, len, cancellationToken).ConfigureAwait(false)); // decode optional tagged elements if (response.Size() > 3) { for (var i = 3; i < response.Size(); i++) { var obj = (Asn1Tagged)response.get_Renamed(i); var id = obj.GetIdentifier(); switch (id.Tag) { case RfcLdapResult.Referral: var content = ((Asn1OctetString)obj.TaggedValue).ByteValue(); var bais = new MemoryStream(content); response.set_Renamed(i, new RfcReferral(await DecodeStructured(dec, bais, content.Length, cancellationToken).ConfigureAwait(false))); response._referralIndex = i; break; case ResponseNameTag: response.set_Renamed(i, new RfcLdapOid(((Asn1OctetString)obj.TaggedValue).ByteValue())); response._responseNameIndex = i; break; case ResponseTag: response.set_Renamed(i, obj.TaggedValue); response._responseIndex = i; break; } } } return(response); }
/// <summary> /// Initializes a new instance of the <see cref="RfcExtendedResponse"/> class. /// The only time a client will create a ExtendedResponse is when it is /// decoding it from an InputStream /// </summary> /// <param name="dec">The decimal.</param> /// <param name="stream">The stream.</param> /// <param name="len">The length.</param> public RfcExtendedResponse(IAsn1Decoder dec, Stream stream, int len) : base(dec, stream, len) { if (Size() > 3) { for (var i = 3; i < Size(); i++) { var obj = (Asn1Tagged)Get(i); var id = obj.GetIdentifier(); switch (id.Tag) { case RfcLdapResult.REFERRAL: var content = ((Asn1OctetString)obj.TaggedValue).ByteValue(); var bais = new MemoryStream(content.ToByteArray()); Set(i, new Asn1SequenceOf(dec, bais, content.Length)); referralIndex = i; break; case RESPONSE_NAME: Set(i, new RfcLdapOID(((Asn1OctetString)obj.TaggedValue).ByteValue())); responseNameIndex = i; break; case RESPONSE: Set(i, obj.TaggedValue); responseIndex = i; break; } } } }
/// <summary> /// The decode byte stream. /// </summary> /// <param name="byteStream"> /// The byte stream. /// </param> /// <param name="decoder"> /// The decoder. /// </param> /// <param name="pduNum"> /// The pdu num. /// </param> /// <returns> /// The <see cref="string"/>. /// </returns> private string DecodeByteStream(string byteStream, IAsn1Decoder decoder, int pduNum) { if (decoder == null) { Log.Error("decoder is empty"); return(null); } byte[] curBytes = this.StringToBytes(byteStream); // convert to bytes if (curBytes == null) { return(null); } string asnStream; var isDecode = decoder.Decode(curBytes, curBytes.Length, pduNum, out asnStream); if (!isDecode) { //yanjiewa Log.Error("asnStream is empty"); return(asnStream); } int finishLength = asnStream.IndexOf('\0'); if (finishLength != -1) { asnStream = asnStream.Substring(0, finishLength); } return(asnStream); }
// ************************************************************************* // Constructors for ExtendedResponse // ************************************************************************* /// <summary> /// The only time a client will create a ExtendedResponse is when it is /// decoding it from an InputStream. /// </summary> public RfcExtendedResponse(IAsn1Decoder dec, Stream inRenamed, int len) : base(dec, inRenamed, len) { // decode optional tagged elements if (Size() > 3) { for (var i = 3; i < Size(); i++) { var obj = (Asn1Tagged)get_Renamed(i); var id = obj.GetIdentifier(); switch (id.Tag) { case RfcLdapResult.Referral: var content = ((Asn1OctetString)obj.TaggedValue).ByteValue(); var bais = new MemoryStream(content); set_Renamed(i, new RfcReferral(dec, bais, content.Length)); _referralIndex = i; break; case ResponseNameTag: set_Renamed(i, new RfcLdapOid(((Asn1OctetString)obj.TaggedValue).ByteValue())); _responseNameIndex = i; break; case ResponseTag: set_Renamed(i, obj.TaggedValue); _responseIndex = i; break; } } } }
/// <summary> /// Constructs an Asn1Tagged object by decoding data from an /// input stream. /// </summary> /// <param name="dec"> /// The decoder object to use when decoding the /// input stream. Sometimes a developer might want to pass /// in his/her own decoder object. /// </param> /// <param name="in"> /// A byte stream that contains the encoded ASN.1. /// </param> public Asn1Tagged(IAsn1Decoder dec, Stream inRenamed, int len, Asn1Identifier identifier) : base(identifier) { // If we are decoding an implicit tag, there is no way to know at this // low level what the base type really is. We can place the content // into an Asn1OctetString type and pass it back to the application who // will be able to create the appropriate ASN.1 type for this tag. _content = new Asn1OctetString(dec, inRenamed, len); }
public RfcControls(IAsn1Decoder dec, Stream stream, int len) : base(dec, stream, len) { // Convert each SEQUENCE element to a Control for (var i = 0; i < Size(); i++) { var tempControl = new RfcControl((Asn1Sequence)Get(i)); Set(i, tempControl); } }
/// <summary> Constructs a Controls object by decoding it from an InputStream.</summary> public RfcControls(IAsn1Decoder dec, Stream inRenamed, int len) : base(dec, inRenamed, len) { // Convert each SEQUENCE element to a Control for (var i = 0; i < Size(); i++) { var tempControl = new RfcControl((Asn1Sequence)get_Renamed(i)); set_Renamed(i, tempControl); } }
/// <summary> Decode an Asn1Structured type from an InputStream.</summary> protected internal void DecodeStructured(IAsn1Decoder dec, Stream inRenamed, int len) { var componentLen = new int[1]; // collects length of component while (len > 0) { Add(dec.Decode(inRenamed, componentLen)); len -= componentLen[0]; } }
// ************************************************************************* // Constructors for SearchResultEntry // ************************************************************************* /// <summary> /// The only time a client will create a SearchResultEntry is when it is /// decoding it from an InputStream. /// </summary> public RfcSearchResultEntry(IAsn1Decoder dec, Stream inRenamed, int len) : base(dec, inRenamed, len) { // Decode objectName // set(0, new RfcLdapDN(((Asn1OctetString)get(0)).stringValue())); // Create PartitalAttributeList. This does not need to be decoded, only // typecast. // set(1, new PartitalAttributeList()); }
/// <summary> /// Initializes a new instance of the <see cref="RfcLdapMessage"/> class. /// Will decode an RfcLdapMessage directly from an InputStream. /// </summary> /// <param name="dec">The decimal.</param> /// <param name="stream">The stream.</param> /// <param name="len">The length.</param> /// <exception cref="Exception">RfcLdapMessage: Invalid tag: " + protocolOpId.Tag</exception> public RfcLdapMessage(IAsn1Decoder dec, Stream stream, int len) : base(dec, stream, len) { // Decode implicitly tagged protocol operation from an Asn1Tagged type // to its appropriate application type. var protocolOp = (Asn1Tagged)Get(1); var protocolOpId = protocolOp.GetIdentifier(); var content = ((Asn1OctetString)protocolOp.TaggedValue).ByteValue(); var bais = new MemoryStream(content.ToByteArray()); switch ((LdapOperation)protocolOpId.Tag) { case LdapOperation.SearchResponse: Set(1, new RfcSearchResultEntry(dec, bais, content.Length)); break; case LdapOperation.SearchResult: Set(1, new RfcSearchResultDone(dec, bais, content.Length)); break; case LdapOperation.SearchResultReference: Set(1, new RfcSearchResultReference(dec, bais, content.Length)); break; case LdapOperation.BindResponse: Set(1, new RfcBindResponse(dec, bais, content.Length)); break; case LdapOperation.ExtendedResponse: Set(1, new RfcExtendedResponse(dec, bais, content.Length)); break; case LdapOperation.IntermediateResponse: Set(1, new RfcIntermediateResponse(dec, bais, content.Length)); break; case LdapOperation.ModifyResponse: Set(1, new RfcModifyResponse(dec, bais, content.Length)); break; default: throw new Exception("RfcLdapMessage: Invalid tag: " + protocolOpId.Tag); } // decode optional implicitly tagged controls from Asn1Tagged type to // to RFC 2251 types. if (Size() > 2) { var controls = (Asn1Tagged)Get(2); content = ((Asn1OctetString)controls.TaggedValue).ByteValue(); bais = new MemoryStream(content.ToByteArray()); Set(2, new RfcControls(dec, bais, content.Length)); } }
// Constructors for BindResponse /// <summary> /// Initializes a new instance of the <see cref="RfcBindResponse"/> class. /// The only time a client will create a BindResponse is when it is /// decoding it from an InputStream /// Note: If serverSaslCreds is included in the BindResponse, it does not /// need to be decoded since it is already an OCTET STRING. /// </summary> /// <param name="dec">The decimal.</param> /// <param name="stream">The in renamed.</param> /// <param name="len">The length.</param> public RfcBindResponse(IAsn1Decoder dec, Stream stream, int len) : base(dec, stream, len) { // Decode optional referral from Asn1OctetString to Referral. if (Size() > 3) { var obj = (Asn1Tagged)Get(3); if (obj.GetIdentifier().Tag == RfcLdapResult.REFERRAL) { var content = ((Asn1OctetString)obj.TaggedValue).ByteValue(); var bais = new MemoryStream(content.ToByteArray()); Set(3, new Asn1SequenceOf(dec, bais, content.Length)); } } }
/// <summary> Decode an Asn1Structured type from an InputStream.</summary> protected internal static ValueTask <Asn1Object[]> DecodeStructured(IAsn1Decoder dec, Stream inRenamed, int len, CancellationToken cancellationToken) { return(Decode().ToArrayAsync(cancellationToken)); async IAsyncEnumerable <Asn1Object> Decode() { var componentLen = new int[1]; // collects length of component while (len > 0) { yield return(await dec.Decode(inRenamed, componentLen, cancellationToken).ConfigureAwait(false)); len -= componentLen[0]; } } }
// ************************************************************************* // Constructors for BindResponse // ************************************************************************* /// <summary> /// The only time a client will create a BindResponse is when it is /// decoding it from an InputStream /// Note: If serverSaslCreds is included in the BindResponse, it does not /// need to be decoded since it is already an OCTET STRING. /// </summary> public RfcBindResponse(IAsn1Decoder dec, Stream inRenamed, int len) : base(dec, inRenamed, len) { // Decode optional referral from Asn1OctetString to Referral. if (Size() > 3) { var obj = (Asn1Tagged)get_Renamed(3); var id = obj.GetIdentifier(); if (id.Tag == RfcLdapResult.Referral) { var content = ((Asn1OctetString)obj.TaggedValue).ByteValue(); var bais = new MemoryStream(content); set_Renamed(3, new RfcReferral(dec, bais, content.Length)); } } }
// ************************************************************************* // Constructors for ExtendedResponse // ************************************************************************* /** * The only time a client will create a IntermediateResponse is when it is * decoding it from an InputStream. The stream contains the intermediate * response sequence that follows the msgID in the PDU. The intermediate * response draft defines this as: * IntermediateResponse ::= [APPLICATION 25] SEQUENCE { * responseName [0] LDAPOID OPTIONAL, * responseValue [1] OCTET STRING OPTIONAL } * * Until post Falcon sp1, the LDAP server was incorrectly encoding * intermediate response as: * IntermediateResponse ::= [APPLICATION 25] SEQUENCE { * Components of LDAPResult, * responseName [0] LDAPOID OPTIONAL, * responseValue [1] OCTET STRING OPTIONAL } * * where the Components of LDAPResult are * resultCode ENUMERATED {...} * matchedDN LDAPDN, * errorMessage LDAPString, * referral [3] Referral OPTIONAL } * * * (The components of LDAPResult never have the optional referral.) * This constructor is written to handle both cases. * * The sequence of this intermediate response will have the element * at index m_responseNameIndex set to an RfcLDAPOID containing the * oid of the response. The element at m_responseValueIndex will be set * to an ASN1OctetString containing the value bytes. */ public RfcIntermediateResponse(IAsn1Decoder dec, Stream inRenamed, int len) : base(dec, inRenamed, len) // throws IOException { // super(dec, in, len); var i = 0; _mResponseNameIndex = _mResponseValueIndex = 0; // decode optional tagged elements. The parent class constructor will // have decoded these elements as ASN1Tagged objects with the value // stored as an ASN1OctectString object. if (Size() >= 3) // the incorrectly encoded case, LDAPResult contains { i = 3; // at least 3 components } else { i = 0; // correctly encoded case, can have zero components } for (; i < Size(); i++) { var obj = (Asn1Tagged)get_Renamed(i); var id = obj.GetIdentifier(); switch (id.Tag) { case TagResponseName: set_Renamed(i, new RfcLdapOid( ((Asn1OctetString)obj.TaggedValue).ByteValue())); _mResponseNameIndex = i; break; case TagResponse: set_Renamed(i, obj.TaggedValue); _mResponseValueIndex = i; break; } } }
public static async ValueTask <RfcBindResponse> Decode(IAsn1Decoder dec, Stream inRenamed, int len, CancellationToken cancellationToken) { var response = new RfcBindResponse(await DecodeStructured(dec, inRenamed, len, cancellationToken).ConfigureAwait(false)); // Decode optional referral from Asn1OctetString to Referral. if (response.Size() > 3) { var obj = (Asn1Tagged)response.get_Renamed(3); var id = obj.GetIdentifier(); if (id.Tag == RfcLdapResult.Referral) { var content = ((Asn1OctetString)obj.TaggedValue).ByteValue(); var bais = new MemoryStream(content); response.set_Renamed(3, new RfcReferral(await DecodeStructured(dec, bais, content.Length, cancellationToken).ConfigureAwait(false))); } } return(response); }
// ************************************************************************* // Constructors for ExtendedResponse // ************************************************************************* /** * The only time a client will create a IntermediateResponse is when it is * decoding it from an InputStream. The stream contains the intermediate * response sequence that follows the msgID in the PDU. The intermediate * response draft defines this as: * IntermediateResponse ::= [APPLICATION 25] SEQUENCE { * responseName [0] LDAPOID OPTIONAL, * responseValue [1] OCTET STRING OPTIONAL } * * Until post Falcon sp1, the LDAP server was incorrectly encoding * intermediate response as: * IntermediateResponse ::= [APPLICATION 25] SEQUENCE { * Components of LDAPResult, * responseName [0] LDAPOID OPTIONAL, * responseValue [1] OCTET STRING OPTIONAL } * * where the Components of LDAPResult are * resultCode ENUMERATED {...} * matchedDN LDAPDN, * errorMessage LDAPString, * referral [3] Referral OPTIONAL } * * * (The components of LDAPResult never have the optional referral.) * This constructor is written to handle both cases. * * The sequence of this intermediate response will have the element * at index m_responseNameIndex set to an RfcLDAPOID containing the * oid of the response. The element at m_responseValueIndex will be set * to an ASN1OctetString containing the value bytes. */ public static async ValueTask <RfcIntermediateResponse> Decode(IAsn1Decoder dec, Stream inRenamed, int len, CancellationToken cancellationToken) { var response = new RfcIntermediateResponse(await DecodeStructured(dec, inRenamed, len, cancellationToken).ConfigureAwait(false)); response._mResponseNameIndex = response._mResponseValueIndex = 0; int i; // decode optional tagged elements. The parent class constructor will // have decoded these elements as ASN1Tagged objects with the value // stored as an ASN1OctectString object. // the incorrectly encoded case, LDAPResult contains if (response.Size() >= 3) { i = 3; // at least 3 components } else { i = 0; // correctly encoded case, can have zero components } for (; i < response.Size(); i++) { var obj = (Asn1Tagged)response.get_Renamed(i); var id = obj.GetIdentifier(); switch (id.Tag) { case TagResponseName: response.set_Renamed(i, new RfcLdapOid( ((Asn1OctetString)obj.TaggedValue).ByteValue())); response._mResponseNameIndex = i; break; case TagResponse: response.set_Renamed(i, obj.TaggedValue); response._mResponseValueIndex = i; break; } } return(response); }
public RfcIntermediateResponse(IAsn1Decoder dec, Stream stream, int len) : base(dec, stream, len) { var i = Size() >= 3 ? 3 : 0; for (; i < Size(); i++) { var obj = (Asn1Tagged)Get(i); switch (obj.GetIdentifier().Tag) { case TagResponseName: Set(i, new Asn1OctetString(((Asn1OctetString)obj.TaggedValue).ByteValue())); break; case TagResponse: Set(i, obj.TaggedValue); break; } } }
/// <summary> Will decode an RfcLdapMessage directly from an InputStream.</summary> public RfcLdapMessage(IAsn1Decoder dec, Stream inRenamed, int len) : base(dec, inRenamed, len) { // Decode implicitly tagged protocol operation from an Asn1Tagged type // to its appropriate application type. var protocolOp = (Asn1Tagged)get_Renamed(1); var protocolOpId = protocolOp.GetIdentifier(); var content = ((Asn1OctetString)protocolOp.TaggedValue).ByteValue(); var bais = new MemoryStream(content); switch (protocolOpId.Tag) { case LdapMessage.SearchResponse: set_Renamed(1, new RfcSearchResultEntry(dec, bais, content.Length)); break; case LdapMessage.SearchResult: set_Renamed(1, new RfcSearchResultDone(dec, bais, content.Length)); break; case LdapMessage.SearchResultReference: set_Renamed(1, new RfcSearchResultReference(dec, bais, content.Length)); break; case LdapMessage.AddResponse: set_Renamed(1, new RfcAddResponse(dec, bais, content.Length)); break; case LdapMessage.BindResponse: set_Renamed(1, new RfcBindResponse(dec, bais, content.Length)); break; case LdapMessage.CompareResponse: set_Renamed(1, new RfcCompareResponse(dec, bais, content.Length)); break; case LdapMessage.DelResponse: set_Renamed(1, new RfcDelResponse(dec, bais, content.Length)); break; case LdapMessage.ExtendedResponse: set_Renamed(1, new RfcExtendedResponse(dec, bais, content.Length)); break; case LdapMessage.IntermediateResponse: set_Renamed(1, new RfcIntermediateResponse(dec, bais, content.Length)); break; case LdapMessage.ModifyResponse: set_Renamed(1, new RfcModifyResponse(dec, bais, content.Length)); break; case LdapMessage.ModifyRdnResponse: set_Renamed(1, new RfcModifyDnResponse(dec, bais, content.Length)); break; default: throw new Exception("RfcLdapMessage: Invalid tag: " + protocolOpId.Tag); } // decode optional implicitly tagged controls from Asn1Tagged type to // to RFC 2251 types. if (Size() > 2) { var controls = (Asn1Tagged)get_Renamed(2); // Asn1Identifier controlsId = protocolOp.getIdentifier(); // we could check to make sure we have controls here.... content = ((Asn1OctetString)controls.TaggedValue).ByteValue(); bais = new MemoryStream(content); set_Renamed(2, new RfcControls(dec, bais, content.Length)); } }
/// <summary> </summary> public RfcLdapString(IAsn1Decoder dec, Stream inRenamed, int len) : base(dec, inRenamed, len) { }
/// <summary> /// Initializes a new instance of the <see cref="RfcControl"/> class. /// </summary> /// <param name="dec">The decoder object to use when decoding the /// input stream. Sometimes a developer might want to pass /// in his/her own decoder object</param> /// <param name="stream">The stream.</param> /// <param name="len">The length.</param> public RfcControl(IAsn1Decoder dec, Stream stream, int len) : base(dec, stream, len) { }
/// <summary> /// Initializes a new instance of the <see cref="RfcSearchResultReference"/> class. /// The only time a client will create a SearchResultReference is when it is /// decoding it from an InputStream /// </summary> /// <param name="dec">The decimal.</param> /// <param name="stream">The in renamed.</param> /// <param name="len">The length.</param> public RfcSearchResultReference(IAsn1Decoder dec, Stream stream, int len) : base(dec, stream, len) { }
public RfcLdapString(IAsn1Decoder dec, Stream stream, int len) : base(dec, stream, len) { }
/// <summary> /// Constructs an Asn1SequenceOf object by decoding data from an /// input stream. /// </summary> /// <param name="dec"> /// The decoder object to use when decoding the /// input stream. Sometimes a developer might want to pass /// in his/her own decoder object. /// </param> /// <param name="in"> /// A byte stream that contains the encoded ASN.1. /// </param> public Asn1SequenceOf(IAsn1Decoder dec, Stream inRenamed, int len) : base(Id) { DecodeStructured(dec, inRenamed, len); }
// ************************************************************************* // Constructor for ModifyResponse // ************************************************************************* /// <summary> /// The only time a client will create a ModifyResponse is when it is /// decoding it from an InputStream. /// </summary> public RfcModifyResponse(IAsn1Decoder dec, Stream inRenamed, int len) : base(dec, inRenamed, len) { }
public RfcSearchResultEntry(IAsn1Decoder dec, Stream stream, int len) : base(dec, stream, len) { }
/// <summary> /// Initializes a new instance of the <see cref="RfcModifyResponse"/> class. /// The only time a client will create a ModifyResponse is when it is /// decoding it from an InputStream /// </summary> /// <param name="dec">The decimal.</param> /// <param name="stream">The in renamed.</param> /// <param name="len">The length.</param> public RfcModifyResponse(IAsn1Decoder dec, Stream stream, int len) : base(dec, stream, len) { }
/// <summary> Constructs a Control object by decoding it from an InputStream.</summary> public RfcControl(IAsn1Decoder dec, Stream inRenamed, int len) : base(dec, inRenamed, len) { }
/// <summary> /// Constructs an Asn1Boolean object by decoding data from an /// input stream. /// </summary> /// <param name="dec"> /// The decoder object to use when decoding the /// input stream. Sometimes a developer might want to pass /// in his/her own decoder object. /// </param> /// <param name="in"> /// A byte stream that contains the encoded ASN.1. /// </param> public Asn1Boolean(IAsn1Decoder dec, Stream inRenamed, int len) : base(Id) { _content = (bool)dec.DecodeBoolean(inRenamed, len); }
// ************************************************************************* // Constructors for SearchResultDone // ************************************************************************* /// <summary> Decode a search result done from the input stream.</summary> public RfcSearchResultDone(IAsn1Decoder dec, Stream inRenamed, int len) : base(dec, inRenamed, len) { }