|
|
@@ -2733,68 +2733,75 @@ int __fastcall TSFTPFileSystem::SendPacketAndReceiveResponse(
|
|
|
//---------------------------------------------------------------------------
|
|
|
UnicodeString __fastcall TSFTPFileSystem::RealPath(const UnicodeString Path)
|
|
|
{
|
|
|
- try
|
|
|
+ if (FTerminal->SessionData->SFTPRealPath == asOff)
|
|
|
{
|
|
|
- FTerminal->LogEvent(0, FORMAT(L"Getting real path for '%s'", (Path)));
|
|
|
-
|
|
|
- TSFTPPacket Packet(SSH_FXP_REALPATH);
|
|
|
- AddPathString(Packet, Path);
|
|
|
-
|
|
|
- // In SFTP-6 new optional field control-byte is added that defaults to
|
|
|
- // SSH_FXP_REALPATH_NO_CHECK=0x01, meaning it won't fail, if the path does not exist.
|
|
|
- // That differs from SFTP-5 recommendation that
|
|
|
- // "The server SHOULD fail the request if the path is not present on the server."
|
|
|
- // Earlier versions had no recommendation, though canonical SFTP-3 implementation
|
|
|
- // in OpenSSH fails.
|
|
|
-
|
|
|
- // While we really do not care much, we anyway set the flag to ~ & 0x01 to make the request fail.
|
|
|
- // First for consistency.
|
|
|
- // Second to workaround a bug in ProFTPD/mod_sftp version 1.3.5rc1 through 1.3.5-stable
|
|
|
- // that sends a completelly malformed response for non-existing paths,
|
|
|
- // when SSH_FXP_REALPATH_NO_CHECK (even implicitly) is used.
|
|
|
- // See http://bugs.proftpd.org/show_bug.cgi?id=4160
|
|
|
-
|
|
|
- // Note that earlier drafts of SFTP-6 (filexfer-07 and -08) had optional compose-path field
|
|
|
- // before control-byte field. If we ever use this against a server conforming to those drafts,
|
|
|
- // it may cause trouble.
|
|
|
- if (FVersion >= 6)
|
|
|
+ return LocalCanonify(Path);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ try
|
|
|
{
|
|
|
- if (FSecureShell->SshImplementation != sshiProFTPD)
|
|
|
+ FTerminal->LogEvent(0, FORMAT(L"Getting real path for '%s'", (Path)));
|
|
|
+
|
|
|
+ TSFTPPacket Packet(SSH_FXP_REALPATH);
|
|
|
+ AddPathString(Packet, Path);
|
|
|
+
|
|
|
+ // In SFTP-6 new optional field control-byte is added that defaults to
|
|
|
+ // SSH_FXP_REALPATH_NO_CHECK=0x01, meaning it won't fail, if the path does not exist.
|
|
|
+ // That differs from SFTP-5 recommendation that
|
|
|
+ // "The server SHOULD fail the request if the path is not present on the server."
|
|
|
+ // Earlier versions had no recommendation, though canonical SFTP-3 implementation
|
|
|
+ // in OpenSSH fails.
|
|
|
+
|
|
|
+ // While we really do not care much, we anyway set the flag to ~ & 0x01 to make the request fail.
|
|
|
+ // First for consistency.
|
|
|
+ // Second to workaround a bug in ProFTPD/mod_sftp version 1.3.5rc1 through 1.3.5-stable
|
|
|
+ // that sends a completelly malformed response for non-existing paths,
|
|
|
+ // when SSH_FXP_REALPATH_NO_CHECK (even implicitly) is used.
|
|
|
+ // See http://bugs.proftpd.org/show_bug.cgi?id=4160
|
|
|
+
|
|
|
+ // Note that earlier drafts of SFTP-6 (filexfer-07 and -08) had optional compose-path field
|
|
|
+ // before control-byte field. If we ever use this against a server conforming to those drafts,
|
|
|
+ // it may cause trouble.
|
|
|
+ if (FVersion >= 6)
|
|
|
{
|
|
|
- Packet.AddByte(SSH_FXP_REALPATH_STAT_ALWAYS);
|
|
|
+ if (FSecureShell->SshImplementation != sshiProFTPD)
|
|
|
+ {
|
|
|
+ Packet.AddByte(SSH_FXP_REALPATH_STAT_ALWAYS);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Cannot use SSH_FXP_REALPATH_STAT_ALWAYS as ProFTPD does wrong bitwise test
|
|
|
+ // so it incorrectly evaluates SSH_FXP_REALPATH_STAT_ALWAYS (0x03) as
|
|
|
+ // SSH_FXP_REALPATH_NO_CHECK (0x01). The only value conforming to the
|
|
|
+ // specification, yet working with ProFTPD is SSH_FXP_REALPATH_STAT_IF (0x02).
|
|
|
+ Packet.AddByte(SSH_FXP_REALPATH_STAT_IF);
|
|
|
+ }
|
|
|
}
|
|
|
- else
|
|
|
+ SendPacketAndReceiveResponse(&Packet, &Packet, SSH_FXP_NAME);
|
|
|
+ if (Packet.GetCardinal() != 1)
|
|
|
{
|
|
|
- // Cannot use SSH_FXP_REALPATH_STAT_ALWAYS as ProFTPD does wrong bitwise test
|
|
|
- // so it incorrectly evaluates SSH_FXP_REALPATH_STAT_ALWAYS (0x03) as
|
|
|
- // SSH_FXP_REALPATH_NO_CHECK (0x01). The only value conforming to the
|
|
|
- // specification, yet working with ProFTPD is SSH_FXP_REALPATH_STAT_IF (0x02).
|
|
|
- Packet.AddByte(SSH_FXP_REALPATH_STAT_IF);
|
|
|
+ FTerminal->FatalError(NULL, LoadStr(SFTP_NON_ONE_FXP_NAME_PACKET));
|
|
|
}
|
|
|
- }
|
|
|
- SendPacketAndReceiveResponse(&Packet, &Packet, SSH_FXP_NAME);
|
|
|
- if (Packet.GetCardinal() != 1)
|
|
|
- {
|
|
|
- FTerminal->FatalError(NULL, LoadStr(SFTP_NON_ONE_FXP_NAME_PACKET));
|
|
|
- }
|
|
|
|
|
|
- UnicodeString RealDir = UnixExcludeTrailingBackslash(Packet.GetPathString(FUtfStrings));
|
|
|
- RealDir = FTerminal->DecryptFileName(RealDir);
|
|
|
- // ignore rest of SSH_FXP_NAME packet
|
|
|
+ UnicodeString RealDir = UnixExcludeTrailingBackslash(Packet.GetPathString(FUtfStrings));
|
|
|
+ RealDir = FTerminal->DecryptFileName(RealDir);
|
|
|
+ // ignore rest of SSH_FXP_NAME packet
|
|
|
|
|
|
- FTerminal->LogEvent(0, FORMAT(L"Real path is '%s'", (RealDir)));
|
|
|
+ FTerminal->LogEvent(0, FORMAT(L"Real path is '%s'", (RealDir)));
|
|
|
|
|
|
- return RealDir;
|
|
|
- }
|
|
|
- catch(Exception & E)
|
|
|
- {
|
|
|
- if (FTerminal->Active)
|
|
|
- {
|
|
|
- throw ExtException(&E, FMTLOAD(SFTP_REALPATH_ERROR, (Path)));
|
|
|
+ return RealDir;
|
|
|
}
|
|
|
- else
|
|
|
+ catch(Exception & E)
|
|
|
{
|
|
|
- throw;
|
|
|
+ if (FTerminal->Active)
|
|
|
+ {
|
|
|
+ throw ExtException(&E, FMTLOAD(SFTP_REALPATH_ERROR, (Path)));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ throw;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|