func TestAgentForward(t *testing.T) { server := newServer(t) defer server.Shutdown() conn := server.Dial(clientConfig()) defer conn.Close() keyring := agent.NewKeyring() keyring.Add(testPrivateKeys["dsa"], nil, "") pub := testPublicKeys["dsa"] sess, err := conn.NewSession() if err != nil { t.Fatalf("NewSession: %v", err) } if err := agent.RequestAgentForwarding(sess); err != nil { t.Fatalf("RequestAgentForwarding: %v", err) } if err := agent.ForwardToAgent(conn, keyring); err != nil { t.Fatalf("SetupForwardKeyring: %v", err) } out, err := sess.CombinedOutput("ssh-add -L") if err != nil { t.Fatalf("running ssh-add: %v, out %s", err, out) } key, _, _, _, err := ssh.ParseAuthorizedKey(out) if err != nil { t.Fatalf("ParseAuthorizedKey(%q): %v", out, err) } if !bytes.Equal(key.Marshal(), pub.Marshal()) { t.Fatalf("got key %s, want %s", ssh.MarshalAuthorizedKey(key), ssh.MarshalAuthorizedKey(pub)) } }
// newServer returns a new mock ssh server. func newServer(t *testing.T) *server { dir, err := ioutil.TempDir("", "sshtest") if err != nil { t.Fatal(err) } f, err := os.Create(filepath.Join(dir, "sshd_config")) if err != nil { t.Fatal(err) } err = configTmpl.Execute(f, map[string]string{ "Dir": dir, }) if err != nil { t.Fatal(err) } f.Close() for k, v := range testdata.PEMBytes { filename := "id_" + k writeFile(filepath.Join(dir, filename), v) writeFile(filepath.Join(dir, filename+".pub"), ssh.MarshalAuthorizedKey(testPublicKeys[k])) } return &server{ t: t, configfile: f.Name(), cleanup: func() { if err := os.RemoveAll(dir); err != nil { t.Error(err) } }, } }
func checkAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { status, err := exitStatus(exec.Command(authChecker[0], append(authChecker[1:], conn.User(), string(bytes.TrimSpace(ssh.MarshalAuthorizedKey(key))))...).Run()) if err != nil { return nil, err } if status.Status == 0 { return nil, nil } return nil, ErrUnauthorized }
func genSSHKey() (*sshData, error) { keyFile, err := ioutil.TempFile("", "") if err != nil { return nil, err } defer keyFile.Close() rsaKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, err } pem.Encode(keyFile, &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(rsaKey), }) pubFile, err := ioutil.TempFile("", "") if err != nil { return nil, err } defer pubFile.Close() rsaPubKey, err := ssh.NewPublicKey(&rsaKey.PublicKey) if err != nil { return nil, err } if _, err := pubFile.Write(ssh.MarshalAuthorizedKey(rsaPubKey)); err != nil { return nil, err } wrapperFile, err := ioutil.TempFile("", "") if err != nil { return nil, err } defer wrapperFile.Close() if err := sshWrapper.Execute(wrapperFile, map[string]string{"SSHKey": keyFile.Name()}); err != nil { return nil, err } if err := wrapperFile.Chmod(0700); err != nil { return nil, err } return &sshData{ Key: keyFile.Name(), Pub: pubFile.Name(), Env: []string{"GIT_SSH=" + wrapperFile.Name()}, Cleanup: func() { os.RemoveAll(keyFile.Name()) os.RemoveAll(pubFile.Name()) os.RemoveAll(wrapperFile.Name()) }, }, nil }
func (a *GenSSHKeyAction) Run(s *State) error { data := &SSHKey{} s.StepData[a.ID] = data var pemBuf bytes.Buffer rsaKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return err } pem.Encode(&pemBuf, &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(rsaKey), }) rsaPubKey, err := ssh.NewPublicKey(&rsaKey.PublicKey) if err != nil { return err } data.RSAPublic = string(bytes.TrimSpace(ssh.MarshalAuthorizedKey(rsaPubKey))) ecKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { return err } ecBytes, err := x509.MarshalECPrivateKey(ecKey) if err != nil { return err } pem.Encode(&pemBuf, &pem.Block{Type: "EC PRIVATE KEY", Bytes: ecBytes}) ecPubKey, err := ssh.NewPublicKey(&ecKey.PublicKey) if err != nil { return err } data.ECDSAPublic = string(bytes.TrimSpace(ssh.MarshalAuthorizedKey(ecPubKey))) data.PrivateKeys = pemBuf.String() return nil }
func (r *KeyRepo) Add(data interface{}) error { key := data.(*ct.Key) if key.Key == "" { return errors.New("controller: key must not be blank") } pubKey, comment, _, _, err := ssh.ParseAuthorizedKey([]byte(key.Key)) if err != nil { return err } key.ID = fingerprintKey(pubKey.Marshal()) key.Key = string(bytes.TrimSpace(ssh.MarshalAuthorizedKey(pubKey))) key.Comment = comment return r.db.QueryRow("INSERT INTO keys (fingerprint, key, comment) VALUES ($1, $2, $3) RETURNING created_at", key.ID, key.Key, key.Comment).Scan(&key.CreatedAt) }