/// <summary>
        /// Adds extended controls to a packet.
        /// </summary>
        /// <param name="packet">The packet to which the controls are added.</param>
        /// <param name="controls">The controls.</param>
        internal void AddDirectoryControls(AdtsLdapPacket packet, params MsLdap.DirectoryControl[] controls)
        {
            LDAPMessage message = packet.ldapMessagev3;

            int existingControlCount = (message.controls != null) ? message.controls.Elements.Length : 0;
            Control[] controlArray = new Control[existingControlCount + controls.Length];

            // Add original existing controls
            for (int i = 0; i < existingControlCount; i++)
            {
                controlArray[i] = message.controls.Elements[i];
            }

            // Add newly added controls
            for (int i = 0; i < controls.Length; i++)
            {
                controlArray[existingControlCount + i] = new Control(
                    new LDAPOID(controls[i].Type),
                    new Asn1Boolean(controls[i].IsCritical),
                    new Asn1OctetString(controls[i].GetValue()));
            }

            Controls allControls = new Controls(controlArray);

            message.controls = allControls;
        }
예제 #2
0
        /// <summary>
        /// Adds extended controls to a packet.
        /// </summary>
        /// <param name="packet">The packet to which the controls are added.</param>
        /// <param name="controls">The controls.</param>
        internal void AddDirectoryControls(AdtsLdapPacket packet, params MsLdap.DirectoryControl[] controls)
        {
            LDAPMessage message = packet.ldapMessagev3;

            int existingControlCount = (message.controls != null) ? message.controls.Elements.Length : 0;

            Control[] controlArray = new Control[existingControlCount + controls.Length];

            // Add original existing controls
            for (int i = 0; i < existingControlCount; i++)
            {
                controlArray[i] = message.controls.Elements[i];
            }

            // Add newly added controls
            for (int i = 0; i < controls.Length; i++)
            {
                controlArray[existingControlCount + i] = new Control(
                    new LDAPOID(controls[i].Type),
                    new Asn1Boolean(controls[i].IsCritical),
                    new Asn1OctetString(controls[i].GetValue()));
            }

            Controls allControls = new Controls(controlArray);

            message.controls = allControls;
        }
예제 #3
0
        /// <summary>
        /// Expects a packet.
        /// </summary>
        /// <param name="timeout">The timeout to be waited.</param>
        /// <param name="context">The context to be returned.</param>
        /// <returns>The packet received.</returns>
        public AdtsLdapPacket ExpectPacket(TimeSpan timeout, out AdtsLdapContext context)
        {
            while (true)
            {
                TransportEvent transportEvent = this.transportStack.ExpectTransportEvent(timeout);
                if (transportEvent.EventType == EventType.ReceivedPacket)
                {
                    AdtsLdapPacket packet = (AdtsLdapPacket)transportEvent.EventObject;
                    context = this.contextManager.GetContext((IPEndPoint)transportEvent.EndPoint, this.isTcp);

                    return(packet);
                }
                else if (transportEvent.EventType == EventType.Disconnected)
                {
                    // Remove context if disconnected.
                    this.transportStack.Disconnect((IPEndPoint)transportEvent.EndPoint);
                    context = this.contextManager.GetContext((IPEndPoint)transportEvent.EndPoint, this.isTcp);
                    this.contextManager.RemoveContext((IPEndPoint)transportEvent.EndPoint, this.isTcp);

                    return(null);
                }
                else if (transportEvent.EventType == EventType.Exception)
                {
                    throw (Exception)transportEvent.EventObject;
                }
            }
        }
예제 #4
0
 /// <summary>
 /// Adds extended controls to a packet.
 /// </summary>
 /// <param name="packet">The packet to which the controls are added.</param>
 /// <param name="controls">The controls.</param>
 /// <exception cref="NotSupportedException">
 /// Thrown when trying to add controls to an LDAP v2 packet.
 /// </exception>
 public void AddDirectoryControls(AdtsLdapPacket packet, params DirectoryControl[] controls)
 {
     if (packet.ldapMessagev2 != null)
     {
         throw new NotSupportedException("Extended controls are only supported for LDAP v3 packets.");
     }
     this.encoderv3.AddDirectoryControls(packet, controls);
 }
