Пример #1
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);
  }
Пример #2
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;
  }
Пример #3
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;
  }
Пример #4
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);
    }
  }
Пример #5
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));
 }
Пример #6
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;
  }
Пример #7
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);
    }
  }
Пример #8
0
  private static ErrorInformation sendNewPasswordEmail(
      final UserInfoBean userInfoBean,
      final PwmApplication pwmApplication,
      final MacroMachine macroMachine,
      final PasswordData newPassword,
      final String toAddress,
      final Locale userLocale)
      throws PwmOperationalException, PwmUnrecoverableException {
    final Configuration config = pwmApplication.getConfig();
    final EmailItemBean configuredEmailSetting =
        config.readSettingAsEmail(PwmSetting.EMAIL_SENDPASSWORD, userLocale);

    if (configuredEmailSetting == null) {
      final String errorMsg = "send password email contents are not configured";
      return new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg);
    }

    final EmailItemBean emailItemBean =
        new EmailItemBean(
            configuredEmailSetting.getTo(),
            configuredEmailSetting.getFrom(),
            configuredEmailSetting.getSubject(),
            configuredEmailSetting.getBodyPlain().replace("%TOKEN%", newPassword.getStringValue()),
            configuredEmailSetting.getBodyHtml().replace("%TOKEN%", newPassword.getStringValue()));
    pwmApplication.getEmailQueue().submitEmail(emailItemBean, userInfoBean, macroMachine);

    LOGGER.debug(
        "new password email to "
            + userInfoBean.getUserIdentity()
            + " added to send queue for "
            + toAddress);
    return null;
  }
Пример #9
0
  private static ErrorInformation sendNewPasswordSms(
      final UserInfoBean userInfoBean,
      final PwmApplication pwmApplication,
      final MacroMachine macroMachine,
      final PasswordData newPassword,
      final String toNumber,
      final Locale userLocale)
      throws PwmOperationalException, PwmUnrecoverableException {
    final Configuration config = pwmApplication.getConfig();
    String message =
        config.readSettingAsLocalizedString(PwmSetting.SMS_CHALLENGE_NEW_PASSWORD_TEXT, userLocale);

    if (toNumber == null || toNumber.length() < 1) {
      final String errorMsg =
          String.format(
              "unable to send new password email for '%s'; no SMS number available in ldap",
              userInfoBean.getUserIdentity());
      return new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg);
    }

    message = message.replace("%TOKEN%", newPassword.getStringValue());

    pwmApplication.sendSmsUsingQueue(new SmsItemBean(toNumber, message), macroMachine);
    LOGGER.debug(String.format("password SMS added to send queue for %s", toNumber));
    return null;
  }
Пример #10
0
  private static void sendChangePasswordHelpdeskEmailNotice(
      final PwmSession pwmSession,
      final PwmApplication pwmApplication,
      final UserInfoBean userInfoBean)
      throws PwmUnrecoverableException {
    final Configuration config = pwmApplication.getConfig();
    final Locale locale = pwmSession.getSessionStateBean().getLocale();
    final EmailItemBean configuredEmailSetting =
        config.readSettingAsEmail(PwmSetting.EMAIL_CHANGEPASSWORD_HELPDESK, locale);

    if (configuredEmailSetting == null) {
      LOGGER.debug(
          pwmSession,
          "skipping send change password email for '"
              + pwmSession.getUserInfoBean().getUserIdentity()
              + "' no email configured");
      return;
    }

    final MacroMachine macroMachine =
        userInfoBean == null
            ? null
            : new MacroMachine(
                pwmApplication,
                pwmSession.getLabel(),
                userInfoBean,
                null,
                LdapUserDataReader.appProxiedReader(
                    pwmApplication, userInfoBean.getUserIdentity()));

    pwmApplication.getEmailQueue().submitEmail(configuredEmailSetting, userInfoBean, macroMachine);
  }
Пример #11
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());
  }
Пример #12
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");
    }
  }
Пример #13
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));
  }
Пример #14
0
 public void close() {
   status = STATUS.CLOSED;
   LOGGER.debug("closed");
   if (cleanerTimer != null) {
     cleanerTimer.cancel();
   }
   localDB = null;
 }
