mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-07-19 15:45:54 +02:00
SMB1Client: Additional client functions implemented
This commit is contained in:
parent
fcec2ea529
commit
ff9d16cb39
3 changed files with 146 additions and 0 deletions
|
@ -12,6 +12,7 @@ using System.Net.Sockets;
|
|||
using System.Threading;
|
||||
using SMBLibrary.Authentication.NTLM;
|
||||
using SMBLibrary.NetBios;
|
||||
using SMBLibrary.Services;
|
||||
using SMBLibrary.SMB1;
|
||||
using Utilities;
|
||||
|
||||
|
@ -28,6 +29,7 @@ namespace SMBLibrary.Client
|
|||
|
||||
private SMBTransportType m_transport;
|
||||
private bool m_isConnected;
|
||||
private bool m_isLoggedIn;
|
||||
private Socket m_clientSocket;
|
||||
private IAsyncResult m_currentAsyncResult;
|
||||
private bool m_forceExtendedSecurity;
|
||||
|
@ -186,6 +188,7 @@ namespace SMBLibrary.Client
|
|||
SMB1Message reply = WaitForMessage(CommandName.SMB_COM_SESSION_SETUP_ANDX);
|
||||
if (reply != null)
|
||||
{
|
||||
m_isLoggedIn = (reply.Header.Status == NTStatus.STATUS_SUCCESS);
|
||||
return reply.Header.Status;
|
||||
}
|
||||
return NTStatus.STATUS_INVALID_SMB;
|
||||
|
@ -217,6 +220,7 @@ namespace SMBLibrary.Client
|
|||
reply = WaitForMessage(CommandName.SMB_COM_SESSION_SETUP_ANDX);
|
||||
if (reply != null)
|
||||
{
|
||||
m_isLoggedIn = (reply.Header.Status == NTStatus.STATUS_SUCCESS);
|
||||
return reply.Header.Status;
|
||||
}
|
||||
}
|
||||
|
@ -229,8 +233,44 @@ namespace SMBLibrary.Client
|
|||
}
|
||||
}
|
||||
|
||||
public NTStatus Logoff()
|
||||
{
|
||||
LogoffAndXRequest request = new LogoffAndXRequest();
|
||||
TrySendMessage(request);
|
||||
|
||||
SMB1Message reply = WaitForMessage(CommandName.SMB_COM_LOGOFF_ANDX);
|
||||
if (reply != null)
|
||||
{
|
||||
m_isLoggedIn = (reply.Header.Status != NTStatus.STATUS_SUCCESS);
|
||||
return reply.Header.Status;
|
||||
}
|
||||
return NTStatus.STATUS_INVALID_SMB;
|
||||
}
|
||||
|
||||
public List<string> ListShares(out NTStatus status)
|
||||
{
|
||||
if (!m_isConnected || !m_isLoggedIn)
|
||||
{
|
||||
throw new InvalidOperationException("A login session must be successfully established before retrieving share list");
|
||||
}
|
||||
|
||||
|
||||
SMB1FileStore namedPipeShare = TreeConnect("IPC$", ServiceName.NamedPipe, out status);
|
||||
if (namedPipeShare == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ServerServiceHelper.ListShares(namedPipeShare, ShareType.DiskDrive, out status);
|
||||
}
|
||||
|
||||
public SMB1FileStore TreeConnect(string shareName, ServiceName serviceName, out NTStatus status)
|
||||
{
|
||||
if (!m_isConnected || !m_isLoggedIn)
|
||||
{
|
||||
throw new InvalidOperationException("A login session must be successfully established before connecting to a share");
|
||||
}
|
||||
|
||||
TreeConnectAndXRequest request = new TreeConnectAndXRequest();
|
||||
request.Path = shareName;
|
||||
request.Service = serviceName;
|
||||
|
|
105
SMBLibrary/Client/ServerServiceHelper.cs
Normal file
105
SMBLibrary/Client/ServerServiceHelper.cs
Normal file
|
@ -0,0 +1,105 @@
|
|||
/* 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.RPC;
|
||||
using SMBLibrary.Services;
|
||||
|
||||
namespace SMBLibrary.Client
|
||||
{
|
||||
public class ServerServiceHelper
|
||||
{
|
||||
public static List<string> ListShares(INTFileStore namedPipeShare, ShareType? shareType, out NTStatus status)
|
||||
{
|
||||
object pipeHandle;
|
||||
FileStatus fileStatus;
|
||||
status = namedPipeShare.CreateFile(out pipeHandle, out fileStatus, ServerService.ServicePipeName, (AccessMask)(FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA), 0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, null);
|
||||
if (status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
BindPDU bindPDU = new BindPDU();
|
||||
bindPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment;
|
||||
bindPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII;
|
||||
bindPDU.DataRepresentation.ByteOrder = ByteOrder.LittleEndian;
|
||||
bindPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE;
|
||||
bindPDU.MaxTransmitFragmentSize = 5680;
|
||||
bindPDU.MaxReceiveFragmentSize = 5680;
|
||||
|
||||
ContextElement serverServiceContext = new ContextElement();
|
||||
serverServiceContext.AbstractSyntax = new SyntaxID(ServerService.ServiceInterfaceGuid, ServerService.ServiceVersion);
|
||||
serverServiceContext.TransferSyntaxList.Add(new SyntaxID(RemoteServiceHelper.NDRTransferSyntaxIdentifier, RemoteServiceHelper.NDRTransferSyntaxVersion));
|
||||
|
||||
bindPDU.ContextList.Add(serverServiceContext);
|
||||
|
||||
byte[] input = bindPDU.GetBytes();
|
||||
byte[] output;
|
||||
status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, 4096);
|
||||
if (status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
BindAckPDU bindAckPDU = RPCPDU.GetPDU(output, 0) as BindAckPDU;
|
||||
if (bindAckPDU == null)
|
||||
{
|
||||
status = NTStatus.STATUS_NOT_SUPPORTED;
|
||||
return null;
|
||||
}
|
||||
|
||||
NetrShareEnumRequest shareEnumRequest = new NetrShareEnumRequest();
|
||||
shareEnumRequest.InfoStruct = new ShareEnum();
|
||||
shareEnumRequest.InfoStruct.Level = 1;
|
||||
shareEnumRequest.InfoStruct.Info = new ShareInfo1Container();
|
||||
shareEnumRequest.PreferedMaximumLength = UInt32.MaxValue;
|
||||
shareEnumRequest.ServerName = "*";
|
||||
RequestPDU requestPDU = new RequestPDU();
|
||||
requestPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment;
|
||||
requestPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII;
|
||||
requestPDU.DataRepresentation.ByteOrder = ByteOrder.LittleEndian;
|
||||
requestPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE;
|
||||
requestPDU.OpNum = (ushort)ServerServiceOpName.NetrShareEnum;
|
||||
requestPDU.Data = shareEnumRequest.GetBytes();
|
||||
requestPDU.AllocationHint = (uint)requestPDU.Data.Length;
|
||||
input = requestPDU.GetBytes();
|
||||
status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, 4096);
|
||||
if (status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ResponsePDU responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU;
|
||||
if (responsePDU == null)
|
||||
{
|
||||
status = NTStatus.STATUS_NOT_SUPPORTED;
|
||||
return null;
|
||||
}
|
||||
NetrShareEnumResponse shareEnumResponse = new NetrShareEnumResponse(responsePDU.Data);
|
||||
ShareInfo1Container shareInfo1 = shareEnumResponse.InfoStruct.Info as ShareInfo1Container;
|
||||
if (shareInfo1 == null)
|
||||
{
|
||||
if (shareEnumResponse.Result == Win32Error.ERROR_ACCESS_DENIED)
|
||||
{
|
||||
status = NTStatus.STATUS_ACCESS_DENIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NTStatus.STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
List<string> result = new List<string>();
|
||||
foreach (ShareInfo1Entry entry in shareInfo1.Entries)
|
||||
{
|
||||
if (!shareType.HasValue || shareType.Value == entry.ShareType.ShareType)
|
||||
{
|
||||
result.Add(entry.NetName.Value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,6 +57,7 @@
|
|||
<Compile Include="Client\ConnectionState.cs" />
|
||||
<Compile Include="Client\Enums\AuthenticationMethod.cs" />
|
||||
<Compile Include="Client\NTLMAuthenticationHelper.cs" />
|
||||
<Compile Include="Client\ServerServiceHelper.cs" />
|
||||
<Compile Include="Client\SMB1Client.cs" />
|
||||
<Compile Include="Client\SMB1FileStore.cs" />
|
||||
<Compile Include="Enums\NTStatus.cs" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue