Пример #1
0
  public boolean containsWord(final String word) {
    if (status != STATUS.OPEN) {
      return false;
    }

    final String testWord = normalizeWord(word);

    if (testWord == null) {
      return false;
    }

    // final long startTime = System.currentTimeMillis();
    boolean result = false;

    try {
      final String hashedWord = hashWord(testWord);
      final boolean inDB = localDB.contains(WORDS_DB, hashedWord);
      if (inDB) {
        final long timeStamp = Long.parseLong(localDB.get(WORDS_DB, hashedWord));
        final long entryAge = System.currentTimeMillis() - timeStamp;
        if (entryAge < settings.maxAgeMs) {
          result = true;
        }
      }

    } catch (Exception e) {
      LOGGER.warn("error checking global history list: " + e.getMessage());
    }

    // LOGGER.trace(pwmSession, "successfully checked word, result=" + result + ", duration=" + new
    // TimeDuration(System.currentTimeMillis(), startTime).asCompactString());
    return result;
  }
Пример #2
0
  public synchronized void addWord(final PwmSession pwmSession, final String word) {
    if (status != STATUS.OPEN) {
      return;
    }

    final String addWord = normalizeWord(word);

    if (addWord == null) {
      return;
    }

    final long startTime = System.currentTimeMillis();

    try {
      final String hashedWord = hashWord(addWord);

      final boolean preExisting = localDB.contains(WORDS_DB, hashedWord);
      localDB.put(WORDS_DB, hashedWord, Long.toString(System.currentTimeMillis()));

      {
        final StringBuilder logOutput = new StringBuilder();
        logOutput.append(preExisting ? "updated" : "added").append(" word");
        logOutput
            .append(" (")
            .append(new TimeDuration(System.currentTimeMillis(), startTime).asCompactString())
            .append(")");
        logOutput.append(" (").append(this.size()).append(" total words)");
        LOGGER.trace(logOutput.toString());
      }
    } catch (Exception e) {
      LOGGER.warn(pwmSession, "error adding word to global history list: " + e.getMessage());
    }
  }
Пример #3
0
  private boolean checkDbVersion() throws Exception {
    LOGGER.trace("checking version number stored in LocalDB");

    final Object versionInDB = localDB.get(META_DB, KEY_VERSION);
    final String currentVersion = "version=" + settings.version;
    final boolean result = currentVersion.equals(versionInDB);

    if (!result) {
      LOGGER.info(
          "existing db version does not match current db version db=("
              + versionInDB
              + ")  current=("
              + currentVersion
              + "), clearing db");
      localDB.truncate(WORDS_DB);
      localDB.put(META_DB, KEY_VERSION, currentVersion);
      localDB.remove(META_DB, KEY_OLDEST_ENTRY);
    } else {
      LOGGER.trace(
          "existing db version matches current db version db=("
              + versionInDB
              + ")  current=("
              + currentVersion
              + ")");
    }

    return result;
  }
Пример #4
0
 @Override
 protected void setUp() throws Exception {
   super.setUp(); // To change body of overridden methods use File | Settings | File Templates.
   TestHelper.setupLogging();
   final File fileLocation = new File(TestHelper.getParameter("pwmDBlocation"));
   pwmDB = LocalDBFactory.getInstance(fileLocation, false, null, null);
   pwmDB.truncate(TEST_DB);
   Assert.assertEquals(0, pwmDB.size(TEST_DB));
 }
Пример #5
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;
 }
Пример #6
0
 public void testSize() throws LocalDBException {
   final long startTime = System.currentTimeMillis();
   for (final LocalDB.DB loopDB : LocalDB.DB.values()) {
     final int size = pwmDB.size(loopDB);
     System.out.println(loopDB + " size=" + size);
   }
   System.out.println("total duration: " + TimeDuration.fromCurrent(startTime).asLongString());
 }
Пример #7
0
 @Override
 protected void tearDown() throws Exception {
   super.tearDown();
   if (pwmDB != null) {
     pwmDB.close();
     pwmDB = null;
   }
 }
Пример #8
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!");
  }
Пример #9
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());
      }
    }
  }
Пример #10
0
 public int size() {
   if (localDB != null) {
     try {
       return localDB.size(WORDS_DB);
     } catch (Exception e) {
       LOGGER.error("error checking wordlist size: " + e.getMessage());
       return 0;
     }
   } else {
     return 0;
   }
 }