Пример #15
0
  private void updateRestingCacheData() {
    final long startTime = System.currentTimeMillis();
    int examinedRecords = 0;
    ClosableIterator<UserCacheRecord> iterator = null;
    try {
      LOGGER.trace(PwmConstants.REPORTING_SESSION_LABEL, "checking size of stored cache records");
      final int totalRecords = userCacheService.size();
      LOGGER.debug(
          PwmConstants.REPORTING_SESSION_LABEL,
          "beginning cache review process of " + totalRecords + " records");
      iterator = iterator();
      Date lastLogOutputTime = new Date();
      while (iterator.hasNext() && status == STATUS.OPEN) {
        final UserCacheRecord record = iterator.next(); // (purge routine is embedded in next();

        if (summaryData != null && record != null) {
          summaryData.update(record);
        }

        examinedRecords++;

        if (TimeDuration.fromCurrent(lastLogOutputTime).isLongerThan(30, TimeUnit.SECONDS)) {
          final TimeDuration progressDuration = TimeDuration.fromCurrent(startTime);
          LOGGER.trace(
              PwmConstants.REPORTING_SESSION_LABEL,
              "cache review process in progress, examined "
                  + examinedRecords
                  + " records in "
                  + progressDuration.asCompactString());
          lastLogOutputTime = new Date();
        }
      }
      final TimeDuration totalTime = TimeDuration.fromCurrent(startTime);
      LOGGER.debug(
          PwmConstants.REPORTING_SESSION_LABEL,
          "completed cache review process of "
              + examinedRecords
              + " cached report records in "
              + totalTime.asCompactString());
    } finally {
      if (iterator != null) {
        iterator.close();
      }
    }
  }
Пример #16
0
  public void close() {
    status = PwmService.STATUS.CLOSED;
    if (connection != null) {
      try {
        connection.close();
      } catch (Exception e) {
        LOGGER.debug("error while closing DB: " + e.getMessage());
      }
    }

    try {
      driver = null;
    } catch (Exception e) {
      LOGGER.debug("error while de-registering driver: " + e.getMessage());
    }

    connection = null;
  }
Пример #17
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;
  }
Пример #18
0
    public boolean meetsChallengeSetRequirements(final ChallengeSet challengeSet) {
      if (challengeSet.getRequiredChallenges().size()
          > this.getChallengeSet().getRequiredChallenges().size()) {
        LOGGER.debug(
            localIdentifier
                + "failed meetsChallengeSetRequirements, not enough required challenge");
        return false;
      }

      for (final Challenge loopChallenge : challengeSet.getRequiredChallenges()) {
        if (loopChallenge.isAdminDefined()) {
          if (!this.getChallengeSet()
              .getChallengeTexts()
              .contains(loopChallenge.getChallengeText())) {
            LOGGER.debug(
                localIdentifier
                    + "failed meetsChallengeSetRequirements, missing required challenge text: '"
                    + loopChallenge.getChallengeText()
                    + "'");
            return false;
          }
        }
      }

      if (challengeSet.getMinRandomRequired() > 0) {
        if (this.getChallengeSet().getChallenges().size() < challengeSet.getMinRandomRequired()) {
          LOGGER.debug(
              localIdentifier
                  + "failed meetsChallengeSetRequirements, not enough questions to meet minrandom; minRandomRequired="
                  + challengeSet.getMinRandomRequired()
                  + ", ChallengesInSet="
                  + this.getChallengeSet().getChallenges().size());
          return false;
        }
      }

      return true;
    }
Пример #19
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;
  }
Пример #20
0
  private boolean isValid(final Connection connection) {
    if (connection == null) {
      return false;
    }

    if (status != PwmService.STATUS.OPEN) {
      return false;
    }

    try {
      final Method getFreeSpaceMethod = File.class.getMethod("isValid");
      final Object rawResult = getFreeSpaceMethod.invoke(connection, 10);
      return (Boolean) rawResult;
    } catch (NoSuchMethodException e) {
      /* no error, pre java 1.6 doesn't have this method */
    } catch (Exception e) {
      LOGGER.debug(
          "error checking for isValid for " + connection.toString() + ",: " + e.getMessage());
    }

    final StringBuilder sb = new StringBuilder();
    sb.append("SELECT * FROM ")
        .append(DatabaseTable.PWM_META.toString())
        .append(" WHERE " + KEY_COLUMN + " = ?");
    PreparedStatement statement = null;
    ResultSet resultSet = null;
    try {
      statement = connection.prepareStatement(sb.toString());
      statement.setString(1, KEY_ENGINE_START_PREFIX + instanceID);
      statement.setMaxRows(1);
      resultSet = statement.executeQuery();
      if (resultSet.next()) {
        resultSet.getString(VALUE_COLUMN);
      }
    } catch (SQLException e) {
      final ErrorInformation errorInformation =
          new ErrorInformation(
              PwmError.ERROR_DB_UNAVAILABLE, "isValid operation failed: " + e.getMessage());
      lastError = errorInformation;
      LOGGER.error(errorInformation.toDebugStr());
      return false;
    } finally {
      close(statement);
      close(resultSet);
    }
    return true;
  }
Пример #21
0
    public NovellWSResponseSet(final PasswordManagement service, final ForgotPasswordWSBean wsBean)
        throws ChaiValidationException {
      this.userDN = wsBean.getUserDN();
      this.service = service;
      this.localIdentifier = "NovellWSResponseSet #" + String.valueOf(lastLocalIdentifier++);
      LOGGER.debug("initialized " + localIdentifier);

      final List<Challenge> challenges = new ArrayList<>();
      for (final String loopQuestion : wsBean.getChallengeQuestions()) {
        final Challenge loopChallenge =
            new ChaiChallenge(true, loopQuestion, 1, 255, true, 0, false);
        challenges.add(loopChallenge);
      }
      locale = PwmConstants.DEFAULT_LOCALE;
      challengeSet =
          new ChaiChallengeSet(challenges, 0, locale, "NovellWSResponseSet derived ChallengeSet");
    }
Пример #22
0
  @GET
  @Path("/audit")
  @Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
  public Response doGetAppAuditData(@QueryParam("maximum") int maximum)
      throws ChaiUnavailableException, PwmUnrecoverableException {
    maximum = maximum > 0 ? maximum : 10 * 1000;

    final RestRequestBean restRequestBean;
    try {
      final ServicePermissions servicePermissions = new ServicePermissions();
      servicePermissions.setAdminOnly(true);
      servicePermissions.setAuthRequired(true);
      servicePermissions.setBlockExternal(true);
      restRequestBean =
          RestServerHelper.initializeRestRequest(request, response, servicePermissions, null);
    } catch (PwmUnrecoverableException e) {
      return RestResultBean.fromError(e.getErrorInformation()).asJsonResponse();
    }

    final ArrayList<UserAuditRecord> userRecords = new ArrayList<>();
    final ArrayList<HelpdeskAuditRecord> helpdeskRecords = new ArrayList<>();
    final ArrayList<SystemAuditRecord> systemRecords = new ArrayList<>();
    final Iterator<AuditRecord> iterator =
        restRequestBean.getPwmApplication().getAuditManager().readVault();
    int counter = 0;
    while (iterator.hasNext() && counter <= maximum) {
      final AuditRecord loopRecord = iterator.next();
      counter++;
      if (loopRecord instanceof SystemAuditRecord) {
        systemRecords.add((SystemAuditRecord) loopRecord);
      } else if (loopRecord instanceof HelpdeskAuditRecord) {
        helpdeskRecords.add((HelpdeskAuditRecord) loopRecord);
      } else if (loopRecord instanceof UserAuditRecord) {
        userRecords.add((UserAuditRecord) loopRecord);
      }
    }
    final HashMap<String, List> outputMap = new HashMap<>();
    outputMap.put("user", userRecords);
    outputMap.put("helpdesk", helpdeskRecords);
    outputMap.put("system", systemRecords);

    final RestResultBean restResultBean = new RestResultBean();
    restResultBean.setData(outputMap);
    LOGGER.debug(restRequestBean.getPwmSession(), "output " + counter + " audit records.");
    return restResultBean.asJsonResponse();
  }
Пример #23
0
  private void sendUpdateGuestEmailConfirmation(
      final PwmRequest pwmRequest, final UserInfoBean guestUserInfoBean)
      throws PwmUnrecoverableException {
    final Configuration config = pwmRequest.getConfig();
    final Locale locale = pwmRequest.getLocale();
    final EmailItemBean configuredEmailSetting =
        config.readSettingAsEmail(PwmSetting.EMAIL_UPDATEGUEST, locale);

    if (configuredEmailSetting == null) {
      LOGGER.debug(pwmRequest, "unable to send updated guest user email: no email configured");
      return;
    }

    pwmRequest
        .getPwmApplication()
        .getEmailQueue()
        .submitEmail(configuredEmailSetting, guestUserInfoBean, null);
  }
