Пример #1
0
// 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
}
Пример #2
0
// 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
}
Пример #3
0
// 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)
		}
	}
}