/// <summary>
        /// to decode the smb parameters: from the general SmbParameters to the concrete Smb Parameters.
        /// </summary>
        protected override void DecodeParameters()
        {
            // When a client requests extended information, the word count must be 42
            if (this.smbParametersBlock.WordCount == CREATE_EXTENDED_INFORMATION_RESPONSE_LENGTH)
            {
                SMB_COM_NT_CREATE_ANDX_Response_SMB_Parameters param =
                    new SMB_COM_NT_CREATE_ANDX_Response_SMB_Parameters();

                using (MemoryStream stream = new MemoryStream(
                           CifsMessageUtils.ToBytesArray <ushort>(this.smbParametersBlock.Words)))
                {
                    using (Channel channel = new Channel(null, stream))
                    {
                        param.WordCount         = this.smbParametersBlock.WordCount;
                        param.AndXCommand       = channel.Read <SmbCommand>();
                        param.AndXReserved      = channel.Read <byte>();
                        param.AndXOffset        = channel.Read <ushort>();
                        param.OplockLevel       = channel.Read <OplockLevelValue>();
                        param.FID               = channel.Read <ushort>();
                        param.CreationAction    = channel.Read <uint>();
                        param.CreateTime        = channel.Read <Cifs.FileTime>();
                        param.LastAccessTime    = channel.Read <Cifs.FileTime>();
                        param.LastWriteTime     = channel.Read <Cifs.FileTime>();
                        param.LastChangeTime    = channel.Read <Cifs.FileTime>();
                        param.ExtFileAttributes = channel.Read <uint>();
                        param.AllocationSize    = channel.Read <ulong>();
                        param.EndOfFile         = channel.Read <ulong>();
                        param.ResourceType      = channel.Read <FileTypeValue>();
                        param.NMPipeStatus_or_FileStatusFlags = channel.Read <SMB_NMPIPE_STATUS>();
                        param.Directory = channel.Read <byte>();
                        // VolumeGUID (16 bytes), td defines this length
                        param.VolumeGUID = channel.ReadBytes(CifsMessageUtils.GetSize <Guid>(new Guid()));
                        // if there is more 16 bytes in the channel.
                        if (channel.Stream.Position <= channel.Stream.Length - WINDOWS_BEHAVIOR_ADDITIONAL_DATA_LENGTH)
                        {
                            // FileId (8 bytes), td defines this length
                            param.FileId = channel.ReadBytes(sizeof(ulong));
                            // MaximalAccessRights (4 bytes), td defines this length
                            param.MaximalAccessRights = channel.ReadBytes(sizeof(uint));
                            // GuestMaximalAccessRights (4 bytes), td defines this length
                            param.GuestMaximalAccessRights = channel.ReadBytes(sizeof(uint));
                        }
                    }
                }

                this.SmbParameters = param;
            }
            else
            {
                base.DecodeParameters();

                this.smbParameters = SmbMessageUtils.ConvertSmbComCreatePacketPayload(base.SmbParameters);
            }
        }
        /// <summary>
        /// Execute a transacted exchange against a named pipe.
        /// </summary>
        /// <param name="timeout">The pending time to get server's response</param>
        /// <param name="writeData">the written data to the named pipe</param>
        /// <param name="readData">The read data from the named pipe</param>
        /// <returns>
        /// a uint value that specifies the status of response packet.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
        public uint Transaction(TimeSpan timeout, byte[] writeData, out byte[] readData)
        {
            this.internalTimeout = timeout;

            SmbTransTransactNmpipeRequestPacket request = smbClient.CreateTransTransactNamedPipeRequest(this.fid, TransSmbParametersFlags.NONE, writeData, smbClient.Capability.MaxDataCount);

            if (this.isSignRequired)
            {
                request.Sign(this.NextSequenceNumber, this.sessionKey);
            }

            uint status = 0;
            SmbTransTransactNmpipeResponsePacket response =
                this.SendAndExpectSmbPacket(request, internalTimeout, out status) as SmbTransTransactNmpipeResponsePacket;

            readData = ArrayUtility.SubArray <byte>(response.TransData.ReadData, 0);

            return(SmbMessageUtils.CheckStatus(status));
        }
        /// <summary>
        /// Read data from server, start at the positon indicated by offset
        /// </summary>
        /// <param name="timeout">The pending time to get server's response</param>
        /// <param name="offset">From where it will read</param>
        /// <param name="length">The length of the data client wants to read</param>
        /// <param name="data">The read data</param>
        /// <returns>
        /// a uint value that specifies the status of response packet.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
        public override uint Read(TimeSpan timeout, ulong offset, uint length, out byte[] data)
        {
            this.internalTimeout = timeout;

            SmbReadAndxRequestPacket request = smbClient.CreateReadRequest(this.fid, (ushort)length, (uint)offset);

            if (this.isSignRequired)
            {
                request.Sign(this.NextSequenceNumber, this.sessionKey);
            }

            uint status = 0;
            SmbReadAndxResponsePacket response =
                this.SendAndExpectSmbPacket(request, internalTimeout, out status) as SmbReadAndxResponsePacket;

            data = ArrayUtility.SubArray <byte>(response.SmbData.Data, 0);

            return(SmbMessageUtils.CheckStatus(status));
        }
