Пример #1
0
  private void doHealthChecks() {
    if (status != STATUS.OPEN) {
      return;
    }

    LOGGER.trace("beginning health check process");
    final List<HealthRecord> newResults = new ArrayList<>();
    for (final HealthChecker loopChecker : healthCheckers) {
      try {
        final List<HealthRecord> loopResults = loopChecker.doHealthCheck(pwmApplication);
        if (loopResults != null) {
          newResults.addAll(loopResults);
        }
      } catch (Exception e) {
        LOGGER.warn("unexpected error during healthCheck: " + e.getMessage(), e);
      }
    }
    for (final PwmService service : pwmApplication.getPwmServices()) {
      try {
        final List<HealthRecord> loopResults = service.healthCheck();
        if (loopResults != null) {
          newResults.addAll(loopResults);
        }
      } catch (Exception e) {
        LOGGER.warn("unexpected error during healthCheck: " + e.getMessage(), e);
      }
    }
    final Set<HealthRecord> sortedRecordList = new TreeSet<>();
    sortedRecordList.addAll(newResults);
    healthRecords = Collections.unmodifiableSet(sortedRecordList);
    lastHealthCheckDate = new Date();
    LOGGER.trace("health check process completed");
  }
Пример #2
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);
  }
Пример #3
0
  private String fetchInstanceID(final LocalDB localDB, final PwmApplication pwmApplication) {
    String newInstanceID =
        pwmApplication.getConfig().readSettingAsString(PwmSetting.PWM_INSTANCE_NAME);

    if (newInstanceID != null && newInstanceID.trim().length() > 0) {
      return newInstanceID;
    }

    newInstanceID = readAppAttribute(AppAttribute.INSTANCE_ID);

    if (newInstanceID == null || newInstanceID.length() < 1) {
      newInstanceID = Long.toHexString(PwmRandom.getInstance().nextLong()).toUpperCase();
      LOGGER.info("generated new random instanceID " + newInstanceID);

      if (localDB != null) {
        writeAppAttribute(AppAttribute.INSTANCE_ID, newInstanceID);
      }
    } else {
      LOGGER.trace("retrieved instanceID " + newInstanceID + "" + " from localDB");
    }

    if (newInstanceID.length() < 1) {
      newInstanceID = DEFAULT_INSTANCE_ID;
    }

    return newInstanceID;
  }
Пример #4
0
  void restUploadWordlist(final PwmRequest pwmRequest)
      throws IOException, ServletException, PwmUnrecoverableException {

    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    final HttpServletRequest req = pwmRequest.getHttpServletRequest();

    if (!ServletFileUpload.isMultipartContent(req)) {
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.ERROR_UNKNOWN, "no file found in upload");
      pwmRequest.outputJsonResult(RestResultBean.fromError(errorInformation, pwmRequest));
      LOGGER.error(pwmRequest, "error during import: " + errorInformation.toDebugStr());
      return;
    }

    final InputStream inputStream =
        ServletHelper.readFileUpload(pwmRequest.getHttpServletRequest(), "uploadFile");
    try {
      pwmApplication.getWordlistManager().populate(inputStream);
    } catch (PwmUnrecoverableException e) {
      final ErrorInformation errorInfo =
          new ErrorInformation(PwmError.ERROR_UNKNOWN, e.getMessage());
      final RestResultBean restResultBean = RestResultBean.fromError(errorInfo, pwmRequest);
      LOGGER.debug(pwmRequest, errorInfo.toDebugStr());
      pwmRequest.outputJsonResult(restResultBean);
      return;
    }

    pwmRequest.outputJsonResult(
        RestResultBean.forSuccessMessage(pwmRequest, Message.Success_Unknown));
  }
Пример #5
0
  private static void invokePostChangePasswordActions(
      final PwmSession pwmSession, final String newPassword) throws PwmUnrecoverableException {
    final List<PostChangePasswordAction> postChangePasswordActions =
        pwmSession.getUserSessionDataCacheBean().removePostChangePasswordActions();
    if (postChangePasswordActions == null || postChangePasswordActions.isEmpty()) {
      LOGGER.trace(pwmSession, "no post change password actions pending from previous operations");
      return;
    }

    for (final PostChangePasswordAction postChangePasswordAction : postChangePasswordActions) {
      try {
        postChangePasswordAction.doAction(pwmSession, newPassword);
      } catch (PwmUnrecoverableException e) {
        LOGGER.error(
            pwmSession,
            "error during post change password action '"
                + postChangePasswordAction.getLabel()
                + "' "
                + e.getMessage());
        throw e;
      } catch (Exception e) {
        LOGGER.error(
            pwmSession,
            "unexpected error during post change password action '"
                + postChangePasswordAction.getLabel()
                + "' "
                + e.getMessage(),
            e);
        final ErrorInformation errorInfo =
            new ErrorInformation(PwmError.ERROR_UNKNOWN, e.getMessage());
        throw new PwmUnrecoverableException(errorInfo);
      }
    }
  }
Пример #6
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;
  }
Пример #7
0
  private void doGenerateSupportZip(final PwmRequest pwmRequest)
      throws IOException, ServletException {
    final PwmResponse resp = pwmRequest.getPwmResponse();
    resp.setHeader(
        PwmConstants.HttpHeader.ContentDisposition,
        "attachment;filename=" + PwmConstants.PWM_APP_NAME + "-Support.zip");
    resp.setContentType(PwmConstants.ContentTypeValue.zip);

    final String pathPrefix = PwmConstants.PWM_APP_NAME + "-Support" + "/";

    ZipOutputStream zipOutput = null;
    try {
      zipOutput = new ZipOutputStream(resp.getOutputStream(), PwmConstants.DEFAULT_CHARSET);
      DebugItemGenerator.outputZipDebugFile(pwmRequest, zipOutput, pathPrefix);
    } catch (Exception e) {
      LOGGER.error(pwmRequest, "error during zip debug building: " + e.getMessage());
    } finally {
      if (zipOutput != null) {
        try {
          zipOutput.close();
        } catch (Exception e) {
          LOGGER.error(pwmRequest, "error during zip debug closing: " + e.getMessage());
        }
      }
    }
  }
Пример #8
0
  @Override
  void closeConnection(final Connection connection) throws SQLException {

    if (aggressiveCompact) {
      CallableStatement statement = null;
      try {
        LOCK.writeLock().lock();
        final java.util.Date start = new java.util.Date();
        LOGGER.trace("beginning shutdown compact");
        statement = dbConnection.prepareCall("SHUTDOWN COMPACT");
        statement.execute();
        LOGGER.trace(
            "completed shutdown compact in " + TimeDuration.fromCurrent(start).asCompactString());
      } catch (SQLException ex) {
        LOGGER.error("error during shutdown compact: " + ex.getMessage());
      } finally {
        close(statement);
        LOCK.writeLock().unlock();
      }
    }

    try {
      connection.close();
      if (driver != null) {
        DriverManager.deregisterDriver(driver);
        driver = null;
      }
    } catch (Exception e) {
      LOGGER.error("error during H2 shutdown: " + e.getMessage());
    }
  }
Пример #9
0
  private void restUpdateLdapForm(
      final PwmRequest pwmRequest, final ConfigGuideBean configGuideBean)
      throws IOException, PwmUnrecoverableException {
    final StoredConfigurationImpl storedConfiguration = configGuideBean.getStoredConfiguration();
    final Map<String, String> incomingFormData = pwmRequest.readBodyAsJsonStringMap();

    if (incomingFormData != null) {
      configGuideBean.getFormData().putAll(incomingFormData);
    }

    if (incomingFormData != null
        && incomingFormData.get(PARAM_TEMPLATE_NAME) != null
        && !incomingFormData.get(PARAM_TEMPLATE_NAME).isEmpty()) {
      try {
        final PwmSettingTemplate template =
            PwmSettingTemplate.valueOf(incomingFormData.get(PARAM_TEMPLATE_NAME));
        if (configGuideBean.getSelectedTemplate() != template) {
          LOGGER.debug(
              pwmRequest, "resetting form defaults using " + template.toString() + " template");
          final Map<String, String> defaultForm = defaultForm(template);
          configGuideBean.getFormData().putAll(defaultForm);
          configGuideBean.setSelectedTemplate(template);
          storedConfiguration.setTemplate(template);
        }
      } catch (Exception e) {
        LOGGER.error("unknown template set request: " + e.getMessage());
      }
    }

    final RestResultBean restResultBean = new RestResultBean();
    pwmRequest.outputJsonResult(restResultBean);
    convertFormToConfiguration(
        storedConfiguration, configGuideBean.getFormData(), incomingFormData);
    // LOGGER.info("config: " + storedConfiguration.toString());
  }
Пример #10
0
  @Override
  public void clearOtpUserConfiguration(
      final PwmSession pwmSession, final UserIdentity theUser, final String userGUID)
      throws PwmUnrecoverableException {
    if (userGUID == null || userGUID.length() < 1) {
      throw new PwmUnrecoverableException(
          new ErrorInformation(
              PwmError.ERROR_MISSING_GUID,
              "cannot save OTP secret to remote database, user "
                  + theUser
                  + " does not have a guid"));
    }

    LOGGER.trace(
        "attempting to clear OTP secret for "
            + theUser
            + " in remote database (key="
            + userGUID
            + ")");

    try {
      final DatabaseAccessorImpl databaseAccessor = pwmApplication.getDatabaseAccessor();
      databaseAccessor.remove(DatabaseTable.OTP, userGUID);
      LOGGER.info(
          "cleared OTP secret for " + theUser + " in remote database (key=" + userGUID + ")");
    } catch (DatabaseException ex) {
      final ErrorInformation errorInfo =
          new ErrorInformation(
              PwmError.ERROR_WRITING_OTP_SECRET,
              "unexpected error saving otp to db: " + ex.getMessage());
      final PwmUnrecoverableException pwmOE = new PwmUnrecoverableException(errorInfo);
      pwmOE.initCause(ex);
      throw pwmOE;
    }
  }
Пример #11
0
  public static void incrementStat(final PwmApplication pwmApplication, final Statistic statistic) {
    if (pwmApplication == null) {
      LOGGER.error(
          "skipping requested statistic increment of " + statistic + " due to null pwmApplication");
      return;
    }

    final StatisticsManager statisticsManager = pwmApplication.getStatisticsManager();
    if (statisticsManager == null) {
      LOGGER.error(
          "skipping requested statistic increment of "
              + statistic
              + " due to null statisticsManager");
      return;
    }

    if (statisticsManager.status() != STATUS.OPEN) {
      LOGGER.trace(
          "skipping requested statistic increment of "
              + statistic
              + " due to StatisticsManager being closed");
      return;
    }

    statisticsManager.incrementValue(statistic);
  }
Пример #12
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());
    }
  }
Пример #13
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;
  }
Пример #14
0
  public static PwmPasswordPolicy readPasswordPolicyForUser(
      final PwmApplication pwmApplication,
      final SessionLabel pwmSession,
      final UserIdentity userIdentity,
      final ChaiUser theUser,
      final Locale locale)
      throws PwmUnrecoverableException {
    final long startTime = System.currentTimeMillis();
    final PasswordPolicySource ppSource =
        PasswordPolicySource.valueOf(
            pwmApplication.getConfig().readSettingAsString(PwmSetting.PASSWORD_POLICY_SOURCE));

    final PwmPasswordPolicy returnPolicy;
    switch (ppSource) {
      case MERGE:
        final PwmPasswordPolicy pwmPolicy =
            determineConfiguredPolicyProfileForUser(
                pwmApplication, pwmSession, userIdentity, locale);
        final PwmPasswordPolicy userPolicy = readLdapPasswordPolicy(pwmApplication, theUser);
        LOGGER.trace(
            pwmSession,
            "read user policy for '"
                + theUser.getEntryDN()
                + "', policy: "
                + userPolicy.toString());
        returnPolicy = pwmPolicy.merge(userPolicy);
        LOGGER.debug(
            pwmSession,
            "merged user password policy of '"
                + theUser.getEntryDN()
                + "' with PWM configured policy: "
                + returnPolicy.toString());
        break;

      case LDAP:
        returnPolicy = readLdapPasswordPolicy(pwmApplication, theUser);
        LOGGER.debug(
            pwmSession,
            "discovered assigned password policy for "
                + theUser.getEntryDN()
                + " "
                + returnPolicy.toString());
        break;

      case PWM:
        returnPolicy =
            determineConfiguredPolicyProfileForUser(
                pwmApplication, pwmSession, userIdentity, locale);
        break;

      default:
        throw new IllegalStateException("unknown policy source defined: " + ppSource.name());
    }

    LOGGER.trace(
        pwmSession,
        "readPasswordPolicyForUser completed in "
            + TimeDuration.fromCurrent(startTime).asCompactString());
    return returnPolicy;
  }
