tabby-rdp 0.4.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +580 -0
  2. package/README.md +252 -34
  3. package/dist/accountForm.js +0 -1
  4. package/dist/accounts.js +0 -1
  5. package/dist/audio.js +0 -1
  6. package/dist/authorities.js +331 -0
  7. package/dist/byteQueue.js +102 -0
  8. package/dist/clipboard.js +106 -0
  9. package/dist/connectionStatus.js +0 -1
  10. package/dist/desk.js +16 -47
  11. package/dist/deskScript.js +196 -6
  12. package/dist/desktop.service.js +1763 -204
  13. package/dist/desktopForm.js +72 -13
  14. package/dist/desktops.js +243 -19
  15. package/dist/drives.js +525 -0
  16. package/dist/fileTransfer.js +1064 -72
  17. package/dist/gateway.js +651 -0
  18. package/dist/header.js +76 -5
  19. package/dist/help.js +34 -13
  20. package/dist/hyperv.js +129 -0
  21. package/dist/index.js +2 -2
  22. package/dist/keyboard.js +0 -1
  23. package/dist/microphone.js +57 -13
  24. package/dist/ntlm.js +225 -0
  25. package/dist/osd.js +56 -15
  26. package/dist/probe.js +15 -3
  27. package/dist/rdcleanpath.js +468 -52
  28. package/dist/rdpFile.js +53 -4
  29. package/dist/rdpProfile.js +75 -22
  30. package/dist/remoteSetup.js +103 -23
  31. package/dist/sessionLog.js +53 -0
  32. package/dist/settingsPage.js +117 -27
  33. package/dist/signin.js +429 -54
  34. package/dist/ssh.js +99 -18
  35. package/dist/sshChannelStream.js +50 -6
  36. package/dist/targets.js +185 -39
  37. package/dist/ui.js +98 -20
  38. package/dist/unshowable.js +41 -0
  39. package/dist/updates.js +37 -2
  40. package/dist/vms.js +36 -5
  41. package/dist/wake.js +31 -12
  42. package/package.json +4 -3
  43. package/remote/trd-pty.py +74 -13
  44. package/vendor/SHA256SUMS +26 -0
  45. package/vendor/iron-remote-desktop-rdp.js +418 -390
  46. package/vendor/ironrdp_web_bg.wasm +0 -0
  47. package/dist/accountForm.js.map +0 -1
  48. package/dist/accounts.js.map +0 -1
  49. package/dist/audio.js.map +0 -1
  50. package/dist/connectionStatus.js.map +0 -1
  51. package/dist/desk.js.map +0 -1
  52. package/dist/deskScript.js.map +0 -1
  53. package/dist/desktop.service.js.map +0 -1
  54. package/dist/desktopForm.js.map +0 -1
  55. package/dist/desktops.js.map +0 -1
  56. package/dist/fileTransfer.js.map +0 -1
  57. package/dist/header.js.map +0 -1
  58. package/dist/help.js.map +0 -1
  59. package/dist/index.js.map +0 -1
  60. package/dist/keyboard.js.map +0 -1
  61. package/dist/microphone.js.map +0 -1
  62. package/dist/osd.js.map +0 -1
  63. package/dist/probe.js.map +0 -1
  64. package/dist/rdcleanpath.js.map +0 -1
  65. package/dist/rdpFile.js.map +0 -1
  66. package/dist/rdpProfile.js.map +0 -1
  67. package/dist/remoteSetup.js.map +0 -1
  68. package/dist/settingsPage.js.map +0 -1
  69. package/dist/signin.js.map +0 -1
  70. package/dist/ssh.js.map +0 -1
  71. package/dist/sshChannelStream.js.map +0 -1
  72. package/dist/targets.js.map +0 -1
  73. package/dist/ui.js.map +0 -1
  74. package/dist/updates.js.map +0 -1
  75. package/dist/vms.js.map +0 -1
  76. package/dist/wake.js.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
 
3
- <img src="docs/images/logo.svg" width="96" height="96" alt="">
3
+ <img src="docs/images/logo.png" width="150" height="150" alt="tabby-rdp: a Tabby window with a GNOME desktop, a Windows desktop and two terminals side by side">
4
4
 
5
5
  # tabby-rdp
6
6
 
