示例#1
0
 public UserCacheRecord next() {
   try {
     UserCacheRecord returnBean = null;
     while (returnBean == null && this.storageKeyIterator.hasNext()) {
       UserCacheService.StorageKey key = this.storageKeyIterator.next();
       returnBean = userCacheService.readStorageKey(key);
       if (returnBean != null) {
         if (returnBean.getCacheTimestamp() == null) {
           LOGGER.debug(
               PwmConstants.REPORTING_SESSION_LABEL,
               "purging record due to missing cache timestamp: "
                   + JsonUtil.serialize(returnBean));
           userCacheService.removeStorageKey(key);
         } else if (TimeDuration.fromCurrent(returnBean.getCacheTimestamp())
             .isLongerThan(settings.getMaxCacheAge())) {
           LOGGER.debug(
               PwmConstants.REPORTING_SESSION_LABEL,
               "purging record due to old age timestamp: " + JsonUtil.serialize(returnBean));
           userCacheService.removeStorageKey(key);
         } else {
           return returnBean;
         }
       }
     }
   } catch (LocalDBException e) {
     throw new IllegalStateException(
         "unexpected iterator traversal error while reading LocalDB: " + e.getMessage());
   }
   return null;
 }
示例#2
0
  private static List<UserIdentity> readAllUsersFromLdap(
      final PwmApplication pwmApplication, final String searchFilter, final int maxResults)
      throws ChaiUnavailableException, ChaiOperationException, PwmUnrecoverableException,
          PwmOperationalException {
    final UserSearchEngine userSearchEngine = new UserSearchEngine(pwmApplication, null);
    final UserSearchEngine.SearchConfiguration searchConfiguration =
        new UserSearchEngine.SearchConfiguration();
    searchConfiguration.setEnableValueEscaping(false);
    searchConfiguration.setSearchTimeout(
        Long.parseLong(
            pwmApplication.getConfig().readAppProperty(AppProperty.REPORTING_LDAP_SEARCH_TIMEOUT)));

    if (searchFilter == null) {
      searchConfiguration.setUsername("*");
    } else {
      searchConfiguration.setFilter(searchFilter);
    }

    LOGGER.debug(
        PwmConstants.REPORTING_SESSION_LABEL,
        "beginning UserReportService user search using parameters: "
            + (JsonUtil.serialize(searchConfiguration)));

    final Map<UserIdentity, Map<String, String>> searchResults =
        userSearchEngine.performMultiUserSearch(
            searchConfiguration, maxResults, Collections.<String>emptyList());
    LOGGER.debug(
        PwmConstants.REPORTING_SESSION_LABEL,
        "user search found " + searchResults.size() + " users for reporting");
    final List<UserIdentity> returnList = new ArrayList<>(searchResults.keySet());
    Collections.shuffle(returnList);
    return returnList;
  }
示例#3
0
  public String getStatistic(final Statistic statistic) {
    switch (statistic.getType()) {
      case INCREMENTOR:
        return valueMap.containsKey(statistic) ? valueMap.get(statistic) : "0";

      case AVERAGE:
        final String avgStrValue = valueMap.get(statistic);

        AverageBean avgBean = new AverageBean();
        if (avgStrValue != null && avgStrValue.length() > 0) {
          try {
            avgBean = JsonUtil.deserialize(avgStrValue, AverageBean.class);
          } catch (Exception e) {
            LOGGER.trace(
                "unable to parse statistics value for stat "
                    + statistic.toString()
                    + ", value="
                    + avgStrValue);
          }
        }
        return avgBean.getAverage().toString();

      default:
        return "";
    }
  }
示例#4
0
  private void restBrowseLdap(final PwmRequest pwmRequest, final ConfigGuideBean configGuideBean)
      throws IOException, ServletException, PwmUnrecoverableException {
    final StoredConfigurationImpl storedConfiguration =
        StoredConfigurationImpl.copy(configGuideBean.getStoredConfiguration());
    if (configGuideBean.getStep() == STEP.LDAP_ADMIN) {
      storedConfiguration.resetSetting(PwmSetting.LDAP_PROXY_USER_DN, LDAP_PROFILE_KEY, null);
      storedConfiguration.resetSetting(PwmSetting.LDAP_PROXY_USER_PASSWORD, LDAP_PROFILE_KEY, null);
    }

    final Date startTime = new Date();
    final Map<String, String> inputMap =
        pwmRequest.readBodyAsJsonStringMap(PwmHttpRequestWrapper.Flag.BypassValidation);
    final String profile = inputMap.get("profile");
    final String dn = inputMap.containsKey("dn") ? inputMap.get("dn") : "";

    final LdapBrowser ldapBrowser = new LdapBrowser(storedConfiguration);
    final LdapBrowser.LdapBrowseResult result = ldapBrowser.doBrowse(profile, dn);
    ldapBrowser.close();

    LOGGER.trace(
        pwmRequest,
        "performed ldapBrowse operation in "
            + TimeDuration.fromCurrent(startTime).asCompactString()
            + ", result="
            + JsonUtil.serialize(result));

    pwmRequest.outputJsonResult(new RestResultBean(result));
  }
示例#5
0
  public void establishEndpointSession() throws PwmUnrecoverableException {
    LOGGER.debug("establishing endpoint connection to " + endpointURL);
    final String m1 = id + salt;
    final String m1Hash = SecureEngine.hash(m1, PwmHashAlgorithm.SHA256).toLowerCase();
    final String m2 = secret + m1Hash;
    final String m2Hash = SecureEngine.hash(m2, PwmHashAlgorithm.SHA256).toLowerCase();

    final HashMap<String, Object> initConnectMap = new HashMap<>();
    initConnectMap.put("salt", salt);
    initConnectMap.put("endpoint_secret_hash", m2Hash);
    initConnectMap.put("session_data", new HashMap<String, String>());

    final PwmHttpClientResponse response =
        makeApiRequest(HttpMethod.POST, "/endpoints/" + id + "/sessions", initConnectMap);

    final String body = response.getBody();
    final Map<String, String> responseValues = JsonUtil.deserializeStringMap(body);

    endpoint_session_id = responseValues.get("endpoint_session_id");
    LOGGER.debug(
        "endpoint connection established to "
            + endpointURL
            + ", endpoint_session_id="
            + endpoint_session_id);
  }
