SessionSetupAndXRequestExtended.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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.SMB1
  12. {
  13. /// <summary>
  14. /// SMB_COM_SESSION_SETUP_ANDX Extended Request
  15. /// </summary>
  16. public class SessionSetupAndXRequestExtended : SMBAndXCommand
  17. {
  18. public const int ParametersLength = 24;
  19. // Parameters:
  20. public ushort MaxBufferSize;
  21. public ushort MaxMpxCount;
  22. public ushort VcNumber;
  23. public uint SessionKey;
  24. private ushort SecurityBlobLength;
  25. public uint Reserved;
  26. public Capabilities Capabilities;
  27. // Data:
  28. public byte[] SecurityBlob;
  29. public string NativeOS; // SMB_STRING (If Unicode, this field MUST be aligned to start on a 2-byte boundary from the start of the SMB header)
  30. public string NativeLanMan; // SMB_STRING (this field WILL be aligned to start on a 2-byte boundary from the start of the SMB header)
  31. public SessionSetupAndXRequestExtended(): base()
  32. {
  33. NativeOS = String.Empty;
  34. NativeLanMan = String.Empty;
  35. }
  36. public SessionSetupAndXRequestExtended(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
  37. {
  38. MaxBufferSize = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
  39. MaxMpxCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 6);
  40. VcNumber = LittleEndianConverter.ToUInt16(this.SMBParameters, 8);
  41. SessionKey = LittleEndianConverter.ToUInt32(this.SMBParameters, 10);
  42. SecurityBlobLength = LittleEndianConverter.ToUInt16(this.SMBParameters, 14);
  43. Reserved = LittleEndianConverter.ToUInt32(this.SMBParameters, 16);
  44. Capabilities = (Capabilities)LittleEndianConverter.ToUInt32(this.SMBParameters, 20);
  45. SecurityBlob = ByteReader.ReadBytes(this.SMBData, 0, SecurityBlobLength);
  46. int dataOffset = SecurityBlob.Length;
  47. if (isUnicode)
  48. {
  49. // A Unicode string MUST be aligned to a 16-bit boundary with respect to the beginning of the SMB Header.
  50. // Note: SMBData starts at an odd offset.
  51. int padding = (1 + SecurityBlobLength) % 2;
  52. dataOffset += padding;
  53. }
  54. NativeOS = SMB1Helper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
  55. NativeLanMan = SMB1Helper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
  56. }
  57. public override byte[] GetBytes(bool isUnicode)
  58. {
  59. Capabilities |= Capabilities.ExtendedSecurity;
  60. SecurityBlobLength = (ushort)SecurityBlob.Length;
  61. this.SMBParameters = new byte[ParametersLength];
  62. LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, MaxBufferSize);
  63. LittleEndianWriter.WriteUInt16(this.SMBParameters, 6, MaxMpxCount);
  64. LittleEndianWriter.WriteUInt16(this.SMBParameters, 8, VcNumber);
  65. LittleEndianWriter.WriteUInt32(this.SMBParameters, 10, SessionKey);
  66. LittleEndianWriter.WriteUInt16(this.SMBParameters, 14, SecurityBlobLength);
  67. LittleEndianWriter.WriteUInt32(this.SMBParameters, 16, Reserved);
  68. LittleEndianWriter.WriteUInt32(this.SMBParameters, 20, (uint)Capabilities);
  69. int padding = 0;
  70. if (isUnicode)
  71. {
  72. // A Unicode string MUST be aligned to a 16-bit boundary with respect to the beginning of the SMB Header.
  73. // Note: SMBData starts at an odd offset.
  74. padding = (1 + SecurityBlobLength) % 2;
  75. this.SMBData = new byte[SecurityBlob.Length + padding + (NativeOS.Length + 1) * 2 + (NativeLanMan.Length + 1) * 2];
  76. }
  77. else
  78. {
  79. this.SMBData = new byte[SecurityBlob.Length + NativeOS.Length + 1 + NativeLanMan.Length + 1];
  80. }
  81. int offset = 0;
  82. ByteWriter.WriteBytes(this.SMBData, ref offset, SecurityBlob);
  83. offset += padding;
  84. SMB1Helper.WriteSMBString(this.SMBData, ref offset, isUnicode, NativeOS);
  85. SMB1Helper.WriteSMBString(this.SMBData, ref offset, isUnicode, NativeLanMan);
  86. return base.GetBytes(isUnicode);
  87. }
  88. public override CommandName CommandName
  89. {
  90. get
  91. {
  92. return CommandName.SMB_COM_SESSION_SETUP_ANDX;
  93. }
  94. }
  95. }
  96. }