1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
package handlers
import (
"context"
"strings"
"github.com/mimecast/dtail/internal"
"github.com/mimecast/dtail/internal/config"
"github.com/mimecast/dtail/internal/io/dlog"
"github.com/mimecast/dtail/internal/io/line"
"github.com/mimecast/dtail/internal/lcontext"
"github.com/mimecast/dtail/internal/omode"
user "github.com/mimecast/dtail/internal/user/server"
)
// ServerHandler implements the Reader and Writer interfaces to handle
// the Bi-directional communication between SSH client and server.
// This handler implements the handler of the SSH server.
type ServerHandler struct {
baseHandler
catLimiter chan struct{}
tailLimiter chan struct{}
regex string
}
// NewServerHandler returns the server handler.
func NewServerHandler(user *user.User, catLimiter,
tailLimiter chan struct{}) *ServerHandler {
dlog.Server.Debug(user, "Creating new server handler")
h := ServerHandler{
baseHandler: baseHandler{
done: internal.NewDone(),
lines: make(chan *line.Line, 100),
serverMessages: make(chan string, 10),
maprMessages: make(chan string, 10),
ackCloseReceived: make(chan struct{}),
user: user,
},
catLimiter: catLimiter,
tailLimiter: tailLimiter,
regex: ".",
}
h.handleCommandCb = h.handleUserCommand
fqdn, err := config.Hostname()
if err != nil {
dlog.Server.FatalPanic(err)
}
s := strings.Split(fqdn, ".")
h.hostname = s[0]
return &h
}
func (h *ServerHandler) handleUserCommand(ctx context.Context, ltx lcontext.LContext,
argc int, args []string, commandName string) {
dlog.Server.Debug(h.user, "Handling user command", argc, args)
h.incrementActiveCommands()
commandFinished := func() {
if h.decrementActiveCommands() == 0 {
h.shutdown()
}
}
switch commandName {
case "grep", "cat":
command := newReadCommand(h, omode.CatClient)
go func() {
command.Start(ctx, ltx, argc, args, 1)
commandFinished()
}()
case "tail":
command := newReadCommand(h, omode.TailClient)
go func() {
command.Start(ctx, ltx, argc, args, 10)
commandFinished()
}()
case "map":
command, aggregate, err := newMapCommand(h, argc, args)
if err != nil {
h.sendln(h.serverMessages, err.Error())
dlog.Server.Error(h.user, err)
commandFinished()
return
}
h.aggregate = aggregate
go func() {
command.Start(ctx, h.maprMessages)
commandFinished()
}()
case ".ack":
h.handleAckCommand(argc, args)
commandFinished()
default:
h.sendln(h.serverMessages, dlog.Server.Error(h.user,
"Received unknown user command", commandName, argc, args))
commandFinished()
}
}
|