internal static Transaction2FindNext2Response GetSubcommandResponse(SMBHeader header, Transaction2FindNext2Request subcommand, FileSystemShare share, StateObject state)
        {
            Transaction2FindNext2Response response = new Transaction2FindNext2Response();

            if (!state.OpenSearches.ContainsKey(subcommand.SID))
            {
                header.Status = NTStatus.STATUS_INVALID_HANDLE;
                return(null);
            }

            bool returnResumeKeys          = (subcommand.Flags & FindFlags.SMB_FIND_RETURN_RESUME_KEYS) > 0;
            List <FileSystemEntry> entries = state.OpenSearches[subcommand.SID];

            for (int index = 0; index < entries.Count; index++)
            {
                FindInformationEntry infoEntry = InfoHelper.FromFileSystemEntry(entries[index], subcommand.InformationLevel, header.UnicodeFlag, returnResumeKeys);
                response.FindInfoList.Add(infoEntry);
                if (response.FindInfoList.GetLength(header.UnicodeFlag) > state.GetMaxDataCount(header.PID))
                {
                    response.FindInfoList.RemoveAt(response.FindInfoList.Count - 1);
                    break;
                }
            }
            int returnCount = response.FindInfoList.Count;

            entries.RemoveRange(0, returnCount);
            state.OpenSearches[subcommand.SID] = entries;
            response.SearchCount = (ushort)returnCount;
            response.EndOfSearch = (returnCount == entries.Count) && (entries.Count <= subcommand.SearchCount);
            return(response);
        }
Esempio n. 2
0
        internal static SMBCommand GetCreateDirectoryResponse(SMBHeader header, CreateDirectoryRequest request, FileSystemShare share, StateObject state)
        {
            string userName = state.GetConnectedUserName(header.UID);

            if (!share.HasWriteAccess(userName))
            {
                header.Status = NTStatus.STATUS_ACCESS_DENIED;
                return(new ErrorResponse(CommandName.SMB_COM_CREATE_DIRECTORY));
            }
            IFileSystem fileSystem = share.FileSystem;

            try
            {
                fileSystem.CreateDirectory(request.DirectoryName);
            }
            catch (IOException)
            {
                header.Status = NTStatus.STATUS_OBJECT_NAME_INVALID;
                return(new ErrorResponse(CommandName.SMB_COM_CREATE_DIRECTORY));
            }
            catch (UnauthorizedAccessException)
            {
                header.Status = NTStatus.STATUS_ACCESS_DENIED;
                return(new ErrorResponse(CommandName.SMB_COM_CREATE_DIRECTORY));
            }

            return(new CreateDirectoryResponse());
        }
        internal static Transaction2QueryFSInformationResponse GetSubcommandResponse(SMBHeader header, Transaction2QueryFSInformationRequest subcommand, FileSystemShare share)
        {
            Transaction2QueryFSInformationResponse response = new Transaction2QueryFSInformationResponse();

            response.QueryFSInfo = InfoHelper.GetFSInformation(subcommand.InformationLevel, share.FileSystem);
            return(response);
        }
        /// <summary>
        /// There are no secondary response messages.
        /// The client MUST send as many secondary requests as are needed to complete the transfer of the transaction request.
        /// The server MUST respond to the transaction request as a whole.
        /// </summary>
        internal static SMBCommand GetTransactionResponse(SMBHeader header, TransactionSecondaryRequest request, object share, StateObject state, List <SMBCommand> sendQueue)
        {
            ProcessStateObject processState = state.GetProcessState(header.PID);

            if (processState == null)
            {
                throw new InvalidRequestException();
            }
            ByteWriter.WriteBytes(processState.TransactionParameters, request.ParameterDisplacement, request.TransParameters);
            ByteWriter.WriteBytes(processState.TransactionData, request.DataDisplacement, request.TransData);
            processState.TransactionParametersReceived += request.TransParameters.Length;
            processState.TransactionDataReceived       += request.TransData.Length;

            if (processState.TransactionParametersReceived < processState.TransactionParameters.Length ||
                processState.TransactionDataReceived < processState.TransactionData.Length)
            {
                return(null);
            }
            else
            {
                // We have a complete command
                if (request is Transaction2SecondaryRequest)
                {
                    return(GetCompleteTransaction2Response(header, processState.TransactionSetup, processState.TransactionParameters, processState.TransactionData, share, state, sendQueue));
                }
                else
                {
                    return(GetCompleteTransactionResponse(header, processState.TransactionSetup, processState.TransactionParameters, processState.TransactionData, share, state, sendQueue));
                }
            }
        }
        /// <summary>
        /// There are no interim response messages.
        /// The client MUST send as many secondary requests as are needed to complete the transfer of the transaction request.
        /// The server MUST respond to the transaction request as a whole.
        /// </summary>
        internal static SMBCommand GetTransactionResponse(SMBHeader header, TransactionRequest request, object share, StateObject state, List <SMBCommand> sendQueue)
        {
            ProcessStateObject processState = state.ObtainProcessState(header.PID);

            processState.MaxDataCount = request.MaxDataCount;

            if (request.TransParameters.Length < request.TotalParameterCount ||
                request.TransData.Length < request.TotalDataCount)
            {
                // A secondary transaction request is pending
                processState.TransactionSetup      = request.Setup;
                processState.TransactionParameters = new byte[request.TotalParameterCount];
                processState.TransactionData       = new byte[request.TotalDataCount];
                ByteWriter.WriteBytes(processState.TransactionParameters, 0, request.TransParameters);
                ByteWriter.WriteBytes(processState.TransactionData, 0, request.TransData);
                processState.TransactionParametersReceived += request.TransParameters.Length;
                processState.TransactionDataReceived       += request.TransData.Length;
                return(null);
            }
            else
            {
                // We have a complete command
                if (request is Transaction2Request)
                {
                    return(GetCompleteTransaction2Response(header, request.Setup, request.TransParameters, request.TransData, share, state, sendQueue));
                }
                else
                {
                    return(GetCompleteTransactionResponse(header, request.Setup, request.TransParameters, request.TransData, share, state, sendQueue));
                }
            }
        }
        internal static NegotiateResponseNTLM GetNegotiateResponse(SMBHeader header, NegotiateRequest request, byte[] serverChallenge)
        {
            NegotiateResponseNTLM response = new NegotiateResponseNTLM();

            response.DialectIndex  = (ushort)request.Dialects.IndexOf(SMBServer.NTLanManagerDialect);
            response.SecurityMode  = SecurityMode.UserSecurityMode | SecurityMode.EncryptPasswords;
            response.MaxMpxCount   = 50;
            response.MaxNumberVcs  = 1;
            response.MaxBufferSize = 16644;
            response.MaxRawSize    = 65536;
            response.Capabilities  = ServerCapabilities.Unicode |
                                     ServerCapabilities.LargeFiles |
                                     ServerCapabilities.NTSMB |
                                     ServerCapabilities.NTStatusCode |
                                     ServerCapabilities.NTFind |
                                     ServerCapabilities.LargeRead |
                                     ServerCapabilities.LargeWrite;
            response.SystemTime     = DateTime.UtcNow;
            response.ServerTimeZone = (short)-TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes;
            response.Challenge      = serverChallenge;
            response.DomainName     = String.Empty;
            response.ServerName     = String.Empty;

            return(response);
        }
Esempio n. 7
0
        internal static TransactionTransactNamedPipeResponse GetSubcommandResponse(SMBHeader header, TransactionTransactNamedPipeRequest subcommand, NamedPipeShare share, StateObject state)
        {
            string openedFilePath = state.GetOpenedFilePath(subcommand.FID);

            if (openedFilePath == null)
            {
                header.Status = NTStatus.STATUS_INVALID_HANDLE;
                return(null);
            }

            TransactionTransactNamedPipeResponse response = new TransactionTransactNamedPipeResponse();
            RemoteService service = share.GetService(openedFilePath);

            if (service != null)
            {
                RPCPDU rpcRequest = RPCPDU.GetPDU(subcommand.WriteData);
                RPCPDU rpcReply   = RemoteServiceHelper.GetRPCReply(rpcRequest, service);
                response.ReadData = rpcReply.GetBytes();
                return(response);
            }

            // This code should not execute unless the request sequence is invalid
            header.Status = NTStatus.STATUS_INVALID_SMB;
            return(null);
        }
