// SSHAgentClient returns an Agent that talks to the local ssh-agent func SSHAgentClient() (gosshagent.Agent, error) { sock := os.Getenv("SSH_AUTH_SOCK") if sock == "" { return nil, errors.New("SSH_AUTH_SOCK environment variable is not set. Verify ssh-agent is running. See https://github.com/coreos/fleet/blob/master/Documentation/using-the-client.md for help.") } agent, err := net.Dial("unix", sock) if err != nil { return nil, err } return gosshagent.NewClient(agent), nil }
// generates an ssh config that attempt ssh-agents and then authorizes from keyFile // if keyFile is nil, we'll search for the usual suspects // (~/.ssh/id_rsa, id_dsa) func SshConf(user string, keyFile string) *ssh.ClientConfig { var auths []ssh.AuthMethod // ssh-agent auth goes first if agentPipe, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil { ag := agent.NewClient(agentPipe) agentSigners, err := ag.Signers() if err != nil { log.Printf("Error pulling signers from ssh-agent: %s", err) } else { if len(agentSigners) > 0 { auths = append(auths, ssh.PublicKeys(agentSigners...)) } } } // provided keyfile or default keyfiles var keyFiles []string if keyFile != "" { keyFiles = []string{keyFile} } else { keyFiles = lookupKeyFiles() } signers := make([]ssh.Signer, 0, 0) for _, keyFile := range keyFiles { keyFileH, err := os.Open(keyFile) if err != nil { log.Printf("Error opening keyFile %s : %s", keyFile, err) continue } keyBytes, err := ioutil.ReadAll(keyFileH) keyFileH.Close() if err != nil { log.Printf("Error reading keyFile %s, skipping : %s", keyFile, err) continue } signer, err := ssh.ParsePrivateKey(keyBytes) if err != nil { log.Printf("Error parsing keyFile contents from %s, skipping: %s", keyFile, err) } signers = append(signers, signer) } auths = append(auths, ssh.PublicKeys(signers...)) return &ssh.ClientConfig{ User: user, Auth: auths, } }
func NewClient(user, address string, privateKey []byte) (*client, error) { c := &client{} config := &ssh.ClientConfig{ User: user, } // Check if we've been given a byte slice from which to parse a key. if privateKey != nil { privateKeyParsed, err := ssh.ParsePrivateKey(privateKey) if err != nil { return c, err } config.Auth = []ssh.AuthMethod{ ssh.PublicKeys(privateKeyParsed), } } else { sshAuthSock := os.Getenv(`SSH_AUTH_SOCK`) socket, err := net.Dial("unix", sshAuthSock) if err != nil { return c, err } sshAgent := agent.NewClient(socket) signers, err := sshAgent.Signers() if err != nil { return c, err } config.Auth = []ssh.AuthMethod{ ssh.PublicKeys(signers...), } } client, err := ssh.Dial("tcp", address, config) if err != nil { return c, err } c.client = client return c, nil }
func (c *Client) Connect() (e error) { if c.Port == 0 { c.Port = 22 } var auths []ssh.AuthMethod if c.password != "" { auths = append(auths, ssh.Password(c.password)) } else if c.Agent, e = net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); e == nil { auths = append(auths, ssh.PublicKeysCallback(agent.NewClient(c.Agent).Signers)) } config := &ssh.ClientConfig{ User: c.User, Auth: auths, } c.Conn, e = ssh.Dial("tcp", fmt.Sprintf("%s:%d", c.Host, c.Port), config) return e }
func (c *Config) Connection() (*ssh.Client, error) { port := c.Port if port == 0 { port = 22 } var auths []ssh.AuthMethod if c.Password != "" { auths = append(auths, ssh.Password(c.Password)) } else if sshAgent, e := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); e == nil { auths = append(auths, ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers)) } config := &ssh.ClientConfig{ User: c.User, Auth: auths, } return ssh.Dial("tcp", fmt.Sprintf("%s:%d", c.Host, port), config) }
func main() { var auths []ssh.AuthMethod if aconn, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil { auths = append(auths, ssh.PublicKeysCallback(agent.NewClient(aconn).Signers)) } if *PASS != "" { auths = append(auths, ssh.Password(*PASS)) } config := ssh.ClientConfig{ User: *USER, Auth: auths, } addr := fmt.Sprintf("%s:%d", *HOST, *PORT) conn, err := ssh.Dial("tcp", addr, &config) if err != nil { log.Fatalf("unable to connect to [%s]: %v", addr, err) } defer conn.Close() client, err := sftp.NewClient(conn) if err != nil { log.Fatalf("unable to start sftp subsytem: %v", err) } defer client.Close() switch cmd := flag.Args()[0]; cmd { case "ls": if len(flag.Args()) < 2 { log.Fatalf("%s %s: remote path required", cmd, os.Args[0]) } walker := client.Walk(flag.Args()[1]) for walker.Step() { if err := walker.Err(); err != nil { log.Println(err) continue } fmt.Println(walker.Path()) } case "fetch": if len(flag.Args()) < 2 { log.Fatalf("%s %s: remote path required", cmd, os.Args[0]) } f, err := client.Open(flag.Args()[1]) if err != nil { log.Fatal(err) } defer f.Close() if _, err := io.Copy(os.Stdout, f); err != nil { log.Fatal(err) } case "put": if len(flag.Args()) < 2 { log.Fatalf("%s %s: remote path required", cmd, os.Args[0]) } f, err := client.Create(flag.Args()[1]) if err != nil { log.Fatal(err) } defer f.Close() if _, err := io.Copy(f, os.Stdin); err != nil { log.Fatal(err) } case "stat": if len(flag.Args()) < 2 { log.Fatalf("%s %s: remote path required", cmd, os.Args[0]) } f, err := client.Open(flag.Args()[1]) if err != nil { log.Fatal(err) } defer f.Close() fi, err := f.Stat() if err != nil { log.Fatalf("unable to stat file: %v", err) } fmt.Printf("%s %d %v\n", fi.Name(), fi.Size(), fi.Mode()) case "rm": if len(flag.Args()) < 2 { log.Fatalf("%s %s: remote path required", cmd, os.Args[0]) } if err := client.Remove(flag.Args()[1]); err != nil { log.Fatalf("unable to remove file: %v", err) } case "mv": if len(flag.Args()) < 3 { log.Fatalf("%s %s: old and new name required", cmd, os.Args[0]) } if err := client.Rename(flag.Args()[1], flag.Args()[2]); err != nil { log.Fatalf("unable to rename file: %v", err) } default: log.Fatal("unknown subcommand: %v", cmd) } }