mirror of
https://github.com/bytedream/docker4ssh.git
synced 2025-06-27 01:40:32 +02:00
Initial commit
This commit is contained in:
79
server/ssh/handle.go
Normal file
79
server/ssh/handle.go
Normal file
@ -0,0 +1,79 @@
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"docker4ssh/docker"
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
type RequestType string
|
||||
|
||||
const (
|
||||
RequestPtyReq RequestType = "pty-req"
|
||||
RequestWindowChange RequestType = "window-change"
|
||||
)
|
||||
|
||||
type PtyReqPayload struct {
|
||||
Term string
|
||||
|
||||
Width, Height uint32
|
||||
PixelWidth, PixelHeight uint32
|
||||
|
||||
Modes []byte
|
||||
}
|
||||
|
||||
func handleChannels(chans <-chan ssh.NewChannel, client *docker.Client, user *User) {
|
||||
for channel := range chans {
|
||||
go handleChannel(channel, client, user)
|
||||
}
|
||||
}
|
||||
|
||||
func handleChannel(channel ssh.NewChannel, client *docker.Client, user *User) {
|
||||
if t := channel.ChannelType(); t != "session" {
|
||||
channel.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t))
|
||||
return
|
||||
}
|
||||
|
||||
conn, requests, err := channel.Accept()
|
||||
if err != nil {
|
||||
zap.S().Warnf("Failed to accept channel for user %s", user.ID)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
user.Terminal.ReadWriter = conn
|
||||
|
||||
// handle all other request besides the normal user input.
|
||||
// currently, only 'pty-req' is implemented which determines a terminal size change
|
||||
go handleRequest(requests, user)
|
||||
|
||||
// this handles the actual user terminal connection.
|
||||
// blocks until the session has finished
|
||||
connection(client, user)
|
||||
|
||||
zap.S().Debugf("Session for user %s ended", user.ID)
|
||||
}
|
||||
|
||||
func handleRequest(requests <-chan *ssh.Request, user *User) {
|
||||
for request := range requests {
|
||||
switch RequestType(request.Type) {
|
||||
case RequestPtyReq:
|
||||
// this could spam the logs when the user resizes his window constantly
|
||||
// log()
|
||||
|
||||
var ptyReq PtyReqPayload
|
||||
ssh.Unmarshal(request.Payload, &ptyReq)
|
||||
|
||||
user.Terminal.Width = ptyReq.Width
|
||||
user.Terminal.Height = ptyReq.Height
|
||||
case RequestWindowChange:
|
||||
// prevent from logging
|
||||
default:
|
||||
zap.S().Debugf("New request from user %s - Type: %s, Want Reply: %t, Payload: '%s'", user.ID, request.Type, request.WantReply, request.Payload)
|
||||
}
|
||||
|
||||
if request.WantReply {
|
||||
request.Reply(true, nil)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user