singrdk/base/Services/Smb/Protocol/SmbMessages.sg

350 lines
12 KiB
Plaintext

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Singularity;
using Microsoft.SingSharp;
using Microsoft.Singularity.Channels;
using Utils;
namespace Smb.Protocol
{
#region SMB Requests
// This region contains structures that define many of the SMB requests that we use,
// and the responses that we will receive from servers. Each request begins with
// an instance of SmbHeader.
[StructLayout(LayoutKind.Sequential, Pack=1)]
pointerfree struct SmbNegotiateRequest
{
public SmbHeader Header;
public ushort ByteCount;
// repeated sets of dialect strings follow
}
public static class SmbDialect
{
public const string PcNetworkProgram = "PC NETWORK PROGRAM 1.0";
public const string Lanman1 = "LANMAN1.0";
public const string WindowsForWorkgroups = "Windows for Workgroups 3.1a";
public const string LM1_2x002 = "LM1.2X002";
public const string NTLM012 = "NT LM 0.12";
}
[Flags]
public enum SmbNegotiateSecurityMode : byte
{
SupportsUserShareLevel = (1 << 0),
SupportsChallengeResponseAuthentication = (1 << 1),
SecuritySignaturesEnabled = (1 << 2),
SignaturesRequired = (1 << 3),
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
pointerfree struct SmbNegotiateResponse17
{
public SmbHeader Header;
public ushort DialectIndex;
public byte SecurityMode;
public ushort MaxMpxCount;
public ushort MaxNumberVcs;
public uint MaxBufferSize;
public uint MaxRawSize;
public uint SessionKey;
public uint Capabilities;
public uint SystemTimeLow;
public uint SystemTimeHigh;
public ushort ServerTimeZone;
public byte EncryptionKeyLength;
// this field is not included in the parameter count
public ushort ByteCount;
// If the negotiate response is NOT using extended security, then the
// following variable-length fields come next:
//
// char OemDomainName[]
}
/*
typedef struct _REQ_SESSION_SETUP_ANDX {
UCHAR WordCount; // Count of parameter words = 10
UCHAR AndXCommand; // Secondary (X) command; 0xFF = none
UCHAR AndXReserved; // Reserved (must be 0)
_USHORT( AndXOffset ); // Offset to next command WordCount
_USHORT( MaxBufferSize ); // Consumer's maximum buffer size
_USHORT( MaxMpxCount ); // Actual maximum multiplexed pending requests
_USHORT( VcNumber ); // 0 = first (only), nonzero=additional VC number
_ULONG( SessionKey ); // Session key (valid iff VcNumber != 0)
_USHORT( PasswordLength ); // Account password size
_ULONG( Reserved );
_USHORT( ByteCount ); // Count of data bytes; min = 0
UCHAR Buffer[1]; // Buffer containing:
//UCHAR AccountPassword[]; // Account Password
//UCHAR AccountName[]; // Account Name
//UCHAR PrimaryDomain[]; // Client's primary domain
//UCHAR NativeOS[]; // Client's native operating system
//UCHAR NativeLanMan[]; // Client's native LAN Manager type
} REQ_SESSION_SETUP_ANDX;
typedef REQ_SESSION_SETUP_ANDX SMB_UNALIGNED *PREQ_SESSION_SETUP_ANDX;
This is the "old school" SessionSetupAndX. Length of parameter block is 11.
*/
[StructLayout(LayoutKind.Explicit, Size=22, Pack=1)]
pointerfree struct SessionSetupAndX_Old
{
// Parameter block, including the AndX data
[FieldOffset(0)] public byte AndXCommand;
[FieldOffset(1)] public byte AndXPadding;
[FieldOffset(2)] public ushort AndXOffset;
[FieldOffset(4)] public ushort MaxBufferSize;
[FieldOffset(6)] public ushort MaxMpxCount;
[FieldOffset(8)] public ushort VcNumber;
[FieldOffset(10)] public ushort SessionKey0;
[FieldOffset(12)] public ushort SessionKey1;
[FieldOffset(14)] public ushort PasswordLength;
[FieldOffset(16)] public ushort Reserved0;
[FieldOffset(18)] public ushort Reserved1;
[FieldOffset(20)] public ushort ByteCount;
// variable-length data follows
public const int SizeOf = 22;
// public const int ParameterCount = 10;
}
/*
Client Request
============================== Description
=====================================
UCHAR WordCount; Count of parameter words = 12
UCHAR AndXCommand; Secondary (X) command; 0xFF = none
UCHAR AndXReserved; Reserved (must be 0)
USHORT AndXOffset; Offset to next command WordCount
USHORT MaxBufferSize; Client's maximum buffer size
USHORT MaxMpxCount; Actual maximum multiplexed pending requests
USHORT VcNumber; 0 = first (only), nonzero=additional VC number
ULONG SessionKey; Session key (valid iff VcNumber != 0)
USHORT SecurityBlobLength; Length of opaque security blob
ULONG Reserved; must be 0
ULONG Capabilities; Client capabilities
USHORT ByteCount; Count of data bytes; min = 0
UCHAR SecurityBlob[] The opaque security blob
STRING NativeOS[]; Client's native operating system, Unicode
STRING NativeLanMan[]; Client's native LAN Manager type, Unicode
NetMon interprets this as the payload being NTLMSSP
*/
[StructLayout(LayoutKind.Explicit, Size=22, Pack=1)]
pointerfree struct SessionSetupAndX_12
{
// Parameter block, including the AndX data
[FieldOffset(0)] public byte AndXCommand;
[FieldOffset(1)] public byte AndXPadding;
[FieldOffset(2)] public ushort AndXOffset;
[FieldOffset(4)] public ushort MaxBufferSize;
[FieldOffset(6)] public ushort MaxMpxCount;
[FieldOffset(8)] public ushort VcNumber;
[FieldOffset(10)] public ushort SessionKey0;
[FieldOffset(12)] public ushort SessionKey1;
[FieldOffset(14)] public ushort SecurityBlobLength;
[FieldOffset(16)] public ushort Reserved0;
[FieldOffset(18)] public ushort Reserved1;
[FieldOffset(20)] public uint Capabilities;
[FieldOffset(24)] public ushort ByteCount;
// variable-length data follows
// byte[] SecurityBlob;
// char[] NativeOS; // in Unicode
// char[] NativeLanMan; // in Unicode
public const int SizeOf = 26;
public const int ParameterCount = 12;
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
pointerfree struct SmbSessionSetupAndXResponse
{
public SmbHeader Header;
public byte AndXCommand;
public byte AndXReserved;
public ushort AndXOffset;
public ushort Action;
public ushort ByteCount;
// string NativeOS
// string NativeLanMan
// string PrimaryDomain
}
/*
This structure is used with the "NT LM 0.12" dialect.
It indicates that the client wants to setup a session, and does not want to use "extended security".
Extended security uses SPNEGO, which is a general security token exchange mechanism, described in
RFC 2478. This SESSION SETUP message can either use cleartext passwords (bad!), or can use NTLM
challenge/response messages. The LM hash response is stored in the CaseInsensitivePassword field,
and the NT hash response (marginally more secure) is stored in the CaseSensitivePassword field.
*/
[StructLayout(LayoutKind.Sequential, Pack=1)]
pointerfree struct SmbSessionSetupAndXRequest13
{
public SmbHeader Header;
// Parameter block, including the AndX data
public byte AndXCommand;
public byte AndXPadding;
public ushort AndXOffset;
public ushort MaxBufferSize;
public ushort MaxMpxCount;
public ushort VcNumber;
public uint SessionKey;
public ushort CaseInsensitivePasswordLength;
public ushort CaseSensitivePasswordLength;
public uint Reserved;
public uint Capabilities;
public ushort ByteCount;
// byte zero padding; // this is here to pad Unicode to 2-byte boundary if necessary
// STRING AccountName;
// STRING PrimaryDomain;
// STRING NativeOS;
// STRING NativeLanMan;
// variable-length data follows
// byte[] SecurityBlob;
// char[] NativeOS; // in Unicode
// char[] NativeLanMan; // in Unicode
public const int ParameterCount = 13;
}
/*
typedef struct _REQ_NT_SESSION_SETUP_ANDX {
UCHAR WordCount; // Count of parameter words = 13
UCHAR AndXCommand; // Secondary (X) command; 0xFF = none
UCHAR AndXReserved; // Reserved (must be 0)
_USHORT( AndXOffset ); // Offset to next command WordCount
_USHORT( MaxBufferSize ); // Consumer's maximum buffer size
_USHORT( MaxMpxCount ); // Actual maximum multiplexed pending requests
_USHORT( VcNumber ); // 0 = first (only), nonzero=additional VC number
_ULONG( SessionKey ); // Session key (valid iff VcNumber != 0)
_USHORT( CaseInsensitivePasswordLength ); // Account password size, ANSI
_USHORT( CaseSensitivePasswordLength ); // Account password size, Unicode
_ULONG( Reserved);
_ULONG( Capabilities ); // Client capabilities
_USHORT( ByteCount ); // Count of data bytes; min = 0
UCHAR Buffer[1]; // Buffer containing:
//UCHAR CaseInsensitivePassword[]; // Account Password, ANSI
//UCHAR CaseSensitivePassword[]; // Account Password, Unicode
//UCHAR AccountName[]; // Account Name
//UCHAR PrimaryDomain[]; // Client's primary domain
//UCHAR NativeOS[]; // Client's native operating system
//UCHAR NativeLanMan[]; // Client's native LAN Manager type
} REQ_NT_SESSION_SETUP_ANDX;
typedef REQ_NT_SESSION_SETUP_ANDX SMB_UNALIGNED *PREQ_NT_SESSION_SETUP_ANDX;
*/
#if false
[StructLayout(LayoutKind.Explicit, Size=26, Pack=1)]
pointerfree struct SessionSetupAndX_Nt
{
// Parameter block, including the AndX data
[FieldOffset(0)] public byte AndXCommand;
[FieldOffset(1)] public byte AndXPadding;
[FieldOffset(2)] public ushort AndXOffset;
[FieldOffset(4)] public ushort MaxBufferSize;
[FieldOffset(6)] public ushort MaxMpxCount;
[FieldOffset(8)] public ushort VcNumber;
[FieldOffset(10)] public ushort SessionKey0;
[FieldOffset(12)] public ushort SessionKey1;
[FieldOffset(14)] public ushort CaseInsensitivePasswordLength;
[FieldOffset(16)] public ushort CaseSensensitivePasswordLength;
[FieldOffset(18)] public ushort Reserved0;
[FieldOffset(20)] public ushort Reserved1;
[FieldOffset(22)] public ushort Capabilities0;
[FieldOffset(24)] public ushort Capabilities1;
[FieldOffset(26)] public ushort ByteCount;
// variable-length data follows
public const int SizeOf = 26;
public const int ParameterCount = 13;
}
#endif
[StructLayout(LayoutKind.Sequential, Pack=1)]
pointerfree struct SmbTreeConnectAndX
{
public SmbHeader Header;
public byte AndXCommand;
public byte AndXReserved;
public ushort AndXOffset;
public ushort Flags;
public ushort PasswordLength;
public ushort ByteCount;
// byte Password[];
// string Path;
// string Service;
}
[StructLayout(LayoutKind.Sequential)]
pointerfree struct AndXParameterBlock
{
public byte NextCommand;
public byte Padding0;
public ushort NextCommandOffset;
public AndXParameterBlock(SmbCommand command, ushort offset)
{
NextCommand = (byte)command;
NextCommandOffset = offset;
Padding0 = 0;
}
}
[Flags]
enum SmbCapability
{
RawMode = 0x0001,
MpxMode = 0x0002,
Unicode = 0x0004,
LargeFiles = 0x0008,
NtSmbs = 0x0010,
RpcRemoteApis = 0x0020,
NtStatus = 0x0040,
Level2Oplocks = 0x0080,
LockAndRead = 0x0100,
NtFind = 0x0200,
Dfs = 0x1000, // This server is DFS aware
InfolevelPassthru = 0x2000, // NT information level requests can pass through
LargeReadx = 0x4000, // Server supports oversized READ&X on files
LargeWritex = 0x8000,
}
#endregion
}