Пример #11
0
  public String readAppAttribute(final AppAttribute appAttribute) {
    if (localDB == null || localDB.status() != LocalDB.Status.OPEN) {
      LOGGER.error("error retrieving key '" + appAttribute.getKey() + "', localDB unavailable: ");
      return null;
    }

    if (appAttribute == null) {
      return null;
    }

    try {
      return localDB.get(LocalDB.DB.PWM_META, appAttribute.getKey());
    } catch (Exception e) {
      LOGGER.error(
          "error retrieving key '"
              + appAttribute.getKey()
              + "' installation date from localDB: "
              + e.getMessage());
    }
    return null;
  }
Пример #12
0
  public void writeAppAttribute(final AppAttribute appAttribute, final String value) {
    if (localDB == null || localDB.status() != LocalDB.Status.OPEN) {
      LOGGER.error("error writing key '" + appAttribute.getKey() + "', localDB unavailable: ");
      return;
    }

    if (appAttribute == null) {
      return;
    }

    try {
      if (value == null) {
        localDB.remove(LocalDB.DB.PWM_META, appAttribute.getKey());
      } else {
        localDB.put(LocalDB.DB.PWM_META, appAttribute.getKey(), value);
      }
    } catch (Exception e) {
      LOGGER.error(
          "error retrieving key '"
              + appAttribute.getKey()
              + "' installation date from localDB: "
              + e.getMessage());
    }
  }
Пример #13
0
  public StatisticsBundle getStatBundleForKey(final String key) {
    if (key == null || key.length() < 1 || KEY_CUMULATIVE.equals(key)) {
      return statsCummulative;
    }

    if (KEY_CURRENT.equals(key)) {
      return statsCurrent;
    }

    if (currentDailyKey.toString().equals(key)) {
      return statsDaily;
    }

    if (cachedStoredStats.containsKey(key)) {
      return cachedStoredStats.get(key);
    }

    if (localDB == null) {
      return null;
    }

    try {
      final String storedStat = localDB.get(LocalDB.DB.PWM_STATS, key);
      final StatisticsBundle returnBundle;
      if (storedStat != null && storedStat.length() > 0) {
        returnBundle = StatisticsBundle.input(storedStat);
      } else {
        returnBundle = new StatisticsBundle();
      }
      cachedStoredStats.put(key, returnBundle);
      return returnBundle;
    } catch (LocalDBException e) {
      LOGGER.error("error retrieving stored stat for " + key + ": " + e.getMessage());
    }

    return null;
  }
Пример #14
0
 private boolean remove(StorageKey key) throws LocalDBException {
   return localDB.remove(DB, key.getKey());
 }
Пример #15
0
  private void init(final PwmApplication pwmApplication, final long maxAgeMs) {
    status = STATUS.OPENING;
    final long startTime = System.currentTimeMillis();

    try {
      checkDbVersion();
    } catch (Exception e) {
      LOGGER.error("error checking db version", e);
      status = STATUS.CLOSED;
      return;
    }

    try {
      final String oldestEntryStr = localDB.get(META_DB, KEY_OLDEST_ENTRY);
      if (oldestEntryStr == null || oldestEntryStr.length() < 1) {
        oldestEntry = 0;
        LOGGER.trace("no oldestEntry timestamp stored, will rescan");
      } else {
        oldestEntry = Long.parseLong(oldestEntryStr);
        LOGGER.trace(
            "oldest timestamp loaded from localDB, age is "
                + TimeDuration.fromCurrent(oldestEntry).asCompactString());
      }
    } catch (LocalDBException e) {
      LOGGER.error(
          "unexpected error loading oldest-entry meta record, will remain closed: "
              + e.getMessage(),
          e);
      status = STATUS.CLOSED;
      return;
    }

    try {
      final int size = localDB.size(WORDS_DB);
      final StringBuilder sb = new StringBuilder();
      sb.append("open with ").append(size).append(" words (");
      sb.append(new TimeDuration(System.currentTimeMillis(), startTime).asCompactString())
          .append(")");
      sb.append(", maxAgeMs=").append(new TimeDuration(maxAgeMs).asCompactString());
      sb.append(", oldestEntry=")
          .append(new TimeDuration(System.currentTimeMillis(), oldestEntry).asCompactString());
      LOGGER.info(sb.toString());
    } catch (LocalDBException e) {
      LOGGER.error(
          "unexpected error examining size of DB, will remain closed: " + e.getMessage(), e);
      status = STATUS.CLOSED;
      return;
    }

    status = STATUS.OPEN;
    // populateFromWordlist();  //only used for debugging!!!

    if (pwmApplication.getApplicationMode() == PwmApplication.MODE.RUNNING
        || pwmApplication.getApplicationMode() == PwmApplication.MODE.CONFIGURATION) {
      long frequencyMs = maxAgeMs > MAX_CLEANER_FREQUENCY ? MAX_CLEANER_FREQUENCY : maxAgeMs;
      frequencyMs = frequencyMs < MIN_CLEANER_FREQUENCY ? MIN_CLEANER_FREQUENCY : frequencyMs;

      LOGGER.debug(
          "scheduling cleaner task to run once every "
              + new TimeDuration(frequencyMs).asCompactString());
      final String threadName = Helper.makeThreadName(pwmApplication, this.getClass()) + " timer";
      cleanerTimer = new Timer(threadName, true);
      cleanerTimer.schedule(new CleanerTask(), 1000, frequencyMs);
    }
  }