Esempio n. 8
0
 public static byte[] PerformRead(SMBHeader header, object share, ushort FID, ulong offset, uint maxCount, StateObject state)
 {
     if (offset > Int64.MaxValue || maxCount > Int32.MaxValue)
     {
         throw new NotImplementedException("Underlying filesystem does not support unsigned offset / read count");
     }
     return(PerformRead(header, share, FID, (long)offset, (int)maxCount, state));
 }
 internal static SMBCommand GetFindClose2Request(SMBHeader header, FindClose2Request request, StateObject state)
 {
     if (state.OpenSearches.ContainsKey(request.SearchHandle))
     {
         state.OpenSearches.Remove(request.SearchHandle);
     }
     return(new FindClose2Response());
 }
Esempio n. 10
0
        internal static SMBCommand GetTreeDisconnectResponse(SMBHeader header, TreeDisconnectRequest request, StateObject state)
        {
            if (!state.IsTreeConnected(header.TID))
            {
                header.Status = NTStatus.STATUS_SMB_BAD_TID;
                return(new ErrorResponse(CommandName.SMB_COM_TREE_DISCONNECT));
            }

            state.RemoveConnectedTree(header.TID);
            return(new TreeDisconnectResponse());
        }
Esempio n. 11
0
        internal static SMBCommand GetCheckDirectoryResponse(SMBHeader header, CheckDirectoryRequest request, FileSystemShare share)
        {
            IFileSystem     fileSystem = share.FileSystem;
            FileSystemEntry entry      = fileSystem.GetEntry(request.DirectoryName);

            if (entry == null || !entry.IsDirectory)
            {
                header.Status = NTStatus.STATUS_NO_SUCH_FILE;
                return(new ErrorResponse(CommandName.SMB_COM_CHECK_DIRECTORY));
            }

            return(new CheckDirectoryResponse());
        }
Esempio n. 12
0
        internal static SMBCommand GetSessionSetupResponseExtended(SMBHeader header, SessionSetupAndXRequestExtended request, StateObject state)
        {
            SessionSetupAndXResponseExtended response = new SessionSetupAndXResponseExtended();

            //see commit dd68473e2086bad4c57d39bb33d7c1a87d037144. Bunch of authentication stuff was removed

            response.Action       = SessionSetupAction.SetupGuest;
            header.UID            = state.AddConnectedUser("Guest");
            response.NativeOS     = String.Empty; // "Windows Server 2003 3790 Service Pack 2"
            response.NativeLanMan = String.Empty; // "Windows Server 2003 5.2"

            return(response);
        }
Esempio n. 13
0
        ////////////////////////////////////////////////////////////////////////////////
        //
        ////////////////////////////////////////////////////////////////////////////////
        public void NegotiateSMB()
        {
            SMBHeader smbHeader = new SMBHeader();

            smbHeader.SetCommand(new Byte[] { 0x72 });
            smbHeader.SetFlags(new Byte[] { 0x18 });
            smbHeader.SetFlags2(new Byte[] { 0x01, 0x48 });
            smbHeader.SetProcessID(processId.Take(2).ToArray());
            smbHeader.SetUserID(new Byte[] { 0x00, 0x00 });
            Byte[] bHeader = smbHeader.GetHeader();

            SMBNegotiateProtocolRequest protocols = new SMBNegotiateProtocolRequest();

            Byte[] bData = protocols.GetProtocols();

            NetBIOSSessionService sessionService = new NetBIOSSessionService();

            sessionService.SetHeaderLength(bHeader.Length);
            sessionService.SetDataLength(bData.Length);
            Byte[] bSessionService = sessionService.GetNetBIOSSessionService();

            Byte[] send = Combine.combine(bSessionService, bHeader);
            send = Combine.combine(send, bData);
            streamSocket.Write(send, 0, send.Length);
            streamSocket.Flush();
            Byte[] recieve = new Byte[81920];
            streamSocket.Read(recieve, 0, recieve.Length);

            Byte[] response = recieve.Skip(5).Take(4).ToArray();
            if (response == new Byte[] { 0xff, 0x53, 0x4d, 0x42 })
            {
                Console.WriteLine("[-] SMB1 is not supported");
                return;
            }

            version = "SMB2";

            Byte[] keyLength = { 0x00, 0x00 };

            if (recieve.Skip(70).Take(1).ToArray().SequenceEqual(new Byte[] { 0x03 }))
            {
                Console.WriteLine("[*] SMB Signing Required");
                signing = true;
                flags   = new Byte[] { 0x15, 0x82, 0x08, 0xa0 };
            }
            else
            {
                signing = false;
                flags   = new Byte[] { 0x05, 0x80, 0x08, 0xa0 };
            }
        }
