ssh: send (and rename) keyboard-interactive name field to the client

The server side implementation was not actually populating the
KeyboardInteractiveChallenge argument, although the client side was
deserializing it and passing it to the KeyboardInteractiveChallenge

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

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 <>
Change-Id: Ic6ec0dfea2122704603c44f42898a980689a15c9
Trust: Filippo Valsorda <>
Run-TryBot: Filippo Valsorda <>
Reviewed-by: Roland Shoemaker <>
TryBot-Result: Gopher Robot <>
diff --git a/ssh/client_auth.go b/ssh/client_auth.go
index c611aeb..affc01d 100644
--- a/ssh/client_auth.go
+++ b/ssh/client_auth.go
@@ -380,10 +380,10 @@
 // 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.
@@ -465,7 +465,7 @@
 			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
diff --git a/ssh/messages.go b/ssh/messages.go
index ac41a41..62f9330 100644
--- a/ssh/messages.go
+++ b/ssh/messages.go
@@ -180,11 +180,11 @@
 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.
diff --git a/ssh/server.go b/ssh/server.go
index d28e1ad..9bb714c 100644
--- a/ssh/server.go
+++ b/ssh/server.go
@@ -695,7 +695,7 @@
-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")
@@ -707,6 +707,7 @@
 	if err := c.transport.writePacket(Marshal(&userAuthInfoRequestMsg{
+		Name:        name,
 		Instruction: instruction,
 		NumPrompts:  uint32(len(questions)),
 		Prompts:     prompts,