Пример #16
0
 private void write(StorageKey key, UserCacheRecord cacheBean) throws LocalDBException {
   final String jsonValue = JsonUtil.serialize(cacheBean);
   localDB.put(DB, key.getKey(), jsonValue);
 }
Пример #17
0
  public void init(final PwmApplication pwmApplication) throws PwmException {
    settings.maxAgeMs =
        1000
            * pwmApplication
                .getConfig()
                .readSettingAsLong(PwmSetting.PASSWORD_SHAREDHISTORY_MAX_AGE); // convert to MS;
    settings.caseInsensitive =
        Boolean.parseBoolean(
            pwmApplication
                .getConfig()
                .readAppProperty(AppProperty.SECURITY_SHAREDHISTORY_CASE_INSENSITIVE));
    settings.hashName =
        pwmApplication.getConfig().readAppProperty(AppProperty.SECURITY_SHAREDHISTORY_HASH_NAME);
    settings.hashIterations =
        Integer.parseInt(
            pwmApplication
                .getConfig()
                .readAppProperty(AppProperty.SECURITY_SHAREDHISTORY_HASH_ITERATIONS));
    settings.version =
        "2"
            + "_"
            + settings.hashName
            + "_"
            + settings.hashIterations
            + "_"
            + settings.caseInsensitive;

    final int SALT_LENGTH =
        Integer.parseInt(
            pwmApplication
                .getConfig()
                .readAppProperty(AppProperty.SECURITY_SHAREDHISTORY_SALT_LENGTH));
    this.localDB = pwmApplication.getLocalDB();

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

    if (settings.maxAgeMs < 1) {
      LOGGER.debug("max age=" + settings.maxAgeMs + ", will remain closed");
      needsClearing = true;
    }

    {
      this.salt = localDB.get(META_DB, KEY_SALT);
      if (salt == null || salt.length() < SALT_LENGTH) {
        LOGGER.warn("stored global salt value is not present, creating new salt");
        this.salt = PwmRandom.getInstance().alphaNumericString(SALT_LENGTH);
        localDB.put(META_DB, KEY_SALT, this.salt);
        needsClearing = true;
      }
    }

    if (needsClearing) {
      LOGGER.trace("clearing wordlist");
      try {
        localDB.truncate(WORDS_DB);
      } catch (Exception e) {
        LOGGER.error("error during wordlist truncate", e);
      }
    }

    new Thread(
            new Runnable() {
              public void run() {
                LOGGER.debug("starting up in background thread");
                init(pwmApplication, settings.maxAgeMs);
              }
            },
            Helper.makeThreadName(pwmApplication, this.getClass()) + " initializer")
        .start();
  }
Пример #18
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;
  }
Пример #19
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());
    }
  }
Пример #20
0
 private void clear() throws LocalDBException {
   localDB.truncate(DB);
 }
Пример #21
0
 private int size() throws LocalDBException {
   return localDB.size(DB);
 }
Пример #22
0
 public void testPut() throws LocalDBException {
   Assert.assertNull(pwmDB.get(TEST_DB, "testKey1"));
   pwmDB.put(TEST_DB, "testKey1", "testValue1");
   Assert.assertEquals(pwmDB.get(TEST_DB, "testKey1"), "testValue1");
 }