===============================================================================
 FlashScp — copy files and folders between computers, over SSH using scp
===============================================================================

 Programmer:  Stan Switaj
 Program:     FlashScp, for LinuxDoors
 Download:    https://LinuxDoors.com/downloads/FlashScp.AppImage
 Size:        48 MB   (single file, nothing to install)
 SHA256:      78387e1585972f589770883c601c7e6ee08b64ee22b80728f455700c2d366bea

 Written for LinuxDoors, though nothing in it is specific to LinuxDoors — it
 should run on Debian and Ubuntu type systems, and on any other Linux
 distribution that can run an AppImage.


-------------------------------------------------------------------------------
 CHANGED, 4 OCTOBER 2026 — "HOST KEY VERIFICATION FAILED" NOW ASKS
-------------------------------------------------------------------------------

 Test this connection would sometimes fail with ssh's own words:

     Host key verification failed.

 and that message sends you looking in the wrong place. It is not the
 password, not the key file, not the passphrase -- ssh refuses before any
 of them is offered. What it means is that the machine answering at that
 address and port is presenting a different host key from the one recorded
 the first time you connected.

 It happens for ordinary reasons: the machine was rebuilt, its ssh keys
 were regenerated, or the address now reaches a different machine. It also
 happens when something is impersonating the machine, which is exactly why
 ssh stops rather than carrying on quietly. The decision belongs to the
 person at the keyboard, so FlashScp now puts it to them.

 A window shows the machine, the fingerprints recorded before, and the
 fingerprints being offered now, side by side. Two buttons: forget the old
 key and connect, or leave it alone. Cancel is what the keyboard reaches
 first, because saying yes should be deliberate. Saying yes removes the old
 record and tries again straight away -- it is what `ssh-keygen -R` does,
 which is the advice ssh would have given if it said anything useful.

 The same question is asked in both places this window connects from: Test
 this connection, and opening a machine on a pane.

 Worth knowing, because it is what made this hard to see: known_hosts keeps
 a separate record per PORT. A machine reached on port 222 and the same
 machine reached on port 22 are two records, and one can be stale while the
 other is fine -- which is why a connection can fail in FlashScp and work
 from a terminal at the same moment, if the two are using different ports.


-------------------------------------------------------------------------------
 CHANGED, 30 SEPTEMBER 2026 — A KEY WITH A PASSPHRASE ON IT
