Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Pouliot <sebastien@ximian.com>2003-12-02 06:38:55 +0300
committerSebastien Pouliot <sebastien@ximian.com>2003-12-02 06:38:55 +0300
commitf5d4134bc9a77dc2ccc6a3708c82f2bdcdf9b8b5 (patch)
tree46684c05ba657739ebaa43c33fc87c86ded80aac /mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type3Message.cs
parent681d87fc108f0df5f9d6701e2a4421927f78d132 (diff)
2003-12-01 Sebastien Pouliot <spouliot@videotron.ca>
* ChallengeResponse.cs: New. Implements the NTLM (v1) Challenge Response. * MessageBase.cs: New. Abstract base class for NTLM messages. * NtlmFlags.cs: New. All known flags for NTLM. * Type1Message.cs: New. Negotiation message. * Type2Message.cs: New. Challenge message. * Type3Message.cs: New. Authentication message. svn path=/trunk/mcs/; revision=20676
Diffstat (limited to 'mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type3Message.cs')
-rwxr-xr-xmcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type3Message.cs223
1 files changed, 223 insertions, 0 deletions
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type3Message.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type3Message.cs
new file mode 100755
index 00000000000..972fa5c3513
--- /dev/null
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type3Message.cs
@@ -0,0 +1,223 @@
+//
+// Mono.Security.Protocol.Ntlm.Type3Message - Authentication
+//
+// Author:
+// Sebastien Pouliot (spouliot@motus.com)
+//
+// Copyright (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+//
+// References
+// a. NTLM Authentication Scheme for HTTP, Ronald Tschalär
+// http://www.innovation.ch/java/ntlm.html
+// b. The NTLM Authentication Protocol, Copyright © 2003 Eric Glass
+// http://davenport.sourceforge.net/ntlm.html
+//
+
+using System;
+using System.Text;
+
+namespace Mono.Security.Protocol.Ntlm {
+
+ public class Type3Message : MessageBase {
+
+ static private byte[] header = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00 };
+
+ private byte[] _challenge;
+ private string _host;
+ private string _domain;
+ private string _username;
+ private string _password;
+ private byte[] _lm;
+ private byte[] _nt;
+ private int _options;
+
+ public Type3Message () : base (3)
+ {
+ // default values
+ _domain = Environment.UserDomainName;
+ _host = Environment.MachineName;
+ _username = Environment.UserName;
+ _options = 0x8201;
+ }
+
+ public Type3Message (byte[] message) : base (3)
+ {
+ Decode (message);
+ }
+
+ ~Type3Message ()
+ {
+ if (_challenge != null)
+ Array.Clear (_challenge, 0, _challenge.Length);
+ if (_lm != null)
+ Array.Clear (_lm, 0, _lm.Length);
+ if (_nt != null)
+ Array.Clear (_nt, 0, _nt.Length);
+ }
+
+ // properties
+
+ public byte[] Challenge {
+ get {
+ if (_challenge == null)
+ return null;
+ return (byte[]) _challenge.Clone (); }
+ set {
+ if (value == null)
+ throw new ArgumentNullException ("Challenge");
+ if (value.Length != 8)
+ throw new ArgumentException ("Invalid Challenge Length");
+ _challenge = (byte[]) value.Clone ();
+ }
+ }
+
+ public string Domain {
+ get { return _domain; }
+ set { _domain = value; }
+ }
+
+ public string Host {
+ get { return _host; }
+ set { _host = value; }
+ }
+
+ public int Options {
+ get { return _options; }
+ set { _options = value; }
+ }
+
+ public string Password {
+ get { return _password; }
+ set { _password = value; }
+ }
+
+ public string Username {
+ get { return _username; }
+ set { _username = value; }
+ }
+
+ public byte[] LM {
+ get { return _lm; }
+ }
+
+ public byte[] NT {
+ get { return _nt; }
+ }
+
+ // methods
+
+ private void Decode (byte[] message)
+ {
+ if (message == null)
+ throw new ArgumentNullException ("message");
+
+ for (int i=0; i < header.Length; i++) {
+ if (message [i] != header [i])
+ throw new ArgumentException ("Invalid Type3 message");
+ }
+
+ if (BitConverter.ToUInt16 (message, 56) != message.Length)
+ throw new ArgumentException ("Invalid Type3 message length");
+
+ _password = null;
+
+ int dom_len = BitConverter.ToUInt16 (message, 28);
+ int dom_off = 64;
+ _domain = Encoding.Unicode.GetString (message, dom_off, dom_len);
+
+ int host_len = BitConverter.ToUInt16 (message, 44);
+ int host_off = BitConverter.ToUInt16 (message, 48);
+ _host = Encoding.Unicode.GetString (message, host_off, host_len);
+
+ int user_len = BitConverter.ToUInt16 (message, 36);
+ int user_off = BitConverter.ToUInt16 (message, 40);
+ _username = Encoding.Unicode.GetString (message, user_off, user_len);
+
+ _options = BitConverter.ToUInt16 (message, 60);
+
+ _lm = new byte [24];
+ int lm_off = BitConverter.ToUInt16 (message, 16);
+ Buffer.BlockCopy (message, lm_off, _lm, 0, 24);
+
+ _nt = new byte [24];
+ int nt_off = BitConverter.ToUInt16 (message, 24);
+ Buffer.BlockCopy (message, nt_off, _nt, 0, 24);
+
+ if (message.Length >= 64)
+ Flags = (NtlmFlags) BitConverter.ToUInt32 (message, 60);
+ }
+
+ public override byte[] GetBytes ()
+ {
+ byte[] domain = Encoding.Unicode.GetBytes (_domain.ToUpper ());
+ byte[] user = Encoding.Unicode.GetBytes (_username);
+ byte[] host = Encoding.Unicode.GetBytes (_host.ToUpper ());
+
+ byte[] data = new byte [64 + domain.Length + user.Length + host.Length + 24 + 24];
+ Buffer.BlockCopy (header, 0, data, 0, header.Length);
+
+ // LM response
+ short lmresp_off = (short)(64 + domain.Length + user.Length + host.Length);
+ data [16] = (byte) lmresp_off;
+ data [17] = (byte)(lmresp_off >> 8);
+
+ // NT response
+ short ntresp_off = (short)(lmresp_off + 24);
+ data [20] = (byte) 0x18;
+ data [21] = (byte) 0x00;
+ data [22] = (byte) 0x18;
+ data [23] = (byte) 0x00;
+ data [24] = (byte) ntresp_off;
+ data [25] = (byte)(ntresp_off >> 8);
+
+ // domain
+ short dom_len = (short)domain.Length;
+ short dom_off = 64;
+ data [28] = (byte) dom_len;
+ data [29] = (byte)(dom_len >> 8);
+ data [30] = data [28];
+ data [31] = data [29];
+ data [32] = (byte) dom_off;
+ data [33] = (byte)(dom_off >> 8);
+
+ // username
+ short uname_len = (short)user.Length;
+ short uname_off = (short)(dom_off + dom_len);
+ data [36] = (byte) uname_len;
+ data [37] = (byte)(uname_len >> 8);
+ data [38] = data [36];
+ data [39] = data [37];
+ data [40] = (byte) uname_off;
+ data [41] = (byte)(uname_off >> 8);
+
+ // host
+ short host_len = (short)host.Length;
+ short host_off = (short)(uname_off + uname_len);
+ data [44] = (byte) host_len;
+ data [45] = (byte)(host_len >> 8);
+ data [46] = data [44];
+ data [47] = data [45];
+ data [48] = (byte) host_off;
+ data [49] = (byte)(host_off >> 8);
+
+ // message length
+ short msg_len = (short)data.Length;
+ data [56] = (byte) msg_len;
+ data [57] = (byte)(msg_len >> 8);
+
+ // options flags
+ data [60] = (byte) _options;
+ data [61] = (byte)(_options >> 8);
+
+ Buffer.BlockCopy (domain, 0, data, dom_off, domain.Length);
+ Buffer.BlockCopy (user, 0, data, uname_off, user.Length);
+ Buffer.BlockCopy (host, 0, data, host_off, host.Length);
+
+ using (ChallengeResponse ntlm = new ChallengeResponse (_password, _challenge)) {
+ Buffer.BlockCopy (ntlm.LM, 0, data, lmresp_off, 24);
+ Buffer.BlockCopy (ntlm.NT, 0, data, ntresp_off, 24);
+ }
+ return data;
+ }
+ }
+}