init
This commit is contained in:
commit
23c7133fa9
33 files changed
+2896
No files matched your search
@@ -0,0 +1,66 @@
|
||||
// Package keymgr generates per-user SSH keypairs and packages them, together
|
||||
// with a ready-to-use client config and Windows-oriented instructions, into
|
||||
// a password-protected 7z archive for delivery.
|
||||
//
|
||||
// The private key only ever exists on disk for the lifetime of one export
|
||||
// operation: generated into a temp directory, packed into the archive, then
|
||||
// securely wiped (see Wipe in pack.go). It is never written into the state
|
||||
// store and therefore never ends up in a backup.
|
||||
package keymgr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// KeyPair is the result of generating one user's SSH keypair.
|
||||
type KeyPair struct {
|
||||
PrivateKeyPath string
|
||||
PublicKeyLine string // full "ssh-ed25519 AAAA... comment" line for authorized_keys
|
||||
Fingerprint string // "SHA256:xxxxx" as reported by ssh-keygen -lf
|
||||
}
|
||||
|
||||
// GeneratePair creates a new passphrase-less ed25519 keypair for username in
|
||||
// dir. The key itself has no passphrase because the archive it ships in is
|
||||
// already encrypted (see pack.go); a second passphrase would only add
|
||||
// friction without a corresponding threat it defends against once the
|
||||
// archive's own encryption and the server-side no-shell restriction are in
|
||||
// place.
|
||||
func GeneratePair(dir, username string) (*KeyPair, error) {
|
||||
priv := filepath.Join(dir, username+"_jump_key")
|
||||
pub := priv + ".pub"
|
||||
|
||||
cmd := exec.Command("ssh-keygen",
|
||||
"-t", "ed25519",
|
||||
"-N", "", // no passphrase
|
||||
"-C", username+"@jump",
|
||||
"-f", priv,
|
||||
)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return nil, fmt.Errorf("ssh-keygen: %w: %s", err, out)
|
||||
}
|
||||
|
||||
pubData, err := os.ReadFile(pub)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read public key: %w", err)
|
||||
}
|
||||
|
||||
fpOut, err := exec.Command("ssh-keygen", "-lf", pub).CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fingerprint: %w: %s", err, fpOut)
|
||||
}
|
||||
fields := strings.Fields(string(fpOut))
|
||||
fingerprint := ""
|
||||
if len(fields) >= 2 {
|
||||
fingerprint = fields[1]
|
||||
}
|
||||
|
||||
return &KeyPair{
|
||||
PrivateKeyPath: priv,
|
||||
PublicKeyLine: strings.TrimSpace(string(pubData)),
|
||||
Fingerprint: fingerprint,
|
||||
}, nil
|
||||
}
|
||||
Reference in new issue
Block a user