Skip to content

Commit

Permalink
Added support for reexec during port forwarding.
Browse files Browse the repository at this point in the history
Added support for reexec during port forwarding. This allows Teleport
nodes to run PAM code before port forwarding requests. This makes any
memory leaks in PAM code less dangerous as well as bringing port
forwarding logic in-line with execution requests (exec or shell).
  • Loading branch information
russjones committed Feb 13, 2020
1 parent b5db717 commit 94c2fd2
Show file tree
Hide file tree
Showing 12 changed files with 724 additions and 490 deletions.
15 changes: 14 additions & 1 deletion constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,21 @@ const (
)

const (
// ExecSubCommand is the sub-command Teleport uses to re-exec itself.
// ExecSubCommand is the sub-command Teleport uses to re-exec itself for
// command execution (exec and shells).
ExecSubCommand = "exec"

// ForwardSubCommand is the sub-command Teleport uses to re-exec itself
// for port forwarding.
ForwardSubCommand = "forward"
)

const (
// ChanDirectTCPIP is a SSH channel of type "direct-tcpip".
ChanDirectTCPIP = "direct-tcpip"

// ChanSession is a SSH channel of type "session".
ChanSession = "session"
)

// RSAKeySize is the size of the RSA key.
Expand Down
5 changes: 3 additions & 2 deletions integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ var _ = check.Suite(&IntSuite{})
func TestMain(m *testing.M) {
// If the test is re-executing itself, execute the command that comes over
// the pipe.
if len(os.Args) == 2 && os.Args[1] == teleport.ExecSubCommand {
srv.RunAndExit()
if len(os.Args) == 2 &&
(os.Args[1] == teleport.ExecSubCommand || os.Args[1] == teleport.ForwardSubCommand) {
srv.RunAndExit(os.Args[1])
return
}

Expand Down
36 changes: 33 additions & 3 deletions lib/srv/ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,20 @@ type ServerContext struct {
// to the child process.
contr *os.File
contw *os.File

// ChannelType holds the type of the channel. For example "session" or
// "direct-tcpip". Used to create correct subcommand during re-exec.
ChannelType string

// SrcAddr is the source address of the request. This the originator IP
// address and port in a SSH "direct-tcpip" request. This value is only
// populated for port forwarding requests.
SrcAddr string

// DstAddr is the destination address of the request. This is the host and
// port to connect to in a "direct-tcpip" request. This value is only
// populated for port forwarding requests.
DstAddr string
}

// NewServerContext creates a new *ServerContext which is used to pass and
Expand Down Expand Up @@ -652,14 +666,30 @@ func (c *ServerContext) ExecCommand() (*execCommand, error) {
roleNames = c.Identity.RoleSet.RoleNames()
}

// Extract the command to be executed. This only exists if command execution
// (exec or shell) is being requested, port forwarding has no command to
// execute.
var command string
if c.ExecRequest != nil {
command = c.ExecRequest.GetCommand()
}

// Extract the request type. This only exists for command execution (exec
// or shell), port forwarding requests have no request type.
var requestType string
if c.request != nil {
requestType = c.request.Type
}

// Create the execCommand that will be sent to the child process.
return &execCommand{
Command: c.ExecRequest.GetCommand(),
Command: command,
DestinationAddress: c.DstAddr,
Username: c.Identity.TeleportUser,
Login: c.Identity.Login,
Roles: roleNames,
Terminal: c.termAllocated || c.ExecRequest.GetCommand() == "",
RequestType: c.request.Type,
Terminal: c.termAllocated || command == "",
RequestType: requestType,
PermitUserEnvironment: c.srv.PermitUserEnvironment(),
Environment: buildEnvironment(c),
PAM: pamEnabled,
Expand Down
Loading

0 comments on commit 94c2fd2

Please sign in to comment.