Esempio n. 14
0
        internal static SMBCommand GetWriteResponse(SMBHeader header, WriteRequest request, object share, StateObject state)
        {
            ushort bytesWritten = (ushort)PerformWrite(header, share, request.FID, request.WriteOffsetInBytes, request.Data, state);

            if (header.Status != NTStatus.STATUS_SUCCESS)
            {
                return(new ErrorResponse(CommandName.SMB_COM_WRITE_ANDX));
            }
            WriteResponse response = new WriteResponse();

            response.CountOfBytesWritten = bytesWritten;

            return(response);
        }
Esempio n. 15
0
        internal static SMBCommand GetReadResponse(SMBHeader header, ReadRequest request, object share, StateObject state)
        {
            byte[] data = PerformRead(header, share, request.FID, request.ReadOffsetInBytes, request.CountOfBytesToRead, state);
            if (header.Status != NTStatus.STATUS_SUCCESS)
            {
                return(new ErrorResponse(CommandName.SMB_COM_READ));
            }

            ReadResponse response = new ReadResponse();

            response.Bytes = data;
            response.CountOfBytesReturned = (ushort)data.Length;
            return(response);
        }
        internal static SMBCommand GetCloseResponse(SMBHeader header, CloseRequest request, StateObject state)
        {
            string openedFilePath = state.GetOpenedFilePath(request.FID);

            if (openedFilePath == null)
            {
                header.Status = NTStatus.STATUS_SMB_BAD_FID;
                return(new ErrorResponse(CommandName.SMB_COM_CLOSE));
            }

            state.RemoveOpenedFile(request.FID);
            CloseResponse response = new CloseResponse();

            return(response);
        }
Esempio n. 17
0
        internal static SMBCommand GetTreeConnectResponse(SMBHeader header, TreeConnectAndXRequest request, StateObject state, ShareCollection shares)
        {
            bool   isExtended   = (request.Flags & TreeConnectFlags.ExtendedResponse) > 0;
            string relativePath = ServerPathUtils.GetRelativeServerPath(request.Path);

            if (String.Equals(relativePath, "\\IPC$", StringComparison.InvariantCultureIgnoreCase))
            {
                header.TID = state.AddConnectedTree(relativePath);
                if (isExtended)
                {
                    return(CreateTreeConnectResponseExtended(ServiceName.NamedPipe));
                }
                else
                {
                    return(CreateTreeConnectResponse(ServiceName.NamedPipe));
                }
            }
            else
            {
                FileSystemShare share = shares.GetShareFromRelativePath(relativePath);
                if (share == null)
                {
                    header.Status = NTStatus.STATUS_OBJECT_PATH_NOT_FOUND;
                    return(new ErrorResponse(CommandName.SMB_COM_TREE_CONNECT_ANDX));
                }
                else
                {
                    string userName = state.GetConnectedUserName(header.UID);
                    if (!share.HasReadAccess(userName))
                    {
                        header.Status = NTStatus.STATUS_ACCESS_DENIED;
                        return(new ErrorResponse(CommandName.SMB_COM_TREE_CONNECT_ANDX));
                    }
                    else
                    {
                        header.TID = state.AddConnectedTree(relativePath);
                        if (isExtended)
                        {
                            return(CreateTreeConnectResponseExtended(ServiceName.DiskShare));
                        }
                        else
                        {
                            return(CreateTreeConnectResponse(ServiceName.DiskShare));
                        }
                    }
                }
            }
        }
Esempio n. 18
0
        internal static SMBCommand GetRenameResponse(SMBHeader header, RenameRequest request, FileSystemShare share, StateObject state)
        {
            string userName = state.GetConnectedUserName(header.UID);

            if (!share.HasWriteAccess(userName))
            {
                header.Status = NTStatus.STATUS_ACCESS_DENIED;
                return(new ErrorResponse(CommandName.SMB_COM_RENAME));
            }
            IFileSystem fileSystem = share.FileSystem;

            FileSystemEntry sourceEntry = fileSystem.GetEntry(request.OldFileName);

            if (sourceEntry == null)
            {
                header.Status = NTStatus.STATUS_NO_SUCH_FILE;
                return(new ErrorResponse(CommandName.SMB_COM_RENAME));
            }

            // The file must not already exist unless we just want to upcase / downcase a filename letter
            FileSystemEntry destinationEntry = fileSystem.GetEntry(request.NewFileName);

            if (destinationEntry != null &&
                !String.Equals(request.OldFileName, request.NewFileName, StringComparison.InvariantCultureIgnoreCase))
            {
                // The new file already exists.
                header.Status = NTStatus.STATUS_OBJECT_NAME_COLLISION;
                return(new ErrorResponse(CommandName.SMB_COM_RENAME));
            }

            try
            {
                fileSystem.Move(request.OldFileName, request.NewFileName);
                return(new RenameResponse());
            }
            catch (IOException)
            {
                header.Status = NTStatus.STATUS_SHARING_VIOLATION;
                return(new ErrorResponse(CommandName.SMB_COM_RENAME));
            }
            catch (UnauthorizedAccessException)
            {
                header.Status = NTStatus.STATUS_ACCESS_DENIED;
                return(new ErrorResponse(CommandName.SMB_COM_RENAME));
            }
        }
