bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The contents of this file are subject to the terms
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * of the Common Development and Distribution License
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (the License). You may not use this file except in
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * compliance with the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You can obtain a copy of the License at
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * opensso/legal/CDDLv1.0.txt
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * See the License for the specific language governing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * permission and limitations under the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * When distributing Covered Code, include this CDDL
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Header Notice in each file and include the License file
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * at opensso/legal/CDDLv1.0.txt.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If applicable, add the following below the CDDL Header,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * with the fields enclosed by brackets [] replaced by
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * your own identifying information:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * $Id: SMSAuthModule.java,v 1.9 2009/12/11 06:51:37 hengming Exp $
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
d5a35ee0e81c6fb618b79309f71177dc876cbd65Neil Madden * Portions Copyrighted 2011-2016 ForgeRock AS.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpackage com.sun.identity.authentication.internal.server;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport static org.forgerock.openam.ldap.LDAPUtils.rdnValueFromDn;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.sso.SSOToken;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.authentication.internal.AuthPrincipal;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.authentication.internal.AuthSubject;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.authentication.internal.LoginModule;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.authentication.spi.InvalidPasswordException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.authentication.util.ISAuthConstants;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.common.DNUtils;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.security.AdminDNAction;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.security.AdminPasswordAction;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.security.AdminTokenAction;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.shared.debug.Debug;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.shared.encode.Hash;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.SMSEntry;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.ServiceConfig;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.ServiceConfigManager;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.ServiceListener;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.ServiceSchemaManager;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.io.IOException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.security.AccessController;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Collections;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.HashMap;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Iterator;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Map;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Set;
d5a35ee0e81c6fb618b79309f71177dc876cbd65Neil Maddenimport java.util.concurrent.ConcurrentSkipListMap;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport javax.security.auth.callback.Callback;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport javax.security.auth.callback.CallbackHandler;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport javax.security.auth.callback.NameCallback;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport javax.security.auth.callback.PasswordCallback;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport javax.security.auth.callback.UnsupportedCallbackException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport javax.security.auth.login.LoginException;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport org.forgerock.openam.ldap.LDAPUtils;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * AM's internal user's authentication module
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpublic class SMSAuthModule implements LoginModule {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Static variables
d5a35ee0e81c6fb618b79309f71177dc876cbd65Neil Madden private static volatile boolean initialized = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
d5a35ee0e81c6fb618b79309f71177dc876cbd65Neil Madden private static volatile boolean loadedInternalUsers = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
d5a35ee0e81c6fb618b79309f71177dc876cbd65Neil Madden private static volatile boolean registeredCallbackHandler = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
d5a35ee0e81c6fb618b79309f71177dc876cbd65Neil Madden private static final Map<String, String> users = new ConcurrentSkipListMap<>(String.CASE_INSENSITIVE_ORDER);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
d5a35ee0e81c6fb618b79309f71177dc876cbd65Neil Madden private static final Map<String, String> userNameToDN = new ConcurrentSkipListMap<>(String.CASE_INSENSITIVE_ORDER);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
d5a35ee0e81c6fb618b79309f71177dc876cbd65Neil Madden private static final Debug debug = Debug.getInstance("amAuthInternalSMModule");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Instance variables
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster AuthSubject subject;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String userDN;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster CallbackHandler cb;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Map sharedState;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Map options;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Constants
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static final String IDREPO_SERVICE = "sunIdentityRepositoryService";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static final String USERS = "users";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static final String DN = "dn";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static final String PASSWORD = "userPassword";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public SMSAuthModule() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // do nothing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule constructor called");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void initialize(AuthSubject subject, CallbackHandler cb,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Map isharedstate, Map ioptions) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster this.subject = subject;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster this.cb = cb;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster this.sharedState = (isharedstate != null) ? isharedstate
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster : Collections.EMPTY_MAP;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster this.options = (ioptions != null) ? ioptions : Collections.EMPTY_MAP;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Copy the shared state and remove password for debugging
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Map ss = new HashMap(sharedState);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean passwordPresent = (ss
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster .remove(ISAuthConstants.SHARED_STATE_PASSWORD) == null)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ? false
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster : true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule::initialize called "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "\nPrincipals: "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + ((subject != null) ? subject.getPrincipals().toString()
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster : "null")
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "\nSharedState: "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + ss
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "\n"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + (passwordPresent ? "<Password Present> "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster : "<Password Absent>") + "\nOptions: " + options);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!initialized) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster initialize();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static void initialize() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule.initialize() Initializing "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Username and password from serverconfig.xml");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // reset so that internal users set will be reloaded later in time.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster loadedInternalUsers = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // initialize caches.
d5a35ee0e81c6fb618b79309f71177dc876cbd65Neil Madden users.clear();
d5a35ee0e81c6fb618b79309f71177dc876cbd65Neil Madden userNameToDN.clear();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get internal user names and passwords from serverconfig.xml
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // %%% Might have to get them directory from DSConfigMgr %%%
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // if other than "default" needs to be used
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String name = (String) AccessController
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster .doPrivileged(new AdminDNAction());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String passwd = (String) AccessController
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster .doPrivileged(new AdminPasswordAction());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster addUserToCache(name, Hash.hash(passwd));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule.initialize() Username "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "serviceconfig.xml: " + name);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster initialized = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public boolean login() throws LoginException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check if the user is already present
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String username = (String) sharedState
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster .get(ISAuthConstants.SHARED_STATE_USERNAME);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String password = (String) sharedState
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster .get(ISAuthConstants.SHARED_STATE_PASSWORD);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule::login() From shared state: "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Username: " + username + " Password: "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + ((password == null) ? "<not present>" : "<present>"));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check if we have username and password, if not send callbacks
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (username == null || password == null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Request for both username and password
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Callback cbs[] = new Callback[2];
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cbs[0] = new NameCallback("User name: ");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cbs[1] = new PasswordCallback("Password: ", false);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule::login() Sending "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Name & Password Callback");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cb.handle(cbs);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (UnsupportedCallbackException e) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw (new LoginException(e.getMessage()));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (IOException ioe) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw (new LoginException(ioe.getMessage()));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster username = ((NameCallback) cbs[0]).getName();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster char[] passwd = ((PasswordCallback) cbs[1]).getPassword();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (passwd != null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster password = new String(password);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Authenticate the user, return false is username or password is null
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean authenticated = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (username != null && password != null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule::login() For authentication: "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Username: " + username + " Password: <present>");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (LDAPUtils.isDN(username)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster userDN = username;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington username = rdnValueFromDn(username);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster userDN = (String) userNameToDN.get(username);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (userDN == null && !loadedInternalUsers) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Load the internal users and try to get userDN
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster loadInternalUsers();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster userDN = (String) userNameToDN.get(username);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Need to make sure userDN is not null, since this
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // be set in the subject
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (userDN != null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get the hashed password for the user
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String hash = (String) users.get(username);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String cachedUserDN = (String) userNameToDN.get(username);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (cachedUserDN != null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String normalizedUserDN = DNUtils.normalizeDN(userDN);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((normalizedUserDN == null) ||
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster !normalizedUserDN.equals(DNUtils.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster normalizeDN(cachedUserDN))) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule::login() Invalid User DN");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Compare the hashed password
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean invalidPassword = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (hash != null && hash.equals(Hash.hash(password))) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule::login() Success AuthN");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster authenticated = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (!loadedInternalUsers) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Load the internal users and compare hashed passwords
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule::login() "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Loading internal users");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster loadInternalUsers();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cachedUserDN = (String) userNameToDN.get(username);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (cachedUserDN != null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String normalizedUserDN = DNUtils.normalizeDN(userDN);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((normalizedUserDN == null) ||
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster !normalizedUserDN.equals(DNUtils.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster normalizeDN(cachedUserDN))) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule::login() "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Invalid User DN");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster hash = (String) users.get(username);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (hash != null && hash.equals(Hash.hash(password))) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule::login() "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Success AuthN");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster authenticated = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (hash != null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Password must be invalid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster invalidPassword = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (hash != null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Password must be invalid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster invalidPassword = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (invalidPassword) {
181a73d2546f0674bf1fe178e9ff2b420b83a949Quentin CASTEL if (debug.messageEnabled()) {
181a73d2546f0674bf1fe178e9ff2b420b83a949Quentin CASTEL debug.message("SMSAuthModule::login() Invalid password for username: {}", username);
181a73d2546f0674bf1fe178e9ff2b420b83a949Quentin CASTEL }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw (new InvalidPasswordException("invalid password",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster userDN));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (authenticated);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public boolean abort() throws LoginException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // do nothing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (true);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public boolean commit() throws LoginException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // add username to Subject
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule::commit() Adding Principal: " + userDN
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + " to Subject");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set principals = subject.getPrincipals();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (principals.isEmpty()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster principals.add(new AuthPrincipal(userDN));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (true);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public boolean logout() throws LoginException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // do nothing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (true);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static synchronized void loadInternalUsers() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (loadedInternalUsers) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get AdminSSOToken
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SSOToken ssoToken = (SSOToken) AccessController
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster .doPrivileged(AdminTokenAction.getInstance());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ServiceConfigManager scm = new ServiceConfigManager(IDREPO_SERVICE,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ssoToken);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ServiceSchemaManager ssm = new ServiceSchemaManager(IDREPO_SERVICE,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ssoToken);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ServiceConfig sc = scm.getGlobalConfig(null);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sc = sc.getSubConfig(USERS);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (Iterator items = sc.getSubConfigNames().iterator(); items
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster .hasNext();) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String scName = (String) items.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ServiceConfig s = sc.getSubConfig(scName);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Map attrs = s.getAttributes();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String name = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set set = (Set) attrs.get(DN);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (set != null && !set.isEmpty()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster name = (String) set.iterator().next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Add root suffix, if revision is greater than 30
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (ssm.getRevisionNumber() >= 30) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // In the case of upgrade the DN will have the suffix
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Hence check if it ends with SMS root suffix
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (name.toLowerCase().endsWith(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.getRootSuffix().toLowerCase())) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Replace only if the they are different
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!SMSEntry.getRootSuffix().equals(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.getAMSdkBaseDN())) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster name = name.substring(0, name.length() -
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.getRootSuffix().length());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster name = name + SMSEntry.getAMSdkBaseDN();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster name = name + SMSEntry.getAMSdkBaseDN();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String hash = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster set = (Set) attrs.get(PASSWORD);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (set != null && !set.isEmpty()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster hash = (String) set.iterator().next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModule::loadInternalUsers() "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Added user: " + name);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster addUserToCache(name, hash);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster loadedInternalUsers = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Setup listeners
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!registeredCallbackHandler) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster scm.addListener(new SMSAuthModuleListener());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster registeredCallbackHandler = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (Exception e) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Handle the exception
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static void addUserToCache(String name, String hash) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Add the DN
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster users.put(name, hash);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Add the "name"
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington String username = rdnValueFromDn(name);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington users.put(username, hash);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington userNameToDN.put(username, name);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Inner class for receiving SMS notifications
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static class SMSAuthModuleListener implements ServiceListener {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSAuthModuleListener() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Do nothing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModuleListener::init called");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void schemaChanged(String serviceName, String version) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Ignore
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModuleListener::schemaChanged called");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void globalConfigChanged(String serviceName, String version,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String groupName, String serviceComponent, int type) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModuleListener::globalConfigChanged");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (serviceName.equalsIgnoreCase(IDREPO_SERVICE)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Force the loading of internal users
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster loadedInternalUsers = false;
d5a35ee0e81c6fb618b79309f71177dc876cbd65Neil Madden users.clear();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void organizationConfigChanged(String serviceName,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String version, String orgName, String groupName,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String serviceComponent, int type) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Ignore
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSAuthModuleListener::orgConfigChanged");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}