示例#6
0
 private void updateCacheFromLdap()
     throws ChaiUnavailableException, ChaiOperationException, PwmOperationalException,
         PwmUnrecoverableException {
   LOGGER.debug(
       PwmConstants.REPORTING_SESSION_LABEL,
       "beginning process to updating user cache records from ldap");
   if (status != STATUS.OPEN) {
     return;
   }
   cancelFlag = false;
   reportStatus = new ReportStatusInfo(settings.getSettingsHash());
   reportStatus.setInProgress(true);
   reportStatus.setStartDate(new Date());
   try {
     final Queue<UserIdentity> allUsers = new LinkedList<>(getListOfUsers());
     reportStatus.setTotal(allUsers.size());
     while (status == STATUS.OPEN && !allUsers.isEmpty() && !cancelFlag) {
       final Date startUpdateTime = new Date();
       final UserIdentity userIdentity = allUsers.poll();
       try {
         if (updateCachedRecordFromLdap(userIdentity)) {
           reportStatus.setUpdated(reportStatus.getUpdated() + 1);
         }
       } catch (Exception e) {
         String errorMsg =
             "error while updating report cache for " + userIdentity.toString() + ", cause: ";
         errorMsg +=
             e instanceof PwmException
                 ? ((PwmException) e).getErrorInformation().toDebugStr()
                 : e.getMessage();
         final ErrorInformation errorInformation;
         errorInformation = new ErrorInformation(PwmError.ERROR_REPORTING_ERROR, errorMsg);
         LOGGER.error(PwmConstants.REPORTING_SESSION_LABEL, errorInformation.toDebugStr());
         reportStatus.setLastError(errorInformation);
         reportStatus.setErrors(reportStatus.getErrors() + 1);
       }
       reportStatus.setCount(reportStatus.getCount() + 1);
       reportStatus.getEventRateMeter().markEvents(1);
       final TimeDuration totalUpdateTime = TimeDuration.fromCurrent(startUpdateTime);
       if (settings.isAutoCalcRest()) {
         avgTracker.addSample(totalUpdateTime.getTotalMilliseconds());
         Helper.pause(avgTracker.avgAsLong());
       } else {
         Helper.pause(settings.getRestTime().getTotalMilliseconds());
       }
     }
     if (cancelFlag) {
       reportStatus.setLastError(
           new ErrorInformation(
               PwmError.ERROR_SERVICE_NOT_AVAILABLE, "report cancelled by operator"));
     }
   } finally {
     reportStatus.setFinishDate(new Date());
     reportStatus.setInProgress(false);
   }
   LOGGER.debug(
       PwmConstants.REPORTING_SESSION_LABEL,
       "update user cache process completed: " + JsonUtil.serialize(reportStatus));
 }
示例#7
0
  public void shutdown() {
    LOGGER.warn("shutting down");
    {
      // send system audit event
      final SystemAuditRecord auditRecord =
          SystemAuditRecord.create(AuditEvent.SHUTDOWN, null, getInstanceID());
      try {
        getAuditManager().submit(auditRecord);
      } catch (PwmException e) {
        LOGGER.warn("unable to submit alert event " + JsonUtil.serialize(auditRecord));
      }
    }

    {
      final List<Class> reverseServiceList = new ArrayList<Class>(PWM_SERVICE_CLASSES);
      Collections.reverse(reverseServiceList);
      for (final Class serviceClass : reverseServiceList) {
        if (pwmServices.containsKey(serviceClass)) {
          LOGGER.trace("closing service " + serviceClass.getName());
          final PwmService loopService = pwmServices.get(serviceClass);
          LOGGER.trace("successfully closed service " + serviceClass.getName());
          try {
            loopService.close();
          } catch (Exception e) {
            LOGGER.error(
                "error closing " + loopService.getClass().getSimpleName() + ": " + e.getMessage(),
                e);
          }
        }
      }
    }

    if (localDBLogger != null) {
      try {
        localDBLogger.close();
      } catch (Exception e) {
        LOGGER.error("error closing localDBLogger: " + e.getMessage(), e);
      }
      localDBLogger = null;
    }

    if (localDB != null) {
      try {
        localDB.close();
      } catch (Exception e) {
        LOGGER.fatal("error closing localDB: " + e, e);
      }
      localDB = null;
    }

    LOGGER.info(
        PwmConstants.PWM_APP_NAME
            + " "
            + PwmConstants.SERVLET_VERSION
            + " closed for bidness, cya!");
  }
示例#8
0
 private void saveTempData() {
   try {
     final String jsonInfo = JsonUtil.serialize(reportStatus);
     pwmApplication.writeAppAttribute(PwmApplication.AppAttribute.REPORT_STATUS, jsonInfo);
   } catch (Exception e) {
     LOGGER.error(
         PwmConstants.REPORTING_SESSION_LABEL,
         "error writing cached report dredge info into memory: " + e.getMessage());
   }
 }
