4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk/**
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * The contents of this file are subject to the terms
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * of the Common Development and Distribution License
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * (the License). You may not use this file except in
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * compliance with the License.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * You can obtain a copy of the License at
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * https://opensso.dev.java.net/public/CDDLv1.0.html or
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * opensso/legal/CDDLv1.0.txt
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * See the License for the specific language governing
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * permission and limitations under the License.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * When distributing Covered Code, include this CDDL
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Header Notice in each file and include the License file
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * at opensso/legal/CDDLv1.0.txt.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * If applicable, add the following below the CDDL Header,
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * with the fields enclosed by brackets [] replaced by
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * your own identifying information:
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * "Portions Copyrighted [year] [name of copyright owner]"
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * $Id: DataStore.java,v 1.4 2008/06/25 05:41:56 qcheng Exp $
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk *
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk/**
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Portions Copyrighted [2011] [ForgeRock AS]
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkpackage com.sun.identity.authentication.modules.datastore;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.authentication.spi.UserNamePasswordValidationException;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.shared.debug.Debug;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.shared.datastruct.CollectionHelper;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.authentication.spi.AMLoginModule;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.authentication.spi.AuthLoginException;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.authentication.spi.InvalidPasswordException;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.authentication.util.ISAuthConstants;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.idm.AMIdentityRepository;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.idm.IdRepoException;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.sm.ServiceConfig;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport java.util.Map;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport java.util.ResourceBundle;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport javax.security.auth.Subject;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport javax.security.auth.callback.Callback;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport javax.security.auth.callback.NameCallback;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport javax.security.auth.callback.PasswordCallback;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport java.security.Principal;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkpublic class DataStore extends AMLoginModule {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk // local variables
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk ResourceBundle bundle = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk protected String validatedUserID;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private String userName;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private String userPassword;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private ServiceConfig sc;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private int currentState;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private String currentConfigName;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private static String AUTHLEVEL = "sunAMAuthDataStoreAuthLevel";
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private static final String INVALID_CHARS =
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk "iplanet-am-auth-ldap-invalid-chars";
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private Map sharedState;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk public Map currentConfig;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk protected Debug debug = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk protected String amAuthDataStore;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk protected Principal userPrincipal;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk public DataStore() {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk amAuthDataStore = "amAuthDataStore";
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk debug = Debug.getInstance(amAuthDataStore);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk public void init(Subject subject, Map sharedState, Map options) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk sc = (ServiceConfig) options.get("ServiceConfig");
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk currentConfig = options;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk currentConfigName =
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk (String)options.get(ISAuthConstants.MODULE_INSTANCE_NAME);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk String authLevel = CollectionHelper.getMapAttr(options, AUTHLEVEL);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk if (authLevel != null) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk try {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk setAuthLevel(Integer.parseInt(authLevel));
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk } catch (Exception e) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk debug.error("Unable to set auth level " + authLevel,e);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk java.util.Locale locale = getLoginLocale();
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk bundle = amCache.getResBundle(amAuthDataStore, locale);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk if (debug.messageEnabled()) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk debug.message("DataStore resbundle locale=" + locale);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk this.sharedState = sharedState;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk public int process(Callback[] callbacks, int state)
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk throws AuthLoginException {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk currentState = state;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk int retVal = 0;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk Callback[] idCallbacks = new Callback[2];
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk try {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk if (currentState == ISAuthConstants.LOGIN_START) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk if (callbacks !=null && callbacks.length == 0) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk userName = (String) sharedState.get(getUserKey());
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk userPassword = (String) sharedState.get(getPwdKey());
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk if (userName == null || userPassword == null) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk return ISAuthConstants.LOGIN_START;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk NameCallback nameCallback = new NameCallback("dummy");
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk nameCallback.setName(userName);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk idCallbacks[0] = nameCallback;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk PasswordCallback passwordCallback = new PasswordCallback
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk ("dummy",false);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk passwordCallback.setPassword(userPassword.toCharArray());
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk idCallbacks[1] = passwordCallback;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk } else {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk idCallbacks = callbacks;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk //callbacks is not null
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk userName = ( (NameCallback) callbacks[0]).getName();
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk char[] password = ((PasswordCallback) callbacks[1]).getPassword();
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk userPassword = password == null ? null : String.valueOf(password);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk if (userName == null) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk debug.message("DataStore.process: Username is null/empty");
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk throw new UserNamePasswordValidationException("amAuth", "InvalidUP", null);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk if (userPassword == null || userPassword.length() == 0) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk debug.message("DataStore.process: Password is null/empty");
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk throw new InvalidPasswordException("amAuth", "invalidPasswd", null);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk //store username password both in success and failure case
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk storeUsernamePasswd(userName, userPassword);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /*
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk Fix for OPENAM-1872. Reject usernames with illegal characters (e.g. * or ! or ) or ( or & ), just
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk like the LDAP LoginModule does. List of invalid characters comes from a new configuration entry (though
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk the list of illegal characters does not seem to be processed in validateUserName). I want the invocation
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk to be just like the LDAP LoginModule, and to handle the case in which the username format validator
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk cannot be successfully loaded in validateUserName.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk validateUserName(userName, CollectionHelper.getMapAttr(
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk currentConfig, INVALID_CHARS));
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk AMIdentityRepository idrepo = getAMIdentityRepository(
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk getRequestOrg());
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk boolean success = idrepo.authenticate(idCallbacks);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk if (success) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk retVal=ISAuthConstants.LOGIN_SUCCEED;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk validatedUserID = userName;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk } else {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk throw new AuthLoginException(amAuthDataStore, "authFailed",
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk null);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk } else {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk setFailureID(userName);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk throw new AuthLoginException(amAuthDataStore, "authFailed",
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk null);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk } catch (IdRepoException ex) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk debug.message("idRepo Exception");
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk setFailureID(userName);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk throw new AuthLoginException(amAuthDataStore, "authFailed",
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk null, ex);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk return retVal;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk public java.security.Principal getPrincipal() {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk if (userPrincipal != null) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk return userPrincipal;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk else if (validatedUserID != null) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk userPrincipal = new DataStorePrincipal(validatedUserID);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk return userPrincipal;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk } else {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk return null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk // cleanup state fields
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk public void destroyModuleState() {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk validatedUserID = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk userPrincipal = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk public void nullifyUsedVars() {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk bundle = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk userName = null ;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk userPassword = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk sc = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk sharedState = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk currentConfig = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk amAuthDataStore = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk }
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk}
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk