001: /*
002: * (C) Copyright 2000 - 2003 Nabh Information Systems, Inc.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU General Public License
006: * as published by the Free Software Foundation; either version 2
007: * of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: *
018: */
019:
020: package com.nabhinc.portal.spi.impl.jaas;
021:
022: import java.sql.SQLException;
023: import java.util.Map;
024: import java.util.Set;
025: import java.util.Vector;
026:
027: import javax.naming.NamingException;
028: import javax.security.auth.Subject;
029: import javax.security.auth.callback.Callback;
030: import javax.security.auth.callback.CallbackHandler;
031: import javax.security.auth.callback.NameCallback;
032: import javax.security.auth.callback.PasswordCallback;
033: import javax.security.auth.callback.UnsupportedCallbackException;
034: import javax.security.auth.login.LoginException;
035: import javax.security.auth.spi.LoginModule;
036:
037: import com.nabhinc.core.Defaults;
038: import com.nabhinc.spi.UserPrincipal;
039: import com.nabhinc.util.EncryptionUtil;
040: import com.nabhinc.util.db.DBUtil;
041:
042: /**
043: *
044: *
045: * @author Wirawan Chokry
046: * (c) 2003 Nabh Information Systems, Inc. All Rights Reserved.
047: */
048: public class DBLoginModule implements LoginModule {
049:
050: public static final String PASSWORD_SQL_PARAM = "passwordSQL";
051: public static final String ROLES_SQL_PARAM = "rolesSQL";
052:
053: private String dlmPasswordSQL = "SELECT pass_word FROM SB_USERS WHERE username = ";
054: private String dlmRolesSQL = "SELECT SB_ROLES.rolename FROM SB_USER_ROLES, SB_USERS, SB_ROLES WHERE SB_USERS.userid = SB_USER_ROLES.userid AND SB_ROLES.roleid = SB_USER_ROLES.roleid AND SB_USERS.username = ";
055: private Subject dlmSubject;
056: private CallbackHandler dlmCallbackHandler;
057: // private Map dlmState;
058: private Map dlmOptions;
059: // private int dlmStatus;
060:
061: private String dlmDatasourceName = Defaults.getDataSourceName();
062:
063: private UserPrincipal dlmUserPrincipal = null;
064: private Vector dlmRolePrincipals = new Vector();
065:
066: /* (non-Javadoc)
067: * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
068: */
069: public void initialize(Subject subject,
070: CallbackHandler callbackHandler, Map sharedState,
071: Map options) {
072: dlmSubject = subject;
073: dlmCallbackHandler = callbackHandler;
074: // dlmState = sharedState;
075: dlmOptions = options;
076: if (dlmOptions != null) {
077: String temp = (String) dlmOptions.get("data-source");
078: if (temp != null)
079: dlmDatasourceName = temp;
080: temp = (String) dlmOptions.get(PASSWORD_SQL_PARAM);
081: if (temp != null)
082: dlmPasswordSQL = temp;
083:
084: temp = (String) dlmOptions.get(ROLES_SQL_PARAM);
085: if (temp != null)
086: dlmRolesSQL = temp;
087:
088: }
089: }
090:
091: /* (non-Javadoc)
092: * @see javax.security.auth.spi.LoginModule#abort()
093: */
094: public boolean abort() throws LoginException {
095:
096: if (dlmSubject != null && dlmRolePrincipals != null) {
097:
098: Set entities = dlmSubject.getPrincipals();
099:
100: if (entities.contains(dlmUserPrincipal)) {
101: entities.remove(dlmUserPrincipal);
102: }
103:
104: for (int i = 0; i < dlmRolePrincipals.size(); i++) {
105: if (entities.contains(dlmRolePrincipals.elementAt(i))) {
106: entities.remove(dlmRolePrincipals.elementAt(i));
107: }
108: }
109: }
110: //dlmSubject = null;
111: dlmUserPrincipal = null;
112: dlmRolePrincipals = null;
113: return true;
114: }
115:
116: /* (non-Javadoc)
117: * @see javax.security.auth.spi.LoginModule#commit()
118: */
119: @SuppressWarnings("unchecked")
120: public boolean commit() throws LoginException {
121:
122: if (dlmSubject == null) {
123: return false;
124: }
125:
126: Set entities = dlmSubject.getPrincipals();
127:
128: if (!entities.contains(dlmUserPrincipal)) {
129: entities.add(dlmUserPrincipal);
130: }
131:
132: for (int i = 0; i < dlmRolePrincipals.size(); i++) {
133: if (!entities.contains(dlmRolePrincipals.get(i))) {
134: entities.add(dlmRolePrincipals.get(i));
135: }
136: }
137:
138: return true;
139: }
140:
141: /* (non-Javadoc)
142: * @see javax.security.auth.spi.LoginModule#login()
143: */
144: public boolean login() throws LoginException {
145: String userName = null;
146: char[] password = null;
147:
148: try {
149: // prompt for a username and password
150: if (dlmCallbackHandler == null)
151: throw new LoginException(
152: "CallbackHandler is null. Unable to authenticate information from the user");
153:
154: Callback[] callbacks = new Callback[2];
155: callbacks[0] = new NameCallback("Username: ");
156: callbacks[1] = new PasswordCallback("Password: ", false);
157:
158: try {
159: dlmCallbackHandler.handle(callbacks);
160:
161: userName = ((NameCallback) callbacks[0]).getName();
162:
163: password = ((PasswordCallback) callbacks[1])
164: .getPassword();
165: ((PasswordCallback) callbacks[1]).clearPassword();
166:
167: } catch (java.io.IOException ex) {
168: throw new LoginException("Error in IO: "
169: + ex.getMessage());
170: } catch (UnsupportedCallbackException uce) {
171: throw new LoginException("Error: Callback "
172: + uce.getCallback().toString()
173: + " is not supported.");
174: }
175:
176: validateUser(userName, password);
177:
178: return true;
179:
180: } finally {
181: //remove password from memory
182: }
183:
184: }
185:
186: /* (non-Javadoc)
187: * @see javax.security.auth.spi.LoginModule#logout()
188: */
189: public boolean logout() throws LoginException {
190: Set entities = dlmSubject.getPrincipals();
191:
192: if (entities.contains(dlmUserPrincipal)) {
193: entities.remove(dlmUserPrincipal);
194: }
195:
196: for (int i = 0; i < dlmRolePrincipals.size(); i++) {
197: if (entities.contains(dlmRolePrincipals.get(i))) {
198: entities.remove(dlmRolePrincipals.get(i));
199: }
200: }
201:
202: dlmUserPrincipal = null;
203: dlmRolePrincipals = null;
204:
205: return true;
206: }
207:
208: @SuppressWarnings("unchecked")
209: private synchronized void validateUser(String userName,
210: char password[]) throws LoginException {
211: String passwdStr = new String(password);
212: try {
213: if (Defaults.getEncryptionAlgorithm() != null
214: && password != null) {
215: passwdStr = EncryptionUtil.encrypt(passwdStr, Defaults
216: .getEncryptionAlgorithm());
217: }
218:
219: String actualPassword = DBUtil.getField(dlmDatasourceName,
220: dlmPasswordSQL + "'" + userName + "'",
221: java.sql.Types.VARCHAR, null);
222:
223: if (actualPassword == null
224: || !actualPassword.equals(passwdStr))
225: throw new LoginException(
226: "Invalid Username or Password.");
227:
228: dlmUserPrincipal = new UserPrincipal(userName);
229:
230: Vector roleVec = DBUtil.getFields(dlmDatasourceName,
231: dlmRolesSQL + "'" + userName + "'",
232: java.sql.Types.VARCHAR, null);
233:
234: dlmRolePrincipals = new Vector();
235: for (int i = 0; i < roleVec.size(); i++) {
236: dlmRolePrincipals.add(new RolePrincipal(
237: (String) roleVec.get(i)));
238: }
239:
240: } catch (NamingException nex) {
241: throw new LoginException("Error: " + nex.getMessage());
242:
243: } catch (SQLException sex) {
244: throw new LoginException("Error: " + sex.getMessage());
245:
246: }
247:
248: }
249:
250: }
|