Skip to content

feat: stabilize SFTP and add secure SSH terminal integration - #2694

Open
bajrangCoder wants to merge 10 commits into
mainfrom
feat/sftp-improvements
Open

feat: stabilize SFTP and add secure SSH terminal integration#2694
bajrangCoder wants to merge 10 commits into
mainfrom
feat/sftp-improvements

Conversation

@bajrangCoder

Copy link
Copy Markdown
Member

Summary

This PR improves the reliability and security of Acode's SFTP integration and adds interactive SSH terminal support using the existing Maverick Synergy SSH library.

It addresses the SFTP lifecycle, cleanup, and path issues reported in:

SFTP reliability improvements

  • Prevent overlapping SFTP connection attempts.
  • Properly close previous SFTP and SSH connections before switching servers.
  • Reduce Maverick SFTP window sizes and asynchronous request limits for Android.
  • Improve handling of disconnected and partially initialized sessions.
  • Clean up SFTP files, folders, recents, and active editor references when a storage is removed.
  • Preserve URL path boundaries when removing or comparing remote entries.
  • Improve private-key and connection error handling.

SSH terminal integration

  • Add interactive SSH terminal sessions using Maverick SessionChannelNG.
  • Allocate an xterm-256color PTY and start an interactive remote shell.
  • Stream binary terminal output safely through the Cordova bridge.
  • Support password and private-key authentication.
  • Forward terminal input in order through a per-session native writer.
  • Synchronize terminal dimensions with the remote PTY.
  • Handle exit codes, connection errors, intentional closes, and plugin lifecycle cleanup.
  • Keep terminal connections independent from the global SFTP browser connection.
  • Add “Open SSH Terminal” to saved SFTP storage and open-folder context menus.
  • Prevent remote hosts from invoking Acode's local OSC 7777 file-opening protocol.
  • Keep remote-terminal creation internal; it is not exposed through the public Acode plugin API.

Secure SFTP profiles

Previously, SFTP URLs could contain usernames, passwords, key-file paths, and passphrases.

This PR replaces persisted connection URLs with opaque identifiers:

sftp://profile-<uuid>/remote/path

The corresponding connection profile is stored natively and encrypted using:

  • Android Keystore-managed AES key
  • AES/GCM/NoPadding
  • Random IV per profile encryption
  • Profile ID as authenticated additional data

Encrypted profiles contain the server details and authentication material. Profile reads exposed to JavaScript return metadata only and never return passwords, passphrases, or private-key contents.

Private-key files selected for new profiles are read by the native plugin and stored inside the encrypted profile instead of being copied into an SFTP URL.

Migration

On startup, legacy SFTP URLs are migrated across:

  • Saved storages
  • Remembered files
  • Remembered folders
  • Recent files
  • Recent folders
  • File-browser state

Migration behavior is intentionally conservative:

  • Repeated URLs using the same credentials reuse the migrated profile.
  • Paths are preserved while credentials and query parameters are removed.
  • A failed profile migration leaves the legacy URL unchanged.
  • App-private plaintext key copies are removed only after successful migration.
  • Shared profiles are not deleted while another saved storage still references them.

@github-actions github-actions Bot added the enhancement New feature or request label Aug 8, 2026
@bajrangCoder
bajrangCoder marked this pull request as ready for review August 8, 2026 03:27
@UnschooledGamer UnschooledGamer added the S/FTP Issues and Pull requests related to SFTP/FTP. label Aug 8, 2026
@greptile-apps

greptile-apps Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR replaces credential-bearing SFTP URLs with encrypted native profiles, strengthens SFTP connection and cleanup behavior, and adds interactive SSH terminals backed by those profiles.

  • Migrates persisted SFTP URLs and authentication material into encrypted native storage.
  • Adds independent interactive SSH shell sessions with terminal input, output, resize, and cleanup bridging.
  • Updates remote-storage removal, path-boundary handling, folder indexing, and SFTP lifecycle management.
  • Adds unit coverage for profile migration, URL relationships, and shell argument quoting.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains in the eligible follow-up review set.

No blocking failure remains.

Important Files Changed

Filename Overview
src/lib/sftpProfiles.js Adds recursive migration of persisted credential-bearing SFTP URLs into opaque encrypted native profiles.
src/plugins/sftp/src/com/foxdebug/sftp/Sftp.java Reworks native SFTP connection security and lifecycle handling while adding independent interactive SSH shell sessions.
src/plugins/sftp/src/com/foxdebug/sftp/SftpSecurityStore.java Introduces strict encrypted storage for SFTP profiles and trusted SSH host keys.
src/components/terminal/terminal.js Connects xterm to native SSH shell events, ordered input, PTY resizing, and session cleanup.
src/components/terminal/terminalManager.js Adds internal remote-terminal creation and prevents remote terminals from invoking the local OSC file-opening protocol.
src/fileSystem/sftp.js Switches SFTP access to opaque profile identifiers and serializes overlapping connection attempts.
src/lib/remoteStorage.js Persists SFTP credentials through native profiles and supports secure profile editing.
src/pages/fileBrowser/fileBrowser.js Adds SSH-terminal actions and coordinated cleanup when saved SFTP storage is removed.
src/lib/fileList.js Makes remote compatibility indexing iterative, serialized, cancellation-aware, and resistant to symlink cycles.
src/main.js Runs legacy SFTP profile migration before restoring application state and loading third-party plugins.

