private void ProcessPacket(SessionPacket packet, ConnectionState state) { if (packet is SessionKeepAlivePacket && m_transport == SMBTransportType.NetBiosOverTCP) { // [RFC 1001] NetBIOS session keep alives do not require a response from the NetBIOS peer } else if (packet is PositiveSessionResponsePacket && m_transport == SMBTransportType.NetBiosOverTCP) { } else if (packet is NegativeSessionResponsePacket && m_transport == SMBTransportType.NetBiosOverTCP) { m_clientSocket.Dispose(); m_isConnected = false; } else if (packet is SessionMessagePacket) { SMB2Command command; try { command = SMB2Command.ReadResponse(packet.Trailer, 0); } catch (Exception ex) { Log("Invalid SMB2 response: " + ex.Message); m_clientSocket.Dispose(); m_isConnected = false; return; } // [MS-SMB2] 3.2.5.1.2 - If the MessageId is 0xFFFFFFFFFFFFFFFF, this is not a reply to a previous request, // and the client MUST NOT attempt to locate the request, but instead process it as follows: // If the command field in the SMB2 header is SMB2 OPLOCK_BREAK, it MUST be processed as specified in 3.2.5.19. // Otherwise, the response MUST be discarded as invalid. if (command.Header.MessageID != 0xFFFFFFFFFFFFFFFF || command.Header.Command == SMB2CommandName.OplockBreak) { lock (m_incomingQueueLock) { m_credits += command.Header.Credits; Log("[ProcessPacket] CreditsResponse:" + m_credits); m_incomingQueue.Add(command); m_incomingQueueEventHandle.Set(); } } } }
private void ProcessPacket(SessionPacket packet, ConnectionState state) { if (packet is SessionMessagePacket) { SMB2Command command; try { command = SMB2Command.ReadResponse(packet.Trailer, 0); } catch (Exception ex) { Log("Invalid SMB2 response: " + ex.Message); state.ClientSocket.Close(); m_isConnected = false; return; } m_availableCredits += command.Header.Credits; if (m_transport == SMBTransportType.DirectTCPTransport && command is NegotiateResponse) { NegotiateResponse negotiateResponse = (NegotiateResponse)command; if ((negotiateResponse.Capabilities & Capabilities.LargeMTU) > 0) { // [MS-SMB2] 3.2.5.1 Receiving Any Message - If the message size received exceeds Connection.MaxTransactSize, the client MUST disconnect the connection. // Note: Windows clients do not enforce the MaxTransactSize value, we add 256 bytes. int maxPacketSize = SessionPacket.HeaderLength + (int)Math.Min(negotiateResponse.MaxTransactSize, ClientMaxTransactSize) + 256; if (maxPacketSize > state.ReceiveBuffer.Buffer.Length) { state.ReceiveBuffer.IncreaseBufferSize(maxPacketSize); } } } // [MS-SMB2] 3.2.5.1.2 - If the MessageId is 0xFFFFFFFFFFFFFFFF, this is not a reply to a previous request, // and the client MUST NOT attempt to locate the request, but instead process it as follows: // If the command field in the SMB2 header is SMB2 OPLOCK_BREAK, it MUST be processed as specified in 3.2.5.19. // Otherwise, the response MUST be discarded as invalid. if (command.Header.MessageID != 0xFFFFFFFFFFFFFFFF || command.Header.Command == SMB2CommandName.OplockBreak) { lock (m_incomingQueueLock) { m_incomingQueue.Add(command); m_incomingQueueEventHandle.Set(); } } } else if ((packet is PositiveSessionResponsePacket || packet is NegativeSessionResponsePacket) && m_transport == SMBTransportType.NetBiosOverTCP) { m_sessionResponsePacket = packet; m_sessionResponseEventHandle.Set(); } else if (packet is SessionKeepAlivePacket && m_transport == SMBTransportType.NetBiosOverTCP) { // [RFC 1001] NetBIOS session keep alives do not require a response from the NetBIOS peer } else { Log("Inappropriate NetBIOS session packet"); state.ClientSocket.Close(); } }