Example #4
0
        /// <summary>
        /// to decode the Trans2 data: from the general Trans2Dada to the concrete Trans2 Data.
        /// </summary>
        protected override void DecodeTrans2Data()
        {
            if (this.smbData.Trans2_Data != null && this.smbData.Trans2_Data.Length > 0)
            {
                TRANS2_FIND_NEXT2_Response_Trans2_Data trans2Data;

                trans2Data.Data = SmbMessageUtils.UnmarshalSmbFindInformationLevelPayloads(
                    (FindInformationLevel)this.informationLevel,
                    this.Trans2Parameters.SearchCount,
                    this.smbData.Trans2_Data);

                if (trans2Data.Data != null)
                {
                    this.Trans2Data = trans2Data;
                    return;
                }
            }

            base.DecodeTrans2Data();
        }
        /// <summary>
        /// Do IO control on remote server
        /// </summary>
        /// <param name="ctlCode">The control code</param>
        /// <param name="isFsCtl">Indicate if the control code is a file system control code</param>
        /// <param name="input">The input data of io control</param>
        /// <param name="output">The output data of io control</param>
        /// <returns>
        /// a uint value that specifies the status of response packet.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">Thrown when meet an transport error</exception>
        private uint InternalIoControl(uint ctlCode, bool isFsCtl, byte[] input, out byte[] output)
        {
            SmbNtTransactIoctlRequestPacket request =
                smbClient.CreateNTTransIOCtlRequest(this.fid, isFsCtl, 0x00, ctlCode, input);

            if (this.isSignRequired)
            {
                request.Sign(this.NextSequenceNumber, this.sessionKey);
            }

            uint status = 0;
            SmbNtTransactIoctlResponsePacket response =
                this.SendAndExpectSmbPacket(request, internalTimeout, out status) as SmbNtTransactIoctlResponsePacket;

            output = null;
            if (response != null)
            {
                output = response.NtTransData.Data;
            }

            return(SmbMessageUtils.CheckStatus(status));
        }
        /// <summary>
        /// to decode the smb parameters: from the general SmbParameters to the concrete Smb Parameters.
        /// </summary>
        protected override void DecodeParameters()
        {
            // if smb packet, the word count must be 7.
            // end with more 2-int fields: MaximalShareAccessRights and GuestMaximalShareAccessRights.
            if (this.smbParametersBlock.WordCount == 7)
            {
                this.SmbParameters = CifsMessageUtils.ToStuct <SMB_COM_TREE_CONNECT_ANDX_Response_SMB_Parameters>(
                    CifsMessageUtils.ToBytes <SmbParameters>(this.smbParametersBlock));
            }
            // if cifs packet, the word count must be 3.
            else if (this.smbParametersBlock.WordCount == 3)
            {
                Cifs.SMB_COM_TREE_CONNECT_ANDX_Response_SMB_Parameters param =
                    CifsMessageUtils.ToStuct <Cifs.SMB_COM_TREE_CONNECT_ANDX_Response_SMB_Parameters>(
                        CifsMessageUtils.ToBytes <SmbParameters>(this.smbParametersBlock));

                this.SmbParameters = SmbMessageUtils.ConvertSmbComTreeConnectPacketPayload(param);
            }
            else
            {
                this.smbParameters.WordCount = this.smbParametersBlock.WordCount;
            }
        }
        /// <summary>
        /// Write data to server. cifs/smb implementation of this interface should pay attention to offset.
        /// They may not accept ulong as offset
        /// </summary>
        /// <param name="timeout">The pending time to get server's response</param>
        /// <param name="offset">The offset of the file from where client wants to start writing</param>
        /// <param name="data">The data which will be written to server</param>
        /// <returns>
        /// a uint value that specifies the status of response packet.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
        public override uint Write(TimeSpan timeout, ulong offset, byte[] data)
        {
            this.internalTimeout = timeout;

            SmbWriteAndxRequestPacket request = smbClient.CreateWriteRequest(this.fid, (uint)offset, data);

            SMB_COM_WRITE_ANDX_Request_SMB_Parameters param = request.SmbParameters;

            // get the high 4 bytes
            param.OffsetHigh = (uint)(offset >> 32);

            request.SmbParameters = param;

            if (this.isSignRequired)
            {
                request.Sign(this.NextSequenceNumber, this.sessionKey);
            }

            uint status = 0;

            this.SendAndExpectSmbPacket(request, internalTimeout, out status);

            return(SmbMessageUtils.CheckStatus(status));
        }
 /// <summary>
 /// initialize packet from base packet.
 /// </summary>
 /// <param name = "packet">the base packet to initialize this packet. </param>
 public SmbTransSetNmpipeStateRequestPacket(Cifs.SmbTransSetNmpipeStateRequestPacket packet)
     : base(packet)
 {
     this.smbParameters = SmbMessageUtils.ConvertTransactionFilePacketPayload(packet.SmbParameters);
 }
