Merge remote-tracking branch 'TalAloni/master' into feat/LAN-13040

This commit is contained in:
Joran Van Craenenbroeck 2022-04-25 11:53:56 +02:00
commit c352e85065
22 changed files with 164 additions and 66 deletions

View file

@ -11,6 +11,7 @@ if (isConnected)
List<string> shares = client.ListShares(out status);
client.Logoff();
}
client.Disconnect();
}
```
@ -93,7 +94,7 @@ status = fileStore.Disconnect();
Create a file and write to it:
==============================
```
ISMBFileStore fileStore = client.TreeConnect("Shared", out status);
ISMBFileStore fileStore = client.TreeConnect("Shared", out status);
string filePath = "NewFile.txt";
if (fileStore is SMB1FileStore)
{
@ -116,10 +117,52 @@ if (status == NTStatus.STATUS_SUCCESS)
status = fileStore.Disconnect();
```
Write a large file:
===================
```
ISMBFileStore fileStore = client.TreeConnect("Shared", out status);
if (status != NTStatus.STATUS_SUCCESS)
{
throw new Exception("Failed to connect to share");
}
string localFilePath = @"C:\Image.jpg";
string remoteFilePath = "NewFile.jpg";
if (fileStore is SMB1FileStore)
{
remoteFilePath = @"\\" + remoteFilePath;
}
FileStream localFileStream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read);
object fileHandle;
FileStatus fileStatus;
status = fileStore.CreateFile(out fileHandle, out fileStatus, remoteFilePath, AccessMask.GENERIC_WRITE | AccessMask.SYNCHRONIZE, FileAttributes.Normal, ShareAccess.None, CreateDisposition.FILE_CREATE, CreateOptions.FILE_NON_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_ALERT, null);
if (status == NTStatus.STATUS_SUCCESS)
{
int writeOffset = 0;
while (localFileStream.Position < localFileStream.Length)
{
byte[] buffer = new byte[(int)client.MaxWriteSize];
int bytesRead = localFileStream.Read(buffer, 0, buffer.Length);
if (bytesRead < (int)client.MaxWriteSize)
{
Array.Resize<byte>(ref buffer, bytesRead);
}
int numberOfBytesWritten;
status = fileStore.WriteFile(out numberOfBytesWritten, fileHandle, writeOffset, buffer);
if (status != NTStatus.STATUS_SUCCESS)
{
throw new Exception("Failed to write to file");
}
writeOffset += bytesRead;
}
status = fileStore.CloseFile(fileHandle);
}
status = fileStore.Disconnect();
```
Delete file:
============
```
ISMBFileStore fileStore = client.TreeConnect("Shared", out status);
ISMBFileStore fileStore = client.TreeConnect("Shared", out status);
string filePath = "DeleteMe.txt";
if (fileStore is SMB1FileStore)
{

View file

@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.4.6.0")]
[assembly: AssemblyFileVersion("1.4.6.0")]
[assembly: AssemblyVersion("1.4.8.0")]
[assembly: AssemblyFileVersion("1.4.8.0")]

View file

@ -4,7 +4,7 @@
<TargetFrameworks>net20;net40;netstandard2.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyName>SMBLibrary.Adapters</AssemblyName>
<Version>1.4.6</Version>
<Version>1.4.8</Version>
<NoWarn>1573;1591</NoWarn>
<RootNamespace>SMBLibrary.Adapters</RootNamespace>
<Authors>Tal Aloni</Authors>

View file

@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.4.6.0")]
[assembly: AssemblyFileVersion("1.4.6.0")]
[assembly: AssemblyVersion("1.4.8.0")]
[assembly: AssemblyFileVersion("1.4.8.0")]

View file

@ -4,7 +4,7 @@
<TargetFrameworks>net20;net40;netstandard2.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyName>SMBLibrary.Win32</AssemblyName>
<Version>1.4.6</Version>
<Version>1.4.8</Version>
<NoWarn>1573;1591</NoWarn>
<RootNamespace>SMBLibrary.Win32</RootNamespace>
<Authors>Tal Aloni</Authors>

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
/* Copyright (C) 2014-2021 Tal Aloni <tal.aloni.il@gmail.com>. 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,
@ -15,6 +15,15 @@ namespace SMBLibrary.Client
public class ServerServiceHelper
{
public static List<string> ListShares(INTFileStore namedPipeShare, ShareType? shareType, out NTStatus status)
{
return ListShares(namedPipeShare, "*", shareType, out status);
}
/// <param name="serverName">
/// When a Windows Server host is using Failover Cluster and Cluster Shared Volumes, each of those CSV file shares is associated
/// with a specific host name associated with the cluster and is not accessible using the node IP address or node host name.
/// </param>
public static List<string> ListShares(INTFileStore namedPipeShare, string serverName, ShareType? shareType, out NTStatus status)
{
object pipeHandle;
int maxTransmitFragmentSize;
@ -29,7 +38,7 @@ namespace SMBLibrary.Client
shareEnumRequest.InfoStruct.Level = 1;
shareEnumRequest.InfoStruct.Info = new ShareInfo1Container();
shareEnumRequest.PreferedMaximumLength = UInt32.MaxValue;
shareEnumRequest.ServerName = "*";
shareEnumRequest.ServerName = @"\\" + serverName;
RequestPDU requestPDU = new RequestPDU();
requestPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment;
requestPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII;

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
/* Copyright (C) 2017-2021 Tal Aloni <tal.aloni.il@gmail.com>. 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,

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
/* Copyright (C) 2014-2021 Tal Aloni <tal.aloni.il@gmail.com>. 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,
@ -29,6 +29,7 @@ namespace SMBLibrary.Client
private static readonly ushort ClientMaxBufferSize = 65535; // Valid range: 512 - 65535
private static readonly ushort ClientMaxMpxCount = 1;
private static readonly int ResponseTimeoutInMilliseconds = 5000;
private SMBTransportType m_transport;
private bool m_isConnected;
@ -81,8 +82,7 @@ namespace SMBLibrary.Client
if (!m_isConnected)
{
m_forceExtendedSecurity = forceExtendedSecurity;
int port;
port = transport == SMBTransportType.NetBiosOverTCP ? NetBiosOverTCPPort : DirectTCPPort;
var port = transport == SMBTransportType.NetBiosOverTCP ? NetBiosOverTCPPort : DirectTCPPort;
if (!await ConnectSocketAsync(serverAddress, port))
{
@ -749,10 +749,9 @@ namespace SMBLibrary.Client
internal SMB1Message WaitForMessage(CommandName commandName)
{
const int TimeOut = 5000;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < TimeOut)
while (stopwatch.ElapsedMilliseconds < ResponseTimeoutInMilliseconds)
{
lock (m_incomingQueueLock)
{

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
/* Copyright (C) 2017-2021 Tal Aloni <tal.aloni.il@gmail.com>. 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,
@ -9,12 +9,9 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using SMBLibrary.Authentication.NTLM;
using SMBLibrary.NetBios;
using SMBLibrary.Services;
using SMBLibrary.SMB2;
using Utilities;
@ -28,8 +25,10 @@ namespace SMBLibrary.Client
public static readonly uint ClientMaxTransactSize = 1048576;
public static readonly uint ClientMaxReadSize = 1048576;
public static readonly uint ClientMaxWriteSize = 1048576;
private static readonly ushort DesiredCredits = 16;
private static readonly ushort DesiredCredits = 16;
public static readonly int ResponseTimeoutInMilliseconds = 5000;
private string m_serverName;
private SMBTransportType m_transport;
private bool m_isConnected;
private bool m_isLoggedIn;
@ -63,11 +62,15 @@ namespace SMBLibrary.Client
public bool Connect(IPAddress serverAddress, SMBTransportType transport, string serverName = null)
{
if (m_serverName == null)
{
m_serverName = serverAddress.ToString();
}
m_transport = transport;
if (!m_isConnected)
{
int port;
port = transport == SMBTransportType.NetBiosOverTCP ? NetBiosOverTCPPort : DirectTCPPort;
var port = transport == SMBTransportType.NetBiosOverTCP ? NetBiosOverTCPPort : DirectTCPPort;
if (!ConnectSocket(serverAddress, port))
{
@ -294,7 +297,7 @@ namespace SMBLibrary.Client
request.Dialects.Add(SMB2Dialect.SMB300);
TrySendCommand(request);
NegotiateResponse response = WaitForCommand(SMB2CommandName.Negotiate) as NegotiateResponse;
NegotiateResponse response = WaitForCommand(request.MessageID) as NegotiateResponse;
if (response != null && response.Header.Status == NTStatus.STATUS_SUCCESS)
{
m_dialect = response.DialectRevision;
@ -327,7 +330,7 @@ namespace SMBLibrary.Client
SecurityBuffer = negotiateMessage
};
TrySendCommand(request);
var response = WaitForCommand(SMB2CommandName.SessionSetup);
var response = WaitForCommand(request.MessageID);
if (response != null
&& response.Header.Status == NTStatus.STATUS_MORE_PROCESSING_REQUIRED
&& response is SessionSetupResponse ssr)
@ -359,7 +362,7 @@ namespace SMBLibrary.Client
request.SecurityMode = SecurityMode.SigningEnabled;
request.SecurityBuffer = negotiateMessage;
TrySendCommand(request);
SMB2Command response = WaitForCommand(SMB2CommandName.SessionSetup);
SMB2Command response = WaitForCommand(request.MessageID);
if (response != null)
{
if (response.Header.Status == NTStatus.STATUS_MORE_PROCESSING_REQUIRED && response is SessionSetupResponse)
@ -375,7 +378,7 @@ namespace SMBLibrary.Client
request.SecurityMode = SecurityMode.SigningEnabled;
request.SecurityBuffer = authenticateMessage;
TrySendCommand(request);
response = WaitForCommand(SMB2CommandName.SessionSetup);
response = WaitForCommand(request.MessageID);
if (response != null)
{
m_isLoggedIn = (response.Header.Status == NTStatus.STATUS_SUCCESS);
@ -410,7 +413,7 @@ namespace SMBLibrary.Client
LogoffRequest request = new LogoffRequest();
TrySendCommand(request);
SMB2Command response = WaitForCommand(SMB2CommandName.Logoff);
SMB2Command response = WaitForCommand(request.MessageID);
if (response != null)
{
m_isLoggedIn = (response.Header.Status != NTStatus.STATUS_SUCCESS);
@ -432,7 +435,7 @@ namespace SMBLibrary.Client
return null;
}
List<string> shares = ServerServiceHelper.ListShares(namedPipeShare, SMBLibrary.Services.ShareType.DiskDrive, out status);
List<string> shares = ServerServiceHelper.ListShares(namedPipeShare, m_serverName, SMBLibrary.Services.ShareType.DiskDrive, out status);
namedPipeShare.Disconnect();
return shares;
}
@ -444,12 +447,11 @@ namespace SMBLibrary.Client
throw new InvalidOperationException("A login session must be successfully established before connecting to a share");
}
IPAddress serverIPAddress = ((IPEndPoint)m_clientSocket.RemoteEndPoint).Address;
string sharePath = String.Format(@"\\{0}\{1}", serverIPAddress.ToString(), shareName);
string sharePath = String.Format(@"\\{0}\{1}", m_serverName, shareName);
TreeConnectRequest request = new TreeConnectRequest();
request.Path = sharePath;
TrySendCommand(request);
SMB2Command response = WaitForCommand(SMB2CommandName.TreeConnect);
SMB2Command response = WaitForCommand(request.MessageID);
if (response != null)
{
status = response.Header.Status;
@ -621,12 +623,11 @@ namespace SMBLibrary.Client
}
}
internal SMB2Command WaitForCommand(SMB2CommandName commandName)
internal SMB2Command WaitForCommand(ulong messageID)
{
const int TimeOut = 5000;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < TimeOut)
while (stopwatch.ElapsedMilliseconds < ResponseTimeoutInMilliseconds)
{
lock (m_incomingQueueLock)
{
@ -634,9 +635,14 @@ namespace SMBLibrary.Client
{
SMB2Command command = m_incomingQueue[index];
if (command.CommandName == commandName)
if (command.Header.MessageID == messageID)
{
m_incomingQueue.RemoveAt(index);
if (command.Header.IsAsync && command.Header.Status == NTStatus.STATUS_PENDING)
{
index--;
continue;
}
return command;
}
}

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
/* Copyright (C) 2017-2021 Tal Aloni <tal.aloni.il@gmail.com>. 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,
@ -40,7 +40,7 @@ namespace SMBLibrary.Client
request.ImpersonationLevel = ImpersonationLevel.Impersonation;
TrySendCommand(request);
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.Create);
SMB2Command response = m_client.WaitForCommand(request.MessageID);
if (response != null)
{
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is CreateResponse)
@ -60,7 +60,7 @@ namespace SMBLibrary.Client
CloseRequest request = new CloseRequest();
request.FileId = (FileID)handle;
TrySendCommand(request);
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.Close);
SMB2Command response = m_client.WaitForCommand(request.MessageID);
if (response != null)
{
return response.Header.Status;
@ -79,7 +79,7 @@ namespace SMBLibrary.Client
request.ReadLength = (uint)maxCount;
TrySendCommand(request);
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.Read);
SMB2Command response = m_client.WaitForCommand(request.MessageID);
if (response != null)
{
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is ReadResponse)
@ -102,7 +102,7 @@ namespace SMBLibrary.Client
request.Data = data;
TrySendCommand(request);
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.Write);
SMB2Command response = m_client.WaitForCommand(request.MessageID);
if (response != null)
{
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is WriteResponse)
@ -117,7 +117,20 @@ namespace SMBLibrary.Client
public NTStatus FlushFileBuffers(object handle)
{
throw new NotImplementedException();
FlushRequest request = new FlushRequest();
request.FileId = (FileID) handle;
TrySendCommand(request);
SMB2Command response = m_client.WaitForCommand(request.MessageID);
if (response != null)
{
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is FlushResponse)
{
return response.Header.Status;
}
}
return NTStatus.STATUS_INVALID_SMB;
}
public NTStatus LockFile(object handle, long byteOffset, long length, bool exclusiveLock)
@ -142,7 +155,7 @@ namespace SMBLibrary.Client
request.FileName = fileName;
TrySendCommand(request);
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.QueryDirectory);
SMB2Command response = m_client.WaitForCommand(request.MessageID);
if (response != null)
{
while (response.Header.Status == NTStatus.STATUS_SUCCESS && response is QueryDirectoryResponse)
@ -151,7 +164,7 @@ namespace SMBLibrary.Client
result.AddRange(page);
request.Reopen = false;
TrySendCommand(request);
response = m_client.WaitForCommand(SMB2CommandName.QueryDirectory);
response = m_client.WaitForCommand(request.MessageID);
}
return response.Header.Status;
}
@ -169,7 +182,7 @@ namespace SMBLibrary.Client
request.FileId = (FileID)handle;
TrySendCommand(request);
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.QueryInfo);
SMB2Command response = m_client.WaitForCommand(request.MessageID);
if (response != null)
{
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is QueryInfoResponse)
@ -191,7 +204,7 @@ namespace SMBLibrary.Client
request.SetFileInformation(information);
TrySendCommand(request);
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.SetInfo);
SMB2Command response = m_client.WaitForCommand(request.MessageID);
if (response != null)
{
return response.Header.Status;
@ -226,7 +239,7 @@ namespace SMBLibrary.Client
request.FileId = (FileID)handle;
TrySendCommand(request);
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.QueryInfo);
SMB2Command response = m_client.WaitForCommand(request.MessageID);
if (response != null)
{
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is QueryInfoResponse)
@ -254,7 +267,7 @@ namespace SMBLibrary.Client
request.FileId = (FileID)handle;
TrySendCommand(request);
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.QueryInfo);
SMB2Command response = m_client.WaitForCommand(request.MessageID);
if (response != null)
{
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is QueryInfoResponse)
@ -293,7 +306,7 @@ namespace SMBLibrary.Client
request.Input = input;
request.MaxOutputResponse = (uint)maxOutputLength;
TrySendCommand(request);
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.IOCtl);
SMB2Command response = m_client.WaitForCommand(request.MessageID);
if (response != null)
{
if ((response.Header.Status == NTStatus.STATUS_SUCCESS || response.Header.Status == NTStatus.STATUS_BUFFER_OVERFLOW) && response is IOCtlResponse)
@ -310,7 +323,7 @@ namespace SMBLibrary.Client
{
TreeDisconnectRequest request = new TreeDisconnectRequest();
TrySendCommand(request);
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.TreeDisconnect);
SMB2Command response = m_client.WaitForCommand(request.MessageID);
if (response != null)
{
return response.Header.Status;

View file

@ -37,6 +37,7 @@ namespace SMBLibrary
STATUS_LOCK_NOT_GRANTED = 0xC0000055,
STATUS_DELETE_PENDING = 0xC0000056,
STATUS_PRIVILEGE_NOT_HELD = 0xC0000061,
STATUS_WRONG_PASSWORD = 0xC000006A,
STATUS_LOGON_FAILURE = 0xC000006D, // Authentication failure.
STATUS_ACCOUNT_RESTRICTION = 0xC000006E, // The user has an empty password, which is not allowed
STATUS_INVALID_LOGON_HOURS = 0xC000006F,
@ -64,9 +65,10 @@ namespace SMBLibrary
STATUS_FS_DRIVER_REQUIRED = 0xC000019C,
STATUS_USER_SESSION_DELETED = 0xC0000203,
STATUS_INSUFF_SERVER_RESOURCES = 0xC0000205,
STATUS_PASSWORD_MUST_CHANGE = 0xC0000224,
STATUS_NOT_FOUND = 0xC0000225,
STATUS_ACCOUNT_LOCKED_OUT = 0xC0000234,
STATUS_PASSWORD_MUST_CHANGE = 0xC0000244,
STATUS_PATH_NOT_COVERED = 0xC0000257,
STATUS_NOT_A_REPARSE_POINT = 0xC0000275,
STATUS_INVALID_SMB = 0x00010002, // SMB1/CIFS: A corrupt or invalid SMB request was received

View file

@ -1,4 +1,4 @@
/// Adapted from https://referencesource.microsoft.com/#system.web/Security/Cryptography/SP800_108.cs
// Adapted from https://referencesource.microsoft.com/#system.web/Security/Cryptography/SP800_108.cs
using System;
using System.Security.Cryptography;
using Utilities;

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
/* Copyright (C) 2017-2021 Tal Aloni <tal.aloni.il@gmail.com>. 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,
@ -88,7 +88,7 @@ namespace SMBLibrary
case FileInformationClass.FileShortNameInformation:
throw new NotImplementedException();
default:
throw new UnsupportedInformationLevelException();
throw new UnsupportedInformationLevelException(String.Format("Unsupported information class: {0}", informationClass));
}
}
}

View file

@ -60,7 +60,7 @@ namespace SMBLibrary.NetBios
return EncodeName(netBiosName, scopeID);
}
/// <param name="name">NetBIOS name</param>
/// <param name="netBiosName">NetBIOS name</param>
/// <param name="scopeID">dot-separated labels, formatted per DNS naming rules</param>
public static byte[] EncodeName(string netBiosName, string scopeID)
{
@ -75,7 +75,7 @@ namespace SMBLibrary.NetBios
// into two nibbles and then adding the value of 'A' (0x41).
// Thus, the '&' character (0x26) would be encoded as "CG".
// NetBIOS names are usually padded with spaces before being encoded.
/// <param name="name">NetBIOS name</param>
/// <param name="netBiosName">NetBIOS name</param>
/// <param name="scopeID">dot-separated labels, formatted per DNS naming rules</param>
public static string FirstLevelEncoding(string netBiosName, string scopeID)
{

View file

@ -31,6 +31,6 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.4.6.0")]
[assembly: AssemblyFileVersion("1.4.6.0")]
[assembly: AssemblyVersion("1.4.8.0")]
[assembly: AssemblyFileVersion("1.4.8.0")]
[assembly: InternalsVisibleTo("SMBLibrary.Tests")]

View file

@ -459,3 +459,15 @@ Revision History:
NTLM: Bugfix: IndependentNTLMAuthenticationProvider login failed to to modification of message byte arrays.
1.4.6 - SMB2Client: Fixed InvalidCastException on failed login to SMB 3.0 server.
1.4.7 - SMBServer: Added private Start overload allowing to specify the listening port.
Client: Added private Connect overload allowing to specify the server port.
SMB2Client: Correctly handle async responses.
SMB2Client: WaitForCommand: Compare MessageID instead of CommandName.
Client: SMB2FileStore: Implement Flush.
Client: Added support for accessing Cluster Shared Volumes file shares.
SMB2Command: Add MessageID property.
NTStatus: Added STATUS_WRONG_PASSWORD.
NTStatus: Correct STATUS_PASSWORD_MUST_CHANGE value.
1.4.8 - SMBServer - Start method bugfix.

View file

@ -12,7 +12,7 @@ namespace SMBLibrary.SMB1
{
/// <summary>
/// TRANS2_QUERY_FILE_INFORMATION Response
/// </summary
/// </summary>
public class Transaction2QueryFileInformationResponse : Transaction2Subcommand
{
public const int ParametersLength = 2;

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
/* Copyright (C) 2017-2021 Tal Aloni <tal.aloni.il@gmail.com>. 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,
@ -49,6 +49,14 @@ namespace SMBLibrary.SMB2
}
}
public ulong MessageID
{
get
{
return Header.MessageID;
}
}
public int Length
{
get
@ -127,7 +135,7 @@ namespace SMBLibrary.SMB2
return GetCommandChainBytes(commands, null, SMB2Dialect.SMB2xx);
}
/// <param name="sessionKey">
/// <param name="signingKey">
/// Message will be signed using this key if (not null and) SMB2_FLAGS_SIGNED is set.
/// </param>
/// <param name="dialect">

View file

@ -6,6 +6,7 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyName>SMBLibrary</AssemblyName>
<Version>1.6.0</Version>
<Version>1.4.8</Version>
<NoWarn>1573;1591</NoWarn>
<RootNamespace>SMBLibrary</RootNamespace>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
/* Copyright (C) 2014-2021 Tal Aloni <tal.aloni.il@gmail.com>. 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,
@ -77,6 +77,12 @@ namespace SMBLibrary.Server
/// </param>
/// <exception cref="System.Net.Sockets.SocketException"></exception>
public void Start(IPAddress serverAddress, SMBTransportType transport, bool enableSMB1, bool enableSMB2, bool enableSMB3, TimeSpan? connectionInactivityTimeout)
{
int port = (transport == SMBTransportType.DirectTCPTransport ? DirectTCPPort : NetBiosOverTCPPort);
Start(serverAddress, transport, port, enableSMB1, enableSMB2, enableSMB3, connectionInactivityTimeout);
}
private void Start(IPAddress serverAddress, SMBTransportType transport, int port, bool enableSMB1, bool enableSMB2, bool enableSMB3, TimeSpan? connectionInactivityTimeout)
{
if (!m_listening)
{
@ -95,7 +101,6 @@ namespace SMBLibrary.Server
m_serverStartTime = DateTime.Now;
m_listenerSocket = new Socket(m_serverAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
int port = (m_transport == SMBTransportType.DirectTCPTransport ? DirectTCPPort : NetBiosOverTCPPort);
m_listenerSocket.Bind(new IPEndPoint(m_serverAddress, port));
m_listenerSocket.Listen((int)SocketOptionName.MaxConnections);
m_listenerSocket.BeginAccept(ConnectRequestCallback, m_listenerSocket);

View file

@ -39,7 +39,7 @@ namespace SMBLibrary.Server
return result;
}
/// <param name="relativePath">e.g. \Shared</param>
/// <param name="shareName">e.g. \Shared</param>
public FileSystemShare GetShareFromName(string shareName)
{
int index = IndexOf(shareName, StringComparison.OrdinalIgnoreCase);

View file

@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.4.6.0")]
[assembly: AssemblyFileVersion("1.4.6.0")]
[assembly: AssemblyVersion("1.4.8.0")]
[assembly: AssemblyFileVersion("1.4.8.0")]