Пример #15
0
  public UserCacheRecord updateUserCache(final UserInfoBean userInfoBean)
      throws PwmUnrecoverableException {
    final StorageKey storageKey = StorageKey.fromUserInfoBean(userInfoBean);

    boolean preExisting = false;
    try {
      UserCacheRecord userCacheRecord = readStorageKey(storageKey);
      if (userCacheRecord == null) {
        userCacheRecord = new UserCacheRecord();
      } else {
        preExisting = true;
      }
      userCacheRecord.addUiBeanData(userInfoBean);
      store(userCacheRecord);
      return userCacheRecord;
    } catch (LocalDBException e) {
      LOGGER.error("unable to store user status cache to localdb: " + e.getMessage());
    }
    LOGGER.trace(
        "updateCache: "
            + (preExisting ? "updated existing" : "created new")
            + " user cache for "
            + userInfoBean.getUserIdentity()
            + " user key "
            + storageKey.getKey());
    return null;
  }
Пример #16
0
  private void handleEnterCodeRequest(
      final PwmRequest pwmRequest, final UpdateProfileBean updateProfileBean)
      throws PwmUnrecoverableException, IOException, ServletException, ChaiUnavailableException {
    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    final PwmSession pwmSession = pwmRequest.getPwmSession();
    final String userEnteredCode = pwmRequest.readParameterAsString(PwmConstants.PARAM_TOKEN);

    boolean tokenPassed = false;
    ErrorInformation errorInformation = null;
    try {
      final TokenPayload tokenPayload =
          pwmApplication
              .getTokenService()
              .processUserEnteredCode(
                  pwmSession, pwmRequest.getUserInfoIfLoggedIn(), null, userEnteredCode);
      if (tokenPayload != null) {
        if (TokenType.UPDATE_EMAIL.matchesName(tokenPayload.getName())) {
          LOGGER.debug(pwmRequest, "email token passed");

          updateProfileBean
              .getTokenVerificationProgress()
              .getPassedTokens()
              .add(TokenVerificationProgress.TokenChannel.EMAIL);
          updateProfileBean
              .getTokenVerificationProgress()
              .getIssuedTokens()
              .add(TokenVerificationProgress.TokenChannel.EMAIL);
          updateProfileBean.getTokenVerificationProgress().setPhase(null);
          tokenPassed = true;
        } else if (TokenType.UPDATE_SMS.matchesName(tokenPayload.getName())) {
          LOGGER.debug(pwmRequest, "SMS token passed");
          updateProfileBean
              .getTokenVerificationProgress()
              .getPassedTokens()
              .add(TokenVerificationProgress.TokenChannel.SMS);
          updateProfileBean
              .getTokenVerificationProgress()
              .getIssuedTokens()
              .add(TokenVerificationProgress.TokenChannel.SMS);
          updateProfileBean.getTokenVerificationProgress().setPhase(null);
          tokenPassed = true;
        } else {
          final String errorMsg = "token name/type is not recognized: " + tokenPayload.getName();
          errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT, errorMsg);
        }
      }
    } catch (PwmOperationalException e) {
      final String errorMsg = "token incorrect: " + e.getMessage();
      errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT, errorMsg);
    }

    if (!tokenPassed) {
      if (errorInformation == null) {
        errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT);
      }
      LOGGER.debug(pwmSession, errorInformation.toDebugStr());
      pwmRequest.setResponseError(errorInformation);
    }
  }
Пример #17
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));
 }
Пример #18
0
  public static void verifyApplicationPath(final File applicationPath)
      throws PwmUnrecoverableException {

    if (applicationPath == null) {
      throw new PwmUnrecoverableException(
          new ErrorInformation(
              PwmError.ERROR_STARTUP_ERROR, "unable to determine valid applicationPath"));
    }

    LOGGER.trace("examining applicationPath of " + applicationPath.getAbsolutePath() + "");

    if (!applicationPath.exists()) {
      throw new PwmUnrecoverableException(
          new ErrorInformation(
              PwmError.ERROR_STARTUP_ERROR,
              "applicationPath " + applicationPath.getAbsolutePath() + " does not exist"));
    }

    if (!applicationPath.canRead()) {
      throw new PwmUnrecoverableException(
          new ErrorInformation(
              PwmError.ERROR_STARTUP_ERROR,
              "unable to read from applicationPath " + applicationPath.getAbsolutePath() + ""));
    }

    if (!applicationPath.canWrite()) {
      throw new PwmUnrecoverableException(
          new ErrorInformation(
              PwmError.ERROR_STARTUP_ERROR,
              "unable to write to applicationPath " + applicationPath.getAbsolutePath() + ""));
    }

    final File infoFile =
        new File(
            applicationPath.getAbsolutePath()
                + File.separator
                + PwmConstants.APPLICATION_PATH_INFO_FILE);
    LOGGER.trace(
        "checking "
            + infoFile.getAbsolutePath()
            + " status, (applicationPathType="
            + PwmEnvironment.ApplicationPathType.derived
            + ")");
    if (infoFile.exists()) {
      final String errorMsg =
          "The file "
              + infoFile.getAbsolutePath()
              + " exists, and an applicationPath was not explicitly specified."
              + "  This happens when an applicationPath was previously configured, but is not now being specified."
              + "  An explicit applicationPath parameter must be specified, or the file can be removed if the applicationPath should be changed to the default /WEB-INF directory.";
      throw new PwmUnrecoverableException(
          new ErrorInformation(PwmError.ERROR_STARTUP_ERROR, errorMsg));
    } else {
      LOGGER.trace("marker file " + infoFile.getAbsolutePath() + " does not exist");
    }
  }