Example #9
0
 /// <summary>
 /// initialize packet from base packet.
 /// </summary>
 /// <param name = "packet">the base packet to initialize this packet. </param>
 public SmbTrans2GetDfsReferralRequestPacket(Cifs.SmbTrans2GetDfsReferalRequestPacket packet)
     : base(packet)
 {
     this.smbParameters = SmbMessageUtils.ConvertTransaction2PacketPayload(packet.SmbParameters);
 }
 /// <summary>
 /// initialize packet from base packet.
 /// </summary>
 /// <param name = "packet">the base packet to initialize this packet. </param>
 public SmbTrans2QueryFileInformationRequestPacket(Cifs.SmbTrans2QueryFileInformationRequestPacket packet)
     : base(packet)
 {
     this.smbParameters = SmbMessageUtils.ConvertTransaction2PacketPayload(packet.SmbParameters);
 }
 /// <summary>
 /// initialize packet from base packet.
 /// </summary>
 /// <param name = "packet">the base packet to initialize this packet. </param>
 public SmbTreeConnectAndxResponsePacket(Cifs.SmbTreeConnectAndxResponsePacket packet)
     : base(packet)
 {
     this.smbParameters = SmbMessageUtils.ConvertSmbComTreeConnectPacketPayload(base.SmbParameters);
 }
 /// <summary>
 /// initialize packet from base packet.
 /// </summary>
 /// <param name = "packet">the base packet to initialize this packet. </param>
 public SmbTrans2FindNext2RequestPacket(Cifs.SmbTrans2FindNext2RequestPacket packet)
     : base(packet)
 {
     this.smbParameters = SmbMessageUtils.ConvertTransaction2PacketPayload(packet.SmbParameters);
 }
 /// <summary>
 /// initialize packet from base packet.
 /// </summary>
 /// <param name = "packet">the base packet to initialize this packet. </param>
 public SmbTransMailslotWriteRequestPacket(Cifs.SmbTransMailslotWriteRequestPacket packet)
     : base(packet)
 {
     this.smbParameters = SmbMessageUtils.ConvertTransactionMailslotPacketPayload(packet.SmbParameters);
 }
