public bool HandleNTLM(ref byte[] bytes, ref bool haveChallenge) { if (haveChallenge) { // FIXME: We don't actually check the result. var message = new Type3Message(bytes); if (message.Type != 3) { throw new InvalidOperationException(); } return(true); } else { var message = new Type1Message(bytes); if (message.Type != 1) { throw new InvalidOperationException(); } var type2 = new Type2Message(); haveChallenge = true; bytes = type2.GetBytes(); return(false); } }
public bool HandleNTLM(ref byte[] bytes) { var type = MessageBase.GetType(bytes); if (type < 0) { throw new InvalidOperationException(); } if (type == 3) { // FIXME: We don't actually check the result. var message = new Type3Message(bytes); if (message.Type != 3) { throw new InvalidOperationException(); } return(true); } if (type == 1) { var message = new Type1Message(bytes); if (message.Type != 1) { throw new InvalidOperationException(); } var type2 = new Type2Message(); bytes = type2.GetBytes(); return(false); } throw new InvalidOperationException(); }
public byte [] ProcessMessageType1() { Type1Message type1 = new Type1Message(NtlmVersion.Version3); type1.Flags = unchecked ((NtlmFlags)0xE21882B7); return(type1.GetBytes()); }
public void SerializeType1Message() { Type1Message msg = new Type1Message("myDomain", "myWorkstation"); byte[] serialized = msg.Serialize(); Assert.IsTrue(type1Message.SequenceEqual(serialized)); }
// Class(60) { // OID(spnego), // Class(A0) { // Class(30) { // Class(A0) { // Class(30) { OID,OID,OID} }, // Class(A2) { OctetStream } } } } public byte [] ProcessSpnegoInitialContextTokenRequest() { Type1Message type1 = new Type1Message(NtlmVersion.Version3); type1.Flags = unchecked ((NtlmFlags)0xE21882B7); type1.Domain = "WORKGROUP"; // FIXME: remove it ASN1 asn = new ASN1(0x60); ASN1 asn2 = new ASN1(0xA0); ASN1 asn21 = new ASN1(0x30); ASN1 asn211 = new ASN1(0xA0); ASN1 asn2111 = new ASN1(0x30); asn211.Add(asn2111); asn2111.Add(ASN1Convert.FromOid(Constants.OidNtlmSsp)); asn2111.Add(ASN1Convert.FromOid(Constants.OidKerberos5)); asn2111.Add(ASN1Convert.FromOid(Constants.OidMIT)); ASN1 asn212 = new ASN1(0xA2); ASN1 asn2121 = new ASN1(0x4); asn2121.Value = type1.GetBytes(); asn212.Add(asn2121); asn21.Add(asn211); asn21.Add(asn212); asn2.Add(asn21); asn.Add(ASN1Convert.FromOid(Constants.OidSpnego)); asn.Add(asn2); return(asn.GetBytes()); }
static MessageBase GetInitialResponse(string domain) { var type1 = new Type1Message(string.Empty, domain); type1.Flags |= NtlmFlags.NegotiateNtlm2Key; return(type1); }
// Example from http://www.innovation.ch/java/ntlm.html public void Encode1() { Type1Message msg = new Type1Message(); AssertEquals("Type", 1, msg.Type); msg.Domain = "Ursa-Minor"; msg.Host = "LightCity"; AssertEquals("GetBytes", "4E-54-4C-4D-53-53-50-00-01-00-00-00-03-B2-00-00-0A-00-0A-00-29-00-00-00-09-00-09-00-20-00-00-00-4C-49-47-48-54-43-49-54-59-55-52-53-41-2D-4D-49-4E-4F-52", BitConverter.ToString(msg.GetBytes())); }
// Example from http://davenport.sourceforge.net/ntlm.html#type1MessageExample public void Decode2() { byte[] data = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x32, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x20, 0x00, 0x00, 0x00, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x44, 0x4f, 0x4d, 0x41, 0x49, 0x4e }; Type1Message msg = new Type1Message(data); AssertEquals("Domain", "DOMAIN", msg.Domain); AssertEquals("Flags", (NtlmFlags)0x3207, msg.Flags); AssertEquals("Host", "WORKSTATION", msg.Host); AssertEquals("Type", 1, msg.Type); }
// Example from http://www.innovation.ch/java/ntlm.html public void Decode1() { byte[] data = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xb2, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, 0x09, 0x00, 0x09, 0x00, 0x20, 0x00, 0x00, 0x00, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x43, 0x49, 0x54, 0x59, 0x55, 0x52, 0x53, 0x41, 0x2d, 0x4d, 0x49, 0x4e, 0x4f, 0x52 }; Type1Message msg = new Type1Message(data); AssertEquals("Domain", "URSA-MINOR", msg.Domain); AssertEquals("Flags", (NtlmFlags)0xb203, msg.Flags); AssertEquals("Host", "LIGHTCITY", msg.Host); AssertEquals("Type", 1, msg.Type); }
// Example from http://www.innovation.ch/java/ntlm.html public void Decode1() { byte[] data = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xb2, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, 0x09, 0x00, 0x09, 0x00, 0x20, 0x00, 0x00, 0x00, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x43, 0x49, 0x54, 0x59, 0x55, 0x52, 0x53, 0x41, 0x2d, 0x4d, 0x49, 0x4e, 0x4f, 0x52 }; Type1Message msg = new Type1Message(data); Assert.AreEqual("URSA-MINOR", msg.Domain, "Domain"); Assert.AreEqual((NtlmFlags)0xb203, msg.Flags, "Flags"); Assert.AreEqual("LIGHTCITY", msg.Host, "Host"); Assert.AreEqual(1, msg.Type, "Type"); }
// Example from http://davenport.sourceforge.net/ntlm.html#type1MessageExample public void Decode2() { byte[] data = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x32, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x20, 0x00, 0x00, 0x00, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x44, 0x4f, 0x4d, 0x41, 0x49, 0x4e }; Type1Message msg = new Type1Message(data); Assert.AreEqual("DOMAIN", msg.Domain, "Domain"); Assert.AreEqual((NtlmFlags)0x3207, msg.Flags, "Flags"); Assert.AreEqual("WORKSTATION", msg.Host, "Host"); Assert.AreEqual(1, msg.Type, "Type"); }
public void TestNtlmType1MessageDecode() { var flags = NtlmFlags.NegotiateUnicode | NtlmFlags.NegotiateDomainSupplied | NtlmFlags.NegotiateWorkstationSupplied | NtlmFlags.NegotiateNtlm | NtlmFlags.NegotiateOem | NtlmFlags.RequestTarget; var type1 = new Type1Message(NtlmType1EncodedMessage, 0, NtlmType1EncodedMessage.Length); Assert.AreEqual(flags, type1.Flags, "The expected flags do not match."); Assert.AreEqual("WORKSTATION", type1.Host, "The expected workstation name does not match."); Assert.AreEqual("DOMAIN", type1.Domain, "The expected domain does not match."); Assert.AreEqual(new Version(5, 0, 2195), type1.OSVersion, "The expected OS Version does not match."); }
public void TestNtlmType1MessageEncode() { var type1 = new Type1Message("Workstation", "Domain", new Version(5, 0, 2195)); var encoded = type1.Encode(); string actual, expected; expected = HexEncode(NtlmType1EncodedMessage); actual = HexEncode(encoded); Assert.AreEqual(expected, actual, "The encoded Type1Message did not match the expected result."); }
public NtlmContext(NtlmPasswordAuthentication auth, bool doSigning) { this.Auth = auth; NtlmsspFlags = NtlmsspFlags | NtlmFlags.NtlmsspRequestTarget | NtlmFlags.NtlmsspNegotiateNtlm2 | NtlmFlags.NtlmsspNegotiate128; if (doSigning) { NtlmsspFlags |= NtlmFlags.NtlmsspNegotiateSign | NtlmFlags.NtlmsspNegotiateAlwaysSign | NtlmFlags.NtlmsspNegotiateKeyExch; } Workstation = Type1Message.GetDefaultWorkstation(); Log = LogStream.GetInstance(); }
/// <summary> /// Computes the initial client response to an NTLM challenge. /// </summary> /// <param name="challenge">The challenge sent by the server. Since /// NTLM expects an initial client response, this will usually be /// empty.</param> /// <returns>The initial response to the NTLM challenge.</returns> /// <exception cref="SaslException">Thrown if the response could not /// be computed.</exception> protected byte[] ComputeInitialResponse(byte[] challenge) { try { string domain = Properties.ContainsKey("Domain") ? Properties["Domain"] as string : "domain"; string workstation = Properties.ContainsKey("Workstation") ? Properties["Workstation"] as string : "workstation"; Type1Message msg = new Type1Message(domain, workstation); return(msg.Serialize()); } catch (Exception e) { throw new SaslException("The initial client response could not " + "be computed.", e); } }
/// <summary> /// Parses the server's challenge token and returns the next challenge response. /// </summary> /// <remarks> /// Parses the server's challenge token and returns the next challenge response. /// </remarks> /// <returns>The next challenge response.</returns> /// <param name="token">The server's challenge token.</param> /// <param name="startIndex">The index into the token specifying where the server's challenge begins.</param> /// <param name="length">The length of the server's challenge.</param> /// <exception cref="System.InvalidOperationException"> /// The SASL mechanism is already authenticated. /// </exception> /// <exception cref="SaslException"> /// An error has occurred while parsing the server's challenge token. /// </exception> protected override byte[] Challenge(byte[] token, int startIndex, int length) { if (IsAuthenticated) { throw new InvalidOperationException(); } string userName = Credentials.UserName; string domain = Credentials.Domain; MessageBase message; if (string.IsNullOrEmpty(domain)) { int index = userName.IndexOf('\\'); if (index == -1) { index = userName.IndexOf('/'); } if (index >= 0) { domain = userName.Substring(0, index); userName = userName.Substring(index + 1); } } switch (state) { case LoginState.Initial: message = new Type1Message(Workstation, domain); state = LoginState.Challenge; break; case LoginState.Challenge: var password = Credentials.Password ?? string.Empty; message = GetChallengeResponse(userName, password, token, startIndex, length); IsAuthenticated = true; break; default: throw new IndexOutOfRangeException("state"); } return(message.Encode()); }
static void AssertNtlmAuthNoDomain(SaslMechanismNtlm sasl, string prefix) { string challenge; byte [] decoded; Assert.IsTrue(sasl.SupportsInitialResponse, "{0}: SupportsInitialResponse", prefix); challenge = sasl.Challenge(string.Empty); decoded = Convert.FromBase64String(challenge); var type1 = new Type1Message(decoded, 0, decoded.Length); Assert.AreEqual(Type1Message.DefaultFlags, type1.Flags, "{0}: Expected initial NTLM client challenge flags do not match.", prefix); Assert.AreEqual(string.Empty, type1.Domain, "{0}: Expected initial NTLM client challenge domain does not match.", prefix); Assert.AreEqual(string.Empty, type1.Host, "{0}: Expected initial NTLM client challenge host does not match.", prefix); Assert.IsFalse(sasl.IsAuthenticated, "{0}: NTLM should not be authenticated.", prefix); }
public void TestNtlmAuthNoDomain() { var credentials = new NetworkCredential("username", "password"); var uri = new Uri("imap://imap.gmail.com"); var sasl = new SaslMechanismNtlm(uri, credentials); string challenge; byte[] decoded; challenge = sasl.Challenge(string.Empty); decoded = Convert.FromBase64String(challenge); var type1 = new Type1Message(decoded, 0, decoded.Length); Assert.AreEqual(Type1Message.DefaultFlags, type1.Flags, "Expected initial NTLM client challenge flags do not match."); Assert.AreEqual(string.Empty, type1.Domain, "Expected initial NTLM client challenge domain does not match."); Assert.AreEqual(string.Empty, type1.Host, "Expected initial NTLM client challenge host does not match."); Assert.IsFalse(sasl.IsAuthenticated, "NTLM should not be authenticated."); }
public void TestNtlmAuthWithDomain() { const NtlmFlags initialFlags = NtlmFlags.NegotiateUnicode | NtlmFlags.NegotiateOem | NtlmFlags.NegotiateNtlm | NtlmFlags.NegotiateNtlm2Key | NtlmFlags.RequestTarget | NtlmFlags.NegotiateDomainSupplied; var credentials = new NetworkCredential("domain\\username", "password"); var uri = new Uri("imap://imap.gmail.com"); var sasl = new SaslMechanismNtlm(uri, credentials); string challenge; byte[] decoded; challenge = sasl.Challenge(string.Empty); decoded = Convert.FromBase64String(challenge); var type1 = new Type1Message(decoded, 0, decoded.Length); Assert.AreEqual(initialFlags, type1.Flags, "Expected initial NTLM client challenge flags do not match."); Assert.AreEqual("DOMAIN", type1.Domain, "Expected initial NTLM client challenge domain does not match."); Assert.AreEqual(string.Empty, type1.Host, "Expected initial NTLM client challenge host does not match."); Assert.IsFalse(sasl.IsAuthenticated, "NTLM should not be authenticated."); }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> public virtual byte[] InitSecContext(byte[] token, int offset, int len) { switch (State) { case 1: { Type1Message msg1 = new Type1Message(NtlmsspFlags, Auth.GetDomain(), Workstation); token = msg1.ToByteArray(); if (Log.Level >= 4) { Log.WriteLine(msg1); if (Log.Level >= 6) { Hexdump.ToHexdump(Log, token, 0, token.Length); } } State++; break; } case 2: { try { Type2Message msg2 = new Type2Message(token); if (Log.Level >= 4) { Log.WriteLine(msg2); if (Log.Level >= 6) { Hexdump.ToHexdump(Log, token, 0, token.Length); } } ServerChallenge = msg2.GetChallenge(); NtlmsspFlags &= msg2.GetFlags(); //netbiosName = getNtlmsspListItem(token, 0x0001); Type3Message msg3 = new Type3Message(msg2, Auth.GetPassword(), Auth.GetDomain(), Auth.GetUsername(), Workstation, NtlmsspFlags); token = msg3.ToByteArray(); if (Log.Level >= 4) { Log.WriteLine(msg3); if (Log.Level >= 6) { Hexdump.ToHexdump(Log, token, 0, token.Length); } } if ((NtlmsspFlags & NtlmFlags.NtlmsspNegotiateSign) != 0) { SigningKey = msg3.GetMasterKey(); } isEstablished = true; State++; break; } catch (Exception e) { throw new SmbException(e.Message, e); } } default: { throw new SmbException("Invalid state"); } } return token; }
public Authorization Authenticate(string challenge, WebRequest webRequest, ICredentials credentials) { HttpWebRequest request = webRequest as HttpWebRequest; if (request == null) { return(null); } NetworkCredential cred = credentials.GetCredential(request.RequestUri, "NTLM"); if (cred == null) { return(null); } string userName = cred.UserName; string domain = cred.Domain; string password = cred.Password; if (userName == null || userName == "") { return(null); } domain = domain != null && domain.Length > 0 ? domain : request.Headers ["Host"]; bool completed = false; if (message == null) { Type1Message type1 = new Type1Message(); type1.Domain = domain; message = type1; } else if (message.Type == 1) { // Should I check the credentials? if (challenge == null) { message = null; return(null); } Type2Message type2 = new Type2Message(Convert.FromBase64String(challenge)); if (password == null) { password = ""; } Type3Message type3 = new Type3Message(); type3.Domain = domain; type3.Username = userName; type3.Challenge = type2.Nonce; type3.Password = password; message = type3; completed = true; } else { // Should I check the credentials? // type must be 3 here if (challenge == null || challenge == String.Empty) { Type1Message type1 = new Type1Message(); type1.Domain = domain; message = type1; } else { completed = true; } } string token = "NTLM " + Convert.ToBase64String(message.GetBytes()); return(new Authorization(token, completed)); }
public HttpResponse HandleAuthentication(HttpRequest request, string authHeader) { if (AuthenticationType == AuthenticationType.ForceNone) { // Must not contain any auth header if (authHeader == null) { return(null); } return(OnError("Must not contain any auth header.")); } if (authHeader == null) { haveChallenge = false; return(OnUnauthenticated(request, AuthenticationType.ToString(), AuthenticationType == AuthenticationType.NTLM)); } int pos = authHeader.IndexOf(' '); var mode = authHeader.Substring(0, pos); var arg = authHeader.Substring(pos + 1); if (!mode.Equals(AuthenticationType.ToString())) { return(OnError("Invalid authentication scheme: {0}", mode)); } if (mode.Equals("Basic")) { if (arg.Equals("eGFtYXJpbjptb25rZXk=")) { return(null); } return(OnError("Invalid Basic Authentication header")); } else if (!mode.Equals("NTLM")) { return(OnError("Invalid authentication scheme: {0}", mode)); } var bytes = Convert.FromBase64String(arg); if (haveChallenge) { // FIXME: We don't actually check the result. var message = new Type3Message(bytes); if (message.Type != 3) { throw new InvalidOperationException(); } return(null); } else { var message = new Type1Message(bytes); if (message.Type != 1) { throw new InvalidOperationException(); } var type2 = new Type2Message(); var token = "NTLM " + Convert.ToBase64String(type2.GetBytes()); haveChallenge = true; return(OnUnauthenticated(request, token, false)); } }
public Authorization Authenticate (string challenge, WebRequest webRequest, ICredentials credentials) { HttpWebRequest request = webRequest as HttpWebRequest; if (request == null) return null; NetworkCredential cred = credentials.GetCredential (request.RequestUri, "NTLM"); if (cred == null) return null; string userName = cred.UserName; string domain = cred.Domain; string password = cred.Password; if (userName == null || userName == "") return null; if (String.IsNullOrEmpty (domain)) { int idx = userName.IndexOf ('\\'); if (idx == -1) { idx = userName.IndexOf ('/'); } if (idx >= 0) { domain = userName.Substring (0, idx); userName = userName.Substring (idx + 1); } } bool completed = false; if (message == null) { Type1Message type1 = new Type1Message (); type1.Domain = domain; type1.Host = ""; // MS does not send it type1.Flags |= NtlmFlags.NegotiateNtlm2Key; message = type1; } else if (message.Type == 1) { // Should I check the credentials? if (challenge == null) { message = null; return null; } Type2Message type2 = new Type2Message (Convert.FromBase64String (challenge)); if (password == null) password = ""; Type3Message type3 = new Type3Message (type2); type3.Username = userName; type3.Password = password; type3.Domain = domain; message = type3; completed = true; } else { // Should I check the credentials? // type must be 3 here if (challenge == null || challenge == String.Empty) { Type1Message type1 = new Type1Message (); type1.Domain = domain; type1.Host = ""; // MS does not send it message = type1; } else { completed = true; } } string token = "NTLM " + Convert.ToBase64String (message.GetBytes ()); return new Authorization (token, completed); }
public Authorization Authenticate(string challenge, WebRequest webRequest, ICredentials credentials) { HttpWebRequest request = webRequest as HttpWebRequest; if (request == null) { return(null); } NetworkCredential cred = credentials.GetCredential(request.RequestUri, "NTLM"); if (cred == null) { return(null); } string userName = cred.UserName; string domain = cred.Domain; string password = cred.Password; if (userName == null || userName == "") { return(null); } if (String.IsNullOrEmpty(domain)) { int idx = userName.IndexOf('\\'); if (idx == -1) { idx = userName.IndexOf('/'); } if (idx >= 0) { domain = userName.Substring(0, idx); userName = userName.Substring(idx + 1); } } bool completed = false; if (message == null) { Type1Message type1 = new Type1Message(); type1.Domain = domain; type1.Host = ""; // MS does not send it type1.Flags |= NtlmFlags.NegotiateNtlm2Key; message = type1; } else if (message.Type == 1) { // Should I check the credentials? if (challenge == null) { message = null; return(null); } Type2Message type2 = new Type2Message(Convert.FromBase64String(challenge)); if (password == null) { password = ""; } Type3Message type3 = new Type3Message(type2); type3.Username = userName; type3.Password = password; message = type3; completed = true; } else { // Should I check the credentials? // type must be 3 here if (challenge == null || challenge == String.Empty) { Type1Message type1 = new Type1Message(); type1.Domain = domain; type1.Host = ""; // MS does not send it message = type1; } else { completed = true; } } string token = "NTLM " + Convert.ToBase64String(message.GetBytes()); return(new Authorization(token, completed)); }
public void ProcessMessageType1(byte [] raw) { type1 = new Type1Message(raw, NtlmVersion.Version3); }