func handleLocalSshConn(lnConn net.Conn) {
	defer func() {
		if Config.Ssh_Reverse_Proxy.Exit_On_Panic {
			return
		}
		if r := recover(); r != nil {
			Log.Error("Recovered from panic in connection from "+
				lnConn.RemoteAddr().String()+":", r)
		}
	}()

	Log.Info("Received connection from", lnConn.RemoteAddr())

	var sClient *ssh.Client
	psConfig := getProxyServerSshConfig(&sClient)
	psConn, psChans, psReqs, err := ssh.NewServerConn(lnConn, psConfig)
	if err != nil {
		Log.Info("Could not establish connection with " + lnConn.RemoteAddr().String() + ": " + err.Error())
		return
	}
	defer psConn.Close()
	defer sClient.Close()

	go ssh.DiscardRequests(psReqs)

	for newChannel := range psChans {
		handleChannel(newChannel, sClient)
	}

	Log.Info("Lost connection with", lnConn.RemoteAddr())
}
Exemple #2
0
func (suite *ServerSuite) TestHandlerError() {

	// Configure client connection
	config := &ssh.ClientConfig{
		User: "******",
		Auth: []ssh.AuthMethod{
			ssh.Password("bandit"),
		},
	}

	// 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("/bad", []byte{})
	if err != nil {
		suite.Fail(err.Error())
		return
	}
	go ssh.DiscardRequests(requests)
	defer channel.Close()
}
Exemple #3
0
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()
}
Exemple #4
0
func (c *adapter) Handle(conn net.Conn, ui packer.Ui) error {
	log.Print("SSH proxy: accepted connection")
	_, chans, reqs, err := ssh.NewServerConn(conn, c.config)
	if err != nil {
		return errors.New("failed to handshake")
	}

	// discard all global requests
	go ssh.DiscardRequests(reqs)

	// Service the incoming NewChannels
	for newChannel := range chans {
		if newChannel.ChannelType() != "session" {
			newChannel.Reject(ssh.UnknownChannelType, "unknown channel type")
			continue
		}

		go func(ch ssh.NewChannel) {
			if err := c.handleSession(ch); err != nil {
				c.ui.Error(err.Error())
			}
		}(newChannel)
	}

	return nil
}
Exemple #5
0
func listen(config *ssh.ServerConfig, port int) {
	listener, err := net.Listen("tcp", "0.0.0.0:"+com.ToStr(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, "Error accepting 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, "Error on handshaking: %v", err)
			continue
		}

		log.Trace("Connection from %s (%s)", sConn.RemoteAddr(), sConn.ClientVersion())
		// The incoming Request channel must be serviced.
		go ssh.DiscardRequests(reqs)
		go handleServerConn(sConn.Permissions.Extensions["key-id"], chans)
	}
}
Exemple #6
0
// handleConn handles an individual client connection.
//
// It manages the connection, but passes channels on to `answer()`.
func (s *server) handleConn(conn net.Conn, conf *ssh.ServerConfig) {
	defer conn.Close()
	log.Info("Accepted connection.")
	sshConn, chans, reqs, err := ssh.NewServerConn(conn, conf)
	if err != nil {
		// Handshake failure.
		log.Err("Failed handshake: %s", err)
		return
	}

	// Discard global requests. We're only concerned with channels.
	go ssh.DiscardRequests(reqs)

	condata := sshConnection(conn)

	// Now we handle the channels.
	for incoming := range chans {
		log.Info("Channel type: %s\n", incoming.ChannelType())
		if incoming.ChannelType() != "session" {
			incoming.Reject(ssh.UnknownChannelType, "Unknown channel type")
		}

		channel, req, err := incoming.Accept()
		if err != nil {
			// Should close request and move on.
			panic(err)
		}
		go s.answer(channel, req, condata, sshConn)
	}
	conn.Close()
}
func (handler *DirectTcpipChannelHandler) HandleNewChannel(logger lager.Logger, newChannel ssh.NewChannel) {
	type channelOpenDirectTcpipMsg struct {
		TargetAddr string
		TargetPort uint32
		OriginAddr string
		OriginPort uint32
	}
	var directTcpipMessage channelOpenDirectTcpipMsg

	err := ssh.Unmarshal(newChannel.ExtraData(), &directTcpipMessage)
	if err != nil {
		newChannel.Reject(ssh.ConnectionFailed, "Failed to parse open channel message")
		return
	}

	destination := fmt.Sprintf("%s:%d", directTcpipMessage.TargetAddr, directTcpipMessage.TargetPort)
	conn, err := handler.dialer.Dial("tcp", destination)
	if err != nil {
		newChannel.Reject(ssh.ConnectionFailed, err.Error())
		return
	}

	channel, requests, err := newChannel.Accept()
	go ssh.DiscardRequests(requests)

	wg := &sync.WaitGroup{}

	wg.Add(2)
	go helpers.CopyAndClose(logger.Session("to-target"), wg, conn, channel)
	go helpers.CopyAndClose(logger.Session("to-channel"), wg, channel, conn)

	wg.Wait()
}
Exemple #8
0
func (server *Server) handleConnection(conn net.Conn) {
	showConnCount := func() {
		server.Logger.Debugf("Current Connections: (%d/%d)",
			atomic.LoadInt32(&server.ClientCount), server.Config.MaxClient)
	}

	defer func() {
		conn.Close()
		server.Logger.Debugf("The connection from %s is closed", conn.RemoteAddr().String())
		atomic.AddInt32(&server.ClientCount, -1)
		showConnCount()
	}()

	atomic.AddInt32(&server.ClientCount, 1)
	showConnCount()
	if atomic.LoadInt32(&server.ClientCount) > server.Config.MaxClient {
		server.Logger.Errorf("Failed to accept incoming connection due to too many connections (%d/%d)",
			server.ClientCount, server.Config.MaxClient)
		return
	}

	sshConnection, chans, reqs, err := ssh.NewServerConn(conn, server.ServerConfig)
	if err != nil {
		if err != io.EOF {
			server.Logger.Errorf("Failed to start SSL connection with %s due to %s",
				conn.RemoteAddr().String(), err)
		}
		return
	}
	server.Logger.Debugf("Built SSL connection with %s, sessionId: %s, client version: %s, user: %s",
		conn.RemoteAddr().String(), hex.EncodeToString(sshConnection.SessionID()),
		sshConnection.ClientVersion(), sshConnection.User())
	go ssh.DiscardRequests(reqs)
	server.handleChannels(chans, sshConnection)
}
Exemple #9
0
// StartSSHD starts the ssh server on address:port provided
func StartSSHD(addr string) error {
	handler.Board = make(map[string]*handler.Handler, 0)

	listener, err := net.Listen("tcp", addr)
	if err != nil {
		return fmt.Errorf("Failed to listen on %v port. Reason: (%s)", addr, err.Error())
	}

	fmt.Printf("GoSSHa is listening on %v port!\n", addr)

	for {
		tcpConn, err := listener.Accept()
		if err != nil {
			fmt.Printf("Failed to accept incoming connection (%s)\n", err)
			continue
		}
		h := handler.New()
		config := h.MakeSSHConfig()
		_, chans, reqs, err := ssh.NewServerConn(tcpConn, config)
		//		sshConn, chans, reqs, err := ssh.NewServerConn(tcpConn, config)
		if err != nil {
			fmt.Printf("Failed to handshake (%s)\n", err.Error())
			continue
		}

		//		fmt.Sprintf("New SSH connection from %s (%s)", sshConn.RemoteAddr(), sshConn.ClientVersion())
		go ssh.DiscardRequests(reqs)
		go handleChannels(chans, &h)
	}
}
func (self *ServerMode) handleSSHRequest(connection *net.Conn, config *ssh.ServerConfig) {

	// TODO: Check if we need to close anything.

	// Before use, a handshake must be performed on the incoming net.Conn.
	_, channels, requests, err := ssh.NewServerConn(*connection, config)
	if err != nil {
		panic("failed to handshake")
	}

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

	// Service the incoming Channel channel.
	for newChannel := range channels {
		// 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)

		term := terminal.NewTerminal(channel, "> ")

		go func() {
			defer channel.Close()
			for {
				line, err := term.ReadLine()
				if err != nil {
					break
				}
				// TODO: Likely we need to interpret the incoming commands in here.
				fmt.Println("INPUT-SSH:" + line)
			}
		}()
	}
}
Exemple #11
0
func OpenStream(conn ssh.Conn, remote string) (io.ReadWriteCloser, error) {
	stream, reqs, err := conn.OpenChannel("chisel", []byte(remote))
	if err != nil {
		return nil, err
	}
	go ssh.DiscardRequests(reqs)
	return stream, nil
}
Exemple #12
0
func (t *tcpHandler) Execute(c context.Context) {
	select {
	case <-c.Done():
		t.conn.Close()
		return
	default:
	}

	// Create reaper
	g := grim.ReaperWithContext(c)
	defer g.Wait()

	// Convert to SSH connection
	sshConn, channels, requests, err := ssh.NewServerConn(t.conn, t.config)
	if err != nil {
		t.logger.Warn("SSH handshake failed:", "addr", t.conn.RemoteAddr().String(), "error", err)
		t.conn.Close()
		g.Kill()
		return
	}

	// Close connection on exit
	t.logger.Debug("Handshake successful")
	defer sshConn.Close()
	defer sshConn.Wait()

	// Discard all out-of-channel requests
	if t.requestHandler != nil {
		go t.requestHandler.Consume(requests)
	} else {
		go ssh.DiscardRequests(requests)
	}

OUTER:
	for {
		select {
		case <-c.Done():
			break OUTER
		case <-g.Dead():
			break OUTER
		case ch := <-channels:

			// Check if chan was closed
			if ch == nil {
				break OUTER
			}

			// Handle the channel
			g.SpawnFunc(func(ctx context.Context) {
				t.dispatcher.Dispatch(ctx, sshConn, ch)
				return
			})
		}
	}

	g.Kill()
}
Exemple #13
0
func main() {

	config := &ssh.ServerConfig{
		//Define a function to run when a client attempts a password login
		PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
			// Should use constant-time compare (or better, salt+hash) in a production setting.
			if c.User() == "vagrant" && string(pass) == "vagrant" {
				return nil, nil
			}
			return nil, fmt.Errorf("password rejected for %q", c.User())
		},
		// NoClientAuth: true,
	}

	// You can generate a keypair with 'ssh-keygen -t rsa'
	privateBytes, err := ioutil.ReadFile("gossh_rsa")
	if err != nil {
		log.Fatal("Failed to load private key (./gossh_rsa)")
	}

	private, err := ssh.ParsePrivateKey(privateBytes)
	if err != nil {
		log.Fatal("Failed to parse private key")
	}

	config.AddHostKey(private)

	// Once a ServerConfig has been configured, connections can be accepted.
	listener, err := net.Listen("tcp", "0.0.0.0:2200")
	if err != nil {
		log.Fatalf("Failed to listen on 2200 (%s)", err)
	}

	// Accept all connections
	log.Print("Listening on 2200...")
	for {
		tcpConn, err := listener.Accept()
		if err != nil {
			log.Printf("Failed to accept incoming connection (%s)", err)
			continue
		}
		// Before use, a handshake must be performed on the incoming net.Conn.
		sshConn, chans, reqs, err := ssh.NewServerConn(tcpConn, config)
		if err != nil {
			log.Printf("Failed to handshake (%s)", err)
			continue
		}

		log.Printf("New SSH connection from %s (%s)", sshConn.RemoteAddr(), sshConn.ClientVersion())
		// Discard all global out-of-band Requests
		go ssh.DiscardRequests(reqs)
		// Accept all channels
		go handleChannels(chans)
	}
}
Exemple #14
0
// ListenAndServe starts a SCP server.
func (s *Server) ListenAndServe() {
	if len(s.BindAddr) == 0 {
		panic("Must specify BindAddr")
	}
	if len(s.CertPath) == 0 {
		panic("Must specify CertPath")
	}

	privateBytes, err := ioutil.ReadFile(s.CertPath)
	if err != nil {
		panic("Failed to load private key")
	}

	private, err := ssh.ParsePrivateKey(privateBytes)
	if err != nil {
		panic("Failed to parse private key")
	}

	config := &ssh.ServerConfig{
		NoClientAuth: true,
	}

	config.AddHostKey(private)

	// Once a ServerConfig has been configured, connections can be
	// accepted.
	listener, err := net.Listen("tcp", s.BindAddr)
	if err != nil {
		s.Fatal("Failed to bind to address", "addr", bindAddr)
	}

	s.Info("Listening for SCP connections", "addr", bindAddr)

	for {
		nConn, err := listener.Accept()
		if err != nil {
			s.Error("Failed to listen for SCP connections", "err", err)
			continue
		}

		// Before use, a handshake must be performed on the incoming
		// net.Conn.
		_, chans, reqs, err := ssh.NewServerConn(nConn, config)
		if err != nil {
			s.Error("Failed to create SCP connection", "err", err)
			continue
		}

		// Discard all global out-of-band Requests
		go ssh.DiscardRequests(reqs)

		// Accept all channels
		go s.handleChannels(chans)
	}
}
Exemple #15
0
func main() {

	// In the latest version of crypto/ssh (after Go 1.3), the SSH server type has been removed
	// in favour of an SSH connection type. A ssh.ServerConn is created by passing an existing
	// net.Conn and a ssh.ServerConfig to ssh.NewServerConn, in effect, upgrading the net.Conn
	// into an ssh.ServerConn

	config := &ssh.ServerConfig{
		// You may also explicitly allow anonymous client authentication, though anon bash
		// sessions may not be a wise idea
		NoClientAuth: true,
	}

	// You can generate a keypair with 'ssh-keygen -t rsa'
	privateBytes, err := ioutil.ReadFile("id_rsa")
	if err != nil {
		log.Fatal("Failed to load private key (./id_rsa)")
	}

	private, err := ssh.ParsePrivateKey(privateBytes)
	if err != nil {
		log.Fatal("Failed to parse private key")
	}

	config.AddHostKey(private)

	// Once a ServerConfig has been configured, connections can be accepted.
	listener, err := net.Listen("tcp", "0.0.0.0:2200")
	if err != nil {
		log.Fatalf("Failed to listen on 2200 (%s)", err)
	}

	// Accept all connections
	log.Print("Listening on 2200...")
	for {
		tcpConn, err := listener.Accept()
		if err != nil {
			log.Printf("Failed to accept incoming connection (%s)", err)
			continue
		}
		// Before use, a handshake must be performed on the incoming net.Conn.
		sshConn, chans, reqs, err := ssh.NewServerConn(tcpConn, config)
		if err != nil {
			log.Printf("Failed to handshake (%s)", err)
			continue
		}

		log.Printf("New SSH connection from %s (%s)", sshConn.RemoteAddr(), sshConn.ClientVersion())
		// Discard all global out-of-band Requests
		go ssh.DiscardRequests(reqs)
		// Accept all channels
		go handleChannels(chans)
	}
}
Exemple #16
0
// StartSSHExecServer runs an ssh server that accepts a single connection and handles only "exec" requests.
// The handler callback is given the command string and stderr io.Writer.  The handler return
// value is propagated to the client via "exit-status".
func StartSSHExecServer(port *int, sh SessionHandler) (*sync.WaitGroup, error) {
	config := &ssh.ServerConfig{
		PublicKeyCallback: TestCertChecker.Authenticate,
		PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
			if c.User() == TestUser && string(pass) == TestPassword {
				return nil, nil
			}
			return nil, errors.New("unauthorized user")
		},
	}

	signer, err := ssh.ParsePrivateKey(testdata.PEMBytes["dsa"])
	if err != nil {
		panic(err)
	}
	config.AddHostKey(signer)

	listener, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", *port))
	if err != nil {
		panic(err)
	}
	*port = listener.Addr().(*net.TCPAddr).Port

	var wg sync.WaitGroup
	wg.Add(1)

	// service 1 request
	go func() {
		defer listener.Close()
		defer wg.Done()

		tcpConn, err := listener.Accept()
		if err != nil {
			log.Printf("Failed to accept incoming connection (%s)", err)
			return
		}
		// Before use, a handshake must be performed on the incoming net.Conn.
		sshConn, chans, reqs, err := ssh.NewServerConn(tcpConn, config)
		if err != nil {
			log.Printf("Failed to handshake (%s)", err)
			return
		}

		log.Printf("New SSH connection from %s (%s)", sshConn.RemoteAddr(), sshConn.ClientVersion())
		// Discard all global out-of-band Requests
		go ssh.DiscardRequests(reqs)
		// Accept all channels
		handleChannels(sshConn, chans, sh)

	}()

	return &wg, nil
}
Exemple #17
0
func (s *SSHServer) handleTCPConnection(parentTomb tomb.Tomb, conn net.Conn) error {

	// Convert to SSH connection
	sshConn, channels, requests, err := ssh.NewServerConn(conn, s.config.sshConfig)
	if err != nil {
		s.config.Logger.Warn("SSH handshake failed: %s", conn.RemoteAddr())
		return err
	}

	// Close connection on exit
	s.config.Logger.Debug("Handshake successful")
	defer sshConn.Conn.Close()

	// Discard requests
	go ssh.DiscardRequests(requests)

	// Create new tomb stone
	var t tomb.Tomb

	for {
		select {
		case ch := <-channels:
			chType := ch.ChannelType()

			// Determine if channel is acceptable (has a registered handler)
			handler, ok := s.config.Handler(chType)
			if !ok {
				s.config.Logger.Info("UnknownChannelType", "type", chType)
				ch.Reject(ssh.UnknownChannelType, chType)
				break
			}

			// Accept channel
			channel, requests, err := ch.Accept()
			if err != nil {
				s.config.Logger.Warn("Error creating channel")
				continue
			}

			t.Go(func() error {
				return handler.Handle(t, sshConn, channel, requests)
			})
		case <-parentTomb.Dying():
			t.Kill(nil)
			if err := t.Wait(); err != nil {
				s.config.Logger.Warn("ssh handler error: %s", err)
			}
			sshConn.Close()
			return sshConn.Wait()
		}
	}
	return nil
}
Exemple #18
0
func (server *SshServer) run(addr string) {
	config := &ssh.ServerConfig{
		PasswordCallback: func(_ ssh.ConnMetadata, pwd []byte) (*ssh.Permissions, error) {
			// it's just a demo, in a real server this should not be done :)
			if string(pwd) == "<3txt" {
				return nil, nil
			}
			return nil, errors.New("pwd error, please enter <3txt to enter")
		},
	}

	// You can generate a keypair with 'ssh-keygen -t rsa'
	privateBytes, err := ioutil.ReadFile(server.id_rsa)
	if err != nil {
		fmt.Printf("Failed to load private key %s\n", server.id_rsa)
		return
	}

	private, err := ssh.ParsePrivateKey(privateBytes)
	if err != nil {
		fmt.Println("Failed to parse private key")
		return
	}

	config.AddHostKey(private)

	listener, err := net.Listen("tcp", addr)
	if err != nil {
		fmt.Printf("Failed to listen on %s (%s)\n", addr, err)
		return
	}
	fmt.Printf("Listening on %s...", addr)

	for {
		tcpConn, err := listener.Accept()
		if err != nil {
			fmt.Printf("Failed to accept incoming connection (%s)\n", err)
			continue
		}

		sshConn, chans, reqs, err := ssh.NewServerConn(tcpConn, config)
		if err != nil {
			fmt.Printf("Failed to handshake (%s)\n", err)
			continue
		}

		fmt.Printf("New SSH connection from %s (%s)\n", sshConn.RemoteAddr(), sshConn.ClientVersion())

		go ssh.DiscardRequests(reqs)
		go server.handleChannels(sshConn.User(), chans)
	}
}
Exemple #19
0
func handler(conn net.Conn, gm *GameManager, config *ssh.ServerConfig) {
	// Before use, a handshake must be performed on the incoming
	// net.Conn.
	_, chans, reqs, err := ssh.NewServerConn(conn, config)
	if err != nil {
		fmt.Println("Failed to handshake with new client")
		return
	}
	// 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 {
			fmt.Println("could not accept channel.")
			return
		}

		// TODO: Remove this -- only temporary while we launch on HN
		//
		// To see how many concurrent users are online
		fmt.Printf("Player joined. Current stats: %d users, %d games\n",
			gm.SessionCount(), gm.GameCount())

		// Reject all out of band requests accept for the unix defaults, pty-req and
		// shell.
		go func(in <-chan *ssh.Request) {
			for req := range in {
				switch req.Type {
				case "pty-req":
					req.Reply(true, nil)
					continue
				case "shell":
					req.Reply(true, nil)
					continue
				}
				req.Reply(false, nil)
			}
		}(requests)

		gm.HandleChannel <- channel
	}
}
Exemple #20
0
// ChannelForward establishes a secure channel forward (ssh -W) to the server
// requested by the user, assuming it is a permitted host.
func (s *Server) ChannelForward(session *Session, newChannel ssh.NewChannel) {
	var msg channelOpenDirectMsg
	ssh.Unmarshal(newChannel.ExtraData(), &msg)
	address := fmt.Sprintf("%s:%d", msg.RAddr, msg.RPort)

	permitted := false
	for _, remote := range session.Remotes {
		if remote == address {
			permitted = true
			break
		}
	}

	if !permitted {
		log.Printf("Disallowed access to %s for user %s", address, session.User.Name)
		newChannel.Reject(ssh.Prohibited, "remote host access denied for user")
		return
	}

	// Log the selection
	if s.Selected != nil {
		if err := s.Selected(session, address); err != nil {
			newChannel.Reject(ssh.Prohibited, "access denied")
			return
		}
	}

	conn, err := net.Dial("tcp", address)
	if err != nil {
		newChannel.Reject(ssh.ConnectionFailed, fmt.Sprintf("error: %v", err))
		return
	}

	channel, reqs, err := newChannel.Accept()

	go ssh.DiscardRequests(reqs)
	var closer sync.Once
	closeFunc := func() {
		channel.Close()
		conn.Close()
	}

	go func() {
		io.Copy(channel, conn)
		closer.Do(closeFunc)
	}()

	go func() {
		io.Copy(conn, channel)
		closer.Do(closeFunc)
	}()
}
Exemple #21
0
// HandleConn takes a net.Conn and runs it through sshmux.
func (s *Server) HandleConn(c net.Conn) {
	sshConn, newChans, reqs, err := ssh.NewServerConn(c, s.sshConfig)
	if err != nil {
		c.Close()
		return
	}

	if sshConn.Permissions == nil || sshConn.Permissions.Extensions == nil {
		sshConn.Close()
		return
	}

	ext := sshConn.Permissions.Extensions
	pk := &publicKey{
		publicKey:     []byte(ext["pubKey"]),
		publicKeyType: ext["pubKeyType"],
	}

	user, err := s.Auther(sshConn, pk)

	session := &Session{
		Conn:      sshConn,
		User:      user,
		PublicKey: pk,
	}

	s.Setup(session)
	go ssh.DiscardRequests(reqs)

	go func() {
		defer sshConn.Close()
		var wg sync.WaitGroup
		for newChannel := range newChans {
			wg.Add(1)
			if newChannel.ChannelType() == "session" {
				go func() {
					defer wg.Done()
					s.SessionForward(session, newChannel, newChans)
				}()
				break
			} else {
				go func() {
					defer wg.Done()
					s.HandleNewChannel(session, newChannel)
				}()
			}
		}

		wg.Wait()
		log.Printf("Closing connection for: %s", session.User.Name)
	}()
}
Exemple #22
0
//AddOutBoundRequestManager simple handless a ssh.ServerConn  out-of-bounds request
func AddOutBoundRequestManager(s *SSHProtocol) {
	s.NetworkOutbounds.Subscribe(func(pack interface{}, sub *flux.Sub) {
		packet, ok := pack.(*RequestPacket)

		if !ok {
			log.Printf("Received invalid RequestPacket for ssh.NewChannel request: %+v %+v", packet, pack)
			return
		}

		// log.Printf("Discarding Out-Of-Bands Requests: %v", packet)
		ssh.DiscardRequests(packet.Reqs)
	})
}
Exemple #23
0
func service(conn net.Conn, config *ssh.ServerConfig) {
	_, chans, reqs, err := ssh.NewServerConn(conn, config)
	if err != nil {
		log.Println("could not complete handshake for", conn.RemoteAddr().String(), ":", err)
		return
	}

	go ssh.DiscardRequests(reqs)

	for newChannel := range chans {
		go handleChanReq(newChannel)
	}

	log.Println("finished servicing")
}
Exemple #24
0
func (l *SSHListener) handleConn(conn net.Conn) (*Terminal, error) {
	if l.RateLimit != nil {
		// TODO: Configurable Limiter?
		conn = ReadLimitConn(conn, l.RateLimit())
	}

	// Upgrade TCP connection to SSH connection
	sshConn, channels, requests, err := ssh.NewServerConn(conn, l.config)
	if err != nil {
		return nil, err
	}

	// FIXME: Disconnect if too many faulty requests? (Avoid DoS.)
	go ssh.DiscardRequests(requests)
	return NewSession(sshConn, channels)
}
Exemple #25
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, 0)
	conn.Close()
}
Exemple #26
0
func sshServer(p string) {
	log.Debugln("sshServer")

	config := &ssh.ServerConfig{
		PasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
			if conn.User() == "protonuke" && string(password) == "password" {
				return &ssh.Permissions{}, nil
			}

			return nil, errors.New("invalid user/password")
		},
	}

	private, err := ssh.ParsePrivateKey([]byte(id_rsa))
	if err != nil {
		log.Fatalln(err)
	}

	config.AddHostKey(private)

	// Once a ServerConfig has been configured, connections can be accepted.
	listener, err := net.Listen(p, PORT)
	if err != nil {
		log.Fatalln(err)
	}

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Errorln(err)
			continue
		}

		// Before use, a handshake must be performed on the incoming net.Conn.
		_, chans, reqs, err := ssh.NewServerConn(conn, config)
		if err != nil {
			log.Errorln(err)
			continue
		}

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

		go sshHandleChannels(conn, chans)
	}
}
Exemple #27
0
func handleConn(conn net.Conn, conf *ssh.ServerConfig) {
	defer conn.Close()
	sshConn, chans, reqs, err := ssh.NewServerConn(conn, conf)
	if err != nil {
		debug("handshake failed:", err)
		return
	}
	go ssh.DiscardRequests(reqs)
	for ch := range chans {
		if ch.ChannelType() != "session" {
			ch.Reject(ssh.UnknownChannelType, "unsupported channel type")
			debug("channel rejected, unsupported type:", ch.ChannelType())
			continue
		}
		go handleChannel(sshConn, ch)
	}
}
Exemple #28
0
func (s *Server) handleConn(conn net.Conn) {
	defer conn.Close()
	sshConn, chans, reqs, err := ssh.NewServerConn(conn, &s.SSH)
	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 s.handleChannel(sshConn, ch)
	}
}
Exemple #29
0
// HandleConn takes a net.Conn and runs it through sshmux.
func (s *Server) HandleConn(c net.Conn) {
	sshConn, chans, reqs, err := ssh.NewServerConn(c, s.sshConfig)
	if err != nil {
		c.Close()
		return
	}

	if sshConn.Permissions == nil || sshConn.Permissions.Extensions == nil {
		sshConn.Close()
		return
	}

	ext := sshConn.Permissions.Extensions
	pk := &publicKey{
		publicKey:     []byte(ext["pubKey"]),
		publicKeyType: ext["pubKeyType"],
	}

	user, err := s.Auther(sshConn, pk)

	session := &Session{
		Conn:      sshConn,
		User:      user,
		PublicKey: pk,
	}

	s.Setup(session)

	go ssh.DiscardRequests(reqs)
	newChannel := <-chans
	if newChannel == nil {
		sshConn.Close()
		return
	}

	switch newChannel.ChannelType() {
	case "session":
		s.SessionForward(session, newChannel, chans)
	case "direct-tcpip":
		s.ChannelForward(session, newChannel)
	default:
		newChannel.Reject(ssh.UnknownChannelType, "connection flow not supported by sshmux")
	}
}
Exemple #30
0
func serve() {
	config := &ssh.ServerConfig{
		PasswordCallback:  passwordCallback,
		PublicKeyCallback: pubkeyCallback,
	}
	priv_fname := util.AppBaseFileName() + ".privkey"
	log.Print("loading private key from " + priv_fname + " ...")
	priv_bytes, err := ioutil.ReadFile(priv_fname)
	if err != nil {
		log.Panicln("private key read error:", err)
	}
	log.Print("parsing private key...")
	private, err := ssh.ParsePrivateKey(priv_bytes)
	if err != nil {
		log.Panicln("private key parse error:", err)
	}
	log.Print("key fingerprint:", fingerprintKey(private.PublicKey()))
	log.Print("adding private key to host...")
	config.AddHostKey(private)

	log.Println("creating listener for", LISTEN_HOST_AND_PORT, " ...")
	listener, err := net.Listen("tcp", LISTEN_HOST_AND_PORT)
	log.Println("entering in the main service loop ...")
	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Println("Failed to accept incoming connection:", err)
			continue
		}
		log.Println("new connection accepted from", conn.RemoteAddr())
		log.Println("upgrading connection to ssh...")
		sshConn, chans, reqs, err := ssh.NewServerConn(conn, config)
		if err != nil {
			log.Println("handshake failed:", err)
			continue
		}
		log.Printf("New SSH connection from %s (%s)", sshConn.RemoteAddr(), sshConn.ClientVersion())
		go ssh.DiscardRequests(reqs)
		go handleChannels(chans)
	}

}