/// <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)); }
/// <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); }
/// <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); }
/// <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); }