예제 #5
0
 /// <summary>
 /// Adds extended controls to a packet.
 /// </summary>
 /// <param name="packet">The packet to which the controls are added.</param>
 /// <param name="controls">The controls.</param>
 /// <exception cref="NotSupportedException">
 /// Thrown when trying to add controls to an LDAP v2 packet.
 /// </exception>
 public virtual void AddDirectoryControls(AdtsLdapPacket packet, params DirectoryControl[] controls)
 {
     if (this.encoder is AdtsLdapV2Encoder)
     {
         throw new NotSupportedException("Extended controls are only supported for LDAP v3 packets.");
     }
     (this.encoder as AdtsLdapV3Encoder).AddDirectoryControls(packet, controls);
 }
예제 #6
0
        /// <summary>
        /// Sends a packet to server.
        /// </summary>
        /// <param name="packet">The packet to be sent.</param>
        /// <exception cref="InvalidOperationException">
        /// thrown when Transport is null! Please invoke Connect() first!
        /// </exception>
        public virtual void SendPacket(AdtsLdapPacket packet)
        {
            if (this.transportStack == null)
            {
                throw new InvalidOperationException("Transport is null! Please invoke Connect() first!");
            }

            this.transportStack.SendPacket(packet);
            this.context.MessageId++;
        }
        /// <summary>
        /// Decodes an LDAP v3 packet.
        /// </summary>
        /// <param name="messageBytes">The message bytes that contains the packet data.</param>
        /// <param name="context">The context that contains decode-related information.</param>
        /// <returns>Decoded LDAP v3 packet.</returns>
        internal override AdtsLdapPacket ParseAdtsLdapPacket(byte[] messageBytes, AdtsLdapContext context)
        {
            LDAPMessage        message      = new LDAPMessage();
            Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(messageBytes);

            message.BerDecode(decodeBuffer);

            Type           innerMessageType = message.protocolOp.GetData().GetType();
            AdtsLdapPacket packet           = CreatePacketFromType(innerMessageType);

            context.MessageId    = (long)message.messageID.Value;
            packet.messageId     = (long)message.messageID.Value;
            packet.ldapMessagev3 = message;

            return(packet);
        }
