Example #1
0
        private void ExpectIoctlPayload(Smb2Client client, out uint status, out byte[] payload)
        {
            if (client == null)
            {
                throw new InvalidOperationException("The transport is not connected.");
            }
            Smb2IOCtlResponsePacket response = client.ExpectPacket <Smb2IOCtlResponsePacket>(ioctlRequestMessageIds.Dequeue());

            payload = null;
            if (response.PayLoad.OutputCount > 0)
            {
                payload = response.Buffer.Skip((int)(response.PayLoad.OutputOffset - response.BufferOffset)).Take((int)response.PayLoad.OutputCount).ToArray();
            }

            status = response.Header.Status;
        }
        private Smb2Packet DecodeSingleResponsePacket(
            byte[] messageBytes,
            bool ignoreCompoundFlag,
            ulong realSessionId,
            uint realTreeId,
            out int consumedLength,
            out int expectedLength
            )
        {
            Packet_Header smb2Header;

            bool isLeaseBreakPacket = false;

            int offset = 0;
            smb2Header = TypeMarshal.ToStruct<Packet_Header>(messageBytes, ref offset);

            if (smb2Header.Command == Smb2Command.OPLOCK_BREAK)
            {
                ushort structureSize = TypeMarshal.ToStruct<ushort>(messageBytes, ref offset);

                if (structureSize == (ushort)OplockLeaseBreakStructureSize.LeaseBreakNotification
                    || structureSize == (ushort)OplockLeaseBreakStructureSize.LeaseBreakResponse
                    || structureSize == 9) // Add this condition temporally to handle LeaseBreakResponse is error response (i.e. structureSize == 9), but this will still hide the condition when OplockBreakResponse is error response
                {
                    isLeaseBreakPacket = true;
                }
            }

            Smb2SinglePacket packet = null;
            ushort structSize = BitConverter.ToUInt16(messageBytes, Smb2Consts.Smb2HeaderLen);

            switch (smb2Header.Command)
            {
                case Smb2Command.CANCEL:
                    packet = new Smb2CancelResponsePacket();
                    break;
                case Smb2Command.CHANGE_NOTIFY:
                    packet = new Smb2ChangeNotifyResponsePacket();
                    break;
                case Smb2Command.CLOSE:
                    packet = new Smb2CloseResponsePacket();
                    break;
                case Smb2Command.CREATE:
                    packet = new Smb2CreateResponsePacket();
                    break;
                case Smb2Command.ECHO:
                    packet = new Smb2EchoResponsePacket();
                    break;
                case Smb2Command.FLUSH:
                    packet = new Smb2FlushResponsePacket();
                    break;
                case Smb2Command.IOCTL:
                    packet = new Smb2IOCtlResponsePacket();
                    break;
                case Smb2Command.LOCK:
                    packet = new Smb2LockResponsePacket();
                    break;
                case Smb2Command.LOGOFF:
                    packet = new Smb2LogOffResponsePacket();
                    break;
                case Smb2Command.NEGOTIATE:
                    packet = new Smb2NegotiateResponsePacket();
                    break;
                case Smb2Command.OPLOCK_BREAK:
                    if (smb2Header.MessageId == ulong.MaxValue)
                    {
                        if (!isLeaseBreakPacket)
                        {
                            packet = new Smb2OpLockBreakNotificationPacket();
                        }
                        else
                        {
                            packet = new Smb2LeaseBreakNotificationPacket();
                        }
                    }
                    else
                    {
                        if (!isLeaseBreakPacket)
                        {
                            packet = new Smb2OpLockBreakResponsePacket();
                        }
                        else
                        {
                            packet = new Smb2LeaseBreakResponsePacket();
                        }
                    }
                    break;
                case Smb2Command.QUERY_DIRECTORY:
                    packet = new Smb2QueryDirectoryResponePacket();
                    break;
                case Smb2Command.QUERY_INFO:
                    packet = new Smb2QueryInfoResponsePacket();
                    break;
                case Smb2Command.READ:
                    packet = new Smb2ReadResponsePacket();
                    break;
                case Smb2Command.SESSION_SETUP:
                    packet = new Smb2SessionSetupResponsePacket();
                    break;
                case Smb2Command.SET_INFO:
                    packet = new Smb2SetInfoResponsePacket();
                    break;
                case Smb2Command.TREE_CONNECT:
                    packet = new Smb2TreeConnectResponsePacket();
                    break;
                case Smb2Command.TREE_DISCONNECT:
                    packet = new Smb2TreeDisconnectResponsePacket();
                    break;
                case Smb2Command.WRITE:
                    packet = new Smb2WriteResponsePacket();
                    break;
                default:
                    throw new InvalidOperationException("Received an unknown packet! the type of the packet is "
                        + smb2Header.Command.ToString());
            }

            if (IsErrorPacket(smb2Header))
            {
                var error = new Smb2ErrorResponsePacket();
                error.FromBytes(messageBytes, out consumedLength, out expectedLength);

                packet.Header = error.Header;
                packet.Error = error;
            }
            else
            {
                packet.FromBytes(messageBytes, out consumedLength, out expectedLength);
            }

            //if ignoreCompoundFlag is false, means the process of decoding this packet
            //is not part of the process of decoding a compound packet. We will update
            //context here.
            if (!ignoreCompoundFlag)
            {
                // TODO
            }

            return packet;
        }
        public Smb2IOCtlResponsePacket CreateIOCtlResponse(
            Smb2Endpoint endpoint,
            ulong messageId,
            byte[] input,
            byte[] output
            )
        {
            Smb2IOCtlResponsePacket packet = new Smb2IOCtlResponsePacket();

            Smb2IOCtlRequestPacket requestPacket = context.FindRequestPacket(endpoint.EndpointId, messageId)
                as Smb2IOCtlRequestPacket;

            SetHeader(packet, endpoint, messageId);

            packet.PayLoad.CtlCode = (uint)requestPacket.PayLoad.CtlCode;
            packet.PayLoad.FileId = requestPacket.PayLoad.FileId;
            packet.PayLoad.Flags = IOCTL_Response_Flags_Values.V1;

            int bufferLen = 0;

            if (input != null)
            {
                packet.PayLoad.InputCount = (uint)input.Length;
                packet.PayLoad.InputOffset = Smb2Consts.InputOffsetInIOCtlResponse;
                bufferLen += Smb2Utility.AlignBy8Bytes(input.Length);
            }

            if (output != null)
            {
                packet.PayLoad.OutputCount = (uint)output.Length;
                packet.PayLoad.OutputOffset = (uint)(Smb2Consts.InputOffsetInIOCtlResponse + bufferLen);
                bufferLen += output.Length;
            }

            byte[] buffer = new byte[bufferLen];

            if (input != null)
            {
                Array.Copy(input, buffer, input.Length);
            }

            if (output != null)
            {
                Array.Copy(output, 0, buffer, packet.PayLoad.OutputOffset - Smb2Consts.InputOffsetInIOCtlResponse,
                    output.Length);
            }

            packet.PayLoad.Reserved = IOCTL_Response_Reserved_Values.V1;
            packet.PayLoad.Reserved2 = IOCTL_Response_Reserved2_Values.V1;
            packet.PayLoad.StructureSize = IOCTL_Response_StructureSize_Values.V1;
            packet.PayLoad.Buffer = buffer;

            packet.Sign();

            return packet;
        }