示例#9
0
  @Override
  void doCommand() throws Exception {
    final PwmApplication pwmApplication = cliEnvironment.getPwmApplication();

    final File outputFile =
        (File) cliEnvironment.getOptions().get(CliParameters.REQUIRED_NEW_OUTPUT_FILE.getName());
    Helper.pause(2000);

    final long startTime = System.currentTimeMillis();
    final UserSearchEngine userSearchEngine =
        new UserSearchEngine(pwmApplication, SessionLabel.SYSTEM_LABEL);
    final UserSearchEngine.SearchConfiguration searchConfiguration =
        new UserSearchEngine.SearchConfiguration();
    searchConfiguration.setEnableValueEscaping(false);
    searchConfiguration.setUsername("*");

    final String systemRecordDelimiter = System.getProperty("line.separator");
    final Writer writer =
        new BufferedWriter(new PrintWriter(outputFile, PwmConstants.DEFAULT_CHARSET.toString()));
    final Map<UserIdentity, Map<String, String>> results =
        userSearchEngine.performMultiUserSearch(
            searchConfiguration, Integer.MAX_VALUE, Collections.<String>emptyList());
    out(
        "searching "
            + results.size()
            + " users for stored responses to write to "
            + outputFile.getAbsolutePath()
            + "....");
    int counter = 0;
    for (final UserIdentity identity : results.keySet()) {
      final ChaiUser user = pwmApplication.getProxiedChaiUser(identity);
      final ResponseSet responseSet =
          pwmApplication.getCrService().readUserResponseSet(null, identity, user);
      if (responseSet != null) {
        counter++;
        out("found responses for '" + user + "', writing to output.");
        final RestChallengesServer.JsonChallengesData outputData =
            new RestChallengesServer.JsonChallengesData();
        outputData.challenges = responseSet.asChallengeBeans(true);
        outputData.helpdeskChallenges = responseSet.asHelpdeskChallengeBeans(true);
        outputData.minimumRandoms = responseSet.getChallengeSet().minimumResponses();
        outputData.username = identity.toDelimitedKey();
        writer.write(JsonUtil.serialize(outputData));
        writer.write(systemRecordDelimiter);
      } else {
        out("skipping '" + user.toString() + "', no stored responses.");
      }
    }
    writer.close();
    out(
        "output complete, "
            + counter
            + " responses exported in "
            + TimeDuration.fromCurrent(startTime).asCompactString());
  }
示例#10
0
  PwmHttpClientResponse makeApiRequest(
      final HttpMethod method, final String urlPart, final Serializable body)
      throws PwmUnrecoverableException {
    final Map<String, String> headers = new HashMap<>();
    headers.put(PwmConstants.HttpHeader.Content_Type.getHttpName(), "application/json");
    if (locale != null) {
      headers.put(PwmConstants.HttpHeader.Accept_Language.getHttpName(), locale.toLanguageTag());
    }

    final PwmHttpClientRequest pwmHttpClientRequest =
        new PwmHttpClientRequest(
            method, getEndpointURL() + urlPart, JsonUtil.serialize(body), headers);
    return pwmHttpClient.makeRequest(pwmHttpClientRequest);
  }
示例#11
0
  public synchronized void updateAverageValue(final Statistic statistic, final long timeDuration) {
    if (Statistic.Type.AVERAGE != statistic.getType()) {
      LOGGER.error("attempt to update average value of non-average stat " + statistic);
      return;
    }

    final String avgStrValue = valueMap.get(statistic);

    AverageBean avgBean = new AverageBean();
    if (avgStrValue != null && avgStrValue.length() > 0) {
      try {
        avgBean = JsonUtil.deserialize(avgStrValue, AverageBean.class);
      } catch (Exception e) {
        LOGGER.trace(
            "unable to parse statistics value for stat "
                + statistic.toString()
                + ", value="
                + avgStrValue);
      }
    }

    avgBean.appendValue(timeDuration);
    valueMap.put(statistic, JsonUtil.serialize(avgBean));
  }
示例#12
0
 @Override
 public boolean contains(final DatabaseTable table, final String key) throws DatabaseException {
   final boolean result = get(table, key) != null;
   if (traceLogging) {
     final Map<String, Object> debugOutput = new LinkedHashMap<>();
     debugOutput.put("table", table);
     debugOutput.put("key", key);
     debugOutput.put("result", result);
     LOGGER.trace(
         "contains operation result: "
             + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint));
   }
   updateStats(true, false);
   return result;
 }
示例#13
0
 private UserCacheRecord read(StorageKey key) throws LocalDBException {
   final String jsonValue = localDB.get(DB, key.getKey());
   if (jsonValue != null && !jsonValue.isEmpty()) {
     try {
       return JsonUtil.deserialize(jsonValue, UserCacheRecord.class);
     } catch (JsonSyntaxException e) {
       LOGGER.error(
           "error reading record from cache store for key="
               + key.getKey()
               + ", error: "
               + e.getMessage());
       localDB.remove(DB, key.getKey());
     }
   }
   return null;
 }
示例#14
0
  public List<NAAFChainBean> readChains(final String username) throws PwmUnrecoverableException {
    final Map<String, String> urlParams = new LinkedHashMap<>();
    urlParams.put("username", username);
    urlParams.put("application", "NAM");
    urlParams.put("is_trusted", "true");
    urlParams.put("endpoint_session_id", this.getEndpoint_session_id());

    final String url = PwmURL.appendAndEncodeUrlParameters("/logon/chains", urlParams);

    final PwmHttpClientResponse response = makeApiRequest(HttpMethod.POST, url, null);

    final NAAFChainInformationResponseBean naafChainInformationResponseBean =
        JsonUtil.deserialize(response.getBody(), NAAFChainInformationResponseBean.class);

    return naafChainInformationResponseBean.getChains();
  }
示例#15
0
  @Override
  public String get(final DatabaseTable table, final String key) throws DatabaseException {
    if (traceLogging) {
      LOGGER.trace("attempting get operation for table=" + table + ", key=" + key);
    }
    preOperationCheck();
    final StringBuilder sb = new StringBuilder();
    sb.append("SELECT * FROM ").append(table.toString()).append(" WHERE " + KEY_COLUMN + " = ?");

    PreparedStatement statement = null;
    ResultSet resultSet = null;
    String returnValue = null;
    try {
      statement = connection.prepareStatement(sb.toString());
      statement.setString(1, key);
      statement.setMaxRows(1);
      resultSet = statement.executeQuery();

      if (resultSet.next()) {
        returnValue = resultSet.getString(VALUE_COLUMN);
      }
    } catch (SQLException e) {
      final ErrorInformation errorInformation =
          new ErrorInformation(
              PwmError.ERROR_DB_UNAVAILABLE, "get operation failed: " + e.getMessage());
      lastError = errorInformation;
      throw new DatabaseException(errorInformation);
    } finally {
      close(statement);
      close(resultSet);
    }

    if (traceLogging) {
      final LinkedHashMap<String, Object> debugOutput = new LinkedHashMap<>();
      debugOutput.put("table", table);
      debugOutput.put("key", key);
      debugOutput.put("result", returnValue);
      LOGGER.trace(
          "get operation result: " + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint));
    }

    updateStats(true, false);
    return returnValue;
  }
