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); }
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); }
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)); } }
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); } }
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; }