Esempio n. 19
0
        internal static SMBCommand GetSetInformationResponse(SMBHeader header, SetInformationRequest request, FileSystemShare share, StateObject state)
        {
            string userName = state.GetConnectedUserName(header.UID);

            if (!share.HasWriteAccess(userName))
            {
                header.Status = NTStatus.STATUS_ACCESS_DENIED;
                return(new ErrorResponse(CommandName.SMB_COM_SET_INFORMATION2));
            }
            IFileSystem fileSystem = share.FileSystem;

            FileSystemEntry entry = fileSystem.GetEntry(request.FileName);

            if (entry == null)
            {
                header.Status = NTStatus.STATUS_NO_SUCH_FILE;
                return(new ErrorResponse(CommandName.SMB_COM_SET_INFORMATION));
            }

            bool?isHidden   = null;
            bool?isReadOnly = null;
            bool?isArchived = null;

            if ((request.FileAttributes & SMBLibrary.SMB1.FileAttributes.Hidden) > 0)
            {
                isHidden = true;
            }
            if ((request.FileAttributes & SMBLibrary.SMB1.FileAttributes.ReadOnly) > 0)
            {
                isReadOnly = true;
            }
            if ((request.FileAttributes & SMBLibrary.SMB1.FileAttributes.Archive) > 0)
            {
                isArchived = true;
            }
            fileSystem.SetAttributes(request.FileName, isHidden, isReadOnly, isArchived);

            if (request.LastWriteTime != SMBHelper.UTimeNotSpecified)
            {
                fileSystem.SetDates(request.FileName, null, request.LastWriteTime, null);
            }

            return(new SetInformationResponse());
        }
Esempio n. 20
0
        internal static SMBCommand GetCompleteNTTransactResponse(SMBHeader header, NTTransactSubcommandName subcommandName, byte[] requestSetup, byte[] requestParameters, byte[] requestData, object share, StateObject state, List <SMBCommand> sendQueue)
        {
            NTTransactSubcommand subcommand         = NTTransactSubcommand.GetSubcommandRequest(subcommandName, requestSetup, requestParameters, requestData, header.UnicodeFlag);
            NTTransactSubcommand subcommandResponse = null;

            if (subcommand is NTTransactCreateRequest)
            {
                header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
            }
            else if (subcommand is NTTransactIOCTLRequest)
            {
                subcommandResponse = GetSubcommandResponse(header, (NTTransactIOCTLRequest)subcommand);
            }
            else if (subcommand is NTTransactSetSecurityDescriptor)
            {
                header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
            }
            else if (subcommand is NTTransactNotifyChangeRequest)
            {
                header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
            }
            else if (subcommand is NTTransactQuerySecurityDescriptorRequest)
            {
                header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
            }
            else
            {
                header.Status = NTStatus.STATUS_SMB_BAD_COMMAND;
            }

            if (header.Status != NTStatus.STATUS_SUCCESS)
            {
                return(new ErrorResponse(CommandName.SMB_COM_NT_TRANSACT));
            }

            byte[]             responseSetup      = subcommandResponse.GetSetup();
            byte[]             responseParameters = subcommandResponse.GetParameters(header.UnicodeFlag);
            byte[]             responseData       = subcommandResponse.GetData();
            NTTransactResponse response           = new NTTransactResponse();

            PrepareResponse(response, responseSetup, responseParameters, responseData, state.MaxBufferSize, sendQueue);
            return(response);
        }
