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); }
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; }
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; }
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); } }
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)); }
@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; }
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); } }
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; }
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; }
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); }
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()); }
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"); } }
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)); }
public void close() { status = STATUS.CLOSED; LOGGER.debug("closed"); if (cleanerTimer != null) { cleanerTimer.cancel(); } localDB = null; }
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(); } } }
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; }
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; }
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; }
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; }
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; }
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"); }
@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(); }
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); }
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"); }
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); } }
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. }
@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; } }
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()); }
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); } }
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; }