/// <summary>
        /// Create File, named pipe, directory. One transport can only create one file.
        /// </summary>
        /// <param name="fileName">The file, namedpipe, directory name</param>
        /// <param name="desiredAccess">The desired access</param>
        /// <param name="impersonationLevel">The impersonation level</param>
        /// <param name="fileAttribute">The file attribute, this field is only valid when create file.
        /// </param>
        /// <param name="createDisposition">Defines the action the server MUST take if the file that is
        /// specified in the name field already exists</param>
        /// <param name="createOption">Specifies the options to be applied when creating or opening the file</param>
        private void InternalCreate(string fileName, NtTransactDesiredAccess desiredAccess,
                                    NtTransactImpersonationLevel impersonationLevel, SMB_EXT_FILE_ATTR fileAttribute,
                                    NtTransactCreateDisposition createDisposition, NtTransactCreateOptions createOption)
        {
            SmbNtCreateAndxRequestPacket request = smbClient.CreateCreateRequest(
                this.treeId,
                fileName,
                desiredAccess,
                fileAttribute,
                NtTransactShareAccess.NONE,
                createDisposition,
                createOption,
                impersonationLevel,
                CreateFlags.NT_CREATE_REQUEST_EXTENDED_RESPONSE);

            if (this.isSignRequired)
            {
                request.Sign(this.NextSequenceNumber, this.sessionKey);
            }

            uint status = 0;
            SmbNtCreateAndxResponsePacket response =
                this.SendAndExpectSmbPacket(request, internalTimeout, out status) as SmbNtCreateAndxResponsePacket;

            if (status != 0)
            {
                throw new InvalidOperationException("Create Failed. ErrorCode: " + status);
            }

            this.fid = response.SmbParameters.FID;
        }
        protected override SmbPacket CreateSmbResponsePacket(
            SmbPacket request,
            SmbHeader smbHeader,
            Channel channel)
        {
            SmbPacket smbPacket = null;

            // error packet
            SmbStatus packetStatus = (SmbStatus)smbHeader.Status;

            // error packet
            if (packetStatus != SmbStatus.STATUS_SUCCESS &&
                packetStatus != SmbStatus.STATUS_MORE_PROCESSING_REQUIRED &&
                packetStatus != SmbStatus.STATUS_BUFFER_OVERFLOW)
            {
                smbPacket           = new SmbErrorResponsePacket();
                smbPacket.SmbHeader = smbHeader;

                return(smbPacket);
            }

            // success packet
            switch (smbHeader.Command)
            {
            case SmbCommand.SMB_COM_NEGOTIATE:
                if (smbClient.Capability.IsSupportsExtendedSecurity)
                {
                    smbPacket = new SmbNegotiateResponsePacket();
                }
                else
                {
                    smbPacket = new SmbNegotiateImplicitNtlmResponsePacket();
                }
                break;

            case SmbCommand.SMB_COM_SESSION_SETUP_ANDX:
                if (smbClient.Capability.IsSupportsExtendedSecurity)
                {
                    smbPacket = new SmbSessionSetupAndxResponsePacket();
                }
                else
                {
                    smbPacket = new SmbSessionSetupImplicitNtlmAndxResponsePacket();
                }
                break;

            case SmbCommand.SMB_COM_TREE_CONNECT_ANDX:
                smbPacket = new SmbTreeConnectAndxResponsePacket();
                break;

            case SmbCommand.SMB_COM_TREE_DISCONNECT:
                smbPacket = new SmbTreeDisconnectResponsePacket();
                break;

            case SmbCommand.SMB_COM_LOGOFF_ANDX:
                smbPacket = new SmbLogoffAndxResponsePacket();
                break;

            case SmbCommand.SMB_COM_NT_CREATE_ANDX:
                smbPacket = new SmbNtCreateAndxResponsePacket();
                break;

            case SmbCommand.SMB_COM_CLOSE:
                smbPacket = new SmbCloseResponsePacket();
                break;

            case SmbCommand.SMB_COM_OPEN_ANDX:
                smbPacket = new SmbOpenAndxResponsePacket();
                break;

            case SmbCommand.SMB_COM_WRITE_ANDX:
                smbPacket = new SmbWriteAndxResponsePacket();
                break;

            case SmbCommand.SMB_COM_READ_ANDX:
                smbPacket = new SmbReadAndxResponsePacket();
                break;

            case SmbCommand.SMB_COM_TRANSACTION:
                smbPacket = this.CreateTransactionResponsePacket(request, smbHeader, channel);

                break;

            case SmbCommand.SMB_COM_TRANSACTION2:
                smbPacket = this.CreateTransaction2ResponsePacket(request, smbHeader, channel);

                break;

            case SmbCommand.SMB_COM_NT_TRANSACT:
                smbPacket = this.CreateNtTransactionResponsePacket(request, smbHeader, channel);

                break;

            default:
                break;
            }
            if (smbPacket != null)
            {
                smbPacket.SmbHeader = smbHeader;
                return(smbPacket);
            }

            return(base.CreateSmbResponsePacket(request, smbHeader, channel));
        }
 /// <summary>
 /// Verify whether the two response are equal or not
 /// </summary>
 /// <param name="response"> The SmbNtCreateAndxResponsePacketResponse For First</param>
 /// <param name="response2"> The SmbNtCreateAndxResponsePacket Response For Second</param>
 private bool VerifyCreateResponse(
     SmbNtCreateAndxResponsePacket response,
     SmbNtCreateAndxResponsePacket response2)
 {
     return (response.IsSignRequired == response2.IsSignRequired)
         && (response.PacketType == response2.PacketType)
         && (response.SmbData.ByteCount == response2.SmbData.ByteCount)
         && (response.SmbParameters.AllocationSize == response2.SmbParameters.AllocationSize)
         && (response.SmbParameters.AndXCommand == response2.SmbParameters.AndXCommand)
         && (response.SmbParameters.AndXOffset == response2.SmbParameters.AndXOffset)
         && (response.SmbParameters.AndXReserved == response2.SmbParameters.AndXReserved)
         && (response.SmbParameters.CreateTime.Time == response2.SmbParameters.CreateTime.Time)
         && (response.SmbParameters.NMPipeStatus_or_FileStatusFlags ==
         response2.SmbParameters.NMPipeStatus_or_FileStatusFlags)
         && (response.SmbParameters.Directory == response2.SmbParameters.Directory)
         && (response.SmbParameters.EndOfFile == response2.SmbParameters.EndOfFile)
         && (response.SmbParameters.ExtFileAttributes == response2.SmbParameters.ExtFileAttributes)
         && CompareArrayEquals(response.SmbParameters.FileId, response2.SmbParameters.FileId)
         && (response.SmbParameters.ResourceType == response2.SmbParameters.ResourceType)
         && CompareArrayEquals(
         response.SmbParameters.GuestMaximalAccessRights,
         response2.SmbParameters.GuestMaximalAccessRights)
         && (response.SmbParameters.LastAccessTime.Time == response2.SmbParameters.LastAccessTime.Time)
         && (response.SmbParameters.LastChangeTime.Time == response2.SmbParameters.LastChangeTime.Time)
         && (response.SmbParameters.LastWriteTime.Time == response2.SmbParameters.LastWriteTime.Time)
         && CompareArrayEquals(
         response.SmbParameters.MaximalAccessRights,
         response2.SmbParameters.MaximalAccessRights)
         && (response.SmbParameters.OplockLevel == response2.SmbParameters.OplockLevel)
         && CompareArrayEquals(response.SmbParameters.VolumeGUID, response2.SmbParameters.VolumeGUID)
         && (response.SmbParameters.WordCount == response2.SmbParameters.WordCount);
 }
