Class SftpSubsystem
- java.lang.Object
-
- org.apache.sshd.common.util.logging.AbstractLoggingBean
-
- org.apache.sshd.sftp.server.AbstractSftpSubsystemHelper
-
- org.apache.sshd.sftp.server.SftpSubsystem
-
- All Implemented Interfaces:
java.io.Closeable
,java.lang.AutoCloseable
,java.lang.Runnable
,FileSystemAware
,SessionContextHolder
,SessionHolder<ServerSession>
,ExecutorServiceCarrier
,ChannelDataReceiver
,ChannelSessionAware
,AsyncCommand
,Command
,CommandLifecycle
,ServerSessionHolder
,SessionAware
,SftpEventListenerManager
,SftpSubsystemEnvironment
,SftpSubsystemProxy
public class SftpSubsystem extends AbstractSftpSubsystemHelper implements Command, java.lang.Runnable, SessionAware, FileSystemAware, ExecutorServiceCarrier, AsyncCommand, ChannelSessionAware, ChannelDataReceiver
SFTP subsystem
-
-
Field Summary
Fields Modifier and Type Field Description protected Buffer
buffer
protected ExitCallback
callback
protected ChannelSession
channelSession
protected static Buffer
CLOSE
protected java.util.concurrent.atomic.AtomicBoolean
closed
protected java.nio.file.Path
defaultDir
protected Environment
env
protected IoOutputStream
err
protected CloseableExecutorService
executorService
protected java.util.Map<java.lang.String,byte[]>
extensions
protected int
fileHandleSize
protected java.nio.file.FileSystem
fileSystem
protected java.util.Map<java.lang.String,Handle>
handles
protected int
maxFileHandleRounds
protected IoOutputStream
out
protected java.util.concurrent.Future<?>
pendingFuture
protected Random
randomizer
protected java.util.concurrent.BlockingQueue<Buffer>
requests
protected java.util.concurrent.atomic.AtomicLong
requestsCount
protected ServerSession
serverSession
protected int
version
protected byte[]
workBuf
-
Fields inherited from class org.apache.sshd.sftp.server.AbstractSftpSubsystemHelper
DEFAULT_ACL_SUPPORTED_MASK, DEFAULT_OPEN_SSH_EXTENSIONS, DEFAULT_OPEN_SSH_EXTENSIONS_NAMES, DEFAULT_SUPPORTED_CLIENT_EXTENSIONS
-
Fields inherited from class org.apache.sshd.common.util.logging.AbstractLoggingBean
log
-
Fields inherited from interface org.apache.sshd.sftp.server.SftpSubsystemEnvironment
ALL_SFTP_IMPL, HIGHER_SFTP_IMPL, LOWER_SFTP_IMPL, SUPPORTED_SFTP_VERSIONS
-
-
Constructor Summary
Constructors Constructor Description SftpSubsystem(CloseableExecutorService executorService, UnsupportedAttributePolicy policy, SftpFileSystemAccessor accessor, SftpErrorStatusDataHandler errorStatusDataHandler)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
close()
protected void
closeAllHandles()
protected void
createLink(int id, java.lang.String existingPath, java.lang.String linkPath, boolean symLink)
int
data(ChannelSession channel, byte[] buf, int start, int len)
Called when the server receives additional bytes from the client.void
destroy(ChannelSession channel)
This method is called by the SSH server to destroy the command because the client has disconnected somehow.protected void
doBlock(int id, java.lang.String handle, long offset, long length, int mask)
protected void
doCheckFileHash(int id, java.lang.String targetType, java.lang.String target, java.util.Collection<java.lang.String> algos, long startOffset, long length, int blockSize, Buffer buffer)
protected void
doClose(int id, java.lang.String handle)
protected void
doCopyData(int id, java.lang.String readHandle, long readOffset, long readLength, java.lang.String writeHandle, long writeOffset)
protected void
doFSetStat(int id, java.lang.String handle, java.util.Map<java.lang.String,?> attrs)
protected java.util.Map<java.lang.String,java.lang.Object>
doFStat(int id, java.lang.String handle, int flags)
protected void
doInit(Buffer buffer, int id)
protected byte[]
doMD5Hash(int id, java.lang.String targetType, java.lang.String target, long startOffset, long length, byte[] quickCheckHash)
protected java.lang.String
doOpen(int id, java.lang.String path, int pflags, int access, java.util.Map<java.lang.String,java.lang.Object> attrs)
protected java.lang.String
doOpenDir(int id, java.lang.String path, java.nio.file.Path p, java.nio.file.LinkOption... options)
protected void
doOpenSSHFsync(int id, java.lang.String handle)
protected void
doProcess(Buffer buffer, int length, int type, int id)
protected int
doRead(int id, java.lang.String handle, long offset, int length, byte[] data, int doff)
protected void
doReadDir(Buffer buffer, int id)
protected void
doTextSeek(int id, java.lang.String handle, long line)
protected void
doUnblock(int id, java.lang.String handle, long offset, long length)
protected void
doVersionSelect(Buffer buffer, int id, java.lang.String proposed)
protected void
doWrite(int id, java.lang.String handle, long offset, int length, byte[] data, int doff, int remaining)
protected java.lang.String
generateFileHandle(java.nio.file.Path file)
java.nio.file.Path
getDefaultDirectory()
CloseableExecutorService
getExecutorService()
ServerSession
getServerSession()
int
getVersion()
protected Buffer
prepareReply(Buffer buffer)
void
run()
protected void
send(Buffer buffer)
void
setChannelSession(ChannelSession session)
Receives the channel in which the command is being executed.void
setErrorStream(java.io.OutputStream err)
Set the error stream that can be used by the shell to write its errors.void
setExitCallback(ExitCallback callback)
Set the callback that the shell has to call when it is closed.void
setFileSystem(java.nio.file.FileSystem fileSystem)
Set the file system in which this shell will be executed.void
setInputStream(java.io.InputStream in)
Set the input stream that can be used by the shell to read input.void
setIoErrorStream(IoOutputStream err)
Set the error stream that can be used by the shell to write its errors.void
setIoInputStream(IoInputStream in)
Set the input stream that can be used by the shell to read input.void
setIoOutputStream(IoOutputStream out)
Set the output stream that can be used by the shell to write its output.void
setOutputStream(java.io.OutputStream out)
Set the output stream that can be used by the shell to write its output.void
setSession(ServerSession session)
void
start(ChannelSession channel, Environment env)
Starts the command execution.-
Methods inherited from class org.apache.sshd.sftp.server.AbstractSftpSubsystemHelper
addMissingAttribute, addSftpEventListener, appendAclSupportedExtension, appendExtensions, appendNewlineExtension, appendOpenSSHExtensions, appendSupported2Extension, appendSupportedExtension, appendVendorIdExtension, appendVersionsExtension, checkVersionCompatibility, doBlock, doCheckFileHash, doCheckFileHash, doClose, doCopyData, doCopyFile, doCopyFile, doCopyFile, doExtended, doFSetStat, doFStat, doLink, doLink, doLStat, doLStat, doMakeDirectory, doMakeDirectory, doMD5Hash, doMD5Hash, doOpen, doOpenDir, doOpenSSHFsync, doOpenSSHHardLink, doOpenSSHHardLink, doRead, doReadDir, doReadLink, doReadLink, doRealPath, doRealPathV345, doRealPathV6, doRemove, doRemove, doRemove, doRemoveDirectory, doRemoveDirectory, doRename, doRename, doRename, doSetAttributes, doSetStat, doSetStat, doSpaceAvailable, doSpaceAvailable, doStat, doStat, doSymLink, doSymLink, doTextSeek, doUnblock, doUnsupported, doUnsupportedExtension, doVersionSelect, doWrite, executeExtendedCommand, getAttributes, getAttributes, getErrorStatusDataHandler, getFileSystemAccessor, getLongName, getLongName, getLongName, getPathResolutionLinkOption, getSftpEventListenerProxy, getShortName, getSupportedClientExtensions, getUnsupportedAttributePolicy, handleReadFileAttributesException, handleSetFileAttributeFailure, handleUnknownStatusFileAttributes, handleUnsupportedAttributes, handleUserPrincipalLookupServiceException, normalize, process, readAttrs, readFileAttributes, removeSftpEventListener, resolveAclSupportedCapabilities, resolveFile, resolveFileAttributes, resolveMissingFileAttributes, resolveMissingFileAttributeValue, resolveNewlineValue, resolveNormalizedLocation, resolveOpenSSHExtensions, resolvePathResolutionFollowLinks, sendAttrs, sendHandle, sendLink, sendPath, sendStatus, sendStatus, sendStatus, setFileAccessControl, setFileAttribute, setFileAttributes, setFileExtensions, setFileOwnership, setFilePermissions, setFileRawViewAttribute, setFileTime, signalOpenFailure, signalRemovalPreConditionFailure, toGroup, toUser, validateHandle, validateProposedVersion, validateRealPath, writeAttrs, writeDirEntry
-
Methods inherited from class org.apache.sshd.common.util.logging.AbstractLoggingBean
debug, debug, debug, debug, debug, error, error, error, error, error, getSimplifiedLogger, info, info, warn, warn, warn, warn, warn, warn, warn, warn
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface org.apache.sshd.common.file.FileSystemAware
setFileSystemFactory
-
Methods inherited from interface org.apache.sshd.common.session.SessionHolder
getSessionContext
-
Methods inherited from interface org.apache.sshd.sftp.server.SftpSubsystemEnvironment
getSession
-
-
-
-
Field Detail
-
CLOSE
protected static final Buffer CLOSE
-
closed
protected final java.util.concurrent.atomic.AtomicBoolean closed
-
requestsCount
protected final java.util.concurrent.atomic.AtomicLong requestsCount
-
extensions
protected final java.util.Map<java.lang.String,byte[]> extensions
-
handles
protected final java.util.Map<java.lang.String,Handle> handles
-
buffer
protected final Buffer buffer
-
requests
protected final java.util.concurrent.BlockingQueue<Buffer> requests
-
callback
protected ExitCallback callback
-
out
protected IoOutputStream out
-
err
protected IoOutputStream err
-
env
protected Environment env
-
randomizer
protected Random randomizer
-
fileHandleSize
protected int fileHandleSize
-
maxFileHandleRounds
protected int maxFileHandleRounds
-
pendingFuture
protected java.util.concurrent.Future<?> pendingFuture
-
workBuf
protected byte[] workBuf
-
fileSystem
protected java.nio.file.FileSystem fileSystem
-
defaultDir
protected java.nio.file.Path defaultDir
-
version
protected int version
-
serverSession
protected ServerSession serverSession
-
channelSession
protected ChannelSession channelSession
-
executorService
protected CloseableExecutorService executorService
-
-
Constructor Detail
-
SftpSubsystem
public SftpSubsystem(CloseableExecutorService executorService, UnsupportedAttributePolicy policy, SftpFileSystemAccessor accessor, SftpErrorStatusDataHandler errorStatusDataHandler)
- Parameters:
executorService
- TheCloseableExecutorService
to be used by theSftpSubsystem
command when starting execution. Ifnull
then a single-threaded ad-hoc service is used.policy
- TheUnsupportedAttributePolicy
to use if failed to access some local file attributesaccessor
- TheSftpFileSystemAccessor
to use for opening files and directorieserrorStatusDataHandler
- The (nevernull
)SftpErrorStatusDataHandler
to use when generating failed commands error messages- See Also:
ThreadUtils.newSingleThreadExecutor(String)
-
-
Method Detail
-
getVersion
public int getVersion()
- Specified by:
getVersion
in interfaceSftpSubsystemEnvironment
- Returns:
- The negotiated version
-
getDefaultDirectory
public java.nio.file.Path getDefaultDirectory()
- Specified by:
getDefaultDirectory
in interfaceSftpSubsystemEnvironment
- Returns:
- The default root directory used to resolve relative paths - a.k.a. the
chroot
location
-
getExecutorService
public CloseableExecutorService getExecutorService()
- Specified by:
getExecutorService
in interfaceExecutorServiceCarrier
- Returns:
- The
CloseableExecutorService
to use
-
setSession
public void setSession(ServerSession session)
- Specified by:
setSession
in interfaceSessionAware
- Parameters:
session
- TheServerSession
in which this shell will be executed.
-
getServerSession
public ServerSession getServerSession()
- Specified by:
getServerSession
in interfaceServerSessionHolder
- Returns:
- The underlying
ServerSession
used
-
setChannelSession
public void setChannelSession(ChannelSession session)
Description copied from interface:ChannelSessionAware
Receives the channel in which the command is being executed.- Specified by:
setChannelSession
in interfaceChannelSessionAware
- Parameters:
session
- never null
-
setFileSystem
public void setFileSystem(java.nio.file.FileSystem fileSystem)
Description copied from interface:FileSystemAware
Set the file system in which this shell will be executed.- Specified by:
setFileSystem
in interfaceFileSystemAware
- Parameters:
fileSystem
- the file system
-
setExitCallback
public void setExitCallback(ExitCallback callback)
Description copied from interface:Command
Set the callback that the shell has to call when it is closed.- Specified by:
setExitCallback
in interfaceCommand
- Parameters:
callback
- TheExitCallback
to call when shell is closed
-
setInputStream
public void setInputStream(java.io.InputStream in)
Description copied from interface:Command
Set the input stream that can be used by the shell to read input.- Specified by:
setInputStream
in interfaceCommand
- Parameters:
in
- TheInputStream
used by the shell to read input.
-
setOutputStream
public void setOutputStream(java.io.OutputStream out)
Description copied from interface:Command
Set the output stream that can be used by the shell to write its output.- Specified by:
setOutputStream
in interfaceCommand
- Parameters:
out
- TheOutputStream
used by the shell to write its output
-
setErrorStream
public void setErrorStream(java.io.OutputStream err)
Description copied from interface:Command
Set the error stream that can be used by the shell to write its errors.- Specified by:
setErrorStream
in interfaceCommand
- Parameters:
err
- TheOutputStream
used by the shell to write its errors
-
setIoInputStream
public void setIoInputStream(IoInputStream in)
Description copied from interface:AsyncCommand
Set the input stream that can be used by the shell to read input.- Specified by:
setIoInputStream
in interfaceAsyncCommand
- Parameters:
in
- TheIoInputStream
used by the shell to read input
-
setIoOutputStream
public void setIoOutputStream(IoOutputStream out)
Description copied from interface:AsyncCommand
Set the output stream that can be used by the shell to write its output.- Specified by:
setIoOutputStream
in interfaceAsyncCommand
- Parameters:
out
- TheIoOutputStream
used by the shell to write its output
-
setIoErrorStream
public void setIoErrorStream(IoOutputStream err)
Description copied from interface:AsyncCommand
Set the error stream that can be used by the shell to write its errors.- Specified by:
setIoErrorStream
in interfaceAsyncCommand
- Parameters:
err
- TheIoOutputStream
used by the shell to write its errors
-
start
public void start(ChannelSession channel, Environment env) throws java.io.IOException
Description copied from interface:CommandLifecycle
Starts the command execution. All streams must have been set before calling this method. The command should implementRunnable
, and this method should spawn a new thread like:Thread(this).start();
- Specified by:
start
in interfaceCommandLifecycle
- Parameters:
channel
- TheChannelSession
through which the command has been receivedenv
- TheEnvironment
- Throws:
java.io.IOException
- If failed to start
-
data
public int data(ChannelSession channel, byte[] buf, int start, int len) throws java.io.IOException
Description copied from interface:ChannelDataReceiver
Called when the server receives additional bytes from the client. When
Closeable.close()
-d then indicates EOF - The client will no longer send us any more data.SSH channels use the windowing mechanism to perform flow control, much like TCP does. The server gives the client the initial window size, which represents the number of bytes the client can send to the server. As the server receives data, it can send a message to the client to allow it to send more data.
The return value from this method is used to control this behaviour. Intuitively speaking, the callee returns the number of bytes consumed by this method, by the time this method returns. Picture a one-way long bridge (for example Golden Gate Bridge) with toll plazas on both sides. The window size is the maximum number of cars allowed on the bridge. Here we are on the receiving end, so our job here is to count the number of cars as it leaves the bridge, and if enough of them left, we'll signal the sending end that they can let in more cars. The return value of this method counts the number of cars that are leaving in this batch.
In simple cases, where the callee has consumed the bytes before it returns, the return value must be the same value as the 'len' parameter given.
On the other hand, if the callee is queueing up the received bytes somewhere to be consumed later (for example by another thread), then this method should return 0, for the bytes aren't really consumed yet. And when at some later point the bytes are actually used, then you'll invoke
channel.getLocalWindow().consumeAndCheck(len)
to let the channel know that bytes are consumed.This behaviour will result in a better flow control, as the server will not allow the SSH client to overflow its buffer. If instead you always return the value passed in the 'len' parameter, the place where you are queueing up bytes may overflow.
In either case, the callee must account for every bytes it receives in this method. Returning 0 and failing to call back
channel.getLocalWindow().consumeAndCheck(len)
later will dry up the window size, and eventually the client will stop sending you any data.In the SSH protocol, this method invocation is triggered by a SSH_MSG_CHANNEL_DATA message.
- Specified by:
data
in interfaceChannelDataReceiver
- Parameters:
channel
- The caller to which thisChannelDataReceiver
is assigned. Never null.buf
- Holds the bytes received. This buffer belongs to the caller, and it might get reused by the caller as soon as this method returns.start
- buf[start] is the first byte that received from the client.len
- the length of the bytes received. Can be zero.- Returns:
- The number of bytes consumed, for the purpose of the flow control. For a simple use case, you return the value given by the 'len' parameter. See the method javadoc for more details.
- Throws:
java.io.IOException
- if failed to consume the data
-
run
public void run()
- Specified by:
run
in interfacejava.lang.Runnable
-
close
public void close() throws java.io.IOException
- Specified by:
close
in interfacejava.lang.AutoCloseable
- Specified by:
close
in interfacejava.io.Closeable
- Throws:
java.io.IOException
-
doProcess
protected void doProcess(Buffer buffer, int length, int type, int id) throws java.io.IOException
- Overrides:
doProcess
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
createLink
protected void createLink(int id, java.lang.String existingPath, java.lang.String linkPath, boolean symLink) throws java.io.IOException
- Specified by:
createLink
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doTextSeek
protected void doTextSeek(int id, java.lang.String handle, long line) throws java.io.IOException
- Specified by:
doTextSeek
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doOpenSSHFsync
protected void doOpenSSHFsync(int id, java.lang.String handle) throws java.io.IOException
- Specified by:
doOpenSSHFsync
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doCheckFileHash
protected void doCheckFileHash(int id, java.lang.String targetType, java.lang.String target, java.util.Collection<java.lang.String> algos, long startOffset, long length, int blockSize, Buffer buffer) throws java.lang.Exception
- Specified by:
doCheckFileHash
in classAbstractSftpSubsystemHelper
- Throws:
java.lang.Exception
-
doMD5Hash
protected byte[] doMD5Hash(int id, java.lang.String targetType, java.lang.String target, long startOffset, long length, byte[] quickCheckHash) throws java.lang.Exception
- Specified by:
doMD5Hash
in classAbstractSftpSubsystemHelper
- Throws:
java.lang.Exception
-
doVersionSelect
protected void doVersionSelect(Buffer buffer, int id, java.lang.String proposed) throws java.io.IOException
- Specified by:
doVersionSelect
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doBlock
protected void doBlock(int id, java.lang.String handle, long offset, long length, int mask) throws java.io.IOException
- Specified by:
doBlock
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doUnblock
protected void doUnblock(int id, java.lang.String handle, long offset, long length) throws java.io.IOException
- Specified by:
doUnblock
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doCopyData
protected void doCopyData(int id, java.lang.String readHandle, long readOffset, long readLength, java.lang.String writeHandle, long writeOffset) throws java.io.IOException
- Specified by:
doCopyData
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doReadDir
protected void doReadDir(Buffer buffer, int id) throws java.io.IOException
- Specified by:
doReadDir
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doOpenDir
protected java.lang.String doOpenDir(int id, java.lang.String path, java.nio.file.Path p, java.nio.file.LinkOption... options) throws java.io.IOException
- Specified by:
doOpenDir
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doFSetStat
protected void doFSetStat(int id, java.lang.String handle, java.util.Map<java.lang.String,?> attrs) throws java.io.IOException
- Specified by:
doFSetStat
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doFStat
protected java.util.Map<java.lang.String,java.lang.Object> doFStat(int id, java.lang.String handle, int flags) throws java.io.IOException
- Specified by:
doFStat
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doWrite
protected void doWrite(int id, java.lang.String handle, long offset, int length, byte[] data, int doff, int remaining) throws java.io.IOException
- Specified by:
doWrite
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doRead
protected int doRead(int id, java.lang.String handle, long offset, int length, byte[] data, int doff) throws java.io.IOException
- Specified by:
doRead
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doClose
protected void doClose(int id, java.lang.String handle) throws java.io.IOException
- Specified by:
doClose
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
doOpen
protected java.lang.String doOpen(int id, java.lang.String path, int pflags, int access, java.util.Map<java.lang.String,java.lang.Object> attrs) throws java.io.IOException
- Specified by:
doOpen
in classAbstractSftpSubsystemHelper
- Parameters:
id
- Request idpath
- Pathpflags
- Open mode flags - seeSSH_FXF_XXX
flagsaccess
- Access mode flags - seeACE4_XXX
flagsattrs
- Requested attributes- Returns:
- The assigned (opaque) handle
- Throws:
java.io.IOException
- if failed to execute
-
generateFileHandle
protected java.lang.String generateFileHandle(java.nio.file.Path file) throws java.io.IOException
- Throws:
java.io.IOException
-
doInit
protected void doInit(Buffer buffer, int id) throws java.io.IOException
- Specified by:
doInit
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
prepareReply
protected Buffer prepareReply(Buffer buffer)
- Specified by:
prepareReply
in classAbstractSftpSubsystemHelper
-
send
protected void send(Buffer buffer) throws java.io.IOException
- Specified by:
send
in classAbstractSftpSubsystemHelper
- Throws:
java.io.IOException
-
destroy
public void destroy(ChannelSession channel)
Description copied from interface:CommandLifecycle
This method is called by the SSH server to destroy the command because the client has disconnected somehow.- Specified by:
destroy
in interfaceCommandLifecycle
- Parameters:
channel
- TheChannelSession
through which the command has been received
-
closeAllHandles
protected void closeAllHandles()
-
-