(config *ServerConfig)
| 515 | } |
| 516 | |
| 517 | func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) { |
| 518 | if config.PreAuthConnCallback != nil { |
| 519 | config.PreAuthConnCallback(s) |
| 520 | } |
| 521 | |
| 522 | sessionID := s.transport.getSessionID() |
| 523 | var cache pubKeyCache |
| 524 | var perms *Permissions |
| 525 | |
| 526 | authFailures := 0 |
| 527 | noneAuthCount := 0 |
| 528 | var authErrs []error |
| 529 | var calledBannerCallback bool |
| 530 | partialSuccessReturned := false |
| 531 | // Set the initial authentication callbacks from the config. They can be |
| 532 | // changed if a PartialSuccessError is returned. |
| 533 | authConfig := ServerAuthCallbacks{ |
| 534 | PasswordCallback: config.PasswordCallback, |
| 535 | PublicKeyCallback: config.PublicKeyCallback, |
| 536 | KeyboardInteractiveCallback: config.KeyboardInteractiveCallback, |
| 537 | GSSAPIWithMICConfig: config.GSSAPIWithMICConfig, |
| 538 | } |
| 539 | |
| 540 | userAuthLoop: |
| 541 | for { |
| 542 | if authFailures >= config.MaxAuthTries && config.MaxAuthTries > 0 { |
| 543 | discMsg := &disconnectMsg{ |
| 544 | Reason: 2, |
| 545 | Message: "too many authentication failures", |
| 546 | } |
| 547 | |
| 548 | if err := s.transport.writePacket(Marshal(discMsg)); err != nil { |
| 549 | return nil, err |
| 550 | } |
| 551 | authErrs = append(authErrs, discMsg) |
| 552 | return nil, &ServerAuthError{Errors: authErrs} |
| 553 | } |
| 554 | |
| 555 | var userAuthReq userAuthRequestMsg |
| 556 | if packet, err := s.transport.readPacket(); err != nil { |
| 557 | if err == io.EOF { |
| 558 | return nil, &ServerAuthError{Errors: authErrs} |
| 559 | } |
| 560 | return nil, err |
| 561 | } else if err = Unmarshal(packet, &userAuthReq); err != nil { |
| 562 | return nil, err |
| 563 | } |
| 564 | |
| 565 | if userAuthReq.Service != serviceSSH { |
| 566 | return nil, errors.New("ssh: client attempted to negotiate for unknown service: " + userAuthReq.Service) |
| 567 | } |
| 568 | |
| 569 | if s.user != userAuthReq.User && partialSuccessReturned { |
| 570 | return nil, fmt.Errorf("ssh: client changed the user after a partial success authentication, previous user %q, current user %q", |
| 571 | s.user, userAuthReq.User) |
| 572 | } |
| 573 | |
| 574 | s.user = userAuthReq.User |
no test coverage detected