grim/hgkeeper

closing merged branch
styling
2019-04-18, Gary Kramlich
110f88f716e7
closing merged branch
package ssh
import (
"fmt"
"net"
log "github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh"
)
type Server struct {
cfg *ssh.ServerConfig
listener net.Listener
}
func NewServer() *Server {
s := &Server{}
s.cfg = &ssh.ServerConfig{
MaxAuthTries: 1,
PublicKeyCallback: s.publicKeyCallback,
}
return s
}
func (s *Server) Listen(addr string) error {
listener, err := net.Listen("tcp", addr)
if err != nil {
return err
}
s.listener = listener
log.Infof("listening for ssh connections on %s", addr)
for {
tcpConn, err := s.listener.Accept()
if err != nil {
log.Errorf("failed to accept ssh connection: %v", err)
continue
}
sshConn, chans, reqs, err := ssh.NewServerConn(tcpConn, s.cfg)
if err != nil {
log.Errorf("ssh handshake failed: %v", err)
continue
}
log.Infof("new ssh connection from %s(%s)", sshConn.RemoteAddr(), sshConn.ClientVersion())
go ssh.DiscardRequests(reqs)
go s.processSSHChannels(chans)
}
}
func (s *Server) publicKeyCallback(meta ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
return nil, nil
}
func (s *Server) processSSHChannels(chans <-chan ssh.NewChannel) {
for ch := range chans {
// we process each channel in a go routine as there's network traffic involved
go s.processSSHChannel(ch)
}
}
func (s *Server) processSSHChannel(ch ssh.NewChannel) {
if t := ch.ChannelType(); t != "session" {
ch.Reject(ssh.UnknownChannelType, fmt.Sprintf("unsupported channel type %s", t))
return
}
conn, requests, err := ch.Accept()
if err != nil {
log.Warnf("failed to accept connection: %v", err)
return
}
defer conn.Close()
// now run through all of the requests but only handle shell requests
go func() {
for req := range requests {
switch req.Type {
case "shell":
log.Infof("payload: %s", string(req.Payload))
req.Reply(true, nil)
default:
log.Warnf("unsupported request: %s", req.Type)
if req.WantReply {
req.Reply(false, nil)
}
}
}
}()
}