[ 
https://issues.apache.org/jira/browse/CAMEL-25886?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18129475#comment-18129475
 ] 

shashank commented on CAMEL-25886:
----------------------------------

Test for the expected behaviour: with jailStartingDirectory (default) the sftp 
consumer consumes the plain file and the link inside the starting directory, 
and skips the link to a file outside it. Goes in camel-ftp’s sftp integration 
tests.

> camel-ftp/mina-sftp - resolve listed symbolic links for jailStartingDirectory
> -----------------------------------------------------------------------------
>
>                 Key: CAMEL-25886
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25886
>             Project: Camel
>          Issue Type: Improvement
>          Components: camel-ftp, camel-mina-sftp
>            Reporter: Andrea Cosentino
>            Assignee: Andrea Cosentino
>            Priority: Major
>             Fix For: 4.18.6, 4.22.3, 4.24.0
>
>         Attachments: SftpConsumerSymlinkJailStartingDirectoryIT.java
>
>
> The SFTP consumers ({{sftp}} in camel-ftp and {{mina-sftp}}) apply 
> {{jailStartingDirectory}} to the path built from each listed name only: 
> {{RemoteFileConsumer.isWithinStartingDirectory()}} (camel-ftp-common) 
> compacts that path and compares it with the starting directory as text. The 
> 4.23 upgrade guide note of CAMEL-25412 states that the remote file consumers 
> keep this lexical check. A listed entry that the server reports as a symbolic 
> link is therefore handled like any other entry:
> * {{SftpRemoteFile}} has no accessor for the link flag of the listing 
> attributes, so {{SftpRemoteFileJCraft}} ({{ChannelSftp.LsEntry}}) and 
> {{MinaSftpRemoteFile}} ({{SftpClient.DirEntry}}) do not expose it.
> * {{AbstractSftpConsumer.doPollDirectory()}} (camel-ftp-common, shared by 
> both consumers) treats every entry that is not a directory as a file.
> * The retrieval ({{ChannelSftp.get()}} in {{SftpOperations}}, 
> {{SftpClient.read()}} in {{MinaSftpOperations}}) is resolved by the server, 
> which follows the link to its target wherever that is.
> camel-file resolves symbolic links for {{jailStartingDirectory}} since 
> CAMEL-25412, and the ftp consumer ignores entries that the server lists as 
> links ({{FtpConsumer}}, "Ignoring unsupported remote file type"). This change 
> gives the SFTP consumers the same semantics as camel-file.
> h3. Behaviour after the change
> With {{jailStartingDirectory}} enabled (the default):
> * A listed entry that the server reports as a symbolic link is resolved on 
> the server before it is accepted. If its target is outside the starting 
> directory, the entry is skipped and logged by 
> {{GenericFileConsumer.isValidFile()}} as for the existing lexical check (WARN 
> the first time, DEBUG on later polls).
> * A link whose target cannot be resolved (a dangling link) is skipped.
> * Links that resolve inside the starting directory, and a starting directory 
> that is itself a link, work as before, so {{MinaSftpSymlinkIT}} and the 
> "Symbolic Links" section of the mina-sftp documentation stay valid.
> With {{jailStartingDirectory=false}} the consumers keep following every link, 
> as today. No new option is added, so the endpoint metadata does not change.
> h3. Proposed change
> * {{SftpRemoteFile}} (camel-ftp-common): add {{default boolean 
> isSymbolicLink()}} returning {{false}}, so {{SftpRemoteFileSingle}} and other 
> implementations stay compatible. {{SftpRemoteFileJCraft}} returns 
> {{entry.getAttrs().isLink()}} and {{MinaSftpRemoteFile}} returns 
> {{entry.getAttributes().isSymbolicLink()}}.
> * A small interface in camel-ftp-common that resolves a link on the server, 
> implemented by {{SftpOperations}} ({{ChannelSftp.realpath()}} and 
> {{readlink()}}) and {{MinaSftpOperations}} ({{SftpClient.canonicalPath()}} 
> and {{readLink()}}), instead of a new method on the public 
> {{RemoteFileOperations}} interface, which {{FtpOperations}} implements too. 
> It uses realpath. Where the server's realpath does not resolve links (it 
> returns the link's own path, as Apache MINA SSHD does), it resolves the 
> target itself with lstat and readlink, component by component, relative to 
> the link's directory and up to a fixed number of links. The starting 
> directory is resolved the same way, once per poll.
> * {{AbstractSftpConsumer}}: check an entry flagged as a link right after the 
> existing lexical check, either through a protected overload of the 
> {{GenericFileConsumer.isWithinStartingDirectory()}} hook that also receives 
> the listed entry (defaulting to the String variant), or in 
> {{AbstractSftpConsumer}} itself.
> * Only entries that the server reports as links are resolved, and no entry is 
> required to be a regular file. CAMEL-1247 removed an earlier check that 
> skipped the entries listed as links, because on Windows it skipped regular 
> files too; the current {{SftpATTRS.isLink()}} compares the whole file type 
> field.
> * camel-4.18.x has no camel-ftp-common: there {{SftpConsumer}} and 
> {{MinaSftpConsumer}} each have their own polling loop, so the change goes 
> into both, and the CAMEL-1247 comment in {{SftpConsumer}} is replaced.
> h3. Documentation
> * {{sftp-component.adoc}}: a "Symbolic links and the starting directory" 
> section, as in {{file-component.adoc}}.
> * {{mina-sftp-component.adoc}}: amend "Symbolic Links": links resolving 
> outside the starting directory are skipped unless 
> {{jailStartingDirectory=false}}.
> * Regenerate the catalog copies of both pages.
> * Upgrade guide notes on main, since links to files outside the starting 
> directory are no longer consumed: {{camel-4x-upgrade-guide-4_24.adoc}}, plus 
> the "Upgrading from 4.22.2 to 4.22.3" section of the 4_22 guide and the 
> "Upgrading from 4.18.5 to 4.18.6" section of the 4_18 guide. While there, add 
> the CAMEL-25412 notes that main's 4_22 and 4_18 guides do not have yet.
> h3. Tests
> * {{RemoteFileConsumerStartingDirectoryJailTest}} (camel-ftp): with stubbed 
> listing entries, a link resolving outside the starting directory is skipped 
> and a link resolving inside is accepted.
> * New {{SftpConsumerJailStartingDirectorySymlinkIT}} (camel-ftp) and 
> {{MinaSftpConsumerJailStartingDirectorySymlinkIT}} (camel-mina-sftp): a link 
> resolving inside is consumed; a link resolving outside is skipped, and 
> consumed when {{jailStartingDirectory=false}}; a dangling link is skipped. 
> The embedded SFTP server (Apache MINA SSHD with its default settings) lists a 
> link as a link, as OpenSSH does, so the tests run against it unchanged.
> * {{MinaSftpSymlinkIT}} stays green.
> h3. Notes
> * Whether a listing reports an entry as a link depends on the server. OpenSSH 
> and Apache MINA SSHD (with its default settings) list a link with its own 
> attributes, so the listing is enough there. A server that reports the 
> target's attributes in its listings hides the link; recognising such entries 
> too would need an LSTAT per listed entry, one more round trip per file and 
> poll. The proposal relies on the listing attributes, and the documentation 
> says so.
> * The check and the retrieval that follows are not atomic (an SFTP open 
> follows links on the server), so the permissions and link settings of the 
> SFTP server still matter.
> * Backport to camel-4.22.x and camel-4.18.x, as for CAMEL-25412.
> ----
> _Claude Code on behalf of [~acosentino]_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to