Exemplo n.º 4
0
        /// <summary>
        /// update the context with response packet
        /// </summary>
        /// <param name="connection">the connection of endpoint</param>
        /// <param name="packet">the packet to update the context</param>
        private void ResponsePacketUpdateRoleContext(SmbServerConnection connection, SmbPacket packet)
        {
            SmbHeader smbHeader = packet.SmbHeader;

            SmbPacket requestPacket = connection.GetRequestPacket(smbHeader.Mid);

            if (requestPacket == null)
            {
                return;
            }

            switch (smbHeader.Command)
            {
            case SmbCommand.SMB_COM_SESSION_SETUP_ANDX:
                if (smbHeader.Uid == 0)
                {
                    break;
                }
                else
                {
                    SmbServerSession session = new SmbServerSession();
                    session.Uid = smbHeader.Uid;
                    session.AuthenticationState = SessionState.Complete;
                    session.Connection          = connection;
                    session.SessionKey          = connection.GssApi.SessionKey;

                    connection.AddSession(session);
                }

                break;

            case SmbCommand.SMB_COM_LOGOFF_ANDX:
                if (requestPacket.SmbHeader.Uid == 0)
                {
                    break;
                }
                else
                {
                    connection.RemoveSession(connection.GetSession(requestPacket.SmbHeader.Uid));
                }

                break;

            case SmbCommand.SMB_COM_TREE_CONNECT_ANDX:
            {
                SmbTreeConnectAndxRequestPacket request = requestPacket as SmbTreeConnectAndxRequestPacket;

                SmbServerTreeConnect treeconnect = new SmbServerTreeConnect();
                treeconnect.TreeId  = smbHeader.Tid;
                treeconnect.Session = connection.GetSession(smbHeader.Uid);
                if (treeconnect.Session == null)
                {
                    break;
                }
                if ((request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) != 0)
                {
                    treeconnect.Path = Encoding.Unicode.GetString(request.SmbData.Path);
                }
                else
                {
                    treeconnect.Path = Encoding.ASCII.GetString(request.SmbData.Path);
                }
                treeconnect.Path = treeconnect.Path.TrimEnd('\0');
                treeconnect.Session.AddTreeConnect(treeconnect);
            }

            break;

            case SmbCommand.SMB_COM_TREE_DISCONNECT:
                if (requestPacket.SmbHeader.Uid != 0)
                {
                    SmbServerSession session = connection.GetSession(requestPacket.SmbHeader.Uid);
                    if (session == null)
                    {
                        break;
                    }
                    session.RemoveTreeConnect(session.GetTreeConnect(requestPacket.SmbHeader.Tid));
                }

                break;

            case SmbCommand.SMB_COM_NT_CREATE_ANDX:
            {
                SmbNtCreateAndxResponsePacket response = packet as SmbNtCreateAndxResponsePacket;
                SmbNtCreateAndxRequestPacket  request  = requestPacket as SmbNtCreateAndxRequestPacket;

                SmbServerOpen open = new SmbServerOpen();
                open.SmbFid   = response.SmbParameters.FID;
                open.PathName = SmbMessageUtils.GetString(request.SmbData.FileName,
                                                          SmbFlags2.SMB_FLAGS2_UNICODE == (request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE));
                open.PathName    = open.PathName.TrimEnd('\0');
                open.Session     = connection.GetSession(smbHeader.Uid);
                open.TreeConnect = connection.GetTreeConnect(smbHeader.Tid);
                if (open.TreeConnect == null)
                {
                    break;
                }
                open.TreeConnect.AddOpen(open);
            }

            break;

            case SmbCommand.SMB_COM_OPEN_ANDX:
            {
                SmbOpenAndxResponsePacket response = packet as SmbOpenAndxResponsePacket;
                SmbOpenAndxRequestPacket  request  = requestPacket as SmbOpenAndxRequestPacket;

                SmbServerOpen open = new SmbServerOpen();
                open.SmbFid   = response.SmbParameters.FID;
                open.PathName = SmbMessageUtils.GetString(request.SmbData.FileName,
                                                          SmbFlags2.SMB_FLAGS2_UNICODE == (request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE));
                open.Session     = connection.GetSession(smbHeader.Uid);
                open.TreeConnect = connection.GetTreeConnect(smbHeader.Tid);
                if (open.TreeConnect == null)
                {
                    break;
                }
                open.TreeConnect.AddOpen(open);
            }

            break;

            case SmbCommand.SMB_COM_CLOSE:
            {
                SmbCloseRequestPacket closeRequest = requestPacket as SmbCloseRequestPacket;

                SmbServerTreeConnect treeconnect = connection.GetTreeConnect(requestPacket.SmbHeader.Tid);
                if (treeconnect == null)
                {
                    break;
                }

                treeconnect.RemoveOpen(treeconnect.GetOpen(closeRequest.SmbParameters.FID));
            }

            break;

            default:
                break;
            }

            connection.RemoveRequestPacket(packet);
        }
 /// <summary>
 /// Deep copy constructor.
 /// </summary>
 public SmbNtCreateAndxResponsePacket(SmbNtCreateAndxResponsePacket packet)
     : base(packet)
 {
 }