Пример #19
0
  static Set<TokenVerificationProgress.TokenChannel> determineTokenPhaseRequired(
      final PwmRequest pwmRequest,
      final UpdateProfileBean updateProfileBean,
      final UpdateAttributesProfile updateAttributesProfile)
      throws PwmUnrecoverableException {
    final Set<TokenVerificationProgress.TokenChannel> returnObj = new HashSet<>();

    final Map<String, String> userFormData = updateProfileBean.getFormData();
    Map<String, String> ldapData = null;

    if (updateAttributesProfile.readSettingAsBoolean(
        PwmSetting.UPDATE_PROFILE_EMAIL_VERIFICATION)) {
      final String emailAddressAttribute =
          pwmRequest.getConfig().readSettingAsString(PwmSetting.EMAIL_USER_MAIL_ATTRIBUTE);
      if (userFormData.containsKey(emailAddressAttribute)) {
        ldapData = formDataFromLdap(pwmRequest, updateAttributesProfile);
        if (userFormData.get(emailAddressAttribute) != null
            && !userFormData
                .get(emailAddressAttribute)
                .equalsIgnoreCase(ldapData.get(emailAddressAttribute))) {
          returnObj.add(TokenVerificationProgress.TokenChannel.EMAIL);
        }
      } else {
        LOGGER.warn(
            pwmRequest,
            "email verification enabled, but email attribute '"
                + emailAddressAttribute
                + "' is not in update form");
      }
    }

    if (updateAttributesProfile.readSettingAsBoolean(PwmSetting.UPDATE_PROFILE_SMS_VERIFICATION)) {
      final String phoneNumberAttribute =
          pwmRequest.getConfig().readSettingAsString(PwmSetting.SMS_USER_PHONE_ATTRIBUTE);
      if (userFormData.containsKey(phoneNumberAttribute)) {
        if (ldapData == null) {
          ldapData = formDataFromLdap(pwmRequest, updateAttributesProfile);
        }
        if (userFormData.get(phoneNumberAttribute) != null
            && !userFormData
                .get(phoneNumberAttribute)
                .equalsIgnoreCase(ldapData.get(phoneNumberAttribute))) {
          returnObj.add(TokenVerificationProgress.TokenChannel.SMS);
        }
      } else {
        LOGGER.warn(
            pwmRequest,
            "sms verification enabled, but phone attribute '"
                + phoneNumberAttribute
                + "' is not in update form");
      }
    }

    return returnObj;
  }
Пример #20
0
  public ResponseSet readResponseSet(
      final ChaiUser theUser, final UserIdentity userIdentity, final String userGUID)
      throws PwmUnrecoverableException {
    if (userGUID == null || userGUID.length() < 1) {
      final String errorMsg =
          "user "
              + theUser.getEntryDN()
              + " does not have a guid, unable to search for responses in remote database";
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.ERROR_MISSING_GUID, errorMsg);
      throw new PwmUnrecoverableException(errorInformation);
    }

    try {
      final DatabaseAccessorImpl databaseAccessor = pwmApplication.getDatabaseAccessor();
      final String responseStringBlob = databaseAccessor.get(DatabaseTable.PWM_RESPONSES, userGUID);
      if (responseStringBlob != null && responseStringBlob.length() > 0) {
        final ResponseSet userResponseSet =
            ChaiResponseSet.parseChaiResponseSetXML(responseStringBlob, theUser);
        LOGGER.debug(
            "found responses for "
                + theUser.getEntryDN()
                + " in remote database: "
                + userResponseSet.toString());
        return userResponseSet;
      } else {
        LOGGER.trace(
            "user guid for "
                + theUser.getEntryDN()
                + " not found in remote database (key="
                + userGUID
                + ")");
      }
    } catch (ChaiValidationException e) {
      final String errorMsg =
          "unexpected error reading responses for "
              + theUser.getEntryDN()
              + " from remote database: "
              + e.getMessage();
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg);
      throw new PwmUnrecoverableException(errorInformation);
    } catch (PwmOperationalException e) {
      final String errorMsg =
          "unexpected error reading responses for "
              + theUser.getEntryDN()
              + " from remote database: "
              + e.getMessage();
      final ErrorInformation errorInformation =
          new ErrorInformation(e.getErrorInformation().getError(), errorMsg);
      throw new PwmUnrecoverableException(errorInformation);
    }
    return null;
  }
Пример #21
0
  @Override
  public void init(PwmApplication pwmApplication) throws PwmException {
    status = STATUS.OPENING;
    this.pwmApplication = pwmApplication;

    if (pwmApplication.getApplicationMode() == PwmApplication.MODE.READ_ONLY) {
      LOGGER.debug(
          PwmConstants.REPORTING_SESSION_LABEL,
          "application mode is read-only, will remain closed");
      status = STATUS.CLOSED;
      return;
    }

    if (pwmApplication.getLocalDB() == null
        || LocalDB.Status.OPEN != pwmApplication.getLocalDB().status()) {
      LOGGER.debug(PwmConstants.REPORTING_SESSION_LABEL, "LocalDB is not open, will remain closed");
      status = STATUS.CLOSED;
      return;
    }

    if (!pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.REPORTING_ENABLE)) {
      LOGGER.debug(
          PwmConstants.REPORTING_SESSION_LABEL,
          "reporting module is not enabled, will remain closed");
      status = STATUS.CLOSED;
      clear();
      return;
    }

    try {
      userCacheService = new UserCacheService();
      userCacheService.init(pwmApplication);
    } catch (Exception e) {
      LOGGER.error(PwmConstants.REPORTING_SESSION_LABEL, "unable to init cache service");
      status = STATUS.CLOSED;
      return;
    }

    settings = ReportSettings.readSettingsFromConfig(pwmApplication.getConfig());
    summaryData = ReportSummaryData.newSummaryData(settings.getTrackDays());

    executorService =
        Executors.newSingleThreadScheduledExecutor(
            Helper.makePwmThreadFactory(
                Helper.makeThreadName(pwmApplication, this.getClass()) + "-", true));

    String startupMsg = "report service started";
    LOGGER.debug(startupMsg);

    executorService.submit(new InitializationTask());

    status = STATUS.OPEN;
  }
Пример #22
0
 public void clear() throws LocalDBException, PwmUnrecoverableException {
   final Date startTime = new Date();
   LOGGER.info(PwmConstants.REPORTING_SESSION_LABEL, "clearing cached report data");
   if (userCacheService != null) {
     userCacheService.clear();
   }
   summaryData = ReportSummaryData.newSummaryData(settings.getTrackDays());
   reportStatus = new ReportStatusInfo(settings.getSettingsHash());
   saveTempData();
   LOGGER.info(
       PwmConstants.REPORTING_SESSION_LABEL,
       "finished clearing report " + TimeDuration.fromCurrent(startTime).asCompactString());
 }
Пример #23
0
  private void initServices() throws PwmUnrecoverableException {
    for (final Class<? extends PwmService> serviceClass : PWM_SERVICE_CLASSES) {
      final Date startTime = new Date();
      final PwmService newServiceInstance;
      try {
        final Object newInstance = serviceClass.newInstance();
        newServiceInstance = (PwmService) newInstance;
      } catch (Exception e) {
        final String errorMsg =
            "unexpected error instantiating service class '"
                + serviceClass.getName()
                + "', error: "
                + e.toString();
        LOGGER.fatal(errorMsg, e);
        throw new PwmUnrecoverableException(
            new ErrorInformation(PwmError.ERROR_STARTUP_ERROR, errorMsg));
      }

      try {
        LOGGER.debug("initializing service " + serviceClass.getName());
        newServiceInstance.init(this);
        LOGGER.debug(
            "completed initialization of service "
                + serviceClass.getName()
                + " in "
                + TimeDuration.fromCurrent(startTime).asCompactString()
                + ", status="
                + newServiceInstance.status());
      } catch (PwmException e) {
        LOGGER.warn(
            "error instantiating service class '"
                + serviceClass.getName()
                + "', service will remain unavailable, error: "
                + e.getMessage());
      } catch (Exception e) {
        String errorMsg =
            "unexpected error instantiating service class '"
                + serviceClass.getName()
                + "', cannot load, error: "
                + e.getMessage();
        if (e.getCause() != null) {
          errorMsg += ", cause: " + e.getCause();
        }
        LOGGER.fatal(errorMsg);
        throw new PwmUnrecoverableException(
            new ErrorInformation(PwmError.ERROR_STARTUP_ERROR, errorMsg));
      }
      pwmServices.put(serviceClass, newServiceInstance);
    }
  }