示例#16
0
  private void writeDbValues() {
    if (localDB != null) {
      try {
        localDB.put(LocalDB.DB.PWM_STATS, DB_KEY_CUMULATIVE, statsCummulative.output());
        localDB.put(LocalDB.DB.PWM_STATS, currentDailyKey.toString(), statsDaily.output());

        for (final Statistic.EpsType loopEpsType : Statistic.EpsType.values()) {
          for (final Statistic.EpsDuration loopEpsDuration : Statistic.EpsDuration.values()) {
            final String key = "EPS-" + loopEpsType.toString();
            final String mapKey = loopEpsType.toString() + loopEpsDuration.toString();
            final String value = JsonUtil.serialize(this.epsMeterMap.get(mapKey));
            localDB.put(LocalDB.DB.PWM_STATS, key, value);
          }
        }
      } catch (LocalDBException e) {
        LOGGER.error("error outputting pwm statistics: " + e.getMessage());
      }
    }
  }
 @Override
 public String toDebugString(boolean prettyFormat, Locale locale) {
   if (prettyFormat && values != null && !values.isEmpty()) {
     final StringBuilder sb = new StringBuilder();
     for (final String localeKey : values.keySet()) {
       if (!values.get(localeKey).isEmpty()) {
         sb.append("Locale: ")
             .append(LocaleHelper.debugLabel(LocaleHelper.parseLocaleString(localeKey)))
             .append("\n");
         for (final String value : values.get(localeKey)) {
           sb.append("  ").append(value).append("\n");
         }
       }
     }
     return sb.toString();
   } else {
     return JsonUtil.serializeMap(values);
   }
 }
示例#18
0
  @Override
  public boolean remove(final DatabaseTable table, final String key) throws DatabaseException {
    if (traceLogging) {
      LOGGER.trace("attempting remove operation for table=" + table + ", key=" + key);
    }

    boolean result = contains(table, key);
    if (result) {
      final StringBuilder sqlText = new StringBuilder();
      sqlText.append("DELETE FROM ").append(table.toString()).append(" WHERE " + KEY_COLUMN + "=?");

      PreparedStatement statement = null;
      try {
        statement = connection.prepareStatement(sqlText.toString());
        statement.setString(1, key);
        statement.executeUpdate();
        LOGGER.trace("remove operation succeeded for table=" + table + ", key=" + key);
      } catch (SQLException e) {
        final ErrorInformation errorInformation =
            new ErrorInformation(
                PwmError.ERROR_DB_UNAVAILABLE, "remove operation failed: " + e.getMessage());
        lastError = errorInformation;
        throw new DatabaseException(errorInformation);
      } finally {
        close(statement);
      }
    }

    if (traceLogging) {
      final Map<String, Object> debugOutput = new LinkedHashMap<>();
      debugOutput.put("table", table);
      debugOutput.put("key", key);
      debugOutput.put("result", result);
      LOGGER.trace(
          "remove operation result: "
              + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint));
    }

    updateStats(true, false);
    return result;
  }
示例#19
0
  public static StatisticsBundle input(final String inputString) {
    final Map<Statistic, String> srcMap = new HashMap<>();
    final Map<String, String> loadedMap = JsonUtil.deserializeStringMap(inputString);
    for (final String key : loadedMap.keySet()) {
      try {
        srcMap.put(Statistic.valueOf(key), loadedMap.get(key));
      } catch (IllegalArgumentException e) {
        LOGGER.error("error parsing statistic key '" + key + "', reason: " + e.getMessage());
      }
    }
    final StatisticsBundle bundle = new StatisticsBundle();

    for (final Statistic loopStat : Statistic.values()) {
      final String value = srcMap.get(loopStat);
      if (value != null && !value.equals("")) {
        bundle.valueMap.put(loopStat, value);
      }
    }

    return bundle;
  }
示例#20
0
  private void initTempData() throws LocalDBException, PwmUnrecoverableException {
    final String cleanFlag =
        pwmApplication.readAppAttribute(PwmApplication.AppAttribute.REPORT_CLEAN_FLAG);
    if (!"true".equals(cleanFlag)) {
      LOGGER.error(PwmConstants.REPORTING_SESSION_LABEL, "did not shut down cleanly");
      reportStatus = new ReportStatusInfo(settings.getSettingsHash());
      reportStatus.setTotal(userCacheService.size());
    } else {
      try {
        final String jsonInfo =
            pwmApplication.readAppAttribute(PwmApplication.AppAttribute.REPORT_STATUS);
        if (jsonInfo != null && !jsonInfo.isEmpty()) {
          reportStatus = JsonUtil.deserialize(jsonInfo, ReportStatusInfo.class);
        }
      } catch (Exception e) {
        LOGGER.error(
            PwmConstants.REPORTING_SESSION_LABEL,
            "error loading cached report status info into memory: " + e.getMessage());
      }
    }

    reportStatus =
        reportStatus == null
            ? new ReportStatusInfo(settings.getSettingsHash())
            : reportStatus; // safety

    final String currentSettingCache = settings.getSettingsHash();
    if (reportStatus.getSettingsHash() != null
        && !reportStatus.getSettingsHash().equals(currentSettingCache)) {
      LOGGER.error(
          PwmConstants.REPORTING_SESSION_LABEL,
          "configuration has changed, will clear cached report data");
      clear();
    }

    reportStatus.setInProgress(false);

    pwmApplication.writeAppAttribute(PwmApplication.AppAttribute.REPORT_CLEAN_FLAG, "false");
  }
