// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ssh

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"slices"
	"strings"
)

type authResult int

const (
	authFailure authResult = iota
	authPartialSuccess
	authSuccess
)

// clientAuthenticate authenticates with the remote server. See RFC 4252.
func (c *connection) clientAuthenticate(config *ClientConfig) error {
	// initiate user auth session
	if err := c.transport.writePacket(Marshal(&serviceRequestMsg{serviceUserAuth})); err != nil {
		return err
	}
	packet, err := c.transport.readPacket()
	if err != nil {
		return err
	}
	// The server may choose to send a SSH_MSG_EXT_INFO at this point (if we
	// advertised willingness to receive one, which we always do) or not. See
	// RFC 8308, Section 2.4.
	extensions := make(map[string][]byte)
	if len(packet) > 0 && packet[0] == msgExtInfo {
		var extInfo extInfoMsg
		if err := Unmarshal(packet, &extInfo); err != nil {
			return err
		}
		payload := extInfo.Payload
		for i := uint32(0); i < extInfo.NumExtensions; i++ {
			name, rest, ok := parseString(payload)
			if !ok {
				return parseError(msgExtInfo)
			}
			value, rest, ok := parseString(rest)
			if !ok {
				return parseError(msgExtInfo)
			}
			extensions[string(name)] = value
			payload = rest
		}
		packet, err = c.transport.readPacket()
		if err != nil {
			return err
		}
	}
	var serviceAccept serviceAcceptMsg
	if err := Unmarshal(packet, &serviceAccept); err != nil {
		return err
	}

	// during the authentication phase the client first attempts the "none" method
	// then any untried methods suggested by the server.
	var tried []string
	var lastMethods []string

	sessionID := c.transport.getSessionID()
	for auth := AuthMethod(new(noneAuth)); auth != nil; {
		ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand, extensions)
		if err != nil {
			// On disconnect, return error immediately
			if _, ok := err.(*disconnectMsg); ok {
				return err
			}
			// We return the error later if there is no other method left to
			// try.
			ok = authFailure
		}
		if ok == authSuccess {
			// success
			return nil
		} else if ok == authFailure {
			if m := auth.method(); !slices.Contains(tried, m) {
				tried = append(tried, m)
			}
		}
		if methods == nil {
			methods = lastMethods
		}
		lastMethods = methods

		auth = nil

	findNext:
		for _, a := range config.Auth {
			candidateMethod := a.method()
			if slices.Contains(tried, candidateMethod) {
				continue
			}
			for _, meth := range methods {
				if meth == candidateMethod {
					auth = a
					break findNext
				}
			}
		}

		if auth == nil && err != nil {
			// We have an error and there are no other authentication methods to
			// try, so we return it.
			return err
		}
	}
	return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", tried)
}

// An AuthMethod represents an instance of an RFC 4252 authentication method.
type AuthMethod interface {
	// auth authenticates user over transport t.
	// Returns true if authentication is successful.
	// If authentication is not successful, a []string of alternative
	// method names is returned. If the slice is nil, it will be ignored
	// and the previous set of possible methods will be reused.
	auth(session []byte, user string, p packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error)

	// method returns the RFC 4252 method name.
	method() string
}

// "none" authentication, RFC 4252 section 5.2.
type noneAuth int

func (n *noneAuth) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
	if err := c.writePacket(Marshal(&userAuthRequestMsg{
		User:    user,
		Service: serviceSSH,
		Method:  "none",
	})); err != nil {
		return authFailure, nil, err
	}

	return handleAuthResponse(c)
}

func (n *noneAuth) method() string {
	return "none"
}

// passwordCallback is an AuthMethod that fetches the password through
// a function call, e.g. by prompting the user.
type passwordCallback func() (password string, err error)

func (cb passwordCallback) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
	type passwordAuthMsg struct {
		User     string `sshtype:"50"`
		Service  string
		Method   string
		Reply    bool
		Password string
	}

	pw, err := cb()
	// REVIEW NOTE: is there a need to support skipping a password attempt?
	// The program may only find out that the user doesn't have a password
	// when prompting.
	if err != nil {
		return authFailure, nil, err
	}

	if err := c.writePacket(Marshal(&passwordAuthMsg{
		User:     user,
		Service:  serviceSSH,
		Method:   cb.method(),
		Reply:    false,
		Password: pw,
	})); err != nil {
		return authFailure, nil, err
	}

	return handleAuthResponse(c)
}

