示例#1
0
  public static String makeClientEtag(
      final PwmApplication pwmApplication,
      final PwmSession pwmSession,
      final HttpServletRequest httpServletRequest)
      throws PwmUnrecoverableException {
    final StringBuilder inputString = new StringBuilder();
    inputString.append(PwmConstants.BUILD_NUMBER);
    inputString.append(pwmApplication.getStartupTime().getTime());
    inputString.append(httpServletRequest.getSession().getMaxInactiveInterval());
    inputString.append(pwmApplication.getInstanceNonce());

    if (pwmSession.getSessionStateBean().getLocale() != null) {
      inputString.append(pwmSession.getSessionStateBean().getLocale());
    }

    inputString.append(pwmSession.getSessionStateBean().getSessionID());
    if (pwmSession.isAuthenticated()) {
      inputString.append(pwmSession.getUserInfoBean().getUserGuid());
      inputString.append(pwmSession.getLoginInfoBean().getAuthTime());
    }

    return SecureEngine.hash(inputString.toString(), PwmHashAlgorithm.SHA1).toLowerCase();
  }
示例#2
0
  /**
   * This is the entry point under which all password changes are managed. The following is the
   * general procedure when this method is invoked.
   *
   * <ul>
   *   <li>password is checked against PWM password requirement
   *   <li>ldap password set is attempted<br>
   *       <br>
   *       if successful:
   *       <ul>
   *         <li>uiBean is updated with old and new passwords
   *         <li>uiBean's password expire flag is set to false
   *         <li>any configured external methods are invoked
   *         <li>user email notification is sent
   *         <li>return true
   *       </ul>
   *       <br>
   *       if unsuccessful
   *       <ul>
   *         <li>ssBean is updated with appropriate error
   *         <li>return false
   *       </ul>
   * </ul>
   *
   * @param newPassword the new password that is being set.
   * @param pwmSession beanmanager for config and user info lookup
   * @throws com.novell.ldapchai.exception.ChaiUnavailableException if the ldap directory is not
   *     unavailable
   * @throws password.pwm.error.PwmUnrecoverableException if user is not authenticated
   */
  public static void setActorPassword(
      final PwmSession pwmSession,
      final PwmApplication pwmApplication,
      final PasswordData newPassword)
      throws ChaiUnavailableException, PwmUnrecoverableException, PwmOperationalException {
    final UserInfoBean uiBean = pwmSession.getUserInfoBean();

    if (!pwmSession
        .getSessionManager()
        .checkPermission(pwmApplication, Permission.CHANGE_PASSWORD)) {
      final String errorMsg =
          "attempt to setActorPassword, but user does not have password change permission";
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.ERROR_UNAUTHORIZED, errorMsg);
      throw new PwmOperationalException(errorInformation);
    }

    // double check to make sure password meets PWM rule requirements.  This should
    // have been done before setActorPassword() is invoked, so it should be redundant
    // but we do it just in case.
    try {
      final PwmPasswordRuleValidator pwmPasswordRuleValidator =
          new PwmPasswordRuleValidator(pwmApplication, uiBean.getPasswordPolicy());
      pwmPasswordRuleValidator.testPassword(
          newPassword, null, uiBean, pwmSession.getSessionManager().getActor(pwmApplication));
    } catch (PwmDataValidationException e) {
      final String errorMsg =
          "attempt to setActorPassword, but password does not pass local policy validator";
      final ErrorInformation errorInformation =
          new ErrorInformation(e.getErrorInformation().getError(), errorMsg);
      throw new PwmOperationalException(errorInformation);
    }

    // retrieve the user's old password from the userInfoBean in the session
    final PasswordData oldPassword = pwmSession.getLoginInfoBean().getUserCurrentPassword();

    boolean setPasswordWithoutOld = false;
    if (oldPassword == null) {
      if (pwmSession
              .getSessionManager()
              .getActor(pwmApplication)
              .getChaiProvider()
              .getDirectoryVendor()
          == ChaiProvider.DIRECTORY_VENDOR.MICROSOFT_ACTIVE_DIRECTORY) {
        setPasswordWithoutOld = true;
      }
    }

    if (!setPasswordWithoutOld) {
      // Check to make sure we actually have an old password
      if (oldPassword == null) {
        final String errorMsg = "cannot set password for user, old password is not available";
        final ErrorInformation errorInformation =
            new ErrorInformation(PwmError.ERROR_WRONGPASSWORD, errorMsg);
        throw new PwmOperationalException(errorInformation);
      }
    }

    try {
      final ChaiProvider provider = pwmSession.getSessionManager().getChaiProvider();
      final ChaiUser theUser =
          ChaiFactory.createChaiUser(
              pwmSession.getUserInfoBean().getUserIdentity().getUserDN(), provider);
      final boolean boundAsSelf =
          theUser
              .getEntryDN()
              .equals(provider.getChaiConfiguration().getSetting(ChaiSetting.BIND_DN));
      LOGGER.trace(
          pwmSession,
          "preparing to setActorPassword for '"
              + theUser.getEntryDN()
              + "', bindAsSelf="
              + boundAsSelf
              + ", authType="
              + pwmSession.getLoginInfoBean().getType());
      if (setPasswordWithoutOld) {
        theUser.setPassword(newPassword.getStringValue(), true);
      } else {
        theUser.changePassword(oldPassword.getStringValue(), newPassword.getStringValue());
      }
    } catch (ChaiPasswordPolicyException e) {
      final String errorMsg =
          "error setting password for user '" + uiBean.getUserIdentity() + "'' " + e.toString();
      final PwmError pwmError = PwmError.forChaiError(e.getErrorCode());
      final ErrorInformation error =
          new ErrorInformation(
              pwmError == null ? PwmError.PASSWORD_UNKNOWN_VALIDATION : pwmError, errorMsg);
      throw new PwmOperationalException(error);
    } catch (ChaiOperationException e) {
      final String errorMsg =
          "error setting password for user '" + uiBean.getUserIdentity() + "'' " + e.getMessage();
      final PwmError pwmError =
          PwmError.forChaiError(e.getErrorCode()) == null
              ? PwmError.ERROR_UNKNOWN
              : PwmError.forChaiError(e.getErrorCode());
      final ErrorInformation error = new ErrorInformation(pwmError, errorMsg);
      throw new PwmOperationalException(error);
    }

    // at this point the password has been changed, so log it.
    LOGGER.info(
        pwmSession, "user '" + uiBean.getUserIdentity() + "' successfully changed password");

    // update the session state bean's password modified flag
    pwmSession.getSessionStateBean().setPasswordModified(true);

    // update the login info bean with the user's new password
    pwmSession.getLoginInfoBean().setUserCurrentPassword(newPassword);

    // close any outstanding ldap connections (since they cache the old password)
    pwmSession
        .getSessionManager()
        .updateUserPassword(pwmApplication, uiBean.getUserIdentity(), newPassword);

    // clear the "requires new password flag"
    uiBean.setRequiresNewPassword(false);

    // mark the auth type as authenticatePd now that we have the user's natural password.
    pwmSession.getLoginInfoBean().setType(AuthenticationType.AUTHENTICATED);

    // update the uibean's "password expired flag".
    final UserStatusReader userStatusReader =
        new UserStatusReader(pwmApplication, pwmSession.getLabel());
    uiBean.setPasswordState(
        userStatusReader.readPasswordStatus(
            pwmSession.getSessionManager().getActor(pwmApplication),
            uiBean.getPasswordPolicy(),
            uiBean,
            newPassword));

    // create a proxy user object for pwm to update/read the user.
    final ChaiUser proxiedUser = pwmSession.getSessionManager().getActor(pwmApplication);

    // update statistics
    {
      pwmApplication.getStatisticsManager().incrementValue(Statistic.PASSWORD_CHANGES);
      pwmApplication.getStatisticsManager().updateEps(Statistic.EpsType.PASSWORD_CHANGES, 1);
      final int passwordStrength =
          PasswordUtility.judgePasswordStrength(newPassword.getStringValue());
      pwmApplication
          .getStatisticsManager()
          .updateAverageValue(Statistic.AVG_PASSWORD_STRENGTH, passwordStrength);
    }

    // add the old password to the global history list (if the old password is known)
    if (oldPassword != null
        && pwmApplication
            .getConfig()
            .readSettingAsBoolean(PwmSetting.PASSWORD_SHAREDHISTORY_ENABLE)) {
      pwmApplication.getSharedHistoryManager().addWord(pwmSession, oldPassword.getStringValue());
    }

    // invoke post password change actions
    invokePostChangePasswordActions(pwmSession, newPassword.getStringValue());

    { // execute configured actions
      LOGGER.debug(pwmSession, "executing configured actions to user " + proxiedUser.getEntryDN());
      final List<ActionConfiguration> configValues =
          pwmApplication
              .getConfig()
              .readSettingAsAction(PwmSetting.CHANGE_PASSWORD_WRITE_ATTRIBUTES);
      if (configValues != null && !configValues.isEmpty()) {
        final LoginInfoBean clonedLoginInfoBean =
            JsonUtil.cloneUsingJson(pwmSession.getLoginInfoBean(), LoginInfoBean.class);
        clonedLoginInfoBean.setUserCurrentPassword(newPassword);

        final MacroMachine macroMachine =
            new MacroMachine(
                pwmApplication,
                pwmSession.getLabel(),
                pwmSession.getUserInfoBean(),
                clonedLoginInfoBean,
                pwmSession.getSessionManager().getUserDataReader(pwmApplication));

        final ActionExecutor actionExecutor =
            new ActionExecutor.ActionExecutorSettings(pwmApplication, uiBean.getUserIdentity())
                .setMacroMachine(macroMachine)
                .setExpandPwmMacros(true)
                .createActionExecutor();
        actionExecutor.executeActions(configValues, pwmSession);
      }
    }

    // update the current last password update field in ldap
    LdapOperationsHelper.updateLastPasswordUpdateAttribute(
        pwmApplication, pwmSession.getLabel(), uiBean.getUserIdentity());
  }
  static boolean checkAuthentication(
      final PwmRequest pwmRequest, final ConfigManagerBean configManagerBean)
      throws IOException, PwmUnrecoverableException, ServletException {
    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    final PwmSession pwmSession = pwmRequest.getPwmSession();
    final ConfigurationReader runningConfigReader =
        ContextManager.getContextManager(pwmRequest.getHttpServletRequest().getSession())
            .getConfigReader();
    final StoredConfigurationImpl storedConfig = runningConfigReader.getStoredConfiguration();

    boolean authRequired = false;
    if (storedConfig.hasPassword()) {
      authRequired = true;
    }

    if (PwmApplication.MODE.RUNNING == pwmRequest.getPwmApplication().getApplicationMode()) {
      if (!pwmSession.getSessionStateBean().isAuthenticated()) {
        throw new PwmUnrecoverableException(PwmError.ERROR_AUTHENTICATION_REQUIRED);
      }

      if (!pwmRequest
          .getPwmSession()
          .getSessionManager()
          .checkPermission(pwmRequest.getPwmApplication(), Permission.PWMADMIN)) {
        final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNAUTHORIZED);
        pwmRequest.respondWithError(errorInformation);
        return true;
      }

      if (pwmSession.getLoginInfoBean().getAuthenticationType()
          != AuthenticationType.AUTHENTICATED) {
        throw new PwmUnrecoverableException(
            new ErrorInformation(
                PwmError.ERROR_AUTHENTICATION_REQUIRED,
                "Username/Password authentication is required to edit configuration.  This session has not been authenticated using a user password (SSO or other method used)."));
      }
    }

    if (PwmApplication.MODE.CONFIGURATION != pwmRequest.getPwmApplication().getApplicationMode()) {
      authRequired = true;
    }

    if (!authRequired) {
      return false;
    }

    if (!storedConfig.hasPassword()) {
      final String errorMsg = "config file does not have a configuration password";
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR, errorMsg, new String[] {errorMsg});
      pwmRequest.respondWithError(errorInformation, true);
      return true;
    }

    if (configManagerBean.isPasswordVerified()) {
      return false;
    }

    String persistentLoginValue = null;
    boolean persistentLoginAccepted = false;
    boolean persistentLoginEnabled = false;
    if (pwmRequest.getConfig().isDefaultValue(PwmSetting.PWM_SECURITY_KEY)) {
      LOGGER.debug(pwmRequest, "security not available, persistent login not possible.");
    } else {
      persistentLoginEnabled = true;
      final PwmSecurityKey securityKey = pwmRequest.getConfig().getSecurityKey();

      if (PwmApplication.MODE.RUNNING == pwmRequest.getPwmApplication().getApplicationMode()) {
        persistentLoginValue =
            SecureEngine.hash(
                storedConfig.readConfigProperty(ConfigurationProperty.PASSWORD_HASH)
                    + pwmSession.getUserInfoBean().getUserIdentity().toDelimitedKey(),
                PwmHashAlgorithm.SHA512);

      } else {
        persistentLoginValue =
            SecureEngine.hash(
                storedConfig.readConfigProperty(ConfigurationProperty.PASSWORD_HASH),
                PwmHashAlgorithm.SHA512);
      }

      {
        final String cookieStr =
            ServletHelper.readCookie(
                pwmRequest.getHttpServletRequest(), PwmConstants.COOKIE_PERSISTENT_CONFIG_LOGIN);
        if (securityKey != null && cookieStr != null && !cookieStr.isEmpty()) {
          try {
            final String jsonStr = pwmApplication.getSecureService().decryptStringValue(cookieStr);
            final PersistentLoginInfo persistentLoginInfo =
                JsonUtil.deserialize(jsonStr, PersistentLoginInfo.class);
            if (persistentLoginInfo != null && persistentLoginValue != null) {
              if (persistentLoginInfo.getExpireDate().after(new Date())) {
                if (persistentLoginValue.equals(persistentLoginInfo.getPassword())) {
                  persistentLoginAccepted = true;
                  LOGGER.debug(
                      pwmRequest,
                      "accepting persistent config login from cookie (expires "
                          + PwmConstants.DEFAULT_DATETIME_FORMAT.format(
                              persistentLoginInfo.getExpireDate())
                          + ")");
                }
              }
            }
          } catch (Exception e) {
            LOGGER.error(
                pwmRequest, "error examining persistent config login cookie: " + e.getMessage());
          }
          if (!persistentLoginAccepted) {
            Cookie removalCookie = new Cookie(PwmConstants.COOKIE_PERSISTENT_CONFIG_LOGIN, null);
            removalCookie.setMaxAge(0);
            pwmRequest.getPwmResponse().addCookie(removalCookie);
            LOGGER.debug(pwmRequest, "removing non-working persistent config login cookie");
          }
        }
      }
    }

    final String password = pwmRequest.readParameterAsString("password");
    boolean passwordAccepted = false;
    if (!persistentLoginAccepted) {
      if (password != null && password.length() > 0) {
        if (storedConfig.verifyPassword(password)) {
          passwordAccepted = true;
          LOGGER.trace(pwmRequest, "valid configuration password accepted");
          updateLoginHistory(pwmRequest, pwmRequest.getUserInfoIfLoggedIn(), true);
        } else {
          LOGGER.trace(pwmRequest, "configuration password is not correct");
          pwmApplication.getIntruderManager().convenience().markAddressAndSession(pwmSession);
          pwmApplication
              .getIntruderManager()
              .mark(
                  RecordType.USERNAME,
                  PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME,
                  pwmSession.getLabel());
          final ErrorInformation errorInformation =
              new ErrorInformation(PwmError.ERROR_WRONGPASSWORD);
          pwmRequest.setResponseError(errorInformation);
          updateLoginHistory(pwmRequest, pwmRequest.getUserInfoIfLoggedIn(), false);
        }
      }
    }

    if ((persistentLoginAccepted || passwordAccepted)) {
      configManagerBean.setPasswordVerified(true);
      pwmApplication.getIntruderManager().convenience().clearAddressAndSession(pwmSession);
      pwmApplication
          .getIntruderManager()
          .clear(RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME);
      if (persistentLoginEnabled
          && !persistentLoginAccepted
          && "on".equals(pwmRequest.readParameterAsString("remember"))) {
        final int persistentSeconds = figureMaxLoginSeconds(pwmRequest);
        if (persistentSeconds > 0) {
          final Date expirationDate =
              new Date(System.currentTimeMillis() + (persistentSeconds * 1000));
          final PersistentLoginInfo persistentLoginInfo =
              new PersistentLoginInfo(expirationDate, persistentLoginValue);
          final String jsonPersistentLoginInfo = JsonUtil.serialize(persistentLoginInfo);
          final String cookieValue =
              pwmApplication.getSecureService().encryptToString(jsonPersistentLoginInfo);
          pwmRequest
              .getPwmResponse()
              .writeCookie(
                  PwmConstants.COOKIE_PERSISTENT_CONFIG_LOGIN, cookieValue, persistentSeconds);
          LOGGER.debug(
              pwmRequest,
              "set persistent config login cookie (expires "
                  + PwmConstants.DEFAULT_DATETIME_FORMAT.format(expirationDate)
                  + ")");
        }
      }

      if (configManagerBean.getPrePasswordEntryUrl() != null) {
        final String originalUrl = configManagerBean.getPrePasswordEntryUrl();
        configManagerBean.setPrePasswordEntryUrl(null);
        pwmRequest.getPwmResponse().sendRedirect(originalUrl);
        return true;
      }
      return false;
    }

    if (configManagerBean.getPrePasswordEntryUrl() == null) {
      configManagerBean.setPrePasswordEntryUrl(
          pwmRequest.getHttpServletRequest().getRequestURL().toString());
    }

    forwardToJsp(pwmRequest);
    return true;
  }