[
https://issues.apache.org/jira/browse/CAMEL-26066?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Federico Mariani updated CAMEL-26066:
-------------------------------------
Description:
The scp producer sends the name of the file it writes inside the scp protocol,
on a line that ends with a line feed: {{D0775 0 <dir>}} for each directory in
the name, then {{C0<chmod> <size> <name>}} for the file
({{ScpOperations.writeFile}}, main faa015319ee7, lines 458 and 488).
The name comes from the {{CamelFileName}} header or the {{fileName}} option.
The producer checks that it stays inside the starting directory, and the
{{chmod}} option must be three octal digits, but nothing checks the name for a
line feed or another control character, which file systems allow in a file
name. A line feed would end the protocol line early, and the remote scp would
read the rest of the name as the next line.
*Proposal*:
* refuse a name with a line feed, a carriage return or another control
character with a {{GenericFileOperationFailedException}}, before anything is
sent;
* test it against the embedded SSH server of the camel-jsch tests;
* mention it in the scp docs.
_Claude Code on behalf of davsclaus_
----
*Update:* the fix ([PR #29285|https://github.com/apache/camel/pull/29285])
refuses only a line feed and a NUL character, with a
{{GenericFileOperationFailedException}} before scp is started on the remote
host. The check covers the directory names as well as the file name.
* *Line feed:* it ends the protocol line early, so the remote scp writes the
file under another name, or leaves a stray directory when the line feed is in a
directory name.
* *NUL:* it is never part of a valid name. Apache SSHD refuses it after scp has
started. The OpenSSH scp sink before 10.6 reads the line as a C string and cuts
the name at the NUL; OpenSSH 10.6p1 refuses it as well (openssh-portable
[e27b6cc2|https://github.com/openssh/openssh-portable/commit/e27b6cc2e6e8ba03808f7078740e5ba800515d4d],
"Disallow nul byte in received scp -O filename").
A carriage return, a tab and the other control characters are still accepted.
The scp sinks of Apache SSHD and OpenSSH end a protocol line on the line feed
only, so such a name is written as given, and refusing it would change the
behaviour without fixing a bug.
_Claude Code on behalf of Federico Mariani_
h3. Update: the scp producer could report success before the file was written
While this issue was reopened for a test that failed on the Jenkins builds, a
second problem in the scp producer was fixed under it
(https://github.com/apache/camel/pull/29333, backported to camel-4.22.x by
https://github.com/apache/camel/pull/29334 and to camel-4.18.x by
https://github.com/apache/camel/pull/29335).
The remote scp sends a first acknowledgement as soon as it starts, and the
producer took the channel streams only after connecting, so JSch could drop
that acknowledgement or not, depending on timing. When it was kept, every later
acknowledgement was read one step behind. The exchange then completed before
the server had written the file, and an error that the server reported for the
file, for example when it could not write it, was not seen, so the exchange
succeeded.
The producer now takes the streams before it connects and reads that first
acknowledgement, so an exchange completes once the server has written the file,
and a server error for the file fails the exchange.
_Claude Code on behalf of Federico Mariani_
was:
The scp producer sends the name of the file it writes inside the scp protocol,
on a line that ends with a line feed: {{D0775 0 <dir>}} for each directory in
the name, then {{C0<chmod> <size> <name>}} for the file
({{ScpOperations.writeFile}}, main faa015319ee7, lines 458 and 488).
The name comes from the {{CamelFileName}} header or the {{fileName}} option.
The producer checks that it stays inside the starting directory, and the
{{chmod}} option must be three octal digits, but nothing checks the name for a
line feed or another control character, which file systems allow in a file
name. A line feed would end the protocol line early, and the remote scp would
read the rest of the name as the next line.
*Proposal*:
* refuse a name with a line feed, a carriage return or another control
character with a {{GenericFileOperationFailedException}}, before anything is
sent;
* test it against the embedded SSH server of the camel-jsch tests;
* mention it in the scp docs.
_Claude Code on behalf of davsclaus_
----
*Update:* the fix ([PR #29285|https://github.com/apache/camel/pull/29285])
refuses only a line feed and a NUL character, with a
{{GenericFileOperationFailedException}} before scp is started on the remote
host. The check covers the directory names as well as the file name.
* *Line feed:* it ends the protocol line early, so the remote scp writes the
file under another name, or leaves a stray directory when the line feed is in a
directory name.
* *NUL:* it is never part of a valid name. Apache SSHD refuses it after scp has
started. The OpenSSH scp sink before 10.6 reads the line as a C string and cuts
the name at the NUL; OpenSSH 10.6p1 refuses it as well (openssh-portable
[e27b6cc2|https://github.com/openssh/openssh-portable/commit/e27b6cc2e6e8ba03808f7078740e5ba800515d4d],
"Disallow nul byte in received scp -O filename").
A carriage return, a tab and the other control characters are still accepted.
The scp sinks of Apache SSHD and OpenSSH end a protocol line on the line feed
only, so such a name is written as given, and refusing it would change the
behaviour without fixing a bug.
_Claude Code on behalf of Federico Mariani_
> camel-jsch - the scp producer should refuse a file name with a line feed or a
> NUL character
> -------------------------------------------------------------------------------------------
>
> Key: CAMEL-26066
> URL: https://issues.apache.org/jira/browse/CAMEL-26066
> Project: Camel
> Issue Type: Improvement
> Components: camel-jsch
> Reporter: Claus Ibsen
> Assignee: Federico Mariani
> Priority: Major
> Fix For: 4.18.6, 4.22.3, 4.24.0
>
>
> The scp producer sends the name of the file it writes inside the scp
> protocol, on a line that ends with a line feed: {{D0775 0 <dir>}} for each
> directory in the name, then {{C0<chmod> <size> <name>}} for the file
> ({{ScpOperations.writeFile}}, main faa015319ee7, lines 458 and 488).
> The name comes from the {{CamelFileName}} header or the {{fileName}} option.
> The producer checks that it stays inside the starting directory, and the
> {{chmod}} option must be three octal digits, but nothing checks the name for
> a line feed or another control character, which file systems allow in a file
> name. A line feed would end the protocol line early, and the remote scp would
> read the rest of the name as the next line.
> *Proposal*:
> * refuse a name with a line feed, a carriage return or another control
> character with a {{GenericFileOperationFailedException}}, before anything is
> sent;
> * test it against the embedded SSH server of the camel-jsch tests;
> * mention it in the scp docs.
> _Claude Code on behalf of davsclaus_
> ----
> *Update:* the fix ([PR #29285|https://github.com/apache/camel/pull/29285])
> refuses only a line feed and a NUL character, with a
> {{GenericFileOperationFailedException}} before scp is started on the remote
> host. The check covers the directory names as well as the file name.
> * *Line feed:* it ends the protocol line early, so the remote scp writes the
> file under another name, or leaves a stray directory when the line feed is in
> a directory name.
> * *NUL:* it is never part of a valid name. Apache SSHD refuses it after scp
> has started. The OpenSSH scp sink before 10.6 reads the line as a C string
> and cuts the name at the NUL; OpenSSH 10.6p1 refuses it as well
> (openssh-portable
> [e27b6cc2|https://github.com/openssh/openssh-portable/commit/e27b6cc2e6e8ba03808f7078740e5ba800515d4d],
> "Disallow nul byte in received scp -O filename").
> A carriage return, a tab and the other control characters are still accepted.
> The scp sinks of Apache SSHD and OpenSSH end a protocol line on the line feed
> only, so such a name is written as given, and refusing it would change the
> behaviour without fixing a bug.
> _Claude Code on behalf of Federico Mariani_
> h3. Update: the scp producer could report success before the file was written
> While this issue was reopened for a test that failed on the Jenkins builds, a
> second problem in the scp producer was fixed under it
> (https://github.com/apache/camel/pull/29333, backported to camel-4.22.x by
> https://github.com/apache/camel/pull/29334 and to camel-4.18.x by
> https://github.com/apache/camel/pull/29335).
> The remote scp sends a first acknowledgement as soon as it starts, and the
> producer took the channel streams only after connecting, so JSch could drop
> that acknowledgement or not, depending on timing. When it was kept, every
> later acknowledgement was read one step behind. The exchange then completed
> before the server had written the file, and an error that the server reported
> for the file, for example when it could not write it, was not seen, so the
> exchange succeeded.
> The producer now takes the streams before it connects and reads that first
> acknowledgement, so an exchange completes once the server has written the
> file, and a server error for the file fails the exchange.
> _Claude Code on behalf of Federico Mariani_
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)