Skip to content

fix: respect exclusive SFTP create requests#322

Open
metabrixkt wants to merge 2 commits into
pterodactyl:developfrom
metabrixkt:fix/sftp-exclusive-create
Open

fix: respect exclusive SFTP create requests#322
metabrixkt wants to merge 2 commits into
pterodactyl:developfrom
metabrixkt:fix/sftp-exclusive-create

Conversation

@metabrixkt
Copy link
Copy Markdown

Fixes pterodactyl/panel#4739

What was wrong?

SFTP request flags SSH_FXF_CREAT | SSH_FXF_EXCL mean "create this file, but fail if it already exists", semantically identical to a POSIX open with flags O_CREAT | O_EXCL.

Wings was ignoring the exclusive-create part of the request. Even when a client opened a file with SSH_FXF_CREAT | SSH_FXF_EXCL, Wings would call Touch with truncation behavior, allowing an existing file to be opened and replaced.

What's the impact?

Mechanically, this violates the expected SFTPv3 open semantics for exclusive create requests.

Practically:

  • Some clients depend on this "create if not exists" atomic behavior instead of proactively checking whether a file already exists before replacing it
  • Some clients (such as GVFS) also use exclusive create attempts during copy operations to show a overwrite prompt to the user when an existing file is being replaced (see No file replacement popup on Linux SFTP clients panel#4739)

The change

This change makes Wings respect exclusive create requests:

  • If the destination already exists, return os.ErrExist, which pkg/sftp maps to an SSH_FXP_STATUS failure response (SSH_FX_FAILURE error code), which matches OpenSSH SFTP behavior for SFTPv3
  • If the destination does not exist, open it with os.O_CREATE | os.O_EXCL, so the exclusive create is enforced atomically by the filesystem
  • If another writer (be it a concurrent SFTP connection/channel or, for whatever reason, a direct write to the volume on the host) creates the file between the pre-check and the open, preserve the same os.ErrExist behavior

Verification

Locally verified that SSH_FXF_CREAT | SSH_FXF_EXCL now fails for an existing file instead of truncating it, matching OpenSSH SFTP behavior and the spec. Also verified that GVFS/GIO now shows the overwrite prompt instead of silently replacing the remote file.

@metabrixkt metabrixkt force-pushed the fix/sftp-exclusive-create branch from 85d0b56 to ac2f4e1 Compare May 29, 2026 19:33
@metabrixkt
Copy link
Copy Markdown
Author

Rebased following the release of v1.12.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No file replacement popup on Linux SFTP clients

1 participant