mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-29 11:58:27 +01:00
merge common implementations and server implementations
This commit is contained in:
197
Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/NtlmFlags.cs
Normal file
197
Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/NtlmFlags.cs
Normal file
@@ -0,0 +1,197 @@
|
||||
// This code is derived from jcifs smb client library <jcifs at samba dot org>
|
||||
// Ported by J. Arturo <webmaster at komodosoft dot net>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
namespace SharpCifs.Ntlmssp
|
||||
{
|
||||
/// <summary>Flags used during negotiation of NTLMSSP authentication.</summary>
|
||||
/// <remarks>Flags used during negotiation of NTLMSSP authentication.</remarks>
|
||||
public abstract class NtlmFlags
|
||||
{
|
||||
/// <summary>Indicates whether Unicode strings are supported or used.</summary>
|
||||
/// <remarks>Indicates whether Unicode strings are supported or used.</remarks>
|
||||
public const int NtlmsspNegotiateUnicode = unchecked(0x00000001);
|
||||
|
||||
/// <summary>Indicates whether OEM strings are supported or used.</summary>
|
||||
/// <remarks>Indicates whether OEM strings are supported or used.</remarks>
|
||||
public const int NtlmsspNegotiateOem = unchecked(0x00000002);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the authentication target is requested from
|
||||
/// the server.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Indicates whether the authentication target is requested from
|
||||
/// the server.
|
||||
/// </remarks>
|
||||
public const int NtlmsspRequestTarget = unchecked(0x00000004);
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that communication across the authenticated channel
|
||||
/// should carry a digital signature (message integrity).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Specifies that communication across the authenticated channel
|
||||
/// should carry a digital signature (message integrity).
|
||||
/// </remarks>
|
||||
public const int NtlmsspNegotiateSign = unchecked(0x00000010);
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that communication across the authenticated channel
|
||||
/// should be encrypted (message confidentiality).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Specifies that communication across the authenticated channel
|
||||
/// should be encrypted (message confidentiality).
|
||||
/// </remarks>
|
||||
public const int NtlmsspNegotiateSeal = unchecked(0x00000020);
|
||||
|
||||
/// <summary>Indicates datagram authentication.</summary>
|
||||
/// <remarks>Indicates datagram authentication.</remarks>
|
||||
public const int NtlmsspNegotiateDatagramStyle = unchecked(0x00000040);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the LAN Manager session key should be used for
|
||||
/// signing and sealing authenticated communication.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Indicates that the LAN Manager session key should be used for
|
||||
/// signing and sealing authenticated communication.
|
||||
/// </remarks>
|
||||
public const int NtlmsspNegotiateLmKey = unchecked(0x00000080);
|
||||
|
||||
public const int NtlmsspNegotiateNetware = unchecked(0x00000100);
|
||||
|
||||
/// <summary>Indicates support for NTLM authentication.</summary>
|
||||
/// <remarks>Indicates support for NTLM authentication.</remarks>
|
||||
public const int NtlmsspNegotiateNtlm = unchecked(0x00000200);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the OEM-formatted domain name in which the
|
||||
/// client workstation has membership is supplied in the Type-1 message.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Indicates whether the OEM-formatted domain name in which the
|
||||
/// client workstation has membership is supplied in the Type-1 message.
|
||||
/// This is used in the negotation of local authentication.
|
||||
/// </remarks>
|
||||
public const int NtlmsspNegotiateOemDomainSupplied = unchecked(0x00001000);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the OEM-formatted workstation name is supplied
|
||||
/// in the Type-1 message.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Indicates whether the OEM-formatted workstation name is supplied
|
||||
/// in the Type-1 message. This is used in the negotiation of local
|
||||
/// authentication.
|
||||
/// </remarks>
|
||||
public const int NtlmsspNegotiateOemWorkstationSupplied = unchecked(0x00002000);
|
||||
|
||||
/// <summary>
|
||||
/// Sent by the server to indicate that the server and client are
|
||||
/// on the same machine.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Sent by the server to indicate that the server and client are
|
||||
/// on the same machine. This implies that the server will include
|
||||
/// a local security context handle in the Type 2 message, for
|
||||
/// use in local authentication.
|
||||
/// </remarks>
|
||||
public const int NtlmsspNegotiateLocalCall = unchecked(0x00004000);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that authenticated communication between the client
|
||||
/// and server should carry a "dummy" digital signature.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Indicates that authenticated communication between the client
|
||||
/// and server should carry a "dummy" digital signature.
|
||||
/// </remarks>
|
||||
public const int NtlmsspNegotiateAlwaysSign = unchecked(0x00008000);
|
||||
|
||||
/// <summary>
|
||||
/// Sent by the server in the Type 2 message to indicate that the
|
||||
/// target authentication realm is a domain.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Sent by the server in the Type 2 message to indicate that the
|
||||
/// target authentication realm is a domain.
|
||||
/// </remarks>
|
||||
public const int NtlmsspTargetTypeDomain = unchecked(0x00010000);
|
||||
|
||||
/// <summary>
|
||||
/// Sent by the server in the Type 2 message to indicate that the
|
||||
/// target authentication realm is a server.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Sent by the server in the Type 2 message to indicate that the
|
||||
/// target authentication realm is a server.
|
||||
/// </remarks>
|
||||
public const int NtlmsspTargetTypeServer = unchecked(0x00020000);
|
||||
|
||||
/// <summary>
|
||||
/// Sent by the server in the Type 2 message to indicate that the
|
||||
/// target authentication realm is a share (presumably for share-level
|
||||
/// authentication).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Sent by the server in the Type 2 message to indicate that the
|
||||
/// target authentication realm is a share (presumably for share-level
|
||||
/// authentication).
|
||||
/// </remarks>
|
||||
public const int NtlmsspTargetTypeShare = unchecked(0x00040000);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the NTLM2 signing and sealing scheme should be used
|
||||
/// for protecting authenticated communications.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Indicates that the NTLM2 signing and sealing scheme should be used
|
||||
/// for protecting authenticated communications. This refers to a
|
||||
/// particular session security scheme, and is not related to the use
|
||||
/// of NTLMv2 authentication.
|
||||
/// </remarks>
|
||||
public const int NtlmsspNegotiateNtlm2 = unchecked(0x00080000);
|
||||
|
||||
public const int NtlmsspRequestInitResponse = unchecked(0x00100000);
|
||||
|
||||
public const int NtlmsspRequestAcceptResponse = unchecked(0x00200000);
|
||||
|
||||
public const int NtlmsspRequestNonNtSessionKey = unchecked(0x00400000
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Sent by the server in the Type 2 message to indicate that it is
|
||||
/// including a Target Information block in the message.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Sent by the server in the Type 2 message to indicate that it is
|
||||
/// including a Target Information block in the message. The Target
|
||||
/// Information block is used in the calculation of the NTLMv2 response.
|
||||
/// </remarks>
|
||||
public const int NtlmsspNegotiateTargetInfo = unchecked(0x00800000);
|
||||
|
||||
/// <summary>Indicates that 128-bit encryption is supported.</summary>
|
||||
/// <remarks>Indicates that 128-bit encryption is supported.</remarks>
|
||||
public const int NtlmsspNegotiate128 = unchecked(0x20000000);
|
||||
|
||||
public const int NtlmsspNegotiateKeyExch = unchecked(0x40000000);
|
||||
|
||||
/// <summary>Indicates that 56-bit encryption is supported.</summary>
|
||||
/// <remarks>Indicates that 56-bit encryption is supported.</remarks>
|
||||
public const int NtlmsspNegotiate56 = unchecked((int)(0x80000000));
|
||||
}
|
||||
}
|
||||
140
Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/NtlmMessage.cs
Normal file
140
Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/NtlmMessage.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
// This code is derived from jcifs smb client library <jcifs at samba dot org>
|
||||
// Ported by J. Arturo <webmaster at komodosoft dot net>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
using System;
|
||||
|
||||
namespace SharpCifs.Ntlmssp
|
||||
{
|
||||
/// <summary>Abstract superclass for all NTLMSSP messages.</summary>
|
||||
/// <remarks>Abstract superclass for all NTLMSSP messages.</remarks>
|
||||
public abstract class NtlmMessage : NtlmFlags
|
||||
{
|
||||
/// <summary>The NTLMSSP "preamble".</summary>
|
||||
/// <remarks>The NTLMSSP "preamble".</remarks>
|
||||
protected internal static readonly byte[] NtlmsspSignature = { unchecked(
|
||||
(byte)('N')), unchecked((byte)('T')), unchecked((byte)('L')),
|
||||
unchecked((byte)('M')), unchecked((byte)('S')), unchecked((byte
|
||||
)('S')), unchecked((byte)('P')), unchecked(0) };
|
||||
|
||||
private static readonly string OemEncoding = Config.DefaultOemEncoding;
|
||||
|
||||
protected internal static readonly string UniEncoding = "UTF-16LE";
|
||||
|
||||
private int _flags;
|
||||
|
||||
/// <summary>Returns the flags currently in use for this message.</summary>
|
||||
/// <remarks>Returns the flags currently in use for this message.</remarks>
|
||||
/// <returns>
|
||||
/// An <code>int</code> containing the flags in use for this
|
||||
/// message.
|
||||
/// </returns>
|
||||
public virtual int GetFlags()
|
||||
{
|
||||
return _flags;
|
||||
}
|
||||
|
||||
/// <summary>Sets the flags for this message.</summary>
|
||||
/// <remarks>Sets the flags for this message.</remarks>
|
||||
/// <param name="flags">The flags for this message.</param>
|
||||
public virtual void SetFlags(int flags)
|
||||
{
|
||||
this._flags = flags;
|
||||
}
|
||||
|
||||
/// <summary>Returns the status of the specified flag.</summary>
|
||||
/// <remarks>Returns the status of the specified flag.</remarks>
|
||||
/// <param name="flag">The flag to test (i.e., <code>NTLMSSP_NEGOTIATE_OEM</code>).</param>
|
||||
/// <returns>A <code>boolean</code> indicating whether the flag is set.</returns>
|
||||
public virtual bool GetFlag(int flag)
|
||||
{
|
||||
return (GetFlags() & flag) != 0;
|
||||
}
|
||||
|
||||
/// <summary>Sets or clears the specified flag.</summary>
|
||||
/// <remarks>Sets or clears the specified flag.</remarks>
|
||||
/// <param name="flag">
|
||||
/// The flag to set/clear (i.e.,
|
||||
/// <code>NTLMSSP_NEGOTIATE_OEM</code>).
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// Indicates whether to set (<code>true</code>) or
|
||||
/// clear (<code>false</code>) the specified flag.
|
||||
/// </param>
|
||||
public virtual void SetFlag(int flag, bool value)
|
||||
{
|
||||
SetFlags(value ? (GetFlags() | flag) : (GetFlags() & (unchecked((int)(0xffffffff)
|
||||
) ^ flag)));
|
||||
}
|
||||
|
||||
internal static int ReadULong(byte[] src, int index)
|
||||
{
|
||||
return (src[index] & unchecked(0xff)) | ((src[index + 1] & unchecked(0xff)) << 8) | ((src[index + 2] & unchecked(0xff)) << 16) | ((src[index
|
||||
+ 3] & unchecked(0xff)) << 24);
|
||||
}
|
||||
|
||||
internal static int ReadUShort(byte[] src, int index)
|
||||
{
|
||||
return (src[index] & unchecked(0xff)) | ((src[index + 1] & unchecked(0xff)) << 8);
|
||||
}
|
||||
|
||||
internal static byte[] ReadSecurityBuffer(byte[] src, int index)
|
||||
{
|
||||
int length = ReadUShort(src, index);
|
||||
int offset = ReadULong(src, index + 4);
|
||||
byte[] buffer = new byte[length];
|
||||
Array.Copy(src, offset, buffer, 0, length);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
internal static void WriteULong(byte[] dest, int offset, int value)
|
||||
{
|
||||
dest[offset] = unchecked((byte)(value & unchecked(0xff)));
|
||||
dest[offset + 1] = unchecked((byte)(value >> 8 & unchecked(0xff)));
|
||||
dest[offset + 2] = unchecked((byte)(value >> 16 & unchecked(0xff)));
|
||||
dest[offset + 3] = unchecked((byte)(value >> 24 & unchecked(0xff)));
|
||||
}
|
||||
|
||||
internal static void WriteUShort(byte[] dest, int offset, int value)
|
||||
{
|
||||
dest[offset] = unchecked((byte)(value & unchecked(0xff)));
|
||||
dest[offset + 1] = unchecked((byte)(value >> 8 & unchecked(0xff)));
|
||||
}
|
||||
|
||||
internal static void WriteSecurityBuffer(byte[] dest, int offset, int bodyOffset,
|
||||
byte[] src)
|
||||
{
|
||||
int length = (src != null) ? src.Length : 0;
|
||||
if (length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
WriteUShort(dest, offset, length);
|
||||
WriteUShort(dest, offset + 2, length);
|
||||
WriteULong(dest, offset + 4, bodyOffset);
|
||||
Array.Copy(src, 0, dest, bodyOffset, length);
|
||||
}
|
||||
|
||||
internal static string GetOemEncoding()
|
||||
{
|
||||
return OemEncoding;
|
||||
}
|
||||
|
||||
/// <summary>Returns the raw byte representation of this message.</summary>
|
||||
/// <remarks>Returns the raw byte representation of this message.</remarks>
|
||||
/// <returns>A <code>byte[]</code> containing the raw message material.</returns>
|
||||
public abstract byte[] ToByteArray();
|
||||
}
|
||||
}
|
||||
249
Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type1Message.cs
Normal file
249
Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type1Message.cs
Normal file
@@ -0,0 +1,249 @@
|
||||
// This code is derived from jcifs smb client library <jcifs at samba dot org>
|
||||
// Ported by J. Arturo <webmaster at komodosoft dot net>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
using System;
|
||||
using System.IO;
|
||||
using SharpCifs.Netbios;
|
||||
using SharpCifs.Util;
|
||||
using SharpCifs.Util.Sharpen;
|
||||
|
||||
namespace SharpCifs.Ntlmssp
|
||||
{
|
||||
/// <summary>Represents an NTLMSSP Type-1 message.</summary>
|
||||
/// <remarks>Represents an NTLMSSP Type-1 message.</remarks>
|
||||
public class Type1Message : NtlmMessage
|
||||
{
|
||||
private static readonly int DefaultFlags;
|
||||
|
||||
private static readonly string DefaultDomain;
|
||||
|
||||
private static readonly string DefaultWorkstation;
|
||||
|
||||
private string _suppliedDomain;
|
||||
|
||||
private string _suppliedWorkstation;
|
||||
|
||||
static Type1Message()
|
||||
{
|
||||
DefaultFlags = NtlmsspNegotiateNtlm | (Config.GetBoolean("jcifs.smb.client.useUnicode"
|
||||
, true) ? NtlmsspNegotiateUnicode : NtlmsspNegotiateOem);
|
||||
DefaultDomain = Config.GetProperty("jcifs.smb.client.domain", null);
|
||||
string defaultWorkstation = null;
|
||||
try
|
||||
{
|
||||
defaultWorkstation = NbtAddress.GetLocalHost().GetHostName();
|
||||
}
|
||||
catch (UnknownHostException)
|
||||
{
|
||||
}
|
||||
DefaultWorkstation = defaultWorkstation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Type-1 message using default values from the current
|
||||
/// environment.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Creates a Type-1 message using default values from the current
|
||||
/// environment.
|
||||
/// </remarks>
|
||||
public Type1Message() : this(GetDefaultFlags(), GetDefaultDomain(), GetDefaultWorkstation
|
||||
())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Creates a Type-1 message with the specified parameters.</summary>
|
||||
/// <remarks>Creates a Type-1 message with the specified parameters.</remarks>
|
||||
/// <param name="flags">The flags to apply to this message.</param>
|
||||
/// <param name="suppliedDomain">The supplied authentication domain.</param>
|
||||
/// <param name="suppliedWorkstation">The supplied workstation name.</param>
|
||||
public Type1Message(int flags, string suppliedDomain, string suppliedWorkstation)
|
||||
{
|
||||
SetFlags(GetDefaultFlags() | flags);
|
||||
SetSuppliedDomain(suppliedDomain);
|
||||
if (suppliedWorkstation == null)
|
||||
{
|
||||
suppliedWorkstation = GetDefaultWorkstation();
|
||||
}
|
||||
SetSuppliedWorkstation(suppliedWorkstation);
|
||||
}
|
||||
|
||||
/// <summary>Creates a Type-1 message using the given raw Type-1 material.</summary>
|
||||
/// <remarks>Creates a Type-1 message using the given raw Type-1 material.</remarks>
|
||||
/// <param name="material">The raw Type-1 material used to construct this message.</param>
|
||||
/// <exception cref="System.IO.IOException">If an error occurs while parsing the material.
|
||||
/// </exception>
|
||||
public Type1Message(byte[] material)
|
||||
{
|
||||
Parse(material);
|
||||
}
|
||||
|
||||
/// <summary>Returns the supplied authentication domain.</summary>
|
||||
/// <remarks>Returns the supplied authentication domain.</remarks>
|
||||
/// <returns>A <code>String</code> containing the supplied domain.</returns>
|
||||
public virtual string GetSuppliedDomain()
|
||||
{
|
||||
return _suppliedDomain;
|
||||
}
|
||||
|
||||
/// <summary>Sets the supplied authentication domain for this message.</summary>
|
||||
/// <remarks>Sets the supplied authentication domain for this message.</remarks>
|
||||
/// <param name="suppliedDomain">The supplied domain for this message.</param>
|
||||
public virtual void SetSuppliedDomain(string suppliedDomain)
|
||||
{
|
||||
this._suppliedDomain = suppliedDomain;
|
||||
}
|
||||
|
||||
/// <summary>Returns the supplied workstation name.</summary>
|
||||
/// <remarks>Returns the supplied workstation name.</remarks>
|
||||
/// <returns>A <code>String</code> containing the supplied workstation name.</returns>
|
||||
public virtual string GetSuppliedWorkstation()
|
||||
{
|
||||
return _suppliedWorkstation;
|
||||
}
|
||||
|
||||
/// <summary>Sets the supplied workstation name for this message.</summary>
|
||||
/// <remarks>Sets the supplied workstation name for this message.</remarks>
|
||||
/// <param name="suppliedWorkstation">The supplied workstation for this message.</param>
|
||||
public virtual void SetSuppliedWorkstation(string suppliedWorkstation)
|
||||
{
|
||||
this._suppliedWorkstation = suppliedWorkstation;
|
||||
}
|
||||
|
||||
public override byte[] ToByteArray()
|
||||
{
|
||||
try
|
||||
{
|
||||
string suppliedDomain = GetSuppliedDomain();
|
||||
string suppliedWorkstation = GetSuppliedWorkstation();
|
||||
int flags = GetFlags();
|
||||
bool hostInfo = false;
|
||||
byte[] domain = new byte[0];
|
||||
if (!string.IsNullOrEmpty(suppliedDomain))
|
||||
{
|
||||
hostInfo = true;
|
||||
flags |= NtlmsspNegotiateOemDomainSupplied;
|
||||
domain = Runtime.GetBytesForString(suppliedDomain.ToUpper(), GetOemEncoding
|
||||
());
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= (NtlmsspNegotiateOemDomainSupplied ^ unchecked((int)(0xffffffff)));
|
||||
}
|
||||
byte[] workstation = new byte[0];
|
||||
if (!string.IsNullOrEmpty(suppliedWorkstation))
|
||||
{
|
||||
hostInfo = true;
|
||||
flags |= NtlmsspNegotiateOemWorkstationSupplied;
|
||||
workstation = Runtime.GetBytesForString(suppliedWorkstation.ToUpper(), GetOemEncoding
|
||||
());
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= (NtlmsspNegotiateOemWorkstationSupplied ^ unchecked((int)(0xffffffff
|
||||
)));
|
||||
}
|
||||
byte[] type1 = new byte[hostInfo ? (32 + domain.Length + workstation.Length) : 16
|
||||
];
|
||||
Array.Copy(NtlmsspSignature, 0, type1, 0, 8);
|
||||
WriteULong(type1, 8, 1);
|
||||
WriteULong(type1, 12, flags);
|
||||
if (hostInfo)
|
||||
{
|
||||
WriteSecurityBuffer(type1, 16, 32, domain);
|
||||
WriteSecurityBuffer(type1, 24, 32 + domain.Length, workstation);
|
||||
}
|
||||
return type1;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new InvalidOperationException(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string suppliedDomain = GetSuppliedDomain();
|
||||
string suppliedWorkstation = GetSuppliedWorkstation();
|
||||
return "Type1Message[suppliedDomain=" + (suppliedDomain ?? "null"
|
||||
) + ",suppliedWorkstation=" + (suppliedWorkstation ?? "null"
|
||||
) + ",flags=0x" + Hexdump.ToHexString(GetFlags(), 8) + "]";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the default flags for a generic Type-1 message in the
|
||||
/// current environment.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Returns the default flags for a generic Type-1 message in the
|
||||
/// current environment.
|
||||
/// </remarks>
|
||||
/// <returns>An <code>int</code> containing the default flags.</returns>
|
||||
public static int GetDefaultFlags()
|
||||
{
|
||||
return DefaultFlags;
|
||||
}
|
||||
|
||||
/// <summary>Returns the default domain from the current environment.</summary>
|
||||
/// <remarks>Returns the default domain from the current environment.</remarks>
|
||||
/// <returns>A <code>String</code> containing the default domain.</returns>
|
||||
public static string GetDefaultDomain()
|
||||
{
|
||||
return DefaultDomain;
|
||||
}
|
||||
|
||||
/// <summary>Returns the default workstation from the current environment.</summary>
|
||||
/// <remarks>Returns the default workstation from the current environment.</remarks>
|
||||
/// <returns>A <code>String</code> containing the default workstation.</returns>
|
||||
public static string GetDefaultWorkstation()
|
||||
{
|
||||
return DefaultWorkstation;
|
||||
}
|
||||
|
||||
/// <exception cref="System.IO.IOException"></exception>
|
||||
private void Parse(byte[] material)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (material[i] != NtlmsspSignature[i])
|
||||
{
|
||||
throw new IOException("Not an NTLMSSP message.");
|
||||
}
|
||||
}
|
||||
if (ReadULong(material, 8) != 1)
|
||||
{
|
||||
throw new IOException("Not a Type 1 message.");
|
||||
}
|
||||
int flags = ReadULong(material, 12);
|
||||
string suppliedDomain = null;
|
||||
if ((flags & NtlmsspNegotiateOemDomainSupplied) != 0)
|
||||
{
|
||||
byte[] domain = ReadSecurityBuffer(material, 16);
|
||||
suppliedDomain = Runtime.GetStringForBytes(domain, GetOemEncoding());
|
||||
}
|
||||
string suppliedWorkstation = null;
|
||||
if ((flags & NtlmsspNegotiateOemWorkstationSupplied) != 0)
|
||||
{
|
||||
byte[] workstation = ReadSecurityBuffer(material, 24);
|
||||
suppliedWorkstation = Runtime.GetStringForBytes(workstation, GetOemEncoding
|
||||
());
|
||||
}
|
||||
SetFlags(flags);
|
||||
SetSuppliedDomain(suppliedDomain);
|
||||
SetSuppliedWorkstation(suppliedWorkstation);
|
||||
}
|
||||
}
|
||||
}
|
||||
438
Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type2Message.cs
Normal file
438
Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type2Message.cs
Normal file
@@ -0,0 +1,438 @@
|
||||
// This code is derived from jcifs smb client library <jcifs at samba dot org>
|
||||
// Ported by J. Arturo <webmaster at komodosoft dot net>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
using System;
|
||||
using System.IO;
|
||||
using SharpCifs.Netbios;
|
||||
using SharpCifs.Util;
|
||||
using SharpCifs.Util.Sharpen;
|
||||
|
||||
namespace SharpCifs.Ntlmssp
|
||||
{
|
||||
/// <summary>Represents an NTLMSSP Type-2 message.</summary>
|
||||
/// <remarks>Represents an NTLMSSP Type-2 message.</remarks>
|
||||
public class Type2Message : NtlmMessage
|
||||
{
|
||||
private static readonly int DefaultFlags;
|
||||
|
||||
private static readonly string DefaultDomain;
|
||||
|
||||
private static readonly byte[] DefaultTargetInformation;
|
||||
|
||||
private byte[] _challenge;
|
||||
|
||||
private string _target;
|
||||
|
||||
private byte[] _context;
|
||||
|
||||
private byte[] _targetInformation;
|
||||
|
||||
static Type2Message()
|
||||
{
|
||||
DefaultFlags = NtlmsspNegotiateNtlm | (Config.GetBoolean("jcifs.smb.client.useUnicode"
|
||||
, true) ? NtlmsspNegotiateUnicode : NtlmsspNegotiateOem);
|
||||
DefaultDomain = Config.GetProperty("jcifs.smb.client.domain", null);
|
||||
byte[] domain = new byte[0];
|
||||
if (DefaultDomain != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
domain = Runtime.GetBytesForString(DefaultDomain, UniEncoding);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
}
|
||||
int domainLength = domain.Length;
|
||||
byte[] server = new byte[0];
|
||||
try
|
||||
{
|
||||
string host = NbtAddress.GetLocalHost().GetHostName();
|
||||
if (host != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
server = Runtime.GetBytesForString(host, UniEncoding);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (UnknownHostException)
|
||||
{
|
||||
}
|
||||
int serverLength = server.Length;
|
||||
byte[] targetInfo = new byte[(domainLength > 0 ? domainLength + 4 : 0) + (serverLength
|
||||
> 0 ? serverLength + 4 : 0) + 4];
|
||||
int offset = 0;
|
||||
if (domainLength > 0)
|
||||
{
|
||||
WriteUShort(targetInfo, offset, 2);
|
||||
offset += 2;
|
||||
WriteUShort(targetInfo, offset, domainLength);
|
||||
offset += 2;
|
||||
Array.Copy(domain, 0, targetInfo, offset, domainLength);
|
||||
offset += domainLength;
|
||||
}
|
||||
if (serverLength > 0)
|
||||
{
|
||||
WriteUShort(targetInfo, offset, 1);
|
||||
offset += 2;
|
||||
WriteUShort(targetInfo, offset, serverLength);
|
||||
offset += 2;
|
||||
Array.Copy(server, 0, targetInfo, offset, serverLength);
|
||||
}
|
||||
DefaultTargetInformation = targetInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Type-2 message using default values from the current
|
||||
/// environment.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Creates a Type-2 message using default values from the current
|
||||
/// environment.
|
||||
/// </remarks>
|
||||
public Type2Message() : this(GetDefaultFlags(), null, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Type-2 message in response to the given Type-1 message
|
||||
/// using default values from the current environment.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Creates a Type-2 message in response to the given Type-1 message
|
||||
/// using default values from the current environment.
|
||||
/// </remarks>
|
||||
/// <param name="type1">The Type-1 message which this represents a response to.</param>
|
||||
public Type2Message(Type1Message type1) : this(type1, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Creates a Type-2 message in response to the given Type-1 message.</summary>
|
||||
/// <remarks>Creates a Type-2 message in response to the given Type-1 message.</remarks>
|
||||
/// <param name="type1">The Type-1 message which this represents a response to.</param>
|
||||
/// <param name="challenge">The challenge from the domain controller/server.</param>
|
||||
/// <param name="target">The authentication target.</param>
|
||||
public Type2Message(Type1Message type1, byte[] challenge, string target) : this(GetDefaultFlags
|
||||
(type1), challenge, (type1 != null && target == null && type1.GetFlag(NtlmsspRequestTarget
|
||||
)) ? GetDefaultDomain() : target)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Creates a Type-2 message with the specified parameters.</summary>
|
||||
/// <remarks>Creates a Type-2 message with the specified parameters.</remarks>
|
||||
/// <param name="flags">The flags to apply to this message.</param>
|
||||
/// <param name="challenge">The challenge from the domain controller/server.</param>
|
||||
/// <param name="target">The authentication target.</param>
|
||||
public Type2Message(int flags, byte[] challenge, string target)
|
||||
{
|
||||
SetFlags(flags);
|
||||
SetChallenge(challenge);
|
||||
SetTarget(target);
|
||||
if (target != null)
|
||||
{
|
||||
SetTargetInformation(GetDefaultTargetInformation());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Creates a Type-2 message using the given raw Type-2 material.</summary>
|
||||
/// <remarks>Creates a Type-2 message using the given raw Type-2 material.</remarks>
|
||||
/// <param name="material">The raw Type-2 material used to construct this message.</param>
|
||||
/// <exception cref="System.IO.IOException">If an error occurs while parsing the material.
|
||||
/// </exception>
|
||||
public Type2Message(byte[] material)
|
||||
{
|
||||
Parse(material);
|
||||
}
|
||||
|
||||
/// <summary>Returns the challenge for this message.</summary>
|
||||
/// <remarks>Returns the challenge for this message.</remarks>
|
||||
/// <returns>A <code>byte[]</code> containing the challenge.</returns>
|
||||
public virtual byte[] GetChallenge()
|
||||
{
|
||||
return _challenge;
|
||||
}
|
||||
|
||||
/// <summary>Sets the challenge for this message.</summary>
|
||||
/// <remarks>Sets the challenge for this message.</remarks>
|
||||
/// <param name="challenge">The challenge from the domain controller/server.</param>
|
||||
public virtual void SetChallenge(byte[] challenge)
|
||||
{
|
||||
this._challenge = challenge;
|
||||
}
|
||||
|
||||
/// <summary>Returns the authentication target.</summary>
|
||||
/// <remarks>Returns the authentication target.</remarks>
|
||||
/// <returns>A <code>String</code> containing the authentication target.</returns>
|
||||
public virtual string GetTarget()
|
||||
{
|
||||
return _target;
|
||||
}
|
||||
|
||||
/// <summary>Sets the authentication target.</summary>
|
||||
/// <remarks>Sets the authentication target.</remarks>
|
||||
/// <param name="target">The authentication target.</param>
|
||||
public virtual void SetTarget(string target)
|
||||
{
|
||||
this._target = target;
|
||||
}
|
||||
|
||||
/// <summary>Returns the target information block.</summary>
|
||||
/// <remarks>Returns the target information block.</remarks>
|
||||
/// <returns>
|
||||
/// A <code>byte[]</code> containing the target information block.
|
||||
/// The target information block is used by the client to create an
|
||||
/// NTLMv2 response.
|
||||
/// </returns>
|
||||
public virtual byte[] GetTargetInformation()
|
||||
{
|
||||
return _targetInformation;
|
||||
}
|
||||
|
||||
/// <summary>Sets the target information block.</summary>
|
||||
/// <remarks>
|
||||
/// Sets the target information block.
|
||||
/// The target information block is used by the client to create
|
||||
/// an NTLMv2 response.
|
||||
/// </remarks>
|
||||
/// <param name="targetInformation">The target information block.</param>
|
||||
public virtual void SetTargetInformation(byte[] targetInformation)
|
||||
{
|
||||
this._targetInformation = targetInformation;
|
||||
}
|
||||
|
||||
/// <summary>Returns the local security context.</summary>
|
||||
/// <remarks>Returns the local security context.</remarks>
|
||||
/// <returns>
|
||||
/// A <code>byte[]</code> containing the local security
|
||||
/// context. This is used by the client to negotiate local
|
||||
/// authentication.
|
||||
/// </returns>
|
||||
public virtual byte[] GetContext()
|
||||
{
|
||||
return _context;
|
||||
}
|
||||
|
||||
/// <summary>Sets the local security context.</summary>
|
||||
/// <remarks>
|
||||
/// Sets the local security context. This is used by the client
|
||||
/// to negotiate local authentication.
|
||||
/// </remarks>
|
||||
/// <param name="context">The local security context.</param>
|
||||
public virtual void SetContext(byte[] context)
|
||||
{
|
||||
this._context = context;
|
||||
}
|
||||
|
||||
public override byte[] ToByteArray()
|
||||
{
|
||||
try
|
||||
{
|
||||
string targetName = GetTarget();
|
||||
byte[] challenge = GetChallenge();
|
||||
byte[] context = GetContext();
|
||||
byte[] targetInformation = GetTargetInformation();
|
||||
int flags = GetFlags();
|
||||
byte[] target = new byte[0];
|
||||
if ((flags & NtlmsspRequestTarget) != 0)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(targetName))
|
||||
{
|
||||
target = (flags & NtlmsspNegotiateUnicode) != 0 ? Runtime.GetBytesForString
|
||||
(targetName, UniEncoding) : Runtime.GetBytesForString(targetName.ToUpper
|
||||
(), GetOemEncoding());
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= (unchecked((int)(0xffffffff)) ^ NtlmsspRequestTarget);
|
||||
}
|
||||
}
|
||||
if (targetInformation != null)
|
||||
{
|
||||
flags |= NtlmsspNegotiateTargetInfo;
|
||||
// empty context is needed for padding when t.i. is supplied.
|
||||
if (context == null)
|
||||
{
|
||||
context = new byte[8];
|
||||
}
|
||||
}
|
||||
int data = 32;
|
||||
if (context != null)
|
||||
{
|
||||
data += 8;
|
||||
}
|
||||
if (targetInformation != null)
|
||||
{
|
||||
data += 8;
|
||||
}
|
||||
byte[] type2 = new byte[data + target.Length + (targetInformation != null ? targetInformation
|
||||
.Length : 0)];
|
||||
Array.Copy(NtlmsspSignature, 0, type2, 0, 8);
|
||||
WriteULong(type2, 8, 2);
|
||||
WriteSecurityBuffer(type2, 12, data, target);
|
||||
WriteULong(type2, 20, flags);
|
||||
Array.Copy(challenge ?? new byte[8], 0, type2, 24, 8);
|
||||
if (context != null)
|
||||
{
|
||||
Array.Copy(context, 0, type2, 32, 8);
|
||||
}
|
||||
if (targetInformation != null)
|
||||
{
|
||||
WriteSecurityBuffer(type2, 40, data + target.Length, targetInformation);
|
||||
}
|
||||
return type2;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new InvalidOperationException(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string target = GetTarget();
|
||||
byte[] challenge = GetChallenge();
|
||||
byte[] context = GetContext();
|
||||
byte[] targetInformation = GetTargetInformation();
|
||||
return "Type2Message[target=" + target + ",challenge=" + (challenge == null ? "null"
|
||||
: "<" + challenge.Length + " bytes>") + ",context=" + (context == null ? "null"
|
||||
: "<" + context.Length + " bytes>") + ",targetInformation=" + (targetInformation
|
||||
== null ? "null" : "<" + targetInformation.Length + " bytes>") + ",flags=0x" +
|
||||
Hexdump.ToHexString(GetFlags(), 8) + "]";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the default flags for a generic Type-2 message in the
|
||||
/// current environment.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Returns the default flags for a generic Type-2 message in the
|
||||
/// current environment.
|
||||
/// </remarks>
|
||||
/// <returns>An <code>int</code> containing the default flags.</returns>
|
||||
public static int GetDefaultFlags()
|
||||
{
|
||||
return DefaultFlags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the default flags for a Type-2 message created in response
|
||||
/// to the given Type-1 message in the current environment.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Returns the default flags for a Type-2 message created in response
|
||||
/// to the given Type-1 message in the current environment.
|
||||
/// </remarks>
|
||||
/// <returns>An <code>int</code> containing the default flags.</returns>
|
||||
public static int GetDefaultFlags(Type1Message type1)
|
||||
{
|
||||
if (type1 == null)
|
||||
{
|
||||
return DefaultFlags;
|
||||
}
|
||||
int flags = NtlmsspNegotiateNtlm;
|
||||
int type1Flags = type1.GetFlags();
|
||||
flags |= ((type1Flags & NtlmsspNegotiateUnicode) != 0) ? NtlmsspNegotiateUnicode
|
||||
: NtlmsspNegotiateOem;
|
||||
if ((type1Flags & NtlmsspRequestTarget) != 0)
|
||||
{
|
||||
string domain = GetDefaultDomain();
|
||||
if (domain != null)
|
||||
{
|
||||
flags |= NtlmsspRequestTarget | NtlmsspTargetTypeDomain;
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
/// <summary>Returns the default domain from the current environment.</summary>
|
||||
/// <remarks>Returns the default domain from the current environment.</remarks>
|
||||
/// <returns>A <code>String</code> containing the domain.</returns>
|
||||
public static string GetDefaultDomain()
|
||||
{
|
||||
return DefaultDomain;
|
||||
}
|
||||
|
||||
public static byte[] GetDefaultTargetInformation()
|
||||
{
|
||||
return DefaultTargetInformation;
|
||||
}
|
||||
|
||||
/// <exception cref="System.IO.IOException"></exception>
|
||||
private void Parse(byte[] material)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (material[i] != NtlmsspSignature[i])
|
||||
{
|
||||
throw new IOException("Not an NTLMSSP message.");
|
||||
}
|
||||
}
|
||||
if (ReadULong(material, 8) != 2)
|
||||
{
|
||||
throw new IOException("Not a Type 2 message.");
|
||||
}
|
||||
int flags = ReadULong(material, 20);
|
||||
SetFlags(flags);
|
||||
string target = null;
|
||||
byte[] bytes = ReadSecurityBuffer(material, 12);
|
||||
if (bytes.Length != 0)
|
||||
{
|
||||
target = Runtime.GetStringForBytes(bytes, ((flags & NtlmsspNegotiateUnicode
|
||||
) != 0) ? UniEncoding : GetOemEncoding());
|
||||
}
|
||||
SetTarget(target);
|
||||
for (int i1 = 24; i1 < 32; i1++)
|
||||
{
|
||||
if (material[i1] != 0)
|
||||
{
|
||||
byte[] challenge = new byte[8];
|
||||
Array.Copy(material, 24, challenge, 0, 8);
|
||||
SetChallenge(challenge);
|
||||
break;
|
||||
}
|
||||
}
|
||||
int offset = ReadULong(material, 16);
|
||||
// offset of targetname start
|
||||
if (offset == 32 || material.Length == 32)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i2 = 32; i2 < 40; i2++)
|
||||
{
|
||||
if (material[i2] != 0)
|
||||
{
|
||||
byte[] context = new byte[8];
|
||||
Array.Copy(material, 32, context, 0, 8);
|
||||
SetContext(context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (offset == 40 || material.Length == 40)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bytes = ReadSecurityBuffer(material, 40);
|
||||
if (bytes.Length != 0)
|
||||
{
|
||||
SetTargetInformation(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
677
Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type3Message.cs
Normal file
677
Emby.Server.Implementations/IO/SharpCifs/Ntlmssp/Type3Message.cs
Normal file
@@ -0,0 +1,677 @@
|
||||
// This code is derived from jcifs smb client library <jcifs at samba dot org>
|
||||
// Ported by J. Arturo <webmaster at komodosoft dot net>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
using System;
|
||||
using System.IO;
|
||||
using SharpCifs.Netbios;
|
||||
using SharpCifs.Smb;
|
||||
using SharpCifs.Util;
|
||||
using SharpCifs.Util.Sharpen;
|
||||
|
||||
namespace SharpCifs.Ntlmssp
|
||||
{
|
||||
/// <summary>Represents an NTLMSSP Type-3 message.</summary>
|
||||
/// <remarks>Represents an NTLMSSP Type-3 message.</remarks>
|
||||
public class Type3Message : NtlmMessage
|
||||
{
|
||||
internal const long MillisecondsBetween1970And1601 = 11644473600000L;
|
||||
|
||||
private static readonly int DefaultFlags;
|
||||
|
||||
private static readonly string DefaultDomain;
|
||||
|
||||
private static readonly string DefaultUser;
|
||||
|
||||
private static readonly string DefaultPassword;
|
||||
|
||||
private static readonly string DefaultWorkstation;
|
||||
|
||||
private static readonly int LmCompatibility;
|
||||
|
||||
//private static readonly SecureRandom RANDOM = new SecureRandom();
|
||||
|
||||
private byte[] _lmResponse;
|
||||
|
||||
private byte[] _ntResponse;
|
||||
|
||||
private string _domain;
|
||||
|
||||
private string _user;
|
||||
|
||||
private string _workstation;
|
||||
|
||||
private byte[] _masterKey;
|
||||
|
||||
private byte[] _sessionKey;
|
||||
|
||||
static Type3Message()
|
||||
{
|
||||
DefaultFlags = NtlmsspNegotiateNtlm | (Config.GetBoolean("jcifs.smb.client.useUnicode"
|
||||
, true) ? NtlmsspNegotiateUnicode : NtlmsspNegotiateOem);
|
||||
DefaultDomain = Config.GetProperty("jcifs.smb.client.domain", null);
|
||||
DefaultUser = Config.GetProperty("jcifs.smb.client.username", null);
|
||||
DefaultPassword = Config.GetProperty("jcifs.smb.client.password", null);
|
||||
string defaultWorkstation = null;
|
||||
try
|
||||
{
|
||||
defaultWorkstation = NbtAddress.GetLocalHost().GetHostName();
|
||||
}
|
||||
catch (UnknownHostException)
|
||||
{
|
||||
}
|
||||
DefaultWorkstation = defaultWorkstation;
|
||||
LmCompatibility = Config.GetInt("jcifs.smb.lmCompatibility", 3);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Type-3 message using default values from the current
|
||||
/// environment.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Creates a Type-3 message using default values from the current
|
||||
/// environment.
|
||||
/// </remarks>
|
||||
public Type3Message()
|
||||
{
|
||||
SetFlags(GetDefaultFlags());
|
||||
SetDomain(GetDefaultDomain());
|
||||
SetUser(GetDefaultUser());
|
||||
SetWorkstation(GetDefaultWorkstation());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Type-3 message in response to the given Type-2 message
|
||||
/// using default values from the current environment.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Creates a Type-3 message in response to the given Type-2 message
|
||||
/// using default values from the current environment.
|
||||
/// </remarks>
|
||||
/// <param name="type2">The Type-2 message which this represents a response to.</param>
|
||||
public Type3Message(Type2Message type2)
|
||||
{
|
||||
SetFlags(GetDefaultFlags(type2));
|
||||
SetWorkstation(GetDefaultWorkstation());
|
||||
string domain = GetDefaultDomain();
|
||||
SetDomain(domain);
|
||||
string user = GetDefaultUser();
|
||||
SetUser(user);
|
||||
string password = GetDefaultPassword();
|
||||
switch (LmCompatibility)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
{
|
||||
SetLmResponse(GetLMResponse(type2, password));
|
||||
SetNtResponse(GetNTResponse(type2, password));
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
byte[] nt = GetNTResponse(type2, password);
|
||||
SetLmResponse(nt);
|
||||
SetNtResponse(nt);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
{
|
||||
byte[] clientChallenge = new byte[8];
|
||||
//RANDOM.NextBytes(clientChallenge);
|
||||
SetLmResponse(GetLMv2Response(type2, domain, user, password, clientChallenge));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
SetLmResponse(GetLMResponse(type2, password));
|
||||
SetNtResponse(GetNTResponse(type2, password));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Creates a Type-3 message in response to the given Type-2 message.</summary>
|
||||
/// <remarks>Creates a Type-3 message in response to the given Type-2 message.</remarks>
|
||||
/// <param name="type2">The Type-2 message which this represents a response to.</param>
|
||||
/// <param name="password">The password to use when constructing the response.</param>
|
||||
/// <param name="domain">The domain in which the user has an account.</param>
|
||||
/// <param name="user">The username for the authenticating user.</param>
|
||||
/// <param name="workstation">
|
||||
/// The workstation from which authentication is
|
||||
/// taking place.
|
||||
/// </param>
|
||||
public Type3Message(Type2Message type2, string password, string domain, string user
|
||||
, string workstation, int flags)
|
||||
{
|
||||
SetFlags(flags | GetDefaultFlags(type2));
|
||||
if (workstation == null)
|
||||
{
|
||||
workstation = GetDefaultWorkstation();
|
||||
}
|
||||
SetWorkstation(workstation);
|
||||
SetDomain(domain);
|
||||
SetUser(user);
|
||||
switch (LmCompatibility)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
{
|
||||
if ((GetFlags() & NtlmsspNegotiateNtlm2) == 0)
|
||||
{
|
||||
SetLmResponse(GetLMResponse(type2, password));
|
||||
SetNtResponse(GetNTResponse(type2, password));
|
||||
}
|
||||
else
|
||||
{
|
||||
// NTLM2 Session Response
|
||||
byte[] clientChallenge = new byte[24];
|
||||
//RANDOM.NextBytes(clientChallenge);
|
||||
Arrays.Fill(clientChallenge, 8, 24, unchecked((byte)unchecked(0x00)));
|
||||
// NTLMv1 w/ NTLM2 session sec and key exch all been verified with a debug build of smbclient
|
||||
byte[] responseKeyNt = NtlmPasswordAuthentication.NtowFv1(password);
|
||||
byte[] ntlm2Response = NtlmPasswordAuthentication.GetNtlm2Response(responseKeyNt,
|
||||
type2.GetChallenge(), clientChallenge);
|
||||
SetLmResponse(clientChallenge);
|
||||
SetNtResponse(ntlm2Response);
|
||||
if ((GetFlags() & NtlmsspNegotiateSign) == NtlmsspNegotiateSign)
|
||||
{
|
||||
byte[] sessionNonce = new byte[16];
|
||||
Array.Copy(type2.GetChallenge(), 0, sessionNonce, 0, 8);
|
||||
Array.Copy(clientChallenge, 0, sessionNonce, 8, 8);
|
||||
Md4 md4 = new Md4();
|
||||
md4.Update(responseKeyNt);
|
||||
byte[] userSessionKey = md4.Digest();
|
||||
Hmact64 hmac = new Hmact64(userSessionKey);
|
||||
hmac.Update(sessionNonce);
|
||||
byte[] ntlm2SessionKey = hmac.Digest();
|
||||
if ((GetFlags() & NtlmsspNegotiateKeyExch) != 0)
|
||||
{
|
||||
_masterKey = new byte[16];
|
||||
//RANDOM.NextBytes(masterKey);
|
||||
byte[] exchangedKey = new byte[16];
|
||||
Rc4 rc4 = new Rc4(ntlm2SessionKey);
|
||||
rc4.Update(_masterKey, 0, 16, exchangedKey, 0);
|
||||
SetSessionKey(exchangedKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
_masterKey = ntlm2SessionKey;
|
||||
SetSessionKey(_masterKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
byte[] nt = GetNTResponse(type2, password);
|
||||
SetLmResponse(nt);
|
||||
SetNtResponse(nt);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
{
|
||||
byte[] responseKeyNt1 = NtlmPasswordAuthentication.NtowFv2(domain, user, password
|
||||
);
|
||||
byte[] clientChallenge1 = new byte[8];
|
||||
//RANDOM.NextBytes(clientChallenge_1);
|
||||
SetLmResponse(GetLMv2Response(type2, domain, user, password, clientChallenge1));
|
||||
byte[] clientChallenge2 = new byte[8];
|
||||
//RANDOM.NextBytes(clientChallenge2);
|
||||
SetNtResponse(GetNtlMv2Response(type2, responseKeyNt1, clientChallenge2));
|
||||
if ((GetFlags() & NtlmsspNegotiateSign) == NtlmsspNegotiateSign)
|
||||
{
|
||||
Hmact64 hmac = new Hmact64(responseKeyNt1);
|
||||
hmac.Update(_ntResponse, 0, 16);
|
||||
// only first 16 bytes of ntResponse
|
||||
byte[] userSessionKey = hmac.Digest();
|
||||
if ((GetFlags() & NtlmsspNegotiateKeyExch) != 0)
|
||||
{
|
||||
_masterKey = new byte[16];
|
||||
//RANDOM.NextBytes(masterKey);
|
||||
byte[] exchangedKey = new byte[16];
|
||||
Rc4 rc4 = new Rc4(userSessionKey);
|
||||
rc4.Update(_masterKey, 0, 16, exchangedKey, 0);
|
||||
SetSessionKey(exchangedKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
_masterKey = userSessionKey;
|
||||
SetSessionKey(_masterKey);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
SetLmResponse(GetLMResponse(type2, password));
|
||||
SetNtResponse(GetNTResponse(type2, password));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Creates a Type-3 message with the specified parameters.</summary>
|
||||
/// <remarks>Creates a Type-3 message with the specified parameters.</remarks>
|
||||
/// <param name="flags">The flags to apply to this message.</param>
|
||||
/// <param name="lmResponse">The LanManager/LMv2 response.</param>
|
||||
/// <param name="ntResponse">The NT/NTLMv2 response.</param>
|
||||
/// <param name="domain">The domain in which the user has an account.</param>
|
||||
/// <param name="user">The username for the authenticating user.</param>
|
||||
/// <param name="workstation">
|
||||
/// The workstation from which authentication is
|
||||
/// taking place.
|
||||
/// </param>
|
||||
public Type3Message(int flags, byte[] lmResponse, byte[] ntResponse, string domain
|
||||
, string user, string workstation)
|
||||
{
|
||||
SetFlags(flags);
|
||||
SetLmResponse(lmResponse);
|
||||
SetNtResponse(ntResponse);
|
||||
SetDomain(domain);
|
||||
SetUser(user);
|
||||
SetWorkstation(workstation);
|
||||
}
|
||||
|
||||
/// <summary>Creates a Type-3 message using the given raw Type-3 material.</summary>
|
||||
/// <remarks>Creates a Type-3 message using the given raw Type-3 material.</remarks>
|
||||
/// <param name="material">The raw Type-3 material used to construct this message.</param>
|
||||
/// <exception cref="System.IO.IOException">If an error occurs while parsing the material.
|
||||
/// </exception>
|
||||
public Type3Message(byte[] material)
|
||||
{
|
||||
Parse(material);
|
||||
}
|
||||
|
||||
/// <summary>Returns the LanManager/LMv2 response.</summary>
|
||||
/// <remarks>Returns the LanManager/LMv2 response.</remarks>
|
||||
/// <returns>A <code>byte[]</code> containing the LanManager response.</returns>
|
||||
public virtual byte[] GetLMResponse()
|
||||
{
|
||||
return _lmResponse;
|
||||
}
|
||||
|
||||
/// <summary>Sets the LanManager/LMv2 response for this message.</summary>
|
||||
/// <remarks>Sets the LanManager/LMv2 response for this message.</remarks>
|
||||
/// <param name="lmResponse">The LanManager response.</param>
|
||||
public virtual void SetLmResponse(byte[] lmResponse)
|
||||
{
|
||||
this._lmResponse = lmResponse;
|
||||
}
|
||||
|
||||
/// <summary>Returns the NT/NTLMv2 response.</summary>
|
||||
/// <remarks>Returns the NT/NTLMv2 response.</remarks>
|
||||
/// <returns>A <code>byte[]</code> containing the NT/NTLMv2 response.</returns>
|
||||
public virtual byte[] GetNTResponse()
|
||||
{
|
||||
return _ntResponse;
|
||||
}
|
||||
|
||||
/// <summary>Sets the NT/NTLMv2 response for this message.</summary>
|
||||
/// <remarks>Sets the NT/NTLMv2 response for this message.</remarks>
|
||||
/// <param name="ntResponse">The NT/NTLMv2 response.</param>
|
||||
public virtual void SetNtResponse(byte[] ntResponse)
|
||||
{
|
||||
this._ntResponse = ntResponse;
|
||||
}
|
||||
|
||||
/// <summary>Returns the domain in which the user has an account.</summary>
|
||||
/// <remarks>Returns the domain in which the user has an account.</remarks>
|
||||
/// <returns>A <code>String</code> containing the domain for the user.</returns>
|
||||
public virtual string GetDomain()
|
||||
{
|
||||
return _domain;
|
||||
}
|
||||
|
||||
/// <summary>Sets the domain for this message.</summary>
|
||||
/// <remarks>Sets the domain for this message.</remarks>
|
||||
/// <param name="domain">The domain.</param>
|
||||
public virtual void SetDomain(string domain)
|
||||
{
|
||||
this._domain = domain;
|
||||
}
|
||||
|
||||
/// <summary>Returns the username for the authenticating user.</summary>
|
||||
/// <remarks>Returns the username for the authenticating user.</remarks>
|
||||
/// <returns>A <code>String</code> containing the user for this message.</returns>
|
||||
public virtual string GetUser()
|
||||
{
|
||||
return _user;
|
||||
}
|
||||
|
||||
/// <summary>Sets the user for this message.</summary>
|
||||
/// <remarks>Sets the user for this message.</remarks>
|
||||
/// <param name="user">The user.</param>
|
||||
public virtual void SetUser(string user)
|
||||
{
|
||||
this._user = user;
|
||||
}
|
||||
|
||||
/// <summary>Returns the workstation from which authentication is being performed.</summary>
|
||||
/// <remarks>Returns the workstation from which authentication is being performed.</remarks>
|
||||
/// <returns>A <code>String</code> containing the workstation.</returns>
|
||||
public virtual string GetWorkstation()
|
||||
{
|
||||
return _workstation;
|
||||
}
|
||||
|
||||
/// <summary>Sets the workstation for this message.</summary>
|
||||
/// <remarks>Sets the workstation for this message.</remarks>
|
||||
/// <param name="workstation">The workstation.</param>
|
||||
public virtual void SetWorkstation(string workstation)
|
||||
{
|
||||
this._workstation = workstation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The real session key if the regular session key is actually
|
||||
/// the encrypted version used for key exchange.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The real session key if the regular session key is actually
|
||||
/// the encrypted version used for key exchange.
|
||||
/// </remarks>
|
||||
/// <returns>A <code>byte[]</code> containing the session key.</returns>
|
||||
public virtual byte[] GetMasterKey()
|
||||
{
|
||||
return _masterKey;
|
||||
}
|
||||
|
||||
/// <summary>Returns the session key.</summary>
|
||||
/// <remarks>Returns the session key.</remarks>
|
||||
/// <returns>A <code>byte[]</code> containing the session key.</returns>
|
||||
public virtual byte[] GetSessionKey()
|
||||
{
|
||||
return _sessionKey;
|
||||
}
|
||||
|
||||
/// <summary>Sets the session key.</summary>
|
||||
/// <remarks>Sets the session key.</remarks>
|
||||
/// <param name="sessionKey">The session key.</param>
|
||||
public virtual void SetSessionKey(byte[] sessionKey)
|
||||
{
|
||||
this._sessionKey = sessionKey;
|
||||
}
|
||||
|
||||
public override byte[] ToByteArray()
|
||||
{
|
||||
try
|
||||
{
|
||||
int flags = GetFlags();
|
||||
bool unicode = (flags & NtlmsspNegotiateUnicode) != 0;
|
||||
string oem = unicode ? null : GetOemEncoding();
|
||||
string domainName = GetDomain();
|
||||
byte[] domain = null;
|
||||
if (!string.IsNullOrEmpty(domainName))
|
||||
{
|
||||
domain = unicode ? Runtime.GetBytesForString(domainName, UniEncoding) :
|
||||
Runtime.GetBytesForString(domainName, oem);
|
||||
}
|
||||
int domainLength = (domain != null) ? domain.Length : 0;
|
||||
string userName = GetUser();
|
||||
byte[] user = null;
|
||||
if (!string.IsNullOrEmpty(userName))
|
||||
{
|
||||
user = unicode ? Runtime.GetBytesForString(userName, UniEncoding) : Runtime.GetBytesForString
|
||||
(userName.ToUpper(), oem);
|
||||
}
|
||||
int userLength = (user != null) ? user.Length : 0;
|
||||
string workstationName = GetWorkstation();
|
||||
byte[] workstation = null;
|
||||
if (!string.IsNullOrEmpty(workstationName))
|
||||
{
|
||||
workstation = unicode ? Runtime.GetBytesForString(workstationName, UniEncoding
|
||||
) : Runtime.GetBytesForString(workstationName.ToUpper(), oem);
|
||||
}
|
||||
int workstationLength = (workstation != null) ? workstation.Length : 0;
|
||||
byte[] lmResponse = GetLMResponse();
|
||||
int lmLength = (lmResponse != null) ? lmResponse.Length : 0;
|
||||
byte[] ntResponse = GetNTResponse();
|
||||
int ntLength = (ntResponse != null) ? ntResponse.Length : 0;
|
||||
byte[] sessionKey = GetSessionKey();
|
||||
int keyLength = (sessionKey != null) ? sessionKey.Length : 0;
|
||||
byte[] type3 = new byte[64 + domainLength + userLength + workstationLength + lmLength
|
||||
+ ntLength + keyLength];
|
||||
Array.Copy(NtlmsspSignature, 0, type3, 0, 8);
|
||||
WriteULong(type3, 8, 3);
|
||||
int offset = 64;
|
||||
WriteSecurityBuffer(type3, 12, offset, lmResponse);
|
||||
offset += lmLength;
|
||||
WriteSecurityBuffer(type3, 20, offset, ntResponse);
|
||||
offset += ntLength;
|
||||
WriteSecurityBuffer(type3, 28, offset, domain);
|
||||
offset += domainLength;
|
||||
WriteSecurityBuffer(type3, 36, offset, user);
|
||||
offset += userLength;
|
||||
WriteSecurityBuffer(type3, 44, offset, workstation);
|
||||
offset += workstationLength;
|
||||
WriteSecurityBuffer(type3, 52, offset, sessionKey);
|
||||
WriteULong(type3, 60, flags);
|
||||
return type3;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new InvalidOperationException(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string user = GetUser();
|
||||
string domain = GetDomain();
|
||||
string workstation = GetWorkstation();
|
||||
byte[] lmResponse = GetLMResponse();
|
||||
byte[] ntResponse = GetNTResponse();
|
||||
byte[] sessionKey = GetSessionKey();
|
||||
return "Type3Message[domain=" + domain + ",user=" + user + ",workstation=" + workstation
|
||||
+ ",lmResponse=" + (lmResponse == null ? "null" : "<" + lmResponse.Length + " bytes>"
|
||||
) + ",ntResponse=" + (ntResponse == null ? "null" : "<" + ntResponse.Length + " bytes>"
|
||||
) + ",sessionKey=" + (sessionKey == null ? "null" : "<" + sessionKey.Length + " bytes>"
|
||||
) + ",flags=0x" + Hexdump.ToHexString(GetFlags(), 8) + "]";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the default flags for a generic Type-3 message in the
|
||||
/// current environment.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Returns the default flags for a generic Type-3 message in the
|
||||
/// current environment.
|
||||
/// </remarks>
|
||||
/// <returns>An <code>int</code> containing the default flags.</returns>
|
||||
public static int GetDefaultFlags()
|
||||
{
|
||||
return DefaultFlags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the default flags for a Type-3 message created in response
|
||||
/// to the given Type-2 message in the current environment.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Returns the default flags for a Type-3 message created in response
|
||||
/// to the given Type-2 message in the current environment.
|
||||
/// </remarks>
|
||||
/// <returns>An <code>int</code> containing the default flags.</returns>
|
||||
public static int GetDefaultFlags(Type2Message type2)
|
||||
{
|
||||
if (type2 == null)
|
||||
{
|
||||
return DefaultFlags;
|
||||
}
|
||||
int flags = NtlmsspNegotiateNtlm;
|
||||
flags |= ((type2.GetFlags() & NtlmsspNegotiateUnicode) != 0) ? NtlmsspNegotiateUnicode
|
||||
: NtlmsspNegotiateOem;
|
||||
return flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the LanManager response to the given Type-2 message using
|
||||
/// the supplied password.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Constructs the LanManager response to the given Type-2 message using
|
||||
/// the supplied password.
|
||||
/// </remarks>
|
||||
/// <param name="type2">The Type-2 message.</param>
|
||||
/// <param name="password">The password.</param>
|
||||
/// <returns>A <code>byte[]</code> containing the LanManager response.</returns>
|
||||
public static byte[] GetLMResponse(Type2Message type2, string password)
|
||||
{
|
||||
if (type2 == null || password == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return NtlmPasswordAuthentication.GetPreNtlmResponse(password, type2.GetChallenge
|
||||
());
|
||||
}
|
||||
|
||||
public static byte[] GetLMv2Response(Type2Message type2, string domain, string user
|
||||
, string password, byte[] clientChallenge)
|
||||
{
|
||||
if (type2 == null || domain == null || user == null || password == null || clientChallenge
|
||||
== null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return NtlmPasswordAuthentication.GetLMv2Response(domain, user, password, type2.GetChallenge
|
||||
(), clientChallenge);
|
||||
}
|
||||
|
||||
public static byte[] GetNtlMv2Response(Type2Message type2, byte[] responseKeyNt,
|
||||
byte[] clientChallenge)
|
||||
{
|
||||
if (type2 == null || responseKeyNt == null || clientChallenge == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
long nanos1601 = (Runtime.CurrentTimeMillis() + MillisecondsBetween1970And1601
|
||||
) * 10000L;
|
||||
return NtlmPasswordAuthentication.GetNtlMv2Response(responseKeyNt, type2.GetChallenge
|
||||
(), clientChallenge, nanos1601, type2.GetTargetInformation());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the NT response to the given Type-2 message using
|
||||
/// the supplied password.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Constructs the NT response to the given Type-2 message using
|
||||
/// the supplied password.
|
||||
/// </remarks>
|
||||
/// <param name="type2">The Type-2 message.</param>
|
||||
/// <param name="password">The password.</param>
|
||||
/// <returns>A <code>byte[]</code> containing the NT response.</returns>
|
||||
public static byte[] GetNTResponse(Type2Message type2, string password)
|
||||
{
|
||||
if (type2 == null || password == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return NtlmPasswordAuthentication.GetNtlmResponse(password, type2.GetChallenge());
|
||||
}
|
||||
|
||||
/// <summary>Returns the default domain from the current environment.</summary>
|
||||
/// <remarks>Returns the default domain from the current environment.</remarks>
|
||||
/// <returns>The default domain.</returns>
|
||||
public static string GetDefaultDomain()
|
||||
{
|
||||
return DefaultDomain;
|
||||
}
|
||||
|
||||
/// <summary>Returns the default user from the current environment.</summary>
|
||||
/// <remarks>Returns the default user from the current environment.</remarks>
|
||||
/// <returns>The default user.</returns>
|
||||
public static string GetDefaultUser()
|
||||
{
|
||||
return DefaultUser;
|
||||
}
|
||||
|
||||
/// <summary>Returns the default password from the current environment.</summary>
|
||||
/// <remarks>Returns the default password from the current environment.</remarks>
|
||||
/// <returns>The default password.</returns>
|
||||
public static string GetDefaultPassword()
|
||||
{
|
||||
return DefaultPassword;
|
||||
}
|
||||
|
||||
/// <summary>Returns the default workstation from the current environment.</summary>
|
||||
/// <remarks>Returns the default workstation from the current environment.</remarks>
|
||||
/// <returns>The default workstation.</returns>
|
||||
public static string GetDefaultWorkstation()
|
||||
{
|
||||
return DefaultWorkstation;
|
||||
}
|
||||
|
||||
/// <exception cref="System.IO.IOException"></exception>
|
||||
private void Parse(byte[] material)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (material[i] != NtlmsspSignature[i])
|
||||
{
|
||||
throw new IOException("Not an NTLMSSP message.");
|
||||
}
|
||||
}
|
||||
if (ReadULong(material, 8) != 3)
|
||||
{
|
||||
throw new IOException("Not a Type 3 message.");
|
||||
}
|
||||
byte[] lmResponse = ReadSecurityBuffer(material, 12);
|
||||
int lmResponseOffset = ReadULong(material, 16);
|
||||
byte[] ntResponse = ReadSecurityBuffer(material, 20);
|
||||
int ntResponseOffset = ReadULong(material, 24);
|
||||
byte[] domain = ReadSecurityBuffer(material, 28);
|
||||
int domainOffset = ReadULong(material, 32);
|
||||
byte[] user = ReadSecurityBuffer(material, 36);
|
||||
int userOffset = ReadULong(material, 40);
|
||||
byte[] workstation = ReadSecurityBuffer(material, 44);
|
||||
int workstationOffset = ReadULong(material, 48);
|
||||
int flags;
|
||||
string charset;
|
||||
byte[] _sessionKey = null;
|
||||
if (lmResponseOffset == 52 || ntResponseOffset == 52 || domainOffset == 52 || userOffset
|
||||
== 52 || workstationOffset == 52)
|
||||
{
|
||||
flags = NtlmsspNegotiateNtlm | NtlmsspNegotiateOem;
|
||||
charset = GetOemEncoding();
|
||||
}
|
||||
else
|
||||
{
|
||||
_sessionKey = ReadSecurityBuffer(material, 52);
|
||||
flags = ReadULong(material, 60);
|
||||
charset = ((flags & NtlmsspNegotiateUnicode) != 0) ? UniEncoding : GetOemEncoding
|
||||
();
|
||||
}
|
||||
SetSessionKey(_sessionKey);
|
||||
SetFlags(flags);
|
||||
SetLmResponse(lmResponse);
|
||||
SetNtResponse(ntResponse);
|
||||
SetDomain(Runtime.GetStringForBytes(domain, charset));
|
||||
SetUser(Runtime.GetStringForBytes(user, charset));
|
||||
SetWorkstation(Runtime.GetStringForBytes(workstation, charset));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user