aboutsummaryrefslogtreecommitdiff
path: root/rsh/main.go
diff options
context:
space:
mode:
authorLena <lena@omega>2026-07-01 00:00:00 +0000
committerLena <lena@omega>2026-07-01 00:00:00 +0000
commit1da5637997e7971cbde77dbf642ea734fbb2f4cc (patch)
tree8b3891c9a6e37275997f0e9d44df219d2b50076c /rsh/main.go
parent72e37d2dac501faa300ca895c56c53eea43ae4ae (diff)
downloadrsend-1da5637997e7971cbde77dbf642ea734fbb2f4cc.tar.gz
keys: never write the plaintext private key to disk
rsh -keygen printed the pubkey but wrote the key pair into a directory, so generating a key briefly left the plaintext private key on flash, contradicting the documented invariant that it only ever exists in memory. -keygen now emits the private key PEM on stdout and nothing else; the app encrypts it immediately and derives the public key via -pubkey, reusing the validated import path. Keygen failures now surface as an error dialog instead of crashing the app from a bare thread.
Diffstat (limited to 'rsh/main.go')
-rw-r--r--rsh/main.go32
1 files changed, 10 insertions, 22 deletions
diff --git a/rsh/main.go b/rsh/main.go
index 31029cb..0204a6b 100644
--- a/rsh/main.go
+++ b/rsh/main.go
@@ -1,7 +1,7 @@
// rsh is rsend's SSH transport. It is invoked three ways:
//
// rsh [-l USER] [USER@]HOST CMD... rsync remote shell (rsync -e), strict
-// rsh -keygen DIR generate an ed25519 key, print the pubkey
+// rsh -keygen generate an ed25519 key, print the private key (PEM)
// rsh -pubkey print the pubkey for RSH_KEY_DATA/RSH_KEY
// rsh -scan USER@HOST connect, print host-key fingerprint + line
//
@@ -29,7 +29,6 @@ import (
"io"
"net"
"os"
- "path/filepath"
"strconv"
"strings"
"time"
@@ -55,10 +54,10 @@ func run(args []string, in io.Reader, out, errw io.Writer) error {
if len(args) >= 1 {
switch args[0] {
case "-keygen":
- if len(args) != 2 {
- return errors.New("usage: rsh -keygen DIR")
+ if len(args) != 1 {
+ return errors.New("usage: rsh -keygen")
}
- return keygen(args[1], out)
+ return keygen(out)
case "-pubkey":
if len(args) != 1 {
return errors.New("usage: rsh -pubkey")
@@ -138,10 +137,11 @@ func scan(target string, out io.Writer) error {
return nil
}
-// keygen writes an ed25519 key pair into dir and prints the public key in
-// authorized_keys format to out.
-func keygen(dir string, out io.Writer) error {
- pub, priv, err := ed25519.GenerateKey(rand.Reader)
+// keygen generates an ed25519 key and prints the private key in PEM form to
+// out. Nothing touches disk: the caller owns persistence (the app stores it
+// encrypted) and derives the public key with -pubkey.
+func keygen(out io.Writer) error {
+ _, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return err
}
@@ -149,19 +149,7 @@ func keygen(dir string, out io.Writer) error {
if err != nil {
return err
}
- if err := os.WriteFile(filepath.Join(dir, "id_ed25519"), pem.EncodeToMemory(block), 0o600); err != nil {
- return err
- }
- sshPub, err := ssh.NewPublicKey(pub)
- if err != nil {
- return err
- }
- authLine := ssh.MarshalAuthorizedKey(sshPub)
- if err := os.WriteFile(filepath.Join(dir, "id_ed25519.pub"), authLine, 0o644); err != nil {
- return err
- }
- _, err = out.Write(authLine)
- return err
+ return pem.Encode(out, block)
}
// pubkey loads the private key (RSH_KEY_DATA or RSH_KEY) and prints its public