/// <summary>
 /// Constructor.
 /// </summary>
 public CifsServerPerConnection()
 {
     this.signingSessionKey = new byte[0];
     this.signingChallengeResponse = new byte[0];
     this.ntlmChallenge = new byte[8];
     new Random().NextBytes(this.ntlmChallenge);
     this.sessionTable = new Dictionary<ushort, IFileServiceServerSession>();
     this.pendingRequestTable = new Dictionary<ushort,SmbFamilyPacket>();
     this.serverNextReceiveSequenceNumber = 2;
     this.serverSendSequenceNumbers = new Dictionary<ushort, ulong>();
     this.negotiateTime = new FileTime();
 }
        public SmbNtCreateAndxResponsePacket CreateNtCreateAndxResponse(
            CifsServerPerConnection connection,
            SmbNtCreateAndxRequestPacket request,
            OplockLevelValue opLockLevel,
            ulong allocationSize,
            ulong endOfFile,
            FileTypeValue resourceType,
            SMB_NMPIPE_STATUS nmPipeStatus,
            byte directory,
            SmbPacket andxPacket)
        {
            SmbNtCreateAndxResponsePacket response = new SmbNtCreateAndxResponsePacket();
            response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request);

            SMB_COM_NT_CREATE_ANDX_Response_SMB_Parameters smbParameters = response.SmbParameters;
            smbParameters.AndXCommand =
                andxPacket != null ? andxPacket.SmbHeader.Command : SmbCommand.SMB_COM_NO_ANDX_COMMAND;
            smbParameters.AndXReserved = 0x00;
            smbParameters.AndXOffset = (ushort)(response.HeaderSize + Marshal.SizeOf(response.SmbParameters)
                + Marshal.SizeOf(response.SmbData));
            smbParameters.OplockLevel = opLockLevel;
            smbParameters.FID = (ushort)connection.GenerateFID();
            smbParameters.CreateDisposition = NtTransactCreateDisposition.FILE_CREATE;
            FileTime fileTime = new FileTime();
            fileTime.Time = (ulong)DateTime.Now.ToFileTime();
            smbParameters.CreateTime = fileTime;
            smbParameters.LastAccessTime = fileTime;
            smbParameters.LastChangeTime = fileTime;
            smbParameters.ExtFileAttributes = (SMB_EXT_FILE_ATTR)request.SmbParameters.ExtFileAttributes;
            smbParameters.AllocationSize = allocationSize;
            smbParameters.EndOfFile = endOfFile;
            smbParameters.ResourceType = resourceType;
            smbParameters.NMPipeStatus = nmPipeStatus;
            smbParameters.Directory = directory;
            smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2);
            response.SmbParameters = smbParameters;

            response.AndxPacket = andxPacket;
            response.UpdateHeader();

            return response;
        }
        public SmbNtTransactCreateResponsePacket CreateNtTransactCreateResponse(
            CifsServerPerConnection connection,
            SmbNtTransactCreateRequestPacket request,
            ulong allocationSize,
            ulong endOfFile,
            FileTypeValue resourceType,
            SMB_NMPIPE_STATUS nmPipeStatus,
            byte directory)
        {
            SmbNtTransactCreateResponsePacket response = new SmbNtTransactCreateResponsePacket();
            response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request);

            NT_TRANSACT_CREATE_Response_NT_Trans_Parameters ntTransParameters = response.NtTransParameters;
            ntTransParameters.OpLockLevel = OplockLevelValue.None;
            ntTransParameters.Reserved = 0x00;
            ntTransParameters.FID = (ushort)connection.GenerateFID();
            ntTransParameters.CreateAction = NtTransactCreateActionValues.FILE_CREATED;
            FileTime fileTime = new FileTime();
            fileTime.Time = (ulong)DateTime.Now.ToFileTime();
            ntTransParameters.CreationTime = fileTime;
            ntTransParameters.LastAccessTime = fileTime;
            ntTransParameters.LastWriteTime = fileTime;
            ntTransParameters.LastChangeTime = fileTime;
            ntTransParameters.ExtFileAttributes = request.NtTransParameters.ExtFileAttributes;
            ntTransParameters.AllocationSize = allocationSize;
            ntTransParameters.EndOfFile = endOfFile;
            ntTransParameters.ResourceType = resourceType;
            ntTransParameters.NMPipeStatus = nmPipeStatus;
            ntTransParameters.Directory = directory;
            response.NtTransParameters = ntTransParameters;

            response.UpdateCountAndOffset();

            return response;
        }
        public SmbNegotiateResponsePacket CreateNegotiateResponse(
            CifsServerPerConnection connection,
            SmbNegotiateRequestPacket request,
            SecurityModes securityMode)
        {
            SmbNegotiateResponsePacket response = new SmbNegotiateResponsePacket();
            response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request);

            Stack<string> dialectStrings = new Stack<string>();

            for (int offset = 0; offset < request.SmbData.Dialects.Length; offset++)
            {
                string dialectString = CifsMessageUtils.ToSmbString(request.SmbData.Dialects, offset, true);
                dialectStrings.Push(dialectString);
                offset += sizeof(byte) + dialectString.Length;
            }

            while(dialectStrings.Count > 0)
            {
                string dialectString = dialectStrings.Pop();
                if(dialectString == CifsMessageUtils.DIALECT_NTLANMAN)
                {
                    SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Parameters smbParameters = response.SmbParameters;
                    smbParameters.WordCount = (byte)((Marshal.SizeOf(response.SmbParameters) - sizeof(byte)) / 2);
                    smbParameters.DialectIndex = (ushort)dialectStrings.Count;
                    smbParameters.SecurityMode = securityMode;
                    smbParameters.MaxMpxCount = (ushort)this.context.MaxMpxCount;
                    smbParameters.MaxNumberVcs = (ushort)this.context.MaxNumberVcs;
                    smbParameters.MaxBufferSize = (ushort)this.context.MaxBufferSize;
                    smbParameters.MaxRawSize = (ushort)this.context.MaxRawSize;
                    smbParameters.SessionKey = 0;
                    smbParameters.Capabilities = this.context.Capabilities;
                    FileTime fileTime = new FileTime();
                    fileTime.Time = (ulong)DateTime.Now.ToFileTime();
                    smbParameters.SystemTime = fileTime;

                    smbParameters.ServerTimeZone = (short)TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).Minutes;
                    smbParameters.ChallengeLength = (byte)connection.NTLMChallenge.Length;
                    response.SmbParameters = smbParameters;

                    SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Data smbData = response.SmbData;
                    smbData.Challenge = connection.NTLMChallenge;
                    smbData.DomainName = CifsMessageUtils.ToSmbStringBytes(this.context.DomainName, true);
                    smbData.ByteCount = (ushort)(smbData.Challenge.Length + smbData.DomainName.Length);
                    response.SmbData = smbData;

                    return response;
                }
                else if (dialectString == CifsMessageUtils.DIALECT_PCLAN
                    || dialectString == CifsMessageUtils.DIALECT_PCNETWORK_PROGRAM)
                {
                    SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Parameters smbParameters = response.SmbParameters;
                    smbParameters.WordCount = 0x1;
                    smbParameters.DialectIndex = (ushort)dialectStrings.Count;
                    response.SmbParameters = smbParameters;

                    SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Data smbData = response.SmbData;
                    smbData.Challenge = connection.NTLMChallenge;
                    smbData.DomainName = CifsMessageUtils.ToSmbStringBytes(this.context.DomainName, true);
                    smbData.ByteCount = (ushort)(smbData.Challenge.Length + smbData.DomainName.Length);
                    response.SmbData = smbData;

                    return response;
                }
            }

            throw new NotSupportedException("None of these dialects is supported.");
        }