// SSHConfig returns a function that can be used for the SSH communicator // config for connecting to the instance created over SSH using the provided // private key func SSHConfig(username string) func(multistep.StateBag) (*ssh.ClientConfig, error) { return func(state multistep.StateBag) (*ssh.ClientConfig, error) { privateKey := state.Get("privateKey").(string) // ad hoc key privateKeyBastion := state.Get("privateKeyBastion").(string) signer, err := ssh.ParsePrivateKey([]byte(privateKey)) if err != nil { return nil, fmt.Errorf("error setting up SSH config: %s", err) } authMethods := []ssh.AuthMethod{ssh.PublicKeys(signer)} // if we have a Bastion, that key should also be supported if privateKeyBastion != "" { signerBastion, err := ssh.ParsePrivateKey([]byte(privateKeyBastion)) if err != nil { return nil, fmt.Errorf("error setting up SSH config for Bastion: %s", err) } authMethods = append(authMethods, ssh.PublicKeys(signerBastion)) } return &ssh.ClientConfig{ User: username, Auth: authMethods, }, nil } }
// NewClientConfig returns a config using an ssh agent unless ident is not empty. func NewClientConfig(ident string, user string) (*ClientConfig, error) { // I think this could be simplified by using PublicKeysCallback cfg := &ClientConfig{ ClientConfig: &ssh.ClientConfig{ User: user, }, } if ident != "" { s, err := pemSigner(ident) if err != nil { return nil, err } cfg.ClientConfig.Auth = []ssh.AuthMethod{ssh.PublicKeys(s)} return cfg, nil } a, s, err := agentSigners() if err != nil { return nil, err } cfg.a = *a cfg.ClientConfig.Auth = []ssh.AuthMethod{ssh.PublicKeys(s...)} return cfg, nil }
func addKeyAuth(auths []ssh.AuthMethod, keypath string) []ssh.AuthMethod { if len(keypath) == 0 { return auths } // read the file pemBytes, err := ioutil.ReadFile(keypath) if err != nil { log.Print(err) os.Exit(1) } // get first pem block block, _ := pem.Decode(pemBytes) if block == nil { log.Printf("no key found in %s", keypath) return auths } // handle plain and encrypted keyfiles if x509.IsEncryptedPEMBlock(block) { prompt := fmt.Sprintf("Enter passphrase for key '%s': ", keypath) pass, err := getpass(prompt) if err != nil { return auths } block.Bytes, err = x509.DecryptPEMBlock(block, []byte(pass)) if err != nil { log.Print(err) return auths } key, err := ParsePemBlock(block) if err != nil { log.Print(err) return auths } signer, err := ssh.NewSignerFromKey(key) if err != nil { log.Print(err) return auths } return append(auths, ssh.PublicKeys(signer)) } else { signer, err := ssh.ParsePrivateKey(pemBytes) if err != nil { log.Print(err) return auths } return append(auths, ssh.PublicKeys(signer)) } }
func (n *Node) NewSSHSession() (session *ssh.Session, err error) { pkey, err := ioutil.ReadFile(n.SSHKeyFile) if err != nil { log.Println("ioutil.ReadFile(sshkey):", err) return session, err } s, err := ssh.ParsePrivateKey(pkey) if err != nil { log.Println("ssh.ParsePrivateKey():", err) return session, err } config := &ssh.ClientConfig{ User: n.User, Auth: []ssh.AuthMethod{ ssh.PublicKeys(s), }, } host := fmt.Sprintf("%s:%d", n.Host, n.Port) client, err := ssh.Dial("tcp", host, config) if err != nil { log.Println("ssh.Dial:", err) return session, err } session, err = client.NewSession() if err != nil { log.Println("cli.NewSession():", err) return session, err } return session, err }
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() }
//NewVagrantNode intializes a node in vagrant testbed func NewVagrantNode(name, port, privKeyFile string) (*VagrantNode, error) { var ( vnode *VagrantNode err error signer ssh.Signer privateKey []byte ) if privateKey, err = ioutil.ReadFile(privKeyFile); err != nil { return nil, err } if signer, err = ssh.ParsePrivateKey(privateKey); err != nil { return nil, err } config := &ssh.ClientConfig{ User: "******", Auth: []ssh.AuthMethod{ ssh.PublicKeys(signer), }, } vnode = &VagrantNode{Name: name} if vnode.client, err = ssh.Dial("tcp", fmt.Sprintf("127.0.0.1:%s", port), config); err != nil { return nil, err } return vnode, nil }
func (cfg *ConfigT) NewSshClientConfig(privKeyPath string) error { var err error var clientKey []byte var signer ssh.Signer Goose.ClientCfg.Logf(4, "Reading SSH private key from %s", privKeyPath) clientKey, err = ioutil.ReadFile(privKeyPath) if err != nil { Goose.ClientCfg.Logf(1, "%s (%s)", ErrReadingSSHKeys, err) return ErrReadingSSHKeys } signer, err = ssh.ParsePrivateKey(clientKey) if err != nil { Goose.ClientCfg.Logf(1, "%s (%s)", ErrParsingSSHKeys, err) return ErrReadingSSHKeys } cfg.SshClientConfig = &ssh.ClientConfig{ // User: user, Auth: []ssh.AuthMethod{ ssh.PublicKeys(signer), }, } return nil }
// remoteCmdOutput runs the given command on a remote server at the given hostname as the given user. func remoteCmdOutput(username, hostname, cmd string, privateKey []byte) (b []byte, err error) { p, err := ssh.ParseRawPrivateKey(privateKey) if err != nil { return b, err } s, err := ssh.NewSignerFromKey(p) if err != nil { return b, err } pub := ssh.PublicKeys(s) clientConfig := &ssh.ClientConfig{ User: username, Auth: []ssh.AuthMethod{pub}, } client, err := ssh.Dial("tcp", hostname, clientConfig) if err != nil { return b, errors.New("ERROR: Failed to dial: " + err.Error()) } defer client.Close() session, err := client.NewSession() if err != nil { return b, errors.New("ERROR: Failed to create session: " + err.Error()) } defer session.Close() b, err = session.Output(cmd) if err != nil { return b, fmt.Errorf("ERROR: Failed to run cmd on host %s: %s", hostname, err.Error()) } return b, nil }
// SSHConfig returns a function that can be used for the SSH communicator // config for connecting to the instance created over SSH using the private key // or password. func SSHConfig(username, password string) func(multistep.StateBag) (*ssh.ClientConfig, error) { return func(state multistep.StateBag) (*ssh.ClientConfig, error) { privateKey, hasKey := state.GetOk("privateKey") if hasKey { signer, err := ssh.ParsePrivateKey([]byte(privateKey.(string))) if err != nil { return nil, fmt.Errorf("Error setting up SSH config: %s", err) } return &ssh.ClientConfig{ User: username, Auth: []ssh.AuthMethod{ ssh.PublicKeys(signer), }, }, nil } else { return &ssh.ClientConfig{ User: username, Auth: []ssh.AuthMethod{ ssh.Password(password), ssh.KeyboardInteractive( packerssh.PasswordKeyboardInteractive(password)), }}, nil } } }
func (suite *ServerSuite) TestUnknownChannel() { // Get signer signer, err := ssh.ParsePrivateKey([]byte(clientPrivateKey)) if err != nil { suite.Fail("Private key could not be parsed" + err.Error()) } // Configure client connection config := &ssh.ClientConfig{ User: "******", Auth: []ssh.AuthMethod{ ssh.PublicKeys(signer), }, } // Create client connection client, err := ssh.Dial("tcp", "127.0.0.1:9022", config) if err != nil { suite.Fail(err.Error()) return } defer client.Close() // Open channel _, _, err = client.OpenChannel("/shell", []byte{}) suite.NotNil(err, "server should not accept shell channels") }
func sshConfig(state multistep.StateBag) (*gossh.ClientConfig, error) { config := state.Get("config").(*Config) var privateKey string var auth []gossh.AuthMethod if config.Comm.SSHPassword != "" { auth = []gossh.AuthMethod{ gossh.Password(config.Comm.SSHPassword), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(config.Comm.SSHPassword)), } } if config.Comm.SSHPrivateKey != "" { if priv, ok := state.GetOk("privateKey"); ok { privateKey = priv.(string) } signer, err := gossh.ParsePrivateKey([]byte(privateKey)) if err != nil { return nil, fmt.Errorf("Error setting up SSH config: %s", err) } if err != nil { return nil, err } auth = append(auth, gossh.PublicKeys(signer)) } return &gossh.ClientConfig{ User: config.Comm.SSHUsername, Auth: auth, }, nil }
// New returns a new SFTP remote Cache implementated. func New(server, username, password, key string) (cache.Cache, error) { config := &ssh.ClientConfig{ Timeout: time.Minute * 5, User: username, Auth: []ssh.AuthMethod{ ssh.Password(password), }, } // private key authentication takes precedence if key != "" { signer, err := ssh.ParsePrivateKey([]byte(key)) if err != nil { return nil, err } config.Auth[0] = ssh.PublicKeys(signer) } // create the ssh connection and client client, err := ssh.Dial("tcp", server, config) if err != nil { return nil, err } // open the sftp session using the ssh connection sftp, err := sftp.NewClient(client) if err != nil { client.Close() return nil, err } return &cacher{sftp, client}, nil }
// initAuthMethod initiates SSH authentication method. func initAuthMethod() { var signers []ssh.Signer // If there's a running SSH Agent, try to use its Private keys. sock, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")) if err == nil { agent := agent.NewClient(sock) signers, _ = agent.Signers() } // Try to read user's SSH private keys form the standard paths. files := []string{ os.Getenv("HOME") + "/.ssh/id_rsa", os.Getenv("HOME") + "/.ssh/id_dsa", } for _, file := range files { data, err := ioutil.ReadFile(file) if err != nil { continue } signer, err := ssh.ParsePrivateKey(data) if err != nil { continue } signers = append(signers, signer) } authMethod = ssh.PublicKeys(signers...) }
func initialize() { privkey_fname := util.AppBaseFileName() + ".privkey" privkey_bytes, err := ioutil.ReadFile(privkey_fname) if err != nil { log.Panicf("privkey load error: %s", err) } signer, err := ssh.ParsePrivateKey(privkey_bytes) if err != nil { log.Panicf("privkey parse error: %s", err) } clientConfig = &ssh.ClientConfig{ User: username, Auth: []ssh.AuthMethod{ ssh.PublicKeys(signer), }, } hostlist_fname := util.AppBaseFileName() + ".hostlist" f, err := os.Open(hostlist_fname) if err != nil { log.Panicf("hostlist open error: %s", err) } defer f.Close() scanner := bufio.NewScanner(f) scanner.Split(bufio.ScanLines) for scanner.Scan() { hostlist = append(hostlist, scanner.Text()) } }
func sshClientConfig(user string, checker *HostKeyChecker, addr string) (*gossh.ClientConfig, error) { agentClient, err := SSHAgentClient() if err != nil { return nil, err } signers, err := agentClient.Signers() if err != nil { return nil, err } cfg := gossh.ClientConfig{ User: user, Auth: []gossh.AuthMethod{ gossh.PublicKeys(signers...), }, } if checker != nil { cfg.HostKeyCallback = checker.Check cfg.HostKeyAlgorithms = checker.GetHostKeyAlgorithms(addr) } return &cfg, nil }
func (r *Runner) ConnectAndRun(host, command string, options *ConnectionOptions) (string, error) { signer, err := ssh.ParsePrivateKey(options.PrivateKeyPEM) if err != nil { return "", err } config := &ssh.ClientConfig{ User: options.Username, Auth: []ssh.AuthMethod{ ssh.PublicKeys(signer), }, } client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", host, options.Port), config) if err != nil { return "", fmt.Errorf("failed to dial: %s", err) } defer client.Close() session, err := client.NewSession() if err != nil { return "", fmt.Errorf("failed to create session: ", err) } defer session.Close() var stdoutBytes bytes.Buffer session.Stdout = &stdoutBytes session.Stderr = os.Stderr if err := session.Run(command); err != nil { return "", fmt.Errorf("failed while running command: %s", err) } return stdoutBytes.String(), nil }
// sshKeyAuth is a helper function to get the ssh key auth struct needed func (obj *Remotes) sshKeyAuth() (ssh.AuthMethod, error) { if obj.sshPrivIdRsa == "" { return nil, fmt.Errorf("Empty path specified!") } p := "" // TODO: this doesn't match strings of the form: ~james/.ssh/id_rsa if strings.HasPrefix(obj.sshPrivIdRsa, "~/") { usr, err := user.Current() if err != nil { log.Printf("Remote: Can't find home directory automatically.") return nil, err } p = path.Join(usr.HomeDir, obj.sshPrivIdRsa[len("~/"):]) } if p == "" { return nil, fmt.Errorf("Empty path specified!") } // A public key may be used to authenticate against the server by using // an unencrypted PEM-encoded private key file. If you have an encrypted // private key, the crypto/x509 package can be used to decrypt it. key, err := ioutil.ReadFile(p) if err != nil { return nil, err } // Create the Signer for this private key. signer, err := ssh.ParsePrivateKey(key) if err != nil { return nil, err } return ssh.PublicKeys(signer), nil }
func (suite *ServerSuite) TestClientConnection() { // Get signer signer, err := ssh.ParsePrivateKey([]byte(clientPrivateKey)) if err != nil { suite.Fail("Private key could not be parsed" + err.Error()) } // Configure client connection config := &ssh.ClientConfig{ User: "******", Auth: []ssh.AuthMethod{ ssh.PublicKeys(signer), }, } // Create client connection client, err := ssh.Dial("tcp", "127.0.0.1:9022", config) if err != nil { suite.Fail(err.Error()) return } defer client.Close() // Open channel channel, requests, err := client.OpenChannel("/echo", []byte{}) if err != nil { suite.Fail(err.Error()) return } go ssh.DiscardRequests(requests) defer channel.Close() }
func ExamplePublicKeys() { // A public key may be used to authenticate against the remote // server by using an unencrypted PEM-encoded private key file. // // If you have an encrypted private key, the crypto/x509 package // can be used to decrypt it. key, err := ioutil.ReadFile("/home/user/.ssh/id_rsa") if err != nil { log.Fatalf("unable to read private key: %v", err) } // Create the Signer for this private key. signer, err := ssh.ParsePrivateKey(key) if err != nil { log.Fatalf("unable to parse private key: %v", err) } config := &ssh.ClientConfig{ User: "******", Auth: []ssh.AuthMethod{ // Use the PublicKeys method for remote authentication. ssh.PublicKeys(signer), }, } // Connect to the remote server and perform the SSH handshake. client, err := ssh.Dial("tcp", "host.com:22", config) if err != nil { log.Fatalf("unable to connect: %v", err) } defer client.Close() }
func readPrivateKey(pk string) (ssh.AuthMethod, error) { key, _, err := pathorcontents.Read(pk) if err != nil { return nil, fmt.Errorf("Failed to read private key %q: %s", pk, err) } // We parse the private key on our own first so that we can // show a nicer error if the private key has a password. block, _ := pem.Decode([]byte(key)) if block == nil { return nil, fmt.Errorf("Failed to read key %q: no key found", pk) } if block.Headers["Proc-Type"] == "4,ENCRYPTED" { return nil, fmt.Errorf( "Failed to read key %q: password protected keys are\n"+ "not supported. Please decrypt the key prior to use.", pk) } signer, err := ssh.ParsePrivateKey([]byte(key)) if err != nil { return nil, fmt.Errorf("Failed to parse key file %q: %s", pk, err) } return ssh.PublicKeys(signer), nil }
func KeyAuth(file string) (ssh.AuthMethod, error) { k := new(keychain) if err := k.PrivateKey(file); err != nil { return nil, err } return ssh.PublicKeys(k.keys...), nil }
func NewConnection(host string, port int, username string, password string, key_path string) (*ssh.Client, error) { var config *ssh.ClientConfig if USEKEY { public_key, err := getKeyFromFile(key_path) if err != nil { log.Panic(err) } config = &ssh.ClientConfig{ User: username, Auth: []ssh.AuthMethod{ ssh.PublicKeys(public_key), }, } } else { config = &ssh.ClientConfig{ User: username, Auth: []ssh.AuthMethod{ ssh.Password(password), }, } } client, err := ssh.Dial("tcp", host+":"+strconv.Itoa(port), config) if err != nil { panic("Failed to dial: " + err.Error()) } // Each ClientConn can support multiple interactive sessions, // represented by a Session. return client, err }
// connects to remote server using ClientSSH struct and returns *ssh.Session func (ssh_conf *ClientSSH) connect() (*ssh.Session, error) { // auths holds the detected ssh auth methods auths := []ssh.AuthMethod{} // figure out what auths are requested, what is supported if ssh_conf.Password != "" { auths = append(auths, ssh.Password(ssh_conf.Password)) } if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil { auths = append(auths, ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers)) defer sshAgent.Close() } if pubkey, err := getKeyFile(ssh_conf.Key); err == nil { auths = append(auths, ssh.PublicKeys(pubkey)) } config := &ssh.ClientConfig{ User: ssh_conf.User, Auth: auths, } client, err := ssh.Dial("tcp", ssh_conf.Server+":"+ssh_conf.Port, config) if err != nil { return nil, err } session, err := client.NewSession() if err != nil { return nil, err } return session, nil }
func (d *ESX5Driver) connect() error { address := fmt.Sprintf("%s:%d", d.Host, d.Port) auth := []gossh.AuthMethod{ gossh.Password(d.Password), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(d.Password)), } if d.PrivateKey != "" { signer, err := commonssh.FileSigner(d.PrivateKey) if err != nil { return err } auth = append(auth, gossh.PublicKeys(signer)) } sshConfig := &ssh.Config{ Connection: ssh.ConnectFunc("tcp", address), SSHConfig: &gossh.ClientConfig{ User: d.Username, Auth: auth, }, } comm, err := ssh.New(address, sshConfig) if err != nil { return err } d.comm = comm return nil }
// Uploads the file to the remote machine func scpUpload(username, ip string, port int, hostkey, fileName, fileContent string) error { signer, err := ssh.ParsePrivateKey([]byte(hostkey)) clientConfig := &ssh.ClientConfig{ User: username, Auth: []ssh.AuthMethod{ ssh.PublicKeys(signer), }, } connfunc := func() (net.Conn, error) { c, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, port), 15*time.Second) if err != nil { return nil, err } if tcpConn, ok := c.(*net.TCPConn); ok { tcpConn.SetKeepAlive(true) tcpConn.SetKeepAlivePeriod(5 * time.Second) } return c, nil } config := &SSHCommConfig{ SSHConfig: clientConfig, Connection: connfunc, Pty: false, DisableAgent: true, } comm, err := SSHCommNew(fmt.Sprintf("%s:%d", ip, port), config) if err != nil { return fmt.Errorf("error connecting to target: %s", err) } comm.Upload(fileName, bytes.NewBufferString(fileContent), nil) return nil }
func (ih *InputHandler) createSession(config *InputEntry) (session *ssh.Session, err error) { var authMethod []ssh.AuthMethod var key *ssh.Signer if !config.Cred.IsPasswordAuth() { key, err = ih.parsePrivateKey(config.Cred.Identity) if err != nil { return } authMethod = []ssh.AuthMethod{ssh.PublicKeys(*key)} } else { authMethod = []ssh.AuthMethod{ssh.Password(config.Cred.Pass)} } sshConfig := new(ssh.ClientConfig) sshConfig.User = config.Cred.User sshConfig.Auth = authMethod port := uint16(22) if config.Port != 0 { port = config.Port } hostNameString := fmt.Sprintf("%s:%d", config.Host, port) client, err := ssh.Dial("tcp", hostNameString, sshConfig) if err != nil { return } session, err = client.NewSession() return }
func loadDefaultKeys() (auths []ssh.AuthMethod, err error) { k := "" currentUser, err := user.Current() defaultKeyPathA := filepath.FromSlash(currentUser.HomeDir + "/.ssh/id_rsa") defaultKeyPathB := filepath.FromSlash(currentUser.HomeDir + "/ssh/id_rsa") if fileExists(defaultKeyPathA) { k = defaultKeyPathA } else if fileExists(defaultKeyPathB) { k = defaultKeyPathB } if len(k) == 0 { err = errors.New("No key specified") return } pemBytes, err := ioutil.ReadFile(k) if err != nil { return } signer, err := ssh.ParsePrivateKey(pemBytes) if err != nil { return } auths = []ssh.AuthMethod{ssh.PublicKeys(signer)} return }
func addKeyAuth(auths []ssh.AuthMethod, keypath string) []ssh.AuthMethod { if len(keypath) == 0 { return auths } keypath = expandPath(keypath) // read the file pemBytes, err := ioutil.ReadFile(keypath) if err != nil { log.Print(err) os.Exit(1) } // get first pem block block, _ := pem.Decode(pemBytes) if block == nil { log.Printf("no key found in %s", keypath) return auths } // handle plain and encrypted keyfiles if x509.IsEncryptedPEMBlock(block) { log.Printf("warning: ignoring encrypted key '%s'", keypath) return auths } else { signer, err := ssh.ParsePrivateKey(pemBytes) if err != nil { log.Print(err) return auths } return append(auths, ssh.PublicKeys(signer)) } }
func NewNativeConfig(user string, auth *Auth) (ssh.ClientConfig, error) { var ( authMethods []ssh.AuthMethod ) for _, k := range auth.Keys { key, err := ioutil.ReadFile(k) if err != nil { return ssh.ClientConfig{}, err } privateKey, err := ssh.ParsePrivateKey(key) if err != nil { return ssh.ClientConfig{}, err } authMethods = append(authMethods, ssh.PublicKeys(privateKey)) } for _, p := range auth.Passwords { authMethods = append(authMethods, ssh.Password(p)) } return ssh.ClientConfig{ User: user, Auth: authMethods, }, nil }
// Run commands on the remote host func (rs *Rsync) run(keys *drone.Key, host string) error { // join the host and port if necessary addr := net.JoinHostPort(host, strconv.Itoa(rs.Port)) // trace command used for debugging in the build logs fmt.Printf("$ ssh %s@%s -p %d\n", rs.User, addr, rs.Port) signer, err := ssh.ParsePrivateKey([]byte(keys.Private)) if err != nil { return fmt.Errorf("Error parsing private key. %s.", err) } config := &ssh.ClientConfig{ User: rs.User, Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)}, } client, err := ssh.Dial("tcp", addr, config) if err != nil { return fmt.Errorf("Error dialing server. %s.", err) } session, err := client.NewSession() if err != nil { return fmt.Errorf("Error starting ssh session. %s.", err) } defer session.Close() session.Stdout = os.Stdout session.Stderr = os.Stderr return session.Run(strings.Join(rs.Commands, "\n")) }