func (cb passwordCallback) method() string {
	return "password"
}

// Password returns an AuthMethod using the given password.
func Password(secret string) AuthMethod {
	return passwordCallback(func() (string, error) { return secret, nil })
}

// PasswordCallback returns an AuthMethod that uses a callback for
// fetching a password.
func PasswordCallback(prompt func() (secret string, err error)) AuthMethod {
	return passwordCallback(prompt)
}

type publickeyAuthMsg struct {
	User    string `sshtype:"50"`
	Service string
	Method  string
	// HasSig indicates to the receiver packet that the auth request is signed and
	// should be used for authentication of the request.
	HasSig   bool
	Algoname string
	PubKey   []byte
	// Sig is tagged with "rest" so Marshal will exclude it during
	// validateKey
	Sig []byte `ssh:"rest"`
}

// publicKeyCallback is an AuthMethod that uses a set of key
// pairs for authentication.
type publicKeyCallback func() ([]Signer, error)

func (cb publicKeyCallback) method() string {
	return "publickey"
}

func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiAlgorithmSigner, string, error) {
	var as MultiAlgorithmSigner
	keyFormat := signer.PublicKey().Type()

	// If the signer implements MultiAlgorithmSigner we use the algorithms it
	// support, if it implements AlgorithmSigner we assume it supports all
	// algorithms, otherwise only the key format one.
	switch s := signer.(type) {
	case MultiAlgorithmSigner:
		as = s
	case AlgorithmSigner:
		as = &multiAlgorithmSigner{
			AlgorithmSigner:     s,
			supportedAlgorithms: algorithmsForKeyFormat(underlyingAlgo(keyFormat)),
		}
	default:
		as = &multiAlgorithmSigner{
			AlgorithmSigner:     algorithmSignerWrapper{signer},
			supportedAlgorithms: []string{underlyingAlgo(keyFormat)},
		}
	}

	getFallbackAlgo := func() (string, error) {
		// Fallback to use if there is no "server-sig-algs" extension or a
		// common algorithm cannot be found. We use the public key format if the
		// MultiAlgorithmSigner supports it, otherwise we return an error.
		if !slices.Contains(as.Algorithms(), underlyingAlgo(keyFormat)) {
			return "", fmt.Errorf("ssh: no common public key signature algorithm, server only supports %q for key type %q, signer only supports %v",
				underlyingAlgo(keyFormat), keyFormat, as.Algorithms())
		}
		return keyFormat, nil
	}

	extPayload, ok := extensions["server-sig-algs"]
	if !ok {
		// If there is no "server-sig-algs" extension use the fallback
		// algorithm.
		algo, err := getFallbackAlgo()
		return as, algo, err
	}

	// The server-sig-algs extension only carries underlying signature
	// algorithm, but we are trying to select a protocol-level public key
	// algorithm, which might be a certificate type. Extend the list of server
	// supported algorithms to include the corresponding certificate algorithms.
	serverAlgos := strings.Split(string(extPayload), ",")
	for _, algo := range serverAlgos {
		if certAlgo, ok := certificateAlgo(algo); ok {
			serverAlgos = append(serverAlgos, certAlgo)
		}
	}

	// Filter algorithms based on those supported by MultiAlgorithmSigner.
	var keyAlgos []string
	for _, algo := range algorithmsForKeyFormat(keyFormat) {
		if slices.Contains(as.Algorithms(), underlyingAlgo(algo)) {
			keyAlgos = append(keyAlgos, algo)
		}
	}

	algo, err := findCommon("public key signature algorithm", keyAlgos, serverAlgos, true)
	if err != nil {
		// If there is no overlap, return the fallback algorithm to support
		// servers that fail to list all supported algorithms.
		algo, err := getFallbackAlgo()
		return as, algo, err
	}
	return as, algo, nil
}