Esempio n. 21
0
        internal static SMBCommand GetWriteResponse(SMBHeader header, WriteAndXRequest request, object share, StateObject state)
        {
            uint bytesWritten = PerformWrite(header, share, request.FID, request.Offset, request.Data, state);

            if (header.Status != NTStatus.STATUS_SUCCESS)
            {
                return(new ErrorResponse(CommandName.SMB_COM_WRITE_ANDX));
            }
            WriteAndXResponse response = new WriteAndXResponse();

            response.Count = bytesWritten;

            if (share is FileSystemShare)
            {
                // If the client wrote to a disk file, this field MUST be set to 0xFFFF.
                response.Available = 0xFFFF;
            }
            return(response);
        }
Esempio n. 22
0
        internal static SMBCommand GetQueryInformationResponse(SMBHeader header, QueryInformationRequest request, FileSystemShare share)
        {
            IFileSystem     fileSystem = share.FileSystem;
            FileSystemEntry entry      = fileSystem.GetEntry(request.FileName);

            if (entry == null)
            {
                header.Status = NTStatus.STATUS_OBJECT_PATH_INVALID;
                return(new ErrorResponse(CommandName.SMB_COM_QUERY_INFORMATION));
            }

            QueryInformationResponse response = new QueryInformationResponse();

            response.FileAttributes = InfoHelper.GetFileAttributes(entry);
            response.LastWriteTime  = entry.LastWriteTime;
            response.FileSize       = (uint)Math.Min(UInt32.MaxValue, entry.Size);

            return(response);
        }
Esempio n. 23
0
        internal static SMBCommand GetDeleteResponse(SMBHeader header, DeleteRequest request, FileSystemShare share, StateObject state)
        {
            string userName = state.GetConnectedUserName(header.UID);

            if (!share.HasWriteAccess(userName))
            {
                header.Status = NTStatus.STATUS_ACCESS_DENIED;
                return(new ErrorResponse(CommandName.SMB_COM_DELETE));
            }
            IFileSystem fileSystem = share.FileSystem;

            FileSystemEntry entry = fileSystem.GetEntry(request.FileName);

            if (entry == null)
            {
                header.Status = NTStatus.STATUS_NO_SUCH_FILE;
                return(new ErrorResponse(CommandName.SMB_COM_DELETE));
            }

            if (!entry.IsDirectory && (request.SearchAttributes & SMBLibrary.SMB1.FileAttributes.Directory) > 0 ||
                entry.IsDirectory && (request.SearchAttributes & SMBLibrary.SMB1.FileAttributes.Directory) == 0)
            {
                header.Status = NTStatus.STATUS_OBJECT_PATH_INVALID;
                return(new ErrorResponse(CommandName.SMB_COM_DELETE));
            }

            try
            {
                fileSystem.Delete(request.FileName);
                return(new DeleteResponse());
            }
            catch (IOException)
            {
                header.Status = NTStatus.STATUS_CANNOT_DELETE;
                return(new ErrorResponse(CommandName.SMB_COM_DELETE));
            }
            catch (UnauthorizedAccessException)
            {
                header.Status = NTStatus.STATUS_ACCESS_DENIED;
                return(new ErrorResponse(CommandName.SMB_COM_DELETE));
            }
        }
Esempio n. 24
0
        private static NTTransactIOCTLResponse GetSubcommandResponse(SMBHeader header, NTTransactIOCTLRequest subcommand)
        {
            const uint FSCTL_CREATE_OR_GET_OBJECT_ID = 0x900C0;

            NTTransactIOCTLResponse response = new NTTransactIOCTLResponse();

            if (subcommand.IsFsctl)
            {
                if (subcommand.FunctionCode == FSCTL_CREATE_OR_GET_OBJECT_ID)
                {
                    ObjectIDBufferType1 objectID = new ObjectIDBufferType1();
                    objectID.ObjectId = Guid.NewGuid();
                    response.Data     = objectID.GetBytes();
                    return(response);
                }
            }

            header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
            return(null);
        }
