|
|
@ -98,7 +98,7 @@ type sshInterceptingServer struct { |
|
|
|
config *ssh.ServerConfig |
|
|
|
netConn net.Conn |
|
|
|
root string |
|
|
|
recorder io.WriteCloser |
|
|
|
recorder io.Writer |
|
|
|
} |
|
|
|
|
|
|
|
func newSSHInterceptingServer(root string) *sshInterceptingServer { |
|
|
@ -156,10 +156,10 @@ func (server *sshInterceptingServer) ProxyClient(client *sshClient) { |
|
|
|
}) |
|
|
|
|
|
|
|
transcript := newSafeFileWriter(filepath.Join(server.root, hex.EncodeToString(client.SessionID()))+".ttyrec", 0600) |
|
|
|
server.recorder = writeCloser{ |
|
|
|
Writer: ttyrec.NewEncoder(transcript), |
|
|
|
Closer: transcript, |
|
|
|
} |
|
|
|
server.recorder = ttyrec.NewEncoder(transcript) |
|
|
|
defer func() { |
|
|
|
_ = transcript.Close() |
|
|
|
}() |
|
|
|
|
|
|
|
for { |
|
|
|
select { |
|
|
@ -209,8 +209,12 @@ func (server *sshInterceptingServer) ProxyClient(client *sshClient) { |
|
|
|
func (server *sshInterceptingServer) multiplexNewChannel(log *logrus.Entry, conn ssh.Conn, newChannel ssh.NewChannel) { |
|
|
|
log.Debug("new channel") |
|
|
|
|
|
|
|
clientChannel, clientRequests, err := conn.OpenChannel(newChannel.ChannelType(), newChannel.ExtraData()) |
|
|
|
if err != nil { |
|
|
|
var ( |
|
|
|
clientChannel, serverChannel ssh.Channel |
|
|
|
clientRequests, serverRequests <-chan *ssh.Request |
|
|
|
err error |
|
|
|
) |
|
|
|
if clientChannel, clientRequests, err = conn.OpenChannel(newChannel.ChannelType(), newChannel.ExtraData()); err != nil { |
|
|
|
log.WithError(err).Warn("failed to open channel") |
|
|
|
if err, ok := err.(*ssh.OpenChannelError); ok { |
|
|
|
_ = newChannel.Reject(err.Reason, err.Message) |
|
|
@ -220,8 +224,7 @@ func (server *sshInterceptingServer) multiplexNewChannel(log *logrus.Entry, conn |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
serverChannel, serverRequests, err := newChannel.Accept() |
|
|
|
if err != nil { |
|
|
|
if serverChannel, serverRequests, err = newChannel.Accept(); err != nil { |
|
|
|
log.WithError(err).Warn("failed to accept channel") |
|
|
|
go ssh.DiscardRequests(clientRequests) |
|
|
|
_ = clientChannel.Close() |
|
|
@ -232,27 +235,24 @@ func (server *sshInterceptingServer) multiplexNewChannel(log *logrus.Entry, conn |
|
|
|
} |
|
|
|
|
|
|
|
func (server *sshInterceptingServer) multiplex(log *logrus.Entry, channelType string, clientChannel, serverChannel ssh.Channel, clientRequests, serverRequests <-chan *ssh.Request) { |
|
|
|
var serverWriter io.Writer |
|
|
|
var serverWriters io.Writer |
|
|
|
switch channelType { |
|
|
|
case "session": |
|
|
|
serverWriter = io.MultiWriter(serverChannel, server.recorder) |
|
|
|
serverWriters = io.MultiWriter(serverChannel, server.recorder) |
|
|
|
default: |
|
|
|
serverWriter = serverChannel |
|
|
|
serverWriters = serverChannel |
|
|
|
} |
|
|
|
|
|
|
|
go func() { |
|
|
|
_, _ = io.Copy(clientChannel, serverChannel) |
|
|
|
}() |
|
|
|
go func() { |
|
|
|
_, _ = io.Copy(serverWriter, clientChannel) |
|
|
|
_, _ = io.Copy(serverWriters, clientChannel) |
|
|
|
}() |
|
|
|
|
|
|
|
defer func() { |
|
|
|
_ = clientChannel.Close() |
|
|
|
_ = serverChannel.Close() |
|
|
|
if server.recorder != nil { |
|
|
|
_ = server.recorder.Close() |
|
|
|
} |
|
|
|
}() |
|
|
|
|
|
|
|
for { |
|
|
|