Пример #24
0
  private void resetDailyStats() {
    try {
      final Map<String, String> emailValues = new LinkedHashMap<>();
      for (final Statistic statistic : Statistic.values()) {
        final String key = statistic.getLabel(PwmConstants.DEFAULT_LOCALE);
        final String value = statsDaily.getStatistic(statistic);
        emailValues.put(key, value);
      }

      AlertHandler.alertDailyStats(pwmApplication, emailValues);
    } catch (Exception e) {
      LOGGER.error("error while generating daily alert statistics: " + e.getMessage());
    }

    currentDailyKey = new DailyKey(new Date());
    statsDaily = new StatisticsBundle();
    LOGGER.debug("reset daily statistics");
  }
Пример #25
0
  private void handleAgreeRequest(
      final PwmRequest pwmRequest, final UpdateProfileBean updateProfileBean)
      throws ServletException, IOException, PwmUnrecoverableException, ChaiUnavailableException {
    LOGGER.debug(pwmRequest, "user accepted agreement");

    if (!updateProfileBean.isAgreementPassed()) {
      updateProfileBean.setAgreementPassed(true);
      AuditRecord auditRecord =
          pwmRequest
              .getPwmApplication()
              .getAuditManager()
              .createUserAuditRecord(
                  AuditEvent.AGREEMENT_PASSED,
                  pwmRequest.getUserInfoIfLoggedIn(),
                  pwmRequest.getSessionLabel(),
                  "UpdateProfile");
      pwmRequest.getPwmApplication().getAuditManager().submit(auditRecord);
    }
  }
Пример #26
0
    public boolean test(final Map<Challenge, String> responseTest) throws ChaiUnavailableException {
      if (service == null) {
        LOGGER.error(
            localIdentifier
                + "beginning web service 'processChaRes' response test, however service bean is not in session memory, aborting response test...");
        return false;
      }
      LOGGER.trace(localIdentifier + "beginning web service 'processChaRes' response test ");
      final String[] responseArray = new String[challengeSet.getAdminDefinedChallenges().size()];
      {
        int i = 0;
        for (final Challenge loopChallenge : challengeSet.getAdminDefinedChallenges()) {
          final String loopResponse = responseTest.get(loopChallenge);
          responseArray[i] = loopResponse;
          i++;
        }
      }
      final ProcessChaResRequest request = new ProcessChaResRequest();
      request.setChaAnswers(responseArray);
      request.setUserDN(userDN);

      try {
        final ForgotPasswordWSBean response = service.processChaRes(request);
        if (response.isTimeout()) {
          LOGGER.error(localIdentifier + "web service reports timeout: " + response.getMessage());
          return false;
        }
        if (response.isError()) {
          if ("Account restrictions prevent you from logging in. See your administrator for more details."
              .equals(response.getMessage())) {
            // throw PwmUnrecoverableException.createPwmException(PwmError.ERROR_INTRUDER_USER);
          }
          LOGGER.error(localIdentifier + "web service reports error: " + response.getMessage());
          return false;
        }
        LOGGER.debug(localIdentifier + "web service has validated the users responses");
        return true;
      } catch (RemoteException e) {
        LOGGER.error(localIdentifier + "error processing web service response: " + e.getMessage());
      }

      return false; // To change body of implemented methods use File | Settings | File Templates.
    }
Пример #27
0
  @Override
  public void writeOtpUserConfiguration(
      final PwmSession pwmSession,
      final UserIdentity theUser,
      final String userGUID,
      final OTPUserRecord otpConfig)
      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 save OTP secret for "
            + theUser
            + " in remote database (key="
            + userGUID
            + ")");

    try {
      String value = composeOtpAttribute(otpConfig);
      if (getPwmApplication().getConfig().readSettingAsBoolean(PwmSetting.OTP_SECRET_ENCRYPT)) {
        LOGGER.debug("Encrypting OTP secret for storage");
        value = encryptAttributeValue(value);
      }
      final DatabaseAccessorImpl databaseAccessor = pwmApplication.getDatabaseAccessor();
      databaseAccessor.put(DatabaseTable.OTP, userGUID, value);
      LOGGER.info("saved OTP secret for " + theUser + " in remote database (key=" + userGUID + ")");
    } catch (PwmOperationalException 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;
    }
  }
