diff --git a/SMBLibrary/Client/SMB1Client.cs b/SMBLibrary/Client/SMB1Client.cs index 3ad47d4..412e414 100644 --- a/SMBLibrary/Client/SMB1Client.cs +++ b/SMBLibrary/Client/SMB1Client.cs @@ -34,6 +34,7 @@ namespace SMBLibrary.Client private bool m_isConnected; private bool m_isLoggedIn; private Socket m_clientSocket; + private ConnectionState m_connectionState; private bool m_forceExtendedSecurity; private bool m_unicode; private bool m_largeFiles; @@ -154,9 +155,9 @@ namespace SMBLibrary.Client return false; } - ConnectionState state = new ConnectionState(m_clientSocket); - NBTConnectionReceiveBuffer buffer = state.ReceiveBuffer; - m_clientSocket.BeginReceive(buffer.Buffer, buffer.WriteOffset, buffer.AvailableLength, SocketFlags.None, new AsyncCallback(OnClientSocketReceive), state); + m_connectionState = new ConnectionState(m_clientSocket); + NBTConnectionReceiveBuffer buffer = m_connectionState.ReceiveBuffer; + m_clientSocket.BeginReceive(buffer.Buffer, buffer.WriteOffset, buffer.AvailableLength, SocketFlags.None, new AsyncCallback(OnClientSocketReceive), m_connectionState); return true; } @@ -165,6 +166,7 @@ namespace SMBLibrary.Client if (m_isConnected) { m_clientSocket.Disconnect(false); + m_connectionState.ReceiveBuffer.Dispose(); m_isConnected = false; m_userID = 0; } @@ -418,6 +420,7 @@ namespace SMBLibrary.Client if (!clientSocket.Connected) { + state.ReceiveBuffer.Dispose(); return; } @@ -428,22 +431,26 @@ namespace SMBLibrary.Client } catch (ArgumentException) // The IAsyncResult object was not returned from the corresponding synchronous method on this class. { + state.ReceiveBuffer.Dispose(); return; } catch (ObjectDisposedException) { Log("[ReceiveCallback] EndReceive ObjectDisposedException"); + state.ReceiveBuffer.Dispose(); return; } catch (SocketException ex) { Log("[ReceiveCallback] EndReceive SocketException: " + ex.Message); + state.ReceiveBuffer.Dispose(); return; } if (numberOfBytesReceived == 0) { m_isConnected = false; + state.ReceiveBuffer.Dispose(); } else { @@ -458,11 +465,13 @@ namespace SMBLibrary.Client catch (ObjectDisposedException) { m_isConnected = false; + buffer.Dispose(); Log("[ReceiveCallback] BeginReceive ObjectDisposedException"); } catch (SocketException ex) { m_isConnected = false; + buffer.Dispose(); Log("[ReceiveCallback] BeginReceive SocketException: " + ex.Message); } } @@ -481,6 +490,7 @@ namespace SMBLibrary.Client catch (Exception) { state.ClientSocket.Close(); + state.ReceiveBuffer.Dispose(); break; } @@ -504,6 +514,7 @@ namespace SMBLibrary.Client { Log("Invalid SMB1 message: " + ex.Message); state.ClientSocket.Close(); + state.ReceiveBuffer.Dispose(); m_isConnected = false; return; } @@ -534,6 +545,7 @@ namespace SMBLibrary.Client { Log("Inappropriate NetBIOS session packet"); state.ClientSocket.Close(); + state.ReceiveBuffer.Dispose(); } } diff --git a/SMBLibrary/Client/SMB2Client.cs b/SMBLibrary/Client/SMB2Client.cs index d5ecaab..f7544e9 100644 --- a/SMBLibrary/Client/SMB2Client.cs +++ b/SMBLibrary/Client/SMB2Client.cs @@ -33,6 +33,7 @@ namespace SMBLibrary.Client private bool m_isConnected; private bool m_isLoggedIn; private Socket m_clientSocket; + private ConnectionState m_connectionState; private int m_responseTimeoutInMilliseconds; private object m_incomingQueueLock = new object(); @@ -169,9 +170,9 @@ namespace SMBLibrary.Client return false; } - ConnectionState state = new ConnectionState(m_clientSocket); - NBTConnectionReceiveBuffer buffer = state.ReceiveBuffer; - m_clientSocket.BeginReceive(buffer.Buffer, buffer.WriteOffset, buffer.AvailableLength, SocketFlags.None, new AsyncCallback(OnClientSocketReceive), state); + m_connectionState = new ConnectionState(m_clientSocket); + NBTConnectionReceiveBuffer buffer = m_connectionState.ReceiveBuffer; + m_clientSocket.BeginReceive(buffer.Buffer, buffer.WriteOffset, buffer.AvailableLength, SocketFlags.None, new AsyncCallback(OnClientSocketReceive), m_connectionState); return true; } @@ -180,6 +181,7 @@ namespace SMBLibrary.Client if (m_isConnected) { m_clientSocket.Disconnect(false); + m_connectionState.ReceiveBuffer.Dispose(); m_isConnected = false; m_messageID = 0; m_sessionID = 0; @@ -356,6 +358,7 @@ namespace SMBLibrary.Client if (!clientSocket.Connected) { + state.ReceiveBuffer.Dispose(); return; } @@ -366,22 +369,26 @@ namespace SMBLibrary.Client } catch (ArgumentException) // The IAsyncResult object was not returned from the corresponding synchronous method on this class. { + state.ReceiveBuffer.Dispose(); return; } catch (ObjectDisposedException) { Log("[ReceiveCallback] EndReceive ObjectDisposedException"); + state.ReceiveBuffer.Dispose(); return; } catch (SocketException ex) { Log("[ReceiveCallback] EndReceive SocketException: " + ex.Message); + state.ReceiveBuffer.Dispose(); return; } if (numberOfBytesReceived == 0) { m_isConnected = false; + state.ReceiveBuffer.Dispose(); } else { @@ -397,11 +404,13 @@ namespace SMBLibrary.Client { m_isConnected = false; Log("[ReceiveCallback] BeginReceive ObjectDisposedException"); + buffer.Dispose(); } catch (SocketException ex) { m_isConnected = false; Log("[ReceiveCallback] BeginReceive SocketException: " + ex.Message); + buffer.Dispose(); } } } @@ -419,6 +428,7 @@ namespace SMBLibrary.Client catch (Exception) { state.ClientSocket.Close(); + state.ReceiveBuffer.Dispose(); break; } @@ -455,6 +465,7 @@ namespace SMBLibrary.Client Log("Invalid SMB2 response: " + ex.Message); state.ClientSocket.Close(); m_isConnected = false; + state.ReceiveBuffer.Dispose(); return; } @@ -501,6 +512,7 @@ namespace SMBLibrary.Client { Log("Inappropriate NetBIOS session packet"); state.ClientSocket.Close(); + state.ReceiveBuffer.Dispose(); } } diff --git a/SMBLibrary/NetBios/NBTConnectionReceiveBuffer.cs b/SMBLibrary/NetBios/NBTConnectionReceiveBuffer.cs index 47148d1..7f3a0a1 100644 --- a/SMBLibrary/NetBios/NBTConnectionReceiveBuffer.cs +++ b/SMBLibrary/NetBios/NBTConnectionReceiveBuffer.cs @@ -1,17 +1,16 @@ -/* Copyright (C) 2014-2020 Tal Aloni . All rights reserved. +/* Copyright (C) 2014-2023 Tal Aloni . All rights reserved. * * You can redistribute this program and/or modify it under the terms of * the GNU Lesser Public License as published by the Free Software Foundation, * either version 3 of the License, or (at your option) any later version. */ using System; -using System.Collections.Generic; using System.IO; using Utilities; namespace SMBLibrary.NetBios { - public class NBTConnectionReceiveBuffer + public class NBTConnectionReceiveBuffer : IDisposable { private byte[] m_buffer; private int m_readOffset = 0; @@ -110,6 +109,11 @@ namespace SMBLibrary.NetBios } } + public void Dispose() + { + m_buffer = null; + } + public byte[] Buffer { get diff --git a/SMBLibrary/Server/ConnectionManager.cs b/SMBLibrary/Server/ConnectionManager.cs index 383308a..acafe36 100644 --- a/SMBLibrary/Server/ConnectionManager.cs +++ b/SMBLibrary/Server/ConnectionManager.cs @@ -42,6 +42,7 @@ namespace SMBLibrary.Server connection.SendQueue.Stop(); SocketUtils.ReleaseSocket(connection.ClientSocket); connection.CloseSessions(); + connection.ReceiveBuffer.Dispose(); RemoveConnection(connection); } diff --git a/SMBLibrary/Server/SMBServer.cs b/SMBLibrary/Server/SMBServer.cs index 817fbd6..9543967 100644 --- a/SMBLibrary/Server/SMBServer.cs +++ b/SMBLibrary/Server/SMBServer.cs @@ -288,6 +288,7 @@ namespace SMBLibrary.Server catch (Exception ex) { state.ClientSocket.Close(); + state.ReceiveBuffer.Dispose(); state.LogToServer(Severity.Warning, "Rejected Invalid NetBIOS session packet: {0}", ex.Message); break; }