-------------------------------------------------------------------------------

 A key file can itself be locked. Making one with a passphrase is the point
 of the thing: a key copied off the machine is useless to whoever took it
 unless they also know the phrase. FlashScp had no way to supply one, so a
 locked key never worked -- and it failed in a way that pointed at the
 wrong thing.

 With no password ticked, the connection was made with BatchMode, which
 turns off every prompt ssh can make, the key's own passphrase prompt
 included. ssh refused the key unread and reported "Permission denied
 (publickey)" -- which reads as the wrong key rather than a locked one.
 With a password ticked it was worse: sshpass answers whatever prompt
 appears with the one secret it holds, so the machine's password was typed
 at the passphrase prompt, the key still did not open, and the password was
 spent.

 THE FIELD AND THE TWO TICKS

 Under Public key there is now a Key passphrase field. It holds a different
 secret from the machine's password, because they are different things: a
 machine can want both, and several do. The phrase unlocks the key, the
 server accepts the key, and then asks for a password as well.

 Above the field: "This public key also wants a password". Tick it, leave
 the field empty, and FlashScp asks for the phrase when it connects, holds
 it for as long as the window is open, and writes nothing down. Fill the
 field in instead and it is kept with the machine.

 Below the field: "Save the key passphrase for this machine" -- its own
 tick, not the password's. They are separate secrets and deserve separate
 decisions: a passphrase opens a key that may reach several machines, where
 a password reaches one. A save file written before this existed keeps
 whatever phrase it holds; if one was stored, the intention to keep it was
 already there.

 Typing a passphrase ticks the box for you, and choosing a locked key with
 Browse ticks it as well and says so -- a key file records whether it is
 encrypted, so there is no need to find that out by failing to connect.

 WHAT IS NOT SHOWN, AND WHAT IS STILL REMEMBERED

 A secret you decline to save is not put on screen. It used to be: asked
 for a password at connect time and told not to keep it, FlashScp wrote it
 into the password box, where Show would reveal it and the next Save would
 write it to disk -- neither of which was asked for.

 It did that for a reason. The form writes itself back into the machine on
 every keystroke, so a box left empty would have erased the very thing the
 dialog had just collected. Filling the box was how the secret survived.

 It is now held aside for the run instead: out of the box, out of the save
 file, and still there when the connection is made. That holds through
 every repaint of the form as well -- selecting another machine and coming
 back, or reopening the manager, rebuilds those boxes from the machine, and
 an earlier version of this fix put the secret back on screen a moment
 later, where clicking Save then wrote it down. The boxes stay empty and
 say "held for this session -- not saved".

 Typing in a box still takes over from whatever is held, and emptying one
 on purpose clears the secret -- which is the only way to discard it
 without closing FlashScp.

 A PASSWORD THAT WAS BEING THROWN AWAY

 One fault came out of the same corner of the code, and it looked like
 something else entirely. A password typed into the field was ignored
 unless the tick above it was on: the tick was read as permission to use
 the password rather than as an instruction to ask for one.

 Against a machine wanting a key AND a password, that meant the key was
 offered, refused, and the password never sent -- and ssh reported
 "Permission denied (publickey)", which reads as a key problem when the key
 was not the problem. A password in the field is now used, tick or no tick.
 The tick means only "ask me for one if I have not given you one".

 HOW BOTH SECRETS TRAVEL

 ssh is given a small helper program to call whenever it wants a secret
 typed in, and ssh passes the prompt to that helper as an argument. So the
 helper can tell which secret is being asked for: a prompt about a
 passphrase is answered with the passphrase, anything else with the
 password. That one detail is what makes both secrets in one connection
 possible, and it is exactly what sshpass cannot do.

 Neither secret ever appears in a command line. They travel in the
 environment of the ssh process, which no other user on the machine can
 read, and the helper file itself holds no secret -- only the names of two
 variables. It is removed when FlashScp closes.

 And Test this connection looks at the key file first: if it is locked and
 nothing has been offered to unlock it, it says so in those words rather
 than letting ssh report a wrong key.


-------------------------------------------------------------------------------
 CHANGED, 30 SEPTEMBER 2026 — BROWSING FOR A KEY SHOWED NOTHING
-------------------------------------------------------------------------------

 In Manager of Computers, the Browse button beside Public key opened a file
 dialog that listed no files at all. Browsing to a folder holding two keys
 showed an empty window: nothing to choose, and no message saying why.

 The cause was not FlashScp's own listing -- the left panel showed the same
 folder and its two files perfectly well. It was the dialog. Asking for a
 file normally hands the job to whatever the desktop provides, and on a
 machine running xdg-desktop-portal that is the portal's chooser, running in
 a separate process. That is what was coming up empty.

 FlashScp now asks for Qt's own dialog instead of the desktop's, so the
 listing comes from the same place the rest of the window's listings come
 from. Two more things went in with it:

   * "All files" is the filter it opens with, because a key is as likely to
     be called sparta_300fs_key as id_rsa. A second entry offers the
     key-shaped names for anyone who wants them.

   * Hidden files are shown, since the usual home for a key is ~/.ssh and a
     dialog that cannot show a dot-directory is no use for choosing one.

 Picking the .pub half still fills in the private one beside it, as before.


-------------------------------------------------------------------------------
 WHAT IT IS
