Commit Graph

127 Commits

Author SHA1 Message Date
Michael Clark
d4b06a6c5c fix: android: replace all-files access with scoped storage (#15602)
* fix: android: replace all-files access with scoped storage + system picker

Remove MANAGE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE, and
WRITE_EXTERNAL_STORAGE from the Android manifest. Remove
requestLegacyExternalStorage. Replace broad external storage with
app-scoped external storage for the file-transfer workspace.

File import uses the system file_picker. File export uses Android's
SAF ACTION_CREATE_DOCUMENT with path validation that restricts
export sources to app-owned directories.

Remove the external_path dependency.

Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>

* fix: android: refine file import feedback

Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>

* fix: android: use SAF for file imports

Replace file_picker imports with Android's Storage Access Framework to avoid legacy storage permissions, stale cached files, and duplicate staging of large imports. Stream selected documents into app-scoped storage with failure-safe replacement, keep exports restricted to validated app storage roots, use filesDir for the internal fallback workspace, and remove legacy permissions contributed during manifest merging.

Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>

* fix: android: keep file imports in the selected directory

Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>

* fix: android: reset projection and constrain file workspace

Release capture resources when media projection is revoked externally. Keep Android local file navigation within the app-scoped workspace.

Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>

* fix: android: handle scoped storage start-up regressions. Allow zero digits in POSIX filenames by rejecting NUL explicitly, and initialise the app-specific home directory before the Android service starts the native server.

Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>

* fix: update content resolver mode to use 'wt' instead of 'w' to prevent trailing bytes from old document whilst reporting sucess

Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>

* fix: android, enforce file workspace boundary on the server, and unblock the ui thread.

Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>

* fix: android: validate rename destinations against the app workspace bound file-operation paths. report rename failures, general import failures, and unregister / reregister projection when its onStop callback fires.

Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>

* fix: reconnect was refreshing the directory with net entry instances, while selected items retained the old instances, it was reporting a selected item, but checkbox statue used object identity, and appeared unchecked. Fixed by reconciling by path and entry type before replacing the directory snapshot, rebinding valid selections, and dropping missing ones.

Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>

* fix: (android) add SAF folder import and multi item export - import directories using ACTION_OPEN_DOCUMENT_TREE. Export multiple files, logs, and screen recordings via export buttons, add localisation keys for new actions

Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>

* fix(android): harden scoped storage file handling

- create new SAF documents instead of overwriting export sources
- reject empty peer paths except for home directory reads
- report directory backup restore and cleanup failures
- resolve log export paths from the configured app name

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(android): harden scoped-storage file operations

- snapshot directory exports before writing to the destination
- query document provider metadata off the main thread
- reject invalid remote directories without read timeouts

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(android): handle SAF directory name collisions

- reject dot-segment folder names during import
- fail imports with duplicate document display names
- only reuse matching directories during export

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(android): handle SAF folder import collisions

Reject filesystem-equivalent destination names and
avoid showing a failure when folder overwrite is skipped.

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: fufesou <linlong1266@gmail.com>
2026-08-31 16:29:51 +08:00
fufesou
0b08a83d4b fix(file-transfer): improve large directory loading (#15830)
* fix(file-transfer): improve large directory loading

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(file-transfer): avoid failing newer directory reads

Track each remote directory request by its registered completer and only remove
the task when it still matches, preventing stale failures from affecting newer
requests for the same path.

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(file-transfer): handle slow directory listings safely

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(file transfer): correlate directory responses with requests

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(file transfer): prevent automatic directory responses from matching requests

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(file-transfer): handle large remote directory listings reliably

- build file rows lazily
- register remote reads before sending requests
- handle Home paths, stale responses, errors, and timeouts
- serialize same-path reads with different hidden-file options

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(file transfer): reduce diffs

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix: build

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix: invalidate pending dir reads on reconnect

Signed-off-by: fufesou <linlong1266@gmail.com>

* test(file-transfer): cover remote directory read lifecycle

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2026-08-27 13:01:11 +08:00
Mariano Abad
3f207e91f6 fix(linux): a session logout should hand the peer to the login screen (#15905)
* fix(linux): a session logout should hand the peer to the login screen

Logging out closes every window in the session, the connection manager's
included, and its close handler kicks every peer with the reason a person
gets when they disconnect one by hand. That reason is the one thing the
client never retries on, so the remote session dies on a frozen frame
instead of reconnecting to the greeter that is already there.

The close carries nothing to tell the two apart: measured on KDE, the CM
receives no signal and logind still reports the session active at that
instant, and the server is killed within a few hundred ms either way, so
neither a state check nor a grace period can decide it. What is
distinguishable is the ACTION: disconnecting a peer is not the same event
as this window going away. So the window-close path now says so, and the
server ends the session without poisoning the retry; the Disconnect
button and the app's own close control keep kicking exactly as before.
Linux only, since that is where a logout closes the window.

Verified on plasma/sddm with a client attached: a logout now reconnects
to the greeter with no dialog, while closing the manager window still
shows Closed manually by the peer.

* fix(linux): close the tunnel too, and keep the web build compiling

Three seams the first pass missed. The web bridge is hand written, not
generated, so the new call needs its stub there or flutter build web
stops compiling - and that job is disabled in CI, so it would have gone
green. try_port_forward_loop is a second consumer of the same channel
and only knew Close, so a forwarded tunnel outlived the window it was
supposed to die with. And the variant had landed inside the DRM section,
whose comment says everything below it is drm-gated.
2026-08-26 18:26:26 +08:00
RustDesk
e63df74715 fix(linux): make quit_cm actually quit the connection manager (#15718)
quit_gui() ends the process on Windows (std::process::exit) and macOS
(NSApp terminate), but on Linux it calls gtk_main_quit(), which has no
effect in the Flutter connection manager: flutter/linux/main.cc runs
g_application_run() (GtkApplication), so gtk_main() is never called and
the assertion inside gtk_main_quit() just fails.

quit_cm() is the only caller that relies on quit_gui() to end the
process. The main window path in ipc.rs calls std::process::exit(-1)
right after it, and the two remaining call sites are in the Sciter UI,
which is not compiled for flutter builds. So a connection manager
reaching quit_cm() on Linux kept running while no longer serving the
`_cm` ipc endpoint, which also stops the server from reusing it, so the
next connection spawns one more.

NOTE: this is a fallback, not an explanation for the stale processes of
#15698: a client merely disconnecting does not reach quit_cm(), the
Flutter side closes the window instead.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 12:01:05 +08:00
rustdesk
f29dec7b13 harden switch side 2026-05-06 19:27:56 +08:00
fufesou
383a5c3478 feat: option, enable-privacy-mode & enable-perm-change-in-accept-window (#14875)
* feat: option, privacy mode

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(privacy mode): update libs/hbb_common

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(privacy mode): turn off on disable privacy mode

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(privacy mode): better check if supported

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(option): enable perm change in accept window

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2026-05-02 00:44:22 +08:00
fufesou
2f694c0eb2 fix: file transfer, path traversal (#14678)
* fix: file transfer, path traversal

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): remove stale files

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): update_folder_files() after set_files()

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): reduce .clone()

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): undo checking "done message for unkown id"

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): refactor

1. Hide `files` in `new_write()`.
2. Use `set_files()` to validate `files` before writing.

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): comments

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): Remove redundant checks

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): update hbb_common

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2026-04-10 18:00:11 +08:00
RustDesk
ab64a32f30 avatar (#14440)
* avatar

* refactor avatar display: unify rendering and resolve at use time

  - Extract buildAvatarWidget() in common.dart to share avatar rendering
    logic across desktop settings, desktop CM and mobile CM
  - Add resolve_avatar_url() in Rust, exposed via FFI (SyncReturn),
    to resolve relative avatar paths (e.g. "/avatar/xxx") to absolute URLs
  - Store avatar as-is in local config, only resolve when displaying
    (settings page) or sending (LoginRequest)
  - Resolve avatar in LoginRequest before sending to remote peer
  - Add error handling for network image load failures
  - Guard against empty client.name[0] crash
  - Show avatar in mobile settings page account tile

Signed-off-by: 21pages <sunboeasy@gmail.com>

* web: implement mainResolveAvatarUrl via js getByName

Signed-off-by: 21pages <sunboeasy@gmail.com>

* increase ipc Data enum size limit to 120 bytes

Signed-off-by: 21pages <sunboeasy@gmail.com>

---------

Signed-off-by: 21pages <sunboeasy@gmail.com>
Co-authored-by: 21pages <sunboeasy@gmail.com>
2026-03-04 21:43:19 +08:00
21pages
3a9084006f Allow configuring remote control permissions for different users (#13974)
Signed-off-by: 21pages <sunboeasy@gmail.com>
2026-01-09 00:21:28 +08:00
fufesou
4d3ccc62e8 fix(file transfer): perm on "access-mode" (#13971)
Signed-off-by: fufesou <linlong1266@gmail.com>
2026-01-07 16:08:15 +08:00
fufesou
969ea28d06 feat(fs): delegate win --server file reading to CM (#13736)
- Route Windows server-to-client file reads through CM instead of the connection layer
- Add FS IPC commands (ReadFile, CancelRead, SendConfirmForRead, ReadAllFiles) and CM data messages
  (ReadJobInitResult, FileBlockFromCM, FileReadDone, FileReadError, FileDigestFromCM, AllFilesResult)
- Track pending read validations and read jobs to coordinate CM-driven file transfers and clean them up
  on completion, cancellation, and errors
- Enforce a configurable file-transfer-max-files limit for ReadAllFiles and add stronger file name/path
  validation on the CM side
- Improve Flutter file transfer UX and robustness:
  - Use explicit percent/percentText progress fields
  - Derive speed and cancel actions from the active job
  - Handle job errors via FileModel.handleJobError and complete pending recursive tasks on failure
  - Wrap recursive directory operations in try/catch and await sendRemoveEmptyDir when removing empty directories

Signed-off-by: fufesou <linlong1266@gmail.com>
2025-12-28 15:39:35 +08:00
fufesou
f4fb31d7a1 feat: file transfer, resume (#12626)
Signed-off-by: fufesou <linlong1266@gmail.com>
2025-08-25 14:34:03 +08:00
fufesou
a22f2108c6 refact: suppress warns on macos (#12449)
Signed-off-by: fufesou <linlong1266@gmail.com>
2025-08-18 15:09:11 +08:00
RustDesk
53efaf125c Revert "Feat: file transfer, resume (#12557)" (#12620)
This reverts commit 43ec57c769.
2025-08-11 23:25:41 +08:00
fufesou
43ec57c769 Feat: file transfer, resume (#12557)
Signed-off-by: fufesou <linlong1266@gmail.com>
2025-08-09 23:47:19 +08:00
RustDesk
5faf0ad3cf terminal works basically. (#12189)
* terminal works basically.
todo:
- persistent
- sessions restore
- web
- mobile

* missed terminal persistent option change

* android sdk 34 -> 35

* +#![cfg_attr(lt_1_77, feature(c_str_literals))]

* fixing ci

* fix ci

* fix ci for android

* try "Fix Android SDK Platform 35"

* fix android 34

* revert flutter_plugin_android_lifecycle to 2.0.17 which used in rustdesk 1.4.0

* refactor, but break something of desktop terminal (new tab showing loading)

* fix connecting...
2025-07-01 13:12:55 +08:00
fufesou
f4bbf82363 feat: remote printer (#11231)
Signed-off-by: fufesou <linlong1266@gmail.com>
2025-03-27 15:34:27 +08:00
21pages
f0f999dc27 view camera (#11040)
* view camera

Signed-off-by: 21pages <sunboeasy@gmail.com>

* `No cameras` prompt if no cameras available,  `peerGetSessionsCount` use
connType as parameter

Signed-off-by: 21pages <sunboeasy@gmail.com>

* fix, use video_service_name rather than display_idx as key in qos,etc

Signed-off-by: 21pages <sunboeasy@gmail.com>

---------

Signed-off-by: 21pages <sunboeasy@gmail.com>
Co-authored-by: Adwin White <adwinw01@gmail.com>
Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
2025-03-10 21:06:53 +08:00
fufesou
fbba8f0b34 refact: file copy&paste, cross platform (no macOS) (#10671)
* feat: unix, file copy&paste

Signed-off-by: fufesou <linlong1266@gmail.com>

* refact: unix file c&p, check peer version

Signed-off-by: fufesou <linlong1266@gmail.com>

* Update pubspec.yaml

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
2025-02-04 20:33:02 +08:00
fufesou
1c17fddf51 fix: android clipboard permission (#10223)
* fix: android clipboard permission

Signed-off-by: fufesou <linlong1266@gmail.com>

* refact: Android, clipboard, floating ball

Call rust to check if clipboard is enabled.

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2024-12-07 22:34:54 +08:00
fufesou
3c838e7a92 fix: Android, try sync clipboard on connecting (#10218)
* fix: Android, try sync clipboard on connecting

Signed-off-by: fufesou <linlong1266@gmail.com>

* Android, clipboard, more clear skip check

Signed-off-by: fufesou <linlong1266@gmail.com>

* comments

Signed-off-by: fufesou <linlong1266@gmail.com>

* comment todo: Android clipboard listener, callback twice

Signed-off-by: fufesou <linlong1266@gmail.com>

* Android, clipboard, remove listner

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2024-12-07 15:12:15 +08:00
zuiyu
314c93b210 Create empty dir on send files in local (#9993)
* feat: Add empty dirs on sendfiles

* Update connection.rs

---------

Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
2024-11-23 23:09:11 +08:00
fufesou
8b710f62c8 feat: android clipboard, multi-formats (#9950)
* feat: android clipboard, multi-formats

Signed-off-by: fufesou <linlong1266@gmail.com>

* Chore

Signed-off-by: fufesou <linlong1266@gmail.com>

* Remove unused code

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2024-11-18 15:43:41 +08:00
fufesou
ba832362a7 fix: installed, copy&paste, special format (#9570)
Signed-off-by: fufesou <linlong1266@gmail.com>
2024-10-06 08:32:04 +08:00
fufesou
e5ec6957fe fix: option OPTION_ONE_WAY_FILE_TRANSFER (#9387)
Signed-off-by: fufesou <linlong1266@gmail.com>
2024-09-18 18:22:12 +08:00
rustdesk
cc288272d3 OPTION_ONE_WAY_CLIPBOARD_REDIRECTION,
OPTION_ENABLE_CLIPBOARD_INIT_SYNC,
        OPTION_ALLOW_LOGON_SCREEN_PASSWORD,
        OPTION_ONE_WAY_FILE_TRANSFER,
2024-09-18 12:18:26 +08:00
fufesou
2922ebe22a Fix/clipboard retry if is occupied (#9293)
* fix: clipboard, retry if is occupied

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix: clipboard service, hold runtime to cm ipc

Signed-off-by: fufesou <linlong1266@gmail.com>

* update arboard

Signed-off-by: fufesou <linlong1266@gmail.com>

* refact: log

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix: get formats, return only not

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2024-09-08 21:13:05 +08:00
21pages
993862c103 quit cm process if ipc connection to ipc server closed (#9292)
Signed-off-by: 21pages <sunboeasy@gmail.com>
2024-09-08 12:37:41 +08:00
fufesou
26ebd0deb9 fix: clipboard, cmd ipc (#9270)
1. Send raw contents if `content_len` > 1024*3.
2. Send raw contents if it is not empty.
3. Try read clipboard again if no data from cm.

Signed-off-by: fufesou <linlong1266@gmail.com>
2024-09-05 23:39:07 +08:00
21pages
ed18e3c786 file rename (#9089)
Signed-off-by: 21pages <sunboeasy@gmail.com>
2024-08-16 12:55:58 +08:00
fufesou
8ced4ddaa2 simple refact (#8888)
Signed-off-by: fufesou <linlong1266@gmail.com>
2024-07-30 13:06:37 +08:00
fufesou
15404ecab4 fix: clipboard, windows, controlled side, formats (#8885)
* fix: clipboard, windows, controlled side, formats

Signed-off-by: fufesou <linlong1266@gmail.com>

* Clipboard, reuse ipc conn and send_raw()

Signed-off-by: fufesou <linlong1266@gmail.com>

* Clipboard, merge content buffer

Signed-off-by: fufesou <linlong1266@gmail.com>

* refact: clipboard service, ipc stream

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2024-07-30 11:35:39 +08:00
21pages
c04f460bbd fix more bool options (#8809)
* fix more bool options
* hide sort ab tags because it's already sorted

Signed-off-by: 21pages <sunboeasy@gmail.com>
2024-07-24 17:20:58 +08:00
fufesou
b047730830 Refact/android input changed notify clients (#8494)
* refact: android, input control changed, notify clients

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix: android init input perm

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2024-06-27 13:05:45 +08:00
fufesou
96f41fcc02 refact: custom client, more advanced settings (#8085)
* refact: custom client, more advanced settings

Signed-off-by: fufesou <shuanglongchen@yeah.net>

* feat: custom client, more advanced settings

Signed-off-by: fufesou <shuanglongchen@yeah.net>

---------

Signed-off-by: fufesou <shuanglongchen@yeah.net>
2024-05-18 23:13:54 +08:00
fufesou
0500bf070e refact: android audio input, voice call (#8037)
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2024-05-14 09:20:27 +08:00
rustdesk
7e263af75f VideoConnCount for future use 2024-04-28 21:08:49 +08:00
fufesou
13bade262f remove warns
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-11-14 21:01:31 +08:00
fufesou
90ac8b7b0b feat/virtual_display_privacy_mode
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-11-14 12:11:38 +08:00
fufesou
895831f46f fix, run check_update_broker_process on privacy mode start
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-11-10 09:56:25 +08:00
21pages
d528fd3762 permisson block input
Signed-off-by: 21pages <pages21@163.com>
2023-11-06 15:07:03 +08:00
21pages
663d355a48 cm file delete/create log
Signed-off-by: 21pages <pages21@163.com>
2023-11-06 14:24:50 +08:00
ClSlaid
62563ad8a1 Merge branch 'feat/x11/clipboard-file/init' into feat/osx/clipboard-file
Signed-off-by: ClSlaid <cailue@bupt.edu.cn>
2023-10-30 15:34:40 +08:00
ClSlaid
30e85c8654 patch: make linux build ok
Signed-off-by: ClSlaid <cailue@bupt.edu.cn>
2023-10-29 23:42:04 +08:00
ClSlaid
80200a9983 patch: add has_file_clipboard field to PeerInfo
Signed-off-by: ClSlaid <cailue@bupt.edu.cn>
2023-10-29 20:49:43 +08:00
ClSlaid
79f6b5c181 patch: forbid enable cliprdr without feature
Signed-off-by: ClSlaid <cailue@bupt.edu.cn>
2023-10-29 20:10:39 +08:00
ClSlaid
3dfa0525bd feat: implement OSX file copy & paste
Signed-off-by: ClSlaid <cailue@bupt.edu.cn>
2023-10-29 07:15:56 +08:00
ClSlaid
7880cba0f9 feat: enable macos cliprdr
Signed-off-by: ClSlaid <cailue@bupt.edu.cn>
2023-10-29 02:40:56 +08:00
ClSlaid
053723647b patch: try fix flutter file copy
Signed-off-by: ClSlaid <cailue@bupt.edu.cn>
2023-10-27 20:40:23 +08:00
ClSlaid
1f52bb35ba patch: fix server file_transfer not enabled
Signed-off-by: ClSlaid <cailue@bupt.edu.cn>
2023-10-19 17:20:44 +08:00