@@ -54,6 +54,8 @@ Making it work with GNOME took fixes in IronRDP, which we contribute upstream ([
54
54
  - [Windows and other desktops behind a host](#windows-and-other-desktops-behind-a-host)
55
55
  - [Remote desktop profiles](#remote-desktop-profiles)
56
56
  - [Saved accounts](#saved-accounts)
57
+ - [Clipboard](#clipboard)
58
+ - [Shared folders](#shared-folders)
57
59
  - [Several desktops in one tab](#several-desktops-in-one-tab)
58
60
  - [VMs on a host](#vms-on-a-host)
59
61
  - [desk: the console on the desktop](#desk-the-console-on-the-desktop)
@@ -62,6 +64,7 @@ Making it work with GNOME took fixes in IronRDP, which we contribute upstream ([
62
64
  - [Built on IronRDP](#built-on-ironrdp)
63
65
  - [Development](#development)
64
66
  - [Limitations](#limitations)
67
+ - [Questions and problems](#questions-and-problems)
65
68
  - [License](#license)
66
69
 
67
70
  ## Install
@@ -91,14 +94,22 @@ running in the background until you disconnect or close the tab.
91
94
 
92
95
  A machine without GNOME but with [xrdp](https://github.com/neutrinolabs/xrdp) running (the usual RDP server for KDE,
93
96
  XFCE, MATE and the rest) gets xrdp's desktop instead: sign in with your Linux password, which the plugin can remember
94
- in the system keychain. A machine with both keeps GNOME as the tab's desktop and, once that has been opened, also
97
+ in the system keychain. xrdp takes the password without Network Level Authentication, and that the machine's desktop
98
+ is xrdp is the machine's own word, so the first sign-in asks before the password goes; the answer is kept with that
99
+ desktop's certificate. A machine with both keeps GNOME as the tab's desktop and, once that has been opened, also
95
100
  offers **Open \<host\> desktop (xrdp)** in its menus.
96
101
 
97
102
  It also works in a plain local terminal where you typed `ssh host` (macOS and Linux), as long as that host accepts
98
103
  your key without a password prompt. And in an SSH tab where you typed `ssh` on to another machine: **Desktop** there
99
104
  opens that machine's desktop, going through the first, as long as the first can log in to it by itself (a key there,
100
105
  or agent forwarding). So one pane of a split can show the first machine's desktop, and the other, after `ssh other`,
101
- that machine's.
106
+ that machine's. Desktop asks which desktop you mean, the first machine's or that one's, this time or **from now on**:
107
+ which `ssh` runs in a console is the first machine's to say. Chosen from now on, that machine's desktop opens at once
108
+ the next times. A machine reached this way keeps its saved sign-in and certificate under the machine it goes through,
109
+ apart from the same machine opened in a tab of its own, and only its own desktop opens that way (VMs aren't looked for
110
+ there): desktops added behind a host open in tabs connected to that host. A "from now on" is taken back by removing its
111
+ entry from `remoteDesktop.nestedSSH` in Tabby's config file (Settings › Config file): `via` is the tab's host,
112
+ `destination` the name typed after `ssh`.
102
113
 
103
114
  One desktop per account: a second tab to the same `user@host` switches to the tab that has it open, rather than
104
115
  connecting again.
@@ -107,12 +118,14 @@ connecting again.
107
118
 
108
119
  | | |
109
120
  |---|---|
110
- | **Clipboard** | Copy and paste text and images in both directions. |
111
- | **Files** | Copy files or folders in Finder and press ⌘V on the desktop, or drop them onto it, or use **Remote Desktop › Send files…** in the pane's menu; they paste in Files or Explorer. Files copied on the remote offer **Save to Downloads**. |
121
+ | **Clipboard** | Copy and paste text and images in both directions; or only from the remote desktop to this computer, or not at all, for every desktop or for some: [below](#clipboard). |
122
+ | **Files** | Copy files or folders in Finder and press ⌘V on the desktop, or drop them onto it, or use **Remote Desktop › Send files…** in the pane's menu; they paste in Files or Explorer. A copied folder's links go along only when they lead somewhere inside it. Files copied on the remote offer **Save to Downloads**, which saves them there (never into a folder that was there before), marks them as downloaded, as a browser does (so macOS can ask before an app among them first opens), and takes invisible characters that could disguise a name out of it. They go the ways the [clipboard](#clipboard) does. |
123
+ | **Shared folders** | Folders from this computer as drives on the remote desktop (`\\tsclient\<name>` in Explorer), read-write or read-only, for working with files in place: [below](#shared-folders). Windows (and xrdp with FUSE). |
112
124
  | **Several desktops in one tab** | Paste to all of them, type into all of them, and see which is which: [below](#several-desktops-in-one-tab). |
125
+ | **RD Gateway** | Desktops behind a Remote Desktop Gateway: the profile names the gateway, and the connection goes through it over HTTPS: [below](#through-an-rd-gateway). |
113
126
  | **VMs on a host** | The host's VMs with a desktop, ready to open: [below](#vms-on-a-host). |
114
127
  | **Sound** | The remote desktop's sound plays locally. |
115
- | **Microphone** | Optional (off by default): an app on the remote desktop that records, such as a call, gets your microphone. It is only captured while the app records, with an indicator in the corner of the desktop. |
128
+ | **Microphone** | Optional (off by default): an app on the remote desktop that records, such as a call, gets your microphone. It is only captured while the remote asks for it, with a red dot in the corner of the desktop and a red microphone in Tabby's header, which stays also while the desktop is hidden or its tab is in the background (in full screen, where Tabby hides its header, it shows at the top of the window, in the middle): click it to show that desktop, or to stop sending the microphone there. Stopped, a desktop gets it again only once **Send the microphone** is turned back on in its menu, or Tabby restarts, its reconnects included; the same switch keeps it from a desktop beforehand. A desktop that starts receiving it while it isn't showing also brings a note. |
116
129
  | **Resize** | The remote resolution follows the pane as you resize the window or split it. Or reconnect at the new size, or keep a fixed resolution, scaled to fit or at actual size with scroll bars. |
117
130
  | **Retina** | Optionally renders at device pixels, with the remote's UI scaled to match (GNOME and Windows alike), for sharp text. For all desktops, or only some. |
118
131
  | **Keyboard on macOS** | ⌘C, ⌘V, ⌘Z and the rest work as on a Mac; tapping ⌘ alone is the Windows key, and ⌃⌘ with a key is the Windows key with it (⌃⌘R for Win+R). Tabby's own shortcuts stay out of the way while a desktop is showing, except switching tabs and returning to the console. |
@@ -123,18 +136,24 @@ connecting again.
123
136
  | **Reconnecting** | After sleep or a network change, the desktop reconnects by itself once the connection is back. |
124
137
  | **Sign-in** | GNOME desktops need none: the plugin manages their credentials. Windows and xrdp desktops ask for the account once and can remember it, in Tabby's Vault when that is on and in the system keychain otherwise; **Sign in again…** in the menu replaces it. Desktops that share an account can use a [saved account](#saved-accounts), whose password is kept once. |
125
138
  | **Shortcuts** | Switching between the desktop and the console, view only, a screenshot, Ctrl+Alt+Del, typing into or pasting to all desktops of a tab, the connection status and Disconnect each have a hotkey, set on the settings page or in Tabby's Hotkeys. They work while the desktop has the keyboard; a key another hotkey has is refused. |
126
- | **Certificates** | GNOME desktops accept only the certificate the plugin made for them. Windows and xrdp desktops remember theirs on first use and ask before accepting a different one. |
139
+ | **Certificates** | GNOME desktops accept only the certificate the plugin made for them. A desktop you connect to directly, and an RD Gateway, connect without a question when their certificate is valid for their name by the certificate authorities this computer trusts; any other is shown, with why it can't be verified, its fingerprint and what it says of itself (whom it was issued to and by, and its dates), and connected only once you trust it. What it says of itself is its own word, unless its chain leads to an authority this computer trusts (another machine's certificate then shows that machine's name) and the TLS library didn't refuse it for a reason of its own (a limit set on the authority, say): an issuer you would expect there proves nothing, since anyone can make a certificate that names it; only the fingerprint, checked with whoever runs the server some other way, does. Desktops behind an SSH host remember theirs on first use. A different certificate later stops the connection and asks, but for one an authority vouches for in place of one it vouched for (a renewal); and one remembered on an authority's word is asked about again once it no longer validates. |
140
+ | **Passwords stay with servers that know them** | Windows signs in with Network Level Authentication: a proof both ways, where the password only reaches a server that knows it already. A Windows desktop whose server doesn't use it would get the password as it is, so the connection stops and asks first, before your password or user name is sent. xrdp signs in that way by design, so desktops you made xrdp ones aren't asked about; one that is xrdp only by a host's word (a VM it lists, a machine reached through it, the host's own desktop) is asked about once. The answer is kept with the certificate of the server you gave it for: another certificate, a new address or a forgotten certificate asks again. |
127
141
 
128
142
  <p align="center"><img src="docs/images/files.png" width="760" alt="A file copied on the remote desktop, offered for saving"></p>
129
143
 
130
144
  ## Windows and other desktops behind a host
131
145
 
132
146
  An SSH host can lead to other desktops it can reach, such as a Windows VM on the same machine. In that host's menu,
133
- choose **Desktops › Add a desktop behind \<host\>…** and enter a name, the address as seen from the host, and optionally the
134
- user name and domain. It opens right away, and from then on appears under **Desktops** in the host's menu.
135
- **Settings › Edit a desktop** changes one (its saved password, sharpness and remembered certificate
136
- follow a new address; a new user name forgets the saved password), and **Remove a desktop** removes one, along with
137
- its saved password and remembered certificate.
147
+ choose **Desktops › Add a desktop behind \<host\>…** and enter a name, the address as seen from the host, and
148
+ optionally the user name and domain. It opens right away, and from then on appears under **Desktops** in the host's
149
+ menu. **Settings › Edit a desktop** changes one (its saved password, sharpness and remembered certificate follow a new
150
+ address, unless a desktop there has its own, the certificate staying at the old address too; and where a desktop at the
151
+ new address is known already, its certificate remembered, the saved password doesn't follow either, since that desktop
152
+ would sign in with it unasked: the edited one asks; a saved password follows only along with its desktop's remembered
153
+ certificate, and is forgotten without one; a new user name, domain, account or gateway forgets the saved password), and
154
+ **Remove a desktop** removes one, along with its saved password and remembered certificate (a Hyper-V VM's are its
155
+ host's, which its other VMs use, and stay). What is kept for a desktop is found by its address: an edit or a removal
156
+ applies to what desktops at that address behind other hosts have too.
138
157
 
139
158
  <p align="center"><img src="docs/images/windows.png" width="760" alt="A Windows 11 desktop, reached through an SSH host, in a Tabby tab"></p>
140
159
 
@@ -144,23 +163,28 @@ In Tabby's config file, they look like this:
144
163
  remoteDesktop:
145
164
  desktops:
146
165
  - name: Windows VM
147
- via: buildhost # the SSH host: alias, hostname, user@hostname or user@hostname:port
166
+ via: buildhost # the SSH host: alias, hostname, user@hostname or user@hostname:port (not a machine
167
+ # reached with ssh typed in another host's console)
148
168
  host: 192.168.122.20 # the RDP server as seen from that host
149
169
  port: 3389
150
170
  kind: windows # or xrdp (a Linux desktop served by xrdp), or gnome
151
171
  username: alice # optional; DOMAIN\user works too
152
172
  domain: CORP # optional
153
173
  wake: { vm: win11 } # optional: start it when it's off (see below)
174
+ clipboard: fromRemote # optional: its own clipboard sharing, both, fromRemote or off (see Clipboard)
154
175
  ```
155
176
 
156
177
  The connection runs through the same SSH connection; the Windows machine needs Remote Desktop turned on, and nothing
157
178
  else.
158
179
 
159
- The first connection to a desktop remembers its TLS certificate, without asking (in Tabby's config, under
160
- `remoteDesktop.trustedCertificates`). If a later connection meets a different one, the plugin stops before signing in
180
+ The first connection to a desktop behind a host remembers its TLS certificate, without asking (in Tabby's config,
181
+ under `remoteDesktop.trustedCertificates`): the way there runs inside SSH. SSH vouches for the host, though, not for
182
+ what answers behind it: a host you don't trust, or something on its network, could answer that first connection, so
183
+ make it where you trust both. If a later connection meets a different certificate, the plugin stops before signing in
161
184
  and shows both fingerprints, with **Trust the new certificate** and **Cancel**. Reinstalling Windows or renewing its
162
185
  certificate changes it; if neither happened, something else is answering at that address. Automatic reconnects stop at
163
- the same question.
186
+ the same question. A desktop allowed to sign in without Network Level Authentication is asked about that again once a
187
+ new certificate is trusted, or its address changes.
164
188
 
165
189
  **An SSH host that is itself Windows** (with OpenSSH Server): its own desktop is Windows' Remote Desktop, at
166
190
  127.0.0.1:3389 as seen from the host. The plugin finds this out the first time you open the desktop there, and asks
@@ -191,10 +215,26 @@ keychain, certificates, resize, sharpness, clipboard, files, sound, microphone,
191
215
  and reconnecting work as in SSH tabs. After **Disconnect**, the tab offers **Connect**. In the profile selector you can
192
216
  also type `user@host:port` and pick **Quick connect (REMOTE DESKTOP (RDP))**.
193
217
 
194
- **Import an .rdp file…** (in the menu's **Settings**, or **Remote desktop: import an .rdp file…** in Tabby's
195
- command palette) makes such a profile from a file saved by Remote Desktop Connection or handed out by an admin: its
196
- address, port, user name and domain, named after the file. Other settings in the file (screen size, drives, gateway)
197
- are ignored.
218
+ **Import an .rdp file…** (in the menu's **Settings**, or **Remote desktop: import an .rdp file…** in Tabby's command
219
+ palette) makes such a profile from a file saved by Remote Desktop Connection or handed out by an admin: its address,
220
+ port, user name and domain, named after the file, and its [RD Gateway](#through-an-rd-gateway) when it connects
221
+ through one; a `desktopscalefactor` of 150 or more sets that desktop's sharpness to Retina, and
222
+ `redirectclipboard:i:0` turns its [clipboard](#clipboard) off (a file can't turn it on). Settings the plugin doesn't
223
+ apply (sound left on the remote, a fixed window size, drive or printer redirection, several monitors) are named in a
224
+ note on import, so the desktop's behaviour isn't a surprise. Nothing in a file runs here, and a program it names to
225
+ start on the remote isn't asked for. What a file does decide is where you connect, so importing asks first, naming the
226
+ address, the gateway and the account it leads to: what you sign in with goes there, and once signed in that desktop
227
+ gets the folders you share, the clipboard as far as its setting goes, and your microphone when it asks for it if that
228
+ setting is on. When the file names a gateway, the note adds that the gateway is signed in to first and is given a
229
+ proof of your password. An imported profile never takes a saved account by itself, whatever its group's defaults say,
230
+ nor a gateway account (whose proof would go to the gateway the file named) or a kind (an xrdp one would get the
231
+ password without Network Level Authentication, unasked): it is a Windows desktop that asks for its sign-in, unless a
232
+ password was saved already for that address reached the same way (through the same gateway, or none; not one version
233
+ 0.5.0 saved there for a desktop reached through a gateway, which is forgotten). The address, gateway, user name and
234
+ domain are shown faithfully (an international name as the punycode it resolves to, so a look-alike can't pose as a
235
+ name you know; one with characters that don't show isn't imported). **Add only** adds the profile without connecting.
236
+ A file whose address, user name, domain (in any case) and gateway a profile has already opens that profile instead; when
237
+ the file turns the clipboard off and that profile shares it, you are asked first whether to turn it off there.
198
238
 
199
239
  Its **Connect** setting can name an SSH profile instead of connecting directly. The address is then as that host sees
200
240
  it, and opening the profile opens that SSH tab and shows the desktop over it once SSH is connected. Such a desktop is
@@ -213,11 +253,72 @@ profiles:
213
253
  kind: windows # or xrdp, or gnome
214
254
  username: alice # optional
215
255
  via: '' # or the id of an SSH profile to go through
256
+ gateway: '' # or an RD Gateway to go through: rdgw.example.com, or host:port
257
+ gatewayAccount: '' # or a saved account's id, for a gateway that takes another account
258
+ clipboard: off # optional: its own clipboard sharing, both, fromRemote or off; '' for the setting's.
259
+ # Left out, its group's and Tabby's profile defaults decide (see Clipboard)
216
260
  ```
217
261
 
218
- A direct connection is a plain TCP connection from this computer, encrypted with TLS like any RDP client's. The
219
- server's certificate is remembered on the first connection and checked on every later one, as for desktops behind a
220
- host (above).
262
+ A direct connection is a plain TCP connection from this computer, encrypted with TLS like any RDP client's, with nothing
263
+ else between the desktop and the network on the way. So its certificate is checked as a browser checks a website's: one
264
+ valid for the desktop's name (or address) by the certificate authorities this computer trusts connects without a
265
+ question (an organisation's desktops often have one). Any other, such as the self-signed one most RDP servers make for
266
+ themselves, is shown on the first connection before anything of your sign-in is sent: the address, why it can't be
267
+ verified, its SHA-256 fingerprint and what it says of itself (whom it was issued to and by, and its dates), with **Trust
268
+ the certificate** and **Cancel** (what Enter picks). Why it can't be verified is Tabby's own reading of the certificate
269
+ (self-signed, from an authority this computer doesn't trust, issued for another name, expired, …), not only what the TLS
270
+ library reported last, which whoever makes the certificate can choose. What it says of itself is its own word, which
271
+ nothing has checked, unless its chain leads to an authority this computer trusts (where another machine's certificate
272
+ shows that machine's name) and the TLS library didn't refuse it for a reason of its own (a limit set on the authority,
273
+ say): an issuer you would expect there proves nothing. Check the fingerprint with whoever runs the desktop, some other
274
+ way than this connection, before you trust it. For a server without Network Level Authentication, the question says that
275
+ signing in would send it your password itself. Once trusted it is remembered, and a different
276
+ certificate later stops the connection as above, whatever vouches for it. One an authority vouched for may be renewed: a
277
+ replacement it vouches for too connects, and the desktop's log says so. The same one connects only while that holds:
278
+ once it has expired, or its authority is gone from this computer's store, it is asked about as at first, since you never
279
+ confirmed it. A certificate whose only use is Remote Desktop Authentication (as Active Directory's Remote Desktop
280
+ templates issue them) isn't valid for a server by Tabby's rules, whatever issued it, so it is asked about too, and again
281
+ when it is renewed. Trusting a certificate never allows signing in without Network Level Authentication, which is asked
282
+ about on its own.
283
+
284
+ ### Through an RD Gateway
285
+
286
+ Where desktops sit behind a Remote Desktop Gateway (the HTTPS front door many companies put before their Windows
287
+ machines), give the profile the gateway's address in **RD Gateway**: `rdgw.example.com`, or `host:port` when it
288
+ isn't on 443. The profile's address is then the desktop as the gateway sees it (`pc17.corp.example`). The connection
289
+ goes to the gateway over HTTPS, signs in there, and the gateway connects it on; the desktop then asks for its own
290
+ sign-in as usual, inside that tunnel.
291
+
292
+ - **One sign-in by default.** The account you enter for the desktop also signs in to the gateway, as with Remote Desktop
293
+ Connection's "use my RD Gateway credentials for the remote computer". A gateway that takes another account: pick a
294
+ [saved account](#saved-accounts) under **Gateway account**; its password is asked for once and kept with the account.
295
+ A remembered desktop password is kept for the gateway it was entered for (whichever account signs in to the gateway),
296
+ so it is never sent through a different gateway named for the same address without asking; a new gateway, user name,
297
+ domain or account asks again, and a new address takes the password along, unless a desktop is known at that address
298
+ already. Version 0.5.0 kept such a password for the address alone, where a desktop at that address without a gateway
299
+ would find it: those of the desktops configured with a gateway by then are forgotten after the update, once in each
300
+ computer's keychain and once in Tabby's Vault, the first time a password is looked up, saved or forgotten there, and
301
+ both desktops ask once. Until that has been done (a keychain that doesn't answer, a Vault whose passphrase prompt was
302
+ cancelled), such a password isn't used. A [saved account](#saved-accounts) is one password for every desktop that
303
+ names it, wherever each of them goes.
304
+ - **A refused sign-in says who refused it.** When it was the gateway (a wrong password, or its policy doesn't let the
305
+ account in), the form comes back saying so, and nothing has gone to the desktop. A desktop the gateway's policy
306
+ doesn't let the account reach, or that the gateway can't reach, is an error with that reason.
307
+ - **The gateway's certificate** is checked as a direct desktop's is ([above](#remote-desktop-profiles)):
308
+ accepted when it is valid for the gateway's name by the certificate authorities this computer trusts (with a recent
309
+ Tabby, an organisation's own in the system's store counts); any other (self-signed, say) is shown on the first
310
+ connection and connected only after you confirm its fingerprint, because your sign-in reaches the gateway as a proof
311
+ of your password. A later change stops the connection, before the sign-in goes out, until you trust the new one,
312
+ unless an authority vouches for the new one and the one before wasn't one you trusted yourself (a gateway's
313
+ certificate remembered by 0.5.0 is replaced so too, whichever way it was remembered). The desktop beyond the gateway
314
+ has a certificate of its own: checked the same way for a remote desktop profile, remembered on first use behind an SSH
315
+ host. Remembered ones are listed under Settings › Remote Desktop › Certificates.
316
+ - **Behind an SSH host too.** A desktop added behind an SSH host takes a gateway the same way (the **RD Gateway**
317
+ field of its form): the gateway is then reached from that host.
318
+
319
+ It speaks the gateway's WebSocket transport (Windows Server 2012 R2 and later) and signs in with a user name and
320
+ password (NTLM, bound to the gateway's TLS certificate as gateways require by default). Smart cards, sign-in pages
321
+ and one-time codes at the gateway are not supported.
221
322
 
222
323
  ## Saved accounts
223
324
 
@@ -234,9 +335,73 @@ Signing in with a saved account that has no password yet, or whose password a se
234
335
  form saves what you enter as the account's new password for every desktop. A refused password is not dropped by
235
336
  itself: one server refusing it doesn't make it wrong for the others. **Sign in again…** on such a desktop asks anew.
236
337
 
237
- The accounts' names and user names are in Tabby's config (`remoteDesktop.accounts`); the passwords are in Tabby's
238
- Vault when it is enabled (encrypted, and carried by Tabby's config sync), else in the system keychain. Removing an
239
- account removes its password and sets its desktops back to asking.
338
+ The accounts' names and user names are in Tabby's config (`remoteDesktop.accounts`); the passwords are in Tabby's Vault
339
+ when it is enabled (encrypted, and carried by Tabby's config sync), else in the system keychain. Removing an account
340
+ removes its password and sets its desktops back to asking, a profile in a group with a default account included: it asks
341
+ rather than take that default. A desktop's saved password that an edit or a removal forgets goes at once from each store
342
+ that can be read, Tabby's Vault or the keychain. In one that can't be just then (the Vault locked and its prompt
343
+ cancelled, the keychain not answering) it isn't used, and goes once that store can be read while the Tabby window is
344
+ open; an edit or a removal says so. Should the window be closed before that, it is found again by a desktop at that
345
+ address (**Sign in again…** in the desktop's menu replaces it). The desktop's remembered certificate stays too, so that
346
+ the password goes only to the machine it was saved for: a removal keeps it (Settings › Remote Desktop › Certificates can
347
+ forget it), and a new address leaves it at the old one too, as well as taking it along.
348
+
349
+ ## Clipboard
350
+
351
+ While a desktop has the keyboard, what you copy here goes to it and what you copy there comes here: text, pictures and
352
+ files. That is what makes it feel like part of this computer, and it also means that the desktop sees what is on your
353
+ clipboard whenever it has the keyboard (what you copy while you work in it, and what you copied elsewhere before you
354
+ clicked back into it), passwords from a password manager included, and can put anything on your clipboard, such as a
355
+ command for you to paste into a terminal here. For a desktop you don't trust that far, **Settings › Remote Desktop ›
356
+ Settings › Clipboard sharing** narrows it:
357
+
358
+ - **Both ways**, the default.
359
+ - **Only from the remote desktop to this computer:** what you copy here stays here, and a desktop connected this way
360
+ only ever gets an empty clipboard from this side; what you copy there still comes here, files included.
361
+ - **Off:** the clipboard is left out of the connection altogether, files included.
362
+
363
+ A desktop can have its own: **Clipboard** in its profile's settings (or its profile group's, or Tabby's defaults for
364
+ remote desktop profiles), or in the form of a desktop added behind an SSH host (the host's own desktop follows the
365
+ setting); the Clipboard menu on such a desktop says so. A desktop configured twice behind a host, as an entry and as an
366
+ RDP profile at the same address, gets the narrower clipboard of the two, and a desktop opened with a narrower clipboard
367
+ while it is open already (from another profile for it, say) narrows the open one until it is closed, its reconnects
368
+ included, and when it is shown again after its server ended it; its Clipboard menu says so meanwhile. Changes apply on
369
+ the next connection, Reconnect included. Narrowing the setting also stops anything more going from here right away to
370
+ the open desktops that follow it, takes back the files offered to them, and stops a paste to all desktops or a save of
371
+ several files that is under way before its next step. Narrowing applies in full only once they reconnect: reconnect a
372
+ desktop you don't trust that far. **Paste to all desktops** leaves out the desktops that don't take this computer's
373
+ clipboard and says which. Shared folders are a setting of their own, and screenshots and **Copy log** (Settings ›
374
+ Remote Desktop › Troubleshooting) still go to your clipboard: they are your own actions.
375
+
376
+ ## Shared folders
377
+
378
+ A folder on this computer can appear as a drive on the remote desktop, as mstsc's drive redirection does: in
379
+ **Settings › Remote Desktop › Settings › Shared folders**, **Share a folder…** picks one. On the remote it is
380
+ `\\tsclient\<name>` ("<name> on <this computer>" under This PC in Explorer), named after the folder; **Read-only**
381
+ keeps the remote from changing, adding or removing anything in it. Every remote desktop you connect to sees the shared
382
+ folders, so share only what each of them may have, and remove a folder to stop sharing it. Changes apply on the next
383
+ connection.
384
+
385
+ <p align="center"><img src="docs/images/shared-folders.png" width="548" alt="Shared folders in Settings › Remote Desktop: two folders, one read-only, and Share a folder…"></p>
386
+
387
+ Files are served through the RDP connection as the remote reads and writes them, which suits opening and saving
388
+ documents in place; for moving large files, copying through the clipboard is just as quick. They are read and written
389
+ in the background, so a slow disk or network folder slows the drive down, not Tabby.
390
+
391
+ The remote gets the shared folder and nothing else: a symbolic link works when it points inside the folder, and one that
392
+ leads out of it isn't shown, read or written through. Only files and folders are served (no devices or pipes). A file
393
+ with more than one name (a hard link, as pnpm's `node_modules` and some backup tools make) is read-only from the remote
394
+ (as its count of names is when it is opened), since the same file may be outside the folder too; the remote can still
395
+ read it, as any file in the folder. A desktop can have up to 1,024 files open at once, and all the desktops in a Tabby
396
+ window 2,048 together. On macOS and Windows a Tabby window may have far more open than that; on Linux it depends on the
397
+ system's limit, and where that is 4,096 or less, these are half of it or more. The remote is shown 1 GB less free space
398
+ than the disk has (on a disk under 20 GB, a twentieth of its size less), and can't take that by making a file larger
399
+ than what it writes to it: a file grows beyond what is written to it only within the free space of the disk it is on (a
400
+ disk mounted inside the folder has its own), less that much. Where files can have holes (APFS, ext4), each file can grow
401
+ so, taking no space until it is written. What the remote writes takes space as any copy does.
402
+
403
+ Windows mounts shared folders (tested); xrdp can when built with FUSE (under `~/thinclient_drives`); GNOME Remote
404
+ Desktop doesn't serve drives, so there the clipboard is the way.
240
405
 
241
406
  ## Several desktops in one tab
242
407
 
@@ -244,10 +409,13 @@ Split a tab (Tabby's **Split** in the tab's menu, or drag one tab onto another)
244
409
  machine's desktop next to another's, or next to its own console. Right-click any of them:
245
410
 
246
411
  - **Paste to all \<n\> desktops in this tab** pastes what's on your clipboard on every desktop in the tab, in whichever
247
- window is active on each: text, a picture, or files and folders copied in Finder (or Explorer, or Files).
412
+ window is active on each: text, a picture, or files and folders copied in Finder (or Explorer, or Files). Desktops
413
+ that don't take this computer's [clipboard](#clipboard) are left out, and a note says which. So is a desktop whose
414
+ console is in front, or that is behind a pane maximized over it (Tabby's **Maximize the active pane**): only the
415
+ desktops showing get the paste, and the menu counts only those.
248
416
  - **Type into all \<n\> desktops in this tab** sends every key you type on one desktop to the others too, shortcuts and
249
417
  **Send keys** included, until you turn it off. An orange label on each desktop says so while it's on. The mouse stays
250
- per desktop, and desktops in view-only mode are left out.
418
+ per desktop, and desktops in view-only mode, with their console in front or behind a maximized pane, are left out.
251
419
  - **Make panes even** evens out the split's panes, which Tabby does itself but offers nowhere else.
252
420
 
253
421
  As you click into a desktop, its name shows in its corner for a moment, like a TV naming its input ("BUILDBOX", or "WIN-11 ·
@@ -258,14 +426,21 @@ preview. Desktops are named after their SSH profile's name.
258
426
  ## VMs on a host
259
427
 
260
428
  When you right-click an SSH host, the plugin looks at the host's libvirt VMs (`virsh`, as your SSH user; read-only, at
261
- most once a minute) and lists the ones with a desktop under **Desktops**, with nothing to set up:
429
+ most once a minute; on a Windows host, [Hyper-V's](#hyper-v)) and lists the ones with a desktop under **Desktops**, with nothing to set up:
262
430
 
263
431
  - a running VM whose RDP port answers: Windows, or Linux with xrdp;
264
432
  - a Windows VM that's shut off: **Start and open**, which starts it (`virsh start`) and connects as soon as it answers.
265
433
 
266
434
  A Linux VM that runs GNOME is left out: its desktop is reached by SSH-ing to it (its own desktop, or `ssh` typed in a
267
435
  console on the host, [above](#use)). A VM found this way asks for its account the first time, like any Windows or xrdp
268
- desktop; **Save \<name\> to this host's desktops** in its menu keeps it, for a name of your own and other settings.
436
+ desktop; one the host lists as Linux (xrdp) also asks once before your password goes to it without Network Level
437
+ Authentication, since that it is xrdp is only the host's word. **Save \<name\> to this host's desktops** in its menu
438
+ keeps it, for a name of your own and other settings; its kind stays the host's word, and asks the same way (a VM saved
439
+ with an earlier version too), until you pick a kind for it in its edit form. VMs aren't looked for on a machine
440
+ reached with `ssh` typed in another host's console. The menu lists 256 VMs at most, and says so when a host has more;
441
+ add other libvirt VMs by their address with **Add a desktop behind \<host\>…**. Hyper-V VMs past the first 256 aren't
442
+ offered in the menu: one opens from a `remoteDesktop.desktops` entry in Tabby's config file, with `via` and `hyperv:
443
+ <its id>` (see [above](#windows-and-other-desktops-behind-a-host)).
269
444
  **Settings › Remote Desktop › Find virtual machines on SSH hosts** turns this off.
270
445
 
271
446
  A VM the plugin started can go back off by itself: **Settings › Remote Desktop › Shut down VMs it started** (5
@@ -275,6 +450,23 @@ host, it asks the VM to shut down (`virsh shutdown`, with a key press first, sin
275
450
  screen sleeps), then ends. VMs that were already running are never touched, and neither are machines woken over the
276
451
  network.
277
452
 
453
+ ### Hyper-V
454
+
455
+ A Windows SSH host that runs Hyper-V gets the same: its VMs (`Get-VM`, with PowerShell over the SSH connection) are
456
+ listed under **Desktops**, and one that is off is started when opened (`Start-VM`). What opens is the VM's console, as
457
+ Hyper-V Manager's **Connect** shows it: reached through the host (its port 2179), so the VM needs no network, no
458
+ Remote Desktop turned on, not even an operating system. A Windows guest that is up is asked for an enhanced session
459
+ (its own sign-in screen, the clipboard, sound, shared folders, resizing); before that, and for other guests, it is the
460
+ basic console: the picture, keyboard and mouse. The basic console is what has been tested so far; enhanced sessions
461
+ take the same path but haven't been tried against a running Windows guest yet.
462
+
463
+ The sign-in is the **host's**, not the guest's: an account that may open the VM's console there, which the plugin
464
+ asks for once per host (the SSH user is filled in). That is an administrator, a member of the host's Hyper-V
465
+ Administrators group, or an account given access with `Grant-VMConnectAccess`. A local administrator other than the
466
+ built-in one can list VMs over SSH and still be refused the console, since Windows gives it a reduced token over the
467
+ network; Hyper-V refuses by ending the connection at once, and the plugin then asks again, saying so. Listing VMs
468
+ takes an account Hyper-V lets do that (an administrator of the host, in practice).
469
+
278
470
  ## desk: the console on the desktop
279
471
 
280
472
  Type `desk` in an SSH console, and the tab switches to that machine's desktop with a terminal attached to the very same
@@ -290,6 +482,16 @@ Turn it on in the pane's menu under **Remote Desktop › Settings**, or in Setti
290
482
  your terminal's scrollback, colors and shortcuts stay as they are. Turning it off removes it again. Details:
291
483
  [docs/desk.md](docs/desk.md).
292
484
 
485
+ Before it acts on what `desk` prints, Tabby checks three things: the key `desk` sends, which only your account on that
486
+ machine can read and which Tabby learns when it opens the machine's desktop with `desk` on; that it is the key of the
487
+ machine the pane is connected to (its SSH host, or the machine `ssh` typed there went to); and that the pane is the
488
+ one you're in. So other output that only looks like what `desk` prints is ignored, and `desk` works on a machine once
489
+ its desktop has been opened with `desk` on from this Tabby, or from one that shares its config through config sync
490
+ (after updating from 0.5.0 or earlier, open it once again). The key tells `desk` apart from look-alikes, not from the
491
+ machine itself, which can always send it, nor from a recording of `desk`'s output (a terminal log, `script`,
492
+ asciinema), which holds it: shown again in that machine's pane while you're in it, it counts as `desk`. Open the
493
+ desktop of a machine you don't trust with `desk` off, which also has Tabby forget a key it had for it.
494
+
293
495
  ## Settings
294
496
 
295
497
  Open **Settings › Remote Desktop** in Tabby, right-click the desktop button in Tabby's header, or open **Settings** in the Remote Desktop section of a terminal's or tab's menu.
@@ -303,17 +505,20 @@ They are stored in Tabby's config under `remoteDesktop`:
303
505
  | For *this desktop* only (`desktopSharpness`) | As above | In the menu of a tab with a desktop open: Standard or Retina for that desktop, whatever the default. Kept by desktop (`user@host`, `user@host#address` for one behind a host, or `rdp#address` for a remote desktop profile's own tab). |
304
506
  | Sound (`sound`) | On | Applies on the next connection. |
305
507
  | Video decoding (`h264`) | On | H.264 decoded by Tabby's browser engine (hardware-accelerated where available), for what the remote sends as video; applies on the next connection. |
306
- | Microphone (`microphone`) | Off | Send your microphone while an app on the remote desktop records. Applies on the next connection. |
508
+ | Microphone (`microphone`) | Off | Send your microphone to a remote desktop that asks for it, as one does while an app there records. Turning it on applies on the next connection; turning it off stops it at once, also on a desktop still connecting. A desktop's menu can stop it for that desktop alone, until it is turned back on there or that Tabby window is closed. |
509
+ | Clipboard sharing (`clipboard`) | Both ways (`both`) | Or only from the remote desktop to this computer (`fromRemote`), or off (`off`), for text, pictures and files alike; a desktop's own (`clipboard` in its profile or its `desktops` entry) takes its place ([Clipboard](#clipboard)). Applies in full on the next connection; narrowing it also stops the sending at once to open desktops that follow it. |
510
+ | Shared folders (`sharedFolders`) | None | `[{ path, name, readOnly }]`: folders shared as drives with every remote desktop ([Shared folders](#shared-folders)). Applies on the next connection. |
307
511
  | Show connection status (`connectionStatus`) | Off | The indicator in the desktop's corner; fades when the pointer comes near. |
308
512
  | Mac shortcuts (`macShortcuts`) | On | macOS. Off: ⌘ is the Windows key. |
513
+ | Send text as typed (`unicodeKeys`) | Off | Sends the characters the keyboard produces rather than key positions, so dead keys and a layout the remote doesn't have come out right; keys with Ctrl, Alt or ⌘ still go by position. Windows types any character; GNOME only those its own layout has (mutter has no keycode for the others). Input methods (CJK) are not supported yet. |
309
514
  | Shortcuts (`hotkeys.remote-desktop-*`) | ⌘⇧G / Ctrl+Shift+G for the switch; the rest unbound | Tabby's hotkeys: the switch between desktop and console, view only, screenshot, Ctrl+Alt+Del, type into all, paste to all, connection status, disconnect. Changed on the settings page (Getting started › Shortcuts) or in Settings › Hotkeys. |
310
515
  | Saved accounts (`accounts`) | None | `[{ id, name, username, domain }]`; see [Saved accounts](#saved-accounts). The passwords are in the Vault (encrypted, part of the config) or the keychain, never in plaintext in the config. |
311
- | Bring the console along with `desk` (`desk`) | Off | Installs `desk` and a login line on each machine you open a desktop on; applies on the next connection there. |
516
+ | Bring the console along with `desk` (`desk`) | Off | Installs `desk` and a login line on each machine you open a desktop on; applies on the next connection there. The key each machine's `desk` sends is kept as a fingerprint (`deskKeys`), from a machine whose desktop was opened with this on, and forgotten when it is opened with this off. |
312
517
  | Session backend (`sessionBackend`) | `native` | For `desk`: `native` (trd-pty) or `tmux`. Config file only. |
313
518
  | Find virtual machines on SSH hosts (`discoverVMs`) | On | Lists a host's libvirt VMs with a desktop in its menu ([VMs on a host](#vms-on-a-host)). |
314
519
  | Shut down VMs it started (`shutDownIdle`) | Never | 5, 15 or 60: minutes without a desktop open after which a VM the plugin started is shut down again ([VMs on a host](#vms-on-a-host)). |
315
520
  | Tell me about new versions (`checkUpdates`) | On | Once a day, asks npm for the latest tabby-rdp (nothing else is sent), and says so in a note, the menus and the settings page when there's a newer one: Tabby itself shows plugin upgrades only on its Plugins page. |
316
- | Desktop name overlay (`osd`) | When it helps | `show` (`auto`, `always`, `off`), `font`, `size`, `position`, `color` (empty: white) and `seconds`; the settings page previews it, at a resolution you pick. |
521
+ | Desktop name overlay (`osd`) | When it helps | `show` (`auto`, `always`, `off`), `font`, `size`, `position`, `color` (empty: white; else a color name, `#hex`, or a color function of numbers such as `rgb()`) and `seconds`; the settings page previews it, at a resolution you pick. |
317
522
 
318
523
  ## Requirements
319
524
 
@@ -341,7 +546,9 @@ needed more: GNOME only speaks RDP's graphics pipeline, which IronRDP's web clie
341
546
  monitor in a way the web client didn't follow; and it depends on details of the sound and dynamic-channel protocols
342
547
  that IronRDP got slightly wrong. The web client also had no sound at all.
343
548
 
344
- tabby-rdp ships IronRDP with a short series of patches ([ironrdp/](ironrdp)). The fixes go upstream, one by one:
549
+ tabby-rdp ships IronRDP with a short series of patches ([ironrdp/](ironrdp)). Before each release, CI rebuilds it
550
+ from IronRDP's source and the patches, and the release goes out only if the two builds are identical, byte for byte
551
+ ([how](ironrdp/README.md#reproducing-vendor)). The fixes go upstream, one by one:
345
552
 
346
553
  | Change | Upstream |
347
554
  |---|---|
@@ -357,6 +564,8 @@ tabby-rdp ships IronRDP with a short series of patches ([ironrdp/](ironrdp)). Th
357
564
  | Microphone in the web client | Not submitted yet: waits for #2020 |
358
565
  | Keep clipboard sync working for the other desktops when one closes | Not submitted yet |
359
566
  | Sync the clipboard only for the desktop that has the focus | Not submitted yet |
567
+ | Drive redirection in the web client, through a JavaScript file system | Not submitted yet |
568
+ | Send chunked static-channel messages without CHANNEL_FLAG_SHOW_PROTOCOL, as Windows' drive redirector expects | Not submitted yet |
360
569
 
361
570
  The aim is to make IronRDP's browser client work well with both Linux and Windows desktops, for everyone who embeds
362
571
  it, not just this plugin.
@@ -407,9 +616,18 @@ npm run build:ironrdp # rebuild vendor/ from IronRDP and ironrdp/patches:
407
616
  far as that xrdp version supports them), sound through the PipeWire or PulseAudio module. Live resize needs xrdp
408
617
  0.10 or newer; with 0.9 (Ubuntu 24.04), the desktop keeps its size, scaled to fit, or choose **Reconnect at the new
409
618
  size**. xrdp's standard RDP security without TLS (`security_layer=rdp`) isn't supported. `desk` needs GNOME.
619
+ - **RD Gateways** are signed in to with a user name and password; ones that ask for a smart card, a sign-in page or
620
+ a one-time code, or that only take Kerberos, can't be used. Gateways before Windows Server 2012 R2 (no WebSocket
621
+ transport) can't either. A desktop behind a gateway isn't started when it is off.
410
622
  - **Waking a desktop** over the network (Wake-on-LAN) starts it but never shuts it down again; for VMs, see
411
623
  [Shut down VMs it started](#vms-on-a-host).
412
624
 
625
+ ## Questions and problems
626
+
627
+ Questions ("how do I…", "is this expected?") go to [Discussions › Q&A](https://github.com/meanaverage/tabby-rdp/discussions/categories/q-a);
628
+ bugs and feature requests to the [issues](https://github.com/meanaverage/tabby-rdp/issues). A bug report is most useful
629
+ with the connection log: **Settings › Remote Desktop › Troubleshooting › Open desktops › Copy log**.
630
+
413
631
  ## License
414
632
 
415
633
  [MIT](LICENSE). The bundled IronRDP build is MIT or Apache-2.0 ([vendor/IRONRDP-LICENSE](vendor/IRONRDP-LICENSE)).
@@ -87,4 +87,3 @@ function newAccountOption(select, label, save, onChange) {
87
87
  field('name').focus();
88
88
  });
89
89
  }
90
- //# sourceMappingURL=accountForm.js.map
package/dist/accounts.js CHANGED
@@ -36,4 +36,3 @@ function signInName(account) {
36
36
  function accountKey(id) {
37
37
  return `account#${id}`;
38
38
  }
39
- //# sourceMappingURL=accounts.js.map
package/dist/audio.js CHANGED
@@ -84,4 +84,3 @@ class AudioPlayer {
84
84
  exports.AudioPlayer = AudioPlayer;
85
85
  AudioPlayer.LEAD = 0.08;
86
86
  AudioPlayer.MAX_AHEAD = 0.5;
87
- //# sourceMappingURL=audio.js.map