github.com/containers/podman/v4@v4.9.4/pkg/machine/keys.go (about) 1 //go:build amd64 || arm64 2 // +build amd64 arm64 3 4 package machine 5 6 import ( 7 "errors" 8 "fmt" 9 "io" 10 "os" 11 "os/exec" 12 "path/filepath" 13 "strings" 14 15 "github.com/sirupsen/logrus" 16 ) 17 18 var sshCommand = []string{"ssh-keygen", "-N", "", "-t", "ed25519", "-f"} 19 20 // CreateSSHKeys makes a priv and pub ssh key for interacting 21 // the a VM. 22 func CreateSSHKeys(writeLocation string) (string, error) { 23 // If the SSH key already exists, hard fail 24 if _, err := os.Stat(writeLocation); err == nil { 25 return "", fmt.Errorf("SSH key already exists: %s", writeLocation) 26 } 27 if err := os.MkdirAll(filepath.Dir(writeLocation), 0700); err != nil { 28 return "", err 29 } 30 if err := generatekeys(writeLocation); err != nil { 31 return "", err 32 } 33 b, err := os.ReadFile(writeLocation + ".pub") 34 if err != nil { 35 return "", err 36 } 37 return strings.TrimSuffix(string(b), "\n"), nil 38 } 39 40 func CreateSSHKeysPrefix(identityPath string, passThru bool, skipExisting bool, prefix ...string) (string, error) { 41 _, e := os.Stat(identityPath) 42 if !skipExisting || errors.Is(e, os.ErrNotExist) { 43 if err := generatekeysPrefix(identityPath, passThru, prefix...); err != nil { 44 return "", err 45 } 46 } else { 47 fmt.Println("Keys already exist, reusing") 48 } 49 b, err := os.ReadFile(identityPath + ".pub") 50 if err != nil { 51 return "", err 52 } 53 return strings.TrimSuffix(string(b), "\n"), nil 54 } 55 56 // generatekeys creates an ed25519 set of keys 57 func generatekeys(writeLocation string) error { 58 args := append(append([]string{}, sshCommand[1:]...), writeLocation) 59 cmd := exec.Command(sshCommand[0], args...) 60 stdErr, err := cmd.StderrPipe() 61 if err != nil { 62 return err 63 } 64 if err := cmd.Start(); err != nil { 65 return err 66 } 67 waitErr := cmd.Wait() 68 if waitErr == nil { 69 return nil 70 } 71 errMsg, err := io.ReadAll(stdErr) 72 if err != nil { 73 return fmt.Errorf("key generation failed, unable to read from stderr: %w", waitErr) 74 } 75 return fmt.Errorf("failed to generate keys: %s: %w", string(errMsg), waitErr) 76 } 77 78 // generatekeys creates an ed25519 set of keys 79 func generatekeysPrefix(identityPath string, passThru bool, prefix ...string) error { 80 dir := filepath.Dir(identityPath) 81 file := filepath.Base(identityPath) 82 83 if err := os.MkdirAll(dir, 0700); err != nil { 84 return fmt.Errorf("could not create ssh directory: %w", err) 85 } 86 87 args := append([]string{}, prefix[1:]...) 88 args = append(args, sshCommand...) 89 args = append(args, file) 90 91 binary, err := exec.LookPath(prefix[0]) 92 if err != nil { 93 return err 94 } 95 binary, err = filepath.Abs(binary) 96 if err != nil { 97 return err 98 } 99 cmd := exec.Command(binary, args...) 100 cmd.Dir = dir 101 if passThru { 102 cmd.Stdin = os.Stdin 103 cmd.Stdout = os.Stdout 104 cmd.Stderr = os.Stderr 105 } 106 logrus.Debugf("Running wsl cmd %v in dir: %s", args, dir) 107 return cmd.Run() 108 }