예제 #1
0
        private string GetRelativePath(SCPEntry entry)
        {
            try {
                // [CVE-2018-20685] [CVE-2019-6109] [CVE-2019-6111]
                _filePathValidator.ValidateRelativeUnixPath(entry.Name, entry.IsDirectory);
            }
            catch (FilePathValidatorException e) {
                throw new SCPClientException(e.Message, e);
            }
            string relPath = entry.Name.Replace('/', '\\');

            return(relPath);
        }
예제 #2
0
        private bool CreateFile(SCPChannelStream stream, string filePath, SCPEntry entry, SCPModTime modTime,
                                Cancellation cancellation,
                                SCPFileTransferProgressDelegate progressDelegate)
        {
            string fileName    = Path.GetFileName(filePath);
            ulong  transmitted = 0;

            if (progressDelegate != null)
            {
                progressDelegate(filePath, fileName, SCPFileTransferStatus.Open, (ulong)entry.FileSize, transmitted);
            }

            FileStream fileStream;

            try {
                fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read);
            }
            catch (Exception e) {
                SendError(stream, "failed to create a file");
                throw new SCPClientException("Failed to create a file: " + filePath, e);
            }
            stream.Write(ZERO);

            using (fileStream) {
                byte[] buff   = new byte[FILE_TRANSFER_BLOCK_SIZE];
                long   remain = entry.FileSize;
                try {
                    while (remain > 0)
                    {
                        if (cancellation != null && cancellation.IsRequested)
                        {
                            if (progressDelegate != null)
                            {
                                progressDelegate(filePath, fileName, SCPFileTransferStatus.CompletedAbort, (ulong)entry.FileSize, transmitted);
                            }
                            return(false);   // cancel
                        }

                        int maxLength  = (int)Math.Min((long)buff.Length, remain);
                        int readLength = stream.Read(buff, maxLength, _protocolTimeout);
                        fileStream.Write(buff, 0, readLength);
                        remain -= readLength;

                        transmitted += (ulong)readLength;
                        if (progressDelegate != null)
                        {
                            progressDelegate(filePath, fileName, SCPFileTransferStatus.Transmitting, (ulong)entry.FileSize, transmitted);
                        }
                    }
                }
                catch (Exception e) {
                    SendError(stream, "failed to write to a file");
                    throw new SCPClientException("Failed to write to a file: " + filePath, e);
                }
            }

            if (modTime != null)
            {
                try {
                    File.SetLastWriteTimeUtc(filePath, modTime.MTime);
                    File.SetLastAccessTimeUtc(filePath, modTime.ATime);
                }
                catch (Exception e) {
                    SendError(stream, "failed to modify time of a file");
                    throw new SCPClientException("Failed to modify time of a file: " + filePath, e);
                }
            }

            CheckResponse(stream);
            stream.Write(ZERO);

            if (progressDelegate != null)
            {
                progressDelegate(filePath, fileName, SCPFileTransferStatus.CompletedSuccess, (ulong)entry.FileSize, transmitted);
            }

            return(true);
        }
예제 #3
0
        private string DeterminePathToCreate(string localBasePath, string initialLocalPath, SCPEntry entry)
        {
            Debug.Assert(initialLocalPath != null);

            if (localBasePath == null)      // first creation
            // use initialLocalPath
            {
                if (Directory.Exists(initialLocalPath))
                {
                    return(Path.Combine(initialLocalPath, entry.Name));
                }
                else
                {
                    return(initialLocalPath);
                }
            }
            else
            {
                return(Path.Combine(localBasePath, entry.Name));
            }
        }
예제 #4
0
        private string DeterminePathToCreate(string localBasePath, string initialLocalPath, SCPEntry entry)
        {
            Debug.Assert(initialLocalPath != null);

            if (localBasePath == null) {    // first creation
                // use initialLocalPath
                if (Directory.Exists(initialLocalPath))
                    return Path.Combine(initialLocalPath, entry.Name);
                else
                    return initialLocalPath;
            }
            else {
                return Path.Combine(localBasePath, entry.Name);
            }
        }
예제 #5
0
        private bool CreateFile(SCPChannelStream stream, string filePath, SCPEntry entry, SCPModTime modTime,
                    Cancellation cancellation,
                    SCPFileTransferProgressDelegate progressDelegate)
        {
            string fileName = Path.GetFileName(filePath);
            ulong transmitted = 0;

            if (progressDelegate != null)
                progressDelegate(filePath, fileName, SCPFileTransferStatus.Open, (ulong)entry.FileSize, transmitted);

            FileStream fileStream;
            try {
                fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read);
            }
            catch (Exception e) {
                SendError(stream, "failed to create a file");
                throw new SCPClientException("Failed to create a file: " + filePath, e);
            }
            stream.Write(ZERO);

            using (fileStream) {
                byte[] buff = new byte[FILE_TRANSFER_BLOCK_SIZE];
                long remain = entry.FileSize;
                try {
                    while (remain > 0) {
                        if (cancellation != null && cancellation.IsRequested) {
                            if (progressDelegate != null)
                                progressDelegate(filePath, fileName, SCPFileTransferStatus.CompletedAbort, (ulong)entry.FileSize, transmitted);
                            return false;   // cancel
                        }

                        int maxLength = (int)Math.Min((long)buff.Length, remain);
                        int readLength = stream.Read(buff, maxLength, _protocolTimeout);
                        fileStream.Write(buff, 0, readLength);
                        remain -= readLength;

                        transmitted += (ulong)readLength;
                        if (progressDelegate != null)
                            progressDelegate(filePath, fileName, SCPFileTransferStatus.Transmitting, (ulong)entry.FileSize, transmitted);
                    }
                }
                catch (Exception e) {
                    SendError(stream, "failed to write to a file");
                    throw new SCPClientException("Failed to write to a file: " + filePath, e);
                }
            }

            if (modTime != null) {
                try {
                    File.SetLastWriteTimeUtc(filePath, modTime.MTime);
                    File.SetLastAccessTimeUtc(filePath, modTime.ATime);
                }
                catch (Exception e) {
                    SendError(stream, "failed to modify time of a file");
                    throw new SCPClientException("Failed to modify time of a file: " + filePath, e);
                }
            }

            CheckResponse(stream);
            stream.Write(ZERO);

            if (progressDelegate != null)
                progressDelegate(filePath, fileName, SCPFileTransferStatus.CompletedSuccess, (ulong)entry.FileSize, transmitted);

            return true;
        }