func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error) {
	// Authentication is performed by sending an enquiry to test if a key is
	// acceptable to the remote. If the key is acceptable, the client will
	// attempt to authenticate with the valid key.  If not the client will repeat
	// the process with the remaining keys.

	signers, err := cb()
	if err != nil {
		return authFailure, nil, err
	}
	var methods []string
	var errSigAlgo error

	origSignersLen := len(signers)
	for idx := 0; idx < len(signers); idx++ {
		signer := signers[idx]
		pub := signer.PublicKey()
		as, algo, err := pickSignatureAlgorithm(signer, extensions)
		if err != nil && errSigAlgo == nil {
			// If we cannot negotiate a signature algorithm store the first
			// error so we can return it to provide a more meaningful message if
			// no other signers work.
			errSigAlgo = err
			continue
		}
		ok, err := validateKey(pub, algo, user, c)
		if err != nil {
			return authFailure, nil, err
		}
		// OpenSSH 7.2-7.7 advertises support for rsa-sha2-256 and rsa-sha2-512
		// in the "server-sig-algs" extension but doesn't support these
		// algorithms for certificate authentication, so if the server rejects
		// the key try to use the obtained algorithm as if "server-sig-algs" had
		// not been implemented if supported from the algorithm signer.
		if !ok && idx < origSignersLen && isRSACert(algo) && algo != CertAlgoRSAv01 {
			if slices.Contains(as.Algorithms(), KeyAlgoRSA) {
				// We retry using the compat algorithm after all signers have
				// been tried normally.
				signers = append(signers, &multiAlgorithmSigner{
					AlgorithmSigner:     as,
					supportedAlgorithms: []string{KeyAlgoRSA},
				})
			}
		}
		if !ok {
			continue
		}

		pubKey := pub.Marshal()
		data := buildDataSignedForAuth(session, userAuthRequestMsg{
			User:    user,
			Service: serviceSSH,
			Method:  cb.method(),
		}, algo, pubKey)
		sign, err := as.SignWithAlgorithm(rand, data, underlyingAlgo(algo))
		if err != nil {
			return authFailure, nil, err
		}

		// manually wrap the serialized signature in a string
		s := Marshal(sign)
		sig := make([]byte, stringLength(len(s)))
		marshalString(sig, s)
		msg := publickeyAuthMsg{
			User:     user,
			Service:  serviceSSH,
			Method:   cb.method(),
			HasSig:   true,
			Algoname: algo,
			PubKey:   pubKey,
			Sig:      sig,
		}
		p := Marshal(&msg)
		if err := c.writePacket(p); err != nil {
			return authFailure, nil, err
		}
		var success authResult
		success, methods, err = handleAuthResponse(c)
		if err != nil {
			return authFailure, nil, err
		}

		// If authentication succeeds or the list of available methods does not
		// contain the "publickey" method, do not attempt to authenticate with any
		// other keys.  According to RFC 4252 Section 7, the latter can occur when
		// additional authentication methods are required.
		if success == authSuccess || !slices.Contains(methods, cb.method()) {
			return success, methods, err
		}
	}

	return authFailure, methods, errSigAlgo
}

// validateKey validates the key provided is acceptable to the server.
func validateKey(key PublicKey, algo string, user string, c packetConn) (bool, error) {
	pubKey := key.Marshal()
	msg := publickeyAuthMsg{
		User:     user,
		Service:  serviceSSH,
		Method:   "publickey",
		HasSig:   false,
		Algoname: algo,
		PubKey:   pubKey,
	}
	if err := c.writePacket(Marshal(&msg)); err != nil {
		return false, err
	}

	return confirmKeyAck(key, c)
}

