/**
   * @param authentication
   * @param msg
   * @return
   * @throws IOException
   */
  public int authenticate(AuthenticationProtocolServer authentication, SshMsgUserAuthRequest msg)
      throws IOException {
    NativeAuthenticationProvider authImpl = NativeAuthenticationProvider.getInstance();

    if (authImpl == null) {
      log.error("Cannot perfrom authentication witout native authentication provider");

      return AuthenticationProtocolState.FAILED;
    }

    ByteArrayReader bar = new ByteArrayReader(msg.getRequestData());
    boolean changepwd = ((bar.read() == 0) ? false : true);
    String password = bar.readString();
    String newpassword = null;

    if (changepwd) {
      newpassword = bar.readString();

      try {
        if (!authImpl.changePassword(msg.getUsername(), password, newpassword)) {
          return AuthenticationProtocolState.FAILED;
        }

        if (authImpl.logonUser(msg.getUsername(), newpassword)) {
          return AuthenticationProtocolState.COMPLETE;
        } else {
          return AuthenticationProtocolState.FAILED;
        }
      } catch (PasswordChangeException ex1) {
        return AuthenticationProtocolState.FAILED;
      }
    } else {
      try {
        if (authImpl.logonUser(msg.getUsername(), password)) {
          log.info(msg.getUsername() + " has passed password authentication");

          return AuthenticationProtocolState.COMPLETE;
        } else {
          log.info(msg.getUsername() + " has failed password authentication");

          return AuthenticationProtocolState.FAILED;
        }
      } catch (PasswordChangeException ex) {
        SshMsgUserAuthPwdChangeReq reply =
            new SshMsgUserAuthPwdChangeReq(
                msg.getUsername() + " is required to change password", "");
        authentication.sendMessage(reply);

        return AuthenticationProtocolState.READY;
      }
    }
  }