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()) }
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() }
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() }
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 }
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) } }
// 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() }
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) }
// 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) } }() } }
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 }
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() }
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) } }
// 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) } }
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) } }
// 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 }
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 }
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) } }
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 } }
// 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) }() }
// 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) }() }
//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) }) }
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") }
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) }
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() }
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) } }
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) } }
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) } }
// 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") } }
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) } }