Пример #24
0
  private static Date determinePwdLastModified(
      final PwmApplication pwmApplication,
      final SessionLabel sessionLabel,
      final ChaiUser theUser,
      final UserIdentity userIdentity)
      throws ChaiUnavailableException, PwmUnrecoverableException {
    // fetch last password modification time from pwm last update attribute operation
    try {
      final Date chaiReadDate = theUser.readPasswordModificationDate();
      if (chaiReadDate != null) {
        LOGGER.trace(
            sessionLabel,
            "read last user password change timestamp (via chai) as: "
                + PwmConstants.DEFAULT_DATETIME_FORMAT.format(chaiReadDate));
        return chaiReadDate;
      }
    } catch (ChaiOperationException e) {
      LOGGER.error(
          sessionLabel,
          "unexpected error reading password last modified timestamp: " + e.getMessage());
    }

    final LdapProfile ldapProfile =
        pwmApplication.getConfig().getLdapProfiles().get(userIdentity.getLdapProfileID());
    final String pwmLastSetAttr =
        ldapProfile.readSettingAsString(PwmSetting.PASSWORD_LAST_UPDATE_ATTRIBUTE);
    if (pwmLastSetAttr != null && pwmLastSetAttr.length() > 0) {
      try {
        final Date pwmPwdLastModified = theUser.readDateAttribute(pwmLastSetAttr);
        LOGGER.trace(
            sessionLabel,
            "read pwmPasswordChangeTime as: "
                + (pwmPwdLastModified == null
                    ? "n/a"
                    : PwmConstants.DEFAULT_DATETIME_FORMAT.format(pwmPwdLastModified)));
        return pwmPwdLastModified;
      } catch (ChaiOperationException e) {
        LOGGER.error(
            sessionLabel,
            "error parsing password last modified PWM password value for user "
                + theUser.getEntryDN()
                + "; error: "
                + e.getMessage());
      }
    }

    LOGGER.debug(sessionLabel, "unable to determine time of user's last password modification");
    return null;
  }
Пример #25
0
  public static void restUploadConfig(final PwmRequest pwmRequest)
      throws PwmUnrecoverableException, IOException, ServletException {
    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    final PwmSession pwmSession = pwmRequest.getPwmSession();
    final HttpServletRequest req = pwmRequest.getHttpServletRequest();

    if (pwmApplication.getApplicationMode() == PwmApplication.MODE.RUNNING) {
      final String errorMsg = "config upload is not permitted when in running mode";
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.CONFIG_UPLOAD_FAILURE, errorMsg, new String[] {errorMsg});
      pwmRequest.respondWithError(errorInformation, true);
      return;
    }

    if (ServletFileUpload.isMultipartContent(req)) {
      final InputStream uploadedFile = ServletHelper.readFileUpload(req, "uploadFile");
      if (uploadedFile != null) {
        try {
          final StoredConfigurationImpl storedConfig =
              StoredConfigurationImpl.fromXml(uploadedFile);
          final List<String> configErrors = storedConfig.validateValues();
          if (configErrors != null && !configErrors.isEmpty()) {
            throw new PwmOperationalException(
                new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR, configErrors.get(0)));
          }
          writeConfig(ContextManager.getContextManager(req.getSession()), storedConfig);
          LOGGER.trace(pwmSession, "read config from file: " + storedConfig.toString());
          final RestResultBean restResultBean = new RestResultBean();
          restResultBean.setSuccessMessage("read message");
          pwmRequest.getPwmResponse().outputJsonResult(restResultBean);
          req.getSession().invalidate();
        } catch (PwmException e) {
          final RestResultBean restResultBean =
              RestResultBean.fromError(e.getErrorInformation(), pwmRequest);
          pwmRequest.getPwmResponse().outputJsonResult(restResultBean);
          LOGGER.error(pwmSession, e.getErrorInformation().toDebugStr());
        }
      } else {
        final ErrorInformation errorInformation =
            new ErrorInformation(
                PwmError.CONFIG_UPLOAD_FAILURE,
                "error reading config file: no file present in upload");
        final RestResultBean restResultBean =
            RestResultBean.fromError(errorInformation, pwmRequest);
        pwmRequest.getPwmResponse().outputJsonResult(restResultBean);
        LOGGER.error(pwmSession, errorInformation.toDebugStr());
      }
    }
  }
