mirror of
https://github.com/shazow/ssh-chat.git
synced 2025-04-14 16:17:17 +03:00
95 lines
1.6 KiB
Go
95 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"golang.org/x/crypto/ssh"
|
|
"golang.org/x/crypto/ssh/terminal"
|
|
)
|
|
|
|
const MSG_BUFFER = 10
|
|
|
|
type Client struct {
|
|
Server *Server
|
|
Msg chan string
|
|
Name string
|
|
}
|
|
|
|
func NewClient(server *Server, name string) *Client {
|
|
if name == "" {
|
|
name = "Anonymoose"
|
|
}
|
|
|
|
return &Client{
|
|
Server: server,
|
|
Name: name,
|
|
Msg: make(chan string, MSG_BUFFER),
|
|
}
|
|
}
|
|
|
|
func (c *Client) handleShell(channel ssh.Channel) {
|
|
defer channel.Close()
|
|
|
|
prompt := fmt.Sprintf("%s> ", c.Name)
|
|
term := terminal.NewTerminal(channel, prompt)
|
|
|
|
go func() {
|
|
for msg := range c.Msg {
|
|
term.Write([]byte(msg))
|
|
}
|
|
}()
|
|
|
|
for {
|
|
line, err := term.ReadLine()
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
switch line {
|
|
case "/exit":
|
|
channel.Close()
|
|
}
|
|
|
|
term.Write(term.Escape.Reset)
|
|
msg := fmt.Sprintf("%s: %s\r\n", c.Name, line)
|
|
c.Server.Broadcast(msg, c)
|
|
}
|
|
}
|
|
|
|
func (c *Client) handleChannels(channels <-chan ssh.NewChannel) {
|
|
for ch := range channels {
|
|
if t := ch.ChannelType(); t != "session" {
|
|
ch.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t))
|
|
continue
|
|
}
|
|
|
|
channel, requests, err := ch.Accept()
|
|
if err != nil {
|
|
logger.Errorf("Could not accept channel: %v", err)
|
|
continue
|
|
}
|
|
|
|
go func(in <-chan *ssh.Request) {
|
|
defer channel.Close()
|
|
for req := range in {
|
|
ok := false
|
|
switch req.Type {
|
|
case "shell":
|
|
if len(req.Payload) == 0 {
|
|
ok = true
|
|
}
|
|
case "pty-req":
|
|
// Setup PTY
|
|
ok = true
|
|
}
|
|
req.Reply(ok, nil)
|
|
}
|
|
}(requests)
|
|
|
|
go c.handleShell(channel)
|
|
|
|
// We don't care about other channels?
|
|
return
|
|
}
|
|
}
|