示例#21
0
  public static PasswordCheckInfo checkEnteredPassword(
      final PwmApplication pwmApplication,
      final Locale locale,
      final ChaiUser user,
      final UserInfoBean userInfoBean,
      final LoginInfoBean loginInfoBean,
      final PasswordData password,
      final PasswordData confirmPassword)
      throws PwmUnrecoverableException, ChaiUnavailableException {
    if (userInfoBean == null) {
      throw new NullPointerException("userInfoBean cannot be null");
    }

    boolean pass = false;
    String userMessage = "";
    int errorCode = 0;

    final boolean passwordIsCaseSensitive =
        userInfoBean.getPasswordPolicy() == null
            || userInfoBean
                .getPasswordPolicy()
                .getRuleHelper()
                .readBooleanValue(PwmPasswordRule.CaseSensitive);
    final CachePolicy cachePolicy;
    {
      final long cacheLifetimeMS =
          Long.parseLong(
              pwmApplication
                  .getConfig()
                  .readAppProperty(AppProperty.CACHE_PWRULECHECK_LIFETIME_MS));
      cachePolicy = CachePolicy.makePolicyWithExpirationMS(cacheLifetimeMS);
    }

    if (password == null) {
      userMessage =
          new ErrorInformation(PwmError.PASSWORD_MISSING)
              .toUserStr(locale, pwmApplication.getConfig());
    } else {
      final CacheService cacheService = pwmApplication.getCacheService();
      final CacheKey cacheKey =
          user != null && userInfoBean.getUserIdentity() != null
              ? CacheKey.makeCacheKey(
                  PasswordUtility.class,
                  userInfoBean.getUserIdentity(),
                  user.getEntryDN() + ":" + password.hash())
              : null;
      if (pwmApplication.getConfig().isDevDebugMode()) {
        LOGGER.trace("generated cacheKey for password check request: " + cacheKey);
      }
      try {
        if (cacheService != null && cacheKey != null) {
          final String cachedValue = cacheService.get(cacheKey);
          if (cachedValue != null) {
            if (NEGATIVE_CACHE_HIT.equals(cachedValue)) {
              pass = true;
            } else {
              LOGGER.trace("cache hit!");
              final ErrorInformation errorInformation =
                  JsonUtil.deserialize(cachedValue, ErrorInformation.class);
              throw new PwmDataValidationException(errorInformation);
            }
          }
        }
        if (!pass) {
          final PwmPasswordRuleValidator pwmPasswordRuleValidator =
              new PwmPasswordRuleValidator(
                  pwmApplication, userInfoBean.getPasswordPolicy(), locale);
          final PasswordData oldPassword =
              loginInfoBean == null ? null : loginInfoBean.getUserCurrentPassword();
          pwmPasswordRuleValidator.testPassword(password, oldPassword, userInfoBean, user);
          pass = true;
          if (cacheService != null && cacheKey != null) {
            cacheService.put(cacheKey, cachePolicy, NEGATIVE_CACHE_HIT);
          }
        }
      } catch (PwmDataValidationException e) {
        errorCode = e.getError().getErrorCode();
        userMessage = e.getErrorInformation().toUserStr(locale, pwmApplication.getConfig());
        pass = false;
        if (cacheService != null && cacheKey != null) {
          final String jsonPayload = JsonUtil.serialize(e.getErrorInformation());
          cacheService.put(cacheKey, cachePolicy, jsonPayload);
        }
      }
    }

    final PasswordCheckInfo.MATCH_STATUS matchStatus =
        figureMatchStatus(passwordIsCaseSensitive, password, confirmPassword);
    if (pass) {
      switch (matchStatus) {
        case EMPTY:
          userMessage =
              new ErrorInformation(PwmError.PASSWORD_MISSING_CONFIRM)
                  .toUserStr(locale, pwmApplication.getConfig());
          break;
        case MATCH:
          userMessage =
              new ErrorInformation(PwmError.PASSWORD_MEETS_RULES)
                  .toUserStr(locale, pwmApplication.getConfig());
          break;
        case NO_MATCH:
          userMessage =
              new ErrorInformation(PwmError.PASSWORD_DOESNOTMATCH)
                  .toUserStr(locale, pwmApplication.getConfig());
          break;
        default:
          userMessage = "";
      }
    }

    final int strength = judgePasswordStrength(password == null ? null : password.getStringValue());
    return new PasswordCheckInfo(userMessage, pass, strength, matchStatus, errorCode);
  }
示例#22
0
  @Override
  void doCommand() throws Exception {
    final PwmApplication pwmApplication = cliEnvironment.getPwmApplication();

    final File inputFile =
        (File)
            cliEnvironment.getOptions().get(CliParameters.REQUIRED_EXISTING_INPUT_FILE.getName());
    final BufferedReader reader =
        new BufferedReader(
            new InputStreamReader(
                new FileInputStream(inputFile), PwmConstants.DEFAULT_CHARSET.toString()));
    out("importing stored responses from " + inputFile.getAbsolutePath() + "....");

    int counter = 0;
    String line;
    final long startTime = System.currentTimeMillis();
    while ((line = reader.readLine()) != null) {
      counter++;
      final RestChallengesServer.JsonChallengesData inputData;
      inputData = JsonUtil.deserialize(line, RestChallengesServer.JsonChallengesData.class);

      final UserIdentity userIdentity = UserIdentity.fromDelimitedKey(inputData.username);
      final ChaiUser user = pwmApplication.getProxiedChaiUser(userIdentity);
      if (user.isValid()) {
        out("writing responses to user '" + user.getEntryDN() + "'");
        try {
          final ChallengeProfile challengeProfile =
              pwmApplication
                  .getCrService()
                  .readUserChallengeProfile(
                      null,
                      userIdentity,
                      user,
                      PwmPasswordPolicy.defaultPolicy(),
                      PwmConstants.DEFAULT_LOCALE);
          final ChallengeSet challengeSet = challengeProfile.getChallengeSet();
          final String userGuid =
              LdapOperationsHelper.readLdapGuidValue(pwmApplication, null, userIdentity, false);
          final ResponseInfoBean responseInfoBean =
              inputData.toResponseInfoBean(
                  PwmConstants.DEFAULT_LOCALE, challengeSet.getIdentifier());
          pwmApplication.getCrService().writeResponses(user, userGuid, responseInfoBean);
        } catch (Exception e) {
          out(
              "error writing responses to user '"
                  + user.getEntryDN()
                  + "', error: "
                  + e.getMessage());
          return;
        }
      } else {
        out("user '" + user.getEntryDN() + "' is not a valid userDN");
        return;
      }
    }

    out(
        "output complete, "
            + counter
            + " responses imported in "
            + TimeDuration.fromCurrent(startTime).asCompactString());
  }
示例#23
0
 public String output() {
   return JsonUtil.serializeMap(valueMap);
 }
