Skip to content

Commit

Permalink
Set permissions on TTY.
Browse files Browse the repository at this point in the history
  • Loading branch information
russjones committed Jan 18, 2019
1 parent 44269af commit d915180
Showing 1 changed file with 71 additions and 9 deletions.
80 changes: 71 additions & 9 deletions lib/srv/term.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"io"
"os"
"os/exec"
"os/user"
"strconv"
"sync"
"syscall"

Expand Down Expand Up @@ -118,19 +120,30 @@ type terminal struct {

// NewLocalTerminal creates and returns a local PTY.
func newLocalTerminal(ctx *ServerContext) (*terminal, error) {
pty, tty, err := pty.Open()
if err != nil {
log.Warnf("Could not start PTY %v", err)
return nil, err
}
return &terminal{
var err error

t := &terminal{
log: log.WithFields(log.Fields{
trace.Component: teleport.ComponentLocalTerm,
}),
ctx: ctx,
pty: pty,
tty: tty,
}, nil
}

// Open PTY and corresponding TTY.
t.pty, t.tty, err = pty.Open()
if err != nil {
log.Warnf("Could not start PTY %v", err)
return nil, err
}

// Set the TTY owner. Failure is not fatal, for example Teleport is running
// on a read-only filesystem, but logging is useful for diagnostic purposes.
err = t.setOwner()
if err != nil {
log.Debugf("Unable to set TTY owner: %v.\n", err)
}

return t, nil
}

// AddParty adds another participant to this terminal. We will keep the
Expand Down Expand Up @@ -294,6 +307,55 @@ func (t *terminal) SetTerminalModes(termModes ssh.TerminalModes) {
return
}

// setOwner sets the owner and mode of the TTY similar to OpenSSH:
// https://github.com/openssh/openssh-portable/blob/ddc0f38/sshpty.c#L164-L215
func (t *terminal) setOwner() error {
var err error
var uid int
var gid int
var mode os.FileMode

// Lookup the Unix login for the UID and fallback GID.
u, err := user.Lookup(t.ctx.Identity.Login)
if err != nil {
return trace.Wrap(err)
}
uid, err = strconv.Atoi(u.Uid)
if err != nil {
return trace.Wrap(err)
}

// If the tty group exists, use that as the gid of the TTY and set mode to
// be u+rw. Otherwise use the group of the user with mode u+rw g+w.
group, err := user.LookupGroup("tty")
if err != nil {
gid, err = strconv.Atoi(u.Gid)
if err != nil {
return trace.Wrap(err)
}
mode = 0620
} else {
gid, err = strconv.Atoi(group.Gid)
if err != nil {
return trace.Wrap(err)
}
mode = 0600
}

err = os.Chown(t.tty.Name(), uid, gid)
if err != nil {
return trace.Wrap(err)
}
err = os.Chmod(t.tty.Name(), mode)
if err != nil {
return trace.Wrap(err)
}

log.Debugf("Set permissions on %v to %v:%v with mode %v.", t.tty.Name(), uid, gid, mode)

return nil
}

type remoteTerminal struct {
wg sync.WaitGroup
mu sync.Mutex
Expand Down

0 comments on commit d915180

Please sign in to comment.