func confirmKeyAck(key PublicKey, c packetConn) (bool, error) {
	pubKey := key.Marshal()

	for {
		packet, err := c.readPacket()
		if err != nil {
			return false, err
		}
		switch packet[0] {
		case msgUserAuthBanner:
			if err := handleBannerResponse(c, packet); err != nil {
				return false, err
			}
		case msgUserAuthPubKeyOk:
			var msg userAuthPubKeyOkMsg
			if err := Unmarshal(packet, &msg); err != nil {
				return false, err
			}
			// According to RFC 4252 Section 7 the algorithm in
			// SSH_MSG_USERAUTH_PK_OK should match that of the request but some
			// servers send the key type instead. OpenSSH allows any algorithm
			// that matches the public key, so we do the same.
			// https://github.com/openssh/openssh-portable/blob/86bdd385/sshconnect2.c#L709
			if !slices.Contains(algorithmsForKeyFormat(key.Type()), msg.Algo) {
				return false, nil
			}
			if !bytes.Equal(msg.PubKey, pubKey) {
				return false, nil
			}
			return true, nil
		case msgUserAuthFailure:
			return false, nil
		default:
			return false, unexpectedMessageError(msgUserAuthPubKeyOk, packet[0])
		}
	}
}

// PublicKeys returns an AuthMethod that uses the given key
// pairs.
func PublicKeys(signers ...Signer) AuthMethod {
	return publicKeyCallback(func() ([]Signer, error) { return signers, nil })
}

// PublicKeysCallback returns an AuthMethod that runs the given
// function to obtain a list of key pairs.
func PublicKeysCallback(getSigners func() (signers []Signer, err error)) AuthMethod {
	return publicKeyCallback(getSigners)
}

// handleAuthResponse returns whether the preceding authentication request succeeded
// along with a list of remaining authentication methods to try next and
// an error if an unexpected response was received.
func handleAuthResponse(c packetConn) (authResult, []string, error) {
	gotMsgExtInfo := false
	for {
		packet, err := c.readPacket()
		if err != nil {
			return authFailure, nil, err
		}

		switch packet[0] {
		case msgUserAuthBanner:
			if err := handleBannerResponse(c, packet); err != nil {
				return authFailure, nil, err
			}
		case msgExtInfo:
			// Ignore post-authentication RFC 8308 extensions, once.
			if gotMsgExtInfo {
				return authFailure, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0])
			}
			gotMsgExtInfo = true
		case msgUserAuthFailure:
			var msg userAuthFailureMsg
			if err := Unmarshal(packet, &msg); err != nil {
				return authFailure, nil, err
			}
			if msg.PartialSuccess {
				return authPartialSuccess, msg.Methods, nil
			}
			return authFailure, msg.Methods, nil
		case msgUserAuthSuccess:
			return authSuccess, nil, nil
		default:
			return authFailure, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0])
		}
	}
}

func handleBannerResponse(c packetConn, packet []byte) error {
	var msg userAuthBannerMsg
	if err := Unmarshal(packet, &msg); err != nil {
		return err
	}

	transport, ok := c.(*handshakeTransport)
	if !ok {
		return nil
	}

	if transport.bannerCallback != nil {
		return transport.bannerCallback(msg.Message)
	}

	return nil
}

// KeyboardInteractiveChallenge should print questions, optionally
// 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 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(name, instruction string, questions []string, echos []bool) (answers []string, err error)

// KeyboardInteractive returns an AuthMethod using a prompt/response
// sequence controlled by the server.
func KeyboardInteractive(challenge KeyboardInteractiveChallenge) AuthMethod {
	return challenge
}

func (cb KeyboardInteractiveChallenge) method() string {
	return "keyboard-interactive"
}