Пример #26
0
  public void clearResponses(final ChaiUser theUser, final String userGUID)
      throws PwmUnrecoverableException {
    if (userGUID == null || userGUID.length() < 1) {
      throw new PwmUnrecoverableException(
          new ErrorInformation(
              PwmError.ERROR_MISSING_GUID,
              "cannot clear responses to remote database, user "
                  + theUser.getEntryDN()
                  + " does not have a guid"));
    }

    try {
      final DatabaseAccessorImpl databaseAccessor = pwmApplication.getDatabaseAccessor();
      databaseAccessor.remove(DatabaseTable.PWM_RESPONSES, userGUID);
      LOGGER.info("cleared responses for user " + theUser.getEntryDN() + " in remote database");
    } catch (DatabaseException e) {
      final ErrorInformation errorInfo =
          new ErrorInformation(
              PwmError.ERROR_CLEARING_RESPONSES,
              "unexpected error clearing responses for "
                  + theUser.getEntryDN()
                  + " in remote database, error: "
                  + e.getMessage());
      final PwmUnrecoverableException pwmOE = new PwmUnrecoverableException(errorInfo);
      pwmOE.initCause(e);
      throw pwmOE;
    }
  }
Пример #27
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;
  }
Пример #28
0
  public void init(final Configuration config) throws PwmException {
    final Map<FileValue.FileInformation, FileValue.FileContent> fileValue =
        config.readSettingAsFile(PwmSetting.DATABASE_JDBC_DRIVER);
    final byte[] jdbcDriverBytes;
    if (fileValue != null && !fileValue.isEmpty()) {
      final FileValue.FileInformation fileInformation1 = fileValue.keySet().iterator().next();
      final FileValue.FileContent fileContent = fileValue.get(fileInformation1);
      jdbcDriverBytes = fileContent.getContents();
    } else {
      jdbcDriverBytes = null;
    }

    this.dbConfiguration =
        new DBConfiguration(
            config.readSettingAsString(PwmSetting.DATABASE_CLASS),
            config.readSettingAsString(PwmSetting.DATABASE_URL),
            config.readSettingAsString(PwmSetting.DATABASE_USERNAME),
            config.readSettingAsPassword(PwmSetting.DATABASE_PASSWORD),
            config.readSettingAsString(PwmSetting.DATABASE_COLUMN_TYPE_KEY),
            config.readSettingAsString(PwmSetting.DATABASE_COLUMN_TYPE_VALUE),
            jdbcDriverBytes);

    this.instanceID = pwmApplication == null ? null : pwmApplication.getInstanceID();
    this.traceLogging = config.readSettingAsBoolean(PwmSetting.DATABASE_DEBUG_TRACE);

    if (this.dbConfiguration.isEmpty()) {
      status = PwmService.STATUS.CLOSED;
      LOGGER.debug("skipping database connection open, no connection parameters configured");
    }
  }
Пример #29
0
 public static SchemaOperationResult extendSchema(
     ConfigGuideBean configGuideBean, final boolean doSchemaExtension) {
   final Map<String, String> form = configGuideBean.getFormData();
   final boolean ldapServerSecure = "true".equalsIgnoreCase(form.get(PARAM_LDAP_SECURE));
   final String ldapUrl =
       "ldap"
           + (ldapServerSecure ? "s" : "")
           + "://"
           + form.get(PARAM_LDAP_HOST)
           + ":"
           + form.get(PARAM_LDAP_PORT);
   try {
     final ChaiConfiguration chaiConfiguration =
         new ChaiConfiguration(
             ldapUrl, form.get(PARAM_LDAP_PROXY_DN), form.get(PARAM_LDAP_PROXY_PW));
     chaiConfiguration.setSetting(ChaiSetting.PROMISCUOUS_SSL, "true");
     final ChaiProvider chaiProvider = ChaiProviderFactory.createProvider(chaiConfiguration);
     if (doSchemaExtension) {
       return SchemaManager.extendSchema(chaiProvider);
     } else {
       return SchemaManager.checkExistingSchema(chaiProvider);
     }
   } catch (Exception e) {
     LOGGER.error("unable to create schema extender object: " + e.getMessage());
     return null;
   }
 }
Пример #30
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));
  }