/// <summary> /// Disconnect the connection specified by endpoint /// </summary> /// <param name="endpoint">The endpoint</param> public override void Disconnect(FsEndpoint endpoint) { CifsServerPerConnection connection = this.cifsServer.Context.ConnectionTable[endpoint.NetBiosEndpoint]; this.cifsServer.Disconnect(connection); this.fsEndpoints.Remove(endpoint.NetBiosEndpoint); }
/// <summary> /// Expect tcp or netbios connection /// </summary> /// <param name="timeout">Timeout</param> /// <returns>The endpoint of client</returns> public override FsEndpoint ExpectConnect(TimeSpan timeout) { CifsServerPerConnection connection = this.cifsServer.ExpectConnect(timeout); FsEndpoint fsEndpoint = new FsEndpoint((int)connection.Identity); this.fsEndpoints.Add(fsEndpoint.NetBiosEndpoint, fsEndpoint); return(fsEndpoint); }
/// <summary> /// server response the negotiate request from client. /// </summary> /// <param name="connection">the connection between server and client</param> /// <param name="requestPacket">the request</param> public override void SendNegotiateResponse( IFileServiceServerConnection connection, SmbFamilyPacket requestPacket) { CifsServerPerConnection cifsConnection = connection as CifsServerPerConnection; SmbPacket response = this.cifsServer.CreateDefaultResponse(cifsConnection, requestPacket as SmbNegotiateRequestPacket); this.cifsServer.SendPacket(response, cifsConnection); }
/// <summary> /// server response the session request from client. /// </summary> /// <param name="connection">the connection between server and client</param> /// <param name="requestPacket">the request</param> /// <returns>The session object.</returns> public override IFileServiceServerSession SendSessionSetupResponse( IFileServiceServerConnection connection, SmbFamilyPacket requestPacket) { CifsServerPerConnection cifsConnection = connection as CifsServerPerConnection; SmbPacket response = this.cifsServer.CreateDefaultResponse(cifsConnection, requestPacket as SmbPacket); this.cifsServer.SendPacket(response, cifsConnection); return(cifsConnection.GetSession(response.SmbHeader.Uid)); }
/// <summary> /// Automatically response latest request. /// </summary> /// <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 DefaultSendResponse( IFileServiceServerConnection connection, IFileServiceServerSession session, IFileServiceServerTreeConnect treeConnect, IFileServiceServerOpen open, SmbFamilyPacket requestPacket) { CifsServerPerConnection cifsConnection = connection as CifsServerPerConnection; SmbPacket response = this.cifsServer.CreateDefaultResponse(cifsConnection, requestPacket as SmbPacket); this.cifsServer.SendPacket(response, cifsConnection); }
/// <summary> /// server response an error packet /// </summary> /// <param name="connection">the connection between server and client</param> /// <param name="status">error code</param> /// <param name="requestPacket">the request packet to send the error response</param> public override void SendErrorResponse( IFileServiceServerConnection connection, uint status, SmbFamilyPacket requestPacket) { CifsServerPerConnection cifsConnection = connection as CifsServerPerConnection; SmbPacket response = this.cifsServer.CreateDefaultResponse(cifsConnection, requestPacket as SmbPacket); SmbHeader smbHeader = response.SmbHeader; smbHeader.Status = status; response.SmbHeader = smbHeader; this.cifsServer.SendPacket(response, cifsConnection); }
/// <summary> /// server response the create request from client. /// </summary> /// <param name="treeConnect">the tree connect between server and client</param> /// <param name="requestPacket">the request</param> /// <returns>The file open object</returns> public override IFileServiceServerOpen SendCreateResponse( IFileServiceServerTreeConnect treeConnect, SmbFamilyPacket requestPacket) { CifsServerPerConnection cifsConnection = treeConnect.Session.Connection as CifsServerPerConnection; IFileServiceServerOpen open = null; SmbCreateResponsePacket response = this.cifsServer.CreateDefaultResponse(cifsConnection, requestPacket as SmbPacket) as SmbCreateResponsePacket; if (response != null) { this.cifsServer.SendPacket(response, cifsConnection); open = (treeConnect as CifsServerPerTreeConnect).GetOpen(response.SmbParameters.FID); } return(open); }
/// <summary> /// server response the logoff request from client. /// </summary> /// <param name="session">the session between server and client</param> public override void SendLogoffResponse(IFileServiceServerSession session) { CifsServerPerConnection connection = session.Connection as CifsServerPerConnection; foreach (SmbLogoffAndxRequestPacket request in connection.PendingRequestTable) { if (request != null && request.SmbHeader.Uid == session.SessionId) { SmbPacket response = this.cifsServer.CreateDefaultResponse(connection, request); this.cifsServer.SendPacket(response, connection); return; } } }
/// <summary> /// server response TransSetNmpipeState request from client. /// </summary> /// <param name="treeConnect">the tree connect between server and client</param> public override void SendTransSetNmpipeStateResponse(IFileServiceServerTreeConnect treeConnect) { CifsServerPerConnection connection = treeConnect.Session.Connection as CifsServerPerConnection; foreach (SmbTransSetNmpipeStateRequestPacket request in connection.PendingRequestTable) { if (request != null && request.SmbHeader.Uid == treeConnect.Session.SessionId && request.SmbHeader.Tid == treeConnect.TreeConnectId) { SmbPacket response = this.cifsServer.CreateTransSetNmpipeStateSuccessResponse( connection, request); this.cifsServer.SendPacket(response, connection); return; } } }
/// <summary> /// server response the close request from client. /// </summary> /// <param name="open">the file open between server and client</param> public override void SendCloseResponse(IFileServiceServerOpen open) { CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection; foreach (SmbCloseRequestPacket request in connection.PendingRequestTable) { if (request != null && request.SmbHeader.Uid == open.TreeConnect.Session.SessionId && request.SmbHeader.Tid == open.TreeConnect.TreeConnectId && request.SmbParameters.FID == open.FileId) { SmbCloseResponsePacket response = this.cifsServer.CreateCloseResponse(connection, request); this.cifsServer.SendPacket(response, connection); return; } } }
/// <summary> /// server response the IO control request from client. /// </summary> /// <param name="open">the file open between server and client</param> /// <param name="controlCode">The file system control code</param> /// <param name="data">The information about this IO control</param> public override void SendIoControlResponse(IFileServiceServerOpen open, FsCtlCode controlCode, byte[] data) { CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection; foreach (SmbIoctlRequestPacket request in connection.PendingRequestTable) { if (request != null && request.SmbHeader.Uid == open.TreeConnect.Session.SessionId && request.SmbHeader.Tid == open.TreeConnect.TreeConnectId && request.SmbParameters.FID == open.FileId) { SmbIoctlResponsePacket response = this.cifsServer.CreateIoctlResponse(connection, request, null, data); this.cifsServer.SendPacket(response, connection); return; } } }
/// <summary> /// server response Trans2QueryFileInformation request from client. /// </summary> /// <param name="open">the file open between server and client</param> /// <param name="data">The transaction2 data to send</param> public override void SendTrans2QueryFileInformationResponse(IFileServiceServerOpen open, object data) { CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection; foreach (SmbTrans2QueryFileInformationRequestPacket request in connection.PendingRequestTable) { if (request != null && request.SmbHeader.Uid == open.TreeConnect.Session.SessionId && request.SmbHeader.Tid == open.TreeConnect.TreeConnectId && request.Trans2Parameters.FID == open.FileId) { SmbPacket response = this.cifsServer.CreateTrans2QueryFileInformationFinalResponse( connection, request, data); this.cifsServer.SendPacket(response, connection); return; } } }
/// <summary> /// server response the read request from client. /// The method will automatically reply multiple READ response if data is too large. /// </summary> /// <param name="open">the file open between server and client</param> /// <param name="data">The actual bytes</param> /// <param name = "available"> /// This field is valid when reading from named pipes or I/O devices. This field indicates the number of bytes /// remaining to be read after the requested read was completed. /// </param> public override void SendReadResponse(IFileServiceServerOpen open, byte[] data, int available) { CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection; foreach (SmbReadAndxRequestPacket request in connection.PendingRequestTable) { if (request != null && request.SmbHeader.Uid == open.TreeConnect.Session.SessionId && request.SmbHeader.Tid == open.TreeConnect.TreeConnectId && request.SmbParameters.FID == open.FileId) { SmbPacket response = this.cifsServer.CreateReadAndxResponse(connection, request, (ushort)available, data, null); this.cifsServer.SendPacket(response, connection); return; } } }
/// <summary> /// server response the write request from client. /// </summary> /// <param name="open">the file open between server and client</param> /// <param name="writtenCount">number of bytes in Write request</param> public override void SendWriteResponse(IFileServiceServerOpen open, int writtenCount) { CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection; foreach (SmbWriteAndxRequestPacket request in connection.PendingRequestTable) { if (request != null && request.SmbHeader.Uid == open.TreeConnect.Session.SessionId && request.SmbHeader.Tid == open.TreeConnect.TreeConnectId && request.SmbParameters.FID == open.FileId) { SmbWriteAndxResponsePacket response = this.cifsServer.CreateWriteAndxResponse( connection, request, 0, null); SMB_COM_WRITE_ANDX_Response_SMB_Parameters smbParameters = response.SmbParameters; smbParameters.Count = (ushort)writtenCount; response.SmbParameters = smbParameters; this.cifsServer.SendPacket(response, connection); return; } } }
/// <summary> /// server response the trans transact nmpipe request from client. /// </summary> /// <param name="open">the file open between server and client</param> /// <param name="data">The actual bytes</param> /// <param name = "available">indicates the number of bytes remaining to be read</param> public override void SendTransTransactNmpipeResponse(IFileServiceServerOpen open, byte[] data, int available) { CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection; foreach (SmbTransTransactNmpipeRequestPacket request in connection.PendingRequestTable) { if (request != null && request.SmbHeader.Uid == open.TreeConnect.Session.SessionId && request.SmbHeader.Tid == open.TreeConnect.TreeConnectId) { SmbTransTransactNmpipeSuccessResponsePacket response = this.cifsServer.CreateTransTransactNmpipeSuccessResponse( connection, request, data); if (available > 0) { Cifs.SmbHeader header = response.SmbHeader; header.Status = (uint)NtStatus.STATUS_BUFFER_OVERFLOW; response.SmbHeader = header; } this.cifsServer.SendPacket(response, connection); return; } } }
public SmbWritePrintFileResponsePacket CreateWritePrintFileResponse( CifsServerPerConnection connection, SmbWritePrintFileRequestPacket request) { SmbWritePrintFileResponsePacket response = new SmbWritePrintFileResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); return response; }
/// <summary> /// Update the context when received request. /// </summary> /// <param name="connection">The connection between client and server.</param> /// <param name="requestPacket">The received packet in stack transport.</param> protected virtual void UpdateRequestRoleConext( CifsServerPerConnection connection, SmbPacket requestPacket) { if (requestPacket == null) { return; } bool isAndxPacket = requestPacket.SmbHeader.Protocol == CifsMessageUtils.SMB_PROTOCOL_ANDXPACKET; if (!isAndxPacket) { connection.MultiplexId = requestPacket.SmbHeader.Mid; } /*If the UID is valid, the server MUST enumerate all connections in the Server.ConnectionTable and MUST *look up Session in the Server.Connection.SessionTable where UID is equal to Server.Session.UID. *If a session is found, Server.Session.IdleTime MUST be set to the current time. If no session is found, *no action regarding idle time is taken.*/ if (requestPacket.SmbHeader.Uid != 0) { foreach (CifsServerPerSession session in connection.SessionTable) { if (session.SessionId == requestPacket.SmbHeader.Uid) { session.IdleTime = DateTime.Now; break; } } } switch (requestPacket.SmbHeader.Command) { case SmbCommand.SMB_COM_SESSION_SETUP_ANDX: { SmbSessionSetupAndxRequestPacket request = requestPacket as SmbSessionSetupAndxRequestPacket; connection.SessionSetupReceived = true; connection.ClientCapabilites = request.SmbParameters.Capabilities; connection.ClientMaxBufferSize = request.SmbParameters.MaxBufferSize; connection.ClientMaxMpxCount = request.SmbParameters.MaxMpxCount; connection.IsSigningActive = false; connection.NativeLanMan = CifsMessageUtils.ToSmbString(request.SmbData.NativeLanMan, 0, false); connection.NativeOS = CifsMessageUtils.ToSmbString(request.SmbData.NativeOS, 0, false); } break; default: break; } if (!isAndxPacket && requestPacket.SmbHeader.Command != SmbCommand.SMB_COM_TRANSACTION_SECONDARY && requestPacket.SmbHeader.Command != SmbCommand.SMB_COM_TRANSACTION2_SECONDARY && requestPacket.SmbHeader.Command != SmbCommand.SMB_COM_NT_TRANSACT_SECONDARY && requestPacket.SmbHeader.Command != SmbCommand.SMB_COM_NT_CANCEL) { connection.AddPendingRequest(requestPacket); } if (!isAndxPacket) { connection.UpdateSequenceNumber(requestPacket); } SmbBatchedRequestPacket batchedRequest = requestPacket as SmbBatchedRequestPacket; if (batchedRequest != null) { SmbPacket andxPacket = batchedRequest.AndxPacket; this.UpdateRequestRoleConext(connection, andxPacket); } }
protected virtual void UpdateResponseRoleContext( CifsServerPerConnection connection, SmbPacket requestPacket, SmbPacket responsePacket) { if (requestPacket == null || responsePacket == null || responsePacket.SmbHeader.Status != 0) { return; } SmbHeader smbHeader = responsePacket.SmbHeader; switch (responsePacket.SmbHeader.Command) { #region Negotiate case SmbCommand.SMB_COM_NEGOTIATE: { SmbNegotiateRequestPacket request = requestPacket as SmbNegotiateRequestPacket; SmbNegotiateResponsePacket response = responsePacket as SmbNegotiateResponsePacket; if (request != null && response != null && request.SmbData.Dialects != null) { int dialectIndex = (int)(response.SmbParameters.DialectIndex); byte[] dialectBytes = request.SmbData.Dialects; int startIndex = 0; for (int i = 0; i < dialectIndex; i++) { startIndex = Array.IndexOf<byte>(dialectBytes, 0, startIndex, dialectBytes.Length - startIndex) + 1; } connection.SelectedDialect = CifsMessageUtils.ToSmbString(dialectBytes, startIndex, true); connection.NTLMChallenge = response.SmbData.Challenge; connection.OpLockSupport = this.opLockSupport; connection.NegotiateTime = response.SmbParameters.SystemTime; if (this.ntlmAuthenticationPolicy != NTLMAuthenticationPolicyValues.Disabled) { //Prepare security context for the coming ntlm authentication. foreach (AccountCredential accountCredential in this.accountCredentials) { NlmpServerSecurityContext serverSecurityContext = new NlmpServerSecurityContext( NegotiateTypes.NTLM_NEGOTIATE_OEM | NegotiateTypes.NTLMSSP_NEGOTIATE_NTLM, new NlmpClientCredential(string.Empty, accountCredential.DomainName, accountCredential.AccountName, accountCredential.Password), !string.IsNullOrEmpty(this.domainName), this.domainName, this.serverName); serverSecurityContext.UpdateServerChallenge( BitConverter.ToUInt64(response.SmbData.Challenge, 0)); this.nlmpServerSecurityContexts.Add(serverSecurityContext); } } if ((response.SmbParameters.SecurityMode & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) == SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) { connection.IsSigningActive = true; } } } break; #endregion #region Session case SmbCommand.SMB_COM_SESSION_SETUP_ANDX: #region SMB_COM_SESSION_SETUP_ANDX { SmbSessionSetupAndxRequestPacket request = requestPacket as SmbSessionSetupAndxRequestPacket; SmbSessionSetupAndxResponsePacket response = responsePacket as SmbSessionSetupAndxResponsePacket; if (request != null && response != null) { NlmpServerSecurityContext securityContext = null; if (response.SmbParameters.Action != ActionValues.GuestAccess) { this.ActiveAccount = CifsMessageUtils.PlainTextAuthenticate(request, this.accountCredentials); if (string.IsNullOrEmpty(this.ActiveAccount)) { securityContext = CifsMessageUtils.NTLMAuthenticate(request, this.nlmpServerSecurityContexts, connection.NegotiateTime.Time); if (securityContext != null) { connection.IsSigningActive = true; connection.SigningChallengeResponse = request.SmbData.UnicodePassword; this.ActiveAccount = securityContext.Context.ClientCredential.AccountName; connection.SigningSessionKey = NlmpUtility.GetResponseKeyNt( NlmpVersion.v1, securityContext.Context.ClientCredential.DomainName, securityContext.Context.ClientCredential.AccountName, securityContext.Context.ClientCredential.Password); } } } CifsServerPerSession session = new CifsServerPerSession( connection, smbHeader.Uid, securityContext, DateTime.Now, DateTime.Now, CifsMessageUtils.ToSmbString(request.SmbData.AccountName, 0, false), GenerateSessionGlobalId()); this.AddSession(session); } } #endregion break; case SmbCommand.SMB_COM_LOGOFF_ANDX: #region SMB_COM_LOGOFF_ANDX { SmbLogoffAndxRequestPacket request = requestPacket as SmbLogoffAndxRequestPacket; SmbLogoffAndxResponsePacket response = responsePacket as SmbLogoffAndxResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { this.RemoveSession(session.SessionGlobalId); } } #endregion break; #endregion #region Tree Connect case SmbCommand.SMB_COM_TREE_CONNECT: #region SMB_COM_TREE_CONNECT { SmbTreeConnectRequestPacket request = requestPacket as SmbTreeConnectRequestPacket; SmbTreeConnectResponsePacket response = responsePacket as SmbTreeConnectResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); //If Core Protocol, No sessions setup, make a default session if (session == null && (connection.SelectedDialect == CifsMessageUtils.DIALECT_PCNETWORK_PROGRAM || connection.SelectedDialect == CifsMessageUtils.DIALECT_NTLANMAN)) { session = new CifsServerPerSession( connection, smbHeader.Uid, //should be unique, windows always be zero null, DateTime.Now, DateTime.Now, string.Empty, GenerateSessionGlobalId()); this.AddSession(session); } if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = new CifsServerPerTreeConnect( session, CifsMessageUtils.ToSmbString(request.SmbData.Path, 0, false), response.SmbParameters.TID, this.GenerateTreeGlobalId(), DateTime.Now); this.AddTreeConnect(treeConnect); } } #endregion break; case SmbCommand.SMB_COM_TREE_CONNECT_ANDX: #region SMB_COM_TREE_CONNECT_ANDX { SmbTreeConnectAndxRequestPacket request = requestPacket as SmbTreeConnectAndxRequestPacket; SmbTreeConnectAndxResponsePacket response = responsePacket as SmbTreeConnectAndxResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = new CifsServerPerTreeConnect( session, CifsMessageUtils.ToString(request.SmbData.Path, request.SmbHeader.Flags2), smbHeader.Tid, this.GenerateTreeGlobalId(), DateTime.Now); this.AddTreeConnect(treeConnect); } } #endregion break; case SmbCommand.SMB_COM_TREE_DISCONNECT: #region SMB_COM_TREE_DISCONNECT { SmbTreeDisconnectRequestPacket request = requestPacket as SmbTreeDisconnectRequestPacket; SmbTreeDisconnectResponsePacket response = responsePacket as SmbTreeDisconnectResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { //If core protocol, no logoff any more, we have to remove the session if there is // no treeconnects in it except this. if (session.TreeConnectTable.Count == 1 && (connection.SelectedDialect == CifsMessageUtils.DIALECT_PCNETWORK_PROGRAM || connection.SelectedDialect == CifsMessageUtils.DIALECT_NTLANMAN)) { this.RemoveSession(session.SessionGlobalId); } else { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { this.RemoveTreeConnect(treeConnect.TreeGlobalId); } } } } #endregion break; #endregion #region Open File/Search case SmbCommand.SMB_COM_OPEN: #region SMB_COM_OPEN { SmbOpenRequestPacket request = requestPacket as SmbOpenRequestPacket; SmbOpenResponsePacket response = responsePacket as SmbOpenResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { OplockLevelValue opLock = OplockLevelValue.None; if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPLOCK) == SmbFlags.SMB_FLAGS_OPLOCK) { opLock = OplockLevelValue.Exclusive; } if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPBATCH) == SmbFlags.SMB_FLAGS_OPBATCH) { opLock = OplockLevelValue.Batch; } CifsServerPerOpenFile open = new CifsServerPerOpenFile( treeConnect, CifsMessageUtils.ToSmbString(request.SmbData.FileName, 0, false), response.SmbParameters.FID, response.SmbParameters.AccessMode, opLock, this.GenerateFileGlobalId(), request.SmbHeader.Pid); this.AddOpenFile(open); } } } #endregion break; case SmbCommand.SMB_COM_CREATE: #region SMB_COM_CREATE { SmbCreateRequestPacket request = requestPacket as SmbCreateRequestPacket; SmbCreateResponsePacket response = responsePacket as SmbCreateResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { OplockLevelValue opLock = OplockLevelValue.None; if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPLOCK) == SmbFlags.SMB_FLAGS_OPLOCK) { opLock = OplockLevelValue.Exclusive; } if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPBATCH) == SmbFlags.SMB_FLAGS_OPBATCH) { opLock = OplockLevelValue.Batch; } CifsServerPerOpenFile open = new CifsServerPerOpenFile( treeConnect, CifsMessageUtils.ToSmbString(request.SmbData.FileName, 0, false), response.SmbParameters.FID, (ushort)request.SmbParameters.FileAttributes, opLock, this.GenerateFileGlobalId(), request.SmbHeader.Pid); this.AddOpenFile(open); } } } #endregion break; case SmbCommand.SMB_COM_CREATE_TEMPORARY: #region SMB_COM_CREATE_TEMPORARY { SmbCreateTemporaryRequestPacket request = requestPacket as SmbCreateTemporaryRequestPacket; SmbCreateTemporaryResponsePacket response = responsePacket as SmbCreateTemporaryResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { OplockLevelValue opLock = OplockLevelValue.None; if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPLOCK) == SmbFlags.SMB_FLAGS_OPLOCK) { opLock = OplockLevelValue.Exclusive; } if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPBATCH) == SmbFlags.SMB_FLAGS_OPBATCH) { opLock = OplockLevelValue.Batch; } CifsServerPerOpenFile open = new CifsServerPerOpenFile( treeConnect, CifsMessageUtils.ToSmbString(response.SmbData.TemporaryFileName, 0, false), response.SmbParameters.FID, (uint)request.SmbParameters.FileAttributes, opLock, this.GenerateFileGlobalId(), request.SmbHeader.Pid); this.AddOpenFile(open); } } } #endregion break; case SmbCommand.SMB_COM_CREATE_NEW: #region SMB_COM_CREATE_NEW { SmbCreateNewRequestPacket request = requestPacket as SmbCreateNewRequestPacket; SmbCreateNewResponsePacket response = responsePacket as SmbCreateNewResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { OplockLevelValue opLock = OplockLevelValue.None; if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPLOCK) == SmbFlags.SMB_FLAGS_OPLOCK) { opLock = OplockLevelValue.Exclusive; } if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPBATCH) == SmbFlags.SMB_FLAGS_OPBATCH) { opLock |= OplockLevelValue.Batch; } CifsServerPerOpenFile open = new CifsServerPerOpenFile( treeConnect, CifsMessageUtils.ToSmbString(request.SmbData.FileName, 0, false), response.SmbParameters.FID, (uint)request.SmbParameters.FileAttributes, opLock, this.GenerateFileGlobalId(), request.SmbHeader.Pid); this.AddOpenFile(open); } } } #endregion break; case SmbCommand.SMB_COM_OPEN_ANDX: #region SMB_COM_OPEN_ANDX { SmbOpenAndxRequestPacket request = requestPacket as SmbOpenAndxRequestPacket; SmbOpenAndxResponsePacket response = responsePacket as SmbOpenAndxResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { OplockLevelValue opLock = OplockLevelValue.None; if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPLOCK) == SmbFlags.SMB_FLAGS_OPLOCK) { opLock = OplockLevelValue.Exclusive; } if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPBATCH) == SmbFlags.SMB_FLAGS_OPBATCH) { opLock |= OplockLevelValue.Batch; } string fileName; if ((request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE) { fileName = Encoding.Unicode.GetString(request.SmbData.FileName); } else { fileName = Encoding.ASCII.GetString(request.SmbData.FileName); } CifsServerPerOpenFile open = new CifsServerPerOpenFile( treeConnect, fileName, response.SmbParameters.FID, (uint)response.SmbParameters.FileAttrs, opLock, this.GenerateFileGlobalId(), request.SmbHeader.Pid); this.AddOpenFile(open); //save FID for chained response like: //treeConnect->openAndx->readAndx->close //when "close", FID is need to close the open opened in openAndx. if (response.AndxPacket != null) { //borrow smbHeader.Protocol to save FID for later process. //smbHeader.Protocol also use a flag to differentiate a single packet from a //batched andx packet. //FID is ushort, impossible to impact smbHeader.Protocol's usage as //a real packet header 0x424D53FF(0xFF, 'S', 'M', 'B') SmbHeader andxHeader = response.AndxPacket.SmbHeader; andxHeader.Protocol = response.SmbParameters.FID; response.AndxPacket.SmbHeader = andxHeader; } } } } #endregion break; case SmbCommand.SMB_COM_NT_CREATE_ANDX: #region SMB_COM_NT_CREATE_ANDX { SmbNtCreateAndxRequestPacket request = requestPacket as SmbNtCreateAndxRequestPacket; SmbNtCreateAndxResponsePacket response = responsePacket as SmbNtCreateAndxResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { string fileName; if ((request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE) { fileName = Encoding.Unicode.GetString(request.SmbData.FileName); } else { fileName = Encoding.ASCII.GetString(request.SmbData.FileName); } CifsServerPerOpenFile open = new CifsServerPerOpenFile( treeConnect, fileName, response.SmbParameters.FID, (uint)response.SmbParameters.ExtFileAttributes, response.SmbParameters.OplockLevel, this.GenerateFileGlobalId(), request.SmbHeader.Pid); this.AddOpenFile(open); } } } #endregion break; case SmbCommand.SMB_COM_OPEN_PRINT_FILE: #region SMB_COM_OPEN_PRINT_FILE { SmbOpenPrintFileRequestPacket request = requestPacket as SmbOpenPrintFileRequestPacket; SmbOpenPrintFileResponsePacket response = responsePacket as SmbOpenPrintFileResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { CifsServerPerOpenFile open = new CifsServerPerOpenFile( treeConnect, CifsMessageUtils.ToSmbString(request.SmbData.Identifier, 0, false), response.SmbParameters.FID, request.SmbParameters.Mode, OplockLevelValue.None, this.GenerateFileGlobalId(), request.SmbHeader.Pid); this.AddOpenFile(open); } } } #endregion break; case SmbCommand.SMB_COM_TRANSACTION2: #region Trans2Open2 { SmbTrans2Open2RequestPacket request = requestPacket as SmbTrans2Open2RequestPacket; SmbTrans2Open2FinalResponsePacket response = responsePacket as SmbTrans2Open2FinalResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { string fileName; if ((request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE) { fileName = Encoding.Unicode.GetString(request.Trans2Parameters.FileName); } else { fileName = Encoding.ASCII.GetString(request.Trans2Parameters.FileName); } CifsServerPerOpenFile open = new CifsServerPerOpenFile( treeConnect, fileName, response.Trans2Parameters.Fid, (uint)response.Trans2Parameters.FileAttributes, OplockLevelValue.None, this.GenerateFileGlobalId(), request.SmbHeader.Pid); this.AddOpenFile(open); } } } #endregion #region Trans2FindFirst2 { SmbTrans2FindFirst2RequestPacket request = requestPacket as SmbTrans2FindFirst2RequestPacket; SmbTrans2FindFirst2FinalResponsePacket response = responsePacket as SmbTrans2FindFirst2FinalResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { string fileName; if ((request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE) { fileName = Encoding.Unicode.GetString(request.Trans2Parameters.FileName); } else { fileName = Encoding.ASCII.GetString(request.Trans2Parameters.FileName); } CifsServerPerOpenSearch openSearch = new CifsServerPerOpenSearch( treeConnect, response.Trans2Parameters.SID, smbHeader.Mid, smbHeader.Pid, this.GenerateSearchGlobalId()); this.AddOpenSearch(openSearch); } } } #endregion break; case SmbCommand.SMB_COM_WRITE_AND_CLOSE: #region SMB_COM_WRITE_AND_CLOSE { SmbWriteAndCloseRequestPacket request = requestPacket as SmbWriteAndCloseRequestPacket; SmbWriteAndCloseResponsePacket response = responsePacket as SmbWriteAndCloseResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { CifsServerPerOpenFile open = treeConnect.GetOpen(request.SmbParameters.FID); if (open != null) { this.RemoveOpenFile(open.FileGlobalId); } } } } #endregion break; case SmbCommand.SMB_COM_CLOSE: #region SMB_COM_CLOSE { SmbCloseRequestPacket request = requestPacket as SmbCloseRequestPacket; SmbCloseResponsePacket response = responsePacket as SmbCloseResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { CifsServerPerOpenFile open = treeConnect.GetOpen(request.SmbParameters.FID); if (open == null) { open = treeConnect.GetOpen((ushort)smbHeader.Protocol); } if (open != null) { this.RemoveOpenFile(open.FileGlobalId); } } } } #endregion break; case SmbCommand.SMB_COM_FIND_CLOSE2: #region SMB_COM_FIND_CLOSE2 { SmbFindClose2RequestPacket request = requestPacket as SmbFindClose2RequestPacket; SmbFindClose2ResponsePacket response = responsePacket as SmbFindClose2ResponsePacket; CifsServerPerSession session = connection.GetSession(smbHeader.Uid); if (request != null && response != null && session != null) { CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid); if (treeConnect != null) { CifsServerPerOpenSearch openSearch = treeConnect.GetOpenSearch( request.SmbParameters.SearchHandle); ; if (openSearch != null) { this.RemoveOpenSearch(openSearch.SearchGlobalId); } } } } #endregion break; #endregion default: // No Connection/Session/Tree/Open will be updated if other types of response. break; } SmbBatchedRequestPacket batchedRequest = requestPacket as SmbBatchedRequestPacket; SmbBatchedResponsePacket batchedResponse = responsePacket as SmbBatchedResponsePacket; if (batchedRequest != null && batchedResponse != null) { //pass the FID stored in the andxHeader.Protocol into response.AndxPacket if (batchedRequest.AndxPacket != null && batchedResponse.AndxPacket != null && batchedResponse.SmbHeader.Protocol != CifsMessageUtils.SMB_PROTOCOL_ANDXPACKET && batchedResponse.SmbHeader.Protocol != CifsMessageUtils.SMB_PROTOCOL_IDENTIFIER) { SmbHeader andxHeader = batchedResponse.AndxPacket.SmbHeader; andxHeader.Protocol = smbHeader.Protocol; batchedResponse.AndxPacket.SmbHeader = andxHeader; } this.UpdateResponseRoleContext(connection, batchedRequest.AndxPacket, batchedResponse.AndxPacket); } }
public SmbTreeConnectAndxResponsePacket CreateTreeConnectAndxResponse( CifsServerPerConnection connection, SmbTreeConnectAndxRequestPacket request, OptionalSupport optionalSupport, string service, SmbPacket andxPacket) { SmbTreeConnectAndxResponsePacket response = new SmbTreeConnectAndxResponsePacket(); SmbHeader smbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); smbHeader.Tid = connection.GenerateTID(); response.SmbHeader = smbHeader; bool isUnicode = (response.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE; byte[] serviceBytes = CifsMessageUtils.ToSmbStringBytes(service, false); byte[] fileSystem = CifsMessageUtils.ToSmbStringBytes(CifsMessageUtils.NATIVE_FS, isUnicode); int padOffset = Marshal.SizeOf(response.SmbParameters) + sizeof(ushort); SMB_COM_TREE_CONNECT_ANDX_Response_SMB_Data smbData = response.SmbData; smbData.Pad = new byte[((padOffset + 3) & ~3) - padOffset]; smbData.Service = serviceBytes; smbData.NativeFileSystem = fileSystem; smbData.ByteCount = (ushort)(smbData.Pad.Length + smbData.Service.Length + smbData.NativeFileSystem.Length); response.SmbData = smbData; SMB_COM_TREE_CONNECT_ANDX_Response_SMB_Parameters smbParameters = response.SmbParameters; smbParameters.AndXCommand = andxPacket != null ? andxPacket.SmbHeader.Command : SmbCommand.SMB_COM_NO_ANDX_COMMAND; smbParameters.AndXReserved = 0x00; smbParameters.AndXOffset = (ushort)(padOffset + response.SmbData.ByteCount); smbParameters.OptionalSupport = (ushort)optionalSupport; smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2); response.SmbParameters = smbParameters; response.AndxPacket = andxPacket; response.UpdateHeader(); return response; }
/// <summary> /// Send packet to a specific connected client /// </summary> /// <param name="connection">connection to remote client</param> /// <param name="packet">the smb packet</param> /// <exception cref="ArgumentNullException">smbPacket</exception> /// <exception cref="ArgumentNullException">endpoint</exception> /// <exception cref="InvalidOperationException"> /// The transport is not started. Please invoke Start() first /// </exception> public virtual void SendPacket(SmbPacket packet, CifsServerPerConnection connection) { if (packet == null) { throw new ArgumentNullException("packet"); } if (connection == null) { throw new ArgumentNullException("connection"); } if (this.isRunning == false) { throw new InvalidOperationException( "The transport is not started. Please invoke Start() first."); } if (connection.IsSigningActive && (packet as SmbLockingAndxRequestPacket == null) && (packet as SmbReadRawResponsePacket == null)) { packet.Sign(connection.ServerSendSequenceNumbers[packet.SmbHeader.Mid], connection.SigningSessionKey, connection.SigningChallengeResponse); } SmbPacket smbPacket = packet as SmbPacket; if (smbPacket != null && this.context.IsContextUpdateEnabled && (smbPacket as SmbLockingAndxRequestPacket == null)) { this.context.UpdateRoleContext(connection, smbPacket); } // send packet through netbios over Tcp this.transport.SendPacket(connection.Identity, smbPacket); }
public SmbUnlockByteRangeResponsePacket CreateUnlockByteRangeResponse( CifsServerPerConnection connection, SmbUnlockByteRangeRequestPacket request) { SmbUnlockByteRangeResponsePacket response = new SmbUnlockByteRangeResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); return response; }
/// <summary> /// <para>Create default response based on the request.</para> /// If the request is a chained andx packet, the corresponding response is also chained. /// </summary> /// <param name="connection">the connection on which the response will be sent.</param> /// <param name="request">the corresponding request</param> /// <returns>the default response to the request.</returns> public SmbPacket CreateDefaultResponse(CifsServerPerConnection connection, SmbPacket request) { return this.CreateDefaultResponseWithCallBack(connection, request, null); }
public SmbTransWriteNmpipeSuccessResponsePacket CreateTransWriteNmpipeSuccessResponse( CifsServerPerConnection connection, SmbTransWriteNmpipeRequestPacket request) { SmbTransWriteNmpipeSuccessResponsePacket response = new SmbTransWriteNmpipeSuccessResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); TRANS_WRITE_NMPIPE_Response_Trans_Parameters transParameters = response.TransParameters; transParameters.BytesWritten = (ushort)request.TransData.WriteData.Length; response.TransParameters = transParameters; response.UpdateCountAndOffset(); return response; }
public SmbFindNotifyCloseResponsePacket CreateFindNotifyCloseResponse( CifsServerPerConnection connection, SmbFindNotifyCloseRequestPacket request) { SmbFindNotifyCloseResponsePacket response = new SmbFindNotifyCloseResponsePacket(); SmbHeader smbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); if ((smbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_NT_STATUS) == SmbFlags2.SMB_FLAGS2_NT_STATUS) { smbHeader.Status = (uint)NtStatus.STATUS_NOT_IMPLEMENTED; } else { SmbStatus smbStatus = new SmbStatus(); smbStatus.ErrorClass = SmbErrorClass.ERRDOS; smbStatus.Reserved = 0; smbStatus.ErrorCode = (ushort)SmbErrorCodeOfERRDOS.ERRbadfunc; smbHeader.Status = smbStatus; } response.SmbHeader = smbHeader; return response; }
public SmbEchoResponsePacket CreateEchoResponse( CifsServerPerConnection connection, SmbEchoRequestPacket request) { SmbEchoResponsePacket response = new SmbEchoResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); SMB_COM_ECHO_Response_SMB_Parameters smbParameters = response.SmbParameters; smbParameters.WordCount = 0x01; //The SMB_Parameters.Words.SequenceNumber field MUST be set to 1.(3.3.5.32) smbParameters.SequenceNumber = 0x01; response.SmbParameters = smbParameters; SMB_COM_ECHO_Response_SMB_Data smbData = response.SmbData; smbData.ByteCount = request.SmbData.ByteCount; smbData.Data = request.SmbData.Data; response.SmbData = smbData; return response; }
public SmbWriteRawFinalResponsePacket CreateWriteRawFinalResponse( CifsServerPerConnection connection, SmbWriteRawRequestPacket request, ushort count) { SmbWriteRawFinalResponsePacket response = new SmbWriteRawFinalResponsePacket(); SmbHeader smbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); smbHeader.Command = SmbCommand.SMB_COM_WRITE_COMPLETE; response.SmbHeader = smbHeader; SMB_COM_WRITE_RAW_FinalResponse_SMB_Parameters smbParameters = response.SmbParameters; smbParameters.Count = count; smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2); response.SmbParameters = smbParameters; return response; }
/// <summary> /// Create Trans response /// </summary> /// <param name="connection">the connection on which the response will be sent.</param> /// <param name="request">the corresponding request</param> /// <returns>the default response to the request.</returns> private SmbPacket CreateDefaultTransResponse( CifsServerPerConnection connection, SmbTransactionRequestPacket request) { SmbTransSetNmpipeStateRequestPacket setStateRequest = request as SmbTransSetNmpipeStateRequestPacket; SmbTransRawReadNmpipeRequestPacket rewReadRequest = request as SmbTransRawReadNmpipeRequestPacket; SmbTransQueryNmpipeStateRequestPacket queryStateRequest = request as SmbTransQueryNmpipeStateRequestPacket; SmbTransQueryNmpipeInfoRequestPacket queryInfoRequest = request as SmbTransQueryNmpipeInfoRequestPacket; SmbTransPeekNmpipeRequestPacket peekStateRequest = request as SmbTransPeekNmpipeRequestPacket; SmbTransTransactNmpipeRequestPacket transactRequest = request as SmbTransTransactNmpipeRequestPacket; SmbTransRawWriteNmpipeRequestPacket rawWriteRequest = request as SmbTransRawWriteNmpipeRequestPacket; SmbTransReadNmpipeRequestPacket readRequest = request as SmbTransReadNmpipeRequestPacket; SmbTransWriteNmpipeRequestPacket writeRequest = request as SmbTransWriteNmpipeRequestPacket; SmbTransCallNmpipeRequestPacket callRequest = request as SmbTransCallNmpipeRequestPacket; SmbTransRapRequestPacket rapRequest = request as SmbTransRapRequestPacket; SmbPacket response = null; if (setStateRequest != null) { response = this.CreateTransSetNmpipeStateSuccessResponse(connection, setStateRequest); } else if (rewReadRequest != null) { response = this.CreateTransRawReadNmpipeSuccessResponse(connection, rewReadRequest, new byte[0]); } else if (queryStateRequest != null) { response = this.CreateTransQueryNmpipeStateSuccessResponse(connection, queryStateRequest, SMB_NMPIPE_STATUS.Endpoint); } else if (queryInfoRequest != null) { response = this.CreateTransQueryNmpipeInfoSuccessResponse(connection, queryInfoRequest, 0x0, 0x0, 0x0, 0x0, @"\\Cifs\share"); } else if (peekStateRequest != null) { response = this.CreateTransPeekNmpipeSuccessResponse(connection, peekStateRequest, 0x0, 0x0, SMB_NMPIPE_STATUS.Endpoint, new byte[0]); } else if (transactRequest != null) { response = this.CreateTransTransactNmpipeSuccessResponse(connection, transactRequest, new byte[0]); } else if (rawWriteRequest != null) { response = this.CreateTransRawWriteNmpipeSuccessResponse(connection, rawWriteRequest); } else if (readRequest != null) { response = this.CreateTransReadNmpipeSuccessResponse(connection, readRequest, new byte[0]); } else if (writeRequest != null) { response = this.CreateTransWriteNmpipeSuccessResponse(connection, writeRequest); } else if (callRequest != null) { response = this.CreateTransCallNmpipeSuccessResponse(connection, callRequest, new byte[0]); } else if (rapRequest != null) { response = new SmbTransRapResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); } return response; }
/// <summary> /// Create default Trans2 response /// </summary> /// <param name="connection">the connection on which the response will be sent.</param> /// <param name="request">the corresponding request</param> /// <returns>the default response to the request.</returns> private SmbPacket CreateDefaultTrans2Response( CifsServerPerConnection connection, SmbTransaction2RequestPacket request) { SmbTrans2Open2RequestPacket open2Request = request as SmbTrans2Open2RequestPacket; SmbTrans2FindFirst2RequestPacket findFirst2Request = request as SmbTrans2FindFirst2RequestPacket; SmbTrans2FindNext2RequestPacket findNext2Request = request as SmbTrans2FindNext2RequestPacket; SmbTrans2QueryFsInformationRequestPacket queryFsRequest = request as SmbTrans2QueryFsInformationRequestPacket; SmbTrans2SetFsInformationRequestPacket setFsInfoRequest = request as SmbTrans2SetFsInformationRequestPacket; SmbTrans2QueryPathInformationRequestPacket queryPathRequest = request as SmbTrans2QueryPathInformationRequestPacket; SmbTrans2SetPathInformationRequestPacket setPathRequest = request as SmbTrans2SetPathInformationRequestPacket; SmbTrans2QueryFileInformationRequestPacket queryFileRequest = request as SmbTrans2QueryFileInformationRequestPacket; SmbTrans2SetFileInformationRequestPacket setFileRequest = request as SmbTrans2SetFileInformationRequestPacket; SmbTrans2FsctlRequestPacket fsctlRequest = request as SmbTrans2FsctlRequestPacket; SmbTrans2Ioctl2RequestPacket ioctl2Request = request as SmbTrans2Ioctl2RequestPacket; SmbTrans2FindNotifyFirstRequestPacket findNotifyFirstRequest = request as SmbTrans2FindNotifyFirstRequestPacket; SmbTrans2FindNotifyNextRequestPacket findNotifyNextRequest = request as SmbTrans2FindNotifyNextRequestPacket; SmbTrans2CreateDirectoryRequestPacket createDirRequest = request as SmbTrans2CreateDirectoryRequestPacket; SmbTrans2SessionSetupRequestPacket sessionSetupRequest = request as SmbTrans2SessionSetupRequestPacket; SmbTrans2GetDfsReferalRequestPacket getDfsReferalRequest = request as SmbTrans2GetDfsReferalRequestPacket; SmbTrans2ReportDfsInconsistencyRequestPacket reportDfsRequest = request as SmbTrans2ReportDfsInconsistencyRequestPacket; SmbPacket response = null; if (open2Request != null) { response = this.CreateTrans2Open2FinalResponse(connection, open2Request, 0x0, FileTypeValue.FileTypeDisk, SMB_NMPIPE_STATUS.Endpoint, OpenResultsValues.LockStatus); } if (findFirst2Request != null) { response = this.CreateTrans2FindFirst2FinalResponse(connection, findFirst2Request, 0x0, null); } if (findNext2Request != null) { response = this.CreateTrans2FindNext2FinalResponse(connection, findNext2Request, 0x0, null); } if (queryFsRequest != null) { response = this.CreateTrans2QueryFsInformationFinalResponse(connection, queryFsRequest, null); } if (setFsInfoRequest != null) { response = this.CreateTrans2SetFsInformationFinalResponse(connection, setFsInfoRequest); } if (queryPathRequest != null) { response = this.CreateTrans2QueryPathInformationFinalResponse(connection, queryPathRequest, null); } if (setPathRequest != null) { response = this.CreateTrans2SetPathInformationFinalResponse(connection, setPathRequest); } if (queryFileRequest != null) { response = this.CreateTrans2QueryFileInformationFinalResponse(connection, queryFileRequest, null); } if (setFileRequest != null) { response = this.CreateTrans2SetFileInformationFinalResponse(connection, setFileRequest); } if (fsctlRequest != null) { response = this.CreateTrans2FsctlFinalResponse(connection, fsctlRequest); } if (ioctl2Request != null) { response = this.CreateTrans2Ioctl2FinalResponse(connection, ioctl2Request); } if (findNotifyFirstRequest != null) { response = this.CreateTrans2FindNotifyFirstFinalResponse(connection, findNotifyFirstRequest); } if (findNotifyNextRequest != null) { response = this.CreateTrans2FindNotifyNextFinalResponse(connection, findNotifyNextRequest); } if (createDirRequest != null) { response = this.CreateTrans2CreateDirectoryFinalResponse(connection, createDirRequest); } if (sessionSetupRequest != null) { response = this.CreateTrans2SessionSetupFinalResponse(connection, sessionSetupRequest); } if (getDfsReferalRequest != null) { response = this.CreateTrans2GetDfsReferalFinalResponse(connection, getDfsReferalRequest, new RESP_GET_DFS_REFERRAL()); } if (reportDfsRequest != null) { response = this.CreateTrans2ReportDfsInconsistencyFinalResponse(connection, reportDfsRequest); } return response; }
/// <summary> /// Create default NtTrans response /// </summary> /// <param name="connection">the connection on which the response will be sent.</param> /// <param name="request">the corresponding request</param> /// <returns>the default response to the request.</returns> private SmbPacket CreateDefaultNtTransResponse( CifsServerPerConnection connection, SmbNtTransactRequestPacket request) { SmbNtTransactCreateRequestPacket ntCreateRequest = request as SmbNtTransactCreateRequestPacket; SmbNtTransactIoctlRequestPacket ioctlRequest = request as SmbNtTransactIoctlRequestPacket; SmbNtTransactSetSecurityDescRequestPacket setSecurityDescRequest = request as SmbNtTransactSetSecurityDescRequestPacket; SmbNtTransactNotifyChangeRequestPacket notifyChangeRequest = request as SmbNtTransactNotifyChangeRequestPacket; SmbNtTransactRenameRequestPacket renameRequest = request as SmbNtTransactRenameRequestPacket; SmbNtTransactQuerySecurityDescRequestPacket querySecurityDesc = request as SmbNtTransactQuerySecurityDescRequestPacket; SmbPacket response = null; if (ntCreateRequest != null) { response = this.CreateNtTransactCreateResponse( connection, ntCreateRequest, 0x0, 0x0, FileTypeValue.FileTypeDisk, SMB_NMPIPE_STATUS.Endpoint, 0x0); } if (ioctlRequest != null) { response = this.CreateNtTransactIoctlResponse(connection, ioctlRequest, new byte[0]); } if (setSecurityDescRequest != null) { response = this.CreateNtTransactSetSecurityDescResponse(connection, setSecurityDescRequest); } if (notifyChangeRequest != null) { response = this.CreateNtTransactNotifyChangeResponse(connection, notifyChangeRequest, null); } if (renameRequest != null) { response = this.CreateNtTransactRenameResponse(connection, renameRequest); } if (querySecurityDesc != null) { response = this.CreateNtTransactQuerySecurityDescResponse(connection, querySecurityDesc, null); } return response; }
public SmbPacket CreateDefaultResponseWithCallBack( CifsServerPerConnection connection, SmbPacket request, CreateDefaultResponseCallBack callBack) { if (connection == null || request == null) { return null; } SmbPacket response = null; if (callBack != null) { response = callBack(connection, request); } if (response != null) { return response; } switch(request.SmbHeader.Command) { case SmbCommand.SMB_COM_CREATE_DIRECTORY: response = this.CreateCreateDirectoryResponse( connection, request as SmbCreateDirectoryRequestPacket); break; case SmbCommand.SMB_COM_DELETE_DIRECTORY: response = this.CreateDeleteDirectoryResponse( connection, request as SmbDeleteDirectoryRequestPacket); break; case SmbCommand.SMB_COM_OPEN: response = this.CreateOpenResponse( connection, request as SmbOpenRequestPacket, 0x0, 0x0); break; case SmbCommand.SMB_COM_CREATE: response = this.CreateCreateResponse( connection, request as SmbCreateRequestPacket); break; case SmbCommand.SMB_COM_CLOSE: response = this.CreateCloseResponse( connection, request as SmbCloseRequestPacket); break; case SmbCommand.SMB_COM_FLUSH: response = this.CreateFlushResponse( connection, request as SmbFlushRequestPacket); break; case SmbCommand.SMB_COM_DELETE: response = this.CreateDeleteResponse( connection, request as SmbDeleteRequestPacket); break; case SmbCommand.SMB_COM_RENAME: response = this.CreateRenameResponse( connection, request as SmbRenameRequestPacket); break; case SmbCommand.SMB_COM_QUERY_INFORMATION: response = this.CreateQueryInformationResponse( connection, request as SmbQueryInformationRequestPacket, SmbFileAttributes.SMB_FILE_ATTRIBUTE_NORMAL, 0x0, 0x0); break; case SmbCommand.SMB_COM_SET_INFORMATION: response = this.CreateSetInformationResponse( connection, request as SmbSetInformationRequestPacket); break; case SmbCommand.SMB_COM_READ: response = this.CreateReadResponse( connection, request as SmbReadRequestPacket, new byte[0]); break; case SmbCommand.SMB_COM_WRITE: response = this.CreateWriteResponse( connection, request as SmbWriteRequestPacket); break; case SmbCommand.SMB_COM_LOCK_byte_RANGE: response = this.CreateLockByteRangeResponse( connection, request as SmbLockByteRangeRequestPacket); break; case SmbCommand.SMB_COM_UNLOCK_byte_RANGE: response = this.CreateUnlockByteRangeResponse( connection, request as SmbUnlockByteRangeRequestPacket); break; case SmbCommand.SMB_COM_CREATE_TEMPORARY: response = this.CreateCreateTemporaryResponse( connection, request as SmbCreateTemporaryRequestPacket, "temp"); break; case SmbCommand.SMB_COM_CREATE_NEW: response = this.CreateCreateNewResponse( connection, request as SmbCreateNewRequestPacket); break; case SmbCommand.SMB_COM_CHECK_DIRECTORY: response = this.CreateCheckDirectoryResponse( connection, request as SmbCheckDirectoryRequestPacket); break; case SmbCommand.SMB_COM_PROCESS_EXIT: response = this.CreateProcessExitResponse( connection, request as SmbProcessExitRequestPacket); break; case SmbCommand.SMB_COM_SEEK: response = this.CreateSeekResponse( connection, request as SmbSeekRequestPacket); break; case SmbCommand.SMB_COM_LOCK_AND_READ: response = this.CreateLockAndReadResponse( connection, request as SmbLockAndReadRequestPacket, new byte[0]); break; case SmbCommand.SMB_COM_WRITE_AND_UNLOCK: response = this.CreateWriteAndUnlockResponse( connection, request as SmbWriteAndUnlockRequestPacket); break; case SmbCommand.SMB_COM_READ_RAW: response = this.CreateReadRawResponse(new byte[0]); break; case SmbCommand.SMB_COM_READ_MPX: response = this.CreateReadMpxResponse( connection, request as SmbReadMpxRequestPacket, 0x0, 0x0, 0x0, new byte[0]); break; case SmbCommand.SMB_COM_WRITE_RAW: response = this.CreateWriteRawFinalResponse( connection, request as SmbWriteRawRequestPacket, 0x0); break; case SmbCommand.SMB_COM_WRITE_MPX: response = this.CreateWriteMpxResponse( connection, request as SmbWriteMpxRequestPacket); break; case SmbCommand.SMB_COM_QUERY_SERVER: response = this.CreateQueryServerResponse( connection, request as SmbQueryServerRequestPacket); break; case SmbCommand.SMB_COM_SET_INFORMATION2: response = this.CreateSetInformation2Response( connection, request as SmbSetInformation2RequestPacket); break; case SmbCommand.SMB_COM_QUERY_INFORMATION2: response = this.CreateQueryInformation2Response( connection, request as SmbQueryInformation2RequestPacket, SmbDate.Now, SmbTime.Now, SmbDate.Now, SmbTime.Now, SmbDate.Now, SmbTime.Now, 0x0, 0x0, SmbFileAttributes.SMB_FILE_ATTRIBUTE_NORMAL); break; case SmbCommand.SMB_COM_LOCKING_ANDX: SmbLockingAndxRequestPacket lockingAndxRequest = request as SmbLockingAndxRequestPacket; response = this.CreateLockingAndxResponse( connection, lockingAndxRequest, this.CreateDefaultResponseWithCallBack(connection, lockingAndxRequest.AndxPacket, callBack)); break; case SmbCommand.SMB_COM_IOCTL: response = this.CreateIoctlResponse( connection, request as SmbIoctlRequestPacket, null, null); break; case SmbCommand.SMB_COM_COPY: response = this.CreateCopyResponse( connection, request as SmbCopyRequestPacket); break; case SmbCommand.SMB_COM_MOVE: response = this.CreateMoveResponse( connection, request as SmbMoveRequestPacket); break; case SmbCommand.SMB_COM_ECHO: response = this.CreateEchoResponse( connection, request as SmbEchoRequestPacket); break; case SmbCommand.SMB_COM_WRITE_AND_CLOSE: response = this.CreateWriteAndCloseResponse( connection, request as SmbWriteAndCloseRequestPacket); break; case SmbCommand.SMB_COM_OPEN_ANDX: SmbOpenAndxRequestPacket openAndxRequest = request as SmbOpenAndxRequestPacket; response = this.CreateOpenAndxResponse( connection, openAndxRequest, 0x0, 0x0, AccessRightsValue.SMB_DA_ACCESS_READ, ResourceTypeValue.FileTypeDisk, SMB_NMPIPE_STATUS.Endpoint, OpenResultsValues.LockStatus, this.CreateDefaultResponseWithCallBack(connection, openAndxRequest.AndxPacket, callBack)); break; case SmbCommand.SMB_COM_READ_ANDX: SmbReadAndxRequestPacket readAndxRequest = request as SmbReadAndxRequestPacket; response = this.CreateReadAndxResponse( connection, readAndxRequest, 0xffff, new byte[0], this.CreateDefaultResponseWithCallBack(connection, readAndxRequest.AndxPacket, callBack)); break; case SmbCommand.SMB_COM_WRITE_ANDX: SmbWriteAndxRequestPacket writeAndxRequest = request as SmbWriteAndxRequestPacket; response = this.CreateWriteAndxResponse( connection, writeAndxRequest, 0xffff, this.CreateDefaultResponseWithCallBack(connection, writeAndxRequest.AndxPacket, callBack)); break; case SmbCommand.SMB_COM_NEW_FILE_SIZE: response = this.CreateNewFileSizeResponse( connection, request as SmbNewFileSizeRequestPacket); break; case SmbCommand.SMB_COM_CLOSE_AND_TREE_DISC: response = this.CreateCloseAndTreeDiscResponse( connection, request as SmbCloseAndTreeDiscRequestPacket); break; case SmbCommand.SMB_COM_FIND_CLOSE2: response = this.CreateFindClose2Response( connection, request as SmbFindClose2RequestPacket); break; case SmbCommand.SMB_COM_FIND_NOTIFY_CLOSE: response = this.CreateFindNotifyCloseResponse( connection, request as SmbFindNotifyCloseRequestPacket); break; case SmbCommand.SMB_COM_TREE_CONNECT: response = this.CreateTreeConnectResponse( connection, request as SmbTreeConnectRequestPacket); break; case SmbCommand.SMB_COM_TREE_DISCONNECT: response = this.CreateTreeDisconnectResponse( connection, request as SmbTreeDisconnectRequestPacket); break; case SmbCommand.SMB_COM_NEGOTIATE: SecurityModes securityModes = SecurityModes.NEGOTIATE_USER_SECURITY; if ((this.context.MessageSigningPolicy & MessageSigningPolicyValues.MessageSigningEnabled) == MessageSigningPolicyValues.MessageSigningEnabled) { securityModes |= SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_ENABLED; } if ((this.context.MessageSigningPolicy & MessageSigningPolicyValues.MessageSigningRequired) == MessageSigningPolicyValues.MessageSigningRequired) { securityModes |= SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED; } if (this.context.NtlmAuthenticationPolicy != NTLMAuthenticationPolicyValues.Disabled && this.context.PlaintextAuthenticationPolicy != PlaintextAuthenticationPolicyValues.Enabled) { securityModes |= SecurityModes.NEGOTIATE_ENCRYPT_PASSWORDS; } response = this.CreateNegotiateResponse( connection, request as SmbNegotiateRequestPacket, securityModes); break; case SmbCommand.SMB_COM_SESSION_SETUP_ANDX: ActionValues action = ActionValues.NONE; SmbSessionSetupAndxRequestPacket sessionAndxRequest = request as SmbSessionSetupAndxRequestPacket; if (!string.IsNullOrEmpty(CifsMessageUtils.PlainTextAuthenticate(sessionAndxRequest, this.context.AccountCredentials))) { action = ActionValues.GuestAccess; } if (CifsMessageUtils.NTLMAuthenticate(sessionAndxRequest, this.context.NlmpServerSecurityContexts, connection.NegotiateTime.Time) == null) { // If clear, the NTLM user session key will be used for message signing (if enabled). // If set, the LM session key will be used for message signing. action = ActionValues.LmSigning; } response = this.CreateSessionSetupAndxResponse( connection, sessionAndxRequest, action, this.CreateDefaultResponseWithCallBack(connection, sessionAndxRequest.AndxPacket, callBack)); break; case SmbCommand.SMB_COM_LOGOFF_ANDX: SmbLogoffAndxRequestPacket logoffAndxRequest = request as SmbLogoffAndxRequestPacket; response = this.CreateLogoffAndxResponse( connection, logoffAndxRequest, this.CreateDefaultResponseWithCallBack(connection, logoffAndxRequest.AndxPacket, callBack)); break; case SmbCommand.SMB_COM_TREE_CONNECT_ANDX: SmbTreeConnectAndxRequestPacket treeConnectAndxRequest = request as SmbTreeConnectAndxRequestPacket; response = this.CreateTreeConnectAndxResponse( connection, treeConnectAndxRequest, OptionalSupport.NONE, CifsMessageUtils.TREE_CONNECT_SERVICE, this.CreateDefaultResponseWithCallBack(connection, treeConnectAndxRequest.AndxPacket, callBack)); break; case SmbCommand.SMB_COM_SECURITY_PACKAGE_ANDX: response = this.CreateSecurityPackageAndxResponse( connection, request as SmbSecurityPackageAndxRequestPacket); break; case SmbCommand.SMB_COM_QUERY_INFORMATION_DISK: response = this.CreateQueryInformationDiskResponse( connection, request as SmbQueryInformationDiskRequestPacket, 0x0, 0x0, 0x0, 0x0); break; case SmbCommand.SMB_COM_SEARCH: response = this.CreateSearchResponse( connection, request as SmbSearchRequestPacket, null); break; case SmbCommand.SMB_COM_FIND: response = this.CreateFindResponse( connection, request as SmbFindRequestPacket, null); break; case SmbCommand.SMB_COM_FIND_UNIQUE: response = this.CreateFindUniqueResponse( connection, request as SmbFindUniqueRequestPacket, null); break; case SmbCommand.SMB_COM_FIND_CLOSE: response = this.CreateFindCloseResponse( connection, request as SmbFindCloseRequestPacket); break; case SmbCommand.SMB_COM_NT_CREATE_ANDX: SmbNtCreateAndxRequestPacket createAndxRequest = request as SmbNtCreateAndxRequestPacket; response = this.CreateNtCreateAndxResponse( connection, createAndxRequest, OplockLevelValue.None, 0x0, 0x0, FileTypeValue.FileTypeDisk, SMB_NMPIPE_STATUS.Endpoint, 0x0, this.CreateDefaultResponseWithCallBack(connection, createAndxRequest.AndxPacket, callBack)); break; case SmbCommand.SMB_COM_NT_RENAME: response = this.CreateNtRenameResponse( connection, request as SmbNtRenameRequestPacket); break; case SmbCommand.SMB_COM_OPEN_PRINT_FILE: response = this.CreateOpenPrintFileResponse( connection, request as SmbOpenPrintFileRequestPacket); break; case SmbCommand.SMB_COM_WRITE_PRINT_FILE: response = this.CreateWritePrintFileResponse( connection, request as SmbWritePrintFileRequestPacket); break; case SmbCommand.SMB_COM_CLOSE_PRINT_FILE: response = this.CreateClosePrintFileResponse( connection, request as SmbClosePrintFileRequestPacket); break; case SmbCommand.SMB_COM_GET_PRINT_QUEUE: response = this.CreateGetPrintQueueResponse( connection, request as SmbGetPrintQueueRequestPacket); break; case SmbCommand.SMB_COM_READ_BULK: response = this.CreateReadBulkResponse( connection, request as SmbReadBulkRequestPacket); break; case SmbCommand.SMB_COM_WRITE_BULK: response = this.CreateWriteBulkResponse( connection, request as SmbWriteBulkRequestPacket); break; case SmbCommand.SMB_COM_WRITE_BULK_DATA: response = this.CreateWriteBulkDataResponse( connection, request as SmbWriteBulkDataRequestPacket); break; case SmbCommand.SMB_COM_INVALID: response = this.CreateInvalidResponse( connection, request as SmbInvalidRequestPacket); break; case SmbCommand.SMB_COM_NO_ANDX_COMMAND: response = this.CreateNoAndxCommandResponse( connection, request as SmbNoAndxCommandRequestPacket); break; case SmbCommand.SMB_COM_TRANSACTION: response = this.CreateDefaultTransResponse( connection, request as SmbTransactionRequestPacket); break; case SmbCommand.SMB_COM_TRANSACTION2: response = this.CreateDefaultTrans2Response( connection, request as SmbTransaction2RequestPacket); break; case SmbCommand.SMB_COM_NT_TRANSACT: response = this.CreateDefaultNtTransResponse( connection, request as SmbNtTransactRequestPacket); break; default: break; } //The request did not pass the signature verification when decoding. if (connection.IsSigningActive && !request.IsSignatureCorrect) { SmbHeader smbHeader = response.SmbHeader; smbHeader.Status = (uint)NtStatus.STATUS_ACCESS_DENIED; response.SmbHeader = smbHeader; return response; } return response; }
/// <summary> /// Expect a packet from a connected client /// </summary> /// <param name="timeout">waiting time</param> /// <param name="connection">the remote client who sent this packet</param> /// <returns>received smb the packet</returns> /// <exception cref="InvalidOperationException"> /// The transport is not started. Please invoke Start() first /// </exception> /// <exception cref="InvalidCastException">Unknown object received from transport.</exception> public virtual SmbPacket ExpectPacket(TimeSpan timeout, out CifsServerPerConnection connection) { if (this.isRunning == false) { throw new InvalidOperationException( "The transport is not started. Please invoke Start() first."); } connection = null; TransportEvent transportEvent = this.transport.ExpectTransportEvent(timeout); switch(transportEvent.EventType) { case EventType.ReceivedPacket: if (this.context.ConnectionTable.ContainsKey(transportEvent.RemoteEndPoint)) { connection = this.context.ConnectionTable[transportEvent.RemoteEndPoint] as CifsServerPerConnection; } return (SmbPacket)transportEvent.EventObject; case EventType.Exception: case EventType.Disconnected: { throw transportEvent.EventObject as Exception; } default: throw new InvalidCastException("Unknown object received from transport."); } }
public SmbWriteAndxResponsePacket CreateWriteAndxResponse( CifsServerPerConnection connection, SmbWriteAndxRequestPacket request, ushort available, SmbPacket andxPacket) { SmbWriteAndxResponsePacket response = new SmbWriteAndxResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); SMB_COM_WRITE_ANDX_Response_SMB_Parameters smbParameters = response.SmbParameters; smbParameters.AndXCommand = andxPacket != null ? andxPacket.SmbHeader.Command : SmbCommand.SMB_COM_NO_ANDX_COMMAND; smbParameters.AndXOffset = (ushort)(response.HeaderSize + Marshal.SizeOf(response.SmbParameters) + Marshal.SizeOf(response.SmbData)); smbParameters.Count = (ushort)request.SmbData.Data.Length; smbParameters.Available = available; smbParameters.AndXReserved = 0x00; smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2); response.SmbParameters = smbParameters; response.AndxPacket = andxPacket; response.UpdateHeader(); return response; }
/// <summary> /// Expect a client connect event /// </summary> /// <param name="timeout">time to wait if no response</param> /// <returns>true for success and false for failure</returns> /// <exception cref="InvalidOperationException"> /// The transport is not started. Please invoke Start() first. /// </exception> /// <exception cref="InvalidCastException">Unknown object received in transport.</exception> public virtual CifsServerPerConnection ExpectConnect(TimeSpan timeout) { if (this.isRunning == false) { throw new InvalidOperationException( "The transport is not started. Please invoke Start() first."); } TransportEvent transportEvent = this.transport.ExpectTransportEvent(timeout); if (transportEvent.EventType == EventType.Connected) { CifsServerPerConnection connection = new CifsServerPerConnection(); connection.Identity = transportEvent.EndPoint; this.context.AddConnection(connection); return connection; } else if (transportEvent.EventType == EventType.Exception) { throw transportEvent.EventObject as Exception; } else { throw new InvalidCastException("Unknown object received in transport."); } }
public SmbTreeConnectResponsePacket CreateTreeConnectResponse( CifsServerPerConnection connection, SmbTreeConnectRequestPacket request) { SmbTreeConnectResponsePacket response = new SmbTreeConnectResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); SMB_COM_TREE_CONNECT_Response_SMB_Parameters smbParameters = response.SmbParameters; smbParameters.MaxBufferSize = (ushort)this.context.MaxBufferSize; smbParameters.TID = (ushort)connection.GenerateTID(); smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2); response.SmbParameters = smbParameters; return response; }
public SmbWriteResponsePacket CreateWriteResponse( CifsServerPerConnection connection, SmbWriteRequestPacket request) { SmbWriteResponsePacket response = new SmbWriteResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); SMB_COM_WRITE_Response_SMB_Parameters smbParameters = response.SmbParameters; smbParameters.CountOfBytesWritten = request.SmbParameters.CountOfBytesToWrite; smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2); response.SmbParameters = smbParameters; return response; }
/// <summary> /// disconnect the connection /// </summary> /// <param name="connection">the connection to disconnect</param> /// <exception cref="ArgumentNullException">the connection is null</exception> public virtual void Disconnect(CifsServerPerConnection connection) { if (connection == null) { throw new ArgumentException("The connection is null."); } this.transport.Disconnect(connection.Identity); this.context.RemoveConnection(connection.Identity); }
/// <summary> /// remove request and sequence if the response is the final response. /// </summary> /// <param name="connection">the connection on which to remove the request and sequence</param> /// <param name="response">the response for which to remove the request and sequence</param> protected virtual void RemoveRequestAndSequence(CifsServerPerConnection connection, SmbPacket response) { if (response is SmbWriteRawInterimResponsePacket || response is SmbNtTransactInterimResponsePacket || response is SmbTransactionInterimResponsePacket || response is SmbTransaction2InterimResponsePacket) { return; } connection.RemovePendingRequest(response.SmbHeader.Mid); connection.RemoveSequenceNumber(response); }
public SmbFindUniqueResponsePacket CreateFindUniqueResponse( CifsServerPerConnection connection, SmbFindUniqueRequestPacket request, SMB_Directory_Information[] directoryInformationData) { directoryInformationData = directoryInformationData ?? new SMB_Directory_Information[0]; SmbFindUniqueResponsePacket response = new SmbFindUniqueResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); SMB_COM_FIND_UNIQUE_Response_SMB_Parameters smbParameters = response.SmbParameters; smbParameters.Count = (ushort)directoryInformationData.Length; smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2); response.SmbParameters = smbParameters; ushort dataLength = 0; foreach (SMB_Directory_Information info in directoryInformationData) { dataLength += (ushort)TypeMarshal.GetBlockMemorySize(info); } SMB_COM_FIND_UNIQUE_Response_SMB_Data smbData = response.SmbData; smbData.BufferFormat = 0x05; smbData.DirectoryInformationData = directoryInformationData; smbData.DataLength = dataLength; smbData.ByteCount = (ushort)(dataLength + 0x03); response.SmbData = smbData; return response; }
/// <summary> /// Send bytes to specific connected client. /// Sdk won't update context because it doesn't know what message will be sent. /// please set IsContextUpdateEnabled false, and update context manually. /// </summary> /// <param name="bytes">the bytes to send to client</param> /// <param name="connection">the connection identified client</param> /// <exception cref="ArgumentNullException">the connection is null</exception> public virtual void SendBytes(byte[] bytes, CifsServerPerConnection connection) { if (connection == null) { throw new ArgumentNullException("connection"); } this.transport.SendBytes(connection.Identity, bytes); }
/// <summary> /// Add a connection into ConnectionTable /// </summary> /// <param name="connection">The connection to be added or updated.</param> /// <exception cref="ArgumentNullException">The connection is null</exception> /// <exception cref="ArgumentException">The connection already exists</exception> public void AddConnection(CifsServerPerConnection connection) { if (connection == null) { throw new ArgumentException("The connection is null."); } lock (this.globalTables) { this.globalTables.ConnectionTable.Add(connection.Identity, connection); } }
/// <summary> /// Update the context of cifs server /// </summary> /// <param name="connection">The connection between client and server.</param> /// <param name="packet">The sent or received packet in stack transport.</param> public virtual void UpdateRoleContext(CifsServerPerConnection connection, SmbPacket packet) { if (connection == null || packet == null) { return; } if (packet is SmbReadRawResponsePacket) { if (connection.PendingRequestTable.Count != 1) { return; } SmbPacket request = connection.PendingRequestTable[0] as SmbPacket; this.UpdateResponseRoleContext(connection, request, packet); connection.RemovePendingRequest(request.SmbHeader.Mid); connection.RemoveSequenceNumber(packet); return; } else { switch(packet.PacketType) { case SmbPacketType.BatchedRequest: case SmbPacketType.SingleRequest: if (connection.IsSigningActive) { packet.IsSignatureCorrect = CifsMessageUtils.VerifySignature(packet, connection.SigningSessionKey, connection.ServerNextReceiveSequenceNumber, connection.SigningChallengeResponse); } this.UpdateRequestRoleConext(connection, packet); break; case SmbPacketType.BatchedResponse: case SmbPacketType.SingleResponse: SmbPacket request = connection.GetPendingRequest(packet.SmbHeader.Mid); this.UpdateResponseRoleContext(connection, request, packet); this.RemoveRequestAndSequence(connection, packet); break; default: break; } } }
public SmbFindClose2ResponsePacket CreateFindClose2Response( CifsServerPerConnection connection, SmbFindClose2RequestPacket request) { SmbFindClose2ResponsePacket response = new SmbFindClose2ResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); return response; }
public SmbWriteRawInterimResponsePacket CreateWriteRawInterimResponse( CifsServerPerConnection connection, SmbWriteRawRequestPacket request, ushort available) { SmbWriteRawInterimResponsePacket response = new SmbWriteRawInterimResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); SMB_COM_WRITE_RAW_InterimResponse_SMB_Parameters smbParameters = response.SmbParameters; smbParameters.Available = available; smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2); response.SmbParameters = smbParameters; return response; }
public SmbFindCloseResponsePacket CreateFindCloseResponse( CifsServerPerConnection connection, SmbFindCloseRequestPacket request) { SmbFindCloseResponsePacket response = new SmbFindCloseResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); SMB_COM_FIND_CLOSE_Response_SMB_Parameters smbParameters = response.SmbParameters; smbParameters.Count = 0x00; smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2); response.SmbParameters = smbParameters; SMB_COM_FIND_CLOSE_Response_SMB_Data smbData = response.SmbData; smbData.BufferFormat = 0x05; smbData.DataLength = 0x0000; smbData.ByteCount = 0x0003; response.SmbData = smbData; return response; }
public SmbTransWaitNmpipeSuccessResponsePacket CreateTransWaitNmpipeSuccessResponse( CifsServerPerConnection connection, SmbTransWaitNmpipeRequestPacket request) { SmbTransWaitNmpipeSuccessResponsePacket response = new SmbTransWaitNmpipeSuccessResponsePacket(); response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request); response.UpdateCountAndOffset(); return response; }