AuthenticateMessage.cs 4.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using Utilities;
  11. namespace SMBLibrary.Authentication
  12. {
  13. /// <summary>
  14. /// [MS-NLMP] AUTHENTICATE_MESSAGE (Type 3 Message)
  15. /// </summary>
  16. public class AuthenticateMessage
  17. {
  18. public string Signature; // 8 bytes
  19. public MessageTypeName MessageType;
  20. public byte[] LmChallengeResponse;
  21. public byte[] NtChallengeResponse;
  22. public string DomainName;
  23. public string UserName;
  24. public string WorkStation;
  25. public byte[] EncryptedRandomSessionKey;
  26. public NegotiateFlags NegotiateFlags;
  27. public Version Version;
  28. // 16-byte MIC field is omitted for Windows NT / 2000 / XP / Server 2003
  29. public AuthenticateMessage()
  30. {
  31. Signature = AuthenticationMessageUtils.ValidSignature;
  32. MessageType = MessageTypeName.Authenticate;
  33. DomainName = String.Empty;
  34. UserName = String.Empty;
  35. WorkStation = String.Empty;
  36. EncryptedRandomSessionKey = new byte[0];
  37. }
  38. public AuthenticateMessage(byte[] buffer)
  39. {
  40. Signature = ByteReader.ReadAnsiString(buffer, 0, 8);
  41. MessageType = (MessageTypeName)LittleEndianConverter.ToUInt32(buffer, 8);
  42. LmChallengeResponse = AuthenticationMessageUtils.ReadBufferPointer(buffer, 12);
  43. NtChallengeResponse = AuthenticationMessageUtils.ReadBufferPointer(buffer, 20);
  44. DomainName = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 28);
  45. UserName = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 36);
  46. WorkStation = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 44);
  47. EncryptedRandomSessionKey = AuthenticationMessageUtils.ReadBufferPointer(buffer, 52);
  48. NegotiateFlags = (NegotiateFlags)LittleEndianConverter.ToUInt32(buffer, 60);
  49. if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0)
  50. {
  51. Version = new Version(buffer, 64);
  52. }
  53. }
  54. public byte[] GetBytes()
  55. {
  56. int fixedLength = 64;
  57. if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0)
  58. {
  59. fixedLength += 8;
  60. }
  61. int payloadLength = LmChallengeResponse.Length + NtChallengeResponse.Length + DomainName.Length * 2 + UserName.Length * 2 + WorkStation.Length * 2 + EncryptedRandomSessionKey.Length;
  62. byte[] buffer = new byte[fixedLength + payloadLength];
  63. ByteWriter.WriteAnsiString(buffer, 0, AuthenticationMessageUtils.ValidSignature, 8);
  64. LittleEndianWriter.WriteUInt32(buffer, 8, (uint)MessageType);
  65. LittleEndianWriter.WriteUInt32(buffer, 60, (uint)NegotiateFlags);
  66. if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0)
  67. {
  68. Version.WriteBytes(buffer, 64);
  69. }
  70. int offset = fixedLength;
  71. AuthenticationMessageUtils.WriteBufferPointer(buffer, 12, (ushort)LmChallengeResponse.Length, (uint)offset);
  72. ByteWriter.WriteBytes(buffer, ref offset, LmChallengeResponse);
  73. AuthenticationMessageUtils.WriteBufferPointer(buffer, 20, (ushort)NtChallengeResponse.Length, (uint)offset);
  74. ByteWriter.WriteBytes(buffer, ref offset, NtChallengeResponse);
  75. AuthenticationMessageUtils.WriteBufferPointer(buffer, 28, (ushort)(DomainName.Length * 2), (uint)offset);
  76. ByteWriter.WriteUTF16String(buffer, ref offset, DomainName);
  77. AuthenticationMessageUtils.WriteBufferPointer(buffer, 36, (ushort)(UserName.Length * 2), (uint)offset);
  78. ByteWriter.WriteUTF16String(buffer, ref offset, UserName);
  79. AuthenticationMessageUtils.WriteBufferPointer(buffer, 44, (ushort)(WorkStation.Length * 2), (uint)offset);
  80. ByteWriter.WriteUTF16String(buffer, ref offset, WorkStation);
  81. AuthenticationMessageUtils.WriteBufferPointer(buffer, 52, (ushort)EncryptedRandomSessionKey.Length, (uint)offset);
  82. ByteWriter.WriteBytes(buffer, ref offset, EncryptedRandomSessionKey);
  83. return buffer;
  84. }
  85. }
  86. }