Sequence Diagram

sequenceDiagram
    participant App as Acode startup
    participant Migration as sftpProfiles.js
    participant Store as Native encrypted profile store
    participant FS as SFTP filesystem
    participant Terminal as SSH terminal
    App->>Migration: Migrate persisted legacy SFTP URLs
    Migration->>Store: Encrypt credentials/private key
    Store-->>Migration: profile-id
    Migration-->>App: Persist sftp://profile-id/path
    App->>FS: Open remote files using profile-id
    FS->>Store: Resolve credentials internally
    App->>Terminal: Open SSH terminal for profile-id
    Terminal->>Store: Resolve credentials internally
    Terminal-->>App: Stream PTY events
Loading

Reviews (5): Last reviewed commit: "fix(ssh): open terminal in selected remo..." | Re-trigger Greptile

RohitKushvaha01

This comment was marked as outdated.

Comment thread src/plugins/sftp/src/com/foxdebug/sftp/SftpSecurityStore.java
@UnschooledGamer UnschooledGamer added the CI: RUN ON-DEMAND PREVIEW RELEASES Triggers an on-demand preview build for this pull request via CI workflow. label Aug 8, 2026
@github-actions github-actions Bot removed the CI: RUN ON-DEMAND PREVIEW RELEASES Triggers an on-demand preview build for this pull request via CI workflow. label Aug 8, 2026
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@bajrangCoder

This comment was marked as outdated.

Comment thread src/pages/fileBrowser/fileBrowser.js Fixed
@bajrangCoder

This comment was marked as outdated.

@RohitKushvaha01 RohitKushvaha01 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@UnschooledGamer

UnschooledGamer commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Tested with Ed25519 private key auth

SSH Terminal works completely fine on my device, find the screenshots below. Tho I cannot keep the Termux Home directory via SFTP open for too long without Error.

Screenshot_2026-08-09-22-22-48-259-edit_com.foxdebug.acode.jpg

IMG_20260809_222916.jpg

Acode Crash Report

WebView Version: 150.0.7871.181
App Language: en-IN
Error Message: Attempt to invoke virtual method 'void com.sshtools.client.sftp.SftpMessage.release()' on a null object reference
App Version: 1.12.9-pr.2694 (1005)
Device: Xiaomi M2003J15SC
Android Version: 12 (SDK 31)

Stack Trace:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.sshtools.client.sftp.SftpMessage.release()' on a null object reference
at com.sshtools.client.sftp.SftpChannel.getOKRequestStatus(SftpChannel.java:694)
at com.sshtools.client.sftp.SftpHandle.close(SftpHandle.java:291)
at com.sshtools.client.sftp.SftpClient.ls(SftpClient.java:934)
at com.foxdebug.sftp.Sftp$12.run(Sftp.java:1124)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1154)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:652)
at java.lang.Thread.run(Thread.java:1564)

@bajrangCoder

Copy link
Copy Markdown
Member Author

@UnschooledGamer try the latest commit , that crash is addressed

@bajrangCoder

This comment was marked as outdated.

@UnschooledGamer UnschooledGamer added the CI: RUN ON-DEMAND PREVIEW RELEASES Triggers an on-demand preview build for this pull request via CI workflow. label Aug 10, 2026
@github-actions github-actions Bot removed the CI: RUN ON-DEMAND PREVIEW RELEASES Triggers an on-demand preview build for this pull request via CI workflow. label Aug 10, 2026
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@UnschooledGamer

Copy link
Copy Markdown
Collaborator

@UnschooledGamer try the latest commit , that crash is addressed

✅ , no longer occurs

@bajrangCoder

This comment was marked as outdated.

@UnschooledGamer UnschooledGamer added the CI: RUN ON-DEMAND PREVIEW RELEASES Triggers an on-demand preview build for this pull request via CI workflow. label Aug 11, 2026
@github-actions github-actions Bot removed the CI: RUN ON-DEMAND PREVIEW RELEASES Triggers an on-demand preview build for this pull request via CI workflow. label Aug 11, 2026
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown

Preview Release for this, has been built.

Click here to view that github actions build

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

Labels

enhancement New feature or request S/FTP Issues and Pull requests related to SFTP/FTP.

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

The app crashes when loading SFTP files Deleted SFTP folders still tries reconnect

4 participants