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) } } }
func HandleIncomingSSHConn(nConn net.Conn, config *ssh.ServerConfig) { DoneCh := make(chan bool) go TimeoutConnection(DoneCh, nConn) _, chans, reqs, err := ssh.NewServerConn(nConn, config) if err == nil { DoneCh <- true } // Right now that we are out of annoying people land. defer nConn.Close() go HandleSSHrequests(reqs) for newChannel := range chans { if newChannel.ChannelType() != "session" { newChannel.Reject(ssh.UnknownChannelType, "unknown channel type") log.Printf("WARNING - Rejecting %s Because they asked for a chan type %s that I don't have", nConn.RemoteAddr().String(), newChannel.ChannelType()) continue } channel, requests, err := newChannel.Accept() if err != nil { log.Printf("WARNING - Was unable to Accept channel with %s", nConn.RemoteAddr().String()) return } go HandleSSHrequests(requests) go ServeDOSTerm(channel) } }
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 }
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 }
func newMockLineServer(t *testing.T) string { l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatalf("Unable to listen for connection: %s", err) } go func() { defer l.Close() c, err := l.Accept() if err != nil { t.Errorf("Unable to accept incoming connection: %s", err) } defer c.Close() conn, chans, _, err := ssh.NewServerConn(c, serverConfig) if err != nil { t.Logf("Handshaking error: %v", err) } t.Log("Accepted SSH connection") for newChannel := range chans { channel, _, err := newChannel.Accept() if err != nil { t.Errorf("Unable to accept channel.") } t.Log("Accepted channel") go func(channelType string) { defer channel.Close() conn.OpenChannel(channelType, nil) }(newChannel.ChannelType()) } conn.Close() }() return l.Addr().String() }
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() }
func HandleConnection(listener net.Listener) { for { nConn, err := listener.Accept() go func() { if err != nil { panic("failed to accept incoming connection") } // Before use, a handshake must be performed on the incoming // net.Conn. _, chans, _, err := ssh.NewServerConn(nConn, config) if err == io.EOF { return } if err != nil { logfile.Printf("Handshake error: %s", err) } for newChannel := range chans { channel, requests, err := newChannel.Accept() if err != nil { logfile.Println("[fatal] could not accept channel.") continue } var term *terminal.Terminal term = terminal.NewTerminal(channel, "") go HandleSshRequests(channel, requests, term) logfile.Println("[channelType]: " + newChannel.ChannelType()) //newChannel.Reject(ssh.ConnectionFailed, "") // Sessions have out-of-band requests such as "shell", // "pty-req" and "env". if newChannel.ChannelType() == "direct-tcpip" { http_request := make(map[string]string) HandleTcpReading(channel, term, http_request) go SaveHttpRequest(http_request) } else { go HandleTerminalReading(channel, term) } } }() } }
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) } }
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) } }
func TestAuth(t *testing.T) { a, b, err := netPipe() if err != nil { t.Fatalf("netPipe: %v", err) } defer a.Close() defer b.Close() agent, _, cleanup := startAgent(t) defer cleanup() if err := agent.Add(testPrivateKeys["rsa"], nil, "comment"); err != nil { t.Errorf("Add: %v", err) } serverConf := ssh.ServerConfig{} serverConf.AddHostKey(testSigners["rsa"]) serverConf.PublicKeyCallback = func(c ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { if bytes.Equal(key.Marshal(), testPublicKeys["rsa"].Marshal()) { return nil, nil } return nil, errors.New("pubkey rejected") } go func() { conn, _, _, err := ssh.NewServerConn(a, &serverConf) if err != nil { t.Fatalf("Server: %v", err) } conn.Close() }() conf := ssh.ClientConfig{} conf.Auth = append(conf.Auth, ssh.PublicKeysCallback(agent.Signers)) conn, _, _, err := ssh.NewClientConn(b, "", &conf) if err != nil { t.Fatalf("NewClientConn: %v", err) } conn.Close() }
func (s *sshServer) run(c *gc.C) { netconn, err := s.listener.Accept() c.Assert(err, gc.IsNil) defer func() { err = netconn.Close() c.Assert(err, gc.IsNil) }() conn, chans, reqs, err := cryptossh.NewServerConn(netconn, s.cfg) c.Assert(err, gc.IsNil) s.client = cryptossh.NewClient(conn, chans, reqs) var wg sync.WaitGroup defer wg.Wait() sessionChannels := s.client.HandleChannelOpen("session") c.Assert(sessionChannels, gc.NotNil) for newChannel := range sessionChannels { c.Assert(newChannel.ChannelType(), gc.Equals, "session") channel, reqs, err := newChannel.Accept() c.Assert(err, gc.IsNil) wg.Add(1) go func() { defer wg.Done() defer channel.Close() for req := range reqs { switch req.Type { case "exec": c.Assert(req.WantReply, jc.IsTrue) n := binary.BigEndian.Uint32(req.Payload[:4]) command := string(req.Payload[4 : n+4]) c.Assert(command, gc.Equals, testCommandFlat) req.Reply(true, nil) channel.Write([]byte("abc value\n")) _, err := channel.SendRequest("exit-status", false, cryptossh.Marshal(&struct{ n uint32 }{0})) c.Assert(err, gc.IsNil) return default: c.Fatalf("Unexpected request type: %v", req.Type) } } }() } }
func (srv *Server) serveConn(nConn net.Conn) { conn, chans, reqs, err := ssh.NewServerConn(nConn, srv.srvcfg) if err != nil { log.Error("failed to handshake: %s", err.Error()) srv.Failed(nConn.RemoteAddr()) return } defer conn.Close() remote := nConn.RemoteAddr() scs, err := srv.getConnInfo(remote) if err != nil { log.Error("%s", err.Error()) return } defer srv.closeConn(remote) err = scs.Serve(conn, chans, reqs) if err != nil { log.Error("%s", err.Error()) } return }
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) } }
func main() { println("starting ssh server...") err := envconfig.Process("wormhole", &appConfig) if err != nil { log.Fatal(err.Error()) } if appConfig.LocalSSHAddr == "" || appConfig.PrivateKeyPath == "" || appConfig.RemoteSSHAddr == "" || appConfig.RemoteForwardAddress == "" || appConfig.RemoteSSHUser == "" || appConfig.RemotePrivateKeyPath == "" { fmt.Println("Missing config") os.Exit(-1) } // An SSH server is represented by a ServerConfig, which holds // certificate details and handles authentication of ServerConns. config := &ssh.ServerConfig{ 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() == "testuser" && string(pass) == "" { return nil, nil } return nil, fmt.Errorf("password rejected for %q", c.User()) }, } privateBytes, err := ioutil.ReadFile(appConfig.PrivateKeyPath) if err != nil { panic("Failed to load private key") } private, err := ssh.ParsePrivateKey(privateBytes) if err != nil { panic("Failed to parse private key") } config.AddHostKey(private) // Once a ServerConfig has been configured, connections can be // accepted. listener, err := net.Listen("tcp", appConfig.LocalSSHAddr) if err != nil { panic("failed to listen for connection") } for { nConn, err := listener.Accept() if err != nil { panic("failed to accept incoming connection") } conn, chans, reqs, err := ssh.NewServerConn(nConn, config) if err != nil { panic("failed to handshake") } go processRequests(conn, reqs) for newChannel := range chans { 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.") } go func(in <-chan *ssh.Request) { for req := range in { ok := false switch req.Type { case "shell": ok = true if len(req.Payload) > 0 { ok = false } } req.Reply(ok, nil) } }(requests) term := terminal.NewTerminal(channel, "> ") go func() { defer channel.Close() for { _, err := term.ReadLine() if err != nil { break } } }() } } }