Пример #28
0
  private void restUpdateLdapForm(
      final PwmRequest pwmRequest, final ConfigGuideBean configGuideBean)
      throws IOException, PwmUnrecoverableException {
    final StoredConfiguration 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);
          {
            final String settingValue = AppProperty.LDAP_PROMISCUOUS_ENABLE.getKey() + "=true";
            storedConfiguration.writeSetting(
                PwmSetting.APP_PROPERTY_OVERRIDES,
                new StringArrayValue(Collections.singletonList(settingValue)),
                null);
          }
        }
      } 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());
  }
Пример #29
0
 public static String makeOutboundRestWSCall(
     final PwmApplication pwmApplication,
     final Locale locale,
     final String url,
     final String jsonRequestBody)
     throws PwmOperationalException, PwmUnrecoverableException {
   final HttpPost httpPost = new HttpPost(url);
   httpPost.setHeader("Accept", PwmConstants.AcceptValue.json.getHeaderValue());
   if (locale != null) {
     httpPost.setHeader("Accept-Locale", locale.toString());
   }
   httpPost.setHeader("Content-Type", PwmConstants.ContentTypeValue.json.getHeaderValue());
   final HttpResponse httpResponse;
   try {
     final StringEntity stringEntity = new StringEntity(jsonRequestBody);
     stringEntity.setContentType(PwmConstants.AcceptValue.json.getHeaderValue());
     httpPost.setEntity(stringEntity);
     LOGGER.debug(
         "beginning external rest call to: " + httpPost.toString() + ", body: " + jsonRequestBody);
     httpResponse = PwmHttpClient.getHttpClient(pwmApplication.getConfig()).execute(httpPost);
     final String responseBody = EntityUtils.toString(httpResponse.getEntity());
     LOGGER.trace(
         "external rest call returned: "
             + httpResponse.getStatusLine().toString()
             + ", body: "
             + responseBody);
     if (httpResponse.getStatusLine().getStatusCode() != 200) {
       final String errorMsg =
           "received non-200 response code ("
               + httpResponse.getStatusLine().getStatusCode()
               + ") when executing web-service";
       LOGGER.error(errorMsg);
       throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg));
     }
     return responseBody;
   } catch (IOException e) {
     final String errorMsg =
         "http response error while executing external rest call, error: " + e.getMessage();
     LOGGER.error(errorMsg);
     throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg), e);
   }
 }
Пример #30
0
    public static LocalDB initializeLocalDB(final PwmApplication pwmApplication) {
      if (pwmApplication.getApplicationMode() == MODE.ERROR
          || pwmApplication.getApplicationMode() == MODE.NEW) {
        LOGGER.warn(
            "skipping LocalDB open due to application mode " + pwmApplication.getApplicationMode());
        return null;
      }

      final File databaseDirectory;
      // see if META-INF isn't already there, then use WEB-INF.
      try {
        final String localDBLocationSetting =
            pwmApplication.getConfig().readSettingAsString(PwmSetting.PWMDB_LOCATION);
        databaseDirectory =
            Helper.figureFilepath(localDBLocationSetting, pwmApplication.applicationPath);
      } catch (Exception e) {
        pwmApplication.lastLocalDBFailure =
            new ErrorInformation(
                PwmError.ERROR_LOCALDB_UNAVAILABLE,
                "error locating configured LocalDB directory: " + e.getMessage());
        LOGGER.warn(pwmApplication.lastLocalDBFailure.toDebugStr());
        return null;
      }

      LOGGER.debug("using localDB path " + databaseDirectory);

      // initialize the localDB
      try {
        final boolean readOnly = pwmApplication.getApplicationMode() == MODE.READ_ONLY;
        return LocalDBFactory.getInstance(
            databaseDirectory, readOnly, pwmApplication, pwmApplication.getConfig());
      } catch (Exception e) {
        pwmApplication.lastLocalDBFailure =
            new ErrorInformation(
                PwmError.ERROR_LOCALDB_UNAVAILABLE,
                "unable to initialize LocalDB: " + e.getMessage());
        LOGGER.warn(pwmApplication.lastLocalDBFailure.toDebugStr());
      }

      return null;
    }