예제 #8
0
        /// <summary>
        /// This method encapsulates LdapV2Decoder and LdapV3Decoder because the incoming packets may be
        /// LDAP v2 or v3 packets, the decoding may require both decoders if the LDAP version that client uses
        /// is not clear.
        /// </summary>
        /// <param name="endPoint">The end point of the client.</param>
        /// <param name="messageBytes">The message bytes that contains the packet data.</param>
        /// <param name="consumedLength">Consumed length.</param>
        /// <param name="expectedLength">
        /// Indicates expected length if the message bytes doesn't all packet data.
        /// </param>
        /// <returns>Decoded packets.</returns>
        internal override StackPacket[] DecodeLdapPacketCallBack(
            object endPoint,
            byte[] messageBytes,
            out int consumedLength,
            out int expectedLength)
        {
            // Get packet data, start decoding.
            IPEndPoint      remote  = (IPEndPoint)endPoint;
            AdtsLdapContext context = GetContext(remote, this.server.IsTcp);

            byte[] data = messageBytes;

            // decode messageBytes if needed
            if (context != null && messageBytes != null)
            {
                // if security is not init, and the package is SslHandshake, init security.
                if (context.Security == null)
                {
                    AdtsLdapSslTlsSecurityHeader header = new AdtsLdapSslTlsSecurityHeader();
                    header.FromBytes(messageBytes);

                    if (header.IsSslHandShake)
                    {
                        this.server.SslStartup(context);
                    }
                }

                // decode messageBytes with security.
                if (context.Security != null)
                {
                    data = this.server.Decrypt(context, messageBytes);
                }
            }

            byte[] packetData = this.GetSinglePacketData(data, out consumedLength, out expectedLength);

            // add the comsumed length of security decorder
            if (context != null && context.Security != null && context.Security.ConsumedData)
            {
                consumedLength = context.Security.ConsumedLength;
            }

            if (packetData == null)
            {
                return(null);
            }

            // New connection. Try both LDAP v2 and v3 decoders. Note that for requests that don't have version
            // context(e.g., UDP search requests), LDAP v3 is used by default.
            AdtsLdapPacket packet = null;

            if (context == null)
            {
                context = new AdtsLdapContext(AdtsLdapVersion.V3, remote);
                packet  = this.decoderv3.ParseAdtsLdapPacket(
                    this.decoderv3.AuthenticateMessage(packetData),
                    context);
                // synchronize the message ID with newly received packet.
                context.MessageId = packet.messageId;

                // Check BindRequestPacket, normally it's the first message from client in which
                // contains the LDAP version. And since LDAP v3 decoder can decode LDAP v2 messages
                // without any exception, we need to check into the 'version' variable in the request.
                AdtsBindRequestPacket bindRequestPacket = packet as AdtsBindRequestPacket;
                if (bindRequestPacket != null)
                {
                    LdapV3.BindRequest bindRequest =
                        (LdapV3.BindRequest)bindRequestPacket.GetInnerRequestOrResponse();
                    // Version doesn't match. Decode again with LDAP v2 decoder and update context version.
                    if ((AdtsLdapVersion)bindRequest.version.Value == AdtsLdapVersion.V2)
                    {
                        packet = this.decoderv2.ParseAdtsLdapPacket(
                            this.decoderv2.AuthenticateMessage(packetData),
                            context);
                        context.ClientVersion = context.ServerVersion = AdtsLdapVersion.V2;
                    }
                }

                // Add context.
                this.server.ContextManager.AddContext(context, this.server.IsTcp);
            }
            else
            {
                if (context.ClientVersion == AdtsLdapVersion.V2)
                {
                    packet = this.decoderv2.ParseAdtsLdapPacket(
                        this.decoderv2.AuthenticateMessage(packetData),
                        context);
                }
                else
                {
                    packet = this.decoderv3.ParseAdtsLdapPacket(
                        this.decoderv3.AuthenticateMessage(packetData),
                        context);
                }
                // synchronize the message ID with newly received packet.
                context.MessageId = packet.messageId;
            }

            return(new StackPacket[] { packet });
        }
 /// <summary>
 /// Sends a packet.
 /// </summary>
 /// <param name="context">The context that contains related info about client.</param>
 /// <param name="packet">The packet to be sent.</param>
 public void SendPacket(AdtsLdapContext context, AdtsLdapPacket packet)
 {
     transportStack.SendPacket(context.RemoteAddress, packet);
 }
 /// <summary>
 /// Adds extended controls to a packet.
 /// </summary>
 /// <param name="packet">The packet to which the controls are added.</param>
 /// <param name="controls">The controls.</param>
 /// <exception cref="NotSupportedException">
 /// Thrown when trying to add controls to an LDAP v2 packet.
 /// </exception>
 public void AddDirectoryControls(AdtsLdapPacket packet, params DirectoryControl[] controls)
 {
     if (packet.ldapMessagev2 != null)
     {
         throw new NotSupportedException("Extended controls are only supported for LDAP v3 packets.");
     }
     this.encoderv3.AddDirectoryControls(packet, controls);
 }