-------------------------------------------------------------------------------

 A two-pane file transfer window in the manner of FlashFXP, but where FlashFXP
 spoke FTP, FlashScp copies with scp over an SSH connection.

 Two computers side by side. Drag from one to the other. A queue underneath
 does the work and tells you how far along it is.

 Either side can be this computer or any machine you have saved, which turns
 three separate jobs into one gesture:

     local     ->  remote        sending files up to a server
     remote    ->  local         bringing files back down
     remote    ->  remote        moving files between two servers

 They are all the same thing: pick the two ends, drag, watch the queue.


-------------------------------------------------------------------------------
 HOW THE COPYING ACTUALLY HAPPENS — SCP, OVER SSH
-------------------------------------------------------------------------------

 This is worth being precise about, because the two names get used loosely.

     SSH is the connection.   It authenticates you to the far machine and
                              encrypts everything that travels between you.

     SCP is the copying.      It is the program that actually moves the bytes,
                              and it runs over the SSH connection that SSH
                              has established.

 So: FlashScp copies files over SSH using scp. SSH gets you securely to the
 machine; scp carries the file across that secure link. FlashScp does not
 invent its own protocol and does not carry its own SSH library — it drives
 the real `ssh` and `scp` programs that are already on your system, the same
 ones you would type in a terminal.

 That last point is the design of the whole program. Because it is the same
 ssh, everything ssh already knows about your machines stays true:

     - your private keys, and ~/.ssh/config
     - your ssh agent
     - your known_hosts file
     - ProxyJump, so you can copy through a bastion host
     - machines that demand a key AND a password (two-factor)

 Nothing here re-implements authentication, so nothing here can get it subtly
 wrong.


-------------------------------------------------------------------------------
 WHY SCP OVER SSH IS THE RIGHT WAY TO DO THIS
-------------------------------------------------------------------------------

 The honest comparison is against FTP, which is what this kind of program
 traditionally used.

 1. EVERYTHING IS ENCRYPTED.
    Your password, the file names, and the contents of the files all travel
    encrypted. Plain FTP sends your password across the network in clear text
    for anyone on the path to read. For a program whose entire job is carrying
    your files to your servers, that difference is the whole argument.

 2. ONE PORT, AND IT IS ALREADY OPEN.
    SSH is a single connection on port 22, which is already there because you
    administer the machine with it. FTP needs a control channel plus a second
    data channel on a port negotiated at the time — which is the thing that
    turns into a fight with NAT and firewall rules. With scp there is nothing
    extra to open and nothing extra to explain to a firewall.

 3. NOTHING TO INSTALL ON THE OTHER MACHINE.
    No FTP server, no daemon, no agent. If you can ssh into a machine, you can
    copy files to it. Every Linux and Unix system already has what is needed on
    the far end.

 4. KEYS INSTEAD OF PASSWORDS.
    You can authenticate with a key and send no password over the wire at all,
    and you can combine a key with a password where a machine demands both.

 5. YOU CAN TELL YOU ARE TALKING TO THE RIGHT MACHINE.
    SSH records each machine's host key the first time and refuses if it ever
    changes, so a substituted server is caught. FTP has no equivalent — you
    simply cannot know.

 6. CORRUPTION IN TRANSIT IS DETECTED.
    SSH authenticates every packet it carries, so a file cannot quietly arrive
    wrong because something along the way damaged it.

 7. PERMISSIONS AND TIMESTAMPS COME WITH THE FILE.
    Files arrive with their modification time and mode intact.


 WHAT SCP COSTS, SAID PLAINLY

 It is not free of trade-offs, and it is better to know them:

     - scp has no resume of its own, and no delta transfer. It cannot send only
       the changed part of a large file the way rsync can. FlashScp works
       around the first of these by walking the folder itself and skipping any
       file already at the far end and proved identical, so an interrupted
       folder copy picks up where it stopped. It cannot work around the
       second.

     - scp has more per-file overhead than FTP, so thousands of small files are
       slower. FlashScp answers this by holding one connection open and sending
       several files at once — see below.

     - SSH has no directory listing protocol, so FlashScp reads folders by
       running `find` on the far machine, falling back to `ls` where `find` is
       not available.


