Skip to content

Commit

Permalink
pam: trigger pam_authenticate on login
Browse files Browse the repository at this point in the history
This will trigger any "auth" PAM modules configured on the system for
teleport. For example, Duo 2FA prompt on each connection.
The module will be able to interact with the user (e.g. print prompts).

Also, make PAM env var propagation consistent for port forwarding
sessions.

Fixes #3929
  • Loading branch information
Andrew Lytvynov committed Jul 8, 2020
1 parent 32a6dbb commit ce5088f
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 6 deletions.
13 changes: 13 additions & 0 deletions lib/pam/pam.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ func Open(config *Config) (*PAM, error) {
}
}

// Trigger the "account" PAM hooks for this login.
//
// Check that the *nix account is valid. Checking an account varies based off
// the PAM modules used in the account stack. Typically this consists of
// checking if the account is expired or has access restrictions.
Expand All @@ -309,6 +311,17 @@ func Open(config *Config) (*PAM, error) {
return nil, p.codeToError(retval)
}

// Trigger the "auth" PAM hooks for this login.
//
// These would perform any extra authentication steps configured in the PAM
// stack, like per-session 2FA.
retval = C._pam_authenticate(pamHandle, p.pamh, 0)
if retval != C.PAM_SUCCESS {
return nil, p.codeToError(retval)
}

// Trigger the "session" PAM hooks for this login.
//
// Open a user session. Opening a session varies based off the PAM modules
// used in the "session" stack. Opening a session typically consists of
// printing the MOTD, mounting a home directory, updating auth.log.
Expand Down
14 changes: 8 additions & 6 deletions lib/srv/reexec.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,19 +239,21 @@ func RunForward() (io.Writer, int, error) {
// else because PAM is sometimes used to create the local user used to
// launch the shell under.
if c.PAM {
// Set Teleport specific environment variables that PAM modules like
// pam_script.so can pick up to potentially customize the account/session.
os.Setenv("TELEPORT_USERNAME", c.Username)
os.Setenv("TELEPORT_LOGIN", c.Login)
os.Setenv("TELEPORT_ROLES", strings.Join(c.Roles, " "))

// Open the PAM context.
pamContext, err := pam.Open(&pam.Config{
ServiceName: c.ServiceName,
Login: c.Login,
Stdin: os.Stdin,
Stdout: ioutil.Discard,
Stderr: ioutil.Discard,
// Set Teleport specific environment variables that PAM modules
// like pam_script.so can pick up to potentially customize the
// account/session.
Env: map[string]string{
"TELEPORT_USERNAME": c.Username,
"TELEPORT_LOGIN": c.Login,
"TELEPORT_ROLES": strings.Join(c.Roles, " "),
},
})
if err != nil {
return errorWriter, teleport.RemoteCommandFailure, trace.Wrap(err)
Expand Down

0 comments on commit ce5088f

Please sign in to comment.