ChallengeMessage.cs 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /* Copyright (C) 2014-2017 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.NTLM
  12. {
  13. /// <summary>
  14. /// [MS-NLMP] CHALLENGE_MESSAGE (Type 2 Message)
  15. /// </summary>
  16. public class ChallengeMessage
  17. {
  18. public string Signature; // 8 bytes
  19. public MessageTypeName MessageType;
  20. public string TargetName;
  21. public NegotiateFlags NegotiateFlags;
  22. public byte[] ServerChallenge; // 8 bytes
  23. // Reserved - 8 bytes
  24. public KeyValuePairList<AVPairKey, byte[]> TargetInfo = new KeyValuePairList<AVPairKey,byte[]>();
  25. public NTLMVersion Version;
  26. public ChallengeMessage()
  27. {
  28. Signature = AuthenticateMessage.ValidSignature;
  29. MessageType = MessageTypeName.Challenge;
  30. }
  31. public ChallengeMessage(byte[] buffer)
  32. {
  33. Signature = ByteReader.ReadAnsiString(buffer, 0, 8);
  34. MessageType = (MessageTypeName)LittleEndianConverter.ToUInt32(buffer, 8);
  35. TargetName = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 12);
  36. NegotiateFlags = (NegotiateFlags)LittleEndianConverter.ToUInt32(buffer, 20);
  37. ServerChallenge = ByteReader.ReadBytes(buffer, 24, 8);
  38. // Reserved
  39. byte[] targetInfoBytes = AuthenticationMessageUtils.ReadBufferPointer(buffer, 40);
  40. if (targetInfoBytes.Length > 0)
  41. {
  42. TargetInfo = AVPairUtils.ReadAVPairSequence(targetInfoBytes, 0);
  43. }
  44. if ((NegotiateFlags & NegotiateFlags.Version) > 0)
  45. {
  46. Version = new NTLMVersion(buffer, 48);
  47. }
  48. }
  49. public byte[] GetBytes()
  50. {
  51. if ((NegotiateFlags & NegotiateFlags.TargetNameSupplied) == 0)
  52. {
  53. TargetName = String.Empty;
  54. }
  55. byte[] targetInfoBytes = AVPairUtils.GetAVPairSequenceBytes(TargetInfo);
  56. if ((NegotiateFlags & NegotiateFlags.TargetInfo) == 0)
  57. {
  58. targetInfoBytes = new byte[0];
  59. }
  60. int fixedLength = 48;
  61. if ((NegotiateFlags & NegotiateFlags.Version) > 0)
  62. {
  63. fixedLength += 8;
  64. }
  65. int payloadLength = TargetName.Length * 2 + targetInfoBytes.Length;
  66. byte[] buffer = new byte[fixedLength + payloadLength];
  67. ByteWriter.WriteAnsiString(buffer, 0, AuthenticateMessage.ValidSignature, 8);
  68. LittleEndianWriter.WriteUInt32(buffer, 8, (uint)MessageType);
  69. LittleEndianWriter.WriteUInt32(buffer, 20, (uint)NegotiateFlags);
  70. ByteWriter.WriteBytes(buffer, 24, ServerChallenge);
  71. if ((NegotiateFlags & NegotiateFlags.Version) > 0)
  72. {
  73. Version.WriteBytes(buffer, 48);
  74. }
  75. int offset = fixedLength;
  76. AuthenticationMessageUtils.WriteBufferPointer(buffer, 12, (ushort)(TargetName.Length * 2), (uint)offset);
  77. ByteWriter.WriteUTF16String(buffer, ref offset, TargetName);
  78. AuthenticationMessageUtils.WriteBufferPointer(buffer, 40, (ushort)targetInfoBytes.Length, (uint)offset);
  79. ByteWriter.WriteBytes(buffer, ref offset, targetInfoBytes);
  80. return buffer;
  81. }
  82. }
  83. }