Example #14
0
        /// <summary>
        /// update the context with response packet
        /// </summary>
        /// <param name="connection">the connection of endpoint</param>
        /// <param name="packet">the packet to update the context</param>
        private void ResponsePacketUpdateRoleContext(SmbServerConnection connection, SmbPacket packet)
        {
            SmbHeader smbHeader = packet.SmbHeader;

            SmbPacket requestPacket = connection.GetRequestPacket(smbHeader.Mid);

            if (requestPacket == null)
            {
                return;
            }

            switch (smbHeader.Command)
            {
            case SmbCommand.SMB_COM_SESSION_SETUP_ANDX:
                if (smbHeader.Uid == 0)
                {
                    break;
                }
                else
                {
                    SmbServerSession session = new SmbServerSession();
                    session.Uid = smbHeader.Uid;
                    session.AuthenticationState = SessionState.Complete;
                    session.Connection          = connection;
                    session.SessionKey          = connection.GssApi.SessionKey;

                    connection.AddSession(session);
                }

                break;

            case SmbCommand.SMB_COM_LOGOFF_ANDX:
                if (requestPacket.SmbHeader.Uid == 0)
                {
                    break;
                }
                else
                {
                    connection.RemoveSession(connection.GetSession(requestPacket.SmbHeader.Uid));
                }

                break;

            case SmbCommand.SMB_COM_TREE_CONNECT_ANDX:
            {
                SmbTreeConnectAndxRequestPacket request = requestPacket as SmbTreeConnectAndxRequestPacket;

                SmbServerTreeConnect treeconnect = new SmbServerTreeConnect();
                treeconnect.TreeId  = smbHeader.Tid;
                treeconnect.Session = connection.GetSession(smbHeader.Uid);
                if (treeconnect.Session == null)
                {
                    break;
                }
                if ((request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) != 0)
                {
                    treeconnect.Path = Encoding.Unicode.GetString(request.SmbData.Path);
                }
                else
                {
                    treeconnect.Path = Encoding.ASCII.GetString(request.SmbData.Path);
                }
                treeconnect.Path = treeconnect.Path.TrimEnd('\0');
                treeconnect.Session.AddTreeConnect(treeconnect);
            }

            break;

            case SmbCommand.SMB_COM_TREE_DISCONNECT:
                if (requestPacket.SmbHeader.Uid != 0)
                {
                    SmbServerSession session = connection.GetSession(requestPacket.SmbHeader.Uid);
                    if (session == null)
                    {
                        break;
                    }
                    session.RemoveTreeConnect(session.GetTreeConnect(requestPacket.SmbHeader.Tid));
                }

                break;

            case SmbCommand.SMB_COM_NT_CREATE_ANDX:
            {
                SmbNtCreateAndxResponsePacket response = packet as SmbNtCreateAndxResponsePacket;
                SmbNtCreateAndxRequestPacket  request  = requestPacket as SmbNtCreateAndxRequestPacket;

                SmbServerOpen open = new SmbServerOpen();
                open.SmbFid   = response.SmbParameters.FID;
                open.PathName = SmbMessageUtils.GetString(request.SmbData.FileName,
                                                          SmbFlags2.SMB_FLAGS2_UNICODE == (request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE));
                open.PathName    = open.PathName.TrimEnd('\0');
                open.Session     = connection.GetSession(smbHeader.Uid);
                open.TreeConnect = connection.GetTreeConnect(smbHeader.Tid);
                if (open.TreeConnect == null)
                {
                    break;
                }
                open.TreeConnect.AddOpen(open);
            }

            break;

            case SmbCommand.SMB_COM_OPEN_ANDX:
            {
                SmbOpenAndxResponsePacket response = packet as SmbOpenAndxResponsePacket;
                SmbOpenAndxRequestPacket  request  = requestPacket as SmbOpenAndxRequestPacket;

                SmbServerOpen open = new SmbServerOpen();
                open.SmbFid   = response.SmbParameters.FID;
                open.PathName = SmbMessageUtils.GetString(request.SmbData.FileName,
                                                          SmbFlags2.SMB_FLAGS2_UNICODE == (request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE));
                open.Session     = connection.GetSession(smbHeader.Uid);
                open.TreeConnect = connection.GetTreeConnect(smbHeader.Tid);
                if (open.TreeConnect == null)
                {
                    break;
                }
                open.TreeConnect.AddOpen(open);
            }

            break;

            case SmbCommand.SMB_COM_CLOSE:
            {
                SmbCloseRequestPacket closeRequest = requestPacket as SmbCloseRequestPacket;

                SmbServerTreeConnect treeconnect = connection.GetTreeConnect(requestPacket.SmbHeader.Tid);
                if (treeconnect == null)
                {
                    break;
                }

                treeconnect.RemoveOpen(treeconnect.GetOpen(closeRequest.SmbParameters.FID));
            }

            break;

            default:
                break;
            }

            connection.RemoveRequestPacket(packet);
        }
 /// <summary>
 /// initialize packet from base packet.
 /// </summary>
 /// <param name = "packet">the base packet to initialize this packet. </param>
 public SmbNtCreateAndxResponsePacket(Cifs.SmbNtCreateAndxResponsePacket packet)
     : base(packet)
 {
     this.smbParameters = SmbMessageUtils.ConvertSmbComCreatePacketPayload(base.SmbParameters);
 }