/// <summary> /// Deep copy constructor. /// </summary> public SmbNtTransactIoctlRequestPacket(SmbNtTransactIoctlRequestPacket packet) : base(packet) { this.InitDefaultValue(); this.ntTransData.Data = new byte[packet.ntTransData.Data.Length]; Array.Copy(packet.ntTransData.Data, this.ntTransData.Data, packet.ntTransData.Data.Length); }
/// <summary> /// Deep copy constructor. /// </summary> public SmbNtTransactIoctlRequestPacket(SmbNtTransactIoctlRequestPacket packet) : base(packet) { this.InitDefaultValue(); this.ntTransData.Data = new byte[packet.ntTransData.Data.Length]; Array.Copy(packet.ntTransData.Data, this.ntTransData.Data, packet.ntTransData.Data.Length); }
/// <summary> /// FSCTL Bad command request. /// </summary> /// <param name="messageId">This is used to associate a response with a request.</param> /// <param name="sessionId">The current session ID for this connection.</param> /// <param name="treeId">The tree ID for the corrent share connection.</param> /// <param name="isSigned">Indicate whether the message is signed or not for this response.</param> /// <param name="fid">The file identifier.</param> /// <param name="command">This is used to tell the adapter to send an invalid kind of command.</param> public void FsctlBadCommandRequest( int messageId, int sessionId, int treeId, bool isSigned, int fid, FsctlInvalidCommand command) { #region Create Packet NamespaceCifs.SmbNtTransactIoctlRequestPacket smbPacket = new NamespaceCifs.SmbNtTransactIoctlRequestPacket(); ushort uid = (ushort)this.uId[(uint)sessionId]; uint functionCode = (uint)command; byte[] data = new byte[DataCount]; smbPacket = this.smbClientStack.CreateNTTransIOCtlRequest( (ushort)this.fId[(uint)fid], true, byte.MinValue, functionCode, data); if (isSigned) { NamespaceCifs.CifsClientPerConnection connection = this.smbClientStack.Context.GetConnection(ConnectionId); NamespaceCifs.CifsClientPerSession session = this.smbClientStack.Context.GetSession(ConnectionId, uid); smbPacket.Sign(connection.ClientNextSendSequenceNumber, session.SessionKey); } #endregion #region Send and Receive ExpectPacket this.smbClientStack.SendPacket(smbPacket); StackPacket response = this.smbClientStack.ExpectPacket(this.timeout); NamespaceCifs.SmbPacket smbPacketResponse = (NamespaceCifs.SmbPacket)response; this.QueryUidTable(smbPacketResponse); this.QueryTidTable(smbPacketResponse); VerifyTransport(smbPacketResponse); VerifyCommonMessageSyntax(smbPacketResponse); SmbErrorResponsePacket smbErrorResponsePacket = response as SmbErrorResponsePacket; NamespaceCifs.SmbHeader smbErrorHeader = smbErrorResponsePacket.SmbHeader; this.ErrorResponse(smbErrorHeader.Mid + this.addMidMark, (MessageStatus)smbErrorHeader.Status); #endregion }
public void FSCCFSCTLNameRequest(int messageId, int sessionId, int treeId, bool isSigned, int fid, FSCCFSCTLName fsctlName) { #region Create Packet NamespaceCifs.SmbNtTransactIoctlRequestPacket smbPacket = new NamespaceCifs.SmbNtTransactIoctlRequestPacket(); ushort uid = (ushort)this.uId[(uint)sessionId]; uint functionCode = (uint)fsctlName; byte[] data = new byte[DataCount]; this.fsccFSCTLName = fsctlName.ToString(); smbPacket = this.smbClientStack.CreateNTTransIOCtlRequest( (ushort)this.fId[(uint)fid], true, byte.MinValue, functionCode, data); if (isSigned) { NamespaceCifs.CifsClientPerConnection connection = this.smbClientStack.Context.GetConnection(ConnectionId); NamespaceCifs.CifsClientPerSession session = this.smbClientStack.Context.GetSession(ConnectionId, uid); smbPacket.Sign(connection.ClientNextSendSequenceNumber, session.SessionKey); } #endregion #region Send and Receive ExpectPacket this.smbClientStack.SendPacket(smbPacket); StackPacket response = this.smbClientStack.ExpectPacket(this.timeout); NamespaceCifs.SmbPacket smbPacketResponse = (NamespaceCifs.SmbPacket)response; this.QueryUidTable(smbPacketResponse); this.QueryTidTable(smbPacketResponse); VerifyTransport(smbPacketResponse); VerifyCommonMessageSyntax(smbPacketResponse); if (response.GetType() == typeof(SmbErrorResponsePacket)) { SmbErrorResponsePacket smbErrorResponsePacket = response as SmbErrorResponsePacket; NamespaceCifs.SmbHeader smbErrorHeader = smbErrorResponsePacket.SmbHeader; this.ErrorResponse( smbErrorHeader.Mid + this.addMidMark, (MessageStatus)smbErrorHeader.Status); } else { NamespaceCifs.SmbNtTransactIoctlResponsePacket smbNtTransactIoctlResponsePacket = response as SmbNtTransactIoctlResponsePacket; NamespaceCifs.SmbHeader ntTransactIoctlResponseHeader = smbNtTransactIoctlResponsePacket.SmbHeader; VerifyMessageSyntaxFsctlNameResponse(smbNtTransactIoctlResponsePacket); this.FSCCFSCTLNameResponse( ntTransactIoctlResponseHeader.Mid + this.addMidMark, this.QueryUidTable(smbPacketResponse), this.QueryTidTable(smbPacketResponse), (smbPacketResponse).IsSignRequired, (MessageStatus)ntTransactIoctlResponseHeader.Status); } #endregion }
/// <summary> /// Expect a request. If user is not interested in the packet, please call DefaultSendResponse(). /// </summary> /// <param name="timeout">timeout</param> /// <param name="connection">the connection between server and client</param> /// <param name="session">the session between server and client</param> /// <param name="treeConnect">the tree connect between server and client</param> /// <param name="open">the file open between server and client</param> /// <param name="requestPacket">the request</param> public override void ExpectRequest( TimeSpan timeout, out IFileServiceServerConnection connection, out IFileServiceServerSession session, out IFileServiceServerTreeConnect treeConnect, out IFileServiceServerOpen open, out SmbFamilyPacket requestPacket) { CifsServerPerConnection cifsConnection; SmbPacket request = this.cifsServer.ExpectPacket(timeout, out cifsConnection); connection = cifsConnection; requestPacket = request; session = null; treeConnect = null; open = null; if (request != null) { session = cifsConnection.GetSession(request.SmbHeader.Uid); if (session != null) { treeConnect = (session as CifsServerPerSession).GetTreeConnect(request.SmbHeader.Tid); if (treeConnect != null) { ushort fid = 0; SmbTransactionRequestPacket transactionRequest = request as SmbTransactionRequestPacket; SmbNtTransactIoctlRequestPacket ioctlRequest = request as SmbNtTransactIoctlRequestPacket; SmbNtTransactNotifyChangeRequestPacket notifyChange = request as SmbNtTransactNotifyChangeRequestPacket; if (transactionRequest != null) { //SubCommand(2bytes), FID(2bytes) fid = transactionRequest.SmbParameters.Setup[1]; } else if (ioctlRequest != null) { //FunctionCode(4bytes), FID(2bytes), IsFctl(1bytes), IsFlags(1bytes) fid = ioctlRequest.SmbParameters.Setup[2]; } else if (notifyChange != null) { //CompletionFilter(4bytes), FID(2bytes), WatchTree(1bytes), Reserved(1bytes) fid = notifyChange.SmbParameters.Setup[2]; } else { Type packetType = request.GetType(); PropertyInfo pi = packetType.GetProperty( "Trans2Parameters", BindingFlags.Instance | BindingFlags.Public); if (pi == null) { pi = packetType.GetProperty( "NtTransParameters", BindingFlags.Instance | BindingFlags.Public); } if (pi == null) { pi = packetType.GetProperty( "SmbParameters", BindingFlags.Instance | BindingFlags.Public); } if (pi != null) { object smbParameters = pi.GetValue(request, null); FieldInfo fi = smbParameters.GetType().GetField( "FID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase); if (fi != null) { fid = (ushort)fi.GetValue(smbParameters); } } } if (fid > 0) { open = (treeConnect as CifsServerPerTreeConnect).GetOpen(fid); } } } } }
/// <summary> /// find the nt transaction packets /// </summary> /// <param name="command">the command of nt transaction</param> /// <param name="setup">the setup contains the sub command</param> /// <returns>the target nt transaction packet</returns> private static SmbPacket FindTheNtTransPacket(NtTransSubCommand command, byte[] setup) { SmbPacket smbPacket = null; switch (command) { case NtTransSubCommand.NT_TRANSACT_CREATE: smbPacket = new SmbNtTransactCreateRequestPacket(); break; case NtTransSubCommand.NT_TRANSACT_RENAME: smbPacket = new SmbNtTransRenameRequestPacket(); break; case NtTransSubCommand.NT_TRANSACT_IOCTL: NT_TRANSACT_IOCTL_SETUP subCommand = CifsMessageUtils.ToStuct<NT_TRANSACT_IOCTL_SETUP>(setup); switch ((NtTransFunctionCode)subCommand.FunctionCode) { case NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS: smbPacket = new SmbNtTransFsctlSrvEnumerateSnapshotsRequestPacket(); break; case NtTransFunctionCode.FSCTL_SRV_REQUEST_RESUME_KEY: smbPacket = new SmbNtTransFsctlSrvRequestResumeKeyRequestPacket(); break; case NtTransFunctionCode.FSCTL_SRV_COPYCHUNK: smbPacket = new SmbNtTransFsctlSrvCopyChunkRequestPacket(); break; default: smbPacket = new SmbNtTransactIoctlRequestPacket(); break; } break; default: switch ((SmbNtTransSubCommand)command) { case SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA: smbPacket = new SmbNtTransQueryQuotaRequestPacket(); break; case SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA: smbPacket = new SmbNtTransSetQuotaRequestPacket(); break; } break; } return smbPacket; }
/// <summary> /// to create a NtTransactIoctl request packet. /// </summary> /// <param name="messageId">This field SHOULD be the multiplex ID that is used to associate a response with a /// request.</param> /// <param name="uid">This field SHOULD identify the authenticated instance of the user.</param> /// <param name="treeId">This field identifies the subdirectory (or tree) on the server that the client is /// accessing.</param> /// <param name="flags">An 8-bit field of 1-bit flags describing various features in effect for the /// message</param> /// <param name="flags2">A 16-bit field of 1-bit flags that represent various features in effect for the /// message. Unspecified bits are reserved and MUST be zero.</param> /// <param name="maxParameterCount">The maximum number of parameter bytes that the client will accept in the /// transaction reply. The server MUST NOT return more than this number of parameter bytes.</param> /// <param name="maxDataCount">The maximum number of data bytes that the client will accept in the transaction /// reply. The server MUST NOT return more than this number of data bytes.</param> /// <param name="maxSetupCount">Maximum number of setup bytes that the client will accept in the transaction /// reply. The server MUST NOT return more than this number of setup bytes</param> /// <param name="functionCode">Windows NT device or file system control code</param> /// <param name="fid">MUST contain a valid FID obtained from a previously successful SMB open command.</param> /// <param name="isFctl">This field is TRUE if the command is a file system control command and the FID is a /// file system control device. Otherwise, the command is a device control command and FID is an I/O /// device.</param> /// <param name="isFlags">If bit 0 is set, the command is to be applied to a share root handle. The share MUST /// be a Distributed File System (DFS) type</param> /// <param name="data">The raw bytes that are passed to the fsctl or ioctl function as the input /// buffer.</param> /// <returns>a NtTransactIoctl request packet</returns> public SmbNtTransactIoctlRequestPacket CreateNtTransactIoctlRequest( ushort messageId, ushort uid, ushort treeId, SmbFlags flags, SmbFlags2 flags2, byte maxSetupCount, uint maxParameterCount, uint maxDataCount, uint functionCode, ushort fid, bool isFctl, byte isFlags, byte[] data) { if (data == null) { data = new byte[0]; } SmbNtTransactIoctlRequestPacket packet = new SmbNtTransactIoctlRequestPacket(); packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(SmbCommand.SMB_COM_NT_TRANSACT, messageId, uid, treeId, flags, flags2); // Set Smb_Parameters SMB_COM_NT_TRANSACT_Request_SMB_Parameters smbParameters = new SMB_COM_NT_TRANSACT_Request_SMB_Parameters(); smbParameters.MaxSetupCount = maxSetupCount; smbParameters.MaxParameterCount = maxParameterCount; smbParameters.MaxDataCount = maxDataCount; smbParameters.SetupCount = 4; // the cout of Setup is 4. smbParameters.Function = NtTransSubCommand.NT_TRANSACT_IOCTL; NT_TRANSACT_IOCTL_SETUP setupStruct = new NT_TRANSACT_IOCTL_SETUP(); setupStruct.FunctionCode = functionCode; setupStruct.FID = fid; setupStruct.IsFctl = (byte)(isFctl ? 1 : 0); setupStruct.IsFlags = isFlags; smbParameters.Setup = CifsMessageUtils.ToTypeArray<ushort>(CifsMessageUtils.ToBytes<NT_TRANSACT_IOCTL_SETUP >(setupStruct)); smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_NT_TRANSACT_Request_SMB_Parameters>( smbParameters) / NumBytesOfWord); // Set Smb_Data SMB_COM_NT_TRANSACT_Request_SMB_Data smbData = new SMB_COM_NT_TRANSACT_Request_SMB_Data(); // Set NT_TransData NT_TRANSACT_IOCTL_Request_NT_Trans_Data ntTransData = new NT_TRANSACT_IOCTL_Request_NT_Trans_Data(); ntTransData.Data = data; packet.SmbParameters = smbParameters; packet.SmbData = smbData; packet.NtTransData = ntTransData; packet.UpdateCountAndOffset(); return packet; }
public SmbNtTransactIoctlResponsePacket CreateNtTransactIoctlResponse( CifsServerPerConnection connection, SmbNtTransactIoctlRequestPacket request, byte[] data) { data = data ?? new byte[0]; SmbNtTransactIoctlResponsePacket response = new SmbNtTransactIoctlResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); NT_TRANSACT_IOCTL_Response_NT_Trans_Data ntTransData = response.NtTransData; ntTransData.Data = data; response.NtTransData = ntTransData; response.UpdateCountAndOffset(); return response; }