Skip to content

Commit

Permalink
ssh: send (and rename) keyboard-interactive name field to the client
Browse files Browse the repository at this point in the history
The server side implementation was not actually populating the
SSH_MSG_USERAUTH_INFO_REQUEST field with the
KeyboardInteractiveChallenge argument, although the client side was
deserializing it and passing it to the KeyboardInteractiveChallenge
callback.

Anyway, the first field of SSH_MSG_USERAUTH_INFO_REQUEST is "name", not
"user". Maybe the confusion was due to the first field of
SSH_MSG_USERAUTH_REQUEST being the user.

RFC 4256, Section 3.3, says this about it

   One possibility is to use the name field (possibly
   prefixed with the application's name) as the title of a dialog window
   in which the prompt(s) are presented.

and examples include "CRYPTOCard Authentication", "Password
Authentication", and "Password Expired".

Co-authored-by: Kevin Wallace <kevin@pentabarf.net>
Change-Id: Ic6ec0dfea2122704603c44f42898a980689a15c9
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/372234
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
  • Loading branch information
FiloSottile and kevinwallace committed Mar 14, 2022
1 parent 1baeb1c commit a577426
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 9 deletions.
6 changes: 3 additions & 3 deletions ssh/client_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,10 @@ func handleBannerResponse(c packetConn, packet []byte) error {
// disabling echoing (e.g. for passwords), and return all the answers.
// Challenge may be called multiple times in a single session. After
// successful authentication, the server may send a challenge with no
// questions, for which the user and instruction messages should be
// questions, for which the name and instruction messages should be
// printed. RFC 4256 section 3.3 details how the UI should behave for
// both CLI and GUI environments.
type KeyboardInteractiveChallenge func(user, instruction string, questions []string, echos []bool) (answers []string, err error)
type KeyboardInteractiveChallenge func(name, instruction string, questions []string, echos []bool) (answers []string, err error)

// KeyboardInteractive returns an AuthMethod using a prompt/response
// sequence controlled by the server.
Expand Down Expand Up @@ -465,7 +465,7 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
return authFailure, nil, errors.New("ssh: extra data following keyboard-interactive pairs")
}

answers, err := cb(msg.User, msg.Instruction, prompts, echos)
answers, err := cb(msg.Name, msg.Instruction, prompts, echos)
if err != nil {
return authFailure, nil, err
}
Expand Down
10 changes: 5 additions & 5 deletions ssh/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,11 @@ const msgUserAuthInfoRequest = 60
const msgUserAuthInfoResponse = 61

type userAuthInfoRequestMsg struct {
User string `sshtype:"60"`
Instruction string
DeprecatedLanguage string
NumPrompts uint32
Prompts []byte `ssh:"rest"`
Name string `sshtype:"60"`
Instruction string
Language string
NumPrompts uint32
Prompts []byte `ssh:"rest"`
}

// See RFC 4254, section 5.1.
Expand Down
3 changes: 2 additions & 1 deletion ssh/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ type sshClientKeyboardInteractive struct {
*connection
}

func (c *sshClientKeyboardInteractive) Challenge(user, instruction string, questions []string, echos []bool) (answers []string, err error) {
func (c *sshClientKeyboardInteractive) Challenge(name, instruction string, questions []string, echos []bool) (answers []string, err error) {
if len(questions) != len(echos) {
return nil, errors.New("ssh: echos and questions must have equal length")
}
Expand All @@ -707,6 +707,7 @@ func (c *sshClientKeyboardInteractive) Challenge(user, instruction string, quest
}

if err := c.transport.writePacket(Marshal(&userAuthInfoRequestMsg{
Name: name,
Instruction: instruction,
NumPrompts: uint32(len(questions)),
Prompts: prompts,
Expand Down

0 comments on commit a577426

Please sign in to comment.