func TestCertLogin(t *testing.T) { s := newServer(t) defer s.Shutdown() // Use a key different from the default. clientKey := testSigners["dsa"] caAuthKey := testSigners["ecdsa"] cert := &ssh.Certificate{ Key: clientKey.PublicKey(), ValidPrincipals: []string{username()}, CertType: ssh.UserCert, ValidBefore: ssh.CertTimeInfinity, } if err := cert.SignCert(rand.Reader, caAuthKey); err != nil { t.Fatalf("SetSignature: %v", err) } certSigner, err := ssh.NewCertSigner(cert, clientKey) if err != nil { t.Fatalf("NewCertSigner: %v", err) } conf := &ssh.ClientConfig{ User: username(), } conf.Auth = append(conf.Auth, ssh.PublicKeys(certSigner)) client, err := s.TryDial(conf) if err != nil { t.Fatalf("TryDial: %v", err) } client.Close() }
func clientConfig() *ssh.ClientConfig { config := &ssh.ClientConfig{ User: username(), Auth: []ssh.AuthMethod{ ssh.PublicKeys(testSigners["user"]), }, HostKeyCallback: hostKeyDB().Check, } return config }
func (c *BaseCluster) sshConfig() (*ssh.ClientConfig, error) { signer, err := ssh.NewSignerFromKey(c.SSHKey.PrivateKey) if err != nil { return nil, err } sshConfig := &ssh.ClientConfig{ User: c.SSHUsername, Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)}, } return sshConfig, nil }
func (c *SSHCluster) importSSHKeyPair(t *TargetServer) error { var buf bytes.Buffer _, file, readFileErrChan := c.base.PromptFileInput(fmt.Sprintf("Please provide your private key for %s@%s", t.User, t.IP)) if _, err := io.Copy(&buf, file); err != nil { readFileErrChan <- err return err } readFileErrChan <- nil // no error reading file b, _ := pem.Decode(buf.Bytes()) if b == nil { return fmt.Errorf("Invalid private key") } var pemBytes []byte if x509.IsEncryptedPEMBlock(b) { passphrase := c.base.PromptProtectedInput("Please enter the passphrase for the key") var err error pemBytes, err = x509.DecryptPEMBlock(b, []byte(passphrase)) if err != nil { return err } } else { pemBytes = b.Bytes } privateKey, err := x509.ParsePKCS1PrivateKey(pemBytes) if err != nil { return err } signer, err := ssh.NewSignerFromKey(privateKey) if err != nil { return err } auth := []ssh.AuthMethod{ssh.PublicKeys(signer)} sshConfig := c.sshConfigForAuth(t, auth) c.base.SendLog(fmt.Sprintf("Testing provided key for %s@%s", t.User, t.IP)) if !c.testAndAddAuthentication(t, sshConfig) { return fmt.Errorf("Provided key for %s@%s failed to authenticate", t.User, t.IP) } c.base.SendLog(fmt.Sprintf("Key verified for %s@%s", t.User, t.IP)) return nil }
func (c *SSHCluster) findSSHAuth() error { c.base.SendLog("Detecting authentication") testAndAddAuthMethod := func(t *TargetServer, a ssh.AuthMethod) bool { sshConfig := c.sshConfigForAuth(t, []ssh.AuthMethod{a}) if c.testAndAddAuthentication(t, sshConfig) { c.base.SendLog(fmt.Sprintf("Verified authentication for %s@%s", t.User, t.IP)) return true } return false } testAndAddSigner := func(t *TargetServer, s ssh.Signer) bool { return testAndAddAuthMethod(t, ssh.PublicKeys(s)) } testAllAuthenticated := func(targets []*TargetServer) bool { for _, t := range targets { if t.SSHConfig == nil { return false } } return true } sshAgent := c.sshAgent() sshAgentAuth := ssh.PublicKeysCallback(sshAgent.Signers) for _, t := range c.Targets { testAndAddAuthMethod(t, sshAgentAuth) } if testAllAuthenticated(c.Targets) { return nil } var agentKeys [][]byte if keys, err := sshAgent.List(); err == nil { agentKeys = make([][]byte, len(keys)) for i, k := range keys { agentKeys[i] = k.Marshal() } } var signers []privateKeySigner signerloop: for _, s := range c.findSSHKeySigners() { if s.publicKey != nil { for _, k := range agentKeys { if bytes.Equal(k, s.publicKey.Marshal()) { continue signerloop } } } signers = append(signers, s) } outer: for _, t := range c.Targets { if t.SSHConfig != nil { continue } for _, s := range signers { if s.Encrypted { if s.publicKey == nil { signer, err := s.Decrypt() if err != nil { continue } if testAndAddSigner(t, signer) { continue outer } } else { if testAndAddSigner(t, s) { continue outer } } } else { signer, err := ssh.NewSignerFromKey(s.key) if err != nil { continue } if testAndAddSigner(t, signer) { continue outer } } } } for _, t := range c.Targets { if t.SSHConfig != nil { continue } answer, err := c.base.ChoicePrompt(Choice{ Message: "No working authentication found.\nPlease choose one of the following options:", Options: []ChoiceOption{ { Type: 1, Name: "Private key", Value: "1", }, { Name: "Password", Value: "2", }, { Name: "Abort", Value: "3", }, }, }) if err != nil { return err } switch answer { case "1": if err := c.importSSHKeyPair(t); err != nil { return err } else { continue } case "2": password := c.base.PromptProtectedInput(fmt.Sprintf("Please enter your password for %s@%s", t.User, t.IP)) if testAndAddAuthMethod(t, ssh.Password(password)) { continue } } return fmt.Errorf("No working authentication found") } return nil }