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 }
// addKey parses an SSH private key for execd. It takes in the SSH server configuration and the key to add. // It returns an error if the key is unsupported by execd. func addKey(conf *ssh.ServerConfig, block *pem.Block) (err error) { var key interface{} switch block.Type { case "RSA PRIVATE KEY": key, err = x509.ParsePKCS1PrivateKey(block.Bytes) case "EC PRIVATE KEY": key, err = x509.ParseECPrivateKey(block.Bytes) case "DSA PRIVATE KEY": key, err = ssh.ParseDSAPrivateKey(block.Bytes) default: return fmt.Errorf("unsupported key type %q", block.Type) } if err != nil { return err } signer, err := ssh.NewSignerFromKey(key) if err != nil { return err } conf.AddHostKey(signer) return nil }
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 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 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() }