-------------------------------------------------------------------------------
 WHAT IS IN THE PROGRAM
-------------------------------------------------------------------------------

 MANAGER OF COMPUTERS
     Every machine you use, with its name, host, port, user, the path to your
     private key, the passphrase that key wants if it is locked, an optional
     password, a starting folder and a note. Either secret can be saved with
     the machine or asked for when connecting and kept only while the window
     is open -- each has its own tick, and what is not saved is not shown. A
     Test button proves a machine is reachable before you rely on it.
     Double-click a machine to connect to it; it opens on whichever side is
     free, and the Manager stays open with the reason if the connection
     fails.

 ONE CONNECTION PER MACHINE
     The first connection opens a shared channel and every listing, every file
     and every command afterwards travels down it. This makes repeat work far
     faster, but the real gain is on a machine that wants a password: it asks
     once, when you connect, instead of once per file. Copying a folder of
     forty files to such a machine is one prompt, not forty.

 THE QUEUE
     A dragged folder is walked first and queued a file at a time, rather than
     handed to scp whole. That buys three things: a progress figure that means
     something (bytes done of bytes known), several files travelling at once,
     and resume — a file already at the far end is skipped rather than sent
     again. You can cap the speed so a large copy does not take the whole
     link.

     A file is only treated as already there if it is genuinely the same
     file. Matching the size is the first test, and where the sizes match
     FlashScp then asks both machines for the SHA-256 of those files and
     compares them. Identical: skipped. Same size but different contents —
     an edit that happened not to change the length, which is the ordinary
     case when you are working on a file — it is sent. Only the same-size
     files are hashed, so a normal transfer costs nothing extra, and the far
     side is asked once for the whole list rather than once per file
     (sha256sum, or shasum, or openssl, whichever that machine has). If
     neither end can produce a hash, the file is sent rather than assumed
     good, and the queue says so.

 COMPARE AND MIRROR
     Put a folder here beside a folder there, see what differs by size and
     modification time, and send only what changed.

 TERMINAL TAB
     Run a command on the selected machine without leaving the program — the
     chmod +x, the mkdir, the ls to confirm something landed.

 FULL FILE MANAGEMENT
     New folder, rename, permissions and delete, on both sides. A delete names
     exactly what it will remove and which machine it will remove it from, and
     waits for you to agree.

 LIGHT AND DARK
     A toggle in the top right, remembered between runs. Every colour was
     measured rather than chosen by eye: text meets the 4.5:1 contrast that
     WCAG asks for, and the outlines of controls meet 3:1. The program will
     check its own colours and tell you if any has slipped:

         FlashScp.AppImage --check-contrast

 KEEP-ALIVE
     The connection is checked every twenty seconds, so a link that has died is
     noticed in about a minute and reported, rather than leaving a transfer to
     hang for ever.


-------------------------------------------------------------------------------
 RUNNING IT
-------------------------------------------------------------------------------

 Download the AppImage, make it executable, and run it:

     chmod +x FlashScp.AppImage
     ./FlashScp.AppImage

 There is nothing to install. The AppImage carries its own Python and its own
 interface libraries, plus sshpass for machines that want a password. It
 deliberately does NOT carry its own ssh or scp: those must be the ones on your
 own machine, because they are what read your keys, your ~/.ssh/config and your
 known_hosts. Every Linux system already has them.

 Your saved machines and settings are kept in:

     ~/.config/FlashScp/FlashScp.save

 That file is created readable only by you. A password is only written there if
 you tick "Save the password for this machine", and it is scrambled so the file
 cannot be read at a glance — which is obfuscation, not encryption, and the
 program says so rather than pretending otherwise. Left unticked, a password is
 asked for once and kept in memory only until you close the program. Either
 way it is handed to ssh through the environment and never on a command line,
 where other users of the machine could see it.

===============================================================================
