// ForwardToAgent routes authentication requests to the given keyring. func ForwardToAgent(client *ssh.Client, keyring Agent) error { channels := client.HandleChannelOpen(channelType) if channels == nil { return errors.New("agent: already have handler for " + channelType) } go func() { for ch := range channels { channel, reqs, err := ch.Accept() if err != nil { continue } go ssh.DiscardRequests(reqs) go func() { ServeAgent(keyring, channel) channel.Close() }() } }() return nil }
// ForwardToRemote routes authentication requests to the ssh-agent // process serving on the given unix socket. func ForwardToRemote(client *ssh.Client, addr string) error { channels := client.HandleChannelOpen(channelType) if channels == nil { return errors.New("agent: already have handler for " + channelType) } conn, err := net.Dial("unix", addr) if err != nil { return err } conn.Close() go func() { for ch := range channels { channel, reqs, err := ch.Accept() if err != nil { continue } go ssh.DiscardRequests(reqs) go forwardUnixSocket(channel, addr) } }() return nil }
// Handle new connection attempts from SSH clients. func handleNewClientConn(newClientInfoChan chan NewClientInfo) { for newClientInfo := range newClientInfoChan { // Before use, a handshake must be performed on the incoming // net.Conn. // Switching from a standard TCP connection to an encrypted SSH connection. sshServerConn, chans, reqs, err := ssh.NewServerConn(newClientInfo.nConn, &(newClientInfo.serverConfigPtr)) if err != nil { log.Printf("(handleNewClientConn) >> Error in ssh.NewServerConn: '%s'", err.Error()) // Go on serving the other SSH client requests. continue } // The incoming Request channel must be serviced. go ssh.DiscardRequests(reqs) // Service the incoming Channel channel. for newChannel := range chans { // Channels have a type, depending on the application level // protocol intended. In the case of a shell, the type is // "session" and ServerShell may be used to present a simple // terminal interface. if newChannel.ChannelType() != "session" { newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") continue } channel, requests, err := newChannel.Accept() if err != nil { panic("could not accept channel.") } // Sessions have out-of-band requests such as "shell", // "pty-req" and "env". Here we handle only the // "shell" request. go func(in <-chan *ssh.Request) { for req := range in { ok := false switch req.Type { case "shell": ok = true if len(req.Payload) > 0 { // We don't accept any // commands, only the // default shell. ok = false } } req.Reply(ok, nil) } }(requests) go func(sshServerConn *ssh.ServerConn) { defer channel.Close() cwd, err := os.Getwd() if err != nil { log.Printf("(handleNewClientConn) >> Error: Could not figure out current working directory: %s", err.Error()) } payloadPath := fmt.Sprintf("%s/data/%s/payload", cwd, sshServerConn.User()) payload, err := ioutil.ReadFile(payloadPath) if err != nil { log.Printf("(handleNewClientConn) >> Error: Could not read payload file '%s' for user '%s': %s", payloadPath, sshServerConn.User(), err.Error()) return } log.Printf("(handleNewClientConn) >> Successfully retrieved contents of payload file '%s' for user '%s'.\n", payloadPath, sshServerConn.User()) _, err = channel.Write(payload) if err != nil { log.Printf("(handleNewClientConn) >> Error sending payload to SSH client: %s\n", err.Error()) } log.Println("(handleNewClientConn) >> Successfully sent payload to SSH client.") }(sshServerConn) } } }