Example #1
0
func (l *sshListener) handle(c net.Conn) error {
	conf := ssh.ServerConfig{
		PublicKeyCallback: l.checkLogin,
	}
	conf.AddHostKey(l.id)
	_, chans, reqs, err := ssh.NewServerConn(c, &conf)
	if err != nil {
		return err
	}

	go ssh.DiscardRequests(reqs)
	for newCh := range chans {
		id := newCh.ChannelType()
		if len(id) != len(RPC_CHANNEL) {
			newCh.Reject(ssh.Prohibited, "wrong ID length")
		}

		ch, reqs, err := newCh.Accept()
		if err != nil {
			continue
		}
		go ssh.DiscardRequests(reqs)

		l.pending.add(id, ch)
	}
	return nil
}
Example #2
0
func main() {
	conf := serverConfig()

	// start the server
	addr := fmt.Sprintf("0.0.0.0:%s", os.Args[1])
	listener, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatalf("[FATAL] failed to listen to %q, err %q", addr, err)
	}
	log.Printf("[INFO] listening to %q", addr)

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Fatalf("[FATAL] failed to accept tcp conn %q", err)
		}
		_, chs, reqs, err := ssh.NewServerConn(conn, conf)
		if err != nil {
			log.Printf("[ERROR] failed to open new ssh server conn %q", err)
			continue
		}
		// discard all requests sent outside of normal data
		go ssh.DiscardRequests(reqs)
		for ch := range chs {
			handleChannel(ch)
		}
	}
}
Example #3
0
func (d *sshDialer) Dial(addr string) (connMuxer, error) {
	conf := ssh.ClientConfig{
		User:            "******",
		Auth:            []ssh.AuthMethod{ssh.PublicKeys(d.identity)},
		HostKeyCallback: d.checkHost,
	}

	c, err := net.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}

	defer func() {
		if c != nil {
			c.Close()
		}
	}()
	conn, chans, reqs, err := ssh.NewClientConn(c, addr, &conf)
	if err != nil {
		return nil, err
	}
	go ssh.DiscardRequests(reqs)
	go func() {
		for c := range chans {
			go c.Reject(ssh.Prohibited, "")
		}
	}()

	c = nil
	return &sshMuxer{conn}, nil
}
Example #4
0
func (srv *Server) ServeConn(conn net.Conn) error {
	_, chans, reqs, err := ssh.NewServerConn(conn, srv.sshCfg)
	if err != nil {
		return fmt.Errorf("handshake: %v", err)
	}
	go ssh.DiscardRequests(reqs)
	for nch := range chans {
		var (
			chType = nch.ChannelType()
			chArg  = string(nch.ExtraData())
		)
		if !srv.h.AcceptSSHRaw(chType, chArg) {
			nch.Reject(ssh.UnknownChannelType, "unknown channel type")
			continue
		}
		ch, reqs, err := nch.Accept()
		if err != nil {
			return fmt.Errorf("accept: %v", err)
		}
		// FIXME: use context.Context to cleanly synchronize with handlers, block on them
		// but still be able to terminate them gracefully.
		go func(ch ssh.Channel, reqs <-chan *ssh.Request) {
			srv.h.HandleSSHRaw(chType, chArg, ch, reqs)
			ch.Close()
		}(ch, reqs)
	}
	return nil
}
Example #5
0
func (m *sshMuxer) Open(id string) (io.ReadWriteCloser, error) {
	channel, reqs, err := m.conn.OpenChannel(id, nil)
	if err != nil {
		return nil, err
	}
	go ssh.DiscardRequests(reqs)

	return channel, nil
}
Example #6
0
func TestSetupForwardAgent(t *testing.T) {
	a, b, err := netPipe()
	if err != nil {
		t.Fatalf("netPipe: %v", err)
	}

	defer a.Close()
	defer b.Close()

	_, socket, cleanup := startAgent(t)
	defer cleanup()

	serverConf := ssh.ServerConfig{
		NoClientAuth: true,
	}
	serverConf.AddHostKey(testSigners["rsa"])
	incoming := make(chan *ssh.ServerConn, 1)
	go func() {
		conn, _, _, err := ssh.NewServerConn(a, &serverConf)
		if err != nil {
			t.Fatalf("Server: %v", err)
		}
		incoming <- conn
	}()

	conf := ssh.ClientConfig{}
	conn, chans, reqs, err := ssh.NewClientConn(b, "", &conf)
	if err != nil {
		t.Fatalf("NewClientConn: %v", err)
	}
	client := ssh.NewClient(conn, chans, reqs)

	if err := ForwardToRemote(client, socket); err != nil {
		t.Fatalf("SetupForwardAgent: %v", err)
	}

	server := <-incoming
	ch, reqs, err := server.OpenChannel(channelType, nil)
	if err != nil {
		t.Fatalf("OpenChannel(%q): %v", channelType, err)
	}
	go ssh.DiscardRequests(reqs)

	agentClient := NewClient(ch)
	testAgentInterface(t, agentClient, testPrivateKeys["rsa"], nil)
	conn.Close()
}
Example #7
0
func NewServer() (err error) {

	// An SSH server is represented by a ServerConfig, which holds
	// certificate details and handles authentication of ServerConns.
	config := new(ssh.ServerConfig)
	config.PublicKeyCallback = HandlePublicKeyCallback
	config.AuthLogCallback = HandleAuthLogCallback

	key, err := osext.ReadHostKeys(HostKeysDir)
	if err != nil {
		return
	}
	for _, v := range key {
		signer, err := ssh.ParsePrivateKey(v)
		if err != nil {
			return err
		}
		config.AddHostKey(signer)
	}

	// Once a ServerConfig has been configured, connections can be
	// accepted.
	conn, err := net.Listen("tcp", ":22")
	if err != nil {
		log.Fatal("Failed to listen for connection: ", err)
	}
	for {
		sConn, err := conn.Accept()
		if err != nil {
			log.Printf("conn.Accept: %s", err)
			continue
		}

		sshconn, chans, reqs, err := ssh.NewServerConn(sConn, config)
		if err != nil {
			log.Printf("ssh.NewServerConn: Failed to handshake: %s", err)
			continue
		}

		// The incoming Request channel must be serviced.
		go ssh.DiscardRequests(reqs)

		// Handle the incomming request
		go HandleServerConn(sshconn, chans)
	}
}
Example #8
0
func handleConn(conn net.Conn, conf *ssh.ServerConfig) {
	defer conn.Close()
	sshConn, chans, reqs, err := ssh.NewServerConn(conn, conf)
	if err != nil {
		log.Println("Failed to handshake:", err)
		return
	}

	go ssh.DiscardRequests(reqs)

	for ch := range chans {
		if ch.ChannelType() != "session" {
			ch.Reject(ssh.UnknownChannelType, "unknown channel type")
			continue
		}
		go handleChannel(sshConn, ch)
	}
}
Example #9
0
func (ri *ReviewInfo) Serve(srvConn *ssh.ServerConn, srvChans <-chan ssh.NewChannel, srvReqs <-chan *ssh.Request) (err error) {
	go ssh.DiscardRequests(srvReqs)
	log.Info("review connect begin.")

	for newChan := range srvChans {
		if newChan.ChannelType() != "session" {
			newChan.Reject(ssh.ResourceShortage, "not session")
			continue
		}
		ch, reqs, err := newChan.Accept()
		if err != nil {
			log.Error("%s", err.Error())
			continue
		}
		go ri.serveChan(ch, reqs)
	}
	log.Info("review connect closed.")
	return
}
Example #10
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
}
Example #11
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
}
Example #12
0
func listen(config *ssh.ServerConfig, port string) {
	listener, err := net.Listen("tcp", "0.0.0.0:"+port)
	if err != nil {
		panic(err)
	}
	for {
		// Once a ServerConfig has been configured, connections can be accepted.
		conn, err := listener.Accept()
		if err != nil {
			log.Error(3, "Fail to accept incoming connection: %v", err)
			continue
		}
		// Before use, a handshake must be performed on the incoming net.Conn.
		sConn, chans, reqs, err := ssh.NewServerConn(conn, config)
		if err != nil {
			log.Error(3, "Fail to handshake: %v", err)
			continue
		}
		// The incoming Request channel must be serviced.
		go ssh.DiscardRequests(reqs)
		go handleServerConn(sConn.Permissions.Extensions["key-id"], chans)
	}
}
Example #13
0
func processRequests(conn *ssh.ServerConn, reqs <-chan *ssh.Request) {
	for req := range reqs {
		if req.Type != "tcpip-forward" {
			// accept only tcpip-forward requests
			if req.WantReply {
				req.Reply(false, nil)
			}
			continue
		}
		type channelForwardMsg struct {
			Laddr string
			Lport uint32
		}
		m := &channelForwardMsg{}
		ssh.Unmarshal(req.Payload, m)

		privateBytes, err := ioutil.ReadFile(appConfig.RemotePrivateKeyPath)
		if err != nil {
			log.Fatal(err.Error())
		}

		signer, err := ssh.ParsePrivateKey(privateBytes)
		if err != nil {
			log.Fatal(err.Error())
		}

		config := &ssh.ClientConfig{
			User: appConfig.RemoteSSHUser,
			Auth: []ssh.AuthMethod{
				ssh.PublicKeys(signer),
			},
		}
		sshClientConn, err := ssh.Dial("tcp", appConfig.RemoteSSHAddr, config)
		if err != nil {
			log.Fatal(err.Error())
		}

		type channelOpenForwardMsg struct {
			raddr string
			rport uint32
			laddr string
			lport uint32
		}

		fm := &channelOpenForwardMsg{
			raddr: "localhost",
			rport: m.Lport,
			laddr: "localhost",
			lport: m.Lport,
		}
		channel, reqs, err := conn.Conn.OpenChannel("forwarded-tcpip", ssh.Marshal(fm))
		if err != nil {
			log.Fatal(err.Error())
		}

		go ssh.DiscardRequests(reqs)

		portListener, err := sshClientConn.Listen("tcp", appConfig.RemoteForwardAddress)
		if err != nil {
			log.Fatal(err.Error())
		}

		go func() {
			for {
				sshConn, err := portListener.Accept()
				if err != nil {
					log.Fatal(err.Error())
				}

				// Copy localConn.Reader to sshConn.Writer
				go func(sshConn net.Conn) {
					_, err := io.Copy(sshConn, channel)
					if err != nil {
						log.Println("io.Copy failed: %v", err)
						sshConn.Close()
						return
					}
				}(sshConn)

				// Copy sshConn.Reader to localConn.Writer
				go func(sshConn net.Conn) {
					_, err := io.Copy(channel, sshConn)
					if err != nil {
						log.Println("io.Copy failed: %v", err)
						sshConn.Close()
						return
					}
				}(sshConn)
			}
		}()
		req.Reply(true, nil)
	}
}