示例#24
0
 private void write(StorageKey key, UserCacheRecord cacheBean) throws LocalDBException {
   final String jsonValue = JsonUtil.serialize(cacheBean);
   localDB.put(DB, key.getKey(), jsonValue);
 }
示例#25
0
  public void init(PwmApplication pwmApplication) throws PwmException {
    for (final Statistic.EpsType type : Statistic.EpsType.values()) {
      for (final Statistic.EpsDuration duration : Statistic.EpsDuration.values()) {
        epsMeterMap.put(
            type.toString() + duration.toString(), new EventRateMeter(duration.getTimeDuration()));
      }
    }

    status = STATUS.OPENING;
    this.localDB = pwmApplication.getLocalDB();
    this.pwmApplication = pwmApplication;

    if (localDB == null) {
      LOGGER.error("LocalDB is not available, will remain closed");
      status = STATUS.CLOSED;
      return;
    }

    {
      final String storedCummulativeBundleStr =
          localDB.get(LocalDB.DB.PWM_STATS, DB_KEY_CUMULATIVE);
      if (storedCummulativeBundleStr != null && storedCummulativeBundleStr.length() > 0) {
        statsCummulative = StatisticsBundle.input(storedCummulativeBundleStr);
      }
    }

    {
      for (final Statistic.EpsType loopEpsType : Statistic.EpsType.values()) {
        for (final Statistic.EpsType loopEpsDuration : Statistic.EpsType.values()) {
          final String key = "EPS-" + loopEpsType.toString() + loopEpsDuration.toString();
          final String storedValue = localDB.get(LocalDB.DB.PWM_STATS, key);
          if (storedValue != null && storedValue.length() > 0) {
            try {
              final EventRateMeter eventRateMeter =
                  JsonUtil.deserialize(storedValue, EventRateMeter.class);
              epsMeterMap.put(loopEpsType.toString() + loopEpsDuration.toString(), eventRateMeter);
            } catch (Exception e) {
              LOGGER.error(
                  "unexpected error reading last EPS rate for "
                      + loopEpsType
                      + " from LocalDB: "
                      + e.getMessage());
            }
          }
        }
      }
    }

    {
      final String storedInitialString =
          localDB.get(LocalDB.DB.PWM_STATS, DB_KEY_INITIAL_DAILY_KEY);
      if (storedInitialString != null && storedInitialString.length() > 0) {
        initialDailyKey = new DailyKey(storedInitialString);
      }
    }

    {
      currentDailyKey = new DailyKey(new Date());
      final String storedDailyStr = localDB.get(LocalDB.DB.PWM_STATS, currentDailyKey.toString());
      if (storedDailyStr != null && storedDailyStr.length() > 0) {
        statsDaily = StatisticsBundle.input(storedDailyStr);
      }
    }

    try {
      localDB.put(
          LocalDB.DB.PWM_STATS,
          DB_KEY_TEMP,
          PwmConstants.DEFAULT_DATETIME_FORMAT.format(new Date()));
    } catch (IllegalStateException e) {
      LOGGER.error("unable to write to localDB, will remain closed, error: " + e.getMessage());
      status = STATUS.CLOSED;
      return;
    }

    localDB.put(LocalDB.DB.PWM_STATS, DB_KEY_VERSION, DB_VALUE_VERSION);
    localDB.put(LocalDB.DB.PWM_STATS, DB_KEY_INITIAL_DAILY_KEY, initialDailyKey.toString());

    { // setup a timer to roll over at 0 Zula and one to write current stats every 10 seconds
      final String threadName = Helper.makeThreadName(pwmApplication, this.getClass()) + " timer";
      daemonTimer = new Timer(threadName, true);
      daemonTimer.schedule(new FlushTask(), 10 * 1000, DB_WRITE_FREQUENCY_MS);
      daemonTimer.schedule(new NightlyTask(), Helper.nextZuluZeroTime());
    }

    if (pwmApplication.getApplicationMode() == PwmApplication.MODE.RUNNING) {
      if (pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.PUBLISH_STATS_ENABLE)) {
        long lastPublishTimestamp = pwmApplication.getInstallTime().getTime();
        {
          final String lastPublishDateStr =
              localDB.get(LocalDB.DB.PWM_STATS, KEY_CLOUD_PUBLISH_TIMESTAMP);
          if (lastPublishDateStr != null && lastPublishDateStr.length() > 0) {
            try {
              lastPublishTimestamp = Long.parseLong(lastPublishDateStr);
            } catch (Exception e) {
              LOGGER.error(
                  "unexpected error reading last publish timestamp from PwmDB: " + e.getMessage());
            }
          }
        }
        final Date nextPublishTime =
            new Date(
                lastPublishTimestamp
                    + PwmConstants.STATISTICS_PUBLISH_FREQUENCY_MS
                    + (long) PwmRandom.getInstance().nextInt(3600 * 1000));
        daemonTimer.schedule(
            new PublishTask(), nextPublishTime, PwmConstants.STATISTICS_PUBLISH_FREQUENCY_MS);
      }
    }

    status = STATUS.OPEN;
  }
示例#26
0
  private void publishStatisticsToCloud()
      throws URISyntaxException, IOException, PwmUnrecoverableException {
    final StatsPublishBean statsPublishData;
    {
      final StatisticsBundle bundle = getStatBundleForKey(KEY_CUMULATIVE);
      final Map<String, String> statData = new HashMap<>();
      for (final Statistic loopStat : Statistic.values()) {
        statData.put(loopStat.getKey(), bundle.getStatistic(loopStat));
      }
      final Configuration config = pwmApplication.getConfig();
      final List<String> configuredSettings = new ArrayList<>();
      for (final PwmSetting pwmSetting : config.nonDefaultSettings()) {
        if (!pwmSetting.getCategory().hasProfiles() && !config.isDefaultValue(pwmSetting)) {
          configuredSettings.add(pwmSetting.getKey());
        }
      }
      final Map<String, String> otherData = new HashMap<>();
      otherData.put(
          StatsPublishBean.KEYS.SITE_URL.toString(),
          config.readSettingAsString(PwmSetting.PWM_SITE_URL));
      otherData.put(
          StatsPublishBean.KEYS.SITE_DESCRIPTION.toString(),
          config.readSettingAsString(PwmSetting.PUBLISH_STATS_SITE_DESCRIPTION));
      otherData.put(
          StatsPublishBean.KEYS.INSTALL_DATE.toString(),
          PwmConstants.DEFAULT_DATETIME_FORMAT.format(pwmApplication.getInstallTime()));

      try {
        otherData.put(
            StatsPublishBean.KEYS.LDAP_VENDOR.toString(),
            pwmApplication
                .getProxyChaiProvider(config.getDefaultLdapProfile().getIdentifier())
                .getDirectoryVendor()
                .toString());
      } catch (Exception e) {
        LOGGER.trace("unable to read ldap vendor type for stats publication: " + e.getMessage());
      }

      statsPublishData =
          new StatsPublishBean(
              pwmApplication.getInstanceID(),
              new Date(),
              statData,
              configuredSettings,
              PwmConstants.BUILD_NUMBER,
              PwmConstants.BUILD_VERSION,
              otherData);
    }
    final URI requestURI = new URI(PwmConstants.PWM_URL_CLOUD + "/rest/pwm/statistics");
    final HttpPost httpPost = new HttpPost(requestURI.toString());
    final String jsonDataString = JsonUtil.serialize(statsPublishData);
    httpPost.setEntity(new StringEntity(jsonDataString));
    httpPost.setHeader("Accept", PwmConstants.AcceptValue.json.getHeaderValue());
    httpPost.setHeader("Content-Type", PwmConstants.ContentTypeValue.json.getHeaderValue());
    LOGGER.debug(
        "preparing to send anonymous statistics to "
            + requestURI.toString()
            + ", data to send: "
            + jsonDataString);
    final HttpResponse httpResponse =
        PwmHttpClient.getHttpClient(pwmApplication.getConfig()).execute(httpPost);
    if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
      throw new IOException(
          "http response error code: " + httpResponse.getStatusLine().getStatusCode());
    }
    LOGGER.info("published anonymous statistics to " + requestURI.toString());
    try {
      localDB.put(
          LocalDB.DB.PWM_STATS,
          KEY_CLOUD_PUBLISH_TIMESTAMP,
          String.valueOf(System.currentTimeMillis()));
    } catch (LocalDBException e) {
      LOGGER.error(
          "unexpected error trying to save last statistics published time to LocalDB: "
              + e.getMessage());
    }
  }
示例#27
0
  public List<HealthRecord> healthCheck() {
    if (status == PwmService.STATUS.CLOSED) {
      return Collections.emptyList();
    }

    final List<HealthRecord> returnRecords = new ArrayList<>();

    try {
      preOperationCheck();
    } catch (DatabaseException e) {
      lastError = e.getErrorInformation();
      returnRecords.add(
          new HealthRecord(
              HealthStatus.WARN,
              HealthTopic.Database,
              "Database server is not available: " + e.getErrorInformation().toDebugStr()));
      return returnRecords;
    }

    try {
      final Map<String, String> tempMap = new HashMap<>();
      tempMap.put("instance", instanceID);
      tempMap.put("date", (new java.util.Date()).toString());
      this.put(
          DatabaseTable.PWM_META, DatabaseAccessorImpl.KEY_TEST, JsonUtil.serializeMap(tempMap));
    } catch (PwmException e) {
      returnRecords.add(
          new HealthRecord(
              HealthStatus.WARN,
              HealthTopic.Database,
              "Error writing to database: " + e.getErrorInformation().toDebugStr()));
      return returnRecords;
    }

    if (lastError != null) {
      final TimeDuration errorAge = TimeDuration.fromCurrent(lastError.getDate().getTime());

      if (errorAge.isShorterThan(TimeDuration.HOUR)) {
        returnRecords.add(
            new HealthRecord(
                HealthStatus.CAUTION,
                HealthTopic.Database,
                "Database server was recently unavailable ("
                    + errorAge.asLongString(PwmConstants.DEFAULT_LOCALE)
                    + " ago at "
                    + lastError.getDate().toString()
                    + "): "
                    + lastError.toDebugStr()));
      }
    }

    if (returnRecords.isEmpty()) {
      returnRecords.add(
          new HealthRecord(
              HealthStatus.GOOD,
              HealthTopic.Database,
              "Database connection to " + this.dbConfiguration.getConnectionString() + " okay"));
    }

    return returnRecords;
  }
示例#28
0
  private Connection openDB(final DBConfiguration dbConfiguration) throws DatabaseException {
    final String connectionURL = dbConfiguration.getConnectionString();
    final String jdbcClassName = dbConfiguration.getDriverClassname();

    try {
      final byte[] jdbcDriverBytes = dbConfiguration.getJdbcDriver();
      if (jdbcDriverBytes != null) {
        LOGGER.debug("loading JDBC database driver stored in configuration");
        final JarClassLoader jarClassLoader = new JarClassLoader();
        jarClassLoader.add(new ByteArrayInputStream(jdbcDriverBytes));
        final JclObjectFactory jclObjectFactory = JclObjectFactory.getInstance();

        // Create object of loaded class
        driver = (Driver) jclObjectFactory.create(jarClassLoader, jdbcClassName);

        LOGGER.debug(
            "successfully loaded JDBC database driver '"
                + jdbcClassName
                + "' from application configuration");
      }
    } catch (Throwable e) {
      final String errorMsg =
          "error registering JDBC database driver stored in configuration: " + e.getMessage();
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.ERROR_DB_UNAVAILABLE, errorMsg);
      LOGGER.error(errorMsg, e);
      throw new DatabaseException(errorInformation);
    }

    if (driver == null) {
      try {
        LOGGER.debug("loading JDBC database driver from classpath: " + jdbcClassName);
        driver = (Driver) Class.forName(jdbcClassName).newInstance();

        LOGGER.debug("successfully loaded JDBC database driver from classpath: " + jdbcClassName);
      } catch (Throwable e) {
        final String errorMsg =
            e.getClass().getName()
                + " error loading JDBC database driver from classpath: "
                + e.getMessage();
        final ErrorInformation errorInformation =
            new ErrorInformation(PwmError.ERROR_DB_UNAVAILABLE, errorMsg);
        throw new DatabaseException(errorInformation);
      }
    }

    try {
      LOGGER.debug("opening connection to database " + connectionURL);
      final Properties connectionProperties = new Properties();
      if (dbConfiguration.getUsername() != null && !dbConfiguration.getUsername().isEmpty()) {
        connectionProperties.setProperty("user", dbConfiguration.getUsername());
      }
      if (dbConfiguration.getPassword() != null) {
        connectionProperties.setProperty(
            "password", dbConfiguration.getPassword().getStringValue());
      }
      final Connection connection = driver.connect(connectionURL, connectionProperties);

      final Map<PwmAboutProperty, String> debugProps = getConnectionDebugProperties(connection);
      ;
      LOGGER.debug(
          "successfully opened connection to database "
              + connectionURL
              + ", properties: "
              + JsonUtil.serializeMap(debugProps));

      connection.setAutoCommit(true);
      return connection;
    } catch (Throwable e) {
      final String errorMsg =
          "error connecting to database: " + Helper.readHostileExceptionMessage(e);
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.ERROR_DB_UNAVAILABLE, errorMsg);
      if (e instanceof IOException) {
        LOGGER.error(errorInformation);
      } else {
        LOGGER.error(errorMsg, e);
      }
      throw new DatabaseException(errorInformation);
    }
  }
