SMB1Client: Additional client functions implemented

This commit is contained in:
Tal Aloni 2017-09-05 22:28:01 +03:00
parent 515a02c09f
commit 928bb59c90
3 changed files with 227 additions and 2 deletions

View file

@ -195,7 +195,7 @@ namespace SMBLibrary.Client
SessionSetupAndXRequestExtended request = new SessionSetupAndXRequestExtended();
request.MaxBufferSize = MaxBufferSize;
request.MaxMpxCount = MaxMpxCount;
request.Capabilities = Capabilities.Unicode | Capabilities.NTStatusCode;
request.Capabilities = Capabilities.Unicode | Capabilities.NTStatusCode | Capabilities.LargeRead | Capabilities.LargeWrite;
request.SecurityBlob = NTLMAuthenticationHelper.GetNegotiateMessage(m_securityBlob, domainName, authenticationMethod);
TrySendMessage(request);
@ -209,7 +209,7 @@ namespace SMBLibrary.Client
request = new SessionSetupAndXRequestExtended();
request.MaxBufferSize = MaxBufferSize;
request.MaxMpxCount = MaxMpxCount;
request.Capabilities = Capabilities.Unicode | Capabilities.NTStatusCode | Capabilities.ExtendedSecurity;
request.Capabilities = Capabilities.Unicode | Capabilities.NTStatusCode | Capabilities.LargeRead | Capabilities.LargeWrite | Capabilities.ExtendedSecurity;
request.SecurityBlob = NTLMAuthenticationHelper.GetAuthenticateMessage(response.SecurityBlob, domainName, userName, password, authenticationMethod, out m_sessionKey);
TrySendMessage(request);
@ -229,6 +229,29 @@ namespace SMBLibrary.Client
}
}
public SMB1FileStore TreeConnect(string shareName, ServiceName serviceName, out NTStatus status)
{
TreeConnectAndXRequest request = new TreeConnectAndXRequest();
request.Path = shareName;
request.Service = serviceName;
TrySendMessage(request);
SMB1Message reply = WaitForMessage(CommandName.SMB_COM_TREE_CONNECT_ANDX);
if (reply != null)
{
status = reply.Header.Status;
if (reply.Header.Status == NTStatus.STATUS_SUCCESS && reply.Commands[0] is TreeConnectAndXResponse)
{
TreeConnectAndXResponse response = (TreeConnectAndXResponse)reply.Commands[0];
return new SMB1FileStore(this, reply.Header.TID);
}
}
else
{
status = NTStatus.STATUS_INVALID_SMB;
}
return null;
}
private void OnServerSocketReceive(IAsyncResult ar)
{
if (ar != m_currentAsyncResult)

View file

@ -0,0 +1,201 @@
/* Copyright (C) 2014-2017 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,
* either version 3 of the License, or (at your option) any later version.
*/
using System;
using System.Collections.Generic;
using SMBLibrary.SMB1;
using Utilities;
namespace SMBLibrary.Client
{
public class SMB1FileStore : INTFileStore
{
private SMB1Client m_client;
private ushort m_treeID;
public SMB1FileStore(SMB1Client client, ushort treeID)
{
m_client = client;
m_treeID = treeID;
}
public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, FileAttributes fileAttributes, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext)
{
handle = null;
fileStatus = FileStatus.FILE_DOES_NOT_EXIST;
NTCreateAndXRequest request = new NTCreateAndXRequest();
request.FileName = path;
request.DesiredAccess = desiredAccess;
request.ExtFileAttributes = ToExtendedFileAttributes(fileAttributes);
request.ShareAccess = shareAccess;
request.CreateDisposition = createDisposition;
request.CreateOptions = createOptions;
TrySendMessage(request);
SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_NT_CREATE_ANDX);
if (reply != null)
{
if (reply.Commands[0] is NTCreateAndXResponse)
{
NTCreateAndXResponse response = reply.Commands[0] as NTCreateAndXResponse;
handle = response.FID;
fileStatus = ToFileStatus(response.CreateDisposition);
return reply.Header.Status;
}
else if (reply.Commands[0] is ErrorResponse)
{
return reply.Header.Status;
}
}
return NTStatus.STATUS_INVALID_SMB;
}
public NTStatus CloseFile(object handle)
{
CloseRequest request = new CloseRequest();
request.FID = (ushort)handle;
TrySendMessage(request);
SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_CLOSE);
if (reply != null)
{
return reply.Header.Status;
}
return NTStatus.STATUS_INVALID_SMB;
}
public NTStatus ReadFile(out byte[] data, object handle, long offset, int maxCount)
{
data = null;
ReadAndXRequest request = new ReadAndXRequest();
request.FID = (ushort)handle;
request.Offset = (ulong)offset;
request.MaxCountLarge = (uint)maxCount;
TrySendMessage(request);
SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_READ_ANDX);
if (reply != null)
{
if (reply.Header.Status == NTStatus.STATUS_SUCCESS && reply.Commands[0] is ReadAndXResponse)
{
data = ((ReadAndXResponse)reply.Commands[0]).Data;
}
return reply.Header.Status;
}
return NTStatus.STATUS_INVALID_SMB;
}
public NTStatus WriteFile(out int numberOfBytesWritten, object handle, long offset, byte[] data)
{
numberOfBytesWritten = 0;
WriteAndXRequest request = new WriteAndXRequest();
request.FID = (ushort)handle;
request.Offset = (ulong)offset;
request.Data = data;
TrySendMessage(request);
SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_WRITE_ANDX);
if (reply != null)
{
if (reply.Header.Status == NTStatus.STATUS_SUCCESS && reply.Commands[0] is WriteAndXResponse)
{
numberOfBytesWritten = (int)((WriteAndXResponse)reply.Commands[0]).Count;
}
return reply.Header.Status;
}
return NTStatus.STATUS_INVALID_SMB;
}
public NTStatus FlushFileBuffers(object handle)
{
throw new NotImplementedException();
}
public NTStatus LockFile(object handle, long byteOffset, long length, bool exclusiveLock)
{
throw new NotImplementedException();
}
public NTStatus UnlockFile(object handle, long byteOffset, long length)
{
throw new NotImplementedException();
}
public NTStatus QueryDirectory(out List<QueryDirectoryFileInformation> result, object handle, string fileName, FileInformationClass informationClass)
{
throw new NotImplementedException();
}
public NTStatus GetFileInformation(out FileInformation result, object handle, FileInformationClass informationClass)
{
throw new NotImplementedException();
}
public NTStatus SetFileInformation(object handle, FileInformation information)
{
throw new NotImplementedException();
}
public NTStatus GetFileSystemInformation(out FileSystemInformation result, FileSystemInformationClass informationClass)
{
throw new NotImplementedException();
}
public NTStatus NotifyChange(out object ioRequest, object handle, NotifyChangeFilter completionFilter, bool watchTree, int outputBufferSize, OnNotifyChangeCompleted onNotifyChangeCompleted, object context)
{
throw new NotImplementedException();
}
public NTStatus Cancel(object ioRequest)
{
throw new NotImplementedException();
}
public NTStatus DeviceIOControl(object handle, uint ctlCode, byte[] input, out byte[] output, int maxOutputLength)
{
throw new NotImplementedException();
}
private static ExtendedFileAttributes ToExtendedFileAttributes(FileAttributes fileAttributes)
{
// We only return flags that can be used with NtCreateFile
ExtendedFileAttributes extendedFileAttributes = ExtendedFileAttributes.ReadOnly |
ExtendedFileAttributes.Hidden |
ExtendedFileAttributes.System |
ExtendedFileAttributes.Archive |
ExtendedFileAttributes.Normal |
ExtendedFileAttributes.Temporary |
ExtendedFileAttributes.Offline |
ExtendedFileAttributes.Encrypted;
return (extendedFileAttributes & (ExtendedFileAttributes)fileAttributes);
}
private void TrySendMessage(SMB1Command request)
{
m_client.TrySendMessage(request, m_treeID);
}
private static FileStatus ToFileStatus(CreateDisposition createDisposition)
{
switch (createDisposition)
{
case CreateDisposition.FILE_SUPERSEDE:
return FileStatus.FILE_SUPERSEDED;
case CreateDisposition.FILE_OPEN:
return FileStatus.FILE_OPENED;
case CreateDisposition.FILE_CREATE:
return FileStatus.FILE_CREATED;
case CreateDisposition.FILE_OPEN_IF:
return FileStatus.FILE_OVERWRITTEN;
case CreateDisposition.FILE_OVERWRITE:
return FileStatus.FILE_EXISTS;
case CreateDisposition.FILE_OVERWRITE_IF:
return FileStatus.FILE_DOES_NOT_EXIST;
default:
return FileStatus.FILE_OPENED;
}
}
}
}

View file

@ -58,6 +58,7 @@
<Compile Include="Client\Enums\AuthenticationMethod.cs" />
<Compile Include="Client\NTLMAuthenticationHelper.cs" />
<Compile Include="Client\SMB1Client.cs" />
<Compile Include="Client\SMB1FileStore.cs" />
<Compile Include="Enums\NTStatus.cs" />
<Compile Include="Enums\SMBTransportType.cs" />
<Compile Include="Enums\Win32Error.cs" />