Esempio n. 25
0
        internal static SMBCommand GetSetInformation2Response(SMBHeader header, SetInformation2Request request, FileSystemShare share, StateObject state)
        {
            string openedFilePath = state.GetOpenedFilePath(request.FID);

            if (openedFilePath == null)
            {
                header.Status = NTStatus.STATUS_SMB_BAD_FID;
                return(new ErrorResponse(CommandName.SMB_COM_SET_INFORMATION2));
            }

            string userName = state.GetConnectedUserName(header.UID);

            if (!share.HasWriteAccess(userName))
            {
                header.Status = NTStatus.STATUS_ACCESS_DENIED;
                return(new ErrorResponse(CommandName.SMB_COM_SET_INFORMATION2));
            }
            IFileSystem fileSystem = share.FileSystem;

            fileSystem.SetDates(openedFilePath, request.CreationDateTime, request.LastWriteDateTime, request.LastAccessDateTime);
            return(new SetInformation2Response());
        }
Esempio n. 26
0
        private static SMBHeader DataToSmbHeader(byte[] data, int receivedBytes, bool allowSuccessfulStatusOnly)
        {
            SMBHeader sMBHeader = default(SMBHeader);
            int       num       = 4;
            int       num2      = Marshal.SizeOf((object)sMBHeader);
            int       num3      = num2 + num;

            if (receivedBytes < num3)
            {
                throw new Exception("Bytes received = " + receivedBytes + " while required size = " + num3);
            }
            IntPtr intPtr = Marshal.AllocHGlobal(num2);

            Marshal.Copy(data, num, intPtr, num2);
            sMBHeader = (SMBHeader)Marshal.PtrToStructure(intPtr, typeof(SMBHeader));
            Marshal.FreeHGlobal(intPtr);
            if (allowSuccessfulStatusOnly && !isSuccessfullSMB(sMBHeader))
            {
                throw new Exception(SmbStatusToMessage(sMBHeader));
            }
            return(sMBHeader);
        }
Esempio n. 27
0
 /// <summary>
 /// The client MUST send as many secondary requests as are needed to complete the transfer of the transaction request.
 /// </summary>
 internal static SMBCommand GetNTTransactResponse(SMBHeader header, NTTransactRequest request, object share, StateObject state, List <SMBCommand> sendQueue)
 {
     if (request.TransParameters.Length < request.TotalParameterCount ||
         request.TransData.Length < request.TotalDataCount)
     {
         ProcessStateObject processState = state.ObtainProcessState(header.PID);
         // A secondary transaction request is pending
         processState.SubcommandID          = (ushort)request.Function;
         processState.TransactionSetup      = request.Setup;
         processState.TransactionParameters = new byte[request.TotalParameterCount];
         processState.TransactionData       = new byte[request.TotalDataCount];
         ByteWriter.WriteBytes(processState.TransactionParameters, 0, request.TransParameters);
         ByteWriter.WriteBytes(processState.TransactionData, 0, request.TransData);
         processState.TransactionParametersReceived += request.TransParameters.Length;
         processState.TransactionDataReceived       += request.TransData.Length;
         return(new NTTransactInterimResponse());
     }
     else
     {
         // We have a complete command
         return(GetCompleteNTTransactResponse(header, request.Function, request.Setup, request.TransParameters, request.TransData, share, state, sendQueue));
     }
 }
Esempio n. 28
0
        internal static SMBCommand GetSessionSetupResponse(SMBHeader header, SessionSetupAndXRequest request, StateObject state)
        {
            SessionSetupAndXResponse response = new SessionSetupAndXResponse();

            // The PrimaryDomain field in the request is used to determine with domain controller should authenticate the user credentials,
            // However, the domain controller itself does not use this field.
            // See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378749%28v=vs.85%29.aspx
            response.Action        = SessionSetupAction.SetupGuest;
            response.PrimaryDomain = request.PrimaryDomain;
            header.UID             = state.AddConnectedUser("Guest");

            if ((request.Capabilities & ServerCapabilities.LargeRead) > 0)
            {
                state.LargeRead = true;
            }
            if ((request.Capabilities & ServerCapabilities.LargeWrite) > 0)
            {
                state.LargeWrite = true;
            }
            response.NativeOS     = String.Empty; // "Windows Server 2003 3790 Service Pack 2"
            response.NativeLanMan = String.Empty; // "Windows Server 2003 5.2"

            return(response);
        }
