code: 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
  	}
  	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.
  	tried := make(map[string]bool)
  	var lastMethods []string
  	for auth := AuthMethod(new(noneAuth)); auth != nil; {
  		ok, methods, err := auth.auth(c.transport.getSessionID(), config.User, c.transport, config.Rand)
  		if err != nil {
  			return err
  		}
  		if ok {
  			// success
  			return nil
  		}
  		tried[auth.method()] = true
  		if methods == nil {
  			methods = lastMethods
  		}
  		lastMethods = methods
  
  		auth = nil
  
  	findNext:
  		for _, a := range config.Auth {
  			candidateMethod := a.method()
  			if tried[candidateMethod] {
  				continue
  			}
  			for _, meth := range methods {
  				if meth == candidateMethod {
  					auth = a
  					break findNext
  				}
  			}
  		}
  	}
  	return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", keys(tried))
  }
docs: // clientAuthenticate authenticates with the remote server. See RFC 4252.