func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
	type initiateMsg struct {
		User       string `sshtype:"50"`
		Service    string
		Method     string
		Language   string
		Submethods string
	}

	if err := c.writePacket(Marshal(&initiateMsg{
		User:    user,
		Service: serviceSSH,
		Method:  "keyboard-interactive",
	})); err != nil {
		return authFailure, nil, err
	}

	gotMsgExtInfo := false
	gotUserAuthInfoRequest := false
	for {
		packet, err := c.readPacket()
		if err != nil {
			return authFailure, nil, err
		}

		// like handleAuthResponse, but with less options.
		switch packet[0] {
		case msgUserAuthBanner:
			if err := handleBannerResponse(c, packet); err != nil {
				return authFailure, nil, err
			}
			continue
		case msgExtInfo:
			// Ignore post-authentication RFC 8308 extensions, once.
			if gotMsgExtInfo {
				return authFailure, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])
			}
			gotMsgExtInfo = true
			continue
		case msgUserAuthInfoRequest:
			// OK
		case msgUserAuthFailure:
			var msg userAuthFailureMsg
			if err := Unmarshal(packet, &msg); err != nil {
				return authFailure, nil, err
			}
			if msg.PartialSuccess {
				return authPartialSuccess, msg.Methods, nil
			}
			if !gotUserAuthInfoRequest {
				return authFailure, msg.Methods, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])
			}
			return authFailure, msg.Methods, nil
		case msgUserAuthSuccess:
			return authSuccess, nil, nil
		default:
			return authFailure, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])
		}

		var msg userAuthInfoRequestMsg
		if err := Unmarshal(packet, &msg); err != nil {
			return authFailure, nil, err
		}
		gotUserAuthInfoRequest = true

		// Manually unpack the prompt/echo pairs.
		rest := msg.Prompts
		var prompts []string
		var echos []bool
		for i := 0; i < int(msg.NumPrompts); i++ {
			prompt, r, ok := parseString(rest)
			if !ok || len(r) == 0 {
				return authFailure, nil, errors.New("ssh: prompt format error")
			}
			prompts = append(prompts, string(prompt))
			echos = append(echos, r[0] != 0)
			rest = r[1:]
		}

		if len(rest) != 0 {
			return authFailure, nil, errors.New("ssh: extra data following keyboard-interactive pairs")
		}

		answers, err := cb(msg.Name, msg.Instruction, prompts, echos)
		if err != nil {
			return authFailure, nil, err
		}

		if len(answers) != len(prompts) {
			return authFailure, nil, fmt.Errorf("ssh: incorrect number of answers from keyboard-interactive callback %d (expected %d)", len(answers), len(prompts))
		}
		responseLength := 1 + 4
		for _, a := range answers {
			responseLength += stringLength(len(a))
		}
		serialized := make([]byte, responseLength)
		p := serialized
		p[0] = msgUserAuthInfoResponse
		p = p[1:]
		p = marshalUint32(p, uint32(len(answers)))
		for _, a := range answers {
			p = marshalString(p, []byte(a))
		}

		if err := c.writePacket(serialized); err != nil {
			return authFailure, nil, err
		}
	}
}

type retryableAuthMethod struct {
	authMethod AuthMethod
	maxTries   int
}

func (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (ok authResult, methods []string, err error) {
	for i := 0; r.maxTries <= 0 || i < r.maxTries; i++ {
		ok, methods, err = r.authMethod.auth(session, user, c, rand, extensions)
		if ok != authFailure || err != nil { // either success, partial success or error terminate
			return ok, methods, err
		}
	}
	return ok, methods, err
}

func (r *retryableAuthMethod) method() string {
	return r.authMethod.method()
}

// RetryableAuthMethod is a decorator for other auth methods enabling them to
// be retried up to maxTries before considering that AuthMethod itself failed.
// If maxTries is <= 0, will retry indefinitely
//
// This is useful for interactive clients using challenge/response type
// authentication (e.g. Keyboard-Interactive, Password, etc) where the user
// could mistype their response resulting in the server issuing a
// SSH_MSG_USERAUTH_FAILURE (rfc4252 #8 [password] and rfc4256 #3.4
// [keyboard-interactive]); Without this decorator, the non-retryable
// AuthMethod would be removed from future consideration, and never tried again
// (and so the user would never be able to retry their entry).
func RetryableAuthMethod(auth AuthMethod, maxTries int) AuthMethod {
	return &retryableAuthMethod{authMethod: auth, maxTries: maxTries}
}

// GSSAPIWithMICAuthMethod is an AuthMethod with "gssapi-with-mic" authentication.
// See RFC 4462 section 3
// gssAPIClient is implementation of the GSSAPIClient interface, see the definition of the interface for details.
// target is the server host you want to log in to.
func GSSAPIWithMICAuthMethod(gssAPIClient GSSAPIClient, target string) AuthMethod {
	if gssAPIClient == nil {
		panic("gss-api client must be not nil with enable gssapi-with-mic")
	}
	return &gssAPIWithMICCallback{gssAPIClient: gssAPIClient, target: target}
}

type gssAPIWithMICCallback struct {
	gssAPIClient GSSAPIClient
	target       string
}

func (g *gssAPIWithMICCallback) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
	m := &userAuthRequestMsg{
		User:    user,
		Service: serviceSSH,
		Method:  g.method(),
	}
	// The GSS-API authentication method is initiated when the client sends an SSH_MSG_USERAUTH_REQUEST.
	// See RFC 4462 section 3.2.
	m.Payload = appendU32(m.Payload, 1)
	m.Payload = appendString(m.Payload, string(krb5OID))
	if err := c.writePacket(Marshal(m)); err != nil {
		return authFailure, nil, err
	}
	// The server responds to the SSH_MSG_USERAUTH_REQUEST with either an
	// SSH_MSG_USERAUTH_FAILURE if none of the mechanisms are supported or
	// with an SSH_MSG_USERAUTH_GSSAPI_RESPONSE.
	// See RFC 4462 section 3.3.
	// OpenSSH supports Kerberos V5 mechanism only for GSS-API authentication,so I don't want to check
	// selected mech if it is valid.
	packet, err := c.readPacket()
	if err != nil {
		return authFailure, nil, err
	}
	userAuthGSSAPIResp := &userAuthGSSAPIResponse{}
	if err := Unmarshal(packet, userAuthGSSAPIResp); err != nil {
		return authFailure, nil, err
	}
	// Start the loop into the exchange token.
	// See RFC 4462 section 3.4.
	var token []byte
	defer g.gssAPIClient.DeleteSecContext()
	for {
		// Initiates the establishment of a security context between the application and a remote peer.
		nextToken, needContinue, err := g.gssAPIClient.InitSecContext("host@"+g.target, token, false)
		if err != nil {
			return authFailure, nil, err
		}
		if len(nextToken) > 0 {
			if err := c.writePacket(Marshal(&userAuthGSSAPIToken{
				Token: nextToken,
			})); err != nil {
				return authFailure, nil, err
			}
		}
		if !needContinue {
			break
		}
		packet, err = c.readPacket()
		if err != nil {
			return authFailure, nil, err
		}
		switch packet[0] {
		case msgUserAuthFailure:
			var msg userAuthFailureMsg
			if err := Unmarshal(packet, &msg); err != nil {
				return authFailure, nil, err
			}
			if msg.PartialSuccess {
				return authPartialSuccess, msg.Methods, nil
			}
			return authFailure, msg.Methods, nil
		case msgUserAuthGSSAPIError:
			userAuthGSSAPIErrorResp := &userAuthGSSAPIError{}
			if err := Unmarshal(packet, userAuthGSSAPIErrorResp); err != nil {
				return authFailure, nil, err
			}
			return authFailure, nil, fmt.Errorf("GSS-API Error:\n"+
				"Major Status: %d\n"+
				"Minor Status: %d\n"+
				"Error Message: %s\n", userAuthGSSAPIErrorResp.MajorStatus, userAuthGSSAPIErrorResp.MinorStatus,
				userAuthGSSAPIErrorResp.Message)
		case msgUserAuthGSSAPIToken:
			userAuthGSSAPITokenReq := &userAuthGSSAPIToken{}
			if err := Unmarshal(packet, userAuthGSSAPITokenReq); err != nil {
				return authFailure, nil, err
			}
			token = userAuthGSSAPITokenReq.Token
		}
	}
	// Binding Encryption Keys.
	// See RFC 4462 section 3.5.
	micField := buildMIC(string(session), user, "ssh-connection", "gssapi-with-mic")
	micToken, err := g.gssAPIClient.GetMIC(micField)
	if err != nil {
		return authFailure, nil, err
	}
	if err := c.writePacket(Marshal(&userAuthGSSAPIMIC{
		MIC: micToken,
	})); err != nil {
		return authFailure, nil, err
	}
	return handleAuthResponse(c)
}

func (g *gssAPIWithMICCallback) method() string {
	return "gssapi-with-mic"
}