Esempio n. 29
0
        internal static SMBCommand GetReadResponse(SMBHeader header, ReadAndXRequest request, object share, StateObject state)
        {
            uint maxCount = request.MaxCount;

            if ((share is FileSystemShare) && state.LargeRead)
            {
                maxCount = request.MaxCountLarge;
            }
            byte[] data = PerformRead(header, share, request.FID, request.Offset, maxCount, state);
            if (header.Status != NTStatus.STATUS_SUCCESS)
            {
                return(new ErrorResponse(CommandName.SMB_COM_READ_ANDX));
            }

            ReadAndXResponse response = new ReadAndXResponse();

            if (share is FileSystemShare)
            {
                // If the client reads from a disk file, this field MUST be set to -1 (0xFFFF)
                response.Available = 0xFFFF;
            }
            response.Data = data;
            return(response);
        }
Esempio n. 30
0
        public static byte[] PerformRead(SMBHeader header, object share, ushort FID, long offset, int maxCount, StateObject state)
        {
            OpenedFileObject openedFile = state.GetOpenedFileObject(FID);

            if (openedFile == null)
            {
                header.Status = NTStatus.STATUS_INVALID_HANDLE;
                return(null);
            }
            string openedFilePath = openedFile.Path;

            if (share is NamedPipeShare)
            {
                return(state.RetrieveNamedPipeReply(FID));
            }
            else // FileSystemShare
            {
                FileSystemShare fileSystemShare = (FileSystemShare)share;
                IFileSystem     fileSystem      = fileSystemShare.FileSystem;
                if (openedFile.IsSequentialAccess)
                {
                    bool isInCache = (offset >= openedFile.CacheOffset) && (offset + maxCount <= openedFile.CacheOffset + openedFile.Cache.Length);
                    if (!isInCache)
                    {
                        int bytesRead;
                        try
                        {
                            Stream stream = fileSystem.OpenFile(openedFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                            stream.Seek(offset, SeekOrigin.Begin);
                            openedFile.CacheOffset = offset;
                            openedFile.Cache       = new byte[OpenedFileObject.CacheSize];
                            bytesRead = stream.Read(openedFile.Cache, 0, OpenedFileObject.CacheSize);
                            stream.Close();
                        }
                        catch (IOException ex)
                        {
                            ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex);
                            if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
                            {
                                // Returning STATUS_SHARING_VIOLATION is undocumented but apparently valid
                                header.Status = NTStatus.STATUS_SHARING_VIOLATION;
                                return(null);
                            }
                            else
                            {
                                header.Status = NTStatus.STATUS_DATA_ERROR;
                                return(null);
                            }
                        }
                        catch (UnauthorizedAccessException)
                        {
                            header.Status = NTStatus.STATUS_ACCESS_DENIED;
                            return(null);
                        }

                        if (bytesRead < OpenedFileObject.CacheSize)
                        {
                            // EOF, we must trim the response data array
                            byte[] buffer = new byte[bytesRead];
                            Array.Copy(openedFile.Cache, 0, buffer, 0, bytesRead);
                            openedFile.Cache = buffer;
                        }
                    }

                    int    offsetInCache = (int)(offset - openedFile.CacheOffset);
                    int    bytesRemained = openedFile.Cache.Length - offsetInCache;
                    int    dataLength    = Math.Min(maxCount, bytesRemained);
                    byte[] data          = new byte[dataLength];
                    Array.Copy(openedFile.Cache, offsetInCache, data, 0, dataLength);
                    return(data);
                }
                else
                {
                    int    bytesRead;
                    byte[] data;
                    try
                    {
                        Stream stream = fileSystem.OpenFile(openedFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                        stream.Seek(offset, SeekOrigin.Begin);
                        data      = new byte[maxCount];
                        bytesRead = stream.Read(data, 0, maxCount);
                        stream.Close();
                    }
                    catch (IOException ex)
                    {
                        ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex);
                        if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
                        {
                            // Returning STATUS_SHARING_VIOLATION is undocumented but apparently valid
                            header.Status = NTStatus.STATUS_SHARING_VIOLATION;
                            return(null);
                        }
                        else
                        {
                            header.Status = NTStatus.STATUS_DATA_ERROR;
                            return(null);
                        }
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        header.Status = NTStatus.STATUS_DATA_ERROR;
                        return(null);
                    }
                    catch (UnauthorizedAccessException)
                    {
                        header.Status = NTStatus.STATUS_ACCESS_DENIED;
                        return(null);
                    }

                    if (bytesRead < maxCount)
                    {
                        // EOF, we must trim the response data array
                        byte[] buffer = new byte[bytesRead];
                        Array.Copy(data, 0, buffer, 0, bytesRead);
                        data = buffer;
                    }
                    return(data);
                }
            }
        }