示例#29
0
  private void postInitTasks() {
    final Date startTime = new Date();

    LOGGER.debug("loaded configuration: \n" + configuration.toDebugString());

    // detect if config has been modified since previous startup
    try {
      final String previousHash = readAppAttribute(AppAttribute.CONFIG_HASH);
      final String currentHash = configuration.configurationHash();
      if (previousHash == null || !previousHash.equals(currentHash)) {
        writeAppAttribute(AppAttribute.CONFIG_HASH, currentHash);
        LOGGER.warn(
            "configuration checksum does not match previously seen checksum, configuration has been modified since last startup");
        if (this.getAuditManager() != null) {
          final String modifyMessage =
              "configuration was modified directly (not using ConfigEditor UI)";
          this.getAuditManager()
              .submit(
                  SystemAuditRecord.create(
                      AuditEvent.MODIFY_CONFIGURATION, modifyMessage, this.getInstanceID()));
        }
      }
    } catch (Exception e) {
      LOGGER.debug(
          "unable to detect if configuration has been modified since previous startup: "
              + e.getMessage());
    }

    if (this.getConfig() != null) {
      final Map<AppProperty, String> nonDefaultProperties =
          getConfig().readAllNonDefaultAppProperties();
      if (nonDefaultProperties != null && !nonDefaultProperties.isEmpty()) {
        final Map<String, String> tempMap = new LinkedHashMap<>();
        for (final AppProperty loopProperty : nonDefaultProperties.keySet()) {
          tempMap.put(loopProperty.getKey(), nonDefaultProperties.get(loopProperty));
        }
        LOGGER.trace(
            "non-default app properties read from configuration: "
                + JsonUtil.serializeMap(tempMap));
      } else {
        LOGGER.trace("no non-default app properties in configuration");
      }
    }

    // send system audit event
    final SystemAuditRecord auditRecord =
        SystemAuditRecord.create(AuditEvent.STARTUP, null, getInstanceID());
    try {
      getAuditManager().submit(auditRecord);
    } catch (PwmException e) {
      LOGGER.warn("unable to submit alert event " + JsonUtil.serialize(auditRecord));
    }

    try {
      Map<PwmAboutProperty, String> infoMap = Helper.makeInfoBean(this);
      LOGGER.trace("application info: " + JsonUtil.serializeMap(infoMap));
    } catch (Exception e) {
      LOGGER.error("error generating about application bean: " + e.getMessage());
    }

    try {
      this.getIntruderManager()
          .clear(RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME);
    } catch (Exception e) {
      LOGGER.debug(
          "error while clearing configmanager-intruder-username from intruder table: "
              + e.getMessage());
    }

    LOGGER.trace(
        "completed post init tasks in " + TimeDuration.fromCurrent(startTime).asCompactString());
  }
示例#30
0
  @Override
  public boolean put(final DatabaseTable table, final String key, final String value)
      throws DatabaseException {

    preOperationCheck();
    if (traceLogging) {
      LOGGER.trace("attempting put operation for table=" + table + ", key=" + key);
    }
    if (!contains(table, key)) {
      final String sqlText =
          "INSERT INTO "
              + table.toString()
              + "("
              + KEY_COLUMN
              + ", "
              + VALUE_COLUMN
              + ") VALUES(?,?)";
      PreparedStatement statement = null;

      try {
        statement = connection.prepareStatement(sqlText);
        statement.setString(1, key);
        statement.setString(2, value);
        statement.executeUpdate();
      } catch (SQLException e) {
        final ErrorInformation errorInformation =
            new ErrorInformation(
                PwmError.ERROR_DB_UNAVAILABLE, "put operation failed: " + e.getMessage());
        lastError = errorInformation;
        throw new DatabaseException(errorInformation);
      } finally {
        close(statement);
      }
      return false;
    }

    final String sqlText =
        "UPDATE " + table.toString() + " SET " + VALUE_COLUMN + "=? WHERE " + KEY_COLUMN + "=?";
    PreparedStatement statement = null;

    try {
      statement = connection.prepareStatement(sqlText);
      statement.setString(1, value);
      statement.setString(2, key);
      statement.executeUpdate();
    } catch (SQLException e) {
      final ErrorInformation errorInformation =
          new ErrorInformation(
              PwmError.ERROR_DB_UNAVAILABLE, "put operation failed: " + e.getMessage());
      lastError = errorInformation;
      throw new DatabaseException(errorInformation);
    } finally {
      close(statement);
    }

    if (traceLogging) {
      final Map<String, Object> debugOutput = new LinkedHashMap<>();
      debugOutput.put("table", table);
      debugOutput.put("key", key);
      debugOutput.put("value", value);
      LOGGER.trace(
          "put operation result: " + JsonUtil.serializeMap(debugOutput, JsonUtil.Flag.PrettyPrint));
    }

    updateStats(false, true);
    return true;
  }