예제 #11
0
 /// <summary>
 /// Sends a packet.
 /// </summary>
 /// <param name="context">The context that contains related info about client.</param>
 /// <param name="packet">The packet to be sent.</param>
 public void SendPacket(AdtsLdapContext context, AdtsLdapPacket packet)
 {
     transportStack.SendPacket(context.RemoteAddress, packet);
 }
 /// <summary>
 /// Adds extended controls to a packet.
 /// </summary>
 /// <param name="packet">The packet to which the controls are added.</param>
 /// <param name="controls">The controls.</param>
 /// <exception cref="NotSupportedException">
 /// Thrown when trying to add controls to an LDAP v2 packet.
 /// </exception>
 public virtual void AddDirectoryControls(AdtsLdapPacket packet, params DirectoryControl[] controls)
 {
     if (this.encoder is AdtsLdapV2Encoder)
     {
         throw new NotSupportedException("Extended controls are only supported for LDAP v3 packets.");
     }
     (this.encoder as AdtsLdapV3Encoder).AddDirectoryControls(packet, controls);
 }
        /// <summary>
        /// Sends a packet to server.
        /// </summary>
        /// <param name="packet">The packet to be sent.</param>
        /// <exception cref="InvalidOperationException">
        /// thrown when Transport is null! Please invoke Connect() first!
        /// </exception>
        public virtual void SendPacket(AdtsLdapPacket packet)
        {
            if (this.transportStack == null)
            {
                throw new InvalidOperationException("Transport is null! Please invoke Connect() first!");
            }

            this.transportStack.SendPacket(packet);
            this.context.MessageId++;
        }
예제 #14
0
        internal AdtsLdapPacket CreatePacketFromType(Type messageType)
        {
            AdtsLdapPacket packet = null;

            if (messageType == typeof(AbandonRequest))
            {
                packet = new AdtsAbandonRequestPacket();
            }
            else if (messageType == typeof(AddRequest))
            {
                packet = new AdtsAddRequestPacket();
            }
            else if (messageType == typeof(AddResponse))
            {
                packet = new AdtsAddResponsePacket();
            }
            else if (messageType == typeof(BindRequest))
            {
                packet = new AdtsBindRequestPacket();
            }
            else if (messageType == typeof(BindResponse))
            {
                packet = new AdtsBindResponsePacket();
            }
            else if (messageType == typeof(CompareRequest))
            {
                packet = new AdtsCompareRequestPacket();
            }
            else if (messageType == typeof(CompareResponse))
            {
                packet = new AdtsCompareResponsePacket();
            }
            else if (messageType == typeof(DelRequest))
            {
                packet = new AdtsDelRequestPacket();
            }
            else if (messageType == typeof(DelResponse))
            {
                packet = new AdtsDelResponsePacket();
            }
            else if (messageType == typeof(ExtendedRequest))
            {
                packet = new AdtsExtendedRequestPacket();
            }
            else if (messageType == typeof(ExtendedResponse))
            {
                packet = new AdtsExtendedResponsePacket();
            }
            else if (messageType == typeof(ModifyDNRequest))
            {
                packet = new AdtsModifyDnRequestPacket();
            }
            else if (messageType == typeof(ModifyDNResponse))
            {
                packet = new AdtsModifyDnResponsePacket();
            }
            else if (messageType == typeof(ModifyRequest))
            {
                packet = new AdtsModifyRequestPacket();
            }
            else if (messageType == typeof(ModifyResponse))
            {
                packet = new AdtsModifyResponsePacket();
            }
            else if (messageType == typeof(SearchRequest))
            {
                packet = new AdtsSearchRequestPacket();
            }
            else if (messageType == typeof(SearchResultEntry))
            {
                packet = new AdtsSearchResultEntryPacket();
            }
            else if (messageType == typeof(SearchResultReference))
            {
                packet = new AdtsSearchResultReferencePacket();
            }
            else if (messageType == typeof(SearchResultDone))
            {
                packet = new AdtsSearchResultDonePacket();
            }
            else if (messageType == typeof(SicilyBindResponse))
            {
                packet = new AdtsSicilyBindResponsePacket();
            }
            else if (messageType == typeof(UnbindRequest))
            {
                packet = new AdtsUnbindRequestPacket();
            }
            else
            {
                throw new StackException("Unknown message type: " + messageType.ToString());
            }

            return(packet);
        }