// GenerateAndSaveKey generates a new SSH key pair and saves it to local. func (s *SSHKey) GenerateAndSaveKey() ([]byte, error) { var perms os.FileMode = 0600 if err := os.MkdirAll(filepath.Dir(s.PrivateKeyPath()), 0700); err != nil { return nil, err } publicKey, privateKey, err := sshkey.Generate() if err != nil { return nil, err } publicKey += fmt.Sprintf(" koding-%d", rand.Int31()) // save ssh private key err = ioutil.WriteFile(s.PrivateKeyPath(), []byte(privateKey), perms) if err != nil { return nil, err } // save ssh public key err = ioutil.WriteFile(s.PublicKeyPath(), []byte(publicKey), perms) if err != nil { return nil, err } return []byte(publicKey), nil }
func TestSSHGenerateCustomName(t *testing.T) { dir, err := ioutil.TempDir("", "ssh") if err != nil { t.Fatalf("want err = nil; got %v", err) } defer os.RemoveAll(dir) customName := filepath.Join(dir, "custom") pubKey, privKey, err := sshkey.Generate() if err != nil { t.Fatalf("want err = nil; got %v", err) } if err := ioutil.WriteFile(customName, []byte(privKey), 0600); err != nil { t.Fatalf("want err = nil; got %v", err) } if err := ioutil.WriteFile(customName+".pub", []byte(pubKey), 0600); err != nil { t.Fatalf("want err = nil; got %v", err) } pubPath, privPath, err := KeyPaths(customName) if err != nil { t.Fatalf("want err = nil; got %v", err) } if _, _, err := GenerateSaved(pubPath, privPath); err == nil { t.Fatalf("want err != nil; got <nil>") } pubPathNonExist, _, err := KeyPaths(dir) if err != nil { t.Fatalf("want err = nil; got %v", err) } if _, err := PublicKey(pubPathNonExist); err == nil { t.Fatalf("want err != nil; got <nil>") } pk, err := PublicKey(pubPath) if err != nil { t.Fatalf("want err = nil; got %v", err) } if pk != pubKey { t.Fatalf("want public key = %s; got %s", pubKey, pk) } }
// GenerateSaved generates SSH key pair and saves it in provided paths. This // function will not replace existing keys if they already exists. func GenerateSaved(pubPath, privPath string) (pubKey, privKey string, err error) { keys := map[string]string{ "public": pubPath, "private": privPath, } // Check if files exist. for name, keyPath := range keys { switch _, err := os.Stat(keyPath); { case err == nil: return "", "", fmt.Errorf("%s key file %s already exists", name, keyPath) case os.IsNotExist(err): default: return "", "", err } } // Generate keys. pubKey, privKey, err = sshkey.Generate() if err != nil { return "", "", err } pubKey += fmt.Sprintf(" koding-%d", rand.Int31()) keys = map[string]string{ pubPath: pubKey, privPath: privKey, } for keyPath, content := range keys { if err := ioutil.WriteFile(keyPath, []byte(content), 